summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.editorconfig3
-rw-r--r--.gitignore1
-rw-r--r--.travis.yml9
-rw-r--r--AUTHORS.md22
-rw-r--r--CONTRIBUTING.md127
-rw-r--r--COPYRIGHT.txt1144
-rw-r--r--LICENSE.md28
-rw-r--r--LICENSE.txt22
-rw-r--r--LOGO_LICENSE.md5
-rw-r--r--README.md2
-rw-r--r--SConstruct32
-rw-r--r--core/SCsub21
-rw-r--r--core/bind/core_bind.cpp32
-rw-r--r--core/bind/core_bind.h13
-rw-r--r--core/color.h34
-rw-r--r--core/command_queue_mt.h127
-rw-r--r--core/dvector.h8
-rw-r--r--core/global_config.cpp77
-rw-r--r--core/global_constants.cpp11
-rw-r--r--core/helper/math_fieldwise.cpp10
-rw-r--r--core/image.cpp1217
-rw-r--r--core/image.h139
-rw-r--r--core/input_map.cpp138
-rw-r--r--core/input_map.h18
-rw-r--r--core/io/compression.cpp20
-rw-r--r--core/io/compression.h9
-rw-r--r--core/io/file_access_compressed.cpp2
-rw-r--r--core/io/file_access_compressed.h2
-rw-r--r--core/io/file_access_pack.cpp9
-rw-r--r--core/io/http_client.cpp14
-rw-r--r--core/io/image_loader.cpp5
-rw-r--r--core/io/image_loader.h4
-rw-r--r--core/io/ip.cpp65
-rw-r--r--core/io/marshalls.cpp213
-rw-r--r--core/io/resource_format_binary.cpp174
-rw-r--r--core/io/resource_import.h1
-rw-r--r--core/math/a_star.cpp16
-rw-r--r--core/math/a_star.h2
-rw-r--r--core/math/bsp_tree.cpp6
-rw-r--r--core/math/camera_matrix.cpp8
-rw-r--r--core/math/face3.cpp28
-rw-r--r--core/math/face3.h54
-rw-r--r--core/math/geometry.cpp6
-rw-r--r--core/math/math_2d.cpp2
-rw-r--r--core/math/math_2d.h229
-rw-r--r--core/math/math_funcs.h25
-rw-r--r--core/math/matrix3.h6
-rw-r--r--core/math/octree.h26
-rw-r--r--core/math/quick_hull.cpp2
-rw-r--r--core/math/rect3.cpp92
-rw-r--r--core/math/rect3.h118
-rw-r--r--core/math/transform.cpp13
-rw-r--r--core/math/transform.h48
-rw-r--r--core/math/triangle_mesh.cpp6
-rw-r--r--core/message_queue.cpp25
-rw-r--r--core/method_bind.h3
-rw-r--r--core/method_ptrcall.h3
-rw-r--r--core/object.cpp12
-rw-r--r--core/object.h12
-rw-r--r--core/os/file_access.cpp21
-rw-r--r--core/os/file_access.h1
-rw-r--r--core/os/input.h4
-rw-r--r--core/os/input_event.cpp984
-rw-r--r--core/os/input_event.h311
-rw-r--r--core/os/main_loop.cpp4
-rw-r--r--core/os/main_loop.h2
-rw-r--r--core/os/os.cpp2
-rw-r--r--core/os/os.h5
-rw-r--r--core/packed_data_container.cpp2
-rw-r--r--core/register_core_types.cpp14
-rw-r--r--core/resource.cpp2
-rw-r--r--core/resource.h2
-rw-r--r--core/ring_buffer.h26
-rw-r--r--core/script_debugger_remote.cpp4
-rw-r--r--core/script_language.h2
-rw-r--r--core/translation.h2
-rw-r--r--core/ustring.cpp67
-rw-r--r--core/ustring.h9
-rw-r--r--core/variant.cpp89
-rw-r--r--core/variant.h23
-rw-r--r--core/variant_call.cpp166
-rw-r--r--core/variant_op.cpp807
-rw-r--r--core/variant_parser.cpp551
-rw-r--r--doc/Makefile19
-rw-r--r--doc/base/classes.xml4908
-rw-r--r--[-rwxr-xr-x]doc/tools/doc_status.py0
-rw-r--r--doc/tools/locales/es/LC_MESSAGES/makedocs.mobin2321 -> 0 bytes
-rw-r--r--doc/tools/locales/es/LC_MESSAGES/makedocs.po142
-rw-r--r--doc/tools/main.css146
-rw-r--r--doc/tools/makedocs.pot108
-rw-r--r--doc/tools/makedocs.py383
-rw-r--r--doc/tools/makedoku.py499
-rw-r--r--doc/tools/makehtml.py689
-rw-r--r--doc/tools/makemd.py6
-rw-r--r--doc/tools/makerst.py6
-rw-r--r--drivers/gles2/rasterizer_gles2.cpp4
-rw-r--r--drivers/gles2/shaders/canvas.glsl19
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.cpp311
-rw-r--r--drivers/gles3/rasterizer_canvas_gles3.h14
-rw-r--r--drivers/gles3/rasterizer_gles3.cpp21
-rw-r--r--drivers/gles3/rasterizer_gles3.h2
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.cpp801
-rw-r--r--drivers/gles3/rasterizer_scene_gles3.h130
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.cpp753
-rw-r--r--drivers/gles3/rasterizer_storage_gles3.h100
-rw-r--r--drivers/gles3/shader_compiler_gles3.cpp21
-rw-r--r--drivers/gles3/shader_gles3.cpp16
-rw-r--r--drivers/gles3/shaders/canvas.glsl105
-rw-r--r--drivers/gles3/shaders/copy.glsl85
-rw-r--r--drivers/gles3/shaders/cubemap_filter.glsl35
-rw-r--r--drivers/gles3/shaders/particles.glsl7
-rw-r--r--drivers/gles3/shaders/resolve.glsl2
-rw-r--r--drivers/gles3/shaders/scene.glsl319
-rw-r--r--drivers/gles3/shaders/screen_space_reflection.glsl47
-rw-r--r--drivers/gles3/shaders/ssao.glsl16
-rw-r--r--drivers/gles3/shaders/ssao_blur.glsl2
-rw-r--r--drivers/gles3/shaders/subsurf_scattering.glsl4
-rw-r--r--drivers/gles3/shaders/tonemap.glsl32
-rw-r--r--drivers/png/image_loader_png.cpp43
-rw-r--r--drivers/png/image_loader_png.h4
-rw-r--r--drivers/png/resource_saver_png.cpp61
-rw-r--r--drivers/png/resource_saver_png.h3
-rw-r--r--drivers/unix/ip_unix.cpp15
-rw-r--r--drivers/unix/packet_peer_udp_posix.cpp2
-rw-r--r--drivers/unix/socket_helpers.h10
-rw-r--r--editor/SCsub28
-rw-r--r--editor/animation_editor.cpp1615
-rw-r--r--editor/animation_editor.h2
-rw-r--r--editor/asset_library_editor_plugin.cpp9
-rw-r--r--editor/code_editor.cpp31
-rw-r--r--editor/code_editor.h4
-rw-r--r--editor/connections_dialog.cpp6
-rw-r--r--editor/create_dialog.cpp18
-rw-r--r--editor/create_dialog.h2
-rw-r--r--editor/doc/doc_data.cpp140
-rw-r--r--editor/doc/doc_dump.cpp15
-rw-r--r--editor/editor_asset_installer.cpp6
-rw-r--r--editor/editor_audio_buses.cpp40
-rw-r--r--editor/editor_audio_buses.h2
-rw-r--r--editor/editor_data.cpp7
-rw-r--r--editor/editor_export.cpp162
-rw-r--r--editor/editor_export.h5
-rw-r--r--editor/editor_file_dialog.cpp27
-rw-r--r--editor/editor_file_dialog.h2
-rw-r--r--editor/editor_file_system.cpp11
-rw-r--r--editor/editor_file_system.h2
-rw-r--r--editor/editor_fonts.cpp4
-rw-r--r--editor/editor_help.cpp53
-rw-r--r--editor/editor_help.h10
-rw-r--r--editor/editor_log.cpp3
-rw-r--r--editor/editor_name_dialog.cpp10
-rw-r--r--editor/editor_name_dialog.h2
-rw-r--r--editor/editor_node.cpp749
-rw-r--r--editor/editor_node.h45
-rw-r--r--editor/editor_path.cpp5
-rw-r--r--editor/editor_path.h2
-rw-r--r--editor/editor_plugin.cpp29
-rw-r--r--editor/editor_plugin.h13
-rw-r--r--editor/editor_profiler.cpp20
-rw-r--r--editor/editor_profiler.h2
-rw-r--r--editor/editor_resource_preview.cpp16
-rw-r--r--editor/editor_run.cpp24
-rw-r--r--editor/editor_run_native.cpp9
-rw-r--r--editor/editor_settings.cpp100
-rw-r--r--editor/editor_settings.h4
-rw-r--r--editor/editor_themes.cpp444
-rw-r--r--editor/filesystem_dock.cpp15
-rw-r--r--editor/icons/2x/icon_checked.pngbin0 -> 534 bytes
-rw-r--r--editor/icons/2x/icon_dropdown.pngbin0 -> 327 bytes
-rw-r--r--editor/icons/2x/icon_godot.pngbin1842 -> 0 bytes
-rw-r--r--editor/icons/2x/icon_godot_docs.pngbin0 -> 1840 bytes
-rw-r--r--editor/icons/2x/icon_hslider_bg.pngbin0 -> 233 bytes
-rw-r--r--editor/icons/2x/icon_option_arrow.pngbin0 -> 360 bytes
-rw-r--r--editor/icons/2x/icon_play_button_group.pngbin0 -> 942 bytes
-rw-r--r--editor/icons/2x/icon_slider_grabber.pngbin0 -> 686 bytes
-rw-r--r--editor/icons/2x/icon_slider_grabber_hl.pngbin0 -> 672 bytes
-rw-r--r--editor/icons/2x/icon_spinbox_updown.pngbin0 -> 562 bytes
-rw-r--r--editor/icons/2x/icon_tab_menu.pngbin0 -> 277 bytes
-rw-r--r--editor/icons/2x/icon_texture.pngbin0 -> 262 bytes
-rw-r--r--editor/icons/2x/icon_tree_arrow_down.pngbin0 -> 312 bytes
-rw-r--r--editor/icons/2x/icon_tree_arrow_right.pngbin0 -> 319 bytes
-rw-r--r--editor/icons/2x/icon_unchecked.pngbin0 -> 404 bytes
-rw-r--r--editor/icons/2x/icon_vslider_bg.pngbin0 -> 236 bytes
-rw-r--r--editor/icons/SCsub6
-rw-r--r--editor/icons/icon_checked.pngbin0 -> 377 bytes
-rw-r--r--editor/icons/icon_default_project_icon.pngbin2713 -> 3480 bytes
-rw-r--r--editor/icons/icon_dropdown.pngbin0 -> 179 bytes
-rw-r--r--editor/icons/icon_godot.pngbin769 -> 0 bytes
-rw-r--r--editor/icons/icon_godot_docs.pngbin0 -> 722 bytes
-rw-r--r--editor/icons/icon_h_button_array.pngbin163 -> 0 bytes
-rw-r--r--editor/icons/icon_hslider_bg.pngbin0 -> 233 bytes
-rw-r--r--editor/icons/icon_hsplit_bg.pngbin0 -> 96 bytes
-rw-r--r--editor/icons/icon_hsplitter.pngbin0 -> 132 bytes
-rw-r--r--editor/icons/icon_logo.pngbin6211 -> 11594 bytes
-rw-r--r--editor/icons/icon_logo_small.pngbin1825 -> 1465 bytes
-rw-r--r--editor/icons/icon_option_arrow.pngbin0 -> 205 bytes
-rw-r--r--editor/icons/icon_play_button_group.png (renamed from scene/resources/default_theme/button_group.png)bin427 -> 427 bytes
-rw-r--r--editor/icons/icon_scroll_bg.pngbin0 -> 90 bytes
-rw-r--r--editor/icons/icon_scroll_grabber.pngbin0 -> 147 bytes
-rw-r--r--editor/icons/icon_scroll_grabber_hl.pngbin0 -> 268 bytes
-rw-r--r--editor/icons/icon_slider_grabber.pngbin0 -> 384 bytes
-rw-r--r--editor/icons/icon_slider_grabber_hl.pngbin0 -> 354 bytes
-rw-r--r--editor/icons/icon_spinbox_updown.pngbin0 -> 345 bytes
-rw-r--r--editor/icons/icon_tab_menu.pngbin251 -> 146 bytes
-rw-r--r--editor/icons/icon_texture.pngbin0 -> 200 bytes
-rw-r--r--editor/icons/icon_tree_arrow_down.pngbin0 -> 170 bytes
-rw-r--r--editor/icons/icon_tree_arrow_right.pngbin0 -> 189 bytes
-rw-r--r--editor/icons/icon_unchecked.pngbin0 -> 267 bytes
-rw-r--r--editor/icons/icon_v_button_array.pngbin147 -> 0 bytes
-rw-r--r--editor/icons/icon_vslider_bg.pngbin0 -> 236 bytes
-rw-r--r--editor/icons/icon_vsplit_bg.pngbin0 -> 96 bytes
-rw-r--r--editor/icons/icon_vsplitter.pngbin0 -> 122 bytes
-rw-r--r--editor/icons/source/icon_3_d.svg105
-rw-r--r--editor/icons/source/icon_checked.svg (renamed from scene/resources/default_theme/source/checked.svg)0
-rw-r--r--editor/icons/source/icon_dropdown.svg (renamed from scene/resources/default_theme/source/dropdown.svg)0
-rw-r--r--editor/icons/source/icon_godot.svg168
-rw-r--r--editor/icons/source/icon_godot_docs.svg173
-rw-r--r--editor/icons/source/icon_hslider_bg.svg (renamed from scene/resources/default_theme/source/hslider_bg.svg)22
-rw-r--r--editor/icons/source/icon_hsplitter.svg (renamed from scene/resources/default_theme/source/hsplitter.svg)0
-rw-r--r--editor/icons/source/icon_mini_matrix32.svg145
-rw-r--r--editor/icons/source/icon_option_arrow.svg (renamed from scene/resources/default_theme/source/tab.svg)25
-rw-r--r--editor/icons/source/icon_particles_shader.svg159
-rw-r--r--editor/icons/source/icon_play_button_group.svg (renamed from scene/resources/default_theme/source/button_group.svg)0
-rw-r--r--editor/icons/source/icon_scroll_bg.svg (renamed from scene/resources/default_theme/source/scroll_bg.svg)0
-rw-r--r--editor/icons/source/icon_scroll_grabber.svg (renamed from scene/resources/default_theme/source/scroll_grabber.svg)0
-rw-r--r--editor/icons/source/icon_scroll_grabber_hl.svg (renamed from scene/resources/default_theme/source/scroll_grabber_hl.svg)29
-rw-r--r--editor/icons/source/icon_slider_grabber.svg (renamed from scene/resources/default_theme/source/hslider_grabber.svg)18
-rw-r--r--editor/icons/source/icon_slider_grabber_hl.svg (renamed from scene/resources/default_theme/source/hslider_grabber_hl.svg)26
-rw-r--r--editor/icons/source/icon_spatial_shader.svg165
-rw-r--r--editor/icons/source/icon_spinbox_updown.svg (renamed from scene/resources/default_theme/source/scroll_button_down.svg)48
-rw-r--r--editor/icons/source/icon_tab_menu.svg (renamed from editor/icons/source/icon_2_d.svg)47
-rw-r--r--editor/icons/source/icon_texture.svg137
-rw-r--r--editor/icons/source/icon_tree_arrow_down.svg (renamed from scene/resources/default_theme/source/vseparator.svg)23
-rw-r--r--editor/icons/source/icon_tree_arrow_right.svg (renamed from scene/resources/default_theme/source/hseparator.svg)23
-rw-r--r--editor/icons/source/icon_unchecked.svg (renamed from scene/resources/default_theme/source/unchecked.svg)0
-rw-r--r--editor/icons/source/icon_vslider_bg.svg (renamed from scene/resources/default_theme/source/vslider_bg.svg)0
-rw-r--r--editor/icons/source/icon_vsplit_bg.svg (renamed from scene/resources/default_theme/source/vsplit_bg.svg)0
-rw-r--r--editor/icons/source/icon_vsplitter.svg (renamed from scene/resources/default_theme/source/vsplitter.svg)0
-rw-r--r--editor/import/editor_import_collada.cpp27
-rw-r--r--editor/import/editor_import_plugin.cpp152
-rw-r--r--editor/import/editor_import_plugin.h (renamed from scene/3d/quad.h)58
-rw-r--r--editor/import/resource_importer_csv_translation.cpp4
-rw-r--r--editor/import/resource_importer_obj.cpp16
-rw-r--r--editor/import/resource_importer_scene.cpp32
-rw-r--r--editor/import/resource_importer_scene.h5
-rw-r--r--editor/import/resource_importer_texture.cpp155
-rw-r--r--editor/import/resource_importer_texture.h8
-rw-r--r--editor/import/resource_importer_wav.cpp4
-rw-r--r--editor/io_plugins/editor_font_import_plugin.cpp14
-rw-r--r--editor/io_plugins/editor_mesh_import_plugin.cpp2
-rw-r--r--editor/io_plugins/editor_sample_import_plugin.cpp6
-rw-r--r--editor/io_plugins/editor_texture_import_plugin.cpp10
-rw-r--r--editor/io_plugins/editor_translation_import_plugin.cpp2
-rw-r--r--editor/pane_drag.cpp7
-rw-r--r--editor/pane_drag.h4
-rw-r--r--editor/plugins/animation_player_editor_plugin.cpp48
-rw-r--r--editor/plugins/animation_player_editor_plugin.h6
-rw-r--r--editor/plugins/animation_tree_editor_plugin.cpp216
-rw-r--r--editor/plugins/animation_tree_editor_plugin.h2
-rw-r--r--editor/plugins/baked_light_baker.h2
-rw-r--r--editor/plugins/canvas_item_editor_plugin.cpp274
-rw-r--r--editor/plugins/canvas_item_editor_plugin.h6
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.cpp287
-rw-r--r--editor/plugins/collision_polygon_2d_editor_plugin.h4
-rw-r--r--editor/plugins/collision_polygon_editor_plugin.cpp16
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.cpp82
-rw-r--r--editor/plugins/collision_shape_2d_editor_plugin.h4
-rw-r--r--editor/plugins/curve_editor_plugin.cpp19
-rw-r--r--editor/plugins/curve_editor_plugin.h2
-rw-r--r--editor/plugins/editor_preview_plugins.cpp542
-rw-r--r--editor/plugins/editor_preview_plugins.h60
-rw-r--r--editor/plugins/gradient_editor_plugin.cpp (renamed from editor/plugins/color_ramp_editor_plugin.cpp)50
-rw-r--r--editor/plugins/gradient_editor_plugin.h (renamed from editor/plugins/color_ramp_editor_plugin.h)16
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.cpp36
-rw-r--r--editor/plugins/gradient_texture_editor_plugin.h2
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.cpp302
-rw-r--r--editor/plugins/light_occluder_2d_editor_plugin.h4
-rw-r--r--editor/plugins/line_2d_editor_plugin.cpp123
-rw-r--r--editor/plugins/line_2d_editor_plugin.h4
-rw-r--r--editor/plugins/mesh_editor_plugin.cpp6
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.cpp361
-rw-r--r--editor/plugins/navigation_polygon_editor_plugin.h4
-rw-r--r--editor/plugins/particles_2d_editor_plugin.cpp15
-rw-r--r--editor/plugins/particles_editor_plugin.cpp8
-rw-r--r--editor/plugins/path_2d_editor_plugin.cpp517
-rw-r--r--editor/plugins/path_2d_editor_plugin.h4
-rw-r--r--editor/plugins/path_editor_plugin.cpp429
-rw-r--r--editor/plugins/path_editor_plugin.h32
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.cpp337
-rw-r--r--editor/plugins/polygon_2d_editor_plugin.h6
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.cpp2
-rw-r--r--editor/plugins/resource_preloader_editor_plugin.h2
-rw-r--r--editor/plugins/script_editor_plugin.cpp104
-rw-r--r--editor/plugins/script_editor_plugin.h13
-rw-r--r--editor/plugins/script_text_editor.cpp20
-rw-r--r--editor/plugins/script_text_editor.h4
-rw-r--r--editor/plugins/shader_editor_plugin.cpp3
-rw-r--r--editor/plugins/shader_graph_editor_plugin.cpp18
-rw-r--r--editor/plugins/spatial_editor_plugin.cpp2265
-rw-r--r--editor/plugins/spatial_editor_plugin.h107
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.h2
-rw-r--r--editor/plugins/texture_editor_plugin.cpp4
-rw-r--r--editor/plugins/texture_editor_plugin.h2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp136
-rw-r--r--editor/plugins/texture_region_editor_plugin.h2
-rw-r--r--editor/plugins/tile_map_editor_plugin.cpp691
-rw-r--r--editor/plugins/tile_map_editor_plugin.h6
-rw-r--r--editor/plugins/tile_set_editor_plugin.cpp26
-rw-r--r--editor/plugins/tile_set_editor_plugin.h1
-rw-r--r--editor/project_export.cpp3
-rw-r--r--editor/project_manager.cpp59
-rw-r--r--editor/project_manager.h4
-rw-r--r--editor/project_settings.cpp239
-rw-r--r--editor/project_settings.h15
-rw-r--r--editor/property_editor.cpp165
-rw-r--r--editor/property_editor.h2
-rw-r--r--editor/property_selector.cpp42
-rw-r--r--editor/property_selector.h5
-rw-r--r--editor/pvrtc_compress.cpp4
-rw-r--r--editor/quick_open.cpp9
-rw-r--r--editor/quick_open.h2
-rw-r--r--editor/scene_tree_dock.cpp78
-rw-r--r--editor/scene_tree_dock.h12
-rw-r--r--editor/scene_tree_editor.cpp8
-rw-r--r--editor/script_create_dialog.cpp569
-rw-r--r--editor/script_create_dialog.h21
-rw-r--r--editor/script_editor_debugger.cpp99
-rw-r--r--editor/settings_config_dialog.cpp42
-rw-r--r--editor/settings_config_dialog.h4
-rw-r--r--editor/spatial_editor_gizmos.cpp74
-rw-r--r--editor/spatial_editor_gizmos.h20
-rw-r--r--editor/translations/ar.po3
-rw-r--r--editor/translations/bg.po3
-rw-r--r--editor/translations/bn.po3
-rw-r--r--editor/translations/ca.po3
-rw-r--r--editor/translations/cs.po3
-rw-r--r--editor/translations/da.po3
-rw-r--r--editor/translations/de.po3
-rw-r--r--editor/translations/de_CH.po3
-rw-r--r--editor/translations/editor.pot3
-rw-r--r--editor/translations/el.po3
-rw-r--r--editor/translations/es.po3
-rw-r--r--editor/translations/es_AR.po3
-rwxr-xr-xeditor/translations/extract.py3
-rw-r--r--editor/translations/fa.po3
-rw-r--r--editor/translations/fr.po3
-rw-r--r--editor/translations/hu.po3
-rw-r--r--editor/translations/id.po3
-rw-r--r--editor/translations/it.po3
-rw-r--r--editor/translations/ja.po3
-rw-r--r--editor/translations/ko.po3
-rw-r--r--editor/translations/nb.po3
-rw-r--r--editor/translations/nl.po3
-rw-r--r--editor/translations/pl.po3
-rw-r--r--editor/translations/pr.po3
-rw-r--r--editor/translations/pt_BR.po3
-rw-r--r--editor/translations/pt_PT.po3
-rw-r--r--editor/translations/ru.po3
-rw-r--r--editor/translations/sk.po3
-rw-r--r--editor/translations/sl.po3
-rw-r--r--editor/translations/th.po3
-rw-r--r--editor/translations/tr.po3
-rw-r--r--editor/translations/ur_PK.po3
-rw-r--r--editor/translations/zh_CN.po3
-rw-r--r--editor/translations/zh_HK.po3
-rw-r--r--editor/translations/zh_TW.po3
-rw-r--r--icon.pngbin12675 -> 11155 bytes
-rw-r--r--icon.svg161
-rw-r--r--logo.pngbin2486 -> 19339 bytes
-rw-r--r--logo.svg335
-rw-r--r--main/app_icon.pngbin18284 -> 5569 bytes
-rw-r--r--main/input_default.cpp180
-rw-r--r--main/input_default.h4
-rw-r--r--main/main.cpp23
-rw-r--r--main/splash.pngbin88469 -> 29867 bytes
-rw-r--r--main/tests/test_containers.cpp12
-rw-r--r--main/tests/test_gui.cpp7
-rw-r--r--main/tests/test_image.cpp7
-rw-r--r--main/tests/test_math.cpp53
-rw-r--r--main/tests/test_physics.cpp28
-rw-r--r--main/tests/test_physics_2d.cpp35
-rw-r--r--main/tests/test_render.cpp4
-rw-r--r--methods.py91
-rw-r--r--misc/dist/osx_template.app/Contents/Resources/icon.icnsbin120942 -> 67500 bytes
-rw-r--r--misc/dist/osx_tools.app/Contents/Resources/Godot.icnsbin120942 -> 67500 bytes
-rw-r--r--misc/dist/project_icon.svg138
-rw-r--r--misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.pngbin7001 -> 5645 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.pngbin14490 -> 16169 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.pngbin2067 -> 1619 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.pngbin3369 -> 2483 bytes
-rw-r--r--misc/dist/uwp_template/Assets/StoreLogo.scale-100.pngbin2339 -> 1792 bytes
-rw-r--r--misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.pngbin7390 -> 6772 bytes
-rw-r--r--misc/scripts/svgs_2_pngs.py12
-rw-r--r--modules/dds/texture_loader_dds.cpp4
-rw-r--r--modules/enet/networked_multiplayer_enet.cpp11
-rw-r--r--modules/enet/networked_multiplayer_enet.h3
-rw-r--r--modules/etc/SCsub37
-rw-r--r--modules/etc/config.py (renamed from modules/etc1/config.py)0
-rw-r--r--modules/etc/image_etc.cpp199
-rw-r--r--modules/etc/image_etc.h (renamed from modules/etc1/image_etc.h)2
-rw-r--r--modules/etc/register_types.cpp (renamed from modules/etc1/register_types.cpp)6
-rw-r--r--modules/etc/register_types.h (renamed from modules/etc1/register_types.h)4
-rw-r--r--modules/etc/texture_loader_pkm.cpp (renamed from modules/etc1/texture_loader_pkm.cpp)2
-rw-r--r--modules/etc/texture_loader_pkm.h (renamed from modules/etc1/texture_loader_pkm.h)0
-rw-r--r--modules/etc1/SCsub20
-rw-r--r--modules/etc1/image_etc.cpp182
-rw-r--r--modules/gdnative/gdnative.cpp21
-rw-r--r--modules/gdnative/gdnative.h6
-rw-r--r--modules/gdnative/godot.cpp39
-rw-r--r--modules/gdnative/godot.h47
-rw-r--r--modules/gdnative/godot/godot_array.cpp283
-rw-r--r--modules/gdnative/godot/godot_array.h75
-rw-r--r--modules/gdnative/godot/godot_basis.cpp287
-rw-r--r--modules/gdnative/godot/godot_basis.h100
-rw-r--r--modules/gdnative/godot/godot_color.cpp147
-rw-r--r--modules/gdnative/godot/godot_color.h44
-rw-r--r--modules/gdnative/godot/godot_dictionary.cpp140
-rw-r--r--modules/gdnative/godot/godot_dictionary.h35
-rw-r--r--modules/gdnative/godot/godot_image.cpp114
-rw-r--r--modules/gdnative/godot/godot_image.h124
-rw-r--r--modules/gdnative/godot/godot_input_event.cpp309
-rw-r--r--modules/gdnative/godot/godot_input_event.h235
-rw-r--r--modules/gdnative/godot/godot_node_path.cpp110
-rw-r--r--modules/gdnative/godot/godot_node_path.h29
-rw-r--r--modules/gdnative/godot/godot_plane.cpp141
-rw-r--r--modules/gdnative/godot/godot_plane.h47
-rw-r--r--modules/gdnative/godot/godot_pool_arrays.cpp602
-rw-r--r--modules/gdnative/godot/godot_pool_arrays.h196
-rw-r--r--modules/gdnative/godot/godot_quat.cpp231
-rw-r--r--modules/gdnative/godot/godot_quat.h56
-rw-r--r--modules/gdnative/godot/godot_rect2.cpp126
-rw-r--r--modules/gdnative/godot/godot_rect2.h40
-rw-r--r--modules/gdnative/godot/godot_rect3.cpp190
-rw-r--r--modules/gdnative/godot/godot_rect3.h58
-rw-r--r--modules/gdnative/godot/godot_rid.cpp40
-rw-r--r--modules/gdnative/godot/godot_rid.h11
-rw-r--r--modules/gdnative/godot/godot_string.cpp96
-rw-r--r--modules/gdnative/godot/godot_string.h24
-rw-r--r--modules/gdnative/godot/godot_transform.cpp192
-rw-r--r--modules/gdnative/godot/godot_transform.h50
-rw-r--r--modules/gdnative/godot/godot_transform2d.cpp186
-rw-r--r--modules/gdnative/godot/godot_transform2d.h56
-rw-r--r--modules/gdnative/godot/godot_variant.cpp644
-rw-r--r--modules/gdnative/godot/godot_variant.h201
-rw-r--r--modules/gdnative/godot/godot_vector2.cpp341
-rw-r--r--modules/gdnative/godot/godot_vector2.h118
-rw-r--r--modules/gdnative/godot/godot_vector3.cpp363
-rw-r--r--modules/gdnative/godot/godot_vector3.h140
-rw-r--r--modules/gdscript/gd_compiler.cpp2
-rw-r--r--modules/gdscript/gd_editor.cpp84
-rw-r--r--modules/gdscript/gd_function.cpp24
-rw-r--r--modules/gdscript/gd_function.h2
-rw-r--r--modules/gdscript/gd_parser.cpp28
-rw-r--r--modules/gdscript/gd_parser.h4
-rw-r--r--modules/gdscript/gd_script.cpp6
-rw-r--r--modules/gdscript/gd_script.h2
-rw-r--r--modules/gdscript/gd_tokenizer.cpp4
-rw-r--r--modules/gdscript/gd_tokenizer.h1
-rw-r--r--modules/gridmap/grid_map.cpp16
-rw-r--r--modules/gridmap/grid_map_editor_plugin.cpp206
-rw-r--r--modules/gridmap/grid_map_editor_plugin.h4
-rw-r--r--modules/hdr/SCsub9
-rw-r--r--modules/hdr/config.py (renamed from modules/multiscript/config.py)1
-rw-r--r--modules/hdr/image_loader_hdr.cpp161
-rw-r--r--modules/hdr/image_loader_hdr.h (renamed from scene/3d/test_cube.h)23
-rw-r--r--modules/hdr/register_types.cpp (renamed from platform/osx/godot_osx.h)21
-rw-r--r--modules/hdr/register_types.h (renamed from modules/multiscript/register_types.h)4
-rw-r--r--modules/jpg/image_loader_jpegd.cpp11
-rw-r--r--modules/jpg/image_loader_jpegd.h2
-rw-r--r--modules/multiscript/SCsub7
-rw-r--r--modules/multiscript/multiscript.cpp750
-rw-r--r--modules/multiscript/multiscript.h200
-rw-r--r--modules/multiscript/register_types.cpp51
-rw-r--r--modules/pvr/texture_loader_pvr.cpp43
-rw-r--r--modules/squish/image_compress_squish.cpp154
-rw-r--r--modules/squish/image_compress_squish.h3
-rw-r--r--modules/squish/register_types.cpp1
-rw-r--r--modules/stb_vorbis/audio_stream_ogg_vorbis.h2
-rw-r--r--modules/stb_vorbis/resource_importer_ogg_vorbis.cpp4
-rw-r--r--modules/tga/SCsub9
-rw-r--r--modules/tga/config.py7
-rw-r--r--modules/tga/image_loader_tga.cpp314
-rw-r--r--modules/tga/image_loader_tga.h (renamed from platform/osx/context_gl_osx.h)67
-rw-r--r--modules/tga/register_types.cpp (renamed from scene/resources/baked_light.h)21
-rw-r--r--modules/tga/register_types.h (renamed from platform/bb10/platform_config.h)5
-rw-r--r--modules/theora/video_stream_theora.cpp2
-rw-r--r--modules/tinyexr/SCsub20
-rw-r--r--modules/tinyexr/config.py7
-rw-r--r--modules/tinyexr/image_loader_tinyexr.cpp168
-rw-r--r--modules/tinyexr/image_loader_tinyexr.h (renamed from platform/bb10/power_bb10.h)29
-rw-r--r--modules/tinyexr/register_types.cpp (renamed from platform/bb10/godot_bb10.cpp)23
-rw-r--r--modules/tinyexr/register_types.h (renamed from platform/bb10/export/export.h)5
-rw-r--r--modules/visual_script/register_types.cpp2
-rw-r--r--modules/visual_script/visual_script.cpp11
-rw-r--r--modules/visual_script/visual_script.h4
-rw-r--r--modules/visual_script/visual_script_editor.cpp26
-rw-r--r--modules/visual_script/visual_script_editor.h3
-rw-r--r--modules/visual_script/visual_script_flow_control.cpp285
-rw-r--r--modules/visual_script/visual_script_flow_control.h5
-rw-r--r--modules/visual_script/visual_script_func_nodes.cpp105
-rw-r--r--modules/visual_script/visual_script_func_nodes.h8
-rw-r--r--modules/visual_script/visual_script_nodes.cpp38
-rw-r--r--modules/visual_script/visual_script_nodes.h4
-rw-r--r--modules/webm/libvpx/SCsub2
-rw-r--r--modules/webp/image_loader_webp.cpp35
-rw-r--r--modules/webp/image_loader_webp.h2
-rw-r--r--platform/android/build.gradle.template8
-rw-r--r--platform/android/detect.py2
-rw-r--r--platform/android/export/export.cpp6
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties5
-rw-r--r--platform/android/java/res/drawable/icon.pngbin12675 -> 11155 bytes
-rw-r--r--platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java16
-rw-r--r--platform/android/java/src/com/android/vending/licensing/ILicensingService.java16
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java4
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java47
-rw-r--r--platform/android/java_glue.cpp31
-rw-r--r--platform/android/os_android.cpp140
-rw-r--r--platform/android/os_android.h2
-rw-r--r--platform/android/power_android.cpp27
-rw-r--r--platform/bb10/SCsub23
-rw-r--r--platform/bb10/audio_driver_bb10.cpp254
-rw-r--r--platform/bb10/audio_driver_bb10.h77
-rw-r--r--platform/bb10/bar/bar-descriptor.xml53
-rw-r--r--platform/bb10/bar/icon.pngbin8809 -> 0 bytes
-rw-r--r--platform/bb10/bbutil.c513
-rw-r--r--platform/bb10/bbutil.h72
-rw-r--r--platform/bb10/detect.py92
-rw-r--r--platform/bb10/export/export.cpp829
-rw-r--r--platform/bb10/logo.pngbin1244 -> 0 bytes
-rw-r--r--platform/bb10/os_bb10.cpp608
-rw-r--r--platform/bb10/os_bb10.h153
-rw-r--r--platform/bb10/payment_service.cpp149
-rw-r--r--platform/bb10/payment_service.h64
-rw-r--r--platform/bb10/power_bb10.cpp72
-rw-r--r--platform/haiku/haiku_direct_window.cpp72
-rw-r--r--platform/iphone/SCsub1
-rw-r--r--platform/iphone/app_delegate.mm526
-rw-r--r--platform/iphone/audio_driver_iphone.cpp5
-rw-r--r--platform/iphone/detect.py46
-rw-r--r--platform/iphone/ios.h2
-rw-r--r--platform/iphone/ios.mm5
-rw-r--r--platform/iphone/os_iphone.cpp113
-rw-r--r--platform/iphone/os_iphone.h11
-rw-r--r--platform/iphone/rasterizer_iphone.cpp2585
-rw-r--r--platform/iphone/rasterizer_iphone.h881
-rw-r--r--platform/javascript/export/export.cpp2
-rw-r--r--platform/javascript/os_javascript.cpp230
-rw-r--r--platform/javascript/os_javascript.h3
-rw-r--r--platform/osx/SCsub1
-rw-r--r--platform/osx/context_gl_osx.cpp103
-rw-r--r--platform/osx/godot_osx.mm208
-rw-r--r--platform/osx/os_osx.h14
-rw-r--r--platform/osx/os_osx.mm445
-rw-r--r--platform/osx/power_osx.cpp26
-rw-r--r--platform/uwp/app.cpp111
-rw-r--r--platform/uwp/detect.py15
-rw-r--r--platform/uwp/gl_context_egl.cpp2
-rw-r--r--platform/uwp/os_uwp.cpp31
-rw-r--r--platform/uwp/os_uwp.h6
-rw-r--r--platform/uwp/power_uwp.cpp3
-rw-r--r--platform/uwp/power_uwp.h3
-rw-r--r--platform/windows/export/export.cpp2
-rw-r--r--platform/windows/godot.icobin370070 -> 370070 bytes
-rw-r--r--platform/windows/os_windows.cpp303
-rw-r--r--platform/windows/os_windows.h4
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp2
-rw-r--r--platform/windows/power_windows.cpp25
-rw-r--r--platform/x11/detect.py9
-rw-r--r--platform/x11/export/export.cpp2
-rw-r--r--platform/x11/os_x11.cpp144
-rw-r--r--platform/x11/os_x11.h4
-rw-r--r--platform/x11/power_x11.cpp25
-rw-r--r--scene/2d/animated_sprite.cpp8
-rw-r--r--scene/2d/animated_sprite.h16
-rw-r--r--scene/2d/area_2d.cpp90
-rw-r--r--scene/2d/area_2d.h20
-rw-r--r--scene/2d/audio_stream_player_2d.cpp463
-rw-r--r--scene/2d/audio_stream_player_2d.h96
-rw-r--r--scene/2d/camera_2d.cpp56
-rw-r--r--scene/2d/canvas_item.cpp42
-rw-r--r--scene/2d/canvas_item.h14
-rw-r--r--scene/2d/collision_object_2d.cpp6
-rw-r--r--scene/2d/collision_object_2d.h2
-rw-r--r--scene/2d/collision_polygon_2d.cpp2
-rw-r--r--scene/2d/light_2d.cpp16
-rw-r--r--scene/2d/light_2d.h4
-rw-r--r--scene/2d/line_2d.cpp6
-rw-r--r--scene/2d/line_2d.h6
-rw-r--r--scene/2d/line_builder.cpp10
-rw-r--r--scene/2d/line_builder.h2
-rw-r--r--scene/2d/node_2d.cpp6
-rw-r--r--scene/2d/particles_2d.cpp52
-rw-r--r--scene/2d/particles_2d.h6
-rw-r--r--scene/2d/physics_body_2d.cpp20
-rw-r--r--scene/2d/physics_body_2d.h4
-rw-r--r--scene/2d/polygon_2d.cpp12
-rw-r--r--scene/2d/ray_cast_2d.cpp26
-rw-r--r--scene/2d/ray_cast_2d.h6
-rw-r--r--scene/2d/screen_button.cpp144
-rw-r--r--scene/2d/screen_button.h5
-rw-r--r--scene/2d/sprite.cpp43
-rw-r--r--scene/2d/sprite.h8
-rw-r--r--scene/2d/tile_map.cpp36
-rw-r--r--scene/3d/area.cpp36
-rw-r--r--scene/3d/area.h10
-rw-r--r--scene/3d/baked_light_instance.cpp1754
-rw-r--r--scene/3d/baked_light_instance.h199
-rw-r--r--scene/3d/camera.cpp2
-rw-r--r--scene/3d/collision_object.cpp6
-rw-r--r--scene/3d/collision_object.h2
-rw-r--r--scene/3d/collision_polygon.cpp2
-rw-r--r--scene/3d/gi_probe.cpp62
-rw-r--r--scene/3d/gi_probe.h8
-rw-r--r--scene/3d/immediate_geometry.cpp2
-rw-r--r--scene/3d/light.cpp34
-rw-r--r--scene/3d/light.h2
-rw-r--r--scene/3d/listener.cpp2
-rw-r--r--scene/3d/navigation_mesh.cpp2
-rw-r--r--scene/3d/navigation_mesh.h2
-rw-r--r--scene/3d/particles.cpp2
-rw-r--r--scene/3d/path.cpp66
-rw-r--r--scene/3d/physics_body.cpp10
-rw-r--r--scene/3d/physics_body.h4
-rw-r--r--scene/3d/quad.cpp226
-rw-r--r--scene/3d/ray_cast.cpp22
-rw-r--r--scene/3d/ray_cast.h6
-rw-r--r--scene/3d/reflection_probe.cpp2
-rw-r--r--scene/3d/sprite_3d.cpp40
-rw-r--r--scene/3d/test_cube.cpp48
-rw-r--r--scene/3d/vehicle_body.cpp18
-rw-r--r--scene/3d/vehicle_body.h5
-rw-r--r--scene/animation/animation_player.cpp1
-rw-r--r--scene/animation/tween.cpp8
-rw-r--r--scene/audio/audio_player.cpp85
-rw-r--r--scene/audio/audio_player.h12
-rw-r--r--scene/gui/base_button.cpp249
-rw-r--r--scene/gui/base_button.h4
-rw-r--r--scene/gui/box_container.cpp1
-rw-r--r--scene/gui/button.cpp41
-rw-r--r--scene/gui/button_array.cpp542
-rw-r--r--scene/gui/button_array.h131
-rw-r--r--scene/gui/color_picker.cpp152
-rw-r--r--scene/gui/color_picker.h9
-rw-r--r--scene/gui/container.cpp6
-rw-r--r--scene/gui/control.cpp33
-rw-r--r--scene/gui/dialogs.cpp91
-rw-r--r--scene/gui/dialogs.h2
-rw-r--r--scene/gui/file_dialog.cpp17
-rw-r--r--scene/gui/file_dialog.h2
-rw-r--r--scene/gui/gradient_edit.cpp (renamed from scene/gui/color_ramp_edit.cpp)85
-rw-r--r--scene/gui/gradient_edit.h (renamed from scene/gui/color_ramp_edit.h)16
-rw-r--r--scene/gui/graph_edit.cpp93
-rw-r--r--scene/gui/graph_edit.h4
-rw-r--r--scene/gui/graph_node.cpp20
-rw-r--r--scene/gui/graph_node.h2
-rw-r--r--scene/gui/input_action.cpp77
-rw-r--r--scene/gui/input_action.h9
-rw-r--r--scene/gui/item_list.cpp146
-rw-r--r--scene/gui/item_list.h6
-rw-r--r--scene/gui/line_edit.cpp607
-rw-r--r--scene/gui/line_edit.h2
-rw-r--r--scene/gui/menu_button.cpp10
-rw-r--r--scene/gui/menu_button.h4
-rw-r--r--scene/gui/option_button.cpp19
-rw-r--r--scene/gui/popup.cpp12
-rw-r--r--scene/gui/popup.h2
-rw-r--r--scene/gui/popup_menu.cpp268
-rw-r--r--scene/gui/popup_menu.h4
-rw-r--r--scene/gui/rich_text_label.cpp231
-rw-r--r--scene/gui/rich_text_label.h2
-rw-r--r--scene/gui/scroll_bar.cpp406
-rw-r--r--scene/gui/scroll_bar.h16
-rw-r--r--scene/gui/scroll_container.cpp154
-rw-r--r--scene/gui/scroll_container.h2
-rw-r--r--scene/gui/slider.cpp49
-rw-r--r--scene/gui/slider.h2
-rw-r--r--scene/gui/spin_box.cpp40
-rw-r--r--scene/gui/spin_box.h4
-rw-r--r--scene/gui/split_container.cpp24
-rw-r--r--scene/gui/split_container.h4
-rw-r--r--scene/gui/tab_container.cpp21
-rw-r--r--scene/gui/tab_container.h2
-rw-r--r--scene/gui/tabs.cpp220
-rw-r--r--scene/gui/tabs.h11
-rw-r--r--scene/gui/text_edit.cpp1847
-rw-r--r--scene/gui/text_edit.h2
-rw-r--r--scene/gui/tool_button.cpp4
-rw-r--r--scene/gui/tool_button.h3
-rw-r--r--scene/gui/tree.cpp940
-rw-r--r--scene/gui/tree.h17
-rw-r--r--scene/gui/video_player.h2
-rwxr-xr-xscene/main/node.cpp8
-rw-r--r--scene/main/scene_main_loop.cpp98
-rw-r--r--scene/main/scene_main_loop.h9
-rw-r--r--scene/main/viewport.cpp848
-rw-r--r--scene/main/viewport.h61
-rw-r--r--scene/register_scene_types.cpp41
-rw-r--r--scene/resources/animation.cpp4
-rw-r--r--scene/resources/animation.h2
-rw-r--r--scene/resources/audio_stream_sample.h2
-rw-r--r--scene/resources/baked_light.cpp31
-rw-r--r--scene/resources/bit_mask.cpp18
-rw-r--r--scene/resources/bit_mask.h3
-rw-r--r--scene/resources/box_shape.cpp4
-rw-r--r--scene/resources/capsule_shape_2d.cpp2
-rw-r--r--scene/resources/circle_shape_2d.cpp2
-rw-r--r--scene/resources/color_ramp.cpp56
-rw-r--r--scene/resources/color_ramp.h10
-rw-r--r--scene/resources/concave_polygon_shape_2d.cpp2
-rw-r--r--scene/resources/convex_polygon_shape_2d.cpp2
-rw-r--r--scene/resources/default_theme/arrow_down.pngbin170 -> 184 bytes
-rw-r--r--scene/resources/default_theme/arrow_right.pngbin189 -> 183 bytes
-rw-r--r--scene/resources/default_theme/button_disabled.pngbin333 -> 486 bytes
-rw-r--r--scene/resources/default_theme/button_hover.pngbin309 -> 606 bytes
-rw-r--r--scene/resources/default_theme/button_normal.pngbin333 -> 598 bytes
-rw-r--r--scene/resources/default_theme/button_pressed.pngbin307 -> 499 bytes
-rw-r--r--scene/resources/default_theme/checked.pngbin341 -> 627 bytes
-rw-r--r--scene/resources/default_theme/close.pngbin265 -> 230 bytes
-rw-r--r--scene/resources/default_theme/close_hl.pngbin265 -> 230 bytes
-rw-r--r--scene/resources/default_theme/default_theme.cpp300
-rw-r--r--scene/resources/default_theme/dropdown.pngbin179 -> 369 bytes
-rw-r--r--scene/resources/default_theme/focus.pngbin90 -> 411 bytes
-rw-r--r--scene/resources/default_theme/frame_focus.pngbin90 -> 448 bytes
-rw-r--r--scene/resources/default_theme/full_panel_bg.pngbin332 -> 430 bytes
-rw-r--r--scene/resources/default_theme/graph_node.pngbin277 -> 762 bytes
-rw-r--r--scene/resources/default_theme/graph_node_comment.pngbin214 -> 506 bytes
-rw-r--r--scene/resources/default_theme/graph_node_comment_focus.pngbin226 -> 482 bytes
-rw-r--r--scene/resources/default_theme/graph_node_position.pngbin252 -> 278 bytes
-rw-r--r--scene/resources/default_theme/graph_node_selected.pngbin271 -> 933 bytes
-rw-r--r--scene/resources/default_theme/hseparator.pngbin90 -> 323 bytes
-rw-r--r--scene/resources/default_theme/hslider_bg.pngbin177 -> 526 bytes
-rw-r--r--scene/resources/default_theme/hslider_grabber.pngbin328 -> 591 bytes
-rw-r--r--scene/resources/default_theme/hslider_grabber_hl.pngbin316 -> 734 bytes
-rw-r--r--scene/resources/default_theme/hsplit_bg.pngbin96 -> 334 bytes
-rw-r--r--scene/resources/default_theme/hsplitter.pngbin132 -> 359 bytes
-rw-r--r--scene/resources/default_theme/icon_close.pngbin265 -> 230 bytes
-rw-r--r--scene/resources/default_theme/line_edit.pngbin408 -> 424 bytes
-rw-r--r--scene/resources/default_theme/line_edit_active.pngbin411 -> 0 bytes
-rw-r--r--scene/resources/default_theme/line_edit_disabled.pngbin389 -> 406 bytes
-rw-r--r--scene/resources/default_theme/line_edit_focus.pngbin0 -> 660 bytes
-rw-r--r--scene/resources/default_theme/line_edit_selected.pngbin411 -> 0 bytes
-rw-r--r--scene/resources/default_theme/option_arrow.pngbin205 -> 227 bytes
-rw-r--r--scene/resources/default_theme/option_button_disabled.pngbin346 -> 901 bytes
-rw-r--r--scene/resources/default_theme/option_button_focus.pngbin0 -> 679 bytes
-rw-r--r--scene/resources/default_theme/option_button_hover.pngbin320 -> 924 bytes
-rw-r--r--scene/resources/default_theme/option_button_normal.pngbin100 -> 922 bytes
-rw-r--r--scene/resources/default_theme/option_button_pressed.pngbin318 -> 931 bytes
-rw-r--r--scene/resources/default_theme/panel_bg.pngbin95 -> 334 bytes
-rw-r--r--scene/resources/default_theme/popup_bg.pngbin425 -> 672 bytes
-rw-r--r--scene/resources/default_theme/popup_hover.pngbin0 -> 404 bytes
-rw-r--r--scene/resources/default_theme/popup_unchecked.pngbin0 -> 310 bytes
-rw-r--r--scene/resources/default_theme/popup_window.pngbin514 -> 1234 bytes
-rw-r--r--scene/resources/default_theme/progress_bar.pngbin93 -> 460 bytes
-rw-r--r--scene/resources/default_theme/progress_fill.pngbin309 -> 402 bytes
-rw-r--r--scene/resources/default_theme/radio_checked.pngbin441 -> 477 bytes
-rw-r--r--scene/resources/default_theme/radio_unchecked.pngbin406 -> 422 bytes
-rw-r--r--scene/resources/default_theme/scroll_bg.pngbin90 -> 510 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_down.pngbin187 -> 418 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_down_hl.pngbin222 -> 418 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_left.pngbin207 -> 444 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_left_hl.pngbin244 -> 461 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_right.pngbin205 -> 446 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_right_hl.pngbin243 -> 464 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_up.pngbin190 -> 421 bytes
-rw-r--r--scene/resources/default_theme/scroll_button_up_hl.pngbin232 -> 421 bytes
-rw-r--r--scene/resources/default_theme/scroll_grabber.pngbin147 -> 523 bytes
-rw-r--r--scene/resources/default_theme/scroll_grabber_hl.pngbin188 -> 536 bytes
-rw-r--r--scene/resources/default_theme/selection.pngbin261 -> 406 bytes
-rw-r--r--scene/resources/default_theme/selection_oof.pngbin257 -> 411 bytes
-rw-r--r--scene/resources/default_theme/source/arrow_down.svg20
-rw-r--r--scene/resources/default_theme/source/arrow_right.svg18
-rw-r--r--scene/resources/default_theme/source/button_disabled.svg80
-rw-r--r--scene/resources/default_theme/source/button_hover.svg80
-rw-r--r--scene/resources/default_theme/source/button_normal.svg80
-rw-r--r--scene/resources/default_theme/source/button_pressed.svg80
-rw-r--r--scene/resources/default_theme/source/focus.svg71
-rw-r--r--scene/resources/default_theme/source/frame_focus.svg71
-rw-r--r--scene/resources/default_theme/source/full_panel_bg.svg80
-rw-r--r--scene/resources/default_theme/source/graph_node.svg83
-rw-r--r--scene/resources/default_theme/source/graph_node_comment.svg83
-rw-r--r--scene/resources/default_theme/source/graph_node_comment_focus.svg83
-rw-r--r--scene/resources/default_theme/source/graph_node_position.svg77
-rw-r--r--scene/resources/default_theme/source/graph_node_selected.svg83
-rw-r--r--scene/resources/default_theme/source/icon_close.svg43
-rw-r--r--scene/resources/default_theme/source/line_edit.svg89
-rw-r--r--scene/resources/default_theme/source/line_edit_active.svg89
-rw-r--r--scene/resources/default_theme/source/line_edit_disabled.svg86
-rw-r--r--scene/resources/default_theme/source/option_arrow.svg28
-rw-r--r--scene/resources/default_theme/source/panel_bg.svg79
-rw-r--r--scene/resources/default_theme/source/popup_bg.svg87
-rw-r--r--scene/resources/default_theme/source/popup_window.svg96
-rw-r--r--scene/resources/default_theme/source/progress_bar.svg72
-rw-r--r--scene/resources/default_theme/source/progress_fill.svg82
-rw-r--r--scene/resources/default_theme/source/radio_checked.svg85
-rw-r--r--scene/resources/default_theme/source/radio_unchecked.svg79
-rw-r--r--scene/resources/default_theme/source/scroll_button_down_hl.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_left.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_left_hl.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_right.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_right_hl.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_up.svg77
-rw-r--r--scene/resources/default_theme/source/scroll_button_up_hl.svg77
-rw-r--r--scene/resources/default_theme/source/selection.svg88
-rw-r--r--scene/resources/default_theme/source/selection_oof.svg88
-rw-r--r--scene/resources/default_theme/source/spinbox_updown.svg33
-rw-r--r--scene/resources/default_theme/source/submenu.svg19
-rw-r--r--scene/resources/default_theme/source/tab_behind.svg71
-rw-r--r--scene/resources/default_theme/source/tab_close.svg46
-rw-r--r--scene/resources/default_theme/source/tab_container_bg.svg80
-rw-r--r--scene/resources/default_theme/source/tab_current.svg79
-rw-r--r--scene/resources/default_theme/source/tab_menu.svg36
-rw-r--r--scene/resources/default_theme/source/toggle_off.svg86
-rw-r--r--scene/resources/default_theme/source/toggle_on.svg85
-rw-r--r--scene/resources/default_theme/source/tooltip_bg.svg85
-rw-r--r--scene/resources/default_theme/source/tree_bg.svg80
-rw-r--r--scene/resources/default_theme/source/tree_title.svg80
-rw-r--r--scene/resources/default_theme/source/tree_title_pressed.svg80
-rw-r--r--scene/resources/default_theme/source/updown.svg14
-rw-r--r--scene/resources/default_theme/source/vslider_grabber.svg80
-rw-r--r--scene/resources/default_theme/source/vslider_grabber_hl.svg80
-rw-r--r--scene/resources/default_theme/source/window_resizer.svg81
-rw-r--r--scene/resources/default_theme/spinbox_updown.pngbin345 -> 280 bytes
-rw-r--r--scene/resources/default_theme/submenu.pngbin217 -> 175 bytes
-rw-r--r--scene/resources/default_theme/tab.pngbin158 -> 300 bytes
-rw-r--r--scene/resources/default_theme/tab_behind.pngbin93 -> 553 bytes
-rw-r--r--scene/resources/default_theme/tab_close.pngbin265 -> 325 bytes
-rw-r--r--scene/resources/default_theme/tab_container_backup.pngbin211 -> 0 bytes
-rw-r--r--scene/resources/default_theme/tab_container_bg.pngbin331 -> 598 bytes
-rw-r--r--scene/resources/default_theme/tab_current.pngbin256 -> 627 bytes
-rw-r--r--scene/resources/default_theme/tab_menu.pngbin146 -> 186 bytes
-rw-r--r--scene/resources/default_theme/tab_menu_hl.pngbin146 -> 186 bytes
-rw-r--r--scene/resources/default_theme/theme_data.h188
-rw-r--r--scene/resources/default_theme/toggle_off.pngbin702 -> 1355 bytes
-rw-r--r--scene/resources/default_theme/toggle_on.pngbin738 -> 1318 bytes
-rw-r--r--scene/resources/default_theme/tool_button_pressed.pngbin0 -> 1230 bytes
-rw-r--r--scene/resources/default_theme/tooltip_bg.pngbin194 -> 424 bytes
-rw-r--r--scene/resources/default_theme/tree_bg.pngbin304 -> 424 bytes
-rw-r--r--scene/resources/default_theme/tree_bg_focus.pngbin0 -> 1039 bytes
-rw-r--r--scene/resources/default_theme/tree_title.pngbin104 -> 335 bytes
-rw-r--r--scene/resources/default_theme/tree_title_pressed.pngbin104 -> 335 bytes
-rw-r--r--scene/resources/default_theme/unchecked.pngbin231 -> 477 bytes
-rw-r--r--scene/resources/default_theme/updown.pngbin214 -> 241 bytes
-rw-r--r--scene/resources/default_theme/vseparator.pngbin90 -> 323 bytes
-rw-r--r--scene/resources/default_theme/vslider_bg.pngbin180 -> 532 bytes
-rw-r--r--scene/resources/default_theme/vslider_grabber.pngbin328 -> 394 bytes
-rw-r--r--scene/resources/default_theme/vslider_grabber_hl.pngbin316 -> 439 bytes
-rw-r--r--scene/resources/default_theme/vsplit_bg.pngbin96 -> 334 bytes
-rw-r--r--scene/resources/default_theme/vsplitter.pngbin122 -> 351 bytes
-rw-r--r--scene/resources/default_theme/window_resizer.pngbin138 -> 181 bytes
-rw-r--r--scene/resources/dynamic_font.cpp2
-rw-r--r--scene/resources/environment.cpp441
-rw-r--r--scene/resources/environment.h92
-rw-r--r--scene/resources/font.cpp8
-rw-r--r--scene/resources/font.h2
-rw-r--r--scene/resources/material.cpp318
-rw-r--r--scene/resources/material.h70
-rw-r--r--scene/resources/mesh.cpp1003
-rw-r--r--scene/resources/mesh.h62
-rw-r--r--scene/resources/mesh_data_tool.cpp6
-rw-r--r--scene/resources/mesh_data_tool.h4
-rw-r--r--scene/resources/mesh_library.h2
-rw-r--r--scene/resources/multimesh.h2
-rw-r--r--scene/resources/polygon_path_finder.cpp2
-rw-r--r--scene/resources/primitive_meshes.cpp1454
-rw-r--r--scene/resources/primitive_meshes.h312
-rw-r--r--scene/resources/segment_shape_2d.cpp6
-rw-r--r--scene/resources/shader_graph.h2
-rw-r--r--scene/resources/shape.cpp4
-rw-r--r--scene/resources/shape.h8
-rw-r--r--scene/resources/shape_line_2d.cpp2
-rw-r--r--scene/resources/sky_box.cpp489
-rw-r--r--scene/resources/sky_box.h137
-rw-r--r--scene/resources/style_box.cpp60
-rw-r--r--scene/resources/style_box.h10
-rw-r--r--scene/resources/surface_tool.cpp6
-rw-r--r--scene/resources/surface_tool.h2
-rw-r--r--scene/resources/texture.cpp292
-rw-r--r--scene/resources/texture.h64
-rw-r--r--scene/resources/theme.h2
-rw-r--r--scene/resources/world.cpp17
-rw-r--r--scene/resources/world.h7
-rw-r--r--scene/resources/world_2d.cpp15
-rw-r--r--scene/resources/world_2d.h4
-rw-r--r--servers/physics/collision_object_sw.cpp4
-rw-r--r--servers/physics/collision_object_sw.h8
-rw-r--r--servers/physics/collision_solver_sw.cpp6
-rw-r--r--servers/physics/gjk_epa.cpp25
-rw-r--r--servers/physics/joints/cone_twist_joint_sw.cpp18
-rw-r--r--servers/physics/joints/generic_6dof_joint_sw.cpp23
-rw-r--r--servers/physics/joints/hinge_joint_sw.cpp16
-rw-r--r--servers/physics/joints/pin_joint_sw.cpp16
-rw-r--r--servers/physics/joints/slider_joint_sw.cpp22
-rw-r--r--servers/physics/physics_server_sw.cpp16
-rw-r--r--servers/physics/physics_server_sw.h10
-rw-r--r--servers/physics/shape_sw.cpp6
-rw-r--r--servers/physics/space_sw.cpp26
-rw-r--r--servers/physics/space_sw.h10
-rw-r--r--servers/physics_2d/broad_phase_2d_hash_grid.cpp12
-rw-r--r--servers/physics_2d/collision_object_2d_sw.cpp4
-rw-r--r--servers/physics_2d/collision_object_2d_sw.h8
-rw-r--r--servers/physics_2d/collision_solver_2d_sw.cpp2
-rw-r--r--servers/physics_2d/physics_2d_server_sw.cpp12
-rw-r--r--servers/physics_2d/physics_2d_server_sw.h6
-rw-r--r--servers/physics_2d/physics_2d_server_wrap_mt.h6
-rw-r--r--servers/physics_2d/shape_2d_sw.cpp16
-rw-r--r--servers/physics_2d/shape_2d_sw.h4
-rw-r--r--servers/physics_2d/space_2d_sw.cpp42
-rw-r--r--servers/physics_2d/space_2d_sw.h12
-rw-r--r--servers/physics_2d_server.cpp32
-rw-r--r--servers/physics_2d_server.h24
-rw-r--r--servers/physics_server.cpp30
-rw-r--r--servers/physics_server.h26
-rw-r--r--servers/server_wrap_mt_common.h30
-rw-r--r--servers/visual/rasterizer.cpp4
-rw-r--r--servers/visual/rasterizer.h71
-rw-r--r--servers/visual/shader_language.cpp39
-rw-r--r--servers/visual/shader_types.cpp18
-rw-r--r--servers/visual/visual_server_canvas.cpp36
-rw-r--r--servers/visual/visual_server_canvas.h13
-rw-r--r--servers/visual/visual_server_raster.cpp38
-rw-r--r--servers/visual/visual_server_raster.h59
-rw-r--r--servers/visual/visual_server_scene.cpp53
-rw-r--r--servers/visual/visual_server_scene.h2
-rw-r--r--servers/visual/visual_server_viewport.cpp81
-rw-r--r--servers/visual/visual_server_viewport.h16
-rw-r--r--servers/visual/visual_server_wrap_mt.cpp193
-rw-r--r--servers/visual/visual_server_wrap_mt.h585
-rw-r--r--servers/visual_server.cpp30
-rw-r--r--servers/visual_server.h81
-rw-r--r--signal_renames.txt21
-rw-r--r--thirdparty/README.md79
-rw-r--r--thirdparty/etc2comp/AUTHORS7
-rw-r--r--thirdparty/etc2comp/Etc.cpp128
-rw-r--r--thirdparty/etc2comp/Etc.h71
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4.cpp425
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4.h172
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding.cpp261
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding.h148
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4EncodingBits.h315
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.cpp1281
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.h186
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_R11.cpp429
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_R11.h122
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.cpp447
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.h86
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp1730
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.h96
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.cpp1819
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.h129
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.cpp474
-rw-r--r--thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.h121
-rw-r--r--thirdparty/etc2comp/EtcColor.h64
-rw-r--r--thirdparty/etc2comp/EtcColorFloatRGBA.h321
-rw-r--r--thirdparty/etc2comp/EtcConfig.h67
-rw-r--r--thirdparty/etc2comp/EtcDifferentialTrys.cpp173
-rw-r--r--thirdparty/etc2comp/EtcDifferentialTrys.h97
-rw-r--r--thirdparty/etc2comp/EtcErrorMetric.h54
-rw-r--r--thirdparty/etc2comp/EtcFile.cpp390
-rw-r--r--thirdparty/etc2comp/EtcFile.h136
-rw-r--r--thirdparty/etc2comp/EtcFileHeader.cpp185
-rw-r--r--thirdparty/etc2comp/EtcFileHeader.h146
-rw-r--r--thirdparty/etc2comp/EtcFilter.cpp401
-rw-r--r--thirdparty/etc2comp/EtcFilter.h244
-rw-r--r--thirdparty/etc2comp/EtcImage.cpp685
-rw-r--r--thirdparty/etc2comp/EtcImage.h249
-rw-r--r--thirdparty/etc2comp/EtcIndividualTrys.cpp85
-rw-r--r--thirdparty/etc2comp/EtcIndividualTrys.h95
-rw-r--r--thirdparty/etc2comp/EtcMath.cpp64
-rw-r--r--thirdparty/etc2comp/EtcMath.h40
-rw-r--r--thirdparty/etc2comp/EtcSortedBlockList.cpp228
-rw-r--r--thirdparty/etc2comp/EtcSortedBlockList.h124
-rw-r--r--thirdparty/etc2comp/LICENSE202
-rw-r--r--thirdparty/etc2comp/README.md197
-rw-r--r--thirdparty/glad/glad.c14
-rw-r--r--thirdparty/glad/glad/glad.h175
-rw-r--r--thirdparty/misc/yuv2rgb.h25
-rw-r--r--thirdparty/openssl/crypto/LPdir_nyi.c3
-rw-r--r--thirdparty/openssl/crypto/LPdir_unix.c4
-rw-r--r--thirdparty/openssl/crypto/LPdir_win32.c4
-rw-r--r--thirdparty/openssl/crypto/LPdir_wince.c4
-rw-r--r--thirdparty/openssl/crypto/asn1/a_bitstr.c7
-rw-r--r--thirdparty/openssl/crypto/asn1/a_bytes.c58
-rw-r--r--thirdparty/openssl/crypto/asn1/a_digest.c8
-rw-r--r--thirdparty/openssl/crypto/asn1/a_gentm.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/a_object.c10
-rw-r--r--thirdparty/openssl/crypto/asn1/a_set.c9
-rw-r--r--thirdparty/openssl/crypto/asn1/a_strex.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/a_strnid.c4
-rw-r--r--thirdparty/openssl/crypto/asn1/a_time.c26
-rw-r--r--thirdparty/openssl/crypto/asn1/a_utctm.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/ameth_lib.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/asn1_lib.c32
-rw-r--r--thirdparty/openssl/crypto/asn1/asn_mime.c4
-rw-r--r--thirdparty/openssl/crypto/asn1/bio_asn1.c6
-rw-r--r--thirdparty/openssl/crypto/asn1/bio_ndef.c1
-rw-r--r--thirdparty/openssl/crypto/asn1/d2i_pr.c8
-rw-r--r--thirdparty/openssl/crypto/asn1/f_enum.c6
-rw-r--r--thirdparty/openssl/crypto/asn1/f_int.c6
-rw-r--r--thirdparty/openssl/crypto/asn1/f_string.c4
-rw-r--r--thirdparty/openssl/crypto/asn1/i2d_pr.c9
-rw-r--r--thirdparty/openssl/crypto/asn1/p5_pbe.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/p5_pbev2.c12
-rw-r--r--thirdparty/openssl/crypto/asn1/t_req.c1
-rw-r--r--thirdparty/openssl/crypto/asn1/tasn_dec.c9
-rw-r--r--thirdparty/openssl/crypto/asn1/tasn_enc.c26
-rw-r--r--thirdparty/openssl/crypto/asn1/tasn_new.c11
-rw-r--r--thirdparty/openssl/crypto/asn1/tasn_prn.c16
-rw-r--r--thirdparty/openssl/crypto/asn1/tasn_utl.c2
-rw-r--r--thirdparty/openssl/crypto/asn1/x_bignum.c15
-rw-r--r--thirdparty/openssl/crypto/asn1/x_crl.c3
-rw-r--r--thirdparty/openssl/crypto/asn1/x_long.c38
-rw-r--r--thirdparty/openssl/crypto/asn1/x_name.c41
-rw-r--r--thirdparty/openssl/crypto/asn1/x_x509.c54
-rw-r--r--thirdparty/openssl/crypto/bio/b_print.c14
-rw-r--r--thirdparty/openssl/crypto/bio/bf_nbio.c4
-rw-r--r--thirdparty/openssl/crypto/bio/bio_cb.c3
-rw-r--r--thirdparty/openssl/crypto/bio/bss_bio.c19
-rw-r--r--thirdparty/openssl/crypto/bio/bss_file.c26
-rw-r--r--thirdparty/openssl/crypto/bio/bss_rtcp.c2
-rw-r--r--thirdparty/openssl/crypto/bn/asm/x86_64-gcc.c2
-rw-r--r--thirdparty/openssl/crypto/bn/bn_div.c4
-rw-r--r--thirdparty/openssl/crypto/bn/bn_exp.c5
-rw-r--r--thirdparty/openssl/crypto/bn/bn_lib.c2
-rw-r--r--thirdparty/openssl/crypto/bn/bn_mul.c5
-rw-r--r--thirdparty/openssl/crypto/bn/bn_prime.c23
-rw-r--r--thirdparty/openssl/crypto/bn/bn_prime.h514
-rw-r--r--thirdparty/openssl/crypto/bn/bn_print.c37
-rw-r--r--thirdparty/openssl/crypto/bn/bn_rand.c23
-rw-r--r--thirdparty/openssl/crypto/bn/bn_sqr.c5
-rw-r--r--thirdparty/openssl/crypto/bn/bn_word.c22
-rw-r--r--thirdparty/openssl/crypto/cms/cms_enc.c12
-rw-r--r--thirdparty/openssl/crypto/cms/cms_ess.c3
-rw-r--r--thirdparty/openssl/crypto/cms/cms_kari.c5
-rw-r--r--thirdparty/openssl/crypto/cms/cms_lib.c4
-rw-r--r--thirdparty/openssl/crypto/cms/cms_pwri.c4
-rw-r--r--thirdparty/openssl/crypto/comp/c_rle.c25
-rw-r--r--thirdparty/openssl/crypto/conf/conf_def.c16
-rw-r--r--thirdparty/openssl/crypto/conf/conf_def.h44
-rw-r--r--thirdparty/openssl/crypto/conf/conf_err.c2
-rw-r--r--thirdparty/openssl/crypto/conf/conf_mod.c4
-rw-r--r--thirdparty/openssl/crypto/conf/ssleay.cnf78
-rw-r--r--thirdparty/openssl/crypto/crypto-lib.com1537
-rw-r--r--thirdparty/openssl/crypto/des/asm/des_enc.m42101
-rw-r--r--thirdparty/openssl/crypto/des/des-lib.com1005
-rw-r--r--thirdparty/openssl/crypto/des/des.c2
-rw-r--r--thirdparty/openssl/crypto/des/enc_writ.c2
-rw-r--r--thirdparty/openssl/crypto/des/makefile.bc50
-rw-r--r--thirdparty/openssl/crypto/des/set_key.c2
-rw-r--r--thirdparty/openssl/crypto/des/t/test27
-rw-r--r--thirdparty/openssl/crypto/des/times/486-50.sol16
-rw-r--r--thirdparty/openssl/crypto/des/times/586-100.lnx20
-rw-r--r--thirdparty/openssl/crypto/des/times/686-200.fre18
-rw-r--r--thirdparty/openssl/crypto/des/times/sparc.gcc17
-rw-r--r--thirdparty/openssl/crypto/dh/dh_ameth.c2
-rw-r--r--thirdparty/openssl/crypto/dh/dh_key.c2
-rw-r--r--thirdparty/openssl/crypto/dsa/dsa_ameth.c2
-rw-r--r--thirdparty/openssl/crypto/dsa/dsa_gen.c7
-rw-r--r--thirdparty/openssl/crypto/dsa/dsa_ossl.c7
-rw-r--r--thirdparty/openssl/crypto/dsa/dsa_pmeth.c2
-rw-r--r--thirdparty/openssl/crypto/ec/ec2_mult.c20
-rw-r--r--thirdparty/openssl/crypto/ec/ec_ameth.c36
-rw-r--r--thirdparty/openssl/crypto/ec/ec_asn1.c11
-rw-r--r--thirdparty/openssl/crypto/ec/ec_key.c13
-rw-r--r--thirdparty/openssl/crypto/ec/ec_mult.c12
-rw-r--r--thirdparty/openssl/crypto/ec/eck_prn.c2
-rw-r--r--thirdparty/openssl/crypto/ec/ecp_nistz256.c125
-rw-r--r--thirdparty/openssl/crypto/ecdh/ech_ossl.c4
-rw-r--r--thirdparty/openssl/crypto/engine/eng_cryptodev.c34
-rw-r--r--thirdparty/openssl/crypto/err/err.c4
-rw-r--r--thirdparty/openssl/crypto/err/openssl.ec98
-rw-r--r--thirdparty/openssl/crypto/evp/bio_enc.c21
-rw-r--r--thirdparty/openssl/crypto/evp/bio_ok.c2
-rw-r--r--thirdparty/openssl/crypto/evp/c_all.c5
-rw-r--r--thirdparty/openssl/crypto/evp/digest.c16
-rw-r--r--thirdparty/openssl/crypto/evp/e_aes.c13
-rw-r--r--thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c2
-rw-r--r--thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c6
-rw-r--r--thirdparty/openssl/crypto/evp/e_des3.c2
-rw-r--r--thirdparty/openssl/crypto/evp/e_rc4_hmac_md5.c6
-rw-r--r--thirdparty/openssl/crypto/evp/e_seed.c3
-rw-r--r--thirdparty/openssl/crypto/evp/evp_enc.c11
-rw-r--r--thirdparty/openssl/crypto/evp/evp_err.c3
-rw-r--r--thirdparty/openssl/crypto/evp/evptests.txt401
-rw-r--r--thirdparty/openssl/crypto/evp/openbsd_hw.c22
-rw-r--r--thirdparty/openssl/crypto/evp/p_lib.c8
-rw-r--r--thirdparty/openssl/crypto/evp/pmeth_fn.c30
-rw-r--r--thirdparty/openssl/crypto/evp/pmeth_gn.c4
-rw-r--r--thirdparty/openssl/crypto/evp/pmeth_lib.c32
-rw-r--r--thirdparty/openssl/crypto/ex_data.c41
-rw-r--r--thirdparty/openssl/crypto/hmac/hm_pmeth.c11
-rw-r--r--thirdparty/openssl/crypto/hmac/hmac.c2
-rw-r--r--thirdparty/openssl/crypto/include/internal/bn_conf.h28
-rw-r--r--thirdparty/openssl/crypto/include/internal/dso_conf.h16
-rwxr-xr-xthirdparty/openssl/crypto/install-crypto.com196
-rw-r--r--thirdparty/openssl/crypto/jpake/jpake.c4
-rw-r--r--thirdparty/openssl/crypto/lhash/lhash.c2
-rw-r--r--thirdparty/openssl/crypto/md2/md2_dgst.c2
-rw-r--r--thirdparty/openssl/crypto/md32_common.h10
-rw-r--r--thirdparty/openssl/crypto/mdc2/mdc2dgst.c2
-rw-r--r--thirdparty/openssl/crypto/mem.c48
-rw-r--r--thirdparty/openssl/crypto/mem_clr.c24
-rw-r--r--thirdparty/openssl/crypto/modes/ctr128.c2
-rw-r--r--thirdparty/openssl/crypto/o_dir.c3
-rw-r--r--thirdparty/openssl/crypto/o_init.c3
-rw-r--r--thirdparty/openssl/crypto/o_str.c9
-rwxr-xr-x[-rw-r--r--]thirdparty/openssl/crypto/o_time.c80
-rw-r--r--thirdparty/openssl/crypto/objects/o_names.c7
-rw-r--r--thirdparty/openssl/crypto/ocsp/ocsp_cl.c4
-rw-r--r--thirdparty/openssl/crypto/ocsp/ocsp_ext.c2
-rw-r--r--thirdparty/openssl/crypto/ocsp/ocsp_lib.c12
-rw-r--r--thirdparty/openssl/crypto/opensslconf.h.in154
-rw-r--r--thirdparty/openssl/crypto/pem/pem_err.c3
-rw-r--r--thirdparty/openssl/crypto/pem/pem_lib.c14
-rw-r--r--thirdparty/openssl/crypto/pem/pvkfmt.c7
-rw-r--r--thirdparty/openssl/crypto/pkcs12/p12_mutl.c7
-rw-r--r--thirdparty/openssl/crypto/pkcs12/p12_npas.c113
-rw-r--r--thirdparty/openssl/crypto/pkcs12/p12_utl.c4
-rw-r--r--thirdparty/openssl/crypto/pkcs7/pk7_doit.c4
-rw-r--r--thirdparty/openssl/crypto/ppccap.c24
-rw-r--r--thirdparty/openssl/crypto/rand/md_rand.c78
-rw-r--r--thirdparty/openssl/crypto/rand/rand_unix.c2
-rwxr-xr-x[-rw-r--r--]thirdparty/openssl/crypto/rand/rand_vms.c123
-rw-r--r--thirdparty/openssl/crypto/rand/rand_win.c12
-rw-r--r--thirdparty/openssl/crypto/rand/randfile.c53
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_ameth.c8
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_chk.c89
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_gen.c3
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_lib.c1
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_oaep.c8
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_pmeth.c17
-rw-r--r--thirdparty/openssl/crypto/rsa/rsa_pss.c13
-rw-r--r--thirdparty/openssl/crypto/s390xcap.c1
-rw-r--r--thirdparty/openssl/crypto/srp/srp_lib.c24
-rw-r--r--thirdparty/openssl/crypto/srp/srp_vfy.c50
-rw-r--r--thirdparty/openssl/crypto/threads/netware.bat79
-rw-r--r--thirdparty/openssl/crypto/threads/profile.sh4
-rwxr-xr-xthirdparty/openssl/crypto/threads/ptest.bat4
-rw-r--r--thirdparty/openssl/crypto/threads/pthread.sh9
-rwxr-xr-xthirdparty/openssl/crypto/threads/pthread2.sh6
-rw-r--r--thirdparty/openssl/crypto/threads/pthreads-vms.com14
-rw-r--r--thirdparty/openssl/crypto/threads/purify.sh4
-rw-r--r--thirdparty/openssl/crypto/threads/solaris.sh4
-rwxr-xr-xthirdparty/openssl/crypto/threads/win32.bat4
-rw-r--r--thirdparty/openssl/crypto/ts/ts_lib.c5
-rw-r--r--thirdparty/openssl/crypto/ts/ts_rsp_verify.c27
-rw-r--r--thirdparty/openssl/crypto/txt_db/txt_db.c32
-rw-r--r--thirdparty/openssl/crypto/ui/ui_lib.c141
-rw-r--r--thirdparty/openssl/crypto/ui/ui_openssl.c59
-rw-r--r--thirdparty/openssl/crypto/whrlpool/wp_dgst.c3
-rw-r--r--thirdparty/openssl/crypto/x509/by_dir.c4
-rw-r--r--thirdparty/openssl/crypto/x509/x509_att.c12
-rw-r--r--thirdparty/openssl/crypto/x509/x509_err.c3
-rw-r--r--thirdparty/openssl/crypto/x509/x509_lu.c41
-rw-r--r--thirdparty/openssl/crypto/x509/x509_obj.c2
-rw-r--r--thirdparty/openssl/crypto/x509/x509_r2x.c14
-rw-r--r--thirdparty/openssl/crypto/x509/x509_txt.c7
-rw-r--r--thirdparty/openssl/crypto/x509/x509_vfy.c168
-rw-r--r--thirdparty/openssl/crypto/x509/x509spki.c2
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_addr.c6
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_alt.c34
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_conf.c4
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_cpols.c14
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_info.c37
-rw-r--r--thirdparty/openssl/crypto/x509v3/v3_purp.c1
-rw-r--r--thirdparty/openssl/openssl/bio.h6
-rw-r--r--thirdparty/openssl/openssl/bn.h2
-rw-r--r--thirdparty/openssl/openssl/comp.h4
-rw-r--r--thirdparty/openssl/openssl/conf.h1
-rw-r--r--thirdparty/openssl/openssl/dh.h29
-rw-r--r--thirdparty/openssl/openssl/dtls1.h7
-rw-r--r--thirdparty/openssl/openssl/err.h1
-rw-r--r--thirdparty/openssl/openssl/evp.h6
-rw-r--r--thirdparty/openssl/openssl/md5.h15
-rw-r--r--thirdparty/openssl/openssl/opensslconf.h75
-rw-r--r--thirdparty/openssl/openssl/opensslv.h6
-rw-r--r--thirdparty/openssl/openssl/ossl_typ.h2
-rw-r--r--thirdparty/openssl/openssl/pem.h6
-rw-r--r--thirdparty/openssl/openssl/pkcs12.h2
-rw-r--r--thirdparty/openssl/openssl/rand.h18
-rw-r--r--thirdparty/openssl/openssl/ssl.h10
-rw-r--r--thirdparty/openssl/openssl/ts.h3
-rw-r--r--thirdparty/openssl/openssl/x509.h6
-rw-r--r--thirdparty/openssl/openssl/x509_vfy.h9
-rw-r--r--thirdparty/openssl/patches/config_windows.patch49
-rw-r--r--thirdparty/openssl/patches/uwp_fix.patch (renamed from thirdparty/openssl/uwp_fix.patch)34
-rw-r--r--thirdparty/openssl/ssl/d1_both.c68
-rw-r--r--thirdparty/openssl/ssl/d1_clnt.c8
-rw-r--r--thirdparty/openssl/ssl/d1_lib.c37
-rw-r--r--thirdparty/openssl/ssl/d1_pkt.c171
-rw-r--r--thirdparty/openssl/ssl/d1_srvr.c31
-rwxr-xr-xthirdparty/openssl/ssl/install-ssl.com136
-rw-r--r--thirdparty/openssl/ssl/s23_clnt.c13
-rw-r--r--thirdparty/openssl/ssl/s23_pkt.c12
-rw-r--r--thirdparty/openssl/ssl/s23_srvr.c5
-rw-r--r--thirdparty/openssl/ssl/s2_clnt.c4
-rw-r--r--thirdparty/openssl/ssl/s2_lib.c2
-rw-r--r--thirdparty/openssl/ssl/s2_pkt.c10
-rw-r--r--thirdparty/openssl/ssl/s2_srvr.c12
-rw-r--r--thirdparty/openssl/ssl/s3_both.c41
-rw-r--r--thirdparty/openssl/ssl/s3_clnt.c86
-rw-r--r--thirdparty/openssl/ssl/s3_enc.c98
-rw-r--r--thirdparty/openssl/ssl/s3_lib.c41
-rw-r--r--thirdparty/openssl/ssl/s3_pkt.c45
-rw-r--r--thirdparty/openssl/ssl/s3_srvr.c157
-rw-r--r--thirdparty/openssl/ssl/ssl-lib.com1229
-rw-r--r--thirdparty/openssl/ssl/ssl_asn1.c3
-rw-r--r--thirdparty/openssl/ssl/ssl_cert.c5
-rw-r--r--thirdparty/openssl/ssl/ssl_ciph.c24
-rw-r--r--thirdparty/openssl/ssl/ssl_err.c5
-rw-r--r--thirdparty/openssl/ssl/ssl_lib.c31
-rw-r--r--thirdparty/openssl/ssl/ssl_locl.h21
-rw-r--r--thirdparty/openssl/ssl/ssl_rsa.c15
-rw-r--r--thirdparty/openssl/ssl/ssl_sess.c22
-rw-r--r--thirdparty/openssl/ssl/t1_enc.c1
-rw-r--r--thirdparty/openssl/ssl/t1_ext.c35
-rw-r--r--thirdparty/openssl/ssl/t1_lib.c418
-rw-r--r--thirdparty/opus/celt/arch.h13
-rw-r--r--thirdparty/opus/celt/arm/arm_celt_map.c24
-rw-r--r--thirdparty/opus/celt/arm/armcpu.c49
-rw-r--r--thirdparty/opus/celt/arm/armcpu.h6
-rw-r--r--thirdparty/opus/celt/arm/celt_neon_intr.c61
-rw-r--r--thirdparty/opus/celt/arm/pitch_arm.h68
-rw-r--r--thirdparty/opus/celt/bands.c4
-rw-r--r--thirdparty/opus/celt/celt.h2
-rw-r--r--thirdparty/opus/celt/celt_decoder.c10
-rw-r--r--thirdparty/opus/celt/celt_encoder.c13
-rw-r--r--thirdparty/opus/celt/celt_lpc.c3
-rw-r--r--thirdparty/opus/celt/cwrs.c2
-rw-r--r--thirdparty/opus/celt/fixed_generic.h16
-rw-r--r--thirdparty/opus/celt/kiss_fft.c2
-rw-r--r--thirdparty/opus/celt/mathops.c2
-rw-r--r--thirdparty/opus/celt/pitch.c67
-rw-r--r--thirdparty/opus/celt/pitch.h20
-rw-r--r--thirdparty/opus/celt/rate.c2
-rw-r--r--thirdparty/opus/celt/vq.c2
-rw-r--r--thirdparty/opus/celt/x86/pitch_sse.h34
-rw-r--r--thirdparty/opus/celt/x86/x86_celt_map.c2
-rw-r--r--thirdparty/opus/celt/x86/x86cpu.c2
-rw-r--r--thirdparty/opus/opus_multistream_encoder.c2
-rw-r--r--thirdparty/opus/silk/CNG.c61
-rw-r--r--thirdparty/opus/silk/NLSF_del_dec_quant.c14
-rw-r--r--thirdparty/opus/silk/NLSF_encode.c5
-rw-r--r--thirdparty/opus/silk/NSQ.c58
-rw-r--r--thirdparty/opus/silk/NSQ_del_dec.c40
-rw-r--r--thirdparty/opus/silk/PLC.c3
-rw-r--r--thirdparty/opus/silk/decode_core.c2
-rw-r--r--thirdparty/opus/silk/fixed/burg_modified_FIX.c21
-rw-r--r--thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c14
-rw-r--r--thirdparty/opus/silk/macros.h22
-rw-r--r--thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h6
-rw-r--r--thirdparty/opus/silk/process_NLSFs.c6
-rw-r--r--thirdparty/opus/silk/sort.c2
-rw-r--r--thirdparty/opus/silk/stereo_LR_to_MS.c8
-rw-r--r--thirdparty/opus/silk/x86/NSQ_sse.c2
-rw-r--r--thirdparty/opus/silk/x86/main_sse.h3
-rw-r--r--thirdparty/rg-etc1/rg_etc1.cpp2446
-rw-r--r--thirdparty/rg-etc1/rg_etc1.h76
-rw-r--r--thirdparty/tinyexr/tinyexr.cc2
-rw-r--r--thirdparty/tinyexr/tinyexr.h12419
-rw-r--r--thirdparty/zstd/LICENSE30
-rw-r--r--thirdparty/zstd/PATENTS33
-rw-r--r--thirdparty/zstd/README.md146
-rw-r--r--thirdparty/zstd/common/bitstream.h446
-rw-r--r--thirdparty/zstd/common/entropy_common.c221
-rw-r--r--thirdparty/zstd/common/error_private.c44
-rw-r--r--thirdparty/zstd/common/error_private.h76
-rw-r--r--thirdparty/zstd/common/fse.h698
-rw-r--r--thirdparty/zstd/common/fse_decompress.c328
-rw-r--r--thirdparty/zstd/common/huf.h283
-rw-r--r--thirdparty/zstd/common/mem.h373
-rw-r--r--thirdparty/zstd/common/pool.c194
-rw-r--r--thirdparty/zstd/common/pool.h56
-rw-r--r--thirdparty/zstd/common/threading.c80
-rw-r--r--thirdparty/zstd/common/threading.h104
-rw-r--r--thirdparty/zstd/common/xxhash.c869
-rw-r--r--thirdparty/zstd/common/xxhash.h305
-rw-r--r--thirdparty/zstd/common/zstd_common.c73
-rw-r--r--thirdparty/zstd/common/zstd_errors.h75
-rw-r--r--thirdparty/zstd/common/zstd_internal.h284
-rw-r--r--thirdparty/zstd/compress/fse_compress.c857
-rw-r--r--thirdparty/zstd/compress/huf_compress.c684
-rw-r--r--thirdparty/zstd/compress/zstd_compress.c3598
-rw-r--r--thirdparty/zstd/compress/zstd_opt.h921
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.c751
-rw-r--r--thirdparty/zstd/compress/zstdmt_compress.h78
-rw-r--r--thirdparty/zstd/decompress/huf_decompress.c888
-rw-r--r--thirdparty/zstd/decompress/zstd_decompress.c2376
-rw-r--r--thirdparty/zstd/zstd.h795
1289 files changed, 79598 insertions, 51604 deletions
diff --git a/.editorconfig b/.editorconfig
index e19057f0e8..b7ef43c340 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -5,6 +5,9 @@ charset = utf-8
end_of_line = lf
indent_style = tab
+[*.{cpp,hpp,c,h,mm}]
+trim_trailing_whitespace = true
+
[.travis.yml]
indent_style = space
indent_size = 2
diff --git a/.gitignore b/.gitignore
index 537ed7d32a..84aaefd736 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ core/version_generated.h
drivers/gles2/shaders/*.h
drivers/gles3/shaders/*.h
drivers/unix/os_unix_global_settings_path.cpp
+editor/authors.h
editor/builtin_fonts.h
editor/certs_compressed.h
editor/doc_data_compressed.h
diff --git a/.travis.yml b/.travis.yml
index 6be9f1f603..12d49f5d5d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,5 +1,7 @@
language: cpp
+dist: trusty
+
sudo: false
compiler:
@@ -73,7 +75,6 @@ addons:
# For style checks.
- clang-format-3.9
-
before_script:
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update; brew install scons; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ] && [ "$GODOT_TARGET" = "android" ]; then
@@ -86,5 +87,9 @@ script:
- if [ "$STATIC_CHECKS" = "yes" ]; then
sh ./misc/travis/clang-format.sh;
else
- scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin;
+ if [ "$TRAVIS_OS_NAME" = "windows" ]; then
+ scons platform=$GODOT_TARGET CXX=$CXX openssl=builtin;
+ else
+ scons platform=$GODOT_TARGET bits=64 CXX=$CXX openssl=builtin;
+ fi
fi
diff --git a/AUTHORS.md b/AUTHORS.md
index 189985309f..84b0754929 100644
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -10,17 +10,26 @@ source code. "Significant" is arbitrarily decided, but should be fair :)
GitHub usernames are indicated in parentheses, or as sole entry when no other
name is available.
-## Original authors
+## Project Founders
Juan Linietsky (reduz)
Ariel Manzur (punto-)
+## Lead Developer
+
+ Juan Linietsky (reduz)
+
+## Project Manager
+
+ Rémi Verschelde (akien-mga)
+
## Developers
(in alphabetical order, with 10 commits or more excluding merges)
Alexander Holland (AlexHolly)
Alexey Velikiy (jonyrock)
+ Alket Rexhepi (alketii)
Andreas Haas (Hinsbart)
Anton Yabchinskiy (a12n)
Aren Villanueva (kurikaesu)
@@ -31,6 +40,7 @@ name is available.
Carl Olsson (not-surt)
Dana Olson (adolson)
Daniel J. Ramirez (djrm)
+ Emmanuel Leblond (touilleMan)
Fabio Alessandrelli (Faless)
Ferenc Arn (tagcup)
Franklin Sobrinho (TheHX)
@@ -40,29 +50,37 @@ name is available.
Guilherme Felipe (guilhermefelipecgs)
Hein-Pieter van Braam (hpvb)
Hubert Jarosz (Marqin)
+ Hugo Locurcio (Calinou)
Ignacio Etcheverry (neikeq)
J08nY
+ Jakub Grzesik (kubecz3k)
Johan Manuel (29jm)
Joshua Grams (JoshuaGrams)
Juan Linietsky (reduz)
Julian Murgia (StraToN)
Kostadin Damyanov (Max-Might)
L. Krause (eska014)
+ Marc Gilleron (Zylann)
Marcelo Fernandez (marcelofg55)
Mariano Javier Suligoy (MarianoGnu)
Mario Schlack (hurikhan)
Masoud BH (masoudbh3)
Nathan Warden (NathanWarden)
+ Nuno Donato (nunodonato)
Ovnuniarchos
Patrick (firefly2442)
Paul Batty (Paulb23)
Pawel Kowal (pkowal1982)
Pedro J. Estébanez (RandomShaper)
+ Poommetee Ketson (Noshyaar)
Ralf Hölzemer (rollenrolm)
- RayKoopa
+ Ramesh Ravone (RameshRavone)
+ Ray Koopa (RayKoopa)
Rémi Verschelde (akien-mga)
SaracenOne
+ Theo Hallenius (TheoXD)
Thomas Herzog (karroffel)
+ Timo (toger5)
V. Vamsi Krishna (vkbsb)
Vinzenz Feenstra (vinzenz)
Zher Huei Lee (leezh)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 23ab874a2e..a9ada58e64 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -4,69 +4,110 @@ Sections covered in this file:
* [Reporting bugs or proposing features](#reporting-bugs-or-proposing-features)
* [Contributing pull requests](#contributing-pull-requests)
+* [Contributing to Godot's translation](#contributing-to-godots-translation)
* [Communicating with developers](#communicating-with-developers)
**Please read the first section before reporting a bug!**
## Reporting bugs or proposing features
-The golden rule is to **always open *one* issue for *one* bug**. If you notice several bugs and want to report them, make sure to create one new issue for each of them.
+The golden rule is to **always open *one* issue for *one* bug**. If you notice
+several bugs and want to report them, make sure to create one new issue for
+each of them.
Everything referred to hereafter as "bug" also applies for feature requests.
-If you are reporting a new issue, you will make our life much simpler (and the fix come much sooner) by following those guidelines:
+If you are reporting a new issue, you will make our life much simpler (and the
+fix come much sooner) by following those guidelines:
#### Search first in the existing database
-Issues are often reported several times by various users. It's a good practice to **search first** in the issues database before reporting your issue. If you don't find a relevant match or if you are unsure, don't hesitate to **open a new issue**. The bugsquad will handle it from there if it's a duplicate.
+Issues are often reported several times by various users. It's a good practice
+to **search first** in the issues database before reporting your issue. If you
+don't find a relevant match or if you are unsure, don't hesitate to **open a
+new issue**. The bugsquad will handle it from there if it's a duplicate.
-#### Specify the platform
-
-Godot runs on a large variety of platforms and operating systems and devices. If you believe your issue is device/platform dependent (for example if it is related to the rendering, crashes or compilation errors), please specify:
+#### Specify the platform
+
+Godot runs on a large variety of platforms and operating systems and devices.
+If you believe your issue is device/platform dependent (for example if it is
+related to the rendering, crashes or compilation errors), please specify:
* Operating system
* Device (including architecture, e.g. x86, x86_64, arm, etc.)
* GPU model (and driver in use if you know it)
#### Specify steps to reproduce
-Many bugs can't be reproduced unless specific steps are taken. Please **specify the exact steps** that must be taken to reproduce the condition, and try to keep them as minimal as possible.
+Many bugs can't be reproduced unless specific steps are taken. Please **specify
+the exact steps** that must be taken to reproduce the condition, and try to
+keep them as minimal as possible.
#### Provide a simple, example project
-Sometimes an unexpected behavior happens in your project. In such case, understand that:
-
+Sometimes an unexpected behavior happens in your project. In such case,
+understand that:
* What happens to you may not happen to other users.
-* We can't take the time to look at your project, understand how it is set up and then figure out why it's failing.
-
-To speed up our work, please prepare for us **a simple project** that isolates and reproduces the issue. This is always the **the best way for us to fix it**. You can attach a zip file with the minimal project directly to the bug report, by drag and dropping the file in the GitHub edition field.
+* We can't take the time to look at your project, understand how it is set up
+ and then figure out why it's failing.
+
+To speed up our work, please prepare for us **a simple project** that isolates
+and reproduces the issue. This is always the **the best way for us to fix it**.
+You can attach a zip file with the minimal project directly to the bug report,
+by drag and dropping the file in the GitHub edition field.
## Contributing pull requests
If you want to add new engine functionalities, please make sure that:
* This functionality is desired.
-* You talked to other developers on how to implement it best (on either communication channel, and maybe in a GitHub issue first before making your PR).
-* Even if it does not get merged, your PR is useful for future work by another developer.
+* You talked to other developers on how to implement it best (on either
+ communication channel, and maybe in a GitHub issue first before making your
+ PR).
+* Even if it does not get merged, your PR is useful for future work by another
+ developer.
-Similar rules can be applied when contributing bug fixes - it's always best to discuss the implementation in the bug report first if you are not 100% about what would be the best fix.
+Similar rules can be applied when contributing bug fixes - it's always best to
+discuss the implementation in the bug report first if you are not 100% about
+what would be the best fix.
#### Be nice to the git history
-Try to make simple PRs with that handle one specific topic. Just like for reporting issues, it's better to open 3 different PRs that each address a different issue than one big PR with three commits.
+Try to make simple PRs with that handle one specific topic. Just like for
+reporting issues, it's better to open 3 different PRs that each address a
+different issue than one big PR with three commits.
-When updating your fork with upstream changes, please use ``git pull --rebase`` to avoid creating "merge commits". Those commits unnecessarily pollute the git history when coming from PRs.
+When updating your fork with upstream changes, please use ``git pull --rebase``
+to avoid creating "merge commits". Those commits unnecessarily pollute the git
+history when coming from PRs.
-Also try to make commits that bring the engine from one stable state to another stable state, i.e. if your first commit has a bug that you fixed in the second commit, try to merge them together before making your pull request (see ``git rebase -i`` and relevant help about rebasing or ammending commits on the Internet).
+Also try to make commits that bring the engine from one stable state to another
+stable state, i.e. if your first commit has a bug that you fixed in the second
+commit, try to merge them together before making your pull request (see ``git
+rebase -i`` and relevant help about rebasing or ammending commits on the
+Internet).
-This git style guide has some good practices to have in mind: https://github.com/agis-/git-style-guide
+This git style guide has some good practices to have in mind:
+https://github.com/agis-/git-style-guide
#### Format your commit logs with readability in mind
-The way you format your commit logs is quite important to ensure that the commit history and changelog will be easy to read and understand. A git commit log is formatted as a short title (first line) and an extended description (everything after the first line and an empty separation line).
+The way you format your commit logs is quite important to ensure that the
+commit history and changelog will be easy to read and understand. A git commit
+log is formatted as a short title (first line) and an extended description
+(everything after the first line and an empty separation line).
-The short title is the most important part, as it is what will appear in the `shortlog` changelog (one line per commit, so no description shown) or in the GitHub interface unless you click the "expand" button. As the name tells it, try to keep that first line relatively short (ideally <= 50 chars, though it's rare to be able to tell enough in so few characters, so you can go a bit higher) - it should describe what the commit does globally, while details would go in the description. Typically, if you can't keep the title short because you have too much stuff to mention, it means that you should probably split your changes in several commits :)
+The short title is the most important part, as it is what will appear in the
+`shortlog` changelog (one line per commit, so no description shown) or in the
+GitHub interface unless you click the "expand" button. As the name tells it,
+try to keep that first line relatively short (ideally <= 50 chars, though it's
+rare to be able to tell enough in so few characters, so you can go a bit
+higher) - it should describe what the commit does globally, while details would
+go in the description. Typically, if you can't keep the title short because you
+have too much stuff to mention, it means that you should probably split your
+changes in several commits :)
-Here's an example of a well-formatted commit log (note how the extended description is also manually wrapped at 80 chars for readability):
+Here's an example of a well-formatted commit log (note how the extended
+description is also manually wrapped at 80 chars for readability):
```
Prevent French fries carbonization by fixing heat regulation
@@ -82,16 +123,44 @@ of cooking oil under normal atmospheric conditions.
Fixes #1789, long live the Realm!
```
-*Note:* When using the GitHub online editor (or worse, the drag and drop feature), *please* edit the commit title to something meaningful. Commits named "Update my_file.cpp" will not be accepted.
+*Note:* When using the GitHub online editor (or worse, the drag and drop
+feature), *please* edit the commit title to something meaningful. Commits named
+"Update my_file.cpp" will not be accepted.
-## Communicating with developers
+## Contributing to Godot's translation
+
+You can contribute to Godot's translation from the [Hosted
+Weblate](https://hosted.weblate.org/projects/godot-engine/godot), an open
+source and web-based translation platform. Please refer to the [translation
+readme](editor/translations/README.md) for more information.
-The Godot Engine community has [many communication channels](https://godotengine.org/community), some used more for user-level discussions and support, others more for development discussions.
+## Communicating with developers
-To communicate with developers (e.g. to discuss a feature you want to implement or a bug you want to fix), the following channels can be used:
-- [GitHub issues](https://github.com/godotengine/godot/issues): If there is an existing issue about a topic you want to discuss, just add a comment to it - all developers watch the repository and will get an email notification. You can also create a new issue - please keep in mind to create issues only to discuss quite specific points about the development, and not general user feedback or support requests.
-- [#godotengine-devel IRC channel on Freenode](https://webchat.freenode.net/?channels=godotengine-devel): You will find most core developers there, so it's the go-to channel for direct chat about Godot Engine development. Feel free to start discussing something there to get some early feedback before writing up a detailed proposal in a GitHub issue.
-- [devel@godotengine.org mailing list](https://listengine.tuxfamily.org/godotengine.org/devel/): Mailing list for Godot developers, used primarily to announce developer meetings on IRC and other important discussions that need to reach people directly in their mailbox. See the [index page](https://listengine.tuxfamily.org/godotengine.org/devel/) for subscription instructions.
+The Godot Engine community has [many communication
+channels](https://godotengine.org/community), some used more for user-level
+discussions and support, others more for development discussions.
+
+To communicate with developers (e.g. to discuss a feature you want to implement
+or a bug you want to fix), the following channels can be used:
+- [GitHub issues](https://github.com/godotengine/godot/issues): If there is an
+ existing issue about a topic you want to discuss, just add a comment to it -
+ all developers watch the repository and will get an email notification. You
+ can also create a new issue - please keep in mind to create issues only to
+ discuss quite specific points about the development, and not general user
+ feedback or support requests.
+- [#godotengine-devel IRC channel on
+ Freenode](https://webchat.freenode.net/?channels=godotengine-devel): You will
+ find most core developers there, so it's the go-to channel for direct chat
+ about Godot Engine development. Feel free to start discussing something there
+ to get some early feedback before writing up a detailed proposal in a GitHub
+ issue.
+- [devel@godotengine.org mailing
+ list](https://listengine.tuxfamily.org/godotengine.org/devel/): Mailing list
+ for Godot developers, used primarily to announce developer meetings on IRC
+ and other important discussions that need to reach people directly in their
+ mailbox. See the [index
+ page](https://listengine.tuxfamily.org/godotengine.org/devel/) for
+ subscription instructions.
Thanks!
diff --git a/COPYRIGHT.txt b/COPYRIGHT.txt
new file mode 100644
index 0000000000..698e4b1dc8
--- /dev/null
+++ b/COPYRIGHT.txt
@@ -0,0 +1,1144 @@
+# Exhaustive licensing information for files in the Godot Engine repository
+# =========================================================================
+#
+# This file aims at documenting the copyright and license for every source
+# file in the Godot Engine repository, and especially outline the files
+# whose license differs from the MIT/Expat license used by Godot Engine.
+#
+# It is written as a machine-readable format following the debian/copyright
+# specification. Globbing patterns (e.g. "Files: *") mean that they affect
+# all corresponding files (also recursively in subfolders), apart from those
+# with a more explicit copyright statement.
+#
+# Licenses are given with their SPDX identifier, and are all included in
+# plain text at the end of this file (in alphabetical order).
+#
+# Disclaimer for thirdparty libraries:
+# ------------------------------------
+#
+# Licensing details for thirdparty libraries in the 'thirdparty/' directory
+# are given in summarized form, i.e. with only the "main" license described
+# in the library's license statement. Different licenses of single files or
+# code snippets in thirdparty libraries are not documented here.
+# For example:
+# Files: ./thirdparty/zlib/
+# Copyright: 1995-2017, Jean-loup Gailly and Mark Adler
+# License: Zlib
+# The exact copyright for each file in that library *may* differ, and some
+# files or code snippets might be distributed under other compatible licenses
+# (e.g. a public domain dedication), but as far as Godot Engine is concerned
+# the library is considered as a whole under the Zlib license.
+#
+# Nota: When linking dynamically against thirdparty libraries instead of
+# building them into the Godot binary, you may remove the corresponding
+# license details from this file.
+
+-----------------------------------------------------------------------
+
+Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
+Upstream-Name: Godot Engine
+Upstream-Contact: Rémi Verschelde <contact@godotengine.org>
+Source: https://github.com/godotengine/godot
+
+Files: *
+Copyright: 2007-2017, Juan Linietsky, Ariel Manzur.
+ 2014-2017, Godot Engine contributors (cf. AUTHORS.md)
+License: Expat
+
+Files: ./icon.png
+ ./icon.svg
+ ./logo.png
+ ./logo.svg
+Copyright: Andrea Calabró
+License: CC-BY-3.0
+
+Files: ./platform/android/android_native_app_glue.c
+ ./platform/android/android_native_app_glue.h
+ ./platform/android/java/aidl/com/android/vending/billing/IInAppBillingService.aidl
+ ./platform/android/java/res/layout/status_bar_ongoing_event_progress_bar.xml
+ ./platform/android/java/src/com/android/vending/licensing/*
+ ./platform/android/java/src/com/google/android/vending/expansion/downloader/*
+ ./platform/android/java/src/org/godotengine/godot/input/InputManagerCompat.java
+ ./platform/android/java/src/org/godotengine/godot/input/InputManagerV16.java
+ ./platform/android/java/src/org/godotengine/godot/input/InputManagerV9.java
+Copyright: 2008-2013, The Android Open Source Project
+License: Apache-2.0
+
+Files: ./platform/android/cpu-features.c
+ ./platform/android/cpu-features.h
+Copyright: 2010, The Android Open Source Project
+License: BSD-2-clause
+
+Files: ./platform/android/ifaddrs_android.cpp
+ ./platform/android/ifaddrs_android.h
+Copyright: 2012-2013, Google Inc.
+License: BSD-3-clause
+
+Files: ./platform/android/java/src/com/android/vending/licensing/util/Base64.java
+ ./platform/android/java/src/com/android/vending/licensing/util/Base64DecoderException.java
+Copyright: 2002, Google Inc.
+License: Apache-2.0
+
+Files: ./platform/android/power_android.cpp
+ ./platform/osx/power_osx.cpp
+ ./platform/windows/power_windows.cpp
+ ./platform/x11/power_x11.cpp
+Copyright: 1997-2017, Sam Lantinga
+ 2007-2017, Juan Linietsky, Ariel Manzur.
+ 2014-2017, Godot Engine contributors (cf. AUTHORS.md)
+License: Expat and Zlib
+
+Files: ./platform/uwp/export/export.cpp
+Copyright: 2016, Facebook, Inc. All rights reserved.
+ 2007-2017, Juan Linietsky, Ariel Manzur.
+ 2014-2017, Godot Engine contributors (cf. AUTHORS.md)
+License: BSD-3-clause and Expat
+
+Files: ./servers/physics/gjk_epa.cpp
+ ./servers/physics/joints/generic_6dof_joint_sw.cpp
+ ./servers/physics/joints/generic_6dof_joint_sw.h
+ ./servers/physics/joints/hinge_joint_sw.cpp
+ ./servers/physics/joints/hinge_joint_sw.h
+ ./servers/physics/joints/jacobian_entry_sw.h
+ ./servers/physics/joints/pin_joint_sw.cpp
+ ./servers/physics/joints/pin_joint_sw.h
+ ./servers/physics/joints/slider_joint_sw.cpp
+ ./servers/physics/joints/slider_joint_sw.h
+Copyright: 2003-2008, Erwin Coumans
+ 2007-2017, Juan Linietsky, Ariel Manzur.
+ 2014-2017, Godot Engine contributors (cf. AUTHORS.md)
+License: Expat and Zlib
+
+Files: ./servers/physics/joints/cone_twist_joint_sw.cpp
+ ./servers/physics/joints/cone_twist_joint_sw.h
+Copyright: 2007, Starbreeze Studios
+ 2007-2017, Juan Linietsky, Ariel Manzur.
+ 2014-2017, Godot Engine contributors (cf. AUTHORS.md)
+License: Expat and Zlib
+
+Files: ./thirdparty/b2d_convexdecomp/
+Copyright: 2007, Eric Jordan
+Copyright: 2006-2009, Erin Catto
+License: Zlib
+
+Files: ./thirdparty/certs/ca-certificates.crt
+Copyright: FIXME
+License: FIXME
+
+Files: ./thirdparty/enet/
+Copyright: 2002-2016, Lee Salzman
+License: Expat
+
+Files: ./thirdparty/fonts/DroidSans*.ttf
+Copyright: 2008, The Android Open Source Project
+License: Apache-2.0
+
+Files: ./thirdparty/fonts/source_code_pro.otf
+Copyright: 2010, 2012, Adobe Systems Incorporated
+License: OFL-1.1
+
+Files: ./thirdparty/freetype/
+Copyright: 1996-2016, David Turner, Robert Wilhelm, and Werner Lemberg.
+License: FTL
+
+Files: ./thirdparty/glad/
+Copyright: 2013, David Herberth
+License: Expat
+
+Files: ./thirdparty/jpeg_compressor/
+Copyright: 2012, Rich Geldreich
+License: public-domain
+
+Files: ./thirdparty/libogg/
+Copyright: 2002, Xiph.org Foundation
+License: BSD-3-clause
+
+Files: ./thirdparty/libpng/
+Copyright: 1995-1996, Guy Eric Schalnat, Group 42, Inc.
+ 1996-1997, Andreas Dilger
+ 1998-2016, Glenn Randers-Pehrson
+License: Zlib
+
+Files: ./thirdparty/libsimplewebm/
+Copyright: 2016, Błażej Szczygieł
+License: Expat
+
+Files: ./thirdparty/libsimplewebm/libwebm/
+Copyright: 2010, Google Inc.
+License: BSD-3-clause
+
+Files: ./thirdparty/libtheora/
+Copyright: 2002-2009, Xiph.org Foundation
+License: BSD-3-clause
+
+Files: ./thirdparty/libvorbis/
+Copyright: 2002-2015, Xiph.org Foundation
+License: BSD-3-clause
+
+Files: ./thirdparty/libvpx/
+Copyright: 2010, The WebM Project authors.
+License: BSD-3-clause
+
+Files: ./thirdparty/libwebp/COPYING
+Copyright: 2010, Google Inc.
+License: BSD-3-clause
+
+Files: ./thirdparty/minizip/
+Copyright: 1998-2010, Gilles Vollant
+ 2007-2008, Even Rouault
+ 2009-2010, Mathias Svensson
+License: Zlib
+
+Files: ./thirdparty/misc/aes256.cpp
+ ./thirdparty/misc/aes256.h
+ ./thirdparty/misc/sha256.c
+ ./thirdparty/misc/sha256.h
+Copyright: 2007-2011, Ilya O. Levin
+License: ISC
+
+Files: ./thirdparty/misc/base64.c
+ ./thirdparty/misc/base64.h
+Copyright: Ari Edelkind
+License: public-domain
+
+Files: ./thirdparty/misc/curl_hostcheck.c
+ ./thirdparty/misc/curl_hostcheck.h
+Copyright: 1998-2012, Daniel Stenberg et al.
+License: curl
+
+Files: ./thirdparty/misc/fastlz.c
+ ./thirdparty/misc/fastlz.h
+Copyright: 2005-2007, Ariya Hidayat
+License: Expat
+
+Files: ./thirdparty/misc/hq2x.cpp
+ ./thirdparty/misc/hq2x.h
+Copyright: 2016, Bruno Ribeiro
+License: Apache-2.0
+
+Files: ./thirdparty/misc/md5.cpp
+ ./thirdparty/misc/md5.h
+Copyright: 1990, RSA Data Security, Inc.
+License: RSA-MD
+
+Files: ./thirdparty/misc/mikktspace.c
+ ./thirdparty/misc/mikktspace.h
+Copyright: 2011, Morten S. Mikkelsen
+License: Zlib
+
+Files: ./thirdparty/misc/pcg.cpp
+ ./thirdparty/misc/pcg.h
+Copyright: 2014, M.E. O'Neill
+License: Apache-2.0
+
+Files: ./thirdparty/misc/smaz.c
+ ./thirdparty/misc/smaz.h
+Copyright: 2006-2009, Salvatore Sanfilippo
+License: BSD-3-clause
+
+Files: ./thirdparty/misc/stb_truetype.h
+ ./thirdparty/misc/stb_vorbis.c
+Copyright: 2007-2015, Sean Barrett
+License: public-domain
+
+Files: ./thirdparty/misc/triangulator.cpp
+ ./thirdparty/misc/triangulator.h
+Copyright: 2011, Ivan Fratric
+License: Expat
+
+Files: ./thirdparty/misc/yuv2rgb.h
+Copyright: 2008-2011, Robin Watts
+License: BSD-2-clause
+
+Files: ./thirdparty/openssl/
+Copyright: 1998-2016, The OpenSSL Project.
+License: OpenSSL
+
+Files: ./thirdparty/opus/
+Copyright: 2001-2011, Xiph.Org, Skype Limited, Octasic,
+ Jean-Marc Valin, Timothy B. Terriberry,
+ CSIRO, Gregory Maxwell, Mark Borgerding,
+ Erik de Castro Lopo
+License: BSD-3-clause
+
+Files: ./thirdparty/pvrtccompressor/
+Copyright: 2014, Jeffrey Lim.
+License: BSD-3-clause
+
+Files: ./thirdparty/rg-etc1/
+Copyright: 2012, Rich Geldreich
+License: Zlib
+
+Files: ./thirdparty/rtaudio/
+Copyright: 2001-2016, Gary P. Scavone
+License: Expat
+
+Files: ./thirdparty/squish/
+Copyright: 2006, Simon Brown
+License: Expat
+
+Files: ./thirdparty/tinyexr/
+Copyright: 2014-2017, Syoyo Fujita
+ 2002, Industrial Light & Magic, a division of Lucas Digital Ltd. LLC
+License: BSD-3-Clause
+
+Files: ./thirdparty/zlib/
+Copyright: 1995-2017, Jean-loup Gailly and Mark Adler
+License: Zlib
+
+
+
+License: Apache-2.0
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ .
+ http://www.apache.org/licenses/LICENSE-2.0
+ .
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+License: BSD-2-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+ .
+ Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+ .
+ Redistributions in binary form must reproduce the above copyright notice, this
+ list of conditions and the following disclaimer in the documentation and/or
+ other materials provided with the distribution. Neither the name of the author
+ nor the names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+License: BSD-3-clause
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ .
+ 3. Neither the name of the University nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+ .
+ THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+License: CC-BY-3.0
+ Creative Commons Attribution 3.0 Unported
+ .
+ CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
+ LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN
+ ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION
+ ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE
+ INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
+ ITS USE.
+ .
+ License
+ .
+ THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE
+ COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY
+ COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS
+ AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.
+ .
+ BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE
+ TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY
+ BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS
+ CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND
+ CONDITIONS.
+ .
+ 1. Definitions
+ .
+ a. "Adaptation" means a work based upon the Work, or upon the Work and
+ other pre-existing works, such as a translation, adaptation, derivative
+ work, arrangement of music or other alterations of a literary or
+ artistic work, or phonogram or performance and includes cinematographic
+ adaptations or any other form in which the Work may be recast,
+ transformed, or adapted including in any form recognizably derived from
+ the original, except that a work that constitutes a Collection will not
+ be considered an Adaptation for the purpose of this License. For the
+ avoidance of doubt, where the Work is a musical work, performance or
+ phonogram, the synchronization of the Work in timed-relation with a
+ moving image ("synching") will be considered an Adaptation for the
+ purpose of this License.
+ .
+ b. "Collection" means a collection of literary or artistic works, such
+ as encyclopedias and anthologies, or performances, phonograms or
+ broadcasts, or other works or subject matter other than works listed in
+ Section 1(f) below, which, by reason of the selection and arrangement of
+ their contents, constitute intellectual creations, in which the Work is
+ included in its entirety in unmodified form along with one or more other
+ contributions, each constituting separate and independent works in
+ themselves, which together are assembled into a collective whole. A work
+ that constitutes a Collection will not be considered an Adaptation (as
+ defined above) for the purposes of this License.
+ .
+ c. "Distribute" means to make available to the public the original and
+ copies of the Work or Adaptation, as appropriate, through sale or other
+ transfer of ownership.
+ .
+ d. "Licensor" means the individual, individuals, entity or entities that
+ offer(s) the Work under the terms of this License.
+ .
+ e. "Original Author" means, in the case of a literary or artistic work,
+ the individual, individuals, entity or entities who created the Work or
+ if no individual or entity can be identified, the publisher; and in
+ addition (i) in the case of a performance the actors, singers,
+ musicians, dancers, and other persons who act, sing, deliver, declaim,
+ play in, interpret or otherwise perform literary or artistic works or
+ expressions of folklore; (ii) in the case of a phonogram the producer
+ being the person or legal entity who first fixes the sounds of a
+ performance or other sounds; and, (iii) in the case of broadcasts, the
+ organization that transmits the broadcast.
+ .
+ f. "Work" means the literary and/or artistic work offered under the
+ terms of this License including without limitation any production in the
+ literary, scientific and artistic domain, whatever may be the mode or
+ form of its expression including digital form, such as a book, pamphlet
+ and other writing; a lecture, address, sermon or other work of the same
+ nature; a dramatic or dramatico-musical work; a choreographic work or
+ entertainment in dumb show; a musical composition with or without words;
+ a cinematographic work to which are assimilated works expressed by a
+ process analogous to cinematography; a work of drawing, painting,
+ architecture, sculpture, engraving or lithography; a photographic work
+ to which are assimilated works expressed by a process analogous to
+ photography; a work of applied art; an illustration, map, plan, sketch
+ or three-dimensional work relative to geography, topography,
+ architecture or science; a performance; a broadcast; a phonogram; a
+ compilation of data to the extent it is protected as a copyrightable
+ work; or a work performed by a variety or circus performer to the extent
+ it is not otherwise considered a literary or artistic work.
+ .
+ g. "You" means an individual or entity exercising rights under this
+ License who has not previously violated the terms of this License with
+ respect to the Work, or who has received express permission from the
+ Licensor to exercise rights under this License despite a previous
+ violation.
+ .
+ h. "Publicly Perform" means to perform public recitations of the Work
+ and to communicate to the public those public recitations, by any means
+ or process, including by wire or wireless means or public digital
+ performances; to make available to the public Works in such a way that
+ members of the public may access these Works from a place and at a place
+ individually chosen by them; to perform the Work to the public by any
+ means or process and the communication to the public of the performances
+ of the Work, including by public digital performance; to broadcast and
+ rebroadcast the Work by any means including signs, sounds or images.
+ .
+ i. "Reproduce" means to make copies of the Work by any means including
+ without limitation by sound or visual recordings and the right of
+ fixation and reproducing fixations of the Work, including storage of a
+ protected performance or phonogram in digital form or other electronic
+ medium.
+ .
+ 2. Fair Dealing Rights. Nothing in this License is intended to reduce,
+ limit, or restrict any uses free from copyright or rights arising from
+ limitations or exceptions that are provided for in connection with the
+ copyright protection under copyright law or other applicable laws.
+ .
+ 3. License Grant. Subject to the terms and conditions of this License,
+ Licensor hereby grants You a worldwide, royalty-free, non-exclusive,
+ perpetual (for the duration of the applicable copyright) license to
+ exercise the rights in the Work as stated below:
+ .
+ a. to Reproduce the Work, to incorporate the Work into one or more
+ Collections, and to Reproduce the Work as incorporated in the
+ Collections;
+ .
+ b. to create and Reproduce Adaptations provided that any such
+ Adaptation, including any translation in any medium, takes reasonable
+ steps to clearly label, demarcate or otherwise identify that changes
+ were made to the original Work. For example, a translation could be
+ marked "The original work was translated from English to Spanish," or a
+ modification could indicate "The original work has been modified.";
+ .
+ c. to Distribute and Publicly Perform the Work including as incorporated
+ in Collections; and,
+ .
+ d. to Distribute and Publicly Perform Adaptations.
+ .
+ e. For the avoidance of doubt:
+ .
+ i. Non-waivable Compulsory License Schemes. In those jurisdictions in
+ which the right to collect royalties through any statutory or compulsory
+ licensing scheme cannot be waived, the Licensor reserves the exclusive
+ right to collect such royalties for any exercise by You of the rights
+ granted under this License;
+ .
+ ii. Waivable Compulsory License Schemes. In those jurisdictions in which
+ the right to collect royalties through any statutory or compulsory
+ licensing scheme can be waived, the Licensor waives the exclusive right
+ to collect such royalties for any exercise by You of the rights granted
+ under this License; and,
+ .
+ iii. Voluntary License Schemes. The Licensor waives the right to collect
+ royalties, whether individually or, in the event that the Licensor is a
+ member of a collecting society that administers voluntary licensing
+ schemes, via that society, from any exercise by You of the rights
+ granted under this License.
+ .
+ The above rights may be exercised in all media and formats whether now
+ known or hereafter devised. The above rights include the right to make
+ such modifications as are technically necessary to exercise the rights
+ in other media and formats. Subject to Section 8(f), all rights not
+ expressly granted by Licensor are hereby reserved.
+ .
+ 4. Restrictions. The license granted in Section 3 above is expressly
+ made subject to and limited by the following restrictions:
+ .
+ a. You may Distribute or Publicly Perform the Work only under the terms
+ of this License. You must include a copy of, or the Uniform Resource
+ Identifier (URI) for, this License with every copy of the Work You
+ Distribute or Publicly Perform. You may not offer or impose any terms on
+ the Work that restrict the terms of this License or the ability of the
+ recipient of the Work to exercise the rights granted to that recipient
+ under the terms of the License. You may not sublicense the Work. You
+ must keep intact all notices that refer to this License and to the
+ disclaimer of warranties with every copy of the Work You Distribute or
+ Publicly Perform. When You Distribute or Publicly Perform the Work, You
+ may not impose any effective technological measures on the Work that
+ restrict the ability of a recipient of the Work from You to exercise the
+ rights granted to that recipient under the terms of the License. This
+ Section 4(a) applies to the Work as incorporated in a Collection, but
+ this does not require the Collection apart from the Work itself to be
+ made subject to the terms of this License. If You create a Collection,
+ upon notice from any Licensor You must, to the extent practicable,
+ remove from the Collection any credit as required by Section 4(b), as
+ requested. If You create an Adaptation, upon notice from any Licensor
+ You must, to the extent practicable, remove from the Adaptation any
+ credit as required by Section 4(b), as requested.
+ .
+ b. If You Distribute, or Publicly Perform the Work or any Adaptations or
+ Collections, You must, unless a request has been made pursuant to
+ Section 4(a), keep intact all copyright notices for the Work and
+ provide, reasonable to the medium or means You are utilizing: (i) the
+ name of the Original Author (or pseudonym, if applicable) if supplied,
+ and/or if the Original Author and/or Licensor designate another party or
+ parties (e.g., a sponsor institute, publishing entity, journal) for
+ attribution ("Attribution Parties") in Licensor's copyright notice,
+ terms of service or by other reasonable means, the name of such party or
+ parties; (ii) the title of the Work if supplied; (iii) to the extent
+ reasonably practicable, the URI, if any, that Licensor specifies to be
+ associated with the Work, unless such URI does not refer to the
+ copyright notice or licensing information for the Work; and (iv) ,
+ consistent with Section 3(b), in the case of an Adaptation, a credit
+ identifying the use of the Work in the Adaptation (e.g., "French
+ translation of the Work by Original Author," or "Screenplay based on
+ original Work by Original Author"). The credit required by this Section
+ 4 (b) may be implemented in any reasonable manner; provided, however,
+ that in the case of a Adaptation or Collection, at a minimum such credit
+ will appear, if a credit for all contributing authors of the Adaptation
+ or Collection appears, then as part of these credits and in a manner at
+ least as prominent as the credits for the other contributing authors.
+ For the avoidance of doubt, You may only use the credit required by this
+ Section for the purpose of attribution in the manner set out above and,
+ by exercising Your rights under this License, You may not implicitly or
+ explicitly assert or imply any connection with, sponsorship or
+ endorsement by the Original Author, Licensor and/or Attribution Parties,
+ as appropriate, of You or Your use of the Work, without the separate,
+ express prior written permission of the Original Author, Licensor and/or
+ Attribution Parties.
+ .
+ c. Except as otherwise agreed in writing by the Licensor or as may be
+ otherwise permitted by applicable law, if You Reproduce, Distribute or
+ Publicly Perform the Work either by itself or as part of any Adaptations
+ or Collections, You must not distort, mutilate, modify or take other
+ derogatory action in relation to the Work which would be prejudicial to
+ the Original Author's honor or reputation. Licensor agrees that in those
+ jurisdictions (e.g. Japan), in which any exercise of the right granted
+ in Section 3(b) of this License (the right to make Adaptations) would be
+ deemed to be a distortion, mutilation, modification or other derogatory
+ action prejudicial to the Original Author's honor and reputation, the
+ Licensor will waive or not assert, as appropriate, this Section, to the
+ fullest extent permitted by the applicable national law, to enable You
+ to reasonably exercise Your right under Section 3(b) of this License
+ (right to make Adaptations) but not otherwise.
+ .
+ 5. Representations, Warranties and Disclaimer
+ .
+ UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR
+ OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY
+ KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,
+ INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,
+ FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF
+ LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,
+ WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE
+ EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.
+ .
+ 6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE
+ LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR
+ ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES
+ ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS
+ BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+ .
+ 7. Termination
+ .
+ a. This License and the rights granted hereunder will terminate
+ automatically upon any breach by You of the terms of this License.
+ Individuals or entities who have received Adaptations or Collections
+ from You under this License, however, will not have their licenses
+ terminated provided such individuals or entities remain in full
+ compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will
+ survive any termination of this License.
+ .
+ b. Subject to the above terms and conditions, the license granted here
+ is perpetual (for the duration of the applicable copyright in the Work).
+ Notwithstanding the above, Licensor reserves the right to release the
+ Work under different license terms or to stop distributing the Work at
+ any time; provided, however that any such election will not serve to
+ withdraw this License (or any other license that has been, or is
+ required to be, granted under the terms of this License), and this
+ License will continue in full force and effect unless terminated as
+ stated above.
+ .
+ 8. Miscellaneous
+ .
+ a. Each time You Distribute or Publicly Perform the Work or a
+ Collection, the Licensor offers to the recipient a license to the Work
+ on the same terms and conditions as the license granted to You under
+ this License.
+ .
+ b. Each time You Distribute or Publicly Perform an Adaptation, Licensor
+ offers to the recipient a license to the original Work on the same terms
+ and conditions as the license granted to You under this License.
+ .
+ c. If any provision of this License is invalid or unenforceable under
+ applicable law, it shall not affect the validity or enforceability of
+ the remainder of the terms of this License, and without further action
+ by the parties to this agreement, such provision shall be reformed to
+ the minimum extent necessary to make such provision valid and
+ enforceable.
+ .
+ d. No term or provision of this License shall be deemed waived and no
+ breach consented to unless such waiver or consent shall be in writing
+ and signed by the party to be charged with such waiver or consent. This
+ License constitutes the entire agreement between the parties with
+ respect to the Work licensed here. There are no understandings,
+ agreements or representations with respect to the Work not specified
+ here. Licensor shall not be bound by any additional provisions that may
+ appear in any communication from You.
+ .
+ e. This License may not be modified without the mutual written agreement
+ of the Licensor and You.
+ .
+ f. The rights granted under, and the subject matter referenced, in this
+ License were drafted utilizing the terminology of the Berne Convention
+ for the Protection of Literary and Artistic Works (as amended on
+ September 28, 1979), the Rome Convention of 1961, the WIPO Copyright
+ Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and
+ the Universal Copyright Convention (as revised on July 24, 1971). These
+ rights and subject matter take effect in the relevant jurisdiction in
+ which the License terms are sought to be enforced according to the
+ corresponding provisions of the implementation of those treaty
+ provisions in the applicable national law. If the standard suite of
+ rights granted under applicable copyright law includes additional rights
+ not granted under this License, such additional rights are deemed to be
+ included in the License; this License is not intended to restrict the
+ license of any rights under applicable law.
+ .
+ Creative Commons Notice
+ .
+ Creative Commons is not a party to this License, and makes no warranty
+ whatsoever in connection with the Work. Creative Commons will not be
+ liable to You or any party on any legal theory for any damages
+ whatsoever, including without limitation any general, special,
+ incidental or consequential damages arising in connection to this
+ license. Notwithstanding the foregoing two (2) sentences, if Creative
+ Commons has expressly identified itself as the Licensor hereunder, it
+ shall have all rights and obligations of Licensor.
+ .
+ Except for the limited purpose of indicating to the public that the Work
+ is licensed under the CCPL, Creative Commons does not authorize the use
+ by either party of the trademark "Creative Commons" or any related
+ trademark or logo of Creative Commons without the prior written consent
+ of Creative Commons. Any permitted use will be in compliance with
+ Creative Commons' then-current trademark usage guidelines, as may be
+ published on its website or otherwise made available upon request from
+ time to time. For the avoidance of doubt, this trademark restriction
+ does not form part of this License.
+ .
+ Creative Commons may be contacted at http://creativecommons.org/.
+
+License: curl
+ All rights reserved.
+ .
+ Permission to use, copy, modify, and distribute this software for any purpose
+ with or without fee is hereby granted, provided that the above copyright
+ notice and this permission notice appear in all copies.
+ .
+ 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 OF THIRD PARTY RIGHTS. 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.
+ .
+ Except as contained in this notice, the name of a copyright holder shall not
+ be used in advertising or otherwise to promote the sale, use or other dealings
+ in this Software without prior written authorization of the copyright holder.
+
+License: Expat
+ 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.
+
+License: FTL
+ The FreeType Project LICENSE
+ ----------------------------
+ .
+ 2000-Feb-08
+ .
+ Copyright 1996-2000 by
+ David Turner, Robert Wilhelm, and Werner Lemberg
+ .
+ .
+ .
+ Introduction
+ ============
+ .
+ The FreeType Project is distributed in several archive packages;
+ some of them may contain, in addition to the FreeType font engine,
+ various tools and contributions which rely on, or relate to, the
+ FreeType Project.
+ .
+ This license applies to all files found in such packages, and
+ which do not fall under their own explicit license. The license
+ affects thus the FreeType font engine, the test programs,
+ documentation and makefiles, at the very least.
+ .
+ This license was inspired by the BSD, Artistic, and IJG
+ (Independent JPEG Group) licenses, which all encourage inclusion
+ and use of free software in commercial and freeware products
+ alike. As a consequence, its main points are that:
+ .
+ o We don't promise that this software works. However, we will be
+ interested in any kind of bug reports. (`as is' distribution)
+ .
+ o You can use this software for whatever you want, in parts or
+ full form, without having to pay us. (`royalty-free' usage)
+ .
+ o You may not pretend that you wrote this software. If you use
+ it, or only parts of it, in a program, you must acknowledge
+ somewhere in your documentation that you have used the
+ FreeType code. (`credits')
+ .
+ We specifically permit and encourage the inclusion of this
+ software, with or without modifications, in commercial products.
+ We disclaim all warranties covering The FreeType Project and
+ assume no liability related to The FreeType Project.
+ .
+ .
+ Legal Terms
+ ===========
+ .
+ 0. Definitions
+ --------------
+ .
+ Throughout this license, the terms `package', `FreeType Project',
+ and `FreeType archive' refer to the set of files originally
+ distributed by the authors (David Turner, Robert Wilhelm, and
+ Werner Lemberg) as the `FreeType Project', be they named as alpha,
+ beta or final release.
+ .
+ `You' refers to the licensee, or person using the project, where
+ `using' is a generic term including compiling the project's source
+ code as well as linking it to form a `program' or `executable'.
+ This program is referred to as `a program using the FreeType
+ engine'.
+ .
+ This license applies to all files distributed in the original
+ FreeType Project, including all source code, binaries and
+ documentation, unless otherwise stated in the file in its
+ original, unmodified form as distributed in the original archive.
+ If you are unsure whether or not a particular file is covered by
+ this license, you must contact us to verify this.
+ .
+ The FreeType Project is copyright (C) 1996-2000 by David Turner,
+ Robert Wilhelm, and Werner Lemberg. All rights reserved except as
+ specified below.
+ .
+ 1. No Warranty
+ --------------
+ .
+ THE FREETYPE PROJECT IS PROVIDED `AS IS' WITHOUT WARRANTY OF ANY
+ KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE. IN NO EVENT WILL ANY OF THE AUTHORS OR COPYRIGHT HOLDERS
+ BE LIABLE FOR ANY DAMAGES CAUSED BY THE USE OR THE INABILITY TO
+ USE, OF THE FREETYPE PROJECT.
+ .
+ 2. Redistribution
+ -----------------
+ .
+ This license grants a worldwide, royalty-free, perpetual and
+ irrevocable right and license to use, execute, perform, compile,
+ display, copy, create derivative works of, distribute and
+ sublicense the FreeType Project (in both source and object code
+ forms) and derivative works thereof for any purpose; and to
+ authorize others to exercise some or all of the rights granted
+ herein, subject to the following conditions:
+ .
+ o Redistribution of source code must retain this license file
+ (`LICENSE.TXT') unaltered; any additions, deletions or changes
+ to the original files must be clearly indicated in
+ accompanying documentation. The copyright notices of the
+ unaltered, original files must be preserved in all copies of
+ source files.
+ .
+ o Redistribution in binary form must provide a disclaimer that
+ states that the software is based in part of the work of the
+ FreeType Team, in the distribution documentation. We also
+ encourage you to put an URL to the FreeType web page in your
+ documentation, though this isn't mandatory.
+ .
+ These conditions apply to any software derived from or based on
+ the FreeType Project, not just the unmodified files. If you use
+ our work, you must acknowledge us. However, no fee need be paid
+ to us.
+ .
+ 3. Advertising
+ --------------
+ .
+ Neither the FreeType authors and contributors nor you shall use
+ the name of the other for commercial, advertising, or promotional
+ purposes without specific prior written permission.
+ .
+ We suggest, but do not require, that you use one or more of the
+ following phrases to refer to this software in your documentation
+ or advertising materials: `FreeType Project', `FreeType Engine',
+ `FreeType library', or `FreeType Distribution'.
+ .
+ As you have not signed this license, you are not required to
+ accept it. However, as the FreeType Project is copyrighted
+ material, only this license, or another one contracted with the
+ authors, grants you the right to use, distribute, and modify it.
+ Therefore, by using, distributing, or modifying the FreeType
+ Project, you indicate that you understand and accept all the terms
+ of this license.
+ .
+ 4. Contacts
+ -----------
+ .
+ There are two mailing lists related to FreeType:
+ .
+ o freetype@freetype.org
+ .
+ Discusses general use and applications of FreeType, as well as
+ future and wanted additions to the library and distribution.
+ If you are looking for support, start in this list if you
+ haven't found anything to help you in the documentation.
+ .
+ o devel@freetype.org
+ .
+ Discusses bugs, as well as engine internals, design issues,
+ specific licenses, porting, etc.
+ .
+ o http://www.freetype.org
+ .
+ Holds the current FreeType web page, which will allow you to
+ download our latest development version and read online
+ documentation.
+ .
+ You can also contact us individually at:
+ .
+ David Turner <david.turner@freetype.org>
+ Robert Wilhelm <robert.wilhelm@freetype.org>
+ Werner Lemberg <werner.lemberg@freetype.org>
+
+License: ISC
+ Permission to use, copy, modify, and/or distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+ .
+ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+License: OFL-1.1
+ PREAMBLE
+ The goals of the Open Font License (OFL) are to stimulate worldwide
+ development of collaborative font projects, to support the font creation
+ efforts of academic and linguistic communities, and to provide a free and
+ open framework in which fonts may be shared and improved in partnership
+ with others.
+ .
+ The OFL allows the licensed fonts to be used, studied, modified and
+ redistributed freely as long as they are not sold by themselves. The
+ fonts, including any derivative works, can be bundled, embedded,
+ redistributed and/or sold with any software provided that any reserved
+ names are not used by derivative works. The fonts and derivatives,
+ however, cannot be released under any other type of license. The
+ requirement for fonts to remain under this license does not apply
+ to any document created using the fonts or their derivatives.
+ .
+ DEFINITIONS
+ "Font Software" refers to the set of files released by the Copyright
+ Holder(s) under this license and clearly marked as such. This may
+ include source files, build scripts and documentation.
+ .
+ "Reserved Font Name" refers to any names specified as such after the
+ copyright statement(s).
+ .
+ "Original Version" refers to the collection of Font Software components as
+ distributed by the Copyright Holder(s).
+ .
+ "Modified Version" refers to any derivative made by adding to, deleting,
+ or substituting -- in part or in whole -- any of the components of the
+ Original Version, by changing formats or by porting the Font Software to a
+ new environment.
+ .
+ "Author" refers to any designer, engineer, programmer, technical
+ writer or other person who contributed to the Font Software.
+ .
+ PERMISSION & CONDITIONS
+ Permission is hereby granted, free of charge, to any person obtaining
+ a copy of the Font Software, to use, study, copy, merge, embed, modify,
+ redistribute, and sell modified and unmodified copies of the Font
+ Software, subject to the following conditions:
+ .
+ 1) Neither the Font Software nor any of its individual components,
+ in Original or Modified Versions, may be sold by itself.
+ .
+ 2) Original or Modified Versions of the Font Software may be bundled,
+ redistributed and/or sold with any software, provided that each copy
+ contains the above copyright notice and this license. These can be
+ included either as stand-alone text files, human-readable headers or
+ in the appropriate machine-readable metadata fields within text or
+ binary files as long as those fields can be easily viewed by the user.
+ .
+ 3) No Modified Version of the Font Software may use the Reserved Font
+ Name(s) unless explicit written permission is granted by the corresponding
+ Copyright Holder. This restriction only applies to the primary font name as
+ presented to the users.
+ .
+ 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+ Software shall not be used to promote, endorse or advertise any
+ Modified Version, except to acknowledge the contribution(s) of the
+ Copyright Holder(s) and the Author(s) or with their explicit written
+ permission.
+ .
+ 5) The Font Software, modified or unmodified, in part or in whole,
+ must be distributed entirely under this license, and must not be
+ distributed under any other license. The requirement for fonts to
+ remain under this license does not apply to any document created
+ using the Font Software.
+ .
+ TERMINATION
+ This license becomes null and void if any of the above conditions are
+ not met.
+ .
+ DISCLAIMER
+ THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+ OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+ COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+ DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE.
+
+License: OpenSSL
+ LICENSE ISSUES
+ ==============
+ .
+ The OpenSSL toolkit stays under a double license, i.e. both the conditions of
+ the OpenSSL License and the original SSLeay license apply to the toolkit.
+ See below for the actual license texts.
+ .
+ OpenSSL License
+ ---------------
+ .
+ ====================================================================
+ Copyright (c) 1998-2017 The OpenSSL Project. All rights reserved.
+ .
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ .
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ .
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+ .
+ 3. All advertising materials mentioning features or use of this
+ software must display the following acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ .
+ 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ endorse or promote products derived from this software without
+ prior written permission. For written permission, please contact
+ openssl-core@openssl.org.
+ .
+ 5. Products derived from this software may not be called "OpenSSL"
+ nor may "OpenSSL" appear in their names without prior written
+ permission of the OpenSSL Project.
+ .
+ 6. Redistributions of any form whatsoever must retain the following
+ acknowledgment:
+ "This product includes software developed by the OpenSSL Project
+ for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ .
+ THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ OF THE POSSIBILITY OF SUCH DAMAGE.
+ ====================================================================
+ .
+ This product includes cryptographic software written by Eric Young
+ (eay@cryptsoft.com). This product includes software written by Tim
+ Hudson (tjh@cryptsoft.com).
+ .
+ Original SSLeay License
+ -----------------------
+ .
+ Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ All rights reserved.
+ .
+ This package is an SSL implementation written
+ by Eric Young (eay@cryptsoft.com).
+ The implementation was written so as to conform with Netscapes SSL.
+ .
+ This library is free for commercial and non-commercial use as long as
+ the following conditions are aheared to. The following conditions
+ apply to all code found in this distribution, be it the RC4, RSA,
+ lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ included with this distribution is covered by the same copyright terms
+ except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ .
+ Copyright remains Eric Young's, and as such any Copyright notices in
+ the code are not to be removed.
+ If this package is used in a product, Eric Young should be given attribution
+ as the author of the parts of the library used.
+ This can be in the form of a textual message at program startup or
+ in documentation (online or textual) provided with the package.
+ .
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+ 1. Redistributions of source code must retain the copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. All advertising materials mentioning features or use of this software
+ must display the following acknowledgement:
+ "This product includes cryptographic software written by
+ Eric Young (eay@cryptsoft.com)"
+ The word 'cryptographic' can be left out if the rouines from the library
+ being used are not cryptographic related :-).
+ 4. If you include any Windows specific code (or a derivative thereof) from
+ the apps directory (application code) you must include an acknowledgement:
+ "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ .
+ THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+ .
+ The licence and distribution terms for any publically available version or
+ derivative of this code cannot be changed. i.e. this code cannot simply be
+ copied and put under another distribution licence
+ [including the GNU Public Licence.]
+
+License: RSA-MD
+ License to copy and use this software is granted provided that it is
+ identified as the "RSA Data Security, Inc. MD5 Message-Digest Algorithm"
+ in all material mentioning or referencing this software or this function.
+ .
+ License is also granted to make and use derivative works provided that such
+ works are identified as "derived from the RSA Data Security, Inc. MD5
+ Message-Digest Algorithm" in all material mentioning or referencing the
+ derived work.
+ .
+ RSA Data Security, Inc. makes no representations concerning either the
+ merchantability of this software or the suitability of this software for
+ any particular purpose. It is provided "as is" without express or implied
+ warranty of any kind.
+ .
+ These notices must be retained in any copies of any part of this
+ documentation and/or software.
+
+License: Zlib
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+ .
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+ .
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
diff --git a/LICENSE.md b/LICENSE.md
deleted file mode 100644
index 83dc84e041..0000000000
--- a/LICENSE.md
+++ /dev/null
@@ -1,28 +0,0 @@
- 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.
-
-************************************************************************
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000000..0b5b0c341f
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,22 @@
+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.
+
+-- Godot Engine <https://godotengine.org>
diff --git a/LOGO_LICENSE.md b/LOGO_LICENSE.md
index 2858712f18..b357c49664 100644
--- a/LOGO_LICENSE.md
+++ b/LOGO_LICENSE.md
@@ -1,2 +1,3 @@
-Godot Logo (c) Andrea Calabró, distributed under the terms of the CC By License:
-https://creativecommons.org/licenses/by/3.0/legalcode \ No newline at end of file
+Godot Logo (C) Andrea Calabró
+Distributed under the terms of the Creative Commons Attribution License
+version 3.0 (CC-BY 3.0) <https://creativecommons.org/licenses/by/3.0/legalcode>.
diff --git a/README.md b/README.md
index 701982da11..0c4ab6498a 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[![GODOT](/logo.png)](https://godotengine.org)
+[![Godot Engine logo](/logo.png)](https://godotengine.org)
## Godot Engine
diff --git a/SConstruct b/SConstruct
index c07baa2709..11cd95464d 100644
--- a/SConstruct
+++ b/SConstruct
@@ -145,7 +145,7 @@ opts.Add('extra_suffix', "Custom extra suffix added to the base filename of all
opts.Add('unix_global_settings_path', "UNIX-specific path to system-wide settings. Currently only used for templates", '')
opts.Add('verbose', "Enable verbose output for the compilation (yes/no)", 'yes')
opts.Add('vsproj', "Generate Visual Studio Project. (yes/no)", 'no')
-opts.Add('warnings', "Enable showing warnings during the compilation (yes/no)", 'yes')
+opts.Add('warnings', "Set the level of warnings emitted during compilation (extra/all/moderate/no)", 'all')
# Thirdparty libraries
opts.Add('builtin_enet', "Use the builtin enet library (yes/no)", 'yes')
@@ -272,16 +272,28 @@ if selected_platform in platform_list:
# must happen after the flags, so when flags are used by configure, stuff happens (ie, ssl on x11)
detect.configure(env)
- # TODO: Add support to specify different levels of warning, e.g. only critical/significant, instead of on/off
- if (env["warnings"] == "yes"):
- if (os.name == "nt" and os.getenv("VSINSTALLDIR")): # MSVC, needs to stand out of course
- pass# env.Append(CCFLAGS=['/W2'])
- else: # Rest of the world
- env.Append(CCFLAGS=['-Wall'])
- else:
- if (os.name == "nt" and os.getenv("VSINSTALLDIR")): # MSVC
+ if (env["warnings"] == 'yes'):
+ print("WARNING: warnings=yes is deprecated; assuming warnings=all")
+
+ if (os.name == "nt" and os.getenv("VSINSTALLDIR")): # MSVC, needs to stand out of course
+ disable_nonessential_warnings = ['/wd4267', '/wd4244', '/wd4305', '/wd4800'] # Truncations, narrowing conversions...
+ if (env["warnings"] == 'extra'):
+ env.Append(CCFLAGS=['/Wall']) # Implies /W4
+ elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
+ env.Append(CCFLAGS=['/W3'] + disable_nonessential_warnings)
+ elif (env["warnings"] == 'moderate'):
+ # C4244 shouldn't be needed here being a level-3 warning, but it is
+ env.Append(CCFLAGS=['/W2'] + disable_nonessential_warnings)
+ else: # 'no'
env.Append(CCFLAGS=['/w'])
- else: # Rest of the world
+ else: # Rest of the world
+ if (env["warnings"] == 'extra'):
+ env.Append(CCFLAGS=['-Wall', '-Wextra'])
+ elif (env["warnings"] == 'all' or env["warnings"] == 'yes'):
+ env.Append(CCFLAGS=['-Wall'])
+ elif (env["warnings"] == 'moderate'):
+ env.Append(CCFLAGS=['-Wall', '-Wno-unused'])
+ else: # 'no'
env.Append(CCFLAGS=['-w'])
#env['platform_libsuffix'] = env['LIBSUFFIX']
diff --git a/core/SCsub b/core/SCsub
index fd3f57dd7c..da2403f1d3 100644
--- a/core/SCsub
+++ b/core/SCsub
@@ -83,6 +83,25 @@ thirdparty_minizip_sources = [
thirdparty_minizip_sources = [thirdparty_minizip_dir + file for file in thirdparty_minizip_sources]
env.add_source_files(env.core_sources, thirdparty_minizip_sources)
+thirdparty_zstd_dir = "#thirdparty/zstd/"
+thirdparty_zstd_sources = [
+ "common/entropy_common.c",
+ "common/error_private.c",
+ "common/fse_decompress.c",
+ "common/pool.c",
+ "common/threading.c",
+ "common/xxhash.c",
+ "common/zstd_common.c",
+ "compress/fse_compress.c",
+ "compress/huf_compress.c",
+ "compress/zstd_compress.c",
+ "compress/zstdmt_compress.c",
+ "decompress/huf_decompress.c",
+ "decompress/zstd_decompress.c",
+]
+thirdparty_zstd_sources = [thirdparty_zstd_dir + file for file in thirdparty_zstd_sources]
+env.add_source_files(env.core_sources, thirdparty_zstd_sources)
+
# Godot's own sources
env.add_source_files(env.core_sources, "*.cpp")
@@ -104,5 +123,5 @@ SConscript('helper/SCsub')
# Build it all as a library
lib = env.Library("core", env.core_sources)
env.Prepend(LIBS=[lib])
-
+env.Append(CPPPATH=["#thirdparty/zstd", "#thirdparty/zstd/common"])
Export('env')
diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp
index 7a03ceb64c..095f058ed9 100644
--- a/core/bind/core_bind.cpp
+++ b/core/bind/core_bind.cpp
@@ -31,6 +31,7 @@
#include "core/global_config.h"
#include "geometry.h"
+#include "io/file_access_compressed.h"
#include "io/file_access_encrypted.h"
#include "io/marshalls.h"
#include "os/keyboard.h"
@@ -505,7 +506,7 @@ int _OS::get_dynamic_memory_usage() const {
return OS::get_singleton()->get_dynamic_memory_usage();
}
-void _OS::set_icon(const Image &p_icon) {
+void _OS::set_icon(const Ref<Image> &p_icon) {
OS::get_singleton()->set_icon(p_icon);
}
@@ -1395,6 +1396,24 @@ Error _File::open_encrypted_pass(const String &p_path, int p_mode_flags, const S
return OK;
}
+Error _File::open_compressed(const String &p_path, int p_mode_flags, int p_compress_mode) {
+
+ FileAccessCompressed *fac = memnew(FileAccessCompressed);
+ Error err = OK;
+
+ fac->configure("GCPF", (Compression::Mode)p_compress_mode);
+
+ err = fac->_open(p_path, p_mode_flags);
+
+ if (err) {
+ memdelete(fac);
+ return err;
+ }
+
+ f = fac;
+ return OK;
+}
+
Error _File::open(const String &p_path, int p_mode_flags) {
close();
@@ -1700,6 +1719,7 @@ void _File::_bind_methods() {
ClassDB::bind_method(D_METHOD("open_encrypted", "path", "mode_flags", "key"), &_File::open_encrypted);
ClassDB::bind_method(D_METHOD("open_encrypted_with_pass", "path", "mode_flags", "pass"), &_File::open_encrypted_pass);
+ ClassDB::bind_method(D_METHOD("open_compressed", "path", "mode_flags", "compression_mode"), &_File::open_compressed, DEFVAL(0));
ClassDB::bind_method(D_METHOD("open", "path", "flags"), &_File::open);
ClassDB::bind_method(D_METHOD("close"), &_File::close);
@@ -1749,6 +1769,10 @@ void _File::_bind_methods() {
BIND_CONSTANT(WRITE);
BIND_CONSTANT(READ_WRITE);
BIND_CONSTANT(WRITE_READ);
+
+ BIND_CONSTANT(COMPRESSION_FASTLZ);
+ BIND_CONSTANT(COMPRESSION_DEFLATE);
+ BIND_CONSTANT(COMPRESSION_ZSTD);
}
_File::_File() {
@@ -2532,6 +2556,10 @@ Dictionary _Engine::get_version_info() const {
return Engine::get_singleton()->get_version_info();
}
+bool _Engine::is_in_fixed_frame() const {
+ return Engine::get_singleton()->is_in_fixed_frame();
+}
+
void _Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_iterations_per_second", "iterations_per_second"), &_Engine::set_iterations_per_second);
@@ -2550,6 +2578,8 @@ void _Engine::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_main_loop:MainLoop"), &_Engine::get_main_loop);
ClassDB::bind_method(D_METHOD("get_version_info"), &_Engine::get_version_info);
+
+ ClassDB::bind_method(D_METHOD("is_in_fixed_frame"), &_Engine::is_in_fixed_frame);
}
_Engine *_Engine::singleton = NULL;
diff --git a/core/bind/core_bind.h b/core/bind/core_bind.h
index 222339bce1..87d84c0732 100644
--- a/core/bind/core_bind.h
+++ b/core/bind/core_bind.h
@@ -30,6 +30,8 @@
#ifndef CORE_BIND_H
#define CORE_BIND_H
+#include "image.h"
+#include "io/compression.h"
#include "io/resource_loader.h"
#include "io/resource_saver.h"
#include "os/dir_access.h"
@@ -226,7 +228,7 @@ public:
void set_use_file_access_save_and_swap(bool p_enable);
- void set_icon(const Image &p_icon);
+ void set_icon(const Ref<Image> &p_icon);
int get_exit_code() const;
void set_exit_code(int p_code);
@@ -365,8 +367,15 @@ public:
WRITE_READ = 7,
};
+ enum CompressionMode {
+ COMPRESSION_FASTLZ = Compression::MODE_FASTLZ,
+ COMPRESSION_DEFLATE = Compression::MODE_DEFLATE,
+ COMPRESSION_ZSTD = Compression::MODE_ZSTD
+ };
+
Error open_encrypted(const String &p_path, int p_mode_flags, const Vector<uint8_t> &p_key);
Error open_encrypted_pass(const String &p_path, int p_mode_flags, const String &p_pass);
+ Error open_compressed(const String &p_path, int p_mode_flags, int p_compress_mode = 0);
Error open(const String &p_path, int p_mode_flags); ///< open a file
void close(); ///< close a file
@@ -633,6 +642,8 @@ public:
Dictionary get_version_info() const;
+ bool is_in_fixed_frame() const;
+
_Engine();
};
diff --git a/core/color.h b/core/color.h
index 46386fac64..c83dcda4b4 100644
--- a/core/color.h
+++ b/core/color.h
@@ -83,6 +83,40 @@ struct Color {
return res;
}
+ _FORCE_INLINE_ uint32_t to_rgbe9995() const {
+
+ const float pow2to9 = 512.0f;
+ const float B = 15.0f;
+ //const float Emax = 31.0f;
+ const float N = 9.0f;
+
+ float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
+
+ float cRed = MAX(0.0f, MIN(sharedexp, r));
+ float cGreen = MAX(0.0f, MIN(sharedexp, g));
+ float cBlue = MAX(0.0f, MIN(sharedexp, b));
+
+ float cMax = MAX(cRed, MAX(cGreen, cBlue));
+
+ // expp = MAX(-B - 1, log2(maxc)) + 1 + B
+
+ float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
+
+ float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
+
+ float exps = expp + 1.0f;
+
+ if (0.0 <= sMax && sMax < pow2to9) {
+ exps = expp;
+ }
+
+ float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+ float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+ float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+
+ return (uint32_t(Math::fast_ftoi(sRed)) & 0x1FF) | ((uint32_t(Math::fast_ftoi(sGreen)) & 0x1FF) << 9) | ((uint32_t(Math::fast_ftoi(sBlue)) & 0x1FF) << 18) | ((uint32_t(Math::fast_ftoi(exps)) & 0x1F) << 27);
+ }
+
_FORCE_INLINE_ Color blend(const Color &p_over) const {
Color res;
diff --git a/core/command_queue_mt.h b/core/command_queue_mt.h
index bae8cf7fca..2e0c478108 100644
--- a/core/command_queue_mt.h
+++ b/core/command_queue_mt.h
@@ -170,6 +170,63 @@ class CommandQueueMT {
virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8); }
};
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
+ struct Command9 : public CommandBase {
+
+ T *instance;
+ M method;
+ typename GetSimpleTypeT<P1>::type_t p1;
+ typename GetSimpleTypeT<P2>::type_t p2;
+ typename GetSimpleTypeT<P3>::type_t p3;
+ typename GetSimpleTypeT<P4>::type_t p4;
+ typename GetSimpleTypeT<P5>::type_t p5;
+ typename GetSimpleTypeT<P6>::type_t p6;
+ typename GetSimpleTypeT<P7>::type_t p7;
+ typename GetSimpleTypeT<P8>::type_t p8;
+ typename GetSimpleTypeT<P9>::type_t p9;
+
+ virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9); }
+ };
+
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
+ struct Command10 : public CommandBase {
+
+ T *instance;
+ M method;
+ typename GetSimpleTypeT<P1>::type_t p1;
+ typename GetSimpleTypeT<P2>::type_t p2;
+ typename GetSimpleTypeT<P3>::type_t p3;
+ typename GetSimpleTypeT<P4>::type_t p4;
+ typename GetSimpleTypeT<P5>::type_t p5;
+ typename GetSimpleTypeT<P6>::type_t p6;
+ typename GetSimpleTypeT<P7>::type_t p7;
+ typename GetSimpleTypeT<P8>::type_t p8;
+ typename GetSimpleTypeT<P9>::type_t p9;
+ typename GetSimpleTypeT<P10>::type_t p10;
+
+ virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); }
+ };
+
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>
+ struct Command11 : public CommandBase {
+
+ T *instance;
+ M method;
+ typename GetSimpleTypeT<P1>::type_t p1;
+ typename GetSimpleTypeT<P2>::type_t p2;
+ typename GetSimpleTypeT<P3>::type_t p3;
+ typename GetSimpleTypeT<P4>::type_t p4;
+ typename GetSimpleTypeT<P5>::type_t p5;
+ typename GetSimpleTypeT<P6>::type_t p6;
+ typename GetSimpleTypeT<P7>::type_t p7;
+ typename GetSimpleTypeT<P8>::type_t p8;
+ typename GetSimpleTypeT<P9>::type_t p9;
+ typename GetSimpleTypeT<P10>::type_t p10;
+ typename GetSimpleTypeT<P11>::type_t p11;
+
+ virtual void call() { (instance->*method)(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); }
+ };
+
/* comands that return */
template <class T, class M, class R>
@@ -779,6 +836,76 @@ public:
if (sync) sync->post();
}
+
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
+ void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9) {
+
+ Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> *cmd = allocate_and_lock<Command9<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9> >();
+
+ cmd->instance = p_instance;
+ cmd->method = p_method;
+ cmd->p1 = p1;
+ cmd->p2 = p2;
+ cmd->p3 = p3;
+ cmd->p4 = p4;
+ cmd->p5 = p5;
+ cmd->p6 = p6;
+ cmd->p7 = p7;
+ cmd->p8 = p8;
+ cmd->p9 = p9;
+
+ unlock();
+
+ if (sync) sync->post();
+ }
+
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10>
+ void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10) {
+
+ Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> *cmd = allocate_and_lock<Command10<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10> >();
+
+ cmd->instance = p_instance;
+ cmd->method = p_method;
+ cmd->p1 = p1;
+ cmd->p2 = p2;
+ cmd->p3 = p3;
+ cmd->p4 = p4;
+ cmd->p5 = p5;
+ cmd->p6 = p6;
+ cmd->p7 = p7;
+ cmd->p8 = p8;
+ cmd->p9 = p9;
+ cmd->p10 = p10;
+
+ unlock();
+
+ if (sync) sync->post();
+ }
+
+ template <class T, class M, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9, class P10, class P11>
+ void push(T *p_instance, M p_method, P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8, P9 p9, P10 p10, P11 p11) {
+
+ Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> *cmd = allocate_and_lock<Command11<T, M, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11> >();
+
+ cmd->instance = p_instance;
+ cmd->method = p_method;
+ cmd->p1 = p1;
+ cmd->p2 = p2;
+ cmd->p3 = p3;
+ cmd->p4 = p4;
+ cmd->p5 = p5;
+ cmd->p6 = p6;
+ cmd->p7 = p7;
+ cmd->p8 = p8;
+ cmd->p9 = p9;
+ cmd->p10 = p10;
+ cmd->p11 = p11;
+
+ unlock();
+
+ if (sync) sync->post();
+ }
+
/*** PUSH AND RET COMMANDS ***/
template <class T, class M, class R>
diff --git a/core/dvector.h b/core/dvector.h
index 2e951b9661..4584a300f9 100644
--- a/core/dvector.h
+++ b/core/dvector.h
@@ -92,6 +92,7 @@ class PoolVector {
// ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all
+ // Refcount should not be zero, otherwise it's a misuse of COW
if (alloc->refcount.get() == 1)
return; //nothing to do
@@ -216,7 +217,12 @@ class PoolVector {
{
int cur_elements = alloc->size / sizeof(T);
- Write w = write();
+
+ // Don't use write() here because it could otherwise provoke COW,
+ // which is not desirable here because we are destroying the last reference anyways
+ Write w;
+ // Reference to still prevent other threads from touching the alloc
+ w._ref(alloc);
for (int i = 0; i < cur_elements; i++) {
diff --git a/core/global_config.cpp b/core/global_config.cpp
index 81b923f01e..ba0a7f3e31 100644
--- a/core/global_config.cpp
+++ b/core/global_config.cpp
@@ -39,6 +39,8 @@
#include "os/os.h"
#include "variant_parser.h"
+#include <zlib.h>
+
#define FORMAT_VERSION 3
GlobalConfig *GlobalConfig::singleton = NULL;
@@ -846,10 +848,8 @@ GlobalConfig::GlobalConfig() {
registering_order = true;
Array va;
- InputEvent key;
- key.type = InputEvent::KEY;
- InputEvent joyb;
- joyb.type = InputEvent::JOYPAD_BUTTON;
+ Ref<InputEventKey> key;
+ Ref<InputEventJoypadButton> joyb;
GLOBAL_DEF("application/name", "");
GLOBAL_DEF("application/main_scene", "");
@@ -858,87 +858,106 @@ GlobalConfig::GlobalConfig() {
GLOBAL_DEF("application/disable_stderr", false);
GLOBAL_DEF("application/use_shared_user_dir", true);
- key.key.scancode = KEY_RETURN;
+ key.instance();
+ key->set_scancode(KEY_RETURN);
va.push_back(key);
- key.key.scancode = KEY_ENTER;
+ key.instance();
+ key->set_scancode(KEY_ENTER);
va.push_back(key);
- key.key.scancode = KEY_SPACE;
+ key.instance();
+ key->set_scancode(KEY_SPACE);
va.push_back(key);
- joyb.joy_button.button_index = JOY_BUTTON_0;
+ joyb.instance();
+ joyb->set_button_index(JOY_BUTTON_0);
va.push_back(joyb);
GLOBAL_DEF("input/ui_accept", va);
input_presets.push_back("input/ui_accept");
va = Array();
- key.key.scancode = KEY_SPACE;
+ key.instance();
+ key->set_scancode(KEY_SPACE);
va.push_back(key);
- joyb.joy_button.button_index = JOY_BUTTON_3;
+ joyb.instance();
+ joyb->set_button_index(JOY_BUTTON_3);
va.push_back(joyb);
GLOBAL_DEF("input/ui_select", va);
input_presets.push_back("input/ui_select");
va = Array();
- key.key.scancode = KEY_ESCAPE;
+ key.instance();
+ key->set_scancode(KEY_ESCAPE);
va.push_back(key);
- joyb.joy_button.button_index = JOY_BUTTON_1;
+ joyb.instance();
+ joyb->set_button_index(JOY_BUTTON_1);
va.push_back(joyb);
GLOBAL_DEF("input/ui_cancel", va);
input_presets.push_back("input/ui_cancel");
va = Array();
- key.key.scancode = KEY_TAB;
+ key.instance();
+ key->set_scancode(KEY_TAB);
va.push_back(key);
GLOBAL_DEF("input/ui_focus_next", va);
input_presets.push_back("input/ui_focus_next");
va = Array();
- key.key.scancode = KEY_TAB;
- key.key.mod.shift = true;
+ key.instance();
+ key->set_scancode(KEY_TAB);
+ key->set_shift(true);
va.push_back(key);
GLOBAL_DEF("input/ui_focus_prev", va);
input_presets.push_back("input/ui_focus_prev");
- key.key.mod.shift = false;
va = Array();
- key.key.scancode = KEY_LEFT;
+ key.instance();
+ key->set_scancode(KEY_LEFT);
va.push_back(key);
- joyb.joy_button.button_index = JOY_DPAD_LEFT;
+ joyb.instance();
+ joyb->set_button_index(JOY_DPAD_LEFT);
va.push_back(joyb);
GLOBAL_DEF("input/ui_left", va);
input_presets.push_back("input/ui_left");
va = Array();
- key.key.scancode = KEY_RIGHT;
+ key.instance();
+ key->set_scancode(KEY_RIGHT);
va.push_back(key);
- joyb.joy_button.button_index = JOY_DPAD_RIGHT;
+ joyb.instance();
+ joyb->set_button_index(JOY_DPAD_RIGHT);
va.push_back(joyb);
GLOBAL_DEF("input/ui_right", va);
input_presets.push_back("input/ui_right");
va = Array();
- key.key.scancode = KEY_UP;
+ key.instance();
+ key->set_scancode(KEY_UP);
va.push_back(key);
- joyb.joy_button.button_index = JOY_DPAD_UP;
+ joyb.instance();
+ joyb->set_button_index(JOY_DPAD_UP);
va.push_back(joyb);
GLOBAL_DEF("input/ui_up", va);
input_presets.push_back("input/ui_up");
va = Array();
- key.key.scancode = KEY_DOWN;
+ key.instance();
+ key->set_scancode(KEY_DOWN);
va.push_back(key);
- joyb.joy_button.button_index = JOY_DPAD_DOWN;
+ joyb.instance();
+ joyb->set_button_index(JOY_DPAD_DOWN);
va.push_back(joyb);
GLOBAL_DEF("input/ui_down", va);
input_presets.push_back("input/ui_down");
va = Array();
- key.key.scancode = KEY_PAGEUP;
+ key.instance();
+ key->set_scancode(KEY_PAGEUP);
va.push_back(key);
GLOBAL_DEF("input/ui_page_up", va);
input_presets.push_back("input/ui_page_up");
va = Array();
- key.key.scancode = KEY_PAGEDOWN;
+ key.instance();
+ key->set_scancode(KEY_PAGEDOWN);
va.push_back(key);
GLOBAL_DEF("input/ui_page_down", va);
input_presets.push_back("input/ui_page_down");
@@ -950,6 +969,12 @@ GlobalConfig::GlobalConfig() {
custom_prop_info["physics/2d/thread_model"] = PropertyInfo(Variant::INT, "physics/2d/thread_model", PROPERTY_HINT_ENUM, "Single-Unsafe,Single-Safe,Multi-Threaded");
GLOBAL_DEF("debug/profiler/max_functions", 16384);
+
+ GLOBAL_DEF("compression/zstd/compression_level", 3);
+ custom_prop_info["compression/zstd/compression_level"] = PropertyInfo(Variant::INT, "compression/zstd/compression_level", PROPERTY_HINT_RANGE, "1,22,1");
+ GLOBAL_DEF("compression/zlib/compression_level", Z_DEFAULT_COMPRESSION);
+ custom_prop_info["compression/zlib/compression_level"] = PropertyInfo(Variant::INT, "compression/zlib/compression_level", PROPERTY_HINT_RANGE, "-1,9,1");
+
using_datapack = false;
}
diff --git a/core/global_constants.cpp b/core/global_constants.cpp
index 9bc98c5ad7..4f535fb05e 100644
--- a/core/global_constants.cpp
+++ b/core/global_constants.cpp
@@ -30,6 +30,7 @@
#include "global_constants.h"
#include "object.h"
+#include "os/input_event.h"
#include "os/keyboard.h"
#include "variant.h"
@@ -506,22 +507,20 @@ static _GlobalConstant _global_constants[] = {
{ "TYPE_TRANSFORM2D", Variant::TRANSFORM2D },
{ "TYPE_PLANE", Variant::PLANE },
{ "TYPE_QUAT", Variant::QUAT }, // 10
- { "TYPE_RECT3", Variant::RECT3 }, //sorry naming convention fail :( not like it's used often
+ { "TYPE_RECT3", Variant::RECT3 },
{ "TYPE_BASIS", Variant::BASIS },
{ "TYPE_TRANSFORM", Variant::TRANSFORM },
{ "TYPE_COLOR", Variant::COLOR },
- { "TYPE_IMAGE", Variant::IMAGE }, // 15
- { "TYPE_NODE_PATH", Variant::NODE_PATH },
+ { "TYPE_NODE_PATH", Variant::NODE_PATH }, // 15
{ "TYPE_RID", Variant::_RID },
{ "TYPE_OBJECT", Variant::OBJECT },
- { "TYPE_INPUT_EVENT", Variant::INPUT_EVENT },
{ "TYPE_DICTIONARY", Variant::DICTIONARY }, // 20
{ "TYPE_ARRAY", Variant::ARRAY },
{ "TYPE_RAW_ARRAY", Variant::POOL_BYTE_ARRAY },
{ "TYPE_INT_ARRAY", Variant::POOL_INT_ARRAY },
{ "TYPE_REAL_ARRAY", Variant::POOL_REAL_ARRAY },
- { "TYPE_STRING_ARRAY", Variant::POOL_STRING_ARRAY }, // 25
- { "TYPE_VECTOR2_ARRAY", Variant::POOL_VECTOR2_ARRAY },
+ { "TYPE_STRING_ARRAY", Variant::POOL_STRING_ARRAY },
+ { "TYPE_VECTOR2_ARRAY", Variant::POOL_VECTOR2_ARRAY }, // 25
{ "TYPE_VECTOR3_ARRAY", Variant::POOL_VECTOR3_ARRAY },
{ "TYPE_COLOR_ARRAY", Variant::POOL_COLOR_ARRAY },
{ "TYPE_MAX", Variant::VARIANT_MAX },
diff --git a/core/helper/math_fieldwise.cpp b/core/helper/math_fieldwise.cpp
index 2f176fb9bf..5545c2d642 100644
--- a/core/helper/math_fieldwise.cpp
+++ b/core/helper/math_fieldwise.cpp
@@ -63,8 +63,8 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
SETUP_TYPE(Rect2)
- /**/ TRY_TRANSFER_FIELD("x", pos.x)
- else TRY_TRANSFER_FIELD("y", pos.y)
+ /**/ TRY_TRANSFER_FIELD("x", position.x)
+ else TRY_TRANSFER_FIELD("y", position.y)
else TRY_TRANSFER_FIELD("w", size.x)
else TRY_TRANSFER_FIELD("h", size.y)
@@ -110,9 +110,9 @@ Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const
SETUP_TYPE(Rect3)
- /**/ TRY_TRANSFER_FIELD("px", pos.x)
- else TRY_TRANSFER_FIELD("py", pos.y)
- else TRY_TRANSFER_FIELD("pz", pos.z)
+ /**/ TRY_TRANSFER_FIELD("px", position.x)
+ else TRY_TRANSFER_FIELD("py", position.y)
+ else TRY_TRANSFER_FIELD("pz", position.z)
else TRY_TRANSFER_FIELD("sx", size.x)
else TRY_TRANSFER_FIELD("sy", size.y)
else TRY_TRANSFER_FIELD("sz", size.z)
diff --git a/core/image.cpp b/core/image.cpp
index b81d92fa33..ec21260b19 100644
--- a/core/image.cpp
+++ b/core/image.cpp
@@ -45,7 +45,6 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
"RedGreen",
"RGB8",
"RGBA8",
- "RGB565", //16 bit
"RGBA4444",
"RGBA5551",
"RFloat", //float
@@ -56,11 +55,12 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
"RGHalf",
"RGBHalf",
"RGBAHalf",
- "DXT1", //s3tc
- "DXT3",
- "DXT5",
- "ATI1",
- "ATI2",
+ "RGBE9995",
+ "DXT1 RGB8", //s3tc
+ "DXT3 RGBA8",
+ "DXT5 RGBA8",
+ "RGTC Red8",
+ "RGTC RedGreen8",
"BPTC_RGBA",
"BPTC_RGBF",
"BPTC_RGBFU",
@@ -81,21 +81,21 @@ const char *Image::format_names[Image::FORMAT_MAX] = {
SavePNGFunc Image::save_png_func = NULL;
-void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_dst, const uint8_t *p_src) {
+void Image::_put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel) {
uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
for (uint32_t i = 0; i < p_pixelsize; i++) {
- p_dst[ofs + i] = p_src[i];
+ p_data[ofs + i] = p_pixel[i];
}
}
-void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_src, uint8_t *p_dst) {
+void Image::_get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel) {
uint32_t ofs = (p_y * width + p_x) * p_pixelsize;
for (uint32_t i = 0; i < p_pixelsize; i++) {
- p_dst[i] = p_src[ofs + i];
+ p_pixel[i] = p_data[ofs + i];
}
}
@@ -110,8 +110,6 @@ int Image::get_format_pixel_size(Format p_format) {
case FORMAT_RG8: return 2;
case FORMAT_RGB8: return 3;
case FORMAT_RGBA8: return 4;
- case FORMAT_RGB565:
- return 2; //16 bit
case FORMAT_RGBA4444: return 2;
case FORMAT_RGBA5551: return 2;
case FORMAT_RF:
@@ -122,17 +120,18 @@ int Image::get_format_pixel_size(Format p_format) {
case FORMAT_RH:
return 2; //half float
case FORMAT_RGH: return 4;
- case FORMAT_RGBH: return 8;
- case FORMAT_RGBAH: return 12;
+ case FORMAT_RGBH: return 6;
+ case FORMAT_RGBAH: return 8;
+ case FORMAT_RGBE9995: return 4;
case FORMAT_DXT1:
return 1; //s3tc bc1
case FORMAT_DXT3:
return 1; //bc2
case FORMAT_DXT5:
return 1; //bc3
- case FORMAT_ATI1:
+ case FORMAT_RGTC_R:
return 1; //bc4
- case FORMAT_ATI2:
+ case FORMAT_RGTC_RG:
return 1; //bc5
case FORMAT_BPTC_RGBA:
return 1; //btpc bc6h
@@ -168,8 +167,8 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
case FORMAT_DXT1: //s3tc bc1
case FORMAT_DXT3: //bc2
case FORMAT_DXT5: //bc3
- case FORMAT_ATI1: //bc4
- case FORMAT_ATI2: { //bc5 case case FORMAT_DXT1:
+ case FORMAT_RGTC_R: //bc4
+ case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1:
r_w = 4;
r_h = 4;
@@ -220,7 +219,7 @@ void Image::get_format_min_pixel_size(Format p_format, int &r_w, int &r_h) {
int Image::get_format_pixel_rshift(Format p_format) {
- if (p_format == FORMAT_DXT1 || p_format == FORMAT_ATI1 || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
+ if (p_format == FORMAT_DXT1 || p_format == FORMAT_RGTC_R || p_format == FORMAT_PVRTC4 || p_format == FORMAT_PVRTC4A || p_format == FORMAT_ETC || p_format == FORMAT_ETC2_R11 || p_format == FORMAT_ETC2_R11S || p_format == FORMAT_ETC2_RGB8 || p_format == FORMAT_ETC2_RGB8A1)
return 1;
else if (p_format == FORMAT_PVRTC2 || p_format == FORMAT_PVRTC2A)
return 2;
@@ -228,6 +227,54 @@ int Image::get_format_pixel_rshift(Format p_format) {
return 0;
}
+int Image::get_format_block_size(Format p_format) {
+
+ switch (p_format) {
+ case FORMAT_DXT1: //s3tc bc1
+ case FORMAT_DXT3: //bc2
+ case FORMAT_DXT5: //bc3
+ case FORMAT_RGTC_R: //bc4
+ case FORMAT_RGTC_RG: { //bc5 case case FORMAT_DXT1:
+
+ return 4;
+ } break;
+ case FORMAT_PVRTC2:
+ case FORMAT_PVRTC2A: {
+
+ return 4;
+ } break;
+ case FORMAT_PVRTC4A:
+ case FORMAT_PVRTC4: {
+
+ return 4;
+ } break;
+ case FORMAT_ETC: {
+
+ return 4;
+ } break;
+ case FORMAT_BPTC_RGBA:
+ case FORMAT_BPTC_RGBF:
+ case FORMAT_BPTC_RGBFU: {
+
+ return 4;
+ } break;
+ case FORMAT_ETC2_R11: //etc2
+ case FORMAT_ETC2_R11S: //signed: NOT srgb.
+ case FORMAT_ETC2_RG11:
+ case FORMAT_ETC2_RG11S:
+ case FORMAT_ETC2_RGB8:
+ case FORMAT_ETC2_RGBA8:
+ case FORMAT_ETC2_RGB8A1: {
+
+ return 4;
+ } break;
+ default: {
+ }
+ }
+
+ return 1;
+}
+
void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const {
int w = width;
@@ -236,11 +283,16 @@ void Image::_get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_widt
int pixel_size = get_format_pixel_size(format);
int pixel_rshift = get_format_pixel_rshift(format);
+ int block = get_format_block_size(format);
int minw, minh;
get_format_min_pixel_size(format, minw, minh);
for (int i = 0; i < p_mipmap; i++) {
- int s = w * h;
+ int bw = w % block != 0 ? w + (block - w % block) : w;
+ int bh = h % block != 0 ? h + (block - h % block) : h;
+
+ int s = bw * bh;
+
s *= pixel_size;
s >>= pixel_rshift;
ofs += s;
@@ -356,10 +408,35 @@ void Image::convert(Format p_new_format) {
if (p_new_format == format)
return;
- if (format >= FORMAT_RGB565 || p_new_format >= FORMAT_RGB565) {
+ if (format > FORMAT_RGBE9995 || p_new_format > FORMAT_RGBE9995) {
- ERR_EXPLAIN("Cannot convert to <-> from non byte formats.");
+ ERR_EXPLAIN("Cannot convert to <-> from compressed formats. Use compress() and decompress() instead.");
ERR_FAIL();
+
+ } else if (format > FORMAT_RGBA8 || p_new_format > FORMAT_RGBA8) {
+
+ //use put/set pixel which is slower but works with non byte formats
+ Image new_img(width, height, 0, p_new_format);
+ lock();
+ new_img.lock();
+
+ for (int i = 0; i < width; i++) {
+ for (int j = 0; j < height; j++) {
+
+ new_img.put_pixel(i, j, get_pixel(i, j));
+ }
+ }
+
+ unlock();
+ new_img.unlock();
+
+ if (has_mipmaps()) {
+ new_img.generate_mipmaps();
+ }
+
+ _copy_internals_from(new_img);
+
+ return;
}
Image new_img(width, height, 0, p_new_format);
@@ -415,7 +492,7 @@ void Image::convert(Format p_new_format) {
//mipmaps=false;
- *this = new_img;
+ _copy_internals_from(new_img);
if (gen_mipmaps)
generate_mipmaps();
@@ -611,14 +688,6 @@ void Image::resize_to_po2(bool p_square) {
resize(w, h);
}
-Image Image::resized(int p_width, int p_height, int p_interpolation) {
-
- Image ret = *this;
- ret.resize(p_width, p_height, (Interpolation)p_interpolation);
-
- return ret;
-};
-
void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (!_can_modify(format)) {
@@ -681,7 +750,7 @@ void Image::resize(int p_width, int p_height, Interpolation p_interpolation) {
if (mipmaps > 0)
dst.generate_mipmaps();
- *this = dst;
+ _copy_internals_from(dst);
}
void Image::crop(int p_width, int p_height) {
@@ -728,7 +797,7 @@ void Image::crop(int p_width, int p_height) {
if (mipmaps > 0)
dst.generate_mipmaps();
- *this = dst;
+ _copy_internals_from(dst);
}
void Image::flip_y() {
@@ -749,7 +818,7 @@ void Image::flip_y() {
uint8_t down[16];
uint32_t pixel_size = get_format_pixel_size(format);
- for (int y = 0; y < height; y++) {
+ for (int y = 0; y < height / 2; y++) {
for (int x = 0; x < width; x++) {
@@ -785,7 +854,7 @@ void Image::flip_x() {
for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
+ for (int x = 0; x < width / 2; x++) {
_get_pixelb(x, y, pixel_size, w.ptr(), up);
_get_pixelb(width - x - 1, y, pixel_size, w.ptr(), down);
@@ -809,12 +878,17 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
int pixsize = get_format_pixel_size(p_format);
int pixshift = get_format_pixel_rshift(p_format);
+ int block = get_format_block_size(p_format);
int minw, minh;
get_format_min_pixel_size(p_format, minw, minh);
while (true) {
- int s = w * h;
+ int bw = w % block != 0 ? w + (block - w % block) : w;
+ int bh = h % block != 0 ? h + (block - h % block) : h;
+
+ int s = bw * bh;
+
s *= pixsize;
s >>= pixshift;
@@ -842,7 +916,7 @@ int Image::_get_dst_image_size(int p_width, int p_height, Format p_format, int &
bool Image::_can_modify(Format p_format) const {
- return p_format < FORMAT_RGB565;
+ return p_format <= FORMAT_RGBE9995;
}
template <int CC>
@@ -1378,22 +1452,12 @@ Error Image::load(const String &p_path) {
return ImageLoader::load_image(p_path, this);
}
-Error Image::save_png(const String &p_path) {
+Error Image::save_png(const String &p_path) const {
if (save_png_func == NULL)
return ERR_UNAVAILABLE;
- return save_png_func(p_path, *this);
-}
-
-bool Image::operator==(const Image &p_image) const {
-
- if (data.size() == 0 && p_image.data.size() == 0)
- return true;
- PoolVector<uint8_t>::Read r = data.read();
- PoolVector<uint8_t>::Read pr = p_image.data.read();
-
- return r.ptr() == pr.ptr();
+ return save_png_func(p_path, Ref<Image>((Image *)this));
}
int Image::get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps) {
@@ -1409,368 +1473,33 @@ int Image::get_image_required_mipmaps(int p_width, int p_height, Format p_format
return mm;
}
-Error Image::_decompress_bc() {
-
- int wd = width, ht = height;
- if (wd % 4 != 0) {
- wd += 4 - (wd % 4);
- }
- if (ht % 4 != 0) {
- ht += 4 - (ht % 4);
- }
-
- int mm;
- int size = _get_dst_image_size(wd, ht, FORMAT_RGBA8, mm);
-
- PoolVector<uint8_t> newdata;
- newdata.resize(size);
-
- PoolVector<uint8_t>::Write w = newdata.write();
- PoolVector<uint8_t>::Read r = data.read();
-
- int rofs = 0;
- int wofs = 0;
-
- //print_line("width: "+itos(wd)+" height: "+itos(ht));
-
- for (int i = 0; i <= mm; i++) {
-
- switch (format) {
-
- case FORMAT_DXT1: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 8];
- uint16_t col_a = src[1];
- col_a <<= 8;
- col_a |= src[0];
- uint16_t col_b = src[3];
- col_b <<= 8;
- col_b |= src[2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- if (col_a < col_b) {
- //punchrough
- table[2][0] = (int(table[0][0]) + int(table[1][0])) >> 1;
- table[2][1] = (int(table[0][1]) + int(table[1][1])) >> 1;
- table[2][2] = (int(table[0][2]) + int(table[1][2])) >> 1;
- table[3][3] = 0; //premul alpha black
- } else {
- //gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
- }
-
- uint32_t block = src[4];
- block <<= 8;
- block |= src[5];
- block <<= 8;
- block |= src[6];
- block <<= 8;
- block |= src[7];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = table[block & 0x3][3];
- block >>= 2;
- }
- }
-
- rofs += len * 8;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- case FORMAT_DXT3: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 16];
-
- uint64_t ablock = src[1];
- ablock <<= 8;
- ablock |= src[0];
- ablock <<= 8;
- ablock |= src[3];
- ablock <<= 8;
- ablock |= src[2];
- ablock <<= 8;
- ablock |= src[5];
- ablock <<= 8;
- ablock |= src[4];
- ablock <<= 8;
- ablock |= src[7];
- ablock <<= 8;
- ablock |= src[6];
-
- uint16_t col_a = src[8 + 1];
- col_a <<= 8;
- col_a |= src[8 + 0];
- uint16_t col_b = src[8 + 3];
- col_b <<= 8;
- col_b |= src[8 + 2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
-
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- //always gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
-
- uint32_t block = src[4 + 8];
- block <<= 8;
- block |= src[5 + 8];
- block <<= 8;
- block |= src[6 + 8];
- block <<= 8;
- block |= src[7 + 8];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- uint8_t alpha = ablock & 0xf;
- alpha = int(alpha) * 255 / 15; //right way for alpha
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = alpha;
- block >>= 2;
- ablock >>= 4;
- }
- }
-
- rofs += len * 16;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- case FORMAT_DXT5: {
-
- int len = (wd * ht) / 16;
- uint8_t *dst = &w[wofs];
-
- uint32_t ofs_table[16];
- for (int x = 0; x < 4; x++) {
-
- for (int y = 0; y < 4; y++) {
-
- ofs_table[15 - (y * 4 + (3 - x))] = (x + y * wd) * 4;
- }
- }
-
- for (int j = 0; j < len; j++) {
-
- const uint8_t *src = &r[rofs + j * 16];
-
- uint8_t a_start = src[1];
- uint8_t a_end = src[0];
-
- uint64_t ablock = src[3];
- ablock <<= 8;
- ablock |= src[2];
- ablock <<= 8;
- ablock |= src[5];
- ablock <<= 8;
- ablock |= src[4];
- ablock <<= 8;
- ablock |= src[7];
- ablock <<= 8;
- ablock |= src[6];
-
- uint8_t atable[8];
-
- if (a_start > a_end) {
-
- atable[0] = (int(a_start) * 7 + int(a_end) * 0) / 7;
- atable[1] = (int(a_start) * 6 + int(a_end) * 1) / 7;
- atable[2] = (int(a_start) * 5 + int(a_end) * 2) / 7;
- atable[3] = (int(a_start) * 4 + int(a_end) * 3) / 7;
- atable[4] = (int(a_start) * 3 + int(a_end) * 4) / 7;
- atable[5] = (int(a_start) * 2 + int(a_end) * 5) / 7;
- atable[6] = (int(a_start) * 1 + int(a_end) * 6) / 7;
- atable[7] = (int(a_start) * 0 + int(a_end) * 7) / 7;
- } else {
-
- atable[0] = (int(a_start) * 5 + int(a_end) * 0) / 5;
- atable[1] = (int(a_start) * 4 + int(a_end) * 1) / 5;
- atable[2] = (int(a_start) * 3 + int(a_end) * 2) / 5;
- atable[3] = (int(a_start) * 2 + int(a_end) * 3) / 5;
- atable[4] = (int(a_start) * 1 + int(a_end) * 4) / 5;
- atable[5] = (int(a_start) * 0 + int(a_end) * 5) / 5;
- atable[6] = 0;
- atable[7] = 255;
- }
-
- uint16_t col_a = src[8 + 1];
- col_a <<= 8;
- col_a |= src[8 + 0];
- uint16_t col_b = src[8 + 3];
- col_b <<= 8;
- col_b |= src[8 + 2];
-
- uint8_t table[4][4] = {
- { uint8_t((col_a >> 11) << 3), uint8_t(((col_a >> 5) & 0x3f) << 2), uint8_t(((col_a)&0x1f) << 3), 255 },
- { uint8_t((col_b >> 11) << 3), uint8_t(((col_b >> 5) & 0x3f) << 2), uint8_t(((col_b)&0x1f) << 3), 255 },
-
- { 0, 0, 0, 255 },
- { 0, 0, 0, 255 }
- };
-
- //always gradient
- table[2][0] = (int(table[0][0]) * 2 + int(table[1][0])) / 3;
- table[2][1] = (int(table[0][1]) * 2 + int(table[1][1])) / 3;
- table[2][2] = (int(table[0][2]) * 2 + int(table[1][2])) / 3;
- table[3][0] = (int(table[0][0]) + int(table[1][0]) * 2) / 3;
- table[3][1] = (int(table[0][1]) + int(table[1][1]) * 2) / 3;
- table[3][2] = (int(table[0][2]) + int(table[1][2]) * 2) / 3;
-
- uint32_t block = src[4 + 8];
- block <<= 8;
- block |= src[5 + 8];
- block <<= 8;
- block |= src[6 + 8];
- block <<= 8;
- block |= src[7 + 8];
-
- int y = (j / (wd / 4)) * 4;
- int x = (j % (wd / 4)) * 4;
- int pixofs = (y * wd + x) * 4;
-
- for (int k = 0; k < 16; k++) {
- uint8_t alpha = ablock & 0x7;
- int idx = pixofs + ofs_table[k];
- dst[idx + 0] = table[block & 0x3][0];
- dst[idx + 1] = table[block & 0x3][1];
- dst[idx + 2] = table[block & 0x3][2];
- dst[idx + 3] = atable[alpha];
- block >>= 2;
- ablock >>= 3;
- }
- }
-
- rofs += len * 16;
- wofs += wd * ht * 4;
-
- wd /= 2;
- ht /= 2;
-
- } break;
- default: {}
- }
- }
-
- w = PoolVector<uint8_t>::Write();
- r = PoolVector<uint8_t>::Read();
-
- data = newdata;
- format = FORMAT_RGBA8;
- if (wd != width || ht != height) {
-
- SWAP(width, wd);
- SWAP(height, ht);
- crop(wd, ht);
- }
-
- return OK;
-}
-
bool Image::is_compressed() const {
- return format >= FORMAT_RGB565;
-}
-
-Image Image::decompressed() const {
-
- Image img = *this;
- img.decompress();
- return img;
+ return format > FORMAT_RGBE9995;
}
Error Image::decompress() {
- if (format >= FORMAT_DXT1 && format <= FORMAT_ATI2)
- _decompress_bc(); //_image_decompress_bc(this);
+ if (format >= FORMAT_DXT1 && format <= FORMAT_BPTC_RGBFU && _image_decompress_bc)
+ _image_decompress_bc(this);
else if (format >= FORMAT_PVRTC2 && format <= FORMAT_PVRTC4A && _image_decompress_pvrtc)
_image_decompress_pvrtc(this);
- else if (format == FORMAT_ETC && _image_decompress_etc)
- _image_decompress_etc(this);
- else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc)
+ else if (format == FORMAT_ETC && _image_decompress_etc1)
+ _image_decompress_etc1(this);
+ else if (format >= FORMAT_ETC2_R11 && format <= FORMAT_ETC2_RGB8A1 && _image_decompress_etc1)
_image_decompress_etc2(this);
else
return ERR_UNAVAILABLE;
return OK;
}
-Error Image::compress(CompressMode p_mode) {
+Error Image::compress(CompressMode p_mode, CompressSource p_source, float p_lossy_quality) {
switch (p_mode) {
- case COMPRESS_16BIT: {
-
- //ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
- //_image_compress_bc_func(this);
- } break;
case COMPRESS_S3TC: {
ERR_FAIL_COND_V(!_image_compress_bc_func, ERR_UNAVAILABLE);
- _image_compress_bc_func(this);
+ _image_compress_bc_func(this, p_source);
} break;
case COMPRESS_PVRTC2: {
@@ -1784,27 +1513,19 @@ Error Image::compress(CompressMode p_mode) {
} break;
case COMPRESS_ETC: {
- ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE);
- _image_compress_etc_func(this);
+ ERR_FAIL_COND_V(!_image_compress_etc1_func, ERR_UNAVAILABLE);
+ _image_compress_etc1_func(this, p_lossy_quality);
} break;
case COMPRESS_ETC2: {
- ERR_FAIL_COND_V(!_image_compress_etc_func, ERR_UNAVAILABLE);
- _image_compress_etc_func(this);
+ ERR_FAIL_COND_V(!_image_compress_etc2_func, ERR_UNAVAILABLE);
+ _image_compress_etc2_func(this, p_lossy_quality, p_source);
} break;
}
return OK;
}
-Image Image::compressed(int p_mode) {
-
- Image ret = *this;
- ret.compress((Image::CompressMode)p_mode);
-
- return ret;
-}
-
Image::Image(const char **p_xpm) {
width = 0;
@@ -1875,47 +1596,47 @@ Rect2 Image::get_used_rect() const {
return Rect2(minx, miny, maxx - minx + 1, maxy - miny + 1);
}
-Image Image::get_rect(const Rect2 &p_area) const {
-
- Image img(p_area.size.x, p_area.size.y, mipmaps, format);
- img.blit_rect(*this, p_area, Point2(0, 0));
+Ref<Image> Image::get_rect(const Rect2 &p_area) const {
+ Ref<Image> img = memnew(Image(p_area.size.x, p_area.size.y, mipmaps, format));
+ img->blit_rect(Ref<Image>((Image *)this), p_area, Point2(0, 0));
return img;
}
-void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+void Image::blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+ ERR_FAIL_COND(p_src.is_null());
int dsize = data.size();
- int srcdsize = p_src.data.size();
+ int srcdsize = p_src->data.size();
ERR_FAIL_COND(dsize == 0);
ERR_FAIL_COND(srcdsize == 0);
- ERR_FAIL_COND(format != p_src.format);
+ ERR_FAIL_COND(format != p_src->format);
- Rect2i local_src_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest + p_src_rect.pos, p_src_rect.size));
-
- if (local_src_rect.size.x <= 0 || local_src_rect.size.y <= 0)
+ Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
return;
- Rect2i src_rect(p_src_rect.pos + (local_src_rect.pos - p_dest), local_src_rect.size);
+
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
PoolVector<uint8_t>::Write wp = data.write();
uint8_t *dst_data_ptr = wp.ptr();
- PoolVector<uint8_t>::Read rp = p_src.data.read();
+ PoolVector<uint8_t>::Read rp = p_src->data.read();
const uint8_t *src_data_ptr = rp.ptr();
int pixel_size = get_format_pixel_size(format);
- for (int i = 0; i < src_rect.size.y; i++) {
+ for (int i = 0; i < dest_rect.size.y; i++) {
- for (int j = 0; j < src_rect.size.x; j++) {
+ for (int j = 0; j < dest_rect.size.x; j++) {
- int src_x = src_rect.pos.x + j;
- int src_y = src_rect.pos.y + i;
+ int src_x = clipped_src_rect.position.x + j;
+ int src_y = clipped_src_rect.position.y + i;
- int dst_x = local_src_rect.pos.x + j;
- int dst_y = local_src_rect.pos.y + i;
+ int dst_x = dest_rect.position.x + j;
+ int dst_y = dest_rect.position.y + i;
- const uint8_t *src = &src_data_ptr[(src_y * p_src.width + src_x) * pixel_size];
+ const uint8_t *src = &src_data_ptr[(src_y * p_src->width + src_x) * pixel_size];
uint8_t *dst = &dst_data_ptr[(dst_y * width + dst_x) * pixel_size];
for (int k = 0; k < pixel_size; k++) {
@@ -1925,25 +1646,637 @@ void Image::blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2
}
}
-Image (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
-Image (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
+void Image::blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest) {
+
+ ERR_FAIL_COND(p_src.is_null());
+ int dsize = data.size();
+ int srcdsize = p_src->data.size();
+ ERR_FAIL_COND(dsize == 0);
+ ERR_FAIL_COND(srcdsize == 0);
+ ERR_FAIL_COND(format != p_src->format);
+
+ Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ return;
+
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+
+ lock();
+ Ref<Image> img = p_src;
+ img->lock();
+
+ for (int i = 0; i < dest_rect.size.y; i++) {
+
+ for (int j = 0; j < dest_rect.size.x; j++) {
+
+ int src_x = clipped_src_rect.position.x + j;
+ int src_y = clipped_src_rect.position.y + i;
+
+ int dst_x = dest_rect.position.x + j;
+ int dst_y = dest_rect.position.y + i;
+
+ Color sc = img->get_pixel(src_x, src_y);
+ Color dc = get_pixel(dst_x, dst_y);
+ dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r);
+ dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g);
+ dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b);
+ dc.a = (double)(sc.a + dc.a * (1.0 - sc.a));
+ put_pixel(dst_x, dst_y, dc);
+ }
+ }
+
+ img->unlock();
+ unlock();
+}
+
+void Image::blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest) {
-void (*Image::_image_compress_bc_func)(Image *) = NULL;
+ ERR_FAIL_COND(p_src.is_null());
+ ERR_FAIL_COND(p_mask.is_null());
+ int dsize = data.size();
+ int srcdsize = p_src->data.size();
+ int maskdsize = p_mask->data.size();
+ ERR_FAIL_COND(dsize == 0);
+ ERR_FAIL_COND(srcdsize == 0);
+ ERR_FAIL_COND(maskdsize == 0);
+ ERR_FAIL_COND(p_src->width != p_mask->width);
+ ERR_FAIL_COND(p_src->height != p_mask->height);
+ ERR_FAIL_COND(format != p_src->format);
+
+ Rect2i clipped_src_rect = Rect2i(0, 0, p_src->width, p_src->height).clip(p_src_rect);
+ if (clipped_src_rect.size.x <= 0 || clipped_src_rect.size.y <= 0)
+ return;
+
+ Rect2i dest_rect = Rect2i(0, 0, width, height).clip(Rect2i(p_dest, clipped_src_rect.size));
+
+ lock();
+ Ref<Image> img = p_src;
+ Ref<Image> msk = p_mask;
+ img->lock();
+ msk->lock();
+
+ for (int i = 0; i < dest_rect.size.y; i++) {
+
+ for (int j = 0; j < dest_rect.size.x; j++) {
+
+ int src_x = clipped_src_rect.position.x + j;
+ int src_y = clipped_src_rect.position.y + i;
+
+ // If the mask's pixel is transparent then we skip it
+ //Color c = msk->get_pixel(src_x, src_y);
+ //if (c.a == 0) continue;
+ if (msk->get_pixel(src_x, src_y).a != 0) {
+
+ int dst_x = dest_rect.position.x + j;
+ int dst_y = dest_rect.position.y + i;
+
+ Color sc = img->get_pixel(src_x, src_y);
+ Color dc = get_pixel(dst_x, dst_y);
+ dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r);
+ dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g);
+ dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b);
+ dc.a = (double)(sc.a + dc.a * (1.0 - sc.a));
+ put_pixel(dst_x, dst_y, dc);
+ }
+ }
+ }
+
+ msk->unlock();
+ img->unlock();
+ unlock();
+}
+
+void Image::fill(const Color &c) {
+
+ lock();
+
+ PoolVector<uint8_t>::Write wp = data.write();
+ uint8_t *dst_data_ptr = wp.ptr();
+
+ int pixel_size = get_format_pixel_size(format);
+
+ // put first pixel with the format-aware API
+ put_pixel(0, 0, c);
+
+ for (int y = 0; y < height; y++) {
+
+ for (int x = 0; x < width; x++) {
+
+ uint8_t *dst = &dst_data_ptr[(y * width + x) * pixel_size];
+
+ for (int k = 0; k < pixel_size; k++) {
+ dst[k] = dst_data_ptr[k];
+ }
+ }
+ }
+
+ unlock();
+}
+
+Ref<Image> (*Image::_png_mem_loader_func)(const uint8_t *, int) = NULL;
+Ref<Image> (*Image::_jpg_mem_loader_func)(const uint8_t *, int) = NULL;
+
+void (*Image::_image_compress_bc_func)(Image *, Image::CompressSource) = NULL;
void (*Image::_image_compress_pvrtc2_func)(Image *) = NULL;
void (*Image::_image_compress_pvrtc4_func)(Image *) = NULL;
-void (*Image::_image_compress_etc_func)(Image *) = NULL;
-void (*Image::_image_compress_etc2_func)(Image *) = NULL;
+void (*Image::_image_compress_etc1_func)(Image *, float) = NULL;
+void (*Image::_image_compress_etc2_func)(Image *, float, Image::CompressSource) = NULL;
void (*Image::_image_decompress_pvrtc)(Image *) = NULL;
void (*Image::_image_decompress_bc)(Image *) = NULL;
-void (*Image::_image_decompress_etc)(Image *) = NULL;
+void (*Image::_image_decompress_etc1)(Image *) = NULL;
void (*Image::_image_decompress_etc2)(Image *) = NULL;
-PoolVector<uint8_t> (*Image::lossy_packer)(const Image &, float) = NULL;
-Image (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
-PoolVector<uint8_t> (*Image::lossless_packer)(const Image &) = NULL;
-Image (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
+PoolVector<uint8_t> (*Image::lossy_packer)(const Ref<Image> &, float) = NULL;
+Ref<Image> (*Image::lossy_unpacker)(const PoolVector<uint8_t> &) = NULL;
+PoolVector<uint8_t> (*Image::lossless_packer)(const Ref<Image> &) = NULL;
+Ref<Image> (*Image::lossless_unpacker)(const PoolVector<uint8_t> &) = NULL;
+
+void Image::_set_data(const Dictionary &p_data) {
+
+ ERR_FAIL_COND(!p_data.has("width"));
+ ERR_FAIL_COND(!p_data.has("height"));
+ ERR_FAIL_COND(!p_data.has("format"));
+ ERR_FAIL_COND(!p_data.has("mipmaps"));
+ ERR_FAIL_COND(!p_data.has("data"));
+
+ int dwidth = p_data["width"];
+ int dheight = p_data["height"];
+ String dformat = p_data["format"];
+ bool dmipmaps = p_data["mipmaps"];
+ PoolVector<uint8_t> ddata = p_data["data"];
+ Format ddformat = FORMAT_MAX;
+ for (int i = 0; i < FORMAT_MAX; i++) {
+ if (dformat == get_format_name(Format(i))) {
+ ddformat = Format(i);
+ break;
+ }
+ }
+
+ ERR_FAIL_COND(ddformat == FORMAT_MAX);
+
+ create(dwidth, dheight, dmipmaps, ddformat, ddata);
+}
+
+Dictionary Image::_get_data() const {
+
+ Dictionary d;
+ d["width"] = width;
+ d["height"] = height;
+ d["format"] = get_format_name(format);
+ d["mipmaps"] = mipmaps;
+ d["data"] = data;
+ return d;
+}
+
+void Image::lock() {
+
+ ERR_FAIL_COND(data.size() == 0);
+ write_lock = data.write();
+}
+
+void Image::unlock() {
+
+ write_lock = PoolVector<uint8_t>::Write();
+}
+
+Color Image::get_pixel(int p_x, int p_y) const {
+
+ uint8_t *ptr = write_lock.ptr();
+#ifdef DEBUG_ENABLED
+ if (!ptr) {
+ ERR_EXPLAIN("Image must be locked with 'lock()' before using get_pixel()");
+ ERR_FAIL_COND_V(!ptr, Color());
+ }
+
+ ERR_FAIL_INDEX_V(p_x, width, Color());
+ ERR_FAIL_INDEX_V(p_y, height, Color());
+
+#endif
+
+ uint32_t ofs = p_y * width + p_x;
+
+ switch (format) {
+ case FORMAT_L8: {
+ float l = ptr[ofs] / 255.0;
+ return Color(l, l, l, 1);
+ } break;
+ case FORMAT_LA8: {
+ float l = ptr[ofs * 2 + 0] / 255.0;
+ float a = ptr[ofs * 2 + 1] / 255.0;
+ return Color(l, l, l, a);
+ } break;
+ case FORMAT_R8: {
+
+ float r = ptr[ofs] / 255.0;
+ return Color(r, 0, 0, 1);
+ } break;
+ case FORMAT_RG8: {
+
+ float r = ptr[ofs * 2 + 0] / 255.0;
+ float g = ptr[ofs * 2 + 1] / 255.0;
+ return Color(r, g, 0, 1);
+ } break;
+ case FORMAT_RGB8: {
+ float r = ptr[ofs * 3 + 0] / 255.0;
+ float g = ptr[ofs * 3 + 1] / 255.0;
+ float b = ptr[ofs * 3 + 2] / 255.0;
+ return Color(r, g, b, 1);
+
+ } break;
+ case FORMAT_RGBA8: {
+ float r = ptr[ofs * 4 + 0] / 255.0;
+ float g = ptr[ofs * 4 + 1] / 255.0;
+ float b = ptr[ofs * 4 + 2] / 255.0;
+ float a = ptr[ofs * 4 + 3] / 255.0;
+ return Color(r, g, b, a);
+
+ } break;
+ case FORMAT_RGBA4444: {
+ uint16_t u = ((uint16_t *)ptr)[ofs];
+ float r = (u & 0xF) / 15.0;
+ float g = ((u >> 4) & 0xF) / 15.0;
+ float b = ((u >> 8) & 0xF) / 15.0;
+ float a = ((u >> 12) & 0xF) / 15.0;
+ return Color(r, g, b, a);
+
+ } break;
+ case FORMAT_RGBA5551: {
+
+ uint16_t u = ((uint16_t *)ptr)[ofs];
+ float r = (u & 0x1F) / 15.0;
+ float g = ((u >> 5) & 0x1F) / 15.0;
+ float b = ((u >> 10) & 0x1F) / 15.0;
+ float a = ((u >> 15) & 0x1) / 1.0;
+ return Color(r, g, b, a);
+ } break;
+ case FORMAT_RF: {
+
+ float r = ((float *)ptr)[ofs];
+ return Color(r, 0, 0, 1);
+ } break;
+ case FORMAT_RGF: {
+
+ float r = ((float *)ptr)[ofs * 2 + 0];
+ float g = ((float *)ptr)[ofs * 2 + 1];
+ return Color(r, g, 0, 1);
+ } break;
+ case FORMAT_RGBF: {
+
+ float r = ((float *)ptr)[ofs * 3 + 0];
+ float g = ((float *)ptr)[ofs * 3 + 1];
+ float b = ((float *)ptr)[ofs * 3 + 2];
+ return Color(r, g, b, 1);
+ } break;
+ case FORMAT_RGBAF: {
+
+ float r = ((float *)ptr)[ofs * 4 + 0];
+ float g = ((float *)ptr)[ofs * 4 + 1];
+ float b = ((float *)ptr)[ofs * 4 + 2];
+ float a = ((float *)ptr)[ofs * 4 + 3];
+ return Color(r, g, b, a);
+ } break;
+ case FORMAT_RH: {
+
+ uint16_t r = ((uint16_t *)ptr)[ofs];
+ return Color(Math::half_to_float(r), 0, 0, 1);
+ } break;
+ case FORMAT_RGH: {
+
+ uint16_t r = ((uint16_t *)ptr)[ofs * 2 + 0];
+ uint16_t g = ((uint16_t *)ptr)[ofs * 2 + 1];
+ return Color(Math::half_to_float(r), Math::half_to_float(g), 0, 1);
+ } break;
+ case FORMAT_RGBH: {
+
+ uint16_t r = ((uint16_t *)ptr)[ofs * 3 + 0];
+ uint16_t g = ((uint16_t *)ptr)[ofs * 3 + 1];
+ uint16_t b = ((uint16_t *)ptr)[ofs * 3 + 2];
+ return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), 1);
+ } break;
+ case FORMAT_RGBAH: {
+
+ uint16_t r = ((uint16_t *)ptr)[ofs * 4 + 0];
+ uint16_t g = ((uint16_t *)ptr)[ofs * 4 + 1];
+ uint16_t b = ((uint16_t *)ptr)[ofs * 4 + 2];
+ uint16_t a = ((uint16_t *)ptr)[ofs * 4 + 3];
+ return Color(Math::half_to_float(r), Math::half_to_float(g), Math::half_to_float(b), Math::half_to_float(a));
+ } break;
+ case FORMAT_RGBE9995: {
+ uint32_t rgbe = ((uint32_t *)ptr)[ofs];
+ float r = rgbe & 0x1ff;
+ float g = (rgbe >> 9) & 0x1ff;
+ float b = (rgbe >> 18) & 0x1ff;
+ float e = (rgbe >> 27);
+ float m = Math::pow(2, e - 15.0 - 9.0);
+ ;
+ float rd = r * m;
+ float gd = g * m;
+ float bd = b * m;
+
+ return Color(rd, gd, bd, 1.0);
+
+ } break;
+ default: {
+ ERR_EXPLAIN("Can't get_pixel() on compressed image, sorry.");
+ ERR_FAIL_V(Color());
+ }
+ }
+
+ return Color();
+}
+
+void Image::put_pixel(int p_x, int p_y, const Color &p_color) {
+
+ uint8_t *ptr = write_lock.ptr();
+#ifdef DEBUG_ENABLED
+ if (!ptr) {
+ ERR_EXPLAIN("Image must be locked with 'lock()' before using put_pixel()");
+ ERR_FAIL_COND(!ptr);
+ }
+
+ ERR_FAIL_INDEX(p_x, width);
+ ERR_FAIL_INDEX(p_y, height);
+
+#endif
+
+ uint32_t ofs = p_y * width + p_x;
+
+ switch (format) {
+ case FORMAT_L8: {
+ ptr[ofs] = uint8_t(CLAMP(p_color.gray() * 255.0, 0, 255));
+ } break;
+ case FORMAT_LA8: {
+ ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.gray() * 255.0, 0, 255));
+ ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
+ } break;
+ case FORMAT_R8: {
+
+ ptr[ofs] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
+ } break;
+ case FORMAT_RG8: {
+
+ ptr[ofs * 2 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
+ ptr[ofs * 2 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
+ } break;
+ case FORMAT_RGB8: {
+ ptr[ofs * 3 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
+ ptr[ofs * 3 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
+ ptr[ofs * 3 + 2] = uint8_t(CLAMP(p_color.b * 255.0, 0, 255));
+ } break;
+ case FORMAT_RGBA8: {
+ ptr[ofs * 4 + 0] = uint8_t(CLAMP(p_color.r * 255.0, 0, 255));
+ ptr[ofs * 4 + 1] = uint8_t(CLAMP(p_color.g * 255.0, 0, 255));
+ ptr[ofs * 4 + 2] = uint8_t(CLAMP(p_color.b * 255.0, 0, 255));
+ ptr[ofs * 4 + 3] = uint8_t(CLAMP(p_color.a * 255.0, 0, 255));
+
+ } break;
+ case FORMAT_RGBA4444: {
+
+ uint16_t rgba = 0;
+
+ rgba = uint16_t(CLAMP(p_color.r * 15.0, 0, 15));
+ rgba |= uint16_t(CLAMP(p_color.g * 15.0, 0, 15)) << 4;
+ rgba |= uint16_t(CLAMP(p_color.b * 15.0, 0, 15)) << 8;
+ rgba |= uint16_t(CLAMP(p_color.a * 15.0, 0, 15)) << 12;
+
+ ((uint16_t *)ptr)[ofs] = rgba;
+
+ } break;
+ case FORMAT_RGBA5551: {
+
+ uint16_t rgba = 0;
-void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) {
+ rgba = uint16_t(CLAMP(p_color.r * 31.0, 0, 31));
+ rgba |= uint16_t(CLAMP(p_color.g * 31.0, 0, 31)) << 5;
+ rgba |= uint16_t(CLAMP(p_color.b * 31.0, 0, 31)) << 10;
+ rgba |= uint16_t(p_color.a > 0.5 ? 1 : 0) << 15;
+
+ ((uint16_t *)ptr)[ofs] = rgba;
+
+ } break;
+ case FORMAT_RF: {
+
+ ((float *)ptr)[ofs] = p_color.r;
+ } break;
+ case FORMAT_RGF: {
+
+ ((float *)ptr)[ofs * 2 + 0] = p_color.r;
+ ((float *)ptr)[ofs * 2 + 1] = p_color.g;
+ } break;
+ case FORMAT_RGBF: {
+
+ ((float *)ptr)[ofs * 3 + 0] = p_color.r;
+ ((float *)ptr)[ofs * 3 + 1] = p_color.g;
+ ((float *)ptr)[ofs * 3 + 2] = p_color.b;
+ } break;
+ case FORMAT_RGBAF: {
+
+ ((float *)ptr)[ofs * 4 + 0] = p_color.r;
+ ((float *)ptr)[ofs * 4 + 1] = p_color.g;
+ ((float *)ptr)[ofs * 4 + 2] = p_color.b;
+ ((float *)ptr)[ofs * 4 + 3] = p_color.a;
+ } break;
+ case FORMAT_RH: {
+
+ ((uint16_t *)ptr)[ofs] = Math::make_half_float(p_color.r);
+ } break;
+ case FORMAT_RGH: {
+
+ ((uint16_t *)ptr)[ofs * 2 + 0] = Math::make_half_float(p_color.r);
+ ((uint16_t *)ptr)[ofs * 2 + 1] = Math::make_half_float(p_color.g);
+ } break;
+ case FORMAT_RGBH: {
+
+ ((uint16_t *)ptr)[ofs * 3 + 0] = Math::make_half_float(p_color.r);
+ ((uint16_t *)ptr)[ofs * 3 + 1] = Math::make_half_float(p_color.g);
+ ((uint16_t *)ptr)[ofs * 3 + 2] = Math::make_half_float(p_color.b);
+ } break;
+ case FORMAT_RGBAH: {
+
+ ((uint16_t *)ptr)[ofs * 4 + 0] = Math::make_half_float(p_color.r);
+ ((uint16_t *)ptr)[ofs * 4 + 1] = Math::make_half_float(p_color.g);
+ ((uint16_t *)ptr)[ofs * 4 + 2] = Math::make_half_float(p_color.b);
+ ((uint16_t *)ptr)[ofs * 4 + 3] = Math::make_half_float(p_color.a);
+ } break;
+ case FORMAT_RGBE9995: {
+
+ ((uint32_t *)ptr)[ofs] = p_color.to_rgbe9995();
+
+ } break;
+ default: {
+ ERR_EXPLAIN("Can't put_pixel() on compressed image, sorry.");
+ ERR_FAIL();
+ }
+ }
+}
+
+Image::DetectChannels Image::get_detected_channels() {
+
+ ERR_FAIL_COND_V(data.size() == 0, DETECTED_RGBA);
+ ERR_FAIL_COND_V(is_compressed(), DETECTED_RGBA);
+ bool r = false, g = false, b = false, a = false, c = false;
+ lock();
+ for (int i = 0; i < width; i++) {
+ for (int j = 0; j < height; j++) {
+
+ Color col = get_pixel(i, j);
+
+ if (col.r > 0.001)
+ r = true;
+ if (col.g > 0.001)
+ g = true;
+ if (col.b > 0.001)
+ b = true;
+ if (col.a < 0.999)
+ a = true;
+
+ if (col.r != col.b || col.r != col.g || col.b != col.g) {
+ c = true;
+ }
+ }
+ }
+
+ unlock();
+
+ if (!c && !a)
+ return DETECTED_L;
+ if (!c && a)
+ return DETECTED_LA;
+
+ if (r && !g && !b && !a)
+ return DETECTED_R;
+
+ if (r && g && !b && !a)
+ return DETECTED_RG;
+
+ if (r && g && b && !a)
+ return DETECTED_RGB;
+
+ return DETECTED_RGBA;
+}
+
+void Image::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("get_width"), &Image::get_width);
+ ClassDB::bind_method(D_METHOD("get_height"), &Image::get_height);
+ ClassDB::bind_method(D_METHOD("has_mipmaps"), &Image::has_mipmaps);
+ ClassDB::bind_method(D_METHOD("get_format"), &Image::get_format);
+ ClassDB::bind_method(D_METHOD("get_data"), &Image::get_data);
+
+ ClassDB::bind_method(D_METHOD("convert", "format"), &Image::convert);
+
+ ClassDB::bind_method(D_METHOD("get_mipmap_offset", "mipmap"), &Image::get_mipmap_offset);
+
+ ClassDB::bind_method(D_METHOD("resize_to_po2", "square"), &Image::resize_to_po2, DEFVAL("false"));
+ ClassDB::bind_method(D_METHOD("resize", "width", "height", "interpolation"), &Image::resize, DEFVAL(INTERPOLATE_BILINEAR));
+ ClassDB::bind_method(D_METHOD("shrink_x2"), &Image::shrink_x2);
+ ClassDB::bind_method(D_METHOD("expand_x2_hq2x"), &Image::expand_x2_hq2x);
+
+ ClassDB::bind_method(D_METHOD("crop", "width", "height"), &Image::crop);
+ ClassDB::bind_method(D_METHOD("flip_x"), &Image::flip_x);
+ ClassDB::bind_method(D_METHOD("flip_y"), &Image::flip_y);
+ ClassDB::bind_method(D_METHOD("generate_mipmaps"), &Image::generate_mipmaps);
+ ClassDB::bind_method(D_METHOD("clear_mipmaps"), &Image::clear_mipmaps);
+
+ ClassDB::bind_method(D_METHOD("create", "width", "height", "use_mipmaps", "format"), &Image::_create_empty);
+ ClassDB::bind_method(D_METHOD("create_from_data", "width", "height", "use_mipmaps", "format", "data"), &Image::_create_from_data);
+
+ ClassDB::bind_method(D_METHOD("is_empty"), &Image::empty);
+
+ ClassDB::bind_method(D_METHOD("load", "path"), &Image::load);
+ ClassDB::bind_method(D_METHOD("save_png", "path"), &Image::save_png);
+
+ ClassDB::bind_method(D_METHOD("detect_alpha"), &Image::detect_alpha);
+ ClassDB::bind_method(D_METHOD("is_invisible"), &Image::is_invisible);
+
+ ClassDB::bind_method(D_METHOD("compress", "mode"), &Image::compress);
+ ClassDB::bind_method(D_METHOD("decompress"), &Image::decompress);
+ ClassDB::bind_method(D_METHOD("is_compressed"), &Image::is_compressed);
+
+ ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &Image::fix_alpha_edges);
+ ClassDB::bind_method(D_METHOD("premultiply_alpha"), &Image::premultiply_alpha);
+ ClassDB::bind_method(D_METHOD("srgb_to_linear"), &Image::srgb_to_linear);
+ ClassDB::bind_method(D_METHOD("normalmap_to_xy"), &Image::normalmap_to_xy);
+
+ ClassDB::bind_method(D_METHOD("blit_rect", "src:Image", "src_rect", "dst"), &Image::blit_rect);
+ ClassDB::bind_method(D_METHOD("blend_rect", "src:Image", "src_rect", "dst"), &Image::blend_rect);
+ ClassDB::bind_method(D_METHOD("blend_rect_mask", "src:Image", "mask:Image", "src_rect", "dst"), &Image::blend_rect_mask);
+ ClassDB::bind_method(D_METHOD("fill", "color"), &Image::fill);
+
+ ClassDB::bind_method(D_METHOD("get_used_rect"), &Image::get_used_rect);
+ ClassDB::bind_method(D_METHOD("get_rect:Image", "rect"), &Image::get_rect);
+
+ ClassDB::bind_method(D_METHOD("copy_from", "src:Image"), &Image::copy_internals_from);
+
+ ClassDB::bind_method(D_METHOD("_set_data", "data"), &Image::_set_data);
+ ClassDB::bind_method(D_METHOD("_get_data"), &Image::_get_data);
+
+ ClassDB::bind_method(D_METHOD("lock"), &Image::lock);
+ ClassDB::bind_method(D_METHOD("unlock"), &Image::unlock);
+ ClassDB::bind_method(D_METHOD("put_pixel", "x", "y", "color"), &Image::put_pixel);
+ ClassDB::bind_method(D_METHOD("get_pixel", "x", "y"), &Image::get_pixel);
+
+ ADD_PROPERTY(PropertyInfo(Variant::DICTIONARY, "data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE), "_set_data", "_get_data");
+
+ BIND_CONSTANT(FORMAT_L8); //luminance
+ BIND_CONSTANT(FORMAT_LA8); //luminance-alpha
+ BIND_CONSTANT(FORMAT_R8);
+ BIND_CONSTANT(FORMAT_RG8);
+ BIND_CONSTANT(FORMAT_RGB8);
+ BIND_CONSTANT(FORMAT_RGBA8);
+ BIND_CONSTANT(FORMAT_RGBA4444);
+ BIND_CONSTANT(FORMAT_RGBA5551);
+ BIND_CONSTANT(FORMAT_RF); //float
+ BIND_CONSTANT(FORMAT_RGF);
+ BIND_CONSTANT(FORMAT_RGBF);
+ BIND_CONSTANT(FORMAT_RGBAF);
+ BIND_CONSTANT(FORMAT_RH); //half float
+ BIND_CONSTANT(FORMAT_RGH);
+ BIND_CONSTANT(FORMAT_RGBH);
+ BIND_CONSTANT(FORMAT_RGBAH);
+ BIND_CONSTANT(FORMAT_RGBE9995);
+ BIND_CONSTANT(FORMAT_DXT1); //s3tc bc1
+ BIND_CONSTANT(FORMAT_DXT3); //bc2
+ BIND_CONSTANT(FORMAT_DXT5); //bc3
+ BIND_CONSTANT(FORMAT_RGTC_R);
+ BIND_CONSTANT(FORMAT_RGTC_RG);
+ BIND_CONSTANT(FORMAT_BPTC_RGBA); //btpc bc6h
+ BIND_CONSTANT(FORMAT_BPTC_RGBF); //float /
+ BIND_CONSTANT(FORMAT_BPTC_RGBFU); //unsigned float
+ BIND_CONSTANT(FORMAT_PVRTC2); //pvrtc
+ BIND_CONSTANT(FORMAT_PVRTC2A);
+ BIND_CONSTANT(FORMAT_PVRTC4);
+ BIND_CONSTANT(FORMAT_PVRTC4A);
+ BIND_CONSTANT(FORMAT_ETC); //etc1
+ BIND_CONSTANT(FORMAT_ETC2_R11); //etc2
+ BIND_CONSTANT(FORMAT_ETC2_R11S); //signed ); NOT srgb.
+ BIND_CONSTANT(FORMAT_ETC2_RG11);
+ BIND_CONSTANT(FORMAT_ETC2_RG11S);
+ BIND_CONSTANT(FORMAT_ETC2_RGB8);
+ BIND_CONSTANT(FORMAT_ETC2_RGBA8);
+ BIND_CONSTANT(FORMAT_ETC2_RGB8A1);
+ BIND_CONSTANT(FORMAT_MAX);
+
+ BIND_CONSTANT(INTERPOLATE_NEAREST);
+ BIND_CONSTANT(INTERPOLATE_BILINEAR);
+ BIND_CONSTANT(INTERPOLATE_CUBIC);
+
+ BIND_CONSTANT(ALPHA_NONE);
+ BIND_CONSTANT(ALPHA_BIT);
+ BIND_CONSTANT(ALPHA_BLEND);
+
+ BIND_CONSTANT(COMPRESS_S3TC);
+ BIND_CONSTANT(COMPRESS_PVRTC2);
+ BIND_CONSTANT(COMPRESS_PVRTC4);
+ BIND_CONSTANT(COMPRESS_ETC);
+ BIND_CONSTANT(COMPRESS_ETC2);
+
+ BIND_CONSTANT(COMPRESS_SOURCE_GENERIC);
+ BIND_CONSTANT(COMPRESS_SOURCE_SRGB);
+ BIND_CONSTANT(COMPRESS_SOURCE_NORMAL);
+}
+
+void Image::set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource)) {
_image_compress_bc_func = p_compress_func;
}
@@ -2108,14 +2441,22 @@ Image::Image(const uint8_t *p_mem_png_jpg, int p_len) {
format = FORMAT_L8;
if (_png_mem_loader_func) {
- *this = _png_mem_loader_func(p_mem_png_jpg, p_len);
+ copy_internals_from(_png_mem_loader_func(p_mem_png_jpg, p_len));
}
if (empty() && _jpg_mem_loader_func) {
- *this = _jpg_mem_loader_func(p_mem_png_jpg, p_len);
+ copy_internals_from(_jpg_mem_loader_func(p_mem_png_jpg, p_len));
}
}
+Ref<Resource> Image::duplicate(bool p_subresources) const {
+
+ Ref<Image> copy;
+ copy.instance();
+ copy->_copy_internals_from(*this);
+ return copy;
+}
+
Image::Image() {
width = 0;
@@ -2125,4 +2466,8 @@ Image::Image() {
}
Image::~Image() {
+
+ if (write_lock.ptr()) {
+ unlock();
+ }
}
diff --git a/core/image.h b/core/image.h
index fc87ee8847..3323afdc4b 100644
--- a/core/image.h
+++ b/core/image.h
@@ -33,6 +33,8 @@
#include "color.h"
#include "dvector.h"
#include "math_2d.h"
+#include "resource.h"
+
/**
* @author Juan Linietsky <reduzio@gmail.com>
*
@@ -43,9 +45,10 @@
class Image;
-typedef Error (*SavePNGFunc)(const String &p_path, Image &p_img);
+typedef Error (*SavePNGFunc)(const String &p_path, const Ref<Image> &p_img);
-class Image {
+class Image : public Resource {
+ GDCLASS(Image, Resource);
enum {
MAX_WIDTH = 16384, // force a limit somehow
@@ -63,7 +66,6 @@ public:
FORMAT_RG8,
FORMAT_RGB8,
FORMAT_RGBA8,
- FORMAT_RGB565, //16 bit
FORMAT_RGBA4444,
FORMAT_RGBA5551,
FORMAT_RF, //float
@@ -74,14 +76,15 @@ public:
FORMAT_RGH,
FORMAT_RGBH,
FORMAT_RGBAH,
+ FORMAT_RGBE9995,
FORMAT_DXT1, //s3tc bc1
FORMAT_DXT3, //bc2
FORMAT_DXT5, //bc3
- FORMAT_ATI1, //bc4
- FORMAT_ATI2, //bc5
- FORMAT_BPTC_RGBA, //btpc bc6h
- FORMAT_BPTC_RGBF, //float /
- FORMAT_BPTC_RGBFU, //unsigned float
+ FORMAT_RGTC_R,
+ FORMAT_RGTC_RG,
+ FORMAT_BPTC_RGBA, //btpc bc7
+ FORMAT_BPTC_RGBF, //float bc6h
+ FORMAT_BPTC_RGBFU, //unsigned float bc6hu
FORMAT_PVRTC2, //pvrtc
FORMAT_PVRTC2A,
FORMAT_PVRTC4,
@@ -106,42 +109,70 @@ public:
/* INTERPOLATE GAUSS */
};
+ enum CompressSource {
+ COMPRESS_SOURCE_GENERIC,
+ COMPRESS_SOURCE_SRGB,
+ COMPRESS_SOURCE_NORMAL
+ };
+
//some functions provided by something else
- static Image (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
- static Image (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
+ static Ref<Image> (*_png_mem_loader_func)(const uint8_t *p_png, int p_size);
+ static Ref<Image> (*_jpg_mem_loader_func)(const uint8_t *p_png, int p_size);
- static void (*_image_compress_bc_func)(Image *);
+ static void (*_image_compress_bc_func)(Image *, CompressSource p_source);
static void (*_image_compress_pvrtc2_func)(Image *);
static void (*_image_compress_pvrtc4_func)(Image *);
- static void (*_image_compress_etc_func)(Image *);
- static void (*_image_compress_etc2_func)(Image *);
+ static void (*_image_compress_etc1_func)(Image *, float);
+ static void (*_image_compress_etc2_func)(Image *, float, CompressSource p_source);
static void (*_image_decompress_pvrtc)(Image *);
static void (*_image_decompress_bc)(Image *);
- static void (*_image_decompress_etc)(Image *);
+ static void (*_image_decompress_etc1)(Image *);
static void (*_image_decompress_etc2)(Image *);
- Error _decompress_bc();
+ static PoolVector<uint8_t> (*lossy_packer)(const Ref<Image> &p_image, float p_quality);
+ static Ref<Image> (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
+ static PoolVector<uint8_t> (*lossless_packer)(const Ref<Image> &p_image);
+ static Ref<Image> (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
- static PoolVector<uint8_t> (*lossy_packer)(const Image &p_image, float p_quality);
- static Image (*lossy_unpacker)(const PoolVector<uint8_t> &p_buffer);
- static PoolVector<uint8_t> (*lossless_packer)(const Image &p_image);
- static Image (*lossless_unpacker)(const PoolVector<uint8_t> &p_buffer);
+ PoolVector<uint8_t>::Write write_lock;
+
+protected:
+ static void _bind_methods();
private:
+ void _create_empty(int p_width, int p_height, bool p_use_mipmaps, Format p_format) {
+ create(p_width, p_height, p_use_mipmaps, p_format);
+ }
+
+ void _create_from_data(int p_width, int p_height, bool p_use_mipmaps, Format p_format, const PoolVector<uint8_t> &p_data) {
+ create(p_width, p_height, p_use_mipmaps, p_format, p_data);
+ }
+
Format format;
PoolVector<uint8_t> data;
int width, height;
bool mipmaps;
+ void _copy_internals_from(const Image &p_image) {
+ format = p_image.format;
+ width = p_image.width;
+ height = p_image.height;
+ mipmaps = p_image.mipmaps;
+ data = p_image.data;
+ }
+
_FORCE_INLINE_ void _get_mipmap_offset_and_size(int p_mipmap, int &r_offset, int &r_width, int &r_height) const; //get where the mipmap begins in data
static int _get_dst_image_size(int p_width, int p_height, Format p_format, int &r_mipmaps, int p_mipmaps = -1);
bool _can_modify(Format p_format) const;
- _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_dst, const uint8_t *p_src);
- _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_src, uint8_t *p_dst);
+ _FORCE_INLINE_ void _put_pixelb(int p_x, int p_y, uint32_t p_pixelsize, uint8_t *p_data, const uint8_t *p_pixel);
+ _FORCE_INLINE_ void _get_pixelb(int p_x, int p_y, uint32_t p_pixelsize, const uint8_t *p_data, uint8_t *p_pixel);
+
+ void _set_data(const Dictionary &p_data);
+ Dictionary _get_data() const;
public:
int get_width() const; ///< Get image width
@@ -154,14 +185,6 @@ public:
*/
void convert(Format p_new_format);
- Image converted(int p_new_format) {
- ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image());
-
- Image ret = *this;
- ret.convert((Format)p_new_format);
- return ret;
- };
-
/**
* Get the current image format.
*/
@@ -178,7 +201,6 @@ public:
void resize_to_po2(bool p_square = false);
void resize(int p_width, int p_height, Interpolation p_interpolation = INTERPOLATE_BILINEAR);
- Image resized(int p_width, int p_height, int p_interpolation = INTERPOLATE_BILINEAR);
void shrink_x2();
void expand_x2_hq2x();
/**
@@ -211,7 +233,7 @@ public:
PoolVector<uint8_t> get_data() const;
Error load(const String &p_path);
- Error save_png(const String &p_path);
+ Error save_png(const String &p_path) const;
/**
* create an empty image
@@ -237,26 +259,22 @@ public:
static int get_format_pixel_size(Format p_format);
static int get_format_pixel_rshift(Format p_format);
+ static int get_format_block_size(Format p_format);
static void get_format_min_pixel_size(Format p_format, int &r_w, int &r_h);
static int get_image_data_size(int p_width, int p_height, Format p_format, int p_mipmaps = 0);
static int get_image_required_mipmaps(int p_width, int p_height, Format p_format);
- bool operator==(const Image &p_image) const;
-
enum CompressMode {
- COMPRESS_16BIT,
COMPRESS_S3TC,
COMPRESS_PVRTC2,
COMPRESS_PVRTC4,
COMPRESS_ETC,
- COMPRESS_ETC2
+ COMPRESS_ETC2,
};
- Error compress(CompressMode p_mode = COMPRESS_S3TC);
- Image compressed(int p_mode); /* from the Image::CompressMode enum */
+ Error compress(CompressMode p_mode = COMPRESS_S3TC, CompressSource p_source = COMPRESS_SOURCE_GENERIC, float p_lossy_quality = 0.7);
Error decompress();
- Image decompressed() const;
bool is_compressed() const;
void fix_alpha_edges();
@@ -264,17 +282,56 @@ public:
void srgb_to_linear();
void normalmap_to_xy();
- void blit_rect(const Image &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void blit_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void blend_rect(const Ref<Image> &p_src, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void blend_rect_mask(const Ref<Image> &p_src, const Ref<Image> &p_mask, const Rect2 &p_src_rect, const Point2 &p_dest);
+ void fill(const Color &c);
Rect2 get_used_rect() const;
- Image get_rect(const Rect2 &p_area) const;
+ Ref<Image> get_rect(const Rect2 &p_area) const;
- static void set_compress_bc_func(void (*p_compress_func)(Image *));
+ static void set_compress_bc_func(void (*p_compress_func)(Image *, CompressSource));
static String get_format_name(Format p_format);
Image(const uint8_t *p_mem_png_jpg, int p_len = -1);
Image(const char **p_xpm);
+
+ virtual Ref<Resource> duplicate(bool p_subresources = false) const;
+
+ void lock();
+ void unlock();
+
+ //this is used for compression
+ enum DetectChannels {
+ DETECTED_L,
+ DETECTED_LA,
+ DETECTED_R,
+ DETECTED_RG,
+ DETECTED_RGB,
+ DETECTED_RGBA,
+ };
+
+ DetectChannels get_detected_channels();
+
+ Color get_pixel(int p_x, int p_y) const;
+ void put_pixel(int p_x, int p_y, const Color &p_color);
+
+ void copy_internals_from(const Ref<Image> &p_image) {
+ ERR_FAIL_COND(p_image.is_null());
+ format = p_image->format;
+ width = p_image->width;
+ height = p_image->height;
+ mipmaps = p_image->mipmaps;
+ data = p_image->data;
+ }
+
~Image();
};
+VARIANT_ENUM_CAST(Image::Format)
+VARIANT_ENUM_CAST(Image::Interpolation)
+VARIANT_ENUM_CAST(Image::CompressMode)
+VARIANT_ENUM_CAST(Image::CompressSource)
+VARIANT_ENUM_CAST(Image::AlphaMode)
+
#endif
diff --git a/core/input_map.cpp b/core/input_map.cpp
index 9f9eba01c7..1307c467e6 100644
--- a/core/input_map.cpp
+++ b/core/input_map.cpp
@@ -37,8 +37,6 @@ InputMap *InputMap::singleton = NULL;
void InputMap::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_action", "action"), &InputMap::has_action);
- ClassDB::bind_method(D_METHOD("get_action_id", "action"), &InputMap::get_action_id);
- ClassDB::bind_method(D_METHOD("get_action_from_id", "id"), &InputMap::get_action_from_id);
ClassDB::bind_method(D_METHOD("get_actions"), &InputMap::_get_actions);
ClassDB::bind_method(D_METHOD("add_action", "action"), &InputMap::add_action);
ClassDB::bind_method(D_METHOD("erase_action", "action"), &InputMap::erase_action);
@@ -57,23 +55,15 @@ void InputMap::add_action(const StringName &p_action) {
input_map[p_action] = Action();
static int last_id = 1;
input_map[p_action].id = last_id;
- input_id_map[last_id] = p_action;
last_id++;
}
void InputMap::erase_action(const StringName &p_action) {
ERR_FAIL_COND(!input_map.has(p_action));
- input_id_map.erase(input_map[p_action].id);
input_map.erase(p_action);
}
-StringName InputMap::get_action_from_id(int p_id) const {
-
- ERR_FAIL_COND_V(!input_id_map.has(p_id), StringName());
- return input_id_map[p_id];
-}
-
Array InputMap::_get_actions() {
Array ret;
@@ -103,49 +93,18 @@ List<StringName> InputMap::get_actions() const {
return actions;
}
-List<InputEvent>::Element *InputMap::_find_event(List<InputEvent> &p_list, const InputEvent &p_event, bool p_action_test) const {
-
- for (List<InputEvent>::Element *E = p_list.front(); E; E = E->next()) {
-
- const InputEvent &e = E->get();
- if (e.type != p_event.type)
- continue;
- if (e.type != InputEvent::KEY && e.device != p_event.device)
- continue;
-
- bool same = false;
-
- switch (p_event.type) {
-
- case InputEvent::KEY: {
-
- if (p_action_test) {
- uint32_t code = e.key.get_scancode_with_modifiers();
- uint32_t event_code = p_event.key.get_scancode_with_modifiers();
- same = (e.key.scancode == p_event.key.scancode && (!p_event.key.pressed || ((code & event_code) == code)));
- } else {
- same = (e.key.scancode == p_event.key.scancode && e.key.mod == p_event.key.mod);
- }
-
- } break;
- case InputEvent::JOYPAD_BUTTON: {
+List<Ref<InputEvent> >::Element *InputMap::_find_event(List<Ref<InputEvent> > &p_list, const Ref<InputEvent> &p_event, bool p_action_test) const {
- same = (e.joy_button.button_index == p_event.joy_button.button_index);
+ for (List<Ref<InputEvent> >::Element *E = p_list.front(); E; E = E->next()) {
- } break;
- case InputEvent::MOUSE_BUTTON: {
+ const Ref<InputEvent> e = E->get();
- same = (e.mouse_button.button_index == p_event.mouse_button.button_index);
+ //if (e.type != Ref<InputEvent>::KEY && e.device != p_event.device) -- unsure about the KEY comparison, why is this here?
+ // continue;
- } break;
- case InputEvent::JOYPAD_MOTION: {
-
- same = (e.joy_motion.axis == p_event.joy_motion.axis && (e.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
-
- } break;
- }
-
- if (same)
+ if (e->get_device() != p_event->get_device())
+ continue;
+ if (e->action_match(p_event))
return E;
}
@@ -157,9 +116,9 @@ bool InputMap::has_action(const StringName &p_action) const {
return input_map.has(p_action);
}
-void InputMap::action_add_event(const StringName &p_action, const InputEvent &p_event) {
+void InputMap::action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
- ERR_FAIL_COND(p_event.type == InputEvent::ACTION);
+ ERR_FAIL_COND(p_event.is_null());
ERR_FAIL_COND(!input_map.has(p_action));
if (_find_event(input_map[p_action].inputs, p_event))
return; //already gots
@@ -167,23 +126,17 @@ void InputMap::action_add_event(const StringName &p_action, const InputEvent &p_
input_map[p_action].inputs.push_back(p_event);
}
-int InputMap::get_action_id(const StringName &p_action) const {
-
- ERR_FAIL_COND_V(!input_map.has(p_action), -1);
- return input_map[p_action].id;
-}
-
-bool InputMap::action_has_event(const StringName &p_action, const InputEvent &p_event) {
+bool InputMap::action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND_V(!input_map.has(p_action), false);
return (_find_event(input_map[p_action].inputs, p_event) != NULL);
}
-void InputMap::action_erase_event(const StringName &p_action, const InputEvent &p_event) {
+void InputMap::action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(!input_map.has(p_action));
- List<InputEvent>::Element *E = _find_event(input_map[p_action].inputs, p_event);
+ List<Ref<InputEvent> >::Element *E = _find_event(input_map[p_action].inputs, p_event);
if (E)
input_map[p_action].inputs.erase(E);
}
@@ -191,9 +144,9 @@ void InputMap::action_erase_event(const StringName &p_action, const InputEvent &
Array InputMap::_get_action_list(const StringName &p_action) {
Array ret;
- const List<InputEvent> *al = get_action_list(p_action);
+ const List<Ref<InputEvent> > *al = get_action_list(p_action);
if (al) {
- for (const List<InputEvent>::Element *E = al->front(); E; E = E->next()) {
+ for (const List<Ref<InputEvent> >::Element *E = al->front(); E; E = E->next()) {
ret.push_back(E->get());
}
@@ -202,7 +155,7 @@ Array InputMap::_get_action_list(const StringName &p_action) {
return ret;
}
-const List<InputEvent> *InputMap::get_action_list(const StringName &p_action) {
+const List<Ref<InputEvent> > *InputMap::get_action_list(const StringName &p_action) {
const Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E)
@@ -211,7 +164,7 @@ const List<InputEvent> *InputMap::get_action_list(const StringName &p_action) {
return &E->get().inputs;
}
-bool InputMap::event_is_action(const InputEvent &p_event, const StringName &p_action) const {
+bool InputMap::event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const {
Map<StringName, Action>::Element *E = input_map.find(p_action);
if (!E) {
@@ -219,9 +172,9 @@ bool InputMap::event_is_action(const InputEvent &p_event, const StringName &p_ac
ERR_FAIL_COND_V(!E, false);
}
- if (p_event.type == InputEvent::ACTION) {
-
- return p_event.action.action == E->get().id;
+ Ref<InputEventAction> iea = p_event;
+ if (iea.is_valid()) {
+ return iea->get_action() == p_action;
}
return _find_event(E->get().inputs, p_event, true) != NULL;
@@ -252,8 +205,8 @@ void InputMap::load_from_globals() {
for (int i = 0; i < va.size(); i++) {
- InputEvent ie = va[i];
- if (ie.type == InputEvent::NONE)
+ Ref<InputEvent> ie = va[i];
+ if (ie.is_null())
continue;
action_add_event(name, ie);
}
@@ -262,57 +215,70 @@ void InputMap::load_from_globals() {
void InputMap::load_default() {
- InputEvent key;
- key.type = InputEvent::KEY;
+ Ref<InputEventKey> key;
add_action("ui_accept");
- key.key.scancode = KEY_RETURN;
+ key.instance();
+ key->set_scancode(KEY_RETURN);
action_add_event("ui_accept", key);
- key.key.scancode = KEY_ENTER;
+
+ key.instance();
+ key->set_scancode(KEY_ENTER);
action_add_event("ui_accept", key);
- key.key.scancode = KEY_SPACE;
+
+ key.instance();
+ key->set_scancode(KEY_SPACE);
action_add_event("ui_accept", key);
add_action("ui_select");
- key.key.scancode = KEY_SPACE;
+ key.instance();
+ key->set_scancode(KEY_SPACE);
action_add_event("ui_select", key);
add_action("ui_cancel");
- key.key.scancode = KEY_ESCAPE;
+ key.instance();
+ key->set_scancode(KEY_ESCAPE);
action_add_event("ui_cancel", key);
add_action("ui_focus_next");
- key.key.scancode = KEY_TAB;
+ key.instance();
+ key->set_scancode(KEY_TAB);
action_add_event("ui_focus_next", key);
add_action("ui_focus_prev");
- key.key.scancode = KEY_TAB;
- key.key.mod.shift = true;
+ key.instance();
+ key->set_scancode(KEY_TAB);
+ key->set_shift(true);
action_add_event("ui_focus_prev", key);
- key.key.mod.shift = false;
add_action("ui_left");
- key.key.scancode = KEY_LEFT;
+ key.instance();
+ key->set_scancode(KEY_LEFT);
action_add_event("ui_left", key);
add_action("ui_right");
- key.key.scancode = KEY_RIGHT;
+ key.instance();
+ key->set_scancode(KEY_RIGHT);
action_add_event("ui_right", key);
add_action("ui_up");
- key.key.scancode = KEY_UP;
+ key.instance();
+ key->set_scancode(KEY_UP);
action_add_event("ui_up", key);
add_action("ui_down");
- key.key.scancode = KEY_DOWN;
+ key.instance();
+ key->set_scancode(KEY_DOWN);
action_add_event("ui_down", key);
add_action("ui_page_up");
- key.key.scancode = KEY_PAGEUP;
+ key.instance();
+ key->set_scancode(KEY_PAGEUP);
action_add_event("ui_page_up", key);
add_action("ui_page_down");
- key.key.scancode = KEY_PAGEDOWN;
+ key.instance();
+ key->set_scancode(KEY_PAGEDOWN);
action_add_event("ui_page_down", key);
//set("display/handheld/orientation", "landscape");
diff --git a/core/input_map.h b/core/input_map.h
index a25255da2d..ba93e61f5f 100644
--- a/core/input_map.h
+++ b/core/input_map.h
@@ -31,6 +31,7 @@
#define INPUT_MAP_H
#include "object.h"
+#include "os/input_event.h"
class InputMap : public Object {
@@ -39,16 +40,15 @@ class InputMap : public Object {
public:
struct Action {
int id;
- List<InputEvent> inputs;
+ List<Ref<InputEvent> > inputs;
};
private:
static InputMap *singleton;
mutable Map<StringName, Action> input_map;
- mutable Map<int, StringName> input_id_map;
- List<InputEvent>::Element *_find_event(List<InputEvent> &p_list, const InputEvent &p_event, bool p_action_test = false) const;
+ List<Ref<InputEvent> >::Element *_find_event(List<Ref<InputEvent> > &p_list, const Ref<InputEvent> &p_event, bool p_action_test = false) const;
Array _get_action_list(const StringName &p_action);
Array _get_actions();
@@ -60,18 +60,16 @@ public:
static _FORCE_INLINE_ InputMap *get_singleton() { return singleton; }
bool has_action(const StringName &p_action) const;
- int get_action_id(const StringName &p_action) const;
- StringName get_action_from_id(int p_id) const;
List<StringName> get_actions() const;
void add_action(const StringName &p_action);
void erase_action(const StringName &p_action);
- void action_add_event(const StringName &p_action, const InputEvent &p_event);
- bool action_has_event(const StringName &p_action, const InputEvent &p_event);
- void action_erase_event(const StringName &p_action, const InputEvent &p_event);
+ void action_add_event(const StringName &p_action, const Ref<InputEvent> &p_event);
+ bool action_has_event(const StringName &p_action, const Ref<InputEvent> &p_event);
+ void action_erase_event(const StringName &p_action, const Ref<InputEvent> &p_event);
- const List<InputEvent> *get_action_list(const StringName &p_action);
- bool event_is_action(const InputEvent &p_event, const StringName &p_action) const;
+ const List<Ref<InputEvent> > *get_action_list(const StringName &p_action);
+ bool event_is_action(const Ref<InputEvent> &p_event, const StringName &p_action) const;
const Map<StringName, Action> &get_action_map() const;
void load_from_globals();
diff --git a/core/io/compression.cpp b/core/io/compression.cpp
index 662411a62e..f806c4da6d 100644
--- a/core/io/compression.cpp
+++ b/core/io/compression.cpp
@@ -28,11 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "compression.h"
-
+#include "global_config.h"
#include "os/copymem.h"
#include "zip_io.h"
#include "thirdparty/misc/fastlz.h"
+#include "thirdparty/zstd/zstd.h"
#include <zlib.h>
@@ -57,7 +58,8 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
strm.zalloc = zipio_alloc;
strm.zfree = zipio_free;
strm.opaque = Z_NULL;
- int err = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
+ int level = GLOBAL_GET("compression/zlib/compression_level");
+ int err = deflateInit(&strm, level);
if (err != Z_OK)
return -1;
@@ -76,6 +78,12 @@ int Compression::compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size,
return aout;
} break;
+ case MODE_ZSTD: {
+
+ int max_dst_size = get_max_compressed_buffer_size(p_src_size, MODE_ZSTD);
+ int level = GLOBAL_GET("compression/zstd/compression_level");
+ return ZSTD_compress(p_dst, max_dst_size, p_src, p_src_size, level);
+ } break;
}
ERR_FAIL_V(-1);
@@ -105,6 +113,10 @@ int Compression::get_max_compressed_buffer_size(int p_src_size, Mode p_mode) {
deflateEnd(&strm);
return aout;
} break;
+ case MODE_ZSTD: {
+
+ return ZSTD_compressBound(p_src_size);
+ } break;
}
ERR_FAIL_V(-1);
@@ -148,6 +160,10 @@ int Compression::decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p
ERR_FAIL_COND_V(err != Z_STREAM_END, -1);
return total;
} break;
+ case MODE_ZSTD: {
+
+ return ZSTD_decompress(p_dst, p_dst_max_size, p_src, p_src_size);
+ } break;
}
ERR_FAIL_V(-1);
diff --git a/core/io/compression.h b/core/io/compression.h
index a982a074b1..742f0f4d68 100644
--- a/core/io/compression.h
+++ b/core/io/compression.h
@@ -36,12 +36,13 @@ class Compression {
public:
enum Mode {
MODE_FASTLZ,
- MODE_DEFLATE
+ MODE_DEFLATE,
+ MODE_ZSTD
};
- static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
- static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_FASTLZ);
- static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_FASTLZ);
+ static int compress(uint8_t *p_dst, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
+ static int get_max_compressed_buffer_size(int p_src_size, Mode p_mode = MODE_ZSTD);
+ static int decompress(uint8_t *p_dst, int p_dst_max_size, const uint8_t *p_src, int p_src_size, Mode p_mode = MODE_ZSTD);
Compression();
};
diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp
index 4c6e8f5507..4e802579c6 100644
--- a/core/io/file_access_compressed.cpp
+++ b/core/io/file_access_compressed.cpp
@@ -369,7 +369,7 @@ FileAccessCompressed::FileAccessCompressed() {
f = NULL;
magic = "GCMP";
block_size = 16384;
- cmode = Compression::MODE_DEFLATE;
+ cmode = Compression::MODE_ZSTD;
writing = false;
write_ptr = 0;
write_buffer_size = 0;
diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h
index 6af9d9b6ca..340c298a0f 100644
--- a/core/io/file_access_compressed.h
+++ b/core/io/file_access_compressed.h
@@ -64,7 +64,7 @@ class FileAccessCompressed : public FileAccess {
FileAccess *f;
public:
- void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_FASTLZ, int p_block_size = 4096);
+ void configure(const String &p_magic, Compression::Mode p_mode = Compression::MODE_ZSTD, int p_block_size = 4096);
Error open_after_magic(FileAccess *p_base);
diff --git a/core/io/file_access_pack.cpp b/core/io/file_access_pack.cpp
index bb942b54d7..79aa39521f 100644
--- a/core/io/file_access_pack.cpp
+++ b/core/io/file_access_pack.cpp
@@ -440,13 +440,12 @@ Error DirAccessPack::change_dir(String p_dir) {
String DirAccessPack::get_current_dir() {
- String p;
PackedData::PackedDir *pd = current;
- while (pd->parent) {
+ String p = current->name;
- if (pd != current)
- p = "/" + p;
- p = p + pd->name;
+ while (pd->parent) {
+ pd = pd->parent;
+ p = pd->name + "/" + p;
}
return "res://" + p;
diff --git a/core/io/http_client.cpp b/core/io/http_client.cpp
index 899f3b3b2d..0c84a5213f 100644
--- a/core/io/http_client.cpp
+++ b/core/io/http_client.cpp
@@ -96,7 +96,12 @@ Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector
};
String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n";
- request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
+ if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) {
+ // don't append the standard ports
+ request += "Host: " + conn_host + "\r\n";
+ } else {
+ request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
+ }
bool add_clen = p_body.size() > 0;
for (int i = 0; i < p_headers.size(); i++) {
request += p_headers[i] + "\r\n";
@@ -151,7 +156,12 @@ Error HTTPClient::request(Method p_method, const String &p_url, const Vector<Str
};
String request = String(_methods[p_method]) + " " + p_url + " HTTP/1.1\r\n";
- request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
+ if ((ssl && conn_port == 443) || (!ssl && conn_port == 80)) {
+ // don't append the standard ports
+ request += "Host: " + conn_host + "\r\n";
+ } else {
+ request += "Host: " + conn_host + ":" + itos(conn_port) + "\r\n";
+ }
bool add_clen = p_body.length() > 0;
for (int i = 0; i < p_headers.size(); i++) {
request += p_headers[i] + "\r\n";
diff --git a/core/io/image_loader.cpp b/core/io/image_loader.cpp
index 4864c18831..23719940be 100644
--- a/core/io/image_loader.cpp
+++ b/core/io/image_loader.cpp
@@ -43,7 +43,8 @@ bool ImageFormatLoader::recognize(const String &p_extension) const {
return false;
}
-Error ImageLoader::load_image(String p_file, Image *p_image, FileAccess *p_custom) {
+Error ImageLoader::load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom, bool p_force_linear) {
+ ERR_FAIL_COND_V(p_image.is_null(), ERR_INVALID_PARAMETER);
FileAccess *f = p_custom;
if (!f) {
@@ -61,7 +62,7 @@ Error ImageLoader::load_image(String p_file, Image *p_image, FileAccess *p_custo
if (!loader[i]->recognize(extension))
continue;
- Error err = loader[i]->load_image(p_image, f);
+ Error err = loader[i]->load_image(p_image, f, p_force_linear);
if (err != ERR_FILE_UNRECOGNIZED) {
diff --git a/core/io/image_loader.h b/core/io/image_loader.h
index 37149dbe9d..e528d1423b 100644
--- a/core/io/image_loader.h
+++ b/core/io/image_loader.h
@@ -56,7 +56,7 @@ class ImageFormatLoader {
friend class ImageLoader;
protected:
- virtual Error load_image(Image *p_image, FileAccess *p_fileaccess) = 0;
+ virtual Error load_image(Ref<Image> p_image, FileAccess *p_fileaccess, bool p_force_linear) = 0;
virtual void get_recognized_extensions(List<String> *p_extensions) const = 0;
bool recognize(const String &p_extension) const;
@@ -75,7 +75,7 @@ class ImageLoader {
protected:
public:
- static Error load_image(String p_file, Image *p_image, FileAccess *p_custom = NULL);
+ static Error load_image(String p_file, Ref<Image> p_image, FileAccess *p_custom = NULL, bool p_force_linear = false);
static void get_recognized_extensions(List<String> *p_extensions);
static bool recognize(const String &p_extension);
diff --git a/core/io/ip.cpp b/core/io/ip.cpp
index bf139eeacb..6c463b983c 100644
--- a/core/io/ip.cpp
+++ b/core/io/ip.cpp
@@ -68,6 +68,7 @@ struct _IP_ResolverPrivate {
return IP::RESOLVER_INVALID_ID;
}
+ Mutex *mutex;
Semaphore *sem;
Thread *thread;
@@ -96,8 +97,10 @@ struct _IP_ResolverPrivate {
while (!ipr->thread_abort) {
ipr->sem->wait();
- GLOBAL_LOCK_FUNCTION;
+
+ ipr->mutex->lock();
ipr->resolve_queues();
+ ipr->mutex->unlock();
}
}
@@ -110,24 +113,30 @@ struct _IP_ResolverPrivate {
IP_Address IP::resolve_hostname(const String &p_hostname, IP::Type p_type) {
- GLOBAL_LOCK_FUNCTION;
+ resolver->mutex->lock();
String key = _IP_ResolverPrivate::get_cache_key(p_hostname, p_type);
- if (resolver->cache.has(key))
- return resolver->cache[key];
+ if (resolver->cache.has(key)) {
+ IP_Address res = resolver->cache[key];
+ resolver->mutex->unlock();
+ return res;
+ }
IP_Address res = _resolve_hostname(p_hostname, p_type);
resolver->cache[key] = res;
+ resolver->mutex->unlock();
return res;
}
+
IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Type p_type) {
- GLOBAL_LOCK_FUNCTION;
+ resolver->mutex->lock();
ResolverID id = resolver->find_empty_id();
if (id == RESOLVER_INVALID_ID) {
WARN_PRINT("Out of resolver queries");
+ resolver->mutex->unlock();
return id;
}
@@ -146,6 +155,7 @@ IP::ResolverID IP::resolve_hostname_queue_item(const String &p_hostname, IP::Typ
resolver->resolve_queues();
}
+ resolver->mutex->unlock();
return id;
}
@@ -153,35 +163,51 @@ IP::ResolverStatus IP::get_resolve_item_status(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP::RESOLVER_STATUS_NONE);
- GLOBAL_LOCK_FUNCTION;
- ERR_FAIL_COND_V(resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE, IP::RESOLVER_STATUS_NONE);
+ resolver->mutex->lock();
+ if (resolver->queue[p_id].status == IP::RESOLVER_STATUS_NONE) {
+ ERR_PRINT("Condition status == IP::RESOLVER_STATUS_NONE");
+ resolver->mutex->unlock();
+ return IP::RESOLVER_STATUS_NONE;
+ }
+ IP::ResolverStatus res = resolver->queue[p_id].status;
- return resolver->queue[p_id].status;
+ resolver->mutex->unlock();
+ return res;
}
+
IP_Address IP::get_resolve_item_address(ResolverID p_id) const {
ERR_FAIL_INDEX_V(p_id, IP::RESOLVER_MAX_QUERIES, IP_Address());
- GLOBAL_LOCK_FUNCTION;
+ resolver->mutex->lock();
if (resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE) {
- ERR_EXPLAIN("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
- ERR_FAIL_COND_V(resolver->queue[p_id].status != IP::RESOLVER_STATUS_DONE, IP_Address());
+ ERR_PRINTS("Resolve of '" + resolver->queue[p_id].hostname + "'' didn't complete yet.");
+ resolver->mutex->unlock();
+ return IP_Address();
}
- return resolver->queue[p_id].response;
+ IP_Address res = resolver->queue[p_id].response;
+
+ resolver->mutex->unlock();
+ return res;
}
+
void IP::erase_resolve_item(ResolverID p_id) {
ERR_FAIL_INDEX(p_id, IP::RESOLVER_MAX_QUERIES);
- GLOBAL_LOCK_FUNCTION;
+ resolver->mutex->lock();
resolver->queue[p_id].status = IP::RESOLVER_STATUS_NONE;
+
+ resolver->mutex->unlock();
}
void IP::clear_cache(const String &p_hostname) {
+ resolver->mutex->lock();
+
if (p_hostname.empty()) {
resolver->cache.clear();
} else {
@@ -190,7 +216,9 @@ void IP::clear_cache(const String &p_hostname) {
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_IPV6));
resolver->cache.erase(_IP_ResolverPrivate::get_cache_key(p_hostname, IP::TYPE_ANY));
}
-};
+
+ resolver->mutex->unlock();
+}
Array IP::_get_local_addresses() const {
@@ -249,12 +277,11 @@ IP::IP() {
singleton = this;
resolver = memnew(_IP_ResolverPrivate);
resolver->sem = NULL;
+ resolver->mutex = Mutex::create();
#ifndef NO_THREADS
- //resolver->sem = Semaphore::create();
-
- resolver->sem = NULL;
+ resolver->sem = Semaphore::create();
if (resolver->sem) {
resolver->thread_abort = false;
@@ -281,7 +308,9 @@ IP::~IP() {
memdelete(resolver->thread);
memdelete(resolver->sem);
}
- memdelete(resolver);
#endif
+
+ memdelete(resolver->mutex);
+ memdelete(resolver);
}
diff --git a/core/io/marshalls.cpp b/core/io/marshalls.cpp
index 5e66b7f7f5..75dfd563dd 100644
--- a/core/io/marshalls.cpp
+++ b/core/io/marshalls.cpp
@@ -139,8 +139,8 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V(len < (int)4 * 4, ERR_INVALID_DATA);
Rect2 val;
- val.pos.x = decode_float(&buf[0]);
- val.pos.y = decode_float(&buf[4]);
+ val.position.x = decode_float(&buf[0]);
+ val.position.y = decode_float(&buf[4]);
val.size.x = decode_float(&buf[8]);
val.size.y = decode_float(&buf[12]);
r_variant = val;
@@ -211,9 +211,9 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
ERR_FAIL_COND_V(len < (int)4 * 6, ERR_INVALID_DATA);
Rect3 val;
- val.pos.x = decode_float(&buf[0]);
- val.pos.y = decode_float(&buf[4]);
- val.pos.z = decode_float(&buf[8]);
+ val.position.x = decode_float(&buf[0]);
+ val.position.y = decode_float(&buf[4]);
+ val.position.z = decode_float(&buf[8]);
val.size.x = decode_float(&buf[12]);
val.size.y = decode_float(&buf[16]);
val.size.z = decode_float(&buf[20]);
@@ -276,38 +276,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
(*r_len) += 4 * 4;
} break;
- case Variant::IMAGE: {
-
- ERR_FAIL_COND_V(len < (int)5 * 4, ERR_INVALID_DATA);
- Image::Format fmt = (Image::Format)decode_uint32(&buf[0]);
- ERR_FAIL_INDEX_V(fmt, Image::FORMAT_MAX, ERR_INVALID_DATA);
- uint32_t mipmaps = decode_uint32(&buf[4]);
- uint32_t w = decode_uint32(&buf[8]);
- uint32_t h = decode_uint32(&buf[12]);
- uint32_t datalen = decode_uint32(&buf[16]);
-
- Image img;
- if (datalen > 0) {
- len -= 5 * 4;
- ERR_FAIL_COND_V(len < datalen, ERR_INVALID_DATA);
- PoolVector<uint8_t> data;
- data.resize(datalen);
- PoolVector<uint8_t>::Write wr = data.write();
- copymem(&wr[0], &buf[20], datalen);
- wr = PoolVector<uint8_t>::Write();
-
- img = Image(w, h, mipmaps, fmt, data);
- }
-
- r_variant = img;
- if (r_len) {
- if (datalen % 4)
- (*r_len) += 4 - datalen % 4;
-
- (*r_len) += 4 * 5 + datalen;
- }
-
- } break;
case Variant::NODE_PATH: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -397,66 +365,6 @@ Error decode_variant(Variant &r_variant, const uint8_t *p_buffer, int p_len, int
r_variant = (Object *)NULL;
} break;
- case Variant::INPUT_EVENT: {
-
- InputEvent ie;
-
- ie.type = decode_uint32(&buf[0]);
- ie.device = decode_uint32(&buf[4]);
-
- if (r_len)
- (*r_len) += 12;
-
- switch (ie.type) {
-
- case InputEvent::KEY: {
-
- uint32_t mods = decode_uint32(&buf[12]);
- if (mods & KEY_MASK_SHIFT)
- ie.key.mod.shift = true;
- if (mods & KEY_MASK_CTRL)
- ie.key.mod.control = true;
- if (mods & KEY_MASK_ALT)
- ie.key.mod.alt = true;
- if (mods & KEY_MASK_META)
- ie.key.mod.meta = true;
- ie.key.scancode = decode_uint32(&buf[16]);
-
- if (r_len)
- (*r_len) += 8;
-
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- ie.mouse_button.button_index = decode_uint32(&buf[12]);
- if (r_len)
- (*r_len) += 4;
-
- } break;
- case InputEvent::JOYPAD_BUTTON: {
-
- ie.joy_button.button_index = decode_uint32(&buf[12]);
- if (r_len)
- (*r_len) += 4;
- } break;
- case InputEvent::SCREEN_TOUCH: {
-
- ie.screen_touch.index = decode_uint32(&buf[12]);
- if (r_len)
- (*r_len) += 4;
- } break;
- case InputEvent::JOYPAD_MOTION: {
-
- ie.joy_motion.axis = decode_uint32(&buf[12]);
- ie.joy_motion.axis_value = decode_float(&buf[16]);
- if (r_len)
- (*r_len) += 8;
- } break;
- }
-
- r_variant = ie;
-
- } break;
case Variant::DICTIONARY: {
ERR_FAIL_COND_V(len < 4, ERR_INVALID_DATA);
@@ -953,8 +861,8 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
if (buf) {
Rect2 r2 = p_variant;
- encode_float(r2.pos.x, &buf[0]);
- encode_float(r2.pos.y, &buf[4]);
+ encode_float(r2.position.x, &buf[0]);
+ encode_float(r2.position.y, &buf[4]);
encode_float(r2.size.x, &buf[8]);
encode_float(r2.size.y, &buf[12]);
}
@@ -1018,9 +926,9 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
if (buf) {
Rect3 aabb = p_variant;
- encode_float(aabb.pos.x, &buf[0]);
- encode_float(aabb.pos.y, &buf[4]);
- encode_float(aabb.pos.z, &buf[8]);
+ encode_float(aabb.position.x, &buf[0]);
+ encode_float(aabb.position.y, &buf[4]);
+ encode_float(aabb.position.z, &buf[8]);
encode_float(aabb.size.x, &buf[12]);
encode_float(aabb.size.y, &buf[16]);
encode_float(aabb.size.z, &buf[20]);
@@ -1078,30 +986,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
r_len += 4 * 4;
} break;
- case Variant::IMAGE: {
-
- Image image = p_variant;
- PoolVector<uint8_t> data = image.get_data();
-
- if (buf) {
-
- encode_uint32(image.get_format(), &buf[0]);
- encode_uint32(image.has_mipmaps(), &buf[4]);
- encode_uint32(image.get_width(), &buf[8]);
- encode_uint32(image.get_height(), &buf[12]);
- int ds = data.size();
- encode_uint32(ds, &buf[16]);
- PoolVector<uint8_t>::Read r = data.read();
- copymem(&buf[20], &r[0], ds);
- }
-
- int pad = 0;
- if (data.size() % 4)
- pad = 4 - data.size() % 4;
-
- r_len += data.size() + 5 * 4 + pad;
-
- } break;
/*case Variant::RESOURCE: {
ERR_EXPLAIN("Can't marshallize resources");
@@ -1111,83 +995,6 @@ Error encode_variant(const Variant &p_variant, uint8_t *r_buffer, int &r_len) {
case Variant::OBJECT: {
} break;
- case Variant::INPUT_EVENT: {
-
- InputEvent ie = p_variant;
-
- if (buf) {
-
- encode_uint32(ie.type, &buf[0]);
- encode_uint32(ie.device, &buf[4]);
- encode_uint32(0, &buf[8]);
- }
-
- int llen = 12;
-
- switch (ie.type) {
-
- case InputEvent::KEY: {
-
- if (buf) {
-
- uint32_t mods = 0;
- if (ie.key.mod.shift)
- mods |= KEY_MASK_SHIFT;
- if (ie.key.mod.control)
- mods |= KEY_MASK_CTRL;
- if (ie.key.mod.alt)
- mods |= KEY_MASK_ALT;
- if (ie.key.mod.meta)
- mods |= KEY_MASK_META;
-
- encode_uint32(mods, &buf[llen]);
- encode_uint32(ie.key.scancode, &buf[llen + 4]);
- }
- llen += 8;
-
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- if (buf) {
-
- encode_uint32(ie.mouse_button.button_index, &buf[llen]);
- }
- llen += 4;
- } break;
- case InputEvent::JOYPAD_BUTTON: {
-
- if (buf) {
-
- encode_uint32(ie.joy_button.button_index, &buf[llen]);
- }
- llen += 4;
- } break;
- case InputEvent::SCREEN_TOUCH: {
-
- if (buf) {
-
- encode_uint32(ie.screen_touch.index, &buf[llen]);
- }
- llen += 4;
- } break;
- case InputEvent::JOYPAD_MOTION: {
-
- if (buf) {
-
- int axis = ie.joy_motion.axis;
- encode_uint32(axis, &buf[llen]);
- encode_float(ie.joy_motion.axis_value, &buf[llen + 4]);
- }
- llen += 8;
- } break;
- }
-
- if (buf)
- encode_uint32(llen, &buf[8]);
- r_len += llen;
-
- // not supported
- } break;
case Variant::DICTIONARY: {
Dictionary d = p_variant;
diff --git a/core/io/resource_format_binary.cpp b/core/io/resource_format_binary.cpp
index fc18a44ed3..0373176cd2 100644
--- a/core/io/resource_format_binary.cpp
+++ b/core/io/resource_format_binary.cpp
@@ -49,12 +49,12 @@ enum {
VARIANT_VECTOR3 = 12,
VARIANT_PLANE = 13,
VARIANT_QUAT = 14,
- VARIANT_AABB = 15,
+ VARIANT_RECT3 = 15,
VARIANT_MATRIX3 = 16,
VARIANT_TRANSFORM = 17,
VARIANT_MATRIX32 = 18,
VARIANT_COLOR = 20,
- VARIANT_IMAGE = 21,
+ //VARIANT_IMAGE = 21, - no longer variant type
VARIANT_NODE_PATH = 22,
VARIANT_RID = 23,
VARIANT_OBJECT = 24,
@@ -71,11 +71,6 @@ enum {
VARIANT_INT64 = 40,
VARIANT_DOUBLE = 41,
- IMAGE_ENCODING_EMPTY = 0,
- IMAGE_ENCODING_RAW = 1,
- IMAGE_ENCODING_LOSSLESS = 2,
- IMAGE_ENCODING_LOSSY = 3,
-
OBJECT_EMPTY = 0,
OBJECT_EXTERNAL_RESOURCE = 1,
OBJECT_INTERNAL_RESOURCE = 2,
@@ -160,8 +155,8 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
case VARIANT_RECT2: {
Rect2 v;
- v.pos.x = f->get_real();
- v.pos.y = f->get_real();
+ v.position.x = f->get_real();
+ v.position.y = f->get_real();
v.size.x = f->get_real();
v.size.y = f->get_real();
r_v = v;
@@ -193,12 +188,12 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
- case VARIANT_AABB: {
+ case VARIANT_RECT3: {
Rect3 v;
- v.pos.x = f->get_real();
- v.pos.y = f->get_real();
- v.pos.z = f->get_real();
+ v.position.x = f->get_real();
+ v.position.y = f->get_real();
+ v.position.z = f->get_real();
v.size.x = f->get_real();
v.size.y = f->get_real();
v.size.z = f->get_real();
@@ -259,74 +254,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
r_v = v;
} break;
- case VARIANT_IMAGE: {
-
- uint32_t encoding = f->get_32();
- if (encoding == IMAGE_ENCODING_EMPTY) {
- r_v = Variant();
- break;
- } else if (encoding == IMAGE_ENCODING_RAW) {
- uint32_t width = f->get_32();
- uint32_t height = f->get_32();
- uint32_t mipmaps = f->get_32();
- uint32_t format = f->get_32();
- const uint32_t format_version_shift = 24;
- const uint32_t format_version_mask = format_version_shift - 1;
-
- uint32_t format_version = format >> format_version_shift;
-
- const uint32_t current_version = 0;
- if (format_version > current_version) {
-
- ERR_PRINT("Format version for encoded binary image is too new");
- return ERR_PARSE_ERROR;
- }
-
- Image::Format fmt = Image::Format(format & format_version_mask); //if format changes, we can add a compatibility bit on top
-
- uint32_t datalen = f->get_32();
- print_line("image format: " + String(Image::get_format_name(fmt)) + " datalen " + itos(datalen));
-
- PoolVector<uint8_t> imgdata;
- imgdata.resize(datalen);
- PoolVector<uint8_t>::Write w = imgdata.write();
- f->get_buffer(w.ptr(), datalen);
- _advance_padding(datalen);
- w = PoolVector<uint8_t>::Write();
-
-#ifdef TOOLS_ENABLED
- //compatibility
- int correct_size = Image::get_image_data_size(width, height, fmt, mipmaps ? -1 : 0);
- if (correct_size < datalen) {
- WARN_PRINT("Image data was too large, shrinking for compatibility")
- imgdata.resize(correct_size);
- }
-#endif
- r_v = Image(width, height, mipmaps, fmt, imgdata);
-
- } else {
- //compressed
- PoolVector<uint8_t> data;
- data.resize(f->get_32());
- PoolVector<uint8_t>::Write w = data.write();
- f->get_buffer(w.ptr(), data.size());
- w = PoolVector<uint8_t>::Write();
-
- Image img;
- if (encoding == IMAGE_ENCODING_LOSSY && Image::lossy_unpacker) {
-
- img = Image::lossy_unpacker(data);
- } else if (encoding == IMAGE_ENCODING_LOSSLESS && Image::lossless_unpacker) {
-
- img = Image::lossless_unpacker(data);
- }
- _advance_padding(data.size());
-
- r_v = img;
- }
-
- } break;
case VARIANT_NODE_PATH: {
Vector<StringName> names;
@@ -431,13 +359,6 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant &r_v) {
}
} break;
- case VARIANT_INPUT_EVENT: {
-
- InputEvent ev;
- ev.type = f->get_32(); //will only work for null though.
- r_v = ev;
-
- } break;
case VARIANT_DICTIONARY: {
uint32_t len = f->get_32();
@@ -1367,8 +1288,8 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
f->store_32(VARIANT_RECT2);
Rect2 val = p_property;
- f->store_real(val.pos.x);
- f->store_real(val.pos.y);
+ f->store_real(val.position.x);
+ f->store_real(val.position.y);
f->store_real(val.size.x);
f->store_real(val.size.y);
@@ -1404,11 +1325,11 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
} break;
case Variant::RECT3: {
- f->store_32(VARIANT_AABB);
+ f->store_32(VARIANT_RECT3);
Rect3 val = p_property;
- f->store_real(val.pos.x);
- f->store_real(val.pos.y);
- f->store_real(val.pos.z);
+ f->store_real(val.position.x);
+ f->store_real(val.position.y);
+ f->store_real(val.position.z);
f->store_real(val.size.x);
f->store_real(val.size.y);
f->store_real(val.size.z);
@@ -1469,67 +1390,7 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
f->store_real(val.a);
} break;
- case Variant::IMAGE: {
-
- f->store_32(VARIANT_IMAGE);
- Image val = p_property;
- if (val.empty()) {
- f->store_32(IMAGE_ENCODING_EMPTY);
- break;
- }
-
- int encoding = IMAGE_ENCODING_RAW;
- float quality = 0.7;
-
- if (!val.is_compressed()) {
- //can only compress uncompressed stuff
-
- if (p_hint.hint == PROPERTY_HINT_IMAGE_COMPRESS_LOSSY && Image::lossy_packer) {
- encoding = IMAGE_ENCODING_LOSSY;
- float qs = p_hint.hint_string.to_double();
- if (qs != 0.0)
- quality = qs;
-
- } else if (p_hint.hint == PROPERTY_HINT_IMAGE_COMPRESS_LOSSLESS && Image::lossless_packer) {
- encoding = IMAGE_ENCODING_LOSSLESS;
- }
- }
-
- f->store_32(encoding); //raw encoding
-
- if (encoding == IMAGE_ENCODING_RAW) {
-
- f->store_32(val.get_width());
- f->store_32(val.get_height());
- f->store_32(val.has_mipmaps());
- f->store_32(val.get_format()); //if format changes we can add a compatibility version bit
-
- int dlen = val.get_data().size();
- f->store_32(dlen);
- PoolVector<uint8_t>::Read r = val.get_data().read();
- f->store_buffer(r.ptr(), dlen);
- _pad_buffer(dlen);
- } else {
- PoolVector<uint8_t> data;
- if (encoding == IMAGE_ENCODING_LOSSY) {
- data = Image::lossy_packer(val, quality);
-
- } else if (encoding == IMAGE_ENCODING_LOSSLESS) {
- data = Image::lossless_packer(val);
- }
-
- int ds = data.size();
- f->store_32(ds);
- if (ds > 0) {
- PoolVector<uint8_t>::Read r = data.read();
- f->store_buffer(r.ptr(), ds);
-
- _pad_buffer(ds);
- }
- }
-
- } break;
case Variant::NODE_PATH: {
f->store_32(VARIANT_NODE_PATH);
NodePath np = p_property;
@@ -1578,13 +1439,6 @@ void ResourceFormatSaverBinaryInstance::write_variant(const Variant &p_property,
}
} break;
- case Variant::INPUT_EVENT: {
-
- f->store_32(VARIANT_INPUT_EVENT);
- InputEvent event = p_property;
- f->store_32(0); //event type none, nothing else suported for now.
-
- } break;
case Variant::DICTIONARY: {
f->store_32(VARIANT_DICTIONARY);
diff --git a/core/io/resource_import.h b/core/io/resource_import.h
index 25b7a534b2..9d2a5180dc 100644
--- a/core/io/resource_import.h
+++ b/core/io/resource_import.h
@@ -61,6 +61,7 @@ public:
String get_internal_resource_path(const String &p_path) const;
void add_importer(const Ref<ResourceImporter> &p_importer) { importers.insert(p_importer); }
+ void remove_importer(const Ref<ResourceImporter> &p_importer) { importers.erase(p_importer); }
Ref<ResourceImporter> get_importer_by_name(const String &p_name);
Ref<ResourceImporter> get_importer_by_extension(const String &p_extension);
void get_importers_for_extension(const String &p_extension, List<Ref<ResourceImporter> > *r_importers);
diff --git a/core/math/a_star.cpp b/core/math/a_star.cpp
index c327f7ca44..838fec22f0 100644
--- a/core/math/a_star.cpp
+++ b/core/math/a_star.cpp
@@ -43,6 +43,7 @@ int AStar::get_available_point_id() const {
void AStar::add_point(int p_id, const Vector3 &p_pos, real_t p_weight_scale) {
ERR_FAIL_COND(p_id < 0);
+ ERR_FAIL_COND(p_weight_scale < 1);
if (!points.has(p_id)) {
Point *pt = memnew(Point);
pt->id = p_id;
@@ -86,7 +87,7 @@ void AStar::remove_point(int p_id) {
points.erase(p_id);
}
-void AStar::connect_points(int p_id, int p_with_id) {
+void AStar::connect_points(int p_id, int p_with_id, bool bidirectional) {
ERR_FAIL_COND(!points.has(p_id));
ERR_FAIL_COND(!points.has(p_with_id));
@@ -95,7 +96,9 @@ void AStar::connect_points(int p_id, int p_with_id) {
Point *a = points[p_id];
Point *b = points[p_with_id];
a->neighbours.push_back(b);
- b->neighbours.push_back(a);
+
+ if (bidirectional)
+ b->neighbours.push_back(a);
Segment s(p_id, p_with_id);
if (s.from == p_id) {
@@ -190,8 +193,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
Point *n = begin_point->neighbours[i];
n->prev_point = begin_point;
- n->distance = _compute_cost(n->id, begin_point->id);
- n->distance *= n->weight_scale;
+ n->distance = _compute_cost(begin_point->id, n->id) * n->weight_scale;
n->last_pass = pass;
open_list.add(&n->list);
@@ -219,7 +221,6 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
real_t cost = p->distance;
cost += _estimate_cost(p->id, end_point->id);
- cost *= p->weight_scale;
if (cost < least_cost) {
@@ -236,8 +237,7 @@ bool AStar::_solve(Point *begin_point, Point *end_point) {
Point *e = p->neighbours[i];
- real_t distance = _compute_cost(p->id, e->id) + p->distance;
- distance *= e->weight_scale;
+ real_t distance = _compute_cost(p->id, e->id) * e->weight_scale + p->distance;
if (e->last_pass == pass) {
//oh this was visited already, can we win the cost?
@@ -401,7 +401,7 @@ void AStar::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_point_weight_scale", "id"), &AStar::get_point_weight_scale);
ClassDB::bind_method(D_METHOD("remove_point", "id"), &AStar::remove_point);
- ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id"), &AStar::connect_points);
+ ClassDB::bind_method(D_METHOD("connect_points", "id", "to_id", "bidirectional"), &AStar::connect_points, DEFVAL(true));
ClassDB::bind_method(D_METHOD("disconnect_points", "id", "to_id"), &AStar::disconnect_points);
ClassDB::bind_method(D_METHOD("are_points_connected", "id", "to_id"), &AStar::are_points_connected);
diff --git a/core/math/a_star.h b/core/math/a_star.h
index b9c8833386..34a5358344 100644
--- a/core/math/a_star.h
+++ b/core/math/a_star.h
@@ -105,7 +105,7 @@ public:
real_t get_point_weight_scale(int p_id) const;
void remove_point(int p_id);
- void connect_points(int p_id, int p_with_id);
+ void connect_points(int p_id, int p_with_id, bool bidirectional = true);
void disconnect_points(int p_id, int p_with_id);
bool are_points_connected(int p_id, int p_with_id) const;
diff --git a/core/math/bsp_tree.cpp b/core/math/bsp_tree.cpp
index 9bbce752c0..327a6017c3 100644
--- a/core/math/bsp_tree.cpp
+++ b/core/math/bsp_tree.cpp
@@ -39,8 +39,8 @@ void BSP_Tree::from_aabb(const Rect3 &p_aabb) {
Vector3 n;
n[i] = 1;
- planes.push_back(Plane(n, p_aabb.pos[i] + p_aabb.size[i]));
- planes.push_back(Plane(-n, -p_aabb.pos[i]));
+ planes.push_back(Plane(n, p_aabb.position[i] + p_aabb.size[i]));
+ planes.push_back(Plane(-n, -p_aabb.position[i]));
}
nodes.clear();
@@ -552,7 +552,7 @@ BSP_Tree::BSP_Tree(const PoolVector<Face3> &p_faces, real_t p_error_radius) {
if (first) {
- aabb.pos = f.vertex[0];
+ aabb.position = f.vertex[0];
first = false;
} else {
diff --git a/core/math/camera_matrix.cpp b/core/math/camera_matrix.cpp
index 5b072b7c53..33ad522315 100644
--- a/core/math/camera_matrix.cpp
+++ b/core/math/camera_matrix.cpp
@@ -507,8 +507,8 @@ void CameraMatrix::set_light_atlas_rect(const Rect2 &p_rect) {
m[9] = 0.0,
m[10] = 1.0,
m[11] = 0.0,
- m[12] = p_rect.pos.x,
- m[13] = p_rect.pos.y,
+ m[12] = p_rect.position.x,
+ m[13] = p_rect.position.y,
m[14] = 0.0,
m[15] = 1.0;
}
@@ -559,8 +559,8 @@ void CameraMatrix::make_scale(const Vector3 &p_scale) {
void CameraMatrix::scale_translate_to_fit(const Rect3 &p_aabb) {
- Vector3 min = p_aabb.pos;
- Vector3 max = p_aabb.pos + p_aabb.size;
+ Vector3 min = p_aabb.position;
+ Vector3 max = p_aabb.position + p_aabb.size;
matrix[0][0] = 2 / (max.x - min.x);
matrix[1][0] = 0;
diff --git a/core/math/face3.cpp b/core/math/face3.cpp
index 6d772cf08c..5b66e1999a 100644
--- a/core/math/face3.cpp
+++ b/core/math/face3.cpp
@@ -197,20 +197,20 @@ bool Face3::intersects_aabb(const Rect3 &p_aabb) const {
/** TEST FACE AXIS */
-#define TEST_AXIS(m_ax) \
- { \
- real_t aabb_min = p_aabb.pos.m_ax; \
- real_t aabb_max = p_aabb.pos.m_ax + p_aabb.size.m_ax; \
- real_t tri_min, tri_max; \
- for (int i = 0; i < 3; i++) { \
- if (i == 0 || vertex[i].m_ax > tri_max) \
- tri_max = vertex[i].m_ax; \
- if (i == 0 || vertex[i].m_ax < tri_min) \
- tri_min = vertex[i].m_ax; \
- } \
- \
- if (tri_max < aabb_min || aabb_max < tri_min) \
- return false; \
+#define TEST_AXIS(m_ax) \
+ { \
+ real_t aabb_min = p_aabb.position.m_ax; \
+ real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
+ real_t tri_min, tri_max; \
+ for (int i = 0; i < 3; i++) { \
+ if (i == 0 || vertex[i].m_ax > tri_max) \
+ tri_max = vertex[i].m_ax; \
+ if (i == 0 || vertex[i].m_ax < tri_min) \
+ tri_min = vertex[i].m_ax; \
+ } \
+ \
+ if (tri_max < aabb_min || aabb_max < tri_min) \
+ return false; \
}
TEST_AXIS(x);
diff --git a/core/math/face3.h b/core/math/face3.h
index 31ab72b925..1cc94321c3 100644
--- a/core/math/face3.h
+++ b/core/math/face3.h
@@ -101,7 +101,7 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const {
Vector3 perp = (vertex[0] - vertex[2]).cross(vertex[0] - vertex[1]);
Vector3 half_extents = p_aabb.size * 0.5;
- Vector3 ofs = p_aabb.pos + half_extents;
+ Vector3 ofs = p_aabb.position + half_extents;
Vector3 sup = Vector3(
(perp.x > 0) ? -half_extents.x : half_extents.x,
@@ -117,8 +117,8 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const {
#define TEST_AXIS(m_ax) \
{ \
- real_t aabb_min = p_aabb.pos.m_ax; \
- real_t aabb_max = p_aabb.pos.m_ax + p_aabb.size.m_ax; \
+ real_t aabb_min = p_aabb.position.m_ax; \
+ real_t aabb_max = p_aabb.position.m_ax + p_aabb.size.m_ax; \
real_t tri_min, tri_max; \
for (int i = 0; i < 3; i++) { \
if (i == 0 || vertex[i].m_ax > tri_max) \
@@ -150,68 +150,68 @@ bool Face3::intersects_aabb2(const Rect3 &p_aabb) const {
case 0: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
} break;
case 1: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
} break;
case 2: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 3: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 4: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 5: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 6: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 7: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 8: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
case 9: {
- from = Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 10: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z);
} break;
case 11: {
- from = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z);
- to = Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z);
+ from = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z);
+ to = Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z);
} break;
}
diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp
index 618017f8b3..2bea514d37 100644
--- a/core/math/geometry.cpp
+++ b/core/math/geometry.cpp
@@ -301,7 +301,7 @@ enum _CellFlags {
static inline void _plot_face(uint8_t ***p_cell_status, int x, int y, int z, int len_x, int len_y, int len_z, const Vector3 &voxelsize, const Face3 &p_face) {
Rect3 aabb(Vector3(x, y, z), Vector3(len_x, len_y, len_z));
- aabb.pos = aabb.pos * voxelsize;
+ aabb.position = aabb.position * voxelsize;
aabb.size = aabb.size * voxelsize;
if (!p_face.intersects_aabb(aabb))
@@ -640,7 +640,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
Face3 f = faces[i];
for (int j = 0; j < 3; j++) {
- f.vertex[j] -= global_aabb.pos;
+ f.vertex[j] -= global_aabb.position;
}
_plot_face(cell_status, 0, 0, 0, div_x, div_y, div_z, voxelsize, f);
}
@@ -707,7 +707,7 @@ PoolVector<Face3> Geometry::wrap_geometry(PoolVector<Face3> p_array, real_t *p_e
Vector3 &v = wrapped_faces_ptr[i].vertex[j];
v = v * voxelsize;
- v += global_aabb.pos;
+ v += global_aabb.position;
}
}
diff --git a/core/math/math_2d.cpp b/core/math/math_2d.cpp
index 962a42acb9..52e240ed47 100644
--- a/core/math/math_2d.cpp
+++ b/core/math/math_2d.cpp
@@ -308,7 +308,7 @@ bool Rect2::intersects_segment(const Point2 &p_from, const Point2 &p_to, Point2
for (int i = 0; i < 2; i++) {
real_t seg_from = p_from[i];
real_t seg_to = p_to[i];
- real_t box_begin = pos[i];
+ real_t box_begin = position[i];
real_t box_end = box_begin + size[i];
real_t cmin, cmax;
real_t csign;
diff --git a/core/math/math_2d.h b/core/math/math_2d.h
index 128b74baf6..780bb532d7 100644
--- a/core/math/math_2d.h
+++ b/core/math/math_2d.h
@@ -207,24 +207,24 @@ struct Transform2D;
struct Rect2 {
- Point2 pos;
+ Point2 position;
Size2 size;
- const Vector2 &get_pos() const { return pos; }
- void set_pos(const Vector2 &p_pos) { pos = p_pos; }
+ const Vector2 &get_position() const { return position; }
+ void set_position(const Vector2 &p_pos) { position = p_pos; }
const Vector2 &get_size() const { return size; }
void set_size(const Vector2 &p_size) { size = p_size; }
real_t get_area() const { return size.width * size.height; }
inline bool intersects(const Rect2 &p_rect) const {
- if (pos.x >= (p_rect.pos.x + p_rect.size.width))
+ if (position.x >= (p_rect.position.x + p_rect.size.width))
return false;
- if ((pos.x + size.width) <= p_rect.pos.x)
+ if ((position.x + size.width) <= p_rect.position.x)
return false;
- if (pos.y >= (p_rect.pos.y + p_rect.size.height))
+ if (position.y >= (p_rect.position.y + p_rect.size.height))
return false;
- if ((pos.y + size.height) <= p_rect.pos.y)
+ if ((position.y + size.height) <= p_rect.position.y)
return false;
return true;
@@ -234,17 +234,17 @@ struct Rect2 {
real_t dist = 1e20;
- if (p_point.x < pos.x) {
- dist = MIN(dist, pos.x - p_point.x);
+ if (p_point.x < position.x) {
+ dist = MIN(dist, position.x - p_point.x);
}
- if (p_point.y < pos.y) {
- dist = MIN(dist, pos.y - p_point.y);
+ if (p_point.y < position.y) {
+ dist = MIN(dist, position.y - p_point.y);
}
- if (p_point.x >= (pos.x + size.x)) {
- dist = MIN(p_point.x - (pos.x + size.x), dist);
+ if (p_point.x >= (position.x + size.x)) {
+ dist = MIN(p_point.x - (position.x + size.x), dist);
}
- if (p_point.y >= (pos.y + size.y)) {
- dist = MIN(p_point.y - (pos.y + size.y), dist);
+ if (p_point.y >= (position.y + size.y)) {
+ dist = MIN(p_point.y - (position.y + size.y), dist);
}
if (dist == 1e20)
@@ -259,9 +259,9 @@ struct Rect2 {
inline bool encloses(const Rect2 &p_rect) const {
- return (p_rect.pos.x >= pos.x) && (p_rect.pos.y >= pos.y) &&
- ((p_rect.pos.x + p_rect.size.x) < (pos.x + size.x)) &&
- ((p_rect.pos.y + p_rect.size.y) < (pos.y + size.y));
+ return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
+ ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
}
inline bool has_no_area() const {
@@ -275,14 +275,14 @@ struct Rect2 {
if (!intersects(new_rect))
return Rect2();
- new_rect.pos.x = MAX(p_rect.pos.x, pos.x);
- new_rect.pos.y = MAX(p_rect.pos.y, pos.y);
+ new_rect.position.x = MAX(p_rect.position.x, position.x);
+ new_rect.position.y = MAX(p_rect.position.y, position.y);
- Point2 p_rect_end = p_rect.pos + p_rect.size;
- Point2 end = pos + size;
+ Point2 p_rect_end = p_rect.position + p_rect.size;
+ Point2 end = position + size;
- new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.pos.x;
- new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.pos.y;
+ new_rect.size.x = MIN(p_rect_end.x, end.x) - new_rect.position.x;
+ new_rect.size.y = MIN(p_rect_end.y, end.y) - new_rect.position.y;
return new_rect;
}
@@ -291,25 +291,25 @@ struct Rect2 {
Rect2 new_rect;
- new_rect.pos.x = MIN(p_rect.pos.x, pos.x);
- new_rect.pos.y = MIN(p_rect.pos.y, pos.y);
+ new_rect.position.x = MIN(p_rect.position.x, position.x);
+ new_rect.position.y = MIN(p_rect.position.y, position.y);
- new_rect.size.x = MAX(p_rect.pos.x + p_rect.size.x, pos.x + size.x);
- new_rect.size.y = MAX(p_rect.pos.y + p_rect.size.y, pos.y + size.y);
+ new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x);
+ new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y);
- new_rect.size = new_rect.size - new_rect.pos; //make relative again
+ new_rect.size = new_rect.size - new_rect.position; //make relative again
return new_rect;
};
inline bool has_point(const Point2 &p_point) const {
- if (p_point.x < pos.x)
+ if (p_point.x < position.x)
return false;
- if (p_point.y < pos.y)
+ if (p_point.y < position.y)
return false;
- if (p_point.x >= (pos.x + size.x))
+ if (p_point.x >= (position.x + size.x))
return false;
- if (p_point.y >= (pos.y + size.y))
+ if (p_point.y >= (position.y + size.y))
return false;
return true;
@@ -317,18 +317,37 @@ struct Rect2 {
inline bool no_area() const { return (size.width <= 0 || size.height <= 0); }
- bool operator==(const Rect2 &p_rect) const { return pos == p_rect.pos && size == p_rect.size; }
- bool operator!=(const Rect2 &p_rect) const { return pos != p_rect.pos || size != p_rect.size; }
+ bool operator==(const Rect2 &p_rect) const { return position == p_rect.position && size == p_rect.size; }
+ bool operator!=(const Rect2 &p_rect) const { return position != p_rect.position || size != p_rect.size; }
inline Rect2 grow(real_t p_by) const {
Rect2 g = *this;
- g.pos.x -= p_by;
- g.pos.y -= p_by;
+ g.position.x -= p_by;
+ g.position.y -= p_by;
g.size.width += p_by * 2;
g.size.height += p_by * 2;
return g;
}
+ inline Rect2 grow_margin(Margin p_margin, real_t p_amount) const {
+ Rect2 g = *this;
+ g.grow_individual((MARGIN_LEFT == p_margin) ? p_amount : 0,
+ (MARGIN_TOP == p_margin) ? p_amount : 0,
+ (MARGIN_RIGHT == p_margin) ? p_amount : 0,
+ (MARGIN_BOTTOM == p_margin) ? p_amount : 0);
+ return g;
+ }
+
+ inline Rect2 grow_individual(real_t p_left, real_t p_top, real_t p_right, real_t p_bottom) const {
+
+ Rect2 g = *this;
+ g.position.x -= p_left;
+ g.position.y -= p_top;
+ g.size.width += p_left + p_right;
+ g.size.height += p_top + p_bottom;
+
+ return g;
+ }
inline Rect2 expand(const Vector2 &p_vector) const {
@@ -339,8 +358,8 @@ struct Rect2 {
inline void expand_to(const Vector2 &p_vector) { //in place function for speed
- Vector2 begin = pos;
- Vector2 end = pos + size;
+ Vector2 begin = position;
+ Vector2 end = position + size;
if (p_vector.x < begin.x)
begin.x = p_vector.x;
@@ -352,19 +371,19 @@ struct Rect2 {
if (p_vector.y > end.y)
end.y = p_vector.y;
- pos = begin;
+ position = begin;
size = end - begin;
}
- operator String() const { return String(pos) + ", " + String(size); }
+ operator String() const { return String(position) + ", " + String(size); }
Rect2() {}
Rect2(real_t p_x, real_t p_y, real_t p_width, real_t p_height) {
- pos = Point2(p_x, p_y);
+ position = Point2(p_x, p_y);
size = Size2(p_width, p_height);
}
Rect2(const Point2 &p_pos, const Size2 &p_size) {
- pos = p_pos;
+ position = p_pos;
size = p_size;
}
};
@@ -434,24 +453,24 @@ typedef Point2i Size2i;
struct Rect2i {
- Point2i pos;
+ Point2i position;
Size2i size;
- const Point2i &get_pos() const { return pos; }
- void set_pos(const Point2i &p_pos) { pos = p_pos; }
+ const Point2i &get_position() const { return position; }
+ void set_position(const Point2i &p_pos) { position = p_pos; }
const Point2i &get_size() const { return size; }
void set_size(const Point2i &p_size) { size = p_size; }
int get_area() const { return size.width * size.height; }
inline bool intersects(const Rect2i &p_rect) const {
- if (pos.x > (p_rect.pos.x + p_rect.size.width))
+ if (position.x > (p_rect.position.x + p_rect.size.width))
return false;
- if ((pos.x + size.width) < p_rect.pos.x)
+ if ((position.x + size.width) < p_rect.position.x)
return false;
- if (pos.y > (p_rect.pos.y + p_rect.size.height))
+ if (position.y > (p_rect.position.y + p_rect.size.height))
return false;
- if ((pos.y + size.height) < p_rect.pos.y)
+ if ((position.y + size.height) < p_rect.position.y)
return false;
return true;
@@ -459,9 +478,9 @@ struct Rect2i {
inline bool encloses(const Rect2i &p_rect) const {
- return (p_rect.pos.x >= pos.x) && (p_rect.pos.y >= pos.y) &&
- ((p_rect.pos.x + p_rect.size.x) < (pos.x + size.x)) &&
- ((p_rect.pos.y + p_rect.size.y) < (pos.y + size.y));
+ return (p_rect.position.x >= position.x) && (p_rect.position.y >= position.y) &&
+ ((p_rect.position.x + p_rect.size.x) < (position.x + size.x)) &&
+ ((p_rect.position.y + p_rect.size.y) < (position.y + size.y));
}
inline bool has_no_area() const {
@@ -475,14 +494,14 @@ struct Rect2i {
if (!intersects(new_rect))
return Rect2i();
- new_rect.pos.x = MAX(p_rect.pos.x, pos.x);
- new_rect.pos.y = MAX(p_rect.pos.y, pos.y);
+ new_rect.position.x = MAX(p_rect.position.x, position.x);
+ new_rect.position.y = MAX(p_rect.position.y, position.y);
- Point2 p_rect_end = p_rect.pos + p_rect.size;
- Point2 end = pos + size;
+ Point2 p_rect_end = p_rect.position + p_rect.size;
+ Point2 end = position + size;
- new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.pos.x);
- new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.pos.y);
+ new_rect.size.x = (int)(MIN(p_rect_end.x, end.x) - new_rect.position.x);
+ new_rect.size.y = (int)(MIN(p_rect_end.y, end.y) - new_rect.position.y);
return new_rect;
}
@@ -491,25 +510,25 @@ struct Rect2i {
Rect2i new_rect;
- new_rect.pos.x = MIN(p_rect.pos.x, pos.x);
- new_rect.pos.y = MIN(p_rect.pos.y, pos.y);
+ new_rect.position.x = MIN(p_rect.position.x, position.x);
+ new_rect.position.y = MIN(p_rect.position.y, position.y);
- new_rect.size.x = MAX(p_rect.pos.x + p_rect.size.x, pos.x + size.x);
- new_rect.size.y = MAX(p_rect.pos.y + p_rect.size.y, pos.y + size.y);
+ new_rect.size.x = MAX(p_rect.position.x + p_rect.size.x, position.x + size.x);
+ new_rect.size.y = MAX(p_rect.position.y + p_rect.size.y, position.y + size.y);
- new_rect.size = new_rect.size - new_rect.pos; //make relative again
+ new_rect.size = new_rect.size - new_rect.position; //make relative again
return new_rect;
};
bool has_point(const Point2 &p_point) const {
- if (p_point.x < pos.x)
+ if (p_point.x < position.x)
return false;
- if (p_point.y < pos.y)
+ if (p_point.y < position.y)
return false;
- if (p_point.x >= (pos.x + size.x))
+ if (p_point.x >= (position.x + size.x))
return false;
- if (p_point.y >= (pos.y + size.y))
+ if (p_point.y >= (position.y + size.y))
return false;
return true;
@@ -517,14 +536,14 @@ struct Rect2i {
bool no_area() { return (size.width <= 0 || size.height <= 0); }
- bool operator==(const Rect2i &p_rect) const { return pos == p_rect.pos && size == p_rect.size; }
- bool operator!=(const Rect2i &p_rect) const { return pos != p_rect.pos || size != p_rect.size; }
+ bool operator==(const Rect2i &p_rect) const { return position == p_rect.position && size == p_rect.size; }
+ bool operator!=(const Rect2i &p_rect) const { return position != p_rect.position || size != p_rect.size; }
Rect2i grow(int p_by) const {
Rect2i g = *this;
- g.pos.x -= p_by;
- g.pos.y -= p_by;
+ g.position.x -= p_by;
+ g.position.y -= p_by;
g.size.width += p_by * 2;
g.size.height += p_by * 2;
return g;
@@ -532,8 +551,8 @@ struct Rect2i {
inline void expand_to(const Point2i &p_vector) {
- Point2i begin = pos;
- Point2i end = pos + size;
+ Point2i begin = position;
+ Point2i end = position + size;
if (p_vector.x < begin.x)
begin.x = p_vector.x;
@@ -545,24 +564,24 @@ struct Rect2i {
if (p_vector.y > end.y)
end.y = p_vector.y;
- pos = begin;
+ position = begin;
size = end - begin;
}
- operator String() const { return String(pos) + ", " + String(size); }
+ operator String() const { return String(position) + ", " + String(size); }
- operator Rect2() const { return Rect2(pos, size); }
+ operator Rect2() const { return Rect2(position, size); }
Rect2i(const Rect2 &p_r2) {
- pos = p_r2.pos;
+ position = p_r2.position;
size = p_r2.size;
}
Rect2i() {}
Rect2i(int p_x, int p_y, int p_width, int p_height) {
- pos = Point2(p_x, p_y);
+ position = Point2(p_x, p_y);
size = Size2(p_width, p_height);
}
Rect2i(const Point2 &p_pos, const Size2 &p_size) {
- pos = p_pos;
+ position = p_pos;
size = p_size;
}
};
@@ -668,30 +687,30 @@ bool Rect2::intersects_transformed(const Transform2D &p_xform, const Rect2 &p_re
//SAT intersection between local and transformed rect2
Vector2 xf_points[4] = {
- p_xform.xform(p_rect.pos),
- p_xform.xform(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y)),
- p_xform.xform(Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.y)),
- p_xform.xform(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y + p_rect.size.y)),
+ p_xform.xform(p_rect.position),
+ p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y)),
+ p_xform.xform(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)),
+ p_xform.xform(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)),
};
real_t low_limit;
//base rect2 first (faster)
- if (xf_points[0].y > pos.y)
+ if (xf_points[0].y > position.y)
goto next1;
- if (xf_points[1].y > pos.y)
+ if (xf_points[1].y > position.y)
goto next1;
- if (xf_points[2].y > pos.y)
+ if (xf_points[2].y > position.y)
goto next1;
- if (xf_points[3].y > pos.y)
+ if (xf_points[3].y > position.y)
goto next1;
return false;
next1:
- low_limit = pos.y + size.y;
+ low_limit = position.y + size.y;
if (xf_points[0].y < low_limit)
goto next2;
@@ -706,20 +725,20 @@ next1:
next2:
- if (xf_points[0].x > pos.x)
+ if (xf_points[0].x > position.x)
goto next3;
- if (xf_points[1].x > pos.x)
+ if (xf_points[1].x > position.x)
goto next3;
- if (xf_points[2].x > pos.x)
+ if (xf_points[2].x > position.x)
goto next3;
- if (xf_points[3].x > pos.x)
+ if (xf_points[3].x > position.x)
goto next3;
return false;
next3:
- low_limit = pos.x + size.x;
+ low_limit = position.x + size.x;
if (xf_points[0].x < low_limit)
goto next4;
@@ -735,10 +754,10 @@ next3:
next4:
Vector2 xf_points2[4] = {
- pos,
- Vector2(pos.x + size.x, pos.y),
- Vector2(pos.x, pos.y + size.y),
- Vector2(pos.x + size.x, pos.y + size.y),
+ position,
+ Vector2(position.x + size.x, position.y),
+ Vector2(position.x, position.y + size.y),
+ Vector2(position.x + size.x, position.y + size.y),
};
real_t maxa = p_xform.elements[0].dot(xf_points2[0]);
@@ -847,10 +866,10 @@ Rect2 Transform2D::xform(const Rect2 &p_rect) const {
Vector2 x = elements[0] * p_rect.size.x;
Vector2 y = elements[1] * p_rect.size.y;
- Vector2 pos = xform(p_rect.pos);
+ Vector2 pos = xform(p_rect.position);
Rect2 new_rect;
- new_rect.pos = pos;
+ new_rect.position = pos;
new_rect.expand_to(pos + x);
new_rect.expand_to(pos + y);
new_rect.expand_to(pos + x + y);
@@ -868,14 +887,14 @@ void Transform2D::set_rotation_and_scale(real_t p_rot, const Size2 &p_scale) {
Rect2 Transform2D::xform_inv(const Rect2 &p_rect) const {
Vector2 ends[4] = {
- xform_inv(p_rect.pos),
- xform_inv(Vector2(p_rect.pos.x, p_rect.pos.y + p_rect.size.y)),
- xform_inv(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y + p_rect.size.y)),
- xform_inv(Vector2(p_rect.pos.x + p_rect.size.x, p_rect.pos.y))
+ xform_inv(p_rect.position),
+ xform_inv(Vector2(p_rect.position.x, p_rect.position.y + p_rect.size.y)),
+ xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y + p_rect.size.y)),
+ xform_inv(Vector2(p_rect.position.x + p_rect.size.x, p_rect.position.y))
};
Rect2 new_rect;
- new_rect.pos = ends[0];
+ new_rect.position = ends[0];
new_rect.expand_to(ends[1]);
new_rect.expand_to(ends[2]);
new_rect.expand_to(ends[3]);
diff --git a/core/math/math_funcs.h b/core/math/math_funcs.h
index 06ec77daae..45509a0808 100644
--- a/core/math/math_funcs.h
+++ b/core/math/math_funcs.h
@@ -51,9 +51,7 @@ class Math {
public:
Math() {} // useless to instance
- enum {
- RANDOM_MAX = 4294967295L
- };
+ static const uint64_t RANDOM_MAX = 4294967295;
static _ALWAYS_INLINE_ double sin(double p_x) { return ::sin(p_x); }
static _ALWAYS_INLINE_ float sin(float p_x) { return ::sinf(p_x); }
@@ -112,6 +110,15 @@ public:
static _ALWAYS_INLINE_ bool is_inf(double p_val) {
#ifdef _MSC_VER
return !_finite(p_val);
+// use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era
+#elif defined(__GNUC__) && __GNUC__ < 6
+ union {
+ uint64_t u;
+ double f;
+ } ieee754;
+ ieee754.f = p_val;
+ return ((unsigned)(ieee754.u >> 32) & 0x7fffffff) == 0x7ff00000 &&
+ ((unsigned)ieee754.u == 0);
#else
return isinf(p_val);
#endif
@@ -120,6 +127,14 @@ public:
static _ALWAYS_INLINE_ bool is_inf(float p_val) {
#ifdef _MSC_VER
return !_finite(p_val);
+// use an inline implementation of isinf as a workaround for problematic libstdc++ versions from gcc 5.x era
+#elif defined(__GNUC__) && __GNUC__ < 6
+ union {
+ uint32_t u;
+ float f;
+ } ieee754;
+ ieee754.f = p_val;
+ return (ieee754.u & 0x7fffffff) == 0x7f800000;
#else
return isinf(p_val);
#endif
@@ -278,6 +293,10 @@ public:
return u.f32;
}
+ static _ALWAYS_INLINE_ float half_to_float(const uint16_t h) {
+ return halfptr_to_float(&h);
+ }
+
static _ALWAYS_INLINE_ uint16_t make_half_float(float f) {
union {
diff --git a/core/math/matrix3.h b/core/math/matrix3.h
index c3eeb1f705..8897c692f7 100644
--- a/core/math/matrix3.h
+++ b/core/math/matrix3.h
@@ -145,6 +145,12 @@ public:
elements[2][1] = zy;
elements[2][2] = zz;
}
+ _FORCE_INLINE_ void set(const Vector3 &p_x, const Vector3 &p_y, const Vector3 &p_z) {
+
+ set_axis(0, p_x);
+ set_axis(1, p_y);
+ set_axis(2, p_z);
+ }
_FORCE_INLINE_ Vector3 get_column(int i) const {
return Vector3(elements[0][i], elements[1][i], elements[2][i]);
diff --git a/core/math/octree.h b/core/math/octree.h
index 4cc046ddf4..010c1b18f7 100644
--- a/core/math/octree.h
+++ b/core/math/octree.h
@@ -483,11 +483,11 @@ void Octree<T, use_pairs, AL>::_insert_element(Element *p_element, Octant *p_oct
aabb.size *= 0.5;
if (i & 1)
- aabb.pos.x += aabb.size.x;
+ aabb.position.x += aabb.size.x;
if (i & 2)
- aabb.pos.y += aabb.size.y;
+ aabb.position.y += aabb.size.y;
if (i & 4)
- aabb.pos.z += aabb.size.z;
+ aabb.position.z += aabb.size.z;
if (aabb.intersects_inclusive(p_element->aabb)) {
/* if actually intersects, create the child */
@@ -544,11 +544,11 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) {
while (!base.encloses(p_aabb)) {
- if (ABS(base.pos.x + base.size.x) <= ABS(base.pos.x)) {
+ if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) {
/* grow towards positive */
base.size *= 2.0;
} else {
- base.pos -= base.size;
+ base.position -= base.size;
base.size *= 2.0;
}
}
@@ -576,14 +576,14 @@ void Octree<T, use_pairs, AL>::_ensure_valid_root(const Rect3 &p_aabb) {
octant_count++;
root->parent = gp;
- if (ABS(base.pos.x + base.size.x) <= ABS(base.pos.x)) {
+ if (ABS(base.position.x + base.size.x) <= ABS(base.position.x)) {
/* grow towards positive */
base.size *= 2.0;
gp->aabb = base;
gp->children[0] = root;
root->parent_index = 0;
} else {
- base.pos -= base.size;
+ base.position -= base.size;
base.size *= 2.0;
gp->aabb = base;
gp->children[(1 << 0) | (1 << 1) | (1 << 2)] = root; // add at all-positive
@@ -797,9 +797,9 @@ OctreeElementID Octree<T, use_pairs, AL>::create(T *p_userdata, const Rect3 &p_a
// check for AABB validity
#ifdef DEBUG_ENABLED
- ERR_FAIL_COND_V(p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15, 0);
- ERR_FAIL_COND_V(p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15, 0);
- ERR_FAIL_COND_V(p_aabb.pos.z > 1e15 || p_aabb.pos.z < -1e15, 0);
+ ERR_FAIL_COND_V(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15, 0);
+ ERR_FAIL_COND_V(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15, 0);
+ ERR_FAIL_COND_V(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15, 0);
ERR_FAIL_COND_V(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0, 0);
ERR_FAIL_COND_V(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0, 0);
ERR_FAIL_COND_V(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0, 0);
@@ -837,9 +837,9 @@ void Octree<T, use_pairs, AL>::move(OctreeElementID p_id, const Rect3 &p_aabb) {
#ifdef DEBUG_ENABLED
// check for AABB validity
- ERR_FAIL_COND(p_aabb.pos.x > 1e15 || p_aabb.pos.x < -1e15);
- ERR_FAIL_COND(p_aabb.pos.y > 1e15 || p_aabb.pos.y < -1e15);
- ERR_FAIL_COND(p_aabb.pos.z > 1e15 || p_aabb.pos.z < -1e15);
+ ERR_FAIL_COND(p_aabb.position.x > 1e15 || p_aabb.position.x < -1e15);
+ ERR_FAIL_COND(p_aabb.position.y > 1e15 || p_aabb.position.y < -1e15);
+ ERR_FAIL_COND(p_aabb.position.z > 1e15 || p_aabb.position.z < -1e15);
ERR_FAIL_COND(p_aabb.size.x > 1e15 || p_aabb.size.x < 0.0);
ERR_FAIL_COND(p_aabb.size.y > 1e15 || p_aabb.size.y < 0.0);
ERR_FAIL_COND(p_aabb.size.z > 1e15 || p_aabb.size.z < 0.0);
diff --git a/core/math/quick_hull.cpp b/core/math/quick_hull.cpp
index ce93720067..9f594ba4fa 100644
--- a/core/math/quick_hull.cpp
+++ b/core/math/quick_hull.cpp
@@ -42,7 +42,7 @@ Error QuickHull::build(const Vector<Vector3> &p_points, Geometry::MeshData &r_me
for (int i = 0; i < p_points.size(); i++) {
if (i == 0) {
- aabb.pos = p_points[i];
+ aabb.position = p_points[i];
} else {
aabb.expand_to(p_points[i]);
}
diff --git a/core/math/rect3.cpp b/core/math/rect3.cpp
index 39b0beb071..973607f565 100644
--- a/core/math/rect3.cpp
+++ b/core/math/rect3.cpp
@@ -38,11 +38,11 @@ real_t Rect3::get_area() const {
bool Rect3::operator==(const Rect3 &p_rval) const {
- return ((pos == p_rval.pos) && (size == p_rval.size));
+ return ((position == p_rval.position) && (size == p_rval.size));
}
bool Rect3::operator!=(const Rect3 &p_rval) const {
- return ((pos != p_rval.pos) || (size != p_rval.size));
+ return ((position != p_rval.position) || (size != p_rval.size));
}
void Rect3::merge_with(const Rect3 &p_aabb) {
@@ -51,8 +51,8 @@ void Rect3::merge_with(const Rect3 &p_aabb) {
Vector3 end_1, end_2;
Vector3 min, max;
- beg_1 = pos;
- beg_2 = p_aabb.pos;
+ beg_1 = position;
+ beg_2 = p_aabb.position;
end_1 = Vector3(size.x, size.y, size.z) + beg_1;
end_2 = Vector3(p_aabb.size.x, p_aabb.size.y, p_aabb.size.z) + beg_2;
@@ -64,16 +64,16 @@ void Rect3::merge_with(const Rect3 &p_aabb) {
max.y = (end_1.y > end_2.y) ? end_1.y : end_2.y;
max.z = (end_1.z > end_2.z) ? end_1.z : end_2.z;
- pos = min;
+ position = min;
size = max - min;
}
Rect3 Rect3::intersection(const Rect3 &p_aabb) const {
- Vector3 src_min = pos;
- Vector3 src_max = pos + size;
- Vector3 dst_min = p_aabb.pos;
- Vector3 dst_max = p_aabb.pos + p_aabb.size;
+ Vector3 src_min = position;
+ Vector3 src_max = position + size;
+ Vector3 dst_min = p_aabb.position;
+ Vector3 dst_max = p_aabb.position + p_aabb.size;
Vector3 min, max;
@@ -107,18 +107,18 @@ Rect3 Rect3::intersection(const Rect3 &p_aabb) const {
bool Rect3::intersects_ray(const Vector3 &p_from, const Vector3 &p_dir, Vector3 *r_clip, Vector3 *r_normal) const {
Vector3 c1, c2;
- Vector3 end = pos + size;
+ Vector3 end = position + size;
real_t near = -1e20;
real_t far = 1e20;
int axis = 0;
for (int i = 0; i < 3; i++) {
if (p_dir[i] == 0) {
- if ((p_from[i] < pos[i]) || (p_from[i] > end[i])) {
+ if ((p_from[i] < position[i]) || (p_from[i] > end[i])) {
return false;
}
} else { // ray not parallel to planes in this direction
- c1[i] = (pos[i] - p_from[i]) / p_dir[i];
+ c1[i] = (position[i] - p_from[i]) / p_dir[i];
c2[i] = (end[i] - p_from[i]) / p_dir[i];
if (c1[i] > c2[i]) {
@@ -156,7 +156,7 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto
for (int i = 0; i < 3; i++) {
real_t seg_from = p_from[i];
real_t seg_to = p_to[i];
- real_t box_begin = pos[i];
+ real_t box_begin = position[i];
real_t box_end = box_begin + size[i];
real_t cmin, cmax;
real_t csign;
@@ -208,14 +208,14 @@ bool Rect3::intersects_segment(const Vector3 &p_from, const Vector3 &p_to, Vecto
bool Rect3::intersects_plane(const Plane &p_plane) const {
Vector3 points[8] = {
- Vector3(pos.x, pos.y, pos.z),
- Vector3(pos.x, pos.y, pos.z + size.z),
- Vector3(pos.x, pos.y + size.y, pos.z),
- Vector3(pos.x, pos.y + size.y, pos.z + size.z),
- Vector3(pos.x + size.x, pos.y, pos.z),
- Vector3(pos.x + size.x, pos.y, pos.z + size.z),
- Vector3(pos.x + size.x, pos.y + size.y, pos.z),
- Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z),
+ Vector3(position.x, position.y, position.z),
+ Vector3(position.x, position.y, position.z + size.z),
+ Vector3(position.x, position.y + size.y, position.z),
+ Vector3(position.x, position.y + size.y, position.z + size.z),
+ Vector3(position.x + size.x, position.y, position.z),
+ Vector3(position.x + size.x, position.y, position.z + size.z),
+ Vector3(position.x + size.x, position.y + size.y, position.z),
+ Vector3(position.x + size.x, position.y + size.y, position.z + size.z),
};
bool over = false;
@@ -327,68 +327,68 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
case 0: {
- r_from = Vector3(pos.x + size.x, pos.y, pos.z);
- r_to = Vector3(pos.x, pos.y, pos.z);
+ r_from = Vector3(position.x + size.x, position.y, position.z);
+ r_to = Vector3(position.x, position.y, position.z);
} break;
case 1: {
- r_from = Vector3(pos.x + size.x, pos.y, pos.z + size.z);
- r_to = Vector3(pos.x + size.x, pos.y, pos.z);
+ r_from = Vector3(position.x + size.x, position.y, position.z + size.z);
+ r_to = Vector3(position.x + size.x, position.y, position.z);
} break;
case 2: {
- r_from = Vector3(pos.x, pos.y, pos.z + size.z);
- r_to = Vector3(pos.x + size.x, pos.y, pos.z + size.z);
+ r_from = Vector3(position.x, position.y, position.z + size.z);
+ r_to = Vector3(position.x + size.x, position.y, position.z + size.z);
} break;
case 3: {
- r_from = Vector3(pos.x, pos.y, pos.z);
- r_to = Vector3(pos.x, pos.y, pos.z + size.z);
+ r_from = Vector3(position.x, position.y, position.z);
+ r_to = Vector3(position.x, position.y, position.z + size.z);
} break;
case 4: {
- r_from = Vector3(pos.x, pos.y + size.y, pos.z);
- r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z);
+ r_from = Vector3(position.x, position.y + size.y, position.z);
+ r_to = Vector3(position.x + size.x, position.y + size.y, position.z);
} break;
case 5: {
- r_from = Vector3(pos.x + size.x, pos.y + size.y, pos.z);
- r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z);
+ r_from = Vector3(position.x + size.x, position.y + size.y, position.z);
+ r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
} break;
case 6: {
- r_from = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z);
- r_to = Vector3(pos.x, pos.y + size.y, pos.z + size.z);
+ r_from = Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
+ r_to = Vector3(position.x, position.y + size.y, position.z + size.z);
} break;
case 7: {
- r_from = Vector3(pos.x, pos.y + size.y, pos.z + size.z);
- r_to = Vector3(pos.x, pos.y + size.y, pos.z);
+ r_from = Vector3(position.x, position.y + size.y, position.z + size.z);
+ r_to = Vector3(position.x, position.y + size.y, position.z);
} break;
case 8: {
- r_from = Vector3(pos.x, pos.y, pos.z + size.z);
- r_to = Vector3(pos.x, pos.y + size.y, pos.z + size.z);
+ r_from = Vector3(position.x, position.y, position.z + size.z);
+ r_to = Vector3(position.x, position.y + size.y, position.z + size.z);
} break;
case 9: {
- r_from = Vector3(pos.x, pos.y, pos.z);
- r_to = Vector3(pos.x, pos.y + size.y, pos.z);
+ r_from = Vector3(position.x, position.y, position.z);
+ r_to = Vector3(position.x, position.y + size.y, position.z);
} break;
case 10: {
- r_from = Vector3(pos.x + size.x, pos.y, pos.z);
- r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z);
+ r_from = Vector3(position.x + size.x, position.y, position.z);
+ r_to = Vector3(position.x + size.x, position.y + size.y, position.z);
} break;
case 11: {
- r_from = Vector3(pos.x + size.x, pos.y, pos.z + size.z);
- r_to = Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z);
+ r_from = Vector3(position.x + size.x, position.y, position.z + size.z);
+ r_to = Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
} break;
}
@@ -396,5 +396,5 @@ void Rect3::get_edge(int p_edge, Vector3 &r_from, Vector3 &r_to) const {
Rect3::operator String() const {
- return String() + pos + " - " + size;
+ return String() + position + " - " + size;
}
diff --git a/core/math/rect3.h b/core/math/rect3.h
index 136a156151..b7c94ad9f7 100644
--- a/core/math/rect3.h
+++ b/core/math/rect3.h
@@ -36,12 +36,12 @@
/**
* AABB / AABB (Axis Aligned Bounding Box)
- * This is implemented by a point (pos) and the box size
+ * This is implemented by a point (position) and the box size
*/
class Rect3 {
public:
- Vector3 pos;
+ Vector3 position;
Vector3 size;
real_t get_area() const; /// get area
@@ -55,8 +55,8 @@ public:
return (size.x <= CMP_EPSILON && size.y <= CMP_EPSILON && size.z <= CMP_EPSILON);
}
- const Vector3 &get_pos() const { return pos; }
- void set_pos(const Vector3 &p_pos) { pos = p_pos; }
+ const Vector3 &get_position() const { return position; }
+ void set_position(const Vector3 &p_pos) { position = p_pos; }
const Vector3 &get_size() const { return size; }
void set_size(const Vector3 &p_size) { size = p_size; }
@@ -102,24 +102,24 @@ public:
_FORCE_INLINE_ Rect3() {}
inline Rect3(const Vector3 &p_pos, const Vector3 &p_size) {
- pos = p_pos;
+ position = p_pos;
size = p_size;
}
};
inline bool Rect3::intersects(const Rect3 &p_aabb) const {
- if (pos.x >= (p_aabb.pos.x + p_aabb.size.x))
+ if (position.x >= (p_aabb.position.x + p_aabb.size.x))
return false;
- if ((pos.x + size.x) <= p_aabb.pos.x)
+ if ((position.x + size.x) <= p_aabb.position.x)
return false;
- if (pos.y >= (p_aabb.pos.y + p_aabb.size.y))
+ if (position.y >= (p_aabb.position.y + p_aabb.size.y))
return false;
- if ((pos.y + size.y) <= p_aabb.pos.y)
+ if ((position.y + size.y) <= p_aabb.position.y)
return false;
- if (pos.z >= (p_aabb.pos.z + p_aabb.size.z))
+ if (position.z >= (p_aabb.position.z + p_aabb.size.z))
return false;
- if ((pos.z + size.z) <= p_aabb.pos.z)
+ if ((position.z + size.z) <= p_aabb.position.z)
return false;
return true;
@@ -127,17 +127,17 @@ inline bool Rect3::intersects(const Rect3 &p_aabb) const {
inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const {
- if (pos.x > (p_aabb.pos.x + p_aabb.size.x))
+ if (position.x > (p_aabb.position.x + p_aabb.size.x))
return false;
- if ((pos.x + size.x) < p_aabb.pos.x)
+ if ((position.x + size.x) < p_aabb.position.x)
return false;
- if (pos.y > (p_aabb.pos.y + p_aabb.size.y))
+ if (position.y > (p_aabb.position.y + p_aabb.size.y))
return false;
- if ((pos.y + size.y) < p_aabb.pos.y)
+ if ((position.y + size.y) < p_aabb.position.y)
return false;
- if (pos.z > (p_aabb.pos.z + p_aabb.size.z))
+ if (position.z > (p_aabb.position.z + p_aabb.size.z))
return false;
- if ((pos.z + size.z) < p_aabb.pos.z)
+ if ((position.z + size.z) < p_aabb.position.z)
return false;
return true;
@@ -145,10 +145,10 @@ inline bool Rect3::intersects_inclusive(const Rect3 &p_aabb) const {
inline bool Rect3::encloses(const Rect3 &p_aabb) const {
- Vector3 src_min = pos;
- Vector3 src_max = pos + size;
- Vector3 dst_min = p_aabb.pos;
- Vector3 dst_max = p_aabb.pos + p_aabb.size;
+ Vector3 src_min = position;
+ Vector3 src_max = position + size;
+ Vector3 dst_min = p_aabb.position;
+ Vector3 dst_max = p_aabb.position + p_aabb.size;
return (
(src_min.x <= dst_min.x) &&
@@ -162,7 +162,7 @@ inline bool Rect3::encloses(const Rect3 &p_aabb) const {
Vector3 Rect3::get_support(const Vector3 &p_normal) const {
Vector3 half_extents = size * 0.5;
- Vector3 ofs = pos + half_extents;
+ Vector3 ofs = position + half_extents;
return Vector3(
(p_normal.x > 0) ? -half_extents.x : half_extents.x,
@@ -174,14 +174,14 @@ Vector3 Rect3::get_support(const Vector3 &p_normal) const {
Vector3 Rect3::get_endpoint(int p_point) const {
switch (p_point) {
- case 0: return Vector3(pos.x, pos.y, pos.z);
- case 1: return Vector3(pos.x, pos.y, pos.z + size.z);
- case 2: return Vector3(pos.x, pos.y + size.y, pos.z);
- case 3: return Vector3(pos.x, pos.y + size.y, pos.z + size.z);
- case 4: return Vector3(pos.x + size.x, pos.y, pos.z);
- case 5: return Vector3(pos.x + size.x, pos.y, pos.z + size.z);
- case 6: return Vector3(pos.x + size.x, pos.y + size.y, pos.z);
- case 7: return Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z);
+ case 0: return Vector3(position.x, position.y, position.z);
+ case 1: return Vector3(position.x, position.y, position.z + size.z);
+ case 2: return Vector3(position.x, position.y + size.y, position.z);
+ case 3: return Vector3(position.x, position.y + size.y, position.z + size.z);
+ case 4: return Vector3(position.x + size.x, position.y, position.z);
+ case 5: return Vector3(position.x + size.x, position.y, position.z + size.z);
+ case 6: return Vector3(position.x + size.x, position.y + size.y, position.z);
+ case 7: return Vector3(position.x + size.x, position.y + size.y, position.z + size.z);
};
ERR_FAIL_V(Vector3());
@@ -192,7 +192,7 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co
#if 1
Vector3 half_extents = size * 0.5;
- Vector3 ofs = pos + half_extents;
+ Vector3 ofs = position + half_extents;
for (int i = 0; i < p_plane_count; i++) {
const Plane &p = p_planes[i];
@@ -210,14 +210,14 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co
//cache all points to check against!
// #warning should be easy to optimize, just use the same as when taking the support and use only that point
Vector3 points[8] = {
- Vector3(pos.x, pos.y, pos.z),
- Vector3(pos.x, pos.y, pos.z + size.z),
- Vector3(pos.x, pos.y + size.y, pos.z),
- Vector3(pos.x, pos.y + size.y, pos.z + size.z),
- Vector3(pos.x + size.x, pos.y, pos.z),
- Vector3(pos.x + size.x, pos.y, pos.z + size.z),
- Vector3(pos.x + size.x, pos.y + size.y, pos.z),
- Vector3(pos.x + size.x, pos.y + size.y, pos.z + size.z),
+ Vector3(position.x, position.y, position.z),
+ Vector3(position.x, position.y, position.z + size.z),
+ Vector3(position.x, position.y + size.y, position.z),
+ Vector3(position.x, position.y + size.y, position.z + size.z),
+ Vector3(position.x + size.x, position.y, position.z),
+ Vector3(position.x + size.x, position.y, position.z + size.z),
+ Vector3(position.x + size.x, position.y + size.y, position.z),
+ Vector3(position.x + size.x, position.y + size.y, position.z + size.z),
};
for (int i = 0; i < p_plane_count; i++) { //for each plane
@@ -246,17 +246,17 @@ bool Rect3::intersects_convex_shape(const Plane *p_planes, int p_plane_count) co
bool Rect3::has_point(const Vector3 &p_point) const {
- if (p_point.x < pos.x)
+ if (p_point.x < position.x)
return false;
- if (p_point.y < pos.y)
+ if (p_point.y < position.y)
return false;
- if (p_point.z < pos.z)
+ if (p_point.z < position.z)
return false;
- if (p_point.x > pos.x + size.x)
+ if (p_point.x > position.x + size.x)
return false;
- if (p_point.y > pos.y + size.y)
+ if (p_point.y > position.y + size.y)
return false;
- if (p_point.z > pos.z + size.z)
+ if (p_point.z > position.z + size.z)
return false;
return true;
@@ -264,8 +264,8 @@ bool Rect3::has_point(const Vector3 &p_point) const {
inline void Rect3::expand_to(const Vector3 &p_vector) {
- Vector3 begin = pos;
- Vector3 end = pos + size;
+ Vector3 begin = position;
+ Vector3 end = position + size;
if (p_vector.x < begin.x)
begin.x = p_vector.x;
@@ -281,14 +281,14 @@ inline void Rect3::expand_to(const Vector3 &p_vector) {
if (p_vector.z > end.z)
end.z = p_vector.z;
- pos = begin;
+ position = begin;
size = end - begin;
}
void Rect3::project_range_in_plane(const Plane &p_plane, real_t &r_min, real_t &r_max) const {
Vector3 half_extents(size.x * 0.5, size.y * 0.5, size.z * 0.5);
- Vector3 center(pos.x + half_extents.x, pos.y + half_extents.y, pos.z + half_extents.z);
+ Vector3 center(position.x + half_extents.x, position.y + half_extents.y, position.z + half_extents.z);
real_t length = p_plane.normal.abs().dot(half_extents);
real_t distance = p_plane.distance_to(center);
@@ -332,21 +332,21 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t
real_t divy = 1.0 / dir.y;
real_t divz = 1.0 / dir.z;
- Vector3 upbound = pos + size;
+ Vector3 upbound = position + size;
real_t tmin, tmax, tymin, tymax, tzmin, tzmax;
if (dir.x >= 0) {
- tmin = (pos.x - from.x) * divx;
+ tmin = (position.x - from.x) * divx;
tmax = (upbound.x - from.x) * divx;
} else {
tmin = (upbound.x - from.x) * divx;
- tmax = (pos.x - from.x) * divx;
+ tmax = (position.x - from.x) * divx;
}
if (dir.y >= 0) {
- tymin = (pos.y - from.y) * divy;
+ tymin = (position.y - from.y) * divy;
tymax = (upbound.y - from.y) * divy;
} else {
tymin = (upbound.y - from.y) * divy;
- tymax = (pos.y - from.y) * divy;
+ tymax = (position.y - from.y) * divy;
}
if ((tmin > tymax) || (tymin > tmax))
return false;
@@ -355,11 +355,11 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t
if (tymax < tmax)
tmax = tymax;
if (dir.z >= 0) {
- tzmin = (pos.z - from.z) * divz;
+ tzmin = (position.z - from.z) * divz;
tzmax = (upbound.z - from.z) * divz;
} else {
tzmin = (upbound.z - from.z) * divz;
- tzmax = (pos.z - from.z) * divz;
+ tzmax = (position.z - from.z) * divz;
}
if ((tmin > tzmax) || (tzmin > tmax))
return false;
@@ -372,9 +372,9 @@ bool Rect3::smits_intersect_ray(const Vector3 &from, const Vector3 &dir, real_t
void Rect3::grow_by(real_t p_amount) {
- pos.x -= p_amount;
- pos.y -= p_amount;
- pos.z -= p_amount;
+ position.x -= p_amount;
+ position.y -= p_amount;
+ position.z -= p_amount;
size.x += 2.0 * p_amount;
size.y += 2.0 * p_amount;
size.z += 2.0 * p_amount;
diff --git a/core/math/transform.cpp b/core/math/transform.cpp
index e53e6cf519..7a50214596 100644
--- a/core/math/transform.cpp
+++ b/core/math/transform.cpp
@@ -82,7 +82,10 @@ Transform Transform::looking_at(const Vector3 &p_target, const Vector3 &p_up) co
}
void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const Vector3 &p_up) {
-
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND(p_eye == p_target);
+ ERR_FAIL_COND(p_up.length() == 0);
+#endif
// Reference: MESA source code
Vector3 v_x, v_y, v_z;
@@ -96,6 +99,9 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const
v_y = p_up;
v_x = v_y.cross(v_z);
+#ifdef MATH_CHECKS
+ ERR_FAIL_COND(v_x.length() == 0);
+#endif
/* Recompute Y = Z cross X */
v_y = v_z.cross(v_x);
@@ -103,9 +109,8 @@ void Transform::set_look_at(const Vector3 &p_eye, const Vector3 &p_target, const
v_x.normalize();
v_y.normalize();
- basis.set_axis(0, v_x);
- basis.set_axis(1, v_y);
- basis.set_axis(2, v_z);
+ basis.set(v_x, v_y, v_z);
+
origin = p_eye;
}
diff --git a/core/math/transform.h b/core/math/transform.h
index 4731496bf3..48467f2ed7 100644
--- a/core/math/transform.h
+++ b/core/math/transform.h
@@ -97,15 +97,7 @@ public:
void set(real_t xx, real_t xy, real_t xz, real_t yx, real_t yy, real_t yz, real_t zx, real_t zy, real_t zz, real_t tx, real_t ty, real_t tz) {
- basis.elements[0][0] = xx;
- basis.elements[0][1] = xy;
- basis.elements[0][2] = xz;
- basis.elements[1][0] = yx;
- basis.elements[1][1] = yy;
- basis.elements[1][2] = yz;
- basis.elements[2][0] = zx;
- basis.elements[2][1] = zy;
- basis.elements[2][2] = zz;
+ basis.set(xx, xy, xz, yx, yy, yz, zx, zy, zz);
origin.x = tx;
origin.y = ty;
origin.z = tz;
@@ -167,10 +159,10 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const {
Vector3 x = basis.get_axis(0) * p_aabb.size.x;
Vector3 y = basis.get_axis(1) * p_aabb.size.y;
Vector3 z = basis.get_axis(2) * p_aabb.size.z;
- Vector3 pos = xform(p_aabb.pos);
+ Vector3 pos = xform(p_aabb.position);
//could be even further optimized
Rect3 new_aabb;
- new_aabb.pos = pos;
+ new_aabb.position = pos;
new_aabb.expand_to(pos + x);
new_aabb.expand_to(pos + y);
new_aabb.expand_to(pos + z);
@@ -182,14 +174,14 @@ _FORCE_INLINE_ Rect3 Transform::xform(const Rect3 &p_aabb) const {
#else
Vector3 vertices[8] = {
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z)
};
AABB ret;
@@ -208,19 +200,19 @@ _FORCE_INLINE_ Rect3 Transform::xform_inv(const Rect3 &p_aabb) const {
/* define vertices */
Vector3 vertices[8] = {
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x + p_aabb.size.x, p_aabb.pos.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y + p_aabb.size.y, p_aabb.pos.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z + p_aabb.size.z),
- Vector3(p_aabb.pos.x, p_aabb.pos.y, p_aabb.pos.z)
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x + p_aabb.size.x, p_aabb.position.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y + p_aabb.size.y, p_aabb.position.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z + p_aabb.size.z),
+ Vector3(p_aabb.position.x, p_aabb.position.y, p_aabb.position.z)
};
Rect3 ret;
- ret.pos = xform_inv(vertices[0]);
+ ret.position = xform_inv(vertices[0]);
for (int i = 1; i < 8; i++) {
diff --git a/core/math/triangle_mesh.cpp b/core/math/triangle_mesh.cpp
index 1cf1351646..08ac08d776 100644
--- a/core/math/triangle_mesh.cpp
+++ b/core/math/triangle_mesh.cpp
@@ -79,7 +79,7 @@ int TriangleMesh::_create_bvh(BVH *p_bvh, BVH **p_bb, int p_from, int p_size, in
int index = max_alloc++;
BVH *_new = &p_bvh[index];
_new->aabb = aabb;
- _new->center = aabb.pos + aabb.size * 0.5;
+ _new->center = aabb.position + aabb.size * 0.5;
_new->face_index = -1;
_new->left = left;
_new->right = right;
@@ -128,7 +128,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
f.indices[j] = vidx;
if (j == 0)
- bw[i].aabb.pos = vs;
+ bw[i].aabb.position = vs;
else
bw[i].aabb.expand_to(vs);
}
@@ -138,7 +138,7 @@ void TriangleMesh::create(const PoolVector<Vector3> &p_faces) {
bw[i].left = -1;
bw[i].right = -1;
bw[i].face_index = i;
- bw[i].center = bw[i].aabb.pos + bw[i].aabb.size * 0.5;
+ bw[i].center = bw[i].aabb.position + bw[i].aabb.size * 0.5;
}
vertices.resize(db.size());
diff --git a/core/message_queue.cpp b/core/message_queue.cpp
index 14e8913d9f..d7d31b6c1e 100644
--- a/core/message_queue.cpp
+++ b/core/message_queue.cpp
@@ -51,9 +51,10 @@ Error MessageQueue::push_call(ObjectID p_id, const StringName &p_method, const V
type = ObjectDB::get_instance(p_id)->get_class();
print_line("failed method: " + type + ":" + p_method + " target ID: " + itos(p_id));
statistics();
+ ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings");
+ ERR_FAIL_V(ERR_OUT_OF_MEMORY);
}
- ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY);
Message *msg = memnew_placement(&buffer[buffer_end], Message);
msg->args = p_argcount;
msg->instance_ID = p_id;
@@ -101,10 +102,10 @@ Error MessageQueue::push_set(ObjectID p_id, const StringName &p_prop, const Vari
type = ObjectDB::get_instance(p_id)->get_class();
print_line("failed set: " + type + ":" + p_prop + " target ID: " + itos(p_id));
statistics();
+ ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings");
+ ERR_FAIL_V(ERR_OUT_OF_MEMORY);
}
- ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY);
-
Message *msg = memnew_placement(&buffer[buffer_end], Message);
msg->args = 1;
msg->instance_ID = p_id;
@@ -134,9 +135,10 @@ Error MessageQueue::push_notification(ObjectID p_id, int p_notification) {
type = ObjectDB::get_instance(p_id)->get_class();
print_line("failed notification: " + itos(p_notification) + " target ID: " + itos(p_id));
statistics();
+ ERR_EXPLAIN("Message queue out of memory. Try increasing 'message_queue_size_kb' in project settings");
+ ERR_FAIL_V(ERR_OUT_OF_MEMORY);
}
- ERR_FAIL_COND_V((buffer_end + room_needed) >= buffer_size, ERR_OUT_OF_MEMORY);
Message *msg = memnew_placement(&buffer[buffer_end], Message);
msg->type = TYPE_NOTIFICATION;
@@ -316,12 +318,19 @@ void MessageQueue::flush() {
while (read_pos < buffer_end) {
- _THREAD_SAFE_UNLOCK_
-
//lock on each interation, so a call can re-add itself to the message queue
Message *message = (Message *)&buffer[read_pos];
+ uint32_t advance = sizeof(Message);
+ if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION)
+ advance += sizeof(Variant) * message->args;
+
+ //pre-advance so this function is reentrant
+ read_pos += advance;
+
+ _THREAD_SAFE_UNLOCK_
+
Object *target = ObjectDB::get_instance(message->instance_ID);
if (target != NULL) {
@@ -357,13 +366,9 @@ void MessageQueue::flush() {
}
}
- uint32_t advance = sizeof(Message);
- if ((message->type & FLAG_MASK) != TYPE_NOTIFICATION)
- advance += sizeof(Variant) * message->args;
message->~Message();
_THREAD_SAFE_LOCK_
- read_pos += advance;
}
buffer_end = 0; // reset buffer
diff --git a/core/method_bind.h b/core/method_bind.h
index 749d8b4fda..8d72c8573a 100644
--- a/core/method_bind.h
+++ b/core/method_bind.h
@@ -146,7 +146,7 @@ struct VariantCaster<const T &> {
// some helpers
VARIANT_ENUM_CAST(Vector3::Axis);
-VARIANT_ENUM_CAST(Image::Format);
+
VARIANT_ENUM_CAST(Error);
VARIANT_ENUM_CAST(wchar_t);
VARIANT_ENUM_CAST(Margin);
@@ -154,7 +154,6 @@ VARIANT_ENUM_CAST(Orientation);
VARIANT_ENUM_CAST(HAlign);
VARIANT_ENUM_CAST(Variant::Type);
VARIANT_ENUM_CAST(Variant::Operator);
-VARIANT_ENUM_CAST(InputEvent::Type);
class MethodBind {
diff --git a/core/method_ptrcall.h b/core/method_ptrcall.h
index 8cb2903842..c6dbfc2a7a 100644
--- a/core/method_ptrcall.h
+++ b/core/method_ptrcall.h
@@ -103,10 +103,8 @@ MAKE_PTRARG(Rect3);
MAKE_PTRARG(Basis);
MAKE_PTRARG(Transform);
MAKE_PTRARG(Color);
-MAKE_PTRARG(Image);
MAKE_PTRARG(NodePath);
MAKE_PTRARG(RID);
-MAKE_PTRARG(InputEvent);
MAKE_PTRARG(Dictionary);
MAKE_PTRARG(Array);
MAKE_PTRARG(PoolByteArray);
@@ -117,7 +115,6 @@ MAKE_PTRARG(PoolVector2Array);
MAKE_PTRARG(PoolVector3Array);
MAKE_PTRARG(PoolColorArray);
MAKE_PTRARG(Variant);
-MAKE_PTRARG(PowerState);
//this is for Object
diff --git a/core/object.cpp b/core/object.cpp
index 7aee936a2d..f20e93f9d7 100644
--- a/core/object.cpp
+++ b/core/object.cpp
@@ -1831,10 +1831,10 @@ void postinitialize_handler(Object *p_object) {
p_object->_postinitialize();
}
-HashMap<uint32_t, Object *> ObjectDB::instances;
-uint32_t ObjectDB::instance_counter = 1;
+HashMap<ObjectID, Object *> ObjectDB::instances;
+ObjectID ObjectDB::instance_counter = 1;
HashMap<Object *, ObjectID, ObjectDB::ObjectPtrHash> ObjectDB::instance_checks;
-uint32_t ObjectDB::add_instance(Object *p_object) {
+ObjectID ObjectDB::add_instance(Object *p_object) {
ERR_FAIL_COND_V(p_object->get_instance_ID() != 0, 0);
@@ -1859,7 +1859,7 @@ void ObjectDB::remove_instance(Object *p_object) {
rw_lock->write_unlock();
}
-Object *ObjectDB::get_instance(uint32_t p_instance_ID) {
+Object *ObjectDB::get_instance(ObjectID p_instance_ID) {
rw_lock->read_lock();
Object **obj = instances.getptr(p_instance_ID);
@@ -1874,7 +1874,7 @@ void ObjectDB::debug_objects(DebugFunc p_func) {
rw_lock->read_lock();
- const uint32_t *K = NULL;
+ const ObjectID *K = NULL;
while ((K = instances.next(K))) {
p_func(instances[*K]);
@@ -1909,7 +1909,7 @@ void ObjectDB::cleanup() {
WARN_PRINT("ObjectDB Instances still exist!");
if (OS::get_singleton()->is_stdout_verbose()) {
- const uint32_t *K = NULL;
+ const ObjectID *K = NULL;
while ((K = instances.next(K))) {
String node_name;
diff --git a/core/object.h b/core/object.h
index 3b39224af0..83b03b9239 100644
--- a/core/object.h
+++ b/core/object.h
@@ -350,7 +350,7 @@ public: \
private:
class ScriptInstance;
-typedef uint32_t ObjectID;
+typedef uint64_t ObjectID;
class Object {
public:
@@ -423,7 +423,7 @@ private:
bool _block_signals;
int _predelete_ok;
Set<Object *> change_receptors;
- uint32_t _instance_ID;
+ ObjectID _instance_ID;
bool _predelete();
void _postinitialize();
bool _can_translate;
@@ -690,16 +690,16 @@ class ObjectDB {
}
};
- static HashMap<uint32_t, Object *> instances;
+ static HashMap<ObjectID, Object *> instances;
static HashMap<Object *, ObjectID, ObjectPtrHash> instance_checks;
- static uint32_t instance_counter;
+ static ObjectID instance_counter;
friend class Object;
friend void unregister_core_types();
static RWLock *rw_lock;
static void cleanup();
- static uint32_t add_instance(Object *p_object);
+ static ObjectID add_instance(Object *p_object);
static void remove_instance(Object *p_object);
friend void register_core_types();
static void setup();
@@ -707,7 +707,7 @@ class ObjectDB {
public:
typedef void (*DebugFunc)(Object *p_obj);
- static Object *get_instance(uint32_t p_instance_ID);
+ static Object *get_instance(ObjectID p_instance_ID);
static void debug_objects(DebugFunc p_func);
static int get_object_count();
diff --git a/core/os/file_access.cpp b/core/os/file_access.cpp
index 375121c0cc..805b66b983 100644
--- a/core/os/file_access.cpp
+++ b/core/os/file_access.cpp
@@ -252,6 +252,27 @@ double FileAccess::get_double() const {
return m.d;
};
+String FileAccess::get_token() const {
+
+ CharString token;
+
+ CharType c = get_8();
+
+ while (!eof_reached()) {
+
+ if (c <= ' ') {
+ if (!token.empty())
+ break;
+ } else {
+ token.push_back(c);
+ }
+ c = get_8();
+ }
+
+ token.push_back(0);
+ return String::utf8(token.get_data());
+}
+
String FileAccess::get_line() const {
CharString line;
diff --git a/core/os/file_access.h b/core/os/file_access.h
index da15ddc544..6d3e491167 100644
--- a/core/os/file_access.h
+++ b/core/os/file_access.h
@@ -106,6 +106,7 @@ public:
virtual int get_buffer(uint8_t *p_dst, int p_length) const; ///< get an array of bytes
virtual String get_line() const;
+ virtual String get_token() const;
virtual Vector<String> get_csv_line(String delim = ",") const;
/**< use this for files WRITTEN in _big_ endian machines (ie, amiga/mac)
diff --git a/core/os/input.h b/core/os/input.h
index 4f26f097c2..6759c624e3 100644
--- a/core/os/input.h
+++ b/core/os/input.h
@@ -82,7 +82,7 @@ public:
virtual int get_mouse_button_mask() const = 0;
virtual void warp_mouse_pos(const Vector2 &p_to) = 0;
- virtual Point2i warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) = 0;
+ virtual Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) = 0;
virtual Vector3 get_gravity() const = 0;
virtual Vector3 get_accelerometer() const = 0;
@@ -104,7 +104,7 @@ public:
virtual int get_joy_button_index_from_string(String p_button) = 0;
virtual int get_joy_axis_index_from_string(String p_axis) = 0;
- virtual void parse_input_event(const InputEvent &p_event) = 0;
+ virtual void parse_input_event(const Ref<InputEvent> &p_event) = 0;
Input();
};
diff --git a/core/os/input_event.cpp b/core/os/input_event.cpp
index 474bc33b41..dbdf9628e3 100644
--- a/core/os/input_event.cpp
+++ b/core/os/input_event.cpp
@@ -34,275 +34,797 @@
*
*/
-bool InputEvent::operator==(const InputEvent &p_event) const {
- if (type != p_event.type) {
- return false;
- }
+void InputEvent::set_id(uint32_t p_id) {
+ id = p_id;
+}
- switch (type) {
- /** Current clang-format style doesn't play well with the aligned return values of that switch. */
- /* clang-format off */
- case NONE:
- return true;
- case KEY:
- return key.unicode == p_event.key.unicode
- && key.scancode == p_event.key.scancode
- && key.echo == p_event.key.echo
- && key.pressed == p_event.key.pressed
- && key.mod == p_event.key.mod;
- case MOUSE_MOTION:
- return mouse_motion.x == p_event.mouse_motion.x
- && mouse_motion.y == p_event.mouse_motion.y
- && mouse_motion.relative_x == p_event.mouse_motion.relative_x
- && mouse_motion.relative_y == p_event.mouse_motion.relative_y
- && mouse_motion.button_mask == p_event.mouse_motion.button_mask
- && key.mod == p_event.key.mod;
- case MOUSE_BUTTON:
- return mouse_button.pressed == p_event.mouse_button.pressed
- && mouse_button.x == p_event.mouse_button.x
- && mouse_button.y == p_event.mouse_button.y
- && mouse_button.button_index == p_event.mouse_button.button_index
- && mouse_button.button_mask == p_event.mouse_button.button_mask
- && key.mod == p_event.key.mod;
- case JOYPAD_MOTION:
- return joy_motion.axis == p_event.joy_motion.axis
- && joy_motion.axis_value == p_event.joy_motion.axis_value;
- case JOYPAD_BUTTON:
- return joy_button.pressed == p_event.joy_button.pressed
- && joy_button.button_index == p_event.joy_button.button_index
- && joy_button.pressure == p_event.joy_button.pressure;
- case SCREEN_TOUCH:
- return screen_touch.pressed == p_event.screen_touch.pressed
- && screen_touch.index == p_event.screen_touch.index
- && screen_touch.x == p_event.screen_touch.x
- && screen_touch.y == p_event.screen_touch.y;
- case SCREEN_DRAG:
- return screen_drag.index == p_event.screen_drag.index
- && screen_drag.x == p_event.screen_drag.x
- && screen_drag.y == p_event.screen_drag.y;
- case ACTION:
- return action.action == p_event.action.action
- && action.pressed == p_event.action.pressed;
- /* clang-format on */
- default:
- ERR_PRINT("No logic to compare InputEvents of this type, this shouldn't happen.");
- }
+uint32_t InputEvent::get_id() const {
+ return id;
+}
+
+void InputEvent::set_device(int p_device) {
+ device = p_device;
+}
+
+int InputEvent::get_device() const {
+ return device;
+}
+
+bool InputEvent::is_pressed() const {
return false;
}
-InputEvent::operator String() const {
-
- String str = "Device " + itos(device) + " ID " + itos(ID) + " ";
-
- switch (type) {
-
- case NONE: {
-
- return "Event: None";
- } break;
- case KEY: {
-
- str += "Event: Key ";
- str = str + "Unicode: " + String::chr(key.unicode) + " Scan: " + itos(key.scancode) + " Echo: " + String(key.echo ? "True" : "False") + " Pressed" + String(key.pressed ? "True" : "False") + " Mod: ";
- if (key.mod.shift)
- str += "S";
- if (key.mod.control)
- str += "C";
- if (key.mod.alt)
- str += "A";
- if (key.mod.meta)
- str += "M";
-
- return str;
- } break;
- case MOUSE_MOTION: {
-
- str += "Event: Motion ";
- str = str + " Pos: " + itos(mouse_motion.x) + "," + itos(mouse_motion.y) + " Rel: " + itos(mouse_motion.relative_x) + "," + itos(mouse_motion.relative_y) + " Mask: ";
- for (int i = 0; i < 8; i++) {
-
- if ((1 << i) & mouse_motion.button_mask)
- str += itos(i + 1);
- }
- str += " Mod: ";
- if (key.mod.shift)
- str += "S";
- if (key.mod.control)
- str += "C";
- if (key.mod.alt)
- str += "A";
- if (key.mod.meta)
- str += "M";
-
- return str;
- } break;
- case MOUSE_BUTTON: {
- str += "Event: Button ";
- str = str + "Pressed: " + itos(mouse_button.pressed) + " Pos: " + itos(mouse_button.x) + "," + itos(mouse_button.y) + " Button: " + itos(mouse_button.button_index) + " Mask: ";
- for (int i = 0; i < 8; i++) {
-
- if ((1 << i) & mouse_button.button_mask)
- str += itos(i + 1);
- }
- str += " Mod: ";
- if (key.mod.shift)
- str += "S";
- if (key.mod.control)
- str += "C";
- if (key.mod.alt)
- str += "A";
- if (key.mod.meta)
- str += "M";
-
- str += String(" DoubleClick: ") + (mouse_button.doubleclick ? "Yes" : "No");
-
- return str;
-
- } break;
- case JOYPAD_MOTION: {
- str += "Event: JoypadMotion ";
- str = str + "Axis: " + itos(joy_motion.axis) + " Value: " + rtos(joy_motion.axis_value);
- return str;
-
- } break;
- case JOYPAD_BUTTON: {
- str += "Event: JoypadButton ";
- str = str + "Pressed: " + itos(joy_button.pressed) + " Index: " + itos(joy_button.button_index) + " pressure " + rtos(joy_button.pressure);
- return str;
-
- } break;
- case SCREEN_TOUCH: {
- str += "Event: ScreenTouch ";
- str = str + "Pressed: " + itos(screen_touch.pressed) + " Index: " + itos(screen_touch.index) + " pos " + rtos(screen_touch.x) + "," + rtos(screen_touch.y);
- return str;
-
- } break;
- case SCREEN_DRAG: {
- str += "Event: ScreenDrag ";
- str = str + " Index: " + itos(screen_drag.index) + " pos " + rtos(screen_drag.x) + "," + rtos(screen_drag.y);
- return str;
-
- } break;
- case ACTION: {
- str += "Event: Action: " + InputMap::get_singleton()->get_action_from_id(action.action) + " Pressed: " + itos(action.pressed);
- return str;
-
- } break;
- }
- return "";
+bool InputEvent::is_action(const StringName &p_action) const {
+
+ return InputMap::get_singleton()->event_is_action(Ref<InputEvent>((InputEvent *)this), p_action);
}
-void InputEvent::set_as_action(const String &p_action, bool p_pressed) {
+bool InputEvent::is_action_pressed(const StringName &p_action) const {
- type = ACTION;
- action.action = InputMap::get_singleton()->get_action_id(p_action);
- action.pressed = p_pressed;
+ return (is_pressed() && !is_echo() && is_action(p_action));
}
+bool InputEvent::is_action_released(const StringName &p_action) const {
-bool InputEvent::is_pressed() const {
+ return (!is_pressed() && is_action(p_action));
+}
- switch (type) {
+bool InputEvent::is_echo() const {
- case KEY: return key.pressed;
- case MOUSE_BUTTON: return mouse_button.pressed;
- case JOYPAD_BUTTON: return joy_button.pressed;
- case SCREEN_TOUCH: return screen_touch.pressed;
- case JOYPAD_MOTION: return ABS(joy_motion.axis_value) > 0.5;
- case ACTION: return action.pressed;
- default: {}
- }
+ return false;
+}
+
+Ref<InputEvent> InputEvent::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
+
+ return Ref<InputEvent>((InputEvent *)this);
+}
+
+String InputEvent::as_text() const {
+
+ return String();
+}
+
+bool InputEvent::action_match(const Ref<InputEvent> &p_event) const {
return false;
}
-bool InputEvent::is_echo() const {
+bool InputEvent::is_action_type() const {
+
+ return false;
+}
+
+#if 0
+if (String(p_method) == "is_action" && p_argidx == 0) {
+
+ List<PropertyInfo> pinfo;
+ GlobalConfig::get_singleton()->get_property_list(&pinfo);
+
+ for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
+ const PropertyInfo &pi = E->get();
+
+ if (!pi.name.begins_with("input/"))
+ continue;
+
+ String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
+ result.insert("\"" + name + "\"");
+ }
+
+} else
+#endif
+
+void InputEvent::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_id", "id"), &InputEvent::set_id);
+ ClassDB::bind_method(D_METHOD("get_id"), &InputEvent::get_id);
+
+ ClassDB::bind_method(D_METHOD("set_device", "device"), &InputEvent::set_device);
+ ClassDB::bind_method(D_METHOD("get_device"), &InputEvent::get_device);
+
+ ClassDB::bind_method(D_METHOD("is_pressed"), &InputEvent::is_pressed);
+ ClassDB::bind_method(D_METHOD("is_action", "action"), &InputEvent::is_action);
+ ClassDB::bind_method(D_METHOD("is_action_pressed", "action"), &InputEvent::is_action_pressed);
+ ClassDB::bind_method(D_METHOD("is_action_released", "action"), &InputEvent::is_action_released);
+ ClassDB::bind_method(D_METHOD("is_echo"), &InputEvent::is_echo);
+
+ ClassDB::bind_method(D_METHOD("as_text"), &InputEvent::as_text);
+
+ ClassDB::bind_method(D_METHOD("action_match", "event:InputEvent"), &InputEvent::action_match);
+
+ ClassDB::bind_method(D_METHOD("is_action_type"), &InputEvent::is_action_type);
+
+ ClassDB::bind_method(D_METHOD("xformed_by:InputEvent", "xform", "local_ofs"), &InputEvent::xformed_by, DEFVAL(Vector2()));
+}
+
+InputEvent::InputEvent() {
+
+ id = 0;
+ device = 0;
+}
+
+//////////////////
+
+void InputEventWithModifiers::set_shift(bool p_enabled) {
+
+ shift = p_enabled;
+}
+
+bool InputEventWithModifiers::get_shift() const {
+
+ return shift;
+}
+
+void InputEventWithModifiers::set_alt(bool p_enabled) {
+
+ alt = p_enabled;
+}
+bool InputEventWithModifiers::get_alt() const {
+
+ return alt;
+}
+
+void InputEventWithModifiers::set_control(bool p_enabled) {
+
+ control = p_enabled;
+}
+bool InputEventWithModifiers::get_control() const {
+
+ return control;
+}
+
+void InputEventWithModifiers::set_metakey(bool p_enabled) {
+
+ meta = p_enabled;
+}
+bool InputEventWithModifiers::get_metakey() const {
+
+ return meta;
+}
+
+void InputEventWithModifiers::set_command(bool p_enabled) {
+
+ command = p_enabled;
+}
+bool InputEventWithModifiers::get_command() const {
+
+ return command;
+}
+
+void InputEventWithModifiers::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_alt", "enable"), &InputEventWithModifiers::set_alt);
+ ClassDB::bind_method(D_METHOD("get_alt"), &InputEventWithModifiers::get_alt);
+
+ ClassDB::bind_method(D_METHOD("set_shift", "enable"), &InputEventWithModifiers::set_shift);
+ ClassDB::bind_method(D_METHOD("get_shift"), &InputEventWithModifiers::get_shift);
+
+ ClassDB::bind_method(D_METHOD("set_control", "enable"), &InputEventWithModifiers::set_control);
+ ClassDB::bind_method(D_METHOD("get_control"), &InputEventWithModifiers::get_control);
+
+ ClassDB::bind_method(D_METHOD("set_metakey", "enable"), &InputEventWithModifiers::set_metakey);
+ ClassDB::bind_method(D_METHOD("get_metakey"), &InputEventWithModifiers::get_metakey);
+
+ ClassDB::bind_method(D_METHOD("set_command", "enable"), &InputEventWithModifiers::set_command);
+ ClassDB::bind_method(D_METHOD("get_command"), &InputEventWithModifiers::get_command);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "alt"), "set_alt", "get_alt");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "shift"), "set_shift", "get_shift");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "control"), "set_control", "get_control");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "meta"), "set_metakey", "get_metakey");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "command"), "set_command", "get_command");
+}
+
+InputEventWithModifiers::InputEventWithModifiers() {
+
+ alt = false;
+ shift = false;
+ control = false;
+ meta = false;
+}
+
+//////////////////////////////////
+
+void InputEventKey::set_pressed(bool p_pressed) {
- return (type == KEY && key.echo);
+ pressed = p_pressed;
}
-bool InputEvent::is_action(const String &p_action) const {
+bool InputEventKey::is_pressed() const {
- return InputMap::get_singleton()->event_is_action(*this, p_action);
+ return pressed;
}
-bool InputEvent::is_action_pressed(const String &p_action) const {
+void InputEventKey::set_scancode(uint32_t p_scancode) {
- return is_action(p_action) && is_pressed() && !is_echo();
+ scancode = p_scancode;
}
+uint32_t InputEventKey::get_scancode() const {
-bool InputEvent::is_action_released(const String &p_action) const {
+ return scancode;
+}
+
+void InputEventKey::set_unicode(uint32_t p_unicode) {
+
+ unicode = p_unicode;
+}
+uint32_t InputEventKey::get_unicode() const {
+
+ return unicode;
+}
- return is_action(p_action) && !is_pressed();
+void InputEventKey::set_echo(bool p_enable) {
+
+ echo = p_enable;
+}
+bool InputEventKey::is_echo() const {
+
+ return echo;
}
uint32_t InputEventKey::get_scancode_with_modifiers() const {
uint32_t sc = scancode;
- if (mod.control)
+ if (get_control())
sc |= KEY_MASK_CTRL;
- if (mod.alt)
+ if (get_alt())
sc |= KEY_MASK_ALT;
- if (mod.shift)
+ if (get_shift())
sc |= KEY_MASK_SHIFT;
- if (mod.meta)
+ if (get_metakey())
sc |= KEY_MASK_META;
return sc;
}
-InputEvent InputEvent::xform_by(const Transform2D &p_xform) const {
-
- InputEvent ev = *this;
-
- switch (ev.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- Vector2 g = p_xform.xform(Vector2(ev.mouse_button.global_x, ev.mouse_button.global_y));
- Vector2 l = p_xform.xform(Vector2(ev.mouse_button.x, ev.mouse_button.y));
- ev.mouse_button.x = l.x;
- ev.mouse_button.y = l.y;
- ev.mouse_button.global_x = g.x;
- ev.mouse_button.global_y = g.y;
-
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- Vector2 g = p_xform.xform(Vector2(ev.mouse_motion.global_x, ev.mouse_motion.global_y));
- Vector2 l = p_xform.xform(Vector2(ev.mouse_motion.x, ev.mouse_motion.y));
- Vector2 r = p_xform.basis_xform(Vector2(ev.mouse_motion.relative_x, ev.mouse_motion.relative_y));
- Vector2 s = p_xform.basis_xform(Vector2(ev.mouse_motion.speed_x, ev.mouse_motion.speed_y));
- ev.mouse_motion.x = l.x;
- ev.mouse_motion.y = l.y;
- ev.mouse_motion.global_x = g.x;
- ev.mouse_motion.global_y = g.y;
- ev.mouse_motion.relative_x = r.x;
- ev.mouse_motion.relative_y = r.y;
- ev.mouse_motion.speed_x = s.x;
- ev.mouse_motion.speed_y = s.y;
-
- } break;
- case InputEvent::SCREEN_TOUCH: {
-
- Vector2 t = p_xform.xform(Vector2(ev.screen_touch.x, ev.screen_touch.y));
- ev.screen_touch.x = t.x;
- ev.screen_touch.y = t.y;
-
- } break;
- case InputEvent::SCREEN_DRAG: {
-
- Vector2 t = p_xform.xform(Vector2(ev.screen_drag.x, ev.screen_drag.y));
- Vector2 r = p_xform.basis_xform(Vector2(ev.screen_drag.relative_x, ev.screen_drag.relative_y));
- Vector2 s = p_xform.basis_xform(Vector2(ev.screen_drag.speed_x, ev.screen_drag.speed_y));
- ev.screen_drag.x = t.x;
- ev.screen_drag.y = t.y;
- ev.screen_drag.relative_x = r.x;
- ev.screen_drag.relative_y = r.y;
- ev.screen_drag.speed_x = s.x;
- ev.screen_drag.speed_y = s.y;
- } break;
- }
+bool InputEventKey::action_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventKey> key = p_event;
+ if (key.is_null())
+ return false;
+
+ uint32_t code = get_scancode_with_modifiers();
+ uint32_t event_code = key->get_scancode_with_modifiers();
+
+ return get_scancode() == key->get_scancode() && (!key->is_pressed() || (code & event_code) == code);
+}
+
+void InputEventKey::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventKey::set_pressed);
+
+ ClassDB::bind_method(D_METHOD("set_scancode", "scancode"), &InputEventKey::set_scancode);
+ ClassDB::bind_method(D_METHOD("get_scancode"), &InputEventKey::get_scancode);
+
+ ClassDB::bind_method(D_METHOD("set_unicode", "unicode"), &InputEventKey::set_unicode);
+ ClassDB::bind_method(D_METHOD("get_unicode"), &InputEventKey::get_unicode);
+
+ ClassDB::bind_method(D_METHOD("set_echo", "echo"), &InputEventKey::set_echo);
+
+ ClassDB::bind_method(D_METHOD("get_scancode_with_modifiers"), &InputEventKey::get_scancode_with_modifiers);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "scancode"), "set_scancode", "get_scancode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "unicode"), "set_unicode", "get_unicode");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "echo"), "set_echo", "is_echo");
+}
+
+InputEventKey::InputEventKey() {
+
+ pressed = false;
+ scancode = 0;
+ unicode = 0; ///unicode
+ echo = false;
+}
+
+////////////////////////////////////////
+
+void InputEventMouse::set_button_mask(int p_mask) {
+
+ button_mask = p_mask;
+}
+int InputEventMouse::get_button_mask() const {
+
+ return button_mask;
+}
+
+void InputEventMouse::set_position(const Vector2 &p_pos) {
+
+ pos = p_pos;
+}
+Vector2 InputEventMouse::get_position() const {
+
+ return pos;
+}
+
+void InputEventMouse::set_global_position(const Vector2 &p_global_pos) {
+
+ global_pos = p_global_pos;
+}
+Vector2 InputEventMouse::get_global_position() const {
+
+ return global_pos;
+}
+
+void InputEventMouse::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_button_mask", "button_mask"), &InputEventMouse::set_button_mask);
+ ClassDB::bind_method(D_METHOD("get_button_mask"), &InputEventMouse::get_button_mask);
+
+ ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventMouse::set_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &InputEventMouse::get_position);
+
+ ClassDB::bind_method(D_METHOD("set_global_position", "global_position"), &InputEventMouse::set_global_position);
+ ClassDB::bind_method(D_METHOD("get_global_position"), &InputEventMouse::get_global_position);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "button_mask"), "set_button_mask", "get_button_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "global_position"), "set_global_position", "get_global_position");
+}
+
+InputEventMouse::InputEventMouse() {
+
+ button_mask = 0;
+}
+
+///////////////////////////////////////
+
+void InputEventMouseButton::set_factor(float p_factor) {
+
+ factor = p_factor;
+}
+
+float InputEventMouseButton::get_factor() {
+
+ return factor;
+}
+
+void InputEventMouseButton::set_button_index(int p_index) {
+
+ button_index = p_index;
+}
+int InputEventMouseButton::get_button_index() const {
+
+ return button_index;
+}
+
+void InputEventMouseButton::set_pressed(bool p_pressed) {
+
+ pressed = p_pressed;
+}
+bool InputEventMouseButton::is_pressed() const {
+
+ return pressed;
+}
+
+void InputEventMouseButton::set_doubleclick(bool p_doubleclick) {
+
+ doubleclick = p_doubleclick;
+}
+bool InputEventMouseButton::is_doubleclick() const {
+
+ return doubleclick;
+}
+
+Ref<InputEvent> InputEventMouseButton::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
+
+ Vector2 g = p_xform.xform(get_global_position());
+ Vector2 l = p_xform.xform(get_position() + p_local_ofs);
+
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ mb->set_id(get_id());
+ mb->set_device(get_device());
+
+ mb->set_alt(get_alt());
+ mb->set_shift(get_shift());
+ mb->set_control(get_control());
+ mb->set_metakey(get_metakey());
+
+ mb->set_position(l);
+ mb->set_global_position(g);
+
+ mb->set_button_mask(get_button_mask());
+ mb->set_pressed(pressed);
+ mb->set_doubleclick(doubleclick);
+ mb->set_factor(factor);
+ mb->set_button_index(button_index);
+
+ return mb;
+}
+
+bool InputEventMouseButton::action_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_null())
+ return false;
+
+ return mb->button_index == button_index;
+}
+
+void InputEventMouseButton::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_factor", "factor"), &InputEventMouseButton::set_factor);
+ ClassDB::bind_method(D_METHOD("get_factor"), &InputEventMouseButton::get_factor);
+
+ ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventMouseButton::set_button_index);
+ ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventMouseButton::get_button_index);
+
+ ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventMouseButton::set_pressed);
+ // ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventMouseButton::is_pressed);
+
+ ClassDB::bind_method(D_METHOD("set_doubleclick", "doubleclick"), &InputEventMouseButton::set_doubleclick);
+ ClassDB::bind_method(D_METHOD("is_doubleclick"), &InputEventMouseButton::is_doubleclick);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "factor"), "set_factor", "get_factor");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "doubleclick"), "set_doubleclick", "is_doubleclick");
+}
+
+InputEventMouseButton::InputEventMouseButton() {
+
+ factor = 1;
+ button_index = 0;
+ pressed = false;
+ doubleclick = false;
+}
+
+////////////////////////////////////////////
+
+void InputEventMouseMotion::set_relative(const Vector2 &p_relative) {
+
+ relative = p_relative;
+}
+Vector2 InputEventMouseMotion::get_relative() const {
+
+ return relative;
+}
+
+void InputEventMouseMotion::set_speed(const Vector2 &p_speed) {
+
+ speed = p_speed;
+}
+Vector2 InputEventMouseMotion::get_speed() const {
+
+ return speed;
+}
+
+Ref<InputEvent> InputEventMouseMotion::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
+
+ Vector2 g = p_xform.xform(get_global_position());
+ Vector2 l = p_xform.xform(get_position() + p_local_ofs);
+ Vector2 r = p_xform.basis_xform(get_relative());
+ Vector2 s = p_xform.basis_xform(get_speed());
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_id(get_id());
+ mm->set_device(get_device());
+
+ mm->set_alt(get_alt());
+ mm->set_shift(get_shift());
+ mm->set_control(get_control());
+ mm->set_metakey(get_metakey());
+
+ mm->set_position(l);
+ mm->set_global_position(g);
+
+ mm->set_button_mask(get_button_mask());
+ mm->set_relative(r);
+ mm->set_speed(s);
+
+ return mm;
+}
+
+void InputEventMouseMotion::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventMouseMotion::set_relative);
+ ClassDB::bind_method(D_METHOD("get_relative"), &InputEventMouseMotion::get_relative);
+
+ ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventMouseMotion::set_speed);
+ ClassDB::bind_method(D_METHOD("get_speed"), &InputEventMouseMotion::get_speed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
+}
+
+InputEventMouseMotion::InputEventMouseMotion() {
+}
+
+////////////////////////////////////////
+
+void InputEventJoypadMotion::set_axis(int p_axis) {
+
+ axis = p_axis;
+}
+
+int InputEventJoypadMotion::get_axis() const {
+
+ return axis;
+}
+
+void InputEventJoypadMotion::set_axis_value(float p_value) {
+
+ axis_value = p_value;
+}
+float InputEventJoypadMotion::get_axis_value() const {
+
+ return axis_value;
+}
+
+bool InputEventJoypadMotion::action_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventJoypadMotion> jm = p_event;
+ if (jm.is_null())
+ return false;
+
+ return (axis == jm->axis && (axis_value < 0) == (jm->axis_value < 0));
+}
+
+void InputEventJoypadMotion::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_axis", "axis"), &InputEventJoypadMotion::set_axis);
+ ClassDB::bind_method(D_METHOD("get_axis"), &InputEventJoypadMotion::get_axis);
+
+ ClassDB::bind_method(D_METHOD("set_axis_value", "axis_value"), &InputEventJoypadMotion::set_axis_value);
+ ClassDB::bind_method(D_METHOD("get_axis_value"), &InputEventJoypadMotion::get_axis_value);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "axis"), "set_axis", "get_axis");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "axis_value"), "set_axis_value", "get_axis_value");
+}
+
+InputEventJoypadMotion::InputEventJoypadMotion() {
+
+ axis = 0;
+ axis_value = 0;
+}
+/////////////////////////////////
+
+void InputEventJoypadButton::set_button_index(int p_index) {
+
+ button_index = p_index;
+}
+
+int InputEventJoypadButton::get_button_index() const {
+
+ return button_index;
+}
+
+void InputEventJoypadButton::set_pressed(bool p_pressed) {
+
+ pressed = p_pressed;
+}
+bool InputEventJoypadButton::is_pressed() const {
+
+ return pressed;
+}
+
+void InputEventJoypadButton::set_pressure(float p_pressure) {
+
+ pressure = p_pressure;
+}
+float InputEventJoypadButton::get_pressure() const {
+
+ return pressure;
+}
+
+bool InputEventJoypadButton::action_match(const Ref<InputEvent> &p_event) const {
+
+ Ref<InputEventJoypadButton> jb = p_event;
+ if (jb.is_null())
+ return false;
+
+ return button_index == jb->button_index;
+}
+
+void InputEventJoypadButton::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_button_index", "button_index"), &InputEventJoypadButton::set_button_index);
+ ClassDB::bind_method(D_METHOD("get_button_index"), &InputEventJoypadButton::get_button_index);
+
+ ClassDB::bind_method(D_METHOD("set_pressure", "pressure"), &InputEventJoypadButton::set_pressure);
+ ClassDB::bind_method(D_METHOD("get_pressure"), &InputEventJoypadButton::get_pressure);
+
+ ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventJoypadButton::set_pressed);
+ // ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventJoypadButton::is_pressed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "button_index"), "set_button_index", "get_button_index");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "pressure"), "set_pressure", "get_pressure");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+}
+
+InputEventJoypadButton::InputEventJoypadButton() {
+
+ button_index = 0;
+ pressure = 0;
+ pressed = false;
+}
+
+//////////////////////////////////////////////
+
+void InputEventScreenTouch::set_index(int p_index) {
+
+ index = p_index;
+}
+int InputEventScreenTouch::get_index() const {
+
+ return index;
+}
+
+void InputEventScreenTouch::set_position(const Vector2 &p_pos) {
+
+ pos = p_pos;
+}
+Vector2 InputEventScreenTouch::get_position() const {
+
+ return pos;
+}
+
+void InputEventScreenTouch::set_pressed(bool p_pressed) {
+
+ pressed = p_pressed;
+}
+bool InputEventScreenTouch::is_pressed() const {
+
+ return pressed;
+}
+
+Ref<InputEvent> InputEventScreenTouch::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
+
+ Ref<InputEventScreenTouch> st;
+ st.instance();
+ st->set_id(get_id());
+ st->set_device(get_device());
+ st->set_index(index);
+ st->set_position(p_xform.xform(pos + p_local_ofs));
+ st->set_pressed(pressed);
+
+ return st;
+}
+
+void InputEventScreenTouch::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenTouch::set_index);
+ ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenTouch::get_index);
+
+ ClassDB::bind_method(D_METHOD("set_position", "pos"), &InputEventScreenTouch::set_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenTouch::get_position);
+
+ ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventScreenTouch::set_pressed);
+ //ClassDB::bind_method(D_METHOD("is_pressed"),&InputEventScreenTouch::is_pressed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+}
+
+InputEventScreenTouch::InputEventScreenTouch() {
+
+ index = 0;
+ pressed = false;
+}
+
+/////////////////////////////
+
+void InputEventScreenDrag::set_index(int p_index) {
+
+ index = p_index;
+}
+
+int InputEventScreenDrag::get_index() const {
+
+ return index;
+}
+
+void InputEventScreenDrag::set_position(const Vector2 &p_pos) {
+
+ pos = p_pos;
+}
+Vector2 InputEventScreenDrag::get_position() const {
+
+ return pos;
+}
+
+void InputEventScreenDrag::set_relative(const Vector2 &p_relative) {
+
+ relative = p_relative;
+}
+Vector2 InputEventScreenDrag::get_relative() const {
+
+ return relative;
+}
+
+void InputEventScreenDrag::set_speed(const Vector2 &p_speed) {
+
+ speed = p_speed;
+}
+Vector2 InputEventScreenDrag::get_speed() const {
+
+ return speed;
+}
+
+Ref<InputEvent> InputEventScreenDrag::xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs) const {
+
+ Ref<InputEventScreenDrag> sd;
+
+ sd.instance();
+
+ sd->set_id(get_id());
+ sd->set_device(get_device());
+
+ sd->set_index(index);
+ sd->set_position(p_xform.xform(pos + p_local_ofs));
+ sd->set_relative(p_xform.basis_xform(relative));
+ sd->set_speed(p_xform.basis_xform(speed));
+
+ return sd;
+}
+
+void InputEventScreenDrag::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_index", "index"), &InputEventScreenDrag::set_index);
+ ClassDB::bind_method(D_METHOD("get_index"), &InputEventScreenDrag::get_index);
+
+ ClassDB::bind_method(D_METHOD("set_position", "position"), &InputEventScreenDrag::set_position);
+ ClassDB::bind_method(D_METHOD("get_position"), &InputEventScreenDrag::get_position);
+
+ ClassDB::bind_method(D_METHOD("set_relative", "relative"), &InputEventScreenDrag::set_relative);
+ ClassDB::bind_method(D_METHOD("get_relative"), &InputEventScreenDrag::get_relative);
+
+ ClassDB::bind_method(D_METHOD("set_speed", "speed"), &InputEventScreenDrag::set_speed);
+ ClassDB::bind_method(D_METHOD("get_speed"), &InputEventScreenDrag::get_speed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "index"), "set_index", "get_index");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "position"), "set_position", "get_position");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "relative"), "set_relative", "get_relative");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "speed"), "set_speed", "get_speed");
+}
+
+InputEventScreenDrag::InputEventScreenDrag() {
+
+ index = 0;
+}
+/////////////////////////////
+
+void InputEventAction::set_action(const StringName &p_action) {
+
+ action = p_action;
+}
+StringName InputEventAction::get_action() const {
+
+ return action;
+}
+
+void InputEventAction::set_pressed(bool p_pressed) {
+
+ pressed = p_pressed;
+}
+bool InputEventAction::is_pressed() const {
+
+ return pressed;
+}
+
+bool InputEventAction::is_action(const StringName &p_action) const {
+
+ return action == p_action;
+}
+
+void InputEventAction::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_action", "action"), &InputEventAction::set_action);
+ ClassDB::bind_method(D_METHOD("get_action"), &InputEventAction::get_action);
+
+ ClassDB::bind_method(D_METHOD("set_pressed", "pressed"), &InputEventAction::set_pressed);
+ //ClassDB::bind_method(D_METHOD("is_pressed"), &InputEventAction::is_pressed);
+
+ // ClassDB::bind_method(D_METHOD("is_action", "name"), &InputEventAction::is_action);
+
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "action"), "set_action", "get_action");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "pressed"), "set_pressed", "is_pressed");
+}
- return ev;
+InputEventAction::InputEventAction() {
+ pressed = false;
}
diff --git a/core/os/input_event.h b/core/os/input_event.h
index eb5c5685e5..6a694df345 100644
--- a/core/os/input_event.h
+++ b/core/os/input_event.h
@@ -32,6 +32,7 @@
#include "math_2d.h"
#include "os/copymem.h"
+#include "resource.h"
#include "typedefs.h"
#include "ustring.h"
/**
@@ -137,7 +138,40 @@ enum {
* Input Modifier Status
* for keyboard/mouse events.
*/
-struct InputModifierState {
+
+class InputEvent : public Resource {
+ GDCLASS(InputEvent, Resource)
+
+ uint32_t id;
+ int device;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_id(uint32_t p_id);
+ uint32_t get_id() const;
+
+ void set_device(int p_device);
+ int get_device() const;
+
+ virtual bool is_pressed() const;
+ virtual bool is_action(const StringName &p_action) const;
+ virtual bool is_action_pressed(const StringName &p_action) const;
+ virtual bool is_action_released(const StringName &p_action) const;
+ virtual bool is_echo() const;
+ virtual String as_text() const;
+
+ virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
+
+ virtual bool action_match(const Ref<InputEvent> &p_event) const;
+ virtual bool is_action_type() const;
+
+ InputEvent();
+};
+
+class InputEventWithModifiers : public InputEvent {
+ GDCLASS(InputEventWithModifiers, InputEvent)
bool shift;
bool alt;
@@ -157,122 +191,267 @@ struct InputModifierState {
#endif
- bool operator==(const InputModifierState &rvalue) const {
+protected:
+ static void _bind_methods();
+
+public:
+ void set_shift(bool p_enabled);
+ bool get_shift() const;
+
+ void set_alt(bool p_enabled);
+ bool get_alt() const;
+
+ void set_control(bool p_enabled);
+ bool get_control() const;
+
+ void set_metakey(bool p_enabled);
+ bool get_metakey() const;
- return ((shift == rvalue.shift) && (alt == rvalue.alt) && (control == rvalue.control) && (meta == rvalue.meta));
- }
+ void set_command(bool p_enabled);
+ bool get_command() const;
+
+ InputEventWithModifiers();
};
-struct InputEventKey {
+class InputEventKey : public InputEventWithModifiers {
- InputModifierState mod;
+ GDCLASS(InputEventKey, InputEventWithModifiers)
bool pressed; /// otherwise release
uint32_t scancode; ///< check keyboard.h , KeyCode enum, without modifier masks
uint32_t unicode; ///unicode
+ bool echo; /// true if this is an echo key
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_pressed(bool p_pressed);
+ virtual bool is_pressed() const;
+
+ void set_scancode(uint32_t p_scancode);
+ uint32_t get_scancode() const;
+
+ void set_unicode(uint32_t p_unicode);
+ uint32_t get_unicode() const;
+
+ void set_echo(bool p_enable);
+ virtual bool is_echo() const;
+
uint32_t get_scancode_with_modifiers() const;
- bool echo; /// true if this is an echo key
+ virtual bool action_match(const Ref<InputEvent> &p_event) const;
+
+ virtual bool is_action_type() const { return true; }
+
+ InputEventKey();
};
-struct InputEventMouse {
+class InputEventMouse : public InputEventWithModifiers {
+
+ GDCLASS(InputEventMouse, InputEventWithModifiers)
- InputModifierState mod;
int button_mask;
- float x, y;
- float global_x, global_y;
- int pointer_index;
+
+ Vector2 pos;
+ Vector2 global_pos;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_button_mask(int p_mask);
+ int get_button_mask() const;
+
+ void set_position(const Vector2 &p_pos);
+ Vector2 get_position() const;
+
+ void set_global_position(const Vector2 &p_global_pos);
+ Vector2 get_global_position() const;
+
+ InputEventMouse();
};
-struct InputEventMouseButton : public InputEventMouse {
+class InputEventMouseButton : public InputEventMouse {
+
+ GDCLASS(InputEventMouseButton, InputEventMouse)
+ float factor;
int button_index;
bool pressed; //otherwise released
bool doubleclick; //last even less than doubleclick time
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_factor(float p_factor);
+ float get_factor();
+
+ void set_button_index(int p_index);
+ int get_button_index() const;
+
+ void set_pressed(bool p_pressed);
+ virtual bool is_pressed() const;
+
+ void set_doubleclick(bool p_doubleclick);
+ bool is_doubleclick() const;
+
+ virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
+ virtual bool action_match(const Ref<InputEvent> &p_event) const;
+
+ virtual bool is_action_type() const { return true; }
+
+ InputEventMouseButton();
};
-struct InputEventMouseMotion : public InputEventMouse {
+class InputEventMouseMotion : public InputEventMouse {
+
+ GDCLASS(InputEventMouseMotion, InputEventMouse)
+ Vector2 relative;
+ Vector2 speed;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_relative(const Vector2 &p_relative);
+ Vector2 get_relative() const;
+
+ void set_speed(const Vector2 &p_speed);
+ Vector2 get_speed() const;
+
+ virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
- float relative_x, relative_y;
- float speed_x, speed_y;
+ InputEventMouseMotion();
};
-struct InputEventJoypadMotion {
+class InputEventJoypadMotion : public InputEvent {
+ GDCLASS(InputEventJoypadMotion, InputEvent)
int axis; ///< Joypad axis
float axis_value; ///< -1 to 1
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_axis(int p_axis);
+ int get_axis() const;
+
+ void set_axis_value(float p_value);
+ float get_axis_value() const;
+
+ virtual bool action_match(const Ref<InputEvent> &p_event) const;
+
+ virtual bool is_action_type() const { return true; }
+
+ InputEventJoypadMotion();
};
-struct InputEventJoypadButton {
+class InputEventJoypadButton : public InputEvent {
+ GDCLASS(InputEventJoypadButton, InputEvent)
int button_index;
bool pressed;
float pressure; //0 to 1
-};
+protected:
+ static void _bind_methods();
+
+public:
+ void set_button_index(int p_index);
+ int get_button_index() const;
+
+ void set_pressed(bool p_pressed);
+ virtual bool is_pressed() const;
+
+ void set_pressure(float p_pressure);
+ float get_pressure() const;
-struct InputEventScreenTouch {
+ virtual bool action_match(const Ref<InputEvent> &p_event) const;
+ virtual bool is_action_type() const { return true; }
+
+ InputEventJoypadButton();
+};
+
+class InputEventScreenTouch : public InputEvent {
+ GDCLASS(InputEventScreenTouch, InputEvent)
int index;
- float x, y;
+ Vector2 pos;
bool pressed;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_index(int p_index);
+ int get_index() const;
+
+ void set_position(const Vector2 &p_pos);
+ Vector2 get_position() const;
+
+ void set_pressed(bool p_pressed);
+ virtual bool is_pressed() const;
+
+ virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
+
+ InputEventScreenTouch();
};
-struct InputEventScreenDrag {
+class InputEventScreenDrag : public InputEvent {
+
+ GDCLASS(InputEventScreenDrag, InputEvent)
int index;
- float x, y;
- float relative_x, relative_y;
- float speed_x, speed_y;
+ Vector2 pos;
+ Vector2 relative;
+ Vector2 speed;
+
+protected:
+ static void _bind_methods();
+
+public:
+ void set_index(int p_index);
+ int get_index() const;
+
+ void set_position(const Vector2 &p_pos);
+ Vector2 get_position() const;
+
+ void set_relative(const Vector2 &p_relative);
+ Vector2 get_relative() const;
+
+ void set_speed(const Vector2 &p_speed);
+ Vector2 get_speed() const;
+
+ virtual Ref<InputEvent> xformed_by(const Transform2D &p_xform, const Vector2 &p_local_ofs = Vector2()) const;
+
+ InputEventScreenDrag();
};
-struct InputEventAction {
+class InputEventAction : public InputEvent {
+
+ GDCLASS(InputEventAction, InputEvent)
- int action;
+ StringName action;
bool pressed;
-};
-struct InputEvent {
-
- enum Type {
- NONE,
- KEY,
- MOUSE_MOTION,
- MOUSE_BUTTON,
- JOYPAD_MOTION,
- JOYPAD_BUTTON,
- SCREEN_TOUCH,
- SCREEN_DRAG,
- ACTION,
- TYPE_MAX
- };
+protected:
+ static void _bind_methods();
- uint32_t ID;
- int type;
- int device;
+public:
+ void set_action(const StringName &p_action);
+ StringName get_action() const;
- union {
- InputEventMouseMotion mouse_motion;
- InputEventMouseButton mouse_button;
- InputEventJoypadMotion joy_motion;
- InputEventJoypadButton joy_button;
- InputEventKey key;
- InputEventScreenTouch screen_touch;
- InputEventScreenDrag screen_drag;
- InputEventAction action;
- };
+ void set_pressed(bool p_pressed);
+ virtual bool is_pressed() const;
+
+ virtual bool is_action(const StringName &p_action) const;
+
+ virtual bool is_action_type() const { return true; }
- bool is_pressed() const;
- bool is_action(const String &p_action) const;
- bool is_action_pressed(const String &p_action) const;
- bool is_action_released(const String &p_action) const;
- bool is_echo() const;
- void set_as_action(const String &p_action, bool p_pressed);
-
- InputEvent xform_by(const Transform2D &p_xform) const;
- bool operator==(const InputEvent &p_event) const;
- operator String() const;
- InputEvent() { zeromem(this, sizeof(InputEvent)); }
+ InputEventAction();
};
#endif
diff --git a/core/os/main_loop.cpp b/core/os/main_loop.cpp
index 9f8fcccd82..248f5537c6 100644
--- a/core/os/main_loop.cpp
+++ b/core/os/main_loop.cpp
@@ -39,7 +39,7 @@ void MainLoop::_bind_methods() {
ClassDB::bind_method(D_METHOD("idle", "delta"), &MainLoop::idle);
ClassDB::bind_method(D_METHOD("finish"), &MainLoop::finish);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::INPUT_EVENT, "ev")));
+ BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "ev", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo("_input_text", PropertyInfo(Variant::STRING, "text")));
BIND_VMETHOD(MethodInfo("_initialize"));
BIND_VMETHOD(MethodInfo("_iteration", PropertyInfo(Variant::REAL, "delta")));
@@ -73,7 +73,7 @@ void MainLoop::input_text(const String &p_text) {
get_script_instance()->call("_input_text", p_text);
}
-void MainLoop::input_event(const InputEvent &p_event) {
+void MainLoop::input_event(const Ref<InputEvent> &p_event) {
if (get_script_instance())
get_script_instance()->call("_input_event", p_event);
diff --git a/core/os/main_loop.h b/core/os/main_loop.h
index a53137afa4..23b352468e 100644
--- a/core/os/main_loop.h
+++ b/core/os/main_loop.h
@@ -59,7 +59,7 @@ public:
NOTIFICATION_TRANSLATION_CHANGED = 10,
};
- virtual void input_event(const InputEvent &p_event);
+ virtual void input_event(const Ref<InputEvent> &p_event);
virtual void input_text(const String &p_text);
virtual void init();
diff --git a/core/os/os.cpp b/core/os/os.cpp
index e323e03829..8bee725813 100644
--- a/core/os/os.cpp
+++ b/core/os/os.cpp
@@ -389,7 +389,7 @@ void OS::_ensure_data_dir() {
memdelete(da);
}
-void OS::set_icon(const Image &p_icon) {
+void OS::set_icon(const Ref<Image> &p_icon) {
}
String OS::get_model_name() const {
diff --git a/core/os/os.h b/core/os/os.h
index ff2a24f40d..11fe8b44e3 100644
--- a/core/os/os.h
+++ b/core/os/os.h
@@ -31,6 +31,7 @@
#define OS_H
#include "engine.h"
+#include "image.h"
#include "list.h"
#include "os/main_loop.h"
#include "power.h"
@@ -357,7 +358,7 @@ public:
virtual void make_rendering_thread();
virtual void swap_buffers();
- virtual void set_icon(const Image &p_icon);
+ virtual void set_icon(const Ref<Image> &p_icon);
virtual int get_exit_code() const;
virtual void set_exit_code(int p_code);
@@ -412,4 +413,6 @@ public:
virtual ~OS();
};
+VARIANT_ENUM_CAST(PowerState);
+
#endif
diff --git a/core/packed_data_container.cpp b/core/packed_data_container.cpp
index addb0841f4..0565d0d3f5 100644
--- a/core/packed_data_container.cpp
+++ b/core/packed_data_container.cpp
@@ -237,8 +237,6 @@ uint32_t PackedDataContainer::_pack(const Variant &p_data, Vector<uint8_t> &tmpd
case Variant::RECT3:
case Variant::BASIS:
case Variant::TRANSFORM:
- case Variant::IMAGE:
- case Variant::INPUT_EVENT:
case Variant::POOL_BYTE_ARRAY:
case Variant::POOL_INT_ARRAY:
case Variant::POOL_REAL_ARRAY:
diff --git a/core/register_core_types.cpp b/core/register_core_types.cpp
index 4d12e42895..b089ba9129 100644
--- a/core/register_core_types.cpp
+++ b/core/register_core_types.cpp
@@ -108,6 +108,20 @@ void register_core_types() {
ClassDB::register_class<Reference>();
ClassDB::register_class<WeakRef>();
ClassDB::register_class<Resource>();
+ ClassDB::register_class<Image>();
+
+ ClassDB::register_virtual_class<InputEvent>();
+ ClassDB::register_virtual_class<InputEventWithModifiers>();
+ ClassDB::register_class<InputEventKey>();
+ ClassDB::register_virtual_class<InputEventMouse>();
+ ClassDB::register_class<InputEventMouseButton>();
+ ClassDB::register_class<InputEventMouseMotion>();
+ ClassDB::register_class<InputEventJoypadButton>();
+ ClassDB::register_class<InputEventJoypadMotion>();
+ ClassDB::register_class<InputEventScreenDrag>();
+ ClassDB::register_class<InputEventScreenTouch>();
+ ClassDB::register_class<InputEventAction>();
+
ClassDB::register_class<FuncRef>();
ClassDB::register_virtual_class<StreamPeer>();
ClassDB::register_class<StreamPeerBuffer>();
diff --git a/core/resource.cpp b/core/resource.cpp
index aa070558f5..559d4c1201 100644
--- a/core/resource.cpp
+++ b/core/resource.cpp
@@ -185,7 +185,7 @@ Ref<Resource> Resource::duplicate_for_local_scene(Node *p_for_scene, Map<Ref<Res
return Ref<Resource>(r);
}
-Ref<Resource> Resource::duplicate(bool p_subresources) {
+Ref<Resource> Resource::duplicate(bool p_subresources) const {
List<PropertyInfo> plist;
get_property_list(&plist);
diff --git a/core/resource.h b/core/resource.h
index ab3404df8f..903edeff52 100644
--- a/core/resource.h
+++ b/core/resource.h
@@ -103,7 +103,7 @@ public:
void set_subindex(int p_sub_index);
int get_subindex() const;
- Ref<Resource> duplicate(bool p_subresources = false);
+ virtual Ref<Resource> duplicate(bool p_subresources = false) const;
Ref<Resource> duplicate_for_local_scene(Node *p_scene, Map<Ref<Resource>, Ref<Resource> > &remap_cache);
void set_local_to_scene(bool p_enable);
diff --git a/core/ring_buffer.h b/core/ring_buffer.h
index d5085e9560..8b32bb5e10 100644
--- a/core/ring_buffer.h
+++ b/core/ring_buffer.h
@@ -101,6 +101,32 @@ public:
return p_size;
};
+ int find(const T &t, int p_offset, int p_max_size) {
+
+ int left = data_left();
+ if ((p_offset + p_max_size) > left) {
+ p_max_size -= left - p_offset;
+ if (p_max_size <= 0)
+ return 0;
+ }
+ p_max_size = MIN(left, p_max_size);
+ int pos = read_pos;
+ inc(pos, p_offset);
+ int to_read = p_max_size;
+ while (to_read) {
+ int end = pos + to_read;
+ end = MIN(end, size());
+ int total = end - pos;
+ for (int i = 0; i < total; i++) {
+ if (data[pos + i] == t)
+ return i + (p_max_size - to_read);
+ };
+ to_read -= total;
+ pos = 0;
+ }
+ return -1;
+ }
+
inline int advance_read(int p_n) {
p_n = MIN(p_n, data_left());
inc(read_pos, p_n);
diff --git a/core/script_debugger_remote.cpp b/core/script_debugger_remote.cpp
index bd0352b7a4..f230a4bc95 100644
--- a/core/script_debugger_remote.cpp
+++ b/core/script_debugger_remote.cpp
@@ -586,9 +586,7 @@ void ScriptDebuggerRemote::_send_object_id(ObjectID p_id) {
packet_peer_stream->put_var(E->get().hint);
packet_peer_stream->put_var(E->get().hint_string);
//only send information that can be sent..
- if (var.get_type() == Variant::IMAGE) {
- var = Image();
- }
+
if (var.get_type() >= Variant::DICTIONARY) {
var = Array(); //send none for now, may be to big
}
diff --git a/core/script_language.h b/core/script_language.h
index 115ab59dca..6e39593a89 100644
--- a/core/script_language.h
+++ b/core/script_language.h
@@ -196,6 +196,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const = 0;
virtual void get_string_delimiters(List<String> *p_delimiters) const = 0;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const = 0;
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {}
+ virtual bool is_using_templates() { return false; }
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const = 0;
virtual Script *create_script() const = 0;
virtual bool has_named_classes() const = 0;
diff --git a/core/translation.h b/core/translation.h
index 577282b45f..8630b8a478 100644
--- a/core/translation.h
+++ b/core/translation.h
@@ -36,7 +36,7 @@ class Translation : public Resource {
GDCLASS(Translation, Resource);
OBJ_SAVE_TYPE(Translation);
- RES_BASE_EXTENSION("xl");
+ RES_BASE_EXTENSION("translation");
String locale;
Map<StringName, StringName> translation_map;
diff --git a/core/ustring.cpp b/core/ustring.cpp
index dcb6545bd1..6a93d7789e 100644
--- a/core/ustring.cpp
+++ b/core/ustring.cpp
@@ -53,6 +53,8 @@
#define MAX_DIGITS 6
#define UPPERCASE(m_c) (((m_c) >= 'a' && (m_c) <= 'z') ? ((m_c) - ('a' - 'A')) : (m_c))
#define LOWERCASE(m_c) (((m_c) >= 'A' && (m_c) <= 'Z') ? ((m_c) + ('a' - 'A')) : (m_c))
+#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
+#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
/** STRING **/
@@ -481,6 +483,68 @@ signed char String::casecmp_to(const String &p_str) const {
return 0; //should never reach anyway
}
+signed char String::naturalnocasecmp_to(const String &p_str) const {
+
+ const CharType *this_str = c_str();
+ const CharType *that_str = p_str.c_str();
+
+ if (this_str && that_str) {
+
+ while (*this_str == '.' || *that_str == '.') {
+ if (*this_str++ != '.')
+ return 1;
+ if (*that_str++ != '.')
+ return -1;
+ if (!*that_str)
+ return 1;
+ if (!*this_str)
+ return -1;
+ }
+
+ while (*this_str) {
+
+ if (!*that_str)
+ return 1;
+ else if (IS_DIGIT(*this_str)) {
+
+ int64_t this_int, that_int;
+
+ if (!IS_DIGIT(*that_str))
+ return -1;
+
+ /* Compare the numbers */
+ this_int = to_int(this_str);
+ that_int = to_int(that_str);
+
+ if (this_int < that_int)
+ return -1;
+ else if (this_int > that_int)
+ return 1;
+
+ /* Skip */
+ while (IS_DIGIT(*this_str))
+ this_str++;
+ while (IS_DIGIT(*that_str))
+ that_str++;
+ } else if (IS_DIGIT(*that_str))
+ return 1;
+ else {
+ if (_find_upper(*this_str) < _find_upper(*that_str)) //more than
+ return -1;
+ else if (_find_upper(*this_str) > _find_upper(*that_str)) //less than
+ return 1;
+
+ this_str++;
+ that_str++;
+ }
+ }
+ if (*that_str)
+ return -1;
+ }
+
+ return 0;
+}
+
void String::erase(int p_pos, int p_chars) {
*this = left(p_pos) + substr(p_pos + p_chars, length() - ((p_pos + p_chars)));
@@ -1698,9 +1762,6 @@ bool String::is_numeric() const {
return true; // TODO: Use the parser below for this instead
};
-#define IS_DIGIT(m_d) ((m_d) >= '0' && (m_d) <= '9')
-#define IS_HEX_DIGIT(m_d) (((m_d) >= '0' && (m_d) <= '9') || ((m_d) >= 'a' && (m_d) <= 'f') || ((m_d) >= 'A' && (m_d) <= 'F'))
-
template <class C>
static double built_in_strtod(const C *string, /* A decimal ASCII floating-point number,
* optionally preceded by white space. Must
diff --git a/core/ustring.h b/core/ustring.h
index 9ee3c2042c..d00bfa59b5 100644
--- a/core/ustring.h
+++ b/core/ustring.h
@@ -98,6 +98,7 @@ public:
signed char casecmp_to(const String &p_str) const;
signed char nocasecmp_to(const String &p_str) const;
+ signed char naturalnocasecmp_to(const String &p_str) const;
const CharType *c_str() const;
/* standard size stuff */
@@ -256,6 +257,14 @@ struct NoCaseComparator {
}
};
+struct NaturalNoCaseComparator {
+
+ bool operator()(const String &p_a, const String &p_b) const {
+
+ return p_a.naturalnocasecmp_to(p_b) < 0;
+ }
+};
+
/* end of namespace */
//tool translate
diff --git a/core/variant.cpp b/core/variant.cpp
index 67ce8af483..0807a33788 100644
--- a/core/variant.cpp
+++ b/core/variant.cpp
@@ -120,11 +120,6 @@ String Variant::get_type_name(Variant::Type p_type) {
return "Color";
} break;
- case IMAGE: {
-
- return "Image";
-
- } break;
case _RID: {
return "RID";
@@ -138,11 +133,6 @@ String Variant::get_type_name(Variant::Type p_type) {
return "NodePath";
} break;
- case INPUT_EVENT: {
-
- return "InputEvent";
-
- } break;
case DICTIONARY: {
return "Dictionary";
@@ -249,7 +239,6 @@ bool Variant::can_convert(Variant::Type p_type_from, Variant::Type p_type_to) {
static const Type invalid[] = {
OBJECT,
- IMAGE,
NIL
};
@@ -791,11 +780,6 @@ bool Variant::is_zero() const {
return *reinterpret_cast<const Color *>(_data._mem) == Color();
} break;
- case IMAGE: {
-
- return _data._image->empty();
-
- } break;
case _RID: {
return *reinterpret_cast<const RID *>(_data._mem) == RID();
@@ -809,11 +793,6 @@ bool Variant::is_zero() const {
return reinterpret_cast<const NodePath *>(_data._mem)->is_empty();
} break;
- case INPUT_EVENT: {
-
- return _data._input_event->type == InputEvent::NONE;
-
- } break;
case DICTIONARY: {
return reinterpret_cast<const Dictionary *>(_data._mem)->empty();
@@ -1016,11 +995,6 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, Color(*reinterpret_cast<const Color *>(p_variant._data._mem)));
} break;
- case IMAGE: {
-
- _data._image = memnew(Image(*p_variant._data._image));
-
- } break;
case _RID: {
memnew_placement(_data._mem, RID(*reinterpret_cast<const RID *>(p_variant._data._mem)));
@@ -1034,11 +1008,6 @@ void Variant::reference(const Variant &p_variant) {
memnew_placement(_data._mem, NodePath(*reinterpret_cast<const NodePath *>(p_variant._data._mem)));
} break;
- case INPUT_EVENT: {
-
- _data._input_event = memnew(InputEvent(*p_variant._data._input_event));
-
- } break;
case DICTIONARY: {
memnew_placement(_data._mem, Dictionary(*reinterpret_cast<const Dictionary *>(p_variant._data._mem)));
@@ -1141,11 +1110,6 @@ void Variant::clear() {
} break;
// misc types
- case IMAGE: {
-
- memdelete(_data._image);
-
- } break;
case NODE_PATH: {
reinterpret_cast<NodePath *>(_data._mem)->~NodePath();
@@ -1170,12 +1134,6 @@ void Variant::clear() {
reinterpret_cast<Array *>(_data._mem)->~Array();
} break;
- case INPUT_EVENT: {
-
- memdelete(_data._input_event);
-
- } break;
-
// arrays
case POOL_BYTE_ARRAY: {
@@ -1524,7 +1482,6 @@ Variant::operator String() const {
} break;
case TRANSFORM: return operator Transform();
case NODE_PATH: return operator NodePath();
- case INPUT_EVENT: return operator InputEvent();
case COLOR: return String::num(operator Color().r) + "," + String::num(operator Color().g) + "," + String::num(operator Color().b) + "," + String::num(operator Color().a);
case DICTIONARY: {
@@ -1760,13 +1717,6 @@ Variant::operator Color() const {
else
return Color();
}
-Variant::operator Image() const {
-
- if (type == IMAGE)
- return *_data._image;
- else
- return Image();
-}
Variant::operator NodePath() const {
@@ -1826,14 +1776,6 @@ Variant::operator Control *() const {
return NULL;
}
-Variant::operator InputEvent() const {
-
- if (type == INPUT_EVENT)
- return *reinterpret_cast<const InputEvent *>(_data._input_event);
- else
- return InputEvent();
-}
-
Variant::operator Dictionary() const {
if (type == DICTIONARY)
@@ -2306,11 +2248,6 @@ Variant::Variant(const Color &p_color) {
type = COLOR;
memnew_placement(_data._mem, Color(p_color));
}
-Variant::Variant(const Image &p_image) {
-
- type = IMAGE;
- _data._image = memnew(Image(p_image));
-}
Variant::Variant(const NodePath &p_node_path) {
@@ -2318,12 +2255,6 @@ Variant::Variant(const NodePath &p_node_path) {
memnew_placement(_data._mem, NodePath(p_node_path));
}
-Variant::Variant(const InputEvent &p_input_event) {
-
- type = INPUT_EVENT;
- _data._input_event = memnew(InputEvent(p_input_event));
-}
-
Variant::Variant(const RefPtr &p_resource) {
type = OBJECT;
@@ -2618,8 +2549,8 @@ uint32_t Variant::hash() const {
} break;
case RECT2: {
- uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->pos.x);
- hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->pos.y, hash);
+ uint32_t hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.x);
+ hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->position.y, hash);
hash = hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.x, hash);
return hash_djb2_one_float(reinterpret_cast<const Rect2 *>(_data._mem)->size.y, hash);
} break;
@@ -2659,7 +2590,7 @@ uint32_t Variant::hash() const {
uint32_t hash = 5831;
for (int i = 0; i < 3; i++) {
- hash = hash_djb2_one_float(_data._rect3->pos[i], hash);
+ hash = hash_djb2_one_float(_data._rect3->position[i], hash);
hash = hash_djb2_one_float(_data._rect3->size[i], hash);
}
@@ -2711,11 +2642,6 @@ uint32_t Variant::hash() const {
return hash_djb2_one_float(reinterpret_cast<const Color *>(_data._mem)->a, hash);
} break;
- case IMAGE: {
-
- return 0;
-
- } break;
case _RID: {
return hash_djb2_one_64(reinterpret_cast<const RID *>(_data._mem)->get_id());
@@ -2728,11 +2654,6 @@ uint32_t Variant::hash() const {
return reinterpret_cast<const NodePath *>(_data._mem)->hash();
} break;
- case INPUT_EVENT: {
-
- return hash_djb2_buffer((uint8_t *)_data._input_event, sizeof(InputEvent));
-
- } break;
case DICTIONARY: {
return reinterpret_cast<const Dictionary *>(_data._mem)->hash();
@@ -2899,7 +2820,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Rect2 *l = reinterpret_cast<const Rect2 *>(_data._mem);
const Rect2 *r = reinterpret_cast<const Rect2 *>(p_variant._data._mem);
- return (hash_compare_vector2(l->pos, r->pos)) &&
+ return (hash_compare_vector2(l->position, r->position)) &&
(hash_compare_vector2(l->size, r->size));
} break;
@@ -2934,7 +2855,7 @@ bool Variant::hash_compare(const Variant &p_variant) const {
const Rect3 *l = _data._rect3;
const Rect3 *r = p_variant._data._rect3;
- return (hash_compare_vector3(l->pos, r->pos) &&
+ return (hash_compare_vector3(l->position, r->position) &&
(hash_compare_vector3(l->size, r->size)));
} break;
diff --git a/core/variant.h b/core/variant.h
index e1a2b89a07..661d31cf16 100644
--- a/core/variant.h
+++ b/core/variant.h
@@ -39,11 +39,9 @@
#include "dictionary.h"
#include "dvector.h"
#include "face3.h"
-#include "image.h"
#include "io/ip_address.h"
#include "math_2d.h"
#include "matrix3.h"
-#include "os/input_event.h"
#include "os/power.h"
#include "path_db.h"
#include "plane.h"
@@ -92,26 +90,24 @@ public:
TRANSFORM2D,
PLANE,
QUAT, // 10
- RECT3, //sorry naming convention fail :( not like it's used often
+ RECT3,
BASIS,
TRANSFORM,
// misc types
COLOR,
- IMAGE, // 15
- NODE_PATH,
+ NODE_PATH, // 15
_RID,
OBJECT,
- INPUT_EVENT,
- DICTIONARY, // 20
- ARRAY,
+ DICTIONARY,
+ ARRAY, // 20
// arrays
POOL_BYTE_ARRAY,
POOL_INT_ARRAY,
POOL_REAL_ARRAY,
- POOL_STRING_ARRAY, // 25
- POOL_VECTOR2_ARRAY,
+ POOL_STRING_ARRAY,
+ POOL_VECTOR2_ARRAY, // 25
POOL_VECTOR3_ARRAY,
POOL_COLOR_ARRAY,
@@ -145,8 +141,6 @@ private:
Basis *_basis;
Transform *_transform;
RefPtr *_resource;
- InputEvent *_input_event;
- Image *_image;
void *_ptr; //generic pointer
uint8_t _mem[sizeof(ObjData) > (sizeof(real_t) * 4) ? sizeof(ObjData) : (sizeof(real_t) * 4)];
} _data;
@@ -207,11 +201,10 @@ public:
operator Transform2D() const;
operator Color() const;
- operator Image() const;
operator NodePath() const;
operator RefPtr() const;
operator RID() const;
- operator InputEvent() const;
+
operator Object *() const;
operator Node *() const;
operator Control *() const;
@@ -276,12 +269,10 @@ public:
Variant(const Transform2D &p_transform);
Variant(const Transform &p_transform);
Variant(const Color &p_color);
- Variant(const Image &p_image);
Variant(const NodePath &p_path);
Variant(const RefPtr &p_resource);
Variant(const RID &p_rid);
Variant(const Object *p_object);
- Variant(const InputEvent &p_input_event);
Variant(const Dictionary &p_dictionary);
Variant(const Array &p_array);
diff --git a/core/variant_call.cpp b/core/variant_call.cpp
index beaee188eb..6936a362e1 100644
--- a/core/variant_call.cpp
+++ b/core/variant_call.cpp
@@ -30,6 +30,7 @@
#include "variant.h"
#include "core_string_names.h"
+#include "io/compression.h"
#include "object.h"
#include "os/os.h"
#include "script_language.h"
@@ -37,9 +38,6 @@
typedef void (*VariantFunc)(Variant &r_ret, Variant &p_self, const Variant **p_args);
typedef void (*VariantConstructFunc)(Variant &r_ret, const Variant **p_args);
-VARIANT_ENUM_CAST(Image::CompressMode);
-//VARIANT_ENUM_CAST(Image::Format);
-
struct _VariantCall {
static void Vector3_dot(Variant &r_ret, Variant &p_self, const Variant **p_args) {
@@ -357,6 +355,8 @@ struct _VariantCall {
VCALL_LOCALMEM1R(Rect2, merge);
VCALL_LOCALMEM1R(Rect2, has_point);
VCALL_LOCALMEM1R(Rect2, grow);
+ VCALL_LOCALMEM2R(Rect2, grow_margin);
+ VCALL_LOCALMEM4R(Rect2, grow_individual);
VCALL_LOCALMEM1R(Rect2, expand);
VCALL_LOCALMEM0R(Vector3, min_axis);
@@ -510,6 +510,44 @@ struct _VariantCall {
r_ret = s;
}
+ static void _call_PoolByteArray_compress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+
+ PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PoolByteArray compressed;
+ Compression::Mode mode = (Compression::Mode)(int)(*p_args[0]);
+
+ compressed.resize(Compression::get_max_compressed_buffer_size(ba->size()));
+ int result = Compression::compress(compressed.write().ptr(), ba->read().ptr(), ba->size(), mode);
+
+ result = result >= 0 ? result : 0;
+ compressed.resize(result);
+
+ r_ret = compressed;
+ }
+
+ static void _call_PoolByteArray_decompress(Variant &r_ret, Variant &p_self, const Variant **p_args) {
+
+ PoolByteArray *ba = reinterpret_cast<PoolByteArray *>(p_self._data._mem);
+ PoolByteArray decompressed;
+ Compression::Mode mode = (Compression::Mode)(int)(*p_args[1]);
+
+ int buffer_size = (int)(*p_args[0]);
+
+ if (buffer_size < 0) {
+ r_ret = decompressed;
+ ERR_EXPLAIN("Decompression buffer size is less than zero");
+ ERR_FAIL();
+ }
+
+ decompressed.resize(buffer_size);
+ int result = Compression::decompress(decompressed.write().ptr(), buffer_size, ba->read().ptr(), ba->size(), mode);
+
+ result = result >= 0 ? result : 0;
+ decompressed.resize(result);
+
+ r_ret = decompressed;
+ }
+
VCALL_LOCALMEM0R(PoolByteArray, size);
VCALL_LOCALMEM2(PoolByteArray, set);
VCALL_LOCALMEM1R(PoolByteArray, get);
@@ -614,22 +652,6 @@ struct _VariantCall {
#define VCALL_PTR5R(m_type, m_method) \
static void _call_##m_type##_##m_method(Variant &r_ret, Variant &p_self, const Variant **p_args) { r_ret = reinterpret_cast<m_type *>(p_self._data._ptr)->m_method(*p_args[0], *p_args[1], *p_args[2], *p_args[3], *p_args[4]); }
- VCALL_PTR0R(Image, get_format);
- VCALL_PTR0R(Image, get_width);
- VCALL_PTR0R(Image, get_height);
- VCALL_PTR0R(Image, empty);
- VCALL_PTR0R(Image, get_used_rect);
- VCALL_PTR1R(Image, load);
- VCALL_PTR1R(Image, save_png);
- VCALL_PTR1R(Image, get_rect);
- VCALL_PTR1R(Image, compressed);
- VCALL_PTR0R(Image, decompressed);
- VCALL_PTR3R(Image, resized);
- VCALL_PTR0R(Image, get_data);
- VCALL_PTR3(Image, blit_rect);
- VCALL_PTR1R(Image, converted);
- VCALL_PTR0(Image, fix_alpha_edges);
-
VCALL_PTR0R(Rect3, get_area);
VCALL_PTR0R(Rect3, has_no_area);
VCALL_PTR0R(Rect3, has_no_surface);
@@ -756,13 +778,6 @@ struct _VariantCall {
VCALL_PTR1( Transform, translate );
VCALL_PTR0( Transform, orthonormalize ); */
- VCALL_PTR0R(InputEvent, is_pressed);
- VCALL_PTR1R(InputEvent, is_action);
- VCALL_PTR1R(InputEvent, is_action_pressed);
- VCALL_PTR1R(InputEvent, is_action_released);
- VCALL_PTR0R(InputEvent, is_echo);
- VCALL_PTR2(InputEvent, set_as_action);
-
struct ConstructData {
int arg_count;
@@ -901,11 +916,6 @@ struct _VariantCall {
r_ret = Transform(p_args[0]->operator Basis(), p_args[1]->operator Vector3());
}
- static void Image_init1(Variant &r_ret, const Variant **p_args) {
-
- r_ret = Image(*p_args[0], *p_args[1], *p_args[2], Image::Format(p_args[3]->operator int()));
- }
-
static void add_constructor(VariantConstructFunc p_func, const Variant::Type p_type,
const String &p_name1 = "", const Variant::Type p_type1 = Variant::NIL,
const String &p_name2 = "", const Variant::Type p_type2 = Variant::NIL,
@@ -1056,12 +1066,10 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
// misc types
case COLOR: return Color();
- case IMAGE: return Image();
case NODE_PATH:
return NodePath(); // 15
case _RID: return RID();
case OBJECT: return (Object *)NULL;
- case INPUT_EVENT: return InputEvent();
case DICTIONARY: return Dictionary();
case ARRAY:
return Array(); // 20
@@ -1138,12 +1146,10 @@ Variant Variant::construct(const Variant::Type p_type, const Variant **p_args, i
// misc types
case COLOR: return p_args[0]->type == Variant::STRING ? Color::html(*p_args[0]) : Color::hex(*p_args[0]);
- case IMAGE: return (Image(*p_args[0]));
case NODE_PATH:
return (NodePath(p_args[0]->operator NodePath())); // 15
case _RID: return (RID(*p_args[0]));
case OBJECT: return ((Object *)(p_args[0]->operator Object *()));
- case INPUT_EVENT: return (InputEvent(*p_args[0]));
case DICTIONARY: return p_args[0]->operator Dictionary();
case ARRAY:
return p_args[0]->operator Array(); // 20
@@ -1468,6 +1474,8 @@ void register_variant_methods() {
ADDFUNC1(RECT2, RECT2, Rect2, merge, RECT2, "b", varray());
ADDFUNC1(RECT2, BOOL, Rect2, has_point, VECTOR2, "point", varray());
ADDFUNC1(RECT2, RECT2, Rect2, grow, REAL, "by", varray());
+ ADDFUNC2(RECT2, RECT2, Rect2, grow_margin, INT, "margin", REAL, "by", varray());
+ ADDFUNC4(RECT2, RECT2, Rect2, grow_individual, REAL, "left", REAL, "top", REAL, "right", REAL, " bottom", varray());
ADDFUNC1(RECT2, RECT2, Rect2, expand, VECTOR2, "to", varray());
ADDFUNC0(VECTOR3, INT, Vector3, min_axis, varray());
@@ -1486,7 +1494,6 @@ void register_variant_methods() {
ADDFUNC1(VECTOR3, BASIS, Vector3, outer, VECTOR3, "b", varray());
ADDFUNC0(VECTOR3, BASIS, Vector3, to_diagonal_matrix, varray());
ADDFUNC0(VECTOR3, VECTOR3, Vector3, abs, varray());
- ADDFUNC0(VECTOR3, VECTOR3, Vector3, abs, varray());
ADDFUNC0(VECTOR3, VECTOR3, Vector3, floor, varray());
ADDFUNC0(VECTOR3, VECTOR3, Vector3, ceil, varray());
ADDFUNC1(VECTOR3, REAL, Vector3, distance_to, VECTOR3, "b", varray());
@@ -1527,22 +1534,6 @@ void register_variant_methods() {
ADDFUNC1(COLOR, COLOR, Color, blend, COLOR, "over", varray());
ADDFUNC1(COLOR, STRING, Color, to_html, BOOL, "with_alpha", varray(true));
- ADDFUNC0(IMAGE, INT, Image, get_format, varray());
- ADDFUNC0(IMAGE, INT, Image, get_width, varray());
- ADDFUNC0(IMAGE, INT, Image, get_height, varray());
- ADDFUNC0(IMAGE, BOOL, Image, empty, varray());
- ADDFUNC1(IMAGE, INT, Image, load, STRING, "path", varray(0));
- ADDFUNC1(IMAGE, INT, Image, save_png, STRING, "path", varray(0));
- ADDFUNC0(IMAGE, RECT2, Image, get_used_rect, varray(0));
- ADDFUNC1(IMAGE, IMAGE, Image, get_rect, RECT2, "area", varray(0));
- ADDFUNC1(IMAGE, IMAGE, Image, compressed, INT, "format", varray(0));
- ADDFUNC0(IMAGE, IMAGE, Image, decompressed, varray(0));
- ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR)));
- ADDFUNC0(IMAGE, POOL_BYTE_ARRAY, Image, get_data, varray());
- ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0));
- ADDFUNC1(IMAGE, IMAGE, Image, converted, INT, "format", varray(0));
- ADDFUNC0(IMAGE, NIL, Image, fix_alpha_edges, varray());
-
ADDFUNC0(_RID, INT, RID, get_id, varray());
ADDFUNC0(NODE_PATH, BOOL, NodePath, is_absolute, varray());
@@ -1600,6 +1591,8 @@ void register_variant_methods() {
ADDFUNC0(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_ascii, varray());
ADDFUNC0(POOL_BYTE_ARRAY, STRING, PoolByteArray, get_string_from_utf8, varray());
+ ADDFUNC1(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, compress, INT, "compression_mode", varray(0));
+ ADDFUNC2(POOL_BYTE_ARRAY, POOL_BYTE_ARRAY, PoolByteArray, decompress, INT, "buffer_size", INT, "compression_mode", varray(0));
ADDFUNC0(POOL_INT_ARRAY, INT, PoolIntArray, size, varray());
ADDFUNC2(POOL_INT_ARRAY, NIL, PoolIntArray, set, INT, "idx", INT, "integer", varray());
@@ -1733,13 +1726,6 @@ void register_variant_methods() {
_VariantCall::type_funcs[Variant::TRANSFORM].functions["xform_inv"].returns = true;
#endif
- ADDFUNC0(INPUT_EVENT, BOOL, InputEvent, is_pressed, varray());
- ADDFUNC1(INPUT_EVENT, BOOL, InputEvent, is_action, STRING, "action", varray());
- ADDFUNC1(INPUT_EVENT, BOOL, InputEvent, is_action_pressed, STRING, "action", varray());
- ADDFUNC1(INPUT_EVENT, BOOL, InputEvent, is_action_released, STRING, "action", varray());
- ADDFUNC0(INPUT_EVENT, BOOL, InputEvent, is_echo, varray());
- ADDFUNC2(INPUT_EVENT, NIL, InputEvent, set_as_action, STRING, "action", BOOL, "pressed", varray());
-
/* REGISTER CONSTRUCTORS */
_VariantCall::add_constructor(_VariantCall::Vector2_init1, Variant::VECTOR2, "x", Variant::REAL, "y", Variant::REAL);
@@ -1771,73 +1757,11 @@ void register_variant_methods() {
_VariantCall::add_constructor(_VariantCall::Transform_init1, Variant::TRANSFORM, "x_axis", Variant::VECTOR3, "y_axis", Variant::VECTOR3, "z_axis", Variant::VECTOR3, "origin", Variant::VECTOR3);
_VariantCall::add_constructor(_VariantCall::Transform_init2, Variant::TRANSFORM, "basis", Variant::BASIS, "origin", Variant::VECTOR3);
- _VariantCall::add_constructor(_VariantCall::Image_init1, Variant::IMAGE, "width", Variant::INT, "height", Variant::INT, "mipmaps", Variant::BOOL, "format", Variant::INT);
-
/* REGISTER CONSTANTS */
_VariantCall::add_constant(Variant::VECTOR3, "AXIS_X", Vector3::AXIS_X);
_VariantCall::add_constant(Variant::VECTOR3, "AXIS_Y", Vector3::AXIS_Y);
_VariantCall::add_constant(Variant::VECTOR3, "AXIS_Z", Vector3::AXIS_Z);
-
- _VariantCall::add_constant(Variant::INPUT_EVENT, "NONE", InputEvent::NONE);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "KEY", InputEvent::KEY);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "MOUSE_MOTION", InputEvent::MOUSE_MOTION);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "MOUSE_BUTTON", InputEvent::MOUSE_BUTTON);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "JOYPAD_MOTION", InputEvent::JOYPAD_MOTION);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "JOYPAD_BUTTON", InputEvent::JOYPAD_BUTTON);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "SCREEN_TOUCH", InputEvent::SCREEN_TOUCH);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "SCREEN_DRAG", InputEvent::SCREEN_DRAG);
- _VariantCall::add_constant(Variant::INPUT_EVENT, "ACTION", InputEvent::ACTION);
-
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_16BIT", Image::COMPRESS_16BIT);
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_S3TC", Image::COMPRESS_S3TC);
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_PVRTC2", Image::COMPRESS_PVRTC2);
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_PVRTC4", Image::COMPRESS_PVRTC4);
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_ETC", Image::COMPRESS_ETC);
- _VariantCall::add_constant(Variant::IMAGE, "COMPRESS_ETC2", Image::COMPRESS_ETC2);
-
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_L8", Image::FORMAT_L8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_LA8", Image::FORMAT_LA8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_R8", Image::FORMAT_R8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RG8", Image::FORMAT_RG8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGB8", Image::FORMAT_RGB8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA8", Image::FORMAT_RGBA8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGB565", Image::FORMAT_RGB565);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA4444", Image::FORMAT_RGBA4444);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBA5551", Image::FORMAT_DXT1);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RF", Image::FORMAT_RF);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGF", Image::FORMAT_RGF);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBF", Image::FORMAT_RGBF);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBAF", Image::FORMAT_RGBAF);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RH", Image::FORMAT_RH);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGH", Image::FORMAT_RGH);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBH", Image::FORMAT_RGBH);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_RGBAH", Image::FORMAT_RGBAH);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT1", Image::FORMAT_DXT1);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT3", Image::FORMAT_DXT3);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_DXT5", Image::FORMAT_DXT5);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ATI1", Image::FORMAT_ATI1);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ATI2", Image::FORMAT_ATI2);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBA", Image::FORMAT_BPTC_RGBA);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBF", Image::FORMAT_BPTC_RGBF);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_BPTC_RGBFU", Image::FORMAT_BPTC_RGBFU);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC2", Image::FORMAT_PVRTC2);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC2A", Image::FORMAT_PVRTC2A);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC4", Image::FORMAT_PVRTC4);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_PVRTC4A", Image::FORMAT_PVRTC4A);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC", Image::FORMAT_ETC);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_R11", Image::FORMAT_ETC2_R11);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_R11S", Image::FORMAT_ETC2_R11S);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RG11", Image::FORMAT_ETC2_RG11);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RG11S", Image::FORMAT_ETC2_RG11S);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGB8", Image::FORMAT_ETC2_RGB8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGBA8", Image::FORMAT_ETC2_RGBA8);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_ETC2_RGB8A1", Image::FORMAT_ETC2_RGB8A1);
- _VariantCall::add_constant(Variant::IMAGE, "FORMAT_MAX", Image::FORMAT_MAX);
-
- _VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_NEAREST", Image::INTERPOLATE_NEAREST);
- _VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_BILINEAR", Image::INTERPOLATE_BILINEAR);
- _VariantCall::add_constant(Variant::IMAGE, "INTERPOLATE_CUBIC", Image::INTERPOLATE_CUBIC);
}
void unregister_variant_methods() {
diff --git a/core/variant_op.cpp b/core/variant_op.cpp
index e8274d10af..7b2d0f6886 100644
--- a/core/variant_op.cpp
+++ b/core/variant_op.cpp
@@ -58,11 +58,9 @@ bool Variant::booleanize(bool &r_valid) const {
case BASIS:
case TRANSFORM:
case COLOR:
- case IMAGE: r_valid = false; return false;
case _RID: return (*reinterpret_cast<const RID *>(_data._mem)).is_valid();
case OBJECT: return _get_obj().obj;
case NODE_PATH: return (*reinterpret_cast<const NodePath *>(_data._mem)) != NodePath();
- case INPUT_EVENT:
case DICTIONARY:
case ARRAY:
case POOL_BYTE_ARRAY:
@@ -283,7 +281,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_PTRREF(==, TRANSFORM, _transform);
DEFAULT_OP_LOCALMEM(==, COLOR, Color);
- DEFAULT_OP_PTRREF(==, IMAGE, _image);
DEFAULT_OP_STR(==, NODE_PATH, NodePath);
DEFAULT_OP_LOCALMEM(==, _RID, RID);
case OBJECT: {
@@ -293,7 +290,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
if (p_b.type == NIL)
_RETURN(!p_a._get_obj().obj);
} break;
- DEFAULT_OP_PTRREF(==, INPUT_EVENT, _input_event);
case DICTIONARY: {
@@ -372,7 +368,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_LOCALMEM(<, _RID, RID);
case OBJECT: {
@@ -380,7 +376,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
if (p_b.type == OBJECT)
_RETURN((p_a._get_obj().obj < p_b._get_obj().obj));
} break;
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
case ARRAY: {
@@ -437,7 +432,7 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_LOCALMEM(<=, _RID, RID);
case OBJECT: {
@@ -445,7 +440,6 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
if (p_b.type == OBJECT)
_RETURN((p_a._get_obj().obj <= p_b._get_obj().obj));
} break;
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -500,11 +494,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
case ARRAY: {
@@ -557,11 +550,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -654,11 +646,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
return;
} break;
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -727,11 +718,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -769,11 +759,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_LOCALMEM_POS(VECTOR2, Vector2);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -809,11 +798,10 @@ void Variant::evaluate(const Operator &p_op, const Variant &p_a, const Variant &
DEFAULT_OP_FAIL(TRANSFORM);
DEFAULT_OP_FAIL(COLOR);
- DEFAULT_OP_FAIL(IMAGE);
+
DEFAULT_OP_FAIL(NODE_PATH);
DEFAULT_OP_FAIL(_RID);
DEFAULT_OP_FAIL(OBJECT);
- DEFAULT_OP_FAIL(INPUT_EVENT);
DEFAULT_OP_FAIL(DICTIONARY);
DEFAULT_OP_FAIL(ARRAY);
DEFAULT_OP_FAIL(POOL_BYTE_ARRAY);
@@ -1143,9 +1131,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Rect2 *v = reinterpret_cast<Rect2 *>(_data._mem);
- if (*str == "pos") {
+ if (*str == "position") {
valid = true;
- v->pos = p_value;
+ v->position = p_value;
return;
} else if (*str == "size") {
valid = true;
@@ -1153,7 +1141,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
} else if (*str == "end") {
valid = true;
- v->size = Vector2(p_value) - v->pos;
+ v->size = Vector2(p_value) - v->position;
return;
}
}
@@ -1305,7 +1293,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
}
- } break;
+ } break; // 10
case RECT3: {
if (p_value.type != Variant::VECTOR3)
@@ -1316,9 +1304,9 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
Rect3 *v = _data._rect3;
- if (*str == "pos") {
+ if (*str == "position") {
valid = true;
- v->pos = p_value;
+ v->position = p_value;
return;
} else if (*str == "size") {
valid = true;
@@ -1326,11 +1314,11 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return;
} else if (*str == "end") {
valid = true;
- v->size = Vector3(p_value) - v->pos;
+ v->size = Vector3(p_value) - v->position;
return;
}
}
- } break; //sorry naming convention fail :( not like it's used often // 10
+ } break;
case BASIS: {
if (p_value.type != Variant::VECTOR3)
@@ -1480,8 +1468,6 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
}
} break;
- case IMAGE: {
- } break;
case NODE_PATH: {
} break; // 15
case _RID: {
@@ -1511,402 +1497,19 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
return obj->set(p_index, p_value, r_valid);
}
} break;
- case INPUT_EVENT: {
-
- InputEvent &ie = *_data._input_event;
-
- if (p_index.get_type() != Variant::STRING)
- return;
-
- const String &str = *reinterpret_cast<const String *>(p_index._data._mem);
-
- if (str == "type") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
-
- int type = p_value;
- if (type < 0 || type >= InputEvent::TYPE_MAX)
- return; //fail
- valid = true;
- ie.type = InputEvent::Type(type);
- return;
- } else if (str == "device") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
-
- valid = true;
- ie.device = p_value;
- return;
- } else if (str == "ID") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
-
- valid = true;
- ie.ID = p_value;
- return;
- }
-
- if (ie.type == InputEvent::KEY || ie.type == InputEvent::MOUSE_BUTTON || ie.type == InputEvent::MOUSE_MOTION) {
-
- if (str == "shift") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.mod.shift = p_value;
- return;
- }
- if (str == "alt") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.mod.alt = p_value;
- return;
- }
- if (str == "control") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.mod.control = p_value;
- return;
- }
- if (str == "meta") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.mod.meta = p_value;
- return;
- }
- }
-
- if (ie.type == InputEvent::KEY) {
-
- if (str == "pressed") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.pressed = p_value;
- return;
- } else if (str == "scancode") {
-
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
-
- valid = true;
- ie.key.scancode = p_value;
- return;
- } else if (str == "unicode") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.key.unicode = p_value;
- return;
- } else if (str == "echo") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.key.echo = p_value;
- return;
- }
- }
-
- if (ie.type == InputEvent::MOUSE_MOTION || ie.type == InputEvent::MOUSE_BUTTON) {
-
- if (str == "button_mask") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.button_mask = p_value;
- return;
- } else if (str == "x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.x = p_value;
- return;
- } else if (str == "y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.y = p_value;
- return;
- } else if (str == "pos") {
- if (p_value.type != Variant::VECTOR2)
- return;
- valid = true;
- Point2 value = p_value;
- ie.mouse_button.x = value.x;
- ie.mouse_button.y = value.y;
- return;
- } else if (str == "global_x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.global_x = p_value;
- return;
- } else if (str == "global_y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.global_y = p_value;
- return;
- } else if (str == "global_pos") {
- if (p_value.type != Variant::VECTOR2)
- return;
- valid = true;
- Point2 value = p_value;
- ie.mouse_button.global_x = value.x;
- ie.mouse_button.global_y = value.y;
- return;
- } /*else if (str=="pointer_index") {
- valid=true;
- return ie.mouse_button.pointer_index;
- }*/
-
- if (ie.type == InputEvent::MOUSE_MOTION) {
-
- if (str == "relative_x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_motion.relative_x = p_value;
- return;
- } else if (str == "relative_y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_motion.relative_y = p_value;
- return;
- } else if (str == "relative_pos") {
- if (p_value.type != Variant::VECTOR2)
- return;
- valid = true;
- Point2 value = p_value;
- ie.mouse_motion.relative_x = value.x;
- ie.mouse_motion.relative_y = value.y;
- return;
- }
-
- if (str == "speed_x") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_motion.speed_x = p_value;
- return;
- } else if (str == "speed_y") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_motion.speed_y = p_value;
- return;
- } else if (str == "speed") {
- if (p_value.type != Variant::VECTOR2)
- return;
- valid = true;
- Point2 value = p_value;
- ie.mouse_motion.speed_x = value.x;
- ie.mouse_motion.speed_y = value.y;
- return;
- }
-
- } else if (ie.type == InputEvent::MOUSE_BUTTON) {
-
- if (str == "button_index") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL)
- return;
- valid = true;
- ie.mouse_button.button_index = p_value;
- return;
- } else if (str == "pressed") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
- valid = true;
- ie.mouse_button.pressed = p_value;
- return;
- } else if (str == "doubleclick") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
- valid = true;
- ie.mouse_button.doubleclick = p_value;
- return;
- }
- }
- }
-
- if (ie.type == InputEvent::JOYPAD_BUTTON) {
-
- if (str == "button_index") {
- if (p_value.type != Variant::REAL && p_value.type != Variant::INT)
- return;
- valid = true;
- ie.joy_button.button_index = p_value;
- return;
- }
- if (str == "pressed") {
- if (p_value.type != Variant::INT && p_value.type != Variant::REAL && p_value.type != Variant::BOOL)
- return;
-
- valid = true;
- ie.joy_button.pressed = p_value;
- return;
- }
- if (str == "pressure") {
- if (p_value.type != Variant::REAL && p_value.type != Variant::INT)
- return;
- valid = true;
- ie.joy_button.pressure = p_value;
- return;
- }
- }
-
- if (ie.type == InputEvent::JOYPAD_MOTION) {
-
- if (str == "axis") {
- if (p_value.type != Variant::REAL && p_value.type != Variant::INT)
- return;
- valid = true;
- ie.joy_motion.axis = p_value;
- return;
- }
- if (str == "value") {
- if (p_value.type != Variant::REAL && p_value.type != Variant::INT)
- return;
- valid = true;
- ie.joy_motion.axis_value = p_value;
- return;
- }
- }
-
- if (ie.type == InputEvent::SCREEN_TOUCH) {
-
- if (str == "index") {
- valid = true;
- ie.screen_touch.index = p_value;
- return;
- }
- if (str == "x") {
- valid = true;
- ie.screen_touch.x = p_value;
- return;
- }
- if (str == "y") {
- valid = true;
- ie.screen_touch.y = p_value;
- return;
- }
- if (str == "pos") {
- valid = true;
- Vector2 v = p_value;
- ie.screen_touch.x = v.x;
- ie.screen_touch.y = v.y;
- return;
- }
- if (str == "pressed") {
- valid = true;
- ie.screen_touch.pressed = p_value;
- return;
- }
- }
-
- if (ie.type == InputEvent::SCREEN_DRAG) {
-
- if (str == "index") {
- valid = true;
- ie.screen_drag.index = p_value;
- return;
- }
- if (str == "x") {
- valid = true;
- ie.screen_drag.x = p_value;
- return;
- }
- if (str == "y") {
- valid = true;
- ie.screen_drag.y = p_value;
- return;
- }
- if (str == "pos") {
- valid = true;
- Vector2 v = p_value;
- ie.screen_drag.x = v.x;
- ie.screen_drag.y = v.y;
- return;
- }
- if (str == "relative_x") {
- valid = true;
- ie.screen_drag.relative_x = p_value;
- return;
- }
- if (str == "relative_y") {
- valid = true;
- ie.screen_drag.relative_y = p_value;
- return;
- }
- if (str == "relative_pos") {
- valid = true;
- Vector2 v = p_value;
- ie.screen_drag.relative_x = v.x;
- ie.screen_drag.relative_y = v.y;
- return;
- }
- if (str == "speed_x") {
- valid = true;
- ie.screen_drag.speed_x = p_value;
- return;
- }
- if (str == "speed_y") {
- valid = true;
- ie.screen_drag.speed_y = p_value;
- return;
- }
- if (str == "speed") {
- valid = true;
- Vector2 v = p_value;
- ie.screen_drag.speed_x = v.x;
- ie.screen_drag.speed_y = v.y;
- return;
- }
- }
- if (ie.type == InputEvent::ACTION) {
-
- if (str == "action") {
- valid = true;
- ie.action.action = p_value;
- return;
- } else if (str == "pressed") {
- valid = true;
- ie.action.pressed = p_value;
- return;
- }
- }
-
- } break;
case DICTIONARY: {
Dictionary *dic = reinterpret_cast<Dictionary *>(_data._mem);
dic->operator[](p_index) = p_value;
valid = true; //always valid, i guess? should this really be ok?
return;
- } break; // 20
- DEFAULT_OP_ARRAY_CMD(ARRAY, Array, ;, (*arr)[index] = p_value; return )
+ } break;
+ DEFAULT_OP_ARRAY_CMD(ARRAY, Array, ;, (*arr)[index] = p_value; return ) // 20
DEFAULT_OP_DVECTOR_SET(POOL_BYTE_ARRAY, uint8_t, p_value.type != Variant::REAL && p_value.type != Variant::INT)
DEFAULT_OP_DVECTOR_SET(POOL_INT_ARRAY, int, p_value.type != Variant::REAL && p_value.type != Variant::INT)
DEFAULT_OP_DVECTOR_SET(POOL_REAL_ARRAY, real_t, p_value.type != Variant::REAL && p_value.type != Variant::INT)
- DEFAULT_OP_DVECTOR_SET(POOL_STRING_ARRAY, String, p_value.type != Variant::STRING) // 25
- DEFAULT_OP_DVECTOR_SET(POOL_VECTOR2_ARRAY, Vector2, p_value.type != Variant::VECTOR2)
+ DEFAULT_OP_DVECTOR_SET(POOL_STRING_ARRAY, String, p_value.type != Variant::STRING)
+ DEFAULT_OP_DVECTOR_SET(POOL_VECTOR2_ARRAY, Vector2, p_value.type != Variant::VECTOR2) // 25
DEFAULT_OP_DVECTOR_SET(POOL_VECTOR3_ARRAY, Vector3, p_value.type != Variant::VECTOR3)
DEFAULT_OP_DVECTOR_SET(POOL_COLOR_ARRAY, Color, p_value.type != Variant::COLOR)
default: return;
@@ -1986,15 +1589,15 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Rect2 *v = reinterpret_cast<const Rect2 *>(_data._mem);
- if (*str == "pos") {
+ if (*str == "position") {
valid = true;
- return v->pos;
+ return v->position;
} else if (*str == "size") {
valid = true;
return v->size;
} else if (*str == "end") {
valid = true;
- return v->size + v->pos;
+ return v->size + v->position;
}
}
} break;
@@ -2107,7 +1710,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
}
- } break;
+ } break; // 10
case RECT3: {
if (p_index.get_type() == Variant::STRING) {
@@ -2115,18 +1718,18 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
const String *str = reinterpret_cast<const String *>(p_index._data._mem);
const Rect3 *v = _data._rect3;
- if (*str == "pos") {
+ if (*str == "position") {
valid = true;
- return v->pos;
+ return v->position;
} else if (*str == "size") {
valid = true;
return v->size;
} else if (*str == "end") {
valid = true;
- return v->size + v->pos;
+ return v->size + v->position;
}
}
- } break; //sorry naming convention fail :( not like it's used often // 10
+ } break;
case BASIS: {
if (p_index.get_type() == Variant::INT || p_index.get_type() == Variant::REAL) {
@@ -2239,8 +1842,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
- case IMAGE: {
- } break;
case NODE_PATH: {
} break; // 15
case _RID: {
@@ -2267,235 +1868,6 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
}
} break;
- case INPUT_EVENT: {
-
- InputEvent ie = operator InputEvent();
-
- if (p_index.get_type() != Variant::STRING)
- break;
-
- const String &str = *reinterpret_cast<const String *>(p_index._data._mem);
-
- if (str == "type") {
- valid = true;
- return ie.type;
- } else if (str == "device") {
- valid = true;
- return ie.device;
- } else if (str == "ID") {
- valid = true;
- return ie.ID;
- }
-
- if (ie.type == InputEvent::KEY || ie.type == InputEvent::MOUSE_BUTTON || ie.type == InputEvent::MOUSE_MOTION) {
-
- if (str == "shift") {
- valid = true;
- return ie.key.mod.shift;
- }
- if (str == "alt") {
- valid = true;
- return ie.key.mod.alt;
- }
- if (str == "control") {
- valid = true;
- return ie.key.mod.control;
- }
- if (str == "meta") {
- valid = true;
- return ie.key.mod.meta;
- }
- }
-
- if (ie.type == InputEvent::KEY) {
-
- if (str == "pressed") {
- valid = true;
- return ie.key.pressed;
- } else if (str == "scancode") {
- valid = true;
- return ie.key.scancode;
- } else if (str == "unicode") {
- valid = true;
- return ie.key.unicode;
- } else if (str == "echo") {
- valid = true;
- return ie.key.echo;
- }
- }
-
- if (ie.type == InputEvent::MOUSE_MOTION || ie.type == InputEvent::MOUSE_BUTTON) {
-
- if (str == "button_mask") {
- valid = true;
- return ie.mouse_button.button_mask;
- } else if (str == "x") {
- valid = true;
- return ie.mouse_button.x;
- } else if (str == "y") {
- valid = true;
- return ie.mouse_button.y;
- } else if (str == "pos") {
- valid = true;
- return Point2(ie.mouse_button.x, ie.mouse_button.y);
- } else if (str == "global_x") {
- valid = true;
- return ie.mouse_button.global_x;
- } else if (str == "global_y") {
- valid = true;
- return ie.mouse_button.global_y;
- } else if (str == "global_pos") {
- valid = true;
- return Point2(ie.mouse_button.global_x, ie.mouse_button.global_y);
- } /*else if (str=="pointer_index") {
- valid=true;
- return ie.mouse_button.pointer_index;
- }*/
-
- if (ie.type == InputEvent::MOUSE_MOTION) {
-
- if (str == "relative_x") {
- valid = true;
- return ie.mouse_motion.relative_x;
- } else if (str == "relative_y") {
- valid = true;
- return ie.mouse_motion.relative_y;
- } else if (str == "relative_pos") {
- valid = true;
- return Point2(ie.mouse_motion.relative_x, ie.mouse_motion.relative_y);
- } else if (str == "speed_x") {
- valid = true;
- return ie.mouse_motion.speed_x;
- } else if (str == "speed_y") {
- valid = true;
- return ie.mouse_motion.speed_y;
- } else if (str == "speed") {
- valid = true;
- return Point2(ie.mouse_motion.speed_x, ie.mouse_motion.speed_y);
- }
-
- } else if (ie.type == InputEvent::MOUSE_BUTTON) {
-
- if (str == "button_index") {
- valid = true;
- return ie.mouse_button.button_index;
- } else if (str == "pressed") {
- valid = true;
- return ie.mouse_button.pressed;
- } else if (str == "doubleclick") {
- valid = true;
- return ie.mouse_button.doubleclick;
- }
- }
- }
-
- if (ie.type == InputEvent::JOYPAD_BUTTON) {
-
- if (str == "button_index") {
- valid = true;
- return ie.joy_button.button_index;
- }
- if (str == "pressed") {
- valid = true;
- return ie.joy_button.pressed;
- }
- if (str == "pressure") {
- valid = true;
- return ie.joy_button.pressure;
- }
- }
-
- if (ie.type == InputEvent::JOYPAD_MOTION) {
-
- if (str == "axis") {
- valid = true;
- return ie.joy_motion.axis;
- }
- if (str == "value") {
- valid = true;
- return ie.joy_motion.axis_value;
- }
- }
-
- if (ie.type == InputEvent::SCREEN_TOUCH) {
-
- if (str == "index") {
- valid = true;
- return ie.screen_touch.index;
- }
- if (str == "x") {
- valid = true;
- return ie.screen_touch.x;
- }
- if (str == "y") {
- valid = true;
- return ie.screen_touch.y;
- }
- if (str == "pos") {
- valid = true;
- return Vector2(ie.screen_touch.x, ie.screen_touch.y);
- }
- if (str == "pressed") {
- valid = true;
- return ie.screen_touch.pressed;
- }
- }
-
- if (ie.type == InputEvent::SCREEN_DRAG) {
-
- if (str == "index") {
- valid = true;
- return ie.screen_drag.index;
- }
- if (str == "x") {
- valid = true;
- return ie.screen_drag.x;
- }
- if (str == "y") {
- valid = true;
- return ie.screen_drag.y;
- }
- if (str == "pos") {
- valid = true;
- return Vector2(ie.screen_drag.x, ie.screen_drag.y);
- }
- if (str == "relative_x") {
- valid = true;
- return ie.screen_drag.relative_x;
- }
- if (str == "relative_y") {
- valid = true;
- return ie.screen_drag.relative_y;
- }
- if (str == "relative_pos") {
- valid = true;
- return Vector2(ie.screen_drag.relative_x, ie.screen_drag.relative_y);
- }
- if (str == "speed_x") {
- valid = true;
- return ie.screen_drag.speed_x;
- }
- if (str == "speed_y") {
- valid = true;
- return ie.screen_drag.speed_y;
- }
- if (str == "speed") {
- valid = true;
- return Vector2(ie.screen_drag.speed_x, ie.screen_drag.speed_y);
- }
- }
- if (ie.type == InputEvent::ACTION) {
-
- if (str == "action") {
- valid = true;
- return ie.action.action;
- } else if (str == "pressed") {
- valid = true;
- return ie.action.pressed;
- }
- }
-
- } break;
case DICTIONARY: {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
@@ -2504,13 +1876,13 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
valid = true;
return *res;
}
- } break; // 20
- DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index])
+ } break;
+ DEFAULT_OP_ARRAY_CMD(ARRAY, const Array, ;, return (*arr)[index]) // 20
DEFAULT_OP_DVECTOR_GET(POOL_BYTE_ARRAY, uint8_t)
DEFAULT_OP_DVECTOR_GET(POOL_INT_ARRAY, int)
DEFAULT_OP_DVECTOR_GET(POOL_REAL_ARRAY, real_t)
DEFAULT_OP_DVECTOR_GET(POOL_STRING_ARRAY, String)
- DEFAULT_OP_DVECTOR_GET(POOL_VECTOR2_ARRAY, Vector2)
+ DEFAULT_OP_DVECTOR_GET(POOL_VECTOR2_ARRAY, Vector2) // 25
DEFAULT_OP_DVECTOR_GET(POOL_VECTOR3_ARRAY, Vector3)
DEFAULT_OP_DVECTOR_GET(POOL_COLOR_ARRAY, Color)
default: return Variant();
@@ -2739,7 +2111,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
} break; // 5
case RECT2: {
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "pos"));
+ p_list->push_back(PropertyInfo(Variant::VECTOR2, "position"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "end"));
@@ -2774,12 +2146,12 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::REAL, "z"));
p_list->push_back(PropertyInfo(Variant::REAL, "w"));
- } break;
+ } break; // 10
case RECT3: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "pos"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "size"));
p_list->push_back(PropertyInfo(Variant::VECTOR3, "end"));
- } break; //sorry naming convention fail :( not like it's used often // 10
+ } break;
case BASIS: {
p_list->push_back(PropertyInfo(Variant::VECTOR3, "x"));
@@ -2807,8 +2179,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::INT, "a8"));
} break;
- case IMAGE: {
- } break;
case NODE_PATH: {
} break; // 15
case _RID: {
@@ -2831,94 +2201,6 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
}
} break;
- case INPUT_EVENT: {
-
- InputEvent ie = operator InputEvent();
-
- p_list->push_back(PropertyInfo(Variant::INT, "type"));
- p_list->push_back(PropertyInfo(Variant::INT, "device"));
- p_list->push_back(PropertyInfo(Variant::INT, "ID"));
-
- if (ie.type == InputEvent::KEY || ie.type == InputEvent::MOUSE_BUTTON || ie.type == InputEvent::MOUSE_MOTION) {
-
- p_list->push_back(PropertyInfo(Variant::BOOL, "shift"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "alt"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "control"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "meta"));
- }
-
- if (ie.type == InputEvent::KEY) {
-
- p_list->push_back(PropertyInfo(Variant::BOOL, "pressed"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "echo"));
- p_list->push_back(PropertyInfo(Variant::INT, "scancode"));
- p_list->push_back(PropertyInfo(Variant::INT, "unicode"));
- }
-
- if (ie.type == InputEvent::MOUSE_MOTION || ie.type == InputEvent::MOUSE_BUTTON) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "button_mask"));
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "pos"));
- p_list->push_back(PropertyInfo(Variant::REAL, "global_x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "global_y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "global_pos"));
-
- if (ie.type == InputEvent::MOUSE_MOTION) {
-
- p_list->push_back(PropertyInfo(Variant::REAL, "relative_x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "relative_y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "relative_pos"));
- p_list->push_back(PropertyInfo(Variant::REAL, "speed_x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "speed_y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "speed"));
-
- } else if (ie.type == InputEvent::MOUSE_BUTTON) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "button_index"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "pressed"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "doubleclick"));
- }
- }
-
- if (ie.type == InputEvent::JOYPAD_BUTTON) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "button_index"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "pressed"));
- p_list->push_back(PropertyInfo(Variant::REAL, "pressure"));
- }
-
- if (ie.type == InputEvent::JOYPAD_MOTION) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "axis"));
- p_list->push_back(PropertyInfo(Variant::REAL, "value"));
- }
-
- if (ie.type == InputEvent::SCREEN_TOUCH) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "index"));
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "pos"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "pressed"));
- }
-
- if (ie.type == InputEvent::SCREEN_DRAG) {
-
- p_list->push_back(PropertyInfo(Variant::INT, "index"));
- p_list->push_back(PropertyInfo(Variant::REAL, "x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "pos"));
- p_list->push_back(PropertyInfo(Variant::REAL, "relative_x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "relative_y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "relative_pos"));
- p_list->push_back(PropertyInfo(Variant::REAL, "speed_x"));
- p_list->push_back(PropertyInfo(Variant::REAL, "speed_y"));
- p_list->push_back(PropertyInfo(Variant::VECTOR2, "speed"));
- }
-
- } break;
case DICTIONARY: {
const Dictionary *dic = reinterpret_cast<const Dictionary *>(_data._mem);
@@ -2929,12 +2211,13 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::STRING, E->get()));
}
}
- } break; // 20
- case ARRAY:
+ } break;
+ case ARRAY: // 20
case POOL_BYTE_ARRAY:
case POOL_INT_ARRAY:
case POOL_REAL_ARRAY:
case POOL_STRING_ARRAY:
+ case POOL_VECTOR2_ARRAY: // 25
case POOL_VECTOR3_ARRAY:
case POOL_COLOR_ARRAY: {
@@ -3476,7 +2759,7 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
case RECT2: {
const Rect2 *ra = reinterpret_cast<const Rect2 *>(a._data._mem);
const Rect2 *rb = reinterpret_cast<const Rect2 *>(b._data._mem);
- r_dst = Rect2(ra->pos + rb->pos * c, ra->size + rb->size * c);
+ r_dst = Rect2(ra->position + rb->position * c, ra->size + rb->size * c);
}
return;
case VECTOR3: {
@@ -3486,7 +2769,7 @@ void Variant::blend(const Variant &a, const Variant &b, float c, Variant &r_dst)
case RECT3: {
const Rect3 *ra = reinterpret_cast<const Rect3 *>(a._data._mem);
const Rect3 *rb = reinterpret_cast<const Rect3 *>(b._data._mem);
- r_dst = Rect3(ra->pos + rb->pos * c, ra->size + rb->size * c);
+ r_dst = Rect3(ra->position + rb->position * c, ra->size + rb->size * c);
}
return;
case QUAT: {
@@ -3596,7 +2879,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case RECT2: {
- r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->pos.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->pos, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
+ r_dst = Rect2(reinterpret_cast<const Rect2 *>(a._data._mem)->position.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->position, c), reinterpret_cast<const Rect2 *>(a._data._mem)->size.linear_interpolate(reinterpret_cast<const Rect2 *>(b._data._mem)->size, c));
}
return;
case VECTOR3: {
@@ -3616,7 +2899,7 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
}
return;
case RECT3: {
- r_dst = Rect3(a._data._rect3->pos.linear_interpolate(b._data._rect3->pos, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c));
+ r_dst = Rect3(a._data._rect3->position.linear_interpolate(b._data._rect3->position, c), a._data._rect3->size.linear_interpolate(b._data._rect3->size, c));
}
return;
case BASIS: {
@@ -3631,10 +2914,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = reinterpret_cast<const Color *>(a._data._mem)->linear_interpolate(*reinterpret_cast<const Color *>(b._data._mem), c);
}
return;
- case IMAGE: {
- r_dst = a;
- }
- return;
case NODE_PATH: {
r_dst = a;
}
@@ -3647,10 +2926,6 @@ void Variant::interpolate(const Variant &a, const Variant &b, float c, Variant &
r_dst = a;
}
return;
- case INPUT_EVENT: {
- r_dst = a;
- }
- return;
case DICTIONARY: {
}
return;
diff --git a/core/variant_parser.cpp b/core/variant_parser.cpp
index 234156d39f..26a6a05a30 100644
--- a/core/variant_parser.cpp
+++ b/core/variant_parser.cpp
@@ -30,6 +30,7 @@
#include "variant_parser.h"
#include "io/resource_loader.h"
+#include "os/input_event.h"
#include "os/keyboard.h"
CharType VariantParser::StreamFile::get_char() {
@@ -504,39 +505,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return OK;
} else if (token.type == TK_IDENTIFIER) {
- /*
- VECTOR2, // 5
- RECT2,
- VECTOR3,
- MATRIX32,
- PLANE,
- QUAT, // 10
- _AABB, //sorry naming convention fail :( not like it's used often
- MATRIX3,
- TRANSFORM,
- // misc types
- COLOR,
- IMAGE, // 15
- NODE_PATH,
- _RID,
- OBJECT,
- INPUT_EVENT,
- DICTIONARY, // 20
- ARRAY,
-
- // arrays
- RAW_ARRAY,
- INT_ARRAY,
- REAL_ARRAY,
- STRING_ARRAY, // 25
- VECTOR2_ARRAY,
- VECTOR3_ARRAY,
- COLOR_ARRAY,
-
- VARIANT_MAX
-
-*/
String id = token.value;
if (id == "true")
value = true;
@@ -681,9 +650,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = Color(args[0], args[1], args[2], args[3]);
return OK;
- } else if (id == "Image") {
-
- //:|
+ } else if (id == "NodePath") {
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_OPEN) {
@@ -692,157 +659,143 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
get_token(p_stream, token, line, r_err_str);
- if (token.type == TK_PARENTHESIS_CLOSE) {
- value = Image(); // just an Image()
- return OK;
- } else if (token.type != TK_NUMBER) {
- r_err_str = "Expected number (width)";
+ if (token.type != TK_STRING) {
+ r_err_str = "Expected string as argument for NodePath()";
return ERR_PARSE_ERROR;
}
- get_token(p_stream, token, line, r_err_str);
-
- int width = token.value;
- if (token.type != TK_COMMA) {
- r_err_str = "Expected ','";
- return ERR_PARSE_ERROR;
- }
+ value = NodePath(String(token.value));
get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_NUMBER) {
- r_err_str = "Expected number (height)";
+ if (token.type != TK_PARENTHESIS_CLOSE) {
+ r_err_str = "Expected ')'";
return ERR_PARSE_ERROR;
}
- int height = token.value;
+ } else if (id == "RID") {
get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_COMMA) {
- r_err_str = "Expected ','";
+ if (token.type != TK_PARENTHESIS_OPEN) {
+ r_err_str = "Expected '('";
return ERR_PARSE_ERROR;
}
get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_NUMBER) {
+ r_err_str = "Expected number as argument";
+ return ERR_PARSE_ERROR;
+ }
- bool has_mipmaps = false;
+ value = token.value;
- if (token.type == TK_NUMBER) {
- has_mipmaps = bool(token.value);
- } else if (token.type == TK_IDENTIFIER && String(token.value) == "true") {
- has_mipmaps = true;
- } else if (token.type == TK_IDENTIFIER && String(token.value) == "false") {
- has_mipmaps = false;
- } else {
- r_err_str = "Expected number/true/false (mipmaps)";
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_PARENTHESIS_CLOSE) {
+ r_err_str = "Expected ')'";
return ERR_PARSE_ERROR;
}
- int mipmaps = token.value;
+ return OK;
+ } else if (id == "Object") {
get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_COMMA) {
- r_err_str = "Expected ','";
+ if (token.type != TK_PARENTHESIS_OPEN) {
+ r_err_str = "Expected '('";
return ERR_PARSE_ERROR;
}
get_token(p_stream, token, line, r_err_str);
+
if (token.type != TK_IDENTIFIER) {
- r_err_str = "Expected identifier (format)";
+ r_err_str = "Expected identifier with type of object";
return ERR_PARSE_ERROR;
}
- String sformat = token.value;
+ String type = token.value;
- Image::Format format = Image::FORMAT_MAX;
-
- for (int i = 0; i < Image::FORMAT_MAX; i++) {
- if (Image::get_format_name(Image::Format(i)) == sformat) {
- format = Image::Format(i);
- }
- }
+ Object *obj = ClassDB::instance(type);
- if (format == Image::FORMAT_MAX) {
- r_err_str = "Unknown image format: " + String(sformat);
+ if (!obj) {
+ r_err_str = "Can't instance Object() of type: " + type;
return ERR_PARSE_ERROR;
}
- int len = Image::get_image_data_size(width, height, format, mipmaps);
-
- PoolVector<uint8_t> buffer;
- buffer.resize(len);
-
- if (buffer.size() != len) {
- r_err_str = "Couldn't allocate image buffer of size: " + itos(len);
+ get_token(p_stream, token, line, r_err_str);
+ if (token.type != TK_COMMA) {
+ r_err_str = "Expected ',' after object type";
+ return ERR_PARSE_ERROR;
}
- {
- PoolVector<uint8_t>::Write w = buffer.write();
-
- for (int i = 0; i < len; i++) {
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_COMMA) {
- r_err_str = "Expected ','";
- return ERR_PARSE_ERROR;
- }
+ bool at_key = true;
+ String key;
+ Token token;
+ bool need_comma = false;
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_NUMBER) {
- r_err_str = "Expected number";
- return ERR_PARSE_ERROR;
- }
+ while (true) {
- w[i] = int(token.value);
+ if (p_stream->is_eof()) {
+ r_err_str = "Unexpected End of File while parsing Object()";
+ return ERR_FILE_CORRUPT;
}
- }
- Image img(width, height, mipmaps, format, buffer);
+ if (at_key) {
- value = img;
+ Error err = get_token(p_stream, token, line, r_err_str);
+ if (err != OK)
+ return err;
- return OK;
+ if (token.type == TK_PARENTHESIS_CLOSE) {
+ Reference *reference = obj->cast_to<Reference>();
+ if (reference) {
+ value = REF(reference);
+ } else {
+ value = obj;
+ }
+ return OK;
+ }
- } else if (id == "NodePath") {
+ if (need_comma) {
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_PARENTHESIS_OPEN) {
- r_err_str = "Expected '('";
- return ERR_PARSE_ERROR;
- }
-
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_STRING) {
- r_err_str = "Expected string as argument for NodePath()";
- return ERR_PARSE_ERROR;
- }
+ if (token.type != TK_COMMA) {
- value = NodePath(String(token.value));
+ r_err_str = "Expected '}' or ','";
+ return ERR_PARSE_ERROR;
+ } else {
+ need_comma = false;
+ continue;
+ }
+ }
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_PARENTHESIS_CLOSE) {
- r_err_str = "Expected ')'";
- return ERR_PARSE_ERROR;
- }
+ if (token.type != TK_STRING) {
+ r_err_str = "Expected property name as string";
+ return ERR_PARSE_ERROR;
+ }
- } else if (id == "RID") {
+ key = token.value;
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_PARENTHESIS_OPEN) {
- r_err_str = "Expected '('";
- return ERR_PARSE_ERROR;
- }
+ err = get_token(p_stream, token, line, r_err_str);
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_NUMBER) {
- r_err_str = "Expected number as argument";
- return ERR_PARSE_ERROR;
- }
+ if (err != OK)
+ return err;
+ if (token.type != TK_COLON) {
- value = token.value;
+ r_err_str = "Expected ':'";
+ return ERR_PARSE_ERROR;
+ }
+ at_key = false;
+ } else {
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_PARENTHESIS_CLOSE) {
- r_err_str = "Expected ')'";
- return ERR_PARSE_ERROR;
+ Error err = get_token(p_stream, token, line, r_err_str);
+ if (err != OK)
+ return err;
+
+ Variant v;
+ err = parse_value(token, v, p_stream, line, r_err_str, p_res_parser);
+ if (err)
+ return err;
+ obj->set(key, v);
+ need_comma = true;
+ at_key = true;
+ }
}
return OK;
@@ -912,7 +865,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
}
return OK;
-
+#ifndef DISABLE_DEPRECATED
} else if (id == "InputEvent") {
get_token(p_stream, token, line, r_err_str);
@@ -930,12 +883,10 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
String id = token.value;
- InputEvent ie;
+ Ref<InputEvent> ie;
if (id == "NONE") {
- ie.type = InputEvent::NONE;
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
@@ -945,21 +896,23 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
} else if (id == "KEY") {
+ Ref<InputEventKey> key;
+ key.instance();
+ ie = key;
+
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_COMMA) {
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
}
- ie.type = InputEvent::KEY;
-
get_token(p_stream, token, line, r_err_str);
if (token.type == TK_IDENTIFIER) {
String name = token.value;
- ie.key.scancode = find_keycode(name);
+ key->set_scancode(find_keycode(name));
} else if (token.type == TK_NUMBER) {
- ie.key.scancode = token.value;
+ key->set_scancode(token.value);
} else {
r_err_str = "Expected string or integer for keycode";
@@ -980,13 +933,13 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
String mods = token.value;
if (mods.findn("C") != -1)
- ie.key.mod.control = true;
+ key->set_control(true);
if (mods.findn("A") != -1)
- ie.key.mod.alt = true;
+ key->set_alt(true);
if (mods.findn("S") != -1)
- ie.key.mod.shift = true;
+ key->set_shift(true);
if (mods.findn("M") != -1)
- ie.key.mod.meta = true;
+ key->set_metakey(true);
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
@@ -1002,21 +955,23 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
} else if (id == "MBUTTON") {
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ ie = mb;
+
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_COMMA) {
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
}
- ie.type = InputEvent::MOUSE_BUTTON;
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_NUMBER) {
r_err_str = "Expected button index";
return ERR_PARSE_ERROR;
}
- ie.mouse_button.button_index = token.value;
+ mb->set_button_index(token.value);
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
@@ -1026,21 +981,23 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
} else if (id == "JBUTTON") {
+ Ref<InputEventJoypadButton> jb;
+ jb.instance();
+ ie = jb;
+
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_COMMA) {
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
}
- ie.type = InputEvent::JOYPAD_BUTTON;
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_NUMBER) {
r_err_str = "Expected button index";
return ERR_PARSE_ERROR;
}
- ie.joy_button.button_index = token.value;
+ jb->set_button_index(token.value);
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_PARENTHESIS_CLOSE) {
@@ -1050,21 +1007,23 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
} else if (id == "JAXIS") {
+ Ref<InputEventJoypadMotion> jm;
+ jm.instance();
+ ie = jm;
+
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_COMMA) {
r_err_str = "Expected ','";
return ERR_PARSE_ERROR;
}
- ie.type = InputEvent::JOYPAD_MOTION;
-
get_token(p_stream, token, line, r_err_str);
if (token.type != TK_NUMBER) {
r_err_str = "Expected axis index";
return ERR_PARSE_ERROR;
}
- ie.joy_motion.axis = token.value;
+ jm->set_axis(token.value);
get_token(p_stream, token, line, r_err_str);
@@ -1079,7 +1038,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
return ERR_PARSE_ERROR;
}
- ie.joy_motion.axis_value = token.value;
+ jm->set_axis_value(token.value);
get_token(p_stream, token, line, r_err_str);
@@ -1097,7 +1056,7 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = ie;
return OK;
-
+#endif
} else if (id == "PoolByteArray" || id == "ByteArray") {
Vector<uint8_t> args;
@@ -1273,152 +1232,11 @@ Error VariantParser::parse_value(Token &token, Variant &value, Stream *p_stream,
value = arr;
return OK;
- } else if (id == "key") { // compatibility with project.godot
-
- Vector<String> params;
- Error err = _parse_enginecfg(p_stream, params, line, r_err_str);
- if (err)
- return err;
- ERR_FAIL_COND_V(params.size() != 1 && params.size() != 2, ERR_PARSE_ERROR);
-
- int scode = 0;
-
- if (params[0].is_numeric()) {
- scode = params[0].to_int();
- if (scode < 10) {
- scode = KEY_0 + scode;
- }
- } else
- scode = find_keycode(params[0]);
-
- InputEvent ie;
- ie.type = InputEvent::KEY;
- ie.key.scancode = scode;
-
- if (params.size() == 2) {
- String mods = params[1];
- if (mods.findn("C") != -1)
- ie.key.mod.control = true;
- if (mods.findn("A") != -1)
- ie.key.mod.alt = true;
- if (mods.findn("S") != -1)
- ie.key.mod.shift = true;
- if (mods.findn("M") != -1)
- ie.key.mod.meta = true;
- }
- value = ie;
- return OK;
-
- } else if (id == "mbutton") { // compatibility with project.godot
-
- Vector<String> params;
- Error err = _parse_enginecfg(p_stream, params, line, r_err_str);
- if (err)
- return err;
- ERR_FAIL_COND_V(params.size() != 2, ERR_PARSE_ERROR);
-
- InputEvent ie;
- ie.type = InputEvent::MOUSE_BUTTON;
- ie.device = params[0].to_int();
- ie.mouse_button.button_index = params[1].to_int();
-
- value = ie;
- return OK;
- } else if (id == "jbutton") { // compatibility with project.godot
-
- Vector<String> params;
- Error err = _parse_enginecfg(p_stream, params, line, r_err_str);
- if (err)
- return err;
- ERR_FAIL_COND_V(params.size() != 2, ERR_PARSE_ERROR);
- InputEvent ie;
- ie.type = InputEvent::JOYPAD_BUTTON;
- ie.device = params[0].to_int();
- ie.joy_button.button_index = params[1].to_int();
-
- value = ie;
-
- return OK;
- } else if (id == "jaxis") { // compatibility with project.godot
-
- Vector<String> params;
- Error err = _parse_enginecfg(p_stream, params, line, r_err_str);
- if (err)
- return err;
- ERR_FAIL_COND_V(params.size() != 2, ERR_PARSE_ERROR);
-
- InputEvent ie;
- ie.type = InputEvent::JOYPAD_MOTION;
- ie.device = params[0].to_int();
- int axis = params[1].to_int();
- ie.joy_motion.axis = axis >> 1;
- ie.joy_motion.axis_value = axis & 1 ? 1 : -1;
-
- value = ie;
-
- return OK;
- } else if (id == "img") { // compatibility with project.godot
-
- Token token; // FIXME: no need for this declaration? the first argument in line 509 is a Token& token.
- get_token(p_stream, token, line, r_err_str);
- if (token.type != TK_PARENTHESIS_OPEN) {
- r_err_str = "Expected '(' in old-style project.godot construct";
- return ERR_PARSE_ERROR;
- }
-
- while (true) {
- CharType c = p_stream->get_char();
- if (p_stream->is_eof()) {
- r_err_str = "Unexpected EOF in old style project.godot img()";
- return ERR_PARSE_ERROR;
- }
- if (c == ')')
- break;
- }
-
- value = Image();
-
- return OK;
-
} else {
r_err_str = "Unexpected identifier: '" + id + "'.";
return ERR_PARSE_ERROR;
}
- /*
- VECTOR2, // 5
- RECT2,
- VECTOR3,
- MATRIX32,
- PLANE,
- QUAT, // 10
- _AABB, //sorry naming convention fail :( not like it's used often
- MATRIX3,
- TRANSFORM,
-
- // misc types
- COLOR,
- IMAGE, // 15
- NODE_PATH,
- _RID,
- OBJECT,
- INPUT_EVENT,
- DICTIONARY, // 20
- ARRAY,
-
- // arrays
- RAW_ARRAY,
- INT_ARRAY,
- REAL_ARRAY,
- STRING_ARRAY, // 25
- VECTOR2_ARRAY,
- VECTOR3_ARRAY,
- COLOR_ARRAY,
-
- VARIANT_MAX
-
- */
-
return OK;
} else if (token.type == TK_NUMBER) {
@@ -1802,7 +1620,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::RECT2: {
Rect2 aabb = p_variant;
- p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.pos.x) + ", " + rtosfix(aabb.pos.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )");
+ p_store_string_func(p_store_string_ud, "Rect2( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + " )");
} break;
case Variant::VECTOR3: {
@@ -1819,7 +1637,7 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::RECT3: {
Rect3 aabb = p_variant;
- p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.pos.x) + ", " + rtosfix(aabb.pos.y) + ", " + rtosfix(aabb.pos.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )");
+ p_store_string_func(p_store_string_ud, "Rect3( " + rtosfix(aabb.position.x) + ", " + rtosfix(aabb.position.y) + ", " + rtosfix(aabb.position.z) + ", " + rtosfix(aabb.size.x) + ", " + rtosfix(aabb.size.y) + ", " + rtosfix(aabb.size.z) + " )");
} break;
case Variant::QUAT: {
@@ -1886,39 +1704,6 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
p_store_string_func(p_store_string_ud, "Color( " + rtosfix(c.r) + ", " + rtosfix(c.g) + ", " + rtosfix(c.b) + ", " + rtosfix(c.a) + " )");
} break;
- case Variant::IMAGE: {
-
- Image img = p_variant;
-
- if (img.empty()) {
- p_store_string_func(p_store_string_ud, "Image()");
- break;
- }
-
- String imgstr = "Image( ";
- imgstr += itos(img.get_width());
- imgstr += ", " + itos(img.get_height());
- imgstr += ", " + String(img.has_mipmaps() ? "true" : "false");
- imgstr += ", " + Image::get_format_name(img.get_format());
-
- String s;
-
- PoolVector<uint8_t> data = img.get_data();
- int len = data.size();
- PoolVector<uint8_t>::Read r = data.read();
- const uint8_t *ptr = r.ptr();
- for (int i = 0; i < len; i++) {
-
- if (i > 0)
- s += ", ";
- s += itos(ptr[i]);
- }
-
- imgstr += ", ";
- p_store_string_func(p_store_string_ud, imgstr);
- p_store_string_func(p_store_string_ud, s);
- p_store_string_func(p_store_string_ud, " )");
- } break;
case Variant::NODE_PATH: {
String str = p_variant;
@@ -1930,76 +1715,66 @@ Error VariantWriter::write(const Variant &p_variant, StoreStringFunc p_store_str
case Variant::OBJECT: {
- RES res = p_variant;
- if (res.is_null()) {
+ Object *obj = p_variant;
+
+ if (!obj) {
p_store_string_func(p_store_string_ud, "null");
break; // don't save it
}
- String res_text;
+ RES res = p_variant;
+ if (res.is_valid()) {
+ //is resource
+ String res_text;
- if (p_encode_res_func) {
+ //try external function
+ if (p_encode_res_func) {
- res_text = p_encode_res_func(p_encode_res_ud, res);
- }
+ res_text = p_encode_res_func(p_encode_res_ud, res);
+ }
- if (res_text == String() && res->get_path().is_resource_file()) {
+ //try path because it's a file
+ if (res_text == String() && res->get_path().is_resource_file()) {
- //external resource
- String path = res->get_path();
- res_text = "Resource( \"" + path + "\")";
+ //external resource
+ String path = res->get_path();
+ res_text = "Resource( \"" + path + "\")";
+ }
+
+ //could come up with some sort of text
+ if (res_text != String()) {
+ p_store_string_func(p_store_string_ud, res_text);
+ break;
+ }
}
- if (res_text == String())
- res_text = "null";
+ //store as generic object
- p_store_string_func(p_store_string_ud, res_text);
+ p_store_string_func(p_store_string_ud, "Object(" + obj->get_class() + ",");
- } break;
- case Variant::INPUT_EVENT: {
-
- String str = "InputEvent(";
-
- InputEvent ev = p_variant;
- switch (ev.type) {
- case InputEvent::KEY: {
-
- str += "KEY," + itos(ev.key.scancode);
- String mod;
- if (ev.key.mod.alt)
- mod += "A";
- if (ev.key.mod.shift)
- mod += "S";
- if (ev.key.mod.control)
- mod += "C";
- if (ev.key.mod.meta)
- mod += "M";
-
- if (mod != String())
- str += "," + mod;
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- str += "MBUTTON," + itos(ev.mouse_button.button_index);
- } break;
- case InputEvent::JOYPAD_BUTTON: {
- str += "JBUTTON," + itos(ev.joy_button.button_index);
-
- } break;
- case InputEvent::JOYPAD_MOTION: {
- str += "JAXIS," + itos(ev.joy_motion.axis) + "," + itos(ev.joy_motion.axis_value);
- } break;
- case InputEvent::NONE: {
- str += "NONE";
- } break;
- default: {}
- }
+ List<PropertyInfo> props;
+ obj->get_property_list(&props);
+ bool first = true;
+ for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
+
+ if (E->get().usage & PROPERTY_USAGE_STORAGE || E->get().usage & PROPERTY_USAGE_SCRIPT_VARIABLE) {
+ //must be serialized
+
+ if (first) {
+ first = false;
+ } else {
+ p_store_string_func(p_store_string_ud, ",");
+ }
- str += ")";
+ p_store_string_func(p_store_string_ud, "\"" + E->get().name + "\":");
+ write(obj->get(E->get().name), p_store_string_func, p_store_string_ud, p_encode_res_func, p_encode_res_ud);
+ }
+ }
- p_store_string_func(p_store_string_ud, str); //will be added later
+ p_store_string_func(p_store_string_ud, ")\n");
} break;
+
case Variant::DICTIONARY: {
Dictionary dict = p_variant;
diff --git a/doc/Makefile b/doc/Makefile
index d59c77063b..4914c657d2 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -8,25 +8,11 @@ TOOLSDIR = $(BASEDIR)/tools
clean:
rm -rf $(OUTPUTDIR)
-doku:
- rm -rf $(OUTPUTDIR)/doku
- mkdir -p $(OUTPUTDIR)/doku
- pushd $(OUTPUTDIR)/doku
- python2 $(TOOLSDIR)/makedoku.py $(CLASSES)
- popd
-
doxygen:
rm -rf $(OUTPUTDIR)/doxygen
mkdir -p $(OUTPUTDIR)/doxygen
doxygen Doxyfile
-html:
- rm -rf $(OUTPUTDIR)/html
- mkdir -p $(OUTPUTDIR)/html
- pushd $(OUTPUTDIR)/html
- python2 $(TOOLSDIR)/makehtml.py -multipage $(CLASSES)
- popd
-
markdown:
rm -rf $(OUTPUTDIR)/markdown
mkdir -p $(OUTPUTDIR)/markdown
@@ -40,8 +26,3 @@ rst:
pushd $(OUTPUTDIR)/rst
python2 $(TOOLSDIR)/makerst.py $(CLASSES)
popd
-
-textile:
- rm -rf $(OUTPUTDIR)/textile
- mkdir -p $(OUTPUTDIR)/textile
- python3 $(TOOLSDIR)/makedocs.py --input $(CLASSES) --output $(OUTPUTDIR)/textile
diff --git a/doc/base/classes.xml b/doc/base/classes.xml
index 03dd151eb2..2139d1a467 100644
--- a/doc/base/classes.xml
+++ b/doc/base/classes.xml
@@ -1,15 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<doc version="3.0.alpha.custom_build" name="Engine Types">
-<class name="@DLScript" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
<class name="@GDScript" category="Core">
<brief_description>
Built-in GDScript functions.
@@ -1914,45 +1904,49 @@
<constant name="TYPE_COLOR" value="14">
Variable is of type [Color].
</constant>
- <constant name="TYPE_IMAGE" value="15">
- Variable is of type [Image].
- </constant>
- <constant name="TYPE_NODE_PATH" value="16">
+ <constant name="TYPE_NODE_PATH" value="15">
Variable is of type [NodePath].
</constant>
- <constant name="TYPE_RID" value="17">
+ <constant name="TYPE_RID" value="16">
Variable is of type [RID].
</constant>
- <constant name="TYPE_OBJECT" value="18">
+ <constant name="TYPE_OBJECT" value="17">
Variable is of type [Object].
</constant>
- <constant name="TYPE_INPUT_EVENT" value="19">
- Variable is of type [InputEvent].
- </constant>
- <constant name="TYPE_DICTIONARY" value="20">
+ <constant name="TYPE_DICTIONARY" value="18">
Variable is of type [Dictionary].
</constant>
- <constant name="TYPE_ARRAY" value="21">
+ <constant name="TYPE_ARRAY" value="19">
Variable is of type [Array].
</constant>
- <constant name="TYPE_RAW_ARRAY" value="22">
+ <constant name="TYPE_RAW_ARRAY" value="20">
</constant>
- <constant name="TYPE_INT_ARRAY" value="23">
+ <constant name="TYPE_INT_ARRAY" value="21">
</constant>
- <constant name="TYPE_REAL_ARRAY" value="24">
+ <constant name="TYPE_REAL_ARRAY" value="22">
</constant>
- <constant name="TYPE_STRING_ARRAY" value="25">
+ <constant name="TYPE_STRING_ARRAY" value="23">
</constant>
- <constant name="TYPE_VECTOR2_ARRAY" value="26">
+ <constant name="TYPE_VECTOR2_ARRAY" value="24">
</constant>
- <constant name="TYPE_VECTOR3_ARRAY" value="27">
+ <constant name="TYPE_VECTOR3_ARRAY" value="25">
</constant>
- <constant name="TYPE_COLOR_ARRAY" value="28">
+ <constant name="TYPE_COLOR_ARRAY" value="26">
</constant>
- <constant name="TYPE_MAX" value="29">
+ <constant name="TYPE_MAX" value="27">
</constant>
</constants>
</class>
+<class name="@Native" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="@VisualScript" category="Core">
<brief_description>
</brief_description>
@@ -1993,6 +1987,7 @@
<argument index="2" name="weight_scale" type="float" default="1">
</argument>
<description>
+ Add a new point at the given position. The [code]weight_scale[/code] has to be 1 or larger.
</description>
</method>
<method name="are_points_connected" qualifiers="const">
@@ -2014,6 +2009,8 @@
</argument>
<argument index="1" name="to_id" type="int">
</argument>
+ <argument index="2" name="bidirectional" type="bool" default="true">
+ </argument>
<description>
</description>
</method>
@@ -2985,7 +2982,7 @@
Return the default blend time between animations.
</description>
</method>
- <method name="get_position" qualifiers="const">
+ <method name="get_pos" qualifiers="const">
<return type="float">
</return>
<description>
@@ -3756,6 +3753,22 @@
Return the angular damp rate.
</description>
</method>
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Return the physics layer this area is in.
+ </description>
+ </method>
+ <method name="get_collision_layer_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ Return an individual bit on the layer mask.
+ </description>
+ </method>
<method name="get_collision_mask" qualifiers="const">
<return type="int">
</return>
@@ -3793,22 +3806,6 @@
Return the gravity vector. If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center.
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the physics layer this area is in.
- </description>
- </method>
- <method name="get_layer_mask_bit" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="bit" type="int">
- </argument>
- <description>
- Return an individual bit on the layer mask.
- </description>
- </method>
<method name="get_linear_damp" qualifiers="const">
<return type="float">
</return>
@@ -3891,6 +3888,24 @@
In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second.
</description>
</method>
+ <method name="set_collision_layer">
+ <argument index="0" name="collision_layer" type="int">
+ </argument>
+ <description>
+ Set the physics layers this area is in.
+ Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask].
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ </description>
+ </method>
+ <method name="set_collision_layer_bit">
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier.
+ </description>
+ </method>
<method name="set_collision_mask">
<argument index="0" name="collision_mask" type="int">
</argument>
@@ -3937,24 +3952,6 @@
If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center.
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="layer_mask" type="int">
- </argument>
- <description>
- Set the physics layers this area is in.
- Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask].
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
- </description>
- </method>
- <method name="set_layer_mask_bit">
- <argument index="0" name="bit" type="int">
- </argument>
- <argument index="1" name="value" type="bool">
- </argument>
- <description>
- Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier.
- </description>
- </method>
<method name="set_linear_damp">
<argument index="0" name="linear_damp" type="float">
</argument>
@@ -4001,7 +3998,7 @@
<members>
<member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief="">
</member>
- <member name="collision_layers" type="int" setter="set_layer_mask" getter="get_layer_mask" brief="">
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="">
</member>
@@ -4124,6 +4121,22 @@
Return the angular damp rate.
</description>
</method>
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Return the physics layer this area is in.
+ </description>
+ </method>
+ <method name="get_collision_layer_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ Return an individual bit on the layer mask.
+ </description>
+ </method>
<method name="get_collision_mask" qualifiers="const">
<return type="int">
</return>
@@ -4161,22 +4174,6 @@
Return the gravity vector. If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center.
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the physics layer this area is in.
- </description>
- </method>
- <method name="get_layer_mask_bit" qualifiers="const">
- <return type="bool">
- </return>
- <argument index="0" name="bit" type="int">
- </argument>
- <description>
- Return an individual bit on the layer mask.
- </description>
- </method>
<method name="get_linear_damp" qualifiers="const">
<return type="float">
</return>
@@ -4259,6 +4256,24 @@
In practice, as the fraction of speed lost gets smaller with each frame, a value of 1.0 does not mean the object will stop in exactly one second. Only when the physics calculations are done at 1 frame per second, it does stop in a second.
</description>
</method>
+ <method name="set_collision_layer">
+ <argument index="0" name="collision_layer" type="int">
+ </argument>
+ <description>
+ Set the physics layers this area is in.
+ Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask].
+ A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
+ </description>
+ </method>
+ <method name="set_collision_layer_bit">
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier.
+ </description>
+ </method>
<method name="set_collision_mask">
<argument index="0" name="collision_mask" type="int">
</argument>
@@ -4305,24 +4320,6 @@
If gravity is a point (see [method is_gravity_a_point]), this will be the attraction center.
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="layer_mask" type="int">
- </argument>
- <description>
- Set the physics layers this area is in.
- Collidable objects can exist in any of 32 different layers. These layers are not visual, but more of a tagging system instead. A collidable can use these layers/tags to select with which objects it can collide, using [method set_collision_mask].
- A contact is detected if object A is in any of the layers that object B scans, or object B is in any layer scanned by object A.
- </description>
- </method>
- <method name="set_layer_mask_bit">
- <argument index="0" name="bit" type="int">
- </argument>
- <argument index="1" name="value" type="bool">
- </argument>
- <description>
- Set/clear individual bits on the layer mask. This makes getting an area in/out of only one layer easier.
- </description>
- </method>
<method name="set_linear_damp">
<argument index="0" name="linear_damp" type="float">
</argument>
@@ -4369,7 +4366,7 @@
<members>
<member name="angular_damp" type="float" setter="set_angular_damp" getter="get_angular_damp" brief="">
</member>
- <member name="collision_layers" type="int" setter="set_layer_mask" getter="get_layer_mask" brief="">
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="">
</member>
@@ -4717,6 +4714,251 @@
<constants>
</constants>
</class>
+<class name="ArrayMesh" inherits="Mesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="add_blend_shape">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="add_surface_from_arrays">
+ <argument index="0" name="primitive" type="int">
+ </argument>
+ <argument index="1" name="arrays" type="Array">
+ </argument>
+ <argument index="2" name="blend_shapes" type="Array" default="[]">
+ </argument>
+ <argument index="3" name="compress_flags" type="int" default="97792">
+ </argument>
+ <description>
+ Create a new surface ([method get_surface_count] that will become surf_idx for this.
+ Surfaces are created to be rendered using a "primitive", which may be PRIMITIVE_POINTS, PRIMITIVE_LINES, PRIMITIVE_LINE_STRIP, PRIMITIVE_LINE_LOOP, PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP, PRIMITIVE_TRIANGLE_FAN. (As a note, when using indices, it is recommended to only use just points, lines or triangles).
+ </description>
+ </method>
+ <method name="center_geometry">
+ <description>
+ </description>
+ </method>
+ <method name="clear_blend_shapes">
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_mode" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_blend_shape_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_custom_aabb" qualifiers="const">
+ <return type="Rect3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_surface_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Return the amount of surfaces that the [ArrayMesh] holds.
+ </description>
+ </method>
+ <method name="regen_normalmaps">
+ <description>
+ </description>
+ </method>
+ <method name="set_blend_shape_mode">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_custom_aabb">
+ <argument index="0" name="aabb" type="Rect3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="surface_get_array_index_len" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Return the length in indices of the index array in the requested surface (see [method add_surface]).
+ </description>
+ </method>
+ <method name="surface_get_array_len" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Return the length in vertices of the vertex array in the requested surface (see [method add_surface]).
+ </description>
+ </method>
+ <method name="surface_get_format" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Return the format mask of the requested surface (see [method add_surface]).
+ </description>
+ </method>
+ <method name="surface_get_material" qualifiers="const">
+ <return type="Material">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Return a [Material] in a given surface. Surface is rendered using this material.
+ </description>
+ </method>
+ <method name="surface_get_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="surface_get_primitive_type" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Return the primitive type of the requested surface (see [method add_surface]).
+ </description>
+ </method>
+ <method name="surface_remove">
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <description>
+ Remove a surface at position surf_idx, shifting greater surfaces one surf_idx slot down.
+ </description>
+ </method>
+ <method name="surface_set_material">
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <argument index="1" name="material" type="Material">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="surface_set_name">
+ <argument index="0" name="surf_idx" type="int">
+ </argument>
+ <argument index="1" name="name" type="String">
+ </argument>
+ <description>
+ Set a [Material] for a given surface. Surface will be rendered using this material.
+ </description>
+ </method>
+ </methods>
+ <constants>
+ <constant name="NO_INDEX_ARRAY" value="-1">
+ Default value used for index_array_len when no indices are present.
+ </constant>
+ <constant name="ARRAY_WEIGHTS_SIZE" value="4">
+ Amount of weights/bone indices per vertex (always 4).
+ </constant>
+ <constant name="ARRAY_VERTEX" value="0">
+ Vertex array (array of [Vector3] vertices).
+ </constant>
+ <constant name="ARRAY_NORMAL" value="1">
+ Normal array (array of [Vector3] normals).
+ </constant>
+ <constant name="ARRAY_TANGENT" value="2">
+ Tangent array, array of groups of 4 floats. first 3 floats determine the tangent, and the last the binormal direction as -1 or 1.
+ </constant>
+ <constant name="ARRAY_COLOR" value="3">
+ Vertex array (array of [Color] colors).
+ </constant>
+ <constant name="ARRAY_TEX_UV" value="4">
+ UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
+ </constant>
+ <constant name="ARRAY_TEX_UV2" value="5">
+ Second UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
+ </constant>
+ <constant name="ARRAY_BONES" value="6">
+ Array of bone indices, as a float array. Each element in groups of 4 floats.
+ </constant>
+ <constant name="ARRAY_WEIGHTS" value="7">
+ Array of bone weights, as a float array. Each element in groups of 4 floats.
+ </constant>
+ <constant name="ARRAY_INDEX" value="8">
+ Array of integers, used as indices referencing vertices. No index can be beyond the vertex array size.
+ </constant>
+ <constant name="ARRAY_FORMAT_VERTEX" value="1">
+ Array format will include vertices (mandatory).
+ </constant>
+ <constant name="ARRAY_FORMAT_NORMAL" value="2">
+ Array format will include normals
+ </constant>
+ <constant name="ARRAY_FORMAT_TANGENT" value="4">
+ Array format will include tangents
+ </constant>
+ <constant name="ARRAY_FORMAT_COLOR" value="8">
+ Array format will include a color array.
+ </constant>
+ <constant name="ARRAY_FORMAT_TEX_UV" value="16">
+ Array format will include UVs.
+ </constant>
+ <constant name="ARRAY_FORMAT_TEX_UV2" value="32">
+ Array format will include another set of UVs.
+ </constant>
+ <constant name="ARRAY_FORMAT_BONES" value="64">
+ Array format will include bone indices.
+ </constant>
+ <constant name="ARRAY_FORMAT_WEIGHTS" value="128">
+ Array format will include bone weights.
+ </constant>
+ <constant name="ARRAY_FORMAT_INDEX" value="256">
+ Index array will be used.
+ </constant>
+ <constant name="PRIMITIVE_POINTS" value="0">
+ Render array as points (one vertex equals one point).
+ </constant>
+ <constant name="PRIMITIVE_LINES" value="1">
+ Render array as lines (every two vertices a line is created).
+ </constant>
+ <constant name="PRIMITIVE_LINE_STRIP" value="2">
+ Render array as line strip.
+ </constant>
+ <constant name="PRIMITIVE_LINE_LOOP" value="3">
+ Render array as line loop (like line strip, but closed).
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLES" value="4">
+ Render array as triangles (every three vertices a triangle is created).
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLE_STRIP" value="5">
+ Render array as triangle strips.
+ </constant>
+ <constant name="PRIMITIVE_TRIANGLE_FAN" value="6">
+ Render array as triangle fans.
+ </constant>
+ </constants>
+</class>
<class name="AtlasTexture" inherits="Texture" category="Core">
<brief_description>
</brief_description>
@@ -6005,7 +6247,7 @@
<description>
</description>
</method>
- <method name="get_position">
+ <method name="get_pos">
<return type="float">
</return>
<description>
@@ -6594,58 +6836,6 @@
</constant>
</constants>
</class>
-<class name="BakedLight" inherits="VisualInstance" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="bake">
- <description>
- </description>
- </method>
- <method name="bake_lights">
- <description>
- </description>
- </method>
- <method name="bake_radiance">
- <description>
- </description>
- </method>
- <method name="debug_mesh_albedo">
- <description>
- </description>
- </method>
- <method name="debug_mesh_light">
- <description>
- </description>
- </method>
- <method name="get_cell_subdiv" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="set_cell_subdiv">
- <argument index="0" name="steps" type="int">
- </argument>
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="cell_subdiv" type="int" setter="set_cell_subdiv" getter="get_cell_subdiv" brief="">
- </member>
- </members>
- <signals>
- <signal name="baked_light_changed">
- <description>
- </description>
- </signal>
- </signals>
- <constants>
- </constants>
-</class>
<class name="BaseButton" inherits="Control" category="Core">
<brief_description>
Provides a base class for different kinds of buttons.
@@ -6857,21 +7047,21 @@
<method name="Basis">
<return type="Basis">
</return>
- <argument index="0" name="axis" type="Vector3">
- </argument>
- <argument index="1" name="phi" type="float">
+ <argument index="0" name="euler" type="Vector3">
</argument>
<description>
- Create a rotation matrix which rotates around the given axis by the specified angle. The axis must be a normalized vector.
+ Create a rotation matrix (in the XYZ convention: first Z, then Y, and X last) from the specified Euler angles, given in the vector format as (third, second, first).
</description>
</method>
<method name="Basis">
<return type="Basis">
</return>
- <argument index="0" name="euler" type="Vector3">
+ <argument index="0" name="axis" type="Vector3">
+ </argument>
+ <argument index="1" name="phi" type="float">
</argument>
<description>
- Create a rotation matrix (in the XYZ convention: first Z, then Y, and X last) from the specified Euler angles, given in the vector format as (third,second,first).
+ Create a rotation matrix which rotates around the given axis by the specified angle. The axis must be a normalized vector.
</description>
</method>
<method name="Basis">
@@ -6940,38 +7130,32 @@
Introduce an additional rotation around the given axis by phi (radians). Only relevant when the matrix is being used as a part of [Transform]. The axis must be a normalized vector.
</description>
</method>
- <method name="set_rotation_euler">
+ <method name="scaled">
<return type="Basis">
</return>
- <argument index="0" name="euler" type="Vector3">
+ <argument index="0" name="scale" type="Vector3">
</argument>
<description>
- Changes only the rotation part of the [Basis] to a rotation corresponding to given Euler angles, while preserving the scaling part (as determined by get_scale).
+ Introduce an additional scaling specified by the given 3D scaling factor. Only relevant when the matrix is being used as a part of [Transform].
</description>
</method>
<method name="set_rotation_axis_angle">
- <return type="Basis">
- </return>
<argument index="0" name="axis" type="Vector3">
</argument>
- <argument index="1" name="phi" type="float">
+ <argument index="1" name="angle" type="float">
</argument>
<description>
Changes only the rotation part of the [Basis] to a rotation around given axis by phi, while preserving the scaling part (as determined by get_scale).
</description>
</method>
- <method name="scaled">
- <return type="Basis">
- </return>
- <argument index="0" name="scale" type="Vector3">
+ <method name="set_rotation_euler">
+ <argument index="0" name="euler" type="Vector3">
</argument>
<description>
- Introduce an additional scaling specified by the given 3D scaling factor. Only relevant when the matrix is being used as a part of [Transform].
+ Changes only the rotation part of the [Basis] to a rotation corresponding to given Euler angles, while preserving the scaling part (as determined by get_scale).
</description>
</method>
<method name="set_scale">
- <return type="Basis">
- </return>
<argument index="0" name="scale" type="Vector3">
</argument>
<description>
@@ -7055,7 +7239,7 @@
</description>
</method>
<method name="create_from_image_alpha">
- <argument index="0" name="image" type="Image">
+ <argument index="0" name="image" type="Object">
</argument>
<description>
</description>
@@ -7472,173 +7656,6 @@
</theme_item>
</theme_items>
</class>
-<class name="ButtonArray" inherits="Control" category="Core">
- <brief_description>
- Array of Buttons.
- </brief_description>
- <description>
- Array of Buttons. A ButtonArray is useful to have an array of buttons laid out vertically or horizontally. Only one button can be selected, and is referenced by its index in the array (first button is 0, second button is 1, etc.).
- This is useful [i]e.g.[/i] for joypad-friendly interfaces and option menus.
- </description>
- <methods>
- <method name="add_button">
- <argument index="0" name="text" type="String">
- </argument>
- <argument index="1" name="tooltip" type="String" default="&quot;&quot;">
- </argument>
- <description>
- Append a new button to the array, with the specified text and tooltip.
- </description>
- </method>
- <method name="add_icon_button">
- <argument index="0" name="icon" type="Texture">
- </argument>
- <argument index="1" name="text" type="String" default="&quot;&quot;">
- </argument>
- <argument index="2" name="tooltip" type="String" default="&quot;&quot;">
- </argument>
- <description>
- Append a new button to the array, with the specified icon, text and tooltip.
- </description>
- </method>
- <method name="clear">
- <description>
- Remove all buttons from the array.
- </description>
- </method>
- <method name="erase_button">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- Remove the specified button in the array.
- </description>
- </method>
- <method name="get_button_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the amount of buttons in the array.
- </description>
- </method>
- <method name="get_button_icon" qualifiers="const">
- <return type="Texture">
- </return>
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- Return the icon of the specified button.
- </description>
- </method>
- <method name="get_button_text" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- Return the text of the specified button.
- </description>
- </method>
- <method name="get_button_tooltip" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- Return the tooltip of the specified button.
- </description>
- </method>
- <method name="get_hovered" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the index of the currently hovered button in the array.
- </description>
- </method>
- <method name="get_selected" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the index of the currently selected button in the array.
- </description>
- </method>
- <method name="is_flat" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
- <method name="set_button_icon">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <argument index="1" name="icon" type="Texture">
- </argument>
- <description>
- Set the icon of the specified button.
- </description>
- </method>
- <method name="set_button_text">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <argument index="1" name="text" type="String">
- </argument>
- <description>
- Define the text of the specified button.
- </description>
- </method>
- <method name="set_button_tooltip">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <argument index="1" name="text" type="String">
- </argument>
- <description>
- Define the tooltip of the specified button.
- </description>
- </method>
- <method name="set_flat">
- <argument index="0" name="enabled" type="bool">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_selected">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- Select a button in the array based on the given index.
- </description>
- </method>
- </methods>
- <members>
- <member name="flat" type="bool" setter="set_flat" getter="is_flat" brief="">
- </member>
- </members>
- <signals>
- <signal name="button_selected">
- <argument index="0" name="button_idx" type="int">
- </argument>
- <description>
- A button has been selected, its index is given as the argument.
- </description>
- </signal>
- </signals>
- <constants>
- <constant name="ALIGN_BEGIN" value="0">
- Align buttons at the beginning.
- </constant>
- <constant name="ALIGN_CENTER" value="1">
- Align buttons in the middle.
- </constant>
- <constant name="ALIGN_END" value="2">
- Align buttons at the end.
- </constant>
- <constant name="ALIGN_FILL" value="3">
- Spread the buttons, but keep them small.
- </constant>
- <constant name="ALIGN_EXPAND_FILL" value="4">
- Spread the buttons, but expand them.
- </constant>
- </constants>
-</class>
<class name="ButtonGroup" inherits="Resource" category="Core">
<brief_description>
Group of Buttons.
@@ -8552,12 +8569,11 @@
</description>
</method>
<method name="make_input_local" qualifiers="const">
- <return type="InputEvent">
+ <return type="Object">
</return>
- <argument index="0" name="event" type="InputEvent">
+ <argument index="0" name="event" type="Object">
</argument>
<description>
- Takes a global input event and convert to this item's coordinate system.
</description>
</method>
<method name="set_as_toplevel">
@@ -8868,6 +8884,74 @@
<constants>
</constants>
</class>
+<class name="CapsuleMesh" inherits="PrimitiveMesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_mid_height" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_radial_segments" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_radius" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_rings" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_mid_height">
+ <argument index="0" name="mid_height" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_radial_segments">
+ <argument index="0" name="segments" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_radius">
+ <argument index="0" name="radius" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_rings">
+ <argument index="0" name="rings" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="mid_height" type="float" setter="set_mid_height" getter="get_mid_height" brief="">
+ </member>
+ <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief="">
+ </member>
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" brief="">
+ </member>
+ <member name="rings" type="int" setter="set_rings" getter="get_rings" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="CapsuleShape" inherits="Shape" category="Core">
<brief_description>
Capsule shape resource.
@@ -9168,6 +9252,16 @@
<description>
</description>
</method>
+ <method name="class_get_property" qualifiers="const">
+ <return type="Variant">
+ </return>
+ <argument index="0" name="object" type="Object">
+ </argument>
+ <argument index="1" name="property" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="class_get_property_list" qualifiers="const">
<return type="Array">
</return>
@@ -9230,6 +9324,18 @@
<description>
</description>
</method>
+ <method name="class_set_property" qualifiers="const">
+ <return type="Error">
+ </return>
+ <argument index="0" name="object" type="Object">
+ </argument>
+ <argument index="1" name="property" type="String">
+ </argument>
+ <argument index="2" name="value" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_class_list" qualifiers="const">
<return type="PoolStringArray">
</return>
@@ -9415,7 +9521,7 @@
<signal name="input_event">
<argument index="0" name="camera" type="Object">
</argument>
- <argument index="1" name="event" type="InputEvent">
+ <argument index="1" name="event" type="Object">
</argument>
<argument index="2" name="click_pos" type="Vector3">
</argument>
@@ -9454,7 +9560,6 @@
<argument index="2" name="shape_idx" type="int">
</argument>
<description>
- This method can be used to override normal input processing. The first parameter is the viewport where the event took place. The second holds the input event received, and the third the shape of this object where it happened.
</description>
</method>
<method name="add_shape">
@@ -9569,12 +9674,11 @@
<signal name="input_event">
<argument index="0" name="viewport" type="Object">
</argument>
- <argument index="1" name="event" type="InputEvent">
+ <argument index="1" name="event" type="Object">
</argument>
<argument index="2" name="shape_idx" type="int">
</argument>
<description>
- This signal triggers when an input event fires over a shape. The first parameter is the viewport where the event took place. The second holds the input event received, and the third the shape of this object where it happened.
</description>
</signal>
<signal name="mouse_entered">
@@ -10183,120 +10287,6 @@
</theme_item>
</theme_items>
</class>
-<class name="ColorRamp" inherits="Resource" category="Core">
- <brief_description>
- Color interpolator node
- </brief_description>
- <description>
- Given a set of colors, this node will interpolate them in order, meaning, that if you have color 1, color 2 and color3, the ramp will interpolate (generate the colors between two colors) from color 1 to color 2 and from color 2 to color 3. Initially the ramp will have 2 colors (black and white), one (black) at ramp lower offset offset 0 and the other (white) at the ramp higher offset 1.
- </description>
- <methods>
- <method name="add_point">
- <argument index="0" name="offset" type="float">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- Adds the specified color to the end of the ramp, with the specified offset
- </description>
- </method>
- <method name="get_color" qualifiers="const">
- <return type="Color">
- </return>
- <argument index="0" name="point" type="int">
- </argument>
- <description>
- Returns the color of the ramp color at index [i]point[/i]
- </description>
- </method>
- <method name="get_colors" qualifiers="const">
- <return type="PoolColorArray">
- </return>
- <description>
- Returns the colors in the ramp
- </description>
- </method>
- <method name="get_offset" qualifiers="const">
- <return type="float">
- </return>
- <argument index="0" name="point" type="int">
- </argument>
- <description>
- Returns the offset of the ramp color at index [i]point[/i]
- </description>
- </method>
- <method name="get_offsets" qualifiers="const">
- <return type="PoolRealArray">
- </return>
- <description>
- Returns the offsets for the colors in this ramp
- </description>
- </method>
- <method name="get_point_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the number of colors in the ramp
- </description>
- </method>
- <method name="interpolate">
- <return type="Color">
- </return>
- <argument index="0" name="offset" type="float">
- </argument>
- <description>
- Returns the interpolated color specified by [i]offset[/i]
- </description>
- </method>
- <method name="remove_point">
- <argument index="0" name="offset" type="int">
- </argument>
- <description>
- Removes the color at the index [i]offset[/i]
- </description>
- </method>
- <method name="set_color">
- <argument index="0" name="point" type="int">
- </argument>
- <argument index="1" name="color" type="Color">
- </argument>
- <description>
- Sets the color of the ramp color at index [i]point[/i]
- </description>
- </method>
- <method name="set_colors">
- <argument index="0" name="colors" type="PoolColorArray">
- </argument>
- <description>
- Sets the colors for the specified amount of elements. Calling this function with a different number of elements than previously defined causes the ramp to resize its colors and offsets array to accommodate the new elements.
- </description>
- </method>
- <method name="set_offset">
- <argument index="0" name="point" type="int">
- </argument>
- <argument index="1" name="offset" type="float">
- </argument>
- <description>
- Sets the offset for the ramp color at index [i]point[/i]
- </description>
- </method>
- <method name="set_offsets">
- <argument index="0" name="offsets" type="PoolRealArray">
- </argument>
- <description>
- Sets the offset for the specified amount of elements. Calling this function with a different number of elements than previously defined causes the ramp to resize its colors and offsets array to accommodate the new elements, all new colors will be black by default.
- </description>
- </method>
- </methods>
- <members>
- <member name="colors" type="float" setter="set_colors" getter="get_colors" brief="">
- </member>
- <member name="offsets" type="float" setter="set_offsets" getter="get_offsets" brief="">
- </member>
- </members>
- <constants>
- </constants>
-</class>
<class name="ColorRect" inherits="Control" category="Core">
<brief_description>
</brief_description>
@@ -10604,7 +10594,7 @@
Control is the base class Node for all the GUI components. Every GUI component inherits from it, directly or indirectly. In this way, sections of the scene tree made of contiguous control nodes, become user interfaces.
Controls are relative to the parent position and size by using anchors and margins. This ensures that they can adapt easily in most situation to changing dialog and screen sizes. When more flexibility is desired, [Container] derived nodes can be used.
Anchors work by defining which margin do they follow, and a value relative to it. Allowed anchoring modes are ANCHOR_BEGIN, where the margin is relative to the top or left margins of the parent (in pixels), ANCHOR_END for the right and bottom margins of the parent and ANCHOR_RATIO, which is a ratio from 0 to 1 in the parent range.
- Input device events ([InputEvent]) are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method MainLoop._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
+ Input device events are first sent to the root controls via the [method Node._input], which distribute it through the tree, then delivers them to the adequate one (under cursor or keyboard focus based) by calling [method MainLoop._input_event]. There is no need to enable input processing on controls to receive such events. To ensure that no one else will receive the event (not even [method Node._unhandled_input]), the control can accept it by calling [method accept_event].
Only one control can hold the keyboard focus (receiving keyboard events), for that the control must define the focus mode with [method set_focus_mode]. Focus is lost when another control gains it, or the current focus owner is hidden.
It is sometimes desired for a control to ignore mouse/pointer events. This is often the case when placing other controls on top of a button, in such cases. Calling [method set_ignore_mouse] enables this function.
Finally, controls are skinned according to a [Theme]. Setting a [Theme] on a control will propagate all the skinning down the tree. Optionally, skinning can be overridden per each control by calling the add_*_override functions, or from the editor.
@@ -10621,7 +10611,6 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Called when an input event reaches the control.
</description>
</method>
<method name="accept_event">
@@ -10818,7 +10807,7 @@
<description>
</description>
</method>
- <method name="get_global_pos" qualifiers="const">
+ <method name="get_global_position" qualifiers="const">
<return type="Vector2">
</return>
<description>
@@ -11183,7 +11172,7 @@
Force a neighbour for moving the input focus to. When pressing TAB or directional/joypad directions focus is moved to the next control in that direction. However, the neighbour to move to can be forced with this function.
</description>
</method>
- <method name="set_global_pos">
+ <method name="set_global_position">
<argument index="0" name="pos" type="Vector2">
</argument>
<description>
@@ -11322,7 +11311,7 @@
</member>
<member name="rect_min_size" type="Vector2" setter="set_custom_minimum_size" getter="get_custom_minimum_size" brief="">
</member>
- <member name="rect_pos" type="Vector2" setter="set_pos" getter="get_pos" brief="">
+ <member name="rect_position" type="Vector2" setter="set_position" getter="get_position" brief="">
</member>
<member name="rect_rotation" type="float" setter="set_rotation_deg" getter="get_rotation_deg" brief="">
</member>
@@ -11351,10 +11340,9 @@
</description>
</signal>
<signal name="gui_input">
- <argument index="0" name="ev" type="InputEvent">
+ <argument index="0" name="ev" type="Object">
</argument>
<description>
- Emitted when an input event is received. Connecting in realtime is recommended for accepting the events.
</description>
</signal>
<signal name="minimum_size_changed">
@@ -11565,7 +11553,7 @@
</description>
</method>
<method name="get_side" qualifiers="const">
- <return type="Image">
+ <return type="Object">
</return>
<argument index="0" name="side" type="int">
</argument>
@@ -11599,7 +11587,7 @@
<method name="set_side">
<argument index="0" name="side" type="int">
</argument>
- <argument index="1" name="image" type="Image">
+ <argument index="1" name="image" type="Object">
</argument>
<description>
</description>
@@ -11640,6 +11628,74 @@
</constant>
</constants>
</class>
+<class name="CubeMesh" inherits="PrimitiveMesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_size" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_depth" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_size">
+ <argument index="0" name="size" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_depth">
+ <argument index="0" name="divisions" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_height">
+ <argument index="0" name="divisions" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_width">
+ <argument index="0" name="subdivide" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ </member>
+ <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief="">
+ </member>
+ <member name="subdivide_height" type="int" setter="set_subdivide_height" getter="get_subdivide_height" brief="">
+ </member>
+ <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="Curve2D" inherits="Resource" category="Core">
<brief_description>
Describes a Bezier curve in 2D space.
@@ -12090,67 +12146,83 @@
<constants>
</constants>
</class>
-<class name="DLLibrary" inherits="Resource" category="Core">
+<class name="CylinderMesh" inherits="PrimitiveMesh" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
- <method name="get_platform_file" qualifiers="const">
- <return type="String">
+ <method name="get_bottom_radius" qualifiers="const">
+ <return type="float">
</return>
- <argument index="0" name="platform" type="String">
- </argument>
<description>
</description>
</method>
- <method name="set_platform_file">
- <argument index="0" name="platform" type="String">
- </argument>
- <argument index="1" name="file" type="String">
- </argument>
+ <method name="get_height" qualifiers="const">
+ <return type="float">
+ </return>
<description>
</description>
</method>
- </methods>
- <constants>
- </constants>
-</class>
-<class name="DLScript" inherits="Script" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_library" qualifiers="const">
- <return type="Object">
+ <method name="get_radial_segments" qualifiers="const">
+ <return type="int">
</return>
<description>
</description>
</method>
- <method name="get_script_name" qualifiers="const">
- <return type="String">
+ <method name="get_rings" qualifiers="const">
+ <return type="int">
</return>
<description>
</description>
</method>
- <method name="set_library">
- <argument index="0" name="library" type="Object">
+ <method name="get_top_radius" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_bottom_radius">
+ <argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_script_name">
- <argument index="0" name="script_name" type="String">
+ <method name="set_height">
+ <argument index="0" name="height" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_radial_segments">
+ <argument index="0" name="segments" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_rings">
+ <argument index="0" name="rings" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_top_radius">
+ <argument index="0" name="radius" type="float">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="library" type="DLLibrary" setter="set_library" getter="get_library" brief="">
+ <member name="bottom_radius" type="float" setter="set_bottom_radius" getter="get_bottom_radius" brief="">
</member>
- <member name="script_name" type="String" setter="set_script_name" getter="get_script_name" brief="">
+ <member name="height" type="float" setter="set_height" getter="get_height" brief="">
+ </member>
+ <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief="">
+ </member>
+ <member name="rings" type="int" setter="set_rings" getter="get_rings" brief="">
+ </member>
+ <member name="top_radius" type="float" setter="set_top_radius" getter="get_top_radius" brief="">
</member>
</members>
<constants>
@@ -12345,8 +12417,6 @@
</method>
</methods>
<members>
- <member name="directional_shadow_bias_split_scale" type="float" setter="set_param" getter="get_param" brief="">
- </member>
<member name="directional_shadow_blend_splits" type="bool" setter="set_blend_splits" getter="is_blend_splits_enabled" brief="">
</member>
<member name="directional_shadow_mode" type="int" setter="set_shadow_mode" getter="get_shadow_mode" brief="">
@@ -13050,6 +13120,94 @@
<constants>
</constants>
</class>
+<class name="EditorImportPlugin" inherits="Reference" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_import_options" qualifiers="virtual">
+ <return type="Array">
+ </return>
+ <argument index="0" name="preset" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_importer_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_option_visibility" qualifiers="virtual">
+ <return type="bool">
+ </return>
+ <argument index="0" name="option" type="String">
+ </argument>
+ <argument index="1" name="options" type="Dictionary">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_preset_count" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_preset_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <argument index="0" name="preset" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_recognized_extensions" qualifiers="virtual">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_resource_type" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_save_extension" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_visible_name" qualifiers="virtual">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="import" qualifiers="virtual">
+ <return type="int">
+ </return>
+ <argument index="0" name="source_file" type="String">
+ </argument>
+ <argument index="1" name="save_path" type="String">
+ </argument>
+ <argument index="2" name="options" type="Dictionary">
+ </argument>
+ <argument index="3" name="r_platform_variants" type="Array">
+ </argument>
+ <argument index="4" name="r_gen_files" type="Array">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
<class name="EditorPlugin" inherits="Node" category="Core">
<brief_description>
Used by the editor to extend its functionality.
@@ -13107,6 +13265,12 @@
During run-time, this will be a simple object with a script so this function does not need to be called then.
</description>
</method>
+ <method name="add_import_plugin">
+ <argument index="0" name="arg0" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="add_tool_submenu_item">
<argument index="0" name="name" type="String">
</argument>
@@ -13156,7 +13320,6 @@
<argument index="1" name="event" type="InputEvent">
</argument>
<description>
- If your plugin is active (because handles() returned true to the object), any input interaction with the 2D canvas editor will be first forwarded here. The canvas transform (containing zoom and offset to transform to edited world coordinates) is provided, but the input supplied is in untransformed coordinates to the canvas editor. Return true if you want to eat this event and not pass it to the canvas editor.
</description>
</method>
<method name="forward_draw_over_canvas" qualifiers="virtual">
@@ -13176,9 +13339,6 @@
<argument index="1" name="event" type="InputEvent">
</argument>
<description>
- This is a low level function for plugins that edit a given objet type derived from Spatial to capture the input of the viewport. The function is only being called if your object is being edited.
- By using the [InputEvent] and the [Camera] arguments it's pretty easy to do raycasts into space using Camera functions.
- Return true if you want to capture the input, otherwise false.
</description>
</method>
<method name="get_base_control">
@@ -13327,6 +13487,12 @@
Remove a custom type added by [method EditorPlugin.add_custom_type]
</description>
</method>
+ <method name="remove_import_plugin">
+ <argument index="0" name="arg0" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="save_external_data" qualifiers="virtual">
<description>
This method is called after the editor saves the project or when it's closed. It asks the plugin to save edited external scenes/resources.
@@ -13722,7 +13888,7 @@
</argument>
<argument index="1" name="billboard" type="bool" default="false">
</argument>
- <argument index="2" name="skeleton" type="RID" default="RID()">
+ <argument index="2" name="skeleton" type="RID" default="[RID]">
</argument>
<description>
Add a mesh to the gizmo, this is used for visualization. Call this function during [method redraw].
@@ -13867,6 +14033,12 @@
"string" - major + minor + patch + status + revision in a single String
</description>
</method>
+ <method name="is_in_fixed_frame" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_iterations_per_second">
<argument index="0" name="iterations_per_second" type="int">
</argument>
@@ -13932,7 +14104,7 @@
<description>
</description>
</method>
- <method name="get_ambient_light_skybox_contribution" qualifiers="const">
+ <method name="get_ambient_light_sky_contribution" qualifiers="const">
<return type="float">
</return>
<description>
@@ -14010,6 +14182,60 @@
<description>
</description>
</method>
+ <method name="get_fog_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_depth_begin" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_depth_curve" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_height_curve" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_height_max" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_height_min" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_sun_amount" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_sun_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_fog_transmit_curve" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_glow_blend_mode" qualifiers="const">
<return type="int">
</return>
@@ -14046,13 +14272,13 @@
<description>
</description>
</method>
- <method name="get_skybox" qualifiers="const">
+ <method name="get_sky" qualifiers="const">
<return type="CubeMap">
</return>
<description>
</description>
</method>
- <method name="get_skybox_scale" qualifiers="const">
+ <method name="get_sky_scale" qualifiers="const">
<return type="float">
</return>
<description>
@@ -14100,19 +14326,19 @@
<description>
</description>
</method>
- <method name="get_ssr_accel" qualifiers="const">
+ <method name="get_ssr_depth_tolerance" qualifiers="const">
<return type="float">
</return>
<description>
</description>
</method>
- <method name="get_ssr_depth_tolerance" qualifiers="const">
+ <method name="get_ssr_fade_in" qualifiers="const">
<return type="float">
</return>
<description>
</description>
</method>
- <method name="get_ssr_fade" qualifiers="const">
+ <method name="get_ssr_fade_out" qualifiers="const">
<return type="float">
</return>
<description>
@@ -14190,6 +14416,30 @@
<description>
</description>
</method>
+ <method name="is_fog_depth_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_fog_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_fog_height_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_fog_transmit_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_glow_bicubic_upscale_enabled" qualifiers="const">
<return type="bool">
</return>
@@ -14234,12 +14484,6 @@
<description>
</description>
</method>
- <method name="is_ssr_smooth" qualifiers="const">
- <return type="bool">
- </return>
- <description>
- </description>
- </method>
<method name="set_adjustment_brightness">
<argument index="0" name="brightness" type="float">
</argument>
@@ -14282,7 +14526,7 @@
<description>
</description>
</method>
- <method name="set_ambient_light_skybox_contribution">
+ <method name="set_ambient_light_sky_contribution">
<argument index="0" name="energy" type="float">
</argument>
<description>
@@ -14372,6 +14616,84 @@
<description>
</description>
</method>
+ <method name="set_fog_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_depth_begin">
+ <argument index="0" name="distance" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_depth_curve">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_depth_enabled">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_enabled">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_height_curve">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_height_enabled">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_height_max">
+ <argument index="0" name="height" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_height_min">
+ <argument index="0" name="height" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_sun_amount">
+ <argument index="0" name="amount" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_sun_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_transmit_curve">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_fog_transmit_enabled">
+ <argument index="0" name="enabled" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_glow_bicubic_upscale">
<argument index="0" name="enabled" type="bool">
</argument>
@@ -14428,13 +14750,13 @@
<description>
</description>
</method>
- <method name="set_skybox">
- <argument index="0" name="skybox" type="CubeMap">
+ <method name="set_sky">
+ <argument index="0" name="sky" type="CubeMap">
</argument>
<description>
</description>
</method>
- <method name="set_skybox_scale">
+ <method name="set_sky_scale">
<argument index="0" name="scale" type="float">
</argument>
<description>
@@ -14494,12 +14816,6 @@
<description>
</description>
</method>
- <method name="set_ssr_accel">
- <argument index="0" name="accel" type="float">
- </argument>
- <description>
- </description>
- </method>
<method name="set_ssr_depth_tolerance">
<argument index="0" name="depth_tolerance" type="float">
</argument>
@@ -14512,26 +14828,26 @@
<description>
</description>
</method>
- <method name="set_ssr_fade">
- <argument index="0" name="fade" type="float">
+ <method name="set_ssr_fade_in">
+ <argument index="0" name="fade_in" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_ssr_max_steps">
- <argument index="0" name="max_steps" type="int">
+ <method name="set_ssr_fade_out">
+ <argument index="0" name="fade_out" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_ssr_rough">
- <argument index="0" name="rough" type="bool">
+ <method name="set_ssr_max_steps">
+ <argument index="0" name="max_steps" type="int">
</argument>
<description>
</description>
</method>
- <method name="set_ssr_smooth">
- <argument index="0" name="smooth" type="bool">
+ <method name="set_ssr_rough">
+ <argument index="0" name="rough" type="bool">
</argument>
<description>
</description>
@@ -14600,17 +14916,17 @@
</member>
<member name="ambient_light_energy" type="float" setter="set_ambient_light_energy" getter="get_ambient_light_energy" brief="">
</member>
- <member name="ambient_light_skybox_contribution" type="float" setter="set_ambient_light_skybox_contribution" getter="get_ambient_light_skybox_contribution" brief="">
+ <member name="ambient_light_sky_contribution" type="float" setter="set_ambient_light_sky_contribution" getter="get_ambient_light_sky_contribution" brief="">
</member>
- <member name="auto_expoure_enabled" type="bool" setter="set_tonemap_auto_exposure" getter="get_tonemap_auto_exposure" brief="">
+ <member name="auto_exposure_enabled" type="bool" setter="set_tonemap_auto_exposure" getter="get_tonemap_auto_exposure" brief="">
</member>
- <member name="auto_expoure_max_luma" type="float" setter="set_tonemap_auto_exposure_max" getter="get_tonemap_auto_exposure_max" brief="">
+ <member name="auto_exposure_max_luma" type="float" setter="set_tonemap_auto_exposure_max" getter="get_tonemap_auto_exposure_max" brief="">
</member>
- <member name="auto_expoure_min_luma" type="float" setter="set_tonemap_auto_exposure_min" getter="get_tonemap_auto_exposure_min" brief="">
+ <member name="auto_exposure_min_luma" type="float" setter="set_tonemap_auto_exposure_min" getter="get_tonemap_auto_exposure_min" brief="">
</member>
- <member name="auto_expoure_scale" type="float" setter="set_tonemap_auto_exposure_grey" getter="get_tonemap_auto_exposure_grey" brief="">
+ <member name="auto_exposure_scale" type="float" setter="set_tonemap_auto_exposure_grey" getter="get_tonemap_auto_exposure_grey" brief="">
</member>
- <member name="auto_expoure_speed" type="float" setter="set_tonemap_auto_exposure_speed" getter="get_tonemap_auto_exposure_speed" brief="">
+ <member name="auto_exposure_speed" type="float" setter="set_tonemap_auto_exposure_speed" getter="get_tonemap_auto_exposure_speed" brief="">
</member>
<member name="background_canvas_max_layer" type="int" setter="set_canvas_max_layer" getter="get_canvas_max_layer" brief="">
</member>
@@ -14620,9 +14936,9 @@
</member>
<member name="background_mode" type="int" setter="set_background" getter="get_background" brief="">
</member>
- <member name="background_skybox" type="SkyBox" setter="set_skybox" getter="get_skybox" brief="">
+ <member name="background_sky" type="Sky" setter="set_sky" getter="get_sky" brief="">
</member>
- <member name="background_skybox_scale" type="float" setter="set_skybox_scale" getter="get_skybox_scale" brief="">
+ <member name="background_sky_scale" type="float" setter="set_sky_scale" getter="get_sky_scale" brief="">
</member>
<member name="dof_blur_far_amount" type="float" setter="set_dof_blur_far_amount" getter="get_dof_blur_far_amount" brief="">
</member>
@@ -14644,6 +14960,32 @@
</member>
<member name="dof_blur_near_transition" type="float" setter="set_dof_blur_near_transition" getter="get_dof_blur_near_transition" brief="">
</member>
+ <member name="fog_color" type="Color" setter="set_fog_color" getter="get_fog_color" brief="">
+ </member>
+ <member name="fog_depth_begin" type="float" setter="set_fog_depth_begin" getter="get_fog_depth_begin" brief="">
+ </member>
+ <member name="fog_depth_curve" type="float" setter="set_fog_depth_curve" getter="get_fog_depth_curve" brief="">
+ </member>
+ <member name="fog_depth_enabled" type="bool" setter="set_fog_depth_enabled" getter="is_fog_depth_enabled" brief="">
+ </member>
+ <member name="fog_enabled" type="bool" setter="set_fog_enabled" getter="is_fog_enabled" brief="">
+ </member>
+ <member name="fog_height_curve" type="float" setter="set_fog_height_curve" getter="get_fog_height_curve" brief="">
+ </member>
+ <member name="fog_height_enabled" type="bool" setter="set_fog_height_enabled" getter="is_fog_height_enabled" brief="">
+ </member>
+ <member name="fog_height_max" type="float" setter="set_fog_height_max" getter="get_fog_height_max" brief="">
+ </member>
+ <member name="fog_height_min" type="float" setter="set_fog_height_min" getter="get_fog_height_min" brief="">
+ </member>
+ <member name="fog_sun_amount" type="float" setter="set_fog_sun_amount" getter="get_fog_sun_amount" brief="">
+ </member>
+ <member name="fog_sun_color" type="Color" setter="set_fog_sun_color" getter="get_fog_sun_color" brief="">
+ </member>
+ <member name="fog_transmit_curve" type="float" setter="set_fog_transmit_curve" getter="get_fog_transmit_curve" brief="">
+ </member>
+ <member name="fog_transmit_enabled" type="bool" setter="set_fog_transmit_enabled" getter="is_fog_transmit_enabled" brief="">
+ </member>
<member name="glow_bicubic_upscale" type="bool" setter="set_glow_bicubic_upscale" getter="is_glow_bicubic_upscale_enabled" brief="">
</member>
<member name="glow_blend_mode" type="int" setter="set_glow_blend_mode" getter="get_glow_blend_mode" brief="">
@@ -14674,15 +15016,13 @@
</member>
<member name="glow_strength" type="float" setter="set_glow_strength" getter="get_glow_strength" brief="">
</member>
- <member name="ss_reflections_accel" type="float" setter="set_ssr_accel" getter="get_ssr_accel" brief="">
- </member>
- <member name="ss_reflections_accel_smooth" type="bool" setter="set_ssr_smooth" getter="is_ssr_smooth" brief="">
- </member>
<member name="ss_reflections_depth_tolerance" type="float" setter="set_ssr_depth_tolerance" getter="get_ssr_depth_tolerance" brief="">
</member>
<member name="ss_reflections_enabled" type="bool" setter="set_ssr_enabled" getter="is_ssr_enabled" brief="">
</member>
- <member name="ss_reflections_fade" type="float" setter="set_ssr_fade" getter="get_ssr_fade" brief="">
+ <member name="ss_reflections_fade_in" type="float" setter="set_ssr_fade_in" getter="get_ssr_fade_in" brief="">
+ </member>
+ <member name="ss_reflections_fade_out" type="float" setter="set_ssr_fade_out" getter="get_ssr_fade_out" brief="">
</member>
<member name="ss_reflections_max_steps" type="int" setter="set_ssr_max_steps" getter="get_ssr_max_steps" brief="">
</member>
@@ -14720,7 +15060,7 @@
</constant>
<constant name="BG_COLOR" value="1">
</constant>
- <constant name="BG_SKYBOX" value="2">
+ <constant name="BG_SKY" value="2">
</constant>
<constant name="BG_CANVAS" value="3">
</constant>
@@ -14913,7 +15253,7 @@
Get a [String] saved in Pascal format from the file.
</description>
</method>
- <method name="get_position" qualifiers="const">
+ <method name="get_pos" qualifiers="const">
<return type="int">
</return>
<description>
@@ -14959,6 +15299,19 @@
Open the file for writing or reading, depending on the flags.
</description>
</method>
+ <method name="open_compressed">
+ <return type="int">
+ </return>
+ <argument index="0" name="path" type="String">
+ </argument>
+ <argument index="1" name="mode_flags" type="int">
+ </argument>
+ <argument index="2" name="compression_mode" type="int" default="0">
+ </argument>
+ <description>
+ Open a compressed file for reading or writing. The compression_mode can be set as one of the COMPRESSION_* constants.
+ </description>
+ </method>
<method name="open_encrypted">
<return type="int">
</return>
@@ -15105,6 +15458,15 @@
<constant name="WRITE_READ" value="7">
Open the file for reading and writing. Create it if the file not exists and truncate if it exists.
</constant>
+ <constant name="COMPRESSION_FASTLZ" value="0">
+ Use the FastLZ compression method.
+ </constant>
+ <constant name="COMPRESSION_DEFLATE" value="1">
+ Use the Deflate compression method.
+ </constant>
+ <constant name="COMPRESSION_ZSTD" value="2">
+ Use the Zstd compression method.
+ </constant>
</constants>
</class>
<class name="FileDialog" inherits="ConfirmationDialog" category="Core">
@@ -15433,8 +15795,11 @@
<method name="is_valid" qualifiers="const">
<return type="bool">
</return>
+ <argument index="0" name="extended_check" type="bool" default="false">
+ </argument>
<description>
Check whether the function call may be resumed. This is not the case if the function state was already resumed.
+ If [code]extended_check[/code] is enabled, it also checks if the associated script and object still exist. The extended check is done in debug mode as part of [method GDFunctionState.resume], but you can use this if you know you may be trying to resume without knowing for sure the object and/or script have survived up to that point.
</description>
</method>
<method name="resume">
@@ -15466,6 +15831,78 @@
<constants>
</constants>
</class>
+<class name="GDNativeLibrary" inherits="Resource" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_platform_file" qualifiers="const">
+ <return type="String">
+ </return>
+ <argument index="0" name="platform" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_platform_file">
+ <argument index="0" name="platform" type="String">
+ </argument>
+ <argument index="1" name="file" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <constants>
+ </constants>
+</class>
+<class name="GDNativeScript" inherits="Script" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_library" qualifiers="const">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_script_name" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="new" qualifiers="vararg">
+ <return type="Object">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_library">
+ <argument index="0" name="library" type="Object">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_script_name">
+ <argument index="0" name="script_name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="library" type="GDNativeLibrary" setter="set_library" getter="get_library" brief="">
+ </member>
+ <member name="script_name" type="String" setter="set_script_name" getter="get_script_name" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="GDScript" inherits="Script" category="Core">
<brief_description>
</brief_description>
@@ -16594,6 +17031,120 @@
<constants>
</constants>
</class>
+<class name="Gradient" inherits="Resource" category="Core">
+ <brief_description>
+ Color interpolator node
+ </brief_description>
+ <description>
+ Given a set of colors, this node will interpolate them in order, meaning, that if you have color 1, color 2 and color3, the ramp will interpolate (generate the colors between two colors) from color 1 to color 2 and from color 2 to color 3. Initially the ramp will have 2 colors (black and white), one (black) at ramp lower offset offset 0 and the other (white) at the ramp higher offset 1.
+ </description>
+ <methods>
+ <method name="add_point">
+ <argument index="0" name="offset" type="float">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <description>
+ Adds the specified color to the end of the ramp, with the specified offset
+ </description>
+ </method>
+ <method name="get_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <argument index="0" name="point" type="int">
+ </argument>
+ <description>
+ Returns the color of the ramp color at index [i]point[/i]
+ </description>
+ </method>
+ <method name="get_colors" qualifiers="const">
+ <return type="PoolColorArray">
+ </return>
+ <description>
+ Returns the colors in the ramp
+ </description>
+ </method>
+ <method name="get_offset" qualifiers="const">
+ <return type="float">
+ </return>
+ <argument index="0" name="point" type="int">
+ </argument>
+ <description>
+ Returns the offset of the ramp color at index [i]point[/i]
+ </description>
+ </method>
+ <method name="get_offsets" qualifiers="const">
+ <return type="PoolRealArray">
+ </return>
+ <description>
+ Returns the offsets for the colors in this ramp
+ </description>
+ </method>
+ <method name="get_point_count" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the number of colors in the ramp
+ </description>
+ </method>
+ <method name="interpolate">
+ <return type="Color">
+ </return>
+ <argument index="0" name="offset" type="float">
+ </argument>
+ <description>
+ Returns the interpolated color specified by [i]offset[/i]
+ </description>
+ </method>
+ <method name="remove_point">
+ <argument index="0" name="offset" type="int">
+ </argument>
+ <description>
+ Removes the color at the index [i]offset[/i]
+ </description>
+ </method>
+ <method name="set_color">
+ <argument index="0" name="point" type="int">
+ </argument>
+ <argument index="1" name="color" type="Color">
+ </argument>
+ <description>
+ Sets the color of the ramp color at index [i]point[/i]
+ </description>
+ </method>
+ <method name="set_colors">
+ <argument index="0" name="colors" type="PoolColorArray">
+ </argument>
+ <description>
+ Sets the colors for the specified amount of elements. Calling this function with a different number of elements than previously defined causes the ramp to resize its colors and offsets array to accommodate the new elements.
+ </description>
+ </method>
+ <method name="set_offset">
+ <argument index="0" name="point" type="int">
+ </argument>
+ <argument index="1" name="offset" type="float">
+ </argument>
+ <description>
+ Sets the offset for the ramp color at index [i]point[/i]
+ </description>
+ </method>
+ <method name="set_offsets">
+ <argument index="0" name="offsets" type="PoolRealArray">
+ </argument>
+ <description>
+ Sets the offset for the specified amount of elements. Calling this function with a different number of elements than previously defined causes the ramp to resize its colors and offsets array to accommodate the new elements, all new colors will be black by default.
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="colors" type="float" setter="set_colors" getter="get_colors" brief="">
+ </member>
+ <member name="offsets" type="float" setter="set_offsets" getter="get_offsets" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="GradientTexture" inherits="Texture" category="Core">
<brief_description>
</brief_description>
@@ -17615,40 +18166,6 @@
</theme_item>
</theme_items>
</class>
-<class name="HButtonArray" inherits="ButtonArray" category="Core">
- <brief_description>
- Horizontal button array.
- </brief_description>
- <description>
- Horizontal button array. See [ButtonArray].
- </description>
- <methods>
- </methods>
- <constants>
- </constants>
- <theme_items>
- <theme_item name="button_separator" type="int">
- </theme_item>
- <theme_item name="focus" type="StyleBox">
- </theme_item>
- <theme_item name="font" type="Font">
- </theme_item>
- <theme_item name="font_color" type="Color">
- </theme_item>
- <theme_item name="font_color_selected" type="Color">
- </theme_item>
- <theme_item name="font_selected" type="Font">
- </theme_item>
- <theme_item name="hover" type="StyleBox">
- </theme_item>
- <theme_item name="icon_separator" type="int">
- </theme_item>
- <theme_item name="normal" type="StyleBox">
- </theme_item>
- <theme_item name="selected" type="StyleBox">
- </theme_item>
- </theme_items>
-</class>
<class name="HScrollBar" inherits="ScrollBar" category="Core">
<brief_description>
Horizontal scroll bar.
@@ -17663,15 +18180,15 @@
<theme_items>
<theme_item name="decrement" type="Texture">
</theme_item>
- <theme_item name="decrement_hilite" type="Texture">
+ <theme_item name="decrement_highlight" type="Texture">
</theme_item>
<theme_item name="grabber" type="StyleBox">
</theme_item>
- <theme_item name="grabber_hilite" type="StyleBox">
+ <theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
- <theme_item name="increment_hilite" type="Texture">
+ <theme_item name="increment_highlight" type="Texture">
</theme_item>
<theme_item name="scroll" type="StyleBox">
</theme_item>
@@ -17713,9 +18230,9 @@
</theme_item>
<theme_item name="grabber" type="Texture">
</theme_item>
- <theme_item name="grabber_hilite" type="Texture">
+ <theme_item name="grabber_highlight" type="Texture">
</theme_item>
- <theme_item name="grabber_hilite" type="StyleBox">
+ <theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
<theme_item name="slider" type="StyleBox">
</theme_item>
@@ -18446,27 +18963,36 @@
<constants>
</constants>
</class>
-<class name="Image" category="Built-In Types">
+<class name="Image" inherits="Resource" category="Core">
<brief_description>
Image datatype.
</brief_description>
<description>
- Built in native image datatype. Contains image data, which can be converted to a texture, and several functions to interact with it.
+ Native image datatype. Contains image data, which can be converted to a texture, and several functions to interact with it.
</description>
<methods>
- <method name="Image">
- <return type="Image">
- </return>
- <argument index="0" name="width" type="int">
+ <method name="blend_rect">
+ <argument index="0" name="src" type="Image">
</argument>
- <argument index="1" name="height" type="int">
+ <argument index="1" name="src_rect" type="Rect2">
</argument>
- <argument index="2" name="mipmaps" type="bool">
+ <argument index="2" name="dst" type="Vector2">
</argument>
- <argument index="3" name="format" type="int">
+ <description>
+ Alpha-blends a "src_rect" [Rect2] from "src" [Image] to this [Image] on coordinates "dest".
+ </description>
+ </method>
+ <method name="blend_rect_mask">
+ <argument index="0" name="src" type="Image">
+ </argument>
+ <argument index="1" name="mask" type="Image">
+ </argument>
+ <argument index="2" name="src_rect" type="Rect2">
+ </argument>
+ <argument index="3" name="dst" type="Vector2">
</argument>
<description>
- Create an empty image of a specific size and format.
+ Alpha-blends a "src_rect" [Rect2] from "src" [Image] to this [Image] using a "mask" [Image] on coordinates "dest". Alpha channels are required for both "src" and "mask", dest pixels and src pixels will blend if the corresponding mask pixel's alpha value is not 0. "src" [Image] and "mask" [Image] *must* have the same size (width and height) but they can have different formats
</description>
</method>
<method name="blit_rect">
@@ -18474,137 +19000,276 @@
</argument>
<argument index="1" name="src_rect" type="Rect2">
</argument>
- <argument index="2" name="dest" type="Vector2" default="0">
+ <argument index="2" name="dst" type="Vector2">
</argument>
<description>
Copy a "src_rect" [Rect2] from "src" [Image] to this [Image] on coordinates "dest".
</description>
</method>
- <method name="compressed">
- <return type="Image">
+ <method name="clear_mipmaps">
+ <description>
+ </description>
+ </method>
+ <method name="compress">
+ <return type="int">
</return>
- <argument index="0" name="format" type="int" default="0">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <argument index="1" name="arg1" type="int">
+ </argument>
+ <argument index="2" name="arg2" type="float">
</argument>
<description>
- Return a new compressed [Image] from this [Image] using one of [Image].COMPRESS_*.
</description>
</method>
- <method name="converted">
- <return type="Image">
- </return>
- <argument index="0" name="format" type="int" default="0">
+ <method name="convert">
+ <argument index="0" name="format" type="int">
</argument>
<description>
- Return a new [Image] from this [Image] with a different format.
</description>
</method>
- <method name="decompressed">
- <return type="Image">
+ <method name="copy_from">
+ <argument index="0" name="src" type="Image">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="create">
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
+ <argument index="2" name="use_mipmaps" type="bool">
+ </argument>
+ <argument index="3" name="format" type="int">
+ </argument>
+ <description>
+ Create an empty image of a specific size and format.
+ </description>
+ </method>
+ <method name="create_from_data">
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
+ <argument index="2" name="use_mipmaps" type="bool">
+ </argument>
+ <argument index="3" name="format" type="int">
+ </argument>
+ <argument index="4" name="data" type="PoolByteArray">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="crop">
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="decompress">
+ <return type="int">
</return>
<description>
- Return a new decompressed [Image].
</description>
</method>
- <method name="empty">
- <return type="bool">
+ <method name="detect_alpha" qualifiers="const">
+ <return type="int">
</return>
<description>
- Return whether this [Image] is empty(no data).
+ </description>
+ </method>
+ <method name="expand_x2_hq2x">
+ <description>
+ </description>
+ </method>
+ <method name="fill">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ Fills an [Image] with a specified [Color]
</description>
</method>
<method name="fix_alpha_edges">
<description>
</description>
</method>
- <method name="get_data">
+ <method name="flip_x">
+ <description>
+ </description>
+ </method>
+ <method name="flip_y">
+ <description>
+ </description>
+ </method>
+ <method name="generate_mipmaps">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_data" qualifiers="const">
<return type="PoolByteArray">
</return>
<description>
Return the raw data of the [Image].
</description>
</method>
- <method name="get_format">
+ <method name="get_format" qualifiers="const">
<return type="int">
</return>
<description>
Return the format of the [Image], one of [Image].FORMAT_*.
</description>
</method>
- <method name="get_height">
+ <method name="get_height" qualifiers="const">
<return type="int">
</return>
<description>
Return the height of the [Image].
</description>
</method>
- <method name="get_rect">
+ <method name="get_mipmap_offset" qualifiers="const">
+ <return type="int">
+ </return>
+ <argument index="0" name="mipmap" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_pixel" qualifiers="const">
+ <return type="Color">
+ </return>
+ <argument index="0" name="x" type="int">
+ </argument>
+ <argument index="1" name="y" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_rect" qualifiers="const">
<return type="Image">
</return>
- <argument index="0" name="area" type="Rect2" default="0">
+ <argument index="0" name="rect" type="Rect2">
</argument>
<description>
Return a new [Image] that is a copy of "area" in this [Image].
</description>
</method>
- <method name="get_used_rect">
+ <method name="get_used_rect" qualifiers="const">
<return type="Rect2">
</return>
<description>
Return the area of this [Image] that is used/visibly colored/opaque.
</description>
</method>
- <method name="get_width">
+ <method name="get_width" qualifiers="const">
<return type="int">
</return>
<description>
Return the width of the [Image].
</description>
</method>
+ <method name="has_mipmaps" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_compressed" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_empty" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_invisible" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="load">
<return type="int">
</return>
- <argument index="0" name="path" type="String" default="0">
+ <argument index="0" name="path" type="String">
</argument>
<description>
Load an [Image].
</description>
</method>
- <method name="resized">
- <return type="Image">
- </return>
+ <method name="lock">
+ <description>
+ </description>
+ </method>
+ <method name="normalmap_to_xy">
+ <description>
+ </description>
+ </method>
+ <method name="premultiply_alpha">
+ <description>
+ </description>
+ </method>
+ <method name="put_pixel">
<argument index="0" name="x" type="int">
</argument>
<argument index="1" name="y" type="int">
</argument>
+ <argument index="2" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="resize">
+ <argument index="0" name="width" type="int">
+ </argument>
+ <argument index="1" name="height" type="int">
+ </argument>
<argument index="2" name="interpolation" type="int" default="1">
</argument>
<description>
- Return a new [Image] from this [Image] that is resized to size "x,y" using [Image].INTERPOLATE_*.
</description>
</method>
- <method name="save_png">
+ <method name="resize_to_po2">
+ <argument index="0" name="square" type="bool" default="&quot;false&quot;">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="save_png" qualifiers="const">
<return type="int">
</return>
- <argument index="0" name="path" type="String" default="0">
+ <argument index="0" name="path" type="String">
</argument>
<description>
Save this [Image] as a png.
</description>
</method>
+ <method name="shrink_x2">
+ <description>
+ </description>
+ </method>
+ <method name="srgb_to_linear">
+ <description>
+ </description>
+ </method>
+ <method name="unlock">
+ <description>
+ </description>
+ </method>
</methods>
+ <members>
+ <member name="data" type="Dictionary" setter="_set_data" getter="_get_data" brief="">
+ </member>
+ </members>
<constants>
- <constant name="COMPRESS_16BIT" value="0">
- </constant>
- <constant name="COMPRESS_S3TC" value="1">
- </constant>
- <constant name="COMPRESS_PVRTC2" value="2">
- </constant>
- <constant name="COMPRESS_PVRTC4" value="3">
- </constant>
- <constant name="COMPRESS_ETC" value="4">
- </constant>
- <constant name="COMPRESS_ETC2" value="5">
- </constant>
<constant name="FORMAT_L8" value="0">
</constant>
<constant name="FORMAT_LA8" value="1">
@@ -18617,27 +19282,27 @@
</constant>
<constant name="FORMAT_RGBA8" value="5">
</constant>
- <constant name="FORMAT_RGB565" value="6">
+ <constant name="FORMAT_RGBA4444" value="6">
</constant>
- <constant name="FORMAT_RGBA4444" value="7">
+ <constant name="FORMAT_RGBA5551" value="7">
</constant>
- <constant name="FORMAT_RGBA5551" value="17">
+ <constant name="FORMAT_RF" value="8">
</constant>
- <constant name="FORMAT_RF" value="9">
+ <constant name="FORMAT_RGF" value="9">
</constant>
- <constant name="FORMAT_RGF" value="10">
+ <constant name="FORMAT_RGBF" value="10">
</constant>
- <constant name="FORMAT_RGBF" value="11">
+ <constant name="FORMAT_RGBAF" value="11">
</constant>
- <constant name="FORMAT_RGBAF" value="12">
+ <constant name="FORMAT_RH" value="12">
</constant>
- <constant name="FORMAT_RH" value="13">
+ <constant name="FORMAT_RGH" value="13">
</constant>
- <constant name="FORMAT_RGH" value="14">
+ <constant name="FORMAT_RGBH" value="14">
</constant>
- <constant name="FORMAT_RGBH" value="15">
+ <constant name="FORMAT_RGBAH" value="15">
</constant>
- <constant name="FORMAT_RGBAH" value="16">
+ <constant name="FORMAT_RGBE9995" value="16">
</constant>
<constant name="FORMAT_DXT1" value="17">
</constant>
@@ -18645,9 +19310,9 @@
</constant>
<constant name="FORMAT_DXT5" value="19">
</constant>
- <constant name="FORMAT_ATI1" value="20">
+ <constant name="FORMAT_RGTC_R" value="20">
</constant>
- <constant name="FORMAT_ATI2" value="21">
+ <constant name="FORMAT_RGTC_RG" value="21">
</constant>
<constant name="FORMAT_BPTC_RGBA" value="22">
</constant>
@@ -18687,59 +19352,27 @@
</constant>
<constant name="INTERPOLATE_CUBIC" value="2">
</constant>
- </constants>
-</class>
-<class name="ImageSkyBox" inherits="SkyBox" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- <method name="get_image_path" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="image" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_image_path">
- <argument index="0" name="image" type="int">
- </argument>
- <argument index="1" name="path" type="String">
- </argument>
- <description>
- </description>
- </method>
- </methods>
- <members>
- <member name="image_path_negative_x" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- <member name="image_path_negative_y" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- <member name="image_path_negative_z" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- <member name="image_path_positive_x" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- <member name="image_path_positive_y" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- <member name="image_path_positive_z" type="String" setter="set_image_path" getter="get_image_path" brief="">
- </member>
- </members>
- <constants>
- <constant name="IMAGE_PATH_NEGATIVE_X" value="0">
+ <constant name="ALPHA_NONE" value="0">
+ </constant>
+ <constant name="ALPHA_BIT" value="1">
+ </constant>
+ <constant name="ALPHA_BLEND" value="2">
</constant>
- <constant name="IMAGE_PATH_POSITIVE_X" value="1">
+ <constant name="COMPRESS_S3TC" value="0">
</constant>
- <constant name="IMAGE_PATH_NEGATIVE_Y" value="2">
+ <constant name="COMPRESS_PVRTC2" value="1">
</constant>
- <constant name="IMAGE_PATH_POSITIVE_Y" value="3">
+ <constant name="COMPRESS_PVRTC4" value="2">
</constant>
- <constant name="IMAGE_PATH_NEGATIVE_Z" value="4">
+ <constant name="COMPRESS_ETC" value="3">
</constant>
- <constant name="IMAGE_PATH_POSITIVE_Z" value="5">
+ <constant name="COMPRESS_ETC2" value="4">
</constant>
- <constant name="IMAGE_PATH_MAX" value="6">
+ <constant name="COMPRESS_SOURCE_GENERIC" value="0">
+ </constant>
+ <constant name="COMPRESS_SOURCE_SRGB" value="1">
+ </constant>
+ <constant name="COMPRESS_SOURCE_NORMAL" value="2">
</constant>
</constants>
</class>
@@ -18775,10 +19408,6 @@
Create a new [ImageTexture] from an [Image] with "flags" from [Texture].FLAG_*.
</description>
</method>
- <method name="fix_alpha_edges">
- <description>
- </description>
- </method>
<method name="get_data" qualifiers="const">
<return type="Image">
</return>
@@ -18814,14 +19443,6 @@
Load an [ImageTexure].
</description>
</method>
- <method name="normal_to_xy">
- <description>
- </description>
- </method>
- <method name="premultiply_alpha">
- <description>
- </description>
- </method>
<method name="set_data">
<argument index="0" name="image" type="Image">
</argument>
@@ -18849,10 +19470,6 @@
Set the storage type. One of [ImageTexture].STORAGE_*.
</description>
</method>
- <method name="shrink_x2_and_keep_size">
- <description>
- </description>
- </method>
</methods>
<constants>
<constant name="STORAGE_RAW" value="0">
@@ -19181,7 +19798,7 @@
</description>
</method>
<method name="parse_input_event">
- <argument index="0" name="event" type="InputEvent">
+ <argument index="0" name="event" type="Object">
</argument>
<description>
</description>
@@ -19275,15 +19892,39 @@
<constants>
</constants>
</class>
-<class name="InputEvent" category="Built-In Types">
+<class name="InputEvent" inherits="Resource" category="Core">
<brief_description>
- Built-in input event data.
</brief_description>
<description>
- Built-in input event data. InputEvent is a built-in engine datatype, given that it's passed around and used so much. Depending on its type, the members contained can be different, so read the documentation well! Input events can also represent actions (editable from the project settings).
</description>
<methods>
- <method name="is_action">
+ <method name="action_match" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="event" type="InputEvent">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="as_text" qualifiers="const">
+ <return type="String">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_device" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_id" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_action" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="action" type="String">
@@ -19292,7 +19933,7 @@
Return if this input event matches a pre-defined action, no matter the type.
</description>
</method>
- <method name="is_action_pressed">
+ <method name="is_action_pressed" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="action" type="String">
@@ -19301,7 +19942,7 @@
Return whether the given action is being pressed (and is not an echo event for KEY events). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE.
</description>
</method>
- <method name="is_action_released">
+ <method name="is_action_released" qualifiers="const">
<return type="bool">
</return>
<argument index="0" name="action" type="String">
@@ -19310,1045 +19951,627 @@
Return whether the given action is released (i.e. not pressed). Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE.
</description>
</method>
- <method name="is_echo">
+ <method name="is_action_type" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_echo" qualifiers="const">
<return type="bool">
</return>
<description>
Return if this input event is an echo event (only for events of type KEY, it will return false for other types).
</description>
</method>
- <method name="is_pressed">
+ <method name="is_pressed" qualifiers="const">
<return type="bool">
</return>
<description>
Return if this input event is pressed. Not relevant for the event types MOUSE_MOTION, SCREEN_DRAG and NONE.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
+ <method name="set_device">
+ <argument index="0" name="device" type="int">
</argument>
- <argument index="1" name="pressed" type="bool">
+ <description>
+ </description>
+ </method>
+ <method name="set_id">
+ <argument index="0" name="id" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="xformed_by" qualifiers="const">
+ <return type="InputEvent">
+ </return>
+ <argument index="0" name="xform" type="Transform2D">
+ </argument>
+ <argument index="1" name="local_ofs" type="Vector2" default="Vector2(0, 0)">
</argument>
<description>
- Change the input event to an action event of the given name, regardless of its initial type, with the pressed status passed as argument.
</description>
</method>
</methods>
- <members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
- </members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventAction" category="Built-In Types">
+<class name="InputEventAction" inherits="InputEvent" category="Core">
<brief_description>
- Built-in input event type for actions.
+ Input event type for actions.
</brief_description>
<description>
- Input event type for actions that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
- </return>
- <argument index="0" name="action" type="String">
- </argument>
- <description>
- Return if this input event matches a pre-defined action, i.e. always true for InputEventAction.
- </description>
- </method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_action" qualifiers="const">
+ <return type="String">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
- </return>
+ <method name="set_action">
<argument index="0" name="action" type="String">
</argument>
<description>
- Return whether the given action is released (i.e. not pressed).
</description>
</method>
- <method name="is_echo">
- <return type="bool">
- </return>
- <description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
- </description>
- </method>
- <method name="is_pressed">
- <return type="bool">
- </return>
- <description>
- Return if this input event is pressed.
- </description>
- </method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
- </argument>
- <argument index="1" name="pressed" type="bool">
+ <method name="set_pressed">
+ <argument index="0" name="pressed" type="bool">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
+ <member name="action" type="String" setter="set_action" getter="get_action" brief="">
</member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
</member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventJoypadButton" category="Built-In Types">
+<class name="InputEventJoypadButton" inherits="InputEvent" category="Core">
<brief_description>
- Built-in input event type for joypad button events.
+ Input event type for joypad button events.
</brief_description>
<description>
- Input event type for joypad button events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_button_index" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_pressure" qualifiers="const">
+ <return type="float">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
- </return>
- <argument index="0" name="action" type="String">
+ <method name="set_button_index">
+ <argument index="0" name="button_index" type="int">
</argument>
<description>
- Return whether the given action is released (i.e. not pressed).
- </description>
- </method>
- <method name="is_echo">
- <return type="bool">
- </return>
- <description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
</description>
</method>
- <method name="is_pressed">
- <return type="bool">
- </return>
+ <method name="set_pressed">
+ <argument index="0" name="pressed" type="bool">
+ </argument>
<description>
- Return if this input event is pressed.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
- </argument>
- <argument index="1" name="pressed" type="bool">
+ <method name="set_pressure">
+ <argument index="0" name="pressure" type="float">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="button_index" type="int" setter="" getter="" brief="">
+ <member name="button_index" type="int" setter="set_button_index" getter="get_button_index" brief="">
Joypad button identifier, one of the JOY_BUTTON_* constants in [@Global Scope].
</member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="pressed" type="bool" setter="" getter="" brief="">
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
Pressed state of the joypad button.
</member>
- <member name="pressure" type="float" setter="" getter="" brief="">
+ <member name="pressure" type="float" setter="set_pressure" getter="get_pressure" brief="">
Intensity of the button pressure, ranges from 0 to 1.0.
</member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventJoypadMotion" category="Built-In Types">
+<class name="InputEventJoypadMotion" inherits="InputEvent" category="Core">
<brief_description>
- Built-in input event type for joypad motion/axis events.
+ Input event type for joypad motion/axis events.
</brief_description>
<description>
- Input event type for joypad motion/axis events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_axis" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_axis_value" qualifiers="const">
+ <return type="float">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
- </return>
- <argument index="0" name="action" type="String">
+ <method name="set_axis">
+ <argument index="0" name="axis" type="int">
</argument>
<description>
- Return whether the given action is released (i.e. not pressed).
- </description>
- </method>
- <method name="is_echo">
- <return type="bool">
- </return>
- <description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
- </description>
- </method>
- <method name="is_pressed">
- <return type="bool">
- </return>
- <description>
- Return if this input event is pressed.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
- </argument>
- <argument index="1" name="pressed" type="bool">
+ <method name="set_axis_value">
+ <argument index="0" name="axis_value" type="float">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="axis" type="int" setter="" getter="" brief="">
+ <member name="axis" type="int" setter="set_axis" getter="get_axis" brief="">
Joypad axis identifier, one of the JOY_AXIS_* constants in [@Global Scope].
</member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
- <member name="value" type="float" setter="" getter="" brief="">
+ <member name="axis_value" type="float" setter="set_axis_value" getter="get_axis_value" brief="">
Position of the axis, ranging from -1.0 to 1.0. A value of 0 means that the axis is in its neutral position.
</member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventKey" category="Built-In Types">
+<class name="InputEventKey" inherits="InputEventWithModifiers" category="Core">
<brief_description>
- Built-in input event type for keyboard events.
+ Input event type for keyboard events.
</brief_description>
<description>
- Input event type for keyboard events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_scancode" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_scancode_with_modifiers" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
+ <method name="get_unicode" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is released (i.e. not pressed).
</description>
</method>
- <method name="is_echo">
- <return type="bool">
- </return>
+ <method name="set_echo">
+ <argument index="0" name="echo" type="bool">
+ </argument>
<description>
- Return if this input event is an echo event.
</description>
</method>
- <method name="is_pressed">
- <return type="bool">
- </return>
+ <method name="set_pressed">
+ <argument index="0" name="pressed" type="bool">
+ </argument>
<description>
- Return if this input event is pressed.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
+ <method name="set_scancode">
+ <argument index="0" name="scancode" type="int">
</argument>
- <argument index="1" name="pressed" type="bool">
+ <description>
+ </description>
+ </method>
+ <method name="set_unicode">
+ <argument index="0" name="unicode" type="int">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="alt" type="bool" setter="" getter="" brief="">
- State of the Alt modifier.
- </member>
- <member name="control" type="bool" setter="" getter="" brief="">
- State of the Ctrl modifier.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="echo" type="bool" setter="" getter="" brief="">
+ <member name="echo" type="int" setter="set_echo" getter="is_echo" brief="">
Echo state of the key, i.e. whether it's a repeat event or not.
</member>
- <member name="meta" type="bool" setter="" getter="" brief="">
- State of the Meta modifier.
- </member>
- <member name="pressed" type="bool" setter="" getter="" brief="">
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
Pressed state of the key.
</member>
- <member name="scancode" type="int" setter="" getter="" brief="">
+ <member name="scancode" type="int" setter="set_scancode" getter="get_scancode" brief="">
Scancode of the key, one of the KEY_* constants in [@Global Scope].
</member>
- <member name="shift" type="bool" setter="" getter="" brief="">
- State of the Shift modifier.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
- <member name="unicode" type="int" setter="" getter="" brief="">
+ <member name="unicode" type="int" setter="set_unicode" getter="get_unicode" brief="">
Unicode identifier of the key (when relevant).
</member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventMouseButton" category="Built-In Types">
+<class name="InputEventMouse" inherits="InputEventWithModifiers" category="Core">
<brief_description>
- Built-in input event type for mouse button events.
+ Base input event type for mouse events.
</brief_description>
<description>
- Input event type for mouse button events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_button_mask" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_global_position" qualifiers="const">
+ <return type="Vector2">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
+ <method name="get_position" qualifiers="const">
+ <return type="Vector2">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is released (i.e. not pressed).
</description>
</method>
- <method name="is_echo">
- <return type="bool">
- </return>
+ <method name="set_button_mask">
+ <argument index="0" name="button_mask" type="int">
+ </argument>
<description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
</description>
</method>
- <method name="is_pressed">
- <return type="bool">
- </return>
+ <method name="set_global_position">
+ <argument index="0" name="global_position" type="Vector2">
+ </argument>
<description>
- Return if this input event is pressed.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
- </argument>
- <argument index="1" name="pressed" type="bool">
+ <method name="set_position">
+ <argument index="0" name="position" type="Vector2">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="alt" type="bool" setter="" getter="" brief="">
- State of the Alt modifier.
- </member>
- <member name="button_index" type="int" setter="" getter="" brief="">
- Mouse button identifier, one of the BUTTON_* or BUTTON_WHEEL_* constants in [@Global Scope].
- </member>
- <member name="button_mask" type="int" setter="" getter="" brief="">
+ <member name="button_mask" type="int" setter="set_button_mask" getter="get_button_mask" brief="">
Mouse button mask identifier, one of or a bitwise combination of the BUTTON_MASK_* constants in [@Global Scope].
</member>
- <member name="control" type="bool" setter="" getter="" brief="">
- State of the Control modifier.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="doubleclick" type="bool" setter="" getter="" brief="">
- Whether the event is a double-click.
- </member>
- <member name="global_pos" type="Vector2" setter="" getter="" brief="">
+ <member name="global_position" type="Vector2" setter="set_global_position" getter="get_global_position" brief="">
Global position of the mouse click.
</member>
- <member name="global_x" type="float" setter="" getter="" brief="">
- Global X coordinate of the mouse click.
- </member>
- <member name="global_y" type="float" setter="" getter="" brief="">
- Global Y coordinate of the mouse click.
- </member>
- <member name="meta" type="bool" setter="" getter="" brief="">
- State of the Meta modifier.
- </member>
- <member name="pos" type="Vector2" setter="" getter="" brief="">
+ <member name="position" type="Vector2" setter="set_position" getter="get_position" brief="">
Local position of the mouse click.
</member>
- <member name="pressed" type="bool" setter="" getter="" brief="">
- Pressed state of the mouse button.
- </member>
- <member name="shift" type="bool" setter="" getter="" brief="">
- State of the Shift modifier.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
- <member name="x" type="float" setter="" getter="" brief="">
- Local X coordinate of the mouse click.
- </member>
- <member name="y" type="float" setter="" getter="" brief="">
- Local Y coordinate of the mouse click.
- </member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventMouseMotion" category="Built-In Types">
+<class name="InputEventMouseButton" inherits="InputEventMouse" category="Core">
<brief_description>
- Built-in input event type for mouse motion events.
+ Input event type for mouse button events.
</brief_description>
<description>
- Input event type for mouse motion events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_button_index" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_factor">
+ <return type="float">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed. Not relevant for MOUSE_MOTION events, always false.
</description>
</method>
- <method name="is_action_released">
+ <method name="is_doubleclick" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is released (i.e. not pressed). Not relevant for MOUSE_MOTION events, can be true or false depending on whether [method is_action] is true.
</description>
</method>
- <method name="is_echo">
- <return type="bool">
- </return>
+ <method name="set_button_index">
+ <argument index="0" name="button_index" type="int">
+ </argument>
<description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
</description>
</method>
- <method name="is_pressed">
- <return type="bool">
- </return>
+ <method name="set_doubleclick">
+ <argument index="0" name="doubleclick" type="bool">
+ </argument>
<description>
- Return if this input event is pressed. Not relevant for MOUSE_MOTION events, always false.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
+ <method name="set_factor">
+ <argument index="0" name="factor" type="float">
</argument>
- <argument index="1" name="pressed" type="bool">
+ <description>
+ </description>
+ </method>
+ <method name="set_pressed">
+ <argument index="0" name="pressed" type="bool">
</argument>
<description>
- Change the input event to an action event of the given name with the (irrelevant for this type) pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="alt" type="bool" setter="" getter="" brief="">
- State of the Alt modifier.
- </member>
- <member name="button_mask" type="int" setter="" getter="" brief="">
- Mouse button mask identifier, one of or a bitwise combination of the BUTTON_MASK_* constants in [@Global Scope].
- </member>
- <member name="control" type="bool" setter="" getter="" brief="">
- State of the Ctrl modifier.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="global_pos" type="Vector2" setter="" getter="" brief="">
- Global position of the mouse pointer.
+ <member name="button_index" type="int" setter="set_button_index" getter="get_button_index" brief="">
+ Mouse button identifier, one of the BUTTON_* or BUTTON_WHEEL_* constants in [@Global Scope].
</member>
- <member name="global_x" type="float" setter="" getter="" brief="">
- Global X coordinate of the mouse pointer.
+ <member name="doubleclick" type="bool" setter="set_doubleclick" getter="is_doubleclick" brief="">
+ Whether the event is a double-click.
</member>
- <member name="global_y" type="float" setter="" getter="" brief="">
- Global Y coordinate of the mouse pointer.
+ <member name="factor" type="float" setter="set_factor" getter="get_factor" brief="">
</member>
- <member name="meta" type="bool" setter="" getter="" brief="">
- State of the Meta modifier.
- </member>
- <member name="pos" type="Vector2" setter="" getter="" brief="">
- Local position of the mouse pointer.
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
+ Pressed state of the mouse button.
</member>
- <member name="relative_pos" type="Vector2" setter="" getter="" brief="">
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="InputEventMouseMotion" inherits="InputEventMouse" category="Core">
+ <brief_description>
+ Input event type for mouse motion events.
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_relative" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_speed" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_relative">
+ <argument index="0" name="relative" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_speed">
+ <argument index="0" name="speed" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="relative" type="Vector2" setter="set_relative" getter="get_relative" brief="">
Position of the mouse pointer relative to the previous mouse position.
</member>
- <member name="relative_x" type="float" setter="" getter="" brief="">
- X coordinate of the mouse pointer relative to the previous mouse position.
- </member>
- <member name="relative_y" type="float" setter="" getter="" brief="">
- Y coordinate of the mouse pointer relative to the previous mouse position.
- </member>
- <member name="shift" type="bool" setter="" getter="" brief="">
- State of the Shift modifier.
- </member>
- <member name="speed" type="Vector2" setter="" getter="" brief="">
+ <member name="speed" type="Vector2" setter="set_speed" getter="get_speed" brief="">
Speed of the mouse pointer.
</member>
- <member name="speed_x" type="float" setter="" getter="" brief="">
- Speed of the mouse pointer on the X axis.
- </member>
- <member name="speed_y" type="float" setter="" getter="" brief="">
- Speed of the mouse pointer on the Y axis.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
- </member>
- <member name="x" type="float" setter="" getter="" brief="">
- Local X coordinate of the mouse pointer.
- </member>
- <member name="y" type="float" setter="" getter="" brief="">
- Local Y coordinate of the mouse pointer.
- </member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventScreenDrag" category="Built-In Types">
+<class name="InputEventScreenDrag" inherits="InputEvent" category="Core">
<brief_description>
- Built-in input event type for screen drag events.
+ Input event type for screen drag events.
</brief_description>
<description>
- Input event type for screen drag events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
- <return type="bool">
+ <method name="get_index" qualifiers="const">
+ <return type="int">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
- <return type="bool">
+ <method name="get_position" qualifiers="const">
+ <return type="Vector2">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed. Not relevant for SCREEN_DRAG events, always false.
</description>
</method>
- <method name="is_action_released">
- <return type="bool">
+ <method name="get_relative" qualifiers="const">
+ <return type="Vector2">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is released (i.e. not pressed). Not relevant for SCREEN_DRAG events, can be true or false depending on whether [method is_action] is true.
</description>
</method>
- <method name="is_echo">
- <return type="bool">
+ <method name="get_speed" qualifiers="const">
+ <return type="Vector2">
</return>
<description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
</description>
</method>
- <method name="is_pressed">
- <return type="bool">
- </return>
+ <method name="set_index">
+ <argument index="0" name="index" type="int">
+ </argument>
<description>
- Return if this input event is pressed. Not relevant for SCREEN_DRAG events, always false.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
+ <method name="set_position">
+ <argument index="0" name="position" type="Vector2">
</argument>
- <argument index="1" name="pressed" type="bool">
+ <description>
+ </description>
+ </method>
+ <method name="set_relative">
+ <argument index="0" name="relative" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_speed">
+ <argument index="0" name="speed" type="Vector2">
</argument>
<description>
- Change the input event to an action event of the given name with the (irrelevant for this type) pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="index" type="int" setter="" getter="" brief="">
+ <member name="index" type="int" setter="set_index" getter="get_index" brief="">
Drag event index in the case of a multi-drag event.
</member>
- <member name="pos" type="Vector2" setter="" getter="" brief="">
+ <member name="position" type="Vector2" setter="set_position" getter="get_position" brief="">
Position of the drag event.
</member>
- <member name="relative_pos" type="Vector2" setter="" getter="" brief="">
+ <member name="relative" type="Vector2" setter="set_relative" getter="get_relative" brief="">
Position of the drag event relative to its start position.
</member>
- <member name="relative_x" type="float" setter="" getter="" brief="">
- X coordinate of the drag event relative to its start position.
- </member>
- <member name="relative_y" type="float" setter="" getter="" brief="">
- Y coordinate of the drag event relative to its start position.
- </member>
- <member name="speed" type="Vector2" setter="" getter="" brief="">
+ <member name="speed" type="Vector2" setter="set_speed" getter="get_speed" brief="">
Speed of the drag event.
</member>
- <member name="speed_x" type="float" setter="" getter="" brief="">
- Speed of the drag event on the X axis.
- </member>
- <member name="speed_y" type="float" setter="" getter="" brief="">
- Speed of the drag event on the Y axis.
- </member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
+ </members>
+ <constants>
+ </constants>
+</class>
+<class name="InputEventScreenTouch" inherits="InputEvent" category="Core">
+ <brief_description>
+ Input event type for screen touch events.
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_index" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_position" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_index">
+ <argument index="0" name="index" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_position">
+ <argument index="0" name="pos" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_pressed">
+ <argument index="0" name="pressed" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="index" type="int" setter="set_index" getter="get_index" brief="">
+ Touch event index in the case of a multi-touch event.
</member>
- <member name="x" type="float" setter="" getter="" brief="">
- X coordinate of the drag event.
+ <member name="position" type="Vector2" setter="set_position" getter="get_position" brief="">
+ Position of the touch event.
</member>
- <member name="y" type="float" setter="" getter="" brief="">
- Y coordinate of the drag event.
+ <member name="pressed" type="bool" setter="set_pressed" getter="is_pressed" brief="">
+ Pressed state of the touch event.
</member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
-<class name="InputEventScreenTouch" category="Built-In Types">
+<class name="InputEventWithModifiers" inherits="InputEvent" category="Core">
<brief_description>
- Built-in input event type for touchscreen drag events.
+ Base class for input events with modifiers.
</brief_description>
<description>
- Input event type for touchscreen drag events that extends the global [InputEvent] type.
</description>
<methods>
- <method name="is_action">
+ <method name="get_alt" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return if this input event matches a pre-defined action.
</description>
</method>
- <method name="is_action_pressed">
+ <method name="get_command" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is being pressed.
</description>
</method>
- <method name="is_action_released">
+ <method name="get_control" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="action" type="String">
- </argument>
<description>
- Return whether the given action is released (i.e. not pressed).
</description>
</method>
- <method name="is_echo">
+ <method name="get_metakey" qualifiers="const">
<return type="bool">
</return>
<description>
- Return if this input event is an echo event (only for events of type KEY, i.e. always false for this type).
</description>
</method>
- <method name="is_pressed">
+ <method name="get_shift" qualifiers="const">
<return type="bool">
</return>
<description>
- Return if this input event is pressed.
</description>
</method>
- <method name="set_as_action">
- <argument index="0" name="action" type="String">
+ <method name="set_alt">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_command">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_control">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_metakey">
+ <argument index="0" name="enable" type="bool">
</argument>
- <argument index="1" name="pressed" type="bool">
+ <description>
+ </description>
+ </method>
+ <method name="set_shift">
+ <argument index="0" name="enable" type="bool">
</argument>
<description>
- Change the input event to an action event of the given name with the pressed status passed as argument.
</description>
</method>
</methods>
<members>
- <member name="ID" type="int" setter="" getter="" brief="">
- Event identifier, positive integer increased at each new event.
- </member>
- <member name="device" type="int" setter="" getter="" brief="">
- Device identifier.
- </member>
- <member name="index" type="int" setter="" getter="" brief="">
- Touch event index in the case of a multi-touch event.
- </member>
- <member name="pos" type="Vector2" setter="" getter="" brief="">
- Position of the touch event.
+ <member name="alt" type="bool" setter="set_alt" getter="get_alt" brief="">
+ State of the Alt modifier.
</member>
- <member name="pressed" type="bool" setter="" getter="" brief="">
- Pressed state of the touch event.
+ <member name="command" type="bool" setter="set_command" getter="get_command" brief="">
+ State of the Command modifier.
</member>
- <member name="type" type="int" setter="" getter="" brief="">
- Type of event (one of the [InputEvent] constants).
+ <member name="control" type="bool" setter="set_control" getter="get_control" brief="">
+ State of the Ctrl modifier.
</member>
- <member name="x" type="float" setter="" getter="" brief="">
- X coordinate of the touch event.
+ <member name="meta" type="bool" setter="set_metakey" getter="get_metakey" brief="">
+ State of the Meta modifier.
</member>
- <member name="y" type="float" setter="" getter="" brief="">
- Y coordinate of the touch event.
+ <member name="shift" type="bool" setter="set_shift" getter="get_shift" brief="">
+ State of the Shift modifier.
</member>
</members>
<constants>
- <constant name="NONE" value="0">
- Empty input event.
- </constant>
- <constant name="KEY" value="1">
- Key event.
- </constant>
- <constant name="MOUSE_MOTION" value="2">
- Mouse motion event.
- </constant>
- <constant name="MOUSE_BUTTON" value="3">
- Mouse button event.
- </constant>
- <constant name="JOYPAD_MOTION" value="4">
- Joypad motion event.
- </constant>
- <constant name="JOYPAD_BUTTON" value="5">
- Joypad button event.
- </constant>
- <constant name="SCREEN_TOUCH" value="6">
- Screen touch event.
- </constant>
- <constant name="SCREEN_DRAG" value="7">
- Screen drag event.
- </constant>
- <constant name="ACTION" value="8">
- Pre-defined action event (see [InputMap]).
- </constant>
</constants>
</class>
<class name="InputMap" inherits="Object" category="Core">
@@ -20356,13 +20579,12 @@
Singleton that manages actions.
</brief_description>
<description>
- Singleton that manages actions. InputMap has a list of the actions used in InputEvent, which can be modified.
</description>
<methods>
<method name="action_add_event">
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="InputEvent">
+ <argument index="1" name="event" type="Object">
</argument>
<description>
Add an [InputEvent] to an action. This [InputEvent] will trigger the action.
@@ -20371,7 +20593,7 @@
<method name="action_erase_event">
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="InputEvent">
+ <argument index="1" name="event" type="Object">
</argument>
<description>
Remove an [InputEvent] from an action.
@@ -20382,7 +20604,7 @@
</return>
<argument index="0" name="action" type="String">
</argument>
- <argument index="1" name="event" type="InputEvent">
+ <argument index="1" name="event" type="Object">
</argument>
<description>
Whether an action has an [InputEvent] associated with it.
@@ -20405,7 +20627,7 @@
<method name="event_is_action" qualifiers="const">
<return type="bool">
</return>
- <argument index="0" name="event" type="InputEvent">
+ <argument index="0" name="event" type="Object">
</argument>
<argument index="1" name="action" type="String">
</argument>
@@ -20413,24 +20635,6 @@
Return whether the given event is part of an existing action. This method ignores keyboard modifiers if the given [InputEvent] is not pressed (for proper release detection). See [method action_has_event] if you don't want this behavior.
</description>
</method>
- <method name="get_action_from_id" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="id" type="int">
- </argument>
- <description>
- Return the action corresponding to the identifier.
- </description>
- </method>
- <method name="get_action_id" qualifiers="const">
- <return type="int">
- </return>
- <argument index="0" name="action" type="String">
- </argument>
- <description>
- Return the identifier of the given action.
- </description>
- </method>
<method name="get_action_list">
<return type="Array">
</return>
@@ -21254,6 +21458,18 @@
Return the point in space where the body is touching another. If there is no collision, this method will return (0,0,0), so collisions must be checked first with [method is_colliding].
</description>
</method>
+ <method name="get_move_and_slide_colliders" qualifiers="const">
+ <return type="Array">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_travel" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_colliding" qualifiers="const">
<return type="bool">
</return>
@@ -21261,6 +21477,24 @@
Return whether the body is colliding with another.
</description>
</method>
+ <method name="is_move_and_slide_on_ceiling" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_move_and_slide_on_floor" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="is_move_and_slide_on_wall" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="move">
<return type="Vector3">
</return>
@@ -21270,6 +21504,26 @@
Move the body in the given direction, stopping if there is an obstacle. The returned vector is how much movement was remaining before being stopped.
</description>
</method>
+ <method name="move_and_slide">
+ <return type="Vector3">
+ </return>
+ <argument index="0" name="linear_velocity" type="Vector3">
+ </argument>
+ <argument index="1" name="floor_normal" type="Vector3" default="Vector3(0, 0, 0)">
+ </argument>
+ <argument index="2" name="ceil_normal" type="Vector3" default="Vector3(0, 0, 0)">
+ </argument>
+ <argument index="3" name="slope_stop_min_velocity" type="float" default="5">
+ </argument>
+ <argument index="4" name="max_bounces" type="int" default="4">
+ </argument>
+ <argument index="5" name="floor_max_angle" type="float" default="0.785398">
+ </argument>
+ <argument index="6" name="ceil_max_angle" type="float" default="0.785398">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="move_to">
<return type="Vector3">
</return>
@@ -21279,6 +21533,10 @@
Move the body to the given position. This is not a teleport, and the body will stop if there is an obstacle. The returned vector is how much movement was remaining before being stopped.
</description>
</method>
+ <method name="revert_motion">
+ <description>
+ </description>
+ </method>
<method name="set_collide_with_character_bodies">
<argument index="0" name="enable" type="bool">
</argument>
@@ -21963,9 +22221,7 @@
</constant>
<constant name="PARAM_SHADOW_BIAS" value="12">
</constant>
- <constant name="PARAM_SHADOW_BIAS_SPLIT_SCALE" value="13">
- </constant>
- <constant name="PARAM_MAX" value="14">
+ <constant name="PARAM_MAX" value="13">
</constant>
</constants>
</class>
@@ -22057,6 +22313,12 @@
<description>
</description>
</method>
+ <method name="get_shadow_smooth" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_texture" qualifiers="const">
<return type="Object">
</return>
@@ -22214,6 +22476,12 @@
<description>
</description>
</method>
+ <method name="set_shadow_smooth">
+ <argument index="0" name="smooth" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_texture">
<argument index="0" name="texture" type="Object">
</argument>
@@ -22285,6 +22553,8 @@
</member>
<member name="shadow_filter" type="float" setter="set_shadow_filter" getter="get_shadow_filter" brief="">
</member>
+ <member name="shadow_filter_smooth" type="float" setter="set_shadow_smooth" getter="get_shadow_smooth" brief="">
+ </member>
<member name="shadow_gradient_length" type="float" setter="set_shadow_gradient_length" getter="get_shadow_gradient_length" brief="">
</member>
<member name="shadow_item_cull_mask" type="int" setter="set_item_shadow_cull_mask" getter="get_item_shadow_cull_mask" brief="">
@@ -22533,7 +22803,7 @@
</member>
<member name="end_cap_mode" type="int" setter="set_end_cap_mode" getter="get_end_cap_mode" brief="">
</member>
- <member name="gradient" type="ColorRamp" setter="set_gradient" getter="get_gradient" brief="">
+ <member name="gradient" type="Gradient" setter="set_gradient" getter="get_gradient" brief="">
</member>
<member name="joint_mode" type="int" setter="set_joint_mode" getter="get_joint_mode" brief="">
</member>
@@ -23054,7 +23324,7 @@
</description>
</method>
<method name="input_event">
- <argument index="0" name="ev" type="InputEvent">
+ <argument index="0" name="ev" type="Object">
</argument>
<description>
</description>
@@ -23244,244 +23514,40 @@
Mesh is a type of [Resource] that contains vertex-array based geometry, divided in [i]surfaces[/i]. Each surface contains a completely separate array and a material used to draw it. Design wise, a mesh with multiple surfaces is preferred to a single surface, because objects created in 3D editing software commonly contain multiple materials.
</description>
<methods>
- <method name="add_blend_shape">
- <argument index="0" name="name" type="String">
- </argument>
- <description>
- </description>
- </method>
- <method name="add_surface_from_arrays">
- <argument index="0" name="primitive" type="int">
- </argument>
- <argument index="1" name="arrays" type="Array">
- </argument>
- <argument index="2" name="blend_shapes" type="Array" default="Array()">
- </argument>
- <argument index="3" name="compress_flags" type="int" default="97792">
- </argument>
- <description>
- Create a new surface ([method get_surface_count] that will become surf_idx for this.
- Surfaces are created to be rendered using a "primitive", which may be PRIMITIVE_POINTS, PRIMITIVE_LINES, PRIMITIVE_LINE_STRIP, PRIMITIVE_LINE_LOOP, PRIMITIVE_TRIANGLES, PRIMITIVE_TRIANGLE_STRIP, PRIMITIVE_TRIANGLE_FAN. (As a note, when using indices, it is recommended to only use just points, lines or triangles).
- (might be obsolete) The format of a surface determines which arrays it will allocate and hold, so "format" is a combination of ARRAY_FORMAT_* mask constants ORed together. ARRAY_FORMAT_VERTEX must be always present. "array_len" determines the amount of vertices in the array (not primitives!). if ARRAY_FORMAT_INDEX is in the format mask, then it means that an index array will be allocated and "index_array_len" must be passed
- </description>
- </method>
- <method name="center_geometry">
- <description>
- </description>
- </method>
- <method name="clear_blend_shapes">
- <description>
- </description>
- </method>
- <method name="get_blend_shape_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_blend_shape_mode" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
- <method name="get_blend_shape_name" qualifiers="const">
- <return type="String">
- </return>
- <argument index="0" name="index" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="get_custom_aabb" qualifiers="const">
- <return type="Rect3">
- </return>
- <description>
- </description>
- </method>
- <method name="get_surface_count" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Return the amount of surfaces that the [Mesh] holds.
- </description>
- </method>
- <method name="regen_normalmaps">
- <description>
- </description>
- </method>
- <method name="set_blend_shape_mode">
- <argument index="0" name="mode" type="int">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_custom_aabb">
- <argument index="0" name="aabb" type="Rect3">
- </argument>
- <description>
- </description>
- </method>
- <method name="surface_get_array_index_len" qualifiers="const">
- <return type="int">
+ <method name="create_convex_shape" qualifiers="const">
+ <return type="Shape">
</return>
- <argument index="0" name="surf_idx" type="int">
- </argument>
<description>
- Return the length in indices of the index array in the requested surface (see [method add_surface]).
</description>
</method>
- <method name="surface_get_array_len" qualifiers="const">
- <return type="int">
+ <method name="create_outline" qualifiers="const">
+ <return type="ArrayMesh">
</return>
- <argument index="0" name="surf_idx" type="int">
- </argument>
- <description>
- Return the length in vertices of the vertex array in the requested surface (see [method add_surface]).
- </description>
- </method>
- <method name="surface_get_format" qualifiers="const">
- <return type="int">
- </return>
- <argument index="0" name="surf_idx" type="int">
+ <argument index="0" name="margin" type="float">
</argument>
<description>
- Return the format mask of the requested surface (see [method add_surface]).
</description>
</method>
- <method name="surface_get_material" qualifiers="const">
- <return type="Material">
+ <method name="create_trimesh_shape" qualifiers="const">
+ <return type="Shape">
</return>
- <argument index="0" name="surf_idx" type="int">
- </argument>
<description>
- Return a [Material] in a given surface. Surface is rendered using this material.
</description>
</method>
- <method name="surface_get_name" qualifiers="const">
- <return type="String">
+ <method name="generate_triangle_mesh" qualifiers="const">
+ <return type="TriangleMesh">
</return>
- <argument index="0" name="surf_idx" type="int">
- </argument>
<description>
</description>
</method>
- <method name="surface_get_primitive_type" qualifiers="const">
- <return type="int">
+ <method name="get_faces" qualifiers="const">
+ <return type="PoolVector3Array">
</return>
- <argument index="0" name="surf_idx" type="int">
- </argument>
- <description>
- Return the primitive type of the requested surface (see [method add_surface]).
- </description>
- </method>
- <method name="surface_remove">
- <argument index="0" name="surf_idx" type="int">
- </argument>
- <description>
- Remove a surface at position surf_idx, shifting greater surfaces one surf_idx slot down.
- </description>
- </method>
- <method name="surface_set_material">
- <argument index="0" name="surf_idx" type="int">
- </argument>
- <argument index="1" name="material" type="Material">
- </argument>
- <description>
- Set a [Material] for a given surface. Surface will be rendered using this material.
- </description>
- </method>
- <method name="surface_set_name">
- <argument index="0" name="surf_idx" type="int">
- </argument>
- <argument index="1" name="name" type="String">
- </argument>
<description>
</description>
</method>
</methods>
<constants>
- <constant name="NO_INDEX_ARRAY" value="-1">
- Default value used for index_array_len when no indices are present.
- </constant>
- <constant name="ARRAY_WEIGHTS_SIZE" value="4">
- Amount of weights/bone indices per vertex (always 4).
- </constant>
- <constant name="ARRAY_VERTEX" value="0">
- Vertex array (array of [Vector3] vertices).
- </constant>
- <constant name="ARRAY_NORMAL" value="1">
- Normal array (array of [Vector3] normals).
- </constant>
- <constant name="ARRAY_TANGENT" value="2">
- Tangent array, array of groups of 4 floats. first 3 floats determine the tangent, and the last the binormal direction as -1 or 1.
- </constant>
- <constant name="ARRAY_COLOR" value="3">
- Vertex array (array of [Color] colors).
- </constant>
- <constant name="ARRAY_TEX_UV" value="4">
- UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
- </constant>
- <constant name="ARRAY_TEX_UV2" value="5">
- Second UV array (array of [Vector3] UVs or float array of groups of 2 floats (u,v)).
- </constant>
- <constant name="ARRAY_BONES" value="6">
- Array of bone indices, as a float array. Each element in groups of 4 floats.
- </constant>
- <constant name="ARRAY_WEIGHTS" value="7">
- Array of bone weights, as a float array. Each element in groups of 4 floats.
- </constant>
- <constant name="ARRAY_INDEX" value="8">
- Array of integers, used as indices referencing vertices. No index can be beyond the vertex array size.
- </constant>
- <constant name="ARRAY_FORMAT_VERTEX" value="1">
- Array format will include vertices (mandatory).
- </constant>
- <constant name="ARRAY_FORMAT_NORMAL" value="2">
- Array format will include normals
- </constant>
- <constant name="ARRAY_FORMAT_TANGENT" value="4">
- Array format will include tangents
- </constant>
- <constant name="ARRAY_FORMAT_COLOR" value="8">
- Array format will include a color array.
- </constant>
- <constant name="ARRAY_FORMAT_TEX_UV" value="16">
- Array format will include UVs.
- </constant>
- <constant name="ARRAY_FORMAT_TEX_UV2" value="32">
- Array format will include another set of UVs.
- </constant>
- <constant name="ARRAY_FORMAT_BONES" value="64">
- Array format will include bone indices.
- </constant>
- <constant name="ARRAY_FORMAT_WEIGHTS" value="128">
- Array format will include bone weights.
- </constant>
- <constant name="ARRAY_FORMAT_INDEX" value="256">
- Index array will be used.
- </constant>
- <constant name="PRIMITIVE_POINTS" value="0">
- Render array as points (one vertex equals one point).
- </constant>
- <constant name="PRIMITIVE_LINES" value="1">
- Render array as lines (every two vertices a line is created).
- </constant>
- <constant name="PRIMITIVE_LINE_STRIP" value="2">
- Render array as line strip.
- </constant>
- <constant name="PRIMITIVE_LINE_LOOP" value="3">
- Render array as line loop (like line strip, but closed).
- </constant>
- <constant name="PRIMITIVE_TRIANGLES" value="4">
- Render array as triangles (every three vertices a triangle is created).
- </constant>
- <constant name="PRIMITIVE_TRIANGLE_STRIP" value="5">
- Render array as triangle strips.
- </constant>
- <constant name="PRIMITIVE_TRIANGLE_FAN" value="6">
- Render array as triangle fans.
- </constant>
</constants>
</class>
<class name="MeshDataTool" inherits="Reference" category="Core">
@@ -24611,6 +24677,8 @@
</constant>
<constant name="COMPRESS_ZLIB" value="3">
</constant>
+ <constant name="COMPRESS_ZSTD" value="4">
+ </constant>
</constants>
</class>
<class name="NetworkedMultiplayerPeer" inherits="PacketPeer" category="Core">
@@ -24772,12 +24840,6 @@
</description>
</method>
<method name="Nil">
- <argument index="0" name="from" type="InputEvent">
- </argument>
- <description>
- </description>
- </method>
- <method name="Nil">
<argument index="0" name="from" type="Object">
</argument>
<description>
@@ -24796,12 +24858,6 @@
</description>
</method>
<method name="Nil">
- <argument index="0" name="from" type="Image">
- </argument>
- <description>
- </description>
- </method>
- <method name="Nil">
<argument index="0" name="from" type="Color">
</argument>
<description>
@@ -25015,8 +25071,6 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Called for every input event.
- It has to be enabled with [method set_process_input] or the corresponding property in the inspector.
</description>
</method>
<method name="_process" qualifiers="virtual">
@@ -25038,16 +25092,12 @@
<argument index="0" name="event" type="InputEvent">
</argument>
<description>
- Called for every input event that has not already been handled by another node.
- It has to be enabled with [method set_process_unhandled_input] or the corresponding property in the inspector.
</description>
</method>
<method name="_unhandled_key_input" qualifiers="virtual">
- <argument index="0" name="key_event" type="InputEvent">
+ <argument index="0" name="event" type="InputEventKey">
</argument>
<description>
- Called for every [i]key[/i] input event that has not already been handled by another node.
- It has to be enabled with [method set_process_unhandled_key_input] or the corresponding property in the inspector.
</description>
</method>
<method name="add_child">
@@ -26131,7 +26181,7 @@
</argument>
<argument index="2" name="blocking" type="bool">
</argument>
- <argument index="3" name="output" type="Array" default="Array()">
+ <argument index="3" name="output" type="Array" default="[]">
</argument>
<description>
Execute the binary file in given path, optionally blocking until it returns. A process ID is returned.
@@ -26264,7 +26314,7 @@
<return type="String">
</return>
<description>
- Return the name of the host OS. Possible values are: "Android", "BlackBerry 10", "Flash", "Haiku", "iOS", "HTML5", "OSX", "Server", "Windows", "UWP", "X11"
+ Return the name of the host OS. Possible values are: "Android", "Haiku", "iOS", "HTML5", "OSX", "Server", "Windows", "UWP", "X11".
</description>
</method>
<method name="get_power_percent_left">
@@ -26645,7 +26695,7 @@
</description>
</method>
<method name="set_icon">
- <argument index="0" name="icon" type="Image">
+ <argument index="0" name="icon" type="Object">
</argument>
<description>
</description>
@@ -26895,7 +26945,7 @@
<method name="add_user_signal">
<argument index="0" name="signal" type="String">
</argument>
- <argument index="1" name="arguments" type="Array" default="Array()">
+ <argument index="1" name="arguments" type="Array" default="[]">
</argument>
<description>
Add a user signal (can be added anytime). Arguments are optional, but can be added as an array of dictionaries, each containing "name" and "type" (from [@Global Scope] TYPE_*).
@@ -26941,7 +26991,7 @@
</argument>
<argument index="2" name="method" type="String">
</argument>
- <argument index="3" name="binds" type="Array" default="Array()">
+ <argument index="3" name="binds" type="Array" default="[]">
</argument>
<argument index="4" name="flags" type="int" default="0">
</argument>
@@ -27184,7 +27234,7 @@
Persisting connections are saved when the object is serialized to file.
</constant>
<constant name="CONNECT_ONESHOT" value="4">
- One short connections disconnect themselves after emission.
+ One shot connections disconnect themselves after emission.
</constant>
</constants>
</class>
@@ -27253,7 +27303,7 @@
OmniDirectional Light, such as a light bulb or a candle.
</brief_description>
<description>
- An OmniDirectional light is a type of [Light] node that emits lights in all directions. The light is attenuated through the distance and this attenuation can be configured by changing the energy, radius and attenuation parameters of [Light]. TODO: Image of an omnilight.
+ An OmniDirectional light is a type of [Light] node that emits lights in all directions. The light is attenuated through the distance and this attenuation can be configured by changing the energy, radius and attenuation parameters of [Light].
</description>
<methods>
<method name="get_shadow_detail" qualifiers="const">
@@ -27622,7 +27672,7 @@
<method name="instance" qualifiers="const">
<return type="Node">
</return>
- <argument index="0" name="edit_state" type="int" default="false">
+ <argument index="0" name="edit_state" type="int" default="0">
</argument>
<description>
</description>
@@ -27835,6 +27885,32 @@
</theme_item>
</theme_items>
</class>
+<class name="PanoramaSky" inherits="Sky" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_panorama" qualifiers="const">
+ <return type="Texture">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_panorama">
+ <argument index="0" name="texture" type="Texture">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="panorama" type="Texture" setter="set_panorama" getter="get_panorama" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="ParallaxBackground" inherits="CanvasLayer" category="Core">
<brief_description>
A node used to create a parallax scrolling background.
@@ -28105,14 +28181,14 @@
<description>
</description>
<methods>
- <method name="get_amount" qualifiers="const">
- <return type="int">
+ <method name="capture_aabb" qualifiers="const">
+ <return type="Rect3">
</return>
<description>
</description>
</method>
- <method name="get_custom_aabb" qualifiers="const">
- <return type="Rect3">
+ <method name="get_amount" qualifiers="const">
+ <return type="int">
</return>
<description>
</description>
@@ -28155,12 +28231,6 @@
<description>
</description>
</method>
- <method name="get_gravity" qualifiers="const">
- <return type="Vector3">
- </return>
- <description>
- </description>
- </method>
<method name="get_lifetime" qualifiers="const">
<return type="float">
</return>
@@ -28185,12 +28255,24 @@
<description>
</description>
</method>
+ <method name="get_speed_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_use_local_coordinates" qualifiers="const">
<return type="bool">
</return>
<description>
</description>
</method>
+ <method name="get_visibility_aabb" qualifiers="const">
+ <return type="Rect3">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_emitting" qualifiers="const">
<return type="bool">
</return>
@@ -28203,12 +28285,6 @@
<description>
</description>
</method>
- <method name="set_custom_aabb">
- <argument index="0" name="aabb" type="Rect3">
- </argument>
- <description>
- </description>
- </method>
<method name="set_draw_order">
<argument index="0" name="order" type="int">
</argument>
@@ -28253,12 +28329,6 @@
<description>
</description>
</method>
- <method name="set_gravity">
- <argument index="0" name="accel_vec" type="Vector3">
- </argument>
- <description>
- </description>
- </method>
<method name="set_lifetime">
<argument index="0" name="secs" type="float">
</argument>
@@ -28283,18 +28353,28 @@
<description>
</description>
</method>
+ <method name="set_speed_scale">
+ <argument index="0" name="scale" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_use_local_coordinates">
<argument index="0" name="enable" type="bool">
</argument>
<description>
</description>
</method>
+ <method name="set_visibility_aabb">
+ <argument index="0" name="aabb" type="Rect3">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="amount" type="int" setter="set_amount" getter="get_amount" brief="">
</member>
- <member name="custom_aabb" type="Rect3" setter="set_custom_aabb" getter="get_custom_aabb" brief="">
- </member>
<member name="draw_order" type="int" setter="set_draw_order" getter="get_draw_order" brief="">
</member>
<member name="draw_pass_1" type="Mesh" setter="set_draw_pass_mesh" getter="get_draw_pass_mesh" brief="">
@@ -28315,8 +28395,6 @@
</member>
<member name="fract_delta" type="bool" setter="set_fractional_delta" getter="get_fractional_delta" brief="">
</member>
- <member name="gravity" type="Vector3" setter="set_gravity" getter="get_gravity" brief="">
- </member>
<member name="lifetime" type="float" setter="set_lifetime" getter="get_lifetime" brief="">
</member>
<member name="local_coords" type="bool" setter="set_use_local_coordinates" getter="get_use_local_coordinates" brief="">
@@ -28327,6 +28405,10 @@
</member>
<member name="randomness" type="float" setter="set_randomness_ratio" getter="get_randomness_ratio" brief="">
</member>
+ <member name="speed_scale" type="float" setter="set_speed_scale" getter="get_speed_scale" brief="">
+ </member>
+ <member name="visibility_aabb" type="Rect3" setter="set_visibility_aabb" getter="get_visibility_aabb" brief="">
+ </member>
</members>
<constants>
<constant name="DRAW_ORDER_INDEX" value="0">
@@ -28383,13 +28465,6 @@
<description>
</description>
</method>
- <method name="get_color_ramp" qualifiers="const">
- <return type="ColorRamp">
- </return>
- <description>
- Returns the [ColorRamp] used to tint each particle
- </description>
- </method>
<method name="get_emission_half_extents" qualifiers="const">
<return type="Vector2">
</return>
@@ -28423,6 +28498,13 @@
<description>
</description>
</method>
+ <method name="get_gradient" qualifiers="const">
+ <return type="Gradient">
+ </return>
+ <description>
+ Returns the [Gradient] used to tint each particle.
+ </description>
+ </method>
<method name="get_h_frames" qualifiers="const">
<return type="int">
</return>
@@ -28563,15 +28645,6 @@
<description>
</description>
</method>
- <method name="set_color_ramp">
- <return type="ColorRamp">
- </return>
- <argument index="0" name="color_ramp" type="Object">
- </argument>
- <description>
- Sets the [ColorRamp] used to tint each particle. Particle will be tinted according to their lifetimes.
- </description>
- </method>
<method name="set_emission_half_extents">
<argument index="0" name="extents" type="Vector2">
</argument>
@@ -28624,6 +28697,15 @@
<description>
</description>
</method>
+ <method name="set_gradient">
+ <return type="Gradient">
+ </return>
+ <argument index="0" name="gradient" type="Object">
+ </argument>
+ <description>
+ Sets the [Gradient] used to tint each particle. Particle will be tinted according to their lifetimes.
+ </description>
+ </method>
<method name="set_h_frames">
<argument index="0" name="enable" type="int">
</argument>
@@ -28705,7 +28787,7 @@
<members>
<member name="color/color" type="Color" setter="set_color" getter="get_color" brief="">
</member>
- <member name="color/color_ramp" type="ColorRamp" setter="set_color_ramp" getter="get_color_ramp" brief="">
+ <member name="color/color_ramp" type="Gradient" setter="set_color_ramp" getter="get_color_ramp" brief="">
</member>
<member name="color_phases/count" type="int" setter="set_color_phases" getter="get_color_phases" brief="">
</member>
@@ -28947,6 +29029,12 @@
<description>
</description>
</method>
+ <method name="get_gravity" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_param" qualifiers="const">
<return type="float">
</return>
@@ -29057,6 +29145,12 @@
<description>
</description>
</method>
+ <method name="set_gravity">
+ <argument index="0" name="accel_vec" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_param">
<argument index="0" name="param" type="int">
</argument>
@@ -29159,6 +29253,8 @@
</member>
<member name="flatness" type="float" setter="set_flatness" getter="get_flatness" brief="">
</member>
+ <member name="gravity" type="Vector3" setter="set_gravity" getter="get_gravity" brief="">
+ </member>
<member name="hue_variation" type="float" setter="set_param" getter="get_param" brief="">
</member>
<member name="hue_variation_curve" type="CurveTexture" setter="set_param_texture" getter="get_param_texture" brief="">
@@ -29912,9 +30008,9 @@
</argument>
<argument index="1" name="max_results" type="int" default="32">
</argument>
- <argument index="2" name="exclude" type="Array" default="Array()">
+ <argument index="2" name="exclude" type="Array" default="[]">
</argument>
- <argument index="3" name="layer_mask" type="int" default="2147483647">
+ <argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
<argument index="4" name="type_mask" type="int" default="15">
</argument>
@@ -29935,9 +30031,9 @@
</argument>
<argument index="1" name="to" type="Vector2">
</argument>
- <argument index="2" name="exclude" type="Array" default="Array()">
+ <argument index="2" name="exclude" type="Array" default="[]">
</argument>
- <argument index="3" name="layer_mask" type="int" default="2147483647">
+ <argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
<argument index="4" name="type_mask" type="int" default="15">
</argument>
@@ -30120,22 +30216,22 @@
Remove a shape from an area. It does not delete the shape, so it can be reassigned later.
</description>
</method>
- <method name="area_set_collision_mask">
+ <method name="area_set_collision_layer">
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="mask" type="int">
+ <argument index="1" name="layer" type="int">
</argument>
<description>
- Set which physics layers the area will monitor.
+ Assign the area to one or many physics layers.
</description>
</method>
- <method name="area_set_layer_mask">
+ <method name="area_set_collision_mask">
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="mask" type="int">
</argument>
<description>
- Assign the area to one or many physics layers.
+ Set which physics layers the area will monitor.
</description>
</method>
<method name="area_set_monitor_callback">
@@ -30283,31 +30379,31 @@
Create a physics body. The first parameter can be any value from constants BODY_MODE*, for the type of body created. Additionally, the body can be created in sleeping state to save processing time.
</description>
</method>
- <method name="body_get_collision_mask" qualifiers="const">
+ <method name="body_get_collision_layer" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the physics layer or layers a body can collide with.
+ Return the physics layer or layers a body belongs to.
</description>
</method>
- <method name="body_get_continuous_collision_detection_mode" qualifiers="const">
+ <method name="body_get_collision_mask" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the continuous collision detection mode.
+ Return the physics layer or layers a body can collide with.
</description>
</method>
- <method name="body_get_layer_mask" qualifiers="const">
+ <method name="body_get_continuous_collision_detection_mode" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="body" type="RID">
</argument>
<description>
- Return the physics layer or layers a body belongs to.
+ Return the continuous collision detection mode.
</description>
</method>
<method name="body_get_max_contacts_reported" qualifiers="const">
@@ -30471,6 +30567,15 @@
Set an axis velocity. The velocity in the given vector axis will be set as the given vector length. This is useful for jumping behavior.
</description>
</method>
+ <method name="body_set_collision_layer">
+ <argument index="0" name="body" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <description>
+ Set the physics layer or layers a body belongs to.
+ </description>
+ </method>
<method name="body_set_collision_mask">
<argument index="0" name="body" type="RID">
</argument>
@@ -30503,15 +30608,6 @@
Set the function used to calculate physics for an object, if that object allows it (see [method body_set_omit_force integration]).
</description>
</method>
- <method name="body_set_layer_mask">
- <argument index="0" name="body" type="RID">
- </argument>
- <argument index="1" name="mask" type="int">
- </argument>
- <description>
- Set the physics layer or layers a body belongs to.
- </description>
- </method>
<method name="body_set_max_contacts_reported">
<argument index="0" name="body" type="RID">
</argument>
@@ -30658,7 +30754,7 @@
</argument>
<argument index="2" name="body_a" type="RID">
</argument>
- <argument index="3" name="body_b" type="RID" default="RID()">
+ <argument index="3" name="body_b" type="RID" default="[RID]">
</argument>
<description>
Create a damped spring joint between two bodies. If not specified, the second body is assumed to be the joint itself.
@@ -30711,9 +30807,9 @@
</argument>
<argument index="2" name="anchor_b" type="Vector2">
</argument>
- <argument index="3" name="body_a" type="RID" default="RID()">
+ <argument index="3" name="body_a" type="RID" default="[RID]">
</argument>
- <argument index="4" name="body_b" type="RID" default="RID()">
+ <argument index="4" name="body_b" type="RID" default="[RID]">
</argument>
<description>
Create a groove joint between two bodies. If not specified, the bodyies are assumed to be the joint itself.
@@ -30757,7 +30853,7 @@
</argument>
<argument index="1" name="body_a" type="RID">
</argument>
- <argument index="2" name="body_b" type="RID" default="RID()">
+ <argument index="2" name="body_b" type="RID" default="[RID]">
</argument>
<description>
Create a pin joint between two bodies. If not specified, the second body is assumed to be the joint itself.
@@ -31061,18 +31157,18 @@
This class contains the shape and other parameters for intersection/collision queries.
</description>
<methods>
- <method name="get_exclude" qualifiers="const">
- <return type="Array">
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
</return>
<description>
- Return the list of objects, or object [RID]s, that will be excluded from collisions.
+ Return the physics layer the shape belongs to.
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
+ <method name="get_exclude" qualifiers="const">
+ <return type="Array">
</return>
<description>
- Return the physics layer(s) the shape belongs to.
+ Return the list of objects, or object [RID]s, that will be excluded from collisions.
</description>
</method>
<method name="get_margin" qualifiers="const">
@@ -31110,18 +31206,18 @@
Return the transform matrix of the shape queried.
</description>
</method>
- <method name="set_exclude">
- <argument index="0" name="exclude" type="Array">
+ <method name="set_collision_layer">
+ <argument index="0" name="collision_layer" type="int">
</argument>
<description>
- Set the list of objects, or object [RID]s, that will be excluded from collisions.
+ Set the physics layer the shape belongs to.
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="layer_mask" type="int">
+ <method name="set_exclude">
+ <argument index="0" name="exclude" type="Array">
</argument>
<description>
- Set the physics layer(s) the shape belongs to.
+ Set the list of objects, or object [RID]s, that will be excluded from collisions.
</description>
</method>
<method name="set_margin">
@@ -31437,7 +31533,7 @@
</description>
</method>
<method name="set_collision_layer">
- <argument index="0" name="mask" type="int">
+ <argument index="0" name="layer" type="int">
</argument>
<description>
Set the physics layers this area is in.
@@ -31767,9 +31863,9 @@
</argument>
<argument index="1" name="to" type="Vector3">
</argument>
- <argument index="2" name="exclude" type="Array" default="Array()">
+ <argument index="2" name="exclude" type="Array" default="[]">
</argument>
- <argument index="3" name="layer_mask" type="int" default="2147483647">
+ <argument index="3" name="collision_layer" type="int" default="2147483647">
</argument>
<argument index="4" name="type_mask" type="int" default="15">
</argument>
@@ -31922,15 +32018,15 @@
<description>
</description>
</method>
- <method name="area_set_collision_mask">
+ <method name="area_set_collision_layer">
<argument index="0" name="area" type="RID">
</argument>
- <argument index="1" name="mask" type="int">
+ <argument index="1" name="layer" type="int">
</argument>
<description>
</description>
</method>
- <method name="area_set_layer_mask">
+ <method name="area_set_collision_mask">
<argument index="0" name="area" type="RID">
</argument>
<argument index="1" name="mask" type="int">
@@ -32078,23 +32174,19 @@
<description>
</description>
</method>
- <method name="body_get_collision_mask" qualifiers="const">
+ <method name="body_get_collision_layer" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="arg1" type="int">
- </argument>
<description>
</description>
</method>
- <method name="body_get_layer_mask" qualifiers="const">
+ <method name="body_get_collision_mask" qualifiers="const">
<return type="int">
</return>
<argument index="0" name="body" type="RID">
</argument>
- <argument index="1" name="arg1" type="int">
- </argument>
<description>
</description>
</method>
@@ -32232,6 +32324,14 @@
<description>
</description>
</method>
+ <method name="body_set_collision_layer">
+ <argument index="0" name="body" type="RID">
+ </argument>
+ <argument index="1" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="body_set_collision_mask">
<argument index="0" name="body" type="RID">
</argument>
@@ -32260,14 +32360,6 @@
<description>
</description>
</method>
- <method name="body_set_layer_mask">
- <argument index="0" name="body" type="RID">
- </argument>
- <argument index="1" name="mask" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="body_set_max_contacts_reported">
<argument index="0" name="body" type="RID">
</argument>
@@ -32959,14 +33051,14 @@
<description>
</description>
<methods>
- <method name="get_exclude" qualifiers="const">
- <return type="Array">
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
</return>
<description>
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
+ <method name="get_exclude" qualifiers="const">
+ <return type="Array">
</return>
<description>
</description>
@@ -32995,14 +33087,14 @@
<description>
</description>
</method>
- <method name="set_exclude">
- <argument index="0" name="exclude" type="Array">
+ <method name="set_collision_layer">
+ <argument index="0" name="collision_layer" type="int">
</argument>
<description>
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="layer_mask" type="int">
+ <method name="set_exclude">
+ <argument index="0" name="exclude" type="Array">
</argument>
<description>
</description>
@@ -33313,6 +33405,60 @@
<constants>
</constants>
</class>
+<class name="PlaneMesh" inherits="PrimitiveMesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_size" qualifiers="const">
+ <return type="Vector2">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_depth" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_size">
+ <argument index="0" name="size" type="Vector2">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_depth">
+ <argument index="0" name="subdivide" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_width">
+ <argument index="0" name="subdivide" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ </member>
+ <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief="">
+ </member>
+ <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="PlaneShape" inherits="Shape" category="Core">
<brief_description>
</brief_description>
@@ -33640,6 +33786,26 @@
Append an [PoolByteArray] at the end of this array.
</description>
</method>
+ <method name="compress">
+ <return type="PoolByteArray">
+ </return>
+ <argument index="0" name="compression_mode" type="int" default="0">
+ </argument>
+ <description>
+ Returns a new [PoolByteArray] with the data compressed. The compression mode can be set using one of the COMPRESS_* constants of [File].
+ </description>
+ </method>
+ <method name="decompress">
+ <return type="PoolByteArray">
+ </return>
+ <argument index="0" name="buffer_size" type="int">
+ </argument>
+ <argument index="1" name="compression_mode" type="int" default="0">
+ </argument>
+ <description>
+ Returns a new [PoolByteArray] with the data decompressed. The buffer_size should be set as the size of the uncompressed data. The compression mode can be set using one of the COMPRESS_* constants of [File].
+ </description>
+ </method>
<method name="get_string_from_ascii">
<return type="String">
</return>
@@ -34900,195 +35066,455 @@
<constants>
</constants>
</class>
-<class name="ProgressBar" inherits="Range" category="Core">
+<class name="PrimitiveMesh" inherits="Mesh" category="Core">
<brief_description>
- General purpose progress bar.
</brief_description>
<description>
- General purpose progress bar. Shows fill percentage from right to left.
</description>
<methods>
- <method name="is_percent_visible" qualifiers="const">
- <return type="bool">
+ <method name="get_material" qualifiers="const">
+ <return type="Material">
</return>
<description>
</description>
</method>
- <method name="set_percent_visible">
- <argument index="0" name="visible" type="bool">
+ <method name="set_material">
+ <argument index="0" name="material" type="Material">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="percent_visible" type="bool" setter="set_percent_visible" getter="is_percent_visible" brief="">
+ <member name="material" type="Material" setter="set_material" getter="get_material" brief="">
</member>
</members>
<constants>
</constants>
- <theme_items>
- <theme_item name="bg" type="StyleBox">
- </theme_item>
- <theme_item name="fg" type="StyleBox">
- </theme_item>
- <theme_item name="font" type="Font">
- </theme_item>
- <theme_item name="font_color" type="Color">
- </theme_item>
- <theme_item name="font_color_shadow" type="Color">
- </theme_item>
- </theme_items>
</class>
-<class name="ProximityGroup" inherits="Spatial" category="Core">
+<class name="PrismMesh" inherits="PrimitiveMesh" category="Core">
<brief_description>
- General purpose proximity-detection node.
</brief_description>
<description>
- General purpose proximity-detection node.
</description>
<methods>
- <method name="broadcast">
- <argument index="0" name="name" type="String">
- </argument>
- <argument index="1" name="parameters" type="Variant">
- </argument>
+ <method name="get_left_to_right" qualifiers="const">
+ <return type="float">
+ </return>
<description>
</description>
</method>
- <method name="get_grid_radius" qualifiers="const">
+ <method name="get_size" qualifiers="const">
<return type="Vector3">
</return>
<description>
</description>
</method>
- <method name="set_dispatch_mode">
- <argument index="0" name="mode" type="int">
+ <method name="get_subdivide_depth" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_height" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_subdivide_width" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_left_to_right">
+ <argument index="0" name="left_to_right" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_grid_radius">
- <argument index="0" name="radius" type="Vector3">
+ <method name="set_size">
+ <argument index="0" name="size" type="Vector3">
</argument>
<description>
</description>
</method>
- <method name="set_group_name">
- <argument index="0" name="name" type="String">
+ <method name="set_subdivide_depth">
+ <argument index="0" name="segments" type="int">
</argument>
<description>
</description>
</method>
- </methods>
- <members>
- <member name="grid_radius" type="Vector3" setter="set_grid_radius" getter="get_grid_radius" brief="">
- </member>
- </members>
- <signals>
- <signal name="broadcast">
- <argument index="0" name="name" type="String">
+ <method name="set_subdivide_height">
+ <argument index="0" name="segments" type="int">
</argument>
- <argument index="1" name="parameters" type="Array">
+ <description>
+ </description>
+ </method>
+ <method name="set_subdivide_width">
+ <argument index="0" name="segments" type="int">
</argument>
<description>
</description>
- </signal>
- </signals>
+ </method>
+ </methods>
+ <members>
+ <member name="left_to_right" type="float" setter="set_left_to_right" getter="get_left_to_right" brief="">
+ </member>
+ <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ </member>
+ <member name="subdivide_depth" type="int" setter="set_subdivide_depth" getter="get_subdivide_depth" brief="">
+ </member>
+ <member name="subdivide_height" type="int" setter="set_subdivide_height" getter="get_subdivide_height" brief="">
+ </member>
+ <member name="subdivide_width" type="int" setter="set_subdivide_width" getter="get_subdivide_width" brief="">
+ </member>
+ </members>
<constants>
</constants>
</class>
-<class name="Quad" inherits="GeometryInstance" category="Core">
+<class name="ProceduralSky" inherits="Sky" category="Core">
<brief_description>
</brief_description>
<description>
</description>
<methods>
- <method name="get_axis" qualifiers="const">
- <return type="int">
+ <method name="get_ground_bottom_color" qualifiers="const">
+ <return type="Color">
</return>
<description>
</description>
</method>
- <method name="get_offset" qualifiers="const">
- <return type="Vector2">
+ <method name="get_ground_curve" qualifiers="const">
+ <return type="float">
</return>
<description>
</description>
</method>
- <method name="get_size" qualifiers="const">
- <return type="Vector2">
+ <method name="get_ground_energy" qualifiers="const">
+ <return type="float">
</return>
<description>
</description>
</method>
- <method name="is_centered" qualifiers="const">
- <return type="bool">
+ <method name="get_ground_horizon_color" qualifiers="const">
+ <return type="Color">
</return>
<description>
</description>
</method>
- <method name="set_axis">
- <argument index="0" name="axis" type="int">
+ <method name="get_sky_curve" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sky_energy" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sky_horizon_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sky_top_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_angle_max" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_angle_min" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_color" qualifiers="const">
+ <return type="Color">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_curve" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_energy" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_latitude" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_sun_longitude" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_texture_size" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_ground_bottom_color">
+ <argument index="0" name="color" type="Color">
</argument>
<description>
</description>
</method>
- <method name="set_centered">
- <argument index="0" name="centered" type="bool">
+ <method name="set_ground_curve">
+ <argument index="0" name="curve" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_offset">
- <argument index="0" name="offset" type="Vector2">
+ <method name="set_ground_energy">
+ <argument index="0" name="energy" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_size">
- <argument index="0" name="size" type="Vector2">
+ <method name="set_ground_horizon_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sky_curve">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sky_energy">
+ <argument index="0" name="energy" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sky_horizon_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sky_top_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_angle_max">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_angle_min">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_color">
+ <argument index="0" name="color" type="Color">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_curve">
+ <argument index="0" name="curve" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_energy">
+ <argument index="0" name="energy" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_latitude">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_sun_longitude">
+ <argument index="0" name="degrees" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_texture_size">
+ <argument index="0" name="size" type="int">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="axis" type="int" setter="set_axis" getter="get_axis" brief="">
+ <member name="ground_bottom_color" type="Color" setter="set_ground_bottom_color" getter="get_ground_bottom_color" brief="">
</member>
- <member name="centered" type="bool" setter="set_centered" getter="is_centered" brief="">
+ <member name="ground_curve" type="float" setter="set_ground_curve" getter="get_ground_curve" brief="">
</member>
- <member name="offset" type="Vector2" setter="set_offset" getter="get_offset" brief="">
+ <member name="ground_energy" type="float" setter="set_ground_energy" getter="get_ground_energy" brief="">
</member>
- <member name="size" type="Vector2" setter="set_size" getter="get_size" brief="">
+ <member name="ground_horizon_color" type="Color" setter="set_ground_horizon_color" getter="get_ground_horizon_color" brief="">
+ </member>
+ <member name="sky_curve" type="float" setter="set_sky_curve" getter="get_sky_curve" brief="">
+ </member>
+ <member name="sky_energy" type="float" setter="set_sky_energy" getter="get_sky_energy" brief="">
+ </member>
+ <member name="sky_horizon_color" type="Color" setter="set_sky_horizon_color" getter="get_sky_horizon_color" brief="">
+ </member>
+ <member name="sky_top_color" type="Color" setter="set_sky_top_color" getter="get_sky_top_color" brief="">
+ </member>
+ <member name="sun_angle_max" type="float" setter="set_sun_angle_max" getter="get_sun_angle_max" brief="">
+ </member>
+ <member name="sun_angle_min" type="float" setter="set_sun_angle_min" getter="get_sun_angle_min" brief="">
+ </member>
+ <member name="sun_color" type="Color" setter="set_sun_color" getter="get_sun_color" brief="">
+ </member>
+ <member name="sun_curve" type="float" setter="set_sun_curve" getter="get_sun_curve" brief="">
+ </member>
+ <member name="sun_energy" type="float" setter="set_sun_energy" getter="get_sun_energy" brief="">
+ </member>
+ <member name="sun_latitude" type="float" setter="set_sun_latitude" getter="get_sun_latitude" brief="">
+ </member>
+ <member name="sun_longitude" type="float" setter="set_sun_longitude" getter="get_sun_longitude" brief="">
+ </member>
+ <member name="texture_size" type="int" setter="set_texture_size" getter="get_texture_size" brief="">
</member>
</members>
<constants>
</constants>
</class>
-<class name="QuadMesh" inherits="Mesh" category="Core">
+<class name="ProgressBar" inherits="Range" category="Core">
<brief_description>
+ General purpose progress bar.
</brief_description>
<description>
+ General purpose progress bar. Shows fill percentage from right to left.
</description>
<methods>
- <method name="get_material" qualifiers="const">
- <return type="Material">
+ <method name="is_percent_visible" qualifiers="const">
+ <return type="bool">
</return>
<description>
</description>
</method>
- <method name="set_material">
- <argument index="0" name="material" type="Material">
+ <method name="set_percent_visible">
+ <argument index="0" name="visible" type="bool">
</argument>
<description>
</description>
</method>
</methods>
<members>
- <member name="material" type="Material" setter="set_material" getter="get_material" brief="">
+ <member name="percent_visible" type="bool" setter="set_percent_visible" getter="is_percent_visible" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+ <theme_items>
+ <theme_item name="bg" type="StyleBox">
+ </theme_item>
+ <theme_item name="fg" type="StyleBox">
+ </theme_item>
+ <theme_item name="font" type="Font">
+ </theme_item>
+ <theme_item name="font_color" type="Color">
+ </theme_item>
+ <theme_item name="font_color_shadow" type="Color">
+ </theme_item>
+ </theme_items>
+</class>
+<class name="ProximityGroup" inherits="Spatial" category="Core">
+ <brief_description>
+ General purpose proximity-detection node.
+ </brief_description>
+ <description>
+ General purpose proximity-detection node.
+ </description>
+ <methods>
+ <method name="broadcast">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="parameters" type="Variant">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="get_grid_radius" qualifiers="const">
+ <return type="Vector3">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_dispatch_mode">
+ <argument index="0" name="mode" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_grid_radius">
+ <argument index="0" name="radius" type="Vector3">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_group_name">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="grid_radius" type="Vector3" setter="set_grid_radius" getter="get_grid_radius" brief="">
</member>
</members>
+ <signals>
+ <signal name="broadcast">
+ <argument index="0" name="name" type="String">
+ </argument>
+ <argument index="1" name="parameters" type="Array">
+ </argument>
+ <description>
+ </description>
+ </signal>
+ </signals>
+ <constants>
+ </constants>
+</class>
+<class name="QuadMesh" inherits="PrimitiveMesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ </methods>
<constants>
</constants>
</class>
@@ -35164,6 +35590,13 @@
Returns the inverse of the quaternion.
</description>
</method>
+ <method name="is_normalized">
+ <return type="bool">
+ </return>
+ <description>
+ Returns whether the quaternion is normalized or not.
+ </description>
+ </method>
<method name="length">
<return type="float">
</return>
@@ -35185,13 +35618,6 @@
Returns a copy of the quaternion, normalized to unit length.
</description>
</method>
- <method name="is_normalized">
- <return type="bool">
- </return>
- <description>
- Returns whether the quaternion is normalized or not.
- </description>
- </method>
<method name="slerp">
<return type="Quat">
</return>
@@ -35478,6 +35904,13 @@
Returns the collision shape of the closest object the ray is pointing to.
</description>
</method>
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the collision layer for this ray.
+ </description>
+ </method>
<method name="get_collision_normal" qualifiers="const">
<return type="Vector3">
</return>
@@ -35492,13 +35925,6 @@
Returns collision point. This point is in [b]global[/b] coordinate system.
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the layer mask for this ray.
- </description>
- </method>
<method name="get_type_mask" qualifiers="const">
<return type="int">
</return>
@@ -35540,18 +35966,18 @@
Sets to which point ray should be casted. This point is in [b]local[/b] coordinate system.
</description>
</method>
- <method name="set_enabled">
- <argument index="0" name="enabled" type="bool">
+ <method name="set_collision_layer">
+ <argument index="0" name="layer" type="int">
</argument>
<description>
- Enables the RayCast2D. Only enabled raycasts will be able to query the space and report collisions.
+ Set the mask to filter objects. Only objects with at least the same mask element set will be detected.
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="mask" type="int">
+ <method name="set_enabled">
+ <argument index="0" name="enabled" type="bool">
</argument>
<description>
- Set the mask to filter objects. Only objects with at least the same mask element set will be detected.
+ Enables the RayCast2D. Only enabled raycasts will be able to query the space and report collisions.
</description>
</method>
<method name="set_type_mask">
@@ -35565,9 +35991,9 @@
<members>
<member name="cast_to" type="Vector3" setter="set_cast_to" getter="get_cast_to" brief="">
</member>
- <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief="">
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
- <member name="layer_mask" type="int" setter="set_layer_mask" getter="get_layer_mask" brief="">
+ <member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief="">
</member>
<member name="type_mask" type="int" setter="set_type_mask" getter="get_type_mask" brief="">
</member>
@@ -35633,6 +36059,13 @@
Returns the collision shape of the closest object the ray is pointing to.
</description>
</method>
+ <method name="get_collision_layer" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ Returns the collision layer for this ray.
+ </description>
+ </method>
<method name="get_collision_normal" qualifiers="const">
<return type="Vector2">
</return>
@@ -35654,13 +36087,6 @@
Returns whether this ray should hit your parent node, if it's a body.
</description>
</method>
- <method name="get_layer_mask" qualifiers="const">
- <return type="int">
- </return>
- <description>
- Returns the layer mask for this ray.
- </description>
- </method>
<method name="get_type_mask" qualifiers="const">
<return type="int">
</return>
@@ -35702,6 +36128,13 @@
Sets the ray destination point, so that the ray will test from the ray's origin to [code]local_point[/code]
</description>
</method>
+ <method name="set_collision_layer">
+ <argument index="0" name="layer" type="int">
+ </argument>
+ <description>
+ Set the mask to filter objects. Only objects with at least the same mask element set will be detected.
+ </description>
+ </method>
<method name="set_enabled">
<argument index="0" name="enabled" type="bool">
</argument>
@@ -35716,13 +36149,6 @@
Toggle whether this ray should hit your parent node, if it's a body.
</description>
</method>
- <method name="set_layer_mask">
- <argument index="0" name="mask" type="int">
- </argument>
- <description>
- Set the mask to filter objects. Only objects with at least the same mask element set will be detected.
- </description>
- </method>
<method name="set_type_mask">
<argument index="0" name="mask" type="int">
</argument>
@@ -35734,12 +36160,12 @@
<members>
<member name="cast_to" type="Vector2" setter="set_cast_to" getter="get_cast_to" brief="">
</member>
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
+ </member>
<member name="enabled" type="bool" setter="set_enabled" getter="is_enabled" brief="">
</member>
<member name="exclude_parent" type="bool" setter="set_exclude_parent_body" getter="get_exclude_parent_body" brief="">
</member>
- <member name="layer_mask" type="int" setter="set_layer_mask" getter="get_layer_mask" brief="">
- </member>
<member name="type_mask" type="int" setter="set_type_mask" getter="get_type_mask" brief="">
</member>
</members>
@@ -35879,6 +36305,30 @@
Return a copy of the [Rect2] grown a given amount of units towards all the sides.
</description>
</method>
+ <method name="grow_individual">
+ <return type="Rect2">
+ </return>
+ <argument index="0" name="left" type="float">
+ </argument>
+ <argument index="1" name="top" type="float">
+ </argument>
+ <argument index="2" name="right" type="float">
+ </argument>
+ <argument index="3" name=" bottom" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="grow_margin">
+ <return type="Rect2">
+ </return>
+ <argument index="0" name="margin" type="int">
+ </argument>
+ <argument index="1" name="by" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="has_no_area">
<return type="bool">
</return>
@@ -35918,8 +36368,7 @@
<member name="end" type="Vector2" setter="" getter="" brief="">
Ending corner.
</member>
- <member name="pos" type="Vector2" setter="" getter="" brief="">
- Position (starting corner).
+ <member name="position" type="Vector2" setter="" getter="" brief="">
</member>
<member name="size" type="Vector2" setter="" getter="" brief="">
Size from position to end.
@@ -36635,7 +37084,7 @@
<description>
</description>
</method>
- <method name="duplicate">
+ <method name="duplicate" qualifiers="const">
<return type="Object">
</return>
<argument index="0" name="subresources" type="bool" default="false">
@@ -36778,7 +37227,7 @@
<return type="int">
</return>
<description>
- Poll the load. If OK is returned, this means poll will have to be called again. If ERR_EOF is returned, them the load has finished and the resource can be obtained by calling [method get_resource].
+ Poll the load. If OK is returned, this means poll will have to be called again. If ERR_FILE_EOF is returned, them the load has finished and the resource can be obtained by calling [method get_resource].
</description>
</method>
<method name="wait">
@@ -39411,7 +39860,7 @@
</constant>
</constants>
</class>
-<class name="SkyBox" inherits="Resource" category="Core">
+<class name="Sky" inherits="Resource" category="Core">
<brief_description>
</brief_description>
<description>
@@ -39963,12 +40412,30 @@
<description>
</description>
</method>
+ <method name="get_depth_deep_parallax_max_layers" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_depth_deep_parallax_min_layers" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_depth_draw_mode" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
+ <method name="get_depth_scale" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_detail_blend_mode" qualifiers="const">
<return type="int">
</return>
@@ -40015,19 +40482,13 @@
<description>
</description>
</method>
- <method name="get_height_scale" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
<method name="get_line_width" qualifiers="const">
<return type="float">
</return>
<description>
</description>
</method>
- <method name="get_metalness" qualifiers="const">
+ <method name="get_metallic" qualifiers="const">
<return type="float">
</return>
<description>
@@ -40069,12 +40530,6 @@
<description>
</description>
</method>
- <method name="get_refraction_roughness" qualifiers="const">
- <return type="float">
- </return>
- <description>
- </description>
- </method>
<method name="get_rim" qualifiers="const">
<return type="float">
</return>
@@ -40094,13 +40549,7 @@
</description>
</method>
<method name="get_specular" qualifiers="const">
- <return type="Color">
- </return>
- <description>
- </description>
- </method>
- <method name="get_specular_mode" qualifiers="const">
- <return type="int">
+ <return type="float">
</return>
<description>
</description>
@@ -40143,6 +40592,12 @@
<description>
</description>
</method>
+ <method name="is_depth_deep_parallax_enabled" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="set_albedo">
<argument index="0" name="albedo" type="Color">
</argument>
@@ -40185,12 +40640,36 @@
<description>
</description>
</method>
+ <method name="set_depth_deep_parallax">
+ <argument index="0" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_depth_deep_parallax_max_layers">
+ <argument index="0" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_depth_deep_parallax_min_layers">
+ <argument index="0" name="layer" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_depth_draw_mode">
<argument index="0" name="depth_draw_mode" type="int">
</argument>
<description>
</description>
</method>
+ <method name="set_depth_scale">
+ <argument index="0" name="depth_scale" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_detail_blend_mode">
<argument index="0" name="detail_blend_mode" type="int">
</argument>
@@ -40237,20 +40716,14 @@
<description>
</description>
</method>
- <method name="set_height_scale">
- <argument index="0" name="height_scale" type="float">
- </argument>
- <description>
- </description>
- </method>
<method name="set_line_width">
<argument index="0" name="line_width" type="float">
</argument>
<description>
</description>
</method>
- <method name="set_metalness">
- <argument index="0" name="metalness" type="float">
+ <method name="set_metallic">
+ <argument index="0" name="metallic" type="float">
</argument>
<description>
</description>
@@ -40291,12 +40764,6 @@
<description>
</description>
</method>
- <method name="set_refraction_roughness">
- <argument index="0" name="refraction_roughness" type="float">
- </argument>
- <description>
- </description>
- </method>
<method name="set_rim">
<argument index="0" name="rim" type="float">
</argument>
@@ -40316,13 +40783,7 @@
</description>
</method>
<method name="set_specular">
- <argument index="0" name="specular" type="Color">
- </argument>
- <description>
- </description>
- </method>
- <method name="set_specular_mode">
- <argument index="0" name="specular_mode" type="int">
+ <argument index="0" name="specular" type="float">
</argument>
<description>
</description>
@@ -40389,6 +40850,18 @@
</member>
<member name="clearcoat_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
+ <member name="depth_deep_parallax" type="bool" setter="set_depth_deep_parallax" getter="is_depth_deep_parallax_enabled" brief="">
+ </member>
+ <member name="depth_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
+ </member>
+ <member name="depth_max_layers" type="int" setter="set_depth_deep_parallax_max_layers" getter="get_depth_deep_parallax_max_layers" brief="">
+ </member>
+ <member name="depth_min_layers" type="int" setter="set_depth_deep_parallax_min_layers" getter="get_depth_deep_parallax_min_layers" brief="">
+ </member>
+ <member name="depth_scale" type="float" setter="set_depth_scale" getter="get_depth_scale" brief="">
+ </member>
+ <member name="depth_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
+ </member>
<member name="detail_albedo" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
<member name="detail_blend_mode" type="int" setter="set_detail_blend_mode" getter="get_detail_blend_mode" brief="">
@@ -40419,11 +40892,11 @@
</member>
<member name="flags_use_point_size" type="bool" setter="set_flag" getter="get_flag" brief="">
</member>
- <member name="height_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
+ <member name="metallic_amount" type="float" setter="set_metallic" getter="get_metallic" brief="">
</member>
- <member name="height_scale" type="float" setter="set_height_scale" getter="get_height_scale" brief="">
+ <member name="metallic_specular" type="float" setter="set_specular" getter="get_specular" brief="">
</member>
- <member name="height_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
+ <member name="metallic_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
<member name="normal_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40451,11 +40924,9 @@
</member>
<member name="particles_anim_v_frames" type="int" setter="set_particles_anim_v_frames" getter="get_particles_anim_v_frames" brief="">
</member>
- <member name="refraction_displacement" type="float" setter="set_refraction" getter="get_refraction" brief="">
- </member>
<member name="refraction_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
- <member name="refraction_roughness" type="float" setter="set_refraction_roughness" getter="get_refraction_roughness" brief="">
+ <member name="refraction_scale" type="float" setter="set_refraction" getter="get_refraction" brief="">
</member>
<member name="refraction_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
@@ -40467,15 +40938,9 @@
</member>
<member name="rim_tint" type="float" setter="set_rim_tint" getter="get_rim_tint" brief="">
</member>
- <member name="specular_color" type="Color" setter="set_specular" getter="get_specular" brief="">
- </member>
- <member name="specular_metalness" type="float" setter="set_metalness" getter="get_metalness" brief="">
- </member>
- <member name="specular_mode" type="int" setter="set_specular_mode" getter="get_specular_mode" brief="">
+ <member name="roughness_amount" type="float" setter="set_roughness" getter="get_roughness" brief="">
</member>
- <member name="specular_roughness" type="float" setter="set_roughness" getter="get_roughness" brief="">
- </member>
- <member name="specular_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
+ <member name="roughness_texture" type="Texture" setter="set_texture" getter="get_texture" brief="">
</member>
<member name="subsurf_scatter_enabled" type="bool" setter="set_feature" getter="get_feature" brief="">
</member>
@@ -40499,27 +40964,27 @@
<constants>
<constant name="TEXTURE_ALBEDO" value="0">
</constant>
- <constant name="TEXTURE_SPECULAR" value="1">
+ <constant name="TEXTURE_METALLIC" value="1">
</constant>
- <constant name="TEXTURE_EMISSION" value="2">
+ <constant name="TEXTURE_ROUGHNESS" value="2">
</constant>
- <constant name="TEXTURE_NORMAL" value="3">
+ <constant name="TEXTURE_EMISSION" value="3">
</constant>
- <constant name="TEXTURE_RIM" value="4">
+ <constant name="TEXTURE_NORMAL" value="4">
</constant>
- <constant name="TEXTURE_CLEARCOAT" value="5">
+ <constant name="TEXTURE_RIM" value="5">
</constant>
- <constant name="TEXTURE_FLOWMAP" value="6">
+ <constant name="TEXTURE_CLEARCOAT" value="6">
</constant>
- <constant name="TEXTURE_AMBIENT_OCCLUSION" value="7">
+ <constant name="TEXTURE_FLOWMAP" value="7">
</constant>
- <constant name="TEXTURE_HEIGHT" value="8">
+ <constant name="TEXTURE_AMBIENT_OCCLUSION" value="8">
</constant>
- <constant name="TEXTURE_SUBSURFACE_SCATTERING" value="9">
+ <constant name="TEXTURE_DEPTH" value="9">
</constant>
- <constant name="TEXTURE_REFRACTION" value="10">
+ <constant name="TEXTURE_SUBSURFACE_SCATTERING" value="10">
</constant>
- <constant name="TEXTURE_REFRACTION_ROUGHNESS" value="11">
+ <constant name="TEXTURE_REFRACTION" value="11">
</constant>
<constant name="TEXTURE_DETAIL_MASK" value="12">
</constant>
@@ -40547,7 +41012,7 @@
</constant>
<constant name="FEATURE_AMBIENT_OCCLUSION" value="6">
</constant>
- <constant name="FEATURE_HEIGHT_MAPPING" value="7">
+ <constant name="FEATURE_DEPTH_MAPPING" value="7">
</constant>
<constant name="FEATURE_SUBSURACE_SCATTERING" value="8">
</constant>
@@ -40595,16 +41060,12 @@
</constant>
<constant name="DIFFUSE_LAMBERT" value="0">
</constant>
- <constant name="DIFFUSE_LAMBERT_WRAP" value="1">
+ <constant name="DIFFUSE_HALF_LAMBERT" value="1">
</constant>
<constant name="DIFFUSE_OREN_NAYAR" value="2">
</constant>
<constant name="DIFFUSE_BURLEY" value="3">
</constant>
- <constant name="SPECULAR_MODE_METALLIC" value="0">
- </constant>
- <constant name="SPECULAR_MODE_SPECULAR" value="1">
- </constant>
<constant name="BILLBOARD_DISABLED" value="0">
</constant>
<constant name="BILLBOARD_ENABLED" value="1">
@@ -40615,6 +41076,88 @@
</constant>
</constants>
</class>
+<class name="SphereMesh" inherits="PrimitiveMesh" category="Core">
+ <brief_description>
+ </brief_description>
+ <description>
+ </description>
+ <methods>
+ <method name="get_height" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_is_hemisphere" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_radial_segments" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_radius" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="get_rings" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
+ <method name="set_height">
+ <argument index="0" name="height" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_is_hemisphere">
+ <argument index="0" name="is_hemisphere" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_radial_segments">
+ <argument index="0" name="radial_segments" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_radius">
+ <argument index="0" name="radius" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
+ <method name="set_rings">
+ <argument index="0" name="rings" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
+ </methods>
+ <members>
+ <member name="height" type="float" setter="set_height" getter="get_height" brief="">
+ </member>
+ <member name="is_hemisphere" type="bool" setter="set_is_hemisphere" getter="get_is_hemisphere" brief="">
+ </member>
+ <member name="radial_segments" type="int" setter="set_radial_segments" getter="get_radial_segments" brief="">
+ </member>
+ <member name="radius" type="float" setter="set_radius" getter="get_radius" brief="">
+ </member>
+ <member name="rings" type="int" setter="set_rings" getter="get_rings" brief="">
+ </member>
+ </members>
+ <constants>
+ </constants>
+</class>
<class name="SphereShape" inherits="Shape" category="Core">
<brief_description>
</brief_description>
@@ -41840,7 +42383,7 @@
<description>
</description>
</method>
- <method name="get_position" qualifiers="const">
+ <method name="get_pos" qualifiers="const">
<return type="int">
</return>
<description>
@@ -42157,14 +42700,6 @@
<method name="String">
<return type="String">
</return>
- <argument index="0" name="from" type="InputEvent">
- </argument>
- <description>
- </description>
- </method>
- <method name="String">
- <return type="String">
- </return>
<argument index="0" name="from" type="Dictionary">
</argument>
<description>
@@ -43151,7 +43686,7 @@
</argument>
<argument index="4" name="normals" type="PoolVector3Array" default="PoolVector3Array([])">
</argument>
- <argument index="5" name="tangents" type="Array" default="Array()">
+ <argument index="5" name="tangents" type="Array" default="[]">
</argument>
<description>
Insert a triangle fan made of array data into [Mesh] being constructed.
@@ -43454,7 +43989,7 @@
<theme_items>
<theme_item name="decrement" type="Texture">
</theme_item>
- <theme_item name="decrement_hilite" type="Texture">
+ <theme_item name="decrement_highlight" type="Texture">
</theme_item>
<theme_item name="font" type="Font">
</theme_item>
@@ -43468,7 +44003,7 @@
</theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
- <theme_item name="increment_hilite" type="Texture">
+ <theme_item name="increment_highlight" type="Texture">
</theme_item>
<theme_item name="label_valign_bg" type="int">
</theme_item>
@@ -43476,7 +44011,7 @@
</theme_item>
<theme_item name="menu" type="Texture">
</theme_item>
- <theme_item name="menu_hilite" type="Texture">
+ <theme_item name="menu_highlight" type="Texture">
</theme_item>
<theme_item name="panel" type="StyleBox">
</theme_item>
@@ -43484,8 +44019,6 @@
</theme_item>
<theme_item name="tab_bg" type="StyleBox">
</theme_item>
- <theme_item name="tab_disabled" type="StyleBox">
- </theme_item>
<theme_item name="tab_fg" type="StyleBox">
</theme_item>
<theme_item name="top_margin" type="int">
@@ -43622,6 +44155,12 @@
<description>
</description>
</signal>
+ <signal name="tab_hover">
+ <argument index="0" name="tab" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
</signals>
<constants>
<constant name="ALIGN_LEFT" value="0">
@@ -43646,7 +44185,7 @@
</theme_item>
<theme_item name="decrement" type="Texture">
</theme_item>
- <theme_item name="decrement_hilite" type="Texture">
+ <theme_item name="decrement_highlight" type="Texture">
</theme_item>
<theme_item name="font" type="Font">
</theme_item>
@@ -43660,7 +44199,7 @@
</theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
- <theme_item name="increment_hilite" type="Texture">
+ <theme_item name="increment_highlight" type="Texture">
</theme_item>
<theme_item name="label_valign_bg" type="int">
</theme_item>
@@ -43670,26 +44209,12 @@
</theme_item>
<theme_item name="tab_bg" type="StyleBox">
</theme_item>
- <theme_item name="tab_disabled" type="StyleBox">
- </theme_item>
<theme_item name="tab_fg" type="StyleBox">
</theme_item>
<theme_item name="top_margin" type="int">
</theme_item>
</theme_items>
</class>
-<class name="TestCube" inherits="GeometryInstance" category="Core">
- <brief_description>
- A simple cube used for testing in 3D.
- </brief_description>
- <description>
- The TestCube is a simple 2x2x2 cube with a basic texture. It can be used as a placeholder, to verify how the lighting looks, to test shaders, or any other task you may need a textured model to test with.
- </description>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
<class name="TextEdit" inherits="Control" category="Core">
<brief_description>
Multiline text editing control.
@@ -43794,7 +44319,7 @@
<method name="cursor_set_column">
<argument index="0" name="column" type="int">
</argument>
- <argument index="1" name="adjust_viewport" type="bool" default="false">
+ <argument index="1" name="adjust_viewport" type="bool" default="true">
</argument>
<description>
</description>
@@ -43802,7 +44327,7 @@
<method name="cursor_set_line">
<argument index="0" name="line" type="int">
</argument>
- <argument index="1" name="adjust_viewport" type="bool" default="false">
+ <argument index="1" name="adjust_viewport" type="bool" default="true">
</argument>
<description>
</description>
@@ -45015,6 +45540,14 @@
Return the collision layer.
</description>
</method>
+ <method name="get_collision_layer_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_collision_mask" qualifiers="const">
<return type="int">
</return>
@@ -45022,6 +45555,14 @@
Return the collision mask.
</description>
</method>
+ <method name="get_collision_mask_bit" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="get_collision_use_kinematic" qualifiers="const">
<return type="bool">
</return>
@@ -45214,13 +45755,21 @@
</description>
</method>
<method name="set_collision_layer">
- <argument index="0" name="mask" type="int">
+ <argument index="0" name="layer" type="int">
</argument>
<description>
Set the collision layer.
Layers are referenced by binary indexes, so allowable values to describe the 20 available layers range from 0 to 2^20-1.
</description>
</method>
+ <method name="set_collision_layer_bit">
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_collision_mask">
<argument index="0" name="mask" type="int">
</argument>
@@ -45229,6 +45778,14 @@
Masks are referenced by binary indexes, so allowable values to describe the 20 available masks range from 0 to 2^20-1.
</description>
</method>
+ <method name="set_collision_mask_bit">
+ <argument index="0" name="bit" type="int">
+ </argument>
+ <argument index="1" name="value" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_collision_use_kinematic">
<argument index="0" name="use_kinematic" type="bool">
</argument>
@@ -45321,7 +45878,7 @@
</member>
<member name="collision_friction" type="float" setter="set_collision_friction" getter="get_collision_friction" brief="">
</member>
- <member name="collision_layers" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
+ <member name="collision_layer" type="int" setter="set_collision_layer" getter="get_collision_layer" brief="">
</member>
<member name="collision_mask" type="int" setter="set_collision_mask" getter="get_collision_mask" brief="">
</member>
@@ -46678,6 +47235,12 @@
Emitted when a cell is selected.
</description>
</signal>
+ <signal name="column_title_pressed">
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ </description>
+ </signal>
<signal name="custom_popup_edited">
<argument index="0" name="arrow_clicked" type="bool">
</argument>
@@ -46704,6 +47267,10 @@
Emitted when an item is collapsed by a click on the folding arrow.
</description>
</signal>
+ <signal name="item_custom_button_pressed">
+ <description>
+ </description>
+ </signal>
<signal name="item_double_clicked">
<description>
</description>
@@ -46771,6 +47338,14 @@
</theme_item>
<theme_item name="cursor_unfocused" type="StyleBox">
</theme_item>
+ <theme_item name="custom_button" type="StyleBox">
+ </theme_item>
+ <theme_item name="custom_button_font_highlight" type="Color">
+ </theme_item>
+ <theme_item name="custom_button_hover" type="StyleBox">
+ </theme_item>
+ <theme_item name="custom_button_pressed" type="StyleBox">
+ </theme_item>
<theme_item name="draw_relationship_lines" type="int">
</theme_item>
<theme_item name="drop_position_color" type="Color">
@@ -46836,6 +47411,8 @@
</argument>
<argument index="3" name="disabled" type="bool" default="false">
</argument>
+ <argument index="4" name="tooltip" type="String" default="&quot;&quot;">
+ </argument>
<description>
</description>
</method>
@@ -47021,6 +47598,14 @@
<description>
</description>
</method>
+ <method name="is_custom_set_as_button" qualifiers="const">
+ <return type="bool">
+ </return>
+ <argument index="0" name="column" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="is_editable">
<return type="bool">
</return>
@@ -47099,6 +47684,14 @@
<description>
</description>
</method>
+ <method name="set_custom_as_button">
+ <argument index="0" name="column" type="int">
+ </argument>
+ <argument index="1" name="enable" type="bool">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_custom_bg_color">
<argument index="0" name="column" type="int">
</argument>
@@ -47826,40 +48419,6 @@ do_property].
</theme_item>
</theme_items>
</class>
-<class name="VButtonArray" inherits="ButtonArray" category="Core">
- <brief_description>
- Vertical button array.
- </brief_description>
- <description>
- Vertical button array. See [ButtonArray].
- </description>
- <methods>
- </methods>
- <constants>
- </constants>
- <theme_items>
- <theme_item name="button_separator" type="int">
- </theme_item>
- <theme_item name="focus" type="StyleBox">
- </theme_item>
- <theme_item name="font" type="Font">
- </theme_item>
- <theme_item name="font_color" type="Color">
- </theme_item>
- <theme_item name="font_color_selected" type="Color">
- </theme_item>
- <theme_item name="font_selected" type="Font">
- </theme_item>
- <theme_item name="hover" type="StyleBox">
- </theme_item>
- <theme_item name="icon_separator" type="int">
- </theme_item>
- <theme_item name="normal" type="StyleBox">
- </theme_item>
- <theme_item name="selected" type="StyleBox">
- </theme_item>
- </theme_items>
-</class>
<class name="VScrollBar" inherits="ScrollBar" category="Core">
<brief_description>
Vertical version of [ScrollBar], which goes from left (min) to right (max).
@@ -47873,15 +48432,15 @@ do_property].
<theme_items>
<theme_item name="decrement" type="Texture">
</theme_item>
- <theme_item name="decrement_hilite" type="Texture">
+ <theme_item name="decrement_highlight" type="Texture">
</theme_item>
<theme_item name="grabber" type="StyleBox">
</theme_item>
- <theme_item name="grabber_hilite" type="StyleBox">
+ <theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
<theme_item name="increment" type="Texture">
</theme_item>
- <theme_item name="increment_hilite" type="Texture">
+ <theme_item name="increment_highlight" type="Texture">
</theme_item>
<theme_item name="scroll" type="StyleBox">
</theme_item>
@@ -47921,9 +48480,9 @@ do_property].
<theme_items>
<theme_item name="grabber" type="Texture">
</theme_item>
- <theme_item name="grabber_hilite" type="Texture">
+ <theme_item name="grabber_highlight" type="Texture">
</theme_item>
- <theme_item name="grabber_hilite" type="StyleBox">
+ <theme_item name="grabber_highlight" type="StyleBox">
</theme_item>
<theme_item name="slider" type="StyleBox">
</theme_item>
@@ -48087,6 +48646,13 @@ do_property].
Remove the fractional part of x and y.
</description>
</method>
+ <method name="is_normalized">
+ <return type="bool">
+ </return>
+ <description>
+ Returns whether the vector is normalized or not.
+ </description>
+ </method>
<method name="length">
<return type="float">
</return>
@@ -48119,13 +48685,6 @@ do_property].
Returns a normalized vector to unit length.
</description>
</method>
- <method name="is_normalized">
- <return type="bool">
- </return>
- <description>
- Returns whether the vector is normalized or not.
- </description>
- </method>
<method name="reflect">
<return type="Vector2">
</return>
@@ -48304,6 +48863,13 @@ do_property].
Returns the inverse of the vector. This is the same as Vector3( 1.0 / v.x, 1.0 / v.y, 1.0 / v.z )
</description>
</method>
+ <method name="is_normalized">
+ <return type="bool">
+ </return>
+ <description>
+ Returns whether the vector is normalized or not.
+ </description>
+ </method>
<method name="length">
<return type="float">
</return>
@@ -48350,13 +48916,6 @@ do_property].
Return a copy of the normalized vector to unit length. This is the same as v / v.length().
</description>
</method>
- <method name="is_normalized">
- <return type="bool">
- </return>
- <description>
- Returns whether the vector is normalized or not.
- </description>
- </method>
<method name="outer">
<return type="Basis">
</return>
@@ -48560,6 +49119,12 @@ do_property].
<description>
</description>
</method>
+ <method name="get_roll_influence" qualifiers="const">
+ <return type="float">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_suspension_max_force" qualifiers="const">
<return type="float">
</return>
@@ -48584,6 +49149,12 @@ do_property].
<description>
</description>
</method>
+ <method name="is_in_contact" qualifiers="const">
+ <return type="bool">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="is_used_as_steering" qualifiers="const">
<return type="bool">
</return>
@@ -48620,6 +49191,12 @@ do_property].
<description>
</description>
</method>
+ <method name="set_roll_influence">
+ <argument index="0" name="roll_influence" type="float">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_suspension_max_force">
<argument index="0" name="length" type="float">
</argument>
@@ -48678,6 +49255,8 @@ do_property].
</member>
<member name="wheel_rest_length" type="float" setter="set_suspension_rest_length" getter="get_suspension_rest_length" brief="">
</member>
+ <member name="wheel_roll_influence" type="float" setter="set_roll_influence" getter="get_roll_influence" brief="">
+ </member>
</members>
<constants>
</constants>
@@ -48921,6 +49500,12 @@ do_property].
Return whether automatic clearing of the render target on each frame is enabled.
</description>
</method>
+ <method name="get_debug_draw" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_final_transform" qualifiers="const">
<return type="Transform2D">
</return>
@@ -48962,11 +49547,12 @@ do_property].
Get whether picking for all physics objects inside the viewport is enabled.
</description>
</method>
- <method name="get_screen_capture" qualifiers="const">
- <return type="Image">
+ <method name="get_render_info">
+ <return type="int">
</return>
+ <argument index="0" name="info" type="int">
+ </argument>
<description>
- Return the captured screenshot after [method queue_screen_capture]. You might need to check more than one frame until the right image is returned.
</description>
</method>
<method name="get_shadow_atlas_quadrant_subdiv" qualifiers="const">
@@ -49011,6 +49597,12 @@ do_property].
Get when the viewport would be updated, will be one of the [code]UPDATE_*[/code] constants.
</description>
</method>
+ <method name="get_usage" qualifiers="const">
+ <return type="int">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_vflip" qualifiers="const">
<return type="bool">
</return>
@@ -49068,7 +49660,7 @@ do_property].
</description>
</method>
<method name="input">
- <argument index="0" name="local_event" type="InputEvent">
+ <argument index="0" name="local_event" type="Object">
</argument>
<description>
</description>
@@ -49121,11 +49713,6 @@ do_property].
Return whether the viewport is using a world separate from the parent viewport's world.
</description>
</method>
- <method name="queue_screen_capture">
- <description>
- Queue a multithreaded screenshot, you can retrive it at a later frame via [method get_screen_capture].
- </description>
- </method>
<method name="set_as_audio_listener">
<argument index="0" name="enable" type="bool">
</argument>
@@ -49159,6 +49746,12 @@ do_property].
<description>
</description>
</method>
+ <method name="set_debug_draw">
+ <argument index="0" name="debug_draw" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_disable_3d">
<argument index="0" name="disable" type="bool">
</argument>
@@ -49251,6 +49844,12 @@ do_property].
Set when the render target would be updated, using the [code]UPDATE_*[/code] constants
</description>
</method>
+ <method name="set_usage">
+ <argument index="0" name="usage" type="int">
+ </argument>
+ <description>
+ </description>
+ </method>
<method name="set_use_own_world">
<argument index="0" name="enable" type="bool">
</argument>
@@ -49279,7 +49878,7 @@ do_property].
</description>
</method>
<method name="unhandled_input">
- <argument index="0" name="local_event" type="InputEvent">
+ <argument index="0" name="local_event" type="Object">
</argument>
<description>
</description>
@@ -49302,6 +49901,8 @@ do_property].
</member>
<member name="audio_listener_enable_3d" type="bool" setter="set_as_audio_listener" getter="is_audio_listener" brief="">
</member>
+ <member name="debug_draw" type="int" setter="set_debug_draw" getter="get_debug_draw" brief="">
+ </member>
<member name="disable_3d" type="bool" setter="set_disable_3d" getter="is_3d_disabled" brief="">
</member>
<member name="gui_disable_input" type="bool" setter="set_disable_input" getter="is_input_disabled" brief="">
@@ -49334,6 +49935,8 @@ do_property].
</member>
<member name="transparent_bg" type="bool" setter="set_transparent_background" getter="has_transparent_background" brief="">
</member>
+ <member name="usage" type="int" setter="set_usage" getter="get_usage" brief="">
+ </member>
<member name="world" type="World" setter="set_world" getter="get_world" brief="">
</member>
</members>
@@ -49372,6 +49975,28 @@ do_property].
</constant>
<constant name="SHADOW_ATLAS_QUADRANT_SUBDIV_MAX" value="7">
</constant>
+ <constant name="RENDER_INFO_OBJECTS_IN_FRAME" value="0">
+ </constant>
+ <constant name="RENDER_INFO_VERTICES_IN_FRAME" value="1">
+ </constant>
+ <constant name="RENDER_INFO_MATERIAL_CHANGES_IN_FRAME" value="2">
+ </constant>
+ <constant name="RENDER_INFO_SHADER_CHANGES_IN_FRAME" value="3">
+ </constant>
+ <constant name="RENDER_INFO_SURFACE_CHANGES_IN_FRAME" value="4">
+ </constant>
+ <constant name="RENDER_INFO_DRAW_CALLS_IN_FRAME" value="5">
+ </constant>
+ <constant name="RENDER_INFO_MAX" value="6">
+ </constant>
+ <constant name="DEBUG_DRAW_DISABLED" value="0">
+ </constant>
+ <constant name="DEBUG_DRAW_UNSHADED" value="1">
+ </constant>
+ <constant name="DEBUG_DRAW_OVERDRAW" value="2">
+ </constant>
+ <constant name="DEBUG_DRAW_WIREFRAME" value="3">
+ </constant>
<constant name="MSAA_DISABLED" value="0">
</constant>
<constant name="MSAA_2X" value="1">
@@ -50503,24 +51128,12 @@ do_property].
<description>
</description>
<methods>
- <method name="get_deconstruct_input_type" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="get_deconstruct_type" qualifiers="const">
<return type="int">
</return>
<description>
</description>
</method>
- <method name="set_deconstruct_input_type">
- <argument index="0" name="input_type" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="set_deconstruct_type">
<argument index="0" name="type" type="int">
</argument>
@@ -50531,8 +51144,6 @@ do_property].
<members>
<member name="elem_cache" type="Array" setter="_set_elem_cache" getter="_get_elem_cache" brief="">
</member>
- <member name="input_type" type="int" setter="set_deconstruct_input_type" getter="get_deconstruct_input_type" brief="">
- </member>
<member name="type" type="int" setter="set_deconstruct_type" getter="get_deconstruct_type" brief="">
</member>
</members>
@@ -50893,16 +51504,6 @@ do_property].
<constants>
</constants>
</class>
-<class name="VisualScriptInputFilter" inherits="VisualScriptNode" category="Core">
- <brief_description>
- </brief_description>
- <description>
- </description>
- <methods>
- </methods>
- <constants>
- </constants>
-</class>
<class name="VisualScriptIterator" inherits="VisualScriptNode" category="Core">
<brief_description>
</brief_description>
@@ -51163,12 +51764,6 @@ do_property].
<description>
</description>
</method>
- <method name="get_event_type" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="get_property" qualifiers="const">
<return type="String">
</return>
@@ -51205,12 +51800,6 @@ do_property].
<description>
</description>
</method>
- <method name="set_event_type">
- <argument index="0" name="event_type" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="set_property">
<argument index="0" name="property" type="String">
</argument>
@@ -51225,8 +51814,6 @@ do_property].
</member>
<member name="property/basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
</member>
- <member name="property/event_type" type="int" setter="set_event_type" getter="get_event_type" brief="">
- </member>
<member name="property/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
<member name="property/property" type="String" setter="set_property" getter="get_property" brief="">
@@ -51281,12 +51868,6 @@ do_property].
<description>
</description>
</method>
- <method name="get_event_type" qualifiers="const">
- <return type="int">
- </return>
- <description>
- </description>
- </method>
<method name="get_property" qualifiers="const">
<return type="String">
</return>
@@ -51323,12 +51904,6 @@ do_property].
<description>
</description>
</method>
- <method name="set_event_type">
- <argument index="0" name="event_type" type="int">
- </argument>
- <description>
- </description>
- </method>
<method name="set_property">
<argument index="0" name="property" type="String">
</argument>
@@ -51343,8 +51918,6 @@ do_property].
</member>
<member name="property/basic_type" type="int" setter="set_basic_type" getter="get_basic_type" brief="">
</member>
- <member name="property/event_type" type="int" setter="set_event_type" getter="get_event_type" brief="">
- </member>
<member name="property/node_path" type="NodePath" setter="set_base_path" getter="get_base_path" brief="">
</member>
<member name="property/property" type="String" setter="set_property" getter="get_property" brief="">
@@ -51767,7 +52340,7 @@ do_property].
<method name="texture_create_from_image">
<return type="RID">
</return>
- <argument index="0" name="arg0" type="Image">
+ <argument index="0" name="arg0" type="Object">
</argument>
<argument index="1" name="arg1" type="int" default="7">
</argument>
@@ -51890,7 +52463,7 @@ do_property].
</theme_item>
<theme_item name="close_h_ofs" type="int">
</theme_item>
- <theme_item name="close_hilite" type="Texture">
+ <theme_item name="close_highlight" type="Texture">
</theme_item>
<theme_item name="close_v_ofs" type="int">
</theme_item>
@@ -51904,8 +52477,6 @@ do_property].
</theme_item>
<theme_item name="title_height" type="int">
</theme_item>
- <theme_item name="titlebar_height" type="int">
- </theme_item>
</theme_items>
</class>
<class name="World" inherits="Resource" category="Core">
@@ -51928,6 +52499,12 @@ do_property].
<description>
</description>
</method>
+ <method name="get_fallback_environment" qualifiers="const">
+ <return type="Environment">
+ </return>
+ <description>
+ </description>
+ </method>
<method name="get_scenario" qualifiers="const">
<return type="RID">
</return>
@@ -51946,10 +52523,18 @@ do_property].
<description>
</description>
</method>
+ <method name="set_fallback_environment">
+ <argument index="0" name="env" type="Environment">
+ </argument>
+ <description>
+ </description>
+ </method>
</methods>
<members>
<member name="environment" type="Environment" setter="set_environment" getter="get_environment" brief="">
</member>
+ <member name="fallback_environment" type="Environment" setter="set_fallback_environment" getter="get_fallback_environment" brief="">
+ </member>
</members>
<constants>
</constants>
@@ -51999,7 +52584,7 @@ do_property].
Sets environment properties for the entire scene
</brief_description>
<description>
- The [WorldEnvironment] node can be added to a scene in order to set default [Environment] variables for the scene. The [WorldEnvironment] can be overridden by an [Environment] node set on the current [Camera]. Additionally, only one [WorldEnvironment] may be instanced in a given scene at a time. The [WorldEnvironment] allows the user to specify default lighting parameters (e.g. ambient lighting), various post-processing effects (e.g. SSAO, DOF, Tonemapping), and how to draw the background (e.g. solid color, skybox).
+ The [WorldEnvironment] node can be added to a scene in order to set default [Environment] variables for the scene. The [WorldEnvironment] can be overridden by an [Environment] node set on the current [Camera]. Additionally, only one [WorldEnvironment] may be instanced in a given scene at a time. The [WorldEnvironment] allows the user to specify default lighting parameters (e.g. ambient lighting), various post-processing effects (e.g. SSAO, DOF, Tonemapping), and how to draw the background (e.g. solid color, skybox).
</description>
<methods>
<method name="get_environment" qualifiers="const">
@@ -52338,4 +52923,3 @@ do_property].
</constants>
</class>
</doc>
-
diff --git a/doc/tools/doc_status.py b/doc/tools/doc_status.py
index 1386e91ce1..1386e91ce1 100755..100644
--- a/doc/tools/doc_status.py
+++ b/doc/tools/doc_status.py
diff --git a/doc/tools/locales/es/LC_MESSAGES/makedocs.mo b/doc/tools/locales/es/LC_MESSAGES/makedocs.mo
deleted file mode 100644
index 8d7ea2689e..0000000000
--- a/doc/tools/locales/es/LC_MESSAGES/makedocs.mo
+++ /dev/null
Binary files differ
diff --git a/doc/tools/locales/es/LC_MESSAGES/makedocs.po b/doc/tools/locales/es/LC_MESSAGES/makedocs.po
deleted file mode 100644
index 82115dd897..0000000000
--- a/doc/tools/locales/es/LC_MESSAGES/makedocs.po
+++ /dev/null
@@ -1,142 +0,0 @@
-# Translations template for PROJECT.
-# Copyright (C) 2015 ORGANIZATION
-# This file is distributed under the same license as the PROJECT project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
-#
-msgid ""
-msgstr ""
-"Project-Id-Version: makedocs\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-10-07 11:47-0600\n"
-"PO-Revision-Date: 2015-10-07 13:10-0600\n"
-"Last-Translator: Jorge Araya Navarro <elcorreo@deshackra.com>\n"
-"Language-Team: \n"
-"Language: es\n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
-"X-Generator: Poedit 1.8.4\n"
-"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-
-#: makedocs.py:74
-msgid ""
-"\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
-msgstr ""
-"\"<code>{gclass}</code>(Ir a la pagina de la clase {gclass})\":/"
-"class_{lkclass}"
-
-#: makedocs.py:76
-msgid ""
-"\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/"
-"class_{lkclass}#{lkmethod}"
-msgstr ""
-"\"<code>{gclass}.{method}</code>(Ir a la pagina {gclass}, sección "
-"{method})\":/class_{lkclass}#{lkmethod}"
-
-#: makedocs.py:79
-msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
-msgstr "\"<code>{method}</code>(Saltar al método {method})\":#{lkmethod}"
-
-#: makedocs.py:81
-msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
-msgstr " \"{rtype}(Ir a la pagina de la clase {rtype})\":/class_{link} "
-
-#: makedocs.py:82
-msgid ""
-"\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
-msgstr ""
-"\"*{funcname}*(Saltar a la descripción para el nodo {funcname})\":#{link} "
-"<b>(</b> "
-
-#: makedocs.py:87
-msgid "h4. Inherits: "
-msgstr "h4. Hereda de: "
-
-#: makedocs.py:232
-msgid "<doc>'s version attribute missing"
-msgstr "El atributo version de <doc> no existe"
-
-#: makedocs.py:246
-msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
-msgstr ""
-"|_. Índice de símbolo |_. Nombre de la clase |_. Índice de símbolo |_. "
-"Nombre de la clase |\n"
-
-#: makedocs.py:305
-msgid ""
-"h4. Category: {}\n"
-"\n"
-msgstr ""
-"h4. Categoría: {}\n"
-"\n"
-
-#: makedocs.py:310
-msgid ""
-"h2. Brief Description\n"
-"\n"
-msgstr ""
-"h2. Descripción breve\n"
-"\n"
-
-#: makedocs.py:312
-msgid ""
-"\"read more\":#more\n"
-"\n"
-msgstr ""
-"\"Leer más\":#more\n"
-"\n"
-
-#: makedocs.py:317
-msgid ""
-"\n"
-"h3. Member Functions\n"
-"\n"
-msgstr ""
-"\n"
-"h3. Funciones miembro\n"
-"\n"
-
-#: makedocs.py:323
-msgid ""
-"\n"
-"h3. Signals\n"
-"\n"
-msgstr ""
-"\n"
-"h3. Señales\n"
-"\n"
-
-#: makedocs.py:331
-msgid ""
-"\n"
-"h3. Numeric Constants\n"
-"\n"
-msgstr ""
-"\n"
-"h3. Constantes numéricas\n"
-"\n"
-
-#: makedocs.py:347
-msgid ""
-"\n"
-"h3(#more). Description\n"
-"\n"
-msgstr ""
-"\n"
-"h3(#more). Descripción\n"
-"\n"
-
-#: makedocs.py:351
-msgid "_Nothing here, yet..._\n"
-msgstr "_Aún nada por aquí..._\n"
-
-#: makedocs.py:355
-msgid ""
-"\n"
-"h3. Member Function Description\n"
-"\n"
-msgstr ""
-"\n"
-"h3. Descripción de las funciones miembro\n"
-"\n"
diff --git a/doc/tools/main.css b/doc/tools/main.css
deleted file mode 100644
index 5eb3df2159..0000000000
--- a/doc/tools/main.css
+++ /dev/null
@@ -1,146 +0,0 @@
-BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV, SPAN {
- font-family: Arial, Geneva, Helvetica, sans-serif;
-}
-
-a {
-
- text-decoration: none;
-
-}
-
-a:hover {
-
- text-decoration: underline;
-}
-
-td.top_table {
-
- padding: 5px;
-}
-
-div.method_doc {
-
- padding-bottom: 30px;
-}
-
-div.method_description {
- margin-left: 30px;
-}
-
-list.inh_class_list {
- margin-left: 30px;
-
-}
-
-div.inh_class_list {
- margin-left: 30px;
-
-}
-
-div.method_doc div.method {
-
- font-size: 12pt;
- font-weight: bold;
-}
-
-span.funcdecl {
-
- color: #202060;
-}
-
-span.funcdef {
-
- color: #202060;
-}
-
-
-span.qualifier {
-
- font-weight: bold;
-}
-
-
-span.symbol {
-
- /*font-weight: bold;*/
- color: #471870;
-}
-
-
-span.datatype {
-
- color: #6a1533;
-}
-
-tr.category_title {
-
- background-color: #333333;
-}
-a.category_title {
- font-weight: bold;
- color: #FFFFFF;
-}
-
-div.method_list {
-
- margin-left: 30px;
-}
-
-div.constant_list {
-
- margin-left: 30px;
-}
-
-div.member_list {
-
- margin-left: 30px;
-}
-
-div.description {
-
- margin-left: 30px;
-}
-
-div.class_description {
-
- margin-left: 30px;
-}
-
-div.method_list li div {
-
- display: inline;
-}
-
-div.member_list li div.member {
-
- display: inline;
-}
-
-div.constant_list li div.constant {
-
- display: inline;
-}
-
-span.member_description {
-
- font-style: italic;
- color: grey;
-}
-
-span.constant_description {
-
- font-style: italic;
- color: grey;
-}
-
-span.identifier {
-
- font-weight: bold;
-}
-
-
-table.class_table td {
-
- vertical-align: top;
-}
-
diff --git a/doc/tools/makedocs.pot b/doc/tools/makedocs.pot
deleted file mode 100644
index be3220f686..0000000000
--- a/doc/tools/makedocs.pot
+++ /dev/null
@@ -1,108 +0,0 @@
-# Translations template for PROJECT.
-# Copyright (C) 2015 ORGANIZATION
-# This file is distributed under the same license as the PROJECT project.
-# FIRST AUTHOR <EMAIL@ADDRESS>, 2015.
-#
-#, fuzzy
-msgid ""
-msgstr ""
-"Project-Id-Version: makedocs 0.1\n"
-"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
-"POT-Creation-Date: 2015-10-07 11:47-0600\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
-"Language-Team: \n"
-"MIME-Version: 1.0\n"
-"Content-Type: text/plain; charset=UTF-8\n"
-"Content-Transfer-Encoding: 8bit\n"
-"Generated-By: Babel 2.0\n"
-"X-Generator: Poedit 1.8.4\n"
-
-#: makedocs.py:74
-msgid "\"<code>{gclass}</code>(Go to page of class {gclass})\":/class_{lkclass}"
-msgstr ""
-
-#: makedocs.py:76
-msgid "\"<code>{gclass}.{method}</code>(Go to page {gclass}, section {method})\":/class_{lkclass}#{lkmethod}"
-msgstr ""
-
-#: makedocs.py:79
-msgid "\"<code>{method}</code>(Jump to method {method})\":#{lkmethod}"
-msgstr ""
-
-#: makedocs.py:81
-msgid " \"{rtype}(Go to page of class {rtype})\":/class_{link} "
-msgstr ""
-
-#: makedocs.py:82
-msgid "\"*{funcname}*(Jump to description for node {funcname})\":#{link} <b>(</b> "
-msgstr ""
-
-#: makedocs.py:87
-msgid "h4. Inherits: "
-msgstr ""
-
-#: makedocs.py:232
-msgid "<doc>'s version attribute missing"
-msgstr ""
-
-#: makedocs.py:246
-msgid "|_. Index symbol |_. Class name |_. Index symbol |_. Class name |\n"
-msgstr ""
-
-#: makedocs.py:305
-msgid ""
-"h4. Category: {}\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:310
-msgid ""
-"h2. Brief Description\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:312
-msgid ""
-"\"read more\":#more\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:317
-msgid ""
-"\n"
-"h3. Member Functions\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:323
-msgid ""
-"\n"
-"h3. Signals\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:331
-msgid ""
-"\n"
-"h3. Numeric Constants\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:347
-msgid ""
-"\n"
-"h3(#more). Description\n"
-"\n"
-msgstr ""
-
-#: makedocs.py:351
-msgid "_Nothing here, yet..._\n"
-msgstr ""
-
-#: makedocs.py:355
-msgid ""
-"\n"
-"h3. Member Function Description\n"
-"\n"
-msgstr ""
diff --git a/doc/tools/makedocs.py b/doc/tools/makedocs.py
deleted file mode 100644
index 9e0430bfbf..0000000000
--- a/doc/tools/makedocs.py
+++ /dev/null
@@ -1,383 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-#
-# makedocs.py: Generate documentation for Open Project Wiki
-# Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.
-# Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
-# Contributor: Jorge Araya Navarro <elcorreo@deshackra.com>
-#
-
-# IMPORTANT NOTICE:
-# If you are going to modify anything from this file, please be sure to follow
-# the Style Guide for Python Code or often called "PEP8". To do this
-# automagically just install autopep8:
-#
-# $ sudo pip3 install autopep8
-#
-# and run:
-#
-# $ autopep8 makedocs.py
-#
-# Before committing your changes. Also be sure to delete any trailing
-# whitespace you may left.
-#
-# TODO:
-# * Refactor code.
-# * Adapt this script for generating content in other markup formats like
-# reStructuredText, Markdown, DokuWiki, etc.
-#
-# Also check other TODO entries in this script for more information on what is
-# left to do.
-import argparse
-import gettext
-import logging
-import re
-from itertools import zip_longest
-from os import path, listdir
-from xml.etree import ElementTree
-
-
-# add an option to change the verbosity
-logging.basicConfig(level=logging.INFO)
-
-
-def getxmlfloc():
- """ Returns the supposed location of the XML file
- """
- filepath = path.dirname(path.abspath(__file__))
- return path.join(filepath, "class_list.xml")
-
-
-def langavailable():
- """ Return a list of languages available for translation
- """
- filepath = path.join(
- path.dirname(path.abspath(__file__)), "locales")
- files = listdir(filepath)
- choices = [x for x in files]
- choices.insert(0, "none")
- return choices
-
-
-desc = "Generates documentation from a XML file to different markup languages"
-
-parser = argparse.ArgumentParser(description=desc)
-parser.add_argument("--input", dest="xmlfp", default=getxmlfloc(),
- help="Input XML file, default: {}".format(getxmlfloc()))
-parser.add_argument("--output-dir", dest="outputdir", required=True,
- help="Output directory for generated files")
-parser.add_argument("--language", choices=langavailable(), default="none",
- help=("Choose the language of translation"
- " for the output files. Default is English (none). "
- "Note: This is NOT for the documentation itself!"))
-# TODO: add an option for outputting different markup formats
-
-args = parser.parse_args()
-# Let's check if the file and output directory exists
-if not path.isfile(args.xmlfp):
- logging.critical("File not found: {}".format(args.xmlfp))
- exit(1)
-elif not path.isdir(args.outputdir):
- logging.critical("Path does not exist: {}".format(args.outputdir))
- exit(1)
-
-_ = gettext.gettext
-if args.language != "none":
- lang = gettext.translation(domain="makedocs",
- localedir="locales",
- languages=[args.language])
- lang.install()
-
- _ = lang.gettext
-
-# Strings
-C_LINK = _("\"<code>{gclass}</code>(Go to page of class"
- " {gclass})\":/class_{lkclass}")
-MC_LINK = _("\"<code>{gclass}.{method}</code>(Go "
- "to page {gclass}, section {method})\""
- ":/class_{lkclass}#{lkmethod}")
-TM_JUMP = _("\"<code>{method}</code>(Jump to method"
- " {method})\":#{lkmethod}")
-GTC_LINK = _(" \"{rtype}(Go to page of class {rtype})\":/class_{link} ")
-DFN_JUMP = _("\"*{funcname}*(Jump to description for"
- " node {funcname})\":#{link} <b>(</b> ")
-M_ARG_DEFAULT = C_LINK + " {name}={default}"
-M_ARG = C_LINK + " {name}"
-
-OPENPROJ_INH = _("h4. Inherits: ") + C_LINK + "\n\n"
-
-
-def tb(string):
- """ Return a byte representation of a string
- """
- return bytes(string, "UTF-8")
-
-
-def sortkey(c):
- """ Symbols are first, letters second
- """
- if "_" == c.attrib["name"][0]:
- return "A"
- else:
- return c.attrib["name"]
-
-
-def toOP(text):
- """ Convert commands in text to Open Project commands
- """
- # TODO: Make this capture content between [command] ... [/command]
- groups = re.finditer((r'\[html (?P<command>/?\w+/?)(\]| |=)?(\]| |=)?(?P<a'
- 'rg>\w+)?(\]| |=)?(?P<value>"[^"]+")?/?\]'), text)
- alignstr = ""
- for group in groups:
- gd = group.groupdict()
- if gd["command"] == "br/":
- text = text.replace(group.group(0), "\n\n", 1)
- elif gd["command"] == "div":
- if gd["value"] == '"center"':
- alignstr = ("{display:block; margin-left:auto;"
- " margin-right:auto;}")
- elif gd["value"] == '"left"':
- alignstr = "<"
- elif gd["value"] == '"right"':
- alignstr = ">"
- text = text.replace(group.group(0), "\n\n", 1)
- elif gd["command"] == "/div":
- alignstr = ""
- text = text.replace(group.group(0), "\n\n", 1)
- elif gd["command"] == "img":
- text = text.replace(group.group(0), "!{align}{src}!".format(
- align=alignstr, src=gd["value"].strip('"')), 1)
- elif gd["command"] == "b" or gd["command"] == "/b":
- text = text.replace(group.group(0), "*", 1)
- elif gd["command"] == "i" or gd["command"] == "/i":
- text = text.replace(group.group(0), "_", 1)
- elif gd["command"] == "u" or gd["command"] == "/u":
- text = text.replace(group.group(0), "+", 1)
- # Process other non-html commands
- groups = re.finditer((r'\[method ((?P<class>[aA0-zZ9_]+)(?:\.))'
- r'?(?P<method>[aA0-zZ9_]+)\]'), text)
- for group in groups:
- gd = group.groupdict()
- if gd["class"]:
- replacewith = (MC_LINK.format(gclass=gd["class"],
- method=gd["method"],
- lkclass=gd["class"].lower(),
- lkmethod=gd["method"].lower()))
- else:
- # The method is located in the same wiki page
- replacewith = (TM_JUMP.format(method=gd["method"],
- lkmethod=gd["method"].lower()))
-
- text = text.replace(group.group(0), replacewith, 1)
- # Finally, [Classes] are around brackets, make them direct links
- groups = re.finditer(r'\[(?P<class>[az0-AZ0_]+)\]', text)
- for group in groups:
- gd = group.groupdict()
- replacewith = (C_LINK.
- format(gclass=gd["class"],
- lkclass=gd["class"].lower()))
- text = text.replace(group.group(0), replacewith, 1)
-
- return text + "\n\n"
-
-
-def mkfn(node, is_signal=False):
- """ Return a string containing a unsorted item for a function
- """
- finalstr = ""
- name = node.attrib["name"]
- rtype = node.find("return")
- if rtype:
- rtype = rtype.attrib["type"]
- else:
- rtype = "void"
- # write the return type and the function name first
- finalstr += "* "
- # return type
- if not is_signal:
- if rtype != "void":
- finalstr += GTC_LINK.format(
- rtype=rtype,
- link=rtype.lower())
- else:
- finalstr += " void "
-
- # function name
- if not is_signal:
- finalstr += DFN_JUMP.format(
- funcname=name,
- link=name.lower())
- else:
- # Signals have no description
- finalstr += "*{funcname}* <b>(</b>".format(funcname=name)
- # loop for the arguments of the function, if any
- args = []
- for arg in sorted(
- node.iter(tag="argument"),
- key=lambda a: int(a.attrib["index"])):
-
- ntype = arg.attrib["type"]
- nname = arg.attrib["name"]
-
- if "default" in arg.attrib:
- args.insert(-1, M_ARG_DEFAULT.format(
- gclass=ntype,
- lkclass=ntype.lower(),
- name=nname,
- default=arg.attrib["default"]))
- else:
- # No default value present
- args.insert(-1, M_ARG.format(gclass=ntype,
- lkclass=ntype.lower(), name=nname))
- # join the arguments together
- finalstr += ", ".join(args)
- # and, close the function with a )
- finalstr += " <b>)</b>"
- # write the qualifier, if any
- if "qualifiers" in node.attrib:
- qualifier = node.attrib["qualifiers"]
- finalstr += " " + qualifier
-
- finalstr += "\n"
-
- return finalstr
-
-# Let's begin
-tree = ElementTree.parse(args.xmlfp)
-root = tree.getroot()
-
-# Check version attribute exists in <doc>
-if "version" not in root.attrib:
- logging.critical(_("<doc>'s version attribute missing"))
- exit(1)
-
-version = root.attrib["version"]
-classes = sorted(root, key=sortkey)
-# first column is always longer, second column of classes should be shorter
-zclasses = zip_longest(classes[:int(len(classes) / 2 + 1)],
- classes[int(len(classes) / 2 + 1):],
- fillvalue="")
-
-# We write the class_list file and also each class file at once
-with open(path.join(args.outputdir, "class_list.txt"), "wb") as fcl:
- # Write header of table
- fcl.write(tb("|^.\n"))
- fcl.write(tb(_("|_. Index symbol |_. Class name "
- "|_. Index symbol |_. Class name |\n")))
- fcl.write(tb("|-.\n"))
-
- indexletterl = ""
- indexletterr = ""
- for gdclassl, gdclassr in zclasses:
- # write a row #
- # write the index symbol column, left
- if indexletterl != gdclassl.attrib["name"][0]:
- indexletterl = gdclassl.attrib["name"][0]
- fcl.write(tb("| *{}* |".format(indexletterl.upper())))
- else:
- # empty cell
- fcl.write(tb("| |"))
- # write the class name column, left
- fcl.write(tb(C_LINK.format(
- gclass=gdclassl.attrib["name"],
- lkclass=gdclassl.attrib["name"].lower())))
-
- # write the index symbol column, right
- if isinstance(gdclassr, ElementTree.Element):
- if indexletterr != gdclassr.attrib["name"][0]:
- indexletterr = gdclassr.attrib["name"][0]
- fcl.write(tb("| *{}* |".format(indexletterr.upper())))
- else:
- # empty cell
- fcl.write(tb("| |"))
- # We are dealing with an empty string
- else:
- # two empty cell
- fcl.write(tb("| | |\n"))
- # We won't get the name of the class since there is no ElementTree
- # object for the right side of the tuple, so we iterate the next
- # tuple instead
- continue
-
- # write the class name column (if any), right
- fcl.write(tb(C_LINK.format(
- gclass=gdclassl.attrib["name"],
- lkclass=gdclassl.attrib["name"].lower()) + "|\n"))
-
- # row written #
- # now, let's write each class page for each class
- for gdclass in [gdclassl, gdclassr]:
- if not isinstance(gdclass, ElementTree.Element):
- continue
-
- classname = gdclass.attrib["name"]
- with open(path.join(args.outputdir, "{}.txt".format(
- classname.lower())), "wb") as clsf:
- # First level header with the name of the class
- clsf.write(tb("h1. {}\n\n".format(classname)))
- # lay the attributes
- if "inherits" in gdclass.attrib:
- inh = gdclass.attrib["inherits"].strip()
- clsf.write(tb(OPENPROJ_INH.format(gclass=inh,
- lkclass=inh.lower())))
- if "category" in gdclass.attrib:
- clsf.write(tb(_("h4. Category: {}\n\n").
- format(gdclass.attrib["category"].strip())))
- # lay child nodes
- briefd = gdclass.find("brief_description")
- if briefd.text.strip():
- clsf.write(tb(_("h2. Brief Description\n\n")))
- clsf.write(tb(toOP(briefd.text.strip()) +
- _("\"read more\":#more\n\n")))
-
- # Write the list of member functions of this class
- methods = gdclass.find("methods")
- if methods and len(methods) > 0:
- clsf.write(tb(_("\nh3. Member Functions\n\n")))
- for method in methods.iter(tag='method'):
- clsf.write(tb(mkfn(method)))
-
- signals = gdclass.find("signals")
- if signals and len(signals) > 0:
- clsf.write(tb(_("\nh3. Signals\n\n")))
- for signal in signals.iter(tag='signal'):
- clsf.write(tb(mkfn(signal, True)))
- # TODO: <members> tag is necessary to process? it does not
- # exists in class_list.xml file.
-
- consts = gdclass.find("constants")
- if consts and len(consts) > 0:
- clsf.write(tb(_("\nh3. Numeric Constants\n\n")))
- for const in sorted(consts, key=lambda k:
- k.attrib["name"]):
- if const.text.strip():
- clsf.write(tb("* *{name}* = *{value}* - {desc}\n".
- format(
- name=const.attrib["name"],
- value=const.attrib["value"],
- desc=const.text.strip())))
- else:
- # Constant have no description
- clsf.write(tb("* *{name}* = *{value}*\n".
- format(
- name=const.attrib["name"],
- value=const.attrib["value"])))
- descrip = gdclass.find("description")
- clsf.write(tb(_("\nh3(#more). Description\n\n")))
- if descrip.text:
- clsf.write(tb(descrip.text.strip() + "\n"))
- else:
- clsf.write(tb(_("_Nothing here, yet..._\n")))
-
- # and finally, the description for each method
- if methods and len(methods) > 0:
- clsf.write(tb(_("\nh3. Member Function Description\n\n")))
- for method in methods.iter(tag='method'):
- clsf.write(tb("h4(#{n}). {name}\n\n".format(
- n=method.attrib["name"].lower(),
- name=method.attrib["name"])))
- clsf.write(tb(mkfn(method) + "\n"))
- clsf.write(tb(toOP(method.find(
- "description").text.strip())))
diff --git a/doc/tools/makedoku.py b/doc/tools/makedoku.py
deleted file mode 100644
index ad3bfd791d..0000000000
--- a/doc/tools/makedoku.py
+++ /dev/null
@@ -1,499 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import sys
-import xml.etree.ElementTree as ET
-
-input_list = []
-
-
-for arg in sys.argv[1:]:
- input_list.append(arg)
-
-if len(input_list) < 1:
- print("usage: makedoku.py <classes.xml>")
- sys.exit(0)
-
-
-def validate_tag(elem, tag):
- if (elem.tag != tag):
- print("Tag mismatch, expected '" + tag + "', got " + elem.tag)
- sys.exit(255)
-
-
-class_names = []
-classes = {}
-
-
-def make_class_list(class_list, columns):
-
- f = open("class_list.txt", "wb")
- prev = 0
- col_max = len(class_list) / columns + 1
- print("col max is ", col_max)
- col_count = 0
- row_count = 0
- last_initial = ""
- fit_columns = []
-
- for n in range(0, columns):
- fit_columns += [[]]
-
- indexers = []
- last_initial = ""
-
- idx = 0
- for n in class_list:
- col = idx / col_max
- if (col >= columns):
- col = columns - 1
- fit_columns[col] += [n]
- idx += 1
- if (n[:1] != last_initial):
- indexers += [n]
- last_initial = n[:1]
-
- row_max = 0
-
- for n in range(0, columns):
- if (len(fit_columns[n]) > row_max):
- row_max = len(fit_columns[n])
-
- for r in range(0, row_max):
- s = "|"
- for c in range(0, columns):
- if (r >= len(fit_columns[c])):
- continue
-
- classname = fit_columns[c][r]
- initial = classname[0]
- if (classname in indexers):
- s += "**" + initial + "**|"
- else:
- s += " |"
-
- s += "[[" + classname.lower() + "|" + classname + "]]|"
-
- s += "\n"
- f.write(s)
-
-
-def dokuize_text(txt):
-
- return txt
-
-
-def dokuize_text(text):
- pos = 0
- while(True):
- pos = text.find("[", pos)
- if (pos == -1):
- break
-
- endq_pos = text.find("]", pos + 1)
- if (endq_pos == -1):
- break
-
- pre_text = text[:pos]
- post_text = text[endq_pos + 1:]
- tag_text = text[pos + 1:endq_pos]
-
- if (tag_text in class_names):
- tag_text = "[[" + tag_text.lower() + "|" + tag_text + "]]"
- else: # command
- cmd = tag_text
- space_pos = tag_text.find(" ")
- if (cmd.find("html") == 0):
- cmd = tag_text[:space_pos]
- param = tag_text[space_pos + 1:]
- tag_text = "<" + param + ">"
- elif(cmd.find("method") == 0):
- cmd = tag_text[:space_pos]
- param = tag_text[space_pos + 1:]
-
- if (param.find(".") != -1):
- class_param, method_param = param.split(".")
- tag_text = "[[" + class_param.lower() + "#" + method_param + "|" + class_param + '.' + method_param + "]]"
- else:
- tag_text = "[[#" + param + "|" + param + "]]"
- elif (cmd.find("image=") == 0):
- tag_text = "{{" + cmd[6:] + "}}"
- elif (cmd.find("url=") == 0):
- tag_text = "[[" + cmd[4:] + "|"
- elif (cmd == "/url"):
- tag_text = "]]>"
- elif (cmd == "center"):
- tag_text = ""
- elif (cmd == "/center"):
- tag_text = ""
- elif (cmd == "br"):
- tag_text = "\\\\\n"
- elif (cmd == "i" or cmd == "/i"):
- tag_text = "//"
- elif (cmd == "b" or cmd == "/b"):
- tag_text = "**"
- elif (cmd == "u" or cmd == "/u"):
- tag_text = "__"
- else:
- tag_text = "[" + tag_text + "]"
-
- text = pre_text + tag_text + post_text
- pos = len(pre_text) + len(tag_text)
-
- #tnode = ET.SubElement(parent,"div")
- # tnode.text=text
- return text
-
-
-def make_type(t):
- global class_names
- if (t in class_names):
- return "[[" + t.lower() + "|" + t + "]]"
- return t
-
-
-def make_method(f, name, m, declare, event=False):
-
- s = " * "
- ret_type = "void"
- args = list(m)
- mdata = {}
- mdata["argidx"] = []
- for a in args:
- if (a.tag == "return"):
- idx = -1
- elif (a.tag == "argument"):
- idx = int(a.attrib["index"])
- else:
- continue
-
- mdata["argidx"].append(idx)
- mdata[idx] = a
-
- if (not event):
- if (-1 in mdata["argidx"]):
- s += make_type(mdata[-1].attrib["type"])
- else:
- s += "void"
- s += " "
-
- if (declare):
-
- # span.attrib["class"]="funcdecl"
- # a=ET.SubElement(span,"a")
- # a.attrib["name"]=name+"_"+m.attrib["name"]
- # a.text=name+"::"+m.attrib["name"]
- s += "**" + m.attrib["name"] + "**"
- else:
- s += "[[#" + m.attrib["name"] + "|" + m.attrib["name"] + "]]"
-
- s += "**(**"
- argfound = False
- for a in mdata["argidx"]:
- arg = mdata[a]
- if (a < 0):
- continue
- if (a > 0):
- s += ", "
- else:
- s += " "
-
- s += make_type(arg.attrib["type"])
- if ("name" in arg.attrib):
- s += " " + arg.attrib["name"]
- else:
- s += " arg" + str(a)
-
- if ("default" in arg.attrib):
- s += "=" + arg.attrib["default"]
-
- argfound = True
-
- if (argfound):
- s += " "
- s += "**)**"
-
- if ("qualifiers" in m.attrib):
- s += " " + m.attrib["qualifiers"]
-
- f.write(s + "\n")
-
-
-def make_doku_class(node):
-
- name = node.attrib["name"]
-
- f = open(name.lower() + ".txt", "wb")
-
- f.write("====== " + name + " ======\n")
-
- if ("inherits" in node.attrib):
- inh = node.attrib["inherits"].strip()
- f.write("**Inherits:** [[" + inh.lower() + "|" + inh + "]]\\\\\n")
- if ("category" in node.attrib):
- f.write("**Category:** " + node.attrib["category"].strip() + "\\\\\n")
-
- briefd = node.find("brief_description")
- if (briefd != None):
- f.write("===== Brief Description ======\n")
- f.write(dokuize_text(briefd.text.strip()) + "\n")
-
- methods = node.find("methods")
-
- if(methods != None and len(list(methods)) > 0):
- f.write("===== Member Functions ======\n")
- for m in list(methods):
- make_method(f, node.attrib["name"], m, False)
-
- events = node.find("signals")
- if(events != None and len(list(events)) > 0):
- f.write("===== Signals ======\n")
- for m in list(events):
- make_method(f, node.attrib["name"], m, True, True)
-
- members = node.find("members")
-
- if(members != None and len(list(members)) > 0):
- f.write("===== Member Variables ======\n")
-
- for c in list(members):
- s = " * "
- s += make_type(c.attrib["type"]) + " "
- s += "**" + c.attrib["name"] + "**"
- if (c.text.strip() != ""):
- s += " - " + c.text.strip()
- f.write(s + "\n")
-
- constants = node.find("constants")
- if(constants != None and len(list(constants)) > 0):
- f.write("===== Numeric Constants ======\n")
- for c in list(constants):
- s = " * "
- s += "**" + c.attrib["name"] + "**"
- if ("value" in c.attrib):
- s += " = **" + c.attrib["value"] + "**"
- if (c.text.strip() != ""):
- s += " - " + c.text.strip()
- f.write(s + "\n")
-
- descr = node.find("description")
- if (descr != None and descr.text.strip() != ""):
- f.write("===== Description ======\n")
- f.write(dokuize_text(descr.text.strip()) + "\n")
-
- methods = node.find("methods")
-
- if(methods != None and len(list(methods)) > 0):
- f.write("===== Member Function Description ======\n")
- for m in list(methods):
-
- d = m.find("description")
- if (d == None or d.text.strip() == ""):
- continue
- f.write("== " + m.attrib["name"] + " ==\n")
- make_method(f, node.attrib["name"], m, False)
- f.write("\\\\\n")
- f.write(dokuize_text(d.text.strip()))
- f.write("\n")
-
- """
- div=ET.Element("div")
- div.attrib["class"]="class";
-
- a=ET.SubElement(div,"a")
- a.attrib["name"]=node.attrib["name"]
-
- h3=ET.SubElement(a,"h3")
- h3.attrib["class"]="title class_title"
- h3.text=node.attrib["name"]
-
- briefd = node.find("brief_description")
- if (briefd!=None):
- div2=ET.SubElement(div,"div")
- div2.attrib["class"]="description class_description"
- div2.text=briefd.text
-
- if ("inherits" in node.attrib):
- ET.SubElement(div,"br")
-
- div2=ET.SubElement(div,"div")
- div2.attrib["class"]="inheritance";
-
- span=ET.SubElement(div2,"span")
- span.text="Inherits: "
-
- make_type(node.attrib["inherits"],div2)
-
- if ("category" in node.attrib):
- ET.SubElement(div,"br")
-
- div3=ET.SubElement(div,"div")
- div3.attrib["class"]="category";
-
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="category"
- span.text="Category: "
-
- a = ET.SubElement(div3,"a")
- a.attrib["class"]="category_ref"
- a.text=node.attrib["category"]
- catname=a.text
- if (catname.rfind("/")!=-1):
- catname=catname[catname.rfind("/"):]
- catname="CATEGORY_"+catname
-
- if (single_page):
- a.attrib["href"]="#"+catname
- else:
- a.attrib["href"]="category.html#"+catname
-
-
- methods = node.find("methods")
-
- if(methods!=None and len(list(methods))>0):
-
- h4=ET.SubElement(div,"h4")
- h4.text="Public Methods:"
-
- method_table=ET.SubElement(div,"table")
- method_table.attrib["class"]="method_list";
-
- for m in list(methods):
-# li = ET.SubElement(div2, "li")
- method_table.append( make_method_def(node.attrib["name"],m,False) )
-
- events = node.find("signals")
-
- if(events!=None and len(list(events))>0):
- h4=ET.SubElement(div,"h4")
- h4.text="Events:"
-
- event_table=ET.SubElement(div,"table")
- event_table.attrib["class"]="method_list";
-
- for m in list(events):
-# li = ET.SubElement(div2, "li")
- event_table.append( make_method_def(node.attrib["name"],m,False,True) )
-
-
- members = node.find("members")
- if(members!=None and len(list(members))>0):
-
- h4=ET.SubElement(div,"h4")
- h4.text="Public Variables:"
- div2=ET.SubElement(div,"div")
- div2.attrib["class"]="member_list";
-
- for c in list(members):
-
- li = ET.SubElement(div2, "li")
- div3=ET.SubElement(li,"div")
- div3.attrib["class"]="member";
- make_type(c.attrib["type"],div3)
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="identifier member_name"
- span.text=" "+c.attrib["name"]+" "
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="member_description"
- span.text=c.text
-
-
- constants = node.find("constants")
- if(constants!=None and len(list(constants))>0):
-
- h4=ET.SubElement(div,"h4")
- h4.text="Constants:"
- div2=ET.SubElement(div,"div")
- div2.attrib["class"]="constant_list";
-
- for c in list(constants):
- li = ET.SubElement(div2, "li")
- div3=ET.SubElement(li,"div")
- div3.attrib["class"]="constant";
-
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="identifier constant_name"
- span.text=c.attrib["name"]+" "
- if ("value" in c.attrib):
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="symbol"
- span.text="= "
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="constant_value"
- span.text=c.attrib["value"]+" "
- span=ET.SubElement(div3,"span")
- span.attrib["class"]="constant_description"
- span.text=c.text
-
-# ET.SubElement(div,"br")
-
-
- descr=node.find("description")
- if (descr!=None and descr.text.strip()!=""):
-
- h4=ET.SubElement(div,"h4")
- h4.text="Description:"
-
- make_text_def(node.attrib["name"],div,descr.text)
-# div2=ET.SubElement(div,"div")
-# div2.attrib["class"]="description";
-# div2.text=descr.text
-
-
-
- if(methods!=None or events!=None):
-
- h4=ET.SubElement(div,"h4")
- h4.text="Method Documentation:"
- iter_list = []
- if (methods!=None):
- iter_list+=list(methods)
- if (events!=None):
- iter_list+=list(events)
-
- for m in iter_list:
-
- descr=m.find("description")
-
- if (descr==None or descr.text.strip()==""):
- continue;
-
- div2=ET.SubElement(div,"div")
- div2.attrib["class"]="method_doc";
-
-
- div2.append( make_method_def(node.attrib["name"],m,True) )
- #anchor = ET.SubElement(div2, "a")
- #anchor.attrib["name"] =
- make_text_def(node.attrib["name"],div2,descr.text)
- #div3=ET.SubElement(div2,"div")
- #div3.attrib["class"]="description";
- #div3.text=descr.text
-
-
- return div
-"""
-for file in input_list:
- tree = ET.parse(file)
- doc = tree.getroot()
-
- if ("version" not in doc.attrib):
- print("Version missing from 'doc'")
- sys.exit(255)
-
- version = doc.attrib["version"]
-
- for c in list(doc):
- if (c.attrib["name"] in class_names):
- continue
- class_names.append(c.attrib["name"])
- classes[c.attrib["name"]] = c
-
-
-class_names.sort()
-
-make_class_list(class_names, 4)
-
-for cn in class_names:
- c = classes[cn]
- make_doku_class(c)
diff --git a/doc/tools/makehtml.py b/doc/tools/makehtml.py
deleted file mode 100644
index 3ecb8220cb..0000000000
--- a/doc/tools/makehtml.py
+++ /dev/null
@@ -1,689 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-import sys
-import xml.etree.ElementTree as ET
-from xml.sax.saxutils import escape, unescape
-
-html_escape_table = {
- '"': "&quot;",
- "'": "&apos;"
-}
-
-html_unescape_table = {v: k for k, v in html_escape_table.items()}
-
-
-def html_escape(text):
- return escape(text, html_escape_table)
-
-
-def html_unescape(text):
- return unescape(text, html_unescape_table)
-
-input_list = []
-
-single_page = True
-
-for arg in sys.argv[1:]:
- if arg[:1] == "-":
- if arg[1:] == "multipage":
- single_page = False
- if arg[1:] == "singlepage":
- single_page = True
- else:
- input_list.append(arg)
-
-if len(input_list) < 1:
- print("usage: makehtml.py <classes.xml>")
- sys.exit(0)
-
-
-def validate_tag(elem, tag):
- if (elem.tag != tag):
- print("Tag mismatch, expected '" + tag + "', got " + elem.tag)
- sys.exit(255)
-
-
-def make_html_bottom(body):
- # make_html_top(body,True)
- ET.SubElement(body, "hr")
- copyright = ET.SubElement(body, "span")
- copyright.text = "Copyright 2008-2010 Codenix SRL"
-
-
-def make_html_top(body, bottom=False):
-
- if (bottom):
- ET.SubElement(body, "hr")
-
- table = ET.SubElement(body, "table")
- table.attrib["class"] = "top_table"
- tr = ET.SubElement(table, "tr")
- td = ET.SubElement(tr, "td")
- td.attrib["class"] = "top_table"
-
- img = ET.SubElement(td, "image")
- img.attrib["src"] = "images/logo.png"
- td = ET.SubElement(tr, "td")
- td.attrib["class"] = "top_table"
- a = ET.SubElement(td, "a")
- a.attrib["href"] = "index.html"
- a.text = "Index"
- td = ET.SubElement(tr, "td")
- td.attrib["class"] = "top_table"
- a = ET.SubElement(td, "a")
- a.attrib["href"] = "alphabetical.html"
- a.text = "Classes"
- td = ET.SubElement(tr, "td")
- td.attrib["class"] = "top_table"
- a = ET.SubElement(td, "a")
- a.attrib["href"] = "category.html"
- a.text = "Categories"
- td = ET.SubElement(tr, "td")
- a = ET.SubElement(td, "a")
- a.attrib["href"] = "inheritance.html"
- a.text = "Inheritance"
- if (not bottom):
- ET.SubElement(body, "hr")
-
-
-def make_html_class_list(class_list, columns):
-
- div = ET.Element("div")
- div.attrib["class"] = "ClassList"
-
- h1 = ET.SubElement(div, "h2")
- h1.text = "Alphabetical Class List"
-
- table = ET.SubElement(div, "table")
- table.attrib["class"] = "class_table"
- table.attrib["width"] = "100%"
- prev = 0
-
- col_max = len(class_list) / columns + 1
- print("col max is ", col_max)
- col_count = 0
- row_count = 0
- last_initial = ""
- fit_columns = []
-
- for n in range(0, columns):
- fit_columns += [[]]
-
- indexers = []
- last_initial = ""
-
- idx = 0
- for n in class_list:
- col = int(idx / col_max)
- if (col >= columns):
- col = columns - 1
- fit_columns[col] += [n]
- idx += 1
- if (n[:1] != last_initial):
- indexers += [n]
- last_initial = n[:1]
-
- row_max = 0
-
- for n in range(0, columns):
- if (len(fit_columns[n]) > row_max):
- row_max = len(fit_columns[n])
-
- for r in range(0, row_max):
- tr = ET.SubElement(table, "tr")
- for c in range(0, columns):
- tdi = ET.SubElement(tr, "td")
- tdi.attrib["align"] = "right"
- td = ET.SubElement(tr, "td")
- if (r >= len(fit_columns[c])):
- continue
-
- classname = fit_columns[c][r]
- print(classname)
- if (classname in indexers):
-
- span = ET.SubElement(tdi, "span")
- span.attrib["class"] = "class_index_letter"
- span.text = classname[:1].upper()
-
- if (single_page):
- link = "#" + classname
- else:
- link = classname + ".html"
-
- a = ET.SubElement(td, "a")
- a.attrib["href"] = link
- a.text = classname
-
- if (not single_page):
- cat_class_list = ET.Element("html")
- csscc = ET.SubElement(cat_class_list, "link")
- csscc.attrib["href"] = "main.css"
- csscc.attrib["rel"] = "stylesheet"
- csscc.attrib["type"] = "text/css"
- bodycc = ET.SubElement(cat_class_list, "body")
- make_html_top(bodycc)
-
- cat_class_parent = bodycc
- else:
- cat_class_parent = div
-
- h1 = ET.SubElement(cat_class_parent, "h2")
- h1.text = "Class List By Category"
-
- class_cat_table = {}
- class_cat_list = []
-
- for c in class_list:
- clss = classes[c]
- if ("category" in clss.attrib):
- class_cat = clss.attrib["category"]
- else:
- class_cat = "Core"
- if (class_cat.find("/") != -1):
- class_cat = class_cat[class_cat.rfind("/") + 1:]
- if (not class_cat in class_cat_list):
- class_cat_list.append(class_cat)
- class_cat_table[class_cat] = []
- class_cat_table[class_cat].append(c)
-
- class_cat_list.sort()
-
- ct = ET.SubElement(cat_class_parent, "table")
- for cl in class_cat_list:
- l = class_cat_table[cl]
- l.sort()
- tr = ET.SubElement(ct, "tr")
- tr.attrib["class"] = "category_title"
- td = ET.SubElement(ct, "td")
- td.attrib["class"] = "category_title"
-
- a = ET.SubElement(td, "a")
- a.attrib["class"] = "category_title"
- a.text = cl
- a.attrib["name"] = "CATEGORY_" + cl
-
- td = ET.SubElement(ct, "td")
- td.attrib["class"] = "category_title"
-
- for clt in l:
- tr = ET.SubElement(ct, "tr")
- td = ET.SubElement(ct, "td")
- make_type(clt, td)
- clss = classes[clt]
- bd = clss.find("brief_description")
- bdtext = ""
- if (bd != None):
- bdtext = bd.text
- td = ET.SubElement(ct, "td")
- td.text = bdtext
-
- if (not single_page):
- make_html_bottom(bodycc)
- catet_out = ET.ElementTree(cat_class_list)
- catet_out.write("category.html")
-
- if (not single_page):
- inh_class_list = ET.Element("html")
- cssic = ET.SubElement(inh_class_list, "link")
- cssic.attrib["href"] = "main.css"
- cssic.attrib["rel"] = "stylesheet"
- cssic.attrib["type"] = "text/css"
- bodyic = ET.SubElement(inh_class_list, "body")
- make_html_top(bodyic)
- inh_class_parent = bodyic
- else:
- inh_class_parent = div
-
- h1 = ET.SubElement(inh_class_parent, "h2")
- h1.text = "Class List By Inheritance"
-
- itemlist = ET.SubElement(inh_class_parent, "list")
-
- class_inh_table = {}
-
- def add_class(clss):
- if (clss.attrib["name"] in class_inh_table):
- return # already added
- parent_list = None
-
- if ("inherits" in clss.attrib):
- inhc = clss.attrib["inherits"]
- if (not (inhc in class_inh_table)):
- add_class(classes[inhc])
-
- parent_list = class_inh_table[inhc].find("div")
- if (parent_list == None):
- parent_div = ET.SubElement(class_inh_table[inhc], "div")
- parent_list = ET.SubElement(parent_div, "list")
- parent_div.attrib["class"] = "inh_class_list"
- else:
- parent_list = parent_list.find("list")
-
- else:
- parent_list = itemlist
-
- item = ET.SubElement(parent_list, "li")
-# item.attrib["class"]="inh_class_list"
- class_inh_table[clss.attrib["name"]] = item
- make_type(clss.attrib["name"], item)
-
- for c in class_list:
- add_class(classes[c])
-
- if (not single_page):
- make_html_bottom(bodyic)
- catet_out = ET.ElementTree(inh_class_list)
- catet_out.write("inheritance.html")
-
- # h1=ET.SubElement(div,"h2")
- #h1.text="Class List By Inheritance"
-
- return div
-
-
-def make_type(p_type, p_parent):
- if (p_type == "RefPtr"):
- p_type = "Resource"
-
- if (p_type in class_names):
- a = ET.SubElement(p_parent, "a")
- a.attrib["class"] = "datatype_existing"
- a.text = p_type + " "
- if (single_page):
- a.attrib["href"] = "#" + p_type
- else:
- a.attrib["href"] = p_type + ".html"
- else:
- span = ET.SubElement(p_parent, "span")
- span.attrib["class"] = "datatype"
- span.text = p_type + " "
-
-
-def make_text_def(class_name, parent, text):
- text = html_escape(text)
- pos = 0
- while(True):
- pos = text.find("[", pos)
- if (pos == -1):
- break
-
- endq_pos = text.find("]", pos + 1)
- if (endq_pos == -1):
- break
-
- pre_text = text[:pos]
- post_text = text[endq_pos + 1:]
- tag_text = text[pos + 1:endq_pos]
-
- if (tag_text in class_names):
- if (single_page):
- tag_text = '<a href="#' + tag_text + '">' + tag_text + '</a>'
- else:
- tag_text = '<a href="' + tag_text + '.html">' + tag_text + '</a>'
- else: # command
- cmd = tag_text
- space_pos = tag_text.find(" ")
- if (cmd.find("html") == 0):
- cmd = tag_text[:space_pos]
- param = tag_text[space_pos + 1:]
- tag_text = "<" + param + ">"
- elif(cmd.find("method") == 0):
- cmd = tag_text[:space_pos]
- param = tag_text[space_pos + 1:]
-
- if (not single_page and param.find(".") != -1):
- class_param, method_param = param.split(".")
- tag_text = tag_text = '<a href="' + class_param + '.html#' + class_param + "_" + method_param + '">' + class_param + '.' + method_param + '()</a>'
- else:
- tag_text = tag_text = '<a href="#' + class_name + "_" + param + '">' + class_name + '.' + param + '()</a>'
- elif (cmd.find("image=") == 0):
- print("found image: " + cmd)
- tag_text = "<img src=" + cmd[6:] + "/>"
- elif (cmd.find("url=") == 0):
- tag_text = "<a href=" + cmd[4:] + ">"
- elif (cmd == "/url"):
- tag_text = "</a>"
- elif (cmd == "center"):
- tag_text = "<div align=\"center\">"
- elif (cmd == "/center"):
- tag_text = "</div>"
- elif (cmd == "br"):
- tag_text = "<br/>"
- elif (cmd == "i" or cmd == "/i" or cmd == "b" or cmd == "/b" or cmd == "u" or cmd == "/u"):
- tag_text = "<" + tag_text + ">" # html direct mapping
- else:
- tag_text = "[" + tag_text + "]"
-
- text = pre_text + tag_text + post_text
- pos = len(pre_text) + len(tag_text)
-
- #tnode = ET.SubElement(parent,"div")
- # tnode.text=text
- text = "<div class=\"description\">" + text + "</div>"
- try:
- tnode = ET.XML(text)
- parent.append(tnode)
- except:
- print("Error parsing description text: '" + text + "'")
- sys.exit(255)
-
- return tnode
-
-
-def make_method_def(name, m, declare, event=False):
-
- mdata = {}
-
- if (not declare):
- div = ET.Element("tr")
- div.attrib["class"] = "method"
- ret_parent = ET.SubElement(div, "td")
- ret_parent.attrib["align"] = "right"
- func_parent = ET.SubElement(div, "td")
- else:
- div = ET.Element("div")
- div.attrib["class"] = "method"
- ret_parent = div
- func_parent = div
-
- mdata["argidx"] = []
- mdata["name"] = m.attrib["name"]
- qualifiers = ""
- if ("qualifiers" in m.attrib):
- qualifiers = m.attrib["qualifiers"]
-
- args = list(m)
- for a in args:
- if (a.tag == "return"):
- idx = -1
- elif (a.tag == "argument"):
- idx = int(a.attrib["index"])
- else:
- continue
-
- mdata["argidx"].append(idx)
- mdata[idx] = a
-
- if (not event):
- if (-1 in mdata["argidx"]):
- make_type(mdata[-1].attrib["type"], ret_parent)
- mdata["argidx"].remove(-1)
- else:
- make_type("void", ret_parent)
-
- span = ET.SubElement(func_parent, "span")
- if (declare):
- span.attrib["class"] = "funcdecl"
- a = ET.SubElement(span, "a")
- a.attrib["name"] = name + "_" + m.attrib["name"]
- a.text = name + "::" + m.attrib["name"]
- else:
- span.attrib["class"] = "identifier funcdef"
- a = ET.SubElement(span, "a")
- a.attrib["href"] = "#" + name + "_" + m.attrib["name"]
- a.text = m.attrib["name"]
-
- span = ET.SubElement(func_parent, "span")
- span.attrib["class"] = "symbol"
- span.text = " ("
-
- for a in mdata["argidx"]:
- arg = mdata[a]
- if (a > 0):
- span = ET.SubElement(func_parent, "span")
- span.text = ", "
- else:
- span = ET.SubElement(func_parent, "span")
- span.text = " "
-
- make_type(arg.attrib["type"], func_parent)
-
- span = ET.SubElement(func_parent, "span")
- span.text = arg.attrib["name"]
- if ("default" in arg.attrib):
- span.text = span.text + "=" + arg.attrib["default"]
-
- span = ET.SubElement(func_parent, "span")
- span.attrib["class"] = "symbol"
- if (len(mdata["argidx"])):
- span.text = " )"
- else:
- span.text = ")"
-
- if (qualifiers):
- span = ET.SubElement(func_parent, "span")
- span.attrib["class"] = "qualifier"
- span.text = " " + qualifiers
-
- return div
-
-
-def make_html_class(node):
-
- div = ET.Element("div")
- div.attrib["class"] = "class"
-
- a = ET.SubElement(div, "a")
- a.attrib["name"] = node.attrib["name"]
-
- h3 = ET.SubElement(a, "h3")
- h3.attrib["class"] = "title class_title"
- h3.text = node.attrib["name"]
-
- briefd = node.find("brief_description")
- if (briefd != None):
- div2 = ET.SubElement(div, "div")
- div2.attrib["class"] = "description class_description"
- div2.text = briefd.text
-
- if ("inherits" in node.attrib):
- ET.SubElement(div, "br")
-
- div2 = ET.SubElement(div, "div")
- div2.attrib["class"] = "inheritance"
-
- span = ET.SubElement(div2, "span")
- span.text = "Inherits: "
-
- make_type(node.attrib["inherits"], div2)
-
- if ("category" in node.attrib):
- ET.SubElement(div, "br")
-
- div3 = ET.SubElement(div, "div")
- div3.attrib["class"] = "category"
-
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "category"
- span.text = "Category: "
-
- a = ET.SubElement(div3, "a")
- a.attrib["class"] = "category_ref"
- a.text = node.attrib["category"]
- catname = a.text
- if (catname.rfind("/") != -1):
- catname = catname[catname.rfind("/"):]
- catname = "CATEGORY_" + catname
-
- if (single_page):
- a.attrib["href"] = "#" + catname
- else:
- a.attrib["href"] = "category.html#" + catname
-
- methods = node.find("methods")
-
- if(methods != None and len(list(methods)) > 0):
-
- h4 = ET.SubElement(div, "h4")
- h4.text = "Public Methods:"
-
- method_table = ET.SubElement(div, "table")
- method_table.attrib["class"] = "method_list"
-
- for m in list(methods):
- #li = ET.SubElement(div2, "li")
- method_table.append(make_method_def(node.attrib["name"], m, False))
-
- events = node.find("signals")
-
- if(events != None and len(list(events)) > 0):
- h4 = ET.SubElement(div, "h4")
- h4.text = "Events:"
-
- event_table = ET.SubElement(div, "table")
- event_table.attrib["class"] = "method_list"
-
- for m in list(events):
- #li = ET.SubElement(div2, "li")
- event_table.append(make_method_def(node.attrib["name"], m, False, True))
-
- members = node.find("members")
- if(members != None and len(list(members)) > 0):
-
- h4 = ET.SubElement(div, "h4")
- h4.text = "Public Variables:"
- div2 = ET.SubElement(div, "div")
- div2.attrib["class"] = "member_list"
-
- for c in list(members):
-
- li = ET.SubElement(div2, "li")
- div3 = ET.SubElement(li, "div")
- div3.attrib["class"] = "member"
- make_type(c.attrib["type"], div3)
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "identifier member_name"
- span.text = " " + c.attrib["name"] + " "
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "member_description"
- span.text = c.text
-
- constants = node.find("constants")
- if(constants != None and len(list(constants)) > 0):
-
- h4 = ET.SubElement(div, "h4")
- h4.text = "Constants:"
- div2 = ET.SubElement(div, "div")
- div2.attrib["class"] = "constant_list"
-
- for c in list(constants):
- li = ET.SubElement(div2, "li")
- div3 = ET.SubElement(li, "div")
- div3.attrib["class"] = "constant"
-
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "identifier constant_name"
- span.text = c.attrib["name"] + " "
- if ("value" in c.attrib):
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "symbol"
- span.text = "= "
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "constant_value"
- span.text = c.attrib["value"] + " "
- span = ET.SubElement(div3, "span")
- span.attrib["class"] = "constant_description"
- span.text = c.text
-
-# ET.SubElement(div,"br")
-
- descr = node.find("description")
- if (descr != None and descr.text.strip() != ""):
- h4 = ET.SubElement(div, "h4")
- h4.text = "Description:"
-
- make_text_def(node.attrib["name"], div, descr.text)
-# div2=ET.SubElement(div,"div")
-# div2.attrib["class"]="description";
-# div2.text=descr.text
-
- if(methods != None or events != None):
-
- h4 = ET.SubElement(div, "h4")
- h4.text = "Method Documentation:"
- iter_list = []
- if (methods != None):
- iter_list += list(methods)
- if (events != None):
- iter_list += list(events)
-
- for m in iter_list:
-
- descr = m.find("description")
-
- if (descr == None or descr.text.strip() == ""):
- continue
-
- div2 = ET.SubElement(div, "div")
- div2.attrib["class"] = "method_doc"
-
- div2.append(make_method_def(node.attrib["name"], m, True))
- #anchor = ET.SubElement(div2, "a")
- # anchor.attrib["name"] =
- make_text_def(node.attrib["name"], div2, descr.text)
- # div3=ET.SubElement(div2,"div")
- # div3.attrib["class"]="description";
- # div3.text=descr.text
-
- return div
-
-class_names = []
-classes = {}
-
-for file in input_list:
- tree = ET.parse(file)
- doc = tree.getroot()
-
- if ("version" not in doc.attrib):
- print("Version missing from 'doc'")
- sys.exit(255)
-
- version = doc.attrib["version"]
-
- for c in list(doc):
- if (c.attrib["name"] in class_names):
- continue
- class_names.append(c.attrib["name"])
- classes[c.attrib["name"]] = c
-
-html = ET.Element("html")
-css = ET.SubElement(html, "link")
-css.attrib["href"] = "main.css"
-css.attrib["rel"] = "stylesheet"
-css.attrib["type"] = "text/css"
-
-body = ET.SubElement(html, "body")
-if (not single_page):
- make_html_top(body)
-
-
-class_names.sort()
-
-body.append(make_html_class_list(class_names, 5))
-
-for cn in class_names:
- c = classes[cn]
- if (single_page):
- body.append(make_html_class(c))
- else:
- html2 = ET.Element("html")
- css = ET.SubElement(html2, "link")
- css.attrib["href"] = "main.css"
- css.attrib["rel"] = "stylesheet"
- css.attrib["type"] = "text/css"
- body2 = ET.SubElement(html2, "body")
- make_html_top(body2)
- body2.append(make_html_class(c))
- make_html_bottom(body2)
- et_out = ET.ElementTree(html2)
- et_out.write(c.attrib["name"] + ".html")
-
-
-et_out = ET.ElementTree(html)
-if (single_page):
- et_out.write("singlepage.html")
-else:
- make_html_bottom(body)
- et_out.write("alphabetical.html")
diff --git a/doc/tools/makemd.py b/doc/tools/makemd.py
index bd0d4c6819..b2444eb47b 100644
--- a/doc/tools/makemd.py
+++ b/doc/tools/makemd.py
@@ -273,6 +273,12 @@ def make_doku_class(node):
f.write('\n### Signals \n')
for m in list(events):
make_method(f, node.attrib['name'], m, True, True)
+ d = m.find('description')
+ if d == None or d.text.strip() == '':
+ continue
+ f.write('\n')
+ f.write(dokuize_text(d.text.strip()))
+ f.write('\n')
members = node.find('members')
diff --git a/doc/tools/makerst.py b/doc/tools/makerst.py
index 6b6780ce1e..8a117f6450 100644
--- a/doc/tools/makerst.py
+++ b/doc/tools/makerst.py
@@ -441,6 +441,12 @@ def make_rst_class(node):
f.write(make_heading('Signals', '-'))
for m in list(events):
make_method(f, node.attrib['name'], m, True, name, True)
+ d = m.find('description')
+ if d == None or d.text.strip() == '':
+ continue
+ f.write(rstize_text(d.text.strip(), name))
+ f.write("\n\n")
+
f.write('\n')
members = node.find('members')
diff --git a/drivers/gles2/rasterizer_gles2.cpp b/drivers/gles2/rasterizer_gles2.cpp
index 60282fb3fa..3c543365f0 100644
--- a/drivers/gles2/rasterizer_gles2.cpp
+++ b/drivers/gles2/rasterizer_gles2.cpp
@@ -342,12 +342,12 @@ void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, c
/* TEXTURE API */
-Image RasterizerGLES2::_get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, int &r_gl_components, bool &r_has_alpha_cache, bool &r_compressed) {
+Ref<Image> RasterizerGLES2::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, int &r_gl_components, bool &r_has_alpha_cache, bool &r_compressed) {
r_has_alpha_cache = false;
r_compressed = false;
r_gl_format = 0;
- Image image = p_image;
+ Ref<Image> image = p_image;
switch (p_format) {
diff --git a/drivers/gles2/shaders/canvas.glsl b/drivers/gles2/shaders/canvas.glsl
index 4bcebbd69d..4b8c553b60 100644
--- a/drivers/gles2/shaders/canvas.glsl
+++ b/drivers/gles2/shaders/canvas.glsl
@@ -30,10 +30,8 @@ uniform highp mat4 light_local_matrix;
uniform vec2 light_pos;
varying vec4 light_uv_interp;
-#if defined(NORMAL_USED)
varying vec4 local_rot;
uniform vec2 normal_flip;
-#endif
#ifdef USE_SHADOWS
varying highp vec2 pos;
@@ -86,10 +84,8 @@ VERTEX_SHADER_CODE
pos=outvec.xy;
#endif
-#if defined(NORMAL_USED)
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x;
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy )*normal_flip.y;
-#endif
#endif
@@ -107,6 +103,7 @@ precision mediump int;
uniform sampler2D texture; // texunit:0
+uniform sampler2D normal_texture; // texunit:0
varying vec2 uv_interp;
varying vec4 color_interp;
@@ -157,9 +154,7 @@ uniform float light_height;
varying vec4 light_uv_interp;
uniform float light_outside_alpha;
-#if defined(NORMAL_USED)
varying vec4 local_rot;
-#endif
#ifdef USE_SHADOWS
@@ -189,19 +184,19 @@ FRAGMENT_SHADER_GLOBALS
void main() {
vec4 color = color_interp;
-#if defined(NORMAL_USED)
- vec3 normal = vec3(0.0,0.0,1.0);
-#endif
#ifdef USE_DISTANCE_FIELD
const float smoothing = 1.0/32.0;
- float distance = texture2D(texture, uv_interp).a;
+ float distance = textureLod(texture, uv_interp,0.0).a;
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a;
#else
color *= texture2D( texture, uv_interp );
#endif
+ vec3 normal;
+ normal.xy = textureLod( normal_texture, uv_interp, 0.0 ).xy * 2.0 - 1.0;
+ normal.z = sqrt(1.0-dot(normal.xy,normal.xy));
#if defined(ENABLE_SCREEN_UV)
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
@@ -236,9 +231,7 @@ FRAGMENT_SHADER_CODE
vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping
-#if defined(NORMAL_USED)
normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
-#endif
float att=1.0;
@@ -263,10 +256,8 @@ LIGHT_SHADER_CODE
#else
-#if defined(NORMAL_USED)
vec3 light_normal = normalize(vec3(light_vec,-light_height));
light*=max(dot(-light_normal,normal),0.0);
-#endif
color*=light;
/*
diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp
index 4f6d68de43..a8895f7bfc 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.cpp
+++ b/drivers/gles3/rasterizer_canvas_gles3.cpp
@@ -29,8 +29,8 @@
/*************************************************************************/
#include "rasterizer_canvas_gles3.h"
+#include "global_config.h"
#include "os/os.h"
-
#ifndef GLES_OVER_GL
#define glClearDepth glClearDepthf
#endif
@@ -113,7 +113,7 @@ void RasterizerCanvasGLES3::light_internal_update(RID p_rid, Light *p_light) {
li->ubo_data.light_pos[0] = p_light->light_shader_pos.x;
li->ubo_data.light_pos[1] = p_light->light_shader_pos.y;
- li->ubo_data.shadowpixel_size = 1.0 / p_light->shadow_buffer_size;
+ li->ubo_data.shadowpixel_size = (1.0 / p_light->shadow_buffer_size) * (1.0 + p_light->shadow_smooth);
li->ubo_data.light_outside_alpha = p_light->mode == VS::CANVAS_LIGHT_MODE_MASK ? 1.0 : 0.0;
li->ubo_data.light_height = p_light->height;
if (p_light->radius_cache == 0)
@@ -188,40 +188,74 @@ void RasterizerCanvasGLES3::canvas_end() {
state.using_texture_rect = false;
}
-RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture) {
+RasterizerStorageGLES3::Texture *RasterizerCanvasGLES3::_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map) {
- if (p_texture == state.current_tex) {
- return state.current_tex_ptr;
- }
+ RasterizerStorageGLES3::Texture *tex_return = NULL;
- if (p_texture.is_valid()) {
+ if (p_texture == state.current_tex) {
+ tex_return = state.current_tex_ptr;
+ } else if (p_texture.is_valid()) {
RasterizerStorageGLES3::Texture *texture = storage->texture_owner.getornull(p_texture);
if (!texture) {
state.current_tex = RID();
state.current_tex_ptr = NULL;
+ glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
- return NULL;
- }
- if (texture->render_target)
- texture->render_target->used_in_frame = true;
+ } else {
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
- state.current_tex = p_texture;
- state.current_tex_ptr = texture;
+ if (texture->render_target)
+ texture->render_target->used_in_frame = true;
- return texture;
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, texture->tex_id);
+ state.current_tex = p_texture;
+ state.current_tex_ptr = texture;
+
+ tex_return = texture;
+ }
} else {
+ glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
state.current_tex = RID();
state.current_tex_ptr = NULL;
}
- return NULL;
+ if (p_normal_map == state.current_normal) {
+ //do none
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, state.current_normal.is_valid());
+
+ } else if (p_normal_map.is_valid()) {
+
+ RasterizerStorageGLES3::Texture *normal_map = storage->texture_owner.getornull(p_normal_map);
+
+ if (!normal_map) {
+ state.current_normal = RID();
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
+
+ } else {
+
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, normal_map->tex_id);
+ state.current_normal = p_normal_map;
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, true);
+ }
+
+ } else {
+
+ state.current_normal = RID();
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, storage->resources.normal_tex);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::USE_DEFAULT_NORMAL, false);
+ }
+
+ return tex_return;
}
void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable) {
@@ -247,113 +281,56 @@ void RasterizerCanvasGLES3::_set_texture_rect_mode(bool p_enable) {
state.using_texture_rect = p_enable;
}
-void RasterizerCanvasGLES3::_draw_polygon(int p_vertex_count, const int *p_indices, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, const RID &p_texture, bool p_singlecolor) {
-
- bool do_colors = false;
- Color m;
- if (p_singlecolor) {
- m = *p_colors;
- glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
- } else if (!p_colors) {
+void RasterizerCanvasGLES3::_draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor) {
- glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
- } else
- do_colors = true;
+ glBindVertexArray(data.polygon_buffer_pointer_array);
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(p_texture);
+ uint32_t buffer_ofs = 0;
-#ifndef GLES_NO_CLIENT_ARRAYS
+ //vertex
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_vertices);
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
- glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), p_vertices);
- if (do_colors) {
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
+ //color
- glEnableVertexAttribArray(VS::ARRAY_COLOR);
- glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), p_colors);
- } else {
+ if (p_singlecolor) {
glDisableVertexAttribArray(VS::ARRAY_COLOR);
- }
-
- if (texture && p_uvs) {
-
- glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
- glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), p_uvs);
- } else {
- glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
- }
-
- if (p_indices) {
- glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_INT, p_indices);
+ Color m = *p_colors;
+ glVertexAttrib4f(VS::ARRAY_COLOR, m.r, m.g, m.b, m.a);
+ } else if (!p_colors) {
+ glDisableVertexAttribArray(VS::ARRAY_COLOR);
+ glVertexAttrib4f(VS::ARRAY_COLOR, 1, 1, 1, 1);
} else {
- glDrawArrays(GL_TRIANGLES, 0, p_vertex_count);
- }
-
-#else //WebGL specific impl.
- glBindBuffer(GL_ARRAY_BUFFER, gui_quad_buffer);
- float *b = GlobalVertexBuffer;
- int ofs = 0;
- if (p_vertex_count > MAX_POLYGON_VERTICES) {
- print_line("Too many vertices to render");
- return;
- }
- glEnableVertexAttribArray(VS::ARRAY_VERTEX);
- glVertexAttribPointer(VS::ARRAY_VERTEX, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
- for (int i = 0; i < p_vertex_count; i++) {
- b[ofs++] = p_vertices[i].x;
- b[ofs++] = p_vertices[i].y;
- }
-
- if (p_colors && do_colors) {
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Color) * p_vertex_count, p_colors);
glEnableVertexAttribArray(VS::ARRAY_COLOR);
- glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(float) * 4, ((float *)0) + ofs);
- for (int i = 0; i < p_vertex_count; i++) {
- b[ofs++] = p_colors[i].r;
- b[ofs++] = p_colors[i].g;
- b[ofs++] = p_colors[i].b;
- b[ofs++] = p_colors[i].a;
- }
-
- } else {
- glDisableVertexAttribArray(VS::ARRAY_COLOR);
+ glVertexAttribPointer(VS::ARRAY_COLOR, 4, GL_FLOAT, false, sizeof(Color), ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(Color) * p_vertex_count;
}
if (p_uvs) {
+ glBufferSubData(GL_ARRAY_BUFFER, buffer_ofs, sizeof(Vector2) * p_vertex_count, p_uvs);
glEnableVertexAttribArray(VS::ARRAY_TEX_UV);
- glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(float) * 2, ((float *)0) + ofs);
- for (int i = 0; i < p_vertex_count; i++) {
- b[ofs++] = p_uvs[i].x;
- b[ofs++] = p_uvs[i].y;
- }
+ glVertexAttribPointer(VS::ARRAY_TEX_UV, 2, GL_FLOAT, false, sizeof(Vector2), ((uint8_t *)0) + buffer_ofs);
+ buffer_ofs += sizeof(Vector2) * p_vertex_count;
} else {
glDisableVertexAttribArray(VS::ARRAY_TEX_UV);
}
- glBufferSubData(GL_ARRAY_BUFFER, 0, ofs * 4, &b[0]);
-
//bind the indices buffer.
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices_buffer);
-
- static const int _max_draw_poly_indices = 16 * 1024; // change this size if needed!!!
- ERR_FAIL_COND(p_vertex_count > _max_draw_poly_indices);
- static uint16_t _draw_poly_indices[_max_draw_poly_indices];
- for (int i = 0; i < p_vertex_count; i++) {
- _draw_poly_indices[i] = p_indices[i];
- //OS::get_singleton()->print("ind: %d ", p_indices[i]);
- };
-
- //copy the data to GPU.
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, p_vertex_count * sizeof(uint16_t), &_draw_poly_indices[0]);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(int) * p_index_count, p_indices);
//draw the triangles.
- glDrawElements(GL_TRIANGLES, p_vertex_count, GL_UNSIGNED_SHORT, 0);
-
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
-#endif
+ glDrawElements(GL_TRIANGLES, p_index_count, GL_UNSIGNED_INT, 0);
storage->frame.canvas_draw_commands++;
+
+ glBindVertexArray(0);
}
void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs) {
@@ -404,9 +381,9 @@ void RasterizerCanvasGLES3::_draw_gui_primitive(int p_points, const Vector2 *p_v
}
}
- glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
glBufferSubData(GL_ARRAY_BUFFER, 0, p_points * stride * 4, &b[0]);
- glBindVertexArray(data.primitive_quad_buffer_arrays[version]);
+ glBindVertexArray(data.polygon_buffer_quad_arrays[version]);
glDrawArrays(prim[p_points], 0, p_points);
glBindVertexArray(0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
@@ -429,7 +406,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Item::CommandLine *line = static_cast<Item::CommandLine *>(c);
_set_texture_rect_mode(false);
- _bind_canvas_texture(RID());
+ _bind_canvas_texture(RID(), RID());
glVertexAttrib4f(VS::ARRAY_COLOR, line->color.r, line->color.g, line->color.b, line->color.a);
@@ -460,7 +437,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
//set color
glVertexAttrib4f(VS::ARRAY_COLOR, rect->modulate.r, rect->modulate.g, rect->modulate.b, rect->modulate.a);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(rect->texture);
+ RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(rect->texture, rect->normal_map);
if (texture) {
@@ -473,7 +450,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
}
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
- Rect2 src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.pos * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
+ Rect2 src_rect = (rect->flags & CANVAS_RECT_REGION) ? Rect2(rect->source.position * texpixel_size, rect->source.size * texpixel_size) : Rect2(0, 0, 1, 1);
if (rect->flags & CANVAS_RECT_FLIP_H) {
src_rect.size.x *= -1;
@@ -489,8 +466,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
- glVertexAttrib4f(1, rect->rect.pos.x, rect->rect.pos.y, rect->rect.size.x, rect->rect.size.y);
- glVertexAttrib4f(2, src_rect.pos.x, src_rect.pos.y, src_rect.size.x, src_rect.size.y);
+ 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));
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(src_rect.position.x, src_rect.position.y, src_rect.size.x, src_rect.size.y));
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, (rect->flags & CANVAS_RECT_CLIP_UV) ? true : false);
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (untile) {
@@ -500,8 +479,9 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
} else {
- glVertexAttrib4f(1, rect->rect.pos.x, rect->rect.pos.y, rect->rect.size.x, rect->rect.size.y);
- glVertexAttrib4f(2, 0, 0, 1, 1);
+ 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));
+ 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);
}
@@ -517,11 +497,11 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
glVertexAttrib4f(VS::ARRAY_COLOR, np->color.r, np->color.g, np->color.b, np->color.a);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(np->texture);
+ RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(np->texture, np->normal_map);
if (!texture) {
- glVertexAttrib4f(1, np->rect.pos.x, np->rect.pos.y, np->rect.size.x, np->rect.size.y);
+ glVertexAttrib4f(1, np->rect.position.x, np->rect.position.y, np->rect.size.x, np->rect.size.y);
glVertexAttrib4f(2, 0, 0, 1, 1);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
continue;
@@ -530,55 +510,56 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false);
-#define DSTRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(1, m_x, m_y, m_w, m_h)
-#define SRCRECT(m_x, m_y, m_w, m_h) glVertexAttrib4f(2, (m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y)
+#define DSTRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(m_x, m_y, m_w, m_h))
+#define SRCRECT(m_x, m_y, m_w, m_h) state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color((m_x)*texpixel_size.x, (m_y)*texpixel_size.y, (m_w)*texpixel_size.x, (m_h)*texpixel_size.y))
//top left
- DSTRECT(np->rect.pos.x, np->rect.pos.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
- SRCRECT(np->source.pos.x, np->source.pos.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.position.x, np->rect.position.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.position.x, np->source.position.y, np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//top right
- DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.position.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.position.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.position.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.position.y, np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom right
- DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.position.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.position.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.position.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.position.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_RIGHT], np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom left
- DSTRECT(np->rect.pos.x, np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->source.pos.x, np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.position.x, np->rect.position.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.position.x, np->source.position.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->margin[MARGIN_LEFT], np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//top
- DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y, np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y, np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.position.x + np->margin[MARGIN_LEFT], np->rect.position.y, np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.position.x + np->margin[MARGIN_LEFT], np->source.position.y, np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//bottom
- DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
- SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
+ DSTRECT(np->rect.position.x + np->margin[MARGIN_LEFT], np->rect.position.y + np->rect.size.height - np->margin[MARGIN_BOTTOM], np->rect.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->margin[MARGIN_TOP]);
+ SRCRECT(np->source.position.x + np->margin[MARGIN_LEFT], np->source.position.y + np->source.size.height - np->margin[MARGIN_BOTTOM], np->source.size.width - np->margin[MARGIN_LEFT] - np->margin[MARGIN_LEFT], np->margin[MARGIN_TOP]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//left
- DSTRECT(np->rect.pos.x, np->rect.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->source.pos.x, np->source.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.position.x, np->rect.position.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.position.x, np->source.position.y + np->margin[MARGIN_TOP], np->margin[MARGIN_LEFT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
//right
- DSTRECT(np->rect.pos.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->source.pos.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.pos.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.position.x + np->rect.size.width - np->margin[MARGIN_RIGHT], np->rect.position.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.position.x + np->source.size.width - np->margin[MARGIN_RIGHT], np->source.position.y + np->margin[MARGIN_TOP], np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
if (np->draw_center) {
//center
- DSTRECT(np->rect.pos.x + np->margin[MARGIN_LEFT], np->rect.pos.y + np->margin[MARGIN_TOP], np->rect.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
- SRCRECT(np->source.pos.x + np->margin[MARGIN_LEFT], np->source.pos.y + np->margin[MARGIN_TOP], np->source.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ DSTRECT(np->rect.position.x + np->margin[MARGIN_LEFT], np->rect.position.y + np->margin[MARGIN_TOP], np->rect.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->rect.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
+ SRCRECT(np->source.position.x + np->margin[MARGIN_LEFT], np->source.position.y + np->margin[MARGIN_TOP], np->source.size.x - np->margin[MARGIN_LEFT] - np->margin[MARGIN_RIGHT], np->source.size.height - np->margin[MARGIN_TOP] - np->margin[MARGIN_BOTTOM]);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
@@ -595,7 +576,7 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
ERR_CONTINUE(primitive->points.size() < 1);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture);
+ RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(primitive->texture, primitive->normal_map);
if (texture) {
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
@@ -618,13 +599,13 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
Item::CommandPolygon *polygon = static_cast<Item::CommandPolygon *>(c);
_set_texture_rect_mode(false);
- RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture);
+ RasterizerStorageGLES3::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
if (texture) {
Size2 texpixel_size(1.0 / texture->width, 1.0 / texture->height);
state.canvas_shader.set_uniform(CanvasShaderGLES3::COLOR_TEXPIXEL_SIZE, texpixel_size);
}
- //_draw_polygon(polygon->count,polygon->indices.ptr(),polygon->points.ptr(),polygon->uvs.ptr(),polygon->colors.ptr(),polygon->texture,polygon->colors.size()==1);
+ _draw_polygon(polygon->indices.ptr(), polygon->count, polygon->points.size(), polygon->points.ptr(), polygon->uvs.ptr(), polygon->colors.ptr(), polygon->colors.size() == 1);
} break;
case Item::Command::TYPE_CIRCLE: {
@@ -644,6 +625,10 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
indices[i * 3 + 1] = (i + 1) % numpoints;
indices[i * 3 + 2] = numpoints;
}
+
+ _bind_canvas_texture(RID(), RID());
+ _draw_polygon(indices, numpoints * 3, numpoints + 1, points, NULL, &circle->color, true);
+
//_draw_polygon(numpoints*3,indices,points,NULL,&circle->color,RID(),true);
//canvas_draw_circle(circle->indices.size(),circle->indices.ptr(),circle->points.ptr(),circle->uvs.ptr(),circle->colors.ptr(),circle->texture,circle->colors.size()==1);
} break;
@@ -670,8 +655,8 @@ void RasterizerCanvasGLES3::_canvas_item_render_commands(Item *p_item, Item *cur
//glScissor(viewport.x+current_clip->final_clip_rect.pos.x,viewport.y+ (viewport.height-(current_clip->final_clip_rect.pos.y+current_clip->final_clip_rect.size.height)),
//current_clip->final_clip_rect.size.width,current_clip->final_clip_rect.size.height);
- int x = current_clip->final_clip_rect.pos.x;
- int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.y);
+ int x = current_clip->final_clip_rect.position.x;
+ int y = storage->frame.current_rt->height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.y);
int w = current_clip->final_clip_rect.size.x;
int h = current_clip->final_clip_rect.size.y;
@@ -759,6 +744,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
state.current_tex = RID();
state.current_tex_ptr = NULL;
+ state.current_normal = RID();
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
@@ -787,7 +773,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
if (current_clip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.pos.x, (rt_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
} else {
@@ -866,7 +852,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
for (int i = 0; i < tc; i++) {
- glActiveTexture(GL_TEXTURE1 + i);
+ glActiveTexture(GL_TEXTURE2 + i);
RasterizerStorageGLES3::Texture *t = storage->texture_owner.getornull(textures[i]);
if (!t) {
@@ -1108,7 +1094,7 @@ void RasterizerCanvasGLES3::canvas_render_items(Item *p_item_list, int p_z, cons
if (reclip) {
glEnable(GL_SCISSOR_TEST);
- glScissor(current_clip->final_clip_rect.pos.x, (rt_size.height - (current_clip->final_clip_rect.pos.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
+ glScissor(current_clip->final_clip_rect.position.x, (rt_size.height - (current_clip->final_clip_rect.position.y + current_clip->final_clip_rect.size.height)), current_clip->final_clip_rect.size.width, current_clip->final_clip_rect.size.height);
}
p_item_list = p_item_list->next;
@@ -1165,7 +1151,6 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons
glBindFramebuffer(GL_FRAMEBUFFER, cls->fbo);
- glEnableVertexAttribArray(VS::ARRAY_VERTEX);
state.canvas_shadow_shader.bind();
glViewport(0, 0, cls->size, cls->height);
@@ -1264,18 +1249,14 @@ void RasterizerCanvasGLES3::canvas_light_shadow_buffer_update(RID p_buffer, cons
}
}
*/
- glBindBuffer(GL_ARRAY_BUFFER, cc->vertex_id);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, cc->index_id);
- glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
+ glBindVertexArray(cc->array_id);
glDrawElements(GL_TRIANGLES, cc->len * 3, GL_UNSIGNED_SHORT, 0);
instance = instance->next;
}
}
- glDisableVertexAttribArray(VS::ARRAY_VERTEX);
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindVertexArray(0);
}
void RasterizerCanvasGLES3::reset_canvas() {
@@ -1299,9 +1280,6 @@ void RasterizerCanvasGLES3::reset_canvas() {
//glLineWidth(1.0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- for (int i = 0; i < VS::ARRAY_MAX; i++) {
- glDisableVertexAttribArray(i);
- }
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->resources.white_tex);
@@ -1327,9 +1305,7 @@ void RasterizerCanvasGLES3::reset_canvas() {
state.vp = canvas_transform;
store_transform(canvas_transform, state.canvas_item_ubo_data.projection_matrix);
- for (int i = 0; i < 4; i++) {
- state.canvas_item_ubo_data.time[i] = storage->frame.time[i];
- }
+ state.canvas_item_ubo_data.time = storage->frame.time[0];
glBindBuffer(GL_UNIFORM_BUFFER, state.canvas_item_ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, sizeof(CanvasItemUBO), &state.canvas_item_ubo_data);
@@ -1340,8 +1316,10 @@ void RasterizerCanvasGLES3::reset_canvas() {
void RasterizerCanvasGLES3::draw_generic_textured_rect(const Rect2 &p_rect, const Rect2 &p_src) {
- glVertexAttrib4f(1, p_rect.pos.x, p_rect.pos.y, p_rect.size.x, p_rect.size.y);
- glVertexAttrib4f(2, p_src.pos.x, p_src.pos.y, p_src.size.x, p_src.size.y);
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::DST_RECT, Color(p_rect.position.x, p_rect.position.y, p_rect.size.x, p_rect.size.y));
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::SRC_RECT, Color(p_src.position.x, p_src.position.y, p_src.size.x, p_src.size.y));
+ state.canvas_shader.set_uniform(CanvasShaderGLES3::CLIP_RECT_UV, false);
+
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
@@ -1376,15 +1354,19 @@ void RasterizerCanvasGLES3::initialize() {
{
- glGenBuffers(1, &data.primitive_quad_buffer);
- glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer);
- glBufferData(GL_ARRAY_BUFFER, (2 + 2 + 4) * 4 * sizeof(float), NULL, GL_DYNAMIC_DRAW); //allocate max size
+ uint32_t poly_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_buffer_size_kb", 128);
+ poly_size *= 1024; //kb
+ poly_size = MAX(poly_size, (2 + 2 + 4) * 4 * sizeof(float));
+ glGenBuffers(1, &data.polygon_buffer);
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
+ glBufferData(GL_ARRAY_BUFFER, poly_size, NULL, GL_DYNAMIC_DRAW); //allocate max size
glBindBuffer(GL_ARRAY_BUFFER, 0);
+ //quad arrays
for (int i = 0; i < 4; i++) {
- glGenVertexArrays(1, &data.primitive_quad_buffer_arrays[i]);
- glBindVertexArray(data.primitive_quad_buffer_arrays[i]);
- glBindBuffer(GL_ARRAY_BUFFER, data.primitive_quad_buffer);
+ glGenVertexArrays(1, &data.polygon_buffer_quad_arrays[i]);
+ glBindVertexArray(data.polygon_buffer_quad_arrays[i]);
+ glBindBuffer(GL_ARRAY_BUFFER, data.polygon_buffer);
int uv_ofs = 0;
int color_ofs = 0;
@@ -1415,6 +1397,15 @@ void RasterizerCanvasGLES3::initialize() {
glBindVertexArray(0);
}
+
+ glGenVertexArrays(1, &data.polygon_buffer_pointer_array);
+
+ uint32_t index_size = GLOBAL_DEF("rendering/buffers/canvas_polygon_index_buffer_size_kb", 128);
+ index_size *= 1024; //kb
+ glGenBuffers(1, &data.polygon_index_buffer);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, data.polygon_index_buffer);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_size, NULL, GL_DYNAMIC_DRAW); //allocate max size
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
store_transform(Transform(), state.canvas_item_ubo_data.projection_matrix);
@@ -1436,6 +1427,8 @@ void RasterizerCanvasGLES3::finalize() {
glDeleteBuffers(1, &data.canvas_quad_vertices);
glDeleteVertexArrays(1, &data.canvas_quad_array);
+
+ glDeleteVertexArrays(1, &data.polygon_buffer_pointer_array);
}
RasterizerCanvasGLES3::RasterizerCanvasGLES3() {
diff --git a/drivers/gles3/rasterizer_canvas_gles3.h b/drivers/gles3/rasterizer_canvas_gles3.h
index 95ef9ee443..4996f0a6b2 100644
--- a/drivers/gles3/rasterizer_canvas_gles3.h
+++ b/drivers/gles3/rasterizer_canvas_gles3.h
@@ -39,7 +39,7 @@ public:
struct CanvasItemUBO {
float projection_matrix[16];
- float time[4];
+ float time;
};
struct Data {
@@ -47,8 +47,11 @@ public:
GLuint canvas_quad_vertices;
GLuint canvas_quad_array;
- GLuint primitive_quad_buffer;
- GLuint primitive_quad_buffer_arrays[4];
+ GLuint polygon_buffer;
+ GLuint polygon_buffer_quad_arrays[4];
+ GLuint polygon_buffer_pointer_array;
+ GLuint polygon_index_buffer;
+ uint32_t polygon_buffer_size;
} data;
@@ -62,6 +65,7 @@ public:
bool using_texture_rect;
RID current_tex;
+ RID current_normal;
RasterizerStorageGLES3::Texture *current_tex_ptr;
Transform vp;
@@ -104,10 +108,10 @@ public:
virtual void canvas_end();
_FORCE_INLINE_ void _set_texture_rect_mode(bool p_enable);
- _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture);
+ _FORCE_INLINE_ RasterizerStorageGLES3::Texture *_bind_canvas_texture(const RID &p_texture, const RID &p_normal_map);
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color *p_colors, const Vector2 *p_uvs);
- _FORCE_INLINE_ void _draw_polygon(int p_vertex_count, const int *p_indices, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, const RID &p_texture, bool p_singlecolor);
+ _FORCE_INLINE_ void _draw_polygon(const int *p_indices, int p_index_count, int p_vertex_count, const Vector2 *p_vertices, const Vector2 *p_uvs, const Color *p_colors, bool p_singlecolor);
_FORCE_INLINE_ void _canvas_item_render_commands(Item *p_item, Item *current_clip, bool &reclip);
virtual void canvas_render_items(Item *p_item_list, int p_z, const Color &p_modulate, Light *p_light);
diff --git a/drivers/gles3/rasterizer_gles3.cpp b/drivers/gles3/rasterizer_gles3.cpp
index db814ec721..53df7e9c3d 100644
--- a/drivers/gles3/rasterizer_gles3.cpp
+++ b/drivers/gles3/rasterizer_gles3.cpp
@@ -212,11 +212,8 @@ void RasterizerGLES3::begin_frame() {
storage->update_dirty_resources();
- storage->info.render_object_count = 0;
- storage->info.render_material_switch_count = 0;
- storage->info.render_surface_switch_count = 0;
- storage->info.render_shader_rebind_count = 0;
- storage->info.render_vertices_count = 0;
+ storage->info.render_final = storage->info.render;
+ storage->info.render.reset();
scene->iteration();
}
@@ -271,9 +268,9 @@ void RasterizerGLES3::clear_render_target(const Color &p_color) {
storage->frame.clear_request_color = p_color;
}
-void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) {
+void RasterizerGLES3::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) {
- if (p_image.empty())
+ if (p_image.is_null() || p_image->empty())
return;
begin_frame();
@@ -290,10 +287,10 @@ void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color,
canvas->canvas_begin();
RID texture = storage->texture_create();
- storage->texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), VS::TEXTURE_FLAG_FILTER);
+ storage->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), VS::TEXTURE_FLAG_FILTER);
storage->texture_set_data(texture, p_image);
- Rect2 imgrect(0, 0, p_image.get_width(), p_image.get_height());
+ Rect2 imgrect(0, 0, p_image->get_width(), p_image->get_height());
Rect2 screenrect;
if (p_scale) {
@@ -301,18 +298,18 @@ void RasterizerGLES3::set_boot_image(const Image &p_image, const Color &p_color,
//scale horizontally
screenrect.size.y = window_h;
screenrect.size.x = imgrect.size.x * window_h / imgrect.size.y;
- screenrect.pos.x = (window_w - screenrect.size.x) / 2;
+ screenrect.position.x = (window_w - screenrect.size.x) / 2;
} else {
//scale vertically
screenrect.size.x = window_w;
screenrect.size.y = imgrect.size.y * window_w / imgrect.size.x;
- screenrect.pos.y = (window_h - screenrect.size.y) / 2;
+ screenrect.position.y = (window_h - screenrect.size.y) / 2;
}
} else {
screenrect = imgrect;
- screenrect.pos += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
+ screenrect.position += ((Size2(window_w, window_h) - screenrect.size) / 2.0).floor();
}
RasterizerStorageGLES3::Texture *t = storage->texture_owner.get(texture);
diff --git a/drivers/gles3/rasterizer_gles3.h b/drivers/gles3/rasterizer_gles3.h
index 12014cd814..ce18d6b6c1 100644
--- a/drivers/gles3/rasterizer_gles3.h
+++ b/drivers/gles3/rasterizer_gles3.h
@@ -48,7 +48,7 @@ public:
virtual RasterizerCanvas *get_canvas();
virtual RasterizerScene *get_scene();
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale);
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void initialize();
virtual void begin_frame();
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp
index a7996b09d3..913aa62452 100644
--- a/drivers/gles3/rasterizer_scene_gles3.cpp
+++ b/drivers/gles3/rasterizer_scene_gles3.cpp
@@ -798,20 +798,20 @@ void RasterizerSceneGLES3::environment_set_background(RID p_env, VS::Environment
env->bg_mode = p_bg;
}
-void RasterizerSceneGLES3::environment_set_skybox(RID p_env, RID p_skybox) {
+void RasterizerSceneGLES3::environment_set_sky(RID p_env, RID p_sky) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->skybox = p_skybox;
+ env->sky = p_sky;
}
-void RasterizerSceneGLES3::environment_set_skybox_scale(RID p_env, float p_scale) {
+void RasterizerSceneGLES3::environment_set_sky_scale(RID p_env, float p_scale) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
- env->skybox_scale = p_scale;
+ env->sky_scale = p_scale;
}
void RasterizerSceneGLES3::environment_set_bg_color(RID p_env, const Color &p_color) {
@@ -836,14 +836,14 @@ void RasterizerSceneGLES3::environment_set_canvas_max_layer(RID p_env, int p_max
env->canvas_max_layer = p_max_layer;
}
-void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy, float p_skybox_contribution) {
+void RasterizerSceneGLES3::environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy, float p_sky_contribution) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->ambient_color = p_color;
env->ambient_energy = p_energy;
- env->ambient_skybox_contribution = p_skybox_contribution;
+ env->ambient_sky_contribution = p_sky_contribution;
}
void RasterizerSceneGLES3::environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_amount, VS::EnvironmentDOFBlurQuality p_quality) {
@@ -887,17 +887,16 @@ void RasterizerSceneGLES3::environment_set_glow(RID p_env, bool p_enable, int p_
void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) {
}
-void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) {
+void RasterizerSceneGLES3::environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) {
Environment *env = environment_owner.getornull(p_env);
ERR_FAIL_COND(!env);
env->ssr_enabled = p_enable;
env->ssr_max_steps = p_max_steps;
- env->ssr_accel = p_accel;
- env->ssr_fade = p_fade;
+ env->ssr_fade_in = p_fade_in;
+ env->ssr_fade_out = p_fade_out;
env->ssr_depth_tolerance = p_depth_tolerance;
- env->ssr_smooth = p_smooth;
env->ssr_roughness = p_roughness;
}
@@ -933,6 +932,49 @@ void RasterizerSceneGLES3::environment_set_tonemap(RID p_env, VS::EnvironmentTon
}
void RasterizerSceneGLES3::environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->adjustments_enabled = p_enable;
+ env->adjustments_brightness = p_brightness;
+ env->adjustments_contrast = p_contrast;
+ env->adjustments_saturation = p_saturation;
+ env->color_correction = p_ramp;
+}
+
+void RasterizerSceneGLES3::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_enabled = p_enable;
+ env->fog_color = p_color;
+ env->fog_sun_color = p_sun_color;
+ env->fog_sun_amount = p_sun_amount;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_depth_enabled = p_enable;
+ env->fog_depth_begin = p_depth_begin;
+ env->fog_depth_curve = p_depth_curve;
+ env->fog_transmit_enabled = p_transmit;
+ env->fog_transmit_curve = p_transmit_curve;
+}
+
+void RasterizerSceneGLES3::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
+
+ Environment *env = environment_owner.getornull(p_env);
+ ERR_FAIL_COND(!env);
+
+ env->fog_height_enabled = p_enable;
+ env->fog_height_min = p_min_height;
+ env->fog_height_max = p_max_height;
+ env->fog_height_curve = p_height_curve;
}
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
@@ -961,7 +1003,7 @@ void RasterizerSceneGLES3::light_instance_set_transform(RID p_light_instance, co
light_instance->transform = p_transform;
}
-void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass) {
+void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale) {
LightInstance *light_instance = light_instance_owner.getornull(p_light_instance);
ERR_FAIL_COND(!light_instance);
@@ -976,6 +1018,7 @@ void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_insta
light_instance->shadow_transform[p_pass].transform = p_transform;
light_instance->shadow_transform[p_pass].farplane = p_far;
light_instance->shadow_transform[p_pass].split = p_split;
+ light_instance->shadow_transform[p_pass].bias_scale = p_bias_scale;
}
void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) {
@@ -1164,6 +1207,7 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
} break;
case ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL: {
tex = storage->resources.normal_tex;
+
} break;
default: {
tex = storage->resources.white_tex;
@@ -1177,6 +1221,15 @@ bool RasterizerSceneGLES3::_setup_material(RasterizerStorageGLES3::Material *p_m
t->detect_3d(t->detect_3d_ud);
}
#endif
+
+#ifdef TOOLS_ENABLED
+ if (t->detect_normal && texture_hints[i] == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL) {
+ t->detect_normal(t->detect_normal_ud);
+ }
+#endif
+ if (t->render_target)
+ t->render_target->used_in_frame = true;
+
if (storage->config.srgb_decode_supported) {
//if SRGB decode extension is present, simply switch the texture to whathever is needed
bool must_srgb = false;
@@ -1247,8 +1300,11 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
storage->mesh_render_blend_shapes(s, e->instance->blend_values.ptr());
//rebind shader
state.scene_shader.bind();
+#ifdef DEBUG_ENABLED
+ } else if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+ glBindVertexArray(s->array_wireframe_id); // everything is so easy nowadays
+#endif
} else {
-
glBindVertexArray(s->array_id); // everything is so easy nowadays
}
@@ -1258,7 +1314,16 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
RasterizerStorageGLES3::MultiMesh *multi_mesh = static_cast<RasterizerStorageGLES3::MultiMesh *>(e->owner);
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the instancing array ID
+ } else
+#endif
+ {
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
+
glBindBuffer(GL_ARRAY_BUFFER, multi_mesh->buffer); //modify the buffer
int stride = (multi_mesh->xform_floats + multi_mesh->color_floats) * 4;
@@ -1323,13 +1388,26 @@ void RasterizerSceneGLES3::_setup_geometry(RenderList::Element *e, const Transfo
sorter.sort(particle_array, particles->amount);
glUnmapBuffer(GL_ARRAY_BUFFER);
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
+ } else
+#endif
+ {
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffer_histories[1]); //modify the buffer
} else {
-
- glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+#ifdef DEBUG_ENABLED
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->instancing_array_wireframe_id) {
+ glBindVertexArray(s->instancing_array_wireframe_id); // use the wireframe instancing array ID
+ } else
+#endif
+ {
+ glBindVertexArray(s->instancing_array_id); // use the instancing array ID
+ }
glBindBuffer(GL_ARRAY_BUFFER, particles->particle_buffers[0]); //modify the buffer
}
@@ -1378,17 +1456,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
RasterizerStorageGLES3::Surface *s = static_cast<RasterizerStorageGLES3::Surface *>(e->geometry);
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElements(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0);
+ storage->info.render.vertices_count += s->index_array_len;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0);
- storage->info.render_vertices_count += s->index_array_len;
+ storage->info.render.vertices_count += s->index_array_len;
} else {
glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
- storage->info.render_vertices_count += s->array_len;
+ storage->info.render.vertices_count += s->array_len;
}
} break;
@@ -1399,17 +1485,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
int amount = MAX(multi_mesh->size, multi_mesh->visible_instances);
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount);
+ storage->info.render.vertices_count += s->index_array_len * amount;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
- storage->info.render_vertices_count += s->index_array_len * amount;
+ storage->info.render.vertices_count += s->index_array_len * amount;
} else {
glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
- storage->info.render_vertices_count += s->array_len * amount;
+ storage->info.render.vertices_count += s->array_len * amount;
}
} break;
@@ -1435,7 +1529,7 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
int vertices = c.vertices.size();
uint32_t buf_ofs = 0;
- storage->info.render_vertices_count += vertices;
+ storage->info.render.vertices_count += vertices;
if (c.texture.is_valid() && storage->texture_owner.owns(c.texture)) {
@@ -1557,18 +1651,25 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
glEnableVertexAttribArray(12); //custom
glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + stride * split + sizeof(float) * 4 * 2);
glVertexAttribDivisor(12, 1);
+#ifdef DEBUG_ENABLED
- if (s->index_array_len > 0) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount - split);
+ storage->info.render.vertices_count += s->index_array_len * (amount - split);
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount - split);
- storage->info.render_vertices_count += s->index_array_len * (amount - split);
+ storage->info.render.vertices_count += s->index_array_len * (amount - split);
} else {
glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount - split);
- storage->info.render_vertices_count += s->array_len * (amount - split);
+ storage->info.render.vertices_count += s->array_len * (amount - split);
}
}
@@ -1588,34 +1689,49 @@ void RasterizerSceneGLES3::_render_geometry(RenderList::Element *e) {
glEnableVertexAttribArray(12); //custom
glVertexAttribPointer(12, 4, GL_FLOAT, GL_FALSE, stride, ((uint8_t *)NULL) + sizeof(float) * 4 * 2);
glVertexAttribDivisor(12, 1);
+#ifdef DEBUG_ENABLED
- if (s->index_array_len > 0) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, split);
+ storage->info.render.vertices_count += s->index_array_len * split;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, split);
- storage->info.render_vertices_count += s->index_array_len * split;
+ storage->info.render.vertices_count += s->index_array_len * split;
} else {
glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, split);
- storage->info.render_vertices_count += s->array_len * split;
+ storage->info.render.vertices_count += s->array_len * split;
}
}
} else {
- if (s->index_array_len > 0) {
+#ifdef DEBUG_ENABLED
+
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_WIREFRAME && s->array_wireframe_id) {
+
+ glDrawElementsInstanced(GL_LINES, s->index_wireframe_len, GL_UNSIGNED_INT, 0, amount);
+ storage->info.render.vertices_count += s->index_array_len * amount;
+ } else
+#endif
+ if (s->index_array_len > 0) {
glDrawElementsInstanced(gl_primitive[s->primitive], s->index_array_len, (s->array_len >= (1 << 16)) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT, 0, amount);
- storage->info.render_vertices_count += s->index_array_len * amount;
+ storage->info.render.vertices_count += s->index_array_len * amount;
} else {
glDrawArraysInstanced(gl_primitive[s->primitive], 0, s->array_len, amount);
- storage->info.render_vertices_count += s->array_len * amount;
+ storage->info.render.vertices_count += s->array_len * amount;
}
}
@@ -1697,7 +1813,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
@@ -1709,7 +1825,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
@@ -1740,19 +1856,10 @@ void RasterizerSceneGLES3::_set_cull(bool p_front, bool p_reverse_cull) {
void RasterizerSceneGLES3::_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) {
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]) {
- //p_reverse_cull=!p_reverse_cull;
- glFrontFace(GL_CCW);
- } else {
- glFrontFace(GL_CW);
- }
-
glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo
if (!p_shadow && !p_directional_add) {
glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
- glBindTexture(GL_TEXTURE_2D, state.brdf_texture);
if (p_base_env) {
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
@@ -1793,7 +1900,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
bool first = true;
bool prev_use_instancing = false;
- storage->info.render_object_count += p_element_count;
+ storage->info.render.draw_call_count += p_element_count;
for (int i = 0; i < p_element_count; i++) {
@@ -1808,7 +1915,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (!p_shadow) {
if (p_directional_add) {
- if (e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask & directional_light->light_ptr->cull_mask)) {
+ if (e->sort_key & SORT_KEY_UNSHADED_FLAG || !(e->instance->layer_mask & directional_light->light_ptr->cull_mask)) {
continue;
}
@@ -1817,7 +1924,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (shading != prev_shading) {
- if (e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) {
+ if (e->sort_key & SORT_KEY_UNSHADED_FLAG) {
state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, true);
state.scene_shader.set_conditional(SceneShaderGLES3::USE_FORWARD_LIGHTING, false);
@@ -1846,7 +1953,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5);
state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13);
- if (p_directional_add || (directional_light && (e->sort_key & RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) {
+ if (p_directional_add || (directional_light && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, true);
if (p_directional_shadows && directional_light->light_ptr->shadow) {
@@ -1934,30 +2041,30 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
if (skeleton.is_valid()) {
RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 1);
glBindTexture(GL_TEXTURE_2D, sk->texture);
}
}
if (material != prev_material || rebind) {
- storage->info.render_material_switch_count++;
+ storage->info.render.material_switch_count++;
rebind = _setup_material(material, p_alpha_pass);
if (rebind) {
- storage->info.render_shader_rebind_count++;
+ storage->info.render.shader_rebind_count++;
}
}
- if (!(e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
+ if (!(e->sort_key & SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
_setup_light(e, p_view_transform);
}
if (e->owner != prev_owner || prev_base_type != e->instance->base_type || prev_geometry != e->geometry) {
_setup_geometry(e, p_view_transform);
- storage->info.render_surface_switch_count++;
+ storage->info.render.surface_switch_count++;
}
_set_cull(e->sort_key & RenderList::SORT_KEY_MIRROR_FLAG, p_reverse_cull);
@@ -2000,6 +2107,10 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
RasterizerStorageGLES3::Material *m = NULL;
RID m_src = p_instance->material_override.is_valid() ? p_instance->material_override : (p_material >= 0 ? p_instance->materials[p_material] : p_geometry->material);
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+ m_src = default_overdraw_material;
+ }
+
/*
#ifdef DEBUG_ENABLED
if (current_debug==VS::SCENARIO_DEBUG_OVERDRAW) {
@@ -2012,7 +2123,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
if (m_src.is_valid()) {
m = storage->material_owner.getornull(m_src);
- if (!m->shader) {
+ if (!m->shader || !m->shader->valid) {
m = NULL;
}
}
@@ -2023,7 +2134,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
ERR_FAIL_COND(!m);
- bool has_base_alpha = (m->shader->spatial.uses_alpha);
+ bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture);
bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop;
bool has_alpha = has_base_alpha || has_blend_alpha;
bool shadow = false;
@@ -2038,6 +2149,10 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
state.used_sss = true;
}
+ if (m->shader->spatial.uses_screen_texture) {
+ state.used_screen_texture = true;
+ }
+
if (p_shadow) {
if (has_blend_alpha || (has_base_alpha && m->shader->spatial.depth_draw_mode != RasterizerStorageGLES3::Shader::Spatial::DEPTH_DRAW_ALPHA_PREPASS))
@@ -2071,7 +2186,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
}
if (!p_shadow && directional_light && (directional_light->light_ptr->cull_mask & e->instance->layer_mask) == 0) {
- e->sort_key |= RenderList::SORT_KEY_NO_DIRECTIONAL_FLAG;
+ e->sort_key |= SORT_KEY_NO_DIRECTIONAL_FLAG;
}
e->sort_key |= uint64_t(e->geometry->index) << RenderList::SORT_KEY_GEOMETRY_INDEX_SHIFT;
@@ -2099,7 +2214,7 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
}
if (e->instance->gi_probe_instances.size()) {
- e->sort_key |= RenderList::SORT_KEY_GI_PROBES_FLAG;
+ e->sort_key |= SORT_KEY_GI_PROBES_FLAG;
}
}
@@ -2114,18 +2229,18 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo
//e->light_type=0xFF; // no lights!
- if (shadow || m->shader->spatial.unshaded /*|| current_debug==VS::SCENARIO_DEBUG_SHADELESS*/) {
+ if (shadow || m->shader->spatial.unshaded || state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_UNSHADED) {
- e->sort_key |= RenderList::SORT_KEY_UNSHADED_FLAG;
+ e->sort_key |= SORT_KEY_UNSHADED_FLAG;
}
}
-void RasterizerSceneGLES3::_draw_skybox(RasterizerStorageGLES3::SkyBox *p_skybox, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale) {
+void RasterizerSceneGLES3::_draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy) {
- if (!p_skybox)
+ if (!p_sky)
return;
- RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(p_skybox->cubemap);
+ RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(p_sky->panorama);
ERR_FAIL_COND(!tex);
glActiveTexture(GL_TEXTURE0);
@@ -2164,7 +2279,7 @@ void RasterizerSceneGLES3::_draw_skybox(RasterizerStorageGLES3::SkyBox *p_skybox
};
- //skybox uv vectors
+ //sky uv vectors
float vw, vh, zn;
p_projection.get_viewport_size(vw, vh);
zn = p_projection.get_z_near();
@@ -2181,21 +2296,24 @@ void RasterizerSceneGLES3::_draw_skybox(RasterizerStorageGLES3::SkyBox *p_skybox
vertices[i * 2 + 1].z = -vertices[i * 2 + 1].z;
}
- glBindBuffer(GL_ARRAY_BUFFER, state.skybox_verts);
+ glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(Vector3) * 8, vertices);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- glBindVertexArray(state.skybox_array);
+ glBindVertexArray(state.sky_array);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, true);
storage->shaders.copy.bind();
+ storage->shaders.copy.set_uniform(CopyShaderGLES3::MULTIPLIER, p_energy);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
glBindVertexArray(0);
glColorMask(1, 1, 1, 1);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_CUBEMAP, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_MULTIPLIER, false);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::USE_PANORAMA, false);
}
void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform) {
@@ -2206,10 +2324,9 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
store_transform(p_cam_transform.affine_inverse(), state.ubo_data.camera_inverse_matrix);
//time global variables
- for (int i = 0; i < 4; i++) {
- state.ubo_data.time[i] = storage->frame.time[i];
- }
+ state.ubo_data.time = storage->frame.time[0];
+ state.ubo_data.z_far = p_cam_projection.get_z_far();
//bg and ambient
if (env) {
state.ubo_data.bg_energy = env->bg_energy;
@@ -2239,8 +2356,32 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.ubo_data.bg_color[2] = bg_color.b;
state.ubo_data.bg_color[3] = bg_color.a;
- state.env_radiance_data.ambient_contribution = env->ambient_skybox_contribution;
+ state.env_radiance_data.ambient_contribution = env->ambient_sky_contribution;
state.ubo_data.ambient_occlusion_affect_light = env->ssao_light_affect;
+
+ //fog
+
+ Color linear_fog = env->fog_color.to_linear();
+ state.ubo_data.fog_color_enabled[0] = linear_fog.r;
+ state.ubo_data.fog_color_enabled[1] = linear_fog.g;
+ state.ubo_data.fog_color_enabled[2] = linear_fog.b;
+ state.ubo_data.fog_color_enabled[3] = env->fog_enabled ? 1.0 : 0.0;
+
+ Color linear_sun = env->fog_sun_color.to_linear();
+ state.ubo_data.fog_sun_color_amount[0] = linear_sun.r;
+ state.ubo_data.fog_sun_color_amount[1] = linear_sun.g;
+ state.ubo_data.fog_sun_color_amount[2] = linear_sun.b;
+ state.ubo_data.fog_sun_color_amount[3] = env->fog_sun_amount;
+ state.ubo_data.fog_depth_enabled = env->fog_depth_enabled;
+ state.ubo_data.fog_depth_begin = env->fog_depth_begin;
+ state.ubo_data.fog_depth_curve = env->fog_depth_curve;
+ state.ubo_data.fog_transmit_enabled = env->fog_transmit_enabled;
+ state.ubo_data.fog_transmit_curve = env->fog_transmit_curve;
+ state.ubo_data.fog_height_enabled = env->fog_height_enabled;
+ state.ubo_data.fog_height_min = env->fog_height_min;
+ state.ubo_data.fog_height_max = env->fog_height_max;
+ state.ubo_data.fog_height_curve = env->fog_height_curve;
+
} else {
state.ubo_data.bg_energy = 1.0;
state.ubo_data.ambient_energy = 1.0;
@@ -2258,6 +2399,8 @@ void RasterizerSceneGLES3::_setup_environment(Environment *env, const CameraMatr
state.env_radiance_data.ambient_contribution = 0;
state.ubo_data.ambient_occlusion_affect_light = 0;
+
+ state.ubo_data.fog_color_enabled[3] = 0.0;
}
{
@@ -2340,8 +2483,8 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
for (int j = 0; j < shadow_count; j++) {
- uint32_t x = li->directional_rect.pos.x;
- uint32_t y = li->directional_rect.pos.y;
+ uint32_t x = li->directional_rect.position.x;
+ uint32_t y = li->directional_rect.position.y;
uint32_t width = li->directional_rect.size.x;
uint32_t height = li->directional_rect.size.y;
@@ -2386,8 +2529,8 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
store_camera(shadow_mtx, &ubo_data.shadow_matrix1[16 * j]);
- ubo_data.light_clamp[0] = atlas_rect.pos.x;
- ubo_data.light_clamp[1] = atlas_rect.pos.y;
+ ubo_data.light_clamp[0] = atlas_rect.position.x;
+ ubo_data.light_clamp[1] = atlas_rect.position.y;
ubo_data.light_clamp[2] = atlas_rect.size.x;
ubo_data.light_clamp[3] = atlas_rect.size.y;
}
@@ -2576,8 +2719,8 @@ void RasterizerSceneGLES3::_setup_lights(RID *p_light_cull_result, int p_light_c
Rect2 rect(float(x) / atlas_size, float(y) / atlas_size, float(width) / atlas_size, float(height) / atlas_size);
ubo_data.light_params[3] = 1.0; //means it has shadow
- ubo_data.light_clamp[0] = rect.pos.x;
- ubo_data.light_clamp[1] = rect.pos.y;
+ ubo_data.light_clamp[0] = rect.position.x;
+ ubo_data.light_clamp[1] = rect.position.y;
ubo_data.light_clamp[2] = rect.size.x;
ubo_data.light_clamp[3] = rect.size.y;
@@ -2683,7 +2826,7 @@ void RasterizerSceneGLES3::_setup_reflections(RID *p_reflection_probe_cull_resul
ambient_linear.r *= p_env->ambient_energy;
ambient_linear.g *= p_env->ambient_energy;
ambient_linear.b *= p_env->ambient_energy;
- contrib = p_env->ambient_skybox_contribution;
+ contrib = p_env->ambient_sky_contribution;
}
reflection_ubo.ambient[0] = ambient_linear.r;
@@ -2794,6 +2937,7 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
current_geometry_index = 0;
current_material_index = 0;
state.used_sss = false;
+ state.used_screen_texture = false;
//fill list
@@ -2871,6 +3015,39 @@ void RasterizerSceneGLES3::_fill_render_list(InstanceBase **p_cull_result, int p
}
}
+void RasterizerSceneGLES3::_blur_effect_buffer() {
+
+ //blur diffuse into effect mipmaps using separatable convolution
+ //storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
+ for (int i = 0; i < storage->frame.current_rt->effects.mip_maps[1].sizes.size(); i++) {
+
+ int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
+ int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
+ glViewport(0, 0, vp_w, vp_h);
+ //horizontal pass
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, true);
+ state.effect_blur_shader.bind();
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
+ _copy_screen();
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false);
+
+ //vertical pass
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, true);
+ state.effect_blur_shader.bind();
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
+ state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color);
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger
+ _copy_screen();
+ state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false);
+ }
+}
+
void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_cam_projection) {
glDepthMask(GL_FALSE);
@@ -3025,8 +3202,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//copy normal and roughness to effect buffer
glBindFramebuffer(GL_READ_FRAMEBUFFER, storage->frame.current_rt->buffers.fbo);
glReadBuffer(GL_COLOR_ATTACHMENT3);
- glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->buffers.effect_fbo);
- glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, storage->frame.current_rt->effects.ssao.blur_fbo[0]);
+ glBlitFramebuffer(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, 0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_11_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_LOW);
state.sss_shader.set_conditional(SubsurfScatteringShaderGLES3::USE_17_SAMPLES, subsurface_scatter_quality == SSS_QUALITY_MEDIUM);
@@ -3042,8 +3219,11 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); //disable filter (fixes bugs on AMD)
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->buffers.effect);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.ssao.blur_red[0]);
glActiveTexture(GL_TEXTURE2);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
@@ -3053,10 +3233,15 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
_copy_screen();
glActiveTexture(GL_TEXTURE0);
+
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
state.sss_shader.set_uniform(SubsurfScatteringShaderGLES3::DIR, Vector2(0, 1));
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo); // copy to base level
_copy_screen();
+
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //restore filter
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
}
if (env->ssr_enabled) {
@@ -3069,38 +3254,11 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//blur diffuse into effect mipmaps using separatable convolution
//storage->shaders.copy.set_conditional(CopyShaderGLES3::GAUSSIAN_HORIZONTAL,true);
- for (int i = 0; i < storage->frame.current_rt->effects.mip_maps[1].sizes.size(); i++) {
-
- int vp_w = storage->frame.current_rt->effects.mip_maps[1].sizes[i].width;
- int vp_h = storage->frame.current_rt->effects.mip_maps[1].sizes[i].height;
- glViewport(0, 0, vp_w, vp_h);
- //horizontal pass
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, true);
- state.effect_blur_shader.bind();
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color); //previous level, since mipmaps[0] starts one level bigger
- glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[1].sizes[i].fbo);
- _copy_screen();
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_HORIZONTAL, false);
-
- //vertical pass
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, true);
- state.effect_blur_shader.bind();
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::PIXEL_SIZE, Vector2(1.0 / vp_w, 1.0 / vp_h));
- state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(i));
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[1].color);
- glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[i + 1].fbo); //next level, since mipmaps[0] starts one level bigger
- _copy_screen();
- state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::GAUSSIAN_VERTICAL, false);
- }
+ _blur_effect_buffer();
//perform SSR
- state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::SMOOTH_ACCEL, env->ssr_accel > 0 && env->ssr_smooth);
- state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_accel > 0 && env->ssr_roughness);
+ state.ssr_shader.set_conditional(ScreenSpaceReflectionShaderGLES3::REFLECT_ROUGHNESS, env->ssr_roughness);
state.ssr_shader.bind();
@@ -3116,9 +3274,9 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FRAME_INDEX,int(render_pass));
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::FILTER_MIPMAP_LEVELS, float(storage->frame.current_rt->effects.mip_maps[0].sizes.size()));
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::NUM_STEPS, env->ssr_max_steps);
- state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::ACCELERATION, env->ssr_accel);
state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DEPTH_TOLERANCE, env->ssr_depth_tolerance);
- state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DISTANCE_FADE, env->ssr_fade);
+ state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::DISTANCE_FADE, env->ssr_fade_out);
+ state.ssr_shader.set_uniform(ScreenSpaceReflectionShaderGLES3::CURVE_FADE_IN, env->ssr_fade_in);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
@@ -3148,6 +3306,8 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
//copy reflection over diffuse, resolving SSR if needed
state.resolve_shader.set_conditional(ResolveShaderGLES3::USE_SSR, env->ssr_enabled);
state.resolve_shader.bind();
+ state.resolve_shader.set_uniform(ResolveShaderGLES3::PIXEL_SIZE, Vector2(1.0 / storage->frame.current_rt->width, 1.0 / storage->frame.current_rt->height));
+
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->color);
if (env->ssr_enabled) {
@@ -3164,6 +3324,13 @@ void RasterizerSceneGLES3::_render_mrts(Environment *env, const CameraMatrix &p_
glDisable(GL_BLEND); //end additive
+ if (state.used_screen_texture) {
+ _blur_effect_buffer();
+ //restored framebuffer
+ glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->effects.mip_maps[0].sizes[0].fbo);
+ glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
+ }
+
state.effect_blur_shader.set_conditional(EffectBlurShaderGLES3::SIMPLE_COPY, true);
state.effect_blur_shader.bind();
state.effect_blur_shader.set_uniform(EffectBlurShaderGLES3::LOD, float(0));
@@ -3206,19 +3373,21 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
- if (!env) {
- //no environment, simply return and convert to SRGB
+ if (!env || storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ //no environment or transparent render, simply return and convert to SRGB
glBindFramebuffer(GL_FRAMEBUFFER, storage->frame.current_rt->fbo);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, true);
- storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, true);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::V_FLIP, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]);
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]);
storage->shaders.copy.bind();
_copy_screen();
storage->shaders.copy.set_conditional(CopyShaderGLES3::LINEAR_TO_SRGB, false);
storage->shaders.copy.set_conditional(CopyShaderGLES3::DISABLE_ALPHA, false); //compute luminance
+ storage->shaders.copy.set_conditional(CopyShaderGLES3::V_FLIP, false);
return;
}
@@ -3581,6 +3750,18 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
}
+ if (env->adjustments_enabled) {
+
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_BCS, true);
+ RasterizerStorageGLES3::Texture *tex = storage->texture_owner.getornull(env->color_correction);
+ if (tex) {
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_COLOR_CORRECTION, true);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(tex->target, tex->tex_id);
+ }
+ }
+
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::V_FLIP, storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP]);
state.tonemap_shader.bind();
state.tonemap_shader.set_uniform(TonemapShaderGLES3::EXPOSURE, env->tone_mapper_exposure);
@@ -3603,6 +3784,11 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_uniform(TonemapShaderGLES3::AUTO_EXPOSURE_GREY, env->auto_exposure_grey);
}
+ if (env->adjustments_enabled) {
+
+ state.tonemap_shader.set_uniform(TonemapShaderGLES3::BCS, Vector3(env->adjustments_brightness, env->adjustments_contrast, env->adjustments_saturation));
+ }
+
_copy_screen();
//turn off everything used
@@ -3621,6 +3807,9 @@ void RasterizerSceneGLES3::_post_process(Environment *env, const CameraMatrix &p
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SCREEN, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_SOFTLIGHT, false);
state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_GLOW_FILTER_BICUBIC, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_BCS, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::USE_COLOR_CORRECTION, false);
+ state.tonemap_shader.set_conditional(TonemapShaderGLES3::V_FLIP, false);
}
void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, InstanceBase **p_cull_result, int p_cull_count, RID *p_light_cull_result, int p_light_cull_count, RID *p_reflection_probe_cull_result, int p_reflection_probe_cull_count, RID p_environment, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass) {
@@ -3630,12 +3819,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
//fill up ubo
+ storage->info.render.object_count += p_cull_count;
+
Environment *env = environment_owner.getornull(p_environment);
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
ReflectionAtlas *reflection_atlas = reflection_atlas_owner.getornull(p_reflection_atlas);
if (shadow_atlas && shadow_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
@@ -3644,7 +3835,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
}
if (reflection_atlas && reflection_atlas->size) {
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 5);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 3);
glBindTexture(GL_TEXTURE_2D, reflection_atlas->color);
}
@@ -3656,8 +3847,8 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.ubo_data.subsurface_scatter_width = subsurface_scatter_size;
- state.ubo_data.shadow_z_offset = 0;
- state.ubo_data.shadow_slope_scale = 0;
+ state.ubo_data.z_offset = 0;
+ state.ubo_data.z_slope_scale = 0;
state.ubo_data.shadow_dual_paraboloid_render_side = 0;
state.ubo_data.shadow_dual_paraboloid_render_zfar = 0;
@@ -3674,7 +3865,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
state.used_contact_shadows = true;
- if (storage->frame.current_rt && true) { //detect with state.used_contact_shadows too
+ if (storage->frame.current_rt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) { //detect with state.used_contact_shadows too
//pre z pass
glDisable(GL_BLEND);
@@ -3708,7 +3899,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read
- glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
}
@@ -3761,7 +3952,11 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
} else {
- use_mrt = state.used_sss || (env && (env->ssao_enabled || env->ssr_enabled)); //only enable MRT rendering if any of these is enabled
+ use_mrt = env && (state.used_screen_texture || state.used_sss || env->ssao_enabled || env->ssr_enabled); //only enable MRT rendering if any of these is enabled
+ //effects disabled and transparency also prevent using MRTs
+ use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT];
+ use_mrt = use_mrt && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS];
+ use_mrt = use_mrt && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW;
glViewport(0, 0, storage->frame.current_rt->width, storage->frame.current_rt->height);
@@ -3807,10 +4002,17 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
Color clear_color(0, 0, 0, 0);
- RasterizerStorageGLES3::SkyBox *skybox = NULL;
+ RasterizerStorageGLES3::Sky *sky = NULL;
GLuint env_radiance_tex = 0;
- if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) {
+ if (state.debug_draw == VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
+ clear_color = Color(0, 0, 0, 0);
+ storage->frame.clear_request = false;
+ } else if (!probe && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
+ clear_color = Color(0, 0, 0, 0);
+ storage->frame.clear_request = false;
+
+ } else if (!env || env->bg_mode == VS::ENV_BG_CLEAR_COLOR) {
if (storage->frame.clear_request) {
@@ -3822,12 +4024,12 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
clear_color = env->bg_color.to_linear();
storage->frame.clear_request = false;
- } else if (env->bg_mode == VS::ENV_BG_SKYBOX) {
+ } else if (env->bg_mode == VS::ENV_BG_SKY) {
- skybox = storage->skybox_owner.getornull(env->skybox);
+ sky = storage->sky_owner.getornull(env->sky);
- if (skybox) {
- env_radiance_tex = skybox->radiance;
+ if (sky) {
+ env_radiance_tex = sky->radiance;
}
storage->frame.clear_request = false;
@@ -3843,20 +4045,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
} else {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_BLEND);
}
- glDisable(GL_BLEND);
-
render_list.sort_by_key(false);
- if (storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT]) {
- glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
- } else {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- }
-
if (state.directional_light_count == 0) {
directional_light = NULL;
_render_list(render_list.elements, render_list.element_count, p_cam_transform, p_cam_projection, env_radiance_tex, false, false, false, false, shadow_atlas != NULL);
@@ -3878,14 +4074,14 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glDrawBuffers(1, &gldb);
}
- if (env && env->bg_mode == VS::ENV_BG_SKYBOX) {
+ if (env && env->bg_mode == VS::ENV_BG_SKY && !storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_TRANSPARENT] && state.debug_draw != VS::VIEWPORT_DEBUG_DRAW_OVERDRAW) {
/*
if (use_mrt) {
- glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for skybox, only diffuse/ambient matters
+ glBindFramebuffer(GL_FRAMEBUFFER,storage->frame.current_rt->buffers.fbo); //switch to alpha fbo for sky, only diffuse/ambient matters
*/
- _draw_skybox(skybox, p_cam_projection, p_cam_transform, storage->frame.current_rt && storage->frame.current_rt->flags[RasterizerStorage::RENDER_TARGET_VFLIP], env->skybox_scale);
+ _draw_sky(sky, p_cam_projection, p_cam_transform, false, env->sky_scale, env->bg_energy);
}
//_render_list_forward(&alpha_render_list,camera_transform,camera_transform_inverse,camera_projection,false,fragment_lighting,true);
@@ -3897,6 +4093,11 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
_render_mrts(env, p_cam_projection);
}
+ if (state.used_screen_texture) {
+ glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7);
+ glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->effects.mip_maps[0].color);
+ }
+
glEnable(GL_BLEND);
glDepthMask(GL_TRUE);
glEnable(GL_DEPTH_TEST);
@@ -3969,151 +4170,6 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindTexture(GL_TEXTURE_2D, env_radiance_tex);
storage->canvas->draw_generic_textured_rect(Rect2(0, 0, storage->frame.current_rt->width / 2, storage->frame.current_rt->height / 2), Rect2(0, 0, 1, 1));
}
-
-#if 0
- if (use_fb) {
-
-
-
- for(int i=0;i<VS::ARRAY_MAX;i++) {
- glDisableVertexAttribArray(i);
- }
- glBindBuffer(GL_ARRAY_BUFFER,0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
- glDisable(GL_BLEND);
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
- glDisable(GL_SCISSOR_TEST);
- glDepthMask(false);
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) {
-
- int hdr_tm = current_env->fx_param[VS::ENV_FX_PARAM_HDR_TONEMAPPER];
- switch(hdr_tm) {
- case VS::ENV_FX_HDR_TONE_MAPPER_LINEAR: {
-
-
- } break;
- case VS::ENV_FX_HDR_TONE_MAPPER_LOG: {
- copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,true);
-
- } break;
- case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT: {
- copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true);
- } break;
- case VS::ENV_FX_HDR_TONE_MAPPER_REINHARDT_AUTOWHITE: {
-
- copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,true);
- copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,true);
- } break;
- }
-
-
- _process_hdr();
- }
- if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
- _process_glow_bloom();
- int glow_transfer_mode=current_env->fx_param[VS::ENV_FX_PARAM_GLOW_BLUR_BLEND_MODE];
- if (glow_transfer_mode==1)
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,true);
- if (glow_transfer_mode==2)
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,true);
- }
-
- glBindFramebuffer(GL_FRAMEBUFFER, current_rt?current_rt->fbo:base_framebuffer);
-
- Size2 size;
- if (current_rt) {
- glBindFramebuffer(GL_FRAMEBUFFER, current_rt->fbo);
- glViewport( 0,0,viewport.width,viewport.height);
- size=Size2(viewport.width,viewport.height);
- } else {
- glBindFramebuffer(GL_FRAMEBUFFER, base_framebuffer);
- glViewport( viewport.x, window_size.height-(viewport.height+viewport.y), viewport.width,viewport.height );
- size=Size2(viewport.width,viewport.height);
- }
-
- //time to copy!!!
- copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,current_env && current_env->fx_enabled[VS::ENV_FX_BCS]);
- copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,current_env && current_env->fx_enabled[VS::ENV_FX_SRGB]);
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]);
- copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,current_env && current_env->fx_enabled[VS::ENV_FX_HDR]);
- copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,true);
- copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,current_env && current_env->fx_enabled[VS::ENV_FX_FXAA]);
-
- copy_shader.bind();
- //copy_shader.set_uniform(CopyShaderGLES2::SOURCE,0);
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_GLOW]) {
-
- glActiveTexture(GL_TEXTURE1);
- glBindTexture(GL_TEXTURE_2D, framebuffer.blur[0].color );
- glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::GLOW_SOURCE),1);
-
- }
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR]) {
-
- glActiveTexture(GL_TEXTURE2);
- glBindTexture(GL_TEXTURE_2D, current_vd->lum_color );
- glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::HDR_SOURCE),2);
- copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_EXPOSURE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_EXPOSURE]));
- copy_shader.set_uniform(CopyShaderGLES2::TONEMAP_WHITE,float(current_env->fx_param[VS::ENV_FX_PARAM_HDR_WHITE]));
-
- }
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_FXAA])
- copy_shader.set_uniform(CopyShaderGLES2::PIXEL_SIZE,Size2(1.0/size.x,1.0/size.y));
-
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_BCS]) {
-
- Vector3 bcs;
- bcs.x=current_env->fx_param[VS::ENV_FX_PARAM_BCS_BRIGHTNESS];
- bcs.y=current_env->fx_param[VS::ENV_FX_PARAM_BCS_CONTRAST];
- bcs.z=current_env->fx_param[VS::ENV_FX_PARAM_BCS_SATURATION];
- copy_shader.set_uniform(CopyShaderGLES2::BCS,bcs);
- }
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, framebuffer.color );
- glUniform1i(copy_shader.get_uniform_location(CopyShaderGLES2::SOURCE),0);
-
- _copy_screen_quad();
-
- copy_shader.set_conditional(CopyShaderGLES2::USE_BCS,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_SRGB,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_HDR,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_NO_ALPHA,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_FXAA,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SCREEN,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_GLOW_SOFTLIGHT,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_REINHARDT_TONEMAPPER,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_AUTOWHITE,false);
- copy_shader.set_conditional(CopyShaderGLES2::USE_LOG_TONEMAPPER,false);
-
- state.scene_shader.set_conditional(SceneShaderGLES3::USE_8BIT_HDR,false);
-
-
- if (current_env && current_env->fx_enabled[VS::ENV_FX_HDR] && GLOBAL_DEF("rasterizer/debug_hdr",false)) {
- _debug_luminances();
- }
- }
-
- current_env=NULL;
- current_debug=VS::SCENARIO_DEBUG_DISABLED;
- if (GLOBAL_DEF("rasterizer/debug_shadow_maps",false)) {
- _debug_shadows();
- }
- //_debug_luminances();
- //_debug_samplers();
-
- if (using_canvas_bg) {
- using_canvas_bg=false;
- glColorMask(1,1,1,1); //don't touch alpha
- }
-#endif
}
void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) {
@@ -4154,15 +4210,15 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
} else if (directional_shadow.light_count == 2) {
light_instance->directional_rect = Rect2(0, 0, directional_shadow.size, directional_shadow.size / 2);
if (light_instance->light_directional_index == 1) {
- light_instance->directional_rect.pos.x += light_instance->directional_rect.size.x;
+ light_instance->directional_rect.position.x += light_instance->directional_rect.size.x;
}
} else { //3 and 4
light_instance->directional_rect = Rect2(0, 0, directional_shadow.size / 2, directional_shadow.size / 2);
if (light_instance->light_directional_index & 1) {
- light_instance->directional_rect.pos.x += light_instance->directional_rect.size.x;
+ light_instance->directional_rect.position.x += light_instance->directional_rect.size.x;
}
if (light_instance->light_directional_index / 2) {
- light_instance->directional_rect.pos.y += light_instance->directional_rect.size.y;
+ light_instance->directional_rect.position.y += light_instance->directional_rect.size.y;
}
}
}
@@ -4170,8 +4226,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
light_projection = light_instance->shadow_transform[p_pass].camera;
light_transform = light_instance->shadow_transform[p_pass].transform;
- x = light_instance->directional_rect.pos.x;
- y = light_instance->directional_rect.pos.y;
+ x = light_instance->directional_rect.position.x;
+ y = light_instance->directional_rect.position.y;
width = light_instance->directional_rect.size.x;
height = light_instance->directional_rect.size.y;
@@ -4203,8 +4259,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
}
zfar = light->param[VS::LIGHT_PARAM_RANGE];
- bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS];
- normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS];
+ bias = light->param[VS::LIGHT_PARAM_SHADOW_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
+ normal_bias = light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] * light_instance->shadow_transform[p_pass].bias_scale;
fbo = directional_shadow.fbo;
vp_height = directional_shadow.size;
@@ -4322,8 +4378,8 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_
glClear(GL_DEPTH_BUFFER_BIT);
glDisable(GL_SCISSOR_TEST);
- state.ubo_data.shadow_z_offset = bias;
- state.ubo_data.shadow_slope_scale = normal_bias;
+ state.ubo_data.z_offset = bias;
+ state.ubo_data.z_slope_scale = normal_bias;
state.ubo_data.shadow_dual_paraboloid_render_side = dp_direction;
state.ubo_data.shadow_dual_paraboloid_render_zfar = zfar;
@@ -4435,136 +4491,39 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
return true;
}
-// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
-static _FORCE_INLINE_ float radicalInverse_VdC(uint32_t bits) {
- bits = (bits << 16u) | (bits >> 16u);
- bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
- bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
- bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
- bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
- return float(bits) * 2.3283064365386963e-10f; // / 0x100000000
-}
-
-static _FORCE_INLINE_ Vector2 Hammersley(uint32_t i, uint32_t N) {
- return Vector2(float(i) / float(N), radicalInverse_VdC(i));
-}
-
-static _FORCE_INLINE_ Vector3 ImportanceSampleGGX(Vector2 Xi, float Roughness, Vector3 N) {
- float a = Roughness * Roughness; // DISNEY'S ROUGHNESS [see Burley'12 siggraph]
-
- // Compute distribution direction
- float Phi = 2.0f * Math_PI * Xi.x;
- float CosTheta = Math::sqrt((float)(1.0f - Xi.y) / (1.0f + (a * a - 1.0f) * Xi.y));
- float SinTheta = Math::sqrt((float)Math::abs(1.0f - CosTheta * CosTheta));
-
- // Convert to spherical direction
- Vector3 H;
- H.x = SinTheta * Math::cos(Phi);
- H.y = SinTheta * Math::sin(Phi);
- H.z = CosTheta;
-
- Vector3 UpVector = Math::abs(N.z) < 0.999 ? Vector3(0.0, 0.0, 1.0) : Vector3(1.0, 0.0, 0.0);
- Vector3 TangentX = UpVector.cross(N);
- TangentX.normalize();
- Vector3 TangentY = N.cross(TangentX);
-
- // Tangent to world space
- return TangentX * H.x + TangentY * H.y + N * H.z;
-}
-
-static _FORCE_INLINE_ float GGX(float NdotV, float a) {
- float k = a / 2.0;
- return NdotV / (NdotV * (1.0 - k) + k);
-}
+void RasterizerSceneGLES3::set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) {
-// http://graphicrants.blogspot.com.au/2013/08/specular-brdf-reference.html
-float _FORCE_INLINE_ G_Smith(float a, float nDotV, float nDotL) {
- return GGX(nDotL, a * a) * GGX(nDotV, a * a);
+ state.debug_draw = p_debug_draw;
}
-void RasterizerSceneGLES3::_generate_brdf() {
-
- int brdf_size = GLOBAL_DEF("rendering/gles3/brdf_texture_size", 64);
-
- PoolVector<uint8_t> brdf;
- brdf.resize(brdf_size * brdf_size * 2);
-
- PoolVector<uint8_t>::Write w = brdf.write();
-
- for (int i = 0; i < brdf_size; i++) {
- for (int j = 0; j < brdf_size; j++) {
-
- float Roughness = float(j) / (brdf_size - 1);
- float NoV = float(i + 1) / (brdf_size); //avoid storing nov0
-
- Vector3 V;
- V.x = Math::sqrt(1.0f - NoV * NoV);
- V.y = 0.0;
- V.z = NoV;
-
- Vector3 N = Vector3(0.0, 0.0, 1.0);
-
- float A = 0;
- float B = 0;
-
- for (int s = 0; s < 512; s++) {
-
- Vector2 xi = Hammersley(s, 512);
- Vector3 H = ImportanceSampleGGX(xi, Roughness, N);
- Vector3 L = 2.0 * V.dot(H) * H - V;
+void RasterizerSceneGLES3::initialize() {
- float NoL = CLAMP(L.z, 0.0, 1.0);
- float NoH = CLAMP(H.z, 0.0, 1.0);
- float VoH = CLAMP(V.dot(H), 0.0, 1.0);
+ render_pass = 0;
- if (NoL > 0.0) {
- float G = G_Smith(Roughness, NoV, NoL);
- float G_Vis = G * VoH / (NoH * NoV);
- float Fc = pow(1.0 - VoH, 5.0);
+ state.scene_shader.init();
- A += (1.0 - Fc) * G_Vis;
- B += Fc * G_Vis;
- }
- }
+ {
+ //default material and shader
- A /= 512.0;
- B /= 512.0;
+ default_shader = storage->shader_create();
+ storage->shader_set_code(default_shader, "shader_type spatial;\n");
+ default_material = storage->material_create();
+ storage->material_set_shader(default_material, default_shader);
- int tofs = ((brdf_size - j - 1) * brdf_size + i) * 2;
- w[tofs + 0] = CLAMP(A * 255, 0, 255);
- w[tofs + 1] = CLAMP(B * 255, 0, 255);
- }
+ default_shader_twosided = storage->shader_create();
+ default_material_twosided = storage->material_create();
+ storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
+ storage->material_set_shader(default_material_twosided, default_shader_twosided);
}
- //set up brdf texture
-
- glGenTextures(1, &state.brdf_texture);
-
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, state.brdf_texture);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RG8, brdf_size, brdf_size, 0, GL_RG, GL_UNSIGNED_BYTE, w.ptr());
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glBindTexture(GL_TEXTURE_2D, 0);
-}
-
-void RasterizerSceneGLES3::initialize() {
-
- render_pass = 0;
-
- state.scene_shader.init();
-
- default_shader = storage->shader_create();
- storage->shader_set_code(default_shader, "shader_type spatial;\n");
- default_material = storage->material_create();
- storage->material_set_shader(default_material, default_shader);
+ {
+ //default material and shader
- default_shader_twosided = storage->shader_create();
- default_material_twosided = storage->material_create();
- storage->shader_set_code(default_shader_twosided, "shader_type spatial; render_mode cull_disabled;\n");
- storage->material_set_shader(default_material_twosided, default_shader_twosided);
+ default_overdraw_shader = storage->shader_create();
+ storage->shader_set_code(default_overdraw_shader, "shader_type spatial;\nrender_mode blend_add,unshaded;\n void fragment() { ALBEDO=vec3(0.4,0.8,0.8); ALPHA=0.2; }");
+ default_overdraw_material = storage->material_create();
+ storage->material_set_shader(default_overdraw_material, default_overdraw_shader);
+ }
glGenBuffers(1, &state.scene_ubo);
glBindBuffer(GL_UNIFORM_BUFFER, state.scene_ubo);
@@ -4585,14 +4544,14 @@ void RasterizerSceneGLES3::initialize() {
{
//quad buffers
- glGenBuffers(1, &state.skybox_verts);
- glBindBuffer(GL_ARRAY_BUFFER, state.skybox_verts);
+ glGenBuffers(1, &state.sky_verts);
+ glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vector3) * 8, NULL, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- glGenVertexArrays(1, &state.skybox_array);
- glBindVertexArray(state.skybox_array);
- glBindBuffer(GL_ARRAY_BUFFER, state.skybox_verts);
+ glGenVertexArrays(1, &state.sky_array);
+ glBindVertexArray(state.sky_array);
+ glBindBuffer(GL_ARRAY_BUFFER, state.sky_verts);
glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, 0);
glEnableVertexAttribArray(VS::ARRAY_VERTEX);
glVertexAttribPointer(VS::ARRAY_TEX_UV, 3, GL_FLOAT, GL_FALSE, sizeof(Vector3) * 2, ((uint8_t *)NULL) + sizeof(Vector3));
@@ -4602,7 +4561,6 @@ void RasterizerSceneGLES3::initialize() {
}
render_list.init();
state.cube_to_dp_shader.init();
- _generate_brdf();
shadow_atlas_realloc_tolerance_msec = 500;
@@ -4651,7 +4609,7 @@ void RasterizerSceneGLES3::initialize() {
{
//directional light shadow
directional_shadow.light_count = 0;
- directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 2048));
+ directional_shadow.size = nearest_power_of_2(GLOBAL_DEF("rendering/shadows/directional_shadow_size", 4096));
glGenFramebuffers(1, &directional_shadow.fbo);
glBindFramebuffer(GL_FRAMEBUFFER, directional_shadow.fbo);
glGenTextures(1, &directional_shadow.depth);
@@ -4831,7 +4789,12 @@ void RasterizerSceneGLES3::initialize() {
glGenTextures(1, &e.color);
glBindTexture(GL_TEXTURE_2D, e.color);
+#ifdef IPHONE_ENABLED
+ ///@TODO ugly hack to get around iOS not supporting 32bit single channel floating point textures...
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R16F, max_exposure_shrink_size, max_exposure_shrink_size, 0, GL_RED, GL_FLOAT, NULL);
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, max_exposure_shrink_size, max_exposure_shrink_size, 0, GL_RED, GL_FLOAT, NULL);
+#endif
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, e.color, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -4844,6 +4807,8 @@ void RasterizerSceneGLES3::initialize() {
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
}
+
+ state.debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
}
void RasterizerSceneGLES3::iteration() {
diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h
index 33698fc267..3e15da52ab 100644
--- a/drivers/gles3/rasterizer_scene_gles3.h
+++ b/drivers/gles3/rasterizer_scene_gles3.h
@@ -77,6 +77,9 @@ public:
RID default_shader;
RID default_shader_twosided;
+ RID default_overdraw_material;
+ RID default_overdraw_shader;
+
RasterizerStorageGLES3 *storage;
Vector<RasterizerStorageGLES3::RenderTarget::Exposure> exposure_shrink;
@@ -108,22 +111,37 @@ public:
float projection_matrix[16];
float camera_inverse_matrix[16];
float camera_matrix[16];
- float time[4];
float ambient_light_color[4];
float bg_color[4];
+ float fog_color_enabled[4];
+ float fog_sun_color_amount[4];
+
float ambient_energy;
float bg_energy;
- float shadow_z_offset;
- float shadow_slope_scale;
+ float z_offset;
+ float z_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
float screen_pixel_size[2];
float shadow_atlas_pixel_size[2];
float shadow_directional_pixel_size[2];
+
+ float time;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
} ubo_data;
GLuint scene_ubo;
@@ -131,18 +149,14 @@ public:
struct EnvironmentRadianceUBO {
float transform[16];
- float box_min[4]; //unused for now
- float box_max[4];
float ambient_contribution;
} env_radiance_data;
GLuint env_radiance_ubo;
- GLuint brdf_texture;
-
- GLuint skybox_verts;
- GLuint skybox_array;
+ GLuint sky_verts;
+ GLuint sky_array;
GLuint directional_ubo;
@@ -172,7 +186,9 @@ public:
bool cull_front;
bool used_sss;
+ bool used_screen_texture;
+ VS::ViewportDebugDraw debug_draw;
} state;
/* SHADOW ATLAS API */
@@ -329,25 +345,24 @@ public:
VS::EnvironmentBG bg_mode;
- RID skybox;
- float skybox_scale;
+ RID sky;
+ float sky_scale;
Color bg_color;
float bg_energy;
- float skybox_ambient;
+ float sky_ambient;
Color ambient_color;
float ambient_energy;
- float ambient_skybox_contribution;
+ float ambient_sky_contribution;
int canvas_max_layer;
bool ssr_enabled;
int ssr_max_steps;
- float ssr_accel;
- float ssr_fade;
+ float ssr_fade_in;
+ float ssr_fade_out;
float ssr_depth_tolerance;
- bool ssr_smooth;
bool ssr_roughness;
bool ssao_enabled;
@@ -391,21 +406,41 @@ public:
float dof_blur_near_amount;
VS::EnvironmentDOFBlurQuality dof_blur_near_quality;
+ bool adjustments_enabled;
+ float adjustments_brightness;
+ float adjustments_contrast;
+ float adjustments_saturation;
+ RID color_correction;
+
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
Environment() {
bg_mode = VS::ENV_BG_CLEAR_COLOR;
- skybox_scale = 1.0;
+ sky_scale = 1.0;
bg_energy = 1.0;
- skybox_ambient = 0;
+ sky_ambient = 0;
ambient_energy = 1.0;
- ambient_skybox_contribution = 0.0;
+ ambient_sky_contribution = 0.0;
canvas_max_layer = 0;
ssr_enabled = false;
ssr_max_steps = 64;
- ssr_accel = 0.04;
- ssr_fade = 2.0;
+ ssr_fade_in = 0.15;
+ ssr_fade_out = 2.0;
ssr_depth_tolerance = 0.2;
- ssr_smooth = true;
ssr_roughness = true;
ssao_enabled = false;
@@ -447,6 +482,29 @@ public:
dof_blur_near_transition = 1;
dof_blur_near_amount = 0.1;
dof_blur_near_quality = VS::ENV_DOF_BLUR_QUALITY_MEDIUM;
+
+ adjustments_enabled = false;
+ adjustments_brightness = 1.0;
+ adjustments_contrast = 1.0;
+ adjustments_saturation = 1.0;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = true;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
}
};
@@ -455,25 +513,29 @@ public:
virtual RID environment_create();
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg);
- virtual void environment_set_skybox(RID p_env, RID p_skybox);
- virtual void environment_set_skybox_scale(RID p_env, float p_scale);
+ virtual void environment_set_sky(RID p_env, RID p_sky);
+ virtual void environment_set_sky_scale(RID p_env, float p_scale);
virtual void environment_set_bg_color(RID p_env, const Color &p_color);
virtual void environment_set_bg_energy(RID p_env, float p_energy);
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer);
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_skybox_contribution = 0.0);
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0);
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality);
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale);
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture);
- virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness);
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness);
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_radius2, float p_intensity2, float p_intensity, float p_bias, float p_light_affect, const Color &p_color, bool p_blur);
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale);
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp);
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount);
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve);
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve);
+
/* LIGHT INSTANCE */
struct LightDataUBO {
@@ -499,6 +561,7 @@ public:
Transform transform;
float farplane;
float split;
+ float bias_scale;
};
ShadowTransform shadow_transform[4];
@@ -534,7 +597,7 @@ public:
virtual RID light_instance_create(RID p_light);
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
- virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass);
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0);
virtual void light_instance_mark_visible(RID p_light_instance);
/* REFLECTION INSTANCE */
@@ -573,9 +636,10 @@ public:
MAX_REFLECTIONS = 1024,
SORT_KEY_DEPTH_LAYER_SHIFT = 60,
- SORT_KEY_UNSHADED_FLAG = uint64_t(1) << 59,
- SORT_KEY_NO_DIRECTIONAL_FLAG = uint64_t(1) << 58,
- SORT_KEY_GI_PROBES_FLAG = uint64_t(1) << 57,
+//64 bits unsupported in MSVC
+#define SORT_KEY_UNSHADED_FLAG (uint64_t(1) << 59)
+#define SORT_KEY_NO_DIRECTIONAL_FLAG (uint64_t(1) << 58)
+#define SORT_KEY_GI_PROBES_FLAG (uint64_t(1) << 57)
SORT_KEY_SHADING_SHIFT = 57,
SORT_KEY_SHADING_MASK = 7,
SORT_KEY_MATERIAL_INDEX_SHIFT = 40,
@@ -700,7 +764,7 @@ public:
_FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow);
- void _draw_skybox(RasterizerStorageGLES3::SkyBox *p_skybox, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale);
+ void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy);
void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform);
void _setup_directional_light(int p_index, const Transform &p_camera_inverse_transformm, bool p_use_shadows);
@@ -713,6 +777,7 @@ public:
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_shadow);
+ void _blur_effect_buffer();
void _render_mrts(Environment *env, const CameraMatrix &p_cam_projection);
void _post_process(Environment *env, const CameraMatrix &p_cam_projection);
@@ -720,9 +785,8 @@ public:
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count);
virtual bool free(RID p_rid);
- void _generate_brdf();
-
virtual void set_scene_pass(uint64_t p_pass);
+ virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw);
void iteration();
void initialize();
diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp
index 73547b5a16..85331342e9 100644
--- a/drivers/gles3/rasterizer_storage_gles3.cpp
+++ b/drivers/gles3/rasterizer_storage_gles3.cpp
@@ -101,11 +101,11 @@
GLuint RasterizerStorageGLES3::system_fbo = 0;
-Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) {
+Ref<Image> RasterizerStorageGLES3::_get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_gl_type, bool &r_compressed, bool &srgb) {
r_compressed = false;
r_gl_format = 0;
- Image image = p_image;
+ Ref<Image> image = p_image;
srgb = false;
bool need_decompress = false;
@@ -164,18 +164,6 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
srgb = true;
} break;
- case Image::FORMAT_RGB565: {
-#ifndef GLES_OVER_GL
- r_gl_internal_format = GL_RGB565;
-#else
- //#warning TODO: Convert tod 555 if 565 is not supported (GLES3.3-)
- r_gl_internal_format = GL_RGB5;
-#endif
- //r_gl_internal_format=GL_RGB565;
- r_gl_format = GL_RGB;
- r_gl_type = GL_UNSIGNED_SHORT_5_6_5;
-
- } break;
case Image::FORMAT_RGBA4444: {
r_gl_internal_format = GL_RGBA4;
@@ -241,11 +229,17 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
r_gl_type = GL_HALF_FLOAT;
} break;
+ case Image::FORMAT_RGBE9995: {
+ r_gl_internal_format = GL_RGB9_E5;
+ r_gl_format = GL_RGB;
+ r_gl_type = GL_UNSIGNED_INT_5_9_9_9_REV;
+
+ } break;
case Image::FORMAT_DXT1: {
if (config.s3tc_supported) {
- r_gl_internal_format = (config.srgb_decode_supported || p_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) ? _EXT_COMPRESSED_SRGB_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;
@@ -289,15 +283,14 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
}
} break;
- case Image::FORMAT_ATI1: {
+ case Image::FORMAT_RGTC_R: {
- if (config.latc_supported) {
+ if (config.rgtc_supported) {
- r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
+ r_gl_internal_format = _EXT_COMPRESSED_RED_RGTC1_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
- srgb = true;
} else {
@@ -305,11 +298,11 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
}
} break;
- case Image::FORMAT_ATI2: {
+ case Image::FORMAT_RGTC_RG: {
- if (config.latc_supported) {
+ if (config.rgtc_supported) {
- r_gl_internal_format = _EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
+ r_gl_internal_format = _EXT_COMPRESSED_RED_GREEN_RGTC2_EXT;
r_gl_format = GL_RGBA;
r_gl_type = GL_UNSIGNED_BYTE;
r_compressed = true;
@@ -538,16 +531,17 @@ Image RasterizerStorageGLES3::_get_gl_image_and_format(const Image &p_image, Ima
} break;
default: {
- ERR_FAIL_V(Image());
+ ERR_FAIL_V(Ref<Image>());
}
}
if (need_decompress) {
- if (!image.empty()) {
- image.decompress();
- ERR_FAIL_COND_V(image.is_compressed(), image);
- image.convert(Image::FORMAT_RGBA8);
+ if (!image.is_null()) {
+ image = image->duplicate();
+ image->decompress();
+ ERR_FAIL_COND_V(image->is_compressed(), image);
+ image->convert(Image::FORMAT_RGBA8);
}
r_gl_format = GL_RGBA;
@@ -607,7 +601,7 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
texture->stored_cube_sides = 0;
texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
- _get_gl_image_and_format(Image(), texture->format, texture->flags, format, internal_format, type, compressed, srgb);
+ _get_gl_image_and_format(Ref<Image>(), texture->format, texture->flags, format, internal_format, type, compressed, srgb);
texture->alloc_width = texture->width;
texture->alloc_height = texture->height;
@@ -631,15 +625,15 @@ void RasterizerStorageGLES3::texture_allocate(RID p_texture, int p_width, int p_
texture->active = true;
}
-void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side) {
+void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side) {
Texture *texture = texture_owner.get(p_texture);
ERR_FAIL_COND(!texture);
ERR_FAIL_COND(!texture->active);
ERR_FAIL_COND(texture->render_target);
- ERR_FAIL_COND(texture->format != p_image.get_format());
- ERR_FAIL_COND(p_image.empty());
+ ERR_FAIL_COND(texture->format != p_image->get_format());
+ ERR_FAIL_COND(p_image.is_null());
GLenum type;
GLenum format;
@@ -651,31 +645,31 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
texture->images[p_cube_side] = p_image;
}
- Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, internal_format, type, compressed, srgb);
+ Ref<Image> img = _get_gl_image_and_format(p_image, p_image->get_format(), texture->flags, format, internal_format, type, compressed, srgb);
- if (config.shrink_textures_x2 && (p_image.has_mipmaps() || !p_image.is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
+ if (config.shrink_textures_x2 && (p_image->has_mipmaps() || !p_image->is_compressed()) && !(texture->flags & VS::TEXTURE_FLAG_USED_FOR_STREAMING)) {
texture->alloc_height = MAX(1, texture->alloc_height / 2);
texture->alloc_width = MAX(1, texture->alloc_width / 2);
- if (texture->alloc_width == img.get_width() / 2 && texture->alloc_height == img.get_height() / 2) {
+ if (texture->alloc_width == img->get_width() / 2 && texture->alloc_height == img->get_height() / 2) {
- img.shrink_x2();
- } else if (img.get_format() <= Image::FORMAT_RGB565) {
+ img->shrink_x2();
+ } else if (img->get_format() <= Image::FORMAT_RGBA8) {
- img.resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
+ img->resize(texture->alloc_width, texture->alloc_height, Image::INTERPOLATE_BILINEAR);
}
};
GLenum blit_target = (texture->target == GL_TEXTURE_CUBE_MAP) ? _cube_side_enum[p_cube_side] : GL_TEXTURE_2D;
- texture->data_size = img.get_data().size();
- PoolVector<uint8_t>::Read read = img.get_data().read();
+ texture->data_size = img->get_data().size();
+ PoolVector<uint8_t>::Read read = img->get_data().read();
glActiveTexture(GL_TEXTURE0);
glBindTexture(texture->target, texture->tex_id);
- texture->ignore_mipmaps = compressed && !img.has_mipmaps();
+ texture->ignore_mipmaps = compressed && !img->has_mipmaps();
if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps)
glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, config.use_fast_texture_filter ? GL_LINEAR_MIPMAP_NEAREST : GL_LINEAR_MIPMAP_LINEAR);
@@ -761,22 +755,33 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
}
}
- 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 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;
- img.get_mipmap_offset_and_size(i, ofs, size);
+ img->get_mipmap_offset_and_size(i, ofs, size);
//print_line("mipmap: "+itos(i)+" size: "+itos(size)+" w: "+itos(mm_w)+", h: "+itos(mm_h));
if (texture->compressed) {
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
- glCompressedTexImage2D(blit_target, i, internal_format, w, h, 0, size, &read[ofs]);
+
+ //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;
+
+ glCompressedTexImage2D(blit_target, i, internal_format, bw, bh, 0, size, &read[ofs]);
} else {
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@@ -813,16 +818,15 @@ void RasterizerStorageGLES3::texture_set_data(RID p_texture, const Image &p_imag
//texture_set_flags(p_texture,texture->flags);
}
-Image RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
+Ref<Image> RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side) const {
Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND_V(!texture, Image());
- ERR_FAIL_COND_V(!texture->active, Image());
- ERR_FAIL_COND_V(texture->data_size == 0, Image());
- ERR_FAIL_COND_V(texture->render_target, Image());
+ ERR_FAIL_COND_V(!texture, Ref<Image>());
+ ERR_FAIL_COND_V(!texture->active, Ref<Image>());
+ ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>());
- if (!texture->images[p_cube_side].empty()) {
+ if (!texture->images[p_cube_side].is_null()) {
return texture->images[p_cube_side];
}
@@ -867,13 +871,13 @@ Image RasterizerStorageGLES3::texture_get_data(RID p_texture, VS::CubeMapSide p_
data.resize(data_size);
- Image img(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, texture->format, data);
+ Image *img = memnew(Image(texture->alloc_width, texture->alloc_height, texture->mipmaps > 1 ? true : false, texture->format, data));
- return img;
+ return Ref<Image>(img);
#else
ERR_EXPLAIN("Sorry, It's not posible to obtain images back in OpenGL ES");
- return Image();
+ return Ref<Image>();
#endif
}
@@ -969,6 +973,14 @@ Image::Format RasterizerStorageGLES3::texture_get_format(RID p_texture) const {
return texture->format;
}
+uint32_t RasterizerStorageGLES3::texture_get_texid(RID p_texture) const {
+
+ Texture *texture = texture_owner.get(p_texture);
+
+ ERR_FAIL_COND_V(!texture, 0);
+
+ return texture->tex_id;
+}
uint32_t RasterizerStorageGLES3::texture_get_width(RID p_texture) const {
Texture *texture = texture_owner.get(p_texture);
@@ -1060,6 +1072,14 @@ void RasterizerStorageGLES3::texture_set_detect_srgb_callback(RID p_texture, Vis
texture->detect_srgb_ud = p_userdata;
}
+void RasterizerStorageGLES3::texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) {
+ Texture *texture = texture_owner.get(p_texture);
+ ERR_FAIL_COND(!texture);
+
+ texture->detect_normal = p_callback;
+ texture->detect_normal_ud = p_userdata;
+}
+
RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_resolution) const {
Texture *texture = texture_owner.get(p_source);
@@ -1204,32 +1224,32 @@ RID RasterizerStorageGLES3::texture_create_radiance_cubemap(RID p_source, int p_
return texture_owner.make_rid(ctex);
}
-RID RasterizerStorageGLES3::skybox_create() {
+RID RasterizerStorageGLES3::sky_create() {
- SkyBox *skybox = memnew(SkyBox);
- skybox->radiance = 0;
- return skybox_owner.make_rid(skybox);
+ Sky *sky = memnew(Sky);
+ sky->radiance = 0;
+ return sky_owner.make_rid(sky);
}
-void RasterizerStorageGLES3::skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size) {
+void RasterizerStorageGLES3::sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size) {
- SkyBox *skybox = skybox_owner.getornull(p_skybox);
- ERR_FAIL_COND(!skybox);
+ Sky *sky = sky_owner.getornull(p_sky);
+ ERR_FAIL_COND(!sky);
- if (skybox->cubemap.is_valid()) {
- skybox->cubemap = RID();
- glDeleteTextures(1, &skybox->radiance);
- skybox->radiance = 0;
+ if (sky->panorama.is_valid()) {
+ sky->panorama = RID();
+ glDeleteTextures(1, &sky->radiance);
+ sky->radiance = 0;
}
- skybox->cubemap = p_cube_map;
- if (!skybox->cubemap.is_valid())
+ sky->panorama = p_panorama;
+ if (!sky->panorama.is_valid())
return; //cleared
- Texture *texture = texture_owner.getornull(skybox->cubemap);
- if (!texture || !(texture->flags & VS::TEXTURE_FLAG_CUBEMAP)) {
- skybox->cubemap = RID();
- ERR_FAIL_COND(!texture || !(texture->flags & VS::TEXTURE_FLAG_CUBEMAP));
+ Texture *texture = texture_owner.getornull(sky->panorama);
+ if (!texture) {
+ sky->panorama = RID();
+ ERR_FAIL_COND(!texture);
}
glBindVertexArray(0);
@@ -1254,8 +1274,8 @@ void RasterizerStorageGLES3::skybox_set_texture(RID p_skybox, RID p_cube_map, in
}
glActiveTexture(GL_TEXTURE1);
- glGenTextures(1, &skybox->radiance);
- glBindTexture(GL_TEXTURE_2D, skybox->radiance);
+ glGenTextures(1, &sky->radiance);
+ glBindTexture(GL_TEXTURE_2D, sky->radiance);
GLuint tmp_fb;
@@ -1295,11 +1315,12 @@ void RasterizerStorageGLES3::skybox_set_texture(RID p_skybox, RID p_cube_map, in
size = p_radiance_size;
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, true);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, true);
shaders.cubemap_filter.bind();
while (mm_level) {
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, skybox->radiance, lod);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, sky->radiance, lod);
#ifdef DEBUG_ENABLED
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
ERR_CONTINUE(status != GL_FRAMEBUFFER_COMPLETE);
@@ -1322,6 +1343,7 @@ void RasterizerStorageGLES3::skybox_set_texture(RID p_skybox, RID p_cube_map, in
mm_level--;
}
shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_DUAL_PARABOLOID, false);
+ shaders.cubemap_filter.set_conditional(CubemapFilterShaderGLES3::USE_PANORAMA, false);
//restore ranges
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
@@ -1411,6 +1433,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
_shader_dirty_list.remove(&p_shader->dirty_list);
p_shader->valid = false;
+ p_shader->ubo_size = 0;
p_shader->uniforms.clear();
@@ -1447,6 +1470,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
p_shader->spatial.unshaded = false;
p_shader->spatial.ontop = false;
p_shader->spatial.uses_sss = false;
+ p_shader->spatial.uses_screen_texture = false;
p_shader->spatial.uses_vertex = false;
p_shader->spatial.writes_modelview_or_projection = false;
@@ -1472,6 +1496,7 @@ void RasterizerStorageGLES3::_update_shader(Shader *p_shader) const {
shaders.actions_scene.usage_flag_pointers["SSS_STRENGTH"] = &p_shader->spatial.uses_sss;
shaders.actions_scene.usage_flag_pointers["DISCARD"] = &p_shader->spatial.uses_discard;
+ shaders.actions_scene.usage_flag_pointers["SCREEN_TEXTURE"] = &p_shader->spatial.uses_screen_texture;
shaders.actions_scene.write_flag_pointers["MODELVIEW_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
shaders.actions_scene.write_flag_pointers["PROJECTION_MATRIX"] = &p_shader->spatial.writes_modelview_or_projection;
@@ -1531,7 +1556,11 @@ void RasterizerStorageGLES3::shader_get_param_list(RID p_shader, List<PropertyIn
for (Map<StringName, ShaderLanguage::ShaderNode::Uniform>::Element *E = shader->uniforms.front(); E; E = E->next()) {
- order[E->get().order] = E->key();
+ if (E->get().texture_order >= 0) {
+ order[E->get().texture_order + 100000] = E->key();
+ } else {
+ order[E->get().order] = E->key();
+ }
}
for (Map<int, StringName>::Element *E = order.front(); E; E = E->next()) {
@@ -1945,8 +1974,8 @@ _FORCE_INLINE_ static void _fill_std140_variant_ubo_value(ShaderLanguage::DataTy
} else if (value.get_type() == Variant::RECT2) {
Rect2 v = value;
- gui[0] = v.pos.x;
- gui[1] = v.pos.y;
+ gui[0] = v.position.x;
+ gui[1] = v.position.y;
gui[2] = v.size.x;
gui[3] = v.size.y;
} else if (value.get_type() == Variant::QUAT) {
@@ -2228,6 +2257,10 @@ void RasterizerStorageGLES3::_update_material(Material *material) {
if (material->shader && material->shader->dirty_list.in_list()) {
_update_shader(material->shader);
}
+
+ if (material->shader && !material->shader->valid)
+ return;
+
//update caches
{
@@ -2642,6 +2675,7 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
surface->skeleton_bone_used.resize(surface->skeleton_bone_aabb.size());
surface->aabb = p_aabb;
surface->max_bone = p_bone_aabbs.size();
+ surface->total_data_size += surface->array_byte_size + surface->index_array_byte_size;
for (int i = 0; i < surface->skeleton_bone_used.size(); i++) {
if (surface->skeleton_bone_aabb[i].size.x < 0 || surface->skeleton_bone_aabb[i].size.y < 0 || surface->skeleton_bone_aabb[i].size.z < 0) {
@@ -2711,6 +2745,112 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
}
+
+#ifdef DEBUG_ENABLED
+
+ if (config.generate_wireframes && p_primitive == VS::PRIMITIVE_TRIANGLES) {
+ //generate wireframes, this is used mostly by editor
+ PoolVector<uint32_t> wf_indices;
+ int index_count;
+
+ if (p_format & VS::ARRAY_FORMAT_INDEX) {
+
+ index_count = p_index_count * 2;
+ wf_indices.resize(index_count);
+
+ PoolVector<uint8_t>::Read ir = p_index_array.read();
+ PoolVector<uint32_t>::Write wr = wf_indices.write();
+
+ if (p_vertex_count < (1 << 16)) {
+ //read 16 bit indices
+ const uint16_t *src_idx = (const uint16_t *)ir.ptr();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = src_idx[i / 2];
+ wr[i + 1] = src_idx[i / 2 + 1];
+ wr[i + 2] = src_idx[i / 2 + 1];
+ wr[i + 3] = src_idx[i / 2 + 2];
+ wr[i + 4] = src_idx[i / 2 + 2];
+ wr[i + 5] = src_idx[i / 2];
+ }
+
+ } else {
+
+ //read 16 bit indices
+ const uint32_t *src_idx = (const uint32_t *)ir.ptr();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = src_idx[i / 2];
+ wr[i + 1] = src_idx[i / 2 + 1];
+ wr[i + 2] = src_idx[i / 2 + 1];
+ wr[i + 3] = src_idx[i / 2 + 2];
+ wr[i + 4] = src_idx[i / 2 + 2];
+ wr[i + 5] = src_idx[i / 2];
+ }
+ }
+
+ } else {
+
+ index_count = p_vertex_count * 2;
+ wf_indices.resize(index_count);
+ PoolVector<uint32_t>::Write wr = wf_indices.write();
+ for (int i = 0; i < index_count; i += 6) {
+
+ wr[i + 0] = i / 2;
+ wr[i + 1] = i / 2 + 1;
+ wr[i + 2] = i / 2 + 1;
+ wr[i + 3] = i / 2 + 2;
+ wr[i + 4] = i / 2 + 2;
+ wr[i + 5] = i / 2;
+ }
+ }
+ {
+ PoolVector<uint32_t>::Read ir = wf_indices.read();
+
+ glGenBuffers(1, &surface->index_wireframe_id);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_count * sizeof(uint32_t), ir.ptr(), GL_STATIC_DRAW);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
+
+ surface->index_wireframe_len = index_count;
+ }
+
+ for (int ai = 0; ai < 2; ai++) {
+
+ if (ai == 0) {
+ //for normal draw
+ glGenVertexArrays(1, &surface->array_wireframe_id);
+ glBindVertexArray(surface->array_wireframe_id);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+ } else if (ai == 1) {
+ //for instancing draw (can be changed and no one cares)
+ glGenVertexArrays(1, &surface->instancing_array_wireframe_id);
+ glBindVertexArray(surface->instancing_array_wireframe_id);
+ glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
+ }
+
+ for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
+
+ if (!attribs[i].enabled)
+ continue;
+
+ if (attribs[i].integer) {
+ glVertexAttribIPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset);
+ } else {
+ glVertexAttribPointer(attribs[i].index, attribs[i].size, attribs[i].type, attribs[i].normalized, attribs[i].stride, ((uint8_t *)0) + attribs[i].offset);
+ }
+ glEnableVertexAttribArray(attribs[i].index);
+ }
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_wireframe_id);
+
+ glBindVertexArray(0);
+ glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
+ }
+ }
+
+#endif
}
{
@@ -2723,6 +2863,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
PoolVector<uint8_t>::Read vr = p_blend_shapes[i].read();
+ surface->total_data_size += array_size;
+
glGenBuffers(1, &mt.vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, mt.vertex_id);
glBufferData(GL_ARRAY_BUFFER, array_size, vr.ptr(), GL_STATIC_DRAW);
@@ -2754,6 +2896,8 @@ void RasterizerStorageGLES3::mesh_add_surface(RID p_mesh, uint32_t p_format, VS:
mesh->surfaces.push_back(surface);
mesh->instance_change_notify();
+
+ info.vertex_mem += surface->total_data_size;
}
void RasterizerStorageGLES3::mesh_set_blend_shape_count(RID p_mesh, int p_amount) {
@@ -2975,6 +3119,7 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
}
glDeleteVertexArrays(1, &surface->array_id);
+ glDeleteVertexArrays(1, &surface->instancing_array_id);
for (int i = 0; i < surface->blend_shapes.size(); i++) {
@@ -2982,6 +3127,14 @@ void RasterizerStorageGLES3::mesh_remove_surface(RID p_mesh, int p_surface) {
glDeleteVertexArrays(1, &surface->blend_shapes[i].array_id);
}
+ if (surface->index_wireframe_id) {
+ glDeleteBuffers(1, &surface->index_wireframe_id);
+ glDeleteVertexArrays(1, &surface->array_wireframe_id);
+ glDeleteVertexArrays(1, &surface->instancing_array_wireframe_id);
+ }
+
+ info.vertex_mem -= surface->total_data_size;
+
mesh->instance_material_change_notify();
memdelete(surface);
@@ -3814,7 +3967,7 @@ void RasterizerStorageGLES3::immediate_vertex(RID p_immediate, const Vector3 &p_
if (c->vertices.empty() && im->chunks.size() == 1) {
- im->aabb.pos = p_vertex;
+ im->aabb.position = p_vertex;
im->aabb.size = Vector3();
} else {
im->aabb.expand_to(p_vertex);
@@ -4133,7 +4286,6 @@ RID RasterizerStorageGLES3::light_create(VS::LightType p_type) {
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light->param[VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light->param[VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 0.1;
- light->param[VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE] = 0.1;
light->color = Color(1, 1, 1, 1);
light->shadow = false;
@@ -4170,8 +4322,7 @@ void RasterizerStorageGLES3::light_set_param(RID p_light, VS::LightParam p_param
case VS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET:
case VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET:
case VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS:
- case VS::LIGHT_PARAM_SHADOW_BIAS:
- case VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE: {
+ case VS::LIGHT_PARAM_SHADOW_BIAS: {
light->version++;
light->instance_change_notify();
@@ -4481,7 +4632,7 @@ Rect3 RasterizerStorageGLES3::reflection_probe_get_aabb(RID p_probe) const {
ERR_FAIL_COND_V(!reflection_probe, Rect3());
Rect3 aabb;
- aabb.pos = -reflection_probe->extents;
+ aabb.position = -reflection_probe->extents;
aabb.size = reflection_probe->extents * 2.0;
return aabb;
@@ -5074,7 +5225,7 @@ Rect3 RasterizerStorageGLES3::particles_get_current_aabb(RID p_particles) {
pos = inv.xform(pos);
}
if (i == 0)
- aabb.pos = pos;
+ aabb.position = pos;
else
aabb.expand_to(pos);
}
@@ -5111,6 +5262,23 @@ void RasterizerStorageGLES3::particles_set_emission_transform(RID p_particles, c
particles->emission_transform = p_transform;
}
+int RasterizerStorageGLES3::particles_get_draw_passes(RID p_particles) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, 0);
+
+ return particles->draw_passes.size();
+}
+
+RID RasterizerStorageGLES3::particles_get_draw_pass_mesh(RID p_particles, int p_pass) const {
+
+ const Particles *particles = particles_owner.getornull(p_particles);
+ ERR_FAIL_COND_V(!particles, RID());
+ ERR_FAIL_INDEX_V(p_pass, particles->draw_passes.size(), RID());
+
+ return particles->draw_passes[p_pass];
+}
+
void RasterizerStorageGLES3::_particles_process(Particles *particles, float p_delta) {
float new_phase = Math::fmod((float)particles->phase + (p_delta / particles->lifetime) * particles->speed_scale, (float)1.0);
@@ -5242,7 +5410,7 @@ void RasterizerStorageGLES3::update_particles() {
shaders.particles.bind();
shaders.particles.set_uniform(ParticlesShaderGLES3::TOTAL_PARTICLES, particles->amount);
- shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, Color(frame.time[0], frame.time[1], frame.time[2], frame.time[3]));
+ shaders.particles.set_uniform(ParticlesShaderGLES3::TIME, frame.time[0]);
shaders.particles.set_uniform(ParticlesShaderGLES3::EXPLOSIVENESS, particles->explosiveness);
shaders.particles.set_uniform(ParticlesShaderGLES3::LIFETIME, particles->lifetime);
shaders.particles.set_uniform(ParticlesShaderGLES3::ATTRACTOR_COUNT, 0);
@@ -5305,13 +5473,11 @@ void RasterizerStorageGLES3::update_particles() {
particles->particle_valid_histories[0] = true;
}
+
+ particles->instance_change_notify(); //make sure shadows are updated
}
glDisable(GL_RASTERIZER_DISCARD);
-
- for (int i = 0; i < 6; i++) {
- glDisableVertexAttribArray(i);
- }
}
////////
@@ -5436,7 +5602,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
glDeleteRenderbuffers(1, &rt->buffers.diffuse);
glDeleteRenderbuffers(1, &rt->buffers.specular);
glDeleteRenderbuffers(1, &rt->buffers.normal_rough);
- glDeleteRenderbuffers(1, &rt->buffers.motion_sss);
+ glDeleteRenderbuffers(1, &rt->buffers.sss);
glDeleteFramebuffers(1, &rt->buffers.effect_fbo);
glDeleteTextures(1, &rt->buffers.effect);
@@ -5475,6 +5641,7 @@ void RasterizerStorageGLES3::_render_target_clear(RenderTarget *rt) {
tex->alloc_width = 0;
tex->width = 0;
tex->height = 0;
+ tex->active = false;
for (int i = 0; i < 2; i++) {
for (int j = 0; j < rt->effects.mip_maps[i].sizes.size(); j++) {
@@ -5506,7 +5673,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
Image::Format image_format;
bool hdr = rt->flags[RENDER_TARGET_HDR] && config.hdr_supported;
- hdr = false;
+ //hdr = false;
if (!hdr || rt->flags[RENDER_TARGET_NO_3D]) {
@@ -5571,13 +5738,14 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
tex->alloc_width = rt->width;
tex->height = rt->height;
tex->alloc_height = rt->height;
+ tex->active = true;
texture_set_flags(rt->texture, tex->flags);
}
/* BACK FBO */
- if (config.render_arch == RENDER_ARCH_DESKTOP && !rt->flags[RENDER_TARGET_NO_3D]) {
+ if (!rt->flags[RENDER_TARGET_NO_3D]) {
static const int msaa_value[] = { 0, 2, 4, 8, 16 };
int msaa = msaa_value[rt->msaa];
@@ -5605,75 +5773,155 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rt->buffers.diffuse);
- glGenRenderbuffers(1, &rt->buffers.specular);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular);
+ if (!rt->flags[RENDER_TARGET_NO_3D_EFFECTS]) {
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, color_internal_format, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.specular);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.specular);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rt->buffers.specular);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, color_internal_format, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, color_internal_format, rt->width, rt->height);
- glGenRenderbuffers(1, &rt->buffers.normal_rough);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.normal_rough);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_RENDERBUFFER, rt->buffers.specular);
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.normal_rough);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.normal_rough);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rt->buffers.normal_rough);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
- glGenRenderbuffers(1, &rt->buffers.motion_sss);
- glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.motion_sss);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, GL_RENDERBUFFER, rt->buffers.normal_rough);
- if (msaa == 0)
- glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, rt->width, rt->height);
- else
- glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_RGBA8, rt->width, rt->height);
+ glGenRenderbuffers(1, &rt->buffers.sss);
+ glBindRenderbuffer(GL_RENDERBUFFER, rt->buffers.sss);
- glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.motion_sss);
+ if (msaa == 0)
+ glRenderbufferStorage(GL_RENDERBUFFER, GL_R8, rt->width, rt->height);
+ else
+ glRenderbufferStorageMultisample(GL_RENDERBUFFER, msaa, GL_R8, rt->width, rt->height);
- GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, GL_RENDERBUFFER, rt->buffers.sss);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- printf("err status: %x\n", status);
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
- glBindRenderbuffer(GL_RENDERBUFFER, 0);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n", status);
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
- // effect resolver
+ glBindRenderbuffer(GL_RENDERBUFFER, 0);
- glGenFramebuffers(1, &rt->buffers.effect_fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.effect_fbo);
+ // effect resolver
- glGenTextures(1, &rt->buffers.effect);
- glBindTexture(GL_TEXTURE_2D, rt->buffers.effect);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, rt->width, rt->height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
- GL_TEXTURE_2D, rt->buffers.effect, 0);
+ glGenFramebuffers(1, &rt->buffers.effect_fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->buffers.effect_fbo);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- printf("err status: %x\n", status);
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
+ glGenTextures(1, &rt->buffers.effect);
+ glBindTexture(GL_TEXTURE_2D, rt->buffers.effect);
+ glTexImage2D(GL_TEXTURE_2D, 0, color_internal_format, rt->width, rt->height, 0,
+ color_format, color_type, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_TEXTURE_2D, rt->buffers.effect, 0);
- glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ printf("err status: %x\n", status);
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ glBindFramebuffer(GL_FRAMEBUFFER, RasterizerStorageGLES3::system_fbo);
+
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
+
+ ///////////////// ssao
+
+ //AO strength textures
+ for (int i = 0; i < 2; i++) {
+
+ glGenFramebuffers(1, &rt->effects.ssao.blur_fbo[i]);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->effects.ssao.blur_fbo[i]);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+ GL_TEXTURE_2D, rt->depth, 0);
+
+ glGenTextures(1, &rt->effects.ssao.blur_red[i]);
+ glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.blur_red[i]);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, rt->width, rt->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.blur_red[i], 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
+ }
+ //5 mip levels for depth texture, but base is read separately
+
+ glGenTextures(1, &rt->effects.ssao.linear_depth);
+ glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.linear_depth);
+
+ int ssao_w = rt->width / 2;
+ int ssao_h = rt->height / 2;
+
+ for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
+
+ glTexImage2D(GL_TEXTURE_2D, i, GL_R16UI, ssao_w, ssao_h, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
+ ssao_w >>= 1;
+ ssao_h >>= 1;
+ }
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
+
+ for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
+
+ GLuint fbo;
+ glGenFramebuffers(1, &fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.linear_depth, i);
+ rt->effects.ssao.depth_mipmap_fbos.push_back(fbo);
+ }
+
+ //////Exposure
+
+ glGenFramebuffers(1, &rt->exposure.fbo);
+ glBindFramebuffer(GL_FRAMEBUFFER, rt->exposure.fbo);
+
+ glGenTextures(1, &rt->exposure.color);
+ glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
+
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if (status != GL_FRAMEBUFFER_COMPLETE) {
+ _render_target_clear(rt);
+ ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
+ }
}
+ }
+
+ if (!rt->flags[RENDER_TARGET_NO_SAMPLING]) {
for (int i = 0; i < 2; i++) {
@@ -5720,7 +5968,7 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glBindFramebuffer(GL_FRAMEBUFFER, mm.fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.mip_maps[i].color, j);
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
_render_target_clear(rt);
ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
@@ -5740,79 +5988,6 @@ void RasterizerStorageGLES3::_render_target_allocate(RenderTarget *rt) {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
}
- ///////////////// ssao
-
- //AO strength textures
- for (int i = 0; i < 2; i++) {
-
- glGenFramebuffers(1, &rt->effects.ssao.blur_fbo[i]);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->effects.ssao.blur_fbo[i]);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
- GL_TEXTURE_2D, rt->depth, 0);
-
- glGenTextures(1, &rt->effects.ssao.blur_red[i]);
- glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.blur_red[i]);
-
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, rt->width, rt->height, 0, GL_RED, GL_UNSIGNED_BYTE, NULL);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.blur_red[i], 0);
-
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
- }
- //5 mip levels for depth texture, but base is read separately
-
- glGenTextures(1, &rt->effects.ssao.linear_depth);
- glBindTexture(GL_TEXTURE_2D, rt->effects.ssao.linear_depth);
-
- int ssao_w = rt->width / 2;
- int ssao_h = rt->height / 2;
-
- for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
-
- glTexImage2D(GL_TEXTURE_2D, i, GL_R16UI, ssao_w, ssao_h, 0, GL_RED_INTEGER, GL_UNSIGNED_SHORT, NULL);
- ssao_w >>= 1;
- ssao_h >>= 1;
- }
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 3);
-
- for (int i = 0; i < 4; i++) { //5, but 4 mips, base is read directly to save bw
-
- GLuint fbo;
- glGenFramebuffers(1, &fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, fbo);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->effects.ssao.linear_depth, i);
- rt->effects.ssao.depth_mipmap_fbos.push_back(fbo);
- }
-
- //////Exposure
-
- glGenFramebuffers(1, &rt->exposure.fbo);
- glBindFramebuffer(GL_FRAMEBUFFER, rt->exposure.fbo);
-
- glGenTextures(1, &rt->exposure.color);
- glBindTexture(GL_TEXTURE_2D, rt->exposure.color);
- glTexImage2D(GL_TEXTURE_2D, 0, GL_R32F, 1, 1, 0, GL_RED, GL_FLOAT, NULL);
- glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->exposure.color, 0);
-
- status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
- if (status != GL_FRAMEBUFFER_COMPLETE) {
- _render_target_clear(rt);
- ERR_FAIL_COND(status != GL_FRAMEBUFFER_COMPLETE);
- }
}
}
@@ -5837,9 +6012,10 @@ RID RasterizerStorageGLES3::render_target_create() {
t->srgb = false;
t->total_data_size = 0;
t->ignore_mipmaps = false;
- t->mipmaps = 0;
+ t->mipmaps = 1;
t->active = true;
t->tex_id = 0;
+ t->render_target = rt;
rt->texture = texture_owner.make_rid(t);
@@ -5876,8 +6052,10 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
rt->flags[p_flag] = p_value;
switch (p_flag) {
+ case RENDER_TARGET_HDR:
case RENDER_TARGET_NO_3D:
- case RENDER_TARGET_TRANSPARENT: {
+ case RENDER_TARGET_NO_SAMPLING:
+ case RENDER_TARGET_NO_3D_EFFECTS: {
//must reset for these formats
_render_target_clear(rt);
_render_target_allocate(rt);
@@ -5886,10 +6064,20 @@ void RasterizerStorageGLES3::render_target_set_flag(RID p_render_target, RenderT
default: {}
}
}
+bool RasterizerStorageGLES3::render_target_was_used(RID p_render_target) {
-bool RasterizerStorageGLES3::render_target_renedered_in_frame(RID p_render_target) {
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND_V(!rt, false);
- return false;
+ return rt->used_in_frame;
+}
+
+void RasterizerStorageGLES3::render_target_clear_used(RID p_render_target) {
+
+ RenderTarget *rt = render_target_owner.getornull(p_render_target);
+ ERR_FAIL_COND(!rt);
+
+ rt->used_in_frame = false;
}
void RasterizerStorageGLES3::render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) {
@@ -5958,6 +6146,7 @@ RID RasterizerStorageGLES3::canvas_light_occluder_create() {
co->index_id = 0;
co->vertex_id = 0;
co->len = 0;
+ glGenVertexArrays(1, &co->array_id);
return canvas_occluder_owner.make_rid(co);
}
@@ -6029,7 +6218,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
if (!co->vertex_id) {
glGenBuffers(1, &co->vertex_id);
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_STATIC_DRAW);
+ glBufferData(GL_ARRAY_BUFFER, lc * 6 * sizeof(real_t), vw.ptr(), GL_DYNAMIC_DRAW);
} else {
glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
@@ -6042,7 +6231,7 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
glGenBuffers(1, &co->index_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_STATIC_DRAW);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, lc * 3 * sizeof(uint16_t), iw.ptr(), GL_DYNAMIC_DRAW);
} else {
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
@@ -6052,6 +6241,12 @@ void RasterizerStorageGLES3::canvas_light_occluder_set_polylines(RID p_occluder,
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
co->len = lc;
+ glBindVertexArray(co->array_id);
+ glBindBuffer(GL_ARRAY_BUFFER, co->vertex_id);
+ glEnableVertexAttribArray(VS::ARRAY_VERTEX);
+ glVertexAttribPointer(VS::ARRAY_VERTEX, 3, GL_FLOAT, false, 0, 0);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, co->index_id);
+ glBindVertexArray(0);
}
}
@@ -6107,12 +6302,12 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
info.texture_mem -= texture->total_data_size;
texture_owner.free(p_rid);
memdelete(texture);
- } else if (skybox_owner.owns(p_rid)) {
- // delete the skybox
- SkyBox *skybox = skybox_owner.get(p_rid);
- skybox_set_texture(p_rid, RID(), 256);
- skybox_owner.free(p_rid);
- memdelete(skybox);
+ } else if (sky_owner.owns(p_rid)) {
+ // delete the sky
+ Sky *sky = sky_owner.get(p_rid);
+ sky_set_texture(p_rid, RID(), 256);
+ sky_owner.free(p_rid);
+ memdelete(sky);
} else if (shader_owner.owns(p_rid)) {
@@ -6280,6 +6475,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
if (co->vertex_id)
glDeleteBuffers(1, &co->vertex_id);
+ glDeleteVertexArrays(1, &co->array_id);
+
canvas_occluder_owner.free(p_rid);
memdelete(co);
@@ -6317,10 +6514,98 @@ bool RasterizerStorageGLES3::has_os_feature(const String &p_feature) const {
////////////////////////////////////////////
-void RasterizerStorageGLES3::initialize() {
+void RasterizerStorageGLES3::set_debug_generate_wireframes(bool p_generate) {
+
+ config.generate_wireframes = p_generate;
+}
+
+void RasterizerStorageGLES3::render_info_begin_capture() {
+
+ info.snap = info.render;
+}
+
+void RasterizerStorageGLES3::render_info_end_capture() {
+
+ info.snap.object_count = info.render.object_count - info.snap.object_count;
+ info.snap.draw_call_count = info.render.draw_call_count - info.snap.draw_call_count;
+ info.snap.material_switch_count = info.render.material_switch_count - info.snap.material_switch_count;
+ info.snap.surface_switch_count = info.render.surface_switch_count - info.snap.surface_switch_count;
+ info.snap.shader_rebind_count = info.render.shader_rebind_count - info.snap.shader_rebind_count;
+ info.snap.vertices_count = info.render.vertices_count - info.snap.vertices_count;
+}
- config.render_arch = RENDER_ARCH_DESKTOP;
- //config.fbo_deferred=int(Globals::get_singleton()->get("rendering/gles3/lighting_technique"));
+int RasterizerStorageGLES3::get_captured_render_info(VS::RenderInfo p_info) {
+
+ switch (p_info) {
+ case VS::INFO_OBJECTS_IN_FRAME: {
+
+ return info.snap.object_count;
+ } break;
+ case VS::INFO_VERTICES_IN_FRAME: {
+
+ return info.snap.vertices_count;
+ } break;
+ case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+ return info.snap.material_switch_count;
+ } break;
+ case VS::INFO_SHADER_CHANGES_IN_FRAME: {
+ return info.snap.shader_rebind_count;
+ } break;
+ case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
+ return info.snap.surface_switch_count;
+ } break;
+ case VS::INFO_DRAW_CALLS_IN_FRAME: {
+ return info.snap.draw_call_count;
+ } break;
+ default: {
+ return get_render_info(p_info);
+ }
+ }
+}
+
+int RasterizerStorageGLES3::get_render_info(VS::RenderInfo p_info) {
+
+ switch (p_info) {
+ case VS::INFO_OBJECTS_IN_FRAME: {
+
+ return info.render_final.object_count;
+ } break;
+ case VS::INFO_VERTICES_IN_FRAME: {
+
+ return info.render_final.vertices_count;
+ } break;
+ case VS::INFO_MATERIAL_CHANGES_IN_FRAME: {
+ return info.render_final.material_switch_count;
+ } break;
+ case VS::INFO_SHADER_CHANGES_IN_FRAME: {
+ return info.render_final.shader_rebind_count;
+ } break;
+ case VS::INFO_SURFACE_CHANGES_IN_FRAME: {
+ return info.render_final.surface_switch_count;
+ } break;
+ case VS::INFO_DRAW_CALLS_IN_FRAME: {
+ return info.render_final.draw_call_count;
+ } break;
+ case VS::INFO_USAGE_VIDEO_MEM_TOTAL: {
+
+ return 0; //no idea
+ } break;
+ case VS::INFO_VIDEO_MEM_USED: {
+
+ return info.vertex_mem + info.texture_mem;
+ } break;
+ case VS::INFO_TEXTURE_MEM_USED: {
+
+ return info.texture_mem;
+ } break;
+ case VS::INFO_VERTEX_MEM_USED: {
+
+ return info.vertex_mem;
+ } break;
+ }
+}
+
+void RasterizerStorageGLES3::initialize() {
RasterizerStorageGLES3::system_fbo = 0;
@@ -6347,6 +6632,7 @@ void RasterizerStorageGLES3::initialize() {
config.s3tc_supported = config.extensions.has("GL_EXT_texture_compression_dxt1") || config.extensions.has("GL_EXT_texture_compression_s3tc") || config.extensions.has("WEBGL_compressed_texture_s3tc");
config.etc_supported = config.extensions.has("GL_OES_compressed_ETC1_RGB8_texture");
config.latc_supported = config.extensions.has("GL_EXT_texture_compression_latc");
+ config.rgtc_supported = config.extensions.has("GL_EXT_texture_compression_rgtc");
config.bptc_supported = config.extensions.has("GL_ARB_texture_compression_bptc");
#ifdef GLES_OVER_GL
config.hdr_supported = true;
@@ -6355,6 +6641,8 @@ void RasterizerStorageGLES3::initialize() {
config.etc2_supported = true;
config.hdr_supported = false;
#endif
+
+ print_line("hdr supported: " + itos(config.hdr_supported));
config.pvrtc_supported = config.extensions.has("GL_IMG_texture_compression_pvrtc");
config.srgb_decode_supported = config.extensions.has("GL_EXT_texture_sRGB_decode");
@@ -6469,7 +6757,7 @@ void RasterizerStorageGLES3::initialize() {
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
}
- //generic quadie for copying without touching skybox
+ //generic quadie for copying without touching sky
{
//transform feedback buffers
@@ -6498,6 +6786,7 @@ void RasterizerStorageGLES3::initialize() {
frame.delta = 0;
frame.current_rt = NULL;
config.keep_original_textures = false;
+ config.generate_wireframes = false;
}
void RasterizerStorageGLES3::finalize() {
diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h
index bb4a7e23a1..ca0194bd5e 100644
--- a/drivers/gles3/rasterizer_storage_gles3.h
+++ b/drivers/gles3/rasterizer_storage_gles3.h
@@ -61,14 +61,13 @@ public:
struct Config {
- RenderArchitecture render_arch;
-
bool shrink_textures_x2;
bool use_fast_texture_filter;
bool use_anisotropic_filter;
bool s3tc_supported;
bool latc_supported;
+ bool rgtc_supported;
bool bptc_supported;
bool etc_supported;
bool etc2_supported;
@@ -85,6 +84,8 @@ public:
int max_texture_image_units;
int max_texture_size;
+ bool generate_wireframes;
+
Set<String> extensions;
bool keep_original_textures;
@@ -125,12 +126,33 @@ public:
struct Info {
uint64_t texture_mem;
+ uint64_t vertex_mem;
+
+ struct Render {
+ uint32_t object_count;
+ uint32_t draw_call_count;
+ uint32_t material_switch_count;
+ uint32_t surface_switch_count;
+ uint32_t shader_rebind_count;
+ uint32_t vertices_count;
+
+ void reset() {
+ object_count = 0;
+ draw_call_count = 0;
+ material_switch_count = 0;
+ surface_switch_count = 0;
+ shader_rebind_count = 0;
+ vertices_count = 0;
+ }
+ } render, render_final, snap;
- uint32_t render_object_count;
- uint32_t render_material_switch_count;
- uint32_t render_surface_switch_count;
- uint32_t render_shader_rebind_count;
- uint32_t render_vertices_count;
+ Info() {
+
+ texture_mem = 0;
+ vertex_mem = 0;
+ render.reset();
+ render_final.reset();
+ }
} info;
@@ -240,7 +262,7 @@ public:
RenderTarget *render_target;
- Image images[6];
+ Ref<Image> images[6];
VisualServer::TextureDetectCallback detect_3d;
void *detect_3d_ud;
@@ -248,6 +270,9 @@ public:
VisualServer::TextureDetectCallback detect_srgb;
void *detect_srgb_ud;
+ VisualServer::TextureDetectCallback detect_normal;
+ void *detect_normal_ud;
+
Texture() {
using_srgb = false;
@@ -267,6 +292,8 @@ public:
detect_3d_ud = NULL;
detect_srgb = NULL;
detect_srgb_ud = NULL;
+ detect_normal = NULL;
+ detect_normal_ud = NULL;
}
~Texture() {
@@ -280,15 +307,16 @@ public:
mutable RID_Owner<Texture> texture_owner;
- Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_type, bool &r_compressed, bool &srgb);
+ Ref<Image> _get_gl_image_and_format(const Ref<Image> &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, GLenum &r_gl_internal_format, GLenum &r_type, bool &r_compressed, bool &srgb);
virtual RID texture_create();
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
- virtual void texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
- virtual Image texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
+ virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
virtual uint32_t texture_get_flags(RID p_texture) const;
virtual Image::Format texture_get_format(RID p_texture) const;
+ virtual uint32_t texture_get_texid(RID p_texture) const;
virtual uint32_t texture_get_width(RID p_texture) const;
virtual uint32_t texture_get_height(RID p_texture) const;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height);
@@ -306,20 +334,21 @@ public:
virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
+ virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata);
- /* SKYBOX API */
+ /* SKY API */
- struct SkyBox : public RID_Data {
+ struct Sky : public RID_Data {
- RID cubemap;
+ RID panorama;
GLuint radiance;
int radiance_size;
};
- mutable RID_Owner<SkyBox> skybox_owner;
+ mutable RID_Owner<Sky> sky_owner;
- virtual RID skybox_create();
- virtual void skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size);
+ virtual RID sky_create();
+ virtual void sky_set_texture(RID p_sky, RID p_panorama, int p_radiance_size);
/* SHADER API */
@@ -409,6 +438,7 @@ public:
bool uses_vertex;
bool uses_discard;
bool uses_sss;
+ bool uses_screen_texture;
bool writes_modelview_or_projection;
} spatial;
@@ -424,6 +454,7 @@ public:
: dirty_list(this) {
shader = NULL;
+ ubo_size = 0;
valid = false;
custom_code_id = 0;
version = 1;
@@ -536,6 +567,11 @@ public:
GLuint vertex_id;
GLuint index_id;
+ GLuint index_wireframe_id;
+ GLuint array_wireframe_id;
+ GLuint instancing_array_wireframe_id;
+ int index_wireframe_len;
+
Vector<Rect3> skeleton_bone_aabb;
Vector<bool> skeleton_bone_used;
@@ -566,6 +602,8 @@ public:
mesh->update_multimeshes();
}
+ int total_data_size;
+
Surface() {
array_byte_size = 0;
@@ -580,6 +618,13 @@ public:
primitive = VS::PRIMITIVE_POINTS;
index_array_len = 0;
active = false;
+
+ total_data_size = 0;
+
+ index_wireframe_id = 0;
+ array_wireframe_id = 0;
+ instancing_array_wireframe_id = 0;
+ index_wireframe_len = 0;
}
~Surface() {
@@ -1104,6 +1149,9 @@ public:
virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform);
void _particles_process(Particles *p_particles, float p_delta);
+ virtual int particles_get_draw_passes(RID p_particles) const;
+ virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const;
+
/* INSTANCE */
virtual void instance_add_skeleton(RID p_skeleton, RasterizerScene::InstanceBase *p_instance);
@@ -1126,7 +1174,7 @@ public:
GLuint specular;
GLuint diffuse;
GLuint normal_rough;
- GLuint motion_sss;
+ GLuint sss;
GLuint effect_fbo;
GLuint effect;
@@ -1206,9 +1254,10 @@ public:
flags[RENDER_TARGET_VFLIP] = false;
flags[RENDER_TARGET_TRANSPARENT] = false;
+ flags[RENDER_TARGET_NO_3D_EFFECTS] = false;
flags[RENDER_TARGET_NO_3D] = false;
- flags[RENDER_TARGET_HDR] = true;
flags[RENDER_TARGET_NO_SAMPLING] = false;
+ flags[RENDER_TARGET_HDR] = true;
last_exposure_tick = 0;
}
@@ -1224,7 +1273,8 @@ public:
virtual RID render_target_get_texture(RID p_render_target) const;
virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value);
- virtual bool render_target_renedered_in_frame(RID p_render_target);
+ virtual bool render_target_was_used(RID p_render_target);
+ virtual void render_target_clear_used(RID p_render_target);
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa);
/* CANVAS SHADOW */
@@ -1246,6 +1296,7 @@ public:
struct CanvasOccluder : public RID_Data {
+ GLuint array_id; // 0 means, unconfigured
GLuint vertex_id; // 0 means, unconfigured
GLuint index_id; // 0 means, unconfigured
PoolVector<Vector2> lines;
@@ -1272,6 +1323,7 @@ public:
float delta;
uint64_t prev_tick;
uint64_t count;
+
} frame;
void initialize();
@@ -1281,6 +1333,14 @@ public:
virtual void update_dirty_resources();
+ virtual void set_debug_generate_wireframes(bool p_generate);
+
+ virtual void render_info_begin_capture();
+ virtual void render_info_end_capture();
+ virtual int get_captured_render_info(VS::RenderInfo p_info);
+
+ virtual int get_render_info(VS::RenderInfo p_info);
+
RasterizerStorageGLES3();
};
diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp
index 89b056df84..3376f99112 100644
--- a/drivers/gles3/shader_compiler_gles3.cpp
+++ b/drivers/gles3/shader_compiler_gles3.cpp
@@ -383,7 +383,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
String vcode;
vcode += _prestr(E->get().precission);
vcode += _typestr(E->get().type);
- vcode += " " + String(E->key());
+ vcode += " " + _mkid(E->key());
vcode += ";\n";
r_gen_code.vertex_global += "out " + vcode;
r_gen_code.fragment_global += "in " + vcode;
@@ -574,6 +574,7 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _dump_node_code(onode->arguments[2], p_level, r_gen_code, p_actions, p_default_actions);
} break;
+
default: {
code = "(" + _dump_node_code(onode->arguments[0], p_level, r_gen_code, p_actions, p_default_actions) + _opstr(onode->op) + _dump_node_code(onode->arguments[1], p_level, r_gen_code, p_actions, p_default_actions) + ")";
@@ -593,6 +594,10 @@ String ShaderCompilerGLES3::_dump_node_code(SL::Node *p_node, int p_level, Gener
code += _mktab(p_level) + "else\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_WHILE) {
+
+ code += _mktab(p_level) + "while (" + _dump_node_code(cfnode->expressions[0], p_level, r_gen_code, p_actions, p_default_actions) + ")\n";
+ code += _dump_node_code(cfnode->blocks[0], p_level + 1, r_gen_code, p_actions, p_default_actions);
} else if (cfnode->flow_op == SL::FLOW_OP_RETURN) {
@@ -663,6 +668,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_CANVAS_ITEM].renames["PROJECTION_MATRIX"] = "projection_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["EXTRA_MATRIX"] == "extra_matrix";
actions[VS::SHADER_CANVAS_ITEM].renames["TIME"] = "time";
+ actions[VS::SHADER_CANVAS_ITEM].renames["AT_LIGHT_PASS"] = "at_light_pass";
actions[VS::SHADER_CANVAS_ITEM].renames["COLOR"] = "color";
actions[VS::SHADER_CANVAS_ITEM].renames["NORMAL"] = "normal";
@@ -723,6 +729,7 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].renames["NORMALMAP_DEPTH"] = "normaldepth";
actions[VS::SHADER_SPATIAL].renames["ALBEDO"] = "albedo";
actions[VS::SHADER_SPATIAL].renames["ALPHA"] = "alpha";
+ actions[VS::SHADER_SPATIAL].renames["METALLIC"] = "metallic";
actions[VS::SHADER_SPATIAL].renames["SPECULAR"] = "specular";
actions[VS::SHADER_SPATIAL].renames["ROUGHNESS"] = "roughness";
actions[VS::SHADER_SPATIAL].renames["RIM"] = "rim";
@@ -739,6 +746,10 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
//actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"]=ShaderLanguage::TYPE_VEC2;
actions[VS::SHADER_SPATIAL].renames["POINT_COORD"] = "gl_PointCoord";
actions[VS::SHADER_SPATIAL].renames["INSTANCE_CUSTOM"] = "instance_custom";
+ actions[VS::SHADER_SPATIAL].renames["SCREEN_UV"] = "screen_uv";
+ actions[VS::SHADER_SPATIAL].renames["SCREEN_TEXTURE"] = "screen_texture";
+ actions[VS::SHADER_SPATIAL].renames["DEPTH_TEXTURE"] = "depth_buffer";
+ actions[VS::SHADER_SPATIAL].renames["SIDE"] = "side";
actions[VS::SHADER_SPATIAL].usage_defines["TANGENT"] = "#define ENABLE_TANGENT_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["BINORMAL"] = "@TANGENT";
@@ -756,12 +767,18 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() {
actions[VS::SHADER_SPATIAL].usage_defines["COLOR"] = "#define ENABLE_COLOR_INTERP\n";
actions[VS::SHADER_SPATIAL].usage_defines["INSTANCE_CUSTOM"] = "#define ENABLE_INSTANCE_CUSTOM\n";
- actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS_MOTION\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SSS_STRENGTH"] = "#define ENABLE_SSS\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_TEXTURE"] = "#define SCREEN_TEXTURE_USED\n";
+ actions[VS::SHADER_SPATIAL].usage_defines["SCREEN_UV"] = "#define SCREEN_UV_USED\n";
actions[VS::SHADER_SPATIAL].renames["SSS_STRENGTH"] = "sss_strength";
actions[VS::SHADER_SPATIAL].render_mode_defines["skip_default_transform"] = "#define SKIP_TRANSFORM_USED\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n";
+ actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n";
+
/* PARTICLES SHADER */
actions[VS::SHADER_PARTICLES].renames["COLOR"] = "out_color";
diff --git a/drivers/gles3/shader_gles3.cpp b/drivers/gles3/shader_gles3.cpp
index bebc006032..8c6d15c3b7 100644
--- a/drivers/gles3/shader_gles3.cpp
+++ b/drivers/gles3/shader_gles3.cpp
@@ -100,14 +100,14 @@ void ShaderGLES3::bind_uniforms() {
};
uniforms_dirty = false;
-};
+}
GLint ShaderGLES3::get_uniform_location(int p_idx) const {
ERR_FAIL_COND_V(!version, -1);
return version->uniform_location[p_idx];
-};
+}
bool ShaderGLES3::bind() {
@@ -399,14 +399,14 @@ ShaderGLES3::Version *ShaderGLES3::get_current_version() {
strings.push_back(fragment_code2.get_data());
if (cc) {
- code_string = cc->fragment.ascii();
+ code_string = cc->light.ascii();
strings.push_back(code_string.get_data());
}
strings.push_back(fragment_code3.get_data());
if (cc) {
- code_string2 = cc->light.ascii();
+ code_string2 = cc->fragment.ascii();
strings.push_back(code_string2.get_data());
}
@@ -666,7 +666,7 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
//print_line("CODE1:\n"+String(fragment_code1.get_data()));
String code2 = code.substr(cpos + material_tag.length(), code.length());
- cpos = code2.find(code_tag);
+ cpos = code2.find(light_code_tag);
if (cpos == -1) {
fragment_code2 = code2.ascii();
@@ -675,16 +675,16 @@ void ShaderGLES3::setup(const char **p_conditional_defines, int p_conditional_co
fragment_code2 = code2.substr(0, cpos).ascii();
//print_line("CODE2:\n"+String(fragment_code2.get_data()));
- String code3 = code2.substr(cpos + code_tag.length(), code2.length());
+ String code3 = code2.substr(cpos + light_code_tag.length(), code2.length());
- cpos = code3.find(light_code_tag);
+ cpos = code3.find(code_tag);
if (cpos == -1) {
fragment_code3 = code3.ascii();
} else {
fragment_code3 = code3.substr(0, cpos).ascii();
//print_line("CODE3:\n"+String(fragment_code3.get_data()));
- fragment_code4 = code3.substr(cpos + light_code_tag.length(), code3.length()).ascii();
+ fragment_code4 = code3.substr(cpos + code_tag.length(), code3.length()).ascii();
//print_line("CODE4:\n"+String(fragment_code4.get_data()));
}
}
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index e6c72da8f1..7be6ee857a 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -6,8 +6,8 @@ layout(location=3) in vec4 color_attrib;
#ifdef USE_TEXTURE_RECT
-layout(location=1) in highp vec4 dst_rect;
-layout(location=2) in highp vec4 src_rect;
+uniform vec4 dst_rect;
+uniform vec4 src_rect;
#else
@@ -20,7 +20,7 @@ layout(location=4) in highp vec2 uv_attrib;
layout(std140) uniform CanvasItemData { //ubo:0
highp mat4 projection_matrix;
- highp vec4 time;
+ highp float time;
};
uniform highp mat4 modelview_matrix;
@@ -51,17 +51,21 @@ layout(std140) uniform LightData { //ubo:1
out vec4 light_uv_interp;
-#if defined(NORMAL_USED)
+
out vec4 local_rot;
-#endif
+
#ifdef USE_SHADOWS
out highp vec2 pos;
#endif
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
#endif
+
VERTEX_SHADER_GLOBALS
#if defined(USE_MATERIAL)
@@ -121,7 +125,7 @@ VERTEX_SHADER_CODE
pos=outvec.xy;
#endif
-#if defined(NORMAL_USED)
+
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy );
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy );
#ifdef USE_TEXTURE_RECT
@@ -129,7 +133,7 @@ VERTEX_SHADER_CODE
local_rot.zw*=sign(src_rect.w);
#endif
-#endif
+
#endif
@@ -141,6 +145,7 @@ VERTEX_SHADER_CODE
uniform mediump sampler2D color_texture; // texunit:0
uniform highp vec2 color_texpixel_size;
+uniform mediump sampler2D normal_texture; // texunit:1
in mediump vec2 uv_interp;
in mediump vec4 color_interp;
@@ -155,7 +160,7 @@ uniform sampler2D screen_texture; // texunit:-3
layout(std140) uniform CanvasItemData {
highp mat4 projection_matrix;
- highp vec4 time;
+ highp float time;
};
@@ -180,9 +185,8 @@ uniform lowp sampler2D light_texture; // texunit:-1
in vec4 light_uv_interp;
-#if defined(NORMAL_USED)
in vec4 local_rot;
-#endif
+
#ifdef USE_SHADOWS
@@ -191,6 +195,9 @@ in highp vec2 pos;
#endif
+const bool at_light_pass = true;
+#else
+const bool at_light_pass = false;
#endif
uniform mediump vec4 final_modulate;
@@ -211,11 +218,39 @@ MATERIAL_UNIFORMS
#endif
+
+void light_compute(inout vec3 light,vec3 light_vec,float light_height,vec4 light_color,vec2 light_uv,vec4 shadow,vec3 normal,vec2 uv,vec2 screen_uv,vec4 color) {
+
+#if defined(USE_LIGHT_SHADER_CODE)
+
+LIGHT_SHADER_CODE
+
+#endif
+
+}
+
+#ifdef USE_TEXTURE_RECT
+
+uniform vec4 dst_rect;
+uniform vec4 src_rect;
+uniform bool clip_rect_uv;
+
+#endif
+
+uniform bool use_default_normal;
+
void main() {
vec4 color = color_interp;
-#if defined(NORMAL_USED)
- vec3 normal = vec3(0.0,0.0,1.0);
+ vec2 uv = uv_interp;
+
+#ifdef USE_TEXTURE_RECT
+ if (clip_rect_uv) {
+
+ vec2 half_texpixel = color_texpixel_size * 0.5;
+ uv = clamp(uv,src_rect.xy+half_texpixel,src_rect.xy+abs(src_rect.zw)-color_texpixel_size);
+ }
+
#endif
#if !defined(COLOR_USED)
@@ -223,15 +258,34 @@ void main() {
#ifdef USE_DISTANCE_FIELD
const float smoothing = 1.0/32.0;
- float distance = texture(color_texture, uv_interp).a;
+ float distance = textureLod(color_texture, uv,0.0).a;
color.a = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance) * color.a;
#else
- color *= texture( color_texture, uv_interp );
+ color *= texture( color_texture, uv );
#endif
#endif
+ vec3 normal;
+
+#if defined(NORMAL_USED)
+
+ bool normal_used = true;
+#else
+ bool normal_used = false;
+#endif
+
+ if (use_default_normal) {
+ normal.xy = textureLod(normal_texture, uv,0.0).xy * 2.0 - 1.0;
+ normal.z = sqrt(1.0-dot(normal.xy,normal.xy));
+ normal_used=true;
+ } else {
+ normal = vec3(0.0,0.0,1.0);
+ }
+
+
+
#if defined(ENABLE_SCREEN_UV)
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
#endif
@@ -266,9 +320,9 @@ FRAGMENT_SHADER_CODE
vec2 light_vec = light_uv_interp.zw;; //for shadow and normal mapping
-#if defined(NORMAL_USED)
- normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
-#endif
+ if (normal_used) {
+ normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
+ }
float att=1.0;
@@ -285,18 +339,15 @@ FRAGMENT_SHADER_CODE
#if defined(USE_LIGHT_SHADER_CODE)
//light is written by the light shader
- {
- vec4 light_out=light*color;
-LIGHT_SHADER_CODE
- color=light_out;
- }
+ light_compute(light,light_vec,light_height,light_color,light_uv,shadow,normal,uv,screen_uv,color);
#else
-#if defined(NORMAL_USED)
- vec3 light_normal = normalize(vec3(light_vec,-light_height));
- light*=max(dot(-light_normal,normal),0.0);
-#endif
+ if (normal_used) {
+
+ vec3 light_normal = normalize(vec3(light_vec,-light_height));
+ light*=max(dot(-light_normal,normal),0.0);
+ }
color*=light;
/*
@@ -373,7 +424,7 @@ LIGHT_SHADER_CODE
#ifdef SHADOW_FILTER_NEAREST
- SHADOW_TEST(su+shadowpixel_size);
+ SHADOW_TEST(su);
#endif
diff --git a/drivers/gles3/shaders/copy.glsl b/drivers/gles3/shaders/copy.glsl
index a87d62f2d7..4c8648903e 100644
--- a/drivers/gles3/shaders/copy.glsl
+++ b/drivers/gles3/shaders/copy.glsl
@@ -2,14 +2,14 @@
layout(location=0) in highp vec4 vertex_attrib;
-#ifdef USE_CUBEMAP
+#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
layout(location=4) in vec3 cube_in;
#else
layout(location=4) in vec2 uv_in;
#endif
layout(location=5) in vec2 uv2_in;
-#ifdef USE_CUBEMAP
+#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
out vec3 cube_interp;
#else
out vec2 uv_interp;
@@ -19,10 +19,14 @@ out vec2 uv2_interp;
void main() {
-#ifdef USE_CUBEMAP
+#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
cube_interp = cube_in;
#else
uv_interp = uv_in;
+#ifdef V_FLIP
+ uv_interp.y = 1.0-uv_interp.y;
+#endif
+
#endif
uv2_interp = uv2_in;
gl_Position = vertex_attrib;
@@ -30,16 +34,46 @@ void main() {
[fragment]
+#define M_PI 3.14159265359
-#ifdef USE_CUBEMAP
+
+#if defined(USE_CUBEMAP) || defined(USE_PANORAMA)
in vec3 cube_interp;
-uniform samplerCube source_cube; //texunit:0
#else
in vec2 uv_interp;
+#endif
+
+#ifdef USE_CUBEMAP
+uniform samplerCube source_cube; //texunit:0
+#else
uniform sampler2D source; //texunit:0
#endif
+#ifdef USE_MULTIPLIER
+uniform float multiplier;
+#endif
+
+#ifdef USE_PANORAMA
+
+vec4 texturePanorama(vec3 normal,sampler2D pano ) {
+
+ vec2 st = vec2(
+ atan(normal.x, normal.z),
+ acos(normal.y)
+ );
+
+ if(st.x < 0.0)
+ st.x += M_PI*2.0;
+
+ st/=vec2(M_PI*2.0,M_PI);
+
+ return textureLod(pano,st,0.0);
+
+}
+
+#endif
+
float sRGB_gamma_correct(float c){
float a = 0.055;
if(c < 0.0031308)
@@ -54,19 +88,41 @@ uniform vec2 pixel_size;
in vec2 uv2_interp;
+
+#ifdef USE_BCS
+
+uniform vec3 bcs;
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+uniform sampler2D color_correction; //texunit:1
+
+#endif
+
layout(location = 0) out vec4 frag_color;
+
+
+
void main() {
//vec4 color = color_interp;
-#ifdef USE_CUBEMAP
+#ifdef USE_PANORAMA
+
+ vec4 color = texturePanorama( normalize(cube_interp), source );
+
+#elif defined(USE_CUBEMAP)
vec4 color = texture( source_cube, normalize(cube_interp) );
#else
vec4 color = texture( source, uv_interp );
#endif
+
+
#ifdef LINEAR_TO_SRGB
//regular Linear -> SRGB conversion
vec3 a = vec3(0.055);
@@ -99,7 +155,24 @@ void main() {
color+=texture( source, uv_interp+vec2( 0.0,-2.0)*pixel_size )*0.06136;
#endif
+#ifdef USE_BCS
+
+ color.rgb = mix(vec3(0.0),color.rgb,bcs.x);
+ color.rgb = mix(vec3(0.5),color.rgb,bcs.y);
+ color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z);
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+ color.r = texture(color_correction,vec2(color.r,0.0)).r;
+ color.g = texture(color_correction,vec2(color.g,0.0)).g;
+ color.b = texture(color_correction,vec2(color.b,0.0)).b;
+#endif
+
+#ifdef USE_MULTIPLIER
+ color.rgb*=multiplier;
+#endif
frag_color = color;
}
diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl
index 768d20ad22..2aec6380f5 100644
--- a/drivers/gles3/shaders/cubemap_filter.glsl
+++ b/drivers/gles3/shaders/cubemap_filter.glsl
@@ -19,8 +19,12 @@ void main() {
precision highp float;
precision highp int;
-
+#ifdef USE_PANORAMA
+uniform sampler2D source_panorama; //texunit:0
+#else
uniform samplerCube source_cube; //texunit:0
+#endif
+
uniform int face_id;
uniform float roughness;
in highp vec2 uv_interp;
@@ -165,6 +169,26 @@ vec2 Hammersley(uint i, uint N) {
uniform bool z_flip;
+#ifdef USE_PANORAMA
+
+vec4 texturePanorama(vec3 normal,sampler2D pano ) {
+
+ vec2 st = vec2(
+ atan(normal.x, normal.z),
+ acos(normal.y)
+ );
+
+ if(st.x < 0.0)
+ st.x += M_PI*2.0;
+
+ st/=vec2(M_PI*2.0,M_PI);
+
+ return textureLod(pano,st,0.0);
+
+}
+
+#endif
+
void main() {
#ifdef USE_DUAL_PARABOLOID
@@ -188,7 +212,12 @@ void main() {
#ifdef USE_DIRECT_WRITE
+#ifdef USE_PANORAMA
+
+ frag_color=vec4(texturePanorama(N,source_panorama).rgb,1.0);
+#else
frag_color=vec4(texture(N,source_cube).rgb,1.0);
+#endif
#else
@@ -204,7 +233,11 @@ void main() {
float ndotl = clamp(dot(N, L),0.0,1.0);
if (ndotl>0.0) {
+#ifdef USE_PANORAMA
+ sum.rgb += texturePanorama(H,source_panorama).rgb *ndotl;
+#else
sum.rgb += textureLod(source_cube, H, 0.0).rgb *ndotl;
+#endif
sum.a += ndotl;
}
}
diff --git a/drivers/gles3/shaders/particles.glsl b/drivers/gles3/shaders/particles.glsl
index fa12dd7408..7e7b083f73 100644
--- a/drivers/gles3/shaders/particles.glsl
+++ b/drivers/gles3/shaders/particles.glsl
@@ -28,7 +28,7 @@ uniform float prev_system_phase;
uniform int total_particles;
uniform float explosiveness;
uniform float randomness;
-uniform vec4 time;
+uniform float time;
uniform float delta;
uniform int attractor_count;
@@ -132,6 +132,7 @@ void main() {
}
uint particle_number = current_cycle * uint(total_particles) + uint(gl_VertexID);
+ int index = int(gl_VertexID);
if (restart) {
shader_active=emitting;
@@ -244,6 +245,10 @@ MATERIAL_UNIFORMS
void main() {
{
+LIGHT_SHADER_CODE
+ }
+
+ {
FRAGMENT_SHADER_CODE
}
}
diff --git a/drivers/gles3/shaders/resolve.glsl b/drivers/gles3/shaders/resolve.glsl
index 6acc712299..181a3c99ec 100644
--- a/drivers/gles3/shaders/resolve.glsl
+++ b/drivers/gles3/shaders/resolve.glsl
@@ -20,7 +20,7 @@ in vec2 uv_interp;
uniform sampler2D source_specular; //texunit:0
uniform sampler2D source_ssr; //texunit:1
-uniform float stuff;
+uniform vec2 pixel_size;
in vec2 uv2_interp;
diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl
index 43a391631f..a047e693cb 100644
--- a/drivers/gles3/shaders/scene.glsl
+++ b/drivers/gles3/shaders/scene.glsl
@@ -63,15 +63,18 @@ layout(std140) uniform SceneData { //ubo:0
highp mat4 projection_matrix;
highp mat4 camera_inverse_matrix;
highp mat4 camera_matrix;
- highp vec4 time;
highp vec4 ambient_light_color;
highp vec4 bg_color;
+
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
+
float ambient_energy;
float bg_energy;
- float shadow_z_offset;
- float shadow_z_slope_scale;
+ float z_offset;
+ float z_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
@@ -79,10 +82,22 @@ layout(std140) uniform SceneData { //ubo:0
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float time;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
};
uniform highp mat4 world_transform;
@@ -153,7 +168,7 @@ out highp float dp_clip;
#define SKELETON_TEXTURE_WIDTH 256
#ifdef USE_SKELETON
-uniform highp sampler2D skeleton_texture; //texunit:-6
+uniform highp sampler2D skeleton_texture; //texunit:-1
#endif
out highp vec4 position_interp;
@@ -230,7 +245,7 @@ void main() {
normal = vec4(normal,0.0) * m;
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP) || defined(LIGHT_USE_ANISOTROPY)
- tangent.xyz = vec4(tangent.xyz,0.0) * mn;
+ tangent.xyz = vec4(tangent.xyz,0.0) * m;
#endif
}
#endif
@@ -304,7 +319,7 @@ VERTEX_SHADER_CODE
//for dual paraboloid shadow mapping, this is the fastest but least correct way, as it curves straight edges
- highp vec3 vtx = vertex_interp+normalize(vertex_interp)*shadow_z_offset;
+ highp vec3 vtx = vertex_interp+normalize(vertex_interp)*z_offset;
highp float distance = length(vtx);
vtx = normalize(vtx);
vtx.xy/=1.0-vtx.z;
@@ -317,8 +332,8 @@ VERTEX_SHADER_CODE
#else
- float z_ofs = shadow_z_offset;
- z_ofs += (1.0-abs(normal_interp.z))*shadow_z_slope_scale;
+ float z_ofs = z_offset;
+ z_ofs += (1.0-abs(normal_interp.z))*z_slope_scale;
vertex_interp.z-=z_ofs;
#endif //RENDER_DEPTH_DUAL_PARABOLOID
@@ -338,7 +353,22 @@ VERTEX_SHADER_CODE
[fragment]
+/* texture unit usage, N is max_texture_unity-N
+
+1-skeleton
+2-radiance
+3-reflection_atlas
+4-directional_shadow
+5-shadow_atlas
+6-decal_atlas
+7-screen
+8-depth
+9-probe1
+10-probe2
+
+*/
+uniform highp mat4 world_transform;
#define M_PI 3.14159265359
@@ -370,7 +400,6 @@ in vec3 normal_interp;
//used on forward mainly
uniform bool no_ambient_light;
-uniform sampler2D brdf_texture; //texunit:-1
#ifdef USE_RADIANCE_MAP
@@ -380,8 +409,6 @@ uniform sampler2D radiance_map; //texunit:-2
layout(std140) uniform Radiance { //ubo:2
mat4 radiance_inverse_xform;
- vec3 radiance_box_min;
- vec3 radiance_box_max;
float radiance_ambient_contribution;
};
@@ -410,17 +437,18 @@ layout(std140) uniform SceneData {
highp mat4 projection_matrix;
highp mat4 camera_inverse_matrix;
highp mat4 camera_matrix;
- highp vec4 time;
highp vec4 ambient_light_color;
highp vec4 bg_color;
+ vec4 fog_color_enabled;
+ vec4 fog_sun_color_amount;
float ambient_energy;
float bg_energy;
- float shadow_z_offset;
- float shadow_z_slope_scale;
+ float z_offset;
+ float z_slope_scale;
float shadow_dual_paraboloid_render_zfar;
float shadow_dual_paraboloid_render_side;
@@ -428,10 +456,21 @@ layout(std140) uniform SceneData {
vec2 shadow_atlas_pixel_size;
vec2 directional_shadow_pixel_size;
+ float time;
+ float z_far;
float reflection_multiplier;
float subsurface_scatter_width;
float ambient_occlusion_affect_light;
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
};
//directional light data
@@ -484,7 +523,7 @@ layout(std140) uniform SpotLightData { //ubo:5
};
-uniform highp sampler2DShadow shadow_atlas; //texunit:-3
+uniform highp sampler2DShadow shadow_atlas; //texunit:-5
struct ReflectionData {
@@ -502,7 +541,7 @@ layout(std140) uniform ReflectionProbeData { //ubo:6
ReflectionData reflections[MAX_REFLECTION_DATA_STRUCTS];
};
-uniform mediump sampler2D reflection_atlas; //texunit:-5
+uniform mediump sampler2D reflection_atlas; //texunit:-3
#ifdef USE_FORWARD_LIGHTING
@@ -519,14 +558,19 @@ uniform int reflection_count;
#endif
+#if defined(SCREEN_TEXTURE_USED)
+
+uniform highp sampler2D screen_texture; //texunit:-7
+
+#endif
#ifdef USE_MULTIPLE_RENDER_TARGETS
layout(location=0) out vec4 diffuse_buffer;
layout(location=1) out vec4 specular_buffer;
layout(location=2) out vec4 normal_mr_buffer;
-#if defined (ENABLE_SSS_MOTION)
-layout(location=3) out vec4 motion_ssr_buffer;
+#if defined(ENABLE_SSS)
+layout(location=3) out float sss_buffer;
#endif
#else
@@ -536,7 +580,7 @@ layout(location=0) out vec4 frag_color;
#endif
in highp vec4 position_interp;
-uniform highp sampler2D depth_buffer; //texunit:-9
+uniform highp sampler2D depth_buffer; //texunit:-8
float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
@@ -598,7 +642,6 @@ float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
return 1.0;
}
-
// GGX Specular
// Source: http://www.filmicworlds.com/images/ggx-opt/optimized-ggx.hlsl
float G1V(float dotNV, float k)
@@ -624,17 +667,68 @@ 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 specular_color, 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 diffuse_color, 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
+
+
+LIGHT_SHADER_CODE
+
+
+#else
float dotNL = max(dot(N,L), 0.0 );
- float dotNV = max(dot(N,V), 0.0 );
+#if defined(DIFFUSE_HALF_LAMBERT)
+
+ float hl = dot(N,L) * 0.5 + 0.5;
+ diffuse += hl * light_color * diffuse_color;
+
+#elif defined(DIFFUSE_OREN_NAYAR)
+
+ {
+ float LdotV = dot(L, V);
+ float NdotL = dot(L, N);
+ float NdotV = dot(N, V);
+
+ float s = LdotV - NdotL * NdotV;
+ float t = mix(1.0, max(NdotL, NdotV), step(0.0, s));
+
+ float sigma2 = roughness * roughness;
+ vec3 A = 1.0 + sigma2 * (diffuse_color / (sigma2 + 0.13) + 0.5 / (sigma2 + 0.33));
+ float B = 0.45 * sigma2 / (sigma2 + 0.09);
+
+ diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI;
+ }
+
+#elif defined(DIFFUSE_BURLEY)
+
+ {
+ float NdotL = dot(L, N);
+ float NdotV = dot(N, V);
+ float VdotH = dot(N, normalize(L+V));
+ 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 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);
+
+ diffuse+= light_color * diffuse_color * lightScatter * viewScatter * energyFactor;
+ }
+#else
+ //lambert
+ diffuse += dotNL * light_color * diffuse_color;
+#endif
+
+
+ float dotNV = max(dot(N,V), 0.0 );
#if defined(LIGHT_USE_RIM)
float rim_light = pow(1.0-dotNV,(1.0-roughness)*16.0);
diffuse += rim_light * rim * mix(vec3(1.0),diffuse_color,rim_tint) * light_color;
#endif
- diffuse += dotNL * light_color * diffuse_color;
if (roughness > 0.0) {
@@ -676,7 +770,7 @@ void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 di
float speci = dotNL * D * F * vis;
- specular += speci * light_color /* specular_color*/ * specular_blob_intensity;
+ specular += speci * light_color * specular_blob_intensity;
#if defined(LIGHT_USE_CLEARCOAT)
float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss));
@@ -688,6 +782,7 @@ void light_compute(vec3 N, vec3 L,vec3 V,vec3 B, vec3 T,vec3 light_color,vec3 di
}
+#endif //defined(USE_LIGHT_SHADER_CODE)
}
@@ -735,6 +830,8 @@ in highp float dp_clip;
#endif
+
+
#if 0
//need to save texture depth for this
@@ -764,7 +861,7 @@ vec3 light_transmittance(float translucency,vec3 light_vec, vec3 normal, vec3 po
}
#endif
-void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, vec3 specular, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_omni(int idx, vec3 vertex, vec3 eye_vec,vec3 normal,vec3 binormal, vec3 tangent, vec3 albedo, float roughness, float rim, float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy,inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = omni_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -815,11 +912,11 @@ 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,specular,omni_lights[idx].light_params.z,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,omni_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
-void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, vec3 specular, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
+void light_process_spot(int idx, vec3 vertex, vec3 eye_vec, vec3 normal, vec3 binormal, vec3 tangent,vec3 albedo, float roughness, float rim,float rim_tint, float clearcoat, float clearcoat_gloss,float anisotropy, inout vec3 diffuse_light, inout vec3 specular_light) {
vec3 light_rel_vec = spot_lights[idx].light_pos_inv_radius.xyz-vertex;
float light_length = length( light_rel_vec );
@@ -848,11 +945,11 @@ 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,specular,spot_lights[idx].light_params.z,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,spot_lights[idx].light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
-void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox,vec2 brdf, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) {
+void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 tangent,float roughness,float anisotropy,vec3 ambient,vec3 skybox, inout highp vec4 reflection_accum,inout highp vec4 ambient_accum) {
vec3 ref_vec = normalize(reflect(vertex,normal));
vec3 local_pos = (reflections[idx].local_matrix * vec4(vertex,1.0)).xyz;
@@ -908,7 +1005,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
splane.xy = clamp(splane.xy,clamp_rect.xy,clamp_rect.xy+clamp_rect.zw);
highp vec4 reflection;
- reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb * brdf.x + brdf.y;
+ reflection.rgb = textureLod(reflection_atlas,splane.xy,roughness*5.0).rgb;
if (reflections[idx].params.z < 0.5) {
reflection.rgb = mix(skybox,reflection.rgb,blend);
@@ -969,7 +1066,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
#ifdef USE_GI_PROBES
-uniform mediump sampler3D gi_probe1; //texunit:-11
+uniform mediump sampler3D gi_probe1; //texunit:-9
uniform highp mat4 gi_probe_xform1;
uniform highp vec3 gi_probe_bounds1;
uniform highp vec3 gi_probe_cell_size1;
@@ -1089,7 +1186,7 @@ void gi_probe_compute(sampler3D probe, mat4 probe_xform, vec3 bounds,vec3 cell_s
}
-void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, inout vec3 out_specular, inout vec3 out_ambient) {
+void gi_probes_compute(vec3 pos, vec3 normal, float roughness, inout vec3 out_specular, inout vec3 out_ambient) {
roughness = roughness * roughness;
@@ -1133,6 +1230,23 @@ void gi_probes_compute(vec3 pos, vec3 normal, float roughness, vec3 specular, in
#endif
+vec3 textureDualParabolod(sampler2D p_tex, vec3 p_vec,float p_lod) {
+
+ vec3 norm = normalize(p_vec);
+ float y_ofs=0.0;
+ if (norm.z>=0.0) {
+
+ norm.z+=1.0;
+ y_ofs+=0.5;
+ } else {
+ norm.z=1.0 - norm.z;
+ norm.y=-norm.y;
+ }
+
+ norm.xy/=norm.z;
+ norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs);
+ return textureLod(p_tex, norm.xy, p_lod).xyz;
+}
void main() {
@@ -1145,7 +1259,8 @@ void main() {
//lay out everything, whathever is unused is optimized away anyway
highp vec3 vertex = vertex_interp;
vec3 albedo = vec3(0.8,0.8,0.8);
- vec3 specular = vec3(0.2,0.2,0.2);
+ float metallic = 0.0;
+ float specular = 0.5;
vec3 emission = vec3(0.0,0.0,0.0);
float roughness = 1.0;
float rim = 0.0;
@@ -1196,13 +1311,15 @@ void main() {
float normaldepth=1.0;
-
+#if defined(SCREEN_UV_USED)
+ vec2 screen_uv = gl_FragCoord.xy*screen_pixel_size;
+#endif
#if defined(ENABLE_DISCARD)
bool discard_=false;
#endif
-#if defined (ENABLE_SSS_MOTION)
+#if defined (ENABLE_SSS)
float sss_strength=0.0;
#endif
@@ -1260,11 +1377,7 @@ FRAGMENT_SHADER_CODE
vec3 eye_vec = -normalize( vertex_interp );
-#ifndef RENDER_DEPTH
- float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
- vec2 brdf = texture(brdf_texture, vec2(roughness, ndotv)).xy;
-#endif
#ifdef USE_RADIANCE_MAP
@@ -1274,28 +1387,15 @@ FRAGMENT_SHADER_CODE
{
-
- float lod = roughness * 5.0;
+#define RADIANCE_MAX_LOD 5.0
+ float lod = roughness * RADIANCE_MAX_LOD;
{ //read radiance from dual paraboloid
vec3 ref_vec = reflect(-eye_vec,normal); //2.0 * ndotv * normal - view; // reflect(v, n);
ref_vec=normalize((radiance_inverse_xform * vec4(ref_vec,0.0)).xyz);
-
- vec3 norm = normalize(ref_vec);
- float y_ofs=0.0;
- if (norm.z>=0.0) {
-
- norm.z+=1.0;
- y_ofs+=0.5;
- } else {
- norm.z=1.0 - norm.z;
- norm.y=-norm.y;
- }
-
- norm.xy/=norm.z;
- norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25+y_ofs);
- specular_light = textureLod(radiance_map, norm.xy, lod).xyz * brdf.x + brdf.y;
+ vec3 radiance = textureDualParabolod(radiance_map,ref_vec,lod) * bg_energy;
+ specular_light = radiance;
}
//no longer a cubemap
@@ -1305,11 +1405,11 @@ FRAGMENT_SHADER_CODE
{
- /*vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
- vec3 env_ambient=textureLod(radiance_cube, ambient_dir, 5.0).xyz;
+ vec3 ambient_dir=normalize((radiance_inverse_xform * vec4(normal,0.0)).xyz);
+ vec3 env_ambient=textureDualParabolod(radiance_map,ambient_dir,RADIANCE_MAX_LOD) * bg_energy;
- ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);*/
- ambient_light=vec3(0.0,0.0,0.0);
+ ambient_light=mix(ambient_light_color.rgb,env_ambient,radiance_ambient_contribution);
+ //ambient_light=vec3(0.0,0.0,0.0);
}
}
@@ -1322,6 +1422,7 @@ FRAGMENT_SHADER_CODE
}
#endif
+ ambient_light*=ambient_energy;
#ifdef USE_LIGHT_DIRECTIONAL
@@ -1444,7 +1545,7 @@ FRAGMENT_SHADER_CODE
#if defined(LIGHT_USE_PSSM_BLEND)
if (use_blend) {
- shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp));
+ shadow=mix(shadow, sample_shadow(directional_shadow,directional_shadow_pixel_size,pssm_coord2.xy,pssm_coord2.z,light_clamp),pssm_blend);
}
#endif
@@ -1462,13 +1563,14 @@ FRAGMENT_SHADER_CODE
#endif //LIGHT_DIRECTIONAL_SHADOW
- light_compute(normal,-light_direction_attenuation.xyz,eye_vec,binormal,tangent,light_color_energy.rgb*light_attenuation,albedo,specular,light_params.z,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,light_params.z,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
#endif //#USE_LIGHT_DIRECTIONAL
#ifdef USE_GI_PROBES
- gi_probes_compute(vertex,normal,roughness,specular,specular_light,ambient_light);
+ gi_probes_compute(vertex,normal,roughness,specular_light,ambient_light);
+
#endif
@@ -1480,7 +1582,7 @@ FRAGMENT_SHADER_CODE
for(int i=0;i<reflection_count;i++) {
- reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,brdf,reflection_accum,ambient_accum);
+ reflection_process(reflection_indices[i],vertex,normal,binormal,tangent,roughness,anisotropy,ambient_light,specular_light,reflection_accum,ambient_accum);
}
if (reflection_accum.a>0.0) {
@@ -1491,11 +1593,11 @@ FRAGMENT_SHADER_CODE
}
for(int i=0;i<omni_light_count;i++) {
- light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_process_omni(omni_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
for(int i=0;i<spot_light_count;i++) {
- light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,specular,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
+ light_process_spot(spot_light_indices[i],vertex,eye_vec,normal,binormal,tangent,albedo,roughness,rim,rim_tint,clearcoat,clearcoat_gloss,anisotropy,diffuse_light,specular_light);
}
@@ -1505,14 +1607,7 @@ FRAGMENT_SHADER_CODE
-#if defined(USE_LIGHT_SHADER_CODE)
-//light is written by the light shader
-{
-
-LIGHT_SHADER_CODE
-}
-#endif
#ifdef RENDER_DEPTH
//nothing happens, so a tree-ssa optimizer will result in no fragment shader :)
@@ -1525,10 +1620,72 @@ LIGHT_SHADER_CODE
ambient_light*=ao;
#endif
- //energy conservation
- diffuse_light=mix(diffuse_light,vec3(0.0),specular);
- ambient_light=mix(ambient_light,vec3(0.0),specular);
- specular_light *= max(vec3(0.04),specular);
+
+
+
+
+
+ //energu conservation
+ diffuse_light=mix(diffuse_light,vec3(0.0),metallic);
+ ambient_light=mix(ambient_light,vec3(0.0),metallic);
+ {
+ //brdf approximation (Lazarov 2013)
+ float ndotv = clamp(dot(normal,eye_vec),0.0,1.0);
+
+ //energy conservation
+ vec3 dielectric = vec3(0.034) * 0.5 * 2.0;
+ vec3 f0 = mix(dielectric, albedo, metallic);
+ const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
+ const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04);
+ vec4 r = roughness * c0 + c1;
+ float a004 = min( r.x * r.x, exp2( -9.28 * ndotv ) ) * r.x + r.y;
+ vec2 brdf = vec2( -1.04, 1.04 ) * a004 + r.zw;
+
+ specular_light *= min(1.0,50.0 * f0.g) * brdf.y + brdf.x * f0;
+ }
+
+ if (fog_color_enabled.a > 0.5) {
+
+ float fog_amount=0;
+
+
+
+#ifdef USE_LIGHT_DIRECTIONAL
+
+ vec3 fog_color = mix( fog_color_enabled.rgb, fog_sun_color_amount.rgb,fog_sun_color_amount.a * pow(max( dot(normalize(vertex),-light_direction_attenuation.xyz), 0.0),8.0) );
+#else
+
+ vec3 fog_color = fog_color_enabled.rgb;
+#endif
+
+ //apply fog
+
+ if (fog_depth_enabled) {
+
+ float fog_z = smoothstep(fog_depth_begin,z_far,-vertex.z);
+
+ fog_amount = pow(fog_z,fog_depth_curve);
+ if (fog_transmit_enabled) {
+ vec3 total_light = emission + ambient_light + specular_light + diffuse_light;
+ float transmit = pow(fog_z,fog_transmit_curve);
+ fog_color = mix(max(total_light,fog_color),fog_color,transmit);
+ }
+ }
+
+ if (fog_height_enabled) {
+ float y = (camera_matrix * vec4(vertex,1.0)).y;
+ fog_amount = max(fog_amount,pow(1.0-smoothstep(fog_height_min,fog_height_max,y),fog_height_curve));
+ }
+
+ float rev_amount = 1.0 - fog_amount;
+
+
+ emission = emission * rev_amount + fog_color * fog_amount;
+ ambient_light*=rev_amount;
+ specular_light*rev_amount;
+ diffuse_light*=rev_amount;
+
+ }
#ifdef USE_MULTIPLE_RENDER_TARGETS
@@ -1545,16 +1702,16 @@ LIGHT_SHADER_CODE
#endif //ENABLE_AO
diffuse_buffer=vec4(emission+diffuse_light+ambient_light,ambient_scale);
- specular_buffer=vec4(specular_light,max(specular.r,max(specular.g,specular.b)));
+ specular_buffer=vec4(specular_light,metallic);
normal_mr_buffer=vec4(normalize(normal)*0.5+0.5,roughness);
-#if defined (ENABLE_SSS_MOTION)
- motion_ssr_buffer = vec4(vec3(0.0),sss_strength);
+#if defined (ENABLE_SSS)
+ sss_buffer = sss_strength;
#endif
-#else
+#else //USE_MULTIPLE_RENDER_TARGETS
#ifdef SHADELESS
diff --git a/drivers/gles3/shaders/screen_space_reflection.glsl b/drivers/gles3/shaders/screen_space_reflection.glsl
index 8eec71ecb6..cc41d36c37 100644
--- a/drivers/gles3/shaders/screen_space_reflection.glsl
+++ b/drivers/gles3/shaders/screen_space_reflection.glsl
@@ -38,7 +38,8 @@ uniform mat4 projection;
uniform int num_steps;
uniform float depth_tolerance;
uniform float distance_fade;
-uniform float acceleration;
+uniform float curve_fade_in;
+
layout(location = 0) out vec4 frag_color;
@@ -148,8 +149,6 @@ void main() {
bool found=false;
- //if acceleration > 0, distance between pixels gets larger each step. This allows covering a larger area
- float accel=1.0+acceleration;
float steps_taken=0.0;
for(int i=0;i<num_steps;i++) {
@@ -177,9 +176,6 @@ void main() {
steps_taken+=1.0;
prev_pos=pos;
- z_advance*=accel;
- w_advance*=accel;
- line_advance*=accel;
}
@@ -207,41 +203,14 @@ void main() {
vec2 final_pos;
float grad;
+ grad=steps_taken/float(num_steps);
+ float initial_fade = curve_fade_in==0.0 ? 1.0 : pow(clamp(grad,0.0,1.0),curve_fade_in);
+ float fade = pow(clamp(1.0-grad,0.0,1.0),distance_fade)*initial_fade;
+ final_pos=pos;
-#ifdef SMOOTH_ACCEL
- //if the distance between point and prev point is >1, then take some samples in the middle for smoothing out the image
- vec2 blend_dir = pos - prev_pos;
- float steps = min(8.0,length(blend_dir));
- if (steps>2.0) {
- vec2 blend_step = blend_dir/steps;
- float blend_z = (z_to-z_from)/steps;
- vec2 new_pos;
- float subgrad=0.0;
- for(float i=0.0;i<steps;i++) {
-
- new_pos = (prev_pos+blend_step*i);
- float z = z_from+blend_z*i;
-
- depth = texture(source_depth, new_pos*pixel_size).r * 2.0 - 1.0;
- depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
- depth=-depth;
-
- subgrad=i/steps;
- if (depth>z)
- break;
- }
- final_pos = new_pos;
- grad=(steps_taken+subgrad)/float(num_steps);
- } else {
-#endif
- grad=steps_taken/float(num_steps);
- final_pos=pos;
-#ifdef SMOOTH_ACCEL
- }
-#endif
@@ -327,10 +296,10 @@ void main() {
final_color = textureLod(source_diffuse,final_pos*pixel_size,0.0);
}
- frag_color = vec4(final_color.rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
+ frag_color = vec4(final_color.rgb,fade*margin_blend);
#else
- frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,pow(clamp(1.0-grad,0.0,1.0),distance_fade)*margin_blend);
+ frag_color = vec4(textureLod(source_diffuse,final_pos*pixel_size,0.0).rgb,fade*margin_blend);
#endif
diff --git a/drivers/gles3/shaders/ssao.glsl b/drivers/gles3/shaders/ssao.glsl
index ba29ec52c7..d8302bd46e 100644
--- a/drivers/gles3/shaders/ssao.glsl
+++ b/drivers/gles3/shaders/ssao.glsl
@@ -12,7 +12,7 @@ void main() {
[fragment]
-#define NUM_SAMPLES (11)
+#define NUM_SAMPLES (15)
// If using depth mip levels, the log of the maximum pixel offset before we need to switch to a lower
// miplevel to maintain reasonable spatial locality in the cache
@@ -25,8 +25,20 @@ void main() {
// This is the number of turns around the circle that the spiral pattern makes. This should be prime to prevent
// taps from lining up. This particular choice was tuned for NUM_SAMPLES == 9
-#define NUM_SPIRAL_TURNS (7)
+const int ROTATIONS[] = int[]( 1, 1, 2, 3, 2, 5, 2, 3, 2,
+3, 3, 5, 5, 3, 4, 7, 5, 5, 7,
+9, 8, 5, 5, 7, 7, 7, 8, 5, 8,
+11, 12, 7, 10, 13, 8, 11, 8, 7, 14,
+11, 11, 13, 12, 13, 19, 17, 13, 11, 18,
+19, 11, 11, 14, 17, 21, 15, 16, 17, 18,
+13, 17, 11, 17, 19, 18, 25, 18, 19, 19,
+29, 21, 19, 27, 31, 29, 21, 18, 17, 29,
+31, 31, 23, 18, 25, 26, 25, 23, 19, 34,
+19, 27, 21, 25, 39, 29, 17, 21, 27 );
+
+//#define NUM_SPIRAL_TURNS (7)
+const int NUM_SPIRAL_TURNS = ROTATIONS[NUM_SAMPLES-1];
uniform sampler2D source_depth; //texunit:0
uniform highp usampler2D source_depth_mipmaps; //texunit:1
diff --git a/drivers/gles3/shaders/ssao_blur.glsl b/drivers/gles3/shaders/ssao_blur.glsl
index ff852487c0..ce4154f50c 100644
--- a/drivers/gles3/shaders/ssao_blur.glsl
+++ b/drivers/gles3/shaders/ssao_blur.glsl
@@ -24,7 +24,7 @@ layout(location = 0) out float visibility;
// Tunable Parameters:
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
-#define EDGE_SHARPNESS (1.0)
+#define EDGE_SHARPNESS (4.0)
/** Step in 2-pixel intervals since we already blurred against neighbors in the
first AO pass. This constant can be increased while R decreases to improve
diff --git a/drivers/gles3/shaders/subsurf_scattering.glsl b/drivers/gles3/shaders/subsurf_scattering.glsl
index eb329dbaed..569be6c5fe 100644
--- a/drivers/gles3/shaders/subsurf_scattering.glsl
+++ b/drivers/gles3/shaders/subsurf_scattering.glsl
@@ -107,14 +107,14 @@ uniform vec2 dir;
in vec2 uv_interp;
uniform sampler2D source_diffuse; //texunit:0
-uniform sampler2D source_motion_ss; //texunit:1
+uniform sampler2D source_sss; //texunit:1
uniform sampler2D source_depth; //texunit:2
layout(location = 0) out vec4 frag_color;
void main() {
- float strength = texture(source_motion_ss,uv_interp).a;
+ float strength = texture(source_sss,uv_interp).r;
strength*=strength; //stored as sqrt
// Fetch color of current pixel:
diff --git a/drivers/gles3/shaders/tonemap.glsl b/drivers/gles3/shaders/tonemap.glsl
index 8f7e0c7be3..3ce2edf4e9 100644
--- a/drivers/gles3/shaders/tonemap.glsl
+++ b/drivers/gles3/shaders/tonemap.glsl
@@ -6,12 +6,13 @@ layout(location=4) in vec2 uv_in;
out vec2 uv_interp;
-
-
void main() {
gl_Position = vertex_attrib;
uv_interp = uv_in;
+#ifdef V_FLIP
+ uv_interp.y = 1.0-uv_interp.y;
+#endif
}
@@ -39,6 +40,19 @@ uniform highp float glow_intensity;
#endif
+#ifdef USE_BCS
+
+uniform vec3 bcs;
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+uniform sampler2D color_correction; //texunit:3
+
+#endif
+
+
layout(location = 0) out vec4 frag_color;
#ifdef USE_GLOW_FILTER_BICUBIC
@@ -255,6 +269,20 @@ void main() {
color.rgb = mix( (vec3(1.0)+a)*pow(color.rgb,vec3(1.0/2.4))-a , 12.92*color.rgb , lessThan(color.rgb,vec3(0.0031308)));
+#ifdef USE_BCS
+
+ color.rgb = mix(vec3(0.0),color.rgb,bcs.x);
+ color.rgb = mix(vec3(0.5),color.rgb,bcs.y);
+ color.rgb = mix(vec3(dot(vec3(1.0),color.rgb)*0.33333),color.rgb,bcs.z);
+
+#endif
+
+#ifdef USE_COLOR_CORRECTION
+
+ color.r = texture(color_correction,vec2(color.r,0.0)).r;
+ color.g = texture(color_correction,vec2(color.g,0.0)).g;
+ color.b = texture(color_correction,vec2(color.b,0.0)).b;
+#endif
frag_color=vec4(color.rgb,1.0);
diff --git a/drivers/png/image_loader_png.cpp b/drivers/png/image_loader_png.cpp
index c9677bed11..33d271248c 100644
--- a/drivers/png/image_loader_png.cpp
+++ b/drivers/png/image_loader_png.cpp
@@ -68,7 +68,7 @@ static void _png_warn_function(png_structp, png_const_charp text) {
typedef void(PNGAPI *png_error_ptr) PNGARG((png_structp, png_const_charp));
-Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Image *p_image) {
+Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image) {
png_structp png;
png_infop info;
@@ -201,7 +201,7 @@ Error ImageLoaderPNG::_load_image(void *rf_up, png_rw_ptr p_func, Image *p_image
return OK;
}
-Error ImageLoaderPNG::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderPNG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
Error err = _load_image(f, _read_png_data, p_image);
f->close();
@@ -238,25 +238,27 @@ static void user_read_data(png_structp png_ptr, png_bytep data, png_size_t p_len
}
}
-static Image _load_mem_png(const uint8_t *p_png, int p_size) {
+static Ref<Image> _load_mem_png(const uint8_t *p_png, int p_size) {
PNGReadStatus prs;
prs.image = p_png;
prs.offset = 0;
prs.size = p_size;
- Image img;
- Error err = ImageLoaderPNG::_load_image(&prs, user_read_data, &img);
- ERR_FAIL_COND_V(err, Image());
+ Ref<Image> img;
+ img.instance();
+ Error err = ImageLoaderPNG::_load_image(&prs, user_read_data, img);
+ ERR_FAIL_COND_V(err, Ref<Image>());
return img;
}
-static Image _lossless_unpack_png(const PoolVector<uint8_t> &p_data) {
+static Ref<Image> _lossless_unpack_png(const PoolVector<uint8_t> &p_data) {
int len = p_data.size();
+ ERR_FAIL_COND_V(len < 4, Ref<Image>());
PoolVector<uint8_t>::Read r = p_data.read();
- ERR_FAIL_COND_V(r[0] != 'P' || r[1] != 'N' || r[2] != 'G' || r[3] != ' ', Image());
+ ERR_FAIL_COND_V(r[0] != 'P' || r[1] != 'N' || r[2] != 'G' || r[3] != ' ', Ref<Image>());
return _load_mem_png(&r[4], len - 4);
}
@@ -271,13 +273,14 @@ static void _write_png_data(png_structp png_ptr, png_bytep data, png_size_t p_le
//print_line("png write: "+itos(p_length));
}
-static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
+static PoolVector<uint8_t> _lossless_pack_png(const Ref<Image> &p_image) {
- Image img = p_image;
- if (img.is_compressed())
- img.decompress();
+ Ref<Image> img = p_image->duplicate();
- ERR_FAIL_COND_V(img.is_compressed(), PoolVector<uint8_t>());
+ if (img->is_compressed())
+ img->decompress();
+
+ ERR_FAIL_COND_V(img->is_compressed(), PoolVector<uint8_t>());
png_structp png_ptr;
png_infop info_ptr;
@@ -311,7 +314,7 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
int pngf = 0;
int cs = 0;
- switch (img.get_format()) {
+ switch (img->get_format()) {
case Image::FORMAT_L8: {
@@ -335,22 +338,22 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
} break;
default: {
- if (img.detect_alpha()) {
+ if (img->detect_alpha()) {
- img.convert(Image::FORMAT_RGBA8);
+ img->convert(Image::FORMAT_RGBA8);
pngf = PNG_COLOR_TYPE_RGB_ALPHA;
cs = 4;
} else {
- img.convert(Image::FORMAT_RGB8);
+ img->convert(Image::FORMAT_RGB8);
pngf = PNG_COLOR_TYPE_RGB;
cs = 3;
}
}
}
- int w = img.get_width();
- int h = img.get_height();
+ int w = img->get_width();
+ int h = img->get_height();
png_set_IHDR(png_ptr, info_ptr, w, h,
8, pngf, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
@@ -362,7 +365,7 @@ static PoolVector<uint8_t> _lossless_pack_png(const Image &p_image) {
ERR_FAIL_V(PoolVector<uint8_t>());
}
- PoolVector<uint8_t>::Read r = img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
row_pointers = (png_bytep *)memalloc(sizeof(png_bytep) * h);
for (int i = 0; i < h; i++) {
diff --git a/drivers/png/image_loader_png.h b/drivers/png/image_loader_png.h
index 78e4252e26..f0a525a9eb 100644
--- a/drivers/png/image_loader_png.h
+++ b/drivers/png/image_loader_png.h
@@ -42,8 +42,8 @@ class ImageLoaderPNG : public ImageFormatLoader {
static void _read_png_data(png_structp png_ptr, png_bytep data, png_size_t p_length);
public:
- static Error _load_image(void *rf_up, png_rw_ptr p_func, Image *p_image);
- virtual Error load_image(Image *p_image, FileAccess *f);
+ static Error _load_image(void *rf_up, png_rw_ptr p_func, Ref<Image> p_image);
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderPNG();
};
diff --git a/drivers/png/resource_saver_png.cpp b/drivers/png/resource_saver_png.cpp
index b754ef97b4..0d7e1d9d72 100644
--- a/drivers/png/resource_saver_png.cpp
+++ b/drivers/png/resource_saver_png.cpp
@@ -50,57 +50,24 @@ Error ResourceSaverPNG::save(const String &p_path, const RES &p_resource, uint32
ERR_EXPLAIN("Can't save empty texture as PNG");
ERR_FAIL_COND_V(!texture->get_width() || !texture->get_height(), ERR_INVALID_PARAMETER);
- Image img = texture->get_data();
+ Ref<Image> img = texture->get_data();
Error err = save_image(p_path, img);
if (err == OK) {
-
- bool global_filter = GlobalConfig::get_singleton()->get("image_loader/filter");
- bool global_mipmaps = GlobalConfig::get_singleton()->get("image_loader/gen_mipmaps");
- bool global_repeat = GlobalConfig::get_singleton()->get("image_loader/repeat");
-
- String text;
-
- if (global_filter != bool(texture->get_flags() & Texture::FLAG_FILTER)) {
- text += bool(texture->get_flags() & Texture::FLAG_FILTER) ? "filter=true\n" : "filter=false\n";
- }
- if (global_mipmaps != bool(texture->get_flags() & Texture::FLAG_MIPMAPS)) {
- text += bool(texture->get_flags() & Texture::FLAG_MIPMAPS) ? "gen_mipmaps=true\n" : "gen_mipmaps=false\n";
- }
- if (global_repeat != bool(texture->get_flags() & Texture::FLAG_REPEAT)) {
- text += bool(texture->get_flags() & Texture::FLAG_REPEAT) ? "repeat=true\n" : "repeat=false\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_ANISOTROPIC_FILTER)) {
- text += "anisotropic=true\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_CONVERT_TO_LINEAR)) {
- text += "tolinear=true\n";
- }
- if (bool(texture->get_flags() & Texture::FLAG_MIRRORED_REPEAT)) {
- text += "mirroredrepeat=true\n";
- }
-
- if (text != "" || FileAccess::exists(p_path + ".flags")) {
-
- FileAccess *f = FileAccess::open(p_path + ".flags", FileAccess::WRITE);
- if (f) {
-
- f->store_string(text);
- memdelete(f);
- }
- }
}
return err;
};
-Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
+Error ResourceSaverPNG::save_image(const String &p_path, const Ref<Image> &p_img) {
+
+ Ref<Image> img = p_img->duplicate();
- if (p_img.is_compressed())
- p_img.decompress();
+ if (img->is_compressed())
+ img->decompress();
- ERR_FAIL_COND_V(p_img.is_compressed(), ERR_INVALID_PARAMETER);
+ ERR_FAIL_COND_V(img->is_compressed(), ERR_INVALID_PARAMETER);
png_structp png_ptr;
png_infop info_ptr;
@@ -135,7 +102,7 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
int pngf = 0;
int cs = 0;
- switch (p_img.get_format()) {
+ switch (img->get_format()) {
case Image::FORMAT_L8: {
@@ -159,22 +126,22 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
} break;
default: {
- if (p_img.detect_alpha()) {
+ if (img->detect_alpha()) {
- p_img.convert(Image::FORMAT_RGBA8);
+ img->convert(Image::FORMAT_RGBA8);
pngf = PNG_COLOR_TYPE_RGB_ALPHA;
cs = 4;
} else {
- p_img.convert(Image::FORMAT_RGB8);
+ img->convert(Image::FORMAT_RGB8);
pngf = PNG_COLOR_TYPE_RGB;
cs = 3;
}
}
}
- int w = p_img.get_width();
- int h = p_img.get_height();
+ int w = img->get_width();
+ int h = img->get_height();
png_set_IHDR(png_ptr, info_ptr, w, h,
8, pngf, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
@@ -187,7 +154,7 @@ Error ResourceSaverPNG::save_image(const String &p_path, Image &p_img) {
ERR_FAIL_V(ERR_CANT_OPEN);
}
- PoolVector<uint8_t>::Read r = p_img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
row_pointers = (png_bytep *)memalloc(sizeof(png_bytep) * h);
for (int i = 0; i < h; i++) {
diff --git a/drivers/png/resource_saver_png.h b/drivers/png/resource_saver_png.h
index c25a01c1f6..31ec35c192 100644
--- a/drivers/png/resource_saver_png.h
+++ b/drivers/png/resource_saver_png.h
@@ -30,11 +30,12 @@
#ifndef RESOURCE_SAVER_PNG_H
#define RESOURCE_SAVER_PNG_H
+#include "image.h"
#include "io/resource_saver.h"
class ResourceSaverPNG : public ResourceFormatSaver {
public:
- static Error save_image(const String &p_path, Image &p_img);
+ static Error save_image(const String &p_path, const Ref<Image> &p_img);
virtual Error save(const String &p_path, const RES &p_resource, uint32_t p_flags = 0);
virtual bool recognize(const RES &p_resource) const;
diff --git a/drivers/unix/ip_unix.cpp b/drivers/unix/ip_unix.cpp
index 1becf3accb..30d2377a04 100644
--- a/drivers/unix/ip_unix.cpp
+++ b/drivers/unix/ip_unix.cpp
@@ -77,7 +77,7 @@ static IP_Address _sockaddr2ip(struct sockaddr *p_addr) {
if (p_addr->sa_family == AF_INET) {
struct sockaddr_in *addr = (struct sockaddr_in *)p_addr;
ip.set_ipv4((uint8_t *)&(addr->sin_addr));
- } else {
+ } else if (p_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)p_addr;
ip.set_ipv6(addr6->sin6_addr.s6_addr);
};
@@ -180,15 +180,16 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
SOCKADDR_IN *ipv4 = reinterpret_cast<SOCKADDR_IN *>(address->Address.lpSockaddr);
ip.set_ipv4((uint8_t *)&(ipv4->sin_addr));
- } else { // ipv6
+ r_addresses->push_back(ip);
+
+ } else if (address->Address.lpSockaddr->sa_family == AF_INET6) { // ipv6
SOCKADDR_IN6 *ipv6 = reinterpret_cast<SOCKADDR_IN6 *>(address->Address.lpSockaddr);
ip.set_ipv6(ipv6->sin6_addr.s6_addr);
+ r_addresses->push_back(ip);
};
- r_addresses->push_back(ip);
-
address = address->Next;
};
adapter = adapter->Next;
@@ -205,6 +206,7 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
struct ifaddrs *ifAddrStruct = NULL;
struct ifaddrs *ifa = NULL;
+ int family;
getifaddrs(&ifAddrStruct);
@@ -212,6 +214,11 @@ void IP_Unix::get_local_addresses(List<IP_Address> *r_addresses) const {
if (!ifa->ifa_addr)
continue;
+ family = ifa->ifa_addr->sa_family;
+
+ if (family != AF_INET && family != AF_INET6)
+ continue;
+
IP_Address ip = _sockaddr2ip(ifa->ifa_addr);
r_addresses->push_back(ip);
}
diff --git a/drivers/unix/packet_peer_udp_posix.cpp b/drivers/unix/packet_peer_udp_posix.cpp
index 5dbccd4b63..74ceb3946a 100644
--- a/drivers/unix/packet_peer_udp_posix.cpp
+++ b/drivers/unix/packet_peer_udp_posix.cpp
@@ -216,6 +216,8 @@ Error PacketPeerUDPPosix::_poll(bool p_wait) {
len = sizeof(struct sockaddr_storage);
++queue_count;
+ if (p_wait)
+ break;
};
// TODO: Should ECONNRESET be handled here?
diff --git a/drivers/unix/socket_helpers.h b/drivers/unix/socket_helpers.h
index 8e54afcdba..5fa727a9b9 100644
--- a/drivers/unix/socket_helpers.h
+++ b/drivers/unix/socket_helpers.h
@@ -100,13 +100,21 @@ static size_t _set_listen_sockaddr(struct sockaddr_storage *p_addr, int p_port,
};
};
-static int _socket_create(IP::Type p_type, int type, int protocol) {
+static int _socket_create(IP::Type &p_type, int type, int protocol) {
ERR_FAIL_COND_V(p_type > IP::TYPE_ANY || p_type < IP::TYPE_NONE, ERR_INVALID_PARAMETER);
int family = p_type == IP::TYPE_IPV4 ? AF_INET : AF_INET6;
int sockfd = socket(family, type, protocol);
+ if (sockfd == -1 && p_type == IP::TYPE_ANY) {
+ // Careful here, changing the referenced parameter so the caller knows that we are using an IPv4 socket
+ // in place of a dual stack one, and further calls to _set_sock_addr will work as expected.
+ p_type = IP::TYPE_IPV4;
+ family = AF_INET;
+ sockfd = socket(family, type, protocol);
+ }
+
ERR_FAIL_COND_V(sockfd == -1, -1);
if (family == AF_INET6) {
diff --git a/editor/SCsub b/editor/SCsub
index d7392f8249..c46e443534 100644
--- a/editor/SCsub
+++ b/editor/SCsub
@@ -141,6 +141,30 @@ def make_translations_header(target, source, env):
g.write("#endif")
+def make_authors_header(target, source, env):
+
+ src = source[0].srcnode().abspath
+ dst = target[0].srcnode().abspath
+ f = open(src, "rb")
+ g = open(dst, "wb")
+
+ g.write("/* THIS FILE IS GENERATED DO NOT EDIT */\n")
+ g.write("#ifndef _EDITOR_AUTHORS_H\n")
+ g.write("#define _EDITOR_AUTHORS_H\n")
+ g.write("static const char *dev_names[] = {\n")
+
+ name_count = -1
+ for line in f:
+ if name_count >= 0:
+ if line.startswith(" "):
+ g.write("\t\"" + line.strip() + "\",\n")
+ name_count += 1
+ elif line.strip() == "## Developers":
+ name_count = 0
+ g.write("\t0\n")
+ g.write("};\n")
+ g.write("#define AUTHORS_COUNT " + str(name_count) + "\n")
+ g.write("#endif\n")
if (env["tools"] == "yes"):
@@ -188,6 +212,10 @@ if (env["tools"] == "yes"):
env.Depends('#editor/builtin_fonts.h', flist)
env.Command('#editor/builtin_fonts.h', flist, make_fonts_header)
+ # Authors
+ env.Depends('#editor/authors.h', "../AUTHORS.md")
+ env.Command('#editor/authors.h', "../AUTHORS.md", make_authors_header)
+
env.add_source_files(env.editor_sources, "*.cpp")
diff --git a/editor/animation_editor.cpp b/editor/animation_editor.cpp
index 63ed27e60c..1798e66e8a 100644
--- a/editor/animation_editor.cpp
+++ b/editor/animation_editor.cpp
@@ -76,7 +76,7 @@ private:
Ref<StyleBox> sb = get_stylebox("normal", "LineEdit");
sb->draw(ci, r);
r.size -= sb->get_minimum_size();
- r.pos += sb->get_offset();
+ r.position += sb->get_offset();
//VisualServer::get_singleton()->canvas_item_add
Ref<Font> f = get_font("font", "Label");
@@ -111,7 +111,7 @@ private:
iflp = 1.0 - iflp;
}
- VisualServer::get_singleton()->canvas_item_add_line(ci, r.pos + Point2(iflp * r.size.width, prev * r.size.height), r.pos + Point2(ifl * r.size.width, h * r.size.height), mcolor);
+ VisualServer::get_singleton()->canvas_item_add_line(ci, r.position + Point2(iflp * r.size.width, prev * r.size.height), r.position + Point2(ifl * r.size.width, h * r.size.height), mcolor);
prev = h;
}
@@ -138,7 +138,7 @@ private:
iflp = 1.0 - iflp;
}
- VisualServer::get_singleton()->canvas_item_add_line(ci, r.pos + Point2(iflp * r.size.width, prev * r.size.height), r.pos + Point2(ifl * r.size.width, h * r.size.height), color);
+ VisualServer::get_singleton()->canvas_item_add_line(ci, r.position + Point2(iflp * r.size.width, prev * r.size.height), r.position + Point2(ifl * r.size.width, h * r.size.height), color);
prev = h;
}
}
@@ -154,13 +154,15 @@ private:
}
}
- void _gui_input(const InputEvent &p_ev) {
- if (p_ev.type == InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ void _gui_input(const Ref<InputEvent> &p_ev) {
+
+ Ref<InputEventMouseMotion> mm = p_ev;
+ if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
if (mode == MODE_DISABLED)
return;
- float rel = p_ev.mouse_motion.relative_x;
+ float rel = mm->get_relative().x;
if (rel == 0)
return;
@@ -1035,7 +1037,7 @@ void AnimationKeyEditor::_track_pos_draw() {
//draw position
int pixel = (timeline_pos - h_scroll->get_value()) * zoom_scale;
pixel += name_limit;
- track_pos->draw_line(ofs + Point2(pixel, 0), ofs + Point2(pixel, size.height), get_color("animation_editor_track_pos", "Editor"));
+ track_pos->draw_line(ofs + Point2(pixel, 0), ofs + Point2(pixel, size.height), get_color("highlight_color", "Editor"));
}
}
@@ -1089,12 +1091,12 @@ void AnimationKeyEditor::_track_editor_draw() {
int sep = get_constant("vseparation", "Tree");
int hsep = get_constant("hseparation", "Tree");
Color color = get_color("font_color", "Tree");
- Color sepcolor = get_color("guide_color", "Editor");
- Color timecolor = get_color("animation_editor_time", "Editor");
+ Color sepcolor = get_color("light_color_1", "Editor");
+ Color timecolor = get_color("dark_color_2", "Editor");
Color hover_color = Color(1, 1, 1, 0.05);
Color select_color = Color(1, 1, 1, 0.1);
Color invalid_path_color = Color(1, 0.6, 0.4, 0.5);
- Color track_select_color = Color::html("ffbd8e8e");
+ Color track_select_color = get_color("highlight_color", "Editor");
Ref<Texture> remove_icon = get_icon("Remove", "EditorIcons");
Ref<Texture> move_up_icon = get_icon("MoveUp", "EditorIcons");
@@ -1154,9 +1156,8 @@ void AnimationKeyEditor::_track_editor_draw() {
int settings_limit = size.width - right_separator_ofs;
int name_limit = settings_limit * name_column_ratio;
- Color line_color = get_color("animation_editor_line", "Editor");
- te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), line_color);
- te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), line_color);
+ te->draw_line(ofs + Point2(name_limit, 0), ofs + Point2(name_limit, size.height), color);
+ te->draw_line(ofs + Point2(settings_limit, 0), ofs + Point2(settings_limit, size.height), color);
te->draw_texture(hsize_icon, ofs + Point2(name_limit - hsize_icon->get_width() - hsep, (h - hsize_icon->get_height()) / 2));
te->draw_line(ofs + Point2(0, h), ofs + Point2(size.width, h), color);
@@ -1179,11 +1180,7 @@ void AnimationKeyEditor::_track_editor_draw() {
int end_px = (l - h_scroll->get_value()) * scale;
int begin_px = -h_scroll->get_value() * scale;
- Color notimecol;
- notimecol.r = timecolor.gray();
- notimecol.g = notimecol.r;
- notimecol.b = notimecol.r;
- notimecol.a = timecolor.a;
+ Color notimecol = get_color("light_color_1", "Editor");
{
@@ -1483,7 +1480,9 @@ void AnimationKeyEditor::_track_editor_draw() {
switch (click.click) {
case ClickOver::CLICK_SELECT_KEYS: {
- te->draw_rect(Rect2(click.at, click.to - click.at), get_color("animation_editor_selection_rect", "Editor"));
+ Color box_color = get_color("highlight_color", "Editor");
+ box_color.a = 0.35;
+ te->draw_rect(Rect2(click.at, click.to - click.at), box_color);
} break;
case ClickOver::CLICK_MOVE_KEYS: {
@@ -1749,7 +1748,7 @@ void AnimationKeyEditor::_anim_delete_keys() {
}
}
-void AnimationKeyEditor::_track_editor_gui_input(const InputEvent &p_input) {
+void AnimationKeyEditor::_track_editor_gui_input(const Ref<InputEvent> &p_input) {
Control *te = track_editor;
Ref<StyleBox> style = get_stylebox("normal", "TextEdit");
@@ -1807,1073 +1806,1083 @@ void AnimationKeyEditor::_track_editor_gui_input(const InputEvent &p_input) {
int settings_limit = size.width - right_separator_ofs;
int name_limit = settings_limit * name_column_ratio;
- switch (p_input.type) {
+ Ref<InputEventKey> key = p_input;
+ if (key.is_valid()) {
- case InputEvent::KEY: {
+ if (key->get_scancode() == KEY_D && key->is_pressed() && key->get_command()) {
- if (p_input.key.scancode == KEY_D && p_input.key.pressed && p_input.key.mod.command) {
+ if (key->get_shift())
+ _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE);
+ else
+ _menu_track(TRACK_MENU_DUPLICATE);
- if (p_input.key.mod.shift)
- _menu_track(TRACK_MENU_DUPLICATE_TRANSPOSE);
- else
- _menu_track(TRACK_MENU_DUPLICATE);
+ accept_event();
- accept_event();
+ } else if (key->get_scancode() == KEY_DELETE && key->is_pressed() && click.click == ClickOver::CLICK_NONE) {
- } else if (p_input.key.scancode == KEY_DELETE && p_input.key.pressed && click.click == ClickOver::CLICK_NONE) {
+ _anim_delete_keys();
+ } else if (animation.is_valid() && animation->get_track_count() > 0) {
- _anim_delete_keys();
- } else if (animation.is_valid() && animation->get_track_count() > 0) {
-
- if (p_input.is_pressed() && (p_input.is_action("ui_up") || p_input.is_action("ui_page_up"))) {
+ if (key->is_pressed() && (key->is_action("ui_up") || key->is_action("ui_page_up"))) {
- if (p_input.is_action("ui_up"))
- selected_track--;
- if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_up"))
- selected_track--;
+ if (key->is_action("ui_up"))
+ selected_track--;
+ if (v_scroll->is_visible_in_tree() && key->is_action("ui_page_up"))
+ selected_track--;
- if (selected_track < 0)
- selected_track = 0;
+ if (selected_track < 0)
+ selected_track = 0;
- if (v_scroll->is_visible_in_tree()) {
- if (v_scroll->get_value() > selected_track)
- v_scroll->set_value(selected_track);
- }
-
- track_editor->update();
- accept_event();
+ if (v_scroll->is_visible_in_tree()) {
+ if (v_scroll->get_value() > selected_track)
+ v_scroll->set_value(selected_track);
}
- if (p_input.is_pressed() && (p_input.is_action("ui_down") || p_input.is_action("ui_page_down"))) {
+ track_editor->update();
+ accept_event();
+ }
- if (p_input.is_action("ui_down"))
- selected_track++;
- else if (v_scroll->is_visible_in_tree() && p_input.is_action("ui_page_down"))
- selected_track += v_scroll->get_page();
+ if (key->is_pressed() && (key->is_action("ui_down") || key->is_action("ui_page_down"))) {
- if (selected_track >= animation->get_track_count())
- selected_track = animation->get_track_count() - 1;
+ if (key->is_action("ui_down"))
+ selected_track++;
+ else if (v_scroll->is_visible_in_tree() && key->is_action("ui_page_down"))
+ selected_track += v_scroll->get_page();
- if (v_scroll->is_visible_in_tree() && v_scroll->get_page() + v_scroll->get_value() < selected_track + 1) {
- v_scroll->set_value(selected_track - v_scroll->get_page() + 1);
- }
+ if (selected_track >= animation->get_track_count())
+ selected_track = animation->get_track_count() - 1;
- track_editor->update();
- accept_event();
+ if (v_scroll->is_visible_in_tree() && v_scroll->get_page() + v_scroll->get_value() < selected_track + 1) {
+ v_scroll->set_value(selected_track - v_scroll->get_page() + 1);
}
+
+ track_editor->update();
+ accept_event();
}
+ }
+ }
- } break;
- case InputEvent::MOUSE_BUTTON: {
+ Ref<InputEventMouseButton> mb = p_input;
- const InputEventMouseButton &mb = p_input.mouse_button;
+ if (mb.is_valid()) {
- if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
+ if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
- if (mb.mod.command) {
- zoom->set_value(zoom->get_value() + zoom->get_step());
- } else {
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8);
- }
- }
+ if (mb->get_command()) {
- if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
+ zoom->set_value(zoom->get_value() + zoom->get_step());
+ } else {
- if (mb.mod.command) {
- zoom->set_value(zoom->get_value() - zoom->get_step());
- } else {
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8);
- }
+ v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * mb->get_factor() / 8);
}
+ }
- if (mb.button_index == BUTTON_RIGHT && mb.pressed) {
+ if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
- Point2 mpos = Point2(mb.x, mb.y) - ofs;
+ if (mb->get_command()) {
- if (selection.size() == 0) {
- // Auto-select on right-click if nothing is selected
- // Note: This code is pretty much duplicated from the left click code,
- // both codes could be moved into a function to avoid the duplicated code.
- Point2 mpos = Point2(mb.x, mb.y) - ofs;
+ zoom->set_value(zoom->get_value() - zoom->get_step());
+ } else {
- if (mpos.y < h) {
- return;
- }
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8);
+ }
+ }
- mpos.y -= h;
+ if (mb->get_button_index() == BUTTON_WHEEL_RIGHT && mb->is_pressed()) {
- int idx = mpos.y / h;
- idx += v_scroll->get_value();
- if (idx < 0 || idx >= animation->get_track_count())
- break;
+ h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb->get_factor() / 8);
+ }
- if (mpos.x < name_limit) {
- } else if (mpos.x < settings_limit) {
- float pos = mpos.x - name_limit;
- pos /= _get_zoom_scale();
- pos += h_scroll->get_value();
- float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
+ if (mb->get_button_index() == BUTTON_WHEEL_LEFT && mb->is_pressed()) {
- int kidx = animation->track_find_key(idx, pos);
- int kidx_n = kidx + 1;
- int key = -1;
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * mb->get_factor() / 8);
+ }
- if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
+ if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
- float kpos = animation->track_get_key_time(idx, kidx);
- if (ABS(pos - kpos) <= w_time) {
+ Point2 mpos = mb->get_position() - ofs;
- key = kidx;
- }
- }
+ if (selection.size() == 0) {
+ // Auto-select on right-click if nothing is selected
+ // Note: This code is pretty much duplicated from the left click code,
+ // both codes could be moved into a function to avoid the duplicated code.
+ Point2 mpos = mb->get_position() - ofs;
- if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
+ if (mpos.y < h) {
+ return;
+ }
- float kpos = animation->track_get_key_time(idx, kidx_n);
- if (ABS(pos - kpos) <= w_time) {
+ mpos.y -= h;
- key = kidx_n;
- }
- }
+ int idx = mpos.y / h;
+ idx += v_scroll->get_value();
+ if (idx < 0 || idx >= animation->get_track_count())
+ return;
- if (key == -1) {
+ if (mpos.x < name_limit) {
+ } else if (mpos.x < settings_limit) {
+ float pos = mpos.x - name_limit;
+ pos /= _get_zoom_scale();
+ pos += h_scroll->get_value();
+ float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
- click.click = ClickOver::CLICK_SELECT_KEYS;
- click.at = Point2(mb.x, mb.y);
- click.to = click.at;
- click.shift = mb.mod.shift;
- selected_track = idx;
- track_editor->update();
- //drag select region
- return;
+ int kidx = animation->track_find_key(idx, pos);
+ int kidx_n = kidx + 1;
+ int key = -1;
+
+ if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
+
+ float kpos = animation->track_get_key_time(idx, kidx);
+ if (ABS(pos - kpos) <= w_time) {
+
+ key = kidx;
}
+ }
- SelectedKey sk;
- sk.track = idx;
- sk.key = key;
- KeyInfo ki;
- ki.pos = animation->track_get_key_time(idx, key);
- click.shift = mb.mod.shift;
- click.selk = sk;
+ if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
- if (!mb.mod.shift && !selection.has(sk))
- _clear_selection();
+ float kpos = animation->track_get_key_time(idx, kidx_n);
+ if (ABS(pos - kpos) <= w_time) {
+
+ key = kidx_n;
+ }
+ }
- selection.insert(sk, ki);
+ if (key == -1) {
- click.click = ClickOver::CLICK_MOVE_KEYS;
- click.at = Point2(mb.x, mb.y);
+ click.click = ClickOver::CLICK_SELECT_KEYS;
+ click.at = mb->get_position();
click.to = click.at;
- update();
+ click.shift = mb->get_shift();
selected_track = idx;
track_editor->update();
-
- if (_edit_if_single_selection() && mb.mod.command) {
- edit_button->set_pressed(true);
- key_editor_tab->show();
- }
+ //drag select region
+ return;
}
- }
- if (selection.size()) {
- // User has right clicked and we have a selection, show a popup menu with options
- track_menu->clear();
- track_menu->set_size(Point2(1, 1));
- track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE);
- track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE);
- track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE);
+ SelectedKey sk;
+ sk.track = idx;
+ sk.key = key;
+ KeyInfo ki;
+ ki.pos = animation->track_get_key_time(idx, key);
+ click.shift = mb->get_shift();
+ click.selk = sk;
- track_menu->set_position(te->get_global_position() + mpos);
+ if (!mb->get_shift() && !selection.has(sk))
+ _clear_selection();
- interp_editing = -1;
- cont_editing = -1;
- wrap_editing = -1;
+ selection.insert(sk, ki);
- track_menu->popup();
+ click.click = ClickOver::CLICK_MOVE_KEYS;
+ click.at = mb->get_position();
+ click.to = click.at;
+ update();
+ selected_track = idx;
+ track_editor->update();
+
+ if (_edit_if_single_selection() && mb->get_command()) {
+ edit_button->set_pressed(true);
+ key_editor_tab->show();
+ }
}
}
- if (mb.button_index == BUTTON_LEFT && !(mb.button_mask & ~BUTTON_MASK_LEFT)) {
+ if (selection.size()) {
+ // User has right clicked and we have a selection, show a popup menu with options
+ track_menu->clear();
+ track_menu->set_size(Point2(1, 1));
+ track_menu->add_item(TTR("Duplicate Selection"), RIGHT_MENU_DUPLICATE);
+ track_menu->add_item(TTR("Duplicate Transposed"), RIGHT_MENU_DUPLICATE_TRANSPOSE);
+ track_menu->add_item(TTR("Remove Selection"), RIGHT_MENU_REMOVE);
- if (mb.pressed) {
+ track_menu->set_position(te->get_global_position() + mpos);
- Point2 mpos = Point2(mb.x, mb.y) - ofs;
+ interp_editing = -1;
+ cont_editing = -1;
+ wrap_editing = -1;
- if (mpos.y < h) {
+ track_menu->popup();
+ }
+ }
- if (mpos.x < name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) {
+ if (mb->get_button_index() == BUTTON_LEFT && !(mb->get_button_mask() & ~BUTTON_MASK_LEFT)) {
- click.click = ClickOver::CLICK_RESIZE_NAMES;
- click.at = Point2(mb.x, mb.y);
- click.to = click.at;
- click.at.y = name_limit;
- }
+ if (mb->is_pressed()) {
- if (mpos.x >= name_limit && mpos.x < settings_limit) {
- //seek
- //int zoomw = settings_limit-name_limit;
- float scale = _get_zoom_scale();
- float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale;
- if (animation->get_step())
- pos = Math::stepify(pos, animation->get_step());
-
- if (pos < 0)
- pos = 0;
- if (pos >= animation->get_length())
- pos = animation->get_length();
- timeline_pos = pos;
- click.click = ClickOver::CLICK_DRAG_TIMELINE;
- click.at = Point2(mb.x, mb.y);
- click.to = click.at;
- emit_signal("timeline_changed", pos, false);
- }
+ Point2 mpos = mb->get_position() - ofs;
- return;
- }
+ if (mpos.y < h) {
- mpos.y -= h;
+ if (mpos.x < name_limit && mpos.x > (name_limit - hsep - hsize_icon->get_width())) {
- int idx = mpos.y / h;
- idx += v_scroll->get_value();
- if (idx < 0)
- break;
+ click.click = ClickOver::CLICK_RESIZE_NAMES;
+ click.at = mb->get_position();
+ click.to = click.at;
+ click.at.y = name_limit;
+ }
- if (idx >= animation->get_track_count()) {
+ if (mpos.x >= name_limit && mpos.x < settings_limit) {
+ //seek
+ //int zoomw = settings_limit-name_limit;
+ float scale = _get_zoom_scale();
+ float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale;
+ if (animation->get_step())
+ pos = Math::stepify(pos, animation->get_step());
- if (mpos.x >= name_limit && mpos.x < settings_limit) {
+ if (pos < 0)
+ pos = 0;
+ if (pos >= animation->get_length())
+ pos = animation->get_length();
+ timeline_pos = pos;
+ click.click = ClickOver::CLICK_DRAG_TIMELINE;
+ click.at = mb->get_position();
+ click.to = click.at;
+ emit_signal("timeline_changed", pos, false);
+ }
- click.click = ClickOver::CLICK_SELECT_KEYS;
- click.at = Point2(mb.x, mb.y);
- click.to = click.at;
- //drag select region
- }
+ return;
+ }
- break;
- }
+ mpos.y -= h;
- if (mpos.x < name_limit) {
- //name column
+ int idx = mpos.y / h;
+ idx += v_scroll->get_value();
+ if (idx < 0)
+ return;
- // area
- if (idx != selected_track) {
+ if (idx >= animation->get_track_count()) {
- selected_track = idx;
- track_editor->update();
- break;
- }
+ if (mpos.x >= name_limit && mpos.x < settings_limit) {
- Rect2 area(ofs.x, ofs.y + ((int(mpos.y) / h) + 1) * h, name_limit, h);
- track_name->set_text(animation->track_get_path(idx));
- track_name->set_position(te->get_global_position() + area.pos);
- track_name->set_size(area.size);
- track_name->show_modal();
- track_name->grab_focus();
- track_name->select_all();
- track_name_editing = idx;
+ click.click = ClickOver::CLICK_SELECT_KEYS;
+ click.at = mb->get_position();
+ click.to = click.at;
+ //drag select region
+ }
- } else if (mpos.x < settings_limit) {
+ return;
+ }
- float pos = mpos.x - name_limit;
- pos /= _get_zoom_scale();
- pos += h_scroll->get_value();
- float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
+ if (mpos.x < name_limit) {
+ //name column
- int kidx = animation->track_find_key(idx, pos);
- int kidx_n = kidx + 1;
- int key = -1;
+ // area
+ if (idx != selected_track) {
- if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
+ selected_track = idx;
+ track_editor->update();
+ return;
+ }
- float kpos = animation->track_get_key_time(idx, kidx);
- if (ABS(pos - kpos) <= w_time) {
+ Rect2 area(ofs.x, ofs.y + ((int(mpos.y) / h) + 1) * h, name_limit, h);
+ track_name->set_text(animation->track_get_path(idx));
+ track_name->set_position(te->get_global_position() + area.position);
+ track_name->set_size(area.size);
+ track_name->show_modal();
+ track_name->grab_focus();
+ track_name->select_all();
+ track_name_editing = idx;
- key = kidx;
- }
- }
+ } else if (mpos.x < settings_limit) {
- if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
+ float pos = mpos.x - name_limit;
+ pos /= _get_zoom_scale();
+ pos += h_scroll->get_value();
+ float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
- float kpos = animation->track_get_key_time(idx, kidx_n);
- if (ABS(pos - kpos) <= w_time) {
+ int kidx = animation->track_find_key(idx, pos);
+ int kidx_n = kidx + 1;
+ int key = -1;
- key = kidx_n;
- }
- }
+ if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
- if (key == -1) {
+ float kpos = animation->track_get_key_time(idx, kidx);
+ if (ABS(pos - kpos) <= w_time) {
- click.click = ClickOver::CLICK_SELECT_KEYS;
- click.at = Point2(mb.x, mb.y);
- click.to = click.at;
- click.shift = mb.mod.shift;
- selected_track = idx;
- track_editor->update();
- //drag select region
- return;
+ key = kidx;
}
+ }
- SelectedKey sk;
- sk.track = idx;
- sk.key = key;
- KeyInfo ki;
- ki.pos = animation->track_get_key_time(idx, key);
- click.shift = mb.mod.shift;
- click.selk = sk;
+ if (key == -1 && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
- if (!mb.mod.shift && !selection.has(sk))
- _clear_selection();
+ float kpos = animation->track_get_key_time(idx, kidx_n);
+ if (ABS(pos - kpos) <= w_time) {
- selection.insert(sk, ki);
+ key = kidx_n;
+ }
+ }
+
+ if (key == -1) {
- click.click = ClickOver::CLICK_MOVE_KEYS;
- click.at = Point2(mb.x, mb.y);
+ click.click = ClickOver::CLICK_SELECT_KEYS;
+ click.at = mb->get_position();
click.to = click.at;
- update();
+ click.shift = mb->get_shift();
selected_track = idx;
track_editor->update();
+ //drag select region
+ return;
+ }
- if (_edit_if_single_selection() && mb.mod.command) {
- edit_button->set_pressed(true);
- key_editor_tab->show();
- }
- } else {
- //button column
- int ofsx = size.width - mpos.x;
- if (ofsx < 0)
- break;
- /*
- if (ofsx < remove_icon->get_width()) {
+ SelectedKey sk;
+ sk.track = idx;
+ sk.key = key;
+ KeyInfo ki;
+ ki.pos = animation->track_get_key_time(idx, key);
+ click.shift = mb->get_shift();
+ click.selk = sk;
- undo_redo->create_action("Remove Anim Track");
- undo_redo->add_do_method(animation.ptr(),"remove_track",idx);
- undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx);
- undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx));
- //todo interpolation
- for(int i=0;i<animation->track_get_key_count(idx);i++) {
+ if (!mb->get_shift() && !selection.has(sk))
+ _clear_selection();
- Variant v = animation->track_get_key_value(idx,i);
- float time = animation->track_get_key_time(idx,i);
- float trans = animation->track_get_key_transition(idx,i);
+ selection.insert(sk, ki);
- undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v);
- undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans);
+ click.click = ClickOver::CLICK_MOVE_KEYS;
+ click.at = mb->get_position();
+ click.to = click.at;
+ update();
+ selected_track = idx;
+ track_editor->update();
- }
+ if (_edit_if_single_selection() && mb->get_command()) {
+ edit_button->set_pressed(true);
+ key_editor_tab->show();
+ }
+ } else {
+ //button column
+ int ofsx = size.width - mpos.x;
+ if (ofsx < 0)
+ return;
+ /*
+ if (ofsx < remove_icon->get_width()) {
- undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx));
- if (animation->track_get_type(idx)==Animation::TYPE_VALUE) {
- undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx));
+ undo_redo->create_action("Remove Anim Track");
+ undo_redo->add_do_method(animation.ptr(),"remove_track",idx);
+ undo_redo->add_undo_method(animation.ptr(),"add_track",animation->track_get_type(idx),idx);
+ undo_redo->add_undo_method(animation.ptr(),"track_set_path",idx,animation->track_get_path(idx));
+ //todo interpolation
+ for(int i=0;i<animation->track_get_key_count(idx);i++) {
- }
+ Variant v = animation->track_get_key_value(idx,i);
+ float time = animation->track_get_key_time(idx,i);
+ float trans = animation->track_get_key_transition(idx,i);
- undo_redo->commit_action();
+ undo_redo->add_undo_method(animation.ptr(),"track_insert_key",idx,time,v);
+ undo_redo->add_undo_method(animation.ptr(),"track_set_key_transition",idx,i,trans);
-
- return;
}
- ofsx-=hsep+remove_icon->get_width();
-
- if (ofsx < move_down_icon->get_width()) {
+ undo_redo->add_undo_method(animation.ptr(),"track_set_interpolation_type",idx,animation->track_get_interpolation_type(idx));
+ if (animation->track_get_type(idx)==Animation::TYPE_VALUE) {
+ undo_redo->add_undo_method(animation.ptr(),"value_track_set_continuous",idx,animation->value_track_is_continuous(idx));
- if (idx < animation->get_track_count() -1) {
- undo_redo->create_action("Move Anim Track Down");
- undo_redo->add_do_method(animation.ptr(),"track_move_up",idx);
- undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1);
- undo_redo->commit_action();
- }
- return;
}
- ofsx-=hsep+move_down_icon->get_width();
+ undo_redo->commit_action();
- if (ofsx < move_up_icon->get_width()) {
- if (idx >0) {
- undo_redo->create_action("Move Anim Track Up");
- undo_redo->add_do_method(animation.ptr(),"track_move_down",idx);
- undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1);
- undo_redo->commit_action();
- }
- return;
- }
+ return;
+ }
+ ofsx-=hsep+remove_icon->get_width();
- ofsx-=hsep*3+move_up_icon->get_width();
- */
+ if (ofsx < move_down_icon->get_width()) {
+
+ if (idx < animation->get_track_count() -1) {
+ undo_redo->create_action("Move Anim Track Down");
+ undo_redo->add_do_method(animation.ptr(),"track_move_up",idx);
+ undo_redo->add_undo_method(animation.ptr(),"track_move_down",idx+1);
+ undo_redo->commit_action();
+ }
+ return;
+ }
- if (ofsx < track_ofs[1]) {
+ ofsx-=hsep+move_down_icon->get_width();
- track_menu->clear();
- track_menu->set_size(Point2(1, 1));
- static const char *interp_name[2] = { "Clamp Loop Interp", "Wrap Loop Interp" };
- for (int i = 0; i < 2; i++) {
- track_menu->add_icon_item(wrap_icon[i], interp_name[i]);
- }
+ if (ofsx < move_up_icon->get_width()) {
- int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
- int popup_x = size.width - track_ofs[1];
+ if (idx >0) {
+ undo_redo->create_action("Move Anim Track Up");
+ undo_redo->add_do_method(animation.ptr(),"track_move_down",idx);
+ undo_redo->add_undo_method(animation.ptr(),"track_move_up",idx-1);
+ undo_redo->commit_action();
+ }
+ return;
+ }
- track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
- wrap_editing = idx;
- interp_editing = -1;
- cont_editing = -1;
+ ofsx-=hsep*3+move_up_icon->get_width();
+ */
- track_menu->popup();
+ if (ofsx < track_ofs[1]) {
- return;
+ track_menu->clear();
+ track_menu->set_size(Point2(1, 1));
+ static const char *interp_name[2] = { "Clamp Loop Interp", "Wrap Loop Interp" };
+ for (int i = 0; i < 2; i++) {
+ track_menu->add_icon_item(wrap_icon[i], interp_name[i]);
}
- if (ofsx < track_ofs[2]) {
+ int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
+ int popup_x = size.width - track_ofs[1];
- track_menu->clear();
- track_menu->set_size(Point2(1, 1));
- static const char *interp_name[3] = { "Nearest", "Linear", "Cubic" };
- for (int i = 0; i < 3; i++) {
- track_menu->add_icon_item(interp_icon[i], interp_name[i]);
- }
+ track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
- int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
- int popup_x = size.width - track_ofs[2];
+ wrap_editing = idx;
+ interp_editing = -1;
+ cont_editing = -1;
- track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
+ track_menu->popup();
- interp_editing = idx;
- cont_editing = -1;
- wrap_editing = -1;
+ return;
+ }
- track_menu->popup();
+ if (ofsx < track_ofs[2]) {
- return;
+ track_menu->clear();
+ track_menu->set_size(Point2(1, 1));
+ static const char *interp_name[3] = { "Nearest", "Linear", "Cubic" };
+ for (int i = 0; i < 3; i++) {
+ track_menu->add_icon_item(interp_icon[i], interp_name[i]);
}
- if (ofsx < track_ofs[3]) {
+ int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
+ int popup_x = size.width - track_ofs[2];
- track_menu->clear();
- track_menu->set_size(Point2(1, 1));
- String cont_name[3] = { TTR("Continuous"), TTR("Discrete"), TTR("Trigger") };
- for (int i = 0; i < 3; i++) {
- track_menu->add_icon_item(cont_icon[i], cont_name[i]);
- }
+ track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
- int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
- int popup_x = size.width - track_ofs[3];
+ interp_editing = idx;
+ cont_editing = -1;
+ wrap_editing = -1;
- track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
+ track_menu->popup();
- interp_editing = -1;
- wrap_editing = -1;
- cont_editing = idx;
+ return;
+ }
- track_menu->popup();
+ if (ofsx < track_ofs[3]) {
- return;
+ track_menu->clear();
+ track_menu->set_size(Point2(1, 1));
+ String cont_name[3] = { TTR("Continuous"), TTR("Discrete"), TTR("Trigger") };
+ for (int i = 0; i < 3; i++) {
+ track_menu->add_icon_item(cont_icon[i], cont_name[i]);
}
- if (ofsx < track_ofs[4]) {
+ int popup_y = ofs.y + ((int(mpos.y) / h) + 2) * h;
+ int popup_x = size.width - track_ofs[3];
- Animation::TrackType tt = animation->track_get_type(idx);
+ track_menu->set_position(te->get_global_position() + Point2(popup_x, popup_y));
- float pos = timeline_pos;
- int existing = animation->track_find_key(idx, pos, true);
+ interp_editing = -1;
+ wrap_editing = -1;
+ cont_editing = idx;
- Variant newval;
+ track_menu->popup();
- if (tt == Animation::TYPE_TRANSFORM) {
- Dictionary d;
- d["loc"] = Vector3();
- d["rot"] = Quat();
- d["scale"] = Vector3();
- newval = d;
+ return;
+ }
- } else if (tt == Animation::TYPE_METHOD) {
+ if (ofsx < track_ofs[4]) {
- Dictionary d;
- d["method"] = "";
- d["args"] = Vector<Variant>();
+ Animation::TrackType tt = animation->track_get_type(idx);
- newval = d;
- } else if (tt == Animation::TYPE_VALUE) {
+ float pos = timeline_pos;
+ int existing = animation->track_find_key(idx, pos, true);
- NodePath np;
- PropertyInfo inf = _find_hint_for_track(idx, np);
- if (inf.type != Variant::NIL) {
+ Variant newval;
- Variant::CallError err;
- newval = Variant::construct(inf.type, NULL, 0, err);
- }
+ if (tt == Animation::TYPE_TRANSFORM) {
+ Dictionary d;
+ d["loc"] = Vector3();
+ d["rot"] = Quat();
+ d["scale"] = Vector3();
+ newval = d;
- if (newval.get_type() == Variant::NIL) {
- //popup a new type
- cvi_track = idx;
- cvi_pos = pos;
+ } else if (tt == Animation::TYPE_METHOD) {
- type_menu->set_position(get_global_position() + mpos + ofs);
- type_menu->popup();
- return;
- }
- }
+ Dictionary d;
+ d["method"] = "";
+ d["args"] = Vector<Variant>();
- undo_redo->create_action(TTR("Anim Add Key"));
+ newval = d;
+ } else if (tt == Animation::TYPE_VALUE) {
- undo_redo->add_do_method(animation.ptr(), "track_insert_key", idx, pos, newval, 1);
- undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", idx, pos);
+ NodePath np;
+ PropertyInfo inf = _find_hint_for_track(idx, np);
+ if (inf.type != Variant::NIL) {
- if (existing != -1) {
- Variant v = animation->track_get_key_value(idx, existing);
- float trans = animation->track_get_key_transition(idx, existing);
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", idx, pos, v, trans);
+ Variant::CallError err;
+ newval = Variant::construct(inf.type, NULL, 0, err);
}
- undo_redo->commit_action();
+ if (newval.get_type() == Variant::NIL) {
+ //popup a new type
+ cvi_track = idx;
+ cvi_pos = pos;
- return;
+ type_menu->set_position(get_global_position() + mpos + ofs);
+ type_menu->popup();
+ return;
+ }
}
- }
- } else {
+ undo_redo->create_action(TTR("Anim Add Key"));
- switch (click.click) {
- case ClickOver::CLICK_SELECT_KEYS: {
+ undo_redo->add_do_method(animation.ptr(), "track_insert_key", idx, pos, newval, 1);
+ undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", idx, pos);
- float zoom_scale = _get_zoom_scale();
- float keys_from = h_scroll->get_value();
- float keys_to = keys_from + (settings_limit - name_limit) / zoom_scale;
+ if (existing != -1) {
+ Variant v = animation->track_get_key_value(idx, existing);
+ float trans = animation->track_get_key_transition(idx, existing);
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", idx, pos, v, trans);
+ }
- float from_time = keys_from + (click.at.x - (name_limit + ofs.x)) / zoom_scale;
- float to_time = keys_from + (click.to.x - (name_limit + ofs.x)) / zoom_scale;
+ undo_redo->commit_action();
- if (to_time < from_time)
- SWAP(from_time, to_time);
+ return;
+ }
+ }
- if (from_time > keys_to || to_time < keys_from)
- break;
+ } else {
- if (from_time < keys_from)
- from_time = keys_from;
+ switch (click.click) {
+ case ClickOver::CLICK_SELECT_KEYS: {
- if (to_time >= keys_to)
- to_time = keys_to;
+ float zoom_scale = _get_zoom_scale();
+ float keys_from = h_scroll->get_value();
+ float keys_to = keys_from + (settings_limit - name_limit) / zoom_scale;
- int from_track = int(click.at.y - ofs.y - h - sep) / h + v_scroll->get_value();
- int to_track = int(click.to.y - ofs.y - h - sep) / h + v_scroll->get_value();
- int from_mod = int(click.at.y - ofs.y - sep) % h;
- int to_mod = int(click.to.y - ofs.y - sep) % h;
+ float from_time = keys_from + (click.at.x - (name_limit + ofs.x)) / zoom_scale;
+ float to_time = keys_from + (click.to.x - (name_limit + ofs.x)) / zoom_scale;
- if (to_track < from_track) {
+ if (to_time < from_time)
+ SWAP(from_time, to_time);
- SWAP(from_track, to_track);
- SWAP(from_mod, to_mod);
- }
+ if (from_time > keys_to || to_time < keys_from)
+ break;
- if ((from_mod > (h / 2)) && ((click.at.y - ofs.y) >= (h + sep))) {
- from_track++;
- }
+ if (from_time < keys_from)
+ from_time = keys_from;
- if (to_mod < h / 2) {
- to_track--;
- }
+ if (to_time >= keys_to)
+ to_time = keys_to;
- if (from_track > to_track) {
- if (!click.shift)
- _clear_selection();
- _edit_if_single_selection();
- break;
- }
+ int from_track = int(click.at.y - ofs.y - h - sep) / h + v_scroll->get_value();
+ int to_track = int(click.to.y - ofs.y - h - sep) / h + v_scroll->get_value();
+ int from_mod = int(click.at.y - ofs.y - sep) % h;
+ int to_mod = int(click.to.y - ofs.y - sep) % h;
+
+ if (to_track < from_track) {
- int tracks_from = v_scroll->get_value();
- int tracks_to = v_scroll->get_value() + fit - 1;
- if (tracks_to >= animation->get_track_count())
- tracks_to = animation->get_track_count() - 1;
+ SWAP(from_track, to_track);
+ SWAP(from_mod, to_mod);
+ }
- tracks_from = 0;
+ if ((from_mod > (h / 2)) && ((click.at.y - ofs.y) >= (h + sep))) {
+ from_track++;
+ }
+
+ if (to_mod < h / 2) {
+ to_track--;
+ }
+
+ if (from_track > to_track) {
+ if (!click.shift)
+ _clear_selection();
+ _edit_if_single_selection();
+ break;
+ }
+
+ int tracks_from = v_scroll->get_value();
+ int tracks_to = v_scroll->get_value() + fit - 1;
+ if (tracks_to >= animation->get_track_count())
tracks_to = animation->get_track_count() - 1;
- if (to_track > tracks_to)
- to_track = tracks_to;
- if (from_track < tracks_from)
- from_track = tracks_from;
-
- if (from_track > tracks_to || to_track < tracks_from) {
- if (!click.shift)
- _clear_selection();
- _edit_if_single_selection();
- break;
- }
+ tracks_from = 0;
+ tracks_to = animation->get_track_count() - 1;
+ if (to_track > tracks_to)
+ to_track = tracks_to;
+ if (from_track < tracks_from)
+ from_track = tracks_from;
+
+ if (from_track > tracks_to || to_track < tracks_from) {
if (!click.shift)
_clear_selection();
+ _edit_if_single_selection();
+ break;
+ }
- int higher_track = 0x7FFFFFFF;
- for (int i = from_track; i <= to_track; i++) {
+ if (!click.shift)
+ _clear_selection();
- int kc = animation->track_get_key_count(i);
- for (int j = 0; j < kc; j++) {
+ int higher_track = 0x7FFFFFFF;
+ for (int i = from_track; i <= to_track; i++) {
- float t = animation->track_get_key_time(i, j);
- if (t < from_time)
- continue;
- if (t > to_time)
- break;
+ int kc = animation->track_get_key_count(i);
+ for (int j = 0; j < kc; j++) {
- if (i < higher_track)
- higher_track = i;
+ float t = animation->track_get_key_time(i, j);
+ if (t < from_time)
+ continue;
+ if (t > to_time)
+ break;
- SelectedKey sk;
- sk.track = i;
- sk.key = j;
- KeyInfo ki;
- ki.pos = t;
- selection[sk] = ki;
- }
- }
+ if (i < higher_track)
+ higher_track = i;
- if (higher_track != 0x7FFFFFFF) {
- selected_track = higher_track;
- track_editor->update();
+ SelectedKey sk;
+ sk.track = i;
+ sk.key = j;
+ KeyInfo ki;
+ ki.pos = t;
+ selection[sk] = ki;
}
+ }
- _edit_if_single_selection();
+ if (higher_track != 0x7FFFFFFF) {
+ selected_track = higher_track;
+ track_editor->update();
+ }
- } break;
- case ClickOver::CLICK_MOVE_KEYS: {
+ _edit_if_single_selection();
- if (selection.empty())
- break;
- if (click.at == click.to) {
+ } break;
+ case ClickOver::CLICK_MOVE_KEYS: {
- if (!click.shift) {
+ if (selection.empty())
+ break;
+ if (click.at == click.to) {
- KeyInfo ki = selection[click.selk];
- _clear_selection();
- selection[click.selk] = ki;
- _edit_if_single_selection();
- }
+ if (!click.shift) {
- break;
+ KeyInfo ki = selection[click.selk];
+ _clear_selection();
+ selection[click.selk] = ki;
+ _edit_if_single_selection();
}
- float from_t = 1e20;
+ break;
+ }
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) {
- float t = animation->track_get_key_time(E->key().track, E->key().key);
- if (t < from_t)
- from_t = t;
- }
+ float from_t = 1e20;
- float motion = from_t + (click.to.x - click.at.x) / _get_zoom_scale();
- if (step->get_value())
- motion = Math::stepify(motion, step->get_value());
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.front(); E; E = E->next()) {
+ float t = animation->track_get_key_time(E->key().track, E->key().key);
+ if (t < from_t)
+ from_t = t;
+ }
- undo_redo->create_action(TTR("Anim Move Keys"));
+ float motion = from_t + (click.to.x - click.at.x) / _get_zoom_scale();
+ if (step->get_value())
+ motion = Math::stepify(motion, step->get_value());
- List<_AnimMoveRestore> to_restore;
+ undo_redo->create_action(TTR("Anim Move Keys"));
- // 1-remove the keys
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ List<_AnimMoveRestore> to_restore;
- undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
- }
- // 2- remove overlapped keys
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ // 1-remove the keys
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
- float newtime = E->get().pos - from_t + motion;
- int idx = animation->track_find_key(E->key().track, newtime, true);
- if (idx == -1)
- continue;
- SelectedKey sk;
- sk.key = idx;
- sk.track = E->key().track;
- if (selection.has(sk))
- continue; //already in selection, don't save
+ undo_redo->add_do_method(animation.ptr(), "track_remove_key", E->key().track, E->key().key);
+ }
+ // 2- remove overlapped keys
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+
+ float newtime = E->get().pos - from_t + motion;
+ int idx = animation->track_find_key(E->key().track, newtime, true);
+ if (idx == -1)
+ continue;
+ SelectedKey sk;
+ sk.key = idx;
+ sk.track = E->key().track;
+ if (selection.has(sk))
+ continue; //already in selection, don't save
+
+ undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newtime);
+ _AnimMoveRestore amr;
+
+ amr.key = animation->track_get_key_value(E->key().track, idx);
+ amr.track = E->key().track;
+ amr.time = newtime;
+ amr.transition = animation->track_get_key_transition(E->key().track, idx);
+
+ to_restore.push_back(amr);
+ }
- undo_redo->add_do_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newtime);
- _AnimMoveRestore amr;
+ // 3-move the keys (re insert them)
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
- amr.key = animation->track_get_key_value(E->key().track, idx);
- amr.track = E->key().track;
- amr.time = newtime;
- amr.transition = animation->track_get_key_transition(E->key().track, idx);
+ float newpos = E->get().pos - from_t + motion;
+ /*
+ if (newpos<0)
+ continue; //no add at the beginning
+ */
+ undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
+ }
- to_restore.push_back(amr);
- }
+ // 4-(undo) remove inserted keys
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
- // 3-move the keys (re insert them)
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ float newpos = E->get().pos + -from_t + motion;
+ /*
+ if (newpos<0)
+ continue; //no remove what no inserted
+ */
+ undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newpos);
+ }
- float newpos = E->get().pos - from_t + motion;
- /*
- if (newpos<0)
- continue; //no add at the beginning
- */
- undo_redo->add_do_method(animation.ptr(), "track_insert_key", E->key().track, newpos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
- }
+ // 5-(undo) reinsert keys
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
- // 4-(undo) remove inserted keys
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
+ }
- float newpos = E->get().pos + -from_t + motion;
- /*
- if (newpos<0)
- continue; //no remove what no inserted
- */
- undo_redo->add_undo_method(animation.ptr(), "track_remove_key_at_pos", E->key().track, newpos);
- }
+ // 6-(undo) reinsert overlapped keys
+ for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
- // 5-(undo) reinsert keys
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ _AnimMoveRestore &amr = E->get();
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
+ }
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", E->key().track, E->get().pos, animation->track_get_key_value(E->key().track, E->key().key), animation->track_get_key_transition(E->key().track, E->key().key));
- }
+ // 6-(undo) reinsert overlapped keys
+ for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
- // 6-(undo) reinsert overlapped keys
- for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
+ _AnimMoveRestore &amr = E->get();
+ undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
+ }
- _AnimMoveRestore &amr = E->get();
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
- }
+ undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
+ undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
- // 6-(undo) reinsert overlapped keys
- for (List<_AnimMoveRestore>::Element *E = to_restore.front(); E; E = E->next()) {
+ // 7-reselect
- _AnimMoveRestore &amr = E->get();
- undo_redo->add_undo_method(animation.ptr(), "track_insert_key", amr.track, amr.time, amr.key, amr.transition);
- }
+ for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
- undo_redo->add_do_method(this, "_clear_selection_for_anim", animation);
- undo_redo->add_undo_method(this, "_clear_selection_for_anim", animation);
+ float oldpos = E->get().pos;
+ float newpos = oldpos - from_t + motion;
+ //if (newpos>=0)
+ undo_redo->add_do_method(this, "_select_at_anim", animation, E->key().track, newpos);
+ undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos);
+ }
- // 7-reselect
+ undo_redo->commit_action();
+ _edit_if_single_selection();
- for (Map<SelectedKey, KeyInfo>::Element *E = selection.back(); E; E = E->prev()) {
+ } break;
+ default: {}
+ }
- float oldpos = E->get().pos;
- float newpos = oldpos - from_t + motion;
- //if (newpos>=0)
- undo_redo->add_do_method(this, "_select_at_anim", animation, E->key().track, newpos);
- undo_redo->add_undo_method(this, "_select_at_anim", animation, E->key().track, oldpos);
- }
+ //button released
+ click.click = ClickOver::CLICK_NONE;
+ track_editor->update();
+ }
+ }
+ }
- undo_redo->commit_action();
- _edit_if_single_selection();
+ Ref<InputEventMouseMotion> mm = p_input;
- } break;
- default: {}
- }
+ if (mm.is_valid()) {
- //button released
- click.click = ClickOver::CLICK_NONE;
- track_editor->update();
- }
- }
+ mouse_over.over = MouseOver::OVER_NONE;
+ mouse_over.track = -1;
+ te->update();
+ track_editor->set_tooltip("");
- } break;
+ if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
+ track_editor->call_deferred("grab_focus");
- case InputEvent::MOUSE_MOTION: {
+ if (click.click != ClickOver::CLICK_NONE) {
- const InputEventMouseMotion &mb = p_input.mouse_motion;
+ switch (click.click) {
+ case ClickOver::CLICK_RESIZE_NAMES: {
- mouse_over.over = MouseOver::OVER_NONE;
- mouse_over.track = -1;
- te->update();
- track_editor->set_tooltip("");
+ float base = click.at.y;
+ float clickp = click.at.x - ofs.x;
+ float dif = base - clickp;
- if (!track_editor->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
- track_editor->call_deferred("grab_focus");
+ float target = mm->get_position().x + dif - ofs.x;
- if (click.click != ClickOver::CLICK_NONE) {
+ float ratio = target / settings_limit;
- switch (click.click) {
- case ClickOver::CLICK_RESIZE_NAMES: {
+ if (ratio > 0.9)
+ ratio = 0.9;
+ else if (ratio < 0.2)
+ ratio = 0.2;
- float base = click.at.y;
- float clickp = click.at.x - ofs.x;
- float dif = base - clickp;
+ name_column_ratio = ratio;
- float target = mb.x + dif - ofs.x;
+ } break;
+ case ClickOver::CLICK_DRAG_TIMELINE: {
- float ratio = target / settings_limit;
+ Point2 mpos = mm->get_position() - ofs;
+ /*
+ if (mpos.x<name_limit)
+ mpos.x=name_limit;
+ if (mpos.x>settings_limit)
+ mpos.x=settings_limit;
+ */
- if (ratio > 0.9)
- ratio = 0.9;
- else if (ratio < 0.2)
- ratio = 0.2;
+ //int zoomw = settings_limit-name_limit;
+ float scale = _get_zoom_scale();
+ float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale;
+ if (animation->get_step()) {
+ pos = Math::stepify(pos, animation->get_step());
+ }
+ if (pos < 0)
+ pos = 0;
+ if (pos >= animation->get_length())
+ pos = animation->get_length();
+
+ if (pos < h_scroll->get_value()) {
+ h_scroll->set_value(pos);
+ } else if (pos > h_scroll->get_value() + (settings_limit - name_limit) / scale) {
+ h_scroll->set_value(pos - (settings_limit - name_limit) / scale);
+ }
- name_column_ratio = ratio;
+ timeline_pos = pos;
+ emit_signal("timeline_changed", pos, true);
- } break;
- case ClickOver::CLICK_DRAG_TIMELINE: {
-
- Point2 mpos = Point2(mb.x, mb.y) - ofs;
- /*
- if (mpos.x<name_limit)
- mpos.x=name_limit;
- if (mpos.x>settings_limit)
- mpos.x=settings_limit;
- */
+ } break;
+ case ClickOver::CLICK_SELECT_KEYS: {
- //int zoomw = settings_limit-name_limit;
- float scale = _get_zoom_scale();
- float pos = h_scroll->get_value() + (mpos.x - name_limit) / scale;
- if (animation->get_step()) {
- pos = Math::stepify(pos, animation->get_step());
- }
- if (pos < 0)
- pos = 0;
- if (pos >= animation->get_length())
- pos = animation->get_length();
+ click.to = mm->get_position();
+ if (click.to.y < h && click.at.y > h && mm->get_relative().y < 0) {
- if (pos < h_scroll->get_value()) {
- h_scroll->set_value(pos);
- } else if (pos > h_scroll->get_value() + (settings_limit - name_limit) / scale) {
- h_scroll->set_value(pos - (settings_limit - name_limit) / scale);
- }
+ float prev = v_scroll->get_value();
+ v_scroll->set_value(v_scroll->get_value() - 1);
+ if (prev != v_scroll->get_value())
+ click.at.y += h;
+ }
+ if (click.to.y > size.height && click.at.y < size.height && mm->get_relative().y > 0) {
- timeline_pos = pos;
- emit_signal("timeline_changed", pos, true);
+ float prev = v_scroll->get_value();
+ v_scroll->set_value(v_scroll->get_value() + 1);
+ if (prev != v_scroll->get_value())
+ click.at.y -= h;
+ }
- } break;
- case ClickOver::CLICK_SELECT_KEYS: {
+ } break;
+ case ClickOver::CLICK_MOVE_KEYS: {
- click.to = Point2(mb.x, mb.y);
- if (click.to.y < h && click.at.y > h && mb.relative_y < 0) {
+ click.to = mm->get_position();
+ } break;
+ default: {}
+ }
- float prev = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() - 1);
- if (prev != v_scroll->get_value())
- click.at.y += h;
- }
- if (click.to.y > size.height && click.at.y < size.height && mb.relative_y > 0) {
+ return;
+ } else if (mm->get_button_mask() & BUTTON_MASK_MIDDLE) {
- float prev = v_scroll->get_value();
- v_scroll->set_value(v_scroll->get_value() + 1);
- if (prev != v_scroll->get_value())
- click.at.y -= h;
- }
+ int rel = mm->get_relative().x;
+ float relf = rel / _get_zoom_scale();
+ h_scroll->set_value(h_scroll->get_value() - relf);
+ }
- } break;
- case ClickOver::CLICK_MOVE_KEYS: {
+ if (mm->get_button_mask() == 0) {
- click.to = Point2(mb.x, mb.y);
- } break;
- default: {}
- }
+ Point2 mpos = mm->get_position() - ofs;
+ if (mpos.y < h) {
+#if 0
+ //seek
+ //int zoomw = settings_limit-name_limit;
+ float scale = _get_zoom_scale();
+ float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale;
+ if (pos<0 )
+ pos=0;
+ if (pos>=animation->get_length())
+ pos=animation->get_length();
+ timeline->set_val(pos);
+#endif
return;
- } else if (mb.button_mask & BUTTON_MASK_MIDDLE) {
-
- int rel = mb.relative_x;
- float relf = rel / _get_zoom_scale();
- h_scroll->set_value(h_scroll->get_value() - relf);
}
- if (mb.button_mask == 0) {
+ mpos.y -= h;
- Point2 mpos = Point2(mb.x, mb.y) - ofs;
+ int idx = mpos.y / h;
+ idx += v_scroll->get_value();
+ if (idx < 0 || idx >= animation->get_track_count())
+ return;
- if (mpos.y < h) {
-#if 0
- //seek
- //int zoomw = settings_limit-name_limit;
- float scale = _get_zoom_scale();
- float pos = h_scroll->get_val() + (mpos.y-name_limit) / scale;
- if (pos<0 )
- pos=0;
- if (pos>=animation->get_length())
- pos=animation->get_length();
- timeline->set_val(pos);
-#endif
- return;
- }
+ mouse_over.track = idx;
- mpos.y -= h;
+ if (mpos.x < name_limit) {
+ //name column
- int idx = mpos.y / h;
- idx += v_scroll->get_value();
- if (idx < 0 || idx >= animation->get_track_count())
- break;
+ mouse_over.over = MouseOver::OVER_NAME;
- mouse_over.track = idx;
+ } else if (mpos.x < settings_limit) {
- if (mpos.x < name_limit) {
- //name column
+ float pos = mpos.x - name_limit;
+ pos /= _get_zoom_scale();
+ pos += h_scroll->get_value();
+ float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
- mouse_over.over = MouseOver::OVER_NAME;
+ int kidx = animation->track_find_key(idx, pos);
+ int kidx_n = kidx + 1;
- } else if (mpos.x < settings_limit) {
+ bool found = false;
- float pos = mpos.x - name_limit;
- pos /= _get_zoom_scale();
- pos += h_scroll->get_value();
- float w_time = (type_icon[0]->get_width() / _get_zoom_scale()) / 2.0;
+ if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
- int kidx = animation->track_find_key(idx, pos);
- int kidx_n = kidx + 1;
+ float kpos = animation->track_get_key_time(idx, kidx);
+ if (ABS(pos - kpos) <= w_time) {
- bool found = false;
+ mouse_over.over = MouseOver::OVER_KEY;
+ mouse_over.track = idx;
+ mouse_over.over_key = kidx;
+ found = true;
+ }
+ }
- if (kidx >= 0 && kidx < animation->track_get_key_count(idx)) {
+ if (!found && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
- float kpos = animation->track_get_key_time(idx, kidx);
- if (ABS(pos - kpos) <= w_time) {
+ float kpos = animation->track_get_key_time(idx, kidx_n);
+ if (ABS(pos - kpos) <= w_time) {
- mouse_over.over = MouseOver::OVER_KEY;
- mouse_over.track = idx;
- mouse_over.over_key = kidx;
- found = true;
- }
+ mouse_over.over = MouseOver::OVER_KEY;
+ mouse_over.track = idx;
+ mouse_over.over_key = kidx_n;
+ found = true;
}
+ }
- if (!found && kidx_n >= 0 && kidx_n < animation->track_get_key_count(idx)) {
+ if (found) {
- float kpos = animation->track_get_key_time(idx, kidx_n);
- if (ABS(pos - kpos) <= w_time) {
+ String text;
+ text = "time: " + rtos(animation->track_get_key_time(idx, mouse_over.over_key)) + "\n";
- mouse_over.over = MouseOver::OVER_KEY;
- mouse_over.track = idx;
- mouse_over.over_key = kidx_n;
- found = true;
- }
- }
+ switch (animation->track_get_type(idx)) {
- if (found) {
-
- String text;
- text = "time: " + rtos(animation->track_get_key_time(idx, mouse_over.over_key)) + "\n";
-
- switch (animation->track_get_type(idx)) {
-
- case Animation::TYPE_TRANSFORM: {
-
- Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key);
- if (d.has("loc"))
- text += "loc: " + String(d["loc"]) + "\n";
- if (d.has("rot"))
- text += "rot: " + String(d["rot"]) + "\n";
- if (d.has("scale"))
- text += "scale: " + String(d["scale"]) + "\n";
- } break;
- case Animation::TYPE_VALUE: {
-
- Variant v = animation->track_get_key_value(idx, mouse_over.over_key);
- //text+="value: "+String(v)+"\n";
-
- bool prop_exists = false;
- Variant::Type valid_type = Variant::NIL;
- Object *obj = NULL;
-
- RES res;
- Node *node = root->get_node_and_resource(animation->track_get_path(idx), res);
-
- if (res.is_valid()) {
- obj = res.ptr();
- } else if (node) {
- obj = node;
- }
-
- if (obj) {
- valid_type = obj->get_static_property_type(animation->track_get_path(idx).get_property(), &prop_exists);
- }
-
- text += "type: " + Variant::get_type_name(v.get_type()) + "\n";
- if (prop_exists && !Variant::can_convert(v.get_type(), valid_type)) {
- text += "value: " + String(v) + " (Invalid, expected type: " + Variant::get_type_name(valid_type) + ")\n";
- } else {
- text += "value: " + String(v) + "\n";
- }
-
- } break;
- case Animation::TYPE_METHOD: {
-
- Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key);
- if (d.has("method"))
- text += String(d["method"]);
- text += "(";
- Vector<Variant> args;
- if (d.has("args"))
- args = d["args"];
- for (int i = 0; i < args.size(); i++) {
-
- if (i > 0)
- text += ", ";
- text += String(args[i]);
- }
- text += ")\n";
-
- } break;
- }
- text += "easing: " + rtos(animation->track_get_key_transition(idx, mouse_over.over_key));
+ case Animation::TYPE_TRANSFORM: {
- track_editor->set_tooltip(text);
- return;
- }
+ Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key);
+ if (d.has("loc"))
+ text += "loc: " + String(d["loc"]) + "\n";
+ if (d.has("rot"))
+ text += "rot: " + String(d["rot"]) + "\n";
+ if (d.has("scale"))
+ text += "scale: " + String(d["scale"]) + "\n";
+ } break;
+ case Animation::TYPE_VALUE: {
- } else {
- //button column
- int ofsx = size.width - mpos.x;
- if (ofsx < 0)
- break;
- /*
- if (ofsx < remove_icon->get_width()) {
+ Variant v = animation->track_get_key_value(idx, mouse_over.over_key);
+ //text+="value: "+String(v)+"\n";
- mouse_over.over=MouseOver::OVER_REMOVE;
+ bool prop_exists = false;
+ Variant::Type valid_type = Variant::NIL;
+ Object *obj = NULL;
- return;
- }
+ RES res;
+ Node *node = root->get_node_and_resource(animation->track_get_path(idx), res);
- ofsx-=hsep+remove_icon->get_width();
+ if (res.is_valid()) {
+ obj = res.ptr();
+ } else if (node) {
+ obj = node;
+ }
- if (ofsx < move_down_icon->get_width()) {
+ if (obj) {
+ valid_type = obj->get_static_property_type(animation->track_get_path(idx).get_property(), &prop_exists);
+ }
- mouse_over.over=MouseOver::OVER_DOWN;
- return;
+ text += "type: " + Variant::get_type_name(v.get_type()) + "\n";
+ if (prop_exists && !Variant::can_convert(v.get_type(), valid_type)) {
+ text += "value: " + String(v) + " (Invalid, expected type: " + Variant::get_type_name(valid_type) + ")\n";
+ } else {
+ text += "value: " + String(v) + "\n";
+ }
+
+ } break;
+ case Animation::TYPE_METHOD: {
+
+ Dictionary d = animation->track_get_key_value(idx, mouse_over.over_key);
+ if (d.has("method"))
+ text += String(d["method"]);
+ text += "(";
+ Vector<Variant> args;
+ if (d.has("args"))
+ args = d["args"];
+ for (int i = 0; i < args.size(); i++) {
+
+ if (i > 0)
+ text += ", ";
+ text += String(args[i]);
+ }
+ text += ")\n";
+
+ } break;
}
+ text += "easing: " + rtos(animation->track_get_key_transition(idx, mouse_over.over_key));
- ofsx-=hsep+move_down_icon->get_width();
+ track_editor->set_tooltip(text);
+ return;
+ }
- if (ofsx < move_up_icon->get_width()) {
+ } else {
+ //button column
+ int ofsx = size.width - mpos.x;
+ if (ofsx < 0)
+ return;
+ /*
+ if (ofsx < remove_icon->get_width()) {
- mouse_over.over=MouseOver::OVER_UP;
- return;
- }
+ mouse_over.over=MouseOver::OVER_REMOVE;
- ofsx-=hsep*3+move_up_icon->get_width();
+ return;
+ }
- */
+ ofsx-=hsep+remove_icon->get_width();
- if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep * 3) {
+ if (ofsx < move_down_icon->get_width()) {
- mouse_over.over = MouseOver::OVER_WRAP;
- return;
- }
+ mouse_over.over=MouseOver::OVER_DOWN;
+ return;
+ }
- ofsx -= hsep * 3 + wrap_icon[0]->get_width() + down_icon->get_width();
+ ofsx-=hsep+move_down_icon->get_width();
- if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep * 3) {
+ if (ofsx < move_up_icon->get_width()) {
- mouse_over.over = MouseOver::OVER_INTERP;
- return;
- }
+ mouse_over.over=MouseOver::OVER_UP;
+ return;
+ }
- ofsx -= hsep * 2 + interp_icon[0]->get_width() + down_icon->get_width();
+ ofsx-=hsep*3+move_up_icon->get_width();
- if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() + hsep * 3) {
+*/
- mouse_over.over = MouseOver::OVER_VALUE;
- return;
- }
+ if (ofsx < down_icon->get_width() + wrap_icon[0]->get_width() + hsep * 3) {
- ofsx -= hsep * 3 + cont_icon[0]->get_width() + down_icon->get_width();
+ mouse_over.over = MouseOver::OVER_WRAP;
+ return;
+ }
- if (ofsx < add_key_icon->get_width()) {
+ ofsx -= hsep * 3 + wrap_icon[0]->get_width() + down_icon->get_width();
- mouse_over.over = MouseOver::OVER_ADD_KEY;
- return;
- }
+ if (ofsx < down_icon->get_width() + interp_icon[0]->get_width() + hsep * 3) {
+
+ mouse_over.over = MouseOver::OVER_INTERP;
+ return;
}
- }
- } break;
+ ofsx -= hsep * 2 + interp_icon[0]->get_width() + down_icon->get_width();
+
+ if (ofsx < down_icon->get_width() + cont_icon[0]->get_width() + hsep * 3) {
+
+ mouse_over.over = MouseOver::OVER_VALUE;
+ return;
+ }
+
+ ofsx -= hsep * 3 + cont_icon[0]->get_width() + down_icon->get_width();
+
+ if (ofsx < add_key_icon->get_width()) {
+
+ mouse_over.over = MouseOver::OVER_ADD_KEY;
+ return;
+ }
+ }
+ }
}
}
@@ -2891,6 +2900,8 @@ void AnimationKeyEditor::_notification(int p_what) {
key_editor->edit(key_edit);
zoomicon->set_texture(get_icon("Zoom", "EditorIcons"));
+ zoomicon->set_custom_minimum_size(Size2(24 * EDSCALE, 0));
+ zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
menu_add_track->set_icon(get_icon("AddTrack", "EditorIcons"));
menu_add_track->get_popup()->add_icon_item(get_icon("KeyValue", "EditorIcons"), "Add Normal Track", ADD_TRACK_MENU_ADD_VALUE_TRACK);
@@ -3753,7 +3764,6 @@ AnimationKeyEditor::AnimationKeyEditor() {
//add_child(menu);
zoomicon = memnew(TextureRect);
- zoomicon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
hb->add_child(zoomicon);
zoomicon->set_tooltip(TTR("Animation zoom."));
@@ -3929,6 +3939,7 @@ AnimationKeyEditor::AnimationKeyEditor() {
v_scroll->set_value(0);
key_editor_tab = memnew(TabContainer);
+ key_editor_tab->set_tab_align(TabContainer::ALIGN_LEFT);
hb->add_child(key_editor_tab);
key_editor_tab->set_custom_minimum_size(Size2(200, 0));
diff --git a/editor/animation_editor.h b/editor/animation_editor.h
index 0f6cc95634..128481c837 100644
--- a/editor/animation_editor.h
+++ b/editor/animation_editor.h
@@ -273,7 +273,7 @@ class AnimationKeyEditor : public VBoxContainer {
float _get_zoom_scale() const;
void _track_editor_draw();
- void _track_editor_gui_input(const InputEvent &p_input);
+ void _track_editor_gui_input(const Ref<InputEvent> &p_input);
void _track_pos_draw();
void _track_name_changed(const String &p_name);
diff --git a/editor/asset_library_editor_plugin.cpp b/editor/asset_library_editor_plugin.cpp
index 971adb14cf..fcb92e13b4 100644
--- a/editor/asset_library_editor_plugin.cpp
+++ b/editor/asset_library_editor_plugin.cpp
@@ -683,17 +683,18 @@ void EditorAssetLibrary::_image_update(bool use_cache, bool final, const PoolByt
int len = image_data.size();
PoolByteArray::Read r = image_data.read();
- Image image(r.ptr(), len);
- if (!image.empty()) {
+ Ref<Image> image = Ref<Image>(memnew(Image(r.ptr(), len)));
+
+ if (!image->empty()) {
float max_height = 10000;
switch (image_queue[p_queue_id].image_type) {
case IMAGE_QUEUE_ICON: max_height = 80; break;
case IMAGE_QUEUE_THUMBNAIL: max_height = 80; break;
case IMAGE_QUEUE_SCREENSHOT: max_height = 345; break;
}
- float scale_ratio = max_height / image.get_height();
+ float scale_ratio = max_height / image->get_height();
if (scale_ratio < 1) {
- image.resize(image.get_width() * scale_ratio, image.get_height() * scale_ratio, Image::INTERPOLATE_CUBIC);
+ image->resize(image->get_width() * scale_ratio, image->get_height() * scale_ratio, Image::INTERPOLATE_CUBIC);
}
Ref<ImageTexture> tex;
diff --git a/editor/code_editor.cpp b/editor/code_editor.cpp
index a84d65de0e..2e406fb23d 100644
--- a/editor/code_editor.cpp
+++ b/editor/code_editor.cpp
@@ -94,17 +94,16 @@ void FindReplaceBar::_notification(int p_what) {
}
}
-void FindReplaceBar::_unhandled_input(const InputEvent &p_event) {
+void FindReplaceBar::_unhandled_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid()) {
- const InputEventKey &k = p_event.key;
-
- if (k.pressed && (text_edit->has_focus() || text_vbc->is_a_parent_of(get_focus_owner()))) {
+ if (k->is_pressed() && (text_edit->has_focus() || text_vbc->is_a_parent_of(get_focus_owner()))) {
bool accepted = true;
- switch (k.scancode) {
+ switch (k->get_scancode()) {
case KEY_ESCAPE: {
@@ -957,23 +956,27 @@ FindReplaceDialog::FindReplaceDialog() {
/*** CODE EDITOR ****/
-void CodeTextEditor::_text_editor_gui_input(const InputEvent &p_event) {
+void CodeTextEditor::_text_editor_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_event;
- const InputEventMouseButton &mb = p_event.mouse_button;
+ if (mb.is_valid()) {
- if (mb.pressed && mb.mod.command) {
+ if (mb->is_pressed() && mb->get_command()) {
- if (mb.button_index == BUTTON_WHEEL_UP) {
+ if (mb->get_button_index() == BUTTON_WHEEL_UP) {
_zoom_in();
- } else if (mb.button_index == BUTTON_WHEEL_DOWN) {
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
_zoom_out();
}
}
- } else if (p_event.type == InputEvent::KEY) {
+ }
+
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid()) {
- if (p_event.key.pressed) {
+ if (k->is_pressed()) {
if (ED_IS_SHORTCUT("script_editor/zoom_in", p_event)) {
_zoom_in();
}
diff --git a/editor/code_editor.h b/editor/code_editor.h
index 44d526fda9..8d48c56503 100644
--- a/editor/code_editor.h
+++ b/editor/code_editor.h
@@ -100,7 +100,7 @@ class FindReplaceBar : public HBoxContainer {
protected:
void _notification(int p_what);
- void _unhandled_input(const InputEvent &p_event);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
bool _search(uint32_t p_flags, int p_from_line, int p_from_col);
@@ -213,7 +213,7 @@ class CodeTextEditor : public VBoxContainer {
void _complete_request();
void _font_resize_timeout();
- void _text_editor_gui_input(const InputEvent &p_event);
+ void _text_editor_gui_input(const Ref<InputEvent> &p_event);
void _zoom_in();
void _zoom_out();
void _reset_zoom();
diff --git a/editor/connections_dialog.cpp b/editor/connections_dialog.cpp
index 93c2b7493c..9762bd2000 100644
--- a/editor/connections_dialog.cpp
+++ b/editor/connections_dialog.cpp
@@ -239,7 +239,6 @@ void ConnectDialog::_add_bind() {
case Variant::BASIS: value = Basis(); break;
case Variant::TRANSFORM: value = Transform(); break;
case Variant::COLOR: value = Color(); break;
- case Variant::IMAGE: value = Image(); break;
default: { ERR_FAIL(); } break;
}
@@ -327,7 +326,6 @@ ConnectDialog::ConnectDialog() {
type_list->add_item("Transform", Variant::TRANSFORM);
//type_list->add_separator();
type_list->add_item("Color", Variant::COLOR);
- type_list->add_item("Image", Variant::IMAGE);
type_list->select(0);
Button *add_bind = memnew(Button);
@@ -419,6 +417,10 @@ void ConnectionsDock::_notification(int p_what) {
//RID ci = get_canvas_item();
//get_stylebox("panel","PopupMenu")->draw(ci,Rect2(Point2(),get_size()));
}
+
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ update_tree();
+ }
}
void ConnectionsDock::_close() {
diff --git a/editor/create_dialog.cpp b/editor/create_dialog.cpp
index 7c9dae1e3f..1089068344 100644
--- a/editor/create_dialog.cpp
+++ b/editor/create_dialog.cpp
@@ -109,14 +109,15 @@ void CreateDialog::_text_changed(const String &p_newtext) {
_update_search();
}
-void CreateDialog::_sbox_input(const InputEvent &p_ie) {
+void CreateDialog::_sbox_input(const Ref<InputEvent> &p_ie) {
- if (p_ie.type == InputEvent::KEY && (p_ie.key.scancode == KEY_UP ||
- p_ie.key.scancode == KEY_DOWN ||
- p_ie.key.scancode == KEY_PAGEUP ||
- p_ie.key.scancode == KEY_PAGEDOWN)) {
+ Ref<InputEventKey> k = p_ie;
+ if (k.is_valid() && (k->get_scancode() == KEY_UP ||
+ k->get_scancode() == KEY_DOWN ||
+ k->get_scancode() == KEY_PAGEUP ||
+ k->get_scancode() == KEY_PAGEDOWN)) {
- search_options->call("_gui_input", p_ie);
+ search_options->call("_gui_input", k);
search_box->accept_event();
}
}
@@ -202,7 +203,7 @@ void CreateDialog::_update_search() {
}
List<StringName>::Element *I = type_list.front();
- TreeItem *to_select = NULL;
+ TreeItem *to_select = search_box->get_text() == base_type ? root : NULL;
for (; I; I = I->next()) {
@@ -488,11 +489,13 @@ void CreateDialog::_favorite_selected() {
void CreateDialog::_history_activated() {
+ _history_selected();
_confirmed();
}
void CreateDialog::_favorite_activated() {
+ _favorite_selected();
_confirmed();
}
@@ -622,7 +625,6 @@ CreateDialog::CreateDialog() {
search_box->set_h_size_flags(SIZE_EXPAND_FILL);
search_hb->add_child(search_box);
favorite = memnew(Button);
- favorite->set_flat(true);
favorite->set_toggle_mode(true);
search_hb->add_child(favorite);
favorite->connect("pressed", this, "_favorite_toggled");
diff --git a/editor/create_dialog.h b/editor/create_dialog.h
index 6170149c6b..02ce762726 100644
--- a/editor/create_dialog.h
+++ b/editor/create_dialog.h
@@ -69,7 +69,7 @@ class CreateDialog : public ConfirmationDialog {
void _history_activated();
void _favorite_activated();
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _confirmed();
void _text_changed(const String &p_newtext);
diff --git a/editor/doc/doc_data.cpp b/editor/doc/doc_data.cpp
index af95f8d919..6a79f99354 100644
--- a/editor/doc/doc_data.cpp
+++ b/editor/doc/doc_data.cpp
@@ -295,8 +295,8 @@ void DocData::generate(bool p_basic_types) {
case Variant::REAL:
//keep it
break;
- case Variant::STRING: // 15
- case Variant::NODE_PATH: // 15
+ case Variant::STRING:
+ case Variant::NODE_PATH:
default_arg_text = "\"" + default_arg_text + "\"";
break;
case Variant::TRANSFORM:
@@ -307,19 +307,19 @@ void DocData::generate(bool p_basic_types) {
default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
break;
- case Variant::RECT3: //sorry naming convention fail :( not like it's used often // 10
+ case Variant::RECT3:
case Variant::COLOR:
case Variant::PLANE:
case Variant::POOL_BYTE_ARRAY:
case Variant::POOL_INT_ARRAY:
case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY: //25
+ case Variant::POOL_STRING_ARRAY:
case Variant::POOL_VECTOR2_ARRAY:
case Variant::POOL_VECTOR3_ARRAY:
case Variant::POOL_COLOR_ARRAY:
default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
break;
- case Variant::VECTOR2: // 5
+ case Variant::VECTOR2:
case Variant::RECT2:
case Variant::VECTOR3:
case Variant::QUAT:
@@ -331,15 +331,10 @@ void DocData::generate(bool p_basic_types) {
default_arg_text = "NULL";
break;
}
- case Variant::INPUT_EVENT:
case Variant::DICTIONARY: // 20
case Variant::ARRAY:
case Variant::_RID:
- case Variant::IMAGE:
- //case Variant::RESOURCE:
- default_arg_text = Variant::get_type_name(default_arg.get_type()) + "()";
- break;
default: {}
}
@@ -481,97 +476,78 @@ void DocData::generate(bool p_basic_types) {
if (i == Variant::OBJECT)
continue; //use the core type instead
- int loops = 1;
-
- if (i == Variant::INPUT_EVENT)
- loops = InputEvent::TYPE_MAX;
-
- for (int j = 0; j < loops; j++) {
-
- String cname = Variant::get_type_name(Variant::Type(i));
-
- if (i == Variant::INPUT_EVENT) {
- static const char *ie_type[InputEvent::TYPE_MAX] = {
- "", "Key", "MouseMotion", "MouseButton", "JoypadMotion", "JoypadButton", "ScreenTouch", "ScreenDrag", "Action"
- };
- cname += ie_type[j];
- }
-
- class_list[cname] = ClassDoc();
- ClassDoc &c = class_list[cname];
- c.name = cname;
- c.category = "Built-In Types";
+ String cname = Variant::get_type_name(Variant::Type(i));
- Variant::CallError cerror;
- Variant v = Variant::construct(Variant::Type(i), NULL, 0, cerror);
-
- if (i == Variant::INPUT_EVENT) {
- v.set("type", j);
- }
+ class_list[cname] = ClassDoc();
+ ClassDoc &c = class_list[cname];
+ c.name = cname;
+ c.category = "Built-In Types";
- List<MethodInfo> method_list;
- v.get_method_list(&method_list);
- method_list.sort();
- Variant::get_constructor_list(Variant::Type(i), &method_list);
+ Variant::CallError cerror;
+ Variant v = Variant::construct(Variant::Type(i), NULL, 0, cerror);
- for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
+ List<MethodInfo> method_list;
+ v.get_method_list(&method_list);
+ method_list.sort();
+ Variant::get_constructor_list(Variant::Type(i), &method_list);
- MethodInfo &mi = E->get();
- MethodDoc method;
+ for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) {
- method.name = mi.name;
+ MethodInfo &mi = E->get();
+ MethodDoc method;
- for (int i = 0; i < mi.arguments.size(); i++) {
+ method.name = mi.name;
- ArgumentDoc arg;
- PropertyInfo pi = mi.arguments[i];
+ for (int i = 0; i < mi.arguments.size(); i++) {
- arg.name = pi.name;
- //print_line("arg name: "+arg.name);
- if (pi.type == Variant::NIL)
- arg.type = "var";
- else
- arg.type = Variant::get_type_name(pi.type);
- int defarg = mi.default_arguments.size() - mi.arguments.size() + i;
- if (defarg >= 0)
- arg.default_value = mi.default_arguments[defarg];
+ ArgumentDoc arg;
+ PropertyInfo pi = mi.arguments[i];
- method.arguments.push_back(arg);
- }
+ arg.name = pi.name;
+ //print_line("arg name: "+arg.name);
+ if (pi.type == Variant::NIL)
+ arg.type = "var";
+ else
+ arg.type = Variant::get_type_name(pi.type);
+ int defarg = mi.default_arguments.size() - mi.arguments.size() + i;
+ if (defarg >= 0)
+ arg.default_value = mi.default_arguments[defarg];
- if (mi.return_val.type == Variant::NIL) {
- if (mi.return_val.name != "")
- method.return_type = "var";
+ method.arguments.push_back(arg);
+ }
- } else {
- method.return_type = Variant::get_type_name(mi.return_val.type);
- }
+ if (mi.return_val.type == Variant::NIL) {
+ if (mi.return_val.name != "")
+ method.return_type = "var";
- c.methods.push_back(method);
+ } else {
+ method.return_type = Variant::get_type_name(mi.return_val.type);
}
- List<PropertyInfo> properties;
- v.get_property_list(&properties);
- for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
+ c.methods.push_back(method);
+ }
- PropertyInfo pi = E->get();
- PropertyDoc property;
- property.name = pi.name;
- property.type = Variant::get_type_name(pi.type);
+ List<PropertyInfo> properties;
+ v.get_property_list(&properties);
+ for (List<PropertyInfo>::Element *E = properties.front(); E; E = E->next()) {
- c.properties.push_back(property);
- }
+ PropertyInfo pi = E->get();
+ PropertyDoc property;
+ property.name = pi.name;
+ property.type = Variant::get_type_name(pi.type);
+
+ c.properties.push_back(property);
+ }
- List<StringName> constants;
- Variant::get_numeric_constants_for_type(Variant::Type(i), &constants);
+ List<StringName> constants;
+ Variant::get_numeric_constants_for_type(Variant::Type(i), &constants);
- for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
+ for (List<StringName>::Element *E = constants.front(); E; E = E->next()) {
- ConstantDoc constant;
- constant.name = E->get();
- constant.value = itos(Variant::get_numeric_constant_value(Variant::Type(i), E->get()));
- c.constants.push_back(constant);
- }
+ ConstantDoc constant;
+ constant.name = E->get();
+ constant.value = itos(Variant::get_numeric_constant_value(Variant::Type(i), E->get()));
+ c.constants.push_back(constant);
}
}
diff --git a/editor/doc/doc_dump.cpp b/editor/doc/doc_dump.cpp
index bda4d80f4d..79a8f79a7c 100644
--- a/editor/doc/doc_dump.cpp
+++ b/editor/doc/doc_dump.cpp
@@ -165,8 +165,8 @@ void DocDump::dump(const String &p_file) {
case Variant::REAL:
//keep it
break;
- case Variant::STRING: // 15
- case Variant::NODE_PATH: // 15
+ case Variant::STRING:
+ case Variant::NODE_PATH:
default_arg_text = "\"" + default_arg_text + "\"";
break;
case Variant::TRANSFORM:
@@ -177,32 +177,27 @@ void DocDump::dump(const String &p_file) {
default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
break;
- case Variant::VECTOR2: // 5
+ case Variant::VECTOR2:
case Variant::RECT2:
case Variant::VECTOR3:
case Variant::PLANE:
case Variant::QUAT:
- case Variant::RECT3: //sorry naming convention fail :( not like it's used often // 10
+ case Variant::RECT3:
case Variant::BASIS:
case Variant::COLOR:
case Variant::POOL_BYTE_ARRAY:
case Variant::POOL_INT_ARRAY:
case Variant::POOL_REAL_ARRAY:
- case Variant::POOL_STRING_ARRAY: //25
+ case Variant::POOL_STRING_ARRAY:
case Variant::POOL_VECTOR3_ARRAY:
case Variant::POOL_COLOR_ARRAY:
default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")";
break;
case Variant::OBJECT:
- case Variant::INPUT_EVENT:
case Variant::DICTIONARY: // 20
case Variant::ARRAY:
case Variant::_RID:
- case Variant::IMAGE:
- //case Variant::RESOURCE:
- default_arg_text = Variant::get_type_name(default_arg.get_type()) + "()";
- break;
default: {}
}
diff --git a/editor/editor_asset_installer.cpp b/editor/editor_asset_installer.cpp
index 5a54f9b46f..96bfb295ea 100644
--- a/editor/editor_asset_installer.cpp
+++ b/editor/editor_asset_installer.cpp
@@ -113,13 +113,13 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
extension_guess["png"] = get_icon("Texture", "EditorIcons");
extension_guess["jpg"] = get_icon("Texture", "EditorIcons");
extension_guess["tex"] = get_icon("Texture", "EditorIcons");
- extension_guess["atex"] = get_icon("Texture", "EditorIcons");
+ extension_guess["atlastex"] = get_icon("Texture", "EditorIcons");
extension_guess["dds"] = get_icon("Texture", "EditorIcons");
extension_guess["scn"] = get_icon("PackedScene", "EditorIcons");
extension_guess["tscn"] = get_icon("PackedScene", "EditorIcons");
extension_guess["xml"] = get_icon("PackedScene", "EditorIcons");
extension_guess["xscn"] = get_icon("PackedScene", "EditorIcons");
- extension_guess["mtl"] = get_icon("Material", "EditorIcons");
+ extension_guess["material"] = get_icon("Material", "EditorIcons");
extension_guess["shd"] = get_icon("Shader", "EditorIcons");
extension_guess["gd"] = get_icon("GDScript", "EditorIcons");
}
@@ -184,6 +184,7 @@ void EditorAssetInstaller::open(const String &p_path, int p_depth) {
dir_map[path] = ti;
ti->set_text(0, path.get_file() + "/");
ti->set_icon(0, get_icon("folder", "FileDialog"));
+ ti->set_metadata(0, String());
} else {
String file = path.get_file();
String extension = file.get_extension().to_lower();
@@ -305,6 +306,7 @@ void EditorAssetInstaller::ok_pressed() {
if (EditorNode::get_singleton() != NULL)
EditorNode::get_singleton()->show_warning("Package Installed Successfully!", "Success!");
}
+ EditorFileSystem::get_singleton()->scan_changes();
}
void EditorAssetInstaller::_bind_methods() {
diff --git a/editor/editor_audio_buses.cpp b/editor/editor_audio_buses.cpp
index 1129a7d633..e3e5793ec8 100644
--- a/editor/editor_audio_buses.cpp
+++ b/editor/editor_audio_buses.cpp
@@ -45,10 +45,6 @@ void EditorAudioBus::_notification(int p_what) {
vu_r->set_progress_texture(get_icon("BusVuFull", "EditorIcons"));
scale->set_texture(get_icon("BusVuDb", "EditorIcons"));
- solo->set_icon(get_icon("AudioBusSolo", "EditorIcons"));
- mute->set_icon(get_icon("AudioBusMute", "EditorIcons"));
- bypass->set_icon(get_icon("AudioBusBypass", "EditorIcons"));
-
disabled_vu = get_icon("BusVuFrozen", "EditorIcons");
prev_active = true;
@@ -346,7 +342,7 @@ void EditorAudioBus::_effect_edited() {
if (effect->get_metadata(0) == Variant()) {
Rect2 area = effects->get_item_rect(effect);
- effect_options->set_position(effects->get_global_position() + area.pos + Vector2(0, area.size.y));
+ effect_options->set_position(effects->get_global_position() + area.position + Vector2(0, area.size.y));
effect_options->popup();
//add effect
} else {
@@ -389,15 +385,18 @@ void EditorAudioBus::_effect_add(int p_which) {
ur->commit_action();
}
-void EditorAudioBus::_gui_input(const InputEvent &p_event) {
+void EditorAudioBus::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && !p_event.key.echo) {
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && !k->is_echo()) {
accept_event();
emit_signal("delete_request");
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 2 && p_event.mouse_button.pressed) {
- Vector2 pos = Vector2(p_event.mouse_button.x, p_event.mouse_button.y);
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) {
+
+ Vector2 pos = Vector2(mb->get_position().x, mb->get_position().y);
delete_popup->set_position(get_global_position() + pos);
delete_popup->popup();
}
@@ -631,23 +630,26 @@ EditorAudioBus::EditorAudioBus(EditorAudioBuses *p_buses) {
vb->add_child(hbc);
hbc->add_spacer();
solo = memnew(ToolButton);
- solo->set_tooltip(TTR("Toggle Solo"));
+ solo->set_text("S");
solo->set_toggle_mode(true);
- // solo->set_modulate(Color(0.8, 1.2, 0.8));
+ solo->add_color_override("font_color_pressed", Color(0.2, 0.9, 0.2));
+ solo->add_color_override("font_color_hover", Color(0.6, 0.9, 0.6));
solo->set_focus_mode(FOCUS_NONE);
solo->connect("pressed", this, "_solo_toggled");
hbc->add_child(solo);
mute = memnew(ToolButton);
- mute->connect("pressed", this, "_mute_toggled");
+ mute->set_text("M");
mute->set_toggle_mode(true);
- // mute->set_modulate(Color(1.2, 0.8, 0.8));
+ mute->add_color_override("font_color_pressed", Color(0.9, 0.2, 0.2));
+ mute->add_color_override("font_color_hover", Color(0.9, 0.6, 0.6));
mute->set_focus_mode(FOCUS_NONE);
- mute->set_tooltip(TTR("Toggle Mute"));
+ mute->connect("pressed", this, "_mute_toggled");
hbc->add_child(mute);
bypass = memnew(ToolButton);
- bypass->set_tooltip(TTR("Toggle Bypass"));
+ bypass->set_text("B");
bypass->set_toggle_mode(true);
- // bypass->set_modulate(Color(1.1, 1.1, 0.8));
+ bypass->add_color_override("font_color_pressed", Color(0.9, 0.9, 0.2));
+ bypass->add_color_override("font_color_hover", Color(0.9, 0.9, 0.6));
bypass->set_focus_mode(FOCUS_NONE);
bypass->connect("pressed", this, "_bypass_toggled");
hbc->add_child(bypass);
@@ -767,7 +769,7 @@ void EditorAudioBuses::_update_buses() {
EditorAudioBus *audio_bus = memnew(EditorAudioBus(this));
if (i == 0) {
- audio_bus->set_self_modulate(Color(0.7, 0.7, 0.7));
+ audio_bus->set_self_modulate(Color(1, 0.9, 0.9));
}
bus_hb->add_child(audio_bus);
audio_bus->connect("delete_request", this, "_delete_bus", varray(audio_bus), CONNECT_DEFERRED);
@@ -1109,9 +1111,9 @@ EditorAudioBuses::EditorAudioBuses() {
file_dialog = memnew(EditorFileDialog);
List<String> ext;
- ResourceLoader::get_recognized_extensions_for_type("AudioServerState", &ext);
+ ResourceLoader::get_recognized_extensions_for_type("AudioBusLayout", &ext);
for (List<String>::Element *E = ext.front(); E; E = E->next()) {
- file_dialog->add_filter("*." + E->get() + "; Audio Bus State");
+ file_dialog->add_filter("*." + E->get() + "; Audio Bus Layout");
}
add_child(file_dialog);
file_dialog->connect("file_selected", this, "_file_dialog_callback");
diff --git a/editor/editor_audio_buses.h b/editor/editor_audio_buses.h
index 4a3d784796..f5bf464fd0 100644
--- a/editor/editor_audio_buses.h
+++ b/editor/editor_audio_buses.h
@@ -75,7 +75,7 @@ class EditorAudioBus : public PanelContainer {
bool updating_bus;
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _delete_pressed(int p_option);
void _name_changed(const String &p_new_name);
diff --git a/editor/editor_data.cpp b/editor/editor_data.cpp
index 31c1402c8f..58ffa223fb 100644
--- a/editor/editor_data.cpp
+++ b/editor/editor_data.cpp
@@ -675,7 +675,12 @@ String EditorData::get_scene_title(int p_idx) const {
return "[empty]";
if (edited_scene[p_idx].root->get_filename() == "")
return "[unsaved]";
- return edited_scene[p_idx].root->get_filename().get_file();
+ bool show_ext = EDITOR_DEF("interface/scene_tabs/show_extension", false);
+ String name = edited_scene[p_idx].root->get_filename().get_file();
+ if (!show_ext) {
+ name = name.get_basename();
+ }
+ return name;
}
String EditorData::get_scene_path(int p_idx) const {
diff --git a/editor/editor_export.cpp b/editor/editor_export.cpp
index 4796640a3d..5cd00738a2 100644
--- a/editor/editor_export.cpp
+++ b/editor/editor_export.cpp
@@ -210,7 +210,8 @@ EditorExportPreset::EditorExportPreset() {
void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) {
- String host = EditorSettings::get_singleton()->get("network/debug_host");
+ String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST)
host = "localhost";
@@ -230,7 +231,7 @@ void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags)
r_flags.push_back("-rdebug");
- r_flags.push_back(host + ":" + String::num(GLOBAL_DEF("network/debug/remote_port", 6007)));
+ r_flags.push_back(host + ":" + String::num(remote_port));
List<String> breakpoints;
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
@@ -321,7 +322,7 @@ Error EditorExportPlatform::_save_zip_file(void *p_userdata, const String &p_pat
return OK;
}
-String EditorExportPlatform::find_export_template(String template_file_name) const {
+String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
String base_name = itos(VERSION_MAJOR) + "." + itos(VERSION_MINOR) + "-" + _MKSTR(VERSION_STATUS) + "/" + template_file_name;
String user_file = EditorSettings::get_singleton()->get_settings_path() + "/templates/" + base_name;
@@ -342,9 +343,20 @@ String EditorExportPlatform::find_export_template(String template_file_name) con
return system_file;
}
}
- print_line("none,sorry");
- return String(); //not found
+ // Not found
+ if (err) {
+ *err += "No export template found at \"" + user_file + "\"";
+ if (has_system_path)
+ *err += "\n or \"" + system_file + "\".";
+ else
+ *err += ".";
+ }
+ return String(); // not found
+}
+
+bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
+ return find_export_template(template_file_name, err) != "";
}
Ref<EditorExportPreset> EditorExportPlatform::create_preset() {
@@ -609,7 +621,8 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) {
- String host = EditorSettings::get_singleton()->get("network/debug_host");
+ String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
if (p_flags & DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST)
host = "localhost";
@@ -629,7 +642,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
r_flags.push_back("-rdebug");
- r_flags.push_back(host + ":" + String::num(GLOBAL_DEF("network/debug/remote_port", 6007)));
+ r_flags.push_back(host + ":" + String::num(remote_port));
List<String> breakpoints;
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
@@ -925,19 +938,47 @@ Ref<Texture> EditorExportPlatformPC::get_logo() const {
bool EditorExportPlatformPC::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
- r_missing_templates = false;
+ String err;
+ bool valid = true;
+
+ if (use64 && (!exists_export_template(debug_file_64, &err) || !exists_export_template(release_file_64, &err))) {
+ valid = false;
+ }
+
+ if (!use64 && (!exists_export_template(debug_file_32, &err) || !exists_export_template(release_file_32, &err))) {
+ valid = false;
+ }
+
+ String custom_debug_binary = p_preset->get("custom_template/debug");
+ String custom_release_binary = p_preset->get("custom_template/release");
+
+ if (custom_debug_binary == "" && custom_release_binary == "") {
+ if (!err.empty())
+ r_error = err;
+ return valid;
+ }
+
+ bool dvalid = true;
+ bool rvalid = true;
+
+ if (!FileAccess::exists(custom_debug_binary)) {
+ dvalid = false;
+ err = "Custom debug binary not found.\n";
+ }
- if (find_export_template(release_file_32) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(debug_file_32) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(release_file_64) == String()) {
- r_missing_templates = true;
- } else if (find_export_template(debug_file_64) == String()) {
- r_missing_templates = true;
+ if (!FileAccess::exists(custom_release_binary)) {
+ rvalid = false;
+ err += "Custom release binary not found.\n";
}
- return !r_missing_templates;
+ if (dvalid || rvalid)
+ valid = true;
+ else
+ valid = false;
+
+ if (!err.empty())
+ r_error = err;
+ return valid;
}
String EditorExportPlatformPC::get_binary_extension() const {
@@ -1497,40 +1538,6 @@ Vector<StringName> EditorExportPlatform::get_dependencies(bool p_bundles) const
}
-String EditorExportPlatform::find_export_template(String template_file_name, String *err) const {
- String user_file = EditorSettings::get_singleton()->get_settings_path()
- +"/templates/"+template_file_name;
- String system_file=OS::get_singleton()->get_installed_templates_path();
- bool has_system_path=(system_file!="");
- system_file+=template_file_name;
-
- // Prefer user file
- if (FileAccess::exists(user_file)) {
- return user_file;
- }
-
- // Now check system file
- if (has_system_path) {
- if (FileAccess::exists(system_file)) {
- return system_file;
- }
- }
-
- // Not found
- if (err) {
- *err+="No export template found at \""+user_file+"\"";
- if (has_system_path)
- *err+="\n or \""+system_file+"\".";
- else
- *err+=".";
- }
- return "";
-}
-
-bool EditorExportPlatform::exists_export_template(String template_file_name, String *err) const {
- return find_export_template(template_file_name,err)!="";
-}
-
///////////////////////////////////////
@@ -1936,14 +1943,14 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
atex->set_region(region);
atex->set_margin(margin);
- String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpatlas.atex";
+ String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmpatlas.atlastex";
Error err = ResourceSaver::save(path,atex);
if (err!=OK) {
EditorNode::add_io_error(TTR("Could not save atlas subtexture:")+" "+path);
return ERR_CANT_CREATE;
}
Vector<uint8_t> data = FileAccess::get_file_as_array(path);
- String dst_path = F->get().operator String().get_basename()+".atex";
+ String dst_path = F->get().operator String().get_basename()+".atlastex";
err = p_func(p_udata,dst_path,data,counter++,files.size());
saved.insert(dst_path);
if (err)
@@ -2103,7 +2110,8 @@ static int _get_pad(int p_alignment, int p_n) {
void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags) {
- String host = EditorSettings::get_singleton()->get("network/debug_host");
+ String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
if (p_flags&EXPORT_REMOTE_DEBUG_LOCALHOST)
host="localhost";
@@ -2123,7 +2131,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
r_flags.push_back("-rdebug");
- r_flags.push_back(host+":"+String::num(GLOBAL_DEF("network/debug/remote_port", 6007)));
+ r_flags.push_back(host+":"+String::num(remote_port));
List<String> breakpoints;
ScriptEditor::get_singleton()->get_breakpoints(&breakpoints);
@@ -2430,50 +2438,6 @@ void EditorExportPlatformPC::set_binary_extension(const String& p_extension) {
binary_extension=p_extension;
}
-bool EditorExportPlatformPC::can_export(String *r_error) const {
-
- String err;
- bool valid=true;
-
- if (use64 && (!exists_export_template(debug_binary64) || !exists_export_template(release_binary64))) {
- valid=false;
- err="No 64 bits export templates found.\nDownload and install export templates.\n";
- }
-
- if (!use64 && (!exists_export_template(debug_binary32) || !exists_export_template(release_binary32))) {
- valid=false;
- err="No 32 bits export templates found.\nDownload and install export templates.\n";
- }
-
- if(custom_debug_binary=="" && custom_release_binary=="") {
- if (r_error) *r_error=err;
- return valid;
- }
-
- bool dvalid = true;
- bool rvalid = true;
-
- if(!FileAccess::exists(custom_debug_binary)) {
- dvalid = false;
- err = "Custom debug binary not found.\n";
- }
-
- if(!FileAccess::exists(custom_release_binary)) {
- rvalid = false;
- err = "Custom release binary not found.\n";
- }
-
- if (dvalid || rvalid)
- valid = true;
- else
- valid = false;
-
- if (r_error)
- *r_error=err;
- return valid;
-}
-
-
EditorExportPlatformPC::EditorExportPlatformPC() {
export_mode=EXPORT_PACK;
diff --git a/editor/editor_export.h b/editor/editor_export.h
index a78762ad80..740f05174b 100644
--- a/editor/editor_export.h
+++ b/editor/editor_export.h
@@ -154,7 +154,8 @@ private:
protected:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) = 0;
- String find_export_template(String template_file_name) const;
+ bool exists_export_template(String template_file_name, String *err) const;
+ String find_export_template(String template_file_name, String *err = NULL) const;
void gen_export_flags(Vector<String> &r_flags, int p_flags);
public:
@@ -258,6 +259,8 @@ class EditorExportPlatformPC : public EditorExportPlatform {
String debug_file_32;
String debug_file_64;
+ bool use64;
+
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
diff --git a/editor/editor_file_dialog.cpp b/editor/editor_file_dialog.cpp
index 1f97aba221..c2a408e8ab 100644
--- a/editor/editor_file_dialog.cpp
+++ b/editor/editor_file_dialog.cpp
@@ -95,11 +95,13 @@ void EditorFileDialog::_notification(int p_what) {
}
}
-void EditorFileDialog::_unhandled_input(const InputEvent &p_event) {
+void EditorFileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && is_window_modal_on_top()) {
+ Ref<InputEventKey> k = p_event;
- if (p_event.key.pressed) {
+ if (k.is_valid() && is_window_modal_on_top()) {
+
+ if (k->is_pressed()) {
bool handled = false;
@@ -488,8 +490,9 @@ void EditorFileDialog::update_file_list() {
if (!has_icon("ResizedFolder", "EditorIcons")) {
Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
- Image img = folder->get_data();
- img.resize(thumbnail_size, thumbnail_size);
+ Ref<Image> img = folder->get_data();
+ img = img->duplicate();
+ img->resize(thumbnail_size, thumbnail_size);
Ref<ImageTexture> resized_folder = Ref<ImageTexture>(memnew(ImageTexture));
resized_folder->create_from_image(img, 0);
Theme::get_default()->set_icon("ResizedFolder", "EditorIcons", resized_folder);
@@ -499,8 +502,9 @@ void EditorFileDialog::update_file_list() {
if (!has_icon("ResizedFile", "EditorIcons")) {
Ref<ImageTexture> file = get_icon("FileBig", "EditorIcons");
- Image img = file->get_data();
- img.resize(thumbnail_size, thumbnail_size);
+ Ref<Image> img = file->get_data();
+ img = img->duplicate();
+ img->resize(thumbnail_size, thumbnail_size);
Ref<ImageTexture> resized_file = Ref<ImageTexture>(memnew(ImageTexture));
resized_file->create_from_image(img, 0);
Theme::get_default()->set_icon("ResizedFile", "EditorIcons", resized_file);
@@ -552,8 +556,8 @@ void EditorFileDialog::update_file_list() {
dirs.push_back("..");
}
- dirs.sort_custom<NoCaseComparator>();
- files.sort_custom<NoCaseComparator>();
+ dirs.sort_custom<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
while (!dirs.empty()) {
const String &dir_name = dirs.front()->get();
@@ -1296,16 +1300,21 @@ EditorFileDialog::EditorFileDialog() {
favorite->connect("toggled", this, "_favorite_toggled");
pathhb->add_child(favorite);
+ Ref<ButtonGroup> view_mode_group;
+ view_mode_group.instance();
+
mode_thumbnails = memnew(ToolButton);
mode_thumbnails->connect("pressed", this, "set_display_mode", varray(DISPLAY_THUMBNAILS));
mode_thumbnails->set_toggle_mode(true);
mode_thumbnails->set_pressed(display_mode == DISPLAY_THUMBNAILS);
+ mode_thumbnails->set_button_group(view_mode_group);
pathhb->add_child(mode_thumbnails);
mode_list = memnew(ToolButton);
mode_list->connect("pressed", this, "set_display_mode", varray(DISPLAY_LIST));
mode_list->set_toggle_mode(true);
mode_list->set_pressed(display_mode == DISPLAY_LIST);
+ mode_list->set_button_group(view_mode_group);
pathhb->add_child(mode_list);
drives = memnew(OptionButton);
diff --git a/editor/editor_file_dialog.h b/editor/editor_file_dialog.h
index f8c85c4ad1..f44193c70b 100644
--- a/editor/editor_file_dialog.h
+++ b/editor/editor_file_dialog.h
@@ -169,7 +169,7 @@ private:
void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
void _request_single_thumbnail(const String &p_path);
- void _unhandled_input(const InputEvent &p_event);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
protected:
void _notification(int p_what);
diff --git a/editor/editor_file_system.cpp b/editor/editor_file_system.cpp
index b7070ab5f6..f314f772d1 100644
--- a/editor/editor_file_system.cpp
+++ b/editor/editor_file_system.cpp
@@ -153,6 +153,7 @@ EditorFileSystemDirectory::EditorFileSystemDirectory() {
modified_time = 0;
parent = NULL;
+ verified = false;
}
EditorFileSystemDirectory::~EditorFileSystemDirectory() {
@@ -522,8 +523,8 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir, DirAccess
da->list_dir_end();
- dirs.sort();
- files.sort();
+ dirs.sort_custom<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
int total = dirs.size() + files.size();
int idx = 0;
@@ -1040,7 +1041,10 @@ bool EditorFileSystem::_find_file(const String &p_file, EditorFileSystemDirector
if (idx == -1) {
//does not exist, create i guess?
EditorFileSystemDirectory *efsd = memnew(EditorFileSystemDirectory);
+
efsd->name = path[i];
+ efsd->parent = fs;
+
int idx2 = 0;
for (int j = 0; j < fs->get_subdir_count(); j++) {
@@ -1421,6 +1425,7 @@ EditorFileSystem::EditorFileSystem() {
singleton = this;
filesystem = memnew(EditorFileSystemDirectory); //like, empty
+ filesystem->parent = NULL;
thread = NULL;
scanning = false;
@@ -1429,7 +1434,9 @@ EditorFileSystem::EditorFileSystem() {
thread_sources = NULL;
new_filesystem = NULL;
+ abort_scan = false;
scanning_changes = false;
+ scanning_changes_done = false;
ResourceSaver::set_save_callback(_resource_saved);
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
diff --git a/editor/editor_file_system.h b/editor/editor_file_system.h
index b5d61d47d3..3522a1ab1d 100644
--- a/editor/editor_file_system.h
+++ b/editor/editor_file_system.h
@@ -168,8 +168,6 @@ class EditorFileSystem : public Node {
void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress);
- int md_count;
-
Set<String> valid_extensions;
Set<String> import_extensions;
diff --git a/editor/editor_fonts.cpp b/editor/editor_fonts.cpp
index dc4c2b21bc..0873b90f22 100644
--- a/editor/editor_fonts.cpp
+++ b/editor/editor_fonts.cpp
@@ -49,8 +49,8 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
int chr = c[0];
Rect2 frect;
- frect.pos.x = c[1];
- frect.pos.y = c[2];
+ frect.position.x = c[1];
+ frect.position.y = c[2];
frect.size.x = c[3];
frect.size.y = c[4];
Point2 align(c[5], c[6] + p_valign);
diff --git a/editor/editor_help.cpp b/editor/editor_help.cpp
index 11fa9396a0..11cb61370d 100644
--- a/editor/editor_help.cpp
+++ b/editor/editor_help.cpp
@@ -61,14 +61,16 @@ void EditorHelpSearch::_text_changed(const String &p_newtext) {
_update_search();
}
-void EditorHelpSearch::_sbox_input(const InputEvent &p_ie) {
+void EditorHelpSearch::_sbox_input(const Ref<InputEvent> &p_ie) {
- if (p_ie.type == InputEvent::KEY && (p_ie.key.scancode == KEY_UP ||
- p_ie.key.scancode == KEY_DOWN ||
- p_ie.key.scancode == KEY_PAGEUP ||
- p_ie.key.scancode == KEY_PAGEDOWN)) {
+ Ref<InputEventKey> k = p_ie;
- search_options->call("_gui_input", p_ie);
+ if (k.is_valid() && (k->get_scancode() == KEY_UP ||
+ k->get_scancode() == KEY_DOWN ||
+ k->get_scancode() == KEY_PAGEUP ||
+ k->get_scancode() == KEY_PAGEDOWN)) {
+
+ search_options->call("_gui_input", k);
search_box->accept_event();
}
}
@@ -250,8 +252,8 @@ void EditorHelpSearch::_confirmed() {
return;
String mdata = ti->get_metadata(0);
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
emit_signal("go_to_help", mdata);
- editor->call("_editor_select", EditorNode::EDITOR_SCRIPT); // in case EditorHelpSearch beeen invoked on top of other editor window
// go to that
hide();
}
@@ -286,7 +288,6 @@ void EditorHelpSearch::_bind_methods() {
EditorHelpSearch::EditorHelpSearch() {
- editor = EditorNode::get_singleton();
VBoxContainer *vbc = memnew(VBoxContainer);
add_child(vbc);
@@ -360,8 +361,8 @@ void EditorHelpIndex::_tree_item_selected() {
if (!s)
return;
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
emit_signal("open_class", s->get_text(0));
-
hide();
//_goto_desc(s->get_text(0));
@@ -448,14 +449,16 @@ void EditorHelpIndex::_update_class_list() {
}
}
-void EditorHelpIndex::_sbox_input(const InputEvent &p_ie) {
+void EditorHelpIndex::_sbox_input(const Ref<InputEvent> &p_ie) {
+
+ Ref<InputEventKey> k = p_ie;
- if (p_ie.type == InputEvent::KEY && (p_ie.key.scancode == KEY_UP ||
- p_ie.key.scancode == KEY_DOWN ||
- p_ie.key.scancode == KEY_PAGEUP ||
- p_ie.key.scancode == KEY_PAGEDOWN)) {
+ if (k.is_valid() && (k->get_scancode() == KEY_UP ||
+ k->get_scancode() == KEY_DOWN ||
+ k->get_scancode() == KEY_PAGEUP ||
+ k->get_scancode() == KEY_PAGEDOWN)) {
- class_list->call("_gui_input", p_ie);
+ class_list->call("_gui_input", k);
search_box->accept_event();
}
}
@@ -499,11 +502,14 @@ EditorHelpIndex::EditorHelpIndex() {
/// /////////////////////////////////
DocData *EditorHelp::doc = NULL;
-void EditorHelp::_unhandled_key_input(const InputEvent &p_ev) {
+void EditorHelp::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
if (!is_visible_in_tree())
return;
- if (p_ev.key.mod.control && p_ev.key.scancode == KEY_F) {
+
+ Ref<InputEventKey> k = p_ev;
+
+ if (k.is_valid() && k->get_control() && k->get_scancode() == KEY_F) {
search->grab_focus();
search->select_all();
@@ -598,8 +604,11 @@ void EditorHelp::_class_desc_select(const String &p_select) {
}
}
-void EditorHelp::_class_desc_input(const InputEvent &p_input) {
- if (p_input.type == InputEvent::MOUSE_BUTTON && p_input.mouse_button.pressed && p_input.mouse_button.button_index == 1) {
+void EditorHelp::_class_desc_input(const Ref<InputEvent> &p_input) {
+
+ Ref<InputEventMouseButton> mb = p_input;
+
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == 1) {
class_desc->set_selection_enabled(false);
class_desc->set_selection_enabled(true);
}
@@ -1269,7 +1278,7 @@ Error EditorHelp::_goto_desc(const String &p_class, int p_vscr) {
void EditorHelp::_request_help(const String &p_string) {
Error err = _goto_desc(p_string);
if (err == OK) {
- editor->call("_editor_select", EditorNode::EDITOR_SCRIPT);
+ EditorNode::get_singleton()->set_visible_editor(EditorNode::EDITOR_SCRIPT);
}
//100 palabras
}
@@ -1679,8 +1688,6 @@ void EditorHelp::_bind_methods() {
EditorHelp::EditorHelp() {
- editor = EditorNode::get_singleton();
-
VBoxContainer *vbc = this;
EDITOR_DEF("text_editor/help/sort_functions_alphabetically", true);
@@ -1776,7 +1783,7 @@ void EditorHelpBit::_bind_methods() {
void EditorHelpBit::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
- add_style_override("panel", get_stylebox("normal", "TextEdit"));
+ add_style_override("panel", get_stylebox("ScriptPanel", "EditorStyles"));
}
}
diff --git a/editor/editor_help.h b/editor/editor_help.h
index d22d61b91d..46d83490f4 100644
--- a/editor/editor_help.h
+++ b/editor/editor_help.h
@@ -49,14 +49,13 @@ class EditorHelpSearch : public ConfirmationDialog {
GDCLASS(EditorHelpSearch, ConfirmationDialog)
- EditorNode *editor;
LineEdit *search_box;
Tree *search_options;
String base_type;
void _update_search();
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _confirmed();
void _text_changed(const String &p_newtext);
@@ -81,7 +80,7 @@ class EditorHelpIndex : public ConfirmationDialog {
void _tree_item_selected();
void _text_changed(const String &p_text);
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _update_class_list();
@@ -119,7 +118,6 @@ class EditorHelp : public VBoxContainer {
String edited_class;
- EditorNode *editor;
Map<String, int> method_line;
Map<String, int> signal_line;
Map<String, int> property_line;
@@ -147,7 +145,7 @@ class EditorHelp : public VBoxContainer {
void _scroll_changed(double p_scroll);
void _class_list_select(const String &p_select);
void _class_desc_select(const String &p_select);
- void _class_desc_input(const InputEvent &p_input);
+ void _class_desc_input(const Ref<InputEvent> &p_input);
Error _goto_desc(const String &p_class, int p_vscr = -1);
//void _update_history_buttons();
@@ -157,7 +155,7 @@ class EditorHelp : public VBoxContainer {
void _search(const String &p_str);
void _search_cbk();
- void _unhandled_key_input(const InputEvent &p_ev);
+ void _unhandled_key_input(const Ref<InputEvent> &p_ev);
protected:
void _notification(int p_what);
diff --git a/editor/editor_log.cpp b/editor/editor_log.cpp
index c15eac67fb..5d13c7c254 100644
--- a/editor/editor_log.cpp
+++ b/editor/editor_log.cpp
@@ -87,6 +87,9 @@ void EditorLog::_notification(int p_what) {
log->add_color_override("default_color", get_color("font_color", "Tree"));
//button->set_icon(get_icon("Console","EditorIcons"));
}
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ _override_logger_styles();
+ }
/*if (p_what==NOTIFICATION_DRAW) {
diff --git a/editor/editor_name_dialog.cpp b/editor/editor_name_dialog.cpp
index 29d5dda658..d4c418bfc9 100644
--- a/editor/editor_name_dialog.cpp
+++ b/editor/editor_name_dialog.cpp
@@ -32,14 +32,16 @@
#include "class_db.h"
#include "os/keyboard.h"
-void EditorNameDialog::_line_gui_input(const InputEvent &p_event) {
+void EditorNameDialog::_line_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_event;
- if (!p_event.key.pressed)
+ if (k.is_valid()) {
+
+ if (!k->is_pressed())
return;
- switch (p_event.key.scancode) {
+ switch (k->get_scancode()) {
case KEY_ENTER:
case KEY_RETURN: {
diff --git a/editor/editor_name_dialog.h b/editor/editor_name_dialog.h
index eeeee34d7e..57586951d1 100644
--- a/editor/editor_name_dialog.h
+++ b/editor/editor_name_dialog.h
@@ -41,7 +41,7 @@ class EditorNameDialog : public ConfirmationDialog {
VBoxContainer *makevb;
LineEdit *name;
- void _line_gui_input(const InputEvent &p_event);
+ void _line_gui_input(const Ref<InputEvent> &p_event);
protected:
static void _bind_methods();
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 6b23a02275..56b62cdf6e 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -30,6 +30,7 @@
#include "editor_node.h"
#include "animation_editor.h"
+#include "authors.h"
#include "bind/core_bind.h"
#include "class_db.h"
#include "core/io/resource_loader.h"
@@ -72,10 +73,10 @@
#include "plugins/collision_polygon_2d_editor_plugin.h"
#include "plugins/collision_polygon_editor_plugin.h"
#include "plugins/collision_shape_2d_editor_plugin.h"
-#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/cube_grid_theme_editor_plugin.h"
#include "plugins/curve_editor_plugin.h"
#include "plugins/gi_probe_editor_plugin.h"
+#include "plugins/gradient_editor_plugin.h"
#include "plugins/gradient_texture_editor_plugin.h"
#include "plugins/item_list_editor_plugin.h"
#include "plugins/light_occluder_2d_editor_plugin.h"
@@ -173,12 +174,13 @@ void EditorNode::_update_title() {
OS::get_singleton()->set_window_title(title);
}
-void EditorNode::_unhandled_input(const InputEvent &p_event) {
+void EditorNode::_unhandled_input(const Ref<InputEvent> &p_event) {
if (Node::get_viewport()->get_modal_stack_top())
return; //ignore because of modal window
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && !p_event.key.echo && !gui_base->get_viewport()->gui_has_modal_stack()) {
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid() && k->is_pressed() && !k->is_echo() && !gui_base->get_viewport()->gui_has_modal_stack()) {
if (ED_IS_SHORTCUT("editor/next_tab", p_event)) {
int next_tab = editor_data.get_edited_scene() + 1;
@@ -194,28 +196,20 @@ void EditorNode::_unhandled_input(const InputEvent &p_event) {
filesystem_dock->focus_on_filter();
}
- switch (p_event.key.scancode) {
-
- /*case KEY_F1:
- if (!p_event.key.mod.shift && !p_event.key.mod.command)
- _editor_select(EDITOR_SCRIPT);
- break;*/
- case KEY_F1:
- if (!p_event.key.mod.shift && !p_event.key.mod.command)
- _editor_select(EDITOR_2D);
- break;
- case KEY_F2:
- if (!p_event.key.mod.shift && !p_event.key.mod.command)
- _editor_select(EDITOR_3D);
- break;
- case KEY_F3:
- if (!p_event.key.mod.shift && !p_event.key.mod.command)
- _editor_select(EDITOR_SCRIPT);
- break;
- /* case KEY_F5: _menu_option_confirm((p_event.key.mod.control&&p_event.key.mod.shift)?RUN_PLAY_CUSTOM_SCENE:RUN_PLAY,true); break;
- case KEY_F6: _menu_option_confirm(RUN_PLAY_SCENE,true); break;
- //case KEY_F7: _menu_option_confirm(RUN_PAUSE,true); break;
- case KEY_F8: _menu_option_confirm(RUN_STOP,true); break;*/
+ if (ED_IS_SHORTCUT("editor/editor_2d", p_event)) {
+ _editor_select(EDITOR_2D);
+ } else if (ED_IS_SHORTCUT("editor/editor_3d", p_event)) {
+ _editor_select(EDITOR_3D);
+ } else if (ED_IS_SHORTCUT("editor/editor_script", p_event)) {
+ _editor_select(EDITOR_SCRIPT);
+ } else if (ED_IS_SHORTCUT("editor/editor_help", p_event)) {
+ emit_signal("request_help_search", "");
+ } else if (ED_IS_SHORTCUT("editor/editor_assetlib", p_event)) {
+ _editor_select(EDITOR_ASSETLIB);
+ } else if (ED_IS_SHORTCUT("editor/editor_next", p_event)) {
+ _editor_select_next();
+ } else if (ED_IS_SHORTCUT("editor/editor_prev", p_event)) {
+ _editor_select_prev();
}
}
}
@@ -276,28 +270,9 @@ void EditorNode::_notification(int p_what) {
update_menu->set_icon(gui_base->get_icon("Progress" + itos(circle_step + 1), "EditorIcons"));
}
}
-
editor_selection->update();
- {
- uint32_t p32 = 0; //AudioServer::get_singleton()->read_output_peak()>>8;
-
- float peak = p32 == 0 ? -80 : Math::linear2db(p32 / 65535.0);
-
- if (peak < -80)
- peak = -80;
- float vu = audio_vu->get_value();
-
- if (peak > vu) {
- audio_vu->set_value(peak);
- } else {
- float new_vu = vu - get_process_delta_time() * 70.0;
- if (new_vu < -80)
- new_vu = -80;
- if (new_vu != -80 && vu != -80)
- audio_vu->set_value(new_vu);
- }
- }
+ scene_root->set_size_override(true, Size2(GlobalConfig::get_singleton()->get("display/window/width"), GlobalConfig::get_singleton()->get("display/window/height")));
ResourceImporterTexture::get_singleton()->update_imports();
}
@@ -356,11 +331,25 @@ void EditorNode::_notification(int p_what) {
if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
_menu_option_confirm(FILE_QUIT, false);
- };
+ }
if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
property_editor->set_enable_capitalize_paths(bool(EDITOR_DEF("interface/capitalize_properties", true)));
+ Ref<Theme> theme = create_editor_theme();
+ theme_base->set_theme(theme);
+ gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
+ play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
+ scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
+ scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
+ scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
+ if (bool(EDITOR_DEF("interface/scene_tabs/resize_if_many_tabs", true))) {
+ scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
+ } else {
+ scene_tabs->set_min_width(0);
+ }
+ _update_scene_tabs();
}
}
@@ -454,6 +443,30 @@ void EditorNode::_node_renamed() {
property_editor->update_tree();
}
+void EditorNode::_editor_select_next() {
+
+ int editor = _get_current_main_editor();
+
+ if (editor == editor_table.size() - 1) {
+ editor = 0;
+ } else {
+ editor++;
+ }
+ _editor_select(editor);
+}
+
+void EditorNode::_editor_select_prev() {
+
+ int editor = _get_current_main_editor();
+
+ if (editor == 0) {
+ editor = editor_table.size() - 1;
+ } else {
+ editor--;
+ }
+ _editor_select(editor);
+}
+
Error EditorNode::load_resource(const String &p_scene) {
RES res = ResourceLoader::load(p_scene);
@@ -820,56 +833,54 @@ void EditorNode::_save_scene_with_preview(String p_file) {
}
save.step(TTR("Creating Thumbnail"), 1);
//current view?
- int screen = -1;
- for (int i = 0; i < editor_table.size(); i++) {
- if (editor_plugin_screen == editor_table[i]) {
- screen = i;
- break;
- }
+
+ Ref<Image> img;
+ if (is2d) {
+ img = scene_root->get_texture()->get_data();
+ } else {
+ img = SpatialEditor::get_singleton()->get_editor_viewport(0)->get_viewport_node()->get_texture()->get_data();
}
- _editor_select(is2d ? EDITOR_2D : EDITOR_3D);
+ if (img.is_valid()) {
+ save.step(TTR("Creating Thumbnail"), 2);
+ save.step(TTR("Creating Thumbnail"), 3);
- save.step(TTR("Creating Thumbnail"), 2);
- save.step(TTR("Creating Thumbnail"), 3);
-#if 0
- Image img = VS::get_singleton()->viewport_texture(scree_capture(viewport);
- int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- preview_size*=EDSCALE;
- int width,height;
- if (img.get_width() > preview_size && img.get_width() >= img.get_height()) {
+ int preview_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+ preview_size *= EDSCALE;
+ int width, height;
+ if (img->get_width() > preview_size && img->get_width() >= img->get_height()) {
- width=preview_size;
- height = img.get_height() * preview_size / img.get_width();
- } else if (img.get_height() > preview_size && img.get_height() >= img.get_width()) {
+ width = preview_size;
+ height = img->get_height() * preview_size / img->get_width();
+ } else if (img->get_height() > preview_size && img->get_height() >= img->get_width()) {
- height=preview_size;
- width = img.get_width() * preview_size / img.get_height();
- } else {
+ height = preview_size;
+ width = img->get_width() * preview_size / img->get_height();
+ } else {
- width=img.get_width();
- height=img.get_height();
- }
+ width = img->get_width();
+ height = img->get_height();
+ }
- img.convert(Image::FORMAT_RGB8);
- img.resize(width,height);
+ img->convert(Image::FORMAT_RGB8);
+ img->resize(width, height);
+ img->flip_y();
- String pfile = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/last_scene_preview.png");
- img.save_png(pfile);
- Vector<uint8_t> imgdata = FileAccess::get_file_as_array(pfile);
+ //save thumbnail directly, as thumbnailer may not update due to actual scene not changing md5
+ String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
+ String cache_base = GlobalConfig::get_singleton()->globalize_path(p_file).md5_text();
+ cache_base = temp_path.plus_file("resthumb-" + cache_base);
- //print_line("img data is "+itos(imgdata.size()));
+ //does not have it, try to load a cached thumbnail
- if (editor_data.get_edited_scene_import_metadata().is_null())
- editor_data.set_edited_scene_import_metadata(Ref<ResourceImportMetadata>( memnew( ResourceImportMetadata ) ) );
- editor_data.get_edited_scene_import_metadata()->set_option("thumbnail",imgdata);
-#endif
- //tamanio tel thumbnail
- if (screen != -1) {
- _editor_select(screen);
+ String file = cache_base + ".png";
+
+ img->save_png(file);
}
+
save.step(TTR("Saving Scene"), 4);
_save_scene(p_file);
+ EditorResourcePreview::get_singleton()->check_for_invalidation(p_file);
}
void EditorNode::_save_scene(String p_file, int idx) {
@@ -887,6 +898,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
}
editor_data.apply_changes_in_editors();
+ _save_default_environment();
_set_scene_metadata(p_file, idx);
@@ -948,7 +960,7 @@ void EditorNode::_save_scene(String p_file, int idx) {
_dialog_display_file_error(p_file, err);
}
-};
+}
void EditorNode::_import_action(const String &p_action) {
#if 0
@@ -1081,6 +1093,7 @@ void EditorNode::_dialog_action(String p_file) {
GlobalConfig::get_singleton()->set("application/main_scene", p_file);
GlobalConfig::get_singleton()->save();
//would be nice to show the project manager opened with the highlighted field..
+ _run(false, ""); // automatically run the project
} break;
case FILE_SAVE_OPTIMIZED: {
@@ -1111,6 +1124,7 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
//_save_scene(p_file);
+ _save_default_environment();
_save_scene_with_preview(p_file);
}
@@ -1120,6 +1134,7 @@ void EditorNode::_dialog_action(String p_file) {
if (file->get_mode() == EditorFileDialog::MODE_SAVE_FILE) {
//_save_scene(p_file);
+ _save_default_environment();
_save_scene_with_preview(p_file);
_call_build();
_run(true);
@@ -1373,6 +1388,17 @@ void EditorNode::_property_editor_back() {
_edit_current();
}
+void EditorNode::_save_default_environment() {
+
+ Ref<Environment> fallback = get_tree()->get_root()->get_world()->get_fallback_environment();
+
+ if (fallback.is_valid() && fallback->get_path().is_resource_file()) {
+ Map<RES, bool> processed;
+ _find_and_save_edited_subresources(fallback.ptr(), processed, 0);
+ save_resource_in_path(fallback, fallback->get_path());
+ }
+}
+
void EditorNode::_imported(Node *p_node) {
/*
@@ -1451,11 +1477,16 @@ void EditorNode::_edit_current() {
Node *current_node = current_obj->cast_to<Node>();
ERR_FAIL_COND(!current_node);
- ERR_FAIL_COND(!current_node->is_inside_tree());
+ // ERR_FAIL_COND(!current_node->is_inside_tree());
property_editor->edit(current_node);
- node_dock->set_node(current_node);
- scene_tree_dock->set_selected(current_node);
+ if (current_node->is_inside_tree()) {
+ node_dock->set_node(current_node);
+ scene_tree_dock->set_selected(current_node);
+ } else {
+ node_dock->set_node(NULL);
+ scene_tree_dock->set_selected(NULL);
+ }
object_menu->get_popup()->clear();
//top_pallete->set_current_tab(0);
@@ -1651,7 +1682,7 @@ void EditorNode::_run(bool p_current, const String &p_custom) {
current_option = -1;
//accept->get_cancel()->hide();
- pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in later in \"Project Settings\" under the 'application' category."));
+ pick_main_scene->set_text(TTR("No main scene has ever been defined, select one?\nYou can change it later in \"Project Settings\" under the 'application' category."));
pick_main_scene->popup_centered_minsize();
return;
}
@@ -1949,17 +1980,20 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
}
} // else: ignore new scenes
}
+
+ _save_default_environment();
} break;
case FILE_SAVE_BEFORE_RUN: {
if (!p_confirmed) {
- accept->get_ok()->set_text(TTR("Yes"));
- accept->set_text(TTR("This scene has never been saved. Save before running?"));
- accept->popup_centered_minsize();
+ confirmation->get_cancel()->set_text(TTR("No"));
+ confirmation->get_ok()->set_text(TTR("Yes"));
+ confirmation->set_text(TTR("This scene has never been saved. Save before running?"));
+ confirmation->popup_centered_minsize();
break;
}
_menu_option(FILE_SAVE_AS_SCENE);
- _menu_option_confirm(FILE_SAVE_AND_RUN, true);
+ _menu_option_confirm(FILE_SAVE_AND_RUN, false);
} break;
case FILE_SAVE_OPTIMIZED: {
@@ -2382,6 +2416,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_PLAY_SCENE: {
+
+ _save_default_environment();
_menu_option_confirm(RUN_STOP, true);
_call_build();
_run(true);
@@ -2434,28 +2470,28 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
case RUN_FILE_SERVER: {
//file_server
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_FILE_SERVER));
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER));
if (ischecked) {
file_server->stop();
run_native->set_deploy_dumb(false);
- //debug_button->set_icon(gui_base->get_icon("FileServer","EditorIcons"));
- //debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server");
+ //debug_menu->set_icon(gui_base->get_icon("FileServer","EditorIcons"));
+ //debug_menu->get_popup()->set_item_text( debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Enable File Server");
} else {
file_server->start();
run_native->set_deploy_dumb(true);
- //debug_button->set_icon(gui_base->get_icon("FileServerActive","EditorIcons"));
- //debug_button->get_popup()->set_item_text( debug_button->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server");
+ //debug_menu->set_icon(gui_base->get_icon("FileServerActive","EditorIcons"));
+ //debug_menu->get_popup()->set_item_text( debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER),"Disable File Server");
}
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_FILE_SERVER), !ischecked);
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_FILE_SERVER), !ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_file_server", !ischecked);
} break;
case RUN_LIVE_DEBUG: {
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG));
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG));
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_LIVE_DEBUG), !ischecked);
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_LIVE_DEBUG), !ischecked);
ScriptEditor::get_singleton()->get_debugger()->set_live_debugging(!ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_live_debug", !ischecked);
@@ -2463,23 +2499,23 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
/*case RUN_DEPLOY_DUMB_CLIENTS: {
- bool ischecked = debug_button->get_popup()->is_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS));
- debug_button->get_popup()->set_item_checked( debug_button->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked);
+ bool ischecked = debug_menu->get_popup()->is_item_checked( debug_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS));
+ debug_menu->get_popup()->set_item_checked( debug_menu->get_popup()->get_item_index(RUN_DEPLOY_DUMB_CLIENTS),!ischecked);
run_native->set_deploy_dumb(!ischecked);
} break;*/
case RUN_DEPLOY_REMOTE_DEBUG: {
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG));
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked);
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG));
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEPLOY_REMOTE_DEBUG), !ischecked);
run_native->set_deploy_debug_remote(!ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_deploy_remote_debug", !ischecked);
} break;
case RUN_DEBUG_COLLISONS: {
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_DEBUG_COLLISONS));
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_DEBUG_COLLISONS), !ischecked);
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS));
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_COLLISONS), !ischecked);
run_native->set_debug_collisions(!ischecked);
editor_run.set_debug_collisions(!ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_collisons", !ischecked);
@@ -2487,8 +2523,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_DEBUG_NAVIGATION: {
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION));
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked);
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION));
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_DEBUG_NAVIGATION), !ischecked);
run_native->set_debug_navigation(!ischecked);
editor_run.set_debug_navigation(!ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_debug_navigation", !ischecked);
@@ -2496,8 +2532,8 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
} break;
case RUN_RELOAD_SCRIPTS: {
- bool ischecked = debug_button->get_popup()->is_item_checked(debug_button->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS));
- debug_button->get_popup()->set_item_checked(debug_button->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked);
+ bool ischecked = debug_menu->get_popup()->is_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS));
+ debug_menu->get_popup()->set_item_checked(debug_menu->get_popup()->get_item_index(RUN_RELOAD_SCRIPTS), !ischecked);
ScriptEditor::get_singleton()->set_live_auto_reload_running_scripts(!ischecked);
EditorSettings::get_singleton()->set_project_metadata("debug_options", "run_reload_scripts", !ischecked);
@@ -2559,8 +2595,25 @@ void EditorNode::_menu_option_confirm(int p_option, bool p_confirmed) {
file->popup_centered_ratio();
} break;
- case SETTINGS_ABOUT: {
-
+ case HELP_CLASSES: {
+ emit_signal("request_help_index", "");
+ } break;
+ case HELP_SEARCH: {
+ emit_signal("request_help_search", "");
+ } break;
+ case HELP_DOCS: {
+ OS::get_singleton()->shell_open("http://docs.godotengine.org/");
+ } break;
+ case HELP_QA: {
+ OS::get_singleton()->shell_open("https://godotengine.org/qa/");
+ } break;
+ case HELP_ISSUES: {
+ OS::get_singleton()->shell_open("https://github.com/godotengine/godot/issues");
+ } break;
+ case HELP_COMMUNITY: {
+ OS::get_singleton()->shell_open("https://godotengine.org/community");
+ } break;
+ case HELP_ABOUT: {
about->popup_centered_minsize(Size2(500, 130) * EDSCALE);
} break;
case SOURCES_REIMPORT: {
@@ -2689,6 +2742,14 @@ void EditorNode::_editor_select(int p_which) {
editor_plugin_screen = new_editor;
editor_plugin_screen->make_visible(true);
editor_plugin_screen->selected_notify();
+
+ if (EditorSettings::get_singleton()->get("interface/separate_distraction_mode")) {
+ if (p_which == EDITOR_SCRIPT) {
+ set_distraction_free_mode(script_distraction);
+ } else {
+ set_distraction_free_mode(scene_distraction);
+ }
+ }
}
void EditorNode::add_editor_plugin(EditorPlugin *p_editor) {
@@ -2698,7 +2759,9 @@ void EditorNode::add_editor_plugin(EditorPlugin *p_editor) {
ToolButton *tb = memnew(ToolButton);
tb->set_toggle_mode(true);
tb->connect("pressed", singleton, "_editor_select", varray(singleton->main_editor_buttons.size()));
- tb->set_icon(singleton->gui_base->get_icon(p_editor->get_name(), "EditorIcons"));
+ tb->set_text(p_editor->get_name());
+ tb->set_icon(p_editor->get_base_control()->get_icon(p_editor->get_name(), "EditorIcons"));
+ tb->set_name(p_editor->get_name());
singleton->main_editor_buttons.push_back(tb);
singleton->main_editor_button_vb->add_child(tb);
singleton->editor_table.push_back(p_editor);
@@ -3558,7 +3621,7 @@ bool EditorNode::is_scene_in_use(const String &p_path) {
void EditorNode::register_editor_types() {
ClassDB::register_class<EditorPlugin>();
- // ClassDB::register_class<EditorImportPlugin>();
+ ClassDB::register_class<EditorImportPlugin>();
// ClassDB::register_class<EditorExportPlugin>();
// ClassDB::register_class<EditorScenePostImport>();
ClassDB::register_class<EditorScript>();
@@ -3678,11 +3741,13 @@ void EditorNode::show_warning(const String &p_text, const String &p_title) {
warning->popup_centered_minsize();
}
-void EditorNode::_dock_select_input(const InputEvent &p_input) {
+void EditorNode::_dock_select_input(const Ref<InputEvent> &p_input) {
+
+ Ref<InputEventMouse> me = p_input;
- if (p_input.type == InputEvent::MOUSE_BUTTON || p_input.type == InputEvent::MOUSE_MOTION) {
+ if (me.is_valid()) {
- Vector2 point(p_input.mouse_motion.x, p_input.mouse_motion.y);
+ Vector2 point = me->get_position();
int nrect = -1;
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
@@ -3700,7 +3765,9 @@ void EditorNode::_dock_select_input(const InputEvent &p_input) {
if (nrect == -1)
return;
- if (p_input.type == InputEvent::MOUSE_BUTTON && p_input.mouse_button.button_index == 1 && p_input.mouse_button.pressed && dock_popup_selected != nrect) {
+ Ref<InputEventMouseButton> mb = me;
+
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && dock_popup_selected != nrect) {
Control *dock = dock_slot[dock_popup_selected]->get_current_tab_control();
if (dock) {
dock_slot[dock_popup_selected]->remove_child(dock);
@@ -3790,7 +3857,7 @@ void EditorNode::_dock_select_draw() {
unusable.a = 0.1;
Rect2 unr(s.x * 2, 0, s.x * 2, s.y * 2);
- unr.pos += Vector2(2, 5);
+ unr.position += Vector2(2, 5);
unr.size -= Vector2(4, 7);
dock_select->draw_rect(unr, unusable);
@@ -3843,7 +3910,7 @@ void EditorNode::_dock_select_draw() {
Rect2 r(ofs, s);
dock_select_rect[i] = r;
- r.pos += Vector2(2, 5);
+ r.position += Vector2(2, 5);
r.size -= Vector2(4, 7);
if (i == dock_select_rect_over) {
@@ -4211,7 +4278,47 @@ void EditorNode::_scene_tab_closed(int p_tab) {
}
}
+void EditorNode::_scene_tab_hover(int p_tab) {
+ if (bool(EDITOR_DEF("interface/scene_tabs/show_thumbnail_on_hover", true)) == false) {
+ return;
+ }
+ int current_tab = scene_tabs->get_current_tab();
+
+ if (p_tab == current_tab || p_tab < 0) {
+ tab_preview_panel->hide();
+ } else {
+ String path = editor_data.get_scene_path(p_tab);
+ EditorResourcePreview::get_singleton()->queue_resource_preview(path, this, "_thumbnail_done", p_tab);
+ }
+}
+
+void EditorNode::_scene_tab_exit() {
+ tab_preview_panel->hide();
+}
+
+void EditorNode::_scene_tab_input(const Ref<InputEvent> &p_input) {
+ Ref<InputEventMouseButton> mb = p_input;
+
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == BUTTON_MIDDLE && mb->is_pressed() && scene_tabs->get_hovered_tab() >= 0) {
+ _scene_tab_closed(scene_tabs->get_hovered_tab());
+ }
+ }
+}
+
+void EditorNode::_thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata) {
+ int p_tab = p_udata.operator signed int();
+ if (p_preview.is_valid()) {
+ Rect2 rect = scene_tabs->get_tab_rect(p_tab);
+ rect.position += scene_tabs->get_global_position();
+ tab_preview->set_texture(p_preview);
+ tab_preview_panel->set_position(rect.position + Vector2(0, rect.size.height));
+ tab_preview_panel->show();
+ }
+}
+
void EditorNode::_scene_tab_changed(int p_tab) {
+ tab_preview_panel->hide();
//print_line("set current 1 ");
bool unsaved = (saved_version != editor_data.get_undo_redo().get_version());
@@ -4382,7 +4489,25 @@ bool EditorNode::get_docks_visible() const {
void EditorNode::_toggle_distraction_free_mode() {
- set_distraction_free_mode(distraction_free->is_pressed());
+ if (EditorSettings::get_singleton()->get("interface/separate_distraction_mode")) {
+ int screen = -1;
+ for (int i = 0; i < editor_table.size(); i++) {
+ if (editor_plugin_screen == editor_table[i]) {
+ screen = i;
+ break;
+ }
+ }
+
+ if (screen == EDITOR_SCRIPT) {
+ script_distraction = !script_distraction;
+ set_distraction_free_mode(script_distraction);
+ } else {
+ scene_distraction = !scene_distraction;
+ set_distraction_free_mode(scene_distraction);
+ }
+ } else {
+ set_distraction_free_mode(distraction_free->is_pressed());
+ }
}
void EditorNode::set_distraction_free_mode(bool p_enter) {
@@ -4437,8 +4562,9 @@ Variant EditorNode::drag_resource(const Ref<Resource> &p_res, Control *p_from) {
{
//todo make proper previews
Ref<ImageTexture> pic = gui_base->get_icon("FileBig", "EditorIcons");
- Image img = pic->get_data();
- img.resize(48, 48); //meh
+ Ref<Image> img = pic->get_data();
+ img = img->duplicate();
+ img->resize(48, 48); //meh
Ref<ImageTexture> resized_pic = Ref<ImageTexture>(memnew(ImageTexture));
resized_pic->create_from_image(img);
preview = resized_pic;
@@ -4682,6 +4808,22 @@ void EditorNode::_dim_timeout() {
}
}
+void EditorNode::_check_gui_base_size() {
+ if (gui_base->get_size().width > 1200 * EDSCALE) {
+ for (int i = 0; i < singleton->main_editor_button_vb->get_child_count(); i++) {
+ ToolButton *btn = singleton->main_editor_button_vb->get_child(i)->cast_to<ToolButton>();
+ if (btn == singleton->distraction_free) continue;
+ btn->set_text(btn->get_name());
+ }
+ } else {
+ for (int i = 0; i < singleton->main_editor_button_vb->get_child_count(); i++) {
+ ToolButton *btn = singleton->main_editor_button_vb->get_child(i)->cast_to<ToolButton>();
+ if (btn == singleton->distraction_free) continue;
+ btn->set_text("");
+ }
+ }
+}
+
void EditorNode::open_export_template_manager() {
export_template_manager->popup_manager();
@@ -4743,6 +4885,10 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method("set_current_version", &EditorNode::set_current_version);
ClassDB::bind_method("_scene_tab_changed", &EditorNode::_scene_tab_changed);
ClassDB::bind_method("_scene_tab_closed", &EditorNode::_scene_tab_closed);
+ ClassDB::bind_method("_scene_tab_hover", &EditorNode::_scene_tab_hover);
+ ClassDB::bind_method("_scene_tab_exit", &EditorNode::_scene_tab_exit);
+ ClassDB::bind_method("_scene_tab_input", &EditorNode::_scene_tab_input);
+ ClassDB::bind_method("_thumbnail_done", &EditorNode::_thumbnail_done);
ClassDB::bind_method("_scene_tab_script_edited", &EditorNode::_scene_tab_script_edited);
ClassDB::bind_method("_set_main_scene_state", &EditorNode::_set_main_scene_state);
ClassDB::bind_method("_update_scene_tabs", &EditorNode::_update_scene_tabs);
@@ -4764,11 +4910,14 @@ void EditorNode::_bind_methods() {
ClassDB::bind_method(D_METHOD("_open_imported"), &EditorNode::_open_imported);
ClassDB::bind_method(D_METHOD("_inherit_imported"), &EditorNode::_inherit_imported);
ClassDB::bind_method(D_METHOD("_dim_timeout"), &EditorNode::_dim_timeout);
+ ClassDB::bind_method(D_METHOD("_check_gui_base_size"), &EditorNode::_check_gui_base_size);
ADD_SIGNAL(MethodInfo("play_pressed"));
ADD_SIGNAL(MethodInfo("pause_pressed"));
ADD_SIGNAL(MethodInfo("stop_pressed"));
ADD_SIGNAL(MethodInfo("request_help"));
+ ADD_SIGNAL(MethodInfo("request_help_search"));
+ ADD_SIGNAL(MethodInfo("request_help_index"));
ADD_SIGNAL(MethodInfo("script_add_function_request", PropertyInfo(Variant::OBJECT, "obj"), PropertyInfo(Variant::STRING, "function"), PropertyInfo(Variant::POOL_STRING_ARRAY, "args")));
ADD_SIGNAL(MethodInfo("resource_saved", PropertyInfo(Variant::OBJECT, "obj")));
}
@@ -4783,6 +4932,7 @@ EditorNode::EditorNode() {
Resource::_get_local_scene_func = _resource_get_edited_scene;
VisualServer::get_singleton()->textures_keep_original(true);
+ VisualServer::get_singleton()->set_debug_generate_wireframes(true);
EditorHelp::generate_doc(); //before any editor classes are crated
SceneState::set_disable_placeholders(true);
@@ -4806,6 +4956,9 @@ EditorNode::EditorNode() {
_initializing_addons = false;
docks_visible = true;
+ scene_distraction = false;
+ script_distraction = false;
+
FileAccess::set_backup_save(true);
TranslationServer::get_singleton()->set_enabled(false);
@@ -4893,17 +5046,19 @@ EditorNode::EditorNode() {
ClassDB::set_class_enabled("CollisionShape2D", true);
ClassDB::set_class_enabled("CollisionPolygon2D", true);
- Control *theme_base = memnew(Control);
+ theme_base = memnew(Control);
add_child(theme_base);
theme_base->set_area_as_parent_rect();
gui_base = memnew(Panel);
theme_base->add_child(gui_base);
gui_base->set_area_as_parent_rect();
+ gui_base->connect("item_rect_changed", this, "_check_gui_base_size");
Ref<Theme> theme = create_editor_theme();
theme_base->set_theme(theme);
gui_base->set_theme(create_custom_theme());
+ gui_base->add_style_override("panel", gui_base->get_stylebox("Background", "EditorStyles"));
resource_preview = memnew(EditorResourcePreview);
add_child(resource_preview);
@@ -4918,6 +5073,7 @@ EditorNode::EditorNode() {
main_vbox = memnew(VBoxContainer);
gui_base->add_child(main_vbox);
main_vbox->set_area_as_parent_rect(8);
+ main_vbox->set_margin(MARGIN_TOP, 5);
#if 0
PanelContainer *top_dark_panel = memnew( PanelContainer );
@@ -5054,7 +5210,7 @@ EditorNode::EditorNode() {
dock_slot[i]->set_v_size_flags(Control::SIZE_EXPAND_FILL);
dock_slot[i]->set_popup(dock_select_popoup);
dock_slot[i]->connect("pre_popup_pressed", this, "_dock_pre_popup", varray(i));
- //dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
+ dock_slot[i]->set_tab_align(TabContainer::ALIGN_LEFT);
}
dock_drag_timer = memnew(Timer);
@@ -5077,24 +5233,50 @@ EditorNode::EditorNode() {
main_editor_tabs->connect("tab_changed",this,"_editor_select");
main_editor_tabs->set_tab_close_display_policy(Tabs::SHOW_NEVER);
*/
+ tab_preview_panel = memnew(Panel);
+ tab_preview_panel->set_size(Size2(100, 100) * EDSCALE);
+ tab_preview_panel->hide();
+ tab_preview_panel->set_self_modulate(Color(1, 1, 1, 0.7));
+ gui_base->add_child(tab_preview_panel);
+
+ tab_preview = memnew(TextureRect);
+ tab_preview->set_stretch_mode(TextureRect::STRETCH_KEEP_ASPECT_CENTERED);
+ tab_preview->set_size(Size2(96, 96) * EDSCALE);
+ tab_preview->set_position(Point2(2, 2) * EDSCALE);
+ tab_preview_panel->add_child(tab_preview);
+
scene_tabs = memnew(Tabs);
+ scene_tabs->add_style_override("tab_fg", gui_base->get_stylebox("SceneTabFG", "EditorStyles"));
+ scene_tabs->add_style_override("tab_bg", gui_base->get_stylebox("SceneTabBG", "EditorStyles"));
scene_tabs->add_tab("unsaved");
scene_tabs->set_tab_align(Tabs::ALIGN_LEFT);
scene_tabs->set_tab_close_display_policy((bool(EDITOR_DEF("interface/always_show_close_button_in_scene_tabs", false)) ? Tabs::CLOSE_BUTTON_SHOW_ALWAYS : Tabs::CLOSE_BUTTON_SHOW_ACTIVE_ONLY));
+ scene_tabs->set_min_width(int(EDITOR_DEF("interface/scene_tabs/minimum_width", 50)) * EDSCALE);
scene_tabs->connect("tab_changed", this, "_scene_tab_changed");
scene_tabs->connect("right_button_pressed", this, "_scene_tab_script_edited");
scene_tabs->connect("tab_close", this, "_scene_tab_closed");
+ scene_tabs->connect("tab_hover", this, "_scene_tab_hover");
+ scene_tabs->connect("mouse_exited", this, "_scene_tab_exit");
+ scene_tabs->connect("gui_input", this, "_scene_tab_input");
- // MarginContainer *st_mc = memnew( MarginContainer );
- // st_mc->add_child(scene_tabs);
- srt->add_child(scene_tabs);
+ HBoxContainer *tabbar_container = memnew(HBoxContainer);
+ scene_tabs->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+
+ srt->add_child(tabbar_container);
+ tabbar_container->add_child(scene_tabs);
+ distraction_free = memnew(ToolButton);
+ tabbar_container->add_child(distraction_free);
+ distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11));
+ distraction_free->connect("pressed", this, "_toggle_distraction_free_mode");
+ distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
+ distraction_free->set_toggle_mode(true);
scene_root_parent = memnew(PanelContainer);
scene_root_parent->set_custom_minimum_size(Size2(0, 80) * EDSCALE);
- scene_root_parent->add_style_override("panel", gui_base->get_stylebox("EditorPanel", "EditorStyles"));
+ scene_root_parent->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
- // Ref<StyleBox> sp = scene_root_parent->get_stylebox("panel_full","PanelContainer");
- // scene_root_parent->add_style_override("panel",sp);
+ //Ref<StyleBox> sp = scene_root_parent->get_stylebox("panel","TabContainer");
+ //scene_root_parent->add_style_override("panel",sp);
/*scene_root_parent->set_anchor( MARGIN_RIGHT, Control::ANCHOR_END );
scene_root_parent->set_anchor( MARGIN_BOTTOM, Control::ANCHOR_END );
@@ -5124,17 +5306,46 @@ EditorNode::EditorNode() {
scene_root_parent->add_child(viewport);
PanelContainer *top_region = memnew(PanelContainer);
- top_region->add_style_override("panel", memnew(StyleBoxEmpty));
+ top_region->add_style_override("panel", gui_base->get_stylebox("MenuPanel", "EditorStyles"));
HBoxContainer *left_menu_hb = memnew(HBoxContainer);
top_region->add_child(left_menu_hb);
menu_hb->add_child(top_region);
PopupMenu *p;
+ project_menu = memnew(MenuButton);
+ project_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools."));
+ project_menu->set_text(TTR("Project"));
+ project_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
+ left_menu_hb->add_child(project_menu);
+
+ p = project_menu->get_popup();
+ p->connect("id_pressed", this, "_menu_option");
+ p->add_item(TTR("Run Script"), FILE_RUN_SCRIPT, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_R);
+ p->add_item(TTR("Export"), FILE_EXPORT_PROJECT);
+
+ PopupMenu *tool_menu = memnew(PopupMenu);
+ tool_menu->set_name("Tools");
+ tool_menu->connect("id_pressed", this, "_menu_option");
+ p->add_child(tool_menu);
+ p->add_submenu_item(TTR("Tools"), "Tools");
+ tool_menu->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
+ p->add_separator();
+ p->add_item(TTR("Project Settings"), RUN_SETTINGS);
+ p->add_separator();
+
+#ifdef OSX_ENABLED
+ p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
+#else
+ p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Q);
+#endif
+ p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
+
file_menu = memnew(MenuButton);
file_menu->set_text(TTR("Scene"));
//file_menu->set_icon(gui_base->get_icon("Save","EditorIcons"));
left_menu_hb->add_child(file_menu);
+ file_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
prev_scene = memnew(ToolButton);
prev_scene->set_icon(gui_base->get_icon("PrevScene", "EditorIcons"));
@@ -5182,18 +5393,7 @@ EditorNode::EditorNode() {
p->add_shortcut(ED_SHORTCUT("editor/undo", TTR("Undo"), KEY_MASK_CMD + KEY_Z), EDIT_UNDO, true);
p->add_shortcut(ED_SHORTCUT("editor/redo", TTR("Redo"), KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_Z), EDIT_REDO, true);
p->add_separator();
- p->add_item(TTR("Run Script"), FILE_RUN_SCRIPT, KEY_MASK_SHIFT + KEY_MASK_CMD + KEY_R);
- p->add_separator();
- p->add_item(TTR("Project Settings"), RUN_SETTINGS);
- p->add_separator();
p->add_item(TTR("Revert Scene"), EDIT_REVERT);
- p->add_separator();
-#ifdef OSX_ENABLED
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_ALT + KEY_Q);
-#else
- p->add_item(TTR("Quit to Project List"), RUN_PROJECT_MANAGER, KEY_MASK_SHIFT + KEY_MASK_CTRL + KEY_Q);
-#endif
- p->add_item(TTR("Quit"), FILE_QUIT, KEY_MASK_CMD + KEY_Q);
recent_scenes = memnew(PopupMenu);
recent_scenes->set_name("RecentScenes");
@@ -5207,17 +5407,11 @@ EditorNode::EditorNode() {
}
PanelContainer *editor_region = memnew(PanelContainer);
- editor_region->add_style_override("panel", memnew(StyleBoxEmpty));
main_editor_button_vb = memnew(HBoxContainer);
editor_region->add_child(main_editor_button_vb);
- menu_hb->add_child(editor_region);
- distraction_free = memnew(ToolButton);
- main_editor_button_vb->add_child(distraction_free);
- distraction_free->set_shortcut(ED_SHORTCUT("editor/distraction_free_mode", TTR("Distraction Free Mode"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F11));
- distraction_free->connect("pressed", this, "_toggle_distraction_free_mode");
- distraction_free->set_icon(gui_base->get_icon("DistractionFree", "EditorIcons"));
- distraction_free->set_toggle_mode(true);
+ menu_hb->add_spacer();
+ menu_hb->add_child(editor_region);
//menu_hb->add_spacer();
#if 0
@@ -5248,25 +5442,66 @@ EditorNode::EditorNode() {
menu_panel->add_child( resource_menu );
#endif
- tool_menu = memnew(MenuButton);
- tool_menu->set_tooltip(TTR("Miscellaneous project or scene-wide tools."));
- tool_menu->set_text(TTR("Tools"));
+ debug_menu = memnew(MenuButton);
+ debug_menu->set_text(TTR("Debug"));
+ debug_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
+ left_menu_hb->add_child(debug_menu);
+ p = debug_menu->get_popup();
+ p->set_hide_on_item_selection(false);
+ p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
+ p->add_check_item(TTR("Small Deploy with Network FS"), RUN_FILE_SERVER);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint."));
+ p->add_separator();
+ p->add_check_item(TTR("Visible Collision Shapes"), RUN_DEBUG_COLLISONS);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on."));
+ p->add_check_item(TTR("Visible Navigation"), RUN_DEBUG_NAVIGATION);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on."));
+ p->add_separator();
+ p->add_check_item(TTR("Sync Scene Changes"), RUN_LIVE_DEBUG);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
+ p->add_check_item(TTR("Sync Script Changes"), RUN_RELOAD_SCRIPTS);
+ p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
+ p->connect("id_pressed", this, "_menu_option");
- //tool_menu->set_icon(gui_base->get_icon("Save","EditorIcons"));
- left_menu_hb->add_child(tool_menu);
+ menu_hb->add_spacer();
- p = tool_menu->get_popup();
- p->connect("id_pressed", this, "_menu_option");
- p->add_item(TTR("Orphan Resource Explorer"), TOOLS_ORPHAN_RESOURCES);
+ settings_menu = memnew(MenuButton);
+ left_menu_hb->add_child(settings_menu);
+ settings_menu->set_text(TTR("Editor"));
+ settings_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
+ //settings_menu->set_anchor(MARGIN_RIGHT,ANCHOR_END);
+ p = settings_menu->get_popup();
- export_button = memnew(ToolButton);
- export_button->set_tooltip(TTR("Export the project to many platforms."));
- export_button->set_text(TTR("Export"));
- export_button->connect("pressed", this, "_menu_option", varray(FILE_EXPORT_PROJECT));
- export_button->set_focus_mode(Control::FOCUS_NONE);
- left_menu_hb->add_child(export_button);
+ //p->add_item("Export Settings",SETTINGS_EXPORT_PREFERENCES);
+ p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
+ //p->add_item("Optimization Presets",SETTINGS_OPTIMIZED_PRESETS);
+ p->add_separator();
+ editor_layouts = memnew(PopupMenu);
+ editor_layouts->set_name("Layouts");
+ p->add_child(editor_layouts);
+ editor_layouts->connect("id_pressed", this, "_layout_menu_option");
+ p->add_submenu_item(TTR("Editor Layout"), "Layouts");
+ p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREN);
+ p->add_separator();
+ p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
- menu_hb->add_spacer();
+ // Help Menu
+ MenuButton *help_menu = memnew(MenuButton);
+ left_menu_hb->add_child(help_menu);
+ help_menu->set_text(TTR("Help"));
+ help_menu->add_style_override("hover", gui_base->get_stylebox("MenuHover", "EditorStyles"));
+ p = help_menu->get_popup();
+ p->connect("id_pressed", this, "_menu_option");
+ p->add_icon_item(gui_base->get_icon("ClassList", "EditorIcons"), TTR("Classes"), HELP_CLASSES);
+ p->add_icon_item(gui_base->get_icon("Help", "EditorIcons"), TTR("Search"), HELP_SEARCH);
+ p->add_separator();
+ p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Online Docs"), HELP_DOCS);
+ p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Q&A"), HELP_QA);
+ p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Issue Tracker"), HELP_ISSUES);
+ p->add_icon_item(gui_base->get_icon("Instance", "EditorIcons"), TTR("Community"), HELP_COMMUNITY);
+ p->add_separator();
+ p->add_icon_item(gui_base->get_icon("GodotDocs", "EditorIcons"), TTR("About"), HELP_ABOUT);
//Separator *s1 = memnew( VSeparator );
//menu_panel->add_child(s1);
@@ -5274,20 +5509,18 @@ EditorNode::EditorNode() {
//s1->set_size(Point2(10,15));
play_cc = memnew(CenterContainer);
- // play_cc->add_style_override("bg",gui_base->get_stylebox("panel","PanelContainer"));
-
play_cc->set_mouse_filter(Control::MOUSE_FILTER_IGNORE);
- gui_base->add_child(play_cc);
+ menu_hb->add_child(play_cc);
play_cc->set_area_as_parent_rect();
play_cc->set_anchor_and_margin(MARGIN_BOTTOM, Control::ANCHOR_BEGIN, 10);
play_cc->set_margin(MARGIN_TOP, 5);
- top_region = memnew(PanelContainer);
- top_region->add_style_override("panel", gui_base->get_stylebox("panel", "ButtonGroup"));
- play_cc->add_child(top_region);
+ play_button_panel = memnew(PanelContainer);
+ play_button_panel->add_style_override("panel", gui_base->get_stylebox("PlayButtonPanel", "EditorStyles"));
+ play_cc->add_child(play_button_panel);
HBoxContainer *play_hb = memnew(HBoxContainer);
- top_region->add_child(play_hb);
+ play_button_panel->add_child(play_hb);
play_button = memnew(ToolButton);
play_hb->add_child(play_button);
@@ -5348,33 +5581,6 @@ EditorNode::EditorNode() {
play_custom_scene_button->set_tooltip(TTR("Play custom scene"));
play_custom_scene_button->set_shortcut(ED_SHORTCUT("editor/play_custom_scene", TTR("Play Custom Scene"), KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_F5));
- debug_button = memnew(MenuButton);
- debug_button->set_flat(true);
- play_hb->add_child(debug_button);
- //debug_button->set_toggle_mode(true);
- debug_button->set_focus_mode(Control::FOCUS_NONE);
- debug_button->set_icon(gui_base->get_icon("Remote", "EditorIcons"));
- //debug_button->connect("pressed", this,"_menu_option",make_binds(RUN_LIVE_DEBUG));
- debug_button->set_tooltip(TTR("Debug options"));
-
- p = debug_button->get_popup();
- p->set_hide_on_item_selection(false);
- p->add_check_item(TTR("Deploy with Remote Debug"), RUN_DEPLOY_REMOTE_DEBUG);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When exporting or deploying, the resulting executable will attempt to connect to the IP of this computer in order to be debugged."));
- p->add_check_item(TTR("Small Deploy with Network FS"), RUN_FILE_SERVER);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is enabled, export or deploy will produce a minimal executable.\nThe filesystem will be provided from the project by the editor over the network.\nOn Android, deploy will use the USB cable for faster performance. This option speeds up testing for games with a large footprint."));
- p->add_separator();
- p->add_check_item(TTR("Visible Collision Shapes"), RUN_DEBUG_COLLISONS);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("Collision shapes and raycast nodes (for 2D and 3D) will be visible on the running game if this option is turned on."));
- p->add_check_item(TTR("Visible Navigation"), RUN_DEBUG_NAVIGATION);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("Navigation meshes and polygons will be visible on the running game if this option is turned on."));
- p->add_separator();
- p->add_check_item(TTR("Sync Scene Changes"), RUN_LIVE_DEBUG);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any changes made to the scene in the editor will be replicated in the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
- p->add_check_item(TTR("Sync Script Changes"), RUN_RELOAD_SCRIPTS);
- p->set_item_tooltip(p->get_item_count() - 1, TTR("When this option is turned on, any script that is saved will be reloaded on the running game.\nWhen used remotely on a device, this is more efficient with network filesystem."));
- p->connect("id_pressed", this, "_menu_option");
-
/*
run_settings_button = memnew( ToolButton );
//menu_hb->add_child(run_settings_button);
@@ -5394,65 +5600,24 @@ EditorNode::EditorNode() {
*/
progress_hb = memnew(BackgroundProgress);
- menu_hb->add_child(progress_hb);
+ //menu_hb->add_child(progress_hb);
{
Control *sp = memnew(Control);
sp->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
- menu_hb->add_child(sp);
+ //menu_hb->add_child(sp);
}
- PanelContainer *vu_cont = memnew(PanelContainer);
- vu_cont->add_style_override("panel", memnew(StyleBoxEmpty));
-
- // CenterContainer *vu_cont = memnew( CenterContainer );
- menu_hb->add_child(vu_cont);
-
- audio_vu = memnew(TextureProgress);
- CenterContainer *vu_cc = memnew(CenterContainer);
- vu_cc->add_child(audio_vu);
- vu_cont->add_child(vu_cc);
- audio_vu->set_under_texture(gui_base->get_icon("VuEmpty", "EditorIcons"));
- audio_vu->set_progress_texture(gui_base->get_icon("VuFull", "EditorIcons"));
- audio_vu->set_max(24);
- audio_vu->set_min(-80);
- audio_vu->set_step(0.01);
- audio_vu->set_value(0);
-
{
Control *sp = memnew(Control);
sp->set_custom_minimum_size(Size2(30, 0) * EDSCALE);
- menu_hb->add_child(sp);
+ //menu_hb->add_child(sp);
}
top_region = memnew(PanelContainer);
- top_region->add_style_override("panel", memnew(StyleBoxEmpty));
HBoxContainer *right_menu_hb = memnew(HBoxContainer);
- top_region->add_child(right_menu_hb);
- menu_hb->add_child(top_region);
-
- settings_menu = memnew(MenuButton);
- settings_menu->set_text(TTR("Settings"));
- //settings_menu->set_anchor(MARGIN_RIGHT,ANCHOR_END);
- right_menu_hb->add_child(settings_menu);
- p = settings_menu->get_popup();
-
- //p->add_item("Export Settings",SETTINGS_EXPORT_PREFERENCES);
- p->add_item(TTR("Editor Settings"), SETTINGS_PREFERENCES);
- //p->add_item("Optimization Presets",SETTINGS_OPTIMIZED_PRESETS);
- p->add_separator();
- editor_layouts = memnew(PopupMenu);
- editor_layouts->set_name("Layouts");
- p->add_child(editor_layouts);
- editor_layouts->connect("id_pressed", this, "_layout_menu_option");
- p->add_submenu_item(TTR("Editor Layout"), "Layouts");
-
- p->add_shortcut(ED_SHORTCUT("editor/fullscreen_mode", TTR("Toggle Fullscreen"), KEY_MASK_SHIFT | KEY_F11), SETTINGS_TOGGLE_FULLSCREN);
-
- p->add_separator();
- p->add_item(TTR("Manage Export Templates"), SETTINGS_MANAGE_EXPORT_TEMPLATES);
- p->add_separator();
- p->add_item(TTR("About"), SETTINGS_ABOUT);
+ //top_region->add_child(right_menu_hb);
+ menu_hb->add_child(right_menu_hb);
layout_dialog = memnew(EditorNameDialog);
gui_base->add_child(layout_dialog);
@@ -5460,16 +5625,11 @@ EditorNode::EditorNode() {
layout_dialog->set_size(Size2(175, 70) * EDSCALE);
layout_dialog->connect("name_confirmed", this, "_dialog_action");
- sources_button = memnew(ToolButton);
- right_menu_hb->add_child(sources_button);
- sources_button->set_icon(gui_base->get_icon("DependencyOk", "EditorIcons"));
- sources_button->connect("pressed", this, "_menu_option", varray(SOURCES_REIMPORT));
- sources_button->set_tooltip(TTR("Alerts when an external resource has changed."));
-
update_menu = memnew(MenuButton);
update_menu->set_tooltip(TTR("Spins when the editor window repaints!"));
right_menu_hb->add_child(update_menu);
update_menu->set_icon(gui_base->get_icon("Progress1", "EditorIcons"));
+ update_menu->get_popup()->connect("id_pressed", this, "_menu_option");
p = update_menu->get_popup();
p->add_check_item(TTR("Update Always"), SETTINGS_UPDATE_ALWAYS);
p->add_check_item(TTR("Update Changes"), SETTINGS_UPDATE_CHANGES);
@@ -5592,7 +5752,7 @@ EditorNode::EditorNode() {
search_button = memnew(ToolButton);
search_button->set_toggle_mode(true);
search_button->set_pressed(false);
- search_button->set_icon(gui_base->get_icon("Search", "EditorIcons"));
+ search_button->set_icon(gui_base->get_icon("Zoom", "EditorIcons"));
prop_editor_hb->add_child(search_button);
search_button->connect("toggled", this, "_toggle_search_bar");
@@ -5682,7 +5842,7 @@ EditorNode::EditorNode() {
_update_layouts_menu();
bottom_panel = memnew(PanelContainer);
- bottom_panel->add_style_override("panel", gui_base->get_stylebox("EditorPanel", "EditorStyles"));
+ bottom_panel->add_style_override("panel", gui_base->get_stylebox("Content", "EditorStyles"));
center_split->add_child(bottom_panel);
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
@@ -5787,14 +5947,49 @@ EditorNode::EditorNode() {
about->get_ok()->set_text(TTR("Thanks!"));
about->set_hide_on_ok(true);
gui_base->add_child(about);
+ VBoxContainer *vbc = memnew(VBoxContainer);
HBoxContainer *hbc = memnew(HBoxContainer);
- about->add_child(hbc);
+ hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ hbc->set_alignment(BoxContainer::ALIGN_CENTER);
+ about->add_child(vbc);
+ vbc->add_child(hbc);
Label *about_text = memnew(Label);
- about_text->set_text(VERSION_FULL_NAME "\n(c) 2008-2017 Juan Linietsky, Ariel Manzur.\n");
+ about_text->set_text(VERSION_FULL_NAME + String::utf8("\n\u00A9 2007-2017 Juan Linietsky, Ariel Manzur.\n\u00A9 2014-2017 ") + TTR("Godot Engine contributors") + "\n");
TextureRect *logo = memnew(TextureRect);
logo->set_texture(gui_base->get_icon("Logo", "EditorIcons"));
hbc->add_child(logo);
hbc->add_child(about_text);
+ TabContainer *tc = memnew(TabContainer);
+ tc->set_custom_minimum_size(Vector2(740, 300));
+ vbc->add_child(tc);
+ ScrollContainer *dev_base = memnew(ScrollContainer);
+ dev_base->set_name(TTR("Developers"));
+ tc->add_child(dev_base);
+ HBoxContainer *dev_hbc = memnew(HBoxContainer);
+ dev_hbc->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ dev_base->add_child(dev_hbc);
+ for (int i = 0; i < 3; i++) {
+ Label *dev_label = memnew(Label);
+ dev_label->set_h_size_flags(Control::SIZE_EXPAND);
+ dev_label->set_v_size_flags(Control::SIZE_FILL);
+ dev_hbc->add_child(dev_label);
+ }
+ int dev_name_index = 0;
+ int dev_name_column = 0;
+ const int dev_index_max = AUTHORS_COUNT / 3 + (AUTHORS_COUNT % 3 == 0 ? 0 : 1);
+ String dev_name = "";
+ const char **dev_names_ptr = dev_names;
+ while (*dev_names_ptr) {
+ dev_name += String::utf8(*dev_names_ptr++);
+ if (++dev_name_index == dev_index_max || !*dev_names_ptr) {
+ dev_hbc->get_child(dev_name_column)->cast_to<Label>()->set_text(dev_name);
+ dev_name_column++;
+ dev_name = "";
+ dev_name_index = 0;
+ } else {
+ dev_name += "\n";
+ }
+ }
warning = memnew(AcceptDialog);
gui_base->add_child(warning);
@@ -5854,7 +6049,6 @@ EditorNode::EditorNode() {
file_menu->get_popup()->connect("id_pressed", this, "_menu_option");
object_menu->get_popup()->connect("id_pressed", this, "_menu_option");
- update_menu->get_popup()->connect("id_pressed", this, "_menu_option");
settings_menu->get_popup()->connect("id_pressed", this, "_menu_option");
file->connect("file_selected", this, "_dialog_action");
@@ -5912,13 +6106,13 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(Particles2DEditorPlugin(this)));
add_editor_plugin(memnew(GIProbeEditorPlugin(this)));
add_editor_plugin(memnew(Path2DEditorPlugin(this)));
- //add_editor_plugin( memnew( PathEditorPlugin(this) ) );
+ add_editor_plugin(memnew(PathEditorPlugin(this)));
//add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) );
add_editor_plugin(memnew(Line2DEditorPlugin(this)));
add_editor_plugin(memnew(Polygon2DEditorPlugin(this)));
add_editor_plugin(memnew(LightOccluder2DEditorPlugin(this)));
add_editor_plugin(memnew(NavigationPolygonEditorPlugin(this)));
- add_editor_plugin(memnew(ColorRampEditorPlugin(this)));
+ add_editor_plugin(memnew(GradientEditorPlugin(this)));
add_editor_plugin(memnew(GradientTextureEditorPlugin(this)));
add_editor_plugin(memnew(CollisionShape2DEditorPlugin(this)));
add_editor_plugin(memnew(CurveTextureEditorPlugin(this)));
@@ -5934,14 +6128,13 @@ EditorNode::EditorNode() {
plugin_init_callbacks[i]();
}
- /*resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorScriptPreviewPlugin>( memnew(EditorScriptPreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorSamplePreviewPlugin>( memnew(EditorSamplePreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorMeshPreviewPlugin>( memnew(EditorMeshPreviewPlugin )));
- resource_preview->add_preview_generator( Ref<EditorBitmapPreviewPlugin>( memnew(EditorBitmapPreviewPlugin )));
-*/
+ resource_preview->add_preview_generator(Ref<EditorTexturePreviewPlugin>(memnew(EditorTexturePreviewPlugin)));
+ resource_preview->add_preview_generator(Ref<EditorPackedScenePreviewPlugin>(memnew(EditorPackedScenePreviewPlugin)));
+ resource_preview->add_preview_generator(Ref<EditorMaterialPreviewPlugin>(memnew(EditorMaterialPreviewPlugin)));
+ resource_preview->add_preview_generator(Ref<EditorScriptPreviewPlugin>(memnew(EditorScriptPreviewPlugin)));
+ //resource_preview->add_preview_generator( Ref<EditorSamplePreviewPlugin>( memnew(EditorSamplePreviewPlugin )));
+ resource_preview->add_preview_generator(Ref<EditorMeshPreviewPlugin>(memnew(EditorMeshPreviewPlugin)));
+ resource_preview->add_preview_generator(Ref<EditorBitmapPreviewPlugin>(memnew(EditorBitmapPreviewPlugin)));
circle_step_msec = OS::get_singleton()->get_ticks_msec();
circle_step_frame = Engine::get_singleton()->get_frames_drawn();
@@ -5949,6 +6142,7 @@ EditorNode::EditorNode() {
editor_plugin_screen = NULL;
editor_plugins_over = memnew(EditorPluginList);
+ editor_plugins_force_input_forwarding = memnew(EditorPluginList);
//force_top_viewport(true);
_edit_current();
@@ -6082,6 +6276,14 @@ EditorNode::EditorNode() {
_dim_timer->set_wait_time(0.01666f);
_dim_timer->connect("timeout", this, "_dim_timeout");
add_child(_dim_timer);
+
+ ED_SHORTCUT("editor/editor_2d", TTR("Open 2D Editor"), KEY_F2);
+ ED_SHORTCUT("editor/editor_3d", TTR("Open 3D Editor"), KEY_F3);
+ ED_SHORTCUT("editor/editor_script", TTR("Open Script Editor"), KEY_F4);
+ ED_SHORTCUT("editor/editor_help", TTR("Search Help"), KEY_F1);
+ ED_SHORTCUT("editor/editor_assetlib", TTR("Open Asset Library"));
+ ED_SHORTCUT("editor/editor_next", TTR("Open the next Editor"));
+ ED_SHORTCUT("editor/editor_prev", TTR("Open the previous Editor"));
}
EditorNode::~EditorNode() {
@@ -6089,6 +6291,7 @@ EditorNode::~EditorNode() {
memdelete(EditorHelp::get_doc_data());
memdelete(editor_selection);
memdelete(editor_plugins_over);
+ memdelete(editor_plugins_force_input_forwarding);
memdelete(file_server);
EditorSettings::destroy();
}
@@ -6111,7 +6314,7 @@ void EditorPluginList::edit(Object *p_object) {
}
}
-bool EditorPluginList::forward_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) {
+bool EditorPluginList::forward_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) {
bool discard = false;
@@ -6124,10 +6327,14 @@ bool EditorPluginList::forward_gui_input(const Transform2D &p_canvas_xform, cons
return discard;
}
-bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const InputEvent &p_event) {
+bool EditorPluginList::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled) {
bool discard = false;
for (int i = 0; i < plugins_list.size(); i++) {
+ if ((!serve_when_force_input_enabled) && plugins_list[i]->is_input_event_forwarding_always_enabled()) {
+ continue;
+ }
+
if (plugins_list[i]->forward_spatial_gui_input(p_camera, p_event)) {
discard = true;
}
@@ -6143,6 +6350,10 @@ void EditorPluginList::forward_draw_over_canvas(const Transform2D &p_canvas_xfor
}
}
+void EditorPluginList::add_plugin(EditorPlugin *p_plugin) {
+ plugins_list.push_back(p_plugin);
+}
+
bool EditorPluginList::empty() {
return plugins_list.empty();
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 7de713eae9..3870edb7c6 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -186,12 +186,19 @@ private:
SETTINGS_PICK_MAIN_SCENE,
SETTINGS_TOGGLE_FULLSCREN,
SETTINGS_HELP,
- SETTINGS_ABOUT,
SOURCES_REIMPORT,
DEPENDENCY_LOAD_CHANGED_IMAGES,
DEPENDENCY_UPDATE_IMPORTED,
SCENE_TAB_CLOSE,
+ HELP_CLASSES,
+ HELP_SEARCH,
+ HELP_DOCS,
+ HELP_QA,
+ HELP_ISSUES,
+ HELP_COMMUNITY,
+ HELP_ABOUT,
+
IMPORT_PLUGIN_BASE = 100,
OBJECT_METHOD_BASE = 500,
@@ -205,8 +212,10 @@ private:
//Ref<ResourceImportMetadata> scene_import_metadata;
PanelContainer *scene_root_parent;
+ Control *theme_base;
Control *gui_base;
VBoxContainer *main_vbox;
+ PanelContainer *play_button_panel;
//split
@@ -224,6 +233,8 @@ private:
//main tabs
Tabs *scene_tabs;
+ Panel *tab_preview_panel;
+ TextureRect *tab_preview;
int tab_closing;
bool exiting;
@@ -242,7 +253,9 @@ private:
HBoxContainer *menu_hb;
Control *viewport;
MenuButton *file_menu;
- MenuButton *tool_menu;
+ MenuButton *project_menu;
+ MenuButton *debug_menu;
+ PopupMenu *tool_menu;
ToolButton *export_button;
ToolButton *prev_scene;
MenuButton *object_menu;
@@ -254,7 +267,6 @@ private:
ToolButton *run_settings_button;
ToolButton *play_scene_button;
ToolButton *play_custom_scene_button;
- MenuButton *debug_button;
ToolButton *search_button;
TextureProgress *audio_vu;
//MenuButton *fileserver_menu;
@@ -310,7 +322,7 @@ private:
LineEdit *file_export_password;
String current_path;
MenuButton *update_menu;
- ToolButton *sources_button;
+
//TabContainer *prop_pallete;
//TabContainer *top_pallete;
String defer_load_scene;
@@ -357,6 +369,9 @@ private:
bool docks_visible;
ToolButton *distraction_free;
+ bool scene_distraction;
+ bool script_distraction;
+
String _tmp_import_path;
EditorExport *editor_export;
@@ -383,6 +398,7 @@ private:
Vector<EditorPlugin *> editor_plugins;
EditorPlugin *editor_plugin_screen;
EditorPluginList *editor_plugins_over;
+ EditorPluginList *editor_plugins_force_input_forwarding;
EditorHistory editor_history;
EditorData editor_data;
@@ -437,6 +453,8 @@ private:
void _imported(Node *p_node);
void _node_renamed();
+ void _editor_select_next();
+ void _editor_select_prev();
void _editor_select(int p_which);
void _set_scene_metadata(const String &p_file, int p_idx = -1);
void _get_scene_metadata(const String &p_file);
@@ -475,7 +493,7 @@ private:
bool convert_old;
- void _unhandled_input(const InputEvent &p_event);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
static void _load_error_notify(void *p_ud, const String &p_text);
@@ -532,7 +550,7 @@ private:
bool _find_scene_in_use(Node *p_node, const String &p_path) const;
- void _dock_select_input(const InputEvent &p_input);
+ void _dock_select_input(const Ref<InputEvent> &p_input);
void _dock_move_left();
void _dock_move_right();
void _dock_select_draw();
@@ -541,6 +559,10 @@ private:
void _dock_popup_exit();
void _scene_tab_changed(int p_tab);
void _scene_tab_closed(int p_tab);
+ void _scene_tab_hover(int p_tab);
+ void _scene_tab_exit();
+ void _scene_tab_input(const Ref<InputEvent> &p_input);
+ void _thumbnail_done(const String &p_path, const Ref<Texture> &p_preview, const Variant &p_udata);
void _scene_tab_script_edited(int p_tab);
Dictionary _get_main_scene_state();
@@ -578,6 +600,7 @@ private:
static int plugin_init_callback_count;
static EditorPluginInitializeCallback plugin_init_callbacks[MAX_INIT_CALLBACKS];
+ void _save_default_environment();
void _call_build();
static int build_callback_count;
@@ -604,6 +627,7 @@ private:
void _start_dimming(bool p_dimming);
void _dim_timeout();
+ void _check_gui_base_size();
protected:
void _notification(int p_what);
@@ -615,7 +639,8 @@ public:
enum EditorTable {
EDITOR_2D = 0,
EDITOR_3D,
- EDITOR_SCRIPT
+ EDITOR_SCRIPT,
+ EDITOR_ASSETLIB
};
void set_visible_editor(EditorTable p_table) { _editor_select(p_table); }
@@ -623,6 +648,7 @@ public:
EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; }
+ EditorPluginList *get_editor_plugins_force_input_forwarding() { return editor_plugins_force_input_forwarding; }
PropertyEditor *get_property_editor() { return property_editor; }
VBoxContainer *get_property_editor_vb() { return prop_editor_vb; }
@@ -798,9 +824,10 @@ public:
void make_visible(bool p_visible);
void edit(Object *p_object);
- bool forward_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event);
- bool forward_spatial_gui_input(Camera *p_camera, const InputEvent &p_event);
+ bool forward_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event);
+ bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event, bool serve_when_force_input_enabled);
void forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas);
+ void add_plugin(EditorPlugin *p_plugin);
void clear();
bool empty();
diff --git a/editor/editor_path.cpp b/editor/editor_path.cpp
index 98e0808ba5..8ce4f88590 100644
--- a/editor/editor_path.cpp
+++ b/editor/editor_path.cpp
@@ -69,9 +69,10 @@ void EditorPath::_add_children_to_popup(Object *p_obj, int p_depth) {
}
}
-void EditorPath::_gui_input(const InputEvent &p_event) {
+void EditorPath::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_LEFT && p_event.mouse_button.pressed) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
Object *obj = ObjectDB::get_instance(history->get_path_object(history->get_path_size() - 1));
if (!obj)
diff --git a/editor/editor_path.h b/editor/editor_path.h
index a142cba44c..7b73e7ebb6 100644
--- a/editor/editor_path.h
+++ b/editor/editor_path.h
@@ -46,7 +46,7 @@ class EditorPath : public Control {
EditorPath();
void _popup_select(int p_idx);
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _add_children_to_popup(Object *p_obj, int p_depth = 0);
protected:
diff --git a/editor/editor_plugin.cpp b/editor/editor_plugin.cpp
index 405784a7e2..75ab1e8a44 100644
--- a/editor/editor_plugin.cpp
+++ b/editor/editor_plugin.cpp
@@ -147,6 +147,12 @@ void EditorPlugin::remove_tool_menu_item(const String &p_name) {
//EditorNode::get_singleton()->remove_tool_menu_item(p_name);
}
+void EditorPlugin::set_input_event_forwarding_always_enabled() {
+ input_event_forwarding_always_enabled = true;
+ EditorPluginList *always_input_forwarding_list = EditorNode::get_singleton()->get_editor_plugins_force_input_forwarding();
+ always_input_forwarding_list->add_plugin(this);
+}
+
Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
//??
if (get_script_instance() && get_script_instance()->has_method("create_spatial_gizmo")) {
@@ -156,7 +162,7 @@ Ref<SpatialEditorGizmo> EditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
return Ref<SpatialEditorGizmo>();
}
-bool EditorPlugin::forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) {
+bool EditorPlugin::forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) {
if (get_script_instance() && get_script_instance()->has_method("forward_canvas_gui_input")) {
return get_script_instance()->call("forward_canvas_gui_input", p_canvas_xform, p_event);
@@ -175,7 +181,7 @@ void EditorPlugin::update_canvas() {
CanvasItemEditor::get_singleton()->get_viewport_control()->update();
}
-bool EditorPlugin::forward_spatial_gui_input(Camera *p_camera, const InputEvent &p_event) {
+bool EditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
if (get_script_instance() && get_script_instance()->has_method("forward_spatial_gui_input")) {
return get_script_instance()->call("forward_spatial_gui_input", p_camera, p_event);
@@ -276,6 +282,16 @@ bool EditorPlugin::get_remove_list(List<Node *> *p_list) {
void EditorPlugin::restore_global_state() {}
void EditorPlugin::save_global_state() {}
+void EditorPlugin::add_import_plugin(const Ref<EditorImportPlugin> &p_importer) {
+ ResourceFormatImporter::get_singleton()->add_importer(p_importer);
+ EditorFileSystem::get_singleton()->scan_changes();
+}
+
+void EditorPlugin::remove_import_plugin(const Ref<EditorImportPlugin> &p_importer) {
+ ResourceFormatImporter::get_singleton()->remove_importer(p_importer);
+ EditorFileSystem::get_singleton()->scan_changes();
+}
+
void EditorPlugin::set_window_layout(Ref<ConfigFile> p_layout) {
if (get_script_instance() && get_script_instance()->has_method("set_window_layout")) {
@@ -360,10 +376,12 @@ void EditorPlugin::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_editor_settings:EditorSettings"), &EditorPlugin::get_editor_settings);
ClassDB::bind_method(D_METHOD("queue_save_layout"), &EditorPlugin::queue_save_layout);
ClassDB::bind_method(D_METHOD("edit_resource"), &EditorPlugin::edit_resource);
-
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::INPUT_EVENT, "event")));
+ ClassDB::bind_method(D_METHOD("add_import_plugin"), &EditorPlugin::add_import_plugin);
+ ClassDB::bind_method(D_METHOD("remove_import_plugin"), &EditorPlugin::remove_import_plugin);
+ ClassDB::bind_method(D_METHOD("set_input_event_forwarding_always_enabled"), &EditorPlugin::set_input_event_forwarding_always_enabled);
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_canvas_gui_input", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
ClassDB::add_virtual_method(get_class_static(), MethodInfo("forward_draw_over_canvas", PropertyInfo(Variant::TRANSFORM2D, "canvas_xform"), PropertyInfo(Variant::OBJECT, "canvas:Control")));
- ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::INPUT_EVENT, "event")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "forward_spatial_gui_input", PropertyInfo(Variant::OBJECT, "camera", PROPERTY_HINT_RESOURCE_TYPE, "Camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
MethodInfo gizmo = MethodInfo(Variant::OBJECT, "create_spatial_gizmo", PropertyInfo(Variant::OBJECT, "for_spatial:Spatial"));
gizmo.return_val.hint = PROPERTY_HINT_RESOURCE_TYPE;
gizmo.return_val.hint_string = "EditorSpatialGizmo";
@@ -403,6 +421,7 @@ void EditorPlugin::_bind_methods() {
EditorPlugin::EditorPlugin() {
undo_redo = NULL;
+ input_event_forwarding_always_enabled = false;
}
EditorPlugin::~EditorPlugin() {
diff --git a/editor/editor_plugin.h b/editor/editor_plugin.h
index 5df1f63fbe..57a22a8b2f 100644
--- a/editor/editor_plugin.h
+++ b/editor/editor_plugin.h
@@ -30,6 +30,7 @@
#ifndef EDITOR_PLUGIN_H
#define EDITOR_PLUGIN_H
+#include "editor/import/editor_import_plugin.h"
#include "io/config_file.h"
#include "scene/gui/tool_button.h"
#include "scene/main/node.h"
@@ -60,6 +61,8 @@ class EditorPlugin : public Node {
UndoRedo *_get_undo_redo() { return undo_redo; }
+ bool input_event_forwarding_always_enabled;
+
protected:
static void _bind_methods();
UndoRedo &get_undo_redo() { return *undo_redo; }
@@ -105,10 +108,13 @@ public:
void add_tool_submenu_item(const String &p_name, Object *p_submenu);
void remove_tool_menu_item(const String &p_name);
+ void set_input_event_forwarding_always_enabled();
+ bool is_input_event_forwarding_always_enabled() { return input_event_forwarding_always_enabled; }
+
virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event);
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event);
virtual void forward_draw_over_canvas(const Transform2D &p_canvas_xform, Control *p_canvas);
- virtual bool forward_spatial_gui_input(Camera *p_camera, const InputEvent &p_event);
+ virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
virtual String get_name() const;
virtual bool has_main_screen() const;
virtual void make_visible(bool p_visible);
@@ -146,6 +152,9 @@ public:
virtual void restore_global_state();
virtual void save_global_state();
+ void add_import_plugin(const Ref<EditorImportPlugin> &p_importer);
+ void remove_import_plugin(const Ref<EditorImportPlugin> &p_importer);
+
EditorPlugin();
virtual ~EditorPlugin();
};
diff --git a/editor/editor_profiler.cpp b/editor/editor_profiler.cpp
index 8f4312111a..64cf275c3a 100644
--- a/editor/editor_profiler.cpp
+++ b/editor/editor_profiler.cpp
@@ -344,14 +344,16 @@ void EditorProfiler::_update_plot() {
wr = PoolVector<uint8_t>::Write();
- Image img(w, h, 0, Image::FORMAT_RGBA8, graph_image);
+ Ref<Image> img;
+ img.instance();
+ img->create(w, h, 0, Image::FORMAT_RGBA8, graph_image);
if (reset_texture) {
if (graph_texture.is_null()) {
graph_texture.instance();
}
- graph_texture->create(img.get_width(), img.get_height(), img.get_format(), Texture::FLAG_VIDEO_SURFACE);
+ graph_texture->create(img->get_width(), img->get_height(), img->get_format(), Texture::FLAG_VIDEO_SURFACE);
}
graph_texture->set_data(img);
@@ -481,16 +483,20 @@ void EditorProfiler::_cursor_metric_changed(double) {
_update_frame();
}
-void EditorProfiler::_graph_tex_input(const InputEvent &p_ev) {
+void EditorProfiler::_graph_tex_input(const Ref<InputEvent> &p_ev) {
if (last_metric < 0)
return;
+ Ref<InputEventMouse> me = p_ev;
+ Ref<InputEventMouseButton> mb = p_ev;
+ Ref<InputEventMouseMotion> mm = p_ev;
+
if (
- (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT && p_ev.mouse_button.pressed) ||
- (p_ev.type == InputEvent::MOUSE_MOTION)) {
+ (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) ||
+ (mm.is_valid())) {
- int x = p_ev.mouse_button.x;
+ int x = me->get_position().x;
x = x * frame_metrics.size() / graph->get_size().width;
bool show_hover = x >= 0 && x < frame_metrics.size();
@@ -517,7 +523,7 @@ void EditorProfiler::_graph_tex_input(const InputEvent &p_ev) {
hover_metric = -1;
}
- if (p_ev.type == InputEvent::MOUSE_BUTTON || p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ if (mb.is_valid() || mm->get_button_mask() & BUTTON_MASK_LEFT) {
//cursor_metric=x;
updating_frame = true;
diff --git a/editor/editor_profiler.h b/editor/editor_profiler.h
index 35b5ae366c..4998d45a89 100644
--- a/editor/editor_profiler.h
+++ b/editor/editor_profiler.h
@@ -143,7 +143,7 @@ private:
void _graph_tex_mouse_exit();
void _graph_tex_draw();
- void _graph_tex_input(const InputEvent &p_ev);
+ void _graph_tex_input(const Ref<InputEvent> &p_ev);
int _get_cursor_index() const;
diff --git a/editor/editor_resource_preview.cpp b/editor/editor_resource_preview.cpp
index 0b1887e8a2..5d68de3bb6 100644
--- a/editor/editor_resource_preview.cpp
+++ b/editor/editor_resource_preview.cpp
@@ -190,7 +190,7 @@ void EditorResourcePreview::_thread() {
} else {
preview_mutex->unlock();
- Ref<Texture> texture;
+ Ref<ImageTexture> texture;
//print_line("pop from queue "+item.path);
@@ -229,6 +229,7 @@ void EditorResourcePreview::_thread() {
bool cache_valid = true;
if (tsize != thumbnail_size) {
+
cache_valid = false;
memdelete(f);
} else if (last_modtime != modtime) {
@@ -240,6 +241,7 @@ void EditorResourcePreview::_thread() {
if (last_md5 != md5) {
cache_valid = false;
+
} else {
//update modified time
@@ -252,14 +254,20 @@ void EditorResourcePreview::_thread() {
memdelete(f);
}
- cache_valid = false;
+ //cache_valid = false;
if (cache_valid) {
- texture = ResourceLoader::load(cache_base + ".png", "ImageTexture", true);
- if (!texture.is_valid()) {
+ Ref<Image> img;
+ img.instance();
+
+ if (img->load(cache_base + ".png") != OK) {
//well fuck
cache_valid = false;
+ } else {
+
+ texture.instance();
+ texture->create_from_image(img, Texture::FLAG_FILTER);
}
}
diff --git a/editor/editor_run.cpp b/editor/editor_run.cpp
index d36b8cece5..a8106b4eec 100644
--- a/editor/editor_run.cpp
+++ b/editor/editor_run.cpp
@@ -41,6 +41,8 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
List<String> args;
String resource_path = GlobalConfig::get_singleton()->get_resource_path();
+ String remote_host = EditorSettings::get_singleton()->get("network/debug/remote_host");
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
if (resource_path != "") {
args.push_back("-path");
@@ -49,7 +51,7 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
if (true) {
args.push_back("-rdebug");
- args.push_back("localhost:" + String::num(GLOBAL_GET("network/debug/remote_port")));
+ args.push_back(remote_host + ":" + String::num(remote_port));
}
args.push_back("-epid");
@@ -72,17 +74,17 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
}
Rect2 screen_rect;
- screen_rect.pos = OS::get_singleton()->get_screen_position(screen);
+ screen_rect.position = OS::get_singleton()->get_screen_position(screen);
screen_rect.size = OS::get_singleton()->get_screen_size(screen);
Size2 desired_size;
- desired_size.x = GlobalConfig::get_singleton()->get("display/width");
- desired_size.y = GlobalConfig::get_singleton()->get("display/height");
+ desired_size.x = GlobalConfig::get_singleton()->get("display/window/width");
+ desired_size.y = GlobalConfig::get_singleton()->get("display/window/height");
Size2 test_size;
- test_size.x = GlobalConfig::get_singleton()->get("display/test_width");
- test_size.y = GlobalConfig::get_singleton()->get("display/test_height");
+ test_size.x = GlobalConfig::get_singleton()->get("display/window/test_width");
+ test_size.y = GlobalConfig::get_singleton()->get("display/window/test_height");
if (test_size.x > 0 && test_size.y > 0) {
desired_size = test_size;
@@ -94,21 +96,21 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
case 0: { // default
args.push_back("-p");
- args.push_back(itos(screen_rect.pos.x) + "x" + itos(screen_rect.pos.y));
+ args.push_back(itos(screen_rect.position.x) + "x" + itos(screen_rect.position.y));
} break;
case 1: { // centered
- Vector2 pos = screen_rect.pos + ((screen_rect.size - desired_size) / 2).floor();
+ Vector2 pos = screen_rect.position + ((screen_rect.size - desired_size) / 2).floor();
args.push_back("-p");
args.push_back(itos(pos.x) + "x" + itos(pos.y));
} break;
case 2: { // custom pos
Vector2 pos = EditorSettings::get_singleton()->get("run/window_placement/rect_custom_position");
- pos += screen_rect.pos;
+ pos += screen_rect.position;
args.push_back("-p");
args.push_back(itos(pos.x) + "x" + itos(pos.y));
} break;
case 3: { // force maximized
- Vector2 pos = screen_rect.pos;
+ Vector2 pos = screen_rect.position;
args.push_back("-p");
args.push_back(itos(pos.x) + "x" + itos(pos.y));
args.push_back("-mx");
@@ -116,7 +118,7 @@ Error EditorRun::run(const String &p_scene, const String p_custom_args, const Li
} break;
case 4: { // force fullscreen
- Vector2 pos = screen_rect.pos;
+ Vector2 pos = screen_rect.position;
args.push_back("-p");
args.push_back(itos(pos.x) + "x" + itos(pos.y));
args.push_back("-f");
diff --git a/editor/editor_run_native.cpp b/editor/editor_run_native.cpp
index 5a519a1dbd..4a767621ef 100644
--- a/editor/editor_run_native.cpp
+++ b/editor/editor_run_native.cpp
@@ -43,11 +43,12 @@ void EditorRunNative::_notification(int p_what) {
continue;
Ref<ImageTexture> icon = eep->get_logo();
if (!icon.is_null()) {
- Image im = icon->get_data();
- im.clear_mipmaps();
- if (!im.empty()) {
+ Ref<Image> im = icon->get_data();
+ im = im->duplicate();
+ im->clear_mipmaps();
+ if (!im->empty()) {
- im.resize(16, 16);
+ im->resize(16, 16);
Ref<ImageTexture> small_icon;
small_icon.instance();
small_icon->create_from_image(im, 0);
diff --git a/editor/editor_settings.cpp b/editor/editor_settings.cpp
index 1b4f77419b..485f8236de 100644
--- a/editor/editor_settings.cpp
+++ b/editor/editor_settings.cpp
@@ -65,7 +65,7 @@ bool EditorSettings::_set(const StringName &p_name, const Variant &p_value) {
for (int i = 0; i < arr.size(); i += 2) {
String name = arr[i];
- InputEvent shortcut = arr[i + 1];
+ Ref<InputEvent> shortcut = arr[i + 1];
Ref<ShortCut> sc;
sc.instance();
@@ -109,8 +109,8 @@ bool EditorSettings::_get(const StringName &p_name, Variant &r_ret) const {
continue; //this came from settings but is not any longer used
}
- InputEvent original = sc->get_meta("original");
- if (sc->is_shortcut(original) || (original.type == InputEvent::NONE && sc->get_shortcut().type == InputEvent::NONE))
+ Ref<InputEvent> original = sc->get_meta("original");
+ if (sc->is_shortcut(original) || (original.is_null() && sc->get_shortcut().is_null()))
continue; //not changed from default, don't save
}
@@ -292,6 +292,12 @@ void EditorSettings::create() {
dir->change_dir("..");
}
+ if (dir->change_dir("script_templates") != OK) {
+ dir->make_dir("script_templates");
+ } else {
+ dir->change_dir("..");
+ }
+
if (dir->change_dir("tmp") != OK) {
dir->make_dir("tmp");
} else {
@@ -407,13 +413,12 @@ void EditorSettings::setup_network() {
IP::get_singleton()->get_local_addresses(&local_ip);
String lip;
String hint;
- String current = has("network/debug_host") ? get("network/debug_host") : "";
+ String current = has("network/debug/remote_host") ? get("network/debug/remote_host") : "";
+ int port = has("network/debug/remote_port") ? (int)get("network/debug/remote_port") : 6007;
for (List<IP_Address>::Element *E = local_ip.front(); E; E = E->next()) {
String ip = E->get();
- if (ip == "127.0.0.1")
- continue;
if (lip == "")
lip = ip;
@@ -424,8 +429,11 @@ void EditorSettings::setup_network() {
hint += ip;
}
- set("network/debug_host", lip);
- add_property_hint(PropertyInfo(Variant::STRING, "network/debug_host", PROPERTY_HINT_ENUM, hint));
+ set("network/debug/remote_host", lip);
+ add_property_hint(PropertyInfo(Variant::STRING, "network/debug/remote_host", PROPERTY_HINT_ENUM, hint));
+
+ set("network/debug/remote_port", port);
+ add_property_hint(PropertyInfo(Variant::INT, "network/debug/remote_port", PROPERTY_HINT_RANGE, "1,65535,1"));
}
void EditorSettings::save() {
@@ -500,15 +508,32 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("interface/source_font_size", 14);
hints["interface/source_font_size"] = PropertyInfo(Variant::INT, "interface/source_font_size", PROPERTY_HINT_RANGE, "8,96,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/custom_font", "");
- hints["interface/custom_font"] = PropertyInfo(Variant::STRING, "interface/custom_font", PROPERTY_HINT_GLOBAL_FILE, "*.fnt", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("interface/custom_theme", "");
- hints["interface/custom_theme"] = PropertyInfo(Variant::STRING, "interface/custom_theme", PROPERTY_HINT_GLOBAL_FILE, "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ hints["interface/custom_font"] = PropertyInfo(Variant::STRING, "interface/custom_font", PROPERTY_HINT_GLOBAL_FILE, "*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
set("interface/dim_editor_on_dialog_popup", true);
set("interface/dim_amount", 0.6f);
hints["interface/dim_amount"] = PropertyInfo(Variant::REAL, "interface/dim_amount", PROPERTY_HINT_RANGE, "0,1,0.01", PROPERTY_USAGE_DEFAULT);
set("interface/dim_transition_time", 0.08f);
hints["interface/dim_transition_time"] = PropertyInfo(Variant::REAL, "interface/dim_transition_time", PROPERTY_HINT_RANGE, "0,1,0.001", PROPERTY_USAGE_DEFAULT);
+ set("interface/separate_distraction_mode", false);
+
+ set("interface/theme/preset", 0);
+ hints["interface/theme/preset"] = PropertyInfo(Variant::INT, "interface/theme/preset", PROPERTY_HINT_ENUM, "Default,Grey,Godot 2,Arc,Custom", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ set("interface/theme/base_color", Color::html("#273241"));
+ hints["interface/theme/highlight_color"] = PropertyInfo(Variant::COLOR, "interface/theme/highlight_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ set("interface/theme/highlight_color", Color::html("#b79047"));
+ hints["interface/theme/base_color"] = PropertyInfo(Variant::COLOR, "interface/theme/base_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+ set("interface/theme/contrast", 0.2);
+ hints["interface/theme/contrast"] = PropertyInfo(Variant::REAL, "interface/theme/contrast", PROPERTY_HINT_RANGE, "0.01, 1, 0.01");
+ set("interface/theme/custom_theme", "");
+ hints["interface/theme/custom_theme"] = PropertyInfo(Variant::STRING, "interface/theme/custom_theme", PROPERTY_HINT_GLOBAL_FILE, "*.res,*.tres,*.theme", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+
+ set("interface/scene_tabs/show_extension", false);
+ set("interface/scene_tabs/show_thumbnail_on_hover", true);
+ set("interface/scene_tabs/resize_if_many_tabs", true);
+ set("interface/scene_tabs/minimum_width", 50);
+ hints["interface/scene_tabs/minimum_width"] = PropertyInfo(Variant::INT, "interface/scene_tabs/minimum_width", PROPERTY_HINT_RANGE, "50,500,1", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
+
set("filesystem/directories/autoscan_project_path", "");
hints["filesystem/directories/autoscan_project_path"] = PropertyInfo(Variant::STRING, "filesystem/directories/autoscan_project_path", PROPERTY_HINT_GLOBAL_DIR);
set("filesystem/directories/default_project_path", "");
@@ -543,6 +568,8 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("text_editor/line_numbers/line_length_guideline_column", 80);
hints["text_editor/line_numbers/line_length_guideline_column"] = PropertyInfo(Variant::INT, "text_editor/line_numbers/line_length_guideline_column", PROPERTY_HINT_RANGE, "20, 160, 10");
+ set("text_editor/open_scripts/show_members_overview", true);
+
set("text_editor/files/trim_trailing_whitespace_on_save", false);
set("text_editor/completion/idle_parse_delay", 2);
set("text_editor/tools/create_signal_callbacks", true);
@@ -554,7 +581,7 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
hints["text_editor/cursor/caret_blink_speed"] = PropertyInfo(Variant::REAL, "text_editor/cursor/caret_blink_speed", PROPERTY_HINT_RANGE, "0.1, 10, 0.1");
set("text_editor/theme/font", "");
- hints["text_editor/theme/font"] = PropertyInfo(Variant::STRING, "text_editor/theme/font", PROPERTY_HINT_GLOBAL_FILE, "*.fnt");
+ hints["text_editor/theme/font"] = PropertyInfo(Variant::STRING, "text_editor/theme/font", PROPERTY_HINT_GLOBAL_FILE, "*.font");
set("text_editor/completion/auto_brace_complete", false);
set("text_editor/files/restore_scripts_on_load", true);
set("text_editor/completion/complete_file_paths", true);
@@ -568,10 +595,10 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/grid_map/pick_distance", 5000.0);
- set("editors/3d/grid_color", Color(1, 1, 1, 0.2));
+ set("editors/3d/grid_color", Color(0, 1, 0, 0.2));
hints["editors/3d/grid_color"] = PropertyInfo(Variant::COLOR, "editors/3d/grid_color", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED);
- set("editors/3d/default_fov", 45.0);
+ set("editors/3d/default_fov", 55.0);
set("editors/3d/default_z_near", 0.1);
set("editors/3d/default_z_far", 500.0);
@@ -589,6 +616,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/3d/emulate_3_button_mouse", false);
set("editors/3d/warped_mouse_panning", true);
+ set("editors/3d/freelook_base_speed", 1);
+ set("editors/3d/freelook_modifier_speed_factor", 5.0);
+
set("editors/2d/bone_width", 5);
set("editors/2d/bone_color1", Color(1.0, 1.0, 1.0, 0.9));
set("editors/2d/bone_color2", Color(0.75, 0.75, 0.75, 0.9));
@@ -596,10 +626,12 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
set("editors/2d/bone_ik_color", Color(0.9, 0.9, 0.45, 0.9));
set("editors/2d/keep_margins_when_changing_anchors", false);
set("editors/2d/warped_mouse_panning", true);
+ set("editors/2d/scroll_to_pan", false);
+ set("editors/2d/pan_speed", 20);
set("editors/poly_editor/point_grab_radius", 8);
- set("run/window_placement/rect", 0);
+ set("run/window_placement/rect", 1);
hints["run/window_placement/rect"] = PropertyInfo(Variant::INT, "run/window_placement/rect", PROPERTY_HINT_ENUM, "Default,Centered,Custom Position,Force Maximized,Force Full Screen");
String screen_hints = TTR("Default (Same as Editor)");
for (int i = 0; i < OS::get_singleton()->get_screen_count(); i++) {
@@ -926,6 +958,25 @@ bool EditorSettings::save_text_editor_theme_as(String p_file) {
return false;
}
+Vector<String> EditorSettings::get_script_templates(const String &p_extension) {
+
+ Vector<String> templates;
+ DirAccess *d = DirAccess::open(settings_path + "/script_templates");
+ if (d) {
+ d->list_dir_begin();
+ String file = d->get_next();
+ while (file != String()) {
+ if (file.get_extension() == p_extension) {
+ templates.push_back(file.get_basename());
+ }
+ file = d->get_next();
+ }
+ d->list_dir_end();
+ memdelete(d);
+ }
+ return templates;
+}
+
bool EditorSettings::_save_text_editor_theme(String p_file) {
String theme_section = "color_theme";
Ref<ConfigFile> cf = memnew(ConfigFile); // hex is better?
@@ -972,7 +1023,7 @@ void EditorSettings::add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcu
shortcuts[p_name] = p_shortcut;
}
-bool EditorSettings::is_shortcut(const String &p_name, const InputEvent &p_event) const {
+bool EditorSettings::is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const {
const Map<String, Ref<ShortCut> >::Element *E = shortcuts.find(p_name);
if (!E) {
@@ -1089,15 +1140,16 @@ Ref<ShortCut> ED_GET_SHORTCUT(const String &p_path) {
Ref<ShortCut> ED_SHORTCUT(const String &p_path, const String &p_name, uint32_t p_keycode) {
- InputEvent ie;
+ Ref<InputEventKey> ie;
if (p_keycode) {
- ie.type = InputEvent::KEY;
- ie.key.unicode = p_keycode & KEY_CODE_MASK;
- ie.key.scancode = p_keycode & KEY_CODE_MASK;
- ie.key.mod.shift = bool(p_keycode & KEY_MASK_SHIFT);
- ie.key.mod.alt = bool(p_keycode & KEY_MASK_ALT);
- ie.key.mod.control = bool(p_keycode & KEY_MASK_CTRL);
- ie.key.mod.meta = bool(p_keycode & KEY_MASK_META);
+ ie.instance();
+
+ ie->set_unicode(p_keycode & KEY_CODE_MASK);
+ ie->set_scancode(p_keycode & KEY_CODE_MASK);
+ ie->set_shift(bool(p_keycode & KEY_MASK_SHIFT));
+ ie->set_alt(bool(p_keycode & KEY_MASK_ALT));
+ ie->set_control(bool(p_keycode & KEY_MASK_CTRL));
+ ie->set_metakey(bool(p_keycode & KEY_MASK_META));
}
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(p_path);
diff --git a/editor/editor_settings.h b/editor/editor_settings.h
index a876f23134..d5adb84b63 100644
--- a/editor/editor_settings.h
+++ b/editor/editor_settings.h
@@ -159,8 +159,10 @@ public:
bool save_text_editor_theme();
bool save_text_editor_theme_as(String p_file);
+ Vector<String> get_script_templates(const String &p_extension);
+
void add_shortcut(const String &p_name, Ref<ShortCut> &p_shortcut);
- bool is_shortcut(const String &p_name, const InputEvent &p_event) const;
+ bool is_shortcut(const String &p_name, const Ref<InputEvent> &p_event) const;
Ref<ShortCut> get_shortcut(const String &p_name) const;
void get_shortcut_list(List<String> *r_shortcuts);
diff --git a/editor/editor_themes.cpp b/editor/editor_themes.cpp
index 1457f6b421..e6df58bc60 100644
--- a/editor/editor_themes.cpp
+++ b/editor/editor_themes.cpp
@@ -35,99 +35,423 @@
#include "editor_scale.h"
#include "editor_settings.h"
+static Ref<StyleBoxTexture> make_stylebox(Ref<Texture> texture, float p_left, float p_top, float p_right, float p_botton, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_botton = -1, bool p_draw_center = true) {
+ Ref<StyleBoxTexture> style(memnew(StyleBoxTexture));
+ style->set_texture(texture);
+ style->set_margin_size(MARGIN_LEFT, p_left * EDSCALE);
+ style->set_margin_size(MARGIN_RIGHT, p_right * EDSCALE);
+ style->set_margin_size(MARGIN_BOTTOM, p_botton * EDSCALE);
+ style->set_margin_size(MARGIN_TOP, p_top * EDSCALE);
+ style->set_default_margin(MARGIN_LEFT, p_margin_left * EDSCALE);
+ style->set_default_margin(MARGIN_RIGHT, p_margin_right * EDSCALE);
+ style->set_default_margin(MARGIN_BOTTOM, p_margin_botton * EDSCALE);
+ style->set_default_margin(MARGIN_TOP, p_margin_top * EDSCALE);
+ style->set_draw_center(p_draw_center);
+ return style;
+}
+
+static Ref<StyleBoxEmpty> make_empty_stylebox(float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
+ Ref<StyleBoxEmpty> style(memnew(StyleBoxEmpty));
+ style->set_default_margin(MARGIN_LEFT, p_margin_left * EDSCALE);
+ style->set_default_margin(MARGIN_RIGHT, p_margin_right * EDSCALE);
+ style->set_default_margin(MARGIN_BOTTOM, p_margin_bottom * EDSCALE);
+ style->set_default_margin(MARGIN_TOP, p_margin_top * EDSCALE);
+ return style;
+}
+
+static Ref<StyleBoxFlat> make_flat_stylebox(Color color, float p_margin_left = -1, float p_margin_top = -1, float p_margin_right = -1, float p_margin_bottom = -1) {
+ Ref<StyleBoxFlat> style(memnew(StyleBoxFlat));
+ style->set_bg_color(color);
+ style->set_default_margin(MARGIN_LEFT, p_margin_left * EDSCALE);
+ style->set_default_margin(MARGIN_RIGHT, p_margin_right * EDSCALE);
+ style->set_default_margin(MARGIN_BOTTOM, p_margin_bottom * EDSCALE);
+ style->set_default_margin(MARGIN_TOP, p_margin_top * EDSCALE);
+ return style;
+}
+
+static Ref<StyleBoxFlat> change_border_color(Ref<StyleBoxFlat> p_style, Color p_color) {
+ Ref<StyleBoxFlat> style = p_style->duplicate();
+ style->set_light_color(p_color);
+ style->set_dark_color(p_color);
+ return style;
+}
+
+static Ref<StyleBoxFlat> add_additional_border(Ref<StyleBoxFlat> p_style, int p_left, int p_top, int p_right, int p_bottom) {
+ Ref<StyleBoxFlat> style = p_style->duplicate();
+ style->_set_additional_border_size(MARGIN_LEFT, p_left * EDSCALE);
+ style->_set_additional_border_size(MARGIN_RIGHT, p_right * EDSCALE);
+ style->_set_additional_border_size(MARGIN_TOP, p_top * EDSCALE);
+ style->_set_additional_border_size(MARGIN_BOTTOM, p_bottom * EDSCALE);
+ return style;
+}
+
+#define HIGHLIGHT_COLOR_LIGHT highlight_color.linear_interpolate(Color(1, 1, 1, 1), 0.3)
+#define HIGHLIGHT_COLOR_DARK highlight_color.linear_interpolate(Color(0, 0, 0, 1), 0.5)
+
Ref<Theme> create_editor_theme() {
Ref<Theme> theme = Ref<Theme>(memnew(Theme));
editor_register_fonts(theme);
editor_register_icons(theme);
- Ref<StyleBoxTexture> focus_sbt = memnew(StyleBoxTexture);
- focus_sbt->set_texture(theme->get_icon("EditorFocus", "EditorIcons"));
- for (int i = 0; i < 4; i++) {
- focus_sbt->set_margin_size(Margin(i), 16 * EDSCALE);
- focus_sbt->set_default_margin(Margin(i), 16 * EDSCALE);
+ // Define colors
+ Color highlight_color = EDITOR_DEF("interface/theme/highlight_color", Color::html("#b79047"));
+ Color base_color = EDITOR_DEF("interface/theme/base_color", Color::html("#273241"));
+ float contrast = EDITOR_DEF("interface/theme/contrast", 0.25);
+ int preset = EDITOR_DEF("interface/theme/preset", 0);
+
+ switch (preset) {
+ case 0: { // Default
+ highlight_color = Color::html("#b79047");
+ base_color = Color::html("#273241");
+ contrast = 0.25;
+ } break;
+ case 1: { // Grey
+ highlight_color = Color::html("#3e3e3e");
+ base_color = Color::html("#3d3d3d");
+ contrast = 0.2;
+ } break;
+ case 2: { // Godot 2
+ highlight_color = Color::html("#86ace2");
+ base_color = Color::html("#3C3A44");
+ contrast = 0.25;
+ } break;
+ case 3: { // Arc
+ highlight_color = Color::html("#68a7f2");
+ base_color = Color::html("#434a59");
+ contrast = 0.2;
+ } break;
}
+
+ Color dark_color_1 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast);
+ Color dark_color_2 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 1.5);
+ Color dark_color_3 = base_color.linear_interpolate(Color(0, 0, 0, 1), contrast * 2);
+
+ Color light_color_1 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast);
+ Color light_color_2 = base_color.linear_interpolate(Color(1, 1, 1, 1), contrast * 1.5);
+
+ theme->set_color("highlight_color", "Editor", highlight_color);
+ theme->set_color("base_color", "Editor", base_color);
+ theme->set_color("dark_color_1", "Editor", dark_color_1);
+ theme->set_color("dark_color_2", "Editor", dark_color_2);
+ theme->set_color("dark_color_3", "Editor", dark_color_3);
+ theme->set_color("light_color_1", "Editor", light_color_1);
+ theme->set_color("light_color_2", "Editor", light_color_2);
+
+ // Checkbox icon
+ theme->set_icon("checked", "CheckBox", theme->get_icon("Checked", "EditorIcons"));
+ theme->set_icon("unchecked", "CheckBox", theme->get_icon("Unchecked", "EditorIcons"));
+ theme->set_icon("checked", "PopupMenu", theme->get_icon("Checked", "EditorIcons"));
+ theme->set_icon("unchecked", "PopupMenu", theme->get_icon("Unchecked", "EditorIcons"));
+
+ // Editor background
+ Ref<StyleBoxFlat> style_panel = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
+ theme->set_stylebox("Background", "EditorStyles", style_panel);
+
+ // Focus
+ Ref<StyleBoxFlat> focus_sbt = make_flat_stylebox(light_color_1, 4, 4, 4, 4);
focus_sbt->set_draw_center(false);
- theme->set_stylebox("EditorFocus", "EditorStyles", focus_sbt);
-
- Ref<StyleBoxFlat> style_panel(memnew(StyleBoxFlat));
- style_panel->set_bg_color(Color::html("#36424e"));
- style_panel->set_default_margin(MARGIN_LEFT, 1);
- style_panel->set_default_margin(MARGIN_RIGHT, 1);
- style_panel->set_default_margin(MARGIN_BOTTOM, 1);
- style_panel->set_default_margin(MARGIN_TOP, 4 * EDSCALE);
- theme->set_stylebox("panel", "TabContainer", style_panel);
- theme->set_stylebox("EditorPanel", "EditorStyles", style_panel);
-
- Ref<StyleBoxFlat> style_bg(memnew(StyleBoxFlat));
- style_bg->set_bg_color(Color::html("#2b353f"));
- style_bg->set_default_margin(MARGIN_LEFT, 0);
- style_bg->set_default_margin(MARGIN_RIGHT, 0);
- style_bg->set_default_margin(MARGIN_BOTTOM, 0);
- style_bg->set_default_margin(MARGIN_TOP, 0);
+ focus_sbt->set_border_size(1 * EDSCALE);
+ focus_sbt = change_border_color(focus_sbt, light_color_2);
+ theme->set_stylebox("Focus", "EditorStyles", focus_sbt);
+
+ // Menu
+ Ref<StyleBoxEmpty> style_menu = make_empty_stylebox(4, 4, 4, 4);
+ theme->set_stylebox("panel", "PanelContainer", style_menu);
+ theme->set_stylebox("MenuPanel", "EditorStyles", style_menu);
+
+ // Play button group
+ theme->set_stylebox("PlayButtonPanel", "EditorStyles", make_stylebox(theme->get_icon("PlayButtonGroup", "EditorIcons"), 16, 16, 16, 16, 8, 4, 8, 4));
+
+ Ref<StyleBoxFlat> style_menu_hover_border = make_flat_stylebox(highlight_color, 4, 4, 4, 4);
+ Ref<StyleBoxFlat> style_menu_hover_bg = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
+
+ style_menu_hover_border->set_draw_center(false);
+ style_menu_hover_border->_set_additional_border_size(MARGIN_BOTTOM, 1 * EDSCALE);
+ theme->set_stylebox("normal", "MenuButton", style_menu);
+ theme->set_stylebox("hover", "MenuButton", style_menu);
+ theme->set_stylebox("pressed", "MenuButton", style_menu);
+ theme->set_stylebox("focus", "MenuButton", style_menu);
+ theme->set_stylebox("disabled", "MenuButton", style_menu);
+
+ theme->set_stylebox("normal", "PopupMenu", style_menu);
+ theme->set_stylebox("hover", "PopupMenu", style_menu_hover_bg);
+ theme->set_stylebox("pressed", "PopupMenu", style_menu);
+ theme->set_stylebox("focus", "PopupMenu", style_menu);
+ theme->set_stylebox("disabled", "PopupMenu", style_menu);
+
+ theme->set_stylebox("normal", "ToolButton", style_menu);
+ theme->set_stylebox("hover", "ToolButton", style_menu);
+ theme->set_stylebox("pressed", "ToolButton", style_menu);
+ theme->set_stylebox("focus", "ToolButton", style_menu);
+ theme->set_stylebox("disabled", "ToolButton", style_menu);
+
+ theme->set_color("font_color_hover", "MenuButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_hover", "ToolButton", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_pressed", "ToolButton", highlight_color);
+
+ theme->set_stylebox("MenuHover", "EditorStyles", style_menu_hover_border);
+
+ // Content of each tab
+ Ref<StyleBoxFlat> style_content_panel = make_flat_stylebox(base_color, 1, 4, 1, 1);
+ theme->set_stylebox("panel", "TabContainer", style_content_panel);
+ theme->set_stylebox("Content", "EditorStyles", style_content_panel);
+
+ // Button
+ Ref<StyleBoxFlat> style_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
+ style_button->set_draw_center(true);
+ style_button->set_border_size(2 * EDSCALE);
+ style_button->set_light_color(light_color_1);
+ style_button->set_dark_color(light_color_1);
+ style_button->set_border_blend(false);
+ theme->set_stylebox("normal", "Button", style_button);
+ theme->set_stylebox("hover", "Button", style_button);
+ theme->set_stylebox("pressed", "Button", style_button);
+ theme->set_stylebox("focus", "Button", style_button);
+ theme->set_stylebox("disabled", "Button", style_button);
+ theme->set_color("font_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
+ theme->set_color("font_color_pressed", "Button", highlight_color);
+ theme->set_color("icon_color_hover", "Button", HIGHLIGHT_COLOR_LIGHT);
+ // make icon color value bigger because icon image is not complete white
+ theme->set_color("icon_color_pressed", "Button", Color(highlight_color.r * 1.15, highlight_color.g * 1.15, highlight_color.b * 1.15, highlight_color.a));
+
+ // OptionButton
+ Ref<StyleBoxFlat> style_option_button = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
+ style_option_button->set_border_size(1 * EDSCALE);
+ style_option_button->set_light_color(light_color_1);
+ style_option_button->set_dark_color(light_color_1);
+ style_option_button->_set_additional_border_size(MARGIN_RIGHT, -16 * EDSCALE);
+ theme->set_stylebox("hover", "OptionButton", change_border_color(style_option_button, HIGHLIGHT_COLOR_LIGHT));
+ theme->set_stylebox("pressed", "OptionButton", change_border_color(style_option_button, highlight_color));
+ theme->set_stylebox("focus", "OptionButton", change_border_color(style_option_button, highlight_color));
+ theme->set_stylebox("disabled", "OptionButton", style_option_button);
+ theme->set_stylebox("normal", "OptionButton", style_option_button);
+ theme->set_icon("arrow", "OptionButton", theme->get_icon("OptionArrow", "EditorIcons"));
+
+ // PopupMenu
+ Ref<StyleBoxFlat> style_popup_menu = make_flat_stylebox(dark_color_1, 8, 8, 8, 8);
+ style_popup_menu->set_border_size(2 * EDSCALE);
+ style_popup_menu->set_light_color(light_color_1);
+ style_popup_menu->set_dark_color(light_color_1);
+ theme->set_stylebox("panel", "PopupMenu", style_popup_menu);
+
+ // Tree & script background
+ Ref<StyleBoxFlat> style_bg = make_flat_stylebox(dark_color_1, 0, 0, 0, 0);
theme->set_stylebox("bg", "Tree", style_bg);
- theme->set_stylebox("bg", "ItemList", style_bg);
- theme->set_stylebox("EditorBG", "EditorStyles", style_bg);
+ theme->set_stylebox("ScriptPanel", "EditorStyles", style_bg);
- Ref<StyleBox> style_tree_btn = theme->get_stylebox("button_pressed", "Tree");
- style_tree_btn->set_default_margin(MARGIN_LEFT, 3 * EDSCALE);
- style_tree_btn->set_default_margin(MARGIN_RIGHT, 3 * EDSCALE);
+ // Tree
+ theme->set_icon("checked", "Tree", theme->get_icon("Checked", "EditorIcons"));
+ theme->set_icon("unchecked", "Tree", theme->get_icon("Unchecked", "EditorIcons"));
+ theme->set_icon("arrow", "Tree", theme->get_icon("TreeArrowDown", "EditorIcons"));
+ theme->set_icon("arrow_collapsed", "Tree", theme->get_icon("TreeArrowRight", "EditorIcons"));
+ theme->set_icon("select_arrow", "Tree", theme->get_icon("Dropdown", "EditorIcons"));
+ theme->set_stylebox("bg_focus", "Tree", focus_sbt);
+ theme->set_stylebox("custom_button", "Tree", style_button);
+ theme->set_stylebox("custom_button_pressed", "Tree", style_button);
+ theme->set_stylebox("custom_button_hover", "Tree", style_button);
+ theme->set_color("custom_button_font_highlight", "Tree", HIGHLIGHT_COLOR_LIGHT);
+
+ Ref<StyleBox> style_tree_btn = make_flat_stylebox(light_color_1, 2, 4, 2, 4);
theme->set_stylebox("button_pressed", "Tree", style_tree_btn);
- Ref<StyleBoxFlat> style_tab(memnew(StyleBoxFlat));
- style_tab->set_default_margin(MARGIN_LEFT, 15 * EDSCALE);
- style_tab->set_default_margin(MARGIN_RIGHT, 15 * EDSCALE);
- style_tab->set_default_margin(MARGIN_BOTTOM, 5 * EDSCALE);
- style_tab->set_default_margin(MARGIN_TOP, 5 * EDSCALE);
+ Ref<StyleBoxFlat> style_tree_focus = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 4, 4, 4, 4);
+ theme->set_stylebox("selected_focus", "Tree", style_tree_focus);
+
+ Ref<StyleBoxFlat> style_tree_selected = make_flat_stylebox(light_color_1, 4, 4, 4, 4);
+ theme->set_stylebox("selected", "Tree", style_tree_selected);
+
+ Ref<StyleBoxFlat> style_tree_cursor = make_flat_stylebox(HIGHLIGHT_COLOR_DARK, 4, 4, 4, 4);
+ style_tree_cursor->set_draw_center(false);
+ style_tree_cursor->set_border_size(1 * EDSCALE);
+ style_tree_cursor->set_light_color(light_color_1);
+ style_tree_cursor->set_dark_color(light_color_1);
+ Ref<StyleBoxFlat> style_tree_title = make_flat_stylebox(dark_color_3, 4, 4, 4, 4);
+ theme->set_stylebox("cursor", "Tree", style_tree_cursor);
+ theme->set_stylebox("cursor_unfocused", "Tree", style_tree_cursor);
+ theme->set_stylebox("title_button_normal", "Tree", style_tree_title);
+ theme->set_stylebox("title_button_hover", "Tree", style_tree_title);
+ theme->set_stylebox("title_button_pressed", "Tree", style_tree_title);
- Ref<StyleBoxFlat> style_tab_fg = style_tab->duplicate();
- style_tab_fg->set_bg_color(Color::html("#36424e"));
+ theme->set_color("prop_category", "Editor", dark_color_3);
+ theme->set_color("prop_section", "Editor", dark_color_1);
+ theme->set_color("prop_subsection", "Editor", dark_color_2);
+ theme->set_color("fg_selected", "Editor", Color::html("ffbd8e8e"));
+ theme->set_color("fg_error", "Editor", Color::html("ffbd8e8e"));
+ theme->set_color("drop_position_color", "Tree", highlight_color);
- Ref<StyleBoxFlat> style_tab_bg = style_tab->duplicate();
+ // ItemList
+ Ref<StyleBoxFlat> style_itemlist_cursor = make_flat_stylebox(highlight_color, 4, 4, 4, 4);
+ style_itemlist_cursor->set_draw_center(false);
+ style_itemlist_cursor->set_border_size(1 * EDSCALE);
+ style_itemlist_cursor->set_light_color(light_color_1);
+ style_itemlist_cursor->set_dark_color(light_color_1);
+ theme->set_stylebox("cursor", "ItemList", style_itemlist_cursor);
+ theme->set_stylebox("cursor_unfocused", "ItemList", style_itemlist_cursor);
+ theme->set_stylebox("selected_focus", "ItemList", style_tree_focus);
+ theme->set_stylebox("selected", "ItemList", style_tree_selected);
+ theme->set_stylebox("bg_focus", "ItemList", focus_sbt);
+ theme->set_stylebox("bg", "ItemList", style_bg);
+ theme->set_constant("vseparation", "ItemList", 5 * EDSCALE);
+
+ Ref<StyleBoxFlat> style_tab_fg = make_flat_stylebox(base_color, 15, 5, 15, 5);
+ Ref<StyleBoxFlat> style_tab_bg = make_flat_stylebox(base_color, 15, 5, 15, 5);
style_tab_bg->set_draw_center(false);
+ // Tabs & TabContainer
theme->set_stylebox("tab_fg", "TabContainer", style_tab_fg);
theme->set_stylebox("tab_bg", "TabContainer", style_tab_bg);
theme->set_stylebox("tab_fg", "Tabs", style_tab_fg);
theme->set_stylebox("tab_bg", "Tabs", style_tab_bg);
+ theme->set_color("font_color_fg", "TabContainer", Color(1, 1, 1, 1));
+ theme->set_color("font_color_bg", "TabContainer", light_color_2);
+ theme->set_icon("menu", "TabContainer", theme->get_icon("TabMenu", "EditorIcons"));
+ theme->set_icon("menu_hl", "TabContainer", theme->get_icon("TabMenu", "EditorIcons"));
+ theme->set_stylebox("SceneTabFG", "EditorStyles", make_flat_stylebox(base_color, 10, 5, 10, 5));
+ theme->set_stylebox("SceneTabBG", "EditorStyles", make_empty_stylebox(6, 5, 6, 5));
- Ref<StyleBoxFlat> style_panel_debugger(memnew(StyleBoxFlat));
- style_panel_debugger->set_bg_color(Color::html("#3e4c5a"));
- style_panel_debugger->set_default_margin(MARGIN_LEFT, 0);
- style_panel_debugger->set_default_margin(MARGIN_RIGHT, 0);
- style_panel_debugger->set_default_margin(MARGIN_BOTTOM, 0);
- style_panel_debugger->set_default_margin(MARGIN_TOP, 4 * EDSCALE);
- theme->set_stylebox("EditorPanelDebugger", "EditorStyles", style_panel_debugger);
-
- Ref<StyleBoxFlat> style_tab_fg_debugger = style_tab->duplicate();
- style_tab_fg_debugger->set_bg_color(Color::html("#3e4c5a"));
- style_tab_fg_debugger->set_default_margin(MARGIN_LEFT, 10 * EDSCALE);
- style_tab_fg_debugger->set_default_margin(MARGIN_RIGHT, 10 * EDSCALE);
- Ref<StyleBoxFlat> style_tab_bg_debugger = style_tab->duplicate();
+ // Debugger
+ Ref<StyleBoxFlat> style_panel_debugger = make_flat_stylebox(dark_color_2, 0, 4, 0, 0);
+ theme->set_stylebox("DebuggerPanel", "EditorStyles", style_panel_debugger);
+
+ Ref<StyleBoxFlat> style_tab_fg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
+ Ref<StyleBoxFlat> style_tab_bg_debugger = make_flat_stylebox(dark_color_2, 10, 5, 10, 5);
style_tab_bg_debugger->set_draw_center(false);
- style_tab_bg_debugger->set_default_margin(MARGIN_LEFT, 10 * EDSCALE);
- style_tab_bg_debugger->set_default_margin(MARGIN_RIGHT, 10 * EDSCALE);
- theme->set_stylebox("EditorTabFGDebugger", "EditorStyles", style_tab_fg_debugger);
- theme->set_stylebox("EditorTabBGDebugger", "EditorStyles", style_tab_bg_debugger);
+ theme->set_stylebox("DebuggerTabFG", "EditorStyles", style_tab_fg_debugger);
+ theme->set_stylebox("DebuggerTabBG", "EditorStyles", style_tab_bg_debugger);
+
+ // LineEdit
+ Ref<StyleBoxFlat> style_lineedit = make_flat_stylebox(dark_color_1, 4, 4, 4, 4);
+ style_lineedit->set_border_size(1 * EDSCALE);
+ style_lineedit = change_border_color(style_lineedit, light_color_1);
+ Ref<StyleBoxFlat> style_lineedit_disabled = style_lineedit->duplicate();
+ style_lineedit_disabled->set_bg_color(light_color_1);
+ Ref<StyleBoxFlat> style_lineedit_focus = change_border_color(style_lineedit, highlight_color);
+ style_lineedit_focus->set_draw_center(false);
+ theme->set_stylebox("normal", "LineEdit", style_lineedit);
+ theme->set_stylebox("focus", "LineEdit", style_lineedit_focus);
+ theme->set_stylebox("read_only", "LineEdit", style_lineedit_disabled);
+ // TextEdit
Ref<StyleBoxFlat> style_textedit_normal(memnew(StyleBoxFlat));
- style_textedit_normal->set_bg_color(Color::html("#29343d"));
+ style_textedit_normal->set_bg_color(dark_color_2);
style_textedit_normal->set_default_margin(MARGIN_LEFT, 0);
style_textedit_normal->set_default_margin(MARGIN_RIGHT, 0);
style_textedit_normal->set_default_margin(MARGIN_BOTTOM, 0);
style_textedit_normal->set_default_margin(MARGIN_TOP, 0);
theme->set_stylebox("normal", "TextEdit", style_textedit_normal);
+ theme->set_stylebox("focus", "TextEdit", focus_sbt);
+ theme->set_constant("side_margin", "TabContainer", 0);
+
+ // H/VSplitContainer
+ theme->set_stylebox("bg", "VSplitContainer", make_stylebox(theme->get_icon("VsplitBg", "EditorIcons"), 1, 1, 1, 1));
+ theme->set_stylebox("bg", "HSplitContainer", make_stylebox(theme->get_icon("HsplitBg", "EditorIcons"), 1, 1, 1, 1));
+
+ theme->set_icon("grabber", "VSplitContainer", theme->get_icon("Vsplitter", "EditorIcons"));
+ theme->set_icon("grabber", "HSplitContainer", theme->get_icon("Hsplitter", "EditorIcons"));
theme->set_constant("separation", "HSplitContainer", 8 * EDSCALE);
theme->set_constant("separation", "VSplitContainer", 8 * EDSCALE);
- theme->set_constant("side_margin", "TabContainer", 0);
- // theme->set_color("prop_category","Editor",Color::hex(0x3f3a44ff));
- // theme->set_color("prop_section","Editor",Color::hex(0x35313aff));
- // theme->set_color("prop_subsection","Editor",Color::hex(0x312e37ff));
- // theme->set_color("fg_selected","Editor",Color::html("ffbd8e8e"));
- // theme->set_color("fg_error","Editor",Color::html("ffbd8e8e"));
+ // WindowDialog
+ Ref<StyleBoxFlat> style_window = make_flat_stylebox(dark_color_2, 4, 4, 4, 4);
+ style_window->set_border_size(2 * EDSCALE);
+ style_window->set_border_blend(false);
+ style_window->set_light_color(light_color_2);
+ style_window->set_dark_color(light_color_2);
+ style_window->_set_additional_border_size(MARGIN_TOP, 24 * EDSCALE);
+ theme->set_stylebox("panel", "WindowDialog", style_window);
+
+ // HScrollBar
+ Ref<Texture> empty_icon = memnew(ImageTexture);
+
+ theme->set_stylebox("scroll", "HScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("grabber", "HScrollBar", make_stylebox(theme->get_icon("ScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
+ theme->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(theme->get_icon("ScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
+
+ theme->set_icon("increment", "HScrollBar", empty_icon);
+ theme->set_icon("increment_highlight", "HScrollBar", empty_icon);
+ theme->set_icon("decrement", "HScrollBar", empty_icon);
+ theme->set_icon("decrement_highlight", "HScrollBar", empty_icon);
+
+ // VScrollBar
+ theme->set_stylebox("scroll", "VScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(theme->get_icon("ScrollBg", "EditorIcons"), 5, 5, 5, 5, 0, 0, 0, 0));
+ theme->set_stylebox("grabber", "VScrollBar", make_stylebox(theme->get_icon("ScrollGrabber", "EditorIcons"), 6, 6, 6, 6, 2, 2, 2, 2));
+ theme->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(theme->get_icon("ScrollGrabberHl", "EditorIcons"), 5, 5, 5, 5, 2, 2, 2, 2));
+
+ theme->set_icon("increment", "VScrollBar", empty_icon);
+ theme->set_icon("increment_highlight", "VScrollBar", empty_icon);
+ theme->set_icon("decrement", "VScrollBar", empty_icon);
+ theme->set_icon("decrement_highlight", "VScrollBar", empty_icon);
+
+ // HSlider
+ theme->set_stylebox("slider", "HSlider", make_stylebox(theme->get_icon("HsliderBg", "EditorIcons"), 4, 4, 4, 4));
+ theme->set_icon("grabber", "HSlider", theme->get_icon("SliderGrabber", "EditorIcons"));
+ theme->set_icon("grabber_highlight", "HSlider", theme->get_icon("SliderGrabberHl", "EditorIcons"));
+
+ // VSlider
+ theme->set_stylebox("slider", "VSlider", make_stylebox(theme->get_icon("VsliderBg", "EditorIcons"), 4, 4, 4, 4));
+ theme->set_icon("grabber", "VSlider", theme->get_icon("SliderGrabber", "EditorIcons"));
+ theme->set_icon("grabber_highlight", "VSlider", theme->get_icon("SliderGrabberHl", "EditorIcons"));
+
+ // Panel
+ theme->set_stylebox("panel", "Panel", style_panel);
+
+ // TooltipPanel
+ Ref<StyleBoxFlat> style_tooltip = make_flat_stylebox(Color(1, 1, 1, 0.8), 8, 8, 8, 8);
+ style_tooltip->set_border_size(2 * EDSCALE);
+ style_tooltip->set_border_blend(false);
+ style_tooltip->set_light_color(Color(1, 1, 1, 0.9));
+ style_tooltip->set_dark_color(Color(1, 1, 1, 0.9));
+ theme->set_stylebox("panel", "TooltipPanel", style_tooltip);
+
+ // PopupPanel
+ Ref<StyleBoxFlat> style_dock_select = make_flat_stylebox(base_color);
+ style_dock_select->set_light_color(light_color_1);
+ style_dock_select->set_dark_color(light_color_1);
+ style_dock_select = add_additional_border(style_dock_select, 2, 2, 2, 2);
+ theme->set_stylebox("panel", "PopupPanel", style_dock_select);
+
+ // SpinBox
+ theme->set_icon("updown", "SpinBox", theme->get_icon("SpinboxUpdown", "EditorIcons"));
+
+ // GraphNode
+ Ref<StyleBoxFlat> graphsb = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
+ graphsb->set_border_blend(false);
+ graphsb->set_border_size(2);
+ graphsb->set_light_color(Color(1, 1, 1, 0.6));
+ graphsb->set_dark_color(Color(1, 1, 1, 0.6));
+ graphsb = add_additional_border(graphsb, 0, -22, 0, 0);
+ Ref<StyleBoxFlat> graphsbselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
+ graphsbselected->set_border_blend(false);
+ graphsbselected->set_border_size(2);
+ graphsbselected->set_light_color(Color(1, 1, 1, 0.9));
+ graphsbselected->set_dark_color(Color(1, 1, 1, 0.9));
+ graphsbselected = add_additional_border(graphsbselected, 0, -22, 0, 0);
+ Ref<StyleBoxFlat> graphsbcomment = make_flat_stylebox(Color(0, 0, 0, 0.3), 16, 24, 16, 5);
+ graphsbcomment->set_border_blend(false);
+ graphsbcomment->set_border_size(1);
+ graphsbcomment->set_light_color(Color(1, 1, 1, 0.6));
+ graphsbcomment->set_dark_color(Color(1, 1, 1, 0.6));
+ graphsbcomment = add_additional_border(graphsbcomment, 0, -22, 0, 0);
+ Ref<StyleBoxFlat> graphsbcommentselected = make_flat_stylebox(Color(0, 0, 0, 0.4), 16, 24, 16, 5);
+ graphsbcommentselected->set_border_blend(false);
+ graphsbcommentselected->set_border_size(1);
+ graphsbcommentselected->set_light_color(Color(1, 1, 1, 0.9));
+ graphsbcommentselected->set_dark_color(Color(1, 1, 1, 0.9));
+ graphsbcommentselected = add_additional_border(graphsbcommentselected, 0, -22, 0, 0);
+ theme->set_stylebox("frame", "GraphNode", graphsb);
+ theme->set_stylebox("selectedframe", "GraphNode", graphsbselected);
+ theme->set_stylebox("comment", "GraphNode", graphsbcomment);
+ theme->set_stylebox("commentfocus", "GraphNode", graphsbcommentselected);
+
+ // FileDialog
+ Color disable_color = light_color_2;
+ disable_color.a = 0.7;
+ theme->set_color("files_disabled", "FileDialog", disable_color);
return theme;
}
@@ -135,7 +459,7 @@ Ref<Theme> create_editor_theme() {
Ref<Theme> create_custom_theme() {
Ref<Theme> theme;
- String custom_theme = EditorSettings::get_singleton()->get("interface/custom_theme");
+ String custom_theme = EditorSettings::get_singleton()->get("interface/theme/custom_theme");
if (custom_theme != "") {
theme = ResourceLoader::load(custom_theme);
}
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index c324f474bb..62fb241ade 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -150,11 +150,10 @@ void FileSystemDock::_notification(int p_what) {
}
button_display_mode->connect("pressed", this, "_change_file_display");
//file_options->set_icon( get_icon("Tools","EditorIcons"));
-
files->connect("item_activated", this, "_select_file");
button_hist_next->connect("pressed", this, "_fw_history");
button_hist_prev->connect("pressed", this, "_bw_history");
- search_icon->set_texture(get_icon("Search", "EditorIcons"));
+ search_icon->set_texture(get_icon("Zoom", "EditorIcons"));
button_hist_next->set_icon(get_icon("Forward", "EditorIcons"));
button_hist_prev->set_icon(get_icon("Back", "EditorIcons"));
@@ -416,8 +415,9 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
if (!has_icon("ResizedFolder", "EditorIcons")) {
Ref<ImageTexture> folder = get_icon("FolderBig", "EditorIcons");
- Image img = folder->get_data();
- img.resize(thumbnail_size, thumbnail_size);
+ Ref<Image> img = folder->get_data();
+ img = img->duplicate();
+ img->resize(thumbnail_size, thumbnail_size);
Ref<ImageTexture> resized_folder = Ref<ImageTexture>(memnew(ImageTexture));
resized_folder->create_from_image(img, 0);
Theme::get_default()->set_icon("ResizedFolder", "EditorIcons", resized_folder);
@@ -427,8 +427,8 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
if (!has_icon("ResizedFile", "EditorIcons")) {
Ref<ImageTexture> file = get_icon("FileBig", "EditorIcons");
- Image img = file->get_data();
- img.resize(thumbnail_size, thumbnail_size);
+ Ref<Image> img = file->get_data();
+ img->resize(thumbnail_size, thumbnail_size);
Ref<ImageTexture> resized_file = Ref<ImageTexture>(memnew(ImageTexture));
resized_file->create_from_image(img, 0);
Theme::get_default()->set_icon("ResizedFile", "EditorIcons", resized_file);
@@ -1668,6 +1668,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
button_reload->set_tooltip(TTR("Re-Scan Filesystem"));
button_reload->hide();
+ //toolbar_hbc->add_spacer();
+
button_favorite = memnew(Button);
button_favorite->set_flat(true);
button_favorite->set_toggle_mode(true);
@@ -1722,7 +1724,6 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
tree->connect("item_rmb_selected", this, "_dir_rmb_pressed");
files = memnew(ItemList);
- files->add_style_override("bg", editor->get_gui_base()->get_stylebox("EditorBG", "EditorStyles"));
files->set_v_size_flags(SIZE_EXPAND_FILL);
files->set_select_mode(ItemList::SELECT_MULTI);
files->set_drag_forwarding(this);
diff --git a/editor/icons/2x/icon_checked.png b/editor/icons/2x/icon_checked.png
new file mode 100644
index 0000000000..6083540ffe
--- /dev/null
+++ b/editor/icons/2x/icon_checked.png
Binary files differ
diff --git a/editor/icons/2x/icon_dropdown.png b/editor/icons/2x/icon_dropdown.png
new file mode 100644
index 0000000000..626dba79ec
--- /dev/null
+++ b/editor/icons/2x/icon_dropdown.png
Binary files differ
diff --git a/editor/icons/2x/icon_godot.png b/editor/icons/2x/icon_godot.png
deleted file mode 100644
index 94d87e23cc..0000000000
--- a/editor/icons/2x/icon_godot.png
+++ /dev/null
Binary files differ
diff --git a/editor/icons/2x/icon_godot_docs.png b/editor/icons/2x/icon_godot_docs.png
new file mode 100644
index 0000000000..be30f092ef
--- /dev/null
+++ b/editor/icons/2x/icon_godot_docs.png
Binary files differ
diff --git a/editor/icons/2x/icon_hslider_bg.png b/editor/icons/2x/icon_hslider_bg.png
new file mode 100644
index 0000000000..e3c61f25e0
--- /dev/null
+++ b/editor/icons/2x/icon_hslider_bg.png
Binary files differ
diff --git a/editor/icons/2x/icon_option_arrow.png b/editor/icons/2x/icon_option_arrow.png
new file mode 100644
index 0000000000..ed177a4451
--- /dev/null
+++ b/editor/icons/2x/icon_option_arrow.png
Binary files differ
diff --git a/editor/icons/2x/icon_play_button_group.png b/editor/icons/2x/icon_play_button_group.png
new file mode 100644
index 0000000000..e28cb52e64
--- /dev/null
+++ b/editor/icons/2x/icon_play_button_group.png
Binary files differ
diff --git a/editor/icons/2x/icon_slider_grabber.png b/editor/icons/2x/icon_slider_grabber.png
new file mode 100644
index 0000000000..64cf83270a
--- /dev/null
+++ b/editor/icons/2x/icon_slider_grabber.png
Binary files differ
diff --git a/editor/icons/2x/icon_slider_grabber_hl.png b/editor/icons/2x/icon_slider_grabber_hl.png
new file mode 100644
index 0000000000..d68da0d12a
--- /dev/null
+++ b/editor/icons/2x/icon_slider_grabber_hl.png
Binary files differ
diff --git a/editor/icons/2x/icon_spinbox_updown.png b/editor/icons/2x/icon_spinbox_updown.png
new file mode 100644
index 0000000000..e711fbf08b
--- /dev/null
+++ b/editor/icons/2x/icon_spinbox_updown.png
Binary files differ
diff --git a/editor/icons/2x/icon_tab_menu.png b/editor/icons/2x/icon_tab_menu.png
new file mode 100644
index 0000000000..becad9db76
--- /dev/null
+++ b/editor/icons/2x/icon_tab_menu.png
Binary files differ
diff --git a/editor/icons/2x/icon_texture.png b/editor/icons/2x/icon_texture.png
new file mode 100644
index 0000000000..ad5d04dfee
--- /dev/null
+++ b/editor/icons/2x/icon_texture.png
Binary files differ
diff --git a/editor/icons/2x/icon_tree_arrow_down.png b/editor/icons/2x/icon_tree_arrow_down.png
new file mode 100644
index 0000000000..00012dea39
--- /dev/null
+++ b/editor/icons/2x/icon_tree_arrow_down.png
Binary files differ
diff --git a/editor/icons/2x/icon_tree_arrow_right.png b/editor/icons/2x/icon_tree_arrow_right.png
new file mode 100644
index 0000000000..baaf016784
--- /dev/null
+++ b/editor/icons/2x/icon_tree_arrow_right.png
Binary files differ
diff --git a/editor/icons/2x/icon_unchecked.png b/editor/icons/2x/icon_unchecked.png
new file mode 100644
index 0000000000..cd8b781000
--- /dev/null
+++ b/editor/icons/2x/icon_unchecked.png
Binary files differ
diff --git a/editor/icons/2x/icon_vslider_bg.png b/editor/icons/2x/icon_vslider_bg.png
new file mode 100644
index 0000000000..a7e0e78564
--- /dev/null
+++ b/editor/icons/2x/icon_vslider_bg.png
Binary files differ
diff --git a/editor/icons/SCsub b/editor/icons/SCsub
index 3fc8e5461f..20a381cc78 100644
--- a/editor/icons/SCsub
+++ b/editor/icons/SCsub
@@ -62,9 +62,9 @@ def make_editor_icons_action(target, source, env):
s.write("static Ref<ImageTexture> make_icon(const uint8_t* p_png,const uint8_t* p_hidpi_png) {\n")
s.write("\tRef<ImageTexture> texture( memnew( ImageTexture ) );\n")
s.write("\tbool use_hidpi_image=(editor_get_scale()>1.0&&p_hidpi_png);\n")
- s.write("\tImage img(use_hidpi_image?p_hidpi_png:p_png);\n")
- s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img.convert(Image::FORMAT_RGBA8); img.expand_x2_hq2x(); use_hidpi_image=true;}\n")
- s.write("\timg.resize(img.get_width()*EDSCALE/(use_hidpi_image?2:1),img.get_height()*EDSCALE/(use_hidpi_image?2:1));\n")
+ s.write("\tRef<Image> img = memnew(Image(use_hidpi_image?p_hidpi_png:p_png));\n")
+ s.write("\tif (editor_get_scale()>1.0 && !p_hidpi_png) { img->convert(Image::FORMAT_RGBA8); img->expand_x2_hq2x(); use_hidpi_image=true;}\n")
+ s.write("\timg->resize(img->get_width()*EDSCALE/(use_hidpi_image?2:1),img->get_height()*EDSCALE/(use_hidpi_image?2:1));\n")
s.write("\ttexture->create_from_image( img,ImageTexture::FLAG_FILTER );\n")
s.write("\treturn texture;\n")
s.write("}\n\n")
diff --git a/editor/icons/icon_checked.png b/editor/icons/icon_checked.png
new file mode 100644
index 0000000000..d3442930bb
--- /dev/null
+++ b/editor/icons/icon_checked.png
Binary files differ
diff --git a/editor/icons/icon_default_project_icon.png b/editor/icons/icon_default_project_icon.png
index e87a49bd28..4c31fe5cb2 100644
--- a/editor/icons/icon_default_project_icon.png
+++ b/editor/icons/icon_default_project_icon.png
Binary files differ
diff --git a/editor/icons/icon_dropdown.png b/editor/icons/icon_dropdown.png
new file mode 100644
index 0000000000..b9a324be7c
--- /dev/null
+++ b/editor/icons/icon_dropdown.png
Binary files differ
diff --git a/editor/icons/icon_godot.png b/editor/icons/icon_godot.png
deleted file mode 100644
index 0b72e6ecc7..0000000000
--- a/editor/icons/icon_godot.png
+++ /dev/null
Binary files differ
diff --git a/editor/icons/icon_godot_docs.png b/editor/icons/icon_godot_docs.png
new file mode 100644
index 0000000000..554280c5b4
--- /dev/null
+++ b/editor/icons/icon_godot_docs.png
Binary files differ
diff --git a/editor/icons/icon_h_button_array.png b/editor/icons/icon_h_button_array.png
deleted file mode 100644
index baf3386801..0000000000
--- a/editor/icons/icon_h_button_array.png
+++ /dev/null
Binary files differ
diff --git a/editor/icons/icon_hslider_bg.png b/editor/icons/icon_hslider_bg.png
new file mode 100644
index 0000000000..e3c61f25e0
--- /dev/null
+++ b/editor/icons/icon_hslider_bg.png
Binary files differ
diff --git a/editor/icons/icon_hsplit_bg.png b/editor/icons/icon_hsplit_bg.png
new file mode 100644
index 0000000000..cfb76f7dc7
--- /dev/null
+++ b/editor/icons/icon_hsplit_bg.png
Binary files differ
diff --git a/editor/icons/icon_hsplitter.png b/editor/icons/icon_hsplitter.png
new file mode 100644
index 0000000000..3ac1dddf90
--- /dev/null
+++ b/editor/icons/icon_hsplitter.png
Binary files differ
diff --git a/editor/icons/icon_logo.png b/editor/icons/icon_logo.png
index 9bbd7dc619..aed94cb87a 100644
--- a/editor/icons/icon_logo.png
+++ b/editor/icons/icon_logo.png
Binary files differ
diff --git a/editor/icons/icon_logo_small.png b/editor/icons/icon_logo_small.png
index 9c7c7fe365..809cf18541 100644
--- a/editor/icons/icon_logo_small.png
+++ b/editor/icons/icon_logo_small.png
Binary files differ
diff --git a/editor/icons/icon_option_arrow.png b/editor/icons/icon_option_arrow.png
new file mode 100644
index 0000000000..b7bc38e03f
--- /dev/null
+++ b/editor/icons/icon_option_arrow.png
Binary files differ
diff --git a/scene/resources/default_theme/button_group.png b/editor/icons/icon_play_button_group.png
index 83820c8e0c..83820c8e0c 100644
--- a/scene/resources/default_theme/button_group.png
+++ b/editor/icons/icon_play_button_group.png
Binary files differ
diff --git a/editor/icons/icon_scroll_bg.png b/editor/icons/icon_scroll_bg.png
new file mode 100644
index 0000000000..1908fd8aee
--- /dev/null
+++ b/editor/icons/icon_scroll_bg.png
Binary files differ
diff --git a/editor/icons/icon_scroll_grabber.png b/editor/icons/icon_scroll_grabber.png
new file mode 100644
index 0000000000..4be7f4e6cc
--- /dev/null
+++ b/editor/icons/icon_scroll_grabber.png
Binary files differ
diff --git a/editor/icons/icon_scroll_grabber_hl.png b/editor/icons/icon_scroll_grabber_hl.png
new file mode 100644
index 0000000000..a81239b84b
--- /dev/null
+++ b/editor/icons/icon_scroll_grabber_hl.png
Binary files differ
diff --git a/editor/icons/icon_slider_grabber.png b/editor/icons/icon_slider_grabber.png
new file mode 100644
index 0000000000..6b6982e26c
--- /dev/null
+++ b/editor/icons/icon_slider_grabber.png
Binary files differ
diff --git a/editor/icons/icon_slider_grabber_hl.png b/editor/icons/icon_slider_grabber_hl.png
new file mode 100644
index 0000000000..03d4b2bb99
--- /dev/null
+++ b/editor/icons/icon_slider_grabber_hl.png
Binary files differ
diff --git a/editor/icons/icon_spinbox_updown.png b/editor/icons/icon_spinbox_updown.png
new file mode 100644
index 0000000000..ff65df801b
--- /dev/null
+++ b/editor/icons/icon_spinbox_updown.png
Binary files differ
diff --git a/editor/icons/icon_tab_menu.png b/editor/icons/icon_tab_menu.png
index 29edd02f01..ffc63f2d41 100644
--- a/editor/icons/icon_tab_menu.png
+++ b/editor/icons/icon_tab_menu.png
Binary files differ
diff --git a/editor/icons/icon_texture.png b/editor/icons/icon_texture.png
new file mode 100644
index 0000000000..7c4493395e
--- /dev/null
+++ b/editor/icons/icon_texture.png
Binary files differ
diff --git a/editor/icons/icon_tree_arrow_down.png b/editor/icons/icon_tree_arrow_down.png
new file mode 100644
index 0000000000..4ef7b41de6
--- /dev/null
+++ b/editor/icons/icon_tree_arrow_down.png
Binary files differ
diff --git a/editor/icons/icon_tree_arrow_right.png b/editor/icons/icon_tree_arrow_right.png
new file mode 100644
index 0000000000..13a42f730d
--- /dev/null
+++ b/editor/icons/icon_tree_arrow_right.png
Binary files differ
diff --git a/editor/icons/icon_unchecked.png b/editor/icons/icon_unchecked.png
new file mode 100644
index 0000000000..9d7d55aa46
--- /dev/null
+++ b/editor/icons/icon_unchecked.png
Binary files differ
diff --git a/editor/icons/icon_v_button_array.png b/editor/icons/icon_v_button_array.png
deleted file mode 100644
index d7ea9cc375..0000000000
--- a/editor/icons/icon_v_button_array.png
+++ /dev/null
Binary files differ
diff --git a/editor/icons/icon_vslider_bg.png b/editor/icons/icon_vslider_bg.png
new file mode 100644
index 0000000000..a7e0e78564
--- /dev/null
+++ b/editor/icons/icon_vslider_bg.png
Binary files differ
diff --git a/editor/icons/icon_vsplit_bg.png b/editor/icons/icon_vsplit_bg.png
new file mode 100644
index 0000000000..0c29b1e35c
--- /dev/null
+++ b/editor/icons/icon_vsplit_bg.png
Binary files differ
diff --git a/editor/icons/icon_vsplitter.png b/editor/icons/icon_vsplitter.png
new file mode 100644
index 0000000000..56fb20bc3f
--- /dev/null
+++ b/editor/icons/icon_vsplitter.png
Binary files differ
diff --git a/editor/icons/source/icon_3_d.svg b/editor/icons/source/icon_3_d.svg
deleted file mode 100644
index 3147d14dc1..0000000000
--- a/editor/icons/source/icon_3_d.svg
+++ /dev/null
@@ -1,105 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 16"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
- inkscape:export-xdpi="45"
- inkscape:export-ydpi="45"
- sodipodi:docname="icon_3_d.svg">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32.000001"
- inkscape:cx="7.1007207"
- inkscape:cy="6.155123"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:snap-bbox-midpoints="false"
- inkscape:snap-object-midpoints="true"
- inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-midpoints="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid3336" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3622)">
- <path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2.0050708,1040.3622 2,-2 2,2"
- id="path4485"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 4.0050708,1039.3622 v 9 h 9.0000002"
- id="path4487"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0"
- id="path4489"
- d="m 12.005071,1046.3622 2,2 -2,2"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 4.0050708,1048.3622 8.0000002,-8"
- id="path4496"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cc" />
- <path
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0"
- id="path4498"
- d="m 10.176644,1039.3622 h 2.828427 v 2.8284"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/checked.svg b/editor/icons/source/icon_checked.svg
index 6d2c03f4c5..6d2c03f4c5 100644
--- a/scene/resources/default_theme/source/checked.svg
+++ b/editor/icons/source/icon_checked.svg
diff --git a/scene/resources/default_theme/source/dropdown.svg b/editor/icons/source/icon_dropdown.svg
index 5963e74007..5963e74007 100644
--- a/scene/resources/default_theme/source/dropdown.svg
+++ b/editor/icons/source/icon_dropdown.svg
diff --git a/editor/icons/source/icon_godot.svg b/editor/icons/source/icon_godot.svg
deleted file mode 100644
index 419f23125b..0000000000
--- a/editor/icons/source/icon_godot.svg
+++ /dev/null
@@ -1,168 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 16"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collision_shape_2d.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90"
- sodipodi:docname="icon_godot.svg">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="9.8470361"
- inkscape:cy="9.8599985"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="false"
- units="px"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:snap-bbox-midpoints="true"
- inkscape:snap-object-midpoints="true"
- inkscape:snap-center="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid3336" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3622)">
- <g
- transform="matrix(0.01724138,0,0,0.01724138,-0.82758647,1035.0456)"
- id="layer1-5"
- inkscape:label="Layer 1">
- <g
- transform="matrix(1.0688992,0,0,1.1334985,-45.061194,-81.689066)"
- id="g4149">
- <path
- style="fill:#ffffff;fill-opacity:1;stroke:none"
- d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
- id="path3239"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccccccccc" />
- <g
- id="g3412"
- transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 Z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3414" />
- </g>
- <g
- id="g3416"
- transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 Z"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3418" />
- </g>
- <g
- id="g3420"
- transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3422" />
- </g>
- <g
- id="g3424"
- transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3426" />
- </g>
- <g
- id="g3428"
- transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3430" />
- </g>
- <g
- id="g3432"
- transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3434" />
- </g>
- <g
- id="g3436"
- transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)">
- <path
- inkscape:connector-curvature="0"
- d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- id="path3438" />
- </g>
- </g>
- </g>
- <path
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.44162436"
- d="m 4,1041.3622 a 3,3 0 0 0 -3,3 3,3 0 0 0 3,3 3,3 0 0 0 3,-3 3,3 0 0 0 -3,-3 z m 0,1 a 2.0000174,2.0000174 0 0 1 2,2 2.0000174,2.0000174 0 0 1 -2,2 2.0000174,2.0000174 0 0 1 -2,-2 2.0000174,2.0000174 0 0 1 2,-2 z"
- id="path4151"
- inkscape:connector-curvature="0" />
- <path
- inkscape:connector-curvature="0"
- id="path4156"
- d="m 12,1041.3622 a 3,3 0 0 0 -3,3 3,3 0 0 0 3,3 3,3 0 0 0 3,-3 3,3 0 0 0 -3,-3 z m 0,1 a 2.0000174,2.0000174 0 0 1 2,2 2.0000174,2.0000174 0 0 1 -2,2 2.0000174,2.0000174 0 0 1 -2,-2 2.0000174,2.0000174 0 0 1 2,-2 z"
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.44162436" />
- <rect
- style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.44162436"
- id="rect4160"
- width="4"
- height="1"
- x="6"
- y="1043.3622"
- ry="0" />
- </g>
-</svg>
diff --git a/editor/icons/source/icon_godot_docs.svg b/editor/icons/source/icon_godot_docs.svg
new file mode 100644
index 0000000000..77aa92b31f
--- /dev/null
+++ b/editor/icons/source/icon_godot_docs.svg
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 15 15"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collision_shape_2d.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:docname="icon_godot_docs.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627417"
+ inkscape:cx="-14.305844"
+ inkscape:cy="5.1981046"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1011"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ originx="0"
+ originy="0"
+ spacingx="1"
+ spacingy="1" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1037.3622)">
+ <g
+ id="g78"
+ transform="matrix(0.06307836,0,0,-0.06307664,13.671143,1047.293)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c 0,0 -0.325,1.994 -0.515,1.976 l -36.182,-3.491 c -2.879,-0.278 -5.115,-2.574 -5.317,-5.459 l -0.994,-14.247 -27.992,-1.997 -1.904,12.912 c -0.424,2.872 -2.932,5.037 -5.835,5.037 h -38.188 c -2.902,0 -5.41,-2.165 -5.834,-5.037 l -1.905,-12.912 -27.992,1.997 -0.994,14.247 c -0.202,2.886 -2.438,5.182 -5.317,5.46 l -36.2,3.49 c -0.187,0.018 -0.324,-1.978 -0.511,-1.978 l -0.049,-7.83 30.658,-4.944 1.004,-14.374 c 0.203,-2.91 2.551,-5.263 5.463,-5.472 l 38.551,-2.75 c 0.146,-0.01 0.29,-0.016 0.434,-0.016 2.897,0 5.401,2.166 5.825,5.038 l 1.959,13.286 h 28.005 l 1.959,-13.286 c 0.423,-2.871 2.93,-5.037 5.831,-5.037 0.142,0 0.284,0.005 0.423,0.015 l 38.556,2.75 c 2.911,0.209 5.26,2.562 5.463,5.472 l 1.003,14.374 30.645,4.966 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path80"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g82-3"
+ transform="matrix(0.06307836,0,0,-0.06307664,1.3279404,1043.5689)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 v -47.514 -6.035 -5.492 c 0.108,-0.001 0.216,-0.005 0.323,-0.015 l 36.196,-3.49 c 1.896,-0.183 3.382,-1.709 3.514,-3.609 l 1.116,-15.978 31.574,-2.253 2.175,14.747 c 0.282,1.912 1.922,3.329 3.856,3.329 h 38.188 c 1.933,0 3.573,-1.417 3.855,-3.329 l 2.175,-14.747 31.575,2.253 1.115,15.978 c 0.133,1.9 1.618,3.425 3.514,3.609 l 36.182,3.49 c 0.107,0.01 0.214,0.014 0.322,0.015 v 4.711 l 0.015,0.005 V 0 h 0.134 c 4.795,6.12 9.232,12.569 13.487,19.449 -5.651,9.62 -12.575,18.217 -19.976,26.182 -6.864,-3.455 -13.531,-7.369 -19.828,-11.534 -3.151,3.132 -6.7,5.694 -10.186,8.372 -3.425,2.751 -7.285,4.768 -10.946,7.118 1.09,8.117 1.629,16.108 1.846,24.448 -9.446,4.754 -19.519,7.906 -29.708,10.17 -4.068,-6.837 -7.788,-14.241 -11.028,-21.479 -3.842,0.642 -7.702,0.88 -11.567,0.926 v 0.006 c -0.027,0 -0.052,-0.006 -0.075,-0.006 -0.024,0 -0.049,0.006 -0.073,0.006 V 63.652 C 93.903,63.606 90.046,63.368 86.203,62.726 82.965,69.964 79.247,77.368 75.173,84.205 64.989,81.941 54.915,78.789 45.47,74.035 45.686,65.695 46.225,57.704 47.318,49.587 43.65,47.237 39.795,45.22 36.369,42.469 32.888,39.791 29.333,37.229 26.181,34.097 19.884,38.262 13.219,42.176 6.353,45.631 -1.048,37.666 -7.968,29.069 -13.621,19.449 -9.368,12.569 -4.928,6.12 -0.134,0 Z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path84-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g86-7"
+ transform="matrix(0.06307836,0,0,-0.06307664,11.62285,1047.9836)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 -1.121,-16.063 c -0.135,-1.936 -1.675,-3.477 -3.611,-3.616 l -38.555,-2.751 c -0.094,-0.007 -0.188,-0.01 -0.281,-0.01 -1.916,0 -3.569,1.406 -3.852,3.33 l -2.211,14.994 H -81.09 l -2.211,-14.994 c -0.297,-2.018 -2.101,-3.469 -4.133,-3.32 l -38.555,2.751 c -1.936,0.139 -3.476,1.68 -3.611,3.616 L -130.721,0 -163.268,3.138 c 0.015,-3.498 0.06,-7.33 0.06,-8.093 0,-34.374 43.605,-50.896 97.781,-51.086 h 0.066 0.067 c 54.176,0.19 97.766,16.712 97.766,51.086 0,0.777 0.047,4.593 0.063,8.093 z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path88-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g90-3"
+ transform="matrix(0.06307836,0,0,-0.06307664,5.6393685,1045.0806)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c 0,-12.052 -9.765,-21.815 -21.813,-21.815 -12.042,0 -21.81,9.763 -21.81,21.815 0,12.044 9.768,21.802 21.81,21.802 C -9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path92-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g94-6"
+ transform="matrix(0.06307836,0,0,-0.06307664,5.3082938,1045.1623)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c 0,-7.994 -6.479,-14.473 -14.479,-14.473 -7.996,0 -14.479,6.479 -14.479,14.473 0,7.994 6.483,14.479 14.479,14.479 C -6.479,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path96-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g98-9"
+ transform="matrix(0.06307836,0,0,-0.06307664,7.4998997,1046.5818)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c -3.878,0 -7.021,2.858 -7.021,6.381 v 20.081 c 0,3.52 3.143,6.381 7.021,6.381 3.878,0 7.028,-2.861 7.028,-6.381 V 6.381 C 7.028,2.858 3.878,0 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path100-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g102-2"
+ transform="matrix(0.06307836,0,0,-0.06307664,9.3606615,1045.0806)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c 0,-12.052 9.765,-21.815 21.815,-21.815 12.041,0 21.808,9.763 21.808,21.815 0,12.044 -9.767,21.802 -21.808,21.802 C 9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path104-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g106-0"
+ transform="matrix(0.06307836,0,0,-0.06307664,9.6918191,1045.1623)"
+ style="stroke-width:19.8168869">
+ <path
+ d="m 0,0 c 0,-7.994 6.477,-14.473 14.471,-14.473 8.002,0 14.479,6.479 14.479,14.473 0,7.994 -6.477,14.479 -14.479,14.479 C 6.477,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:19.8168869"
+ id="path108-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ <path
+ inkscape:connector-curvature="0"
+ id="path4392"
+ d="m 4.3227149,1042.5597 a 2.5297459,2.5296773 0 0 0 -2.5297461,2.5297 2.5297459,2.5296773 0 0 0 2.5297461,2.5297 2.5297459,2.5296773 0 0 0 2.5297463,-2.5297 2.5297459,2.5296773 0 0 0 -2.5297463,-2.5297 z m 0,0.5084 a 2.0213759,2.021321 0 0 1 2.0213758,2.0213 2.0213759,2.021321 0 0 1 -2.0213758,2.0213 2.0213759,2.021321 0 0 1 -2.0213757,-2.0213 2.0213759,2.021321 0 0 1 2.0213757,-2.0213 z"
+ style="opacity:1;fill:#414042;fill-opacity:1;stroke:none;stroke-width:1.94780529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4200);enable-background:new" />
+ <path
+ style="opacity:1;fill:#414042;fill-opacity:1;stroke:none;stroke-width:1.94780529;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4200);enable-background:new"
+ d="m 10.679126,1042.5597 a 2.5297459,2.5296773 0 0 0 -2.5297472,2.5297 2.5297459,2.5296773 0 0 0 2.5297472,2.5297 2.5297459,2.5296773 0 0 0 2.529744,-2.5297 2.5297459,2.5296773 0 0 0 -2.529744,-2.5297 z m 0,0.5084 a 2.0213759,2.021321 0 0 1 2.021373,2.0213 2.0213759,2.021321 0 0 1 -2.021373,2.0213 2.0213759,2.021321 0 0 1 -2.0213767,-2.0213 2.0213759,2.021321 0 0 1 2.0213767,-2.0213 z"
+ id="path4403"
+ inkscape:connector-curvature="0" />
+ <rect
+ style="opacity:1;fill:#414042;fill-opacity:1;stroke:none;stroke-width:5.625;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.44162436"
+ id="rect4160"
+ width="2.3136585"
+ height="0.53352129"
+ x="6.3440895"
+ y="1043.9767" />
+ </g>
+</svg>
diff --git a/scene/resources/default_theme/source/hslider_bg.svg b/editor/icons/source/icon_hslider_bg.svg
index f247904a33..10bea12ab8 100644
--- a/scene/resources/default_theme/source/hslider_bg.svg
+++ b/editor/icons/source/icon_hslider_bg.svg
@@ -14,11 +14,11 @@
viewBox="0 0 16 15.999999"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="hslider_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
+ inkscape:version="0.92.1 unknown"
+ sodipodi:docname="icon_hslider_bg.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/2x/icon_hslider_bg.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96">
<defs
id="defs4" />
<sodipodi:namedview
@@ -29,7 +29,7 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
- inkscape:cx="9.463221"
+ inkscape:cx="4.166346"
inkscape:cy="6.5721301"
inkscape:document-units="px"
inkscape:current-layer="layer1"
@@ -41,11 +41,11 @@
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
+ inkscape:window-width="929"
+ inkscape:window-height="897"
+ inkscape:window-x="436"
+ inkscape:window-y="155"
+ inkscape:window-maximized="0"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="true">
<inkscape:grid
diff --git a/scene/resources/default_theme/source/hsplitter.svg b/editor/icons/source/icon_hsplitter.svg
index 01c893fc56..01c893fc56 100644
--- a/scene/resources/default_theme/source/hsplitter.svg
+++ b/editor/icons/source/icon_hsplitter.svg
diff --git a/editor/icons/source/icon_mini_matrix32.svg b/editor/icons/source/icon_mini_matrix32.svg
new file mode 100644
index 0000000000..5159ea0b87
--- /dev/null
+++ b/editor/icons/source/icon_mini_matrix32.svg
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="12"
+ viewBox="0 0 16 12"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="icon_mini_matrix32.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32.000001"
+ inkscape:cx="1.5471383"
+ inkscape:cy="5.978497"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1040.3622)">
+ <path
+ style="fill:#ddf4aa;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 8 2 L 8 4 L 9 4 L 10 4 A 1 1 0 0 1 9 5 L 9 7 A 1 1 0 0 1 10 8 A 1 1 0 0 1 9 9 L 8 9 L 8 11 L 9 11 A 3 3 0 0 0 11.597656 9.5 A 3 3 0 0 0 11.597656 6.5 A 3 3 0 0 0 11.232422 5.9980469 A 3 3 0 0 0 11.597656 5.5 A 3 3 0 0 0 11.994141 4 L 12 4 L 12 2 L 9 2 L 8 2 z "
+ transform="translate(0,1040.3622)"
+ id="path4753" />
+ <rect
+ y="1048.3622"
+ x="11"
+ height="2"
+ width="5"
+ id="rect4763"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ sodipodi:open="true"
+ d="m 13,1050.3622 a 2,2 0 0 1 -1.732051,-1 2,2 0 0 1 0,-2 2,2 0 0 1 1.732051,-1"
+ sodipodi:end="4.712389"
+ sodipodi:start="1.5707963"
+ sodipodi:ry="2"
+ sodipodi:rx="2"
+ sodipodi:cy="1048.3622"
+ sodipodi:cx="13"
+ sodipodi:type="arc"
+ id="path4765"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4767"
+ d="m 13,1042.3622 0,2 a 1,1 0 0 1 1,1 1,1 0 0 1 -1,1 l 0,2 a 3,3 0 0 0 2.597656,-1.5 3,3 0 0 0 0,-3 3,3 0 0 0 -2.597656,-1.5 z"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2,1044.3622 a 3,3 0 0 1 3,3 l -2,0 a 1.0000174,1.0000174 0 0 0 -1,-1 l 0,-2 z"
+ id="path4771"
+ inkscape:connector-curvature="0" />
+ <rect
+ y="-1050.3622"
+ x="3"
+ height="3"
+ width="2"
+ id="rect4773"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ transform="scale(1,-1)" />
+ <rect
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4775"
+ width="2"
+ height="5.9999828"
+ x="0"
+ y="-1050.3622"
+ transform="scale(1,-1)" />
+ <rect
+ transform="scale(1,-1)"
+ y="-1050.3622"
+ x="3"
+ height="5.9999828"
+ width="2"
+ id="rect4777"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4779"
+ d="m 5,1044.3622 a 3,3 0 0 1 3,3 l -2,0 a 1.0000174,1.0000174 0 0 0 -1,-1 l 0,-2 z"
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="fill:#c4ec69;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4781"
+ width="2"
+ height="3.0000002"
+ x="6"
+ y="-1050.3622"
+ transform="scale(1,-1)" />
+ </g>
+</svg>
diff --git a/scene/resources/default_theme/source/tab.svg b/editor/icons/source/icon_option_arrow.svg
index 612977953a..5cd943e9e3 100644
--- a/scene/resources/default_theme/source/tab.svg
+++ b/editor/icons/source/icon_option_arrow.svg
@@ -9,16 +9,16 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- viewBox="0 0 8 8"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
- sodipodi:docname="tab.svg">
+ sodipodi:docname="option_arrow.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="32.000001"
- inkscape:cx="-2.6446005"
- inkscape:cy="5.445875"
+ inkscape:zoom="45.254834"
+ inkscape:cx="3.1667338"
+ inkscape:cy="5.9875884"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -69,13 +69,12 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(0,-1044.3622)">
+ transform="translate(0,-1040.3622)">
<path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.07843138;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 8,3.984375 c -4,2.6770833 -2,1.3385417 0,0 z M 8,4 C 7.9958579,3.7402262 7.8907874,3.4766349 7.7070312,3.2929688 l -3,-3.00000005 C 4.5187601,0.09943602 4.2602361,-0.00974989 3.9902344,-0.00976563 3.0928174,-0.00952997 2.6498571,1.0811201 3.2929688,1.7070312 L 4.5859375,3 H 0 V 5 L 4.5859375,5 3.2929688,6.2929688 C 2.3113156,7.2354775 3.7645225,8.6886844 4.7070312,7.7070312 l 3,-3 C 7.898443,4.5157079 8.0041444,4.2706029 8,4 Z"
- transform="translate(0,1044.3622)"
- id="path814"
inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccccccccccccccc" />
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="m 9.9999996,1043.3583 c -0.2637796,0.01 -0.5144012,0.1165 -0.697265,0.3067 l -3.292969,3.2929 -3.2929688,-3.2929 C 2.5285367,1043.4714 2.2700113,1043.3622 2,1043.3622 c -0.8974208,2e-4 -1.34038281,1.0909 -0.6972656,1.7168 l 4,4 c 0.3905299,0.3904 1.0235325,0.3904 1.4140624,0 l 4.0000002,-4 c 0.657344,-0.6321 0.194906,-1.7422 -0.7167974,-1.7207 z"
+ id="path4484"
+ sodipodi:nodetypes="cccccccccc" />
</g>
</svg>
diff --git a/editor/icons/source/icon_particles_shader.svg b/editor/icons/source/icon_particles_shader.svg
new file mode 100644
index 0000000000..b4c2ef7ccd
--- /dev/null
+++ b/editor/icons/source/icon_particles_shader.svg
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_node_2d.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:docname="icon_particles_shader.svg">
+ <defs
+ id="defs4">
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath4253">
+ <path
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 16.458984,1024.37 a 12.000027,12.000027 0 0 0 -3.564453,0.4004 12.000027,12.000027 0 0 0 -8.4863279,14.6973 12.000027,12.000027 0 0 0 14.6972659,8.4863 12.000027,12.000027 0 0 0 8.486328,-14.6973 12.000027,12.000027 0 0 0 -11.132813,-8.8867 z M 16.25,1029.8212 a 6.5451717,6.5451717 0 0 1 6.072266,4.8476 6.5451717,6.5451717 0 0 1 -4.628907,8.0157 6.5451717,6.5451717 0 0 1 -8.0156246,-4.6289 6.5451717,6.5451717 0 0 1 4.6289066,-8.0157 6.5451717,6.5451717 0 0 1 1.943359,-0.2187 z"
+ id="path4255"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath4199">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4201"
+ d="m 16.5,1025.8622 a 11.8125,10.499999 0 0 0 -11.8125001,10.5 11.8125,10.499999 0 0 0 11.8125001,10.5 11.8125,10.499999 0 0 0 11.8125,-10.5 11.8125,10.499999 0 0 0 -11.8125,-10.5 z m -3.375,3 a 3.375,2.9999997 0 0 1 3.375,3 3.375,2.9999997 0 0 1 -3.375,3 3.375,2.9999997 0 0 1 -3.3750001,-3 3.375,2.9999997 0 0 1 3.3750001,-3 z"
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath4208">
+ <path
+ style="opacity:1;fill:#a5b7f5;fill-opacity:0.98823529;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ d="M 8,1037.3622 A 4.4999948,4.9999847 0 0 0 3.5859375,1041.3934 3,3 0 0 0 1,1044.3622 a 3,3 0 0 0 3,3 l 8,0 a 3,3 0 0 0 3,-3 3,3 0 0 0 -2.589844,-2.9668 A 4.4999948,4.9999847 0 0 0 8,1037.3622 Z m -4,11 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z m 8,0 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z m -4,1 a 1,1 0 0 0 -1,1 1,1 0 0 0 1,1 1,1 0 0 0 1,-1 1,1 0 0 0 -1,-1 z"
+ id="path4210"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="15.999999"
+ inkscape:cx="8.2922739"
+ inkscape:cy="6.6952763"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:object-paths="true"
+ inkscape:snap-intersection-paths="true"
+ inkscape:object-nodes="true"
+ inkscape:snap-smooth-nodes="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336"
+ empspacing="4" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <g
+ id="g4271"
+ clip-path="url(#clipPath4208)"
+ transform="translate(0,1.8694115e-5)">
+ <rect
+ y="1037.3622"
+ x="0"
+ height="2.0000031"
+ width="16"
+ id="rect4159"
+ style="fill:#ff7070;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="fill:#ffeb70;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4161"
+ width="16"
+ height="2.0000029"
+ x="0"
+ y="1039.3622" />
+ <rect
+ style="fill:#9dff70;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4163"
+ width="16"
+ height="1.9999999"
+ x="0"
+ y="1041.3622" />
+ <rect
+ y="1043.3622"
+ x="0"
+ height="2.0000024"
+ width="16"
+ id="rect4165"
+ style="fill:#70ffb9;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="1045.3622"
+ x="0"
+ height="2.0000021"
+ width="16"
+ id="rect4167"
+ style="fill:#70deff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="fill:#ff70ac;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4169"
+ width="16"
+ height="1.9999987"
+ x="0"
+ y="1049.3622" />
+ <rect
+ style="fill:#9f70ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4146"
+ width="16"
+ height="2.0000021"
+ x="0"
+ y="1047.3622" />
+ </g>
+ </g>
+</svg>
diff --git a/scene/resources/default_theme/source/button_group.svg b/editor/icons/source/icon_play_button_group.svg
index 84bdb00505..84bdb00505 100644
--- a/scene/resources/default_theme/source/button_group.svg
+++ b/editor/icons/source/icon_play_button_group.svg
diff --git a/scene/resources/default_theme/source/scroll_bg.svg b/editor/icons/source/icon_scroll_bg.svg
index 29604b9e14..29604b9e14 100644
--- a/scene/resources/default_theme/source/scroll_bg.svg
+++ b/editor/icons/source/icon_scroll_bg.svg
diff --git a/scene/resources/default_theme/source/scroll_grabber.svg b/editor/icons/source/icon_scroll_grabber.svg
index b9d2bbbec0..b9d2bbbec0 100644
--- a/scene/resources/default_theme/source/scroll_grabber.svg
+++ b/editor/icons/source/icon_scroll_grabber.svg
diff --git a/scene/resources/default_theme/source/scroll_grabber_hl.svg b/editor/icons/source/icon_scroll_grabber_hl.svg
index 88f4317b8d..ce9a66c5bc 100644
--- a/scene/resources/default_theme/source/scroll_grabber_hl.svg
+++ b/editor/icons/source/icon_scroll_grabber_hl.svg
@@ -14,9 +14,9 @@
viewBox="0 0 12 11.999999"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_grabber_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
+ inkscape:version="0.92.1 unknown"
+ sodipodi:docname="icon_scroll_grabber_hl.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/icon_scroll_grabber_hl.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="45.254836"
- inkscape:cx="1.4412236"
- inkscape:cy="5.623836"
+ inkscape:cx="3.0874565"
+ inkscape:cy="5.7564185"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -41,11 +41,11 @@
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
+ inkscape:window-width="1097"
+ inkscape:window-height="1076"
+ inkscape:window-x="161"
+ inkscape:window-y="200"
+ inkscape:window-maximized="0"
inkscape:snap-nodes="false">
<inkscape:grid
type="xygrid"
@@ -60,7 +60,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -70,10 +70,13 @@
id="layer1"
transform="translate(0,-1040.3623)">
<circle
- style="opacity:1;fill:#7eff8a;fill-opacity:1;stroke:none;stroke-width:2.24999642;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ style="opacity:1;fill:#f9f9f9;fill-opacity:0.73000002;stroke:none;stroke-width:2.24999642;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path4239"
cx="6"
cy="1046.3623"
- r="2.9999952" />
+ r="2.9999952"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/icon_scroll_grabber_hl.png"
+ inkscape:export-xdpi="96"
+ inkscape:export-ydpi="96" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/hslider_grabber.svg b/editor/icons/source/icon_slider_grabber.svg
index a222edd37e..b13ca5d1a9 100644
--- a/scene/resources/default_theme/source/hslider_grabber.svg
+++ b/editor/icons/source/icon_slider_grabber.svg
@@ -14,8 +14,8 @@
viewBox="0 0 16 15.999999"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="hslider_grabber.svg"
+ inkscape:version="0.92.1 unknown"
+ sodipodi:docname="icon_slider_grabber.svg"
inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
- inkscape:cx="2.6109686"
- inkscape:cy="6.3424144"
+ inkscape:cx="3.7828436"
+ inkscape:cy="7.4986644"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -41,11 +41,11 @@
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
+ inkscape:window-width="1195"
+ inkscape:window-height="722"
+ inkscape:window-x="91"
+ inkscape:window-y="633"
+ inkscape:window-maximized="0"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="true">
<inkscape:grid
diff --git a/scene/resources/default_theme/source/hslider_grabber_hl.svg b/editor/icons/source/icon_slider_grabber_hl.svg
index d53aa5c0e9..5d53811c55 100644
--- a/scene/resources/default_theme/source/hslider_grabber_hl.svg
+++ b/editor/icons/source/icon_slider_grabber_hl.svg
@@ -14,11 +14,11 @@
viewBox="0 0 16 15.999999"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="hslider_grabber_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
+ inkscape:version="0.92.1 unknown"
+ sodipodi:docname="icon_slider_grabber_hl.svg"
+ inkscape:export-filename="/mnt/2TB/Development/godot_dev/editor/icons/2x/icon_slider_grabber_hl.png"
+ inkscape:export-xdpi="192"
+ inkscape:export-ydpi="192">
<defs
id="defs4" />
<sodipodi:namedview
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32"
- inkscape:cx="7.0748113"
- inkscape:cy="6.0432589"
+ inkscape:cx="7.6841863"
+ inkscape:cy="6.0120089"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -41,11 +41,11 @@
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
+ inkscape:window-width="1092"
+ inkscape:window-height="880"
+ inkscape:window-x="92"
+ inkscape:window-y="49"
+ inkscape:window-maximized="0"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="true">
<inkscape:grid
@@ -75,6 +75,6 @@
cy="1044.3623"
cx="8.0000057"
id="circle4262"
- style="fill:#7eff8a;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ style="fill:#f9f9f9;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
</g>
</svg>
diff --git a/editor/icons/source/icon_spatial_shader.svg b/editor/icons/source/icon_spatial_shader.svg
new file mode 100644
index 0000000000..329354b716
--- /dev/null
+++ b/editor/icons/source/icon_spatial_shader.svg
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collision_shape.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:docname="icon_spatial_shader.svg">
+ <defs
+ id="defs4">
+ <clipPath
+ id="clipPath4253"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ inkscape:connector-curvature="0"
+ id="path4255"
+ d="m 16.458984,1024.37 a 12.000027,12.000027 0 0 0 -3.564453,0.4004 12.000027,12.000027 0 0 0 -8.4863279,14.6973 12.000027,12.000027 0 0 0 14.6972659,8.4863 12.000027,12.000027 0 0 0 8.486328,-14.6973 12.000027,12.000027 0 0 0 -11.132813,-8.8867 z M 16.25,1029.8212 a 6.5451717,6.5451717 0 0 1 6.072266,4.8476 6.5451717,6.5451717 0 0 1 -4.628907,8.0157 6.5451717,6.5451717 0 0 1 -8.0156246,-4.6289 6.5451717,6.5451717 0 0 1 4.6289066,-8.0157 6.5451717,6.5451717 0 0 1 1.943359,-0.2187 z"
+ style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ </clipPath>
+ <clipPath
+ id="clipPath4199"
+ clipPathUnits="userSpaceOnUse">
+ <path
+ style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ d="m 16.5,1025.8622 a 11.8125,10.499999 0 0 0 -11.8125001,10.5 11.8125,10.499999 0 0 0 11.8125001,10.5 11.8125,10.499999 0 0 0 11.8125,-10.5 11.8125,10.499999 0 0 0 -11.8125,-10.5 z m -3.375,3 a 3.375,2.9999997 0 0 1 3.375,3 3.375,2.9999997 0 0 1 -3.375,3 3.375,2.9999997 0 0 1 -3.3750001,-3 3.375,2.9999997 0 0 1 3.3750001,-3 z"
+ id="path4201"
+ inkscape:connector-curvature="0" />
+ </clipPath>
+ <clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath4280">
+ <g
+ id="g4282"
+ inkscape:label="Layer 1"
+ transform="translate(0,1.1802001e-5)"
+ style="stroke:#fc9c9c;stroke-opacity:0.99607843">
+ <path
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;baseline-shift:baseline;text-anchor:start;white-space:normal;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#fc9c9c;fill-opacity:0.99607843;fill-rule:evenodd;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 7.9628906,1.0019531 A 1.0001,1.0001 0 0 0 7.5527344,1.1054688 l -6,3 A 1.0001,1.0001 0 0 0 1,5 l 0,6 a 1.0001,1.0001 0 0 0 0.5527344,0.894531 l 6,3 a 1.0001,1.0001 0 0 0 0.8945312,0 l 6.0000004,-3 A 1.0001,1.0001 0 0 0 15,11 L 15,5 A 1.0001,1.0001 0 0 0 14.447266,4.1054688 l -6.0000004,-3 A 1.0001,1.0001 0 0 0 7.9628906,1.0019531 Z M 8,3.1191406 11.763672,5 8,6.8828125 4.2363281,5 8,3.1191406 Z m -5,3.5 4,2 0,3.7636714 -4,-2 0,-3.7636714 z m 10,0 0,3.7636714 -4,2 0,-3.7636714 4,-2 z"
+ transform="translate(0,1036.3622)"
+ id="path4284"
+ inkscape:connector-curvature="0" />
+ </g>
+ </clipPath>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="22.627417"
+ inkscape:cx="7.8442401"
+ inkscape:cy="13.929239"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="true"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-nodes="false"
+ inkscape:snap-smooth-nodes="false"
+ inkscape:snap-midpoints="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <g
+ id="g4271"
+ clip-path="url(#clipPath4280)">
+ <rect
+ y="1037.3622"
+ x="0"
+ height="2.0000031"
+ width="16"
+ id="rect4159"
+ style="fill:#ff7070;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="fill:#ffeb70;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4161"
+ width="16"
+ height="2.0000029"
+ x="0"
+ y="1039.3622" />
+ <rect
+ style="fill:#9dff70;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4163"
+ width="16"
+ height="1.9999999"
+ x="0"
+ y="1041.3622" />
+ <rect
+ y="1043.3622"
+ x="0"
+ height="2.0000024"
+ width="16"
+ id="rect4165"
+ style="fill:#70ffb9;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ y="1045.3622"
+ x="0"
+ height="2.0000021"
+ width="16"
+ id="rect4167"
+ style="fill:#70deff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ style="fill:#ff70ac;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4169"
+ width="16"
+ height="1.9999987"
+ x="0"
+ y="1049.3622" />
+ <rect
+ style="fill:#9f70ff;fill-opacity:1;stroke:none;stroke-width:4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4146"
+ width="16"
+ height="2.0000021"
+ x="0"
+ y="1047.3622" />
+ </g>
+ </g>
+</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_down.svg b/editor/icons/source/icon_spinbox_updown.svg
index 078cc5c37c..e29d7fe0d2 100644
--- a/scene/resources/default_theme/source/scroll_button_down.svg
+++ b/editor/icons/source/icon_spinbox_updown.svg
@@ -9,16 +9,16 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_down.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
+ inkscape:export-xdpi="45"
+ inkscape:export-ydpi="45"
+ sodipodi:docname="spinbox_updown.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,28 +28,30 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="1.4098045"
- inkscape:cy="5.764877"
+ inkscape:zoom="16"
+ inkscape:cx="-1.901723"
+ inkscape:cy="9.1326297"
inkscape:document-units="px"
- inkscape:current-layer="layer1"
+ inkscape:current-layer="layer1-5"
showgrid="true"
units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
inkscape:snap-bbox="true"
inkscape:bbox-paths="true"
inkscape:bbox-nodes="true"
inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
inkscape:window-width="1600"
inkscape:window-height="836"
inkscape:window-x="0"
inkscape:window-y="27"
- inkscape:window-maximized="1">
+ inkscape:window-maximized="1"
+ inkscape:snap-smooth-nodes="true"
+ inkscape:object-nodes="true">
<inkscape:grid
type="xygrid"
- id="grid4136"
- empspacing="4" />
+ id="grid3336" />
</sodipodi:namedview>
<metadata
id="metadata7">
@@ -67,11 +69,15 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(0,-1040.3623)">
+ transform="translate(0,-1036.3622)">
<path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.27450982;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 10.023438,1044.3535 a 1.0001,1.0001 0 0 0 -0.6230474,0.209 L 6,1047.1113 2.5996094,1044.5625 a 1.0001,1.0001 0 1 0 -1.1992188,1.5996 l 4,3 a 1.0001,1.0001 0 0 0 1.1992188,0 l 3.9999996,-3 a 1.0001,1.0001 0 0 0 -0.576171,-1.8086 z"
- id="path4511"
- inkscape:connector-curvature="0" />
+ style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+ d="M 7.984375 1.0019531 A 1.0001 1.0001 0 0 0 7.2929688 1.2929688 L 3.2929688 5.2929688 A 1.0001 1.0001 0 1 0 4.7070312 6.7070312 L 8 3.4140625 L 11.292969 6.7070312 A 1.0001 1.0001 0 1 0 12.707031 5.2929688 L 8.7070312 1.2929688 A 1.0001 1.0001 0 0 0 7.984375 1.0019531 z M 11.990234 8.9863281 A 1.0001 1.0001 0 0 0 11.292969 9.2929688 L 8 12.585938 L 4.7070312 9.2929688 A 1.0001 1.0001 0 0 0 3.9902344 8.9902344 A 1.0001 1.0001 0 0 0 3.2929688 10.707031 L 7.2929688 14.707031 A 1.0001 1.0001 0 0 0 8.7070312 14.707031 L 12.707031 10.707031 A 1.0001 1.0001 0 0 0 11.990234 8.9863281 z "
+ transform="translate(0,1036.3622)"
+ id="path4484" />
+ <g
+ id="layer1-5"
+ inkscape:label="Layer 1"
+ transform="translate(14.210182,-5.3664)" />
</g>
</svg>
diff --git a/editor/icons/source/icon_2_d.svg b/editor/icons/source/icon_tab_menu.svg
index 54c93a45aa..39e0d1f261 100644
--- a/editor/icons/source/icon_2_d.svg
+++ b/editor/icons/source/icon_tab_menu.svg
@@ -15,10 +15,10 @@
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
- inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
- sodipodi:docname="icon_2_d.svg">
+ sodipodi:docname="tab_menu.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="22.627418"
- inkscape:cx="1.7654173"
- inkscape:cy="7.2653991"
+ inkscape:zoom="32.000001"
+ inkscape:cx="4.0814179"
+ inkscape:cy="8.4695645"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -47,7 +47,6 @@
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
- inkscape:snap-midpoints="true"
inkscape:snap-smooth-nodes="true"
inkscape:object-nodes="true">
<inkscape:grid
@@ -71,23 +70,23 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
- <path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1040.3622 2,-2 2,2"
- id="path4485"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 4,1039.3622 v 9 h 9"
- id="path4487"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
- <path
- sodipodi:nodetypes="ccc"
- inkscape:connector-curvature="0"
- id="path4489"
- d="m 12,1046.3622 2,2 -2,2"
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <circle
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
+ id="path819"
+ cx="8"
+ cy="1038.3622"
+ r="2" />
+ <circle
+ r="2"
+ cy="1044.3622"
+ cx="8"
+ id="circle821"
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118" />
+ <circle
+ style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
+ id="circle823"
+ cx="8"
+ cy="1050.3622"
+ r="2" />
</g>
</svg>
diff --git a/editor/icons/source/icon_texture.svg b/editor/icons/source/icon_texture.svg
new file mode 100644
index 0000000000..39e88e592b
--- /dev/null
+++ b/editor/icons/source/icon_texture.svg
@@ -0,0 +1,137 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ viewBox="0 0 16 16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.91 r13725"
+ inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_key.png"
+ inkscape:export-xdpi="90"
+ inkscape:export-ydpi="90"
+ sodipodi:docname="icon_image_texture.svg">
+ <defs
+ id="defs4" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="32"
+ inkscape:cx="9.9365814"
+ inkscape:cy="6.4466253"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="true"
+ units="px"
+ inkscape:snap-bbox="true"
+ inkscape:bbox-paths="true"
+ inkscape:bbox-nodes="true"
+ inkscape:snap-bbox-edge-midpoints="true"
+ inkscape:snap-bbox-midpoints="false"
+ inkscape:snap-object-midpoints="true"
+ inkscape:snap-center="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
+ inkscape:window-x="0"
+ inkscape:window-y="27"
+ inkscape:window-maximized="1"
+ inkscape:object-paths="false"
+ inkscape:snap-intersection-paths="false"
+ inkscape:object-nodes="false"
+ inkscape:snap-smooth-nodes="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid3336" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-1036.3622)">
+ <path
+ style="opacity:1;fill:#e0e0e0;fill-opacity:0.99607843;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ d="M 2 1 A 1 1 0 0 0 1 2 L 1 14 A 1 1 0 0 0 2 15 L 14 15 A 1 1 0 0 0 15 14 L 15 2 A 1 1 0 0 0 14 1 L 2 1 z M 3 3 L 13 3 L 13 11 L 3 11 L 3 3 z "
+ transform="translate(0,1036.3622)"
+ id="rect4156" />
+ <rect
+ y="1043.3622"
+ x="6"
+ height="1"
+ width="2"
+ id="rect4197"
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843" />
+ <rect
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ id="rect4199"
+ width="2"
+ height="2.0000174"
+ x="6"
+ y="1044.3622" />
+ <rect
+ y="1045.3622"
+ x="4"
+ height="1"
+ width="2"
+ id="rect4201"
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843" />
+ <rect
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ id="rect4203"
+ width="2"
+ height="2.0000174"
+ x="8"
+ y="1044.3622" />
+ <rect
+ y="1044.3622"
+ x="10"
+ height="2.0000174"
+ width="2"
+ id="rect4205"
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843" />
+ <rect
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ id="rect4207"
+ width="3"
+ height="2.0000174"
+ x="8"
+ y="1042.3622" />
+ <rect
+ y="1041.3622"
+ x="9"
+ height="1"
+ width="1"
+ id="rect4217"
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843" />
+ <rect
+ style="opacity:1;fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.99607843"
+ id="rect4219"
+ width="1"
+ height="1"
+ x="5"
+ y="1044.3622" />
+ </g>
+</svg>
diff --git a/scene/resources/default_theme/source/vseparator.svg b/editor/icons/source/icon_tree_arrow_down.svg
index 40c2c674a1..1dd209720f 100644
--- a/scene/resources/default_theme/source/vseparator.svg
+++ b/editor/icons/source/icon_tree_arrow_down.svg
@@ -9,16 +9,16 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- viewBox="0 0 8 8"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
- sodipodi:docname="vseparator.svg">
+ sodipodi:docname="arrow_down.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="5.3201856"
- inkscape:cy="4.9836785"
+ inkscape:zoom="22.627417"
+ inkscape:cx="1.7981958"
+ inkscape:cy="7.5815407"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -69,5 +69,12 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(0,-1044.3622)" />
+ transform="translate(0,-1040.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
+ d="m 3,1045.3622 3,3 3,-3"
+ id="path814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc" />
+ </g>
</svg>
diff --git a/scene/resources/default_theme/source/hseparator.svg b/editor/icons/source/icon_tree_arrow_right.svg
index 4bf5381240..43134ba1b1 100644
--- a/scene/resources/default_theme/source/hseparator.svg
+++ b/editor/icons/source/icon_tree_arrow_right.svg
@@ -9,16 +9,16 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- viewBox="0 0 8 8"
+ width="12"
+ height="12"
+ viewBox="0 0 12 12"
id="svg2"
version="1.1"
inkscape:version="0.92.1 r"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
- sodipodi:docname="hseparator.svg">
+ sodipodi:docname="arrow_right.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="64.000004"
- inkscape:cx="1.1715704"
- inkscape:cy="4.26452"
+ inkscape:zoom="45.254836"
+ inkscape:cx="4.0845752"
+ inkscape:cy="5.8802612"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -69,5 +69,12 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(0,-1044.3622)" />
+ transform="translate(0,-1040.3622)">
+ <path
+ style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
+ d="m 4,1049.3622 3.0000202,-3 -3.0000202,-3"
+ id="path814"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="ccc" />
+ </g>
</svg>
diff --git a/scene/resources/default_theme/source/unchecked.svg b/editor/icons/source/icon_unchecked.svg
index 053cbe6de5..053cbe6de5 100644
--- a/scene/resources/default_theme/source/unchecked.svg
+++ b/editor/icons/source/icon_unchecked.svg
diff --git a/scene/resources/default_theme/source/vslider_bg.svg b/editor/icons/source/icon_vslider_bg.svg
index b34dddc2d0..b34dddc2d0 100644
--- a/scene/resources/default_theme/source/vslider_bg.svg
+++ b/editor/icons/source/icon_vslider_bg.svg
diff --git a/scene/resources/default_theme/source/vsplit_bg.svg b/editor/icons/source/icon_vsplit_bg.svg
index e11940cf53..e11940cf53 100644
--- a/scene/resources/default_theme/source/vsplit_bg.svg
+++ b/editor/icons/source/icon_vsplit_bg.svg
diff --git a/scene/resources/default_theme/source/vsplitter.svg b/editor/icons/source/icon_vsplitter.svg
index 80f7c2ce12..80f7c2ce12 100644
--- a/scene/resources/default_theme/source/vsplitter.svg
+++ b/editor/icons/source/icon_vsplitter.svg
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 2cefcdbc4a..e0a2ea624e 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -72,7 +72,7 @@ struct ColladaImport {
Map<String, NodeMap> node_map; //map from collada node to engine node
Map<String, String> node_name_map; //map from collada node to engine node
- Map<String, Ref<Mesh> > mesh_cache;
+ Map<String, Ref<ArrayMesh> > mesh_cache;
Map<String, Ref<Curve3D> > curve_cache;
Map<String, Ref<Material> > material_cache;
Map<Collada::Node *, Skeleton *> skeleton_map;
@@ -88,7 +88,7 @@ struct ColladaImport {
Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
Error _create_resources(Collada::Node *p_node);
Error _create_material(const String &p_material);
- Error _create_mesh_surfaces(bool p_optimize, Ref<Mesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes = Vector<Ref<Mesh> >(), bool p_for_morph = false, bool p_use_mesh_material = false);
+ Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_data, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes = Vector<Ref<ArrayMesh> >(), bool p_for_morph = false, bool p_use_mesh_material = false);
Error load(const String &p_path, int p_flags, bool p_force_make_tangents = false);
void _fix_param_animation_tracks();
void create_animation(int p_clip, bool p_make_tracks_in_all_bones, bool p_import_value_tracks);
@@ -402,8 +402,8 @@ Error ColladaImport::_create_material(const String &p_target) {
Ref<Texture> texture = ResourceLoader::load(texfile, "Texture");
if (texture.is_valid()) {
- material->set_texture(SpatialMaterial::TEXTURE_SPECULAR, texture);
- material->set_specular(Color(1, 1, 1, 1));
+ material->set_texture(SpatialMaterial::TEXTURE_METALLIC, texture);
+ material->set_specular(1.0);
//material->set_texture(SpatialMaterial::PARAM_SPECULAR,texture);
//material->set_parameter(SpatialMaterial::PARAM_SPECULAR,Color(1,1,1,1));
@@ -411,8 +411,9 @@ Error ColladaImport::_create_material(const String &p_target) {
missing_textures.push_back(texfile.get_file());
}
}
+
} else {
- material->set_metalness(effect.specular.color.get_v());
+ material->set_metallic(effect.specular.color.get_v());
}
// EMISSION
@@ -553,10 +554,10 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
tangent = Vector3();
} else {
tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
- (t2 * z1 - t1 * z2) * r)
+ (t2 * z1 - t1 * z2) * r)
.normalized();
binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
- (s1 * z2 - s2 * z1) * r)
+ (s1 * z2 - s2 * z1) * r)
.normalized();
}
@@ -590,7 +591,7 @@ static void _generate_tangents_and_binormals(const PoolVector<int> &p_indices, c
}
}
-Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<Mesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<Mesh> > p_morph_meshes, bool p_for_morph, bool p_use_mesh_material) {
+Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh> > p_morph_meshes, bool p_for_morph, bool p_use_mesh_material) {
bool local_xform_mirror = p_local_xform.basis.determinant() < 0;
@@ -1529,7 +1530,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
String meshid;
Transform apply_xform;
Vector<int> bone_remap;
- Vector<Ref<Mesh> > morphs;
+ Vector<Ref<ArrayMesh> > morphs;
print_line("mesh: " + String(mi->get_name()));
@@ -1620,9 +1621,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
String meshid = names[i];
if (collada.state.mesh_data_map.has(meshid)) {
- Ref<Mesh> mesh = Ref<Mesh>(memnew(Mesh));
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
- Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<Mesh> >(), true);
+ Error err = _create_mesh_surfaces(false, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh> >(), true);
ERR_FAIL_COND_V(err, err);
morphs.push_back(mesh);
@@ -1647,7 +1648,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
meshid = ng->source;
}
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
if (mesh_cache.has(meshid)) {
mesh = mesh_cache[meshid];
} else {
@@ -1655,7 +1656,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
//bleh, must ignore invalid
ERR_FAIL_COND_V(!collada.state.mesh_data_map.has(meshid), ERR_INVALID_DATA);
- mesh = Ref<Mesh>(memnew(Mesh));
+ mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid];
mesh->set_name(meshdata.name);
Error err = _create_mesh_surfaces(morphs.size() == 0, mesh, ng->material_map, meshdata, apply_xform, bone_remap, skin, morph, morphs, false, use_mesh_builtin_materials);
diff --git a/editor/import/editor_import_plugin.cpp b/editor/import/editor_import_plugin.cpp
new file mode 100644
index 0000000000..6dee5da538
--- /dev/null
+++ b/editor/import/editor_import_plugin.cpp
@@ -0,0 +1,152 @@
+/*************************************************************************/
+/* editor_import_plugin.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 "editor_import_plugin.h"
+#include "core/script_language.h"
+
+EditorImportPlugin::EditorImportPlugin() {
+}
+
+String EditorImportPlugin::get_importer_name() const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_importer_name")), "");
+ return get_script_instance()->call("get_importer_name");
+}
+
+String EditorImportPlugin::get_visible_name() const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_visible_name")), "");
+ return get_script_instance()->call("get_visible_name");
+}
+
+void EditorImportPlugin::get_recognized_extensions(List<String> *p_extensions) const {
+ ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("get_recognized_extensions")));
+ Array extensions = get_script_instance()->call("get_recognized_extensions");
+ for (int i = 0; i < extensions.size(); i++) {
+ p_extensions->push_back(extensions[i]);
+ }
+}
+
+String EditorImportPlugin::get_preset_name(int p_idx) const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_preset_name")), "");
+ return get_script_instance()->call("get_preset_name", p_idx);
+}
+
+int EditorImportPlugin::get_preset_count() {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_preset_count")), 0);
+ return get_script_instance()->call("get_preset_count");
+}
+
+String EditorImportPlugin::get_save_extension() const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_save_extension")), "");
+ return get_script_instance()->call("get_save_extension");
+}
+
+String EditorImportPlugin::get_resource_type() const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_resource_type")), "");
+ return get_script_instance()->call("get_resource_type");
+}
+
+void EditorImportPlugin::get_import_options(List<ResourceImporter::ImportOption> *r_options, int p_preset) const {
+
+ ERR_FAIL_COND(!(get_script_instance() && get_script_instance()->has_method("get_import_options")));
+ Array needed;
+ needed.push_back("name");
+ needed.push_back("default_value");
+ Array options = get_script_instance()->call("get_import_options", p_preset);
+ for (int i = 0; i < options.size(); i++) {
+ Dictionary d = options[i];
+ ERR_FAIL_COND(!d.has_all(needed));
+ String name = d["name"];
+ Variant default_value = d["default_value"];
+
+ PropertyHint hint = PROPERTY_HINT_NONE;
+ if (d.has("property_hint")) {
+ hint = (PropertyHint)d["property_hint"].operator int64_t();
+ }
+
+ String hint_string;
+ if (d.has("hint_string")) {
+ hint_string = d["hint_string"];
+ }
+
+ uint32_t usage = PROPERTY_USAGE_DEFAULT;
+ if (d.has("usage")) {
+ usage = d["usage"];
+ }
+
+ ImportOption option(PropertyInfo(default_value.get_type(), name, hint, hint_string, usage), default_value);
+ r_options->push_back(option);
+ }
+}
+
+bool EditorImportPlugin::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("get_option_visibility")), true);
+ Dictionary d;
+ Map<StringName, Variant>::Element *E = p_options.front();
+ while (E) {
+ d[E->key()] = E->get();
+ E = E->next();
+ }
+ return get_script_instance()->call("get_option_visibility", p_option, d);
+}
+
+Error EditorImportPlugin::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) {
+
+ ERR_FAIL_COND_V(!(get_script_instance() && get_script_instance()->has_method("import")), ERR_UNAVAILABLE);
+ Dictionary options;
+ Array platform_variants, gen_files;
+
+ Map<StringName, Variant>::Element *E = p_options.front();
+ while (E) {
+ options[E->key()] = E->get();
+ E = E->next();
+ }
+ Error err = (Error)get_script_instance()->call("import", p_source_file, p_save_path, options, platform_variants, gen_files).operator int64_t();
+
+ for (int i = 0; i < platform_variants.size(); i++) {
+ r_platform_variants->push_back(platform_variants[i]);
+ }
+ for (int i = 0; i < gen_files.size(); i++) {
+ r_gen_files->push_back(gen_files[i]);
+ }
+ return err;
+}
+
+void EditorImportPlugin::_bind_methods() {
+
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_importer_name"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_visible_name"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "get_preset_count"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_preset_name", PropertyInfo(Variant::INT, "preset")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::ARRAY, "get_recognized_extensions"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::ARRAY, "get_import_options", PropertyInfo(Variant::INT, "preset")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_save_extension"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::STRING, "get_resource_type"));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::BOOL, "get_option_visibility", PropertyInfo(Variant::STRING, "option"), PropertyInfo(Variant::DICTIONARY, "options")));
+ ClassDB::add_virtual_method(get_class_static(), MethodInfo(Variant::INT, "import", PropertyInfo(Variant::STRING, "source_file"), PropertyInfo(Variant::STRING, "save_path"), PropertyInfo(Variant::DICTIONARY, "options"), PropertyInfo(Variant::ARRAY, "r_platform_variants"), PropertyInfo(Variant::ARRAY, "r_gen_files")));
+}
diff --git a/scene/3d/quad.h b/editor/import/editor_import_plugin.h
index bb6c1219ad..3c16b79713 100644
--- a/scene/3d/quad.h
+++ b/editor/import/editor_import_plugin.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* quad.h */
+/* editor_import_plugin.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,50 +27,28 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef QUAD_H
-#define QUAD_H
+#ifndef EDITOR_IMPORT_PLUGIN_H
+#define EDITOR_IMPORT_PLUGIN_H
-#include "rid.h"
-#include "scene/3d/visual_instance.h"
-
-class Quad : public GeometryInstance {
-
- GDCLASS(Quad, GeometryInstance);
-
- Vector3::Axis axis;
- bool centered;
- Vector2 offset;
- Vector2 size;
-
- Rect3 aabb;
- bool configured;
- bool pending_update;
- RID mesh;
-
- void _update();
+#include "io/resource_import.h"
+class EditorImportPlugin : public ResourceImporter {
+ GDCLASS(EditorImportPlugin, Reference)
protected:
- void _notification(int p_what);
static void _bind_methods();
public:
- void set_axis(Vector3::Axis p_axis);
- Vector3::Axis get_axis() const;
-
- void set_size(const Vector2 &p_sizze);
- Vector2 get_size() const;
-
- void set_offset(const Vector2 &p_offset);
- Vector2 get_offset() const;
-
- void set_centered(bool p_enabled);
- bool is_centered() const;
-
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
- virtual Rect3 get_aabb() const;
-
- Quad();
- ~Quad();
+ EditorImportPlugin();
+ 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_preset_name(int p_idx) const;
+ virtual int get_preset_count();
+ virtual String get_save_extension() const;
+ virtual String get_resource_type() const;
+ virtual void get_import_options(List<ImportOption> *r_options, int p_preset) 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);
};
-#endif // QUAD_H
+#endif //EDITOR_IMPORT_PLUGIN_H
diff --git a/editor/import/resource_importer_csv_translation.cpp b/editor/import/resource_importer_csv_translation.cpp
index ea43477dc3..9214b8f45e 100644
--- a/editor/import/resource_importer_csv_translation.cpp
+++ b/editor/import/resource_importer_csv_translation.cpp
@@ -54,7 +54,7 @@ String ResourceImporterCSVTranslation::get_save_extension() const {
String ResourceImporterCSVTranslation::get_resource_type() const {
- return "StreamCSVTranslation";
+ return "Translation";
}
bool ResourceImporterCSVTranslation::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
@@ -128,7 +128,7 @@ Error ResourceImporterCSVTranslation::import(const String &p_source_file, const
xlt = cxl;
}
- String save_path = p_source_file.get_basename() + "." + translations[i]->get_locale() + ".xl";
+ String save_path = p_source_file.get_basename() + "." + translations[i]->get_locale() + ".translation";
ResourceSaver::save(save_path, xlt);
if (r_gen_files) {
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index 19fd1208b9..1c5aa95ff1 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -33,7 +33,6 @@
#include "os/file_access.h"
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
-#include "scene/resources/surface_tool.h"
String ResourceImporterOBJ::get_importer_name() const {
@@ -49,12 +48,12 @@ void ResourceImporterOBJ::get_recognized_extensions(List<String> *p_extensions)
p_extensions->push_back("obj");
}
String ResourceImporterOBJ::get_save_extension() const {
- return "msh";
+ return "mesh";
}
String ResourceImporterOBJ::get_resource_type() const {
- return "Mesh";
+ return "ArrayMesh";
}
bool ResourceImporterOBJ::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
@@ -89,7 +88,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
FileAccessRef f = FileAccess::open(p_source_file, FileAccess::READ);
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
- Ref<Mesh> mesh = Ref<Mesh>(memnew(Mesh));
+ Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Map<String, Ref<Material> > name_map;
bool generate_normals = p_options["generate/normals"];
@@ -168,18 +167,23 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
if (face[idx].size() == 3) {
int norm = face[idx][2].to_int() - 1;
+ if (norm < 0)
+ norm += normals.size() + 1;
ERR_FAIL_INDEX_V(norm, normals.size(), ERR_PARSE_ERROR);
surf_tool->add_normal(normals[norm]);
}
if (face[idx].size() >= 2 && face[idx][1] != String()) {
-
int uv = face[idx][1].to_int() - 1;
+ if (uv < 0)
+ uv += uvs.size() + 1;
ERR_FAIL_INDEX_V(uv, uvs.size(), ERR_PARSE_ERROR);
surf_tool->add_uv(uvs[uv]);
}
int vtx = face[idx][0].to_int() - 1;
+ if (vtx < 0)
+ vtx += vertices.size() + 1;
ERR_FAIL_INDEX_V(vtx, vertices.size(), ERR_PARSE_ERROR);
Vector3 vertex = vertices[vtx];
@@ -239,7 +243,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
}
*/
- Error err = ResourceSaver::save(p_save_path + ".msh", mesh);
+ Error err = ResourceSaver::save(p_save_path + ".mesh", mesh);
return err;
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 755f4eb219..2409f6707d 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -137,7 +137,7 @@ static String _fixstr(const String &p_what, const String &p_str) {
return p_what;
}
-Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, Ref<Shape> > &collision_map) {
+Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map) {
// children first..
for (int i = 0; i < p_node->get_child_count(); i++) {
@@ -175,7 +175,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
mi->set_flag(GeometryInstance::FLAG_BILLBOARD, true);
if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -194,7 +194,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
if (m.is_valid()) {
@@ -275,7 +275,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for (int i = 0; i < m->get_surface_count(); i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -325,7 +325,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
/*if (mi->get_mesh().is_valid()) {
- Ref<Mesh> m = mi->get_mesh();
+ Ref<ArrayMesh> m = mi->get_mesh();
for(int i=0;i<m->get_surface_count();i++) {
Ref<SpatialMaterial> fm = m->surface_get_material(i);
@@ -477,7 +477,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
ERR_FAIL_COND_V(mesh.is_null(), NULL);
NavigationMeshInstance *nmi = memnew(NavigationMeshInstance);
@@ -655,7 +655,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
MeshInstance *mi = p_node->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
if (_teststr(mesh->get_name(), "col")) {
@@ -972,7 +972,7 @@ static String _make_extname(const String &p_str) {
return ext_name;
}
-void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<Mesh>, Ref<Mesh> > &p_meshes) {
+void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
List<PropertyInfo> pi;
@@ -987,7 +987,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_materials.has(mat)) {
- String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".mtl";
+ String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".material";
if (FileAccess::exists(ext_name)) {
//if exists, use it
Ref<Material> existing = ResourceLoader::load(ext_name);
@@ -1005,7 +1005,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
} else {
- Ref<Mesh> mesh = p_node->get(E->get().name);
+ Ref<ArrayMesh> mesh = p_node->get(E->get().name);
if (mesh.is_valid()) {
@@ -1015,10 +1015,10 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_meshes.has(mesh)) {
- String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".msh";
+ String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".mesh";
if (FileAccess::exists(ext_name)) {
//if exists, use it
- Ref<Mesh> existing = ResourceLoader::load(ext_name);
+ Ref<ArrayMesh> existing = ResourceLoader::load(ext_name);
p_meshes[mesh] = existing;
} else {
@@ -1040,7 +1040,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_materials.has(mat)) {
- String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".mtl";
+ String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".material";
if (FileAccess::exists(ext_name)) {
//if exists, use it
Ref<Material> existing = ResourceLoader::load(ext_name);
@@ -1059,7 +1059,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
}
if (!p_make_meshes) {
- p_meshes[mesh] = Ref<Mesh>(); //save it anyway, so it won't be checked again
+ p_meshes[mesh] = Ref<ArrayMesh>(); //save it anyway, so it won't be checked again
}
}
}
@@ -1192,7 +1192,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
float anim_optimizer_angerr = p_options["animation/optimizer/max_angular_error"];
float anim_optimizer_maxang = p_options["animation/optimizer/max_angle"];
- Map<Ref<Mesh>, Ref<Shape> > collision_map;
+ Map<Ref<ArrayMesh>, Ref<Shape> > collision_map;
scene = _fix_node(scene, scene, collision_map);
@@ -1230,7 +1230,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
if (external_materials || external_meshes) {
Map<Ref<Material>, Ref<Material> > mat_map;
- Map<Ref<Mesh>, Ref<Mesh> > mesh_map;
+ Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map;
_make_external_resources(scene, p_source_file.get_basename(), external_materials, external_meshes, mat_map, mesh_map);
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 9f7b1a84e6..ede3028b29 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -32,6 +32,7 @@
#include "io/resource_import.h"
#include "scene/resources/animation.h"
+#include "scene/resources/mesh.h"
#include "scene/resources/shape.h"
class Material;
@@ -100,9 +101,9 @@ public:
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;
- void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<Mesh>, Ref<Mesh> > &p_meshes);
+ void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
- Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, Ref<Shape> > &collision_map);
+ Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<ArrayMesh>, Ref<Shape> > &collision_map);
void _create_clips(Node *scene, const Array &p_clips, bool p_bake_all);
void _filter_anim_tracks(Ref<Animation> anim, Set<String> &keep);
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index f0dcc4a298..41b2353ed3 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -66,6 +66,22 @@ void ResourceImporterTexture::_texture_reimport_3d(const Ref<StreamTexture> &p_t
singleton->mutex->unlock();
}
+void ResourceImporterTexture::_texture_reimport_normal(const Ref<StreamTexture> &p_tex) {
+
+ singleton->mutex->lock();
+ StringName path = p_tex->get_path();
+
+ if (!singleton->make_flags.has(path)) {
+ singleton->make_flags[path] = 0;
+ }
+
+ singleton->make_flags[path] |= MAKE_NORMAL_FLAG;
+
+ print_line("requesting normalfor " + String(path));
+
+ singleton->mutex->unlock();
+}
+
void ResourceImporterTexture::update_imports() {
if (EditorFileSystem::get_singleton()->is_scanning() || EditorFileSystem::get_singleton()->is_importing()) {
@@ -96,6 +112,11 @@ void ResourceImporterTexture::update_imports() {
changed = true;
}
+ if (E->get() & MAKE_NORMAL_FLAG && int(cf->get_value("params", "compress/normal_map")) == 0) {
+ cf->set_value("params", "compress/normal_map", 1);
+ changed = true;
+ }
+
if (E->get() & MAKE_3D_FLAG && bool(cf->get_value("params", "detect_3d"))) {
cf->set_value("params", "detect_3d", false);
cf->set_value("params", "compress/mode", 2);
@@ -144,8 +165,12 @@ String ResourceImporterTexture::get_resource_type() const {
bool ResourceImporterTexture::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const {
- if (p_option == "compress/lossy_quality" && int(p_options["compress/mode"]) != COMPRESS_LOSSY)
- return false;
+ if (p_option == "compress/lossy_quality") {
+ int compress_mode = int(p_options["compress/mode"]);
+ if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VIDEO_RAM) {
+ return false;
+ }
+ }
return true;
}
@@ -169,6 +194,8 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,Video RAM,Uncompressed", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_mode", PROPERTY_HINT_ENUM, "Compress,Force RGBE"), 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/repeat", PROPERTY_HINT_ENUM, "Disabled,Enabled,Mirrored"), p_preset == PRESET_3D ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/filter"), p_preset == PRESET_2D_PIXEL ? false : true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "flags/mipmaps"), p_preset == PRESET_3D ? true : false));
@@ -176,21 +203,23 @@ void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "flags/srgb", PROPERTY_HINT_ENUM, "Disable,Enable,Detect"), 2));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/fix_alpha_border"), p_preset != PRESET_3D ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/premult_alpha"), true));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "process/HDR_as_SRGB"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "stream"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "size_limit", PROPERTY_HINT_RANGE, "0,4096,1"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "detect_3d"), p_preset == PRESET_DETECT));
}
-void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb) {
+void ResourceImporterTexture::_save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal) {
+ print_line("saving: " + p_to_path);
FileAccess *f = FileAccess::open(p_to_path, FileAccess::WRITE);
f->store_8('G');
f->store_8('D');
f->store_8('S');
f->store_8('T'); //godot streamable texture
- f->store_32(p_image.get_width());
- f->store_32(p_image.get_height());
+ f->store_32(p_image->get_width());
+ f->store_32(p_image->get_height());
f->store_32(p_texture_flags);
uint32_t format = 0;
@@ -203,18 +232,24 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
format |= StreamTexture::FORMAT_BIT_DETECT_3D;
if (p_detect_srgb)
format |= StreamTexture::FORMAT_BIT_DETECT_SRGB;
+ if (p_detect_normal)
+ format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL;
+
+ if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) {
+ p_compress_mode == COMPRESS_UNCOMPRESSED; //these can't go as lossy
+ }
switch (p_compress_mode) {
case COMPRESS_LOSSLESS: {
- Image image = p_image;
+ Ref<Image> image = p_image->duplicate();
if (p_mipmaps) {
- image.generate_mipmaps();
+ image->generate_mipmaps();
} else {
- image.clear_mipmaps();
+ image->clear_mipmaps();
}
- int mmc = image.get_mipmap_count() + 1;
+ int mmc = image->get_mipmap_count() + 1;
format |= StreamTexture::FORMAT_BIT_LOSSLESS;
f->store_32(format);
@@ -223,7 +258,7 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
for (int i = 0; i < mmc; i++) {
if (i > 0) {
- image.shrink_x2();
+ image->shrink_x2();
}
PoolVector<uint8_t> data = Image::lossless_packer(image);
@@ -236,14 +271,14 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
} break;
case COMPRESS_LOSSY: {
- Image image = p_image;
+ Ref<Image> image = p_image->duplicate();
if (p_mipmaps) {
- image.generate_mipmaps();
+ image->generate_mipmaps();
} else {
- image.clear_mipmaps();
+ image->clear_mipmaps();
}
- int mmc = image.get_mipmap_count() + 1;
+ int mmc = image->get_mipmap_count() + 1;
format |= StreamTexture::FORMAT_BIT_LOSSY;
f->store_32(format);
@@ -252,7 +287,7 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
for (int i = 0; i < mmc; i++) {
if (i > 0) {
- image.shrink_x2();
+ image->shrink_x2();
}
PoolVector<uint8_t> data = Image::lossy_packer(image, p_lossy_quality);
@@ -265,33 +300,44 @@ void ResourceImporterTexture::_save_stex(const Image &p_image, const String &p_t
} break;
case COMPRESS_VIDEO_RAM: {
- Image image = p_image;
- image.generate_mipmaps();
- image.compress(p_vram_compression);
+ Ref<Image> image = p_image->duplicate();
+ image->generate_mipmaps();
- format |= image.get_format();
+ if (p_force_rgbe && image->get_format() >= Image::FORMAT_R8 && image->get_format() <= Image::FORMAT_RGBE9995) {
+ image->convert(Image::FORMAT_RGBE9995);
+ } else {
+ Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC;
+ if (p_force_normal) {
+ csource = Image::COMPRESS_SOURCE_NORMAL;
+ } else if (p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
+ csource = Image::COMPRESS_SOURCE_SRGB;
+ }
+
+ image->compress(p_vram_compression, csource, p_lossy_quality);
+ }
+
+ format |= image->get_format();
f->store_32(format);
- PoolVector<uint8_t> data = image.get_data();
+ PoolVector<uint8_t> data = image->get_data();
int dl = data.size();
PoolVector<uint8_t>::Read r = data.read();
f->store_buffer(r.ptr(), dl);
-
} break;
case COMPRESS_UNCOMPRESSED: {
- Image image = p_image;
+ Ref<Image> image = p_image->duplicate();
if (p_mipmaps) {
- image.generate_mipmaps();
+ image->generate_mipmaps();
} else {
- image.clear_mipmaps();
+ image->clear_mipmaps();
}
- format |= image.get_format();
+ format |= image->get_format();
f->store_32(format);
- PoolVector<uint8_t> data = image.get_data();
+ PoolVector<uint8_t> data = image->get_data();
int dl = data.size();
PoolVector<uint8_t>::Read r = data.read();
@@ -316,9 +362,13 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
bool premult_alpha = p_options["process/premult_alpha"];
bool stream = p_options["stream"];
int size_limit = p_options["size_limit"];
+ bool force_rgbe = int(p_options["compress/hdr_mode"]) == 1;
+ bool hdr_as_srgb = p_options["process/HDR_as_SRGB"];
+ int normal = p_options["compress/normal_map"];
- Image image;
- Error err = ImageLoader::load_image(p_source_file, &image);
+ Ref<Image> image;
+ image.instance();
+ Error err = ImageLoader::load_image(p_source_file, image, NULL, hdr_as_srgb);
if (err != OK)
return err;
@@ -336,46 +386,64 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
if (srgb == 1)
tex_flags |= Texture::FLAG_CONVERT_TO_LINEAR;
- if (size_limit > 0 && (image.get_width() > size_limit || image.get_height() > size_limit)) {
+ if (size_limit > 0 && (image->get_width() > size_limit || image->get_height() > size_limit)) {
//limit size
- if (image.get_width() >= image.get_height()) {
+ if (image->get_width() >= image->get_height()) {
int new_width = size_limit;
- int new_height = image.get_height() * new_width / image.get_width();
+ int new_height = image->get_height() * new_width / image->get_width();
- image.resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
+ image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
} else {
int new_height = size_limit;
- int new_width = image.get_width() * new_height / image.get_height();
+ int new_width = image->get_width() * new_height / image->get_height();
- image.resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
+ image->resize(new_width, new_height, Image::INTERPOLATE_CUBIC);
}
}
if (fix_alpha_border) {
- image.fix_alpha_edges();
+ image->fix_alpha_edges();
}
if (premult_alpha) {
- image.premultiply_alpha();
+ image->premultiply_alpha();
}
bool detect_3d = p_options["detect_3d"];
bool detect_srgb = srgb == 2;
+ bool detect_normal = normal == 0;
+ bool force_normal = normal == 1;
if (compress_mode == COMPRESS_VIDEO_RAM) {
//must import in all formats
//Android, GLES 2.x
- _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb);
- r_platform_variants->push_back("etc");
- //_save_stex(image,p_save_path+".etc2.stex",compress_mode,lossy,Image::COMPRESS_ETC2,mipmaps,tex_flags,stream);
- //r_platform_variants->push_back("etc2");
- _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb);
- r_platform_variants->push_back("s3tc");
+ if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_s3tc")) {
+
+ _save_stex(image, p_save_path + ".s3tc.stex", compress_mode, lossy, Image::COMPRESS_S3TC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+ r_platform_variants->push_back("s3tc");
+ }
+
+ if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_etc")) {
+ _save_stex(image, p_save_path + ".etc.stex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+ r_platform_variants->push_back("etc");
+ }
+
+ if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_etc2")) {
+
+ _save_stex(image, p_save_path + ".etc2.stex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+ r_platform_variants->push_back("etc2");
+ }
+
+ if (GlobalConfig::get_singleton()->get("rendering/vram_formats/use_pvrtc")) {
+
+ _save_stex(image, p_save_path + ".pvrtc.stex", compress_mode, lossy, Image::COMPRESS_PVRTC4, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
+ r_platform_variants->push_back("pvrtc");
+ }
} else {
//import normally
- _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_16BIT /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb);
+ _save_stex(image, p_save_path + ".stex", compress_mode, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, tex_flags, stream, detect_3d, detect_srgb, force_rgbe, detect_normal, force_normal);
}
return OK;
@@ -388,6 +456,7 @@ ResourceImporterTexture::ResourceImporterTexture() {
singleton = this;
StreamTexture::request_3d_callback = _texture_reimport_3d;
StreamTexture::request_srgb_callback = _texture_reimport_srgb;
+ StreamTexture::request_normal_callback = _texture_reimport_normal;
mutex = Mutex::create();
}
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index 196eb48469..31bd0f29b0 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -30,7 +30,9 @@
#ifndef RESOURCEIMPORTTEXTURE_H
#define RESOURCEIMPORTTEXTURE_H
+#include "image.h"
#include "io/resource_import.h"
+
class StreamTexture;
class ResourceImporterTexture : public ResourceImporter {
@@ -39,7 +41,8 @@ class ResourceImporterTexture : public ResourceImporter {
protected:
enum {
MAKE_3D_FLAG = 1,
- MAKE_SRGB_FLAG = 2
+ MAKE_SRGB_FLAG = 2,
+ MAKE_NORMAL_FLAG = 4
};
Mutex *mutex;
@@ -47,6 +50,7 @@ protected:
static void _texture_reimport_srgb(const Ref<StreamTexture> &p_tex);
static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
+ static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
static ResourceImporterTexture *singleton;
@@ -78,7 +82,7 @@ public:
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;
- void _save_stex(const Image &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb);
+ void _save_stex(const Ref<Image> &p_image, const String &p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal);
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);
diff --git a/editor/import/resource_importer_wav.cpp b/editor/import/resource_importer_wav.cpp
index 92c1aa47db..7841baa02e 100644
--- a/editor/import/resource_importer_wav.cpp
+++ b/editor/import/resource_importer_wav.cpp
@@ -48,7 +48,7 @@ void ResourceImporterWAV::get_recognized_extensions(List<String> *p_extensions)
p_extensions->push_back("wav");
}
String ResourceImporterWAV::get_save_extension() const {
- return "smp";
+ return "sample";
}
String ResourceImporterWAV::get_resource_type() const {
@@ -485,7 +485,7 @@ Error ResourceImporterWAV::import(const String &p_source_file, const String &p_s
sample->set_loop_end(loop_end);
sample->set_stereo(format_channels == 2);
- ResourceSaver::save(p_save_path + ".smp", sample);
+ ResourceSaver::save(p_save_path + ".sample", sample);
return OK;
}
diff --git a/editor/io_plugins/editor_font_import_plugin.cpp b/editor/io_plugins/editor_font_import_plugin.cpp
index fa66328887..9831e08cf1 100644
--- a/editor/io_plugins/editor_font_import_plugin.cpp
+++ b/editor/io_plugins/editor_font_import_plugin.cpp
@@ -533,16 +533,16 @@ class EditorFontImportDialog : public ConfirmationDialog {
return;
}
- if (dest->get_line_edit()->get_text().get_file()==".fnt") {
- dest->get_line_edit()->set_text(dest->get_line_edit()->get_text().get_base_dir() + "/" + source->get_line_edit()->get_text().get_file().get_basename() + ".fnt" );
+ if (dest->get_line_edit()->get_text().get_file()==".font") {
+ dest->get_line_edit()->set_text(dest->get_line_edit()->get_text().get_base_dir() + "/" + source->get_line_edit()->get_text().get_file().get_basename() + ".font" );
}
if (dest->get_line_edit()->get_text().get_extension() == dest->get_line_edit()->get_text()) {
- dest->get_line_edit()->set_text(dest->get_line_edit()->get_text() + ".fnt");
+ dest->get_line_edit()->set_text(dest->get_line_edit()->get_text() + ".font");
}
- if (dest->get_line_edit()->get_text().get_extension().to_lower() != "fnt") {
- error_dialog->set_text(TTR("Invalid file extension.\nPlease use .fnt."));
+ if (dest->get_line_edit()->get_text().get_extension().to_lower() != "font") {
+ error_dialog->set_text(TTR("Invalid file extension.\nPlease use .font."));
error_dialog->popup_centered(Size2(200,100));
return;
}
@@ -665,7 +665,7 @@ public:
//
List<String> fl;
Ref<BitmapFont> font= memnew(BitmapFont);
- dest->get_file_dialog()->add_filter("*.fnt ; Font" );
+ dest->get_file_dialog()->add_filter("*.font ; Font" );
/*
ResourceSaver::get_recognized_extensions(font,&fl);
for(List<String>::Element *E=fl.front();E;E=E->next()) {
@@ -1690,7 +1690,7 @@ void EditorFontImportPlugin::import_from_drop(const Vector<String>& p_drop, cons
if (ext=="ttf" || ext=="otf" || ext=="fnt") {
import_dialog();
- dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.get_basename()+".fnt"));
+ dialog->set_source_and_dest(p_drop[i],p_dest_path.plus_file(file.get_basename()+".font"));
break;
}
}
diff --git a/editor/io_plugins/editor_mesh_import_plugin.cpp b/editor/io_plugins/editor_mesh_import_plugin.cpp
index a8ecc2f10e..0c9f3a3f37 100644
--- a/editor/io_plugins/editor_mesh_import_plugin.cpp
+++ b/editor/io_plugins/editor_mesh_import_plugin.cpp
@@ -262,7 +262,7 @@ public:
imd->add_source(EditorImportPlugin::validate_source_path(meshes[i]));
- String file_path = dst.plus_file(meshes[i].get_file().get_basename()+".msh");
+ String file_path = dst.plus_file(meshes[i].get_file().get_basename()+".mesh");
plugin->import(file_path,imd);
}
diff --git a/editor/io_plugins/editor_sample_import_plugin.cpp b/editor/io_plugins/editor_sample_import_plugin.cpp
index 7836b60fde..0909b96cdc 100644
--- a/editor/io_plugins/editor_sample_import_plugin.cpp
+++ b/editor/io_plugins/editor_sample_import_plugin.cpp
@@ -299,7 +299,7 @@ public:
error_dialog->popup_centered(Size2(200,100)*EDSCALE);
}
- dst = dst.plus_file(samples[i].get_file().get_basename()+".smp");
+ dst = dst.plus_file(samples[i].get_file().get_basename()+".sample");
plugin->import(dst,imd);
}
@@ -910,13 +910,13 @@ Vector<uint8_t> EditorSampleExportPlugin::custom_export(String& p_path,const Ref
imd->set_option("edit/loop",false);
imd->set_option("compress/mode",1);
- String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.smp");
+ String savepath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/smpconv.sample");
Error err = EditorSampleImportPlugin::singleton->import(savepath,imd);
ERR_FAIL_COND_V(err!=OK,Vector<uint8_t>());
- p_path=p_path.get_basename()+".converted.smp";
+ p_path=p_path.get_basename()+".converted.sample";
return FileAccess::get_file_as_array(savepath);
}
diff --git a/editor/io_plugins/editor_texture_import_plugin.cpp b/editor/io_plugins/editor_texture_import_plugin.cpp
index d9b4a95045..d48675fa30 100644
--- a/editor/io_plugins/editor_texture_import_plugin.cpp
+++ b/editor/io_plugins/editor_texture_import_plugin.cpp
@@ -596,7 +596,7 @@ void EditorTextureImportDialog::_mode_changed(int p_mode) {
size->show();
file_select->set_mode(EditorFileDialog::MODE_OPEN_FILE);
- save_file_select->add_filter("*.ltex;"+TTR("Large Texture"));
+ save_file_select->add_filter("*.largetex;"+TTR("Large Texture"));
texture_options->set_flags(EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA|EditorTextureImportPlugin::IMAGE_FLAG_NO_MIPMAPS|EditorTextureImportPlugin::IMAGE_FLAG_FILTER);
texture_options->set_quality(0.7);
@@ -680,7 +680,7 @@ EditorTextureImportDialog::EditorTextureImportDialog(EditorTextureImportPlugin*
};
- mode_check[i]=memnew( CheckBox );
+ mode_check[i]=memnew(CheckBox);
bg->add_child(mode_check[i]);
mode_check[i]->set_text(mode_name[i]);
mode_check[i]->connect("pressed",this,"_mode_changed",varray(i));
@@ -1097,7 +1097,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
int cell_size=from->get_option("large_cell_size");
ERR_FAIL_COND_V(cell_size<128 || cell_size>16384,ERR_CANT_OPEN);
- EditorProgress pg("ltex",TTR("Import Large Texture"),3);
+ EditorProgress pg("largetex",TTR("Import Large Texture"),3);
pg.step(TTR("Load Source Image"),0);
Image img;
@@ -1317,9 +1317,9 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref<Resourc
String spath = from->get_source_path(E->get()).get_file();
if (p_external) {
- apath = p_path.get_base_dir().plus_file(spath.get_basename()+"."+from->get_source_path(E->get()).md5_text()+".atex");
+ apath = p_path.get_base_dir().plus_file(spath.get_basename()+"."+from->get_source_path(E->get()).md5_text()+".atlastex");
} else {
- apath = p_path.get_base_dir().plus_file(spath.get_basename()+".atex");
+ apath = p_path.get_base_dir().plus_file(spath.get_basename()+".atlastex");
}
Ref<AtlasTexture> at;
diff --git a/editor/io_plugins/editor_translation_import_plugin.cpp b/editor/io_plugins/editor_translation_import_plugin.cpp
index caa0659046..5b15b94006 100644
--- a/editor/io_plugins/editor_translation_import_plugin.cpp
+++ b/editor/io_plugins/editor_translation_import_plugin.cpp
@@ -258,7 +258,7 @@ public:
imd->set_option("skip_first",ignore_first->is_pressed());
imd->set_option("compress",compress->is_pressed());
- String savefile = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+"."+locale+".xl");
+ String savefile = save_path->get_text().plus_file(import_path->get_text().get_file().get_basename()+"."+locale+".translation");
Error err = plugin->import(savefile,imd);
if (err!=OK) {
error_dialog->set_text(TTR("Couldn't import!"));
diff --git a/editor/pane_drag.cpp b/editor/pane_drag.cpp
index 69a1f07fba..22b306f941 100644
--- a/editor/pane_drag.cpp
+++ b/editor/pane_drag.cpp
@@ -29,11 +29,12 @@
/*************************************************************************/
#include "pane_drag.h"
-void PaneDrag::_gui_input(const InputEvent &p_input) {
+void PaneDrag::_gui_input(const Ref<InputEvent> &p_input) {
- if (p_input.type == InputEvent::MOUSE_MOTION && p_input.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ Ref<InputEventMouseMotion> mm = p_input;
+ if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
- emit_signal("dragged", Point2(p_input.mouse_motion.relative_x, p_input.mouse_motion.relative_y));
+ emit_signal("dragged", Point2(mm->get_relative().x, mm->get_relative().y));
}
}
diff --git a/editor/pane_drag.h b/editor/pane_drag.h
index bd26621c83..0be017b8f7 100644
--- a/editor/pane_drag.h
+++ b/editor/pane_drag.h
@@ -34,12 +34,12 @@
class PaneDrag : public Control {
- GDCLASS(PaneDrag, Control);
+ GDCLASS(PaneDrag, Control)
bool mouse_over;
protected:
- void _gui_input(const InputEvent &p_input);
+ void _gui_input(const Ref<InputEvent> &p_input);
void _notification(int p_what);
virtual Size2 get_minimum_size() const;
static void _bind_methods();
diff --git a/editor/plugins/animation_player_editor_plugin.cpp b/editor/plugins/animation_player_editor_plugin.cpp
index b4398427f8..28c5b89741 100644
--- a/editor/plugins/animation_player_editor_plugin.cpp
+++ b/editor/plugins/animation_player_editor_plugin.cpp
@@ -51,7 +51,7 @@ void AnimationPlayerEditor::_node_removed(Node *p_node) {
}
}
-void AnimationPlayerEditor::_gui_input(InputEvent p_event) {
+void AnimationPlayerEditor::_gui_input(Ref<InputEvent> p_event) {
}
void AnimationPlayerEditor::_notification(int p_what) {
@@ -118,7 +118,14 @@ void AnimationPlayerEditor::_notification(int p_what) {
blend_editor.next->connect("item_selected", this, "_blend_editor_next_changed");
- // nodename->set_icon(get_icon("AnimationPlayer", "EditorIcons"));
+ /*
+ anim_editor_load->set_normal_texture( get_icon("AnimGet","EditorIcons"));
+ anim_editor_store->set_normal_texture( get_icon("AnimSet","EditorIcons"));
+ anim_editor_load->set_pressed_texture( get_icon("AnimGet","EditorIcons"));
+ anim_editor_store->set_pressed_texture( get_icon("AnimSet","EditorIcons"));
+ anim_editor_load->set_hover_texture( get_icon("AnimGetHl","EditorIcons"));
+ anim_editor_store->set_hover_texture( get_icon("AnimSetHl","EditorIcons"));
+*/
get_tree()->connect("node_removed", this, "_node_removed");
}
@@ -781,10 +788,6 @@ void AnimationPlayerEditor::_update_player() {
player->get_animation_list(&animlist);
animation->clear();
- if (player)
- nodename->set_text(player->get_name());
- else
- nodename->set_text(TTR("No player selected"));
add_anim->set_disabled(player == NULL);
load_anim->set_disabled(player == NULL);
@@ -1157,14 +1160,15 @@ void AnimationPlayerEditor::_animation_save_menu(int p_option) {
}
}
-void AnimationPlayerEditor::_unhandled_key_input(const InputEvent &p_ev) {
+void AnimationPlayerEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
- if (is_visible_in_tree() && p_ev.type == InputEvent::KEY && p_ev.key.pressed && !p_ev.key.echo && !p_ev.key.mod.alt && !p_ev.key.mod.control && !p_ev.key.mod.meta) {
+ Ref<InputEventKey> k = p_ev;
+ if (is_visible_in_tree() && k.is_valid() && k->is_pressed() && !k->is_echo() && !k->get_alt() && !k->get_control() && !k->get_metakey()) {
- switch (p_ev.key.scancode) {
+ switch (k->get_scancode()) {
case KEY_A: {
- if (!p_ev.key.mod.shift)
+ if (!k->get_shift())
_play_bw_from_pressed();
else
_play_bw_pressed();
@@ -1173,7 +1177,7 @@ void AnimationPlayerEditor::_unhandled_key_input(const InputEvent &p_ev) {
_stop_pressed();
} break;
case KEY_D: {
- if (!p_ev.key.mod.shift)
+ if (!k->get_shift())
_play_from_pressed();
else
_play_pressed();
@@ -1358,14 +1362,7 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
//tool_anim->get_popup()->add_item("Edit Anim Resource",TOOL_PASTE_ANIM);
hb->add_child(tool_anim);
- hb->add_child(memnew(VSeparator));
- nodename_icon = memnew(TextureRect);
- nodename_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
- hb->add_child(nodename_icon);
- nodename = memnew(Label);
- hb->add_child(nodename);
pin = memnew(ToolButton);
- pin->set_tooltip(TTR("Keep this animation selected?"));
pin->set_toggle_mode(true);
hb->add_child(pin);
@@ -1380,19 +1377,18 @@ AnimationPlayerEditor::AnimationPlayerEditor(EditorNode *p_editor) {
name_dialog->set_title(TTR("Create New Animation"));
name_dialog->set_hide_on_ok(false);
add_child(name_dialog);
- name = memnew(LineEdit);
- name_dialog->add_child(name);
- name->set_position(Point2(18, 30));
- name->set_anchor_and_margin(MARGIN_RIGHT, ANCHOR_END, 10);
- name_dialog->register_text_enter(name);
+ VBoxContainer *vb = memnew(VBoxContainer);
+ name_dialog->add_child(vb);
l = memnew(Label);
l->set_text(TTR("Animation Name:"));
- l->set_position(Point2(10, 10));
-
- name_dialog->add_child(l);
+ vb->add_child(l);
name_title = l;
+ name = memnew(LineEdit);
+ vb->add_child(name);
+ name_dialog->register_text_enter(name);
+
error_dialog = memnew(ConfirmationDialog);
error_dialog->get_ok()->set_text(TTR("Close"));
//error_dialog->get_cancel()->set_text("Close");
diff --git a/editor/plugins/animation_player_editor_plugin.h b/editor/plugins/animation_player_editor_plugin.h
index d80f9dccf2..ceaa73569a 100644
--- a/editor/plugins/animation_player_editor_plugin.h
+++ b/editor/plugins/animation_player_editor_plugin.h
@@ -85,8 +85,6 @@ class AnimationPlayerEditor : public VBoxContainer {
Button *remove_anim;
MenuButton *tool_anim;
ToolButton *pin;
- Label *nodename;
- TextureRect *nodename_icon;
SpinBox *frame;
LineEdit *scale;
LineEdit *name;
@@ -160,7 +158,7 @@ class AnimationPlayerEditor : public VBoxContainer {
void _animation_key_editor_anim_len_changed(float p_new);
void _animation_key_editor_anim_step_changed(float p_len);
- void _unhandled_key_input(const InputEvent &p_ev);
+ void _unhandled_key_input(const Ref<InputEvent> &p_ev);
void _animation_tool_menu(int p_option);
void _animation_save_menu(int p_option);
@@ -168,7 +166,7 @@ class AnimationPlayerEditor : public VBoxContainer {
protected:
void _notification(int p_what);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
void _node_removed(Node *p_node);
static void _bind_methods();
diff --git a/editor/plugins/animation_tree_editor_plugin.cpp b/editor/plugins/animation_tree_editor_plugin.cpp
index e126cdf40f..d67832e10b 100644
--- a/editor/plugins/animation_tree_editor_plugin.cpp
+++ b/editor/plugins/animation_tree_editor_plugin.cpp
@@ -735,139 +735,139 @@ void AnimationTreeEditor::_node_edit_property(const StringName& p_node) {
}
#endif
-void AnimationTreeEditor::_gui_input(InputEvent p_event) {
+void AnimationTreeEditor::_gui_input(Ref<InputEvent> p_event) {
- switch (p_event.type) {
+ Ref<InputEventMouseButton> mb = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
- if (p_event.mouse_button.pressed) {
+ if (mb->is_pressed()) {
- if (p_event.mouse_button.button_index == 1) {
- click_pos = Point2(p_event.mouse_button.x, p_event.mouse_button.y);
- click_motion = click_pos;
- click_type = _locate_click(click_pos, &click_node, &click_slot);
- if (click_type != CLICK_NONE) {
+ if (mb->get_button_index() == 1) {
+ click_pos = Point2(mb->get_position().x, mb->get_position().y);
+ click_motion = click_pos;
+ click_type = _locate_click(click_pos, &click_node, &click_slot);
+ if (click_type != CLICK_NONE) {
- order.erase(click_node);
- order.push_back(click_node);
- update();
- }
+ order.erase(click_node);
+ order.push_back(click_node);
+ update();
+ }
- switch (click_type) {
- case CLICK_INPUT_SLOT: {
- click_pos = _get_slot_pos(click_node, true, click_slot);
- } break;
- case CLICK_OUTPUT_SLOT: {
- click_pos = _get_slot_pos(click_node, false, click_slot);
- } break;
- case CLICK_PARAMETER: {
-
- edited_node = click_node;
- renaming_edit = false;
- _popup_edit_dialog();
- //open editor
- //_node_edit_property(click_node);
- } break;
- default: {}
- }
+ switch (click_type) {
+ case CLICK_INPUT_SLOT: {
+ click_pos = _get_slot_pos(click_node, true, click_slot);
+ } break;
+ case CLICK_OUTPUT_SLOT: {
+ click_pos = _get_slot_pos(click_node, false, click_slot);
+ } break;
+ case CLICK_PARAMETER: {
+
+ edited_node = click_node;
+ renaming_edit = false;
+ _popup_edit_dialog();
+ //open editor
+ //_node_edit_property(click_node);
+ } break;
+ default: {}
}
- if (p_event.mouse_button.button_index == 2) {
-
- if (click_type != CLICK_NONE) {
- click_type = CLICK_NONE;
- update();
- } else {
- // try to disconnect/remove
-
- Point2 rclick_pos = Point2(p_event.mouse_button.x, p_event.mouse_button.y);
- rclick_type = _locate_click(rclick_pos, &rclick_node, &rclick_slot);
- if (rclick_type == CLICK_INPUT_SLOT || rclick_type == CLICK_OUTPUT_SLOT) {
-
- node_popup->clear();
- node_popup->add_item(TTR("Disconnect"), NODE_DISCONNECT);
- if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) {
- node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT);
- if (rclick_type == CLICK_INPUT_SLOT) {
- if (anim_tree->transition_node_has_input_auto_advance(rclick_node, rclick_slot))
- node_popup->add_item(TTR("Clear Auto-Advance"), NODE_CLEAR_AUTOADVANCE);
- else
- node_popup->add_item(TTR("Set Auto-Advance"), NODE_SET_AUTOADVANCE);
- node_popup->add_item(TTR("Delete Input"), NODE_DELETE_INPUT);
- }
- }
+ }
+ if (mb->get_button_index() == 2) {
- node_popup->set_position(rclick_pos + get_global_position());
- node_popup->popup();
+ if (click_type != CLICK_NONE) {
+ click_type = CLICK_NONE;
+ update();
+ } else {
+ // try to disconnect/remove
+
+ Point2 rclick_pos = Point2(mb->get_position().x, mb->get_position().y);
+ rclick_type = _locate_click(rclick_pos, &rclick_node, &rclick_slot);
+ if (rclick_type == CLICK_INPUT_SLOT || rclick_type == CLICK_OUTPUT_SLOT) {
+
+ node_popup->clear();
+ node_popup->add_item(TTR("Disconnect"), NODE_DISCONNECT);
+ if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION) {
+ node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT);
+ if (rclick_type == CLICK_INPUT_SLOT) {
+ if (anim_tree->transition_node_has_input_auto_advance(rclick_node, rclick_slot))
+ node_popup->add_item(TTR("Clear Auto-Advance"), NODE_CLEAR_AUTOADVANCE);
+ else
+ node_popup->add_item(TTR("Set Auto-Advance"), NODE_SET_AUTOADVANCE);
+ node_popup->add_item(TTR("Delete Input"), NODE_DELETE_INPUT);
+ }
}
- if (rclick_type == CLICK_NODE) {
- node_popup->clear();
- node_popup->add_item(TTR("Rename"), NODE_RENAME);
- node_popup->add_item(TTR("Remove"), NODE_ERASE);
- if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION)
- node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT);
- node_popup->set_position(rclick_pos + get_global_position());
- node_popup->popup();
- }
+ node_popup->set_position(rclick_pos + get_global_position());
+ node_popup->popup();
}
- }
- } else {
- if (p_event.mouse_button.button_index == 1 && click_type != CLICK_NONE) {
+ if (rclick_type == CLICK_NODE) {
+ node_popup->clear();
+ node_popup->add_item(TTR("Rename"), NODE_RENAME);
+ node_popup->add_item(TTR("Remove"), NODE_ERASE);
+ if (anim_tree->node_get_type(rclick_node) == AnimationTreePlayer::NODE_TRANSITION)
+ node_popup->add_item(TTR("Add Input"), NODE_ADD_INPUT);
+ node_popup->set_position(rclick_pos + get_global_position());
+ node_popup->popup();
+ }
+ }
+ }
+ } else {
- switch (click_type) {
- case CLICK_INPUT_SLOT:
- case CLICK_OUTPUT_SLOT: {
+ if (mb->get_button_index() == 1 && click_type != CLICK_NONE) {
- Point2 dst_click_pos = Point2(p_event.mouse_button.x, p_event.mouse_button.y);
- StringName id;
- int slot;
- ClickType dst_click_type = _locate_click(dst_click_pos, &id, &slot);
+ switch (click_type) {
+ case CLICK_INPUT_SLOT:
+ case CLICK_OUTPUT_SLOT: {
- if (dst_click_type == CLICK_INPUT_SLOT && click_type == CLICK_OUTPUT_SLOT) {
+ Point2 dst_click_pos = Point2(mb->get_position().x, mb->get_position().y);
+ StringName id;
+ int slot;
+ ClickType dst_click_type = _locate_click(dst_click_pos, &id, &slot);
- anim_tree->connect_nodes(click_node, id, slot);
- }
- if (click_type == CLICK_INPUT_SLOT && dst_click_type == CLICK_OUTPUT_SLOT) {
+ if (dst_click_type == CLICK_INPUT_SLOT && click_type == CLICK_OUTPUT_SLOT) {
- anim_tree->connect_nodes(id, click_node, click_slot);
- }
+ anim_tree->connect_nodes(click_node, id, slot);
+ }
+ if (click_type == CLICK_INPUT_SLOT && dst_click_type == CLICK_OUTPUT_SLOT) {
- } break;
- case CLICK_NODE: {
- Point2 new_pos = anim_tree->node_get_pos(click_node) + (click_motion - click_pos);
- if (new_pos.x < 5)
- new_pos.x = 5;
- if (new_pos.y < 5)
- new_pos.y = 5;
- anim_tree->node_set_pos(click_node, new_pos);
-
- } break;
- default: {}
- }
+ anim_tree->connect_nodes(id, click_node, click_slot);
+ }
- click_type = CLICK_NONE;
- update();
+ } break;
+ case CLICK_NODE: {
+ Point2 new_pos = anim_tree->node_get_pos(click_node) + (click_motion - click_pos);
+ if (new_pos.x < 5)
+ new_pos.x = 5;
+ if (new_pos.y < 5)
+ new_pos.y = 5;
+ anim_tree->node_set_pos(click_node, new_pos);
+
+ } break;
+ default: {}
}
+
+ click_type = CLICK_NONE;
+ update();
}
}
+ }
- case InputEvent::MOUSE_MOTION: {
+ Ref<InputEventMouseMotion> mm = p_event;
- if (p_event.mouse_motion.button_mask & 1 && click_type != CLICK_NONE) {
+ if (mm.is_valid()) {
- click_motion = Point2(p_event.mouse_button.x, p_event.mouse_button.y);
- update();
- }
- if ((p_event.mouse_motion.button_mask & 4 || Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
+ if (mm->get_button_mask() & 1 && click_type != CLICK_NONE) {
- h_scroll->set_value(h_scroll->get_value() - p_event.mouse_motion.relative_x);
- v_scroll->set_value(v_scroll->get_value() - p_event.mouse_motion.relative_y);
- update();
- }
+ click_motion = Point2(mm->get_position().x, mm->get_position().y);
+ update();
+ }
+ if ((mm->get_button_mask() & 4 || Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
- } break;
+ h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
+ v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
+ update();
+ }
}
}
@@ -876,7 +876,7 @@ void AnimationTreeEditor::_draw_cos_line(const Vector2 &p_from, const Vector2 &p
static const int steps = 20;
Rect2 r;
- r.pos = p_from;
+ r.position = p_from;
r.expand_to(p_to);
Vector2 sign = Vector2((p_from.x < p_to.x) ? 1 : -1, (p_from.y < p_to.y) ? 1 : -1);
bool flip = sign.x * sign.y < 0;
@@ -888,7 +888,7 @@ void AnimationTreeEditor::_draw_cos_line(const Vector2 &p_from, const Vector2 &p
float c = -Math::cos(d * Math_PI) * 0.5 + 0.5;
if (flip)
c = 1.0 - c;
- Vector2 p = r.pos + Vector2(d * r.size.width, c * r.size.height);
+ Vector2 p = r.position + Vector2(d * r.size.width, c * r.size.height);
if (i > 0) {
diff --git a/editor/plugins/animation_tree_editor_plugin.h b/editor/plugins/animation_tree_editor_plugin.h
index 8bbe22387b..785f042dd9 100644
--- a/editor/plugins/animation_tree_editor_plugin.h
+++ b/editor/plugins/animation_tree_editor_plugin.h
@@ -155,7 +155,7 @@ class AnimationTreeEditor : public Control {
protected:
void _notification(int p_what);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
public:
diff --git a/editor/plugins/baked_light_baker.h b/editor/plugins/baked_light_baker.h
index 5f32e236c0..123812fc07 100644
--- a/editor/plugins/baked_light_baker.h
+++ b/editor/plugins/baked_light_baker.h
@@ -31,7 +31,7 @@
#define BAKED_LIGHT_BAKER_H
#include "os/thread.h"
-#include "scene/3d/baked_light_instance.h"
+
#include "scene/3d/light.h"
#include "scene/3d/mesh_instance.h"
diff --git a/editor/plugins/canvas_item_editor_plugin.cpp b/editor/plugins/canvas_item_editor_plugin.cpp
index 430a5adeb1..803e59469c 100644
--- a/editor/plugins/canvas_item_editor_plugin.cpp
+++ b/editor/plugins/canvas_item_editor_plugin.cpp
@@ -204,17 +204,19 @@ void CanvasItemEditor::_edit_set_pivot(const Vector2 &mouse_pos) {
undo_redo->commit_action();
}
-void CanvasItemEditor::_unhandled_key_input(const InputEvent &p_ev) {
+void CanvasItemEditor::_unhandled_key_input(const Ref<InputEvent> &p_ev) {
+
+ Ref<InputEventKey> k = p_ev;
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
return;
- if (p_ev.key.mod.control)
+ if (k->get_control())
return;
- if (p_ev.key.pressed && !p_ev.key.echo && p_ev.key.scancode == KEY_V && drag == DRAG_NONE && can_move_pivot) {
+ if (k->is_pressed() && !k->is_echo() && k->get_scancode() == KEY_V && drag == DRAG_NONE && can_move_pivot) {
- if (p_ev.key.mod.shift) {
+ if (k->get_shift()) {
//move drag pivot
drag = DRAG_PIVOT;
} else if (!Input::get_singleton()->is_mouse_button_pressed(0)) {
@@ -534,10 +536,10 @@ void CanvasItemEditor::_find_canvas_items_at_rect(const Rect2 &p_rect, Node *p_n
Rect2 rect = c->get_item_rect();
Transform2D xform = p_parent_xform * p_canvas_xform * c->get_transform();
- if (p_rect.has_point(xform.xform(rect.pos)) &&
- p_rect.has_point(xform.xform(rect.pos + Vector2(rect.size.x, 0))) &&
- p_rect.has_point(xform.xform(rect.pos + Vector2(rect.size.x, rect.size.y))) &&
- p_rect.has_point(xform.xform(rect.pos + Vector2(0, rect.size.y)))) {
+ if (p_rect.has_point(xform.xform(rect.position)) &&
+ p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, 0))) &&
+ p_rect.has_point(xform.xform(rect.position + Vector2(rect.size.x, rect.size.y))) &&
+ p_rect.has_point(xform.xform(rect.position + Vector2(0, rect.size.y)))) {
r_items->push_back(c);
}
@@ -650,7 +652,7 @@ void CanvasItemEditor::_key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE
// drag = transform.affine_inverse().basis_xform(p_dir); // zoom sensitive
drag = canvas_item->get_global_transform_with_canvas().affine_inverse().basis_xform(drag);
Rect2 local_rect = canvas_item->get_item_rect();
- local_rect.pos += drag;
+ local_rect.position += drag;
undo_redo->add_do_method(canvas_item, "edit_set_rect", local_rect);
} else { // p_move_mode==MOVE_LOCAL_BASE || p_move_mode==MOVE_LOCAL_WITH_ROT
@@ -678,7 +680,7 @@ Point2 CanvasItemEditor::_find_topleftmost_point() {
Vector2 tl = Point2(1e10, 1e10);
Rect2 r2;
- r2.pos = tl;
+ r2.position = tl;
List<Node *> &selection = editor_selection->get_selected_node_list();
@@ -693,13 +695,13 @@ Point2 CanvasItemEditor::_find_topleftmost_point() {
Rect2 rect = canvas_item->get_item_rect();
Transform2D xform = canvas_item->get_global_transform_with_canvas();
- r2.expand_to(xform.xform(rect.pos));
- r2.expand_to(xform.xform(rect.pos + Vector2(rect.size.x, 0)));
- r2.expand_to(xform.xform(rect.pos + rect.size));
- r2.expand_to(xform.xform(rect.pos + Vector2(0, rect.size.y)));
+ r2.expand_to(xform.xform(rect.position));
+ r2.expand_to(xform.xform(rect.position + Vector2(rect.size.x, 0)));
+ r2.expand_to(xform.xform(rect.position + rect.size));
+ r2.expand_to(xform.xform(rect.position + Vector2(0, rect.size.y)));
}
- return r2.pos;
+ return r2.position;
}
int CanvasItemEditor::get_item_count() {
@@ -757,18 +759,18 @@ CanvasItemEditor::DragType CanvasItemEditor::_find_drag_type(const Transform2D &
Vector2 endpoints[4] = {
- xform.xform(rect.pos),
- xform.xform(rect.pos + Vector2(rect.size.x, 0)),
- xform.xform(rect.pos + rect.size),
- xform.xform(rect.pos + Vector2(0, rect.size.y))
+ xform.xform(rect.position),
+ xform.xform(rect.position + Vector2(rect.size.x, 0)),
+ xform.xform(rect.position + rect.size),
+ xform.xform(rect.position + Vector2(0, rect.size.y))
};
Vector2 endpointsl[4] = {
- xforml.xform(rect.pos),
- xforml.xform(rect.pos + Vector2(rect.size.x, 0)),
- xforml.xform(rect.pos + rect.size),
- xforml.xform(rect.pos + Vector2(0, rect.size.y))
+ xforml.xform(rect.position),
+ xforml.xform(rect.position + Vector2(rect.size.x, 0)),
+ xforml.xform(rect.position + rect.size),
+ xforml.xform(rect.position + Vector2(0, rect.size.y))
};
DragType dragger[] = {
@@ -958,9 +960,9 @@ bool CanvasItemEditor::get_remove_list(List<Node *> *p_list) {
return false; //!p_list->empty();
}
-void CanvasItemEditor::_list_select(const InputEventMouseButton &b) {
+void CanvasItemEditor::_list_select(const Ref<InputEventMouseButton> &b) {
- Point2 click = Point2(b.x, b.y);
+ Point2 click = b->get_position();
Node *scene = editor->get_edited_scene();
if (!scene)
@@ -982,7 +984,7 @@ void CanvasItemEditor::_list_select(const InputEventMouseButton &b) {
CanvasItem *item = selection_results[0].item;
selection_results.clear();
- additive_selection = b.mod.shift;
+ additive_selection = b->get_shift();
if (!_select(item, click, additive_selection, false))
return;
@@ -1008,13 +1010,12 @@ void CanvasItemEditor::_list_select(const InputEventMouseButton &b) {
selection_menu->add_item(item->get_name());
selection_menu->set_item_icon(i, icon);
selection_menu->set_item_metadata(i, node_path);
- selection_menu->set_item_tooltip(i, String(item->get_name()) +
- "\nType: " + item->get_class() + "\nPath: " + node_path);
+ selection_menu->set_item_tooltip(i, String(item->get_name()) + "\nType: " + item->get_class() + "\nPath: " + node_path);
}
- additive_selection = b.mod.shift;
+ additive_selection = b->get_shift();
- selection_menu->set_global_position(Vector2(b.global_x, b.global_y));
+ selection_menu->set_global_position(b->get_global_position());
selection_menu->popup();
selection_menu->call_deferred("grab_click_focus");
selection_menu->set_invalidate_click_until_motion();
@@ -1023,7 +1024,7 @@ void CanvasItemEditor::_list_select(const InputEventMouseButton &b) {
}
}
-void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
+void CanvasItemEditor::_viewport_gui_input(const Ref<InputEvent> &p_event) {
{
@@ -1039,40 +1040,53 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> b = p_event;
- const InputEventMouseButton &b = p_event.mouse_button;
+ if (b.is_valid()) {
- if (b.button_index == BUTTON_WHEEL_DOWN) {
+ if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
- if (zoom < MIN_ZOOM)
- return;
+ if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+
+ v_scroll->set_value(v_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
+
+ } else {
+
+ if (zoom < MIN_ZOOM)
+ return;
- float prev_zoom = zoom;
- zoom = zoom * 0.95;
- {
- Point2 ofs(b.x, b.y);
- ofs = ofs / prev_zoom - ofs / zoom;
- h_scroll->set_value(h_scroll->get_value() + ofs.x);
- v_scroll->set_value(v_scroll->get_value() + ofs.y);
+ float prev_zoom = zoom;
+ zoom = zoom * (1 - (0.05 * b->get_factor()));
+ {
+ Point2 ofs = b->get_position();
+ ofs = ofs / prev_zoom - ofs / zoom;
+ h_scroll->set_value(h_scroll->get_value() + ofs.x);
+ v_scroll->set_value(v_scroll->get_value() + ofs.y);
+ }
}
+
_update_scroll(0);
viewport->update();
return;
}
- if (b.button_index == BUTTON_WHEEL_UP) {
+ if (b->get_button_index() == BUTTON_WHEEL_UP) {
- if (zoom > MAX_ZOOM)
- return;
+ if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+
+ v_scroll->set_value(v_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
+
+ } else {
+ if (zoom > MAX_ZOOM) return;
- float prev_zoom = zoom;
- zoom = zoom * (1.0 / 0.95);
- {
- Point2 ofs(b.x, b.y);
- ofs = ofs / prev_zoom - ofs / zoom;
- h_scroll->set_value(h_scroll->get_value() + ofs.x);
- v_scroll->set_value(v_scroll->get_value() + ofs.y);
+ float prev_zoom = zoom;
+ zoom = zoom * ((0.95 + (0.05 * b->get_factor())) / 0.95);
+ {
+ Point2 ofs = b->get_position();
+ ofs = ofs / prev_zoom - ofs / zoom;
+ h_scroll->set_value(h_scroll->get_value() + ofs.x);
+ v_scroll->set_value(v_scroll->get_value() + ofs.y);
+ }
}
_update_scroll(0);
@@ -1080,9 +1094,25 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
return;
}
- if (b.button_index == BUTTON_RIGHT) {
+ if (b->get_button_index() == BUTTON_WHEEL_LEFT) {
+
+ if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+
+ h_scroll->set_value(h_scroll->get_value() - int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
+ }
+ }
+
+ if (b->get_button_index() == BUTTON_WHEEL_RIGHT) {
- if (b.pressed && (tool == TOOL_SELECT && b.mod.alt)) {
+ if (bool(EditorSettings::get_singleton()->get("editors/2d/scroll_to_pan"))) {
+
+ h_scroll->set_value(h_scroll->get_value() + int(EditorSettings::get_singleton()->get("editors/2d/pan_speed")) / zoom * b->get_factor());
+ }
+ }
+
+ if (b->get_button_index() == BUTTON_RIGHT) {
+
+ if (b->is_pressed() && (tool == TOOL_SELECT && b->get_alt())) {
_list_select(b);
return;
@@ -1129,7 +1159,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
} else if (box_selecting) {
box_selecting = false;
viewport->update();
- } else if (b.pressed) {
+ } else if (b->is_pressed()) {
#if 0
ref_item = NULL;
Node* scene = get_scene()->get_root_node()->cast_to<EditorNode>()->get_edited_scene();
@@ -1145,16 +1175,16 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
return;
*/
- if (b.button_index == BUTTON_LEFT && tool == TOOL_LIST_SELECT) {
- if (b.pressed)
+ if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_LIST_SELECT) {
+ if (b->is_pressed())
_list_select(b);
return;
}
- if (b.button_index == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) {
- if (b.pressed) {
+ if (b->get_button_index() == BUTTON_LEFT && tool == TOOL_EDIT_PIVOT) {
+ if (b->is_pressed()) {
- Point2 mouse_pos(b.x, b.y);
+ Point2 mouse_pos = b->get_position();
mouse_pos = transform.affine_inverse().xform(mouse_pos);
mouse_pos = snap_point(mouse_pos);
_edit_set_pivot(mouse_pos);
@@ -1162,10 +1192,10 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
return;
}
- if (tool == TOOL_PAN || b.button_index != BUTTON_LEFT || Input::get_singleton()->is_key_pressed(KEY_SPACE))
+ if (tool == TOOL_PAN || b->get_button_index() != BUTTON_LEFT || Input::get_singleton()->is_key_pressed(KEY_SPACE))
return;
- if (!b.pressed) {
+ if (!b->is_pressed()) {
if (drag != DRAG_NONE) {
@@ -1227,7 +1257,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
if (box_selecting) {
#if 0
- if ( ! b.mod.shift ) _clear_canvas_items();
+ if ( ! b->get_shift() ) _clear_canvas_items();
if ( box_selection_end() ) return;
#endif
@@ -1272,8 +1302,8 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
E->get().to
};
- Vector2 p = Geometry::get_closest_point_to_segment_2d(Vector2(b.x, b.y), s);
- float d = p.distance_to(Vector2(b.x, b.y));
+ Vector2 p = Geometry::get_closest_point_to_segment_2d(b->get_position(), s);
+ float d = p.distance_to(b->get_position());
if (d < bone_width && d < closest_dist) {
Cbone = E;
closest_dist = d;
@@ -1340,9 +1370,9 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
CanvasItemEditorSelectedItem *se = editor_selection->get_node_editor_data<CanvasItemEditorSelectedItem>(canvas_item);
ERR_FAIL_COND(!se);
- Point2 click(b.x, b.y);
+ Point2 click = b->get_position();
- if ((b.mod.control && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
+ if ((b->get_control() && tool == TOOL_SELECT) || tool == TOOL_ROTATE) {
drag = DRAG_ROTATE;
drag_from = transform.affine_inverse().xform(click);
@@ -1361,7 +1391,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
if (tool == TOOL_SELECT) {
drag = _find_drag_type(xform, rect, click, drag_point_from);
- if (b.doubleclick) {
+ if (b->is_doubleclick()) {
if (canvas_item->get_filename() != "" && canvas_item != editor->get_edited_scene()) {
@@ -1386,9 +1416,9 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
//multi canvas_item edit
- Point2 click = Point2(b.x, b.y);
+ Point2 click = b->get_position();
- if ((b.mod.alt || tool == TOOL_MOVE) && get_item_count()) {
+ if ((b->get_alt() || tool == TOOL_MOVE) && get_item_count()) {
_prepare_drag(click);
viewport->update();
return;
@@ -1433,37 +1463,36 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
};
c = n->cast_to<CanvasItem>();
#if 0
- if ( b.pressed ) box_selection_start( click );
+ if ( b->is_pressed() ) box_selection_start( click );
#endif
- additive_selection = b.mod.shift;
+ additive_selection = b->get_shift();
if (!_select(c, click, additive_selection))
return;
}
- if (p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> m = p_event;
+ if (m.is_valid()) {
if (!viewport->has_focus() && (!get_focus_owner() || !get_focus_owner()->is_text_field()))
viewport->call_deferred("grab_focus");
- const InputEventMouseMotion &m = p_event.mouse_motion;
-
if (box_selecting) {
- box_selecting_to = transform.affine_inverse().xform(Point2(m.x, m.y));
+ box_selecting_to = transform.affine_inverse().xform(m->get_position());
viewport->update();
return;
}
if (drag == DRAG_NONE) {
- if ((m.button_mask & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m.button_mask & BUTTON_MASK_MIDDLE || (m.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
+ if ((m->get_button_mask() & BUTTON_MASK_LEFT && tool == TOOL_PAN) || m->get_button_mask() & BUTTON_MASK_MIDDLE || (m->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE))) {
Point2i relative;
if (bool(EditorSettings::get_singleton()->get("editors/2d/warped_mouse_panning"))) {
relative = Input::get_singleton()->warp_mouse_motion(m, viewport->get_global_rect());
} else {
- relative = Point2i(m.relative_x, m.relative_y);
+ relative = m->get_relative();
}
h_scroll->set_value(h_scroll->get_value() - relative.x / zoom);
@@ -1496,7 +1525,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
}
Vector2 dfrom = drag_from;
- Vector2 dto = transform.affine_inverse().xform(Point2(m.x, m.y));
+ Vector2 dto = transform.affine_inverse().xform(m->get_position());
if (canvas_item->has_meta("_edit_lock_"))
continue;
@@ -1530,8 +1559,8 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
continue;
}
- bool uniform = m.mod.shift;
- bool symmetric = m.mod.alt;
+ bool uniform = m->get_shift();
+ bool symmetric = m->get_alt();
dto = dto - (drag == DRAG_ALL || drag == DRAG_NODE_2D ? drag_from - drag_point_from : Vector2(0, 0));
@@ -1551,8 +1580,8 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
canvas_item->get_global_transform_with_canvas().affine_inverse().xform(dfrom);
Rect2 local_rect = canvas_item->get_item_rect();
- Vector2 begin = local_rect.pos;
- Vector2 end = local_rect.pos + local_rect.size;
+ Vector2 begin = local_rect.position;
+ Vector2 end = local_rect.position + local_rect.size;
Vector2 minsize = canvas_item->edit_get_minimum_size();
if (uniform) {
@@ -1644,7 +1673,7 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
if (!dragging_bone) {
- local_rect.pos = begin;
+ local_rect.position = begin;
local_rect.size = end - begin;
canvas_item->edit_set_rect(local_rect);
@@ -1765,25 +1794,25 @@ void CanvasItemEditor::_viewport_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_event;
- const InputEventKey &k = p_event.key;
+ if (k.is_valid()) {
- if (k.pressed && drag == DRAG_NONE) {
+ if (k->is_pressed() && drag == DRAG_NONE) {
KeyMoveMODE move_mode = MOVE_VIEW_BASE;
- if (k.mod.alt) move_mode = MOVE_LOCAL_BASE;
- if (k.mod.control || k.mod.meta) move_mode = MOVE_LOCAL_WITH_ROT;
-
- if (k.scancode == KEY_UP)
- _key_move(Vector2(0, -1), k.mod.shift, move_mode);
- else if (k.scancode == KEY_DOWN)
- _key_move(Vector2(0, 1), k.mod.shift, move_mode);
- else if (k.scancode == KEY_LEFT)
- _key_move(Vector2(-1, 0), k.mod.shift, move_mode);
- else if (k.scancode == KEY_RIGHT)
- _key_move(Vector2(1, 0), k.mod.shift, move_mode);
- else if (k.scancode == KEY_ESCAPE) {
+ if (k->get_alt()) move_mode = MOVE_LOCAL_BASE;
+ if (k->get_control() || k->get_metakey()) move_mode = MOVE_LOCAL_WITH_ROT;
+
+ if (k->get_scancode() == KEY_UP)
+ _key_move(Vector2(0, -1), k->get_shift(), move_mode);
+ else if (k->get_scancode() == KEY_DOWN)
+ _key_move(Vector2(0, 1), k->get_shift(), move_mode);
+ else if (k->get_scancode() == KEY_LEFT)
+ _key_move(Vector2(-1, 0), k->get_shift(), move_mode);
+ else if (k->get_scancode() == KEY_RIGHT)
+ _key_move(Vector2(1, 0), k->get_shift(), move_mode);
+ else if (k->get_scancode() == KEY_ESCAPE) {
editor_selection->clear();
viewport->update();
} else
@@ -1837,7 +1866,7 @@ void CanvasItemEditor::_viewport_draw() {
if (h_scroll->is_visible_in_tree())
size.height -= h_scroll->get_size().height;
- get_stylebox("EditorFocus", "EditorStyles")->draw(ci, Rect2(Point2(), size));
+ get_stylebox("Focus", "EditorStyles")->draw(ci, Rect2(Point2(), size));
}
Ref<Texture> lock = get_icon("Lock", "EditorIcons");
@@ -1867,10 +1896,10 @@ void CanvasItemEditor::_viewport_draw() {
Vector2 endpoints[4] = {
- xform.xform(rect.pos),
- xform.xform(rect.pos + Vector2(rect.size.x, 0)),
- xform.xform(rect.pos + rect.size),
- xform.xform(rect.pos + Vector2(0, rect.size.y))
+ xform.xform(rect.position),
+ xform.xform(rect.position + Vector2(rect.size.x, 0)),
+ xform.xform(rect.position + rect.size),
+ xform.xform(rect.position + Vector2(0, rect.size.y))
};
Color c = Color(1, 0.6, 0.4, 0.7);
@@ -2211,7 +2240,7 @@ void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2 &r_rect, cons
lock.group = c->has_meta("_edit_group_");
if (lock.group || lock.lock) {
- lock.pos = xform.xform(rect.pos);
+ lock.pos = xform.xform(rect.position);
lock_list.push_back(lock);
}
@@ -2227,10 +2256,10 @@ void CanvasItemEditor::_find_canvas_items_span(Node *p_node, Rect2 &r_rect, cons
bone_list[id].last_pass = bone_last_frame;
}
- r_rect.expand_to(xform.xform(rect.pos));
- r_rect.expand_to(xform.xform(rect.pos + Point2(rect.size.x, 0)));
- r_rect.expand_to(xform.xform(rect.pos + Point2(0, rect.size.y)));
- r_rect.expand_to(xform.xform(rect.pos + rect.size));
+ r_rect.expand_to(xform.xform(rect.position));
+ r_rect.expand_to(xform.xform(rect.position + Point2(rect.size.x, 0)));
+ r_rect.expand_to(xform.xform(rect.position + Point2(0, rect.size.y)));
+ r_rect.expand_to(xform.xform(rect.position + rect.size));
}
}
@@ -2276,19 +2305,19 @@ void CanvasItemEditor::_update_scrollbars() {
//expand area so it's easier to do animations and stuff at 0,0
canvas_item_rect.size += screen_rect * 2;
- canvas_item_rect.pos -= screen_rect;
+ canvas_item_rect.position -= screen_rect;
Point2 ofs;
if (canvas_item_rect.size.height <= (local_rect.size.y / zoom)) {
v_scroll->hide();
- ofs.y = canvas_item_rect.pos.y;
+ ofs.y = canvas_item_rect.position.y;
} else {
v_scroll->show();
- v_scroll->set_min(canvas_item_rect.pos.y);
- v_scroll->set_max(canvas_item_rect.pos.y + canvas_item_rect.size.y);
+ v_scroll->set_min(canvas_item_rect.position.y);
+ v_scroll->set_max(canvas_item_rect.position.y + canvas_item_rect.size.y);
v_scroll->set_page(local_rect.size.y / zoom);
if (first_update) {
//so 0,0 is visible
@@ -2303,12 +2332,12 @@ void CanvasItemEditor::_update_scrollbars() {
if (canvas_item_rect.size.width <= (local_rect.size.x / zoom)) {
h_scroll->hide();
- ofs.x = canvas_item_rect.pos.x;
+ ofs.x = canvas_item_rect.position.x;
} else {
h_scroll->show();
- h_scroll->set_min(canvas_item_rect.pos.x);
- h_scroll->set_max(canvas_item_rect.pos.x + canvas_item_rect.size.x);
+ h_scroll->set_min(canvas_item_rect.position.x);
+ h_scroll->set_max(canvas_item_rect.position.x + canvas_item_rect.size.x);
h_scroll->set_page(local_rect.size.x / zoom);
ofs.x = h_scroll->get_value();
}
@@ -2976,7 +3005,7 @@ void CanvasItemEditor::_focus_selection(int p_op) {
Transform2D t(angle, Vector2(0.f, 0.f));
item_rect = t.xform(item_rect);
- Rect2 canvas_item_rect(pos + scale * item_rect.pos, scale * item_rect.size);
+ Rect2 canvas_item_rect(pos + scale * item_rect.position, scale * item_rect.size);
if (count == 1) {
rect = canvas_item_rect;
} else {
@@ -2987,7 +3016,7 @@ void CanvasItemEditor::_focus_selection(int p_op) {
if (p_op == VIEW_CENTER_TO_SELECTION) {
- center = rect.pos + rect.size / 2;
+ center = rect.position + rect.size / 2;
Vector2 offset = viewport->get_size() / 2 - editor->get_scene_root()->get_global_canvas_transform().xform(center);
h_scroll->set_value(h_scroll->get_value() - offset.x / zoom);
v_scroll->set_value(v_scroll->get_value() - offset.y / zoom);
@@ -3123,7 +3152,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
editor_selection->connect("selection_changed", this, "update");
hb = memnew(HBoxContainer);
- hb->add_style_override("bg", editor->get_gui_base()->get_stylebox("panel", "PanelContainer"));
add_child(hb);
hb->set_area_as_parent_rect();
@@ -3300,8 +3328,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
animation_hb->hide();
key_loc_button = memnew(Button("loc"));
- key_loc_button = memnew(Button("loc"));
- key_loc_button->set_flat(true);
key_loc_button->set_toggle_mode(true);
key_loc_button->set_pressed(true);
key_loc_button->set_focus_mode(FOCUS_NONE);
@@ -3310,7 +3336,6 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
key_loc_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_POS));
animation_hb->add_child(key_loc_button);
key_rot_button = memnew(Button("rot"));
- key_rot_button->set_flat(true);
key_rot_button->set_toggle_mode(true);
key_rot_button->set_pressed(true);
key_rot_button->set_focus_mode(FOCUS_NONE);
@@ -3319,14 +3344,13 @@ CanvasItemEditor::CanvasItemEditor(EditorNode *p_editor) {
key_rot_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_ROT));
animation_hb->add_child(key_rot_button);
key_scale_button = memnew(Button("scl"));
- key_scale_button->set_flat(true);
key_scale_button->set_toggle_mode(true);
key_scale_button->set_focus_mode(FOCUS_NONE);
key_scale_button->add_color_override("font_color", Color(1, 0.6, 0.6));
key_scale_button->add_color_override("font_color_pressed", Color(0.6, 1, 0.6));
key_scale_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_SCALE));
animation_hb->add_child(key_scale_button);
- key_insert_button = memnew(ToolButton);
+ key_insert_button = memnew(Button);
key_insert_button->set_focus_mode(FOCUS_NONE);
key_insert_button->connect("pressed", this, "_popup_callback", varray(ANIM_INSERT_KEY));
key_insert_button->set_tooltip(TTR("Insert Keys"));
diff --git a/editor/plugins/canvas_item_editor_plugin.h b/editor/plugins/canvas_item_editor_plugin.h
index 7f09b92f4c..22fa5b5db8 100644
--- a/editor/plugins/canvas_item_editor_plugin.h
+++ b/editor/plugins/canvas_item_editor_plugin.h
@@ -322,7 +322,7 @@ class CanvasItemEditor : public VBoxContainer {
void _clear_canvas_items();
void _visibility_changed(ObjectID p_canvas_item);
void _key_move(const Vector2 &p_dir, bool p_snap, KeyMoveMODE p_move_mode);
- void _list_select(const InputEventMouseButton &b);
+ void _list_select(const Ref<InputEventMouseButton> &b);
DragType _find_drag_type(const Transform2D &p_xform, const Rect2 &p_local_rect, const Point2 &p_click, Vector2 &r_point);
void _prepare_drag(const Point2 &p_click_pos);
@@ -352,9 +352,9 @@ class CanvasItemEditor : public VBoxContainer {
int get_item_count();
void _keying_changed();
- void _unhandled_key_input(const InputEvent &p_ev);
+ void _unhandled_key_input(const Ref<InputEvent> &p_ev);
- void _viewport_gui_input(const InputEvent &p_event);
+ void _viewport_gui_input(const Ref<InputEvent> &p_event);
void _viewport_draw();
void _focus_selection(int p_op);
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.cpp b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
index ae426ba29e..43abea0131 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.cpp
@@ -94,213 +94,208 @@ void CollisionPolygon2DEditor::_wip_close() {
edited_point = -1;
}
-bool CollisionPolygon2DEditor::forward_gui_input(const InputEvent &p_event) {
+bool CollisionPolygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
- switch (p_event.type) {
+ Ref<InputEventMouseButton> mb;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- const InputEventMouseButton &mb = p_event.mouse_button;
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Vector<Vector2> poly = node->get_polygon();
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- Vector<Vector2> poly = node->get_polygon();
+ switch (mode) {
- //first check if a point is to be added (segment split)
- real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
+ case MODE_CREATE: {
- switch (mode) {
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- case MODE_CREATE: {
+ if (!wip_active) {
- if (mb.button_index == BUTTON_LEFT && mb.pressed) {
+ wip.clear();
+ wip.push_back(cpoint);
+ wip_active = true;
+ edited_point_pos = cpoint;
+ canvas_item_editor->get_viewport_control()->update();
+ edited_point = 1;
+ return true;
+ } else {
- if (!wip_active) {
+ if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close();
- wip.clear();
- wip.push_back(cpoint);
- wip_active = true;
- edited_point_pos = cpoint;
- canvas_item_editor->get_viewport_control()->update();
- edited_point = 1;
return true;
} else {
- if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
- //wip closed
- _wip_close();
-
- return true;
- } else {
-
- wip.push_back(cpoint);
- edited_point = wip.size();
- canvas_item_editor->get_viewport_control()->update();
- return true;
+ wip.push_back(cpoint);
+ edited_point = wip.size();
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
- //add wip point
- }
+ //add wip point
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && wip_active) {
- _wip_close();
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close();
+ }
- } break;
-
- case MODE_EDIT: {
+ } break;
- if (mb.button_index == BUTTON_LEFT) {
- if (mb.pressed) {
+ case MODE_EDIT: {
- if (mb.mod.control) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- if (poly.size() < 3) {
+ if (mb->get_control()) {
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
- poly.push_back(cpoint);
- undo_redo->add_do_method(node, "set_polygon", poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- return true;
- }
-
- //search edges
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
-
- Vector2 points[2] = { xform.xform(poly[i]),
- xform.xform(poly[(i + 1) % poly.size()]) };
-
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
- if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
- continue; //not valid to reuse point
-
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
- }
-
- if (closest_idx >= 0) {
+ if (poly.size() < 3) {
- pre_move_edit = poly;
- poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
- edited_point = closest_idx + 1;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- node->set_polygon(poly);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
- } else {
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
- //look for points to move
+ //search edges
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
+ Vector2 points[2] = { xform.xform(poly[i]),
+ xform.xform(poly[(i + 1) % poly.size()]) };
- Vector2 cp = xform.xform(poly[i]);
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ continue; //not valid to reuse point
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
}
+ }
- if (closest_idx >= 0) {
+ if (closest_idx >= 0) {
- pre_move_edit = poly;
- edited_point = closest_idx;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
+ pre_move_edit = poly;
+ poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
+ edited_point = closest_idx + 1;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ node->set_polygon(poly);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
} else {
- if (edited_point != -1) {
+ //look for points to move
- //apply
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node, "set_polygon", poly);
- undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ Vector2 cp = xform.xform(poly[i]);
- edited_point = -1;
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
}
- }
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && edited_point == -1) {
-
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
- Vector2 cp = xform.xform(poly[i]);
+ if (closest_idx >= 0) {
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
+ pre_move_edit = poly;
+ edited_point = closest_idx;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
}
+ } else {
+
+ if (edited_point != -1) {
- if (closest_idx >= 0) {
+ //apply
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
- poly.remove(closest_idx);
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly[edited_point] = edited_point_pos;
+ undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->commit_action();
+
+ edited_point = -1;
return true;
}
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
- } break;
- }
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- } break;
- case InputEvent::MOUSE_MOTION: {
+ Vector2 cp = xform.xform(poly[i]);
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
+ }
- if (edited_point != -1 && (wip_active || mm.button_mask & BUTTON_MASK_LEFT)) {
+ if (closest_idx >= 0) {
- Vector2 gpoint = Point2(mm.x, mm.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
+ }
- canvas_item_editor->get_viewport_control()->update();
- }
+ } break;
+ }
+ }
- } break;
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+
+ if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
+
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+
+ canvas_item_editor->get_viewport_control()->update();
+ }
}
return false;
diff --git a/editor/plugins/collision_polygon_2d_editor_plugin.h b/editor/plugins/collision_polygon_2d_editor_plugin.h
index babe653581..382c0d6c37 100644
--- a/editor/plugins/collision_polygon_2d_editor_plugin.h
+++ b/editor/plugins/collision_polygon_2d_editor_plugin.h
@@ -80,7 +80,7 @@ protected:
static void _bind_methods();
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
CollisionPolygon2DEditor(EditorNode *p_editor);
};
@@ -93,7 +93,7 @@ class CollisionPolygon2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "CollisionPolygon2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/collision_polygon_editor_plugin.cpp b/editor/plugins/collision_polygon_editor_plugin.cpp
index fdb1bf984e..c89e6f59a4 100644
--- a/editor/plugins/collision_polygon_editor_plugin.cpp
+++ b/editor/plugins/collision_polygon_editor_plugin.cpp
@@ -131,7 +131,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
- Vector2 gpoint=Point2(mb.x,mb.y);
+ Vector2 gpoint=Point2(mb->get_pos().x,mb->get_pos().y);
Vector3 ray_from = p_camera->project_ray_origin(gpoint);
Vector3 ray_dir = p_camera->project_ray_normal(gpoint);
@@ -156,7 +156,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
case MODE_CREATE: {
- if (mb.button_index==BUTTON_LEFT && mb.pressed) {
+ if (mb->get_button_index()==BUTTON_LEFT && mb->is_pressed()) {
if (!wip_active) {
@@ -186,7 +186,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
//add wip point
}
}
- } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) {
+ } else if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && wip_active) {
_wip_close();
}
@@ -196,10 +196,10 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
case MODE_EDIT: {
- if (mb.button_index==BUTTON_LEFT) {
- if (mb.pressed) {
+ if (mb->get_button_index()==BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- if (mb.mod.control) {
+ if (mb->get_control()) {
if (poly.size() < 3) {
@@ -297,7 +297,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
return true;
}
}
- } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) {
+ } if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && edited_point==-1) {
@@ -344,7 +344,7 @@ bool CollisionPolygonEditor::forward_spatial_gui_input(Camera* p_camera,const In
const InputEventMouseMotion &mm=p_event.mouse_motion;
- if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) {
+ if (edited_point!=-1 && (wip_active || mm->get_button_mask()&BUTTON_MASK_LEFT)) {
Vector2 gpoint = Point2(mm.x,mm.y);
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.cpp b/editor/plugins/collision_shape_2d_editor_plugin.cpp
index 70cc81efb0..9a6ee8153e 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.cpp
+++ b/editor/plugins/collision_shape_2d_editor_plugin.cpp
@@ -302,7 +302,7 @@ void CollisionShape2DEditor::commit_handle(int idx, Variant &p_org) {
undo_redo->commit_action();
}
-bool CollisionShape2DEditor::forward_gui_input(const InputEvent &p_event) {
+bool CollisionShape2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node) {
return false;
@@ -316,68 +316,66 @@ bool CollisionShape2DEditor::forward_gui_input(const InputEvent &p_event) {
return false;
}
- switch (p_event.type) {
- case InputEvent::MOUSE_BUTTON: {
- const InputEventMouseButton &mb = p_event.mouse_button;
+ Ref<InputEventMouseButton> mb = p_event;
- Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ if (mb.is_valid()) {
- Point2 gpoint(mb.x, mb.y);
+ Transform2D gt = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- if (mb.button_index == BUTTON_LEFT) {
- if (mb.pressed) {
- for (int i = 0; i < handles.size(); i++) {
- if (gt.xform(handles[i]).distance_to(gpoint) < 8) {
- edit_handle = i;
+ Point2 gpoint(mb->get_position().x, mb->get_position().y);
- break;
- }
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
+ for (int i = 0; i < handles.size(); i++) {
+ if (gt.xform(handles[i]).distance_to(gpoint) < 8) {
+ edit_handle = i;
+
+ break;
}
+ }
- if (edit_handle == -1) {
- pressed = false;
+ if (edit_handle == -1) {
+ pressed = false;
- return false;
- }
+ return false;
+ }
- original = get_handle_value(edit_handle);
- pressed = true;
+ original = get_handle_value(edit_handle);
+ pressed = true;
- return true;
+ return true;
- } else {
- if (pressed) {
- commit_handle(edit_handle, original);
+ } else {
+ if (pressed) {
+ commit_handle(edit_handle, original);
- edit_handle = -1;
- pressed = false;
+ edit_handle = -1;
+ pressed = false;
- return true;
- }
+ return true;
}
}
+ }
- return false;
-
- } break;
+ return false;
+ }
- case InputEvent::MOUSE_MOTION: {
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ Ref<InputEventMouseMotion> mm = p_event;
- if (edit_handle == -1 || !pressed) {
- return false;
- }
+ if (mm.is_valid()) {
- Point2 gpoint = Point2(mm.x, mm.y);
- Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ if (edit_handle == -1 || !pressed) {
+ return false;
+ }
- set_handle(edit_handle, cpoint);
+ Point2 gpoint = mm->get_position();
+ Point2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
- return true;
+ set_handle(edit_handle, cpoint);
- } break;
+ return true;
}
return false;
diff --git a/editor/plugins/collision_shape_2d_editor_plugin.h b/editor/plugins/collision_shape_2d_editor_plugin.h
index bbd94516a8..09aefc65c0 100644
--- a/editor/plugins/collision_shape_2d_editor_plugin.h
+++ b/editor/plugins/collision_shape_2d_editor_plugin.h
@@ -74,7 +74,7 @@ protected:
static void _bind_methods();
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_node);
CollisionShape2DEditor(EditorNode *p_editor);
@@ -87,7 +87,7 @@ class CollisionShape2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return collision_shape_2d_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_shape_2d_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "CollisionShape2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/curve_editor_plugin.cpp b/editor/plugins/curve_editor_plugin.cpp
index f3ad5c0fd1..d869d703f1 100644
--- a/editor/plugins/curve_editor_plugin.cpp
+++ b/editor/plugins/curve_editor_plugin.cpp
@@ -33,9 +33,10 @@
#include "os/keyboard.h"
#include "spatial_editor_plugin.h"
-void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
+void CurveTextureEdit::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) {
points.remove(grabbed);
grabbed = -1;
@@ -44,7 +45,9 @@ void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
accept_event();
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
update();
Ref<Font> font = get_font("font", "Label");
@@ -54,7 +57,7 @@ void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
Vector2 size = get_size();
size.y -= font_h;
- Point2 p = Vector2(p_event.mouse_button.x, p_event.mouse_button.y) / size;
+ Point2 p = Vector2(mb->get_position().x, mb->get_position().y) / size;
p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
grabbed = -1;
grabbing = true;
@@ -90,7 +93,7 @@ void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
emit_signal("curve_changed");
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
if (grabbing) {
grabbing = false;
@@ -99,14 +102,16 @@ void CurveTextureEdit::_gui_input(const InputEvent &p_event) {
update();
}
- if (p_event.type == InputEvent::MOUSE_MOTION && grabbing && grabbed != -1) {
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid() && grabbing && grabbed != -1) {
Ref<Font> font = get_font("font", "Label");
int font_h = font->get_height();
Vector2 size = get_size();
size.y -= font_h;
- Point2 p = Vector2(p_event.mouse_motion.x, p_event.mouse_motion.y) / size;
+ Point2 p = mm->get_position() / size;
p.y = CLAMP(1.0 - p.y, 0, 1) * (max - min) + min;
p.x = CLAMP(p.x, 0.0, 1.0);
diff --git a/editor/plugins/curve_editor_plugin.h b/editor/plugins/curve_editor_plugin.h
index ebe05539aa..4e75ba407c 100644
--- a/editor/plugins/curve_editor_plugin.h
+++ b/editor/plugins/curve_editor_plugin.h
@@ -54,7 +54,7 @@ class CurveTextureEdit : public Control {
void _plot_curve(const Vector2 &p_a, const Vector2 &p_b, const Vector2 &p_c, const Vector2 &p_d);
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/plugins/editor_preview_plugins.cpp b/editor/plugins/editor_preview_plugins.cpp
index db8060d591..11d804422a 100644
--- a/editor/plugins/editor_preview_plugins.cpp
+++ b/editor/plugins/editor_preview_plugins.cpp
@@ -39,239 +39,226 @@
#include "scene/resources/bit_mask.h"
#include "scene/resources/mesh.h"
-#if 0
-bool EditorTexturePreviewPlugin::handles(const String& p_type) const {
+bool EditorTexturePreviewPlugin::handles(const String &p_type) const {
- return (ClassDB::is_type(p_type,"ImageTexture") || ClassDB::is_type(p_type, "AtlasTexture"));
+ return ClassDB::is_parent_class(p_type, "Texture");
}
-Ref<Texture> EditorTexturePreviewPlugin::generate(const RES& p_from) {
+Ref<Texture> EditorTexturePreviewPlugin::generate(const RES &p_from) {
- Image img;
+ Ref<Image> img;
Ref<AtlasTexture> atex = p_from;
if (atex.is_valid()) {
- Ref<ImageTexture> tex = atex->get_atlas();
+ Ref<Texture> tex = atex->get_atlas();
if (!tex.is_valid()) {
return Ref<Texture>();
}
- Image atlas = tex->get_data();
- img = atlas.get_rect(atex->get_region());
- }
- else {
- Ref<ImageTexture> tex = p_from;
+ Ref<Image> atlas = tex->get_data();
+ img = atlas->get_rect(atex->get_region());
+ } else {
+ Ref<Texture> tex = p_from;
img = tex->get_data();
}
- if (img.empty())
+ if (img.is_null() || img->empty())
return Ref<Texture>();
- img.clear_mipmaps();
+ img->clear_mipmaps();
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size*=EDSCALE;
- if (img.is_compressed()) {
- if (img.decompress()!=OK)
+ thumbnail_size *= EDSCALE;
+ if (img->is_compressed()) {
+ if (img->decompress() != OK)
return Ref<Texture>();
- } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) {
- img.convert(Image::FORMAT_RGBA8);
+ } else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
+ img->convert(Image::FORMAT_RGBA8);
}
- int width,height;
- if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) {
+ int width, height;
+ if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
- width=thumbnail_size;
- height = img.get_height() * thumbnail_size / img.get_width();
- } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) {
+ width = thumbnail_size;
+ height = img->get_height() * thumbnail_size / img->get_width();
+ } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
- height=thumbnail_size;
- width = img.get_width() * thumbnail_size / img.get_height();
- } else {
+ height = thumbnail_size;
+ width = img->get_width() * thumbnail_size / img->get_height();
+ } else {
- width=img.get_width();
- height=img.get_height();
+ width = img->get_width();
+ height = img->get_height();
}
- img.resize(width,height);
+ img->resize(width, height);
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
- ptex->create_from_image(img,0);
+ ptex->create_from_image(img, 0);
return ptex;
-
}
EditorTexturePreviewPlugin::EditorTexturePreviewPlugin() {
-
-
}
////////////////////////////////////////////////////////////////////////////
-bool EditorBitmapPreviewPlugin::handles(const String& p_type) const {
+bool EditorBitmapPreviewPlugin::handles(const String &p_type) const {
- return ClassDB::is_type(p_type,"BitMap");
+ return ClassDB::is_parent_class(p_type, "BitMap");
}
-Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES& p_from) {
+Ref<Texture> EditorBitmapPreviewPlugin::generate(const RES &p_from) {
- Ref<BitMap> bm =p_from;
+ Ref<BitMap> bm = p_from;
- if (bm->get_size()==Size2()) {
+ if (bm->get_size() == Size2()) {
return Ref<Texture>();
}
PoolVector<uint8_t> data;
- data.resize(bm->get_size().width*bm->get_size().height);
+ data.resize(bm->get_size().width * bm->get_size().height);
{
- PoolVector<uint8_t>::Write w=data.write();
+ PoolVector<uint8_t>::Write w = data.write();
- for(int i=0;i<bm->get_size().width;i++) {
- for(int j=0;j<bm->get_size().height;j++) {
- if (bm->get_bit(Point2i(i,j))) {
- w[j*bm->get_size().width+i]=255;
+ for (int i = 0; i < bm->get_size().width; i++) {
+ for (int j = 0; j < bm->get_size().height; j++) {
+ if (bm->get_bit(Point2i(i, j))) {
+ w[j * bm->get_size().width + i] = 255;
} else {
- w[j*bm->get_size().width+i]=0;
-
+ w[j * bm->get_size().width + i] = 0;
}
}
-
}
}
-
- Image img(bm->get_size().width,bm->get_size().height,0,Image::FORMAT_L8,data);
+ Ref<Image> img;
+ img.instance();
+ img->create(bm->get_size().width, bm->get_size().height, 0, Image::FORMAT_L8, data);
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size*=EDSCALE;
- if (img.is_compressed()) {
- if (img.decompress()!=OK)
+ thumbnail_size *= EDSCALE;
+ if (img->is_compressed()) {
+ if (img->decompress() != OK)
return Ref<Texture>();
- } else if (img.get_format()!=Image::FORMAT_RGB8 && img.get_format()!=Image::FORMAT_RGBA8) {
- img.convert(Image::FORMAT_RGBA8);
+ } else if (img->get_format() != Image::FORMAT_RGB8 && img->get_format() != Image::FORMAT_RGBA8) {
+ img->convert(Image::FORMAT_RGBA8);
}
- int width,height;
- if (img.get_width() > thumbnail_size && img.get_width() >= img.get_height()) {
+ int width, height;
+ if (img->get_width() > thumbnail_size && img->get_width() >= img->get_height()) {
- width=thumbnail_size;
- height = img.get_height() * thumbnail_size / img.get_width();
- } else if (img.get_height() > thumbnail_size && img.get_height() >= img.get_width()) {
+ width = thumbnail_size;
+ height = img->get_height() * thumbnail_size / img->get_width();
+ } else if (img->get_height() > thumbnail_size && img->get_height() >= img->get_width()) {
- height=thumbnail_size;
- width = img.get_width() * thumbnail_size / img.get_height();
- } else {
+ height = thumbnail_size;
+ width = img->get_width() * thumbnail_size / img->get_height();
+ } else {
- width=img.get_width();
- height=img.get_height();
+ width = img->get_width();
+ height = img->get_height();
}
- img.resize(width,height);
+ img->resize(width, height);
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
- ptex->create_from_image(img,0);
+ ptex->create_from_image(img, 0);
return ptex;
-
}
EditorBitmapPreviewPlugin::EditorBitmapPreviewPlugin() {
-
-
}
///////////////////////////////////////////////////////////////////////////
+bool EditorPackedScenePreviewPlugin::handles(const String &p_type) const {
-Ref<Texture> EditorPackedScenePreviewPlugin::_gen_from_imd(Ref<ResourceImportMetadata> p_imd) {
-
- if (p_imd.is_null()) {
- return Ref<Texture>();
- }
+ return ClassDB::is_parent_class(p_type, "PackedScene");
+}
+Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES &p_from) {
- if (!p_imd->has_option("thumbnail"))
- return Ref<Texture>();
+ return generate_from_path(p_from->get_path());
+}
- Variant tn = p_imd->get_option("thumbnail");
- //print_line(Variant::get_type_name(tn.get_type()));
- PoolVector<uint8_t> thumbnail = tn;
+Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String &p_path) {
- int len = thumbnail.size();
- if (len==0)
- return Ref<Texture>();
+ String temp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp");
+ String cache_base = GlobalConfig::get_singleton()->globalize_path(p_path).md5_text();
+ cache_base = temp_path.plus_file("resthumb-" + cache_base);
+ //does not have it, try to load a cached thumbnail
- PoolVector<uint8_t>::Read r = thumbnail.read();
+ String path = cache_base + ".png";
- Image img(r.ptr(),len);
- if (img.empty())
+ if (!FileAccess::exists(path))
return Ref<Texture>();
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
- ptex->create_from_image(img,0);
- return ptex;
+ Ref<Image> img;
+ img.instance();
+ Error err = img->load(path);
+ if (err == OK) {
-}
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
-bool EditorPackedScenePreviewPlugin::handles(const String& p_type) const {
+ ptex->create_from_image(img, 0);
+ return ptex;
- return ClassDB::is_type(p_type,"PackedScene");
+ } else {
+ return Ref<Texture>();
+ }
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate(const RES& p_from) {
- Ref<ResourceImportMetadata> imd = p_from->get_import_metadata();
- return _gen_from_imd(imd);
+EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
}
-Ref<Texture> EditorPackedScenePreviewPlugin::generate_from_path(const String& p_path) {
+//////////////////////////////////////////////////////////////////
+
+void EditorMaterialPreviewPlugin::_preview_done(const Variant &p_udata) {
- Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path);
- return _gen_from_imd(imd);
+ preview_done = true;
}
-EditorPackedScenePreviewPlugin::EditorPackedScenePreviewPlugin() {
+void EditorMaterialPreviewPlugin::_bind_methods() {
+ ClassDB::bind_method("_preview_done", &EditorMaterialPreviewPlugin::_preview_done);
}
-//////////////////////////////////////////////////////////////////
+bool EditorMaterialPreviewPlugin::handles(const String &p_type) const {
-bool EditorMaterialPreviewPlugin::handles(const String& p_type) const {
-
- return ClassDB::is_type(p_type,"Material"); //any material
+ return ClassDB::is_parent_class(p_type, "Material"); //any material
}
-Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES& p_from) {
+Ref<Texture> EditorMaterialPreviewPlugin::generate(const RES &p_from) {
Ref<Material> material = p_from;
- ERR_FAIL_COND_V(material.is_null(),Ref<Texture>());
+ ERR_FAIL_COND_V(material.is_null(), Ref<Texture>());
- VS::get_singleton()->mesh_surface_set_material(sphere,0,material->get_rid());
+ VS::get_singleton()->mesh_surface_set_material(sphere, 0, material->get_rid());
- VS::get_singleton()->viewport_queue_screen_capture(viewport);
- VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture
+ VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
//print_line("queue capture!");
- Image img;
- int timeout=1000;
- while(timeout) {
- //print_line("try capture?");
+ preview_done = false;
+ VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+
+ while (!preview_done) {
OS::get_singleton()->delay_usec(10);
- img = VS::get_singleton()->viewport_get_screen_capture(viewport);
- if (!img.empty())
- break;
- timeout--;
}
- //print_line("captured!");
- VS::get_singleton()->mesh_surface_set_material(sphere,0,RID());
+ Ref<Image> img = VS::get_singleton()->VS::get_singleton()->texture_get_data(viewport_texture);
+ VS::get_singleton()->mesh_surface_set_material(sphere, 0, RID());
- int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size*=EDSCALE;
- img.resize(thumbnail_size,thumbnail_size);
+ ERR_FAIL_COND_V(!img.is_valid(), Ref<ImageTexture>());
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
- ptex->create_from_image(img,0);
+ int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
+ thumbnail_size *= EDSCALE;
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(thumbnail_size, thumbnail_size);
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
+ ptex->create_from_image(img, 0);
return ptex;
}
@@ -280,70 +267,68 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
scenario = VS::get_singleton()->scenario_create();
viewport = VS::get_singleton()->viewport_create();
- VS::get_singleton()->viewport_set_as_render_target(viewport,true);
- VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED);
- VS::get_singleton()->viewport_set_scenario(viewport,scenario);
- VS::ViewportRect vr;
- vr.x=0;
- vr.y=0;
- vr.width=128;
- vr.height=128;
- VS::get_singleton()->viewport_set_rect(viewport,vr);
+ VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED);
+ VS::get_singleton()->viewport_set_scenario(viewport, scenario);
+ VS::get_singleton()->viewport_set_size(viewport, 128, 128);
+ VS::get_singleton()->viewport_set_transparent_background(viewport, true);
+ VS::get_singleton()->viewport_set_active(viewport, true);
+ VS::get_singleton()->viewport_set_vflip(viewport, true);
+ viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
camera = VS::get_singleton()->camera_create();
- VS::get_singleton()->viewport_attach_camera(viewport,camera);
- VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3)));
- VS::get_singleton()->camera_set_perspective(camera,45,0.1,10);
+ VS::get_singleton()->viewport_attach_camera(viewport, camera);
+ VS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3)));
+ VS::get_singleton()->camera_set_perspective(camera, 45, 0.1, 10);
light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
- light_instance = VS::get_singleton()->instance_create2(light,scenario);
- VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
+ light_instance = VS::get_singleton()->instance_create2(light, scenario);
+ VS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0)));
light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
- VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7));
- VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0));
- light_instance2 = VS::get_singleton()->instance_create2(light2,scenario);
+ VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
+ //VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
+
+ light_instance2 = VS::get_singleton()->instance_create2(light2, scenario);
- VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
+ VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
sphere = VS::get_singleton()->mesh_create();
- sphere_instance = VS::get_singleton()->instance_create2(sphere,scenario);
+ sphere_instance = VS::get_singleton()->instance_create2(sphere, scenario);
- int lats=32;
- int lons=32;
- float radius=1.0;
+ int lats = 32;
+ int lons = 32;
+ float radius = 1.0;
PoolVector<Vector3> vertices;
PoolVector<Vector3> normals;
PoolVector<Vector2> uvs;
PoolVector<float> tangents;
- Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5);
+ Basis tt = Basis(Vector3(0, 1, 0), Math_PI * 0.5);
- for(int i = 1; i <= lats; i++) {
- double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
- double z0 = Math::sin(lat0);
- double zr0 = Math::cos(lat0);
+ for (int i = 1; i <= lats; i++) {
+ double lat0 = Math_PI * (-0.5 + (double)(i - 1) / lats);
+ double z0 = Math::sin(lat0);
+ double zr0 = Math::cos(lat0);
- double lat1 = Math_PI * (-0.5 + (double) i / lats);
+ double lat1 = Math_PI * (-0.5 + (double)i / lats);
double z1 = Math::sin(lat1);
double zr1 = Math::cos(lat1);
- for(int j = lons; j >= 1; j--) {
+ for (int j = lons; j >= 1; j--) {
- double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
+ double lng0 = 2 * Math_PI * (double)(j - 1) / lons;
double x0 = Math::cos(lng0);
double y0 = Math::sin(lng0);
- double lng1 = 2 * Math_PI * (double) (j) / lons;
+ double lng1 = 2 * Math_PI * (double)(j) / lons;
double x1 = Math::cos(lng1);
double y1 = Math::sin(lng1);
-
- Vector3 v[4]={
- Vector3(x1 * zr0, z0, y1 *zr0),
- Vector3(x1 * zr1, z1, y1 *zr1),
- Vector3(x0 * zr1, z1, y0 *zr1),
- Vector3(x0 * zr0, z0, y0 *zr0)
+ Vector3 v[4] = {
+ Vector3(x1 * zr0, z0, y1 * zr0),
+ Vector3(x1 * zr1, z1, y1 * zr1),
+ Vector3(x0 * zr1, z1, y0 * zr1),
+ Vector3(x0 * zr0, z0, y0 * zr0)
};
#define ADD_POINT(m_idx) \
@@ -364,8 +349,6 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
tangents.push_back(1.0); \
}
-
-
ADD_POINT(0);
ADD_POINT(1);
ADD_POINT(2);
@@ -378,12 +361,11 @@ EditorMaterialPreviewPlugin::EditorMaterialPreviewPlugin() {
Array arr;
arr.resize(VS::ARRAY_MAX);
- arr[VS::ARRAY_VERTEX]=vertices;
- arr[VS::ARRAY_NORMAL]=normals;
- arr[VS::ARRAY_TANGENT]=tangents;
- arr[VS::ARRAY_TEX_UV]=uvs;
- VS::get_singleton()->mesh_add_surface(sphere,VS::PRIMITIVE_TRIANGLES,arr);
-
+ arr[VS::ARRAY_VERTEX] = vertices;
+ arr[VS::ARRAY_NORMAL] = normals;
+ arr[VS::ARRAY_TANGENT] = tangents;
+ arr[VS::ARRAY_TEX_UV] = uvs;
+ VS::get_singleton()->mesh_add_surface_from_arrays(sphere, VS::PRIMITIVE_TRIANGLES, arr);
}
EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
@@ -397,30 +379,28 @@ EditorMaterialPreviewPlugin::~EditorMaterialPreviewPlugin() {
VS::get_singleton()->free(light_instance2);
VS::get_singleton()->free(camera);
VS::get_singleton()->free(scenario);
-
}
///////////////////////////////////////////////////////////////////////////
static bool _is_text_char(CharType c) {
- return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9') || c=='_';
+ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-bool EditorScriptPreviewPlugin::handles(const String& p_type) const {
+bool EditorScriptPreviewPlugin::handles(const String &p_type) const {
- return ClassDB::is_type(p_type,"Script");
+ return ClassDB::is_parent_class(p_type, "Script");
}
-Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) {
-
+Ref<Texture> EditorScriptPreviewPlugin::generate(const RES &p_from) {
Ref<Script> scr = p_from;
if (scr.is_null())
return Ref<Texture>();
String code = scr->get_source_code().strip_edges();
- if (code=="")
+ if (code == "")
return Ref<Texture>();
List<String> kwors;
@@ -428,107 +408,104 @@ Ref<Texture> EditorScriptPreviewPlugin::generate(const RES& p_from) {
Set<String> keywords;
- for(List<String>::Element *E=kwors.front();E;E=E->next()) {
+ for (List<String>::Element *E = kwors.front(); E; E = E->next()) {
keywords.insert(E->get());
-
}
-
int line = 0;
- int col=0;
+ int col = 0;
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size*=EDSCALE;
- Image img(thumbnail_size,thumbnail_size,0,Image::FORMAT_RGBA8);
-
-
+ thumbnail_size *= EDSCALE;
+ Ref<Image> img;
+ img.instance();
+ img->create(thumbnail_size, thumbnail_size, 0, Image::FORMAT_RGBA8);
Color bg_color = EditorSettings::get_singleton()->get("text_editor/highlighting/background_color");
- bg_color.a=1.0;
+ bg_color.a = 1.0;
Color keyword_color = EditorSettings::get_singleton()->get("text_editor/highlighting/keyword_color");
Color text_color = EditorSettings::get_singleton()->get("text_editor/highlighting/text_color");
Color symbol_color = EditorSettings::get_singleton()->get("text_editor/highlighting/symbol_color");
+ img->lock();
- for(int i=0;i<thumbnail_size;i++) {
- for(int j=0;j<thumbnail_size;j++) {
- img.put_pixel(i,j,bg_color);
+ for (int i = 0; i < thumbnail_size; i++) {
+ for (int j = 0; j < thumbnail_size; j++) {
+ img->put_pixel(i, j, bg_color);
}
-
}
- bool prev_is_text=false;
- bool in_keyword=false;
- for(int i=0;i<code.length();i++) {
+ bool prev_is_text = false;
+ bool in_keyword = false;
+ for (int i = 0; i < code.length(); i++) {
CharType c = code[i];
- if (c>32) {
- if (col<thumbnail_size) {
+ if (c > 32) {
+ if (col < thumbnail_size) {
Color color = text_color;
- if (c!='_' && ((c>='!' && c<='/') || (c>=':' && c<='@') || (c>='[' && c<='`') || (c>='{' && c<='~') || c=='\t')) {
+ if (c != '_' && ((c >= '!' && c <= '/') || (c >= ':' && c <= '@') || (c >= '[' && c <= '`') || (c >= '{' && c <= '~') || c == '\t')) {
//make symbol a little visible
- color=symbol_color;
- in_keyword=false;
+ color = symbol_color;
+ in_keyword = false;
} else if (!prev_is_text && _is_text_char(c)) {
int pos = i;
- while(_is_text_char(code[pos])) {
+ while (_is_text_char(code[pos])) {
pos++;
}
///print_line("from "+itos(i)+" to "+itos(pos));
- String word = code.substr(i,pos-i);
+ String word = code.substr(i, pos - i);
//print_line("found word: "+word);
if (keywords.has(word))
- in_keyword=true;
+ in_keyword = true;
} else if (!_is_text_char(c)) {
- in_keyword=false;
+ in_keyword = false;
}
if (in_keyword)
- color=keyword_color;
+ color = keyword_color;
- Color ul=color;
- ul.a*=0.5;
- img.put_pixel(col,line*2,bg_color.blend(ul));
- img.put_pixel(col,line*2+1,color);
+ Color ul = color;
+ ul.a *= 0.5;
+ img->put_pixel(col, line * 2, bg_color.blend(ul));
+ img->put_pixel(col, line * 2 + 1, color);
- prev_is_text=_is_text_char(c);
+ prev_is_text = _is_text_char(c);
}
} else {
- prev_is_text=false;
- in_keyword=false;
+ prev_is_text = false;
+ in_keyword = false;
- if (c=='\n') {
- col=0;
+ if (c == '\n') {
+ col = 0;
line++;
- if (line>=thumbnail_size/2)
+ if (line >= thumbnail_size / 2)
break;
- } else if (c=='\t') {
- col+=3;
+ } else if (c == '\t') {
+ col += 3;
}
}
col++;
}
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture));
+ img->unlock();
- ptex->create_from_image(img,0);
- return ptex;
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
+ ptex->create_from_image(img, 0);
+ return ptex;
}
EditorScriptPreviewPlugin::EditorScriptPreviewPlugin() {
-
-
}
///////////////////////////////////////////////////////////////////
#if 0
bool EditorSamplePreviewPlugin::handles(const String& p_type) const {
- return ClassDB::is_type(p_type,"Sample");
+ return ClassDB::is_parent_class(p_type,"Sample");
}
Ref<Texture> EditorSamplePreviewPlugin::generate(const RES& p_from) {
@@ -795,105 +772,108 @@ EditorSamplePreviewPlugin::EditorSamplePreviewPlugin() {
#endif
///////////////////////////////////////////////////////////////////////////
-bool EditorMeshPreviewPlugin::handles(const String& p_type) const {
+void EditorMeshPreviewPlugin::_preview_done(const Variant &p_udata) {
- return ClassDB::is_type(p_type,"Mesh"); //any Mesh
+ preview_done = true;
}
-Ref<Texture> EditorMeshPreviewPlugin::generate(const RES& p_from) {
+void EditorMeshPreviewPlugin::_bind_methods() {
+
+ ClassDB::bind_method("_preview_done", &EditorMeshPreviewPlugin::_preview_done);
+}
+bool EditorMeshPreviewPlugin::handles(const String &p_type) const {
+
+ return ClassDB::is_parent_class(p_type, "Mesh"); //any Mesh
+}
+Ref<Texture> EditorMeshPreviewPlugin::generate(const RES &p_from) {
+
+ print_line("**Generating for mesh finally??");
Ref<Mesh> mesh = p_from;
- ERR_FAIL_COND_V(mesh.is_null(),Ref<Texture>());
+ ERR_FAIL_COND_V(mesh.is_null(), Ref<Texture>());
- VS::get_singleton()->instance_set_base(mesh_instance,mesh->get_rid());
+ VS::get_singleton()->instance_set_base(mesh_instance, mesh->get_rid());
- AABB aabb= mesh->get_aabb();
- Vector3 ofs = aabb.pos + aabb.size*0.5;
- aabb.pos-=ofs;
+ Rect3 aabb = mesh->get_aabb();
+ print_line("mesh aabb: " + aabb);
+ Vector3 ofs = aabb.position + aabb.size * 0.5;
+ aabb.position -= ofs;
Transform xform;
- xform.basis=Matrix3().rotated(Vector3(0,1,0),-Math_PI*0.125);
- xform.basis = Matrix3().rotated(Vector3(1,0,0),Math_PI*0.125)*xform.basis;
- AABB rot_aabb = xform.xform(aabb);
- float m = MAX(rot_aabb.size.x,rot_aabb.size.y)*0.5;
- if (m==0)
+ xform.basis = Basis().rotated(Vector3(0, 1, 0), -Math_PI * 0.125);
+ xform.basis = Basis().rotated(Vector3(1, 0, 0), Math_PI * 0.125) * xform.basis;
+ Rect3 rot_aabb = xform.xform(aabb);
+ float m = MAX(rot_aabb.size.x, rot_aabb.size.y) * 0.5;
+ if (m == 0)
return Ref<Texture>();
- m=1.0/m;
- m*=0.5;
+ m = 1.0 / m;
+ m *= 0.5;
//print_line("scale: "+rtos(m));
- xform.basis.scale(Vector3(m,m,m));
- xform.origin=-xform.basis.xform(ofs); //-ofs*m;
- xform.origin.z-=rot_aabb.size.z*2;
- VS::get_singleton()->instance_set_transform(mesh_instance,xform);
-
+ xform.basis.scale(Vector3(m, m, m));
+ xform.origin = -xform.basis.xform(ofs); //-ofs*m;
+ xform.origin.z -= rot_aabb.size.z * 2;
+ VS::get_singleton()->instance_set_transform(mesh_instance, xform);
-
- VS::get_singleton()->viewport_queue_screen_capture(viewport);
- VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_ONCE); //once used for capture
+ VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_ONCE); //once used for capture
//print_line("queue capture!");
- Image img;
- int timeout=1000;
- while(timeout) {
- //print_line("try capture?");
+ preview_done = false;
+ VS::get_singleton()->request_frame_drawn_callback(this, "_preview_done", Variant());
+
+ while (!preview_done) {
OS::get_singleton()->delay_usec(10);
- img = VS::get_singleton()->viewport_get_screen_capture(viewport);
- if (!img.empty())
- break;
- timeout--;
}
- //print_line("captured!");
- VS::get_singleton()->instance_set_base(mesh_instance,RID());
+ Ref<Image> img = VS::get_singleton()->VS::get_singleton()->texture_get_data(viewport_texture);
+ ERR_FAIL_COND_V(img.is_null(), Ref<ImageTexture>());
+
+ print_line("captured! " + itos(img->get_width()) + "x" + itos(img->get_height()));
+ VS::get_singleton()->instance_set_base(mesh_instance, RID());
int thumbnail_size = EditorSettings::get_singleton()->get("filesystem/file_dialog/thumbnail_size");
- thumbnail_size*=EDSCALE;
- img.resize(thumbnail_size,thumbnail_size);
+ thumbnail_size *= EDSCALE;
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(thumbnail_size, thumbnail_size);
- Ref<ImageTexture> ptex = Ref<ImageTexture>( memnew( ImageTexture ));
- ptex->create_from_image(img,0);
+ Ref<ImageTexture> ptex = Ref<ImageTexture>(memnew(ImageTexture));
+ ptex->create_from_image(img, 0);
return ptex;
}
EditorMeshPreviewPlugin::EditorMeshPreviewPlugin() {
scenario = VS::get_singleton()->scenario_create();
+
viewport = VS::get_singleton()->viewport_create();
- VS::get_singleton()->viewport_set_as_render_target(viewport,true);
- VS::get_singleton()->viewport_set_render_target_update_mode(viewport,VS::RENDER_TARGET_UPDATE_DISABLED);
- VS::get_singleton()->viewport_set_scenario(viewport,scenario);
- VS::ViewportRect vr;
- vr.x=0;
- vr.y=0;
- vr.width=128;
- vr.height=128;
- VS::get_singleton()->viewport_set_rect(viewport,vr);
+ VS::get_singleton()->viewport_set_update_mode(viewport, VS::VIEWPORT_UPDATE_DISABLED);
+ VS::get_singleton()->viewport_set_vflip(viewport, true);
+ VS::get_singleton()->viewport_set_scenario(viewport, scenario);
+ VS::get_singleton()->viewport_set_size(viewport, 128, 128);
+ VS::get_singleton()->viewport_set_transparent_background(viewport, true);
+ VS::get_singleton()->viewport_set_active(viewport, true);
+ viewport_texture = VS::get_singleton()->viewport_get_texture(viewport);
camera = VS::get_singleton()->camera_create();
- VS::get_singleton()->viewport_attach_camera(viewport,camera);
- VS::get_singleton()->camera_set_transform(camera,Transform(Matrix3(),Vector3(0,0,3)));
+ VS::get_singleton()->viewport_attach_camera(viewport, camera);
+ VS::get_singleton()->camera_set_transform(camera, Transform(Basis(), Vector3(0, 0, 3)));
//VS::get_singleton()->camera_set_perspective(camera,45,0.1,10);
- VS::get_singleton()->camera_set_orthogonal(camera,1.0,0.01,1000.0);
+ VS::get_singleton()->camera_set_orthogonal(camera, 1.0, 0.01, 1000.0);
light = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
- light_instance = VS::get_singleton()->instance_create2(light,scenario);
- VS::get_singleton()->instance_set_transform(light_instance,Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
+ light_instance = VS::get_singleton()->instance_create2(light, scenario);
+ VS::get_singleton()->instance_set_transform(light_instance, Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0)));
light2 = VS::get_singleton()->light_create(VS::LIGHT_DIRECTIONAL);
- VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_DIFFUSE,Color(0.7,0.7,0.7));
- VS::get_singleton()->light_set_color(light2,VS::LIGHT_COLOR_SPECULAR,Color(0.0,0.0,0.0));
- light_instance2 = VS::get_singleton()->instance_create2(light2,scenario);
+ VS::get_singleton()->light_set_color(light2, Color(0.7, 0.7, 0.7));
+ //VS::get_singleton()->light_set_color(light2, VS::LIGHT_COLOR_SPECULAR, Color(0.0, 0.0, 0.0));
+ light_instance2 = VS::get_singleton()->instance_create2(light2, scenario);
- VS::get_singleton()->instance_set_transform(light_instance2,Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
+ VS::get_singleton()->instance_set_transform(light_instance2, Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
//sphere = VS::get_singleton()->mesh_create();
mesh_instance = VS::get_singleton()->instance_create();
- VS::get_singleton()->instance_set_scenario(mesh_instance,scenario);
-
-
-
+ VS::get_singleton()->instance_set_scenario(mesh_instance, scenario);
}
-
EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
//VS::get_singleton()->free(sphere);
@@ -905,6 +885,4 @@ EditorMeshPreviewPlugin::~EditorMeshPreviewPlugin() {
VS::get_singleton()->free(light_instance2);
VS::get_singleton()->free(camera);
VS::get_singleton()->free(scenario);
-
}
-#endif
diff --git a/editor/plugins/editor_preview_plugins.h b/editor/plugins/editor_preview_plugins.h
index 993e36df02..7e7d36eb1e 100644
--- a/editor/plugins/editor_preview_plugins.h
+++ b/editor/plugins/editor_preview_plugins.h
@@ -32,55 +32,58 @@
#include "editor/editor_resource_preview.h"
-#if 0
class EditorTexturePreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorTexturePreviewPlugin, EditorResourcePreviewGenerator)
public:
-
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
EditorTexturePreviewPlugin();
};
-
class EditorBitmapPreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorBitmapPreviewPlugin, EditorResourcePreviewGenerator)
public:
-
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
EditorBitmapPreviewPlugin();
};
-
-
class EditorPackedScenePreviewPlugin : public EditorResourcePreviewGenerator {
- Ref<Texture> _gen_from_imd(Ref<ResourceImportMetadata> p_imd);
public:
-
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
- virtual Ref<Texture> generate_from_path(const String& p_path);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
+ virtual Ref<Texture> generate_from_path(const String &p_path);
EditorPackedScenePreviewPlugin();
};
class EditorMaterialPreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorMaterialPreviewPlugin, EditorResourcePreviewGenerator)
+
RID scenario;
RID sphere;
RID sphere_instance;
RID viewport;
+ RID viewport_texture;
RID light;
RID light_instance;
RID light2;
RID light_instance2;
RID camera;
-public:
+ volatile bool preview_done;
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
+ void _preview_done(const Variant &p_udata);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
EditorMaterialPreviewPlugin();
~EditorMaterialPreviewPlugin();
@@ -88,9 +91,8 @@ public:
class EditorScriptPreviewPlugin : public EditorResourcePreviewGenerator {
public:
-
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
EditorScriptPreviewPlugin();
};
@@ -108,22 +110,30 @@ public:
#endif
class EditorMeshPreviewPlugin : public EditorResourcePreviewGenerator {
+ GDCLASS(EditorMeshPreviewPlugin, EditorResourcePreviewGenerator)
+
RID scenario;
RID mesh_instance;
RID viewport;
+ RID viewport_texture;
RID light;
RID light_instance;
RID light2;
RID light_instance2;
RID camera;
-public:
+ volatile bool preview_done;
- virtual bool handles(const String& p_type) const;
- virtual Ref<Texture> generate(const RES& p_from);
+ void _preview_done(const Variant &p_udata);
+
+protected:
+ static void _bind_methods();
+
+public:
+ virtual bool handles(const String &p_type) const;
+ virtual Ref<Texture> generate(const RES &p_from);
EditorMeshPreviewPlugin();
~EditorMeshPreviewPlugin();
};
-#endif
#endif // EDITORPREVIEWPLUGINS_H
diff --git a/editor/plugins/color_ramp_editor_plugin.cpp b/editor/plugins/gradient_editor_plugin.cpp
index 63369e5475..9884db934b 100644
--- a/editor/plugins/color_ramp_editor_plugin.cpp
+++ b/editor/plugins/gradient_editor_plugin.cpp
@@ -27,15 +27,15 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "color_ramp_editor_plugin.h"
+#include "gradient_editor_plugin.h"
#include "canvas_item_editor_plugin.h"
#include "spatial_editor_plugin.h"
-ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
+GradientEditorPlugin::GradientEditorPlugin(EditorNode *p_node) {
editor = p_node;
- ramp_editor = memnew(ColorRampEdit);
+ ramp_editor = memnew(GradientEdit);
add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, ramp_editor);
@@ -44,21 +44,21 @@ ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
ramp_editor->connect("ramp_changed", this, "ramp_changed");
}
-void ColorRampEditorPlugin::edit(Object *p_object) {
+void GradientEditorPlugin::edit(Object *p_object) {
- ColorRamp *color_ramp = p_object->cast_to<ColorRamp>();
- if (!color_ramp)
+ Gradient *gradient = p_object->cast_to<Gradient>();
+ if (!gradient)
return;
- color_ramp_ref = Ref<ColorRamp>(color_ramp);
- ramp_editor->set_points(color_ramp_ref->get_points());
+ gradient_ref = Ref<Gradient>(gradient);
+ ramp_editor->set_points(gradient_ref->get_points());
}
-bool ColorRampEditorPlugin::handles(Object *p_object) const {
+bool GradientEditorPlugin::handles(Object *p_object) const {
- return p_object->is_class("ColorRamp");
+ return p_object->is_class("Gradient");
}
-void ColorRampEditorPlugin::make_visible(bool p_visible) {
+void GradientEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
ramp_editor->show();
@@ -67,43 +67,43 @@ void ColorRampEditorPlugin::make_visible(bool p_visible) {
}
}
-void ColorRampEditorPlugin::_ramp_changed() {
+void GradientEditorPlugin::_ramp_changed() {
- if (color_ramp_ref.is_valid()) {
+ if (gradient_ref.is_valid()) {
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
//Not sure if I should convert this data to PoolVector
Vector<float> new_offsets = ramp_editor->get_offsets();
Vector<Color> new_colors = ramp_editor->get_colors();
- Vector<float> old_offsets = color_ramp_ref->get_offsets();
- Vector<Color> old_colors = color_ramp_ref->get_colors();
+ Vector<float> old_offsets = gradient_ref->get_offsets();
+ Vector<Color> old_colors = gradient_ref->get_colors();
if (old_offsets.size() != new_offsets.size())
ur->create_action(TTR("Add/Remove Color Ramp Point"));
else
ur->create_action(TTR("Modify Color Ramp"), UndoRedo::MERGE_ENDS);
- ur->add_do_method(this, "undo_redo_color_ramp", new_offsets, new_colors);
- ur->add_undo_method(this, "undo_redo_color_ramp", old_offsets, old_colors);
+ ur->add_do_method(this, "undo_redo_gradient", new_offsets, new_colors);
+ ur->add_undo_method(this, "undo_redo_gradient", old_offsets, old_colors);
ur->commit_action();
//color_ramp_ref->set_points(ramp_editor->get_points());
}
}
-void ColorRampEditorPlugin::_undo_redo_color_ramp(const Vector<float> &offsets,
+void GradientEditorPlugin::_undo_redo_gradient(const Vector<float> &offsets,
const Vector<Color> &colors) {
- color_ramp_ref->set_offsets(offsets);
- color_ramp_ref->set_colors(colors);
- ramp_editor->set_points(color_ramp_ref->get_points());
+ gradient_ref->set_offsets(offsets);
+ gradient_ref->set_colors(colors);
+ ramp_editor->set_points(gradient_ref->get_points());
ramp_editor->update();
}
-ColorRampEditorPlugin::~ColorRampEditorPlugin() {
+GradientEditorPlugin::~GradientEditorPlugin() {
}
-void ColorRampEditorPlugin::_bind_methods() {
- ClassDB::bind_method(D_METHOD("ramp_changed"), &ColorRampEditorPlugin::_ramp_changed);
- ClassDB::bind_method(D_METHOD("undo_redo_color_ramp", "offsets", "colors"), &ColorRampEditorPlugin::_undo_redo_color_ramp);
+void GradientEditorPlugin::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("ramp_changed"), &GradientEditorPlugin::_ramp_changed);
+ ClassDB::bind_method(D_METHOD("undo_redo_gradient", "offsets", "colors"), &GradientEditorPlugin::_undo_redo_gradient);
}
diff --git a/editor/plugins/color_ramp_editor_plugin.h b/editor/plugins/gradient_editor_plugin.h
index 73b15b85a1..843e98a917 100644
--- a/editor/plugins/color_ramp_editor_plugin.h
+++ b/editor/plugins/gradient_editor_plugin.h
@@ -32,21 +32,21 @@
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
-#include "scene/gui/color_ramp_edit.h"
+#include "scene/gui/gradient_edit.h"
-class ColorRampEditorPlugin : public EditorPlugin {
+class GradientEditorPlugin : public EditorPlugin {
- GDCLASS(ColorRampEditorPlugin, EditorPlugin);
+ GDCLASS(GradientEditorPlugin, EditorPlugin);
bool _2d;
- Ref<ColorRamp> color_ramp_ref;
- ColorRampEdit *ramp_editor;
+ Ref<Gradient> gradient_ref;
+ GradientEdit *ramp_editor;
EditorNode *editor;
protected:
static void _bind_methods();
void _ramp_changed();
- void _undo_redo_color_ramp(const Vector<float> &offsets, const Vector<Color> &colors);
+ void _undo_redo_gradient(const Vector<float> &offsets, const Vector<Color> &colors);
public:
virtual String get_name() const { return "ColorRamp"; }
@@ -55,8 +55,8 @@ public:
virtual bool handles(Object *p_node) const;
virtual void make_visible(bool p_visible);
- ColorRampEditorPlugin(EditorNode *p_node);
- ~ColorRampEditorPlugin();
+ GradientEditorPlugin(EditorNode *p_node);
+ ~GradientEditorPlugin();
};
#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */
diff --git a/editor/plugins/gradient_texture_editor_plugin.cpp b/editor/plugins/gradient_texture_editor_plugin.cpp
index 41dd64d931..bc985dcdf7 100644
--- a/editor/plugins/gradient_texture_editor_plugin.cpp
+++ b/editor/plugins/gradient_texture_editor_plugin.cpp
@@ -48,7 +48,8 @@ GradientTextureEdit::GradientTextureEdit() {
add_child(popup);
checker = Ref<ImageTexture>(memnew(ImageTexture));
- checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+ Ref<Image> checker_bg = memnew(Image(checker_bg_png));
+ checker->create_from_image(checker_bg, ImageTexture::FLAG_REPEAT);
}
int GradientTextureEdit::_get_point_from_pos(int x) {
@@ -76,9 +77,11 @@ void GradientTextureEdit::_show_color_picker() {
GradientTextureEdit::~GradientTextureEdit() {
}
-void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
+void GradientTextureEdit::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) {
points.remove(grabbed);
grabbed = -1;
@@ -88,16 +91,17 @@ void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
accept_event();
}
+ Ref<InputEventMouseButton> mb = p_event;
//Show color picker on double click.
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
- grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) {
+ grabbed = _get_point_from_pos(mb->get_position().x);
_show_color_picker();
accept_event();
}
//Delete point on right click
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 2 && p_event.mouse_button.pressed) {
- grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) {
+ grabbed = _get_point_from_pos(mb->get_position().x);
if (grabbed != -1) {
points.remove(grabbed);
grabbed = -1;
@@ -109,9 +113,9 @@ void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
}
//Hold alt key to duplicate selected color
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed && p_event.key.mod.alt) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) {
- int x = p_event.mouse_button.x;
+ int x = mb->get_position().x;
grabbed = _get_point_from_pos(x);
if (grabbed != -1) {
@@ -133,10 +137,10 @@ void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
update();
- int x = p_event.mouse_button.x;
+ int x = mb->get_position().x;
int total_w = get_size().width - get_size().height - 3;
//Check if color selector was clicked.
@@ -201,7 +205,7 @@ void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
emit_signal("ramp_changed");
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
if (grabbing) {
grabbing = false;
@@ -210,15 +214,17 @@ void GradientTextureEdit::_gui_input(const InputEvent &p_event) {
update();
}
- if (p_event.type == InputEvent::MOUSE_MOTION && grabbing) {
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid() && grabbing) {
int total_w = get_size().width - get_size().height - 3;
- int x = p_event.mouse_motion.x;
+ int x = mm->get_position().x;
float newofs = CLAMP(x / float(total_w), 0, 1);
//Snap to nearest point if holding shift
- if (p_event.key.mod.shift) {
+ if (mm->get_shift()) {
float snap_treshhold = 0.03;
float smallest_ofs = snap_treshhold;
bool founded = false;
diff --git a/editor/plugins/gradient_texture_editor_plugin.h b/editor/plugins/gradient_texture_editor_plugin.h
index cb2f6b4061..842d586541 100644
--- a/editor/plugins/gradient_texture_editor_plugin.h
+++ b/editor/plugins/gradient_texture_editor_plugin.h
@@ -53,7 +53,7 @@ class GradientTextureEdit : public Control {
void _show_color_picker();
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
static void _bind_methods();
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.cpp b/editor/plugins/light_occluder_2d_editor_plugin.cpp
index 73b615d817..09021446dc 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.cpp
+++ b/editor/plugins/light_occluder_2d_editor_plugin.cpp
@@ -98,225 +98,223 @@ void LightOccluder2DEditor::_wip_close(bool p_closed) {
edited_point = -1;
}
-bool LightOccluder2DEditor::forward_gui_input(const InputEvent &p_event) {
+bool LightOccluder2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
if (node->get_occluder_polygon().is_null()) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+ Ref<InputEventMouseButton> mb = p_event;
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?");
create_poly->popup_centered_minsize();
}
- return (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1);
+ return (mb.is_valid() && mb->get_button_index() == 1);
}
- switch (p_event.type) {
- case InputEvent::MOUSE_BUTTON: {
+ Ref<InputEventMouseButton> mb = p_event;
- const InputEventMouseButton &mb = p_event.mouse_button;
+ if (mb.is_valid()) {
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
- Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon());
+ Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon());
- //first check if a point is to be added (segment split)
- real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- switch (mode) {
+ switch (mode) {
- case MODE_CREATE: {
+ case MODE_CREATE: {
- if (mb.button_index == BUTTON_LEFT && mb.pressed) {
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- if (!wip_active) {
+ if (!wip_active) {
- wip.clear();
- wip.push_back(cpoint);
- wip_active = true;
- edited_point_pos = cpoint;
- canvas_item_editor->get_viewport_control()->update();
- edited_point = 1;
- return true;
- } else {
+ wip.clear();
+ wip.push_back(cpoint);
+ wip_active = true;
+ edited_point_pos = cpoint;
+ canvas_item_editor->get_viewport_control()->update();
+ edited_point = 1;
+ return true;
+ } else {
- if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
- //wip closed
- _wip_close(true);
+ if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close(true);
- return true;
- } else if (wip.size() > 1 && xform.xform(wip[wip.size() - 1]).distance_to(gpoint) < grab_treshold) {
- //wip closed
- _wip_close(false);
- return true;
+ return true;
+ } else if (wip.size() > 1 && xform.xform(wip[wip.size() - 1]).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close(false);
+ return true;
- } else {
+ } else {
- wip.push_back(cpoint);
- edited_point = wip.size();
- canvas_item_editor->get_viewport_control()->update();
- return true;
+ wip.push_back(cpoint);
+ edited_point = wip.size();
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
- //add wip point
- }
+ //add wip point
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && wip_active) {
- _wip_close(true);
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close(true);
+ }
- } break;
-
- case MODE_EDIT: {
-
- if (mb.button_index == BUTTON_LEFT) {
- if (mb.pressed) {
-
- if (mb.mod.control) {
+ } break;
- if (poly.size() < 3) {
+ case MODE_EDIT: {
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- poly.push_back(cpoint);
- undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- return true;
- }
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- //search edges
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
-
- Vector2 points[2] = { xform.xform(poly[i]),
- xform.xform(poly[(i + 1) % poly.size()]) };
-
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
- if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
- continue; //not valid to reuse point
-
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
- }
+ if (mb->get_control()) {
- if (closest_idx >= 0) {
+ if (poly.size() < 3) {
- pre_move_edit = poly;
- poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
- edited_point = closest_idx + 1;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- node->get_occluder_polygon()->set_polygon(Variant(poly));
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
- } else {
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
- //look for points to move
+ //search edges
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
+ Vector2 points[2] = { xform.xform(poly[i]),
+ xform.xform(poly[(i + 1) % poly.size()]) };
- Vector2 cp = xform.xform(poly[i]);
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ continue; //not valid to reuse point
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
}
+ }
- if (closest_idx >= 0) {
+ if (closest_idx >= 0) {
- pre_move_edit = poly;
- edited_point = closest_idx;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
+ pre_move_edit = poly;
+ poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
+ edited_point = closest_idx + 1;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ node->get_occluder_polygon()->set_polygon(Variant(poly));
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
} else {
- if (edited_point != -1) {
+ //look for points to move
- //apply
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos;
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ Vector2 cp = xform.xform(poly[i]);
- edited_point = -1;
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
}
- }
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && edited_point == -1) {
-
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
- Vector2 cp = xform.xform(poly[i]);
+ if (closest_idx >= 0) {
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
+ pre_move_edit = poly;
+ edited_point = closest_idx;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
}
+ } else {
+
+ if (edited_point != -1) {
- if (closest_idx >= 0) {
+ //apply
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
- poly.remove(closest_idx);
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly[edited_point] = edited_point_pos;
+ undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
+ undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", pre_move_edit);
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->commit_action();
+
+ edited_point = -1;
return true;
}
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
- } break;
- }
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- } break;
- case InputEvent::MOUSE_MOTION: {
+ Vector2 cp = xform.xform(poly[i]);
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
+ }
- if (edited_point != -1 && (wip_active || mm.button_mask & BUTTON_MASK_LEFT)) {
+ if (closest_idx >= 0) {
- Vector2 gpoint = Point2(mm.x, mm.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node->get_occluder_polygon().ptr(), "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
+ }
- canvas_item_editor->get_viewport_control()->update();
- }
+ } break;
+ }
+ }
- } break;
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+
+ if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
+
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+
+ canvas_item_editor->get_viewport_control()->update();
+ }
}
return false;
diff --git a/editor/plugins/light_occluder_2d_editor_plugin.h b/editor/plugins/light_occluder_2d_editor_plugin.h
index 8e0817e61e..d6579fc94c 100644
--- a/editor/plugins/light_occluder_2d_editor_plugin.h
+++ b/editor/plugins/light_occluder_2d_editor_plugin.h
@@ -84,7 +84,7 @@ protected:
public:
Vector2 snap_point(const Vector2 &p_point) const;
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
LightOccluder2DEditor(EditorNode *p_editor);
};
@@ -97,7 +97,7 @@ class LightOccluder2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "LightOccluder2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/line_2d_editor_plugin.cpp b/editor/plugins/line_2d_editor_plugin.cpp
index 4df0d2605a..76906a5b93 100644
--- a/editor/plugins/line_2d_editor_plugin.cpp
+++ b/editor/plugins/line_2d_editor_plugin.cpp
@@ -75,7 +75,7 @@ int Line2DEditor::get_point_index_at(Vector2 gpos) {
return -1;
}
-bool Line2DEditor::forward_gui_input(const InputEvent &p_event) {
+bool Line2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
@@ -83,75 +83,74 @@ bool Line2DEditor::forward_gui_input(const InputEvent &p_event) {
if (!node->is_visible())
return false;
- switch (p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- const InputEventMouseButton &mb = p_event.mouse_button;
-
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = mouse_to_local_pos(gpoint, mb.mod.alt);
-
- if (mb.pressed && _dragging == false) {
- int i = get_point_index_at(gpoint);
- if (i != -1) {
- if (mb.button_index == BUTTON_LEFT && !mb.mod.shift && mode == MODE_EDIT) {
- _dragging = true;
- action_point = i;
- moving_from = node->get_point_pos(i);
- moving_screen_from = gpoint;
- } else if ((mb.button_index == BUTTON_RIGHT && mode == MODE_EDIT) || (mb.button_index == BUTTON_LEFT && mode == MODE_DELETE)) {
- undo_redo->create_action(TTR("Remove Point from Line2D"));
- undo_redo->add_do_method(node, "remove_point", i);
- undo_redo->add_undo_method(node, "add_point", node->get_point_pos(i), i);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- }
- return true;
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid()) {
+
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = mouse_to_local_pos(gpoint, mb->get_alt());
+
+ if (mb->is_pressed() && _dragging == false) {
+ int i = get_point_index_at(gpoint);
+ if (i != -1) {
+ if (mb->get_button_index() == BUTTON_LEFT && !mb->get_shift() && mode == MODE_EDIT) {
+ _dragging = true;
+ action_point = i;
+ moving_from = node->get_point_pos(i);
+ moving_screen_from = gpoint;
+ } else if ((mb->get_button_index() == BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == BUTTON_LEFT && mode == MODE_DELETE)) {
+ undo_redo->create_action(TTR("Remove Point from Line2D"));
+ undo_redo->add_do_method(node, "remove_point", i);
+ undo_redo->add_undo_method(node, "add_point", node->get_point_pos(i), i);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
}
+ return true;
}
+ }
- if (mb.pressed && mb.button_index == BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
- undo_redo->create_action(TTR("Add Point to Line2D"));
- undo_redo->add_do_method(node, "add_point", cpoint);
- undo_redo->add_undo_method(node, "remove_point", node->get_point_count());
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ undo_redo->create_action(TTR("Add Point to Line2D"));
+ undo_redo->add_do_method(node, "add_point", cpoint);
+ undo_redo->add_undo_method(node, "remove_point", node->get_point_count());
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- _dragging = true;
- action_point = node->get_point_count() - 1;
- moving_from = node->get_point_pos(action_point);
- moving_screen_from = gpoint;
+ _dragging = true;
+ action_point = node->get_point_count() - 1;
+ moving_from = node->get_point_pos(action_point);
+ moving_screen_from = gpoint;
- canvas_item_editor->get_viewport_control()->update();
+ canvas_item_editor->get_viewport_control()->update();
- return true;
- }
+ return true;
+ }
- if (!mb.pressed && mb.button_index == BUTTON_LEFT && _dragging) {
- undo_redo->create_action(TTR("Move Point in Line2D"));
- undo_redo->add_do_method(node, "set_point_pos", action_point, cpoint);
- undo_redo->add_undo_method(node, "set_point_pos", action_point, moving_from);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- _dragging = false;
- return true;
- }
- } break;
-
- case InputEvent::MOUSE_MOTION: {
- if (_dragging) {
- const InputEventMouseMotion &mm = p_event.mouse_motion;
- Vector2 cpoint = mouse_to_local_pos(Vector2(mm.x, mm.y), mm.mod.alt);
- node->set_point_pos(action_point, cpoint);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
- } break;
+ if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && _dragging) {
+ undo_redo->create_action(TTR("Move Point in Line2D"));
+ undo_redo->add_do_method(node, "set_point_pos", action_point, cpoint);
+ undo_redo->add_undo_method(node, "set_point_pos", action_point, moving_from);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ _dragging = false;
+ return true;
+ }
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+
+ if (_dragging) {
+ Vector2 cpoint = mouse_to_local_pos(mm->get_position(), mm->get_alt());
+ node->set_point_pos(action_point, cpoint);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
}
return false;
diff --git a/editor/plugins/line_2d_editor_plugin.h b/editor/plugins/line_2d_editor_plugin.h
index 7477f7eee5..3a1f841556 100644
--- a/editor/plugins/line_2d_editor_plugin.h
+++ b/editor/plugins/line_2d_editor_plugin.h
@@ -43,7 +43,7 @@ class Line2DEditor : public HBoxContainer {
GDCLASS(Line2DEditor, HBoxContainer)
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_line2d);
Line2DEditor(EditorNode *p_editor);
@@ -95,7 +95,7 @@ class Line2DEditorPlugin : public EditorPlugin {
public:
virtual bool forward_canvas_gui_input(
const Transform2D &p_canvas_xform,
- const InputEvent &p_event) {
+ const Ref<InputEvent> &p_event) {
return line2d_editor->forward_gui_input(p_event);
}
diff --git a/editor/plugins/mesh_editor_plugin.cpp b/editor/plugins/mesh_editor_plugin.cpp
index 61da860cab..f377d3a7cc 100644
--- a/editor/plugins/mesh_editor_plugin.cpp
+++ b/editor/plugins/mesh_editor_plugin.cpp
@@ -33,10 +33,10 @@
void MeshEditor::_gui_input(InputEvent p_event) {
- if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
+ if (p_event.type==InputEvent::MOUSE_MOTION && p_event->get_button_mask()&BUTTON_MASK_LEFT) {
- rot_x-=p_event.mouse_motion.relative_y*0.01;
- rot_y-=p_event.mouse_motion.relative_x*0.01;
+ rot_x-=p_event->get_relative().y*0.01;
+ rot_y-=p_event->get_relative().x*0.01;
if (rot_x<-Math_PI/2)
rot_x=-Math_PI/2;
else if (rot_x>Math_PI/2) {
diff --git a/editor/plugins/navigation_polygon_editor_plugin.cpp b/editor/plugins/navigation_polygon_editor_plugin.cpp
index be8c46f379..1457b28ed1 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.cpp
+++ b/editor/plugins/navigation_polygon_editor_plugin.cpp
@@ -112,263 +112,262 @@ void NavigationPolygonEditor::_wip_close() {
edited_point = -1;
}
-bool NavigationPolygonEditor::forward_gui_input(const InputEvent &p_event) {
+bool NavigationPolygonEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
if (node->get_navigation_polygon().is_null()) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
create_nav->set_text("No NavigationPolygon resource on this node.\nCreate and assign one?");
create_nav->popup_centered_minsize();
}
- return (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1);
+ return (mb.is_valid() && mb->get_button_index() == 1);
}
- switch (p_event.type) {
+ Ref<InputEventMouseButton> mb = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb = p_event.mouse_button;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- //first check if a point is to be added (segment split)
- real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
+ switch (mode) {
- switch (mode) {
+ case MODE_CREATE: {
- case MODE_CREATE: {
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- if (mb.button_index == BUTTON_LEFT && mb.pressed) {
+ if (!wip_active) {
- if (!wip_active) {
+ wip.clear();
+ wip.push_back(cpoint);
+ wip_active = true;
+ edited_point_pos = cpoint;
+ edited_outline = -1;
+ canvas_item_editor->get_viewport_control()->update();
+ edited_point = 1;
+ return true;
+ } else {
+
+ if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close();
- wip.clear();
- wip.push_back(cpoint);
- wip_active = true;
- edited_point_pos = cpoint;
- edited_outline = -1;
- canvas_item_editor->get_viewport_control()->update();
- edited_point = 1;
return true;
} else {
- if (wip.size() > 1 && xform.xform(wip[0]).distance_to(gpoint) < grab_treshold) {
- //wip closed
- _wip_close();
-
- return true;
- } else {
-
- wip.push_back(cpoint);
- edited_point = wip.size();
- canvas_item_editor->get_viewport_control()->update();
- return true;
+ wip.push_back(cpoint);
+ edited_point = wip.size();
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
- //add wip point
- }
+ //add wip point
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && wip_active) {
- _wip_close();
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close();
+ }
- } break;
+ } break;
- case MODE_EDIT: {
+ case MODE_EDIT: {
- if (mb.button_index == BUTTON_LEFT) {
- if (mb.pressed) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- if (mb.mod.control) {
+ if (mb->get_control()) {
- //search edges
- int closest_outline = -1;
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
+ //search edges
+ int closest_outline = -1;
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
- for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
+ for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
- PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
+ PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
- int pc = points.size();
- PoolVector<Vector2>::Read poly = points.read();
+ int pc = points.size();
+ PoolVector<Vector2>::Read poly = points.read();
- for (int i = 0; i < pc; i++) {
+ for (int i = 0; i < pc; i++) {
- Vector2 points[2] = { xform.xform(poly[i]),
- xform.xform(poly[(i + 1) % pc]) };
+ Vector2 points[2] = { xform.xform(poly[i]),
+ xform.xform(poly[(i + 1) % pc]) };
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
- if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
- continue; //not valid to reuse point
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ continue; //not valid to reuse point
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_outline = j;
- closest_pos = cp;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_outline = j;
+ closest_pos = cp;
+ closest_idx = i;
}
}
+ }
- if (closest_idx >= 0) {
-
- pre_move_edit = node->get_navigation_polygon()->get_outline(closest_outline);
- PoolVector<Point2> poly = pre_move_edit;
- poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
- edited_point = closest_idx + 1;
- edited_outline = closest_outline;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- node->get_navigation_polygon()->set_outline(closest_outline, poly);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
- } else {
+ if (closest_idx >= 0) {
+
+ pre_move_edit = node->get_navigation_polygon()->get_outline(closest_outline);
+ PoolVector<Point2> poly = pre_move_edit;
+ poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos));
+ edited_point = closest_idx + 1;
+ edited_outline = closest_outline;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ node->get_navigation_polygon()->set_outline(closest_outline, poly);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
+ } else {
- //look for points to move
- int closest_outline = -1;
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
+ //look for points to move
+ int closest_outline = -1;
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
- for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
+ for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
- PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
+ PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
- int pc = points.size();
- PoolVector<Vector2>::Read poly = points.read();
+ int pc = points.size();
+ PoolVector<Vector2>::Read poly = points.read();
- for (int i = 0; i < pc; i++) {
+ for (int i = 0; i < pc; i++) {
- Vector2 cp = xform.xform(poly[i]);
+ Vector2 cp = xform.xform(poly[i]);
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_outline = j;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_outline = j;
+ closest_idx = i;
}
}
+ }
- if (closest_idx >= 0) {
+ if (closest_idx >= 0) {
- pre_move_edit = node->get_navigation_polygon()->get_outline(closest_outline);
- edited_point = closest_idx;
- edited_outline = closest_outline;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
+ pre_move_edit = node->get_navigation_polygon()->get_outline(closest_outline);
+ edited_point = closest_idx;
+ edited_outline = closest_outline;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
- } else {
+ }
+ } else {
- if (edited_point != -1) {
+ if (edited_point != -1) {
- //apply
+ //apply
- PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline);
- ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly.set(edited_point, edited_point_pos);
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "set_outline", edited_outline, poly);
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "set_outline", edited_outline, pre_move_edit);
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(edited_outline);
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly.set(edited_point, edited_point_pos);
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "set_outline", edited_outline, poly);
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "set_outline", edited_outline, pre_move_edit);
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- edited_point = -1;
- return true;
- }
+ edited_point = -1;
+ return true;
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && edited_point == -1) {
+ }
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
- int closest_outline = -1;
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
+ int closest_outline = -1;
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
- for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
+ for (int j = 0; j < node->get_navigation_polygon()->get_outline_count(); j++) {
- PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
+ PoolVector<Vector2> points = node->get_navigation_polygon()->get_outline(j);
- int pc = points.size();
- PoolVector<Vector2>::Read poly = points.read();
+ int pc = points.size();
+ PoolVector<Vector2>::Read poly = points.read();
- for (int i = 0; i < pc; i++) {
+ for (int i = 0; i < pc; i++) {
- Vector2 cp = xform.xform(poly[i]);
+ Vector2 cp = xform.xform(poly[i]);
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_outline = j;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_outline = j;
+ closest_idx = i;
}
}
+ }
- if (closest_idx >= 0) {
-
- PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline);
-
- if (poly.size() > 3) {
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "set_outline", closest_outline, poly);
- poly.remove(closest_idx);
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "set_outline", closest_outline, poly);
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- } else {
-
- undo_redo->create_action(TTR("Remove Poly And Point"));
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "add_outline_at_index", poly, closest_outline);
- poly.remove(closest_idx);
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "remove_outline", closest_outline);
- undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- }
- return true;
+ if (closest_idx >= 0) {
+
+ PoolVector<Vector2> poly = node->get_navigation_polygon()->get_outline(closest_outline);
+
+ if (poly.size() > 3) {
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "set_outline", closest_outline, poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "set_outline", closest_outline, poly);
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ } else {
+
+ undo_redo->create_action(TTR("Remove Poly And Point"));
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "add_outline_at_index", poly, closest_outline);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "remove_outline", closest_outline);
+ undo_redo->add_do_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_undo_method(node->get_navigation_polygon().ptr(), "make_polygons_from_outlines");
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
}
+ return true;
}
+ }
- } break;
- }
-
- } break;
- case InputEvent::MOUSE_MOTION: {
+ } break;
+ }
+ }
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ Ref<InputEventMouseMotion> mm = p_event;
- if (edited_point != -1 && (wip_active || mm.button_mask & BUTTON_MASK_LEFT)) {
+ if (mm.is_valid()) {
- Vector2 gpoint = Point2(mm.x, mm.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+ if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
- canvas_item_editor->get_viewport_control()->update();
- }
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
- } break;
+ canvas_item_editor->get_viewport_control()->update();
+ }
}
return false;
diff --git a/editor/plugins/navigation_polygon_editor_plugin.h b/editor/plugins/navigation_polygon_editor_plugin.h
index 6de77b5ef3..62a83983fd 100644
--- a/editor/plugins/navigation_polygon_editor_plugin.h
+++ b/editor/plugins/navigation_polygon_editor_plugin.h
@@ -85,7 +85,7 @@ protected:
static void _bind_methods();
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
NavigationPolygonEditor(EditorNode *p_editor);
};
@@ -98,7 +98,7 @@ class NavigationPolygonEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "NavigationPolygonInstance"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/particles_2d_editor_plugin.cpp b/editor/plugins/particles_2d_editor_plugin.cpp
index 35743ce0b3..c6c85d8be2 100644
--- a/editor/plugins/particles_2d_editor_plugin.cpp
+++ b/editor/plugins/particles_2d_editor_plugin.cpp
@@ -64,17 +64,18 @@ void Particles2DEditorPlugin::_file_selected(const String &p_file) {
int epc = epoints->get_value();
- Image img;
- Error err = ImageLoader::load_image(p_file, &img);
+ Ref<Image> img;
+ img.instance();
+ Error err = ImageLoader::load_image(p_file, img);
ERR_EXPLAIN(TTR("Error loading image:") + " " + p_file);
ERR_FAIL_COND(err != OK);
- img.convert(Image::FORMAT_LA8);
- ERR_FAIL_COND(img.get_format() != Image::FORMAT_LA8);
- Size2i s = Size2(img.get_width(), img.get_height());
+ img->convert(Image::FORMAT_LA8);
+ ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8);
+ Size2i s = Size2(img->get_width(), img->get_height());
ERR_FAIL_COND(s.width == 0 || s.height == 0);
- PoolVector<uint8_t> data = img.get_data();
+ PoolVector<uint8_t> data = img->get_data();
PoolVector<uint8_t>::Read r = data.read();
Vector<Point2i> valid_positions;
@@ -98,7 +99,7 @@ void Particles2DEditorPlugin::_file_selected(const String &p_file) {
epoints.resize(epc);
PoolVector<Point2>::Write w = epoints.write();
- Size2 extents = Size2(img.get_width() * 0.5, img.get_height() * 0.5);
+ Size2 extents = Size2(img->get_width() * 0.5, img->get_height() * 0.5);
for (int i = 0; i < epc; i++) {
diff --git a/editor/plugins/particles_editor_plugin.cpp b/editor/plugins/particles_editor_plugin.cpp
index 4c84e831c1..d918a3e24e 100644
--- a/editor/plugins/particles_editor_plugin.cpp
+++ b/editor/plugins/particles_editor_plugin.cpp
@@ -254,7 +254,7 @@ void ParticlesEditor::_generate_emission_points() {
for (int j = 0; j < 3; j++) {
if (i == 0 && j == 0)
- aabb.pos = r[i].vertex[j];
+ aabb.position = r[i].vertex[j];
else
aabb.expand_to(r[i].vertex[j]);
}
@@ -272,7 +272,7 @@ void ParticlesEditor::_generate_emission_points() {
dir[Math::rand() % 3] = 1.0;
Vector3 ofs = Vector3(1, 1, 1) - dir;
ofs = (Vector3(1, 1, 1) - dir) * Vector3(Math::randf(), Math::randf(), Math::randf()) * aabb.size;
- ofs += aabb.pos;
+ ofs += aabb.position;
Vector3 ofsv = ofs + aabb.size * dir;
@@ -329,7 +329,7 @@ void ParticlesEditor::_generate_emission_points() {
copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
}
- Image image(w, h, false, Image::FORMAT_RGBF, point_img);
+ Ref<Image> image = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img));
Ref<ImageTexture> tex;
tex.instance();
@@ -354,7 +354,7 @@ void ParticlesEditor::_generate_emission_points() {
copymem(iw.ptr(), r.ptr(), point_count * sizeof(float) * 3);
}
- Image image2(w, h, false, Image::FORMAT_RGBF, point_img2);
+ Ref<Image> image2 = memnew(Image(w, h, false, Image::FORMAT_RGBF, point_img2));
Ref<ImageTexture> tex2;
tex2.instance();
diff --git a/editor/plugins/path_2d_editor_plugin.cpp b/editor/plugins/path_2d_editor_plugin.cpp
index e00111b565..f9f16fea16 100644
--- a/editor/plugins/path_2d_editor_plugin.cpp
+++ b/editor/plugins/path_2d_editor_plugin.cpp
@@ -58,8 +58,7 @@ void Path2DEditor::_node_removed(Node *p_node) {
}
}
-bool Path2DEditor::forward_gui_input(const InputEvent &p_event) {
-
+bool Path2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node)
return false;
@@ -69,70 +68,50 @@ bool Path2DEditor::forward_gui_input(const InputEvent &p_event) {
if (!node->get_curve().is_valid())
return false;
- switch (p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- const InputEventMouseButton &mb = p_event.mouse_button;
-
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Ref<InputEventMouseButton> mb = p_event;
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = !mb.mod.alt ? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) : node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
+ if (mb.is_valid()) {
- //first check if a point is to be added (segment split)
- real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- // Test move point!!
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint =
+ !mb->get_alt() ?
+ canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) :
+ node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
- if (mb.pressed && action == ACTION_NONE) {
+ real_t grab_threshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- Ref<Curve2D> curve = node->get_curve();
+ if (mb->is_pressed() && action == ACTION_NONE) {
- for (int i = 0; i < curve->get_point_count(); i++) {
+ Ref<Curve2D> curve = node->get_curve();
- bool pointunder = false;
+ for (int i = 0; i < curve->get_point_count(); i++) {
- {
- Point2 p = xform.xform(curve->get_point_pos(i));
- if (gpoint.distance_to(p) < grab_treshold) {
+ real_t dist_to_p = gpoint.distance_to(xform.xform(curve->get_point_pos(i)));
+ real_t dist_to_p_out = gpoint.distance_to(xform.xform(curve->get_point_pos(i) + curve->get_point_out(i)));
+ real_t dist_to_p_in = gpoint.distance_to(xform.xform(curve->get_point_pos(i) + curve->get_point_in(i)));
- if (mb.button_index == BUTTON_LEFT && !mb.mod.shift && mode == MODE_EDIT) {
+ // Check for point movement start (for point + in/out controls).
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mode == MODE_EDIT && !mb->get_shift() && dist_to_p < grab_threshold) {
+ // Points can only be moved in edit mode.
- action = ACTION_MOVING_POINT;
- action_point = i;
- moving_from = curve->get_point_pos(i);
- moving_screen_from = gpoint;
- return true;
- } else if ((mb.button_index == BUTTON_RIGHT && mode == MODE_EDIT) || (mb.button_index == BUTTON_LEFT && mode == MODE_DELETE)) {
-
- undo_redo->create_action(TTR("Remove Point from Curve"));
- undo_redo->add_do_method(curve.ptr(), "remove_point", i);
- undo_redo->add_undo_method(curve.ptr(), "add_point", curve->get_point_pos(i), curve->get_point_in(i), curve->get_point_out(i), i);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- return true;
- } else
- pointunder = true;
- }
- }
-
- if (mb.button_index == BUTTON_LEFT && i < (curve->get_point_count() - 1)) {
- Point2 p = xform.xform(curve->get_point_pos(i) + curve->get_point_out(i));
- if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode == MODE_EDIT_CURVE)) {
+ action = ACTION_MOVING_POINT;
+ action_point = i;
+ moving_from = curve->get_point_pos(i);
+ moving_screen_from = gpoint;
+ return true;
+ } else if (mode == MODE_EDIT || mode == MODE_EDIT_CURVE) {
+ // In/out controls can be moved in multiple modes.
+ if (dist_to_p_out < grab_threshold && i < (curve->get_point_count() - 1)) {
action = ACTION_MOVING_OUT;
action_point = i;
moving_from = curve->get_point_out(i);
moving_screen_from = gpoint;
return true;
- }
- }
-
- if (mb.button_index == BUTTON_LEFT && i > 0) {
- Point2 p = xform.xform(curve->get_point_pos(i) + curve->get_point_in(i));
- if (gpoint.distance_to(p) < grab_treshold && (mode == MODE_EDIT || mode == MODE_EDIT_CURVE)) {
+ } else if (dist_to_p_in < grab_threshold && i > 0) {
action = ACTION_MOVING_IN;
action_point = i;
@@ -141,314 +120,362 @@ bool Path2DEditor::forward_gui_input(const InputEvent &p_event) {
return true;
}
}
+ }
- if (pointunder)
+ // Check for point deletion.
+ if ((mb->get_button_index() == BUTTON_RIGHT && mode == MODE_EDIT) || (mb->get_button_index() == BUTTON_LEFT && mode == MODE_DELETE)) {
+ if (dist_to_p < grab_threshold) {
+
+ undo_redo->create_action(TTR("Remove Point from Curve"));
+ undo_redo->add_do_method(curve.ptr(), "remove_point", i);
+ undo_redo->add_undo_method(curve.ptr(), "add_point", curve->get_point_pos(i), curve->get_point_in(i), curve->get_point_out(i), i);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ } else if (dist_to_p_out < grab_threshold) {
+
+ undo_redo->create_action(TTR("Remove Out-Control from Curve"));
+ undo_redo->add_do_method(curve.ptr(), "set_point_out", i, Vector2());
+ undo_redo->add_undo_method(curve.ptr(), "set_point_out", i, curve->get_point_out(i));
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
return true;
+ } else if (dist_to_p_in < grab_threshold) {
+
+ undo_redo->create_action(TTR("Remove In-Control from Curve"));
+ undo_redo->add_do_method(curve.ptr(), "set_point_in", i, Vector2());
+ undo_redo->add_undo_method(curve.ptr(), "set_point_in", i, curve->get_point_in(i));
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
}
}
+ }
- // Test add point in empty space!
+ // Check for point creation.
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && ((mb->get_command() && mode == MODE_EDIT) || mode == MODE_CREATE)) {
- if (mb.pressed && mb.button_index == BUTTON_LEFT && ((mb.mod.command && mode == MODE_EDIT) || mode == MODE_CREATE)) {
+ Ref<Curve2D> curve = node->get_curve();
- Ref<Curve2D> curve = node->get_curve();
+ undo_redo->create_action(TTR("Add Point to Curve"));
+ undo_redo->add_do_method(curve.ptr(), "add_point", cpoint);
+ undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count());
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- undo_redo->create_action(TTR("Add Point to Curve"));
- undo_redo->add_do_method(curve.ptr(), "add_point", cpoint);
- undo_redo->add_undo_method(curve.ptr(), "remove_point", curve->get_point_count());
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ action = ACTION_MOVING_POINT;
+ action_point = curve->get_point_count() - 1;
+ moving_from = curve->get_point_pos(action_point);
+ moving_screen_from = gpoint;
- action = ACTION_MOVING_POINT;
- action_point = curve->get_point_count() - 1;
- moving_from = curve->get_point_pos(action_point);
- moving_screen_from = gpoint;
+ canvas_item_editor->get_viewport_control()->update();
- canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
- return true;
- }
+ // Check for point movement completion.
+ if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && action != ACTION_NONE) {
- if (!mb.pressed && mb.button_index == BUTTON_LEFT && action != ACTION_NONE) {
+ Ref<Curve2D> curve = node->get_curve();
- Ref<Curve2D> curve = node->get_curve();
+ Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
+ switch (action) {
- Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
- switch (action) {
+ case ACTION_NONE:
+ // N/A, handled in above condition.
+ break;
- case ACTION_MOVING_POINT: {
+ case ACTION_MOVING_POINT: {
- undo_redo->create_action(TTR("Move Point in Curve"));
- undo_redo->add_do_method(curve.ptr(), "set_point_pos", action_point, cpoint);
- undo_redo->add_undo_method(curve.ptr(), "set_point_pos", action_point, moving_from);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ undo_redo->create_action(TTR("Move Point in Curve"));
+ undo_redo->add_do_method(curve.ptr(), "set_point_pos", action_point, cpoint);
+ undo_redo->add_undo_method(curve.ptr(), "set_point_pos", action_point, moving_from);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- } break;
- case ACTION_MOVING_IN: {
+ } break;
- undo_redo->create_action(TTR("Move In-Control in Curve"));
- undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, new_pos);
- undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, moving_from);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ case ACTION_MOVING_IN: {
- } break;
- case ACTION_MOVING_OUT: {
+ undo_redo->create_action(TTR("Move In-Control in Curve"));
+ undo_redo->add_do_method(curve.ptr(), "set_point_in", action_point, new_pos);
+ undo_redo->add_undo_method(curve.ptr(), "set_point_in", action_point, moving_from);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- undo_redo->create_action(TTR("Move Out-Control in Curve"));
- undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, new_pos);
- undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, moving_from);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ } break;
- } break;
- }
+ case ACTION_MOVING_OUT: {
- action = ACTION_NONE;
+ undo_redo->create_action(TTR("Move Out-Control in Curve"));
+ undo_redo->add_do_method(curve.ptr(), "set_point_out", action_point, new_pos);
+ undo_redo->add_undo_method(curve.ptr(), "set_point_out", action_point, moving_from);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
- return true;
+ } break;
}
+ action = ACTION_NONE;
+
+ return true;
+ }
+
#if 0
- switch(mode) {
+ switch(mode) {
- case MODE_CREATE: {
+ case MODE_CREATE: {
- if (mb.button_index==BUTTON_LEFT && mb.pressed) {
+ if (mb->get_button_index()==BUTTON_LEFT && mb->is_pressed()) {
- if (!wip_active) {
+ if (!wip_active) {
- wip.clear();
- wip.push_back( canvas_item_editor->snap_point(cpoint) );
- wip_active=true;
- edited_point_pos=canvas_item_editor->snap_point(cpoint);
- canvas_item_editor->update();
- edited_point=1;
- return true;
- } else {
+ wip.clear();
+ wip.push_back( canvas_item_editor->snap_point(cpoint) );
+ wip_active=true;
+ edited_point_pos=canvas_item_editor->snap_point(cpoint);
+ canvas_item_editor->update();
+ edited_point=1;
+ return true;
+ } else {
+ if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
+ //wip closed
+ _wip_close();
- if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
- //wip closed
- _wip_close();
- return true;
- } else {
+ return true;
+ } else {
- wip.push_back( canvas_item_editor->snap_point(cpoint) );
- edited_point=wip.size();
- canvas_item_editor->update();
- return true;
+ wip.push_back( canvas_item_editor->snap_point(cpoint) );
+ edited_point=wip.size();
+ canvas_item_editor->update();
+ return true;
- //add wip point
- }
+ //add wip point
}
- } else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) {
- _wip_close();
}
+ } else if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close();
+ }
+ } break;
+ case MODE_EDIT: {
- } break;
-
- case MODE_EDIT: {
-
- if (mb.button_index==BUTTON_LEFT) {
- if (mb.pressed) {
-
- if (mb.mod.control) {
+ if (mb->get_button_index()==BUTTON_LEFT) {
+ if (mb->is_pressed()) {
+ if (mb->get_control()) {
- if (poly.size() < 3) {
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node,"set_polygon",poly);
- poly.push_back(cpoint);
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->commit_action();
- return true;
- }
+ if (poly.size() < 3) {
- //search edges
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
-
- Vector2 points[2] ={ xform.xform(poly[i]),
- xform.xform(poly[(i+1)%poly.size()]) };
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_undo_method(node,"set_polygon",poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+ return true;
+ }
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
- if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
- continue; //not valid to reuse point
+ //search edges
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
- real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
}
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
+ if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
+ continue; //not valid to reuse point
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
}
- if (closest_idx>=0) {
-
- pre_move_edit=poly;
- poly.insert(closest_idx+1,canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos)));
- edited_point=closest_idx+1;
- edited_point_pos=canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos));
- node->set_polygon(poly);
- canvas_item_editor->update();
- return true;
- }
- } else {
- //look for points to move
+ }
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
+ if (closest_idx>=0) {
- Vector2 cp =xform.xform(poly[i]);
+ pre_move_edit=poly;
+ poly.insert(closest_idx+1,canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos)));
+ edited_point=closest_idx+1;
+ edited_point_pos=canvas_item_editor->snap_point(xform.affine_inverse().xform(closest_pos));
+ node->set_polygon(poly);
+ canvas_item_editor->update();
+ return true;
+ }
+ } else {
real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
}
- }
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
- if (closest_idx>=0) {
+ Vector2 cp =xform.xform(poly[i]);
- pre_move_edit=poly;
- edited_point=closest_idx;
- edited_point_pos=xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->update();
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
}
- }
- } else {
- if (edited_point!=-1) {
+ }
- //apply
+ if (closest_idx>=0) {
- ERR_FAIL_INDEX_V(edited_point,poly.size(),false);
- poly[edited_point]=edited_point_pos;
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_undo_method(node,"set_polygon",pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->commit_action();
-
- edited_point=-1;
+ pre_move_edit=poly;
+ edited_point=closest_idx;
+ edited_point_pos=xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->update();
return true;
}
}
- } if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) {
+ } else {
+ if (edited_point!=-1) {
+ //apply
- int closest_idx=-1;
- Vector2 closest_pos;
- real_t closest_dist=1e10;
- for(int i=0;i<poly.size();i++) {
+ ERR_FAIL_INDEX_V(edited_point,poly.size(),false);
+ poly[edited_point]=edited_point_pos;
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_undo_method(node,"set_polygon",pre_move_edit);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
- Vector2 cp =xform.xform(poly[i]);
+ edited_point=-1;
+ return true;
+ }
+ }
+ } if (mb->get_button_index()==BUTTON_RIGHT && mb->is_pressed() && edited_point==-1) {
real_t d = cp.distance_to(gpoint);
- if (d<closest_dist && d<grab_treshold) {
+ if (d<closest_dist && d<grab_threshold) {
closest_dist=d;
closest_pos=cp;
closest_idx=i;
}
- }
-
- if (closest_idx>=0) {
+ int closest_idx=-1;
+ Vector2 closest_pos;
+ real_t closest_dist=1e10;
+ for(int i=0;i<poly.size();i++) {
+ Vector2 cp =xform.xform(poly[i]);
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node,"set_polygon",poly);
- poly.remove(closest_idx);
- undo_redo->add_do_method(node,"set_polygon",poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
- undo_redo->commit_action();
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d<closest_dist && d<grab_treshold) {
+ closest_dist=d;
+ closest_pos=cp;
+ closest_idx=i;
}
}
+ if (closest_idx>=0) {
- } break;
- }
-
-#endif
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node,"set_polygon",poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node,"set_polygon",poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
+ undo_redo->commit_action();
+ return true;
+ }
- if (action != ACTION_NONE) {
+ }
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Vector2 gpoint = Point2(mm.x, mm.y);
- Vector2 cpoint = !mm.mod.alt ? canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) : node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
+ } break;
+ }
+#endif
+ }
- Ref<Curve2D> curve = node->get_curve();
+ Ref<InputEventMouseMotion> mm = p_event;
- Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
+ if (mm.is_valid()) {
- switch (action) {
+ if (action != ACTION_NONE) {
+ // Handle point/control movement.
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint =
+ !mm->get_alt() ?
+ canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint)) :
+ node->get_global_transform().affine_inverse().xform(canvas_item_editor->snap_point(canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint)));
- case ACTION_MOVING_POINT: {
+ Ref<Curve2D> curve = node->get_curve();
- curve->set_point_pos(action_point, cpoint);
- } break;
- case ACTION_MOVING_IN: {
+ Vector2 new_pos = moving_from + xform.affine_inverse().basis_xform(gpoint - moving_screen_from);
- curve->set_point_in(action_point, new_pos);
+ switch (action) {
- } break;
- case ACTION_MOVING_OUT: {
+ case ACTION_NONE:
+ // N/A, handled in above condition.
+ break;
- curve->set_point_out(action_point, new_pos);
+ case ACTION_MOVING_POINT: {
+ curve->set_point_pos(action_point, cpoint);
+ } break;
- } break;
- }
+ case ACTION_MOVING_IN: {
+ curve->set_point_in(action_point, new_pos);
+ } break;
- canvas_item_editor->get_viewport_control()->update();
- return true;
+ case ACTION_MOVING_OUT: {
+ curve->set_point_out(action_point, new_pos);
+ } break;
}
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
+ }
+
#if 0
- if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) {
+ if (edited_point!=-1 && (wip_active || mm->get_button_mask()&BUTTON_MASK_LEFT)) {
- Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Vector2 gpoint = Point2(mm.x,mm.y);
- edited_point_pos = canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint));
- canvas_item_editor->update();
+ Vector2 gpoint = Point2(mm.x,mm.y);
+ edited_point_pos = canvas_item_editor->snap_point(xform.affine_inverse().xform(gpoint));
+ canvas_item_editor->update();
- }
+ }
#endif
- } break;
}
return false;
diff --git a/editor/plugins/path_2d_editor_plugin.h b/editor/plugins/path_2d_editor_plugin.h
index 67c6f3c8cb..70911444ad 100644
--- a/editor/plugins/path_2d_editor_plugin.h
+++ b/editor/plugins/path_2d_editor_plugin.h
@@ -95,7 +95,7 @@ protected:
static void _bind_methods();
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_path2d);
Path2DEditor(EditorNode *p_editor);
};
@@ -108,7 +108,7 @@ class Path2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return path2d_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return path2d_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "Path2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/path_editor_plugin.cpp b/editor/plugins/path_editor_plugin.cpp
index 9c95cee388..877707d77b 100644
--- a/editor/plugins/path_editor_plugin.cpp
+++ b/editor/plugins/path_editor_plugin.cpp
@@ -33,61 +33,57 @@
#include "scene/resources/curve.h"
#include "spatial_editor_plugin.h"
-#if 0
String PathSpatialGizmo::get_handle_name(int p_idx) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
return "";
- if (p_idx<c->get_point_count()) {
+ if (p_idx < c->get_point_count()) {
- return TTR("Curve Point #")+itos(p_idx);
+ return TTR("Curve Point #") + itos(p_idx);
}
- p_idx=p_idx-c->get_point_count()+1;
+ p_idx = p_idx - c->get_point_count() + 1;
- int idx=p_idx/2;
- int t=p_idx%2;
- String n = TTR("Curve Point #")+itos(idx);
- if (t==0)
- n+=" In";
+ int idx = p_idx / 2;
+ int t = p_idx % 2;
+ String n = TTR("Curve Point #") + itos(idx);
+ if (t == 0)
+ n += " In";
else
- n+=" Out";
+ n += " Out";
return n;
-
-
}
-Variant PathSpatialGizmo::get_handle_value(int p_idx) const{
+Variant PathSpatialGizmo::get_handle_value(int p_idx) const {
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
return Variant();
- if (p_idx<c->get_point_count()) {
+ if (p_idx < c->get_point_count()) {
- original=c->get_point_pos(p_idx);
+ original = c->get_point_pos(p_idx);
return original;
}
- p_idx=p_idx-c->get_point_count()+1;
+ p_idx = p_idx - c->get_point_count() + 1;
- int idx=p_idx/2;
- int t=p_idx%2;
+ int idx = p_idx / 2;
+ int t = p_idx % 2;
Vector3 ofs;
- if (t==0)
- ofs=c->get_point_in(idx);
+ if (t == 0)
+ ofs = c->get_point_in(idx);
else
- ofs= c->get_point_out(idx);
+ ofs = c->get_point_out(idx);
- original=ofs+c->get_point_pos(idx);
+ original = ofs + c->get_point_pos(idx);
return ofs;
-
}
-void PathSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_point){
+void PathSpatialGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_point) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
@@ -98,51 +94,49 @@ void PathSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Point2& p_po
Vector3 ray_from = p_camera->project_ray_origin(p_point);
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
- if (p_idx<c->get_point_count()) {
+ if (p_idx < c->get_point_count()) {
- Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2));
+ Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2));
Vector3 inters;
- if (p.intersects_ray(ray_from,ray_dir,&inters)) {
+ if (p.intersects_ray(ray_from, ray_dir, &inters)) {
- if(SpatialEditor::get_singleton()->is_snap_enabled())
- {
+ if (SpatialEditor::get_singleton()->is_snap_enabled()) {
float snap = SpatialEditor::get_singleton()->get_translate_snap();
inters.snap(snap);
}
-
+
Vector3 local = gi.xform(inters);
- c->set_point_pos(p_idx,local);
+ c->set_point_pos(p_idx, local);
}
return;
}
- p_idx=p_idx-c->get_point_count()+1;
+ p_idx = p_idx - c->get_point_count() + 1;
- int idx=p_idx/2;
- int t=p_idx%2;
+ int idx = p_idx / 2;
+ int t = p_idx % 2;
Vector3 base = c->get_point_pos(idx);
- Plane p(gt.xform(original),p_camera->get_transform().basis.get_axis(2));
+ Plane p(gt.xform(original), p_camera->get_transform().basis.get_axis(2));
Vector3 inters;
- if (p.intersects_ray(ray_from,ray_dir,&inters)) {
+ if (p.intersects_ray(ray_from, ray_dir, &inters)) {
- Vector3 local = gi.xform(inters)-base;
- if (t==0) {
- c->set_point_in(idx,local);
+ Vector3 local = gi.xform(inters) - base;
+ if (t == 0) {
+ c->set_point_in(idx, local);
} else {
- c->set_point_out(idx,local);
+ c->set_point_out(idx, local);
}
}
-
}
-void PathSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_cancel){
+void PathSpatialGizmo::commit_handle(int p_idx, const Variant &p_restore, bool p_cancel) {
Ref<Curve3D> c = path->get_curve();
if (c.is_null())
@@ -150,67 +144,59 @@ void PathSpatialGizmo::commit_handle(int p_idx,const Variant& p_restore,bool p_c
UndoRedo *ur = SpatialEditor::get_singleton()->get_undo_redo();
- if (p_idx<c->get_point_count()) {
+ if (p_idx < c->get_point_count()) {
if (p_cancel) {
- c->set_point_pos(p_idx,p_restore);
+ c->set_point_pos(p_idx, p_restore);
return;
}
ur->create_action(TTR("Set Curve Point Pos"));
- ur->add_do_method(c.ptr(),"set_point_pos",p_idx,c->get_point_pos(p_idx));
- ur->add_undo_method(c.ptr(),"set_point_pos",p_idx,p_restore);
+ ur->add_do_method(c.ptr(), "set_point_pos", p_idx, c->get_point_pos(p_idx));
+ ur->add_undo_method(c.ptr(), "set_point_pos", p_idx, p_restore);
ur->commit_action();
return;
}
- p_idx=p_idx-c->get_point_count()+1;
+ p_idx = p_idx - c->get_point_count() + 1;
- int idx=p_idx/2;
- int t=p_idx%2;
+ int idx = p_idx / 2;
+ int t = p_idx % 2;
Vector3 ofs;
if (p_cancel) {
-
-
return;
}
-
-
- if (t==0) {
+ if (t == 0) {
if (p_cancel) {
- c->set_point_in(p_idx,p_restore);
+ c->set_point_in(p_idx, p_restore);
return;
}
ur->create_action(TTR("Set Curve In Pos"));
- ur->add_do_method(c.ptr(),"set_point_in",idx,c->get_point_in(idx));
- ur->add_undo_method(c.ptr(),"set_point_in",idx,p_restore);
+ ur->add_do_method(c.ptr(), "set_point_in", idx, c->get_point_in(idx));
+ ur->add_undo_method(c.ptr(), "set_point_in", idx, p_restore);
ur->commit_action();
-
} else {
if (p_cancel) {
- c->set_point_out(idx,p_restore);
+ c->set_point_out(idx, p_restore);
return;
}
ur->create_action(TTR("Set Curve Out Pos"));
- ur->add_do_method(c.ptr(),"set_point_out",idx,c->get_point_out(idx));
- ur->add_undo_method(c.ptr(),"set_point_out",idx,p_restore);
+ ur->add_do_method(c.ptr(), "set_point_out", idx, c->get_point_out(idx));
+ ur->add_undo_method(c.ptr(), "set_point_out", idx, p_restore);
ur->commit_action();
-
}
-
}
-
-void PathSpatialGizmo::redraw(){
+void PathSpatialGizmo::redraw() {
clear();
@@ -218,80 +204,76 @@ void PathSpatialGizmo::redraw(){
if (c.is_null())
return;
- Vector3Array v3a=c->tesselate();
- //Vector3Array v3a=c->get_baked_points();
+ PoolVector<Vector3> v3a = c->tesselate();
+ //PoolVector<Vector3> v3a=c->get_baked_points();
int v3s = v3a.size();
- if (v3s==0)
+ if (v3s == 0)
return;
Vector<Vector3> v3p;
- Vector3Array::Read r = v3a.read();
+ PoolVector<Vector3>::Read r = v3a.read();
- for(int i=0;i<v3s-1;i++) {
+ // BUG: the following won't work when v3s, avoid drawing as a temporary workaround.
+ for (int i = 0; i < v3s - 1; i++) {
v3p.push_back(r[i]);
- v3p.push_back(r[i+1]);
+ v3p.push_back(r[i + 1]);
//v3p.push_back(r[i]);
//v3p.push_back(r[i]+Vector3(0,0.2,0));
}
- add_lines(v3p,PathEditorPlugin::singleton->path_material);
+ add_lines(v3p, PathEditorPlugin::singleton->path_material);
add_collision_segments(v3p);
- if (PathEditorPlugin::singleton->get_edited_path()==path) {
+ if (PathEditorPlugin::singleton->get_edited_path() == path) {
v3p.clear();
Vector<Vector3> handles;
Vector<Vector3> sec_handles;
- for(int i=0;i<c->get_point_count();i++) {
+ for (int i = 0; i < c->get_point_count(); i++) {
Vector3 p = c->get_point_pos(i);
handles.push_back(p);
- if (i>0) {
+ if (i > 0) {
v3p.push_back(p);
- v3p.push_back(p+c->get_point_in(i));
- sec_handles.push_back(p+c->get_point_in(i));
+ v3p.push_back(p + c->get_point_in(i));
+ sec_handles.push_back(p + c->get_point_in(i));
}
- if (i<c->get_point_count()-1) {
+ if (i < c->get_point_count() - 1) {
v3p.push_back(p);
- v3p.push_back(p+c->get_point_out(i));
- sec_handles.push_back(p+c->get_point_out(i));
+ v3p.push_back(p + c->get_point_out(i));
+ sec_handles.push_back(p + c->get_point_out(i));
}
}
- add_lines(v3p,PathEditorPlugin::singleton->path_thin_material);
+ add_lines(v3p, PathEditorPlugin::singleton->path_thin_material);
add_handles(handles);
- add_handles(sec_handles,false,true);
+ add_handles(sec_handles, false, true);
}
-
}
-PathSpatialGizmo::PathSpatialGizmo(Path* p_path){
+PathSpatialGizmo::PathSpatialGizmo(Path *p_path) {
- path=p_path;
+ path = p_path;
set_spatial_node(p_path);
-
-
-
}
-Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial* p_spatial) {
-
+Ref<SpatialEditorGizmo> PathEditorPlugin::create_spatial_gizmo(Spatial *p_spatial) {
if (p_spatial->cast_to<Path>()) {
- return memnew( PathSpatialGizmo(p_spatial->cast_to<Path>()));
+ return memnew(PathSpatialGizmo(p_spatial->cast_to<Path>()));
}
return Ref<SpatialEditorGizmo>();
}
-bool PathEditorPlugin::forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event) {
+bool PathEditorPlugin::forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event) {
if (!path)
return false;
- Ref<Curve3D> c=path->get_curve();
+ Ref<Curve3D> c = path->get_curve();
if (c.is_null())
return false;
Transform gt = path->get_global_transform();
@@ -299,105 +281,99 @@ bool PathEditorPlugin::forward_spatial_gui_input(Camera* p_camera,const InputEve
static const int click_dist = 10; //should make global
+ Ref<InputEventMouseButton> mb = p_event;
- if (p_event.type==InputEvent::MOUSE_BUTTON) {
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb=p_event.mouse_button;
- Point2 mbpos(mb.x,mb.y);
+ Point2 mbpos(mb->get_position().x, mb->get_position().y);
- if (mb.pressed && mb.button_index==BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb.mod.control))) {
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT && (curve_create->is_pressed() || (curve_edit->is_pressed() && mb->get_control()))) {
//click into curve, break it down
- Vector3Array v3a = c->tesselate();
- int idx=0;
- int rc=v3a.size();
- int closest_seg=-1;
+ PoolVector<Vector3> v3a = c->tesselate();
+ int idx = 0;
+ int rc = v3a.size();
+ int closest_seg = -1;
Vector3 closest_seg_point;
- float closest_d=1e20;
+ float closest_d = 1e20;
- if (rc>=2) {
- Vector3Array::Read r = v3a.read();
+ if (rc >= 2) {
+ PoolVector<Vector3>::Read r = v3a.read();
- if (p_camera->unproject_position(gt.xform(c->get_point_pos(0))).distance_to(mbpos)<click_dist)
+ if (p_camera->unproject_position(gt.xform(c->get_point_pos(0))).distance_to(mbpos) < click_dist)
return false; //nope, existing
-
- for(int i=0;i<c->get_point_count()-1;i++) {
+ for (int i = 0; i < c->get_point_count() - 1; i++) {
//find the offset and point index of the place to break up
- int j=idx;
- if (p_camera->unproject_position(gt.xform(c->get_point_pos(i+1))).distance_to(mbpos)<click_dist)
+ int j = idx;
+ if (p_camera->unproject_position(gt.xform(c->get_point_pos(i + 1))).distance_to(mbpos) < click_dist)
return false; //nope, existing
+ while (j < rc && c->get_point_pos(i + 1) != r[j]) {
- while(j<rc && c->get_point_pos(i+1)!=r[j]) {
-
- Vector3 from =r[j];
- Vector3 to =r[j+1];
+ Vector3 from = r[j];
+ Vector3 to = r[j + 1];
real_t cdist = from.distance_to(to);
- from=gt.xform(from);
- to=gt.xform(to);
- if (cdist>0) {
+ from = gt.xform(from);
+ to = gt.xform(to);
+ if (cdist > 0) {
Vector2 s[2];
s[0] = p_camera->unproject_position(from);
s[1] = p_camera->unproject_position(to);
- Vector2 inters = Geometry::get_closest_point_to_segment_2d(mbpos,s);
+ Vector2 inters = Geometry::get_closest_point_to_segment_2d(mbpos, s);
float d = inters.distance_to(mbpos);
- if (d<10 && d<closest_d) {
+ if (d < 10 && d < closest_d) {
+ closest_d = d;
+ closest_seg = i;
+ Vector3 ray_from = p_camera->project_ray_origin(mbpos);
+ Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
- closest_d=d;
- closest_seg=i;
- Vector3 ray_from=p_camera->project_ray_origin(mbpos);
- Vector3 ray_dir=p_camera->project_ray_normal(mbpos);
+ Vector3 ra, rb;
+ Geometry::get_closest_points_between_segments(ray_from, ray_from + ray_dir * 4096, from, to, ra, rb);
- Vector3 ra,rb;
- Geometry::get_closest_points_between_segments(ray_from,ray_from+ray_dir*4096,from,to,ra,rb);
-
- closest_seg_point=it.xform(rb);
+ closest_seg_point = it.xform(rb);
}
-
}
j++;
-
}
- if (idx==j)
+ if (idx == j)
idx++; //force next
else
- idx=j; //swap
+ idx = j; //swap
-
- if (j==rc)
+ if (j == rc)
break;
}
}
UndoRedo *ur = editor->get_undo_redo();
- if (closest_seg!=-1) {
+ if (closest_seg != -1) {
//subdivide
ur->create_action(TTR("Split Path"));
- ur->add_do_method(c.ptr(),"add_point",closest_seg_point,Vector3(),Vector3(),closest_seg+1);
- ur->add_undo_method(c.ptr(),"remove_point",closest_seg+1);
+ ur->add_do_method(c.ptr(), "add_point", closest_seg_point, Vector3(), Vector3(), closest_seg + 1);
+ ur->add_undo_method(c.ptr(), "remove_point", closest_seg + 1);
ur->commit_action();
return true;
} else {
Vector3 org;
- if (c->get_point_count()==0)
- org=path->get_transform().get_origin();
+ if (c->get_point_count() == 0)
+ org = path->get_transform().get_origin();
else
- org=gt.xform(c->get_point_pos(c->get_point_count()));
- Plane p(org,p_camera->get_transform().basis.get_axis(2));
- Vector3 ray_from=p_camera->project_ray_origin(mbpos);
- Vector3 ray_dir=p_camera->project_ray_normal(mbpos);
+ org = gt.xform(c->get_point_pos(c->get_point_count() - 1));
+ Plane p(org, p_camera->get_transform().basis.get_axis(2));
+ Vector3 ray_from = p_camera->project_ray_origin(mbpos);
+ Vector3 ray_dir = p_camera->project_ray_normal(mbpos);
Vector3 inters;
- if (p.intersects_ray(ray_from,ray_dir,&inters)) {
+ if (p.intersects_ray(ray_from, ray_dir, &inters)) {
ur->create_action(TTR("Add Point to Curve"));
- ur->add_do_method(c.ptr(),"add_point",it.xform(inters),Vector3(),Vector3(),-1);
- ur->add_undo_method(c.ptr(),"remove_point",c->get_point_count());
+ ur->add_do_method(c.ptr(), "add_point", it.xform(inters), Vector3(), Vector3(), -1);
+ ur->add_undo_method(c.ptr(), "remove_point", c->get_point_count());
ur->commit_action();
return true;
}
@@ -405,39 +381,51 @@ bool PathEditorPlugin::forward_spatial_gui_input(Camera* p_camera,const InputEve
//add new at pos
}
- } else if (mb.pressed && ((mb.button_index==BUTTON_LEFT && curve_del->is_pressed()) || (mb.button_index==BUTTON_RIGHT && curve_edit->is_pressed()))) {
+ } else if (mb->is_pressed() && ((mb->get_button_index() == BUTTON_LEFT && curve_del->is_pressed()) || (mb->get_button_index() == BUTTON_RIGHT && curve_edit->is_pressed()))) {
- int erase_idx=-1;
- for(int i=0;i<c->get_point_count();i++) {
- //find the offset and point index of the place to break up
- if (p_camera->unproject_position(gt.xform(c->get_point_pos(i))).distance_to(mbpos)<click_dist) {
+ for (int i = 0; i < c->get_point_count(); i++) {
+ real_t dist_to_p = p_camera->unproject_position(gt.xform(c->get_point_pos(i))).distance_to(mbpos);
+ real_t dist_to_p_out = p_camera->unproject_position(gt.xform(c->get_point_pos(i) + c->get_point_out(i))).distance_to(mbpos);
+ real_t dist_to_p_in = p_camera->unproject_position(gt.xform(c->get_point_pos(i) + c->get_point_in(i))).distance_to(mbpos);
- erase_idx=i;
- break;
- }
- }
+ // Find the offset and point index of the place to break up.
+ // Also check for the control points.
+ if (dist_to_p < click_dist) {
- if (erase_idx!=-1) {
+ UndoRedo *ur = editor->get_undo_redo();
+ ur->create_action(TTR("Remove Path Point"));
+ ur->add_do_method(c.ptr(), "remove_point", i);
+ ur->add_undo_method(c.ptr(), "add_point", c->get_point_pos(i), c->get_point_in(i), c->get_point_out(i), i);
+ ur->commit_action();
+ return true;
+ } else if (dist_to_p_out < click_dist) {
- UndoRedo *ur = editor->get_undo_redo();
- ur->create_action(TTR("Remove Path Point"));
- ur->add_do_method(c.ptr(),"remove_point",erase_idx);
- ur->add_undo_method(c.ptr(),"add_point",c->get_point_pos(erase_idx),c->get_point_in(erase_idx),c->get_point_out(erase_idx),erase_idx);
- ur->commit_action();
- return true;
+ UndoRedo *ur = editor->get_undo_redo();
+ ur->create_action(TTR("Remove Out-Control Point"));
+ ur->add_do_method(c.ptr(), "set_point_out", i, Vector3());
+ ur->add_undo_method(c.ptr(), "set_point_out", i, c->get_point_out(i));
+ ur->commit_action();
+ return true;
+ } else if (dist_to_p_in < click_dist) {
+
+ UndoRedo *ur = editor->get_undo_redo();
+ ur->create_action(TTR("Remove In-Control Point"));
+ ur->add_do_method(c.ptr(), "set_point_in", i, Vector3());
+ ur->add_undo_method(c.ptr(), "set_point_in", i, c->get_point_in(i));
+ ur->commit_action();
+ return true;
+ }
}
}
-
}
return false;
}
-
void PathEditorPlugin::edit(Object *p_object) {
if (p_object) {
- path=p_object->cast_to<Path>();
+ path = p_object->cast_to<Path>();
if (path) {
if (path->get_curve().is_valid()) {
@@ -445,8 +433,8 @@ void PathEditorPlugin::edit(Object *p_object) {
}
}
} else {
- Path *pre=path;
- path=NULL;
+ Path *pre = path;
+ path = NULL;
if (pre) {
pre->get_curve()->emit_signal("changed");
}
@@ -456,7 +444,7 @@ void PathEditorPlugin::edit(Object *p_object) {
bool PathEditorPlugin::handles(Object *p_object) const {
- return p_object->is_type("Path");
+ return p_object->is_class("Path");
}
void PathEditorPlugin::make_visible(bool p_visible) {
@@ -466,120 +454,115 @@ void PathEditorPlugin::make_visible(bool p_visible) {
curve_create->show();
curve_edit->show();
curve_del->show();
- curve_close->show();
- sep->show();
+ curve_close->show();
+ sep->show();
} else {
curve_create->hide();
curve_edit->hide();
curve_del->hide();
- curve_close->hide();
- sep->hide();
+ curve_close->hide();
+ sep->hide();
{
- Path *pre=path;
- path=NULL;
+ Path *pre = path;
+ path = NULL;
if (pre && pre->get_curve().is_valid()) {
pre->get_curve()->emit_signal("changed");
}
}
}
-
}
void PathEditorPlugin::_mode_changed(int p_idx) {
- curve_create->set_pressed(p_idx==0);
- curve_edit->set_pressed(p_idx==1);
- curve_del->set_pressed(p_idx==2);
+ curve_create->set_pressed(p_idx == 0);
+ curve_edit->set_pressed(p_idx == 1);
+ curve_del->set_pressed(p_idx == 2);
}
void PathEditorPlugin::_close_curve() {
- Ref<Curve3D> c = path->get_curve();
- if (c.is_null())
- return ;
- if (c->get_point_count()<2)
- return;
- c->add_point(c->get_point_pos(0),c->get_point_in(0),c->get_point_out(0));
-
+ Ref<Curve3D> c = path->get_curve();
+ if (c.is_null())
+ return;
+ if (c->get_point_count() < 2)
+ return;
+ c->add_point(c->get_point_pos(0), c->get_point_in(0), c->get_point_out(0));
}
void PathEditorPlugin::_notification(int p_what) {
- if (p_what==NOTIFICATION_ENTER_TREE) {
+ if (p_what == NOTIFICATION_ENTER_TREE) {
- curve_create->connect("pressed",this,"_mode_changed",make_binds(0));
- curve_edit->connect("pressed",this,"_mode_changed",make_binds(1));
- curve_del->connect("pressed",this,"_mode_changed",make_binds(2));
- curve_close->connect("pressed",this,"_close_curve");
- }
+ curve_create->connect("pressed", this, "_mode_changed", make_binds(0));
+ curve_edit->connect("pressed", this, "_mode_changed", make_binds(1));
+ curve_del->connect("pressed", this, "_mode_changed", make_binds(2));
+ curve_close->connect("pressed", this, "_close_curve");
+ }
}
void PathEditorPlugin::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_mode_changed"),&PathEditorPlugin::_mode_changed);
- ClassDB::bind_method(D_METHOD("_close_curve"),&PathEditorPlugin::_close_curve);
+ ClassDB::bind_method(D_METHOD("_mode_changed"), &PathEditorPlugin::_mode_changed);
+ ClassDB::bind_method(D_METHOD("_close_curve"), &PathEditorPlugin::_close_curve);
}
-PathEditorPlugin* PathEditorPlugin::singleton=NULL;
-
+PathEditorPlugin *PathEditorPlugin::singleton = NULL;
PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
- path=NULL;
- editor=p_node;
- singleton=this;
+ path = NULL;
+ editor = p_node;
+ singleton = this;
- path_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
- path_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.8) );
- path_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ path_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ path_material->set_albedo(Color(0.5, 0.5, 1.0, 0.8));
+ path_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
path_material->set_line_width(3);
- path_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
- path_material->set_flag(Material::FLAG_UNSHADED,true);
+ path_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ path_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- path_thin_material = Ref<SpatialMaterial>( memnew( SpatialMaterial ));
- path_thin_material->set_parameter( SpatialMaterial::PARAM_DIFFUSE,Color(0.5,0.5,1.0,0.4) );
- path_thin_material->set_fixed_flag(SpatialMaterial::FLAG_USE_ALPHA, true);
+ path_thin_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));
+ path_thin_material->set_albedo(Color(0.5, 0.5, 1.0, 0.4));
+ path_thin_material->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
path_thin_material->set_line_width(1);
- path_thin_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
- path_thin_material->set_flag(Material::FLAG_UNSHADED,true);
+ path_thin_material->set_cull_mode(SpatialMaterial::CULL_DISABLED);
+ path_thin_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
//SpatialEditor::get_singleton()->add_gizmo_plugin(this);
- sep = memnew( VSeparator);
+ sep = memnew(VSeparator);
sep->hide();
SpatialEditor::get_singleton()->add_control_to_menu_panel(sep);
- curve_edit = memnew( ToolButton );
- curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit","EditorIcons"));
+ curve_edit = memnew(ToolButton);
+ curve_edit->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveEdit", "EditorIcons"));
curve_edit->set_toggle_mode(true);
curve_edit->hide();
curve_edit->set_focus_mode(Control::FOCUS_NONE);
- curve_edit->set_tooltip(TTR("Select Points")+"\n"+TTR("Shift+Drag: Select Control Points")+"\n"+keycode_get_string(KEY_MASK_CMD)+TTR("Click: Add Point")+"\n"+TTR("Right Click: Delete Point"));
+ curve_edit->set_tooltip(TTR("Select Points") + "\n" + TTR("Shift+Drag: Select Control Points") + "\n" + keycode_get_string(KEY_MASK_CMD) + TTR("Click: Add Point") + "\n" + TTR("Right Click: Delete Point"));
SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_edit);
- curve_create = memnew( ToolButton );
- curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate","EditorIcons"));
+ curve_create = memnew(ToolButton);
+ curve_create->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveCreate", "EditorIcons"));
curve_create->set_toggle_mode(true);
curve_create->hide();
curve_create->set_focus_mode(Control::FOCUS_NONE);
- curve_create->set_tooltip(TTR("Add Point (in empty space)")+"\n"+TTR("Split Segment (in curve)"));
+ curve_create->set_tooltip(TTR("Add Point (in empty space)") + "\n" + TTR("Split Segment (in curve)"));
SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_create);
- curve_del = memnew( ToolButton );
- curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete","EditorIcons"));
+ curve_del = memnew(ToolButton);
+ curve_del->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveDelete", "EditorIcons"));
curve_del->set_toggle_mode(true);
curve_del->hide();
curve_del->set_focus_mode(Control::FOCUS_NONE);
curve_del->set_tooltip(TTR("Delete Point"));
SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_del);
- curve_close = memnew( ToolButton );
- curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveClose","EditorIcons"));
+ curve_close = memnew(ToolButton);
+ curve_close->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("CurveClose", "EditorIcons"));
curve_close->hide();
curve_close->set_focus_mode(Control::FOCUS_NONE);
curve_close->set_tooltip(TTR("Close Curve"));
SpatialEditor::get_singleton()->add_control_to_menu_panel(curve_close);
-
-
curve_edit->set_pressed(true);
/*
collision_polygon_editor = memnew( PathEditor(p_node) );
@@ -593,13 +576,7 @@ PathEditorPlugin::PathEditorPlugin(EditorNode *p_node) {
collision_polygon_editor->hide();
*/
-
-
}
-
-PathEditorPlugin::~PathEditorPlugin()
-{
+PathEditorPlugin::~PathEditorPlugin() {
}
-
-#endif
diff --git a/editor/plugins/path_editor_plugin.h b/editor/plugins/path_editor_plugin.h
index 4dbda10263..651dcdaa78 100644
--- a/editor/plugins/path_editor_plugin.h
+++ b/editor/plugins/path_editor_plugin.h
@@ -32,30 +32,27 @@
#include "editor/spatial_editor_gizmos.h"
#include "scene/3d/path.h"
-#if 0
-class PathSpatialGizmo : public EditorSpatialGizmo {
- GDCLASS(PathSpatialGizmo,EditorSpatialGizmo);
+class PathSpatialGizmo : public EditorSpatialGizmo {
- Path* path;
+ GDCLASS(PathSpatialGizmo, EditorSpatialGizmo);
+
+ Path *path;
mutable Vector3 original;
public:
-
virtual String get_handle_name(int p_idx) const;
virtual Variant get_handle_value(int p_idx) const;
- virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point);
- virtual void commit_handle(int p_idx,const Variant& p_restore,bool p_cancel=false);
+ virtual void set_handle(int p_idx, Camera *p_camera, const Point2 &p_point);
+ virtual void commit_handle(int p_idx, const Variant &p_restore, bool p_cancel = false);
void redraw();
- PathSpatialGizmo(Path* p_path=NULL);
-
+ PathSpatialGizmo(Path *p_path = NULL);
};
class PathEditorPlugin : public EditorPlugin {
- GDCLASS( PathEditorPlugin, EditorPlugin );
-
+ GDCLASS(PathEditorPlugin, EditorPlugin);
Separator *sep;
ToolButton *curve_create;
@@ -65,26 +62,25 @@ class PathEditorPlugin : public EditorPlugin {
EditorNode *editor;
-
Path *path;
void _mode_changed(int p_idx);
- void _close_curve();
+ void _close_curve();
+
protected:
void _notification(int p_what);
static void _bind_methods();
public:
-
Path *get_edited_path() { return path; }
- static PathEditorPlugin* singleton;
+ static PathEditorPlugin *singleton;
Ref<SpatialMaterial> path_material;
Ref<SpatialMaterial> path_thin_material;
- virtual bool forward_spatial_gui_input(Camera* p_camera,const InputEvent& p_event);
+ virtual bool forward_spatial_gui_input(Camera *p_camera, const Ref<InputEvent> &p_event);
//virtual bool forward_gui_input(const InputEvent& p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
- virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial* p_spatial);
+ virtual Ref<SpatialEditorGizmo> create_spatial_gizmo(Spatial *p_spatial);
virtual String get_name() const { return "Path"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
@@ -93,8 +89,6 @@ public:
PathEditorPlugin(EditorNode *p_node);
~PathEditorPlugin();
-
};
-#endif
#endif // PATH_EDITOR_PLUGIN_H
diff --git a/editor/plugins/polygon_2d_editor_plugin.cpp b/editor/plugins/polygon_2d_editor_plugin.cpp
index e84e782580..dd13ca0e63 100644
--- a/editor/plugins/polygon_2d_editor_plugin.cpp
+++ b/editor/plugins/polygon_2d_editor_plugin.cpp
@@ -201,213 +201,209 @@ void Polygon2DEditor::_wip_close() {
edited_point = -1;
}
-bool Polygon2DEditor::forward_gui_input(const InputEvent &p_event) {
+bool Polygon2DEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (node == NULL)
return false;
- switch (p_event.type) {
+ Ref<InputEventMouseButton> mb = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb = p_event.mouse_button;
+ Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
- Transform2D xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
+ Vector2 gpoint = mb->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
- Vector2 gpoint = Point2(mb.x, mb.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
+ Vector<Vector2> poly = Variant(node->get_polygon());
- Vector<Vector2> poly = Variant(node->get_polygon());
+ //first check if a point is to be added (segment split)
+ real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
- //first check if a point is to be added (segment split)
- real_t grab_treshold = EDITOR_DEF("editors/poly_editor/point_grab_radius", 8);
+ switch (mode) {
- switch (mode) {
+ case MODE_CREATE: {
- case MODE_CREATE: {
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- if (mb.button_index == BUTTON_LEFT && mb.pressed) {
+ if (!wip_active) {
- if (!wip_active) {
+ wip.clear();
+ wip.push_back(cpoint - node->get_offset());
+ wip_active = true;
+ edited_point_pos = cpoint;
+ canvas_item_editor->get_viewport_control()->update();
+ edited_point = 1;
+ return true;
+ } else {
+
+ if (wip.size() > 1 && xform.xform(wip[0] + node->get_offset()).distance_to(gpoint) < grab_treshold) {
+ //wip closed
+ _wip_close();
- wip.clear();
- wip.push_back(cpoint - node->get_offset());
- wip_active = true;
- edited_point_pos = cpoint;
- canvas_item_editor->get_viewport_control()->update();
- edited_point = 1;
return true;
} else {
- if (wip.size() > 1 && xform.xform(wip[0] + node->get_offset()).distance_to(gpoint) < grab_treshold) {
- //wip closed
- _wip_close();
-
- return true;
- } else {
-
- wip.push_back(cpoint - node->get_offset());
- edited_point = wip.size();
- canvas_item_editor->get_viewport_control()->update();
- return true;
+ wip.push_back(cpoint - node->get_offset());
+ edited_point = wip.size();
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
- //add wip point
- }
+ //add wip point
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && wip_active) {
- _wip_close();
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && wip_active) {
+ _wip_close();
+ }
- } break;
-
- case MODE_EDIT: {
-
- if (mb.button_index == BUTTON_LEFT) {
- if (mb.pressed) {
-
- if (mb.mod.control) {
+ } break;
- if (poly.size() < 3) {
+ case MODE_EDIT: {
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
- poly.push_back(cpoint);
- undo_redo->add_do_method(node, "set_polygon", poly);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
- return true;
- }
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- //search edges
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
-
- Vector2 points[2] = { xform.xform(poly[i] + node->get_offset()),
- xform.xform(poly[(i + 1) % poly.size()] + node->get_offset()) };
-
- Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
- if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
- continue; //not valid to reuse point
-
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
- }
+ if (mb->get_control()) {
- if (closest_idx >= 0) {
+ if (poly.size() < 3) {
- pre_move_edit = poly;
- poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos) - node->get_offset());
- edited_point = closest_idx + 1;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- node->set_polygon(Variant(poly));
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
- } else {
+ undo_redo->create_action(TTR("Edit Poly"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.push_back(cpoint);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
- //look for points to move
+ //search edges
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
+ Vector2 points[2] = { xform.xform(poly[i] + node->get_offset()),
+ xform.xform(poly[(i + 1) % poly.size()] + node->get_offset()) };
- Vector2 cp = xform.xform(poly[i] + node->get_offset());
+ Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint, points);
+ if (cp.distance_squared_to(points[0]) < CMP_EPSILON2 || cp.distance_squared_to(points[1]) < CMP_EPSILON2)
+ continue; //not valid to reuse point
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
- }
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
}
+ }
- if (closest_idx >= 0) {
+ if (closest_idx >= 0) {
- pre_move_edit = poly;
- edited_point = closest_idx;
- edited_point_pos = xform.affine_inverse().xform(closest_pos);
- canvas_item_editor->get_viewport_control()->update();
- return true;
- }
+ pre_move_edit = poly;
+ poly.insert(closest_idx + 1, xform.affine_inverse().xform(closest_pos) - node->get_offset());
+ edited_point = closest_idx + 1;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ node->set_polygon(Variant(poly));
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
} else {
- if (edited_point != -1) {
+ //look for points to move
- //apply
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
- poly[edited_point] = edited_point_pos - node->get_offset();
- undo_redo->create_action(TTR("Edit Poly"));
- undo_redo->add_do_method(node, "set_polygon", poly);
- undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
- undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
- undo_redo->commit_action();
+ Vector2 cp = xform.xform(poly[i] + node->get_offset());
- edited_point = -1;
- return true;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
}
- }
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed && edited_point == -1) {
- int closest_idx = -1;
- Vector2 closest_pos;
- real_t closest_dist = 1e10;
- for (int i = 0; i < poly.size(); i++) {
+ if (closest_idx >= 0) {
- Vector2 cp = xform.xform(poly[i] + node->get_offset());
-
- real_t d = cp.distance_to(gpoint);
- if (d < closest_dist && d < grab_treshold) {
- closest_dist = d;
- closest_pos = cp;
- closest_idx = i;
+ pre_move_edit = poly;
+ edited_point = closest_idx;
+ edited_point_pos = xform.affine_inverse().xform(closest_pos);
+ canvas_item_editor->get_viewport_control()->update();
+ return true;
}
}
+ } else {
+
+ if (edited_point != -1) {
- if (closest_idx >= 0) {
+ //apply
- undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
- undo_redo->add_undo_method(node, "set_polygon", poly);
- poly.remove(closest_idx);
+ ERR_FAIL_INDEX_V(edited_point, poly.size(), false);
+ poly[edited_point] = edited_point_pos - node->get_offset();
+ undo_redo->create_action(TTR("Edit Poly"));
undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_undo_method(node, "set_polygon", pre_move_edit);
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
undo_redo->commit_action();
+
+ edited_point = -1;
return true;
}
}
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed() && edited_point == -1) {
- } break;
- }
+ int closest_idx = -1;
+ Vector2 closest_pos;
+ real_t closest_dist = 1e10;
+ for (int i = 0; i < poly.size(); i++) {
- } break;
- case InputEvent::MOUSE_MOTION: {
+ Vector2 cp = xform.xform(poly[i] + node->get_offset());
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ real_t d = cp.distance_to(gpoint);
+ if (d < closest_dist && d < grab_treshold) {
+ closest_dist = d;
+ closest_pos = cp;
+ closest_idx = i;
+ }
+ }
- if (edited_point != -1 && (wip_active || mm.button_mask & BUTTON_MASK_LEFT)) {
+ if (closest_idx >= 0) {
- Vector2 gpoint = Point2(mm.x, mm.y);
- Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
- cpoint = canvas_item_editor->snap_point(cpoint);
- edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+ undo_redo->create_action(TTR("Edit Poly (Remove Point)"));
+ undo_redo->add_undo_method(node, "set_polygon", poly);
+ poly.remove(closest_idx);
+ undo_redo->add_do_method(node, "set_polygon", poly);
+ undo_redo->add_do_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(), "update");
+ undo_redo->commit_action();
+ return true;
+ }
+ }
- canvas_item_editor->get_viewport_control()->update();
- }
+ } break;
+ }
+ }
- } break;
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+
+ if (edited_point != -1 && (wip_active || mm->get_button_mask() & BUTTON_MASK_LEFT)) {
+
+ Vector2 gpoint = mm->get_position();
+ Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
+ cpoint = canvas_item_editor->snap_point(cpoint);
+ edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
+
+ canvas_item_editor->get_viewport_control()->update();
+ }
}
return false;
@@ -455,31 +451,31 @@ void Polygon2DEditor::_uv_mode(int p_mode) {
}
}
-void Polygon2DEditor::_uv_input(const InputEvent &p_input) {
+void Polygon2DEditor::_uv_input(const Ref<InputEvent> &p_input) {
Transform2D mtx;
mtx.elements[2] = -uv_draw_ofs;
mtx.scale_basis(Vector2(uv_draw_zoom, uv_draw_zoom));
- if (p_input.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_input;
- const InputEventMouseButton &mb = p_input.mouse_button;
+ if (mb.is_valid()) {
- if (mb.button_index == BUTTON_LEFT) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
- if (mb.pressed) {
+ if (mb->is_pressed()) {
- uv_drag_from = Vector2(mb.x, mb.y);
+ uv_drag_from = Vector2(mb->get_position().x, mb->get_position().y);
uv_drag = true;
uv_prev = node->get_uv();
uv_move_current = uv_mode;
if (uv_move_current == UV_MODE_EDIT_POINT) {
- if (mb.mod.shift && mb.mod.command)
+ if (mb->get_shift() && mb->get_command())
uv_move_current = UV_MODE_SCALE;
- else if (mb.mod.shift)
+ else if (mb->get_shift())
uv_move_current = UV_MODE_MOVE;
- else if (mb.mod.command)
+ else if (mb->get_command())
uv_move_current = UV_MODE_ROTATE;
}
@@ -489,7 +485,7 @@ void Polygon2DEditor::_uv_input(const InputEvent &p_input) {
for (int i = 0; i < uv_prev.size(); i++) {
Vector2 tuv = mtx.xform(uv_prev[i]);
- if (tuv.distance_to(Vector2(mb.x, mb.y)) < 8) {
+ if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) {
uv_drag_from = tuv;
uv_drag_index = i;
}
@@ -511,7 +507,7 @@ void Polygon2DEditor::_uv_input(const InputEvent &p_input) {
uv_drag = false;
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed) {
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
if (uv_drag) {
@@ -520,27 +516,28 @@ void Polygon2DEditor::_uv_input(const InputEvent &p_input) {
uv_edit_draw->update();
}
- } else if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
+ } else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
- uv_zoom->set_value(uv_zoom->get_value() / 0.9);
- } else if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
+ uv_zoom->set_value(uv_zoom->get_value() / (1 - (0.1 * mb->get_factor())));
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
- uv_zoom->set_value(uv_zoom->get_value() * 0.9);
+ uv_zoom->set_value(uv_zoom->get_value() * (1 - (0.1 * mb->get_factor())));
}
+ }
- } else if (p_input.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_input;
- const InputEventMouseMotion &mm = p_input.mouse_motion;
+ if (mm.is_valid()) {
- if (mm.button_mask & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+ if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
- Vector2 drag(mm.relative_x, mm.relative_y);
+ Vector2 drag(mm->get_relative().x, mm->get_relative().y);
uv_hscroll->set_value(uv_hscroll->get_value() - drag.x);
uv_vscroll->set_value(uv_vscroll->get_value() - drag.y);
} else if (uv_drag) {
- Vector2 uv_drag_to = snap_point(Vector2(mm.x, mm.y));
+ Vector2 uv_drag_to = mm->get_position();
Vector2 drag = mtx.affine_inverse().xform(uv_drag_to) - mtx.affine_inverse().xform(uv_drag_from);
switch (uv_move_current) {
@@ -678,14 +675,14 @@ void Polygon2DEditor::_uv_draw() {
rect = rect.grow(200);
updating_uv_scroll = true;
- uv_hscroll->set_min(rect.pos.x);
- uv_hscroll->set_max(rect.pos.x + rect.size.x);
+ uv_hscroll->set_min(rect.position.x);
+ uv_hscroll->set_max(rect.position.x + rect.size.x);
uv_hscroll->set_page(uv_edit_draw->get_size().x);
uv_hscroll->set_value(uv_draw_ofs.x);
uv_hscroll->set_step(0.001);
- uv_vscroll->set_min(rect.pos.y);
- uv_vscroll->set_max(rect.pos.y + rect.size.y);
+ uv_vscroll->set_min(rect.position.y);
+ uv_vscroll->set_max(rect.position.y + rect.size.y);
uv_vscroll->set_page(uv_edit_draw->get_size().y);
uv_vscroll->set_value(uv_draw_ofs.y);
uv_vscroll->set_step(0.001);
diff --git a/editor/plugins/polygon_2d_editor_plugin.h b/editor/plugins/polygon_2d_editor_plugin.h
index 00926bf2d1..0901cc9082 100644
--- a/editor/plugins/polygon_2d_editor_plugin.h
+++ b/editor/plugins/polygon_2d_editor_plugin.h
@@ -113,7 +113,7 @@ class Polygon2DEditor : public HBoxContainer {
Vector2 snap_step;
void _uv_scroll_changed(float);
- void _uv_input(const InputEvent &p_input);
+ void _uv_input(const Ref<InputEvent> &p_input);
void _uv_draw();
void _uv_mode(int p_mode);
void _wip_close();
@@ -135,7 +135,7 @@ protected:
Vector2 snap_point(Vector2 p_target) const;
public:
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_collision_polygon);
Polygon2DEditor(EditorNode *p_editor);
};
@@ -148,7 +148,7 @@ class Polygon2DEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return collision_polygon_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "Polygon2D"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/resource_preloader_editor_plugin.cpp b/editor/plugins/resource_preloader_editor_plugin.cpp
index 3b8d655af7..ea7a84d2f4 100644
--- a/editor/plugins/resource_preloader_editor_plugin.cpp
+++ b/editor/plugins/resource_preloader_editor_plugin.cpp
@@ -33,7 +33,7 @@
#include "global_config.h"
#include "io/resource_loader.h"
-void ResourcePreloaderEditor::_gui_input(InputEvent p_event) {
+void ResourcePreloaderEditor::_gui_input(Ref<InputEvent> p_event) {
}
void ResourcePreloaderEditor::_notification(int p_what) {
diff --git a/editor/plugins/resource_preloader_editor_plugin.h b/editor/plugins/resource_preloader_editor_plugin.h
index fad3ba93f1..1f54620ba4 100644
--- a/editor/plugins/resource_preloader_editor_plugin.h
+++ b/editor/plugins/resource_preloader_editor_plugin.h
@@ -70,7 +70,7 @@ class ResourcePreloaderEditor : public PanelContainer {
protected:
void _notification(int p_what);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
public:
diff --git a/editor/plugins/script_editor_plugin.cpp b/editor/plugins/script_editor_plugin.cpp
index a5414325d0..f3941d6a16 100644
--- a/editor/plugins/script_editor_plugin.cpp
+++ b/editor/plugins/script_editor_plugin.cpp
@@ -38,7 +38,6 @@
#include "os/file_access.h"
#include "os/input.h"
#include "os/keyboard.h"
-#include "os/keyboard.h"
#include "os/os.h"
#include "scene/main/viewport.h"
@@ -48,6 +47,7 @@ void ScriptEditorBase::_bind_methods() {
ADD_SIGNAL(MethodInfo("name_changed"));
ADD_SIGNAL(MethodInfo("request_help_search", PropertyInfo(Variant::STRING, "topic")));
+ ADD_SIGNAL(MethodInfo("request_help_index"));
ADD_SIGNAL(MethodInfo("request_open_script_at_line", PropertyInfo(Variant::OBJECT, "script"), PropertyInfo(Variant::INT, "line")));
ADD_SIGNAL(MethodInfo("request_save_history"));
ADD_SIGNAL(MethodInfo("go_to_help", PropertyInfo(Variant::STRING, "what")));
@@ -164,14 +164,16 @@ void ScriptEditorQuickOpen::_text_changed(const String &p_newtext) {
_update_search();
}
-void ScriptEditorQuickOpen::_sbox_input(const InputEvent &p_ie) {
+void ScriptEditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
+
+ Ref<InputEventKey> k = p_ie;
- if (p_ie.type == InputEvent::KEY && (p_ie.key.scancode == KEY_UP ||
- p_ie.key.scancode == KEY_DOWN ||
- p_ie.key.scancode == KEY_PAGEUP ||
- p_ie.key.scancode == KEY_PAGEDOWN)) {
+ if (k.is_valid() && (k->get_scancode() == KEY_UP ||
+ k->get_scancode() == KEY_DOWN ||
+ k->get_scancode() == KEY_PAGEUP ||
+ k->get_scancode() == KEY_PAGEDOWN)) {
- search_options->call("_gui_input", p_ie);
+ search_options->call("_gui_input", k);
search_box->accept_event();
}
}
@@ -408,7 +410,9 @@ void ScriptEditor::_go_to_tab(int p_idx) {
c->set_meta("__editor_pass", ++edit_pass);
_update_history_arrows();
_update_script_colors();
+ _update_members_overview();
_update_selected_editor_menu();
+ _update_members_overview_visibility();
}
void ScriptEditor::_add_recent_script(String p_path) {
@@ -538,6 +542,7 @@ void ScriptEditor::_close_tab(int p_idx, bool p_save) {
_update_history_arrows();
_update_script_names();
+ _update_members_overview_visibility();
_save_layout();
}
@@ -1023,6 +1028,7 @@ void ScriptEditor::_notification(int p_what) {
editor->connect("script_add_function_request", this, "_add_callback");
editor->connect("resource_saved", this, "_res_saved_callback");
script_list->connect("item_selected", this, "_script_selected");
+ members_overview->connect("item_selected", this, "_members_overview_selected");
script_split->connect("dragged", this, "_script_split_dragged");
autosave_timer->connect("timeout", this, "_autosave_scripts");
{
@@ -1037,7 +1043,7 @@ void ScriptEditor::_notification(int p_what) {
EditorSettings::get_singleton()->connect("settings_changed", this, "_editor_settings_changed");
help_search->set_icon(get_icon("Help", "EditorIcons"));
- site_search->set_icon(get_icon("Godot", "EditorIcons"));
+ site_search->set_icon(get_icon("Instance", "EditorIcons"));
class_search->set_icon(get_icon("ClassList", "EditorIcons"));
script_forward->set_icon(get_icon("Forward", "EditorIcons"));
@@ -1048,6 +1054,8 @@ void ScriptEditor::_notification(int p_what) {
get_tree()->connect("tree_changed", this, "_tree_changed");
editor->connect("request_help", this, "_request_help");
+ editor->connect("request_help_search", this, "_help_search");
+ editor->connect("request_help_index", this, "_help_index");
}
if (p_what == NOTIFICATION_EXIT_TREE) {
@@ -1269,6 +1277,16 @@ void ScriptEditor::ensure_focus_current() {
se->ensure_focus();
}
+void ScriptEditor::_members_overview_selected(int p_idx) {
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ return;
+ }
+ se->goto_line(members_overview->get_item_metadata(p_idx));
+ se->ensure_focus();
+}
+
void ScriptEditor::_script_selected(int p_idx) {
grab_focus_block = !Input::get_singleton()->is_mouse_button_pressed(1); //amazing hack, simply amazing
@@ -1338,6 +1356,37 @@ struct _ScriptEditorItemData {
}
};
+void ScriptEditor::_update_members_overview_visibility() {
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ members_overview->set_visible(false);
+ return;
+ }
+
+ if (members_overview_enabled && se->show_members_overview()) {
+ members_overview->set_visible(true);
+ } else {
+ members_overview->set_visible(false);
+ }
+}
+
+void ScriptEditor::_update_members_overview() {
+ members_overview->clear();
+
+ Node *current = tab_container->get_child(tab_container->get_current_tab());
+ ScriptEditorBase *se = current->cast_to<ScriptEditorBase>();
+ if (!se) {
+ return;
+ }
+
+ Vector<String> functions = se->get_functions();
+ for (int i = 0; i < functions.size(); i++) {
+ members_overview->add_item(functions[i].get_slice(":", 0));
+ members_overview->set_item_metadata(i, functions[i].get_slice(":", 1).to_int() - 1);
+ }
+}
+
void ScriptEditor::_update_script_colors() {
bool script_temperature_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/script_temperature_enabled");
@@ -1374,8 +1423,7 @@ void ScriptEditor::_update_script_colors() {
int non_zero_hist_size = (hist_size == 0) ? 1 : hist_size;
float v = Math::ease((edit_pass - pass) / float(non_zero_hist_size), 0.4);
- //script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v));
- script_list->set_item_custom_font_color(i, hot_color.linear_interpolate(cold_color, v));
+ script_list->set_item_custom_bg_color(i, hot_color.linear_interpolate(cold_color, v));
}
}
}
@@ -1482,6 +1530,7 @@ void ScriptEditor::_update_script_names() {
}
}
+ _update_members_overview();
_update_script_colors();
}
@@ -1730,6 +1779,9 @@ void ScriptEditor::_editor_settings_changed() {
convert_indent_on_save = EditorSettings::get_singleton()->get("text_editor/indent/convert_indent_on_save");
use_space_indentation = EditorSettings::get_singleton()->get("text_editor/indent/type");
+ members_overview_enabled = EditorSettings::get_singleton()->get("text_editor/open_scripts/show_members_overview");
+ _update_members_overview_visibility();
+
float autosave_time = EditorSettings::get_singleton()->get("text_editor/files/autosave_interval_secs");
if (autosave_time > 0) {
autosave_timer->set_wait_time(autosave_time);
@@ -1778,8 +1830,8 @@ void ScriptEditor::_script_split_dragged(float) {
_save_layout();
}
-void ScriptEditor::_unhandled_input(const InputEvent &p_event) {
- if (p_event.key.pressed || !is_visible_in_tree()) return;
+void ScriptEditor::_unhandled_input(const Ref<InputEvent> &p_event) {
+ if (p_event->is_pressed() || !is_visible_in_tree()) return;
if (ED_IS_SHORTCUT("script_editor/next_script", p_event)) {
int next_tab = script_list->get_current() + 1;
next_tab %= script_list->get_item_count();
@@ -2026,6 +2078,10 @@ void ScriptEditor::set_live_auto_reload_running_scripts(bool p_enabled) {
auto_reload_running_scripts = p_enabled;
}
+void ScriptEditor::_help_index(String p_text) {
+ help_index->popup();
+}
+
void ScriptEditor::_help_search(String p_text) {
help_search_dialog->popup(p_text);
}
@@ -2067,6 +2123,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_goto_script_line", &ScriptEditor::_goto_script_line);
ClassDB::bind_method("_goto_script_line2", &ScriptEditor::_goto_script_line2);
ClassDB::bind_method("_help_search", &ScriptEditor::_help_search);
+ ClassDB::bind_method("_help_index", &ScriptEditor::_help_index);
ClassDB::bind_method("_save_history", &ScriptEditor::_save_history);
ClassDB::bind_method("_breaked", &ScriptEditor::_breaked);
@@ -2076,6 +2133,7 @@ void ScriptEditor::_bind_methods() {
ClassDB::bind_method("_editor_settings_changed", &ScriptEditor::_editor_settings_changed);
ClassDB::bind_method("_update_script_names", &ScriptEditor::_update_script_names);
ClassDB::bind_method("_tree_changed", &ScriptEditor::_tree_changed);
+ ClassDB::bind_method("_members_overview_selected", &ScriptEditor::_members_overview_selected);
ClassDB::bind_method("_script_selected", &ScriptEditor::_script_selected);
ClassDB::bind_method("_script_created", &ScriptEditor::_script_created);
ClassDB::bind_method("_script_split_dragged", &ScriptEditor::_script_split_dragged);
@@ -2097,6 +2155,7 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
waiting_update_names = false;
pending_auto_reload = false;
auto_reload_running_scripts = false;
+ members_overview_enabled = true;
editor = p_editor;
menu_hb = memnew(HBoxContainer);
@@ -2106,13 +2165,22 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
add_child(script_split);
script_split->set_v_size_flags(SIZE_EXPAND_FILL);
+ list_split = memnew(VSplitContainer);
+ script_split->add_child(list_split);
+ list_split->set_v_size_flags(SIZE_EXPAND_FILL);
+
script_list = memnew(ItemList);
- script_split->add_child(script_list);
+ list_split->add_child(script_list);
script_list->set_custom_minimum_size(Size2(0, 0));
script_split->set_split_offset(140);
+ list_split->set_split_offset(500);
+
+ members_overview = memnew(ItemList);
+ list_split->add_child(members_overview);
+ members_overview->set_custom_minimum_size(Size2(0, 0));
tab_container = memnew(TabContainer);
- tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("EditorBG", "EditorStyles"));
+ tab_container->add_style_override("panel", p_editor->get_gui_base()->get_stylebox("ScriptPanel", "EditorStyles"));
tab_container->set_tabs_visible(false);
script_split->add_child(tab_container);
@@ -2209,10 +2277,10 @@ ScriptEditor::ScriptEditor(EditorNode *p_editor) {
menu_hb->add_spacer();
site_search = memnew(ToolButton);
- site_search->set_text(TTR("Tutorials"));
+ site_search->set_text(TTR("Online Docs"));
site_search->connect("pressed", this, "_menu_option", varray(SEARCH_WEBSITE));
menu_hb->add_child(site_search);
- site_search->set_tooltip(TTR("Open https://godotengine.org at tutorials section."));
+ site_search->set_tooltip(TTR("Open Godot online documentation"));
class_search = memnew(ToolButton);
class_search->set_text(TTR("Classes"));
@@ -2431,8 +2499,8 @@ ScriptEditorPlugin::ScriptEditorPlugin(EditorNode *p_node) {
EDITOR_DEF("text_editor/open_scripts/script_temperature_enabled", true);
EDITOR_DEF("text_editor/open_scripts/highlight_current_script", true);
EDITOR_DEF("text_editor/open_scripts/script_temperature_history_size", 15);
- EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color::html("ff5446"));
- EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color::html("647b93"));
+ EDITOR_DEF("text_editor/open_scripts/script_temperature_hot_color", Color(1, 0, 0, 0.3));
+ EDITOR_DEF("text_editor/open_scripts/script_temperature_cold_color", Color(0, 0, 1, 0.3));
EDITOR_DEF("text_editor/open_scripts/current_script_background_color", Color(0.81, 0.81, 0.14, 0.63));
EDITOR_DEF("text_editor/open_scripts/group_help_pages", true);
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT, "text_editor/open_scripts/sort_scripts_by", PROPERTY_HINT_ENUM, "Name,Path"));
diff --git a/editor/plugins/script_editor_plugin.h b/editor/plugins/script_editor_plugin.h
index 983847ddaf..e036d1ed9c 100644
--- a/editor/plugins/script_editor_plugin.h
+++ b/editor/plugins/script_editor_plugin.h
@@ -54,7 +54,7 @@ class ScriptEditorQuickOpen : public ConfirmationDialog {
void _update_search();
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
Vector<String> functions;
void _confirmed();
@@ -102,6 +102,8 @@ public:
virtual void set_debugger_active(bool p_active) = 0;
virtual bool can_lose_focus_on_node_selection() { return true; }
+ virtual bool show_members_overview() = 0;
+
virtual void set_tooltip_request_func(String p_method, Object *p_obj) = 0;
virtual Control *get_edit_menu() = 0;
@@ -179,6 +181,9 @@ class ScriptEditor : public VBoxContainer {
ItemList *script_list;
HSplitContainer *script_split;
+ ItemList *members_overview;
+ bool members_overview_enabled;
+ VSplitContainer *list_split;
TabContainer *tab_container;
EditorFileDialog *file_dialog;
ConfirmationDialog *erase_tab_confirm;
@@ -278,8 +283,11 @@ class ScriptEditor : public VBoxContainer {
void _editor_settings_changed();
void _autosave_scripts();
+ void _update_members_overview_visibility();
+ void _update_members_overview();
void _update_script_names();
+ void _members_overview_selected(int p_idx);
void _script_selected(int p_idx);
void _find_scripts(Node *p_base, Node *p_current, Set<Ref<Script> > &used);
@@ -288,9 +296,10 @@ class ScriptEditor : public VBoxContainer {
void _script_split_dragged(float);
- void _unhandled_input(const InputEvent &p_event);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
void _help_search(String p_text);
+ void _help_index(String p_text);
void _history_forward();
void _history_back();
diff --git a/editor/plugins/script_text_editor.cpp b/editor/plugins/script_text_editor.cpp
index 3bb1c7852b..9f76119374 100644
--- a/editor/plugins/script_text_editor.cpp
+++ b/editor/plugins/script_text_editor.cpp
@@ -124,7 +124,6 @@ void ScriptTextEditor::_load_theme_settings() {
text_edit->add_keyword_color("Transform", basetype_color);
text_edit->add_keyword_color("Color", basetype_color);
text_edit->add_keyword_color("Image", basetype_color);
- text_edit->add_keyword_color("InputEvent", basetype_color);
text_edit->add_keyword_color("Rect2", basetype_color);
text_edit->add_keyword_color("NodePath", basetype_color);
@@ -219,6 +218,10 @@ void ScriptTextEditor::add_callback(const String &p_function, PoolStringArray p_
code_editor->get_text_edit()->cursor_set_column(1);
}
+bool ScriptTextEditor::show_members_overview() {
+ return true;
+}
+
void ScriptTextEditor::update_settings() {
code_editor->update_editor_settings();
@@ -1227,15 +1230,18 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
}
}
-void ScriptTextEditor::_text_edit_gui_input(const InputEvent &ev) {
- if (ev.type == InputEvent::MOUSE_BUTTON) {
- InputEventMouseButton mb = ev.mouse_button;
- if (mb.button_index == BUTTON_RIGHT && !mb.pressed) {
+void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> mb = ev;
+
+ if (mb.is_valid()) {
+
+ if (mb->get_button_index() == BUTTON_RIGHT && !mb->is_pressed()) {
int col, row;
TextEdit *tx = code_editor->get_text_edit();
- tx->_get_mouse_pos(Point2i(mb.global_x, mb.global_y) - tx->get_global_position(), row, col);
- Vector2 mpos = Vector2(mb.global_x, mb.global_y) - tx->get_global_position();
+ tx->_get_mouse_pos(mb->get_global_position() - tx->get_global_position(), row, col);
+ Vector2 mpos = mb->get_global_position() - tx->get_global_position();
bool have_selection = (tx->get_selection_text().length() > 0);
bool have_color = (tx->get_word_at_pos(mpos) == "Color");
if (have_color) {
diff --git a/editor/plugins/script_text_editor.h b/editor/plugins/script_text_editor.h
index 77bce59f2e..ba40645161 100644
--- a/editor/plugins/script_text_editor.h
+++ b/editor/plugins/script_text_editor.h
@@ -106,7 +106,7 @@ protected:
void _edit_option(int p_op);
void _make_context_menu(bool p_selection, bool p_color);
- void _text_edit_gui_input(const InputEvent &ev);
+ void _text_edit_gui_input(const Ref<InputEvent> &ev);
void _color_changed(const Color &p_color);
void _goto_line(int p_line) { goto_line(p_line); }
@@ -149,6 +149,8 @@ public:
virtual void add_callback(const String &p_function, PoolStringArray p_args);
virtual void update_settings();
+ virtual bool show_members_overview();
+
virtual void set_tooltip_request_func(String p_method, Object *p_obj);
virtual void set_debugger_active(bool p_active);
diff --git a/editor/plugins/shader_editor_plugin.cpp b/editor/plugins/shader_editor_plugin.cpp
index 8ae7d55bdd..7c8ee97f22 100644
--- a/editor/plugins/shader_editor_plugin.cpp
+++ b/editor/plugins/shader_editor_plugin.cpp
@@ -552,7 +552,8 @@ ShaderEditorPlugin::ShaderEditorPlugin(EditorNode *p_node) {
shader_editor = memnew(ShaderEditor);
shader_editor->set_custom_minimum_size(Size2(0, 300));
- button = editor->add_bottom_panel_item("Shader", shader_editor);
+ button = editor->add_bottom_panel_item(TTR("Shader"), shader_editor);
+ button->hide();
}
ShaderEditorPlugin::~ShaderEditorPlugin() {
diff --git a/editor/plugins/shader_graph_editor_plugin.cpp b/editor/plugins/shader_graph_editor_plugin.cpp
index 0fd28a0b59..9c65ef667a 100644
--- a/editor/plugins/shader_graph_editor_plugin.cpp
+++ b/editor/plugins/shader_graph_editor_plugin.cpp
@@ -40,7 +40,7 @@
void GraphColorRampEdit::_gui_input(const InputEvent& p_event) {
- if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) {
+ if (p_event.type==InputEvent::KEY && p_event->is_pressed() && p_event->get_scancode()==KEY_DELETE && grabbed!=-1) {
points.remove(grabbed);
grabbed=-1;
@@ -49,10 +49,10 @@ void GraphColorRampEdit::_gui_input(const InputEvent& p_event) {
accept_event();
}
- if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==1 && p_event->is_pressed()) {
update();
- int x = p_event.mouse_button.x;
+ int x = p_event->get_pos().x;
int total_w = get_size().width-get_size().height-3;
if (x>total_w+3) {
@@ -132,7 +132,7 @@ void GraphColorRampEdit::_gui_input(const InputEvent& p_event) {
}
- if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) {
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==1 && !p_event->is_pressed()) {
if (grabbing) {
grabbing=false;
@@ -319,7 +319,7 @@ GraphColorRampEdit::GraphColorRampEdit(){
void GraphCurveMapEdit::_gui_input(const InputEvent& p_event) {
- if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) {
+ if (p_event.type==InputEvent::KEY && p_event->is_pressed() && p_event->get_scancode()==KEY_DELETE && grabbed!=-1) {
points.remove(grabbed);
grabbed=-1;
@@ -328,10 +328,10 @@ void GraphCurveMapEdit::_gui_input(const InputEvent& p_event) {
accept_event();
}
- if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==1 && p_event->is_pressed()) {
update();
- Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size();
+ Point2 p = Vector2(p_event->get_pos().x,p_event->get_pos().y)/get_size();
p.y=1.0-p.y;
grabbed=-1;
grabbing=true;
@@ -371,7 +371,7 @@ void GraphCurveMapEdit::_gui_input(const InputEvent& p_event) {
}
- if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) {
+ if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==1 && !p_event->is_pressed()) {
if (grabbing) {
grabbing=false;
@@ -382,7 +382,7 @@ void GraphCurveMapEdit::_gui_input(const InputEvent& p_event) {
if (p_event.type==InputEvent::MOUSE_MOTION && grabbing && grabbed != -1) {
- Point2 p = Vector2(p_event.mouse_button.x,p_event.mouse_button.y)/get_size();
+ Point2 p = Vector2(p_event->get_pos().x,p_event->get_pos().y)/get_size();
p.y=1.0-p.y;
p.x = CLAMP(p.x,0.0,1.0);
diff --git a/editor/plugins/spatial_editor_plugin.cpp b/editor/plugins/spatial_editor_plugin.cpp
index d73349f773..2d27e218ec 100644
--- a/editor/plugins/spatial_editor_plugin.cpp
+++ b/editor/plugins/spatial_editor_plugin.cpp
@@ -51,6 +51,12 @@
//#define GIZMO_SCALE_DEFAULT 0.28
#define GIZMO_SCALE_DEFAULT 0.15
+#define ZOOM_MIN_DISTANCE 0.001
+#define ZOOM_MULTIPLIER 1.08
+#define ZOOM_INDICATOR_DELAY_S 1.5
+
+#define FREELOOK_MIN_SPEED 0.1
+
void SpatialEditorViewport::_update_camera() {
if (orthogonal) {
//camera->set_orthogonal(size.width*cursor.distance,get_znear(),get_zfar());
@@ -58,20 +64,26 @@ void SpatialEditorViewport::_update_camera() {
} else
camera->set_perspective(get_fov(), get_znear(), get_zfar());
+ Transform camera_transform = to_camera_transform(cursor);
+
+ if (camera->get_global_transform() != camera_transform) {
+ camera->set_global_transform(camera_transform);
+ update_transform_gizmo_view();
+ }
+}
+
+Transform SpatialEditorViewport::to_camera_transform(const Cursor &p_cursor) const {
Transform camera_transform;
- camera_transform.translate(cursor.pos);
- camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
- camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
+ camera_transform.translate(p_cursor.pos);
+ camera_transform.basis.rotate(Vector3(1, 0, 0), -p_cursor.x_rot);
+ camera_transform.basis.rotate(Vector3(0, 1, 0), -p_cursor.y_rot);
if (orthogonal)
camera_transform.translate(0, 0, 4096);
else
- camera_transform.translate(0, 0, cursor.distance);
+ camera_transform.translate(0, 0, p_cursor.distance);
- if (camera->get_global_transform() != camera_transform) {
- camera->set_global_transform(camera_transform);
- update_transform_gizmo_view();
- }
+ return camera_transform;
}
String SpatialEditorGizmo::get_handle_name(int p_idx) const {
@@ -519,12 +531,12 @@ static int _get_key_modifier(const String &p_property) {
return 0;
}
-bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hilite_only) {
+bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only) {
if (!spatial_editor->is_gizmo_visible())
return false;
if (get_selected_count() == 0) {
- if (p_hilite_only)
+ if (p_highlight_only)
spatial_editor->select_gizmo_highlight_axis(-1);
return false;
}
@@ -557,7 +569,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
if (col_axis != -1) {
- if (p_hilite_only) {
+ if (p_highlight_only) {
spatial_editor->select_gizmo_highlight_axis(col_axis);
@@ -597,7 +609,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
if (col_axis != -1) {
- if (p_hilite_only) {
+ if (p_highlight_only) {
spatial_editor->select_gizmo_highlight_axis(col_axis + 3);
} else {
@@ -610,7 +622,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2 &p_screenpos, bool p_hil
}
}
- if (p_hilite_only)
+ if (p_highlight_only)
spatial_editor->select_gizmo_highlight_axis(-1);
return false;
@@ -622,9 +634,9 @@ void SpatialEditorViewport::_smouseenter() {
surface->grab_focus();
}
-void SpatialEditorViewport::_list_select(InputEventMouseButton b) {
+void SpatialEditorViewport::_list_select(Ref<InputEventMouseButton> b) {
- _find_items_at_pos(Vector2(b.x, b.y), clicked_includes_current, selection_results, b.mod.shift);
+ _find_items_at_pos(b->get_position(), clicked_includes_current, selection_results, b->get_shift());
Node *scene = editor->get_edited_scene();
@@ -637,7 +649,7 @@ void SpatialEditorViewport::_list_select(InputEventMouseButton b) {
}
}
- clicked_wants_append = b.mod.shift;
+ clicked_wants_append = b->get_shift();
if (selection_results.size() == 1) {
@@ -669,877 +681,933 @@ void SpatialEditorViewport::_list_select(InputEventMouseButton b) {
selection_menu->add_item(spat->get_name());
selection_menu->set_item_icon(i, icon);
selection_menu->set_item_metadata(i, node_path);
- selection_menu->set_item_tooltip(i, String(spat->get_name()) +
- "\nType: " + spat->get_class() + "\nPath: " + node_path);
+ selection_menu->set_item_tooltip(i, String(spat->get_name()) + "\nType: " + spat->get_class() + "\nPath: " + node_path);
}
- selection_menu->set_global_position(Vector2(b.global_x, b.global_y));
+ selection_menu->set_global_position(b->get_global_position());
selection_menu->popup();
selection_menu->call_deferred("grab_click_focus");
selection_menu->set_invalidate_click_until_motion();
}
}
-void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
+void SpatialEditorViewport::_sinput(const Ref<InputEvent> &p_event) {
if (previewing)
return; //do NONE
{
-
+ EditorNode *en = editor;
+ EditorPluginList *force_input_forwarding_list = en->get_editor_plugins_force_input_forwarding();
+ if (!force_input_forwarding_list->empty()) {
+ bool discard = force_input_forwarding_list->forward_spatial_gui_input(camera, p_event, true);
+ if (discard)
+ return;
+ }
+ }
+ {
EditorNode *en = editor;
EditorPluginList *over_plugin_list = en->get_editor_plugins_over();
-
if (!over_plugin_list->empty()) {
- bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event);
+ bool discard = over_plugin_list->forward_spatial_gui_input(camera, p_event, false);
if (discard)
return;
}
}
- switch (p_event.type) {
- case InputEvent::MOUSE_BUTTON: {
-
- const InputEventMouseButton &b = p_event.mouse_button;
-
- switch (b.button_index) {
+ Ref<InputEventMouseButton> b = p_event;
- case BUTTON_WHEEL_UP: {
+ if (b.is_valid()) {
- cursor.distance /= 1.08;
- if (cursor.distance < 0.001)
- cursor.distance = 0.001;
+ switch (b->get_button_index()) {
- } break;
- case BUTTON_WHEEL_DOWN: {
+ case BUTTON_WHEEL_UP: {
+ scale_cursor_distance(is_freelook_active() ? ZOOM_MULTIPLIER : 1.0 / ZOOM_MULTIPLIER);
+ } break;
- if (cursor.distance < 0.001)
- cursor.distance = 0.001;
- cursor.distance *= 1.08;
+ case BUTTON_WHEEL_DOWN: {
+ scale_cursor_distance(is_freelook_active() ? 1.0 / ZOOM_MULTIPLIER : ZOOM_MULTIPLIER);
+ } break;
- } break;
- case BUTTON_RIGHT: {
+ case BUTTON_RIGHT: {
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
- if (b.pressed && _edit.gizmo.is_valid()) {
- //restore
- _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true);
- _edit.gizmo = Ref<SpatialEditorGizmo>();
- }
+ if (b->is_pressed() && _edit.gizmo.is_valid()) {
+ //restore
+ _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, true);
+ _edit.gizmo = Ref<SpatialEditorGizmo>();
+ }
- if (_edit.mode == TRANSFORM_NONE && b.pressed) {
+ if (_edit.mode == TRANSFORM_NONE && b->is_pressed()) {
- Plane cursor_plane(cursor.cursor_pos, _get_camera_normal());
+ if (b->get_alt()) {
- Vector3 ray_origin = _get_ray_pos(Vector2(b.x, b.y));
- Vector3 ray_dir = _get_ray(Vector2(b.x, b.y));
+ if (nav_scheme == NAVIGATION_MAYA)
+ break;
- //gizmo modify
+ _list_select(b);
+ return;
+ }
+ }
- if (b.mod.control) {
+ if (_edit.mode != TRANSFORM_NONE && b->is_pressed()) {
+ //cancel motion
+ _edit.mode = TRANSFORM_NONE;
+ //_validate_selection();
- Vector<ObjectID> instances = VisualServer::get_singleton()->instances_cull_ray(ray_origin, ray_dir, get_tree()->get_root()->get_world()->get_scenario());
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- Plane p(ray_origin, _get_camera_normal());
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- float min_d = 1e10;
- bool found = false;
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp)
+ continue;
- for (int i = 0; i < instances.size(); i++) {
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se)
+ continue;
- Object *obj = ObjectDB::get_instance(instances[i]);
+ sp->set_global_transform(se->original);
+ }
+ surface->update();
+ //VisualServer::get_singleton()->poly_clear(indicators);
+ set_message(TTR("Transform Aborted."), 3);
+ }
- if (!obj)
- continue;
+ freelook_active = b->is_pressed();
- VisualInstance *vi = obj->cast_to<VisualInstance>();
- if (!vi)
- continue;
+ } break;
+ case BUTTON_MIDDLE: {
- //optimize by checking AABB (although should pre sort by distance)
- Rect3 aabb = vi->get_global_transform().xform(vi->get_aabb());
- if (p.distance_to(aabb.get_support(-ray_dir)) > min_d)
- continue;
+ if (b->is_pressed() && _edit.mode != TRANSFORM_NONE) {
- PoolVector<Face3> faces = vi->get_faces(VisualInstance::FACES_SOLID);
- int c = faces.size();
- if (c > 0) {
- PoolVector<Face3>::Read r = faces.read();
+ switch (_edit.plane) {
- for (int j = 0; j < c; j++) {
+ case TRANSFORM_VIEW: {
- Vector3 inters;
- if (r[j].intersects_ray(ray_origin, ray_dir, &inters)) {
+ _edit.plane = TRANSFORM_X_AXIS;
+ set_message(TTR("X-Axis Transform."), 2);
+ name = "";
+ _update_name();
+ } break;
+ case TRANSFORM_X_AXIS: {
- float d = p.distance_to(inters);
- if (d < 0)
- continue;
+ _edit.plane = TRANSFORM_Y_AXIS;
+ set_message(TTR("Y-Axis Transform."), 2);
- if (d < min_d) {
- min_d = d;
- found = true;
- }
- }
- }
- }
- }
+ } break;
+ case TRANSFORM_Y_AXIS: {
- if (found) {
+ _edit.plane = TRANSFORM_Z_AXIS;
+ set_message(TTR("Z-Axis Transform."), 2);
- //cursor.cursor_pos=ray_origin+ray_dir*min_d;
- //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos));
- }
+ } break;
+ case TRANSFORM_Z_AXIS: {
- } else {
- Vector3 new_pos;
- if (cursor_plane.intersects_ray(ray_origin, ray_dir, &new_pos)) {
+ _edit.plane = TRANSFORM_VIEW;
+ set_message(TTR("View Plane Transform."), 2);
- //cursor.cursor_pos=new_pos;
- //VisualServer::get_singleton()->instance_set_transform(cursor_instance,Transform(Matrix3(),cursor.cursor_pos));
- }
- }
+ } break;
+ }
+ }
+ } break;
+ case BUTTON_LEFT: {
- if (b.mod.alt) {
+ if (b->is_pressed()) {
- if (nav_scheme == NAVIGATION_MAYA)
- break;
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b->get_alt()) {
+ break;
+ }
- _list_select(b);
- return;
- }
+ if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_LIST_SELECT) {
+ _list_select(b);
+ break;
}
- if (_edit.mode != TRANSFORM_NONE && b.pressed) {
- //cancel motion
- _edit.mode = TRANSFORM_NONE;
- //_validate_selection();
+ _edit.mouse_pos = b->get_position();
+ _edit.snap = false;
+ _edit.mode = TRANSFORM_NONE;
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ //gizmo has priority over everything
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ bool can_select_gizmos = true;
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp)
- continue;
+ {
+ int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
+ can_select_gizmos = view_menu->get_popup()->is_item_checked(idx);
+ }
- SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se)
- continue;
+ if (can_select_gizmos && spatial_editor->get_selected()) {
+
+ Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+ if (seg.is_valid()) {
+ int handle = -1;
+ Vector3 point;
+ Vector3 normal;
+ bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b->get_shift());
+ if (inters && handle != -1) {
- sp->set_global_transform(se->original);
+ _edit.gizmo = seg;
+ _edit.gizmo_handle = handle;
+ //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle);
+ _edit.gizmo_initial_value = seg->get_handle_value(handle);
+ break;
+ }
}
- surface->update();
- //VisualServer::get_singleton()->poly_clear(indicators);
- set_message(TTR("Transform Aborted."), 3);
}
- } break;
- case BUTTON_MIDDLE: {
- if (b.pressed && _edit.mode != TRANSFORM_NONE) {
+ if (_gizmo_select(_edit.mouse_pos))
+ break;
- switch (_edit.plane) {
+ clicked = 0;
+ clicked_includes_current = false;
- case TRANSFORM_VIEW: {
+ if ((spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT && b->get_control()) || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE) {
- _edit.plane = TRANSFORM_X_AXIS;
- set_message(TTR("X-Axis Transform."), 2);
- name = "";
- _update_name();
- } break;
- case TRANSFORM_X_AXIS: {
+ /* HANDLE ROTATION */
+ if (get_selected_count() == 0)
+ break; //bye
+ //handle rotate
+ _edit.mode = TRANSFORM_ROTATE;
+ _compute_edit(b->get_position());
+ break;
+ }
- _edit.plane = TRANSFORM_Y_AXIS;
- set_message(TTR("Y-Axis Transform."), 2);
+ if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE) {
- } break;
- case TRANSFORM_Y_AXIS: {
+ if (get_selected_count() == 0)
+ break; //bye
+ //handle rotate
+ _edit.mode = TRANSFORM_TRANSLATE;
+ _compute_edit(b->get_position());
+ break;
+ }
- _edit.plane = TRANSFORM_Z_AXIS;
- set_message(TTR("Z-Axis Transform."), 2);
+ if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE) {
- } break;
- case TRANSFORM_Z_AXIS: {
+ if (get_selected_count() == 0)
+ break; //bye
+ //handle rotate
+ _edit.mode = TRANSFORM_SCALE;
+ _compute_edit(b->get_position());
+ break;
+ }
- _edit.plane = TRANSFORM_VIEW;
- set_message(TTR("View Plane Transform."), 2);
+ // todo scale
- } break;
- }
- }
- } break;
- case BUTTON_LEFT: {
+ int gizmo_handle = -1;
- if (b.pressed) {
+ clicked = _select_ray(b->get_position(), b->get_shift(), clicked_includes_current, &gizmo_handle, b->get_shift());
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
- if ((nav_scheme == NAVIGATION_MAYA || nav_scheme == NAVIGATION_MODO) && b.mod.alt) {
- break;
- }
+ //clicking is always deferred to either move or release
- if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_LIST_SELECT) {
- _list_select(b);
- break;
- }
+ clicked_wants_append = b->get_shift();
- _edit.mouse_pos = Point2(b.x, b.y);
- _edit.snap = false;
- _edit.mode = TRANSFORM_NONE;
+ if (!clicked) {
- //gizmo has priority over everything
+ if (!clicked_wants_append)
+ _clear_selected();
- bool can_select_gizmos = true;
+ //default to regionselect
+ cursor.region_select = true;
+ cursor.region_begin = b->get_position();
+ cursor.region_end = b->get_position();
+ }
- {
- int idx = view_menu->get_popup()->get_item_index(VIEW_GIZMOS);
- can_select_gizmos = view_menu->get_popup()->is_item_checked(idx);
- }
+ if (clicked && gizmo_handle >= 0) {
+
+ Object *obj = ObjectDB::get_instance(clicked);
+ if (obj) {
- if (can_select_gizmos && spatial_editor->get_selected()) {
+ Spatial *spa = obj->cast_to<Spatial>();
+ if (spa) {
- Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
- if (seg.is_valid()) {
- int handle = -1;
- Vector3 point;
- Vector3 normal;
- bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, b.mod.shift);
- if (inters && handle != -1) {
+ Ref<SpatialEditorGizmo> seg = spa->get_gizmo();
+ if (seg.is_valid()) {
_edit.gizmo = seg;
- _edit.gizmo_handle = handle;
+ _edit.gizmo_handle = gizmo_handle;
//_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle);
- _edit.gizmo_initial_value = seg->get_handle_value(handle);
+ _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle);
+ //print_line("GIZMO: "+itos(gizmo_handle)+" FROMPOS: "+_edit.orig_gizmo_pos);
break;
}
}
}
+ //_compute_edit(Point2(b.x,b.y)); //in case a motion happens..
+ }
- if (_gizmo_select(_edit.mouse_pos))
- break;
-
- clicked = 0;
- clicked_includes_current = false;
-
- if ((spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SELECT && b.mod.control) || spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_ROTATE) {
-
- /* HANDLE ROTATION */
- if (get_selected_count() == 0)
- break; //bye
- //handle rotate
- _edit.mode = TRANSFORM_ROTATE;
- _compute_edit(Point2(b.x, b.y));
- break;
- }
-
- if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_MOVE) {
-
- if (get_selected_count() == 0)
- break; //bye
- //handle rotate
- _edit.mode = TRANSFORM_TRANSLATE;
- _compute_edit(Point2(b.x, b.y));
- break;
- }
-
- if (spatial_editor->get_tool_mode() == SpatialEditor::TOOL_MODE_SCALE) {
-
- if (get_selected_count() == 0)
- break; //bye
- //handle rotate
- _edit.mode = TRANSFORM_SCALE;
- _compute_edit(Point2(b.x, b.y));
- break;
- }
-
- // todo scale
-
- int gizmo_handle = -1;
-
- clicked = _select_ray(Vector2(b.x, b.y), b.mod.shift, clicked_includes_current, &gizmo_handle, b.mod.shift);
-
- //clicking is always deferred to either move or release
-
- clicked_wants_append = b.mod.shift;
-
- if (!clicked) {
-
- if (!clicked_wants_append)
- _clear_selected();
-
- //default to regionselect
- cursor.region_select = true;
- cursor.region_begin = Point2(b.x, b.y);
- cursor.region_end = Point2(b.x, b.y);
- }
-
- if (clicked && gizmo_handle >= 0) {
-
- Object *obj = ObjectDB::get_instance(clicked);
- if (obj) {
-
- Spatial *spa = obj->cast_to<Spatial>();
- if (spa) {
+ surface->update();
+ } else {
- Ref<SpatialEditorGizmo> seg = spa->get_gizmo();
- if (seg.is_valid()) {
+ if (_edit.gizmo.is_valid()) {
- _edit.gizmo = seg;
- _edit.gizmo_handle = gizmo_handle;
- //_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle);
- _edit.gizmo_initial_value = seg->get_handle_value(gizmo_handle);
- //print_line("GIZMO: "+itos(gizmo_handle)+" FROMPOS: "+_edit.orig_gizmo_pos);
- break;
- }
- }
- }
- //_compute_edit(Point2(b.x,b.y)); //in case a motion happens..
- }
+ _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false);
+ _edit.gizmo = Ref<SpatialEditorGizmo>();
+ break;
+ }
+ if (clicked) {
+ _select_clicked(clicked_wants_append, true);
+ //clickd processing was deferred
+ clicked = 0;
+ }
+ if (cursor.region_select) {
+ _select_region();
+ cursor.region_select = false;
surface->update();
- } else {
+ }
- if (_edit.gizmo.is_valid()) {
+ if (_edit.mode != TRANSFORM_NONE) {
- _edit.gizmo->commit_handle(_edit.gizmo_handle, _edit.gizmo_initial_value, false);
- _edit.gizmo = Ref<SpatialEditorGizmo>();
- break;
- }
- if (clicked) {
- _select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
- clicked = 0;
- }
+ static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" };
+ undo_redo->create_action(_transform_name[_edit.mode]);
- if (cursor.region_select) {
- _select_region();
- cursor.region_select = false;
- surface->update();
- }
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- if (_edit.mode != TRANSFORM_NONE) {
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- static const char *_transform_name[4] = { "None", "Rotate", "Translate", "Scale" };
- undo_redo->create_action(_transform_name[_edit.mode]);
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp)
+ continue;
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se)
+ continue;
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_transform());
+ undo_redo->add_undo_method(sp, "set_global_transform", se->original);
+ }
+ undo_redo->commit_action();
+ _edit.mode = TRANSFORM_NONE;
+ //VisualServer::get_singleton()->poly_clear(indicators);
+ set_message("");
+ }
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp)
- continue;
+ surface->update();
+ }
- SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se)
- continue;
+ } break;
+ }
+ }
- undo_redo->add_do_method(sp, "set_global_transform", sp->get_global_transform());
- undo_redo->add_undo_method(sp, "set_global_transform", se->original);
- }
- undo_redo->commit_action();
- _edit.mode = TRANSFORM_NONE;
- //VisualServer::get_singleton()->poly_clear(indicators);
- set_message("");
- }
+ Ref<InputEventMouseMotion> m = p_event;
- surface->update();
- }
- } break;
- }
- } break;
- case InputEvent::MOUSE_MOTION: {
- const InputEventMouseMotion &m = p_event.mouse_motion;
- _edit.mouse_pos = Point2(p_event.mouse_motion.x, p_event.mouse_motion.y);
+ if (m.is_valid()) {
- if (spatial_editor->get_selected()) {
+ _edit.mouse_pos = m->get_position();
- Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
- if (seg.is_valid()) {
+ if (spatial_editor->get_selected()) {
- int selected_handle = -1;
+ Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+ if (seg.is_valid()) {
- int handle = -1;
- Vector3 point;
- Vector3 normal;
- bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, false);
- if (inters && handle != -1) {
+ int selected_handle = -1;
- selected_handle = handle;
- }
+ int handle = -1;
+ Vector3 point;
+ Vector3 normal;
+ bool inters = seg->intersect_ray(camera, _edit.mouse_pos, point, normal, &handle, false);
+ if (inters && handle != -1) {
- if (selected_handle != spatial_editor->get_over_gizmo_handle()) {
- spatial_editor->set_over_gizmo_handle(selected_handle);
- spatial_editor->get_selected()->update_gizmo();
- if (selected_handle != -1)
- spatial_editor->select_gizmo_highlight_axis(-1);
- }
+ selected_handle = handle;
}
- }
-
- if (spatial_editor->get_over_gizmo_handle() == -1 && !(m.button_mask & 1) && !_edit.gizmo.is_valid()) {
- _gizmo_select(_edit.mouse_pos, true);
+ if (selected_handle != spatial_editor->get_over_gizmo_handle()) {
+ spatial_editor->set_over_gizmo_handle(selected_handle);
+ spatial_editor->get_selected()->update_gizmo();
+ if (selected_handle != -1)
+ spatial_editor->select_gizmo_highlight_axis(-1);
+ }
}
+ }
- NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
- NavigationMode nav_mode = NAVIGATION_NONE;
+ if (spatial_editor->get_over_gizmo_handle() == -1 && !(m->get_button_mask() & 1) && !_edit.gizmo.is_valid()) {
- if (_edit.gizmo.is_valid()) {
+ _gizmo_select(_edit.mouse_pos, true);
+ }
- _edit.gizmo->set_handle(_edit.gizmo_handle, camera, Vector2(m.x, m.y));
- Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle);
- String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
- set_message(n + ": " + String(v));
+ NavigationScheme nav_scheme = (NavigationScheme)EditorSettings::get_singleton()->get("editors/3d/navigation_scheme").operator int();
+ NavigationMode nav_mode = NAVIGATION_NONE;
- } else if (m.button_mask & 1) {
+ if (_edit.gizmo.is_valid()) {
- if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) {
- nav_mode = NAVIGATION_ORBIT;
- } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.shift) {
- nav_mode = NAVIGATION_PAN;
- } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt && m.mod.control) {
- nav_mode = NAVIGATION_ZOOM;
- } else if (nav_scheme == NAVIGATION_MODO && m.mod.alt) {
- nav_mode = NAVIGATION_ORBIT;
- } else {
- if (clicked) {
+ _edit.gizmo->set_handle(_edit.gizmo_handle, camera, m->get_position());
+ Variant v = _edit.gizmo->get_handle_value(_edit.gizmo_handle);
+ String n = _edit.gizmo->get_handle_name(_edit.gizmo_handle);
+ set_message(n + ": " + String(v));
- if (!clicked_includes_current) {
+ } else if (m->get_button_mask() & BUTTON_MASK_LEFT) {
- _select_clicked(clicked_wants_append, true);
- //clickd processing was deferred
- }
+ if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) {
+ nav_mode = NAVIGATION_ORBIT;
+ } else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_shift()) {
+ nav_mode = NAVIGATION_PAN;
+ } else if (nav_scheme == NAVIGATION_MODO && m->get_alt() && m->get_control()) {
+ nav_mode = NAVIGATION_ZOOM;
+ } else if (nav_scheme == NAVIGATION_MODO && m->get_alt()) {
+ nav_mode = NAVIGATION_ORBIT;
+ } else {
+ if (clicked) {
- _compute_edit(_edit.mouse_pos);
- clicked = 0;
+ if (!clicked_includes_current) {
- _edit.mode = TRANSFORM_TRANSLATE;
+ _select_clicked(clicked_wants_append, true);
+ //clickd processing was deferred
}
- if (cursor.region_select && nav_mode == NAVIGATION_NONE) {
+ _compute_edit(_edit.mouse_pos);
+ clicked = 0;
- cursor.region_end = Point2(m.x, m.y);
- surface->update();
- return;
- }
+ _edit.mode = TRANSFORM_TRANSLATE;
+ }
- if (_edit.mode == TRANSFORM_NONE && nav_mode == NAVIGATION_NONE)
- break;
+ if (cursor.region_select && nav_mode == NAVIGATION_NONE) {
- Vector3 ray_pos = _get_ray_pos(Vector2(m.x, m.y));
- Vector3 ray = _get_ray(Vector2(m.x, m.y));
+ cursor.region_end = m->get_position();
+ surface->update();
+ return;
+ }
- switch (_edit.mode) {
+ if (_edit.mode == TRANSFORM_NONE && nav_mode == NAVIGATION_NONE)
+ return;
- case TRANSFORM_SCALE: {
+ Vector3 ray_pos = _get_ray_pos(m->get_position());
+ Vector3 ray = _get_ray(m->get_position());
- Plane plane = Plane(_edit.center, _get_camera_normal());
+ switch (_edit.mode) {
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
- break;
+ case TRANSFORM_SCALE: {
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
- break;
+ Plane plane = Plane(_edit.center, _get_camera_normal());
- float center_click_dist = click.distance_to(_edit.center);
- float center_inters_dist = intersection.distance_to(_edit.center);
- if (center_click_dist == 0)
- break;
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ break;
- float scale = (center_inters_dist / center_click_dist) * 100.0;
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ break;
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ float center_click_dist = click.distance_to(_edit.center);
+ float center_inters_dist = intersection.distance_to(_edit.center);
+ if (center_click_dist == 0)
+ break;
- scale = Math::stepify(scale, spatial_editor->get_scale_snap());
- }
+ float scale = (center_inters_dist / center_click_dist) * 100.0;
- set_message(vformat(TTR("Scaling to %s%%."), String::num(scale, 1)));
- scale /= 100.0;
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
- Transform r;
- r.basis.scale(Vector3(scale, scale, scale));
+ scale = Math::stepify(scale, spatial_editor->get_scale_snap());
+ }
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ set_message(vformat(TTR("Scaling to %s%%."), String::num(scale, 1)));
+ scale /= 100.0;
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ Transform r;
+ r.basis.scale(Vector3(scale, scale, scale));
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp)
- continue;
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se)
- continue;
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- Transform original = se->original;
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp)
+ continue;
- Transform base = Transform(Basis(), _edit.center);
- Transform t = base * (r * (base.inverse() * original));
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se)
+ continue;
- sp->set_global_transform(t);
- }
+ Transform original = se->original;
- surface->update();
+ Transform base = Transform(Basis(), _edit.center);
+ Transform t = base * (r * (base.inverse() * original));
- } break;
+ sp->set_global_transform(t);
+ }
- case TRANSFORM_TRANSLATE: {
+ surface->update();
- Vector3 motion_mask;
- Plane plane;
+ } break;
- switch (_edit.plane) {
- case TRANSFORM_VIEW:
- motion_mask = Vector3(0, 0, 0);
- plane = Plane(_edit.center, _get_camera_normal());
- break;
- case TRANSFORM_X_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0);
- plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
- break;
- case TRANSFORM_Y_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1);
- plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
- break;
- case TRANSFORM_Z_AXIS:
- motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
- plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
- break;
- }
+ case TRANSFORM_TRANSLATE: {
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
- break;
+ Vector3 motion_mask;
+ Plane plane;
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ motion_mask = Vector3(0, 0, 0);
+ plane = Plane(_edit.center, _get_camera_normal());
break;
+ case TRANSFORM_X_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(0);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ case TRANSFORM_Y_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(1);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ case TRANSFORM_Z_AXIS:
+ motion_mask = spatial_editor->get_gizmo_transform().basis.get_axis(2);
+ plane = Plane(_edit.center, motion_mask.cross(motion_mask.cross(_get_camera_normal())).normalized());
+ break;
+ }
- //_validate_selection();
- Vector3 motion = intersection - click;
- if (motion_mask != Vector3()) {
- motion = motion_mask.dot(motion) * motion_mask;
- }
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ break;
- float snap = 0;
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ break;
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ //_validate_selection();
+ Vector3 motion = intersection - click;
+ if (motion_mask != Vector3()) {
+ motion = motion_mask.dot(motion) * motion_mask;
+ }
- snap = spatial_editor->get_translate_snap();
- motion.snap(snap);
- }
+ float snap = 0;
- //set_message("Translating: "+motion);
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ snap = spatial_editor->get_translate_snap();
+ motion.snap(snap);
+ }
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ //set_message("Translating: "+motion);
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp) {
- continue;
- }
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se) {
- continue;
- }
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp) {
+ continue;
+ }
- Transform t = se->original;
- t.origin += motion;
- sp->set_global_transform(t);
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se) {
+ continue;
}
- } break;
- case TRANSFORM_ROTATE: {
+ Transform t = se->original;
+ t.origin += motion;
+ sp->set_global_transform(t);
+ }
+ } break;
- Plane plane;
+ case TRANSFORM_ROTATE: {
- switch (_edit.plane) {
- case TRANSFORM_VIEW:
- plane = Plane(_edit.center, _get_camera_normal());
- break;
- case TRANSFORM_X_AXIS:
- plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(0));
- break;
- case TRANSFORM_Y_AXIS:
- plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(1));
- break;
- case TRANSFORM_Z_AXIS:
- plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2));
- break;
- }
+ Plane plane;
- Vector3 intersection;
- if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ switch (_edit.plane) {
+ case TRANSFORM_VIEW:
+ plane = Plane(_edit.center, _get_camera_normal());
break;
-
- Vector3 click;
- if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ case TRANSFORM_X_AXIS:
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(0));
+ break;
+ case TRANSFORM_Y_AXIS:
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(1));
break;
+ case TRANSFORM_Z_AXIS:
+ plane = Plane(_edit.center, spatial_editor->get_gizmo_transform().basis.get_axis(2));
+ break;
+ }
- Vector3 y_axis = (click - _edit.center).normalized();
- Vector3 x_axis = plane.normal.cross(y_axis).normalized();
+ Vector3 intersection;
+ if (!plane.intersects_ray(ray_pos, ray, &intersection))
+ break;
- float angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
- if (_edit.snap || spatial_editor->is_snap_enabled()) {
+ Vector3 click;
+ if (!plane.intersects_ray(_edit.click_ray_pos, _edit.click_ray, &click))
+ break;
+
+ Vector3 y_axis = (click - _edit.center).normalized();
+ Vector3 x_axis = plane.normal.cross(y_axis).normalized();
- float snap = spatial_editor->get_rotate_snap();
+ float angle = Math::atan2(x_axis.dot(intersection - _edit.center), y_axis.dot(intersection - _edit.center));
+ if (_edit.snap || spatial_editor->is_snap_enabled()) {
- if (snap) {
- angle = Math::rad2deg(angle) + snap * 0.5; //else it wont reach +180
- angle -= Math::fmod(angle, snap);
- set_message(vformat(TTR("Rotating %s degrees."), rtos(angle)));
- angle = Math::deg2rad(angle);
- } else
- set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
+ float snap = spatial_editor->get_rotate_snap();
- } else {
+ if (snap) {
+ angle = Math::rad2deg(angle) + snap * 0.5; //else it wont reach +180
+ angle -= Math::fmod(angle, snap);
+ set_message(vformat(TTR("Rotating %s degrees."), rtos(angle)));
+ angle = Math::deg2rad(angle);
+ } else
set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
- }
- Transform r;
- r.basis.rotate(plane.normal, angle);
+ } else {
+ set_message(vformat(TTR("Rotating %s degrees."), rtos(Math::rad2deg(angle))));
+ }
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ Transform r;
+ r.basis.rotate(plane.normal, angle);
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+ List<Node *> &selection = editor_selection->get_selected_node_list();
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp)
- continue;
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
- SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
- if (!se)
- continue;
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp)
+ continue;
- Transform original = se->original;
+ SpatialEditorSelectedItem *se = editor_selection->get_node_editor_data<SpatialEditorSelectedItem>(sp);
+ if (!se)
+ continue;
- Transform base = Transform(Basis(), _edit.center);
- Transform t = base * r * base.inverse() * original;
+ Transform original = se->original;
- sp->set_global_transform(t);
- }
+ Transform base = Transform(Basis(), _edit.center);
+ Transform t = base * r * base.inverse() * original;
- surface->update();
- /*
- VisualServer::get_singleton()->poly_clear(indicators);
-
- Vector<Vector3> points;
- Vector<Vector3> empty;
- Vector<Color> colors;
- points.push_back(intersection);
- points.push_back(_edit.original.origin);
- colors.push_back( Color(255,155,100) );
- colors.push_back( Color(255,155,100) );
- VisualServer::get_singleton()->poly_add_primitive(indicators,points,empty,colors,empty);
- */
- } break;
- default: {}
- }
+ sp->set_global_transform(t);
+ }
+
+ surface->update();
+ /*
+ VisualServer::get_singleton()->poly_clear(indicators);
+
+ Vector<Vector3> points;
+ Vector<Vector3> empty;
+ Vector<Color> colors;
+ points.push_back(intersection);
+ points.push_back(_edit.original.origin);
+ colors.push_back( Color(255,155,100) );
+ colors.push_back( Color(255,155,100) );
+ VisualServer::get_singleton()->poly_add_primitive(indicators,points,empty,colors,empty);
+ */
+ } break;
+ default: {}
}
+ }
- } else if (m.button_mask & 2) {
+ } else if (m->get_button_mask() & BUTTON_MASK_RIGHT) {
- if (nav_scheme == NAVIGATION_MAYA && m.mod.alt) {
- nav_mode = NAVIGATION_ZOOM;
- }
+ if (nav_scheme == NAVIGATION_MAYA && m->get_alt()) {
+ nav_mode = NAVIGATION_ZOOM;
+ } else {
+ nav_mode = NAVIGATION_LOOK;
+ }
- } else if (m.button_mask & 4) {
-
- if (nav_scheme == NAVIGATION_GODOT) {
-
- int mod = 0;
- if (m.mod.shift)
- mod = KEY_SHIFT;
- if (m.mod.alt)
- mod = KEY_ALT;
- if (m.mod.control)
- mod = KEY_CONTROL;
- if (m.mod.meta)
- mod = KEY_META;
-
- if (mod == _get_key_modifier("editors/3d/pan_modifier"))
- nav_mode = NAVIGATION_PAN;
- else if (mod == _get_key_modifier("editors/3d/zoom_modifier"))
- nav_mode = NAVIGATION_ZOOM;
- else if (mod == _get_key_modifier("editors/3d/orbit_modifier"))
- nav_mode = NAVIGATION_ORBIT;
-
- } else if (nav_scheme == NAVIGATION_MAYA) {
- if (m.mod.alt)
- nav_mode = NAVIGATION_PAN;
- }
+ } else if (m->get_button_mask() & BUTTON_MASK_MIDDLE) {
+
+ if (nav_scheme == NAVIGATION_GODOT) {
- } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) {
- // Handle trackpad (no external mouse) use case
int mod = 0;
- if (m.mod.shift)
+ if (m->get_shift())
mod = KEY_SHIFT;
- if (m.mod.alt)
+ if (m->get_alt())
mod = KEY_ALT;
- if (m.mod.control)
+ if (m->get_control())
mod = KEY_CONTROL;
- if (m.mod.meta)
+ if (m->get_metakey())
mod = KEY_META;
- if (mod) {
- if (mod == _get_key_modifier("editors/3d/pan_modifier"))
- nav_mode = NAVIGATION_PAN;
- else if (mod == _get_key_modifier("editors/3d/zoom_modifier"))
- nav_mode = NAVIGATION_ZOOM;
- else if (mod == _get_key_modifier("editors/3d/orbit_modifier"))
- nav_mode = NAVIGATION_ORBIT;
- }
+ if (mod == _get_key_modifier("editors/3d/pan_modifier"))
+ nav_mode = NAVIGATION_PAN;
+ else if (mod == _get_key_modifier("editors/3d/zoom_modifier"))
+ nav_mode = NAVIGATION_ZOOM;
+ else if (mod == _get_key_modifier("editors/3d/orbit_modifier"))
+ nav_mode = NAVIGATION_ORBIT;
+
+ } else if (nav_scheme == NAVIGATION_MAYA) {
+ if (m->get_alt())
+ nav_mode = NAVIGATION_PAN;
}
- switch (nav_mode) {
- case NAVIGATION_PAN: {
+ } else if (EditorSettings::get_singleton()->get("editors/3d/emulate_3_button_mouse")) {
+ // Handle trackpad (no external mouse) use case
+ int mod = 0;
+ if (m->get_shift())
+ mod = KEY_SHIFT;
+ if (m->get_alt())
+ mod = KEY_ALT;
+ if (m->get_control())
+ mod = KEY_CONTROL;
+ if (m->get_metakey())
+ mod = KEY_META;
+
+ if (mod) {
+ if (mod == _get_key_modifier("editors/3d/pan_modifier"))
+ nav_mode = NAVIGATION_PAN;
+ else if (mod == _get_key_modifier("editors/3d/zoom_modifier"))
+ nav_mode = NAVIGATION_ZOOM;
+ else if (mod == _get_key_modifier("editors/3d/orbit_modifier"))
+ nav_mode = NAVIGATION_ORBIT;
+ }
+ }
- real_t pan_speed = 1 / 150.0;
- int pan_speed_modifier = 10;
- if (nav_scheme == NAVIGATION_MAYA && m.mod.shift)
- pan_speed *= pan_speed_modifier;
+ switch (nav_mode) {
+ case NAVIGATION_PAN: {
- Point2i relative;
- if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) {
- relative = Input::get_singleton()->warp_mouse_motion(m, surface->get_global_rect());
- } else {
- relative = Point2i(m.relative_x, m.relative_y);
- }
+ real_t pan_speed = 1 / 150.0;
+ int pan_speed_modifier = 10;
+ if (nav_scheme == NAVIGATION_MAYA && m->get_shift())
+ pan_speed *= pan_speed_modifier;
- Transform camera_transform;
-
- camera_transform.translate(cursor.pos);
- camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
- camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
- Vector3 translation(-relative.x * pan_speed, relative.y * pan_speed, 0);
- translation *= cursor.distance / DISTANCE_DEFAULT;
- camera_transform.translate(translation);
- cursor.pos = camera_transform.origin;
-
- } break;
-
- case NAVIGATION_ZOOM: {
- real_t zoom_speed = 1 / 80.0;
- int zoom_speed_modifier = 10;
- if (nav_scheme == NAVIGATION_MAYA && m.mod.shift)
- zoom_speed *= zoom_speed_modifier;
-
- NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int();
- if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
- if (m.relative_x > 0)
- cursor.distance *= 1 - m.relative_x * zoom_speed;
- else if (m.relative_x < 0)
- cursor.distance /= 1 + m.relative_x * zoom_speed;
- } else {
- if (m.relative_y > 0)
- cursor.distance *= 1 + m.relative_y * zoom_speed;
- else if (m.relative_y < 0)
- cursor.distance /= 1 - m.relative_y * zoom_speed;
- }
+ Point2i relative = _get_warped_mouse_motion(m);
- } break;
+ Transform camera_transform;
+
+ camera_transform.translate(cursor.pos);
+ camera_transform.basis.rotate(Vector3(1, 0, 0), -cursor.x_rot);
+ camera_transform.basis.rotate(Vector3(0, 1, 0), -cursor.y_rot);
+ Vector3 translation(-relative.x * pan_speed, relative.y * pan_speed, 0);
+ translation *= cursor.distance / DISTANCE_DEFAULT;
+ camera_transform.translate(translation);
+ cursor.pos = camera_transform.origin;
+
+ } break;
+
+ case NAVIGATION_ZOOM: {
+ real_t zoom_speed = 1 / 80.0;
+ int zoom_speed_modifier = 10;
+ if (nav_scheme == NAVIGATION_MAYA && m->get_shift())
+ zoom_speed *= zoom_speed_modifier;
+
+ NavigationZoomStyle zoom_style = (NavigationZoomStyle)EditorSettings::get_singleton()->get("editors/3d/zoom_style").operator int();
+ if (zoom_style == NAVIGATION_ZOOM_HORIZONTAL) {
+ if (m->get_relative().x > 0)
+ scale_cursor_distance(1 - m->get_relative().x * zoom_speed);
+ else if (m->get_relative().x < 0)
+ scale_cursor_distance(1.0 / (1 + m->get_relative().x * zoom_speed));
+ } else {
+ if (m->get_relative().y > 0)
+ scale_cursor_distance(1 + m->get_relative().y * zoom_speed);
+ else if (m->get_relative().y < 0)
+ scale_cursor_distance(1.0 / (1 - m->get_relative().y * zoom_speed));
+ }
+
+ } break;
+
+ case NAVIGATION_ORBIT: {
+ Point2i relative = _get_warped_mouse_motion(m);
+ cursor.x_rot += relative.y / 80.0;
+ cursor.y_rot += relative.x / 80.0;
+ if (cursor.x_rot > Math_PI / 2.0)
+ cursor.x_rot = Math_PI / 2.0;
+ if (cursor.x_rot < -Math_PI / 2.0)
+ cursor.x_rot = -Math_PI / 2.0;
+ name = "";
+ _update_name();
+ } break;
- case NAVIGATION_ORBIT: {
- cursor.x_rot += m.relative_y / 80.0;
- cursor.y_rot += m.relative_x / 80.0;
+ case NAVIGATION_LOOK: {
+ // Freelook only works properly in perspective.
+ // It technically works too in ortho, but it's awful for a user due to fov being near zero
+ if (!orthogonal) {
+ Point2i relative = _get_warped_mouse_motion(m);
+ cursor.x_rot += relative.y / 120.0;
+ cursor.y_rot += relative.x / 120.0;
if (cursor.x_rot > Math_PI / 2.0)
cursor.x_rot = Math_PI / 2.0;
if (cursor.x_rot < -Math_PI / 2.0)
cursor.x_rot = -Math_PI / 2.0;
+
+ // Look is like Orbit, except the cursor translates, not the camera
+ Transform camera_transform = to_camera_transform(cursor);
+ Vector3 pos = camera_transform.xform(Vector3(0, 0, 0));
+ Vector3 diff = camera->get_translation() - pos;
+ cursor.pos += diff;
+
name = "";
_update_name();
- } break;
+ }
- default: {}
- }
- } break;
- case InputEvent::KEY: {
- const InputEventKey &k = p_event.key;
- if (!k.pressed)
- break;
+ } break;
- if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
- if (_edit.mode != TRANSFORM_NONE) {
- _edit.snap = true;
- }
- }
- if (ED_IS_SHORTCUT("spatial_editor/bottom_view", p_event)) {
- cursor.y_rot = 0;
- cursor.x_rot = -Math_PI / 2.0;
- set_message(TTR("Bottom View."), 2);
- name = TTR("Bottom");
- _update_name();
- }
- if (ED_IS_SHORTCUT("spatial_editor/top_view", p_event)) {
- cursor.y_rot = 0;
- cursor.x_rot = Math_PI / 2.0;
- set_message(TTR("Top View."), 2);
- name = TTR("Top");
- _update_name();
- }
- if (ED_IS_SHORTCUT("spatial_editor/rear_view", p_event)) {
- cursor.x_rot = 0;
- cursor.y_rot = Math_PI;
- set_message(TTR("Rear View."), 2);
- name = TTR("Rear");
- _update_name();
- }
- if (ED_IS_SHORTCUT("spatial_editor/front_view", p_event)) {
- cursor.x_rot = 0;
- cursor.y_rot = 0;
- set_message(TTR("Front View."), 2);
- name = TTR("Front");
- _update_name();
- }
- if (ED_IS_SHORTCUT("spatial_editor/left_view", p_event)) {
- cursor.x_rot = 0;
- cursor.y_rot = Math_PI / 2.0;
- set_message(TTR("Left View."), 2);
- name = TTR("Left");
- _update_name();
+ default: {}
+ }
+ }
+
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid()) {
+ if (!k->is_pressed())
+ return;
+
+ if (ED_IS_SHORTCUT("spatial_editor/snap", p_event)) {
+ if (_edit.mode != TRANSFORM_NONE) {
+ _edit.snap = true;
}
- if (ED_IS_SHORTCUT("spatial_editor/right_view", p_event)) {
- cursor.x_rot = 0;
- cursor.y_rot = -Math_PI / 2.0;
- set_message(TTR("Right View."), 2);
- name = TTR("Right");
- _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/bottom_view", p_event)) {
+ cursor.y_rot = 0;
+ cursor.x_rot = -Math_PI / 2.0;
+ set_message(TTR("Bottom View."), 2);
+ name = TTR("Bottom");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/top_view", p_event)) {
+ cursor.y_rot = 0;
+ cursor.x_rot = Math_PI / 2.0;
+ set_message(TTR("Top View."), 2);
+ name = TTR("Top");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/rear_view", p_event)) {
+ cursor.x_rot = 0;
+ cursor.y_rot = Math_PI;
+ set_message(TTR("Rear View."), 2);
+ name = TTR("Rear");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/front_view", p_event)) {
+ cursor.x_rot = 0;
+ cursor.y_rot = 0;
+ set_message(TTR("Front View."), 2);
+ name = TTR("Front");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/left_view", p_event)) {
+ cursor.x_rot = 0;
+ cursor.y_rot = Math_PI / 2.0;
+ set_message(TTR("Left View."), 2);
+ name = TTR("Left");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/right_view", p_event)) {
+ cursor.x_rot = 0;
+ cursor.y_rot = -Math_PI / 2.0;
+ set_message(TTR("Right View."), 2);
+ name = TTR("Right");
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
+ _menu_option(orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL);
+ _update_name();
+ }
+ if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) {
+ if (!get_selected_count() || _edit.mode != TRANSFORM_NONE)
+ return;
+
+ if (!AnimationPlayerEditor::singleton->get_key_editor()->has_keying()) {
+ set_message(TTR("Keying is disabled (no key inserted)."));
+ return;
}
- if (ED_IS_SHORTCUT("spatial_editor/switch_perspective_orthogonal", p_event)) {
- _menu_option(orthogonal ? VIEW_PERSPECTIVE : VIEW_ORTHOGONAL);
- _update_name();
+
+ List<Node *> &selection = editor_selection->get_selected_node_list();
+
+ for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+
+ Spatial *sp = E->get()->cast_to<Spatial>();
+ if (!sp)
+ continue;
+
+ emit_signal("transform_key_request", sp, "", sp->get_transform());
}
- if (ED_IS_SHORTCUT("spatial_editor/insert_anim_key", p_event)) {
- if (!get_selected_count() || _edit.mode != TRANSFORM_NONE)
- break;
- if (!AnimationPlayerEditor::singleton->get_key_editor()->has_keying()) {
- set_message(TTR("Keying is disabled (no key inserted)."));
- break;
- }
+ set_message(TTR("Animation Key Inserted."));
+ }
- List<Node *> &selection = editor_selection->get_selected_node_list();
+ if (k->get_scancode() == KEY_SPACE) {
+ if (!k->is_pressed()) emit_signal("toggle_maximize_view", this);
+ }
+ }
+}
- for (List<Node *>::Element *E = selection.front(); E; E = E->next()) {
+void SpatialEditorViewport::scale_cursor_distance(real_t scale) {
- Spatial *sp = E->get()->cast_to<Spatial>();
- if (!sp)
- continue;
+ // Prevents zero distance which would short-circuit any scaling
+ if (cursor.distance < ZOOM_MIN_DISTANCE)
+ cursor.distance = ZOOM_MIN_DISTANCE;
- emit_signal("transform_key_request", sp, "", sp->get_transform());
- }
+ real_t prev_distance = cursor.distance;
+ cursor.distance *= scale;
- set_message(TTR("Animation Key Inserted."));
- }
+ if (cursor.distance < ZOOM_MIN_DISTANCE)
+ cursor.distance = ZOOM_MIN_DISTANCE;
- if (k.scancode == KEY_SPACE) {
- if (!k.pressed) emit_signal("toggle_maximize_view", this);
- }
+ if (is_freelook_active()) {
+ // In freelook mode, cursor reference is reversed so it needs to be adjusted
+ Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ cursor.pos += (cursor.distance - prev_distance) * forward;
+ }
- } break;
+ zoom_indicator_delay = ZOOM_INDICATOR_DELAY_S;
+ surface->update();
+}
+
+Point2i SpatialEditorViewport::_get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const {
+ Point2i relative;
+ if (bool(EditorSettings::get_singleton()->get("editors/3d/warped_mouse_panning"))) {
+ relative = Input::get_singleton()->warp_mouse_motion(p_ev_mouse_motion, surface->get_global_rect());
+ } else {
+ relative = p_ev_mouse_motion->get_relative();
+ }
+ return relative;
+}
+
+void SpatialEditorViewport::_update_freelook(real_t delta) {
+
+ if (!is_freelook_active())
+ return;
+
+ Vector3 forward = camera->get_transform().basis.xform(Vector3(0, 0, -1));
+ Vector3 right = camera->get_transform().basis.xform(Vector3(1, 0, 0));
+ Vector3 up = camera->get_transform().basis.xform(Vector3(0, 1, 0));
+
+ int key_left = ED_SHORTCUT("spatial_editor/freelook_left", TTR("Freelook Left"), KEY_A)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_right = ED_SHORTCUT("spatial_editor/freelook_right", TTR("Freelook Right"), KEY_D)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_forward = ED_SHORTCUT("spatial_editor/freelook_forward", TTR("Freelook Forward"), KEY_W)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_backwards = ED_SHORTCUT("spatial_editor/freelook_backwards", TTR("Freelook Backwards"), KEY_S)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_up = ED_SHORTCUT("spatial_editor/freelook_up", TTR("Freelook Up"), KEY_Q)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_down = ED_SHORTCUT("spatial_editor/freelook_down", TTR("Freelook Down"), KEY_E)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+ int key_speed_modifier = ED_SHORTCUT("spatial_editor/freelook_speed_modifier", TTR("Freelook Speed Modifier"), KEY_SHIFT)->get_shortcut()->cast_to<InputEventKey>()->get_scancode();
+
+ Vector3 velocity;
+ bool pressed = false;
+ bool speed_modifier = false;
+
+ const Input &input = *Input::get_singleton();
+
+ if (input.is_key_pressed(key_left)) {
+ velocity -= right;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_right)) {
+ velocity += right;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_forward)) {
+ velocity += forward;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_backwards)) {
+ velocity -= forward;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_up)) {
+ velocity += up;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_down)) {
+ velocity -= up;
+ pressed = true;
+ }
+ if (input.is_key_pressed(key_speed_modifier)) {
+ speed_modifier = true;
+ }
+
+ if (pressed) {
+ const EditorSettings &s = *EditorSettings::get_singleton();
+ const real_t base_speed = s.get("editors/3d/freelook_base_speed");
+ const real_t modifier_speed_factor = s.get("editors/3d/freelook_modifier_speed_factor");
+
+ real_t speed = base_speed * cursor.distance;
+ if (speed_modifier)
+ speed *= modifier_speed_factor;
+
+ velocity.normalize();
+
+ cursor.pos += velocity * (speed * delta);
}
}
@@ -1579,6 +1647,17 @@ void SpatialEditorViewport::_notification(int p_what) {
}
*/
+ real_t delta = get_tree()->get_idle_process_time();
+
+ if (zoom_indicator_delay > 0) {
+ zoom_indicator_delay -= delta;
+ if (zoom_indicator_delay <= 0) {
+ surface->update();
+ }
+ }
+
+ _update_freelook(delta);
+
_update_camera();
Map<Node *, Object *> &selection = editor_selection->get_selection();
@@ -1604,7 +1683,7 @@ void SpatialEditorViewport::_notification(int p_what) {
}
Transform t = sp->get_global_transform();
- t.translate(se->aabb.pos);
+ t.translate(se->aabb.position);
t.basis.scale(se->aabb.size);
exist = true;
@@ -1652,6 +1731,33 @@ void SpatialEditorViewport::_notification(int p_what) {
bool hdr = GlobalConfig::get_singleton()->get("rendering/quality/hdr");
viewport->set_hdr(hdr);
+
+ bool show_info = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(VIEW_INFORMATION));
+ if (show_info != info->is_visible()) {
+ if (show_info)
+ info->show();
+ else
+ info->hide();
+ }
+
+ if (show_info) {
+
+ String text;
+ text += TTR("Objects Drawn") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_OBJECTS_IN_FRAME)) + "\n";
+ text += TTR("Material Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_MATERIAL_CHANGES_IN_FRAME)) + "\n";
+ text += TTR("Shader Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SHADER_CHANGES_IN_FRAME)) + "\n";
+ text += TTR("Surface Changes") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_SURFACE_CHANGES_IN_FRAME)) + "\n";
+ text += TTR("Draw Calls") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_DRAW_CALLS_IN_FRAME)) + "\n";
+ text += TTR("Vertices") + ": " + itos(viewport->get_render_info(Viewport::RENDER_INFO_VERTICES_IN_FRAME));
+
+ if (info_label->get_text() != text || surface->get_size() != prev_size) {
+ info_label->set_text(text);
+ Size2 ms = info->get_minimum_size();
+ info->set_position(surface->get_size() - ms - Vector2(20, 20) * EDSCALE);
+ }
+ }
+
+ prev_size = surface->get_size();
}
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -1659,6 +1765,7 @@ void SpatialEditorViewport::_notification(int p_what) {
surface->connect("draw", this, "_draw");
surface->connect("gui_input", this, "_sinput");
surface->connect("mouse_entered", this, "_smouseenter");
+ info->add_style_override("panel", get_stylebox("panel", "Panel"));
preview_camera->set_icon(get_icon("Camera", "EditorIcons"));
_init_gizmo_instance(index);
}
@@ -1674,12 +1781,29 @@ void SpatialEditorViewport::_notification(int p_what) {
}
}
+// TODO That should be part of the drawing API...
+static void stroke_rect(CanvasItem *ci, Rect2 rect, Color color, real_t width = 1.0) {
+
+ // a---b
+ // | |
+ // c---d
+ Vector2 a(rect.position);
+ Vector2 b(rect.position.x + rect.size.x, rect.position.y);
+ Vector2 c(rect.position.x, rect.position.y + rect.size.y);
+ Vector2 d(rect.position + rect.size);
+
+ ci->draw_line(a, b, color, width);
+ ci->draw_line(b, d, color, width);
+ ci->draw_line(d, c, color, width);
+ ci->draw_line(c, a, color, width);
+}
+
void SpatialEditorViewport::_draw() {
if (surface->has_focus()) {
Size2 size = surface->get_size();
Rect2 r = Rect2(Point2(), size);
- get_stylebox("EditorFocus", "EditorStyles")->draw(surface->get_canvas_item(), r);
+ get_stylebox("Focus", "EditorStyles")->draw(surface->get_canvas_item(), r);
}
RID ci = surface->get_canvas_item();
@@ -1715,25 +1839,52 @@ void SpatialEditorViewport::_draw() {
case Camera::KEEP_WIDTH: {
draw_rect.size = Size2(s.width, s.width / aspect);
- draw_rect.pos.x = 0;
- draw_rect.pos.y = (s.height - draw_rect.size.y) * 0.5;
+ draw_rect.position.x = 0;
+ draw_rect.position.y = (s.height - draw_rect.size.y) * 0.5;
} break;
case Camera::KEEP_HEIGHT: {
draw_rect.size = Size2(s.height * aspect, s.height);
- draw_rect.pos.y = 0;
- draw_rect.pos.x = (s.width - draw_rect.size.x) * 0.5;
+ draw_rect.position.y = 0;
+ draw_rect.position.x = (s.width - draw_rect.size.x) * 0.5;
} break;
}
draw_rect = Rect2(Vector2(), s).clip(draw_rect);
- surface->draw_line(draw_rect.pos, draw_rect.pos + Vector2(draw_rect.size.x, 0), Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos + Vector2(draw_rect.size.x, 0), draw_rect.pos + draw_rect.size, Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos + draw_rect.size, draw_rect.pos + Vector2(0, draw_rect.size.y), Color(0.6, 0.6, 0.1, 0.5), 2.0);
- surface->draw_line(draw_rect.pos, draw_rect.pos + Vector2(0, draw_rect.size.y), Color(0.6, 0.6, 0.1, 0.5), 2.0);
+ stroke_rect(surface, draw_rect, Color(0.6, 0.6, 0.1, 0.5), 2.0);
+
+ } else {
+
+ if (zoom_indicator_delay > 0.0) {
+ // Show indicative zoom factor
+
+ real_t min_distance = ZOOM_MIN_DISTANCE; // TODO Why not pick znear to limit zoom?
+ real_t max_distance = camera->get_zfar();
+ real_t scale_length = (max_distance - min_distance);
+
+ if (Math::abs(scale_length) > CMP_EPSILON) {
+ real_t logscale_t = 1.0 - Math::log(1 + cursor.distance - min_distance) / Math::log(1 + scale_length);
+
+ // There is no real maximum distance so that factor can become negative,
+ // Let's make it look asymptotic instead (will decrease slower and slower).
+ if (logscale_t < 0.25)
+ logscale_t = 0.25 * Math::exp(4.0 * logscale_t - 1.0);
+
+ Vector2 surface_size = surface->get_size();
+ real_t h = surface_size.y / 2.0;
+ real_t y = (surface_size.y - h) / 2.0;
+
+ Rect2 r(10, y, 6, h);
+ real_t sy = r.size.y * logscale_t;
+
+ surface->draw_rect(r, Color(1, 1, 1, 0.2));
+ surface->draw_rect(Rect2(r.position.x, r.position.y + r.size.y - sy, r.size.x, sy), Color(1, 1, 1, 0.6));
+ stroke_rect(surface, r.grow(1), Color(0, 0, 0, 0.7));
+ }
+ }
}
}
@@ -1881,6 +2032,52 @@ void SpatialEditorViewport::_menu_option(int p_option) {
view_menu->get_popup()->set_item_checked(idx, current);
} break;
+ case VIEW_INFORMATION: {
+
+ int idx = view_menu->get_popup()->get_item_index(VIEW_INFORMATION);
+ bool current = view_menu->get_popup()->is_item_checked(idx);
+ view_menu->get_popup()->set_item_checked(idx, !current);
+
+ } break;
+ case VIEW_DISPLAY_NORMAL: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_DISABLED);
+
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_WIREFRAME: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_WIREFRAME);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_OVERDRAW: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_OVERDRAW);
+ VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), true);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), false);
+
+ } break;
+ case VIEW_DISPLAY_SHADELESS: {
+
+ viewport->set_debug_draw(Viewport::DEBUG_DRAW_UNSHADED);
+ VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_WIREFRAME), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_OVERDRAW), false);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_SHADELESS), true);
+
+ } break;
}
}
@@ -2143,6 +2340,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
clicked_includes_current = false;
orthogonal = false;
message_time = 0;
+ zoom_indicator_delay = 0.0;
spatial_editor = p_spatial_editor;
ViewportContainer *c = memnew(ViewportContainer);
@@ -2156,6 +2354,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
surface = memnew(Control);
add_child(surface);
surface->set_area_as_parent_rect();
+ surface->set_clip_contents(true);
camera = memnew(Camera);
camera->set_disable_gizmo(true);
camera->set_cull_mask(((1 << 20) - 1) | (1 << (GIZMO_BASE_LAYER + p_index)) | (1 << GIZMO_EDIT_LAYER) | (1 << GIZMO_GRID_LAYER));
@@ -2179,12 +2378,18 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
view_menu->get_popup()->add_check_item(TTR("Orthogonal") + " (" + ED_GET_SHORTCUT("spatial_editor/switch_perspective_orthogonal")->get_as_text() + ")", VIEW_ORTHOGONAL);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true);
view_menu->get_popup()->add_separator();
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("Environment")), VIEW_ENVIRONMENT);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_normal", TTR("Display Normal")), VIEW_DISPLAY_NORMAL);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_wireframe", TTR("Display Wireframe")), VIEW_DISPLAY_WIREFRAME);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_overdraw", TTR("Display Overdraw")), VIEW_DISPLAY_OVERDRAW);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_display_unshaded", TTR("Display Unshaded")), VIEW_DISPLAY_SHADELESS);
+ view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_DISPLAY_NORMAL), true);
+ view_menu->get_popup()->add_separator();
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_environment", TTR("View Environment")), VIEW_ENVIRONMENT);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("View Gizmos")), VIEW_GIZMOS);
+ view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_information", TTR("View Information")), VIEW_INFORMATION);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT), true);
view_menu->get_popup()->add_separator();
view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_audio_listener", TTR("Audio Listener")), VIEW_AUDIO_LISTENER);
- view_menu->get_popup()->add_separator();
- view_menu->get_popup()->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_gizmos", TTR("Gizmos")), VIEW_GIZMOS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_GIZMOS), true);
view_menu->get_popup()->add_separator();
@@ -2205,6 +2410,15 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
preview = NULL;
gizmo_scale = 1.0;
+ info = memnew(PanelContainer);
+ info->set_self_modulate(Color(1, 1, 1, 0.4));
+ surface->add_child(info);
+ info_label = memnew(Label);
+ info->add_child(info_label);
+ info->hide();
+
+ freelook_active = false;
+
selection_menu = memnew(PopupMenu);
add_child(selection_menu);
selection_menu->set_custom_minimum_size(Vector2(100, 0));
@@ -2222,6 +2436,305 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed
EditorSettings::get_singleton()->connect("settings_changed", this, "update_transform_gizmo_view");
}
+//////////////////////////////////////////////////////////////
+
+void SpatialEditorViewportContainer::_gui_input(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+
+ Vector2 size = get_size();
+
+ int h_sep = get_constant("separation", "HSplitContainer");
+ int v_sep = get_constant("separation", "VSplitContainer");
+
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
+
+ dragging_h = mb->get_position().x > (mid_w - h_sep / 2) && mb->get_position().x < (mid_w + h_sep / 2);
+ dragging_v = mb->get_position().y > (mid_h - v_sep / 2) && mb->get_position().y < (mid_h + v_sep / 2);
+
+ drag_begin_pos = mb->get_position();
+ drag_begin_ratio.x = ratio_h;
+ drag_begin_ratio.y = ratio_v;
+
+ switch (view) {
+ case VIEW_USE_1_VIEWPORT: {
+
+ dragging_h = false;
+ dragging_v = false;
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
+
+ dragging_h = false;
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
+
+ dragging_v = false;
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS: {
+
+ if (dragging_v)
+ dragging_h = false;
+ else
+ dragging_v = false;
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS_ALT: {
+
+ if (dragging_h)
+ dragging_v = false;
+ else
+ dragging_h = false;
+ } break;
+ case VIEW_USE_4_VIEWPORTS: {
+
+ } break;
+ }
+ }
+
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+ dragging_h = false;
+ dragging_v = false;
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid() && (dragging_h || dragging_v)) {
+
+ if (dragging_h) {
+ float new_ratio = drag_begin_ratio.x + (mm->get_position().x - drag_begin_pos.x) / get_size().width;
+ new_ratio = CLAMP(new_ratio, 40 / get_size().width, (get_size().width - 40) / get_size().width);
+ ratio_h = new_ratio;
+ queue_sort();
+ update();
+ }
+ if (dragging_v) {
+ float new_ratio = drag_begin_ratio.y + (mm->get_position().y - drag_begin_pos.y) / get_size().height;
+ new_ratio = CLAMP(new_ratio, 40 / get_size().height, (get_size().height - 40) / get_size().height);
+ ratio_v = new_ratio;
+ queue_sort();
+ update();
+ }
+ }
+}
+
+void SpatialEditorViewportContainer::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_MOUSE_ENTER || p_what == NOTIFICATION_MOUSE_EXIT) {
+
+ mouseover = (p_what == NOTIFICATION_MOUSE_ENTER);
+ update();
+ }
+
+ if (p_what == NOTIFICATION_DRAW && mouseover) {
+
+ Ref<Texture> h_grabber = get_icon("grabber", "HSplitContainer");
+
+ Ref<Texture> v_grabber = get_icon("grabber", "VSplitContainer");
+
+ Vector2 size = get_size();
+
+ int h_sep = get_constant("separation", "HSplitContainer");
+
+ int v_sep = get_constant("separation", "VSplitContainer");
+
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
+
+ int size_left = mid_w - h_sep / 2;
+ int size_bottom = size.height - mid_h - v_sep / 2;
+
+ switch (view) {
+
+ case VIEW_USE_1_VIEWPORT: {
+
+ //nothing to show
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
+
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
+
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS: {
+
+ draw_texture(v_grabber, Vector2((size.width - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, mid_h + v_grabber->get_height() / 2 + (size_bottom - h_grabber->get_height()) / 2));
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS_ALT: {
+
+ draw_texture(v_grabber, Vector2((size_left - v_grabber->get_width()) / 2, mid_h - v_grabber->get_height() / 2));
+ draw_texture(h_grabber, Vector2(mid_w - h_grabber->get_width() / 2, (size.height - h_grabber->get_height()) / 2));
+ } break;
+ case VIEW_USE_4_VIEWPORTS: {
+
+ Vector2 half(mid_w, mid_h);
+ draw_texture(v_grabber, half - v_grabber->get_size() / 2.0);
+ draw_texture(h_grabber, half - h_grabber->get_size() / 2.0);
+
+ } break;
+ }
+ }
+
+ if (p_what == NOTIFICATION_SORT_CHILDREN) {
+
+ SpatialEditorViewport *viewports[4];
+ int vc = 0;
+ for (int i = 0; i < get_child_count(); i++) {
+ viewports[vc] = get_child(i)->cast_to<SpatialEditorViewport>();
+ if (viewports[vc]) {
+ vc++;
+ }
+ }
+
+ ERR_FAIL_COND(vc != 4);
+
+ Size2 size = get_size();
+
+ if (size.x < 10 || size.y < 10) {
+ for (int i = 0; i < 4; i++) {
+ viewports[i]->hide();
+ }
+ return;
+ }
+ int h_sep = get_constant("separation", "HSplitContainer");
+
+ int v_sep = get_constant("separation", "VSplitContainer");
+
+ int mid_w = size.width * ratio_h;
+ int mid_h = size.height * ratio_v;
+
+ int size_left = mid_w - h_sep / 2;
+ int size_right = size.width - mid_w - h_sep / 2;
+
+ int size_top = mid_h - v_sep / 2;
+ int size_bottom = size.height - mid_h - v_sep / 2;
+
+ switch (view) {
+
+ case VIEW_USE_1_VIEWPORT: {
+
+ for (int i = 1; i < 4; i++) {
+
+ viewports[i]->hide();
+ }
+
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), size));
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS: {
+
+ for (int i = 1; i < 4; i++) {
+
+ if (i == 1 || i == 3)
+ viewports[i]->hide();
+ else
+ viewports[i]->show();
+ }
+
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size.width, size_bottom)));
+
+ } break;
+ case VIEW_USE_2_VIEWPORTS_ALT: {
+
+ for (int i = 1; i < 4; i++) {
+
+ if (i == 1 || i == 3)
+ viewports[i]->hide();
+ else
+ viewports[i]->show();
+ }
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size.height)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS: {
+
+ for (int i = 1; i < 4; i++) {
+
+ if (i == 1)
+ viewports[i]->hide();
+ else
+ viewports[i]->show();
+ }
+
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size.width, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
+
+ } break;
+ case VIEW_USE_3_VIEWPORTS_ALT: {
+
+ for (int i = 1; i < 4; i++) {
+
+ if (i == 1)
+ viewports[i]->hide();
+ else
+ viewports[i]->show();
+ }
+
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size.height)));
+
+ } break;
+ case VIEW_USE_4_VIEWPORTS: {
+
+ for (int i = 1; i < 4; i++) {
+
+ viewports[i]->show();
+ }
+
+ fit_child_in_rect(viewports[0], Rect2(Vector2(), Vector2(size_left, size_top)));
+ fit_child_in_rect(viewports[1], Rect2(Vector2(mid_w + h_sep / 2, 0), Vector2(size_right, size_top)));
+ fit_child_in_rect(viewports[2], Rect2(Vector2(0, mid_h + v_sep / 2), Vector2(size_left, size_bottom)));
+ fit_child_in_rect(viewports[3], Rect2(Vector2(mid_w + h_sep / 2, mid_h + v_sep / 2), Vector2(size_right, size_bottom)));
+
+ } break;
+ }
+ }
+}
+
+void SpatialEditorViewportContainer::set_view(View p_view) {
+
+ view = p_view;
+ queue_sort();
+}
+
+SpatialEditorViewportContainer::View SpatialEditorViewportContainer::get_view() {
+
+ return view;
+}
+
+void SpatialEditorViewportContainer::_bind_methods() {
+
+ ClassDB::bind_method("_gui_input", &SpatialEditorViewportContainer::_gui_input);
+}
+
+SpatialEditorViewportContainer::SpatialEditorViewportContainer() {
+
+ view = VIEW_USE_1_VIEWPORT;
+ mouseover = false;
+ ratio_h = 0.5;
+ ratio_v = 0.5;
+ dragging_v = false;
+ dragging_h = false;
+}
+
+///////////////////////////////////////////////////////////////////
+
SpatialEditor *SpatialEditor::singleton = NULL;
SpatialEditorSelectedItem::~SpatialEditorSelectedItem() {
@@ -2260,7 +2773,7 @@ void SpatialEditor::update_transform_gizmo() {
Transform xf = se->sp->get_global_transform();
if (first) {
- center.pos = xf.origin;
+ center.position = xf.origin;
first = false;
if (local_gizmo_coords) {
gizmo_basis = xf.basis;
@@ -2273,12 +2786,12 @@ void SpatialEditor::update_transform_gizmo() {
//count++;
}
- Vector3 pcenter = center.pos + center.size * 0.5;
+ Vector3 pcenter = center.position + center.size * 0.5;
gizmo.visible = !first;
gizmo.transform.origin = pcenter;
gizmo.transform.basis = gizmo_basis;
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->update_transform_gizmo_view();
}
}
@@ -2374,17 +2887,11 @@ Dictionary SpatialEditor::get_state() const {
d["viewports"] = vpdata;
- d["default_light"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT));
- d["ambient_light_color"] = settings_ambient_color->get_pick_color();
-
- d["default_srgb"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_SRGB));
d["show_grid"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID));
d["show_origin"] = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN));
d["fov"] = get_fov();
d["znear"] = get_znear();
d["zfar"] = get_zfar();
- d["deflight_rot_x"] = settings_default_light_rot_x;
- d["deflight_rot_y"] = settings_default_light_rot_y;
return d;
}
@@ -2434,7 +2941,7 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
Array vp = d["viewports"];
ERR_FAIL_COND(vp.size() > 4);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->set_state(vp[i]);
}
}
@@ -2446,26 +2953,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
if (d.has("fov"))
settings_fov->set_value(float(d["fov"]));
- if (d.has("default_light")) {
- bool use = d["default_light"];
-
- bool existing = light_instance.is_valid();
- if (use != existing) {
- if (existing) {
- VisualServer::get_singleton()->free(light_instance);
- light_instance = RID();
- } else {
- light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
- VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
- }
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), light_instance.is_valid());
- }
- }
- if (d.has("ambient_light_color")) {
- settings_ambient_color->set_pick_color(d["ambient_light_color"]);
- //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,d["ambient_light_color"]);
- }
-
if (d.has("default_srgb")) {
bool use = d["default_srgb"];
@@ -2488,13 +2975,6 @@ void SpatialEditor::set_state(const Dictionary &p_state) {
VisualServer::get_singleton()->instance_set_visible(origin_instance, use);
}
}
-
- if (d.has("deflight_rot_x"))
- settings_default_light_rot_x = d["deflight_rot_x"];
- if (d.has("deflight_rot_y"))
- settings_default_light_rot_y = d["deflight_rot_y"];
-
- _update_default_light_angle();
}
void SpatialEditor::edit(Spatial *p_spatial) {
@@ -2631,46 +3111,9 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
xform_dialog->popup_centered(Size2(200, 200));
} break;
- case MENU_VIEW_USE_DEFAULT_LIGHT: {
-
- bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
-
- if (is_checked) {
- VisualServer::get_singleton()->free(light_instance);
- light_instance = RID();
- } else {
- light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
- VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
-
- _update_default_light_angle();
- }
-
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), light_instance.is_valid());
-
- } break;
- case MENU_VIEW_USE_DEFAULT_SRGB: {
-
- bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
-
- if (is_checked) {
- //viewport_environment->set_enable_fx(Environment::FX_SRGB,false);
- } else {
- //viewport_environment->set_enable_fx(Environment::FX_SRGB,true);
- }
-
- is_checked = !is_checked;
-
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(p_option), is_checked);
-
- } break;
case MENU_VIEW_USE_1_VIEWPORT: {
- for (int i = 1; i < 4; i++) {
-
- viewports[i]->hide();
- }
-
- viewports[0]->set_area_as_parent_rect();
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_1_VIEWPORT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), true);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false);
@@ -2682,17 +3125,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_2_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
-
- if (i == 1 || i == 3)
- viewports[i]->hide();
- else
- viewports[i]->show();
- }
- viewports[0]->set_area_as_parent_rect();
- //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5);
- viewports[2]->set_area_as_parent_rect();
- //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_2_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), true);
@@ -2704,17 +3137,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_2_VIEWPORTS_ALT: {
- for (int i = 1; i < 4; i++) {
-
- if (i == 1 || i == 3)
- viewports[i]->hide();
- else
- viewports[i]->show();
- }
- viewports[0]->set_area_as_parent_rect();
- //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- viewports[2]->set_area_as_parent_rect();
- //viewports[2]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_2_VIEWPORTS_ALT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false);
@@ -2726,21 +3149,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
-
- if (i == 1)
- viewports[i]->hide();
- else
- viewports[i]->show();
- }
- viewports[0]->set_area_as_parent_rect();
- //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5);
- viewports[2]->set_area_as_parent_rect();
- //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
- viewports[3]->set_area_as_parent_rect();
- //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
- //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_3_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false);
@@ -2752,21 +3161,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_3_VIEWPORTS_ALT: {
- for (int i = 1; i < 4; i++) {
-
- if (i == 1)
- viewports[i]->hide();
- else
- viewports[i]->show();
- }
- viewports[0]->set_area_as_parent_rect();
- //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5);
- //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- viewports[2]->set_area_as_parent_rect();
- //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
- //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- viewports[3]->set_area_as_parent_rect();
- //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_3_VIEWPORTS_ALT);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false);
@@ -2778,22 +3173,7 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
} break;
case MENU_VIEW_USE_4_VIEWPORTS: {
- for (int i = 1; i < 4; i++) {
-
- viewports[i]->show();
- }
- viewports[0]->set_area_as_parent_rect();
- //viewports[0]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- //viewports[0]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5);
- viewports[1]->set_area_as_parent_rect();
- //viewports[1]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
- //viewports[1]->set_anchor_and_margin(MARGIN_BOTTOM,ANCHOR_RATIO,0.5);
- viewports[2]->set_area_as_parent_rect();
- //viewports[2]->set_anchor_and_margin(MARGIN_RIGHT,ANCHOR_RATIO,0.5);
- //viewports[2]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
- viewports[3]->set_area_as_parent_rect();
- //viewports[3]->set_anchor_and_margin(MARGIN_LEFT,ANCHOR_RATIO,0.5);
- //viewports[3]->set_anchor_and_margin(MARGIN_TOP,ANCHOR_RATIO,0.5);
+ viewport_base->set_view(SpatialEditorViewportContainer::VIEW_USE_4_VIEWPORTS);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), false);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), false);
@@ -2803,43 +3183,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_3_VIEWPORTS_ALT), false);
} break;
- case MENU_VIEW_DISPLAY_NORMAL: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_DISABLED);
-
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_WIREFRAME: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_WIREFRAME);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_OVERDRAW: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_OVERDRAW);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), true);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), false);
-
- } break;
- case MENU_VIEW_DISPLAY_SHADELESS: {
-
- VisualServer::get_singleton()->scenario_set_debug(get_tree()->get_root()->get_world()->get_scenario(), VisualServer::SCENARIO_DEBUG_SHADELESS);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_NORMAL), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_OVERDRAW), false);
- view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_SHADELESS), true);
-
- } break;
case MENU_VIEW_ORIGIN: {
bool is_checked = view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(p_option));
@@ -2874,14 +3217,6 @@ void SpatialEditor::_menu_item_pressed(int p_option) {
void SpatialEditor::_init_indicators() {
- //make sure that the camera indicator is not selectable
- light = VisualServer::get_singleton()->light_create(VisualServer::LIGHT_DIRECTIONAL);
- //VisualServer::get_singleton()->light_set_shadow( light, true );
- light_instance = VisualServer::get_singleton()->instance_create2(light, get_tree()->get_root()->get_world()->get_scenario());
-
- light_transform.rotate(Vector3(1, 0, 0), -Math_PI / 5.0);
- VisualServer::get_singleton()->instance_set_transform(light_instance, light_transform);
-
//RID mat = VisualServer::get_singleton()->fixed_material_create();
///VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_ALPHA,true);
//VisualServer::get_singleton()->fixed_material_set_flag(mat, VisualServer::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY,true);
@@ -3009,8 +3344,8 @@ void SpatialEditor::_init_indicators() {
for (int i = 0; i < 3; i++) {
- move_gizmo[i] = Ref<Mesh>(memnew(Mesh));
- rotate_gizmo[i] = Ref<Mesh>(memnew(Mesh));
+ move_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
+ rotate_gizmo[i] = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
mat->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
@@ -3139,8 +3474,6 @@ void SpatialEditor::_finish_indicators() {
VisualServer::get_singleton()->free(grid_instance[i]);
VisualServer::get_singleton()->free(grid[i]);
}
- VisualServer::get_singleton()->free(light_instance);
- VisualServer::get_singleton()->free(light);
//VisualServer::get_singleton()->free(poly);
//VisualServer::get_singleton()->free(indicators_instance);
//VisualServer::get_singleton()->free(indicators);
@@ -3149,37 +3482,15 @@ void SpatialEditor::_finish_indicators() {
VisualServer::get_singleton()->free(cursor_mesh);
}
-void SpatialEditor::_instance_scene() {
-#if 0
- EditorNode *en = get_scene()->get_root_node()->cast_to<EditorNode>();
- ERR_FAIL_COND(!en);
- String path = en->get_filesystem_dock()->get_selected_path();
- if (path=="") {
- set_message(TTR("No scene selected to instance!"));
- return;
- }
-
- undo_redo->create_action(TTR("Instance at Cursor"));
-
- Node* scene = en->request_instance_scene(path);
-
- if (!scene) {
- set_message(TTR("Could not instance scene!"));
- undo_redo->commit_action(); //bleh
- return;
- }
-
- Spatial *s = scene->cast_to<Spatial>();
- if (s) {
-
- undo_redo->add_do_method(s,"set_global_transform",Transform(Matrix3(),cursor.cursor_pos));
+bool SpatialEditor::is_any_freelook_active() const {
+ for (unsigned int i = 0; i < VIEWPORTS_COUNT; ++i) {
+ if (viewports[i]->is_freelook_active())
+ return true;
}
-
- undo_redo->commit_action();
-#endif
+ return false;
}
-void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
+void SpatialEditor::_unhandled_key_input(Ref<InputEvent> p_event) {
if (!is_visible_in_tree() || get_viewport()->gui_has_modal_stack())
return;
@@ -3199,38 +3510,28 @@ void SpatialEditor::_unhandled_key_input(InputEvent p_event) {
}
#endif
- switch (p_event.type) {
-
- case InputEvent::KEY: {
+ Ref<InputEventKey> k = p_event;
- const InputEventKey &k = p_event.key;
+ if (k.is_valid()) {
- if (!k.pressed)
- break;
+ // Note: need to check is_echo because first person movement keys might still be held
+ if (!is_any_freelook_active() && !p_event->is_echo()) {
- switch (k.scancode) {
+ if (!k->is_pressed())
+ return;
- case KEY_Q: _menu_item_pressed(MENU_TOOL_SELECT); break;
- case KEY_W: _menu_item_pressed(MENU_TOOL_MOVE); break;
- case KEY_E: _menu_item_pressed(MENU_TOOL_ROTATE); break;
- case KEY_R: _menu_item_pressed(MENU_TOOL_SCALE); break;
+ if (ED_IS_SHORTCUT("spatial_editor/tool_select", p_event))
+ _menu_item_pressed(MENU_TOOL_SELECT);
- case KEY_Z: {
- if (k.mod.shift || k.mod.control || k.mod.command)
- break;
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_move", p_event))
+ _menu_item_pressed(MENU_TOOL_MOVE);
- if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_DISPLAY_WIREFRAME))) {
- _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL);
- } else {
- _menu_item_pressed(MENU_VIEW_DISPLAY_WIREFRAME);
- }
- } break;
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_rotate", p_event))
+ _menu_item_pressed(MENU_TOOL_ROTATE);
-#if 0
-#endif
- }
-
- } break;
+ else if (ED_IS_SHORTCUT("spatial_editor/tool_scale", p_event))
+ _menu_item_pressed(MENU_TOOL_SCALE);
+ }
}
}
void SpatialEditor::_notification(int p_what) {
@@ -3242,8 +3543,6 @@ void SpatialEditor::_notification(int p_what) {
tool_button[SpatialEditor::TOOL_MODE_ROTATE]->set_icon(get_icon("ToolRotate", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_SCALE]->set_icon(get_icon("ToolScale", "EditorIcons"));
tool_button[SpatialEditor::TOOL_MODE_LIST_SELECT]->set_icon(get_icon("ListSelect", "EditorIcons"));
- instance_button->set_icon(get_icon("SpatialAdd", "EditorIcons"));
- instance_button->hide();
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT), get_icon("Panels1", "EditorIcons"));
view_menu->get_popup()->set_item_icon(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_2_VIEWPORTS), get_icon("Panels2", "EditorIcons"));
@@ -3255,14 +3554,12 @@ void SpatialEditor::_notification(int p_what) {
_menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
get_tree()->connect("node_removed", this, "_node_removed");
- VS::get_singleton()->scenario_set_fallback_environment(get_viewport()->find_world()->get_scenario(), viewport_environment->get_rid());
}
if (p_what == NOTIFICATION_ENTER_TREE) {
gizmos = memnew(SpatialEditorGizmos);
_init_indicators();
- _update_default_light_angle();
}
if (p_what == NOTIFICATION_EXIT_TREE) {
@@ -3344,7 +3641,7 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
if (!maximized) {
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
if (i == index)
viewports[i]->set_area_as_parent_rect();
else
@@ -3352,7 +3649,7 @@ void SpatialEditor::_toggle_maximize_view(Object *p_viewport) {
}
} else {
- for (int i = 0; i < 4; i++)
+ for (int i = 0; i < VIEWPORTS_COUNT; i++)
viewports[i]->show();
if (view_menu->get_popup()->is_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_USE_1_VIEWPORT)))
@@ -3383,11 +3680,8 @@ void SpatialEditor::_bind_methods() {
ClassDB::bind_method("_node_removed", &SpatialEditor::_node_removed);
ClassDB::bind_method("_menu_item_pressed", &SpatialEditor::_menu_item_pressed);
ClassDB::bind_method("_xform_dialog_action", &SpatialEditor::_xform_dialog_action);
- ClassDB::bind_method("_instance_scene", &SpatialEditor::_instance_scene);
ClassDB::bind_method("_get_editor_data", &SpatialEditor::_get_editor_data);
ClassDB::bind_method("_request_gizmo", &SpatialEditor::_request_gizmo);
- ClassDB::bind_method("_default_light_angle_input", &SpatialEditor::_default_light_angle_input);
- ClassDB::bind_method("_update_ambient_light_color", &SpatialEditor::_update_ambient_light_color);
ClassDB::bind_method("_toggle_maximize_view", &SpatialEditor::_toggle_maximize_view);
ADD_SIGNAL(MethodInfo("transform_key_request"));
@@ -3395,17 +3689,14 @@ void SpatialEditor::_bind_methods() {
void SpatialEditor::clear() {
- settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov", 60.0));
+ settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov", 55.0));
settings_znear->set_value(EDITOR_DEF("editors/3d/default_z_near", 0.1));
settings_zfar->set_value(EDITOR_DEF("editors/3d/default_z_far", 1500.0));
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->reset();
}
- _menu_item_pressed(MENU_VIEW_USE_1_VIEWPORT);
- _menu_item_pressed(MENU_VIEW_DISPLAY_NORMAL);
-
VisualServer::get_singleton()->instance_set_visible(origin_instance, true);
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_ORIGIN), true);
for (int i = 0; i < 3; ++i) {
@@ -3415,49 +3706,13 @@ void SpatialEditor::clear() {
}
}
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER), i == 0);
viewports[i]->viewport->set_as_audio_listener(i == 0);
}
view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true);
-
- settings_default_light_rot_x = Math_PI * 0.3;
- settings_default_light_rot_y = Math_PI * 0.2;
-
- //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,Color(0.15,0.15,0.15));
- settings_ambient_color->set_pick_color(Color(0.15, 0.15, 0.15));
- if (!light_instance.is_valid())
- _menu_item_pressed(MENU_VIEW_USE_DEFAULT_LIGHT);
-
- _update_default_light_angle();
-}
-
-void SpatialEditor::_update_ambient_light_color(const Color &p_color) {
-
- //viewport_environment->fx_set_param(Environment::FX_PARAM_AMBIENT_LIGHT_COLOR,settings_ambient_color->get_color());
-}
-
-void SpatialEditor::_update_default_light_angle() {
-
- Transform t;
- t.basis.rotate(Vector3(1, 0, 0), -settings_default_light_rot_x);
- t.basis.rotate(Vector3(0, 1, 0), -settings_default_light_rot_y);
- settings_dlight->set_transform(t);
- if (light_instance.is_valid()) {
- VS::get_singleton()->instance_set_transform(light_instance, t);
- }
-}
-
-void SpatialEditor::_default_light_angle_input(const InputEvent &p_event) {
-
- if (p_event.type == InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask & (0x1 | 0x2 | 0x4)) {
-
- settings_default_light_rot_y = Math::fposmod(settings_default_light_rot_y - p_event.mouse_motion.relative_x * 0.01, Math_PI * 2.0);
- settings_default_light_rot_x = Math::fposmod(settings_default_light_rot_x - p_event.mouse_motion.relative_y * 0.01, Math_PI * 2.0);
- _update_default_light_angle();
- }
}
SpatialEditor::SpatialEditor(EditorNode *p_editor) {
@@ -3520,12 +3775,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
tool_button[TOOL_MODE_SCALE]->connect("pressed", this, "_menu_item_pressed", button_binds);
tool_button[TOOL_MODE_SCALE]->set_tooltip(TTR("Scale Mode (R)"));
- instance_button = memnew(Button);
- hbc_menu->add_child(instance_button);
- instance_button->set_flat(true);
- instance_button->connect("pressed", this, "_instance_scene");
- instance_button->hide();
-
VSeparator *vs = memnew(VSeparator);
hbc_menu->add_child(vs);
@@ -3553,6 +3802,13 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
ED_SHORTCUT("spatial_editor/focus_selection", TTR("Focus Selection"), KEY_F);
ED_SHORTCUT("spatial_editor/align_selection_with_view", TTR("Align Selection With View"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_F);
+ ED_SHORTCUT("spatial_editor/tool_select", TTR("Tool Select"), KEY_Q);
+ ED_SHORTCUT("spatial_editor/tool_move", TTR("Tool Move"), KEY_W);
+ ED_SHORTCUT("spatial_editor/tool_rotate", TTR("Tool Rotate"), KEY_E);
+ ED_SHORTCUT("spatial_editor/tool_scale", TTR("Tool Scale"), KEY_R);
+
+ ED_SHORTCUT("spatial_editor/display_wireframe", TTR("Display Wireframe"), KEY_Z);
+
PopupMenu *p;
transform_menu = memnew(MenuButton);
@@ -3577,10 +3833,6 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p = view_menu->get_popup();
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_light", TTR("Use Default Light")), MENU_VIEW_USE_DEFAULT_LIGHT);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/use_default_srgb", TTR("Use Default sRGB")), MENU_VIEW_USE_DEFAULT_SRGB);
- p->add_separator();
-
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/1_viewport", TTR("1 Viewport"), KEY_MASK_CMD + KEY_1), MENU_VIEW_USE_1_VIEWPORT);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports", TTR("2 Viewports"), KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/2_viewports_alt", TTR("2 Viewports (Alt)"), KEY_MASK_ALT + KEY_MASK_CMD + KEY_2), MENU_VIEW_USE_2_VIEWPORTS_ALT);
@@ -3589,18 +3841,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/4_viewports", TTR("4 Viewports"), KEY_MASK_CMD + KEY_4), MENU_VIEW_USE_4_VIEWPORTS);
p->add_separator();
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_normal", TTR("Display Normal")), MENU_VIEW_DISPLAY_NORMAL);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_wireframe", TTR("Display Wireframe")), MENU_VIEW_DISPLAY_WIREFRAME);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_overdraw", TTR("Display Overdraw")), MENU_VIEW_DISPLAY_OVERDRAW);
- p->add_check_shortcut(ED_SHORTCUT("spatial_editor/display_shadeless", TTR("Display Shadeless")), MENU_VIEW_DISPLAY_SHADELESS);
- p->add_separator();
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_origin", TTR("View Origin")), MENU_VIEW_ORIGIN);
p->add_check_shortcut(ED_SHORTCUT("spatial_editor/view_grid", TTR("View Grid")), MENU_VIEW_GRID);
p->add_separator();
p->add_shortcut(ED_SHORTCUT("spatial_editor/settings", TTR("Settings")), MENU_VIEW_CAMERA_SETTINGS);
- p->set_item_checked(p->get_item_index(MENU_VIEW_USE_DEFAULT_LIGHT), true);
- p->set_item_checked(p->get_item_index(MENU_VIEW_DISPLAY_NORMAL), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_ORIGIN), true);
p->set_item_checked(p->get_item_index(MENU_VIEW_GRID), true);
@@ -3615,10 +3860,10 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
shader_split = memnew(VSplitContainer);
shader_split->set_h_size_flags(SIZE_EXPAND_FILL);
palette_split->add_child(shader_split);
- viewport_base = memnew(Control);
+ viewport_base = memnew(SpatialEditorViewportContainer);
shader_split->add_child(viewport_base);
viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
- for (int i = 0; i < 4; i++) {
+ for (int i = 0; i < VIEWPORTS_COUNT; i++) {
viewports[i] = memnew(SpatialEditorViewport(this, editor, i));
viewports[i]->connect("toggle_maximize_view", this, "_toggle_maximize_view");
@@ -3658,41 +3903,11 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
settings_dialog->add_child(settings_vbc);
//settings_dialog->set_child_rect(settings_vbc);
- settings_light_base = memnew(ViewportContainer);
- settings_light_base->set_custom_minimum_size(Size2(128, 128));
- settings_light_base->connect("gui_input", this, "_default_light_angle_input");
- settings_vbc->add_margin_child(TTR("Default Light Normal:"), settings_light_base);
- settings_light_vp = memnew(Viewport);
- settings_light_vp->set_disable_input(true);
- settings_light_vp->set_use_own_world(true);
- settings_light_base->add_child(settings_light_vp);
-
- settings_dlight = memnew(DirectionalLight);
- settings_light_vp->add_child(settings_dlight);
- settings_sphere = memnew(ImmediateGeometry);
- settings_sphere->begin(Mesh::PRIMITIVE_TRIANGLES, Ref<Texture>());
- settings_sphere->set_color(Color(1, 1, 1));
- settings_sphere->add_sphere(32, 16, 1);
- settings_sphere->end();
- settings_light_vp->add_child(settings_sphere);
- settings_camera = memnew(Camera);
- settings_light_vp->add_child(settings_camera);
- settings_camera->set_translation(Vector3(0, 0, 2));
- settings_camera->set_orthogonal(2.1, 0.1, 5);
-
- settings_default_light_rot_x = Math_PI * 0.3;
- settings_default_light_rot_y = Math_PI * 0.2;
-
- settings_ambient_color = memnew(ColorPickerButton);
- settings_vbc->add_margin_child(TTR("Ambient Light Color:"), settings_ambient_color);
- settings_ambient_color->connect("color_changed", this, "_update_ambient_light_color");
- settings_ambient_color->set_pick_color(Color(0.15, 0.15, 0.15));
-
settings_fov = memnew(SpinBox);
settings_fov->set_max(179);
settings_fov->set_min(1);
settings_fov->set_step(0.01);
- settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov", 60.0));
+ settings_fov->set_value(EDITOR_DEF("editors/3d/default_fov", 55.0));
settings_vbc->add_margin_child(TTR("Perspective FOV (deg.):"), settings_fov);
settings_znear = memnew(SpinBox);
diff --git a/editor/plugins/spatial_editor_plugin.h b/editor/plugins/spatial_editor_plugin.h
index 4302927426..6b05a8b370 100644
--- a/editor/plugins/spatial_editor_plugin.h
+++ b/editor/plugins/spatial_editor_plugin.h
@@ -84,6 +84,11 @@ class SpatialEditorViewport : public Control {
VIEW_ORTHOGONAL,
VIEW_AUDIO_LISTENER,
VIEW_GIZMOS,
+ VIEW_INFORMATION,
+ VIEW_DISPLAY_NORMAL,
+ VIEW_DISPLAY_WIREFRAME,
+ VIEW_DISPLAY_OVERDRAW,
+ VIEW_DISPLAY_SHADELESS,
};
public:
@@ -114,6 +119,11 @@ private:
bool orthogonal;
float gizmo_scale;
+ bool freelook_active;
+
+ PanelContainer *info;
+ Label *info_label;
+
struct _RayResult {
Spatial *item;
@@ -140,7 +150,7 @@ private:
Vector3 _get_screen_to_space(const Vector3 &p_vector3);
void _select_region();
- bool _gizmo_select(const Vector2 &p_screenpos, bool p_hilite_only = false);
+ bool _gizmo_select(const Vector2 &p_screenpos, bool p_highlight_only = false);
float get_znear() const;
float get_zfar() const;
@@ -168,7 +178,8 @@ private:
NAVIGATION_NONE,
NAVIGATION_PAN,
NAVIGATION_ZOOM,
- NAVIGATION_ORBIT
+ NAVIGATION_ORBIT,
+ NAVIGATION_LOOK
};
enum TransformMode {
TRANSFORM_NONE,
@@ -203,8 +214,6 @@ private:
struct Cursor {
- Vector3 cursor_pos;
-
Vector3 pos;
float x_rot, y_rot, distance;
bool region_select;
@@ -217,6 +226,10 @@ private:
}
} cursor;
+ void scale_cursor_distance(real_t scale);
+
+ real_t zoom_indicator_delay;
+
RID move_gizmo_instance[3], rotate_gizmo_instance[3];
String last_message;
@@ -227,10 +240,12 @@ private:
//
void _update_camera();
+ Transform to_camera_transform(const Cursor &p_cursor) const;
void _draw();
void _smouseenter();
- void _sinput(const InputEvent &p_ie);
+ void _sinput(const Ref<InputEvent> &p_ie);
+ void _update_freelook(real_t delta);
SpatialEditor *spatial_editor;
Camera *previewing;
@@ -242,7 +257,8 @@ private:
void _finish_gizmo_instances();
void _selection_result_pressed(int);
void _selection_menu_hide();
- void _list_select(InputEventMouseButton b);
+ void _list_select(Ref<InputEventMouseButton> b);
+ Point2i _get_warped_mouse_motion(const Ref<InputEventMouseMotion> &p_ev_mouse_motion) const;
protected:
void _notification(int p_what);
@@ -255,6 +271,7 @@ public:
void set_state(const Dictionary &p_state);
Dictionary get_state() const;
void reset();
+ bool is_freelook_active() const { return freelook_active; }
void focus_selection();
@@ -278,6 +295,43 @@ public:
~SpatialEditorSelectedItem();
};
+class SpatialEditorViewportContainer : public Container {
+
+ GDCLASS(SpatialEditorViewportContainer, Container)
+public:
+ enum View {
+ VIEW_USE_1_VIEWPORT,
+ VIEW_USE_2_VIEWPORTS,
+ VIEW_USE_2_VIEWPORTS_ALT,
+ VIEW_USE_3_VIEWPORTS,
+ VIEW_USE_3_VIEWPORTS_ALT,
+ VIEW_USE_4_VIEWPORTS,
+ };
+
+private:
+ View view;
+ bool mouseover;
+ float ratio_h;
+ float ratio_v;
+
+ bool dragging_v;
+ bool dragging_h;
+ Vector2 drag_begin_pos;
+ Vector2 drag_begin_ratio;
+
+ void _gui_input(const Ref<InputEvent> &p_event);
+
+protected:
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_view(View p_view);
+ View get_view();
+
+ SpatialEditorViewportContainer();
+};
+
class SpatialEditor : public VBoxContainer {
GDCLASS(SpatialEditor, VBoxContainer);
@@ -295,11 +349,13 @@ public:
};
private:
+ static const unsigned int VIEWPORTS_COUNT = 4;
+
EditorNode *editor;
EditorSelection *editor_selection;
- Control *viewport_base;
- SpatialEditorViewport *viewports[4];
+ SpatialEditorViewportContainer *viewport_base;
+ SpatialEditorViewport *viewports[VIEWPORTS_COUNT];
VSplitContainer *shader_split;
HSplitContainer *palette_split;
@@ -310,10 +366,6 @@ private:
VisualServer::ScenarioDebugMode scenario_debug;
- RID light;
- RID light_instance;
- Transform light_transform;
-
RID origin;
RID origin_instance;
RID grid[3];
@@ -323,13 +375,13 @@ private:
bool grid_enable[3]; //should be always visible if true
bool grid_enabled;
- Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
+ Ref<ArrayMesh> move_gizmo[3], rotate_gizmo[3];
Ref<SpatialMaterial> gizmo_color[3];
Ref<SpatialMaterial> gizmo_hl;
int over_gizmo_handle;
- Ref<Mesh> selection_box;
+ Ref<ArrayMesh> selection_box;
RID indicators;
RID indicators_instance;
RID cursor_mesh;
@@ -372,12 +424,6 @@ private:
MENU_VIEW_USE_3_VIEWPORTS,
MENU_VIEW_USE_3_VIEWPORTS_ALT,
MENU_VIEW_USE_4_VIEWPORTS,
- MENU_VIEW_USE_DEFAULT_LIGHT,
- MENU_VIEW_USE_DEFAULT_SRGB,
- MENU_VIEW_DISPLAY_NORMAL,
- MENU_VIEW_DISPLAY_WIREFRAME,
- MENU_VIEW_DISPLAY_OVERDRAW,
- MENU_VIEW_DISPLAY_SHADELESS,
MENU_VIEW_ORIGIN,
MENU_VIEW_GRID,
MENU_VIEW_CAMERA_SETTINGS,
@@ -385,7 +431,6 @@ private:
};
Button *tool_button[TOOL_MAX];
- Button *instance_button;
MenuButton *transform_menu;
MenuButton *view_menu;
@@ -409,16 +454,6 @@ private:
SpinBox *settings_fov;
SpinBox *settings_znear;
SpinBox *settings_zfar;
- DirectionalLight *settings_dlight;
- ImmediateGeometry *settings_sphere;
- Camera *settings_camera;
- float settings_default_light_rot_x;
- float settings_default_light_rot_y;
-
- ViewportContainer *settings_light_base;
- Viewport *settings_light_vp;
- ColorPickerButton *settings_ambient_color;
- Image settings_light_dir_image;
void _xform_dialog_action();
void _menu_item_pressed(int p_option);
@@ -452,14 +487,12 @@ private:
SpatialEditorGizmos *gizmos;
SpatialEditor();
- void _update_ambient_light_color(const Color &p_color);
- void _update_default_light_angle();
- void _default_light_angle_input(const InputEvent &p_event);
+ bool is_any_freelook_active() const;
protected:
void _notification(int p_what);
//void _gui_input(InputEvent p_event);
- void _unhandled_key_input(InputEvent p_event);
+ void _unhandled_key_input(Ref<InputEvent> p_event);
static void _bind_methods();
@@ -480,8 +513,8 @@ public:
float get_rotate_snap() const { return snap_rotate->get_text().to_double(); }
float get_scale_snap() const { return snap_scale->get_text().to_double(); }
- Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
- Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
+ Ref<ArrayMesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
+ Ref<ArrayMesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
void update_transform_gizmo();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index c7c77fa960..d06c065f4f 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -34,7 +34,7 @@
#include "io/resource_loader.h"
#include "scene/3d/sprite_3d.h"
-void SpriteFramesEditor::_gui_input(InputEvent p_event) {
+void SpriteFramesEditor::_gui_input(Ref<InputEvent> p_event) {
}
void SpriteFramesEditor::_notification(int p_what) {
diff --git a/editor/plugins/sprite_frames_editor_plugin.h b/editor/plugins/sprite_frames_editor_plugin.h
index 3778e4ca55..c9081c599a 100644
--- a/editor/plugins/sprite_frames_editor_plugin.h
+++ b/editor/plugins/sprite_frames_editor_plugin.h
@@ -100,7 +100,7 @@ class SpriteFramesEditor : public PanelContainer {
protected:
void _notification(int p_what);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_editor_plugin.cpp b/editor/plugins/texture_editor_plugin.cpp
index 62977d86ea..676e50d61c 100644
--- a/editor/plugins/texture_editor_plugin.cpp
+++ b/editor/plugins/texture_editor_plugin.cpp
@@ -33,7 +33,7 @@
#include "global_config.h"
#include "io/resource_loader.h"
-void TextureEditor::_gui_input(InputEvent p_event) {
+void TextureEditor::_gui_input(Ref<InputEvent> p_event) {
}
void TextureEditor::_notification(int p_what) {
@@ -71,6 +71,8 @@ void TextureEditor::_notification(int p_what) {
String format;
if (texture->cast_to<ImageTexture>()) {
format = Image::get_format_name(texture->cast_to<ImageTexture>()->get_format());
+ } else if (texture->cast_to<StreamTexture>()) {
+ format = Image::get_format_name(texture->cast_to<StreamTexture>()->get_format());
} else {
format = texture->get_class();
}
diff --git a/editor/plugins/texture_editor_plugin.h b/editor/plugins/texture_editor_plugin.h
index 8750ce4d5e..9382983538 100644
--- a/editor/plugins/texture_editor_plugin.h
+++ b/editor/plugins/texture_editor_plugin.h
@@ -42,7 +42,7 @@ class TextureEditor : public Control {
protected:
void _notification(int p_what);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
public:
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 4c49b467d8..976a7b6271 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -114,10 +114,10 @@ void TextureRegionEditor::_region_draw() {
for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
Rect2 r = E->get();
Vector2 endpoints[4] = {
- mtx.basis_xform(r.pos),
- mtx.basis_xform(r.pos + Vector2(r.size.x, 0)),
- mtx.basis_xform(r.pos + r.size),
- mtx.basis_xform(r.pos + Vector2(0, r.size.y))
+ mtx.basis_xform(r.position),
+ mtx.basis_xform(r.position + Vector2(r.size.x, 0)),
+ mtx.basis_xform(r.position + r.size),
+ mtx.basis_xform(r.position + Vector2(0, r.size.y))
};
for (int i = 0; i < 4; i++) {
int next = (i + 1) % 4;
@@ -132,10 +132,10 @@ void TextureRegionEditor::_region_draw() {
scroll_rect.expand_to(mtx.basis_xform(edit_draw->get_size()));
Vector2 endpoints[4] = {
- mtx.basis_xform(rect.pos),
- mtx.basis_xform(rect.pos + Vector2(rect.size.x, 0)),
- mtx.basis_xform(rect.pos + rect.size),
- mtx.basis_xform(rect.pos + Vector2(0, rect.size.y))
+ mtx.basis_xform(rect.position),
+ mtx.basis_xform(rect.position + Vector2(rect.size.x, 0)),
+ mtx.basis_xform(rect.position + rect.size),
+ mtx.basis_xform(rect.position + Vector2(0, rect.size.y))
};
Color color(0.9, 0.5, 0.5);
for (int i = 0; i < 4; i++) {
@@ -162,14 +162,14 @@ void TextureRegionEditor::_region_draw() {
scroll_rect = scroll_rect.grow(200);
updating_scroll = true;
- hscroll->set_min(scroll_rect.pos.x);
- hscroll->set_max(scroll_rect.pos.x + scroll_rect.size.x);
+ hscroll->set_min(scroll_rect.position.x);
+ hscroll->set_max(scroll_rect.position.x + scroll_rect.size.x);
hscroll->set_page(edit_draw->get_size().x);
hscroll->set_value(draw_ofs.x);
hscroll->set_step(0.001);
- vscroll->set_min(scroll_rect.pos.y);
- vscroll->set_max(scroll_rect.pos.y + scroll_rect.size.y);
+ vscroll->set_min(scroll_rect.position.y);
+ vscroll->set_max(scroll_rect.position.y + scroll_rect.size.y);
vscroll->set_page(edit_draw->get_size().y);
vscroll->set_value(draw_ofs.y);
vscroll->set_step(0.001);
@@ -202,29 +202,28 @@ void TextureRegionEditor::_region_draw() {
}
}
-void TextureRegionEditor::_region_input(const InputEvent &p_input) {
+void TextureRegionEditor::_region_input(const Ref<InputEvent> &p_input) {
Transform2D mtx;
mtx.elements[2] = -draw_ofs;
mtx.scale_basis(Vector2(draw_zoom, draw_zoom));
Vector2 endpoints[8] = {
- mtx.xform(rect.pos) + Vector2(-4, -4),
- mtx.xform(rect.pos + Vector2(rect.size.x / 2, 0)) + Vector2(0, -4),
- mtx.xform(rect.pos + Vector2(rect.size.x, 0)) + Vector2(4, -4),
- mtx.xform(rect.pos + Vector2(rect.size.x, rect.size.y / 2)) + Vector2(4, 0),
- mtx.xform(rect.pos + rect.size) + Vector2(4, 4),
- mtx.xform(rect.pos + Vector2(rect.size.x / 2, rect.size.y)) + Vector2(0, 4),
- mtx.xform(rect.pos + Vector2(0, rect.size.y)) + Vector2(-4, 4),
- mtx.xform(rect.pos + Vector2(0, rect.size.y / 2)) + Vector2(-4, 0)
+ mtx.xform(rect.position) + Vector2(-4, -4),
+ mtx.xform(rect.position + Vector2(rect.size.x / 2, 0)) + Vector2(0, -4),
+ mtx.xform(rect.position + Vector2(rect.size.x, 0)) + Vector2(4, -4),
+ mtx.xform(rect.position + Vector2(rect.size.x, rect.size.y / 2)) + Vector2(4, 0),
+ mtx.xform(rect.position + rect.size) + Vector2(4, 4),
+ mtx.xform(rect.position + Vector2(rect.size.x / 2, rect.size.y)) + Vector2(0, 4),
+ mtx.xform(rect.position + Vector2(0, rect.size.y)) + Vector2(-4, 4),
+ mtx.xform(rect.position + Vector2(0, rect.size.y / 2)) + Vector2(-4, 0)
};
- if (p_input.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb;
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb = p_input.mouse_button;
+ if (mb->get_button_index() == BUTTON_LEFT) {
- if (mb.button_index == BUTTON_LEFT) {
-
- if (mb.pressed) {
+ if (mb->is_pressed()) {
if (node_patch9 || obj_styleBox.is_valid()) {
edited_margin = -1;
float margins[4];
@@ -240,31 +239,31 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
margins[3] = obj_styleBox->get_margin_size(MARGIN_RIGHT);
}
Vector2 pos[4] = {
- mtx.basis_xform(rect.pos + Vector2(0, margins[0])) - draw_ofs,
- mtx.basis_xform(rect.pos + rect.size - Vector2(0, margins[1])) - draw_ofs,
- mtx.basis_xform(rect.pos + Vector2(margins[2], 0)) - draw_ofs,
- mtx.basis_xform(rect.pos + rect.size - Vector2(margins[3], 0)) - draw_ofs
+ mtx.basis_xform(rect.position + Vector2(0, margins[0])) - draw_ofs,
+ mtx.basis_xform(rect.position + rect.size - Vector2(0, margins[1])) - draw_ofs,
+ mtx.basis_xform(rect.position + Vector2(margins[2], 0)) - draw_ofs,
+ mtx.basis_xform(rect.position + rect.size - Vector2(margins[3], 0)) - draw_ofs
};
- if (Math::abs(mb.y - pos[0].y) < 8) {
+ if (Math::abs(mb->get_position().y - pos[0].y) < 8) {
edited_margin = 0;
prev_margin = margins[0];
- } else if (Math::abs(mb.y - pos[1].y) < 8) {
+ } else if (Math::abs(mb->get_position().y - pos[1].y) < 8) {
edited_margin = 1;
prev_margin = margins[1];
- } else if (Math::abs(mb.x - pos[2].x) < 8) {
+ } else if (Math::abs(mb->get_position().x - pos[2].x) < 8) {
edited_margin = 2;
prev_margin = margins[2];
- } else if (Math::abs(mb.x - pos[3].x) < 8) {
+ } else if (Math::abs(mb->get_position().x - pos[3].x) < 8) {
edited_margin = 3;
prev_margin = margins[3];
}
if (edited_margin >= 0) {
- drag_from = Vector2(mb.x, mb.y);
+ drag_from = Vector2(mb->get_position().x, mb->get_position().y);
drag = true;
}
}
if (edited_margin < 0 && snap_mode == SNAP_AUTOSLICE) {
- Vector2 point = mtx.affine_inverse().xform(Vector2(mb.x, mb.y));
+ Vector2 point = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y));
for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
if (E->get().has_point(point)) {
rect = E->get();
@@ -278,8 +277,8 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
r = obj_styleBox->get_region_rect();
else if (atlas_tex.is_valid())
r = atlas_tex->get_region();
- rect.expand_to(r.pos);
- rect.expand_to(r.pos + r.size);
+ rect.expand_to(r.position);
+ rect.expand_to(r.position + r.size);
}
undo_redo->create_action("Set Region Rect");
if (node_sprite) {
@@ -302,7 +301,7 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
}
}
} else if (edited_margin < 0) {
- drag_from = mtx.affine_inverse().xform(Vector2(mb.x, mb.y));
+ drag_from = mtx.affine_inverse().xform(Vector2(mb->get_position().x, mb->get_position().y));
if (snap_mode == SNAP_PIXEL)
drag_from = drag_from.snapped(Vector2(1, 1));
else if (snap_mode == SNAP_GRID)
@@ -319,7 +318,7 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
for (int i = 0; i < 8; i++) {
Vector2 tuv = endpoints[i];
- if (tuv.distance_to(Vector2(mb.x, mb.y)) < 8) {
+ if (tuv.distance_to(Vector2(mb->get_position().x, mb->get_position().y)) < 8) {
drag_index = i;
}
}
@@ -369,7 +368,7 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
creating = false;
}
- } else if (mb.button_index == BUTTON_RIGHT && mb.pressed) {
+ } else if (mb->get_button_index() == BUTTON_RIGHT && mb->is_pressed()) {
if (drag) {
drag = false;
@@ -387,18 +386,20 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
drag_index = -1;
}
}
- } else if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
+ } else if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
_zoom_in();
- } else if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
_zoom_out();
}
- } else if (p_input.type == InputEvent::MOUSE_MOTION) {
+ }
+
+ Ref<InputEventMouseMotion> mm = p_input;
- const InputEventMouseMotion &mm = p_input.mouse_motion;
+ if (mm.is_valid()) {
- if (mm.button_mask & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
+ if (mm->get_button_mask() & BUTTON_MASK_MIDDLE || Input::get_singleton()->is_key_pressed(KEY_SPACE)) {
- Vector2 draged(mm.relative_x, mm.relative_y);
+ Vector2 draged(mm->get_relative().x, mm->get_relative().y);
hscroll->set_value(hscroll->get_value() - draged.x);
vscroll->set_value(vscroll->get_value() - draged.y);
@@ -407,13 +408,13 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
if (edited_margin >= 0) {
float new_margin;
if (edited_margin == 0)
- new_margin = prev_margin + (mm.y - drag_from.y) / draw_zoom;
+ new_margin = prev_margin + (mm->get_position().y - drag_from.y) / draw_zoom;
else if (edited_margin == 1)
- new_margin = prev_margin - (mm.y - drag_from.y) / draw_zoom;
+ new_margin = prev_margin - (mm->get_position().y - drag_from.y) / draw_zoom;
else if (edited_margin == 2)
- new_margin = prev_margin + (mm.x - drag_from.x) / draw_zoom;
+ new_margin = prev_margin + (mm->get_position().x - drag_from.x) / draw_zoom;
else if (edited_margin == 3)
- new_margin = prev_margin - (mm.x - drag_from.x) / draw_zoom;
+ new_margin = prev_margin - (mm->get_position().x - drag_from.x) / draw_zoom;
if (new_margin < 0)
new_margin = 0;
static Margin m[4] = { MARGIN_TOP, MARGIN_BOTTOM, MARGIN_LEFT, MARGIN_RIGHT };
@@ -422,7 +423,7 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
if (obj_styleBox.is_valid())
obj_styleBox->set_margin_size(m[edited_margin], new_margin);
} else {
- Vector2 new_pos = mtx.affine_inverse().xform(Vector2(mm.x, mm.y));
+ Vector2 new_pos = mtx.affine_inverse().xform(mm->get_position());
if (snap_mode == SNAP_PIXEL)
new_pos = new_pos.snapped(Vector2(1, 1));
else if (snap_mode == SNAP_GRID)
@@ -438,49 +439,49 @@ void TextureRegionEditor::_region_input(const InputEvent &p_input) {
switch (drag_index) {
case 0: {
- Vector2 p = rect_prev.pos + rect_prev.size;
+ Vector2 p = rect_prev.position + rect_prev.size;
rect = Rect2(p, Size2());
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 1: {
- Vector2 p = rect_prev.pos + Vector2(0, rect_prev.size.y);
+ Vector2 p = rect_prev.position + Vector2(0, rect_prev.size.y);
rect = Rect2(p, Size2(rect_prev.size.x, 0));
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 2: {
- Vector2 p = rect_prev.pos + Vector2(0, rect_prev.size.y);
+ Vector2 p = rect_prev.position + Vector2(0, rect_prev.size.y);
rect = Rect2(p, Size2());
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 3: {
- Vector2 p = rect_prev.pos;
+ Vector2 p = rect_prev.position;
rect = Rect2(p, Size2(0, rect_prev.size.y));
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 4: {
- Vector2 p = rect_prev.pos;
+ Vector2 p = rect_prev.position;
rect = Rect2(p, Size2());
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 5: {
- Vector2 p = rect_prev.pos;
+ Vector2 p = rect_prev.position;
rect = Rect2(p, Size2(rect_prev.size.x, 0));
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 6: {
- Vector2 p = rect_prev.pos + Vector2(rect_prev.size.x, 0);
+ Vector2 p = rect_prev.position + Vector2(rect_prev.size.x, 0);
rect = Rect2(p, Size2());
rect.expand_to(new_pos);
apply_rect(rect);
} break;
case 7: {
- Vector2 p = rect_prev.pos + Vector2(rect_prev.size.x, 0);
+ Vector2 p = rect_prev.position + Vector2(rect_prev.size.x, 0);
rect = Rect2(p, Size2(0, rect_prev.size.y));
rect.expand_to(new_pos);
apply_rect(rect);
@@ -678,12 +679,13 @@ void TextureRegionEditor::_edit_region() {
}
autoslice_cache.clear();
- Image i;
- if (i.load(texture->get_path()) == OK) {
+ Ref<Image> i;
+ i.instance();
+ if (i->load(texture->get_path()) == OK) {
BitMap bm;
bm.create_from_image_alpha(i);
- for (int y = 0; y < i.get_height(); y++) {
- for (int x = 0; x < i.get_width(); x++) {
+ for (int y = 0; y < i->get_height(); y++) {
+ for (int x = 0; x < i->get_width(); x++) {
if (bm.get_bit(Point2(x, y))) {
bool found = false;
for (List<Rect2>::Element *E = autoslice_cache.front(); E; E = E->next()) {
@@ -691,7 +693,7 @@ void TextureRegionEditor::_edit_region() {
if (grown.has_point(Point2(x, y))) {
E->get().expand_to(Point2(x, y));
E->get().expand_to(Point2(x + 1, y + 1));
- x = E->get().pos.x + E->get().size.x - 1;
+ x = E->get().position.x + E->get().size.x - 1;
bool merged = true;
while (merged) {
merged = false;
@@ -704,8 +706,8 @@ void TextureRegionEditor::_edit_region() {
if (F == E)
continue;
if (E->get().grow(1).intersects(F->get())) {
- E->get().expand_to(F->get().pos);
- E->get().expand_to(F->get().pos + F->get().size);
+ E->get().expand_to(F->get().position);
+ E->get().expand_to(F->get().position + F->get().size);
if (F->prev()) {
F = F->prev();
autoslice_cache.erase(F->next());
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index 093e2f7d01..cb0b9fc372 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -122,7 +122,7 @@ protected:
public:
void _edit_region();
void _region_draw();
- void _region_input(const InputEvent &p_input);
+ void _region_input(const Ref<InputEvent> &p_input);
void _scroll_changed(float);
void edit(Object *p_obj);
diff --git a/editor/plugins/tile_map_editor_plugin.cpp b/editor/plugins/tile_map_editor_plugin.cpp
index 9f99a9b978..d12b979121 100644
--- a/editor/plugins/tile_map_editor_plugin.cpp
+++ b/editor/plugins/tile_map_editor_plugin.cpp
@@ -98,8 +98,8 @@ void TileMapEditor::_menu_option(int p_option) {
return;
undo_redo->create_action("Erase Selection");
- for (int i = rectangle.pos.y; i <= rectangle.pos.y + rectangle.size.y; i++) {
- for (int j = rectangle.pos.x; j <= rectangle.pos.x + rectangle.size.x; j++) {
+ for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
+ for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
_set_cell(Point2i(j, i), TileMap::INVALID_CELL, false, false, false, true);
}
@@ -179,14 +179,16 @@ void TileMapEditor::_text_changed(const String &p_text) {
_update_palette();
}
-void TileMapEditor::_sbox_input(const InputEvent &p_ie) {
+void TileMapEditor::_sbox_input(const Ref<InputEvent> &p_ie) {
- if (p_ie.type == InputEvent::KEY && (p_ie.key.scancode == KEY_UP ||
- p_ie.key.scancode == KEY_DOWN ||
- p_ie.key.scancode == KEY_PAGEUP ||
- p_ie.key.scancode == KEY_PAGEDOWN)) {
+ Ref<InputEventKey> k = p_ie;
- palette->call("_gui_input", p_ie);
+ if (k.is_valid() && (k->get_scancode() == KEY_UP ||
+ k->get_scancode() == KEY_DOWN ||
+ k->get_scancode() == KEY_PAGEUP ||
+ k->get_scancode() == KEY_PAGEDOWN)) {
+
+ palette->call("_gui_input", k);
search_box->accept_event();
}
}
@@ -331,7 +333,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
}
Rect2i r = node->get_item_rect();
- r.pos = r.pos / node->get_cell_size();
+ r.position = r.position / node->get_cell_size();
r.size = r.size / node->get_cell_size();
int area = r.get_area();
@@ -347,7 +349,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
invalidate_cache = true;
}
// Tile ID changed or position wasn't visited by the previous fill
- int loc = (p_start.x - r.get_pos().x) + (p_start.y - r.get_pos().y) * r.get_size().x;
+ int loc = (p_start.x - r.position.x) + (p_start.y - r.position.y) * r.get_size().x;
if (prev_id != bucket_cache_tile || !bucket_cache_visited[loc]) {
invalidate_cache = true;
}
@@ -378,7 +380,7 @@ PoolVector<Vector2> TileMapEditor::_bucket_fill(const Point2i &p_start, bool era
if (node->get_cell(n.x, n.y) == prev_id) {
if (preview) {
- int loc = (n.x - r.get_pos().x) + (n.y - r.get_pos().y) * r.get_size().x;
+ int loc = (n.x - r.position.x) + (n.y - r.position.y) * r.get_size().x;
if (bucket_cache_visited[loc])
continue;
bucket_cache_visited[loc] = true;
@@ -439,7 +441,7 @@ void TileMapEditor::_select(const Point2i &p_from, const Point2i &p_to) {
SWAP(begin.y, end.y);
}
- rectangle.pos = begin;
+ rectangle.position = begin;
rectangle.size = end - begin;
canvas_item_editor->update();
@@ -458,7 +460,7 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h
Size2 sc = p_xform.get_scale();
Rect2 rect = Rect2();
- rect.pos = node->map_to_world(p_point) + node->get_cell_draw_offset();
+ rect.position = node->map_to_world(p_point) + node->get_cell_draw_offset();
if (r.has_no_area()) {
rect.size = t->get_size();
@@ -488,42 +490,42 @@ void TileMapEditor::_draw_cell(int p_cell, const Point2i &p_point, bool p_flip_h
if (node->get_tile_origin() == TileMap::TILE_ORIGIN_TOP_LEFT) {
- rect.pos += tile_ofs;
+ rect.position += tile_ofs;
} else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_BOTTOM_LEFT) {
Size2 cell_size = node->get_cell_size();
- rect.pos += tile_ofs;
+ rect.position += tile_ofs;
if (p_transpose) {
if (p_flip_h)
- rect.pos.x -= cell_size.x;
+ rect.position.x -= cell_size.x;
else
- rect.pos.x += cell_size.x;
+ rect.position.x += cell_size.x;
} else {
if (p_flip_v)
- rect.pos.y -= cell_size.y;
+ rect.position.y -= cell_size.y;
else
- rect.pos.y += cell_size.y;
+ rect.position.y += cell_size.y;
}
} else if (node->get_tile_origin() == TileMap::TILE_ORIGIN_CENTER) {
- rect.pos += node->get_cell_size() / 2;
+ rect.position += node->get_cell_size() / 2;
Vector2 s = r.size;
Vector2 center = (s / 2) - tile_ofs;
if (p_flip_h)
- rect.pos.x -= s.x - center.x;
+ rect.position.x -= s.x - center.x;
else
- rect.pos.x -= center.x;
+ rect.position.x -= center.x;
if (p_flip_v)
- rect.pos.y -= s.y - center.y;
+ rect.position.y -= s.y - center.y;
else
- rect.pos.y -= center.y;
+ rect.position.y -= center.y;
}
- rect.pos = p_xform.xform(rect.pos);
+ rect.position = p_xform.xform(rect.position);
rect.size *= sc;
if (r.has_no_area())
@@ -558,9 +560,9 @@ void TileMapEditor::_update_copydata() {
if (!selection_active)
return;
- for (int i = rectangle.pos.y; i <= rectangle.pos.y + rectangle.size.y; i++) {
+ for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
- for (int j = rectangle.pos.x; j <= rectangle.pos.x + rectangle.size.x; j++) {
+ for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
TileData tcd;
@@ -622,7 +624,7 @@ static inline Vector<Point2i> line(int x0, int x1, int y0, int y1) {
return points;
}
-bool TileMapEditor::forward_gui_input(const InputEvent &p_event) {
+bool TileMapEditor::forward_gui_input(const Ref<InputEvent> &p_event) {
if (!node || !node->get_tileset().is_valid() || !node->is_visible_in_tree())
return false;
@@ -630,464 +632,459 @@ bool TileMapEditor::forward_gui_input(const InputEvent &p_event) {
Transform2D xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform();
Transform2D xform_inv = xform.affine_inverse();
- switch (p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- const InputEventMouseButton &mb = p_event.mouse_button;
-
- if (mb.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
- if (mb.pressed) {
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
- if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
- return false; //drag
+ if (mb->is_pressed()) {
- if (tool == TOOL_NONE) {
+ if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
+ return false; //drag
- if (mb.mod.shift) {
+ if (tool == TOOL_NONE) {
- if (mb.mod.control)
- tool = TOOL_RECTANGLE_PAINT;
- else
- tool = TOOL_LINE_PAINT;
+ if (mb->get_shift()) {
- selection_active = false;
- rectangle_begin = over_tile;
+ if (mb->get_control())
+ tool = TOOL_RECTANGLE_PAINT;
+ else
+ tool = TOOL_LINE_PAINT;
- return true;
- }
+ selection_active = false;
+ rectangle_begin = over_tile;
- if (mb.mod.control) {
+ return true;
+ }
- tool = TOOL_PICKING;
- _pick_tile(over_tile);
+ if (mb->get_control()) {
- return true;
- }
+ tool = TOOL_PICKING;
+ _pick_tile(over_tile);
- tool = TOOL_PAINTING;
+ return true;
}
- if (tool == TOOL_PAINTING) {
-
- int id = get_selected_tile();
+ tool = TOOL_PAINTING;
+ }
- if (id != TileMap::INVALID_CELL) {
+ if (tool == TOOL_PAINTING) {
- tool = TOOL_PAINTING;
+ int id = get_selected_tile();
- paint_undo.clear();
- paint_undo[over_tile] = _get_op_from_cell(over_tile);
+ if (id != TileMap::INVALID_CELL) {
- _set_cell(over_tile, id, flip_h, flip_v, transpose);
- }
- } else if (tool == TOOL_PICKING) {
+ tool = TOOL_PAINTING;
- _pick_tile(over_tile);
- } else if (tool == TOOL_SELECTING) {
+ paint_undo.clear();
+ paint_undo[over_tile] = _get_op_from_cell(over_tile);
- selection_active = true;
- rectangle_begin = over_tile;
+ _set_cell(over_tile, id, flip_h, flip_v, transpose);
}
+ } else if (tool == TOOL_PICKING) {
- return true;
+ _pick_tile(over_tile);
+ } else if (tool == TOOL_SELECTING) {
- } else {
+ selection_active = true;
+ rectangle_begin = over_tile;
+ }
+
+ return true;
- if (tool != TOOL_NONE) {
+ } else {
- if (tool == TOOL_PAINTING) {
+ if (tool != TOOL_NONE) {
- int id = get_selected_tile();
+ if (tool == TOOL_PAINTING) {
- if (id != TileMap::INVALID_CELL && paint_undo.size()) {
+ int id = get_selected_tile();
- undo_redo->create_action(TTR("Paint TileMap"));
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ if (id != TileMap::INVALID_CELL && paint_undo.size()) {
- Point2 p = E->key();
- undo_redo->add_do_method(node, "set_cellv", p, id, flip_h, flip_v, transpose);
- undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
- undo_redo->commit_action();
+ undo_redo->create_action(TTR("Paint TileMap"));
+ for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- paint_undo.clear();
+ Point2 p = E->key();
+ undo_redo->add_do_method(node, "set_cellv", p, id, flip_h, flip_v, transpose);
+ undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
}
- } else if (tool == TOOL_LINE_PAINT) {
-
- int id = get_selected_tile();
+ undo_redo->commit_action();
- if (id != TileMap::INVALID_CELL) {
+ paint_undo.clear();
+ }
+ } else if (tool == TOOL_LINE_PAINT) {
- undo_redo->create_action("Line Draw");
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ int id = get_selected_tile();
- _set_cell(E->key(), id, flip_h, flip_v, transpose, true);
- }
- undo_redo->commit_action();
+ if (id != TileMap::INVALID_CELL) {
- paint_undo.clear();
+ undo_redo->create_action("Line Draw");
+ for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- canvas_item_editor->update();
+ _set_cell(E->key(), id, flip_h, flip_v, transpose, true);
}
- } else if (tool == TOOL_RECTANGLE_PAINT) {
-
- int id = get_selected_tile();
-
- if (id != TileMap::INVALID_CELL) {
+ undo_redo->commit_action();
- undo_redo->create_action("Rectangle Paint");
- for (int i = rectangle.pos.y; i <= rectangle.pos.y + rectangle.size.y; i++) {
- for (int j = rectangle.pos.x; j <= rectangle.pos.x + rectangle.size.x; j++) {
+ paint_undo.clear();
- _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
- }
- }
- undo_redo->commit_action();
+ canvas_item_editor->update();
+ }
+ } else if (tool == TOOL_RECTANGLE_PAINT) {
- canvas_item_editor->update();
- }
- } else if (tool == TOOL_DUPLICATING) {
+ int id = get_selected_tile();
- Point2 ofs = over_tile - rectangle.pos;
+ if (id != TileMap::INVALID_CELL) {
- undo_redo->create_action(TTR("Duplicate"));
- for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
+ undo_redo->create_action("Rectangle Paint");
+ for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
+ for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
- _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose, true);
+ _set_cell(Point2i(j, i), id, flip_h, flip_v, transpose, true);
+ }
}
undo_redo->commit_action();
- copydata.clear();
-
canvas_item_editor->update();
+ }
+ } else if (tool == TOOL_DUPLICATING) {
- } else if (tool == TOOL_SELECTING) {
+ Point2 ofs = over_tile - rectangle.position;
- canvas_item_editor->update();
+ undo_redo->create_action(TTR("Duplicate"));
+ for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
- } else if (tool == TOOL_BUCKET) {
+ _set_cell(E->get().pos + ofs, E->get().cell, E->get().flip_h, E->get().flip_v, E->get().transpose, true);
+ }
+ undo_redo->commit_action();
- Dictionary pop;
- pop["id"] = node->get_cell(over_tile.x, over_tile.y);
- pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
- pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
- pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
+ copydata.clear();
+
+ canvas_item_editor->update();
- PoolVector<Vector2> points = _bucket_fill(over_tile);
+ } else if (tool == TOOL_SELECTING) {
- if (points.size() == 0)
- return false;
+ canvas_item_editor->update();
- Dictionary op;
- op["id"] = get_selected_tile();
- op["flip_h"] = flip_h;
- op["flip_v"] = flip_v;
- op["transpose"] = transpose;
+ } else if (tool == TOOL_BUCKET) {
- undo_redo->create_action("Bucket Fill");
+ Dictionary pop;
+ pop["id"] = node->get_cell(over_tile.x, over_tile.y);
+ pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
+ pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
+ pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
- undo_redo->add_do_method(this, "_fill_points", points, op);
- undo_redo->add_undo_method(this, "_fill_points", points, pop);
+ PoolVector<Vector2> points = _bucket_fill(over_tile);
- undo_redo->commit_action();
- }
+ if (points.size() == 0)
+ return false;
- tool = TOOL_NONE;
+ Dictionary op;
+ op["id"] = get_selected_tile();
+ op["flip_h"] = flip_h;
+ op["flip_v"] = flip_v;
+ op["transpose"] = transpose;
- return true;
+ undo_redo->create_action("Bucket Fill");
+
+ undo_redo->add_do_method(this, "_fill_points", points, op);
+ undo_redo->add_undo_method(this, "_fill_points", points, pop);
+
+ undo_redo->commit_action();
}
- }
- } else if (mb.button_index == BUTTON_RIGHT) {
- if (mb.pressed) {
+ tool = TOOL_NONE;
- if (tool == TOOL_SELECTING || selection_active) {
+ return true;
+ }
+ }
+ } else if (mb->get_button_index() == BUTTON_RIGHT) {
- tool = TOOL_NONE;
- selection_active = false;
+ if (mb->is_pressed()) {
- canvas_item_editor->update();
+ if (tool == TOOL_SELECTING || selection_active) {
- return true;
- }
+ tool = TOOL_NONE;
+ selection_active = false;
- if (tool == TOOL_DUPLICATING) {
+ canvas_item_editor->update();
- tool = TOOL_NONE;
- copydata.clear();
+ return true;
+ }
- canvas_item_editor->update();
+ if (tool == TOOL_DUPLICATING) {
- return true;
- }
+ tool = TOOL_NONE;
+ copydata.clear();
- if (tool == TOOL_NONE) {
+ canvas_item_editor->update();
- paint_undo.clear();
+ return true;
+ }
- Point2 local = node->world_to_map(xform_inv.xform(Point2(mb.x, mb.y)));
+ if (tool == TOOL_NONE) {
- if (mb.mod.shift) {
+ paint_undo.clear();
- if (mb.mod.control)
- tool = TOOL_RECTANGLE_ERASE;
- else
- tool = TOOL_LINE_ERASE;
+ Point2 local = node->world_to_map(xform_inv.xform(mb->get_position()));
- selection_active = false;
- rectangle_begin = local;
- } else {
+ if (mb->get_shift()) {
- tool = TOOL_ERASING;
+ if (mb->get_control())
+ tool = TOOL_RECTANGLE_ERASE;
+ else
+ tool = TOOL_LINE_ERASE;
- paint_undo[local] = _get_op_from_cell(local);
- _set_cell(local, TileMap::INVALID_CELL);
- }
+ selection_active = false;
+ rectangle_begin = local;
+ } else {
- return true;
+ tool = TOOL_ERASING;
+
+ paint_undo[local] = _get_op_from_cell(local);
+ _set_cell(local, TileMap::INVALID_CELL);
}
- } else {
- if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
+ return true;
+ }
- if (paint_undo.size()) {
- undo_redo->create_action(TTR("Erase TileMap"));
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ } else {
+ if (tool == TOOL_ERASING || tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
- Point2 p = E->key();
- undo_redo->add_do_method(node, "set_cellv", p, TileMap::INVALID_CELL, false, false, false);
- undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
+ if (paint_undo.size()) {
+ undo_redo->create_action(TTR("Erase TileMap"));
+ for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
- undo_redo->commit_action();
- paint_undo.clear();
+ Point2 p = E->key();
+ undo_redo->add_do_method(node, "set_cellv", p, TileMap::INVALID_CELL, false, false, false);
+ undo_redo->add_undo_method(node, "set_cellv", p, E->get().idx, E->get().xf, E->get().yf, E->get().tr);
}
- if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
- canvas_item_editor->update();
- }
+ undo_redo->commit_action();
+ paint_undo.clear();
+ }
- tool = TOOL_NONE;
+ if (tool == TOOL_RECTANGLE_ERASE || tool == TOOL_LINE_ERASE) {
+ canvas_item_editor->update();
+ }
- return true;
+ tool = TOOL_NONE;
- } else if (tool == TOOL_BUCKET) {
+ return true;
- Dictionary pop;
- pop["id"] = node->get_cell(over_tile.x, over_tile.y);
- pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
- pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
- pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
+ } else if (tool == TOOL_BUCKET) {
- PoolVector<Vector2> points = _bucket_fill(over_tile, true);
+ Dictionary pop;
+ pop["id"] = node->get_cell(over_tile.x, over_tile.y);
+ pop["flip_h"] = node->is_cell_x_flipped(over_tile.x, over_tile.y);
+ pop["flip_v"] = node->is_cell_y_flipped(over_tile.x, over_tile.y);
+ pop["transpose"] = node->is_cell_transposed(over_tile.x, over_tile.y);
- if (points.size() == 0)
- return false;
+ PoolVector<Vector2> points = _bucket_fill(over_tile, true);
- undo_redo->create_action("Bucket Fill");
+ if (points.size() == 0)
+ return false;
- undo_redo->add_do_method(this, "_erase_points", points);
- undo_redo->add_undo_method(this, "_fill_points", points, pop);
+ undo_redo->create_action("Bucket Fill");
- undo_redo->commit_action();
- }
+ undo_redo->add_do_method(this, "_erase_points", points);
+ undo_redo->add_undo_method(this, "_fill_points", points, pop);
+
+ undo_redo->commit_action();
}
}
- } break;
- case InputEvent::MOUSE_MOTION: {
+ }
+ }
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ Ref<InputEventMouseMotion> mm = p_event;
- Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x, mm.y)));
+ if (mm.is_valid()) {
- if (new_over_tile != over_tile) {
+ Point2i new_over_tile = node->world_to_map(xform_inv.xform(mm->get_position()));
- over_tile = new_over_tile;
- canvas_item_editor->update();
- }
+ if (new_over_tile != over_tile) {
- int tile_under = node->get_cell(over_tile.x, over_tile.y);
- String tile_name = "none";
+ over_tile = new_over_tile;
+ canvas_item_editor->update();
+ }
- if (node->get_tileset()->has_tile(tile_under))
- tile_name = node->get_tileset()->tile_get_name(tile_under);
- tile_info->set_text(String::num(over_tile.x) + ", " + String::num(over_tile.y) + " [" + tile_name + "]");
+ int tile_under = node->get_cell(over_tile.x, over_tile.y);
+ String tile_name = "none";
- if (tool == TOOL_PAINTING) {
+ if (node->get_tileset()->has_tile(tile_under))
+ tile_name = node->get_tileset()->tile_get_name(tile_under);
+ tile_info->set_text(String::num(over_tile.x) + ", " + String::num(over_tile.y) + " [" + tile_name + "]");
- int id = get_selected_tile();
- if (id != TileMap::INVALID_CELL) {
+ if (tool == TOOL_PAINTING) {
- if (!paint_undo.has(over_tile)) {
- paint_undo[over_tile] = _get_op_from_cell(over_tile);
- }
-
- _set_cell(over_tile, id, flip_h, flip_v, transpose);
+ int id = get_selected_tile();
+ if (id != TileMap::INVALID_CELL) {
- return true;
+ if (!paint_undo.has(over_tile)) {
+ paint_undo[over_tile] = _get_op_from_cell(over_tile);
}
- }
- if (tool == TOOL_SELECTING) {
-
- _select(rectangle_begin, over_tile);
+ _set_cell(over_tile, id, flip_h, flip_v, transpose);
return true;
}
+ }
- if (tool == TOOL_LINE_PAINT || tool == TOOL_LINE_ERASE) {
+ if (tool == TOOL_SELECTING) {
- int id = get_selected_tile();
- bool erasing = (tool == TOOL_LINE_ERASE);
+ _select(rectangle_begin, over_tile);
- if (erasing && paint_undo.size()) {
+ return true;
+ }
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ if (tool == TOOL_LINE_PAINT || tool == TOOL_LINE_ERASE) {
- _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
- }
+ int id = get_selected_tile();
+ bool erasing = (tool == TOOL_LINE_ERASE);
- paint_undo.clear();
+ if (erasing && paint_undo.size()) {
+
+ for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+
+ _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
+ }
+ }
- if (id != TileMap::INVALID_CELL) {
+ paint_undo.clear();
- Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);
+ if (id != TileMap::INVALID_CELL) {
- for (int i = 0; i < points.size(); i++) {
+ Vector<Point2i> points = line(rectangle_begin.x, over_tile.x, rectangle_begin.y, over_tile.y);
- paint_undo[points[i]] = _get_op_from_cell(points[i]);
+ for (int i = 0; i < points.size(); i++) {
- if (erasing)
- _set_cell(points[i], TileMap::INVALID_CELL);
- }
+ paint_undo[points[i]] = _get_op_from_cell(points[i]);
- canvas_item_editor->update();
+ if (erasing)
+ _set_cell(points[i], TileMap::INVALID_CELL);
}
- return true;
+ canvas_item_editor->update();
}
- if (tool == TOOL_RECTANGLE_PAINT || tool == TOOL_RECTANGLE_ERASE) {
- _select(rectangle_begin, over_tile);
+ return true;
+ }
+ if (tool == TOOL_RECTANGLE_PAINT || tool == TOOL_RECTANGLE_ERASE) {
- if (tool == TOOL_RECTANGLE_ERASE) {
+ _select(rectangle_begin, over_tile);
- if (paint_undo.size()) {
+ if (tool == TOOL_RECTANGLE_ERASE) {
- for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+ if (paint_undo.size()) {
- _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
- }
+ for (Map<Point2i, CellOp>::Element *E = paint_undo.front(); E; E = E->next()) {
+
+ _set_cell(E->key(), E->get().idx, E->get().xf, E->get().yf, E->get().tr);
}
+ }
- paint_undo.clear();
+ paint_undo.clear();
- for (int i = rectangle.pos.y; i <= rectangle.pos.y + rectangle.size.y; i++) {
- for (int j = rectangle.pos.x; j <= rectangle.pos.x + rectangle.size.x; j++) {
+ for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
+ for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
- Point2i tile = Point2i(j, i);
- paint_undo[tile] = _get_op_from_cell(tile);
+ Point2i tile = Point2i(j, i);
+ paint_undo[tile] = _get_op_from_cell(tile);
- _set_cell(tile, TileMap::INVALID_CELL);
- }
+ _set_cell(tile, TileMap::INVALID_CELL);
}
}
-
- return true;
}
- if (tool == TOOL_ERASING) {
-
- if (!paint_undo.has(over_tile)) {
- paint_undo[over_tile] = _get_op_from_cell(over_tile);
- }
- _set_cell(over_tile, TileMap::INVALID_CELL);
+ return true;
+ }
+ if (tool == TOOL_ERASING) {
- return true;
+ if (!paint_undo.has(over_tile)) {
+ paint_undo[over_tile] = _get_op_from_cell(over_tile);
}
- if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
- _pick_tile(over_tile);
+ _set_cell(over_tile, TileMap::INVALID_CELL);
- return true;
- }
- } break;
- case InputEvent::KEY: {
+ return true;
+ }
+ if (tool == TOOL_PICKING && Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
- const InputEventKey &k = p_event.key;
+ _pick_tile(over_tile);
- if (!k.pressed)
- break;
+ return true;
+ }
+ }
- if (k.scancode == KEY_ESCAPE) {
+ Ref<InputEventKey> k = p_event;
- if (tool == TOOL_DUPLICATING)
- copydata.clear();
- else if (tool == TOOL_SELECTING || selection_active)
- selection_active = false;
+ if (k.is_valid() && k->is_pressed()) {
- tool = TOOL_NONE;
+ if (k->get_scancode() == KEY_ESCAPE) {
- canvas_item_editor->update();
+ if (tool == TOOL_DUPLICATING)
+ copydata.clear();
+ else if (tool == TOOL_SELECTING || selection_active)
+ selection_active = false;
- return true;
- }
+ tool = TOOL_NONE;
- if (tool != TOOL_NONE || !mouse_over)
- return false;
+ canvas_item_editor->update();
- if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) {
- _menu_option(OPTION_ERASE_SELECTION);
+ return true;
+ }
- return true;
- }
- if (ED_IS_SHORTCUT("tile_map_editor/select", p_event)) {
- tool = TOOL_SELECTING;
- selection_active = false;
+ if (tool != TOOL_NONE || !mouse_over)
+ return false;
- canvas_item_editor->update();
+ if (ED_IS_SHORTCUT("tile_map_editor/erase_selection", p_event)) {
+ _menu_option(OPTION_ERASE_SELECTION);
- return true;
- }
- if (ED_IS_SHORTCUT("tile_map_editor/duplicate_selection", p_event)) {
- _update_copydata();
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/select", p_event)) {
+ tool = TOOL_SELECTING;
+ selection_active = false;
- if (selection_active) {
- tool = TOOL_DUPLICATING;
+ canvas_item_editor->update();
- canvas_item_editor->update();
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/duplicate_selection", p_event)) {
+ _update_copydata();
- return true;
- }
- }
- if (ED_IS_SHORTCUT("tile_map_editor/find_tile", p_event)) {
- search_box->select_all();
- search_box->grab_focus();
+ if (selection_active) {
+ tool = TOOL_DUPLICATING;
- return true;
- }
- if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) {
- flip_h = !flip_h;
- mirror_x->set_pressed(flip_h);
- canvas_item_editor->update();
- return true;
- }
- if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) {
- flip_v = !flip_v;
- mirror_y->set_pressed(flip_v);
- canvas_item_editor->update();
- return true;
- }
- if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) {
- transpose = !transpose;
- transp->set_pressed(transpose);
canvas_item_editor->update();
+
return true;
}
- } break;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/find_tile", p_event)) {
+ search_box->select_all();
+ search_box->grab_focus();
+
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/mirror_x", p_event)) {
+ flip_h = !flip_h;
+ mirror_x->set_pressed(flip_h);
+ canvas_item_editor->update();
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/mirror_y", p_event)) {
+ flip_v = !flip_v;
+ mirror_y->set_pressed(flip_v);
+ canvas_item_editor->update();
+ return true;
+ }
+ if (ED_IS_SHORTCUT("tile_map_editor/transpose", p_event)) {
+ transpose = !transpose;
+ transp->set_pressed(transpose);
+ canvas_item_editor->update();
+ return true;
+ }
}
return false;
@@ -1106,7 +1103,7 @@ void TileMapEditor::_canvas_draw() {
Size2 screen_size = canvas_item_editor->get_size();
{
Rect2 aabb;
- aabb.pos = node->world_to_map(xform_inv.xform(Vector2()));
+ aabb.position = node->world_to_map(xform_inv.xform(Vector2()));
aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0, screen_size.height))));
aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width, 0))));
aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size)));
@@ -1116,10 +1113,10 @@ void TileMapEditor::_canvas_draw() {
int max_lines = 2000; //avoid crash if size too smal
- for (int i = (si.pos.x) - 1; i <= (si.pos.x + si.size.x); i++) {
+ for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
- Vector2 from = xform.xform(node->map_to_world(Vector2(i, si.pos.y)));
- Vector2 to = xform.xform(node->map_to_world(Vector2(i, si.pos.y + si.size.y + 1)));
+ Vector2 from = xform.xform(node->map_to_world(Vector2(i, si.position.y)));
+ Vector2 to = xform.xform(node->map_to_world(Vector2(i, si.position.y + si.size.y + 1)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
canvas_item_editor->draw_line(from, to, col, 1);
@@ -1130,9 +1127,9 @@ void TileMapEditor::_canvas_draw() {
int max_lines = 10000; //avoid crash if size too smal
- for (int i = (si.pos.x) - 1; i <= (si.pos.x + si.size.x); i++) {
+ for (int i = (si.position.x) - 1; i <= (si.position.x + si.size.x); i++) {
- for (int j = (si.pos.y) - 1; j <= (si.pos.y + si.size.y); j++) {
+ for (int j = (si.position.y) - 1; j <= (si.position.y + si.size.y); j++) {
Vector2 ofs;
if (ABS(j) & 1) {
@@ -1154,10 +1151,10 @@ void TileMapEditor::_canvas_draw() {
if (node->get_half_offset() != TileMap::HALF_OFFSET_Y) {
- for (int i = (si.pos.y) - 1; i <= (si.pos.y + si.size.y); i++) {
+ for (int i = (si.position.y) - 1; i <= (si.position.y + si.size.y); i++) {
- Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x, i)));
- Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x + si.size.x + 1, i)));
+ Vector2 from = xform.xform(node->map_to_world(Vector2(si.position.x, i)));
+ Vector2 to = xform.xform(node->map_to_world(Vector2(si.position.x + si.size.x + 1, i)));
Color col = i == 0 ? Color(1, 0.8, 0.2, 0.5) : Color(1, 0.3, 0.1, 0.2);
canvas_item_editor->draw_line(from, to, col, 1);
@@ -1167,9 +1164,9 @@ void TileMapEditor::_canvas_draw() {
}
} else {
- for (int i = (si.pos.y) - 1; i <= (si.pos.y + si.size.y); i++) {
+ for (int i = (si.position.y) - 1; i <= (si.position.y + si.size.y); i++) {
- for (int j = (si.pos.x) - 1; j <= (si.pos.x + si.size.x); j++) {
+ for (int j = (si.position.x) - 1; j <= (si.position.x + si.size.x); j++) {
Vector2 ofs;
if (ABS(j) & 1) {
@@ -1191,10 +1188,10 @@ void TileMapEditor::_canvas_draw() {
if (selection_active) {
Vector<Vector2> points;
- points.push_back(xform.xform(node->map_to_world((rectangle.pos))));
- points.push_back(xform.xform(node->map_to_world((rectangle.pos + Point2(rectangle.size.x + 1, 0)))));
- points.push_back(xform.xform(node->map_to_world((rectangle.pos + Point2(rectangle.size.x + 1, rectangle.size.y + 1)))));
- points.push_back(xform.xform(node->map_to_world((rectangle.pos + Point2(0, rectangle.size.y + 1)))));
+ points.push_back(xform.xform(node->map_to_world((rectangle.position))));
+ points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(rectangle.size.x + 1, 0)))));
+ points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(rectangle.size.x + 1, rectangle.size.y + 1)))));
+ points.push_back(xform.xform(node->map_to_world((rectangle.position + Point2(0, rectangle.size.y + 1)))));
canvas_item_editor->draw_colored_polygon(points, Color(0.2, 0.8, 1, 0.4));
}
@@ -1251,8 +1248,8 @@ void TileMapEditor::_canvas_draw() {
if (id == TileMap::INVALID_CELL)
return;
- for (int i = rectangle.pos.y; i <= rectangle.pos.y + rectangle.size.y; i++) {
- for (int j = rectangle.pos.x; j <= rectangle.pos.x + rectangle.size.x; j++) {
+ for (int i = rectangle.position.y; i <= rectangle.position.y + rectangle.size.y; i++) {
+ for (int j = rectangle.position.x; j <= rectangle.position.x + rectangle.size.x; j++) {
_draw_cell(id, Point2i(j, i), flip_h, flip_v, transpose, xform);
}
@@ -1267,7 +1264,7 @@ void TileMapEditor::_canvas_draw() {
if (ts.is_null())
return;
- Point2 ofs = over_tile - rectangle.pos;
+ Point2 ofs = over_tile - rectangle.position;
for (List<TileData>::Element *E = copydata.front(); E; E = E->next()) {
@@ -1280,13 +1277,13 @@ void TileMapEditor::_canvas_draw() {
}
Rect2i duplicate = rectangle;
- duplicate.pos = over_tile;
+ duplicate.position = over_tile;
Vector<Vector2> points;
- points.push_back(xform.xform(node->map_to_world(duplicate.pos)));
- points.push_back(xform.xform(node->map_to_world((duplicate.pos + Point2(duplicate.size.x + 1, 0)))));
- points.push_back(xform.xform(node->map_to_world((duplicate.pos + Point2(duplicate.size.x + 1, duplicate.size.y + 1)))));
- points.push_back(xform.xform(node->map_to_world((duplicate.pos + Point2(0, duplicate.size.y + 1)))));
+ points.push_back(xform.xform(node->map_to_world(duplicate.position)));
+ points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(duplicate.size.x + 1, 0)))));
+ points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(duplicate.size.x + 1, duplicate.size.y + 1)))));
+ points.push_back(xform.xform(node->map_to_world((duplicate.position + Point2(0, duplicate.size.y + 1)))));
canvas_item_editor->draw_colored_polygon(points, Color(0.2, 1.0, 0.8, 0.2));
diff --git a/editor/plugins/tile_map_editor_plugin.h b/editor/plugins/tile_map_editor_plugin.h
index 3eedb6c941..981d5c66a1 100644
--- a/editor/plugins/tile_map_editor_plugin.h
+++ b/editor/plugins/tile_map_editor_plugin.h
@@ -158,7 +158,7 @@ class TileMapEditor : public VBoxContainer {
void _text_entered(const String &p_text);
void _text_changed(const String &p_text);
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _update_palette();
void _canvas_draw();
void _menu_option(int p_option);
@@ -179,7 +179,7 @@ protected:
public:
HBoxContainer *get_toolbar() const { return toolbar; }
- bool forward_gui_input(const InputEvent &p_event);
+ bool forward_gui_input(const Ref<InputEvent> &p_event);
void edit(Node *p_tile_map);
TileMapEditor(EditorNode *p_editor);
@@ -193,7 +193,7 @@ class TileMapEditorPlugin : public EditorPlugin {
TileMapEditor *tile_map_editor;
public:
- virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const InputEvent &p_event) { return tile_map_editor->forward_gui_input(p_event); }
+ virtual bool forward_canvas_gui_input(const Transform2D &p_canvas_xform, const Ref<InputEvent> &p_event) { return tile_map_editor->forward_gui_input(p_event); }
virtual String get_name() const { return "TileMap"; }
bool has_main_screen() const { return false; }
diff --git a/editor/plugins/tile_set_editor_plugin.cpp b/editor/plugins/tile_set_editor_plugin.cpp
index e79cbd0d35..0b088f7171 100644
--- a/editor/plugins/tile_set_editor_plugin.cpp
+++ b/editor/plugins/tile_set_editor_plugin.cpp
@@ -37,24 +37,18 @@ void TileSetEditor::edit(const Ref<TileSet> &p_tileset) {
tileset = p_tileset;
}
-void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_merge) {
-
- if (!p_merge)
- p_library->clear();
+void TileSetEditor::_import_node(Node *p_node, Ref<TileSet> p_library) {
- for (int i = 0; i < scene->get_child_count(); i++) {
+ for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *child = scene->get_child(i);
+ Node *child = p_node->get_child(i);
if (!child->cast_to<Sprite>()) {
if (child->get_child_count() > 0) {
- child = child->get_child(0);
- if (!child->cast_to<Sprite>()) {
- continue;
- }
+ _import_node(child, p_library);
+ }
- } else
- continue;
+ continue;
}
Sprite *mi = child->cast_to<Sprite>();
@@ -138,6 +132,14 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
}
}
+void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_merge) {
+
+ if (!p_merge)
+ p_library->clear();
+
+ _import_node(scene, p_library);
+}
+
void TileSetEditor::_menu_confirm() {
switch (option) {
diff --git a/editor/plugins/tile_set_editor_plugin.h b/editor/plugins/tile_set_editor_plugin.h
index 42084c05a3..d04ebc7197 100644
--- a/editor/plugins/tile_set_editor_plugin.h
+++ b/editor/plugins/tile_set_editor_plugin.h
@@ -59,6 +59,7 @@ class TileSetEditor : public Control {
void _menu_confirm();
void _name_dialog_confirm(const String &name);
+ static void _import_node(Node *p_node, Ref<TileSet> p_library);
static void _import_scene(Node *p_scene, Ref<TileSet> p_library, bool p_merge);
protected:
diff --git a/editor/project_export.cpp b/editor/project_export.cpp
index 90db23d236..d58454a223 100644
--- a/editor/project_export.cpp
+++ b/editor/project_export.cpp
@@ -229,6 +229,8 @@ void ProjectExportDialog::_edit_preset(int p_index) {
}
if (needs_templates)
export_templates_error->show();
+ else
+ export_templates_error->hide();
export_button->set_disabled(true);
@@ -752,6 +754,7 @@ ProjectExportDialog::ProjectExportDialog() {
settings_vb->add_child(runnable);
sections = memnew(TabContainer);
+ sections->set_tab_align(TabContainer::ALIGN_LEFT);
settings_vb->add_child(sections);
sections->set_v_size_flags(SIZE_EXPAND_FILL);
diff --git a/editor/project_manager.cpp b/editor/project_manager.cpp
index 289655e9da..a3d3d42110 100644
--- a/editor/project_manager.cpp
+++ b/editor/project_manager.cpp
@@ -203,10 +203,23 @@ private:
f->store_line("\n");
f->store_line("name=\"" + project_name->get_text() + "\"");
f->store_line("icon=\"res://icon.png\"");
-
+ f->store_line("[rendering]");
+ f->store_line("viewport/default_environment=\"res://default_env.tres\"");
memdelete(f);
ResourceSaver::save(dir.plus_file("/icon.png"), get_icon("DefaultProjectIcon", "EditorIcons"));
+
+ f = FileAccess::open(dir.plus_file("/default_env.tres"), FileAccess::WRITE);
+ if (!f) {
+ error->set_text(TTR("Couldn't create project.godot in project path."));
+ } else {
+ f->store_line("[gd_resource type=\"Environment\" load_steps=2 format=2]");
+ f->store_line("[sub_resource type=\"ProceduralSky\" id=1]");
+ f->store_line("[resource]");
+ f->store_line("background_mode = 2");
+ f->store_line("background_sky = SubResource( 1 )");
+ memdelete(f);
+ }
}
} else if (mode == MODE_INSTALL) {
@@ -503,14 +516,16 @@ void ProjectManager::_update_project_buttons() {
run_btn->set_disabled(!has_runnable_scene);
}
-void ProjectManager::_panel_input(const InputEvent &p_ev, Node *p_hb) {
+void ProjectManager::_panel_input(const Ref<InputEvent> &p_ev, Node *p_hb) {
+
+ Ref<InputEventMouseButton> mb = p_ev;
- if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index == BUTTON_LEFT) {
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
String clicked = p_hb->get_meta("name");
String clicked_main_scene = p_hb->get_meta("main_scene");
- if (p_ev.key.mod.shift && selected_list.size() > 0 && last_clicked != "" && clicked != last_clicked) {
+ if (mb->get_shift() && selected_list.size() > 0 && last_clicked != "" && clicked != last_clicked) {
int clicked_id = -1;
int last_clicked_id = -1;
@@ -527,7 +542,7 @@ void ProjectManager::_panel_input(const InputEvent &p_ev, Node *p_hb) {
for (int i = 0; i < scroll_childs->get_child_count(); ++i) {
HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>();
if (!hb) continue;
- if (i != clicked_id && (i < min || i > max) && !p_ev.key.mod.control) {
+ if (i != clicked_id && (i < min || i > max) && !mb->get_control()) {
selected_list.erase(hb->get_meta("name"));
} else if (i >= min && i <= max) {
selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
@@ -535,14 +550,14 @@ void ProjectManager::_panel_input(const InputEvent &p_ev, Node *p_hb) {
}
}
- } else if (selected_list.has(clicked) && p_ev.key.mod.control) {
+ } else if (selected_list.has(clicked) && mb->get_control()) {
selected_list.erase(clicked);
} else {
last_clicked = clicked;
- if (p_ev.key.mod.control || selected_list.size() == 0) {
+ if (mb->get_control() || selected_list.size() == 0) {
selected_list.insert(clicked, clicked_main_scene);
} else {
selected_list.clear();
@@ -552,23 +567,23 @@ void ProjectManager::_panel_input(const InputEvent &p_ev, Node *p_hb) {
_update_project_buttons();
- if (p_ev.mouse_button.doubleclick)
+ if (mb->is_doubleclick())
_open_project(); //open if doubleclicked
}
}
-void ProjectManager::_unhandled_input(const InputEvent &p_ev) {
+void ProjectManager::_unhandled_input(const Ref<InputEvent> &p_ev) {
- if (p_ev.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_ev;
- const InputEventKey &k = p_ev.key;
+ if (k.is_valid()) {
- if (!k.pressed)
+ if (!k->is_pressed())
return;
bool scancode_handled = true;
- switch (k.scancode) {
+ switch (k->get_scancode()) {
case KEY_RETURN: {
@@ -606,7 +621,7 @@ void ProjectManager::_unhandled_input(const InputEvent &p_ev) {
} break;
case KEY_UP: {
- if (k.mod.shift)
+ if (k->get_shift())
break;
if (selected_list.size()) {
@@ -645,7 +660,7 @@ void ProjectManager::_unhandled_input(const InputEvent &p_ev) {
}
case KEY_DOWN: {
- if (k.mod.shift)
+ if (k->get_shift())
break;
bool found = selected_list.empty();
@@ -679,7 +694,7 @@ void ProjectManager::_unhandled_input(const InputEvent &p_ev) {
} break;
case KEY_F: {
- if (k.mod.command)
+ if (k->get_command())
this->project_filter->search_box->grab_focus();
else
scancode_handled = false;
@@ -806,11 +821,12 @@ void ProjectManager::_load_recent_projects() {
if (cf->has_section_key("application", "icon")) {
String appicon = cf->get_value("application", "icon");
if (appicon != "") {
- Image img;
- Error err = img.load(appicon.replace_first("res://", path + "/"));
+ Ref<Image> img;
+ img.instance();
+ Error err = img->load(appicon.replace_first("res://", path + "/"));
if (err == OK) {
- img.resize(64, 64);
+ img->resize(64, 64);
Ref<ImageTexture> it = memnew(ImageTexture);
it->create_from_image(img);
icon = it;
@@ -898,8 +914,9 @@ void ProjectManager::_on_project_created(const String &dir) {
_update_scroll_pos(dir);
} else {
_load_recent_projects();
- scroll->connect("draw", this, "_update_scroll_pos", varray(dir), CONNECT_ONESHOT);
+ _update_scroll_pos(dir);
}
+ _open_project();
}
void ProjectManager::_update_scroll_pos(const String &dir) {
@@ -1453,7 +1470,7 @@ ProjectListFilter::ProjectListFilter() {
_current_filter = FILTER_NAME;
filter_option = memnew(OptionButton);
- filter_option->set_custom_minimum_size(Size2(80, 10));
+ filter_option->set_custom_minimum_size(Size2(80 * EDSCALE, 10 * EDSCALE));
filter_option->set_clip_text(true);
filter_option->connect("item_selected", this, "_filter_option_selected");
add_child(filter_option);
diff --git a/editor/project_manager.h b/editor/project_manager.h
index 5be28ce2f0..27886132c5 100644
--- a/editor/project_manager.h
+++ b/editor/project_manager.h
@@ -91,8 +91,8 @@ class ProjectManager : public Control {
void _install_project(const String &p_zip_path, const String &p_title);
void _panel_draw(Node *p_hb);
- void _panel_input(const InputEvent &p_ev, Node *p_hb);
- void _unhandled_input(const InputEvent &p_ev);
+ void _panel_input(const Ref<InputEvent> &p_ev, Node *p_hb);
+ void _unhandled_input(const Ref<InputEvent> &p_ev);
void _favorite_pressed(Node *p_hb);
void _files_dropped(PoolStringArray p_files, int p_screen);
void _scan_multiple_folders(PoolStringArray p_files);
diff --git a/editor/project_settings.cpp b/editor/project_settings.cpp
index 5795e41b92..8ef7bd427f 100644
--- a/editor/project_settings.cpp
+++ b/editor/project_settings.cpp
@@ -78,15 +78,15 @@ void ProjectSettings::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
globals_editor->edit(GlobalConfig::get_singleton());
- search_button->set_icon(get_icon("Search", "EditorIcons"));
+ search_button->set_icon(get_icon("Zoom", "EditorIcons"));
clear_button->set_icon(get_icon("Close", "EditorIcons"));
translation_list->connect("button_pressed", this, "_translation_delete");
_update_actions();
- popup_add->add_icon_item(get_icon("Keyboard", "EditorIcons"), TTR("Key "), InputEvent::KEY); //"Key " - because the word 'key' has already been used as a key animation
- popup_add->add_icon_item(get_icon("JoyButton", "EditorIcons"), TTR("Joy Button"), InputEvent::JOYPAD_BUTTON);
- popup_add->add_icon_item(get_icon("JoyAxis", "EditorIcons"), TTR("Joy Axis"), InputEvent::JOYPAD_MOTION);
- popup_add->add_icon_item(get_icon("Mouse", "EditorIcons"), TTR("Mouse Button"), InputEvent::MOUSE_BUTTON);
+ popup_add->add_icon_item(get_icon("Keyboard", "EditorIcons"), TTR("Key "), INPUT_KEY); //"Key " - because the word 'key' has already been used as a key animation
+ popup_add->add_icon_item(get_icon("JoyButton", "EditorIcons"), TTR("Joy Button"), INPUT_JOY_BUTTON);
+ popup_add->add_icon_item(get_icon("JoyAxis", "EditorIcons"), TTR("Joy Axis"), INPUT_JOY_MOTION);
+ popup_add->add_icon_item(get_icon("Mouse", "EditorIcons"), TTR("Mouse Button"), INPUT_MOUSE_BUTTON);
List<String> tfn;
ResourceLoader::get_recognized_extensions_for_type("Translation", &tfn);
@@ -106,6 +106,9 @@ void ProjectSettings::_notification(int p_what) {
case NOTIFICATION_POPUP_HIDE: {
EditorSettings::get_singleton()->set("interface/dialogs/project_settings_bounds", get_rect());
} break;
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ _update_actions();
+ } break;
}
}
@@ -175,54 +178,74 @@ void ProjectSettings::_action_edited() {
void ProjectSettings::_device_input_add() {
- InputEvent ie;
+ Ref<InputEvent> ie;
String name = add_at;
Variant old_val = GlobalConfig::get_singleton()->get(name);
Array arr = old_val;
- ie.device = device_id->get_value();
-
- ie.type = add_type;
+ // ie.device = device_id->get_value();
+ // ie.type = add_type;
switch (add_type) {
- case InputEvent::MOUSE_BUTTON: {
+ case INPUT_MOUSE_BUTTON: {
- ie.mouse_button.button_index = device_index->get_selected() + 1;
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ mb->set_button_index(device_index->get_selected() + 1);
+ mb->set_device(device_id->get_value());
for (int i = 0; i < arr.size(); i++) {
- InputEvent aie = arr[i];
- if (aie.device == ie.device && aie.type == InputEvent::MOUSE_BUTTON && aie.mouse_button.button_index == ie.mouse_button.button_index) {
+ Ref<InputEventMouseButton> aie = arr[i];
+ if (aie.is_null())
+ continue;
+ if (aie->get_device() == mb->get_device() && aie->get_button_index() == mb->get_button_index()) {
return;
}
}
+ ie = mb;
+
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case INPUT_JOY_MOTION: {
- ie.joy_motion.axis = device_index->get_selected() >> 1;
- ie.joy_motion.axis_value = device_index->get_selected() & 1 ? 1 : -1;
+ Ref<InputEventJoypadMotion> jm;
+ jm.instance();
+ jm->set_axis(device_index->get_selected() >> 1);
+ jm->set_axis_value(device_index->get_selected() & 1 ? 1 : -1);
+ jm->set_device(device_id->get_value());
for (int i = 0; i < arr.size(); i++) {
- InputEvent aie = arr[i];
- if (aie.device == ie.device && aie.type == InputEvent::JOYPAD_MOTION && aie.joy_motion.axis == ie.joy_motion.axis && aie.joy_motion.axis_value == ie.joy_motion.axis_value) {
+ Ref<InputEventJoypadMotion> aie = arr[i];
+ if (aie.is_null())
+ continue;
+ if (aie->get_device() == jm->get_device() && aie->get_axis() == jm->get_axis() && aie->get_axis_value() == jm->get_axis_value()) {
return;
}
}
+ ie = jm;
+
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case INPUT_JOY_BUTTON: {
+
+ Ref<InputEventJoypadButton> jb;
+ jb.instance();
- ie.joy_button.button_index = device_index->get_selected();
+ jb->set_button_index(device_index->get_selected());
+ jb->set_device(device_id->get_value());
for (int i = 0; i < arr.size(); i++) {
- InputEvent aie = arr[i];
- if (aie.device == ie.device && aie.type == InputEvent::JOYPAD_BUTTON && aie.joy_button.button_index == ie.joy_button.button_index) {
+ Ref<InputEventJoypadButton> aie = arr[i];
+ if (aie.is_null())
+ continue;
+ if (aie->get_device() == jb->get_device() && aie->get_button_index() == jb->get_button_index()) {
return;
}
}
+ ie = jb;
} break;
default: {}
@@ -244,13 +267,17 @@ void ProjectSettings::_device_input_add() {
void ProjectSettings::_press_a_key_confirm() {
- if (last_wait_for_key.type != InputEvent::KEY)
+ if (last_wait_for_key.is_null())
return;
- InputEvent ie;
- ie.type = InputEvent::KEY;
- ie.key.scancode = last_wait_for_key.key.scancode;
- ie.key.mod = last_wait_for_key.key.mod;
+ Ref<InputEventKey> ie;
+ ie.instance();
+ ie->set_scancode(last_wait_for_key->get_scancode());
+ ie->set_shift(last_wait_for_key->get_shift());
+ ie->set_alt(last_wait_for_key->get_alt());
+ ie->set_control(last_wait_for_key->get_control());
+ ie->set_metakey(last_wait_for_key->get_metakey());
+
String name = add_at;
Variant old_val = GlobalConfig::get_singleton()->get(name);
@@ -258,8 +285,10 @@ void ProjectSettings::_press_a_key_confirm() {
for (int i = 0; i < arr.size(); i++) {
- InputEvent aie = arr[i];
- if (aie.type == InputEvent::KEY && aie.key.scancode == ie.key.scancode && aie.key.mod == ie.key.mod) {
+ Ref<InputEventKey> aie = arr[i];
+ if (aie.is_null())
+ continue;
+ if (aie->get_scancode_with_modifiers() == ie->get_scancode_with_modifiers()) {
return;
}
}
@@ -278,7 +307,7 @@ void ProjectSettings::_press_a_key_confirm() {
_show_last_added(ie, name);
}
-void ProjectSettings::_show_last_added(const InputEvent &p_event, const String &p_name) {
+void ProjectSettings::_show_last_added(const Ref<InputEvent> &p_event, const String &p_name) {
TreeItem *r = input_editor->get_root();
String name = p_name;
@@ -311,19 +340,21 @@ void ProjectSettings::_show_last_added(const InputEvent &p_event, const String &
if (found) input_editor->ensure_cursor_is_visible();
}
-void ProjectSettings::_wait_for_key(const InputEvent &p_event) {
+void ProjectSettings::_wait_for_key(const Ref<InputEvent> &p_event) {
+
+ Ref<InputEventKey> k = p_event;
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode != 0) {
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() != 0) {
last_wait_for_key = p_event;
- String str = keycode_get_string(p_event.key.scancode).capitalize();
- if (p_event.key.mod.meta)
+ String str = keycode_get_string(k->get_scancode()).capitalize();
+ if (k->get_metakey())
str = TTR("Meta+") + str;
- if (p_event.key.mod.shift)
+ if (k->get_shift())
str = TTR("Shift+") + str;
- if (p_event.key.mod.alt)
+ if (k->get_alt())
str = TTR("Alt+") + str;
- if (p_event.key.mod.control)
+ if (k->get_control())
str = TTR("Control+") + str;
press_a_key_label->set_text(str);
@@ -333,18 +364,18 @@ void ProjectSettings::_wait_for_key(const InputEvent &p_event) {
void ProjectSettings::_add_item(int p_item) {
- add_type = InputEvent::Type(p_item);
+ add_type = InputType(p_item);
switch (add_type) {
- case InputEvent::KEY: {
+ case INPUT_KEY: {
press_a_key_label->set_text(TTR("Press a Key.."));
- last_wait_for_key = InputEvent();
+ last_wait_for_key = Ref<InputEvent>();
press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
press_a_key->grab_focus();
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case INPUT_MOUSE_BUTTON: {
device_id->set_value(0);
device_index_label->set_text(TTR("Mouse Button Index:"));
@@ -360,7 +391,7 @@ void ProjectSettings::_add_item(int p_item) {
device_index->add_item(TTR("Button 9"));
device_input->popup_centered_minsize(Size2(350, 95));
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case INPUT_JOY_MOTION: {
device_id->set_value(0);
device_index_label->set_text(TTR("Joypad Axis Index:"));
@@ -373,7 +404,7 @@ void ProjectSettings::_add_item(int p_item) {
device_input->popup_centered_minsize(Size2(350, 95));
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case INPUT_JOY_BUTTON: {
device_id->set_value(0);
device_index_label->set_text(TTR("Joypad Button Index:"));
@@ -399,8 +430,8 @@ void ProjectSettings::_action_button_pressed(Object *p_obj, int p_column, int p_
if (p_id == 1) {
Point2 ofs = input_editor->get_global_position();
Rect2 ir = input_editor->get_item_rect(ti);
- ir.pos.y -= input_editor->get_scroll().y;
- ofs += ir.pos + ir.size;
+ ir.position.y -= input_editor->get_scroll().y;
+ ofs += ir.position + ir.size;
ofs.x -= 100;
popup_add->set_position(ofs);
popup_add->popup();
@@ -493,65 +524,70 @@ void ProjectSettings::_update_actions() {
for (int i = 0; i < actions.size(); i++) {
- if (actions[i].get_type() != Variant::INPUT_EVENT)
+ Ref<InputEvent> ie = actions[i];
+ if (ie.is_null())
continue;
- InputEvent ie = actions[i];
TreeItem *action = input_editor->create_item(item);
- switch (ie.type) {
-
- case InputEvent::KEY: {
-
- String str = keycode_get_string(ie.key.scancode).capitalize();
- if (ie.key.mod.meta)
- str = TTR("Meta+") + str;
- if (ie.key.mod.shift)
- str = TTR("Shift+") + str;
- if (ie.key.mod.alt)
- str = TTR("Alt+") + str;
- if (ie.key.mod.control)
- str = TTR("Control+") + str;
-
- action->set_text(0, str);
- action->set_icon(0, get_icon("Keyboard", "EditorIcons"));
-
- } break;
- case InputEvent::JOYPAD_BUTTON: {
-
- String str = TTR("Device") + " " + itos(ie.device) + ", " + TTR("Button") + " " + itos(ie.joy_button.button_index);
- if (ie.joy_button.button_index >= 0 && ie.joy_button.button_index < JOY_BUTTON_MAX)
- str += String() + " (" + _button_names[ie.joy_button.button_index] + ").";
- else
- str += ".";
-
- action->set_text(0, str);
- action->set_icon(0, get_icon("JoyButton", "EditorIcons"));
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- String str = TTR("Device") + " " + itos(ie.device) + ", ";
- switch (ie.mouse_button.button_index) {
- case BUTTON_LEFT: str += TTR("Left Button."); break;
- case BUTTON_RIGHT: str += TTR("Right Button."); break;
- case BUTTON_MIDDLE: str += TTR("Middle Button."); break;
- case BUTTON_WHEEL_UP: str += TTR("Wheel Up."); break;
- case BUTTON_WHEEL_DOWN: str += TTR("Wheel Down."); break;
- default: str += TTR("Button") + " " + itos(ie.mouse_button.button_index) + ".";
- }
-
- action->set_text(0, str);
- action->set_icon(0, get_icon("Mouse", "EditorIcons"));
- } break;
- case InputEvent::JOYPAD_MOTION: {
-
- int ax = ie.joy_motion.axis;
- int n = 2 * ax + (ie.joy_motion.axis_value < 0 ? 0 : 1);
- String desc = _axis_names[n];
- String str = TTR("Device") + " " + itos(ie.device) + ", " + TTR("Axis") + " " + itos(ax) + " " + (ie.joy_motion.axis_value < 0 ? "-" : "+") + desc + ".";
- action->set_text(0, str);
- action->set_icon(0, get_icon("JoyAxis", "EditorIcons"));
- } break;
+ Ref<InputEventKey> k = ie;
+ if (k.is_valid()) {
+
+ String str = keycode_get_string(k->get_scancode()).capitalize();
+ if (k->get_metakey())
+ str = TTR("Meta+") + str;
+ if (k->get_shift())
+ str = TTR("Shift+") + str;
+ if (k->get_alt())
+ str = TTR("Alt+") + str;
+ if (k->get_control())
+ str = TTR("Control+") + str;
+
+ action->set_text(0, str);
+ action->set_icon(0, get_icon("Keyboard", "EditorIcons"));
+ }
+
+ Ref<InputEventJoypadButton> jb = ie;
+
+ if (jb.is_valid()) {
+
+ String str = TTR("Device") + " " + itos(jb->get_device()) + ", " + TTR("Button") + " " + itos(jb->get_button_index());
+ if (jb->get_button_index() >= 0 && jb->get_button_index() < JOY_BUTTON_MAX)
+ str += String() + " (" + _button_names[jb->get_button_index()] + ").";
+ else
+ str += ".";
+
+ action->set_text(0, str);
+ action->set_icon(0, get_icon("JoyButton", "EditorIcons"));
+ }
+
+ Ref<InputEventMouseButton> mb = ie;
+
+ if (mb.is_valid()) {
+ String str = TTR("Device") + " " + itos(mb->get_device()) + ", ";
+ switch (mb->get_button_index()) {
+ case BUTTON_LEFT: str += TTR("Left Button."); break;
+ case BUTTON_RIGHT: str += TTR("Right Button."); break;
+ case BUTTON_MIDDLE: str += TTR("Middle Button."); break;
+ case BUTTON_WHEEL_UP: str += TTR("Wheel Up."); break;
+ case BUTTON_WHEEL_DOWN: str += TTR("Wheel Down."); break;
+ default: str += TTR("Button") + " " + itos(mb->get_button_index()) + ".";
+ }
+
+ action->set_text(0, str);
+ action->set_icon(0, get_icon("Mouse", "EditorIcons"));
+ }
+
+ Ref<InputEventJoypadMotion> jm = ie;
+
+ if (jm.is_valid()) {
+
+ int ax = jm->get_axis();
+ int n = 2 * ax + (jm->get_axis_value() < 0 ? 0 : 1);
+ String desc = _axis_names[n];
+ String str = TTR("Device") + " " + itos(jm->get_device()) + ", " + TTR("Axis") + " " + itos(ax) + " " + (jm->get_axis_value() < 0 ? "-" : "+") + desc + ".";
+ action->set_text(0, str);
+ action->set_icon(0, get_icon("JoyAxis", "EditorIcons"));
}
action->add_button(0, get_icon("Remove", "EditorIcons"), 2, false, TTR("Remove"));
action->set_metadata(0, i);
@@ -1174,6 +1210,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
data = p_data;
tab_container = memnew(TabContainer);
+ tab_container->set_tab_align(TabContainer::ALIGN_LEFT);
add_child(tab_container);
//set_child_rect(tab_container);
@@ -1264,7 +1301,6 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
//globals_editor->hide_top_label();
globals_editor->set_v_size_flags(Control::SIZE_EXPAND_FILL);
globals_editor->get_property_editor()->register_text_enter(search_box);
- globals_editor->get_property_editor()->set_enable_capitalize_paths(false);
globals_editor->get_property_editor()->get_scene_tree()->connect("cell_selected", this, "_item_selected");
globals_editor->get_property_editor()->connect("property_toggled", this, "_item_checked", varray(), CONNECT_DEFERRED);
globals_editor->get_property_editor()->connect("property_edited", this, "_settings_prop_edited");
@@ -1416,6 +1452,7 @@ ProjectSettings::ProjectSettings(EditorData *p_data) {
//translations
TabContainer *translations = memnew(TabContainer);
+ translations->set_tab_align(TabContainer::ALIGN_LEFT);
translations->set_name(TTR("Localization"));
tab_container->add_child(translations);
diff --git a/editor/project_settings.h b/editor/project_settings.h
index a5a9e04250..47fb45cf8e 100644
--- a/editor/project_settings.h
+++ b/editor/project_settings.h
@@ -43,10 +43,17 @@
class ProjectSettings : public AcceptDialog {
GDCLASS(ProjectSettings, AcceptDialog);
+ enum InputType {
+ INPUT_KEY,
+ INPUT_JOY_BUTTON,
+ INPUT_JOY_MOTION,
+ INPUT_MOUSE_BUTTON
+ };
+
TabContainer *tab_container;
Timer *timer;
- InputEvent::Type add_type;
+ InputType add_type;
String add_at;
EditorData *data;
@@ -77,7 +84,7 @@ class ProjectSettings : public AcceptDialog {
bool setting;
bool updating_translations;
- InputEvent last_wait_for_key;
+ Ref<InputEventKey> last_wait_for_key;
EditorFileDialog *translation_file_open;
Tree *translation_list;
@@ -108,9 +115,9 @@ class ProjectSettings : public AcceptDialog {
void _action_selected();
void _action_edited();
void _action_button_pressed(Object *p_obj, int p_column, int p_id);
- void _wait_for_key(const InputEvent &p_event);
+ void _wait_for_key(const Ref<InputEvent> &p_event);
void _press_a_key_confirm();
- void _show_last_added(const InputEvent &p_event, const String &p_name);
+ void _show_last_added(const Ref<InputEvent> &p_event, const String &p_name);
void _settings_prop_edited(const String &p_name);
void _settings_changed();
diff --git a/editor/property_editor.cpp b/editor/property_editor.cpp
index 5ff5e680f6..da26c84e45 100644
--- a/editor/property_editor.cpp
+++ b/editor/property_editor.cpp
@@ -65,6 +65,9 @@ void CustomPropertyEditor::_notification(int p_what) {
VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2( 10,10,60, get_size().height-20 ), v );
}*/
}
+ if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
+ hide();
+ }
}
void CustomPropertyEditor::_menu_option(int p_which) {
@@ -323,7 +326,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
c->show();
checks20gc->set_size(checks20gc->get_minimum_size());
- set_size(checks20gc->get_position() + checks20gc->get_size() + Vector2(4, 4) * EDSCALE);
+ set_size(checks20gc->get_position() + checks20gc->get_size() + c->get_size() + Vector2(4, 4) * EDSCALE);
} break;
case Variant::INT:
@@ -609,12 +612,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
type = Variant::Type(Variant::Type(i));
}
}
- InputEvent::Type iet = InputEvent::NONE;
- if (hint_text.find(".") != -1) {
- iet = InputEvent::Type(int(hint_text.get_slice(".", 1).to_int()));
- }
+
if (type)
- property_select->select_property_from_basic_type(type, iet, v);
+ property_select->select_property_from_basic_type(type, v);
updating = false;
return false;
@@ -681,8 +681,8 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
field_names.push_back("h");
config_value_editors(4, 4, 10, field_names);
Rect2 r = v;
- value_editor[0]->set_text(String::num(r.pos.x));
- value_editor[1]->set_text(String::num(r.pos.y));
+ value_editor[0]->set_text(String::num(r.position.x));
+ value_editor[1]->set_text(String::num(r.position.y));
value_editor[2]->set_text(String::num(r.size.x));
value_editor[3]->set_text(String::num(r.size.y));
} break;
@@ -736,9 +736,9 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
config_value_editors(6, 3, 16, field_names);
Rect3 aabb = v;
- value_editor[0]->set_text(String::num(aabb.pos.x));
- value_editor[1]->set_text(String::num(aabb.pos.y));
- value_editor[2]->set_text(String::num(aabb.pos.z));
+ value_editor[0]->set_text(String::num(aabb.position.x));
+ value_editor[1]->set_text(String::num(aabb.position.y));
+ value_editor[2]->set_text(String::num(aabb.position.z));
value_editor[3]->set_text(String::num(aabb.size.x));
value_editor[4]->set_text(String::num(aabb.size.y));
value_editor[5]->set_text(String::num(aabb.size.z));
@@ -861,15 +861,7 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
*/
} break;
- case Variant::IMAGE: {
- List<String> names;
- names.push_back(TTR("New"));
- names.push_back(TTR("Load"));
- names.push_back(TTR("Clear"));
- config_action_buttons(names);
-
- } break;
case Variant::NODE_PATH: {
List<String> names;
@@ -987,9 +979,6 @@ bool CustomPropertyEditor::edit(Object *p_owner, const String &p_name, Variant::
return false;
} break;
- case Variant::INPUT_EVENT: {
-
- } break;
case Variant::DICTIONARY: {
} break;
@@ -1061,16 +1050,6 @@ void CustomPropertyEditor::_file_selected(String p_file) {
emit_signal("variant_changed");
hide();
} break;
- case Variant::IMAGE: {
-
- Image image;
- Error err = ImageLoader::load_image(p_file, &image);
- ERR_EXPLAIN(TTR("Couldn't load image"));
- ERR_FAIL_COND(err);
- v = image;
- emit_signal("variant_changed");
- hide();
- } break;
default: {}
}
}
@@ -1387,36 +1366,7 @@ void CustomPropertyEditor::_action_pressed(int p_which) {
}
} break;
- case Variant::IMAGE: {
-
- if (p_which == 0) {
- //new image too difficult
- ERR_PRINT("New Image Unimplemented");
-
- } else if (p_which == 1) {
-
- file->set_access(EditorFileDialog::ACCESS_RESOURCES);
- file->set_mode(EditorFileDialog::MODE_OPEN_FILE);
- List<String> extensions;
- ImageLoader::get_recognized_extensions(&extensions);
-
- file->clear_filters();
-
- for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
-
- file->add_filter("*." + E->get() + " ; " + E->get().to_upper());
- }
-
- file->popup_centered_ratio();
-
- } else if (p_which == 2) {
- v = Image();
- emit_signal("variant_changed");
- hide();
- }
-
- } break;
default: {};
}
}
@@ -1448,11 +1398,13 @@ void CustomPropertyEditor::_scroll_modified(double p_value) {
*/
}
-void CustomPropertyEditor::_drag_easing(const InputEvent &p_ev) {
+void CustomPropertyEditor::_drag_easing(const Ref<InputEvent> &p_ev) {
- if (p_ev.type == InputEvent::MOUSE_MOTION && p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ Ref<InputEventMouseMotion> mm = p_ev;
- float rel = p_ev.mouse_motion.relative_x;
+ if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
+
+ float rel = mm->get_relative().x;
if (rel == 0)
return;
@@ -1481,8 +1433,8 @@ void CustomPropertyEditor::_drag_easing(const InputEvent &p_ev) {
//emit_signal("variant_changed");
emit_signal("variant_changed");
}
- if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT) {
- }
+ // if (p_ev.type == Ref<InputEvent>::MOUSE_BUTTON && p_ev->get_button_index() == BUTTON_LEFT) {
+ // }
}
void CustomPropertyEditor::_draw_easing() {
@@ -1590,13 +1542,13 @@ void CustomPropertyEditor::_modified(String p_string) {
Rect2 r2;
if (evaluator) {
- r2.pos.x = evaluator->eval(value_editor[0]->get_text());
- r2.pos.y = evaluator->eval(value_editor[1]->get_text());
+ r2.position.x = evaluator->eval(value_editor[0]->get_text());
+ r2.position.y = evaluator->eval(value_editor[1]->get_text());
r2.size.x = evaluator->eval(value_editor[2]->get_text());
r2.size.y = evaluator->eval(value_editor[3]->get_text());
} else {
- r2.pos.x = value_editor[0]->get_text().to_double();
- r2.pos.y = value_editor[1]->get_text().to_double();
+ r2.position.x = value_editor[0]->get_text().to_double();
+ r2.position.y = value_editor[1]->get_text().to_double();
r2.size.x = value_editor[2]->get_text().to_double();
r2.size.y = value_editor[3]->get_text().to_double();
}
@@ -1756,17 +1708,12 @@ void CustomPropertyEditor::_modified(String p_string) {
emit_signal("variant_changed");
*/
} break;
- case Variant::IMAGE: {
- } break;
case Variant::NODE_PATH: {
v = NodePath(value_editor[0]->get_text());
emit_signal("variant_changed");
} break;
- case Variant::INPUT_EVENT: {
-
- } break;
case Variant::DICTIONARY: {
} break;
@@ -2357,15 +2304,6 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
//p_item->set_text(1,obj->get(p_name));
} break;
- case Variant::IMAGE: {
-
- Image img = obj->get(p_name);
- if (img.empty())
- p_item->set_text(1, "[Image (empty)]");
- else
- p_item->set_text(1, "[Image " + itos(img.get_width()) + "x" + itos(img.get_height()) + "-" + String(Image::get_format_name(img.get_format())) + "]");
-
- } break;
case Variant::NODE_PATH: {
p_item->set_text(1, obj->get(p_name));
@@ -2375,6 +2313,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
if (obj->get(p_name).get_type() == Variant::NIL || obj->get(p_name).operator RefPtr().is_null()) {
p_item->set_text(1, "<null>");
p_item->set_icon(1, Ref<Texture>());
+ p_item->set_custom_as_button(1, false);
Dictionary d = p_item->get_metadata(0);
int hint = d.has("hint") ? d["hint"].operator int() : -1;
@@ -2384,6 +2323,7 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String &p
}
} else {
+ p_item->set_custom_as_button(1, true);
RES res = obj->get(p_name).operator RefPtr();
if (res->is_class("Texture")) {
int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width");
@@ -2750,6 +2690,10 @@ void PropertyEditor::_notification(int p_what) {
changing = false;
}
+
+ if (p_what == EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED) {
+ update_tree();
+ }
}
TreeItem *PropertyEditor::get_parent_node(String p_path, HashMap<String, TreeItem *> &item_paths, TreeItem *root) {
@@ -3588,19 +3532,7 @@ void PropertyEditor::update_tree() {
item->set_icon(0, get_icon("Color", "EditorIcons"));
} break;
- case Variant::IMAGE: {
- item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
- item->set_editable(1, !read_only);
- Image img = obj->get(p.name);
- if (img.empty())
- item->set_text(1, "[Image (empty)]");
- else
- item->set_text(1, "[Image " + itos(img.get_width()) + "x" + itos(img.get_height()) + "-" + String(Image::get_format_name(img.get_format())) + "]");
- if (show_type_icons)
- item->set_icon(0, get_icon("Image", "EditorIcons"));
-
- } break;
case Variant::NODE_PATH: {
item->set_cell_mode(1, TreeItem::CELL_MODE_STRING);
@@ -3613,17 +3545,21 @@ void PropertyEditor::update_tree() {
item->set_cell_mode(1, TreeItem::CELL_MODE_CUSTOM);
item->set_editable(1, !read_only);
- item->add_button(1, get_icon("EditResource", "EditorIcons"));
+ //item->add_button(1, get_icon("EditResource", "EditorIcons"));
String type;
if (p.hint == PROPERTY_HINT_RESOURCE_TYPE)
type = p.hint_string;
- if (obj->get(p.name).get_type() == Variant::NIL || obj->get(p.name).operator RefPtr().is_null()) {
+ RES res = obj->get(p.name).operator RefPtr();
+
+ if (obj->get(p.name).get_type() == Variant::NIL || res.is_null()) {
item->set_text(1, "<null>");
item->set_icon(1, Ref<Texture>());
+ item->set_custom_as_button(1, false);
- } else {
- RES res = obj->get(p.name).operator RefPtr();
+ } else if (res.is_valid()) {
+
+ item->set_custom_as_button(1, true);
if (res->is_class("Texture")) {
int tw = EditorSettings::get_singleton()->get("docks/property_editor/texture_preview_width");
@@ -3741,7 +3677,7 @@ void PropertyEditor::_draw_transparency(Object *t, const Rect2 &p_rect) {
// make a little space between consecutive color fields
Rect2 area = p_rect;
- area.pos.y += 1;
+ area.position.y += 1;
area.size.height -= 2;
area.size.width -= arrow->get_size().width + 5;
tree->draw_texture_rect(get_icon("Transparent", "EditorIcons"), area, true);
@@ -3922,17 +3858,22 @@ void PropertyEditor::_item_edited() {
case Variant::COLOR: {
//_edit_set(name,item->get_custom_bg_color(0));
} break;
- case Variant::IMAGE: {
- } break;
case Variant::NODE_PATH: {
_edit_set(name, NodePath(item->get_text(1)), refresh_all);
} break;
+ case Variant::OBJECT: {
+ if (!item->is_custom_set_as_button(1))
+ break;
- case Variant::INPUT_EVENT: {
+ RES res = obj->get(name);
+ if (res.is_valid()) {
+ emit_signal("resource_selected", res.get_ref_ptr(), name);
+ }
} break;
+
case Variant::DICTIONARY: {
} break;
@@ -4004,7 +3945,7 @@ void PropertyEditor::_custom_editor_request(bool p_arrow) {
int hint = d.has("hint") ? d["hint"].operator int() : -1;
String hint_text = d.has("hint_text") ? d["hint_text"] : "";
Rect2 where = tree->get_custom_popup_rect();
- custom_editor->set_position(where.pos);
+ custom_editor->set_position(where.position);
if (custom_editor->edit(obj, name, type, v, hint, hint_text)) {
custom_editor->popup();
@@ -4111,9 +4052,9 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
Variant v = obj->get(n);
custom_editor->edit(obj, n, (Variant::Type)t, v, h, ht);
Rect2 where = tree->get_item_rect(ti, 1);
- where.pos -= tree->get_scroll();
- where.pos += tree->get_global_position();
- custom_editor->set_position(where.pos);
+ where.position -= tree->get_scroll();
+ where.position += tree->get_global_position();
+ custom_editor->set_position(where.position);
custom_editor->popup();
} else if (t == Variant::STRING) {
@@ -4124,9 +4065,9 @@ void PropertyEditor::_edit_button(Object *p_item, int p_column, int p_button) {
if (h == PROPERTY_HINT_FILE || h == PROPERTY_HINT_DIR || h == PROPERTY_HINT_GLOBAL_DIR || h == PROPERTY_HINT_GLOBAL_FILE) {
Rect2 where = tree->get_item_rect(ti, 1);
- where.pos -= tree->get_scroll();
- where.pos += tree->get_global_position();
- custom_editor->set_position(where.pos);
+ where.position -= tree->get_scroll();
+ where.position += tree->get_global_position();
+ custom_editor->set_position(where.position);
custom_editor->popup();
} else {
custom_editor->popup_centered_ratio();
@@ -4202,7 +4143,7 @@ void PropertyEditor::_draw_flags(Object *t, const Rect2 &p_rect) {
if (i == 1)
ofs.y += bsize + 1;
- ofs += p_rect.pos;
+ ofs += p_rect.position;
for (int j = 0; j < 10; j++) {
Point2 o = ofs + Point2(j * (bsize + 1), 0);
diff --git a/editor/property_editor.h b/editor/property_editor.h
index b88ba38e19..c02c301acf 100644
--- a/editor/property_editor.h
+++ b/editor/property_editor.h
@@ -134,7 +134,7 @@ class CustomPropertyEditor : public Popup {
void _draw_easing();
void _menu_option(int p_which);
- void _drag_easing(const InputEvent &p_ev);
+ void _drag_easing(const Ref<InputEvent> &p_ev);
void _node_path_selected(NodePath p_path);
void show_value_editors(int p_amount);
diff --git a/editor/property_selector.cpp b/editor/property_selector.cpp
index 565d25e0e5..47e5994e3f 100644
--- a/editor/property_selector.cpp
+++ b/editor/property_selector.cpp
@@ -37,17 +37,19 @@ void PropertySelector::_text_changed(const String &p_newtext) {
_update_search();
}
-void PropertySelector::_sbox_input(const InputEvent &p_ie) {
+void PropertySelector::_sbox_input(const Ref<InputEvent> &p_ie) {
- if (p_ie.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_ie;
- switch (p_ie.key.scancode) {
+ if (k.is_valid()) {
+
+ switch (k->get_scancode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", p_ie);
+ search_options->call("_gui_input", k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
@@ -89,14 +91,8 @@ void PropertySelector::_update_search() {
instance->get_property_list(&props, true);
} else if (type != Variant::NIL) {
Variant v;
- if (type == Variant::INPUT_EVENT) {
- InputEvent ie;
- ie.type = event_type;
- v = ie;
- } else {
- Variant::CallError ce;
- v = Variant::construct(type, NULL, 0, ce);
- }
+ Variant::CallError ce;
+ v = Variant::construct(type, NULL, 0, ce);
v.get_property_list(&props);
} else {
@@ -136,11 +132,9 @@ void PropertySelector::_update_search() {
Control::get_icon("MiniMatrix3", "EditorIcons"),
Control::get_icon("MiniTransform", "EditorIcons"),
Control::get_icon("MiniColor", "EditorIcons"),
- Control::get_icon("MiniImage", "EditorIcons"),
Control::get_icon("MiniPath", "EditorIcons"),
Control::get_icon("MiniRid", "EditorIcons"),
Control::get_icon("MiniObject", "EditorIcons"),
- Control::get_icon("MiniInput", "EditorIcons"),
Control::get_icon("MiniDictionary", "EditorIcons"),
Control::get_icon("MiniArray", "EditorIcons"),
Control::get_icon("MiniRawArray", "EditorIcons"),
@@ -326,22 +320,7 @@ void PropertySelector::_item_selected() {
String name = item->get_metadata(0);
String class_type;
- if (properties && type == Variant::INPUT_EVENT) {
-
- switch (event_type) {
- case InputEvent::NONE: class_type = "InputEvent"; break;
- case InputEvent::KEY: class_type = "InputEventKey"; break;
- case InputEvent::MOUSE_MOTION: class_type = "InputEventMouseMotion"; break;
- case InputEvent::MOUSE_BUTTON: class_type = "InputEventMouseButton"; break;
- case InputEvent::JOYPAD_MOTION: class_type = "InputEventJoypadMotion"; break;
- case InputEvent::JOYPAD_BUTTON: class_type = "InputEventJoypadButton"; break;
- case InputEvent::SCREEN_TOUCH: class_type = "InputEventScreenTouch"; break;
- case InputEvent::SCREEN_DRAG: class_type = "InputEventScreenDrag"; break;
- case InputEvent::ACTION: class_type = "InputEventAction"; break;
- default: {}
- }
-
- } else if (type) {
+ if (type) {
class_type = Variant::get_type_name(type);
} else {
@@ -515,13 +494,12 @@ void PropertySelector::select_property_from_script(const Ref<Script> &p_script,
search_box->grab_focus();
_update_search();
}
-void PropertySelector::select_property_from_basic_type(Variant::Type p_type, InputEvent::Type p_event_type, const String &p_current) {
+void PropertySelector::select_property_from_basic_type(Variant::Type p_type, const String &p_current) {
ERR_FAIL_COND(p_type == Variant::NIL);
base_type = "";
selected = p_current;
type = p_type;
- event_type = p_event_type;
script = 0;
properties = true;
instance = NULL;
diff --git a/editor/property_selector.h b/editor/property_selector.h
index 6dc2592176..def791a3fd 100644
--- a/editor/property_selector.h
+++ b/editor/property_selector.h
@@ -42,7 +42,7 @@ class PropertySelector : public ConfirmationDialog {
void _update_search();
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _confirmed();
void _text_changed(const String &p_newtext);
@@ -52,7 +52,6 @@ class PropertySelector : public ConfirmationDialog {
bool properties;
String selected;
Variant::Type type;
- InputEvent::Type event_type;
String base_type;
ObjectID script;
Object *instance;
@@ -71,7 +70,7 @@ public:
void select_property_from_base_type(const String &p_base, const String &p_current = "");
void select_property_from_script(const Ref<Script> &p_script, const String &p_current = "");
- void select_property_from_basic_type(Variant::Type p_type, InputEvent::Type p_event_type, const String &p_current = "");
+ void select_property_from_basic_type(Variant::Type p_type, const String &p_current = "");
void select_property_from_instance(Object *p_instance, const String &p_current = "");
PropertySelector();
diff --git a/editor/pvrtc_compress.cpp b/editor/pvrtc_compress.cpp
index 6edcd60188..ef875bbead 100644
--- a/editor/pvrtc_compress.cpp
+++ b/editor/pvrtc_compress.cpp
@@ -89,7 +89,7 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
args.push_back("-m");
Ref<ImageTexture> t = memnew(ImageTexture);
- t->create_from_image(*p_image, 0);
+ t->create_from_image(Ref<Image>(p_image), 0);
ResourceSaver::save(src_img, t);
Error err = OS::get_singleton()->execute(ttpath, args, true);
@@ -101,7 +101,7 @@ static void _compress_image(Image::CompressMode p_mode, Image *p_image) {
ERR_EXPLAIN(TTR("Can't load back converted image using PVRTC tool:") + " " + dst_img);
ERR_FAIL_COND(t.is_null());
- *p_image = t->get_data();
+ p_image->copy_internals_from(t->get_data());
}
static void _compress_pvrtc2(Image *p_image) {
diff --git a/editor/quick_open.cpp b/editor/quick_open.cpp
index 7fce485f3a..7fb9666afb 100644
--- a/editor/quick_open.cpp
+++ b/editor/quick_open.cpp
@@ -77,17 +77,18 @@ void EditorQuickOpen::_text_changed(const String &p_newtext) {
_update_search();
}
-void EditorQuickOpen::_sbox_input(const InputEvent &p_ie) {
+void EditorQuickOpen::_sbox_input(const Ref<InputEvent> &p_ie) {
- if (p_ie.type == InputEvent::KEY) {
+ Ref<InputEventKey> k = p_ie;
+ if (k.is_valid()) {
- switch (p_ie.key.scancode) {
+ switch (k->get_scancode()) {
case KEY_UP:
case KEY_DOWN:
case KEY_PAGEUP:
case KEY_PAGEDOWN: {
- search_options->call("_gui_input", p_ie);
+ search_options->call("_gui_input", k);
search_box->accept_event();
TreeItem *root = search_options->get_root();
diff --git a/editor/quick_open.h b/editor/quick_open.h
index 0e5766033f..44f8c025e6 100644
--- a/editor/quick_open.h
+++ b/editor/quick_open.h
@@ -47,7 +47,7 @@ class EditorQuickOpen : public ConfirmationDialog {
void _update_search();
- void _sbox_input(const InputEvent &p_ie);
+ void _sbox_input(const Ref<InputEvent> &p_ie);
void _parse_fs(EditorFileSystemDirectory *efsd, Vector<Pair<String, Ref<Texture> > > &list);
float _path_cmp(String search, String path) const;
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 901b259960..da2d22b900 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -52,19 +52,21 @@ void SceneTreeDock::_nodes_drag_begin() {
}
}
-void SceneTreeDock::_input(InputEvent p_event) {
+void SceneTreeDock::_input(Ref<InputEvent> p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
restore_script_editor_on_drag = false; //lost chance
}
}
-void SceneTreeDock::_unhandled_key_input(InputEvent p_event) {
+void SceneTreeDock::_unhandled_key_input(Ref<InputEvent> p_event) {
if (get_viewport()->get_modal_stack_top())
return; //ignore because of modal window
- if (!p_event.key.pressed || p_event.key.echo)
+ if (!p_event->is_pressed() || p_event->is_echo())
return;
if (ED_IS_SHORTCUT("scene_tree/add_child_node", p_event)) {
@@ -362,8 +364,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
else {
String path = selected->get_filename();
script_create_dialog->config(selected->get_class(), path);
- script_create_dialog->popup_centered(Size2(300, 290));
- //script_create_dialog->popup_centered_minsize();
+ script_create_dialog->popup_centered();
}
} break;
@@ -657,6 +658,21 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
}
}
} break;
+
+ default: {
+
+ if (p_tool >= EDIT_SUBRESOURCE_BASE) {
+
+ int idx = p_tool - EDIT_SUBRESOURCE_BASE;
+
+ ERR_FAIL_INDEX(idx, subresources.size());
+
+ Object *obj = ObjectDB::get_instance(subresources[idx]);
+ ERR_FAIL_COND(!obj);
+
+ editor->push_item(obj);
+ }
+ }
}
}
@@ -681,8 +697,6 @@ void SceneTreeDock::_notification(int p_what) {
button_create_script->set_icon(get_icon("ScriptCreate", "EditorIcons"));
button_clear_script->set_icon(get_icon("ScriptRemove", "EditorIcons"));
- filter_icon->set_texture(get_icon("Zoom", "EditorIcons"));
-
filter_icon->set_texture(get_icon("Search", "EditorIcons"));
EditorNode::get_singleton()->get_editor_selection()->connect("selection_changed", this, "_selection_changed");
@@ -1663,6 +1677,47 @@ void SceneTreeDock::_nodes_dragged(Array p_nodes, NodePath p_to, int p_type) {
_do_reparent(to_node, to_pos, nodes, true);
}
+void SceneTreeDock::_add_children_to_popup(Object *p_obj, int p_depth) {
+
+ if (p_depth > 8)
+ return;
+
+ List<PropertyInfo> pinfo;
+ p_obj->get_property_list(&pinfo);
+ for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
+
+ if (!(E->get().usage & PROPERTY_USAGE_EDITOR))
+ continue;
+ if (E->get().hint != PROPERTY_HINT_RESOURCE_TYPE)
+ continue;
+
+ Variant value = p_obj->get(E->get().name);
+ if (value.get_type() != Variant::OBJECT)
+ continue;
+ Object *obj = value;
+ if (!obj)
+ continue;
+
+ Ref<Texture> icon;
+
+ if (has_icon(obj->get_class(), "EditorIcons"))
+ icon = get_icon(obj->get_class(), "EditorIcons");
+ else
+ icon = get_icon("Object", "EditorIcons");
+
+ if (menu->get_item_count() == 0) {
+ menu->add_item(TTR("Sub-Resources:"));
+ menu->set_item_disabled(0, true);
+ }
+ int index = menu->get_item_count();
+ menu->add_icon_item(icon, E->get().name.capitalize(), EDIT_SUBRESOURCE_BASE + subresources.size());
+ menu->set_item_h_offset(index, p_depth * 10 * EDSCALE);
+ subresources.push_back(obj->get_instance_ID());
+
+ _add_children_to_popup(obj, p_depth + 1);
+ }
+}
+
void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
if (!EditorNode::get_singleton()->get_edited_scene()) {
@@ -1684,6 +1739,12 @@ void SceneTreeDock::_tree_rmb(const Vector2 &p_menu_pos) {
menu->clear();
if (selection.size() == 1) {
+
+ subresources.clear();
+ _add_children_to_popup(selection.front()->get(), 0);
+ if (menu->get_item_count() > 0)
+ menu->add_separator();
+
menu->add_icon_shortcut(get_icon("Add", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/add_child_node"), TOOL_NEW);
menu->add_icon_shortcut(get_icon("Instance", "EditorIcons"), ED_GET_SHORTCUT("scene_tree/instance_scene"), TOOL_INSTANCE);
menu->add_separator();
@@ -1830,6 +1891,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor, Node *p_scene_root, EditorSel
filter->set_h_size_flags(SIZE_EXPAND_FILL);
filter_hbc->add_child(filter);
filter_icon = memnew(TextureRect);
+ filter_icon->set_custom_minimum_size(Size2(24 * EDSCALE, 0));
filter_hbc->add_child(filter_icon);
filter_icon->set_stretch_mode(TextureRect::STRETCH_KEEP_CENTERED);
filter->connect("text_changed", this, "_filter_changed");
diff --git a/editor/scene_tree_dock.h b/editor/scene_tree_dock.h
index de6b81d44a..79e01e7571 100644
--- a/editor/scene_tree_dock.h
+++ b/editor/scene_tree_dock.h
@@ -73,6 +73,12 @@ class SceneTreeDock : public VBoxContainer {
TOOL_BUTTON_MAX
};
+ enum {
+ EDIT_SUBRESOURCE_BASE = 100
+ };
+
+ Vector<ObjectID> subresources;
+
bool restore_script_editor_on_drag;
int current_option;
@@ -114,6 +120,8 @@ class SceneTreeDock : public VBoxContainer {
Node *edited_scene;
EditorNode *editor;
+ void _add_children_to_popup(Object *p_obj, int p_depth);
+
Node *_duplicate(Node *p_node, Map<Node *, Node *> &duplimap);
void _node_reparent(NodePath p_path, bool p_keep_global_xform);
void _do_reparent(Node *p_new_parent, int p_position_in_parent, Vector<Node *> p_nodes, bool p_keep_global_xform);
@@ -133,8 +141,8 @@ class SceneTreeDock : public VBoxContainer {
void _node_prerenamed(Node *p_node, const String &p_new_name);
void _nodes_drag_begin();
- void _input(InputEvent p_event);
- void _unhandled_key_input(InputEvent p_event);
+ void _input(Ref<InputEvent> p_event);
+ void _unhandled_key_input(Ref<InputEvent> p_event);
void _import_subscene();
diff --git a/editor/scene_tree_editor.cpp b/editor/scene_tree_editor.cpp
index 2945abbd8c..d4e5714c0d 100644
--- a/editor/scene_tree_editor.cpp
+++ b/editor/scene_tree_editor.cpp
@@ -161,17 +161,17 @@ void SceneTreeEditor::_cell_button_pressed(Object *p_item, int p_column, int p_i
if (p_id == BUTTON_SUBSCENE) {
//open scene request
Rect2 item_rect = tree->get_item_rect(item, 0);
- item_rect.pos.y -= tree->get_scroll().y;
- item_rect.pos += tree->get_global_position();
+ item_rect.position.y -= tree->get_scroll().y;
+ item_rect.position += tree->get_global_position();
if (n == get_scene_node()) {
- inheritance_menu->set_position(item_rect.pos + Vector2(0, item_rect.size.y));
+ inheritance_menu->set_position(item_rect.position + Vector2(0, item_rect.size.y));
inheritance_menu->set_size(Vector2(item_rect.size.x, 0));
inheritance_menu->popup();
instance_node = n->get_instance_ID();
} else {
- instance_menu->set_position(item_rect.pos + Vector2(0, item_rect.size.y));
+ instance_menu->set_position(item_rect.position + Vector2(0, item_rect.size.y));
instance_menu->set_size(Vector2(item_rect.size.x, 0));
if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n))
instance_menu->set_item_checked(0, true);
diff --git a/editor/script_create_dialog.cpp b/editor/script_create_dialog.cpp
index 15c540e132..dbd0758256 100644
--- a/editor/script_create_dialog.cpp
+++ b/editor/script_create_dialog.cpp
@@ -29,12 +29,23 @@
/*************************************************************************/
#include "script_create_dialog.h"
+#include "editor/editor_scale.h"
#include "editor_file_system.h"
#include "global_config.h"
#include "io/resource_saver.h"
#include "os/file_access.h"
#include "script_language.h"
+void ScriptCreateDialog::_notification(int p_what) {
+
+ switch (p_what) {
+ case NOTIFICATION_ENTER_TREE: {
+ path_button->set_icon(get_icon("Folder", "EditorIcons"));
+ parent_browse_button->set_icon(get_icon("Folder", "EditorIcons"));
+ }
+ }
+}
+
void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_path) {
class_name->set_text("");
@@ -46,6 +57,8 @@ void ScriptCreateDialog::config(const String &p_base_name, const String &p_base_
initial_bp = "";
file_path->set_text("");
}
+ _lang_changed(current_language);
+ _parent_name_changed(parent_name->get_text());
_class_name_changed("");
_path_changed(file_path->get_text());
}
@@ -85,57 +98,61 @@ bool ScriptCreateDialog::_validate(const String &p_string) {
void ScriptCreateDialog::_class_name_changed(const String &p_name) {
- if (!_validate(parent_name->get_text())) {
- error_label->set_text(TTR("Invalid parent class name or path"));
- error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
- } else if (class_name->is_editable()) {
- if (class_name->get_text() == "") {
- error_label->set_text(TTR("Valid chars:") + " a-z A-Z 0-9 _");
- error_label->add_color_override("font_color", Color(1, 1, 1, 0.6));
- } else if (!_validate(class_name->get_text())) {
- error_label->set_text(TTR("Invalid class name"));
- error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
- } else {
- error_label->set_text(TTR("Valid name"));
- error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
- }
+ if (_validate(class_name->get_text())) {
+ is_class_name_valid = true;
+ } else {
+ is_class_name_valid = false;
+ }
+ _update_dialog();
+}
+
+void ScriptCreateDialog::_parent_name_changed(const String &p_parent) {
+
+ if (_validate(parent_name->get_text())) {
+ is_parent_name_valid = true;
} else {
+ is_parent_name_valid = false;
+ }
+ _update_dialog();
+}
- error_label->set_text(TTR("N/A"));
- error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+void ScriptCreateDialog::_template_changed(int p_template) {
+
+ if (p_template == 0) {
+ //default
+ script_template = "";
+ return;
}
+ String ext = ScriptServer::get_language(language_menu->get_selected())->get_extension();
+ String name = template_menu->get_item_text(p_template) + "." + ext;
+ script_template = EditorSettings::get_singleton()->get_settings_path() + "/script_templates/" + name;
}
void ScriptCreateDialog::ok_pressed() {
- if (create_new) {
+ if (is_new_script_created) {
_create_new();
} else {
_load_exist();
}
- create_new = true;
- _update_controls();
+ is_new_script_created = true;
+ _update_dialog();
}
void ScriptCreateDialog::_create_new() {
- if (class_name->is_editable() && !_validate(class_name->get_text())) {
- alert->set_text(TTR("Class name is invalid!"));
- alert->popup_centered_minsize();
- return;
- }
- if (!_validate(parent_name->get_text())) {
- alert->set_text(TTR("Parent class name is invalid!"));
- alert->popup_centered_minsize();
- return;
- }
-
String cname;
- if (class_name->is_editable())
+ if (has_named_classes)
cname = class_name->get_text();
- Ref<Script> scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+ Ref<Script> scr;
+ if (script_template != "") {
+ scr = ResourceLoader::load(script_template)->duplicate();
+ ScriptServer::get_language(language_menu->get_selected())->make_template(cname, parent_name->get_text(), scr);
+ } else {
+ scr = ScriptServer::get_language(language_menu->get_selected())->get_template(cname, parent_name->get_text());
+ }
String selected_language = language_menu->get_item_text(language_menu->get_selected());
editor_settings->set_project_metadata("script_setup", "last_selected_language", selected_language);
@@ -143,18 +160,13 @@ void ScriptCreateDialog::_create_new() {
if (cname != "")
scr->set_name(cname);
- if (!internal->is_pressed()) {
+ if (!is_built_in) {
String lpath = GlobalConfig::get_singleton()->localize_path(file_path->get_text());
scr->set_path(lpath);
- if (!path_valid) {
- alert->set_text(TTR("Invalid path!"));
- alert->popup_centered_minsize();
- return;
- }
Error err = ResourceSaver::save(lpath, scr, ResourceSaver::FLAG_CHANGE_PATH);
if (err != OK) {
- alert->set_text(TTR("Could not create script in filesystem."));
- alert->popup_centered_minsize();
+ alert->set_text(TTR("Error - Could not create script in filesystem."));
+ alert->popup_centered();
return;
}
}
@@ -168,9 +180,9 @@ void ScriptCreateDialog::_load_exist() {
String path = file_path->get_text();
RES p_script = ResourceLoader::load(path, "Script");
if (p_script.is_null()) {
- alert->get_ok()->set_text(TTR("Ugh"));
+ alert->get_ok()->set_text(TTR("OK"));
alert->set_text(vformat(TTR("Error loading script from %s"), path));
- alert->popup_centered_minsize();
+ alert->popup_centered();
return;
}
@@ -181,56 +193,73 @@ void ScriptCreateDialog::_load_exist() {
void ScriptCreateDialog::_lang_changed(int l) {
l = language_menu->get_selected();
- if (ScriptServer::get_language(l)->has_named_classes()) {
- class_name->set_editable(true);
+ ScriptLanguage *language = ScriptServer::get_language(l);
+ if (language->has_named_classes()) {
+ has_named_classes = true;
} else {
- class_name->set_editable(false);
+ has_named_classes = false;
}
if (ScriptServer::get_language(l)->can_inherit_from_file()) {
- parent_browse_button->show();
+ can_inherit_from_file = true;
} else {
- parent_browse_button->hide();
+ can_inherit_from_file = false;
}
- String selected_ext = "." + ScriptServer::get_language(l)->get_extension();
+ String selected_ext = "." + language->get_extension();
String path = file_path->get_text();
String extension = "";
- if (path.find(".") >= 0) {
- extension = path.get_extension();
- }
-
- if (extension.length() == 0) {
- // add extension if none
- path += selected_ext;
- _path_changed(path);
- } else {
- // change extension by selected language
- List<String> extensions;
- // get all possible extensions for script
- for (int l = 0; l < language_menu->get_item_count(); l++) {
- ScriptServer::get_language(l)->get_recognized_extensions(&extensions);
+ if (path != "") {
+ if (path.find(".") >= 0) {
+ extension = path.get_extension();
}
- for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
- if (E->get().nocasecmp_to(extension) == 0) {
- path = path.get_basename() + selected_ext;
- _path_changed(path);
- break;
+ if (extension.length() == 0) {
+ // add extension if none
+ path += selected_ext;
+ _path_changed(path);
+ } else {
+ // change extension by selected language
+ List<String> extensions;
+ // get all possible extensions for script
+ for (int l = 0; l < language_menu->get_item_count(); l++) {
+ language->get_recognized_extensions(&extensions);
+ }
+
+ for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
+ if (E->get().nocasecmp_to(extension) == 0) {
+ path = path.get_basename() + selected_ext;
+ _path_changed(path);
+ break;
+ }
}
}
+ file_path->set_text(path);
+ }
+
+ bool use_templates = language->is_using_templates();
+ template_menu->set_disabled(!use_templates);
+ if (use_templates) {
+ Vector<String> template_list = EditorSettings::get_singleton()->get_script_templates(language->get_extension());
+
+ template_menu->clear();
+ template_menu->add_item(TTR("Default"));
+ for (int i = 0; i < template_list.size(); i++) {
+ template_menu->add_item(template_list[i]);
+ }
}
- file_path->set_text(path);
- _class_name_changed(class_name->get_text());
+
+ _update_dialog();
}
void ScriptCreateDialog::_built_in_pressed() {
if (internal->is_pressed()) {
- path_vb->hide();
+ is_built_in = true;
} else {
- path_vb->show();
+ is_built_in = false;
}
+ _update_dialog();
}
void ScriptCreateDialog::_browse_path(bool browse_parent) {
@@ -269,40 +298,45 @@ void ScriptCreateDialog::_file_selected(const String &p_file) {
void ScriptCreateDialog::_path_changed(const String &p_path) {
- path_valid = false;
+ is_path_valid = false;
+ is_new_script_created = true;
String p = p_path;
if (p == "") {
-
- path_error_label->set_text(TTR("Path is empty"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Path is empty"));
+ _update_dialog();
return;
}
p = GlobalConfig::get_singleton()->localize_path(p);
if (!p.begins_with("res://")) {
-
- path_error_label->set_text(TTR("Path is not local"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Path is not local"));
+ _update_dialog();
return;
}
if (p.find("/") || p.find("\\")) {
DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES);
-
if (d->change_dir(p.get_base_dir()) != OK) {
-
- path_error_label->set_text(TTR("Invalid base path"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Invalid base path"));
memdelete(d);
+ _update_dialog();
return;
}
memdelete(d);
}
- FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES);
- create_new = !f->file_exists(p);
+ /* Does file already exist */
+
+ DirAccess *f = DirAccess::create(DirAccess::ACCESS_RESOURCES);
+ if (f->file_exists(p) && !(f->current_is_dir())) {
+ is_new_script_created = false;
+ is_path_valid = true;
+ }
memdelete(f);
+ _update_dialog();
+
+ /* Check file extension */
String extension = p.get_extension();
List<String> extensions;
@@ -313,86 +347,263 @@ void ScriptCreateDialog::_path_changed(const String &p_path) {
}
bool found = false;
+ bool match = false;
int index = 0;
for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
if (E->get().nocasecmp_to(extension) == 0) {
- language_menu->select(index); // change Language option by extension
+ //FIXME (?) - changing language this way doesn't update controls, needs rework
+ //language_menu->select(index); // change Language option by extension
found = true;
+ if (E->get() == ScriptServer::get_language(language_menu->get_selected())->get_extension()) {
+ match = true;
+ }
break;
}
index++;
}
if (!found) {
- path_error_label->set_text(TTR("Invalid extension"));
- path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ _msg_path_valid(false, TTR("Invalid extension"));
+ _update_dialog();
return;
}
- _update_controls();
+ if (!match) {
+ _msg_path_valid(false, TTR("Wrong extension chosen"));
+ _update_dialog();
+ return;
+ }
- path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ /* All checks passed */
- path_valid = true;
+ is_path_valid = true;
+ _update_dialog();
}
-void ScriptCreateDialog::_update_controls() {
+void ScriptCreateDialog::_msg_script_valid(bool valid, const String &p_msg) {
+
+ error_label->set_text(TTR(p_msg));
+ if (valid) {
+ error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ } else {
+ error_label->add_color_override("font_color", Color(1, 0.2, 0.2, 0.8));
+ }
+}
+
+void ScriptCreateDialog::_msg_path_valid(bool valid, const String &p_msg) {
+
+ path_error_label->set_text(TTR(p_msg));
+ if (valid) {
+ path_error_label->add_color_override("font_color", Color(0, 1.0, 0.8, 0.8));
+ } else {
+ path_error_label->add_color_override("font_color", Color(1, 0.4, 0.0, 0.8));
+ }
+}
+
+void ScriptCreateDialog::_update_dialog() {
+
+ bool script_ok = true;
+
+ /* "Add Script Dialog" gui logic and script checks */
+
+ // Is Script Valid (order from top to bottom)
+ get_ok()->set_disabled(true);
+ if (!is_built_in) {
+ if (!is_path_valid) {
+ _msg_script_valid(false, TTR("Invalid Path"));
+ script_ok = false;
+ }
+ }
+ if (has_named_classes && (!is_class_name_valid)) {
+ _msg_script_valid(false, TTR("Invalid class name"));
+ script_ok = false;
+ }
+ if (!is_parent_name_valid) {
+ _msg_script_valid(false, TTR("Invalid inherited parent name or path"));
+ script_ok = false;
+ }
+ if (script_ok) {
+ _msg_script_valid(true, TTR("Script valid"));
+ get_ok()->set_disabled(false);
+ }
+
+ /* Does script have named classes */
+
+ if (has_named_classes) {
+ if (is_new_script_created) {
+ class_name->set_editable(true);
+ class_name->set_placeholder(TTR("Allowed: a-z, A-Z, 0-9 and _"));
+ class_name->set_placeholder_alpha(0.3);
+ } else {
+ class_name->set_editable(false);
+ }
+ } else {
+ class_name->set_editable(false);
+ class_name->set_placeholder(TTR("N/A"));
+ class_name->set_placeholder_alpha(1);
+ }
+
+ /* Can script inherit from a file */
+
+ if (can_inherit_from_file) {
+ parent_browse_button->set_disabled(false);
+ } else {
+ parent_browse_button->set_disabled(true);
+ }
+
+ /* Is script Built-in */
+
+ if (is_built_in) {
+ file_path->set_editable(false);
+ path_button->set_disabled(true);
+ re_check_path = true;
+ } else {
+ file_path->set_editable(true);
+ path_button->set_disabled(false);
+ if (re_check_path) {
+ re_check_path = false;
+ _path_changed(file_path->get_text());
+ }
+ }
- if (create_new) {
- path_error_label->set_text(TTR("Create new script"));
+ /* Is Script created or loaded from existing file */
+
+ if (is_new_script_created) {
+ // New Script Created
get_ok()->set_text(TTR("Create"));
+ parent_name->set_editable(true);
+ parent_browse_button->set_disabled(false);
+ internal->set_disabled(false);
+ if (is_built_in) {
+ _msg_path_valid(true, TTR("Built-in script (into scene file)"));
+ } else {
+ if (script_ok) {
+ _msg_path_valid(true, TTR("Create new script file"));
+ }
+ }
} else {
- path_error_label->set_text(TTR("Load existing script"));
+ // Script Loaded
get_ok()->set_text(TTR("Load"));
+ parent_name->set_editable(false);
+ parent_browse_button->set_disabled(true);
+ internal->set_disabled(true);
+ if (script_ok) {
+ _msg_path_valid(true, TTR("Load existing script file"));
+ }
}
- parent_name->set_editable(create_new);
- internal->set_disabled(!create_new);
}
void ScriptCreateDialog::_bind_methods() {
ClassDB::bind_method("_class_name_changed", &ScriptCreateDialog::_class_name_changed);
+ ClassDB::bind_method("_parent_name_changed", &ScriptCreateDialog::_parent_name_changed);
ClassDB::bind_method("_lang_changed", &ScriptCreateDialog::_lang_changed);
ClassDB::bind_method("_built_in_pressed", &ScriptCreateDialog::_built_in_pressed);
ClassDB::bind_method("_browse_path", &ScriptCreateDialog::_browse_path);
ClassDB::bind_method("_file_selected", &ScriptCreateDialog::_file_selected);
ClassDB::bind_method("_path_changed", &ScriptCreateDialog::_path_changed);
+ ClassDB::bind_method("_template_changed", &ScriptCreateDialog::_template_changed);
ADD_SIGNAL(MethodInfo("script_created", PropertyInfo(Variant::OBJECT, "script", PROPERTY_HINT_RESOURCE_TYPE, "Script")));
}
ScriptCreateDialog::ScriptCreateDialog() {
- /* SNAP DIALOG */
+ editor_settings = EditorSettings::get_singleton();
+ GridContainer *gc = memnew(GridContainer);
VBoxContainer *vb = memnew(VBoxContainer);
- add_child(vb);
- //set_child_rect(vb);
+ HBoxContainer *hb = memnew(HBoxContainer);
+ Label *l = memnew(Label);
+ Control *empty = memnew(Control);
+ Control *empty_h = memnew(Control);
+ Control *empty_v = memnew(Control);
+ PanelContainer *pc = memnew(PanelContainer);
- class_name = memnew(LineEdit);
- VBoxContainer *vb2 = memnew(VBoxContainer);
- vb2->add_child(class_name);
- class_name->connect("text_changed", this, "_class_name_changed");
- error_label = memnew(Label);
- error_label->set_text("valid chars: a-z A-Z 0-9 _");
- error_label->set_align(Label::ALIGN_CENTER);
- vb2->add_child(error_label);
- vb->add_margin_child(TTR("Class Name:"), vb2);
+ /* DIALOG */
- HBoxContainer *hb1 = memnew(HBoxContainer);
- parent_name = memnew(LineEdit);
- parent_name->connect("text_changed", this, "_class_name_changed");
- parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
- hb1->add_child(parent_name);
- parent_browse_button = memnew(Button);
- parent_browse_button->set_text(" .. ");
- parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
- hb1->add_child(parent_browse_button);
- parent_browse_button->hide();
- vb->add_margin_child(TTR("Inherits:"), hb1);
- is_browsing_parent = false;
+ /* Main Controls */
+
+ gc = memnew(GridContainer);
+ gc->set_columns(2);
+
+ /* Error Stylebox Background */
+
+ StyleBoxFlat *sb = memnew(StyleBoxFlat);
+ sb->set_bg_color(Color(0, 0, 0, 0.05));
+ sb->set_light_color(Color(1, 1, 1, 0.05));
+ sb->set_dark_color(Color(1, 1, 1, 0.05));
+ sb->set_border_blend(false);
+ sb->set_border_size(1);
+ sb->set_default_margin(MARGIN_TOP, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_BOTTOM, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_LEFT, 10.0 * EDSCALE);
+ sb->set_default_margin(MARGIN_RIGHT, 10.0 * EDSCALE);
+
+ /* Error Messages Field */
+
+ vb = memnew(VBoxContainer);
+
+ hb = memnew(HBoxContainer);
+ l = memnew(Label);
+ l->set_text(" - ");
+ hb->add_child(l);
+ error_label = memnew(Label);
+ error_label->set_text(TTR("Error!"));
+ error_label->set_align(Label::ALIGN_LEFT);
+ hb->add_child(error_label);
+ vb->add_child(hb);
+
+ hb = memnew(HBoxContainer);
+ l = memnew(Label);
+ l->set_text(" - ");
+ hb->add_child(l);
+ path_error_label = memnew(Label);
+ path_error_label->set_text(TTR("Error!"));
+ path_error_label->set_align(Label::ALIGN_LEFT);
+ hb->add_child(path_error_label);
+ vb->add_child(hb);
+
+ pc = memnew(PanelContainer);
+ pc->set_h_size_flags(Control::SIZE_FILL);
+ pc->add_style_override("panel", sb);
+ pc->add_child(vb);
+
+ /* Margins */
+
+ empty_h = memnew(Control);
+ empty_h->set_name("empty_h"); //duplicate() doesn't like nodes without a name
+ empty_h->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_h->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_h->set_custom_minimum_size(Size2(0, 10 * EDSCALE));
+ empty_v = memnew(Control);
+ empty_v->set_name("empty_v");
+ empty_v->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_v->set_v_size_flags(Control::SIZE_EXPAND_FILL);
+ empty_v->set_custom_minimum_size(Size2(10, 0 * EDSCALE));
+
+ vb = memnew(VBoxContainer);
+ vb->add_child(empty_h->duplicate());
+ vb->add_child(gc);
+ vb->add_child(empty_h->duplicate());
+ vb->add_child(pc);
+ vb->add_child(empty_h->duplicate());
+ hb = memnew(HBoxContainer);
+ hb->add_child(empty_v->duplicate());
+ hb->add_child(vb);
+ hb->add_child(empty_v->duplicate());
+
+ add_child(hb);
+
+ /* Language */
language_menu = memnew(OptionButton);
- vb->add_margin_child(TTR("Language"), language_menu);
+ language_menu->set_custom_minimum_size(Size2(250, 0) * EDSCALE);
+ language_menu->set_h_size_flags(SIZE_EXPAND_FILL);
+ l = memnew(Label);
+ l->set_text(TTR("Language"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(language_menu);
int default_lang = 0;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
@@ -404,60 +615,118 @@ ScriptCreateDialog::ScriptCreateDialog() {
}
}
- editor_settings = EditorSettings::get_singleton();
String last_selected_language = editor_settings->get_project_metadata("script_setup", "last_selected_language", "");
if (last_selected_language != "") {
for (int i = 0; i < language_menu->get_item_count(); i++) {
if (language_menu->get_item_text(i) == last_selected_language) {
language_menu->select(i);
+ current_language = i;
break;
}
}
} else {
language_menu->select(default_lang);
+ current_language = default_lang;
}
language_menu->connect("item_selected", this, "_lang_changed");
- //parent_name->set_text();
+ /* Inherits */
- vb2 = memnew(VBoxContainer);
- path_vb = memnew(VBoxContainer);
- vb2->add_child(path_vb);
+ hb = memnew(HBoxContainer);
+ hb->set_h_size_flags(SIZE_EXPAND_FILL);
+ parent_name = memnew(LineEdit);
+ parent_name->connect("text_changed", this, "_parent_name_changed");
+ parent_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ hb->add_child(parent_name);
+ parent_browse_button = memnew(Button);
+ parent_browse_button->set_flat(true);
+ parent_browse_button->connect("pressed", this, "_browse_path", varray(true));
+ hb->add_child(parent_browse_button);
+ l = memnew(Label);
+ l->set_text(TTR("Inherits"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+ is_browsing_parent = false;
- HBoxContainer *hbc = memnew(HBoxContainer);
- file_path = memnew(LineEdit);
- file_path->connect("text_changed", this, "_path_changed");
- hbc->add_child(file_path);
- file_path->set_h_size_flags(SIZE_EXPAND_FILL);
- Button *b = memnew(Button);
- b->set_text(" .. ");
- b->connect("pressed", this, "_browse_path", varray(false));
- hbc->add_child(b);
- path_vb->add_child(hbc);
- path_error_label = memnew(Label);
- path_vb->add_child(path_error_label);
- path_error_label->set_text(TTR("Error!"));
- path_error_label->set_align(Label::ALIGN_CENTER);
+ /* Class Name */
- internal = memnew(CheckButton);
- internal->set_text(TTR("Built-In Script"));
- vb2->add_child(internal);
- internal->connect("pressed", this, "_built_in_pressed");
+ class_name = memnew(LineEdit);
+ class_name->connect("text_changed", this, "_class_name_changed");
+ class_name->set_h_size_flags(SIZE_EXPAND_FILL);
+ l = memnew(Label);
+ l->set_text(TTR("Class Name"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(class_name);
- vb->add_margin_child(TTR("Path:"), vb2);
+ /* Templates */
- set_size(Size2(200, 150));
- set_hide_on_ok(false);
- set_title(TTR("Attach Node Script"));
+ template_menu = memnew(OptionButton);
+ l = memnew(Label);
+ l->set_text(TTR("Template"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(template_menu);
+ template_menu->connect("item_selected", this, "_template_changed");
+
+ /* Built-in Script */
+
+ internal = memnew(CheckButton);
+ internal->connect("pressed", this, "_built_in_pressed");
+ hb = memnew(HBoxContainer);
+ empty = memnew(Control);
+ hb->add_child(internal);
+ hb->add_child(empty);
+ l = memnew(Label);
+ l->set_text(TTR("Built-in Script"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+
+ /* Path */
+
+ hb = memnew(HBoxContainer);
+ file_path = memnew(LineEdit);
+ file_path->connect("text_changed", this, "_path_changed");
+ file_path->set_h_size_flags(SIZE_EXPAND_FILL);
+ hb->add_child(file_path);
+ path_button = memnew(Button);
+ path_button->set_flat(true);
+ path_button->connect("pressed", this, "_browse_path", varray(false));
+ hb->add_child(path_button);
+ l = memnew(Label);
+ l->set_text(TTR("Path"));
+ l->set_align(Label::ALIGN_RIGHT);
+ gc->add_child(l);
+ gc->add_child(hb);
+
+ /* Dialog Setup */
file_browse = memnew(EditorFileDialog);
file_browse->connect("file_selected", this, "_file_selected");
add_child(file_browse);
get_ok()->set_text(TTR("Create"));
alert = memnew(AcceptDialog);
+ alert->set_as_minsize();
+ alert->get_label()->set_autowrap(true);
+ alert->get_label()->set_align(Label::ALIGN_CENTER);
+ alert->get_label()->set_valign(Label::VALIGN_CENTER);
+ alert->get_label()->set_custom_minimum_size(Size2(325, 60) * EDSCALE);
add_child(alert);
- _lang_changed(0);
- create_new = true;
+ set_as_minsize();
+ set_hide_on_ok(false);
+ set_title(TTR("Attach Node Script"));
+
+ is_parent_name_valid = false;
+ is_class_name_valid = false;
+ is_path_valid = false;
+
+ has_named_classes = false;
+ can_inherit_from_file = false;
+ is_built_in = false;
+
+ is_new_script_created = true;
}
diff --git a/editor/script_create_dialog.h b/editor/script_create_dialog.h
index 113d4a468c..1adbfe3f7d 100644
--- a/editor/script_create_dialog.h
+++ b/editor/script_create_dialog.h
@@ -34,8 +34,10 @@
#include "editor/editor_settings.h"
#include "scene/gui/check_button.h"
#include "scene/gui/dialogs.h"
+#include "scene/gui/grid_container.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
+#include "scene/gui/panel_container.h"
class ScriptCreateDialog : public ConfirmationDialog {
GDCLASS(ScriptCreateDialog, ConfirmationDialog);
@@ -46,7 +48,9 @@ class ScriptCreateDialog : public ConfirmationDialog {
LineEdit *parent_name;
Button *parent_browse_button;
OptionButton *language_menu;
+ OptionButton *template_menu;
LineEdit *file_path;
+ Button *path_button;
EditorFileDialog *file_browse;
CheckButton *internal;
VBoxContainer *path_vb;
@@ -56,20 +60,35 @@ class ScriptCreateDialog : public ConfirmationDialog {
bool is_browsing_parent;
String initial_bp;
EditorSettings *editor_settings;
+ bool is_new_script_created;
+ bool is_path_valid;
+ bool has_named_classes;
+ bool can_inherit_from_file;
+ bool is_parent_name_valid;
+ bool is_class_name_valid;
+ bool is_built_in;
+ int current_language;
+ bool re_check_path;
+ String script_template;
void _path_changed(const String &p_path = String());
void _lang_changed(int l = 0);
void _built_in_pressed();
bool _validate(const String &p_strin);
void _class_name_changed(const String &p_name);
+ void _parent_name_changed(const String &p_parent);
+ void _template_changed(int p_template = 0);
void _browse_path(bool browse_parent);
void _file_selected(const String &p_file);
virtual void ok_pressed();
void _create_new();
void _load_exist();
- void _update_controls();
+ void _msg_script_valid(bool valid, const String &p_msg = String());
+ void _msg_path_valid(bool valid, const String &p_msg = String());
+ void _update_dialog();
protected:
+ void _notification(int p_what);
static void _bind_methods();
public:
diff --git a/editor/script_editor_debugger.cpp b/editor/script_editor_debugger.cpp
index 2bc00c62fb..6d22935dcb 100644
--- a/editor/script_editor_debugger.cpp
+++ b/editor/script_editor_debugger.cpp
@@ -90,11 +90,13 @@ public:
return "";
}
- void add_property(const String &p_name, const Variant &p_value) {
+ void add_property(const String &p_name, const Variant &p_value, const PropertyHint &p_hint, const String p_hint_string) {
PropertyInfo pinfo;
pinfo.name = p_name;
pinfo.type = p_value.get_type();
+ pinfo.hint = p_hint;
+ pinfo.hint_string = p_hint_string;
props.push_back(pinfo);
values[p_name] = p_value;
}
@@ -437,7 +439,11 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
inspected_object->last_edited_id = id;
- inspect_properties->edit(inspected_object);
+ if (tabs->get_current_tab() == 2) {
+ inspect_properties->edit(inspected_object);
+ } else {
+ editor->push_item(inspected_object);
+ }
} else if (p_msg == "message:video_mem") {
@@ -499,13 +505,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String n = p_data[ofs + i * 2 + 0];
Variant v = p_data[ofs + i * 2 + 1];
+ PropertyHint h = PROPERTY_HINT_NONE;
+ String hs = String();
if (n.begins_with("*")) {
n = n.substr(1, n.length());
+ h = PROPERTY_HINT_OBJECT_ID;
+ String s = v;
+ s = s.replace("[", "");
+ hs = s.get_slice(":", 0);
+ v = s.get_slice(":", 1).to_int();
}
- variables->add_property("members/" + n, v);
+ variables->add_property("members/" + n, v, h, hs);
}
ofs += mcount * 2;
@@ -516,13 +529,20 @@ void ScriptEditorDebugger::_parse_message(const String &p_msg, const Array &p_da
String n = p_data[ofs + i * 2 + 0];
Variant v = p_data[ofs + i * 2 + 1];
+ PropertyHint h = PROPERTY_HINT_NONE;
+ String hs = String();
if (n.begins_with("*")) {
n = n.substr(1, n.length());
+ h = PROPERTY_HINT_OBJECT_ID;
+ String s = v;
+ s = s.replace("[", "");
+ hs = s.get_slice(":", 0);
+ v = s.get_slice(":", 1).to_int();
}
- variables->add_property("locals/" + n, v);
+ variables->add_property("locals/" + n, v, h, hs);
}
variables->update();
@@ -770,19 +790,19 @@ void ScriptEditorDebugger::_performance_draw() {
Point2i p(i % cols, i / cols);
Rect2i r(p * s, s);
- r.pos += Point2(margin, margin);
+ r.position += Point2(margin, margin);
r.size -= Point2(margin, margin) * 2.0;
perf_draw->draw_style_box(graph_sb, r);
- r.pos += graph_sb->get_offset();
+ r.position += graph_sb->get_offset();
r.size -= graph_sb->get_minimum_size();
int pi = which[i];
Color c = Color(0.7, 0.9, 0.5);
c.set_hsv(Math::fmod(c.get_h() + pi * 0.7654, 1), c.get_s(), c.get_v());
c.a = 0.8;
- perf_draw->draw_string(graph_font, r.pos + Point2(0, graph_font->get_ascent()), perf_items[pi]->get_text(0), c, r.size.x);
+ perf_draw->draw_string(graph_font, r.position + Point2(0, graph_font->get_ascent()), perf_items[pi]->get_text(0), c, r.size.x);
c.a = 0.6;
- perf_draw->draw_string(graph_font, r.pos + Point2(graph_font->get_char_size('X').width, graph_font->get_ascent() + graph_font->get_height()), perf_items[pi]->get_text(1), c, r.size.y);
+ perf_draw->draw_string(graph_font, r.position + Point2(graph_font->get_char_size('X').width, graph_font->get_ascent() + graph_font->get_height()), perf_items[pi]->get_text(1), c, r.size.y);
float spacing = point_sep / float(cols);
float from = r.size.width;
@@ -799,7 +819,7 @@ void ScriptEditorDebugger::_performance_draw() {
c.a = 0.7;
if (E != perf_history.front())
- perf_draw->draw_line(r.pos + Point2(from, h), r.pos + Point2(from + spacing, prev), c, 2.0);
+ perf_draw->draw_line(r.position + Point2(from, h), r.position + Point2(from + spacing, prev), c, 2.0);
prev = h;
E = E->next();
from -= spacing;
@@ -999,6 +1019,11 @@ void ScriptEditorDebugger::_notification(int p_what) {
}
} break;
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
+ tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles"));
+ tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
+ tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
+ } break;
}
}
@@ -1010,14 +1035,17 @@ void ScriptEditorDebugger::start() {
EditorNode::get_singleton()->make_bottom_panel_item_visible(this);
}
- uint16_t port = GLOBAL_GET("network/debug/remote_port");
perf_history.clear();
for (int i = 0; i < Performance::MONITOR_MAX; i++) {
perf_max[i] = 0;
}
- server->listen(port);
+ int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
+ if (server->listen(remote_port) != OK) {
+ EditorNode::get_log()->add_message(String("** Error listening on port ") + itos(remote_port) + String(" **"));
+ return;
+ }
set_process(true);
}
@@ -1056,6 +1084,9 @@ void ScriptEditorDebugger::stop() {
EditorNode::get_singleton()->get_pause_button()->set_pressed(false);
EditorNode::get_singleton()->get_pause_button()->set_disabled(true);
+ //avoid confusion when stopped debugging but an object is still edited
+ EditorNode::get_singleton()->push_item(NULL);
+
if (hide_on_stop) {
if (is_visible_in_tree())
EditorNode::get_singleton()->hide_bottom_panel();
@@ -1551,9 +1582,10 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
editor = p_editor;
tabs = memnew(TabContainer);
- tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("EditorPanelDebugger", "EditorStyles"));
- tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("EditorTabFGDebugger", "EditorStyles"));
- tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("EditorTabBGDebugger", "EditorStyles"));
+ tabs->set_tab_align(TabContainer::ALIGN_LEFT);
+ tabs->add_style_override("panel", editor->get_gui_base()->get_stylebox("DebuggerPanel", "EditorStyles"));
+ tabs->add_style_override("tab_fg", editor->get_gui_base()->get_stylebox("DebuggerTabFG", "EditorStyles"));
+ tabs->add_style_override("tab_bg", editor->get_gui_base()->get_stylebox("DebuggerTabBG", "EditorStyles"));
tabs->set_v_size_flags(SIZE_EXPAND_FILL);
tabs->set_area_as_parent_rect();
add_child(tabs);
@@ -1578,13 +1610,11 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
hbc->add_child(memnew(VSeparator));
step = memnew(Button);
- step->set_flat(true);
hbc->add_child(step);
step->set_tooltip(TTR("Step Into"));
step->connect("pressed", this, "debug_step");
next = memnew(Button);
- next->set_flat(true);
hbc->add_child(next);
next->set_tooltip(TTR("Step Over"));
next->connect("pressed", this, "debug_next");
@@ -1592,13 +1622,11 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
hbc->add_child(memnew(VSeparator));
dobreak = memnew(Button);
- dobreak->set_flat(true);
hbc->add_child(dobreak);
dobreak->set_tooltip(TTR("Break"));
dobreak->connect("pressed", this, "debug_break");
docontinue = memnew(Button);
- docontinue->set_flat(true);
hbc->add_child(docontinue);
docontinue->set_tooltip(TTR("Continue"));
docontinue->connect("pressed", this, "debug_continue");
@@ -1606,13 +1634,11 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
//hbc->add_child( memnew( VSeparator) );
back = memnew(Button);
- back->set_flat(true);
hbc->add_child(back);
back->set_tooltip(TTR("Inspect Previous Instance"));
back->hide();
forward = memnew(Button);
- forward->set_flat(true);
hbc->add_child(forward);
forward->set_tooltip(TTR("Inspect Next Instance"));
forward->hide();
@@ -1636,6 +1662,7 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
inspector->get_scene_tree()->set_column_title(0, TTR("Variable"));
inspector->set_enable_capitalize_paths(false);
inspector->set_read_only(true);
+ inspector->connect("object_id_selected", this, "_scene_tree_property_select_object");
sc->add_child(inspector);
server = TCP_Server::create_ref();
@@ -1774,7 +1801,6 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
vmem_total->set_custom_minimum_size(Size2(100, 1) * EDSCALE);
vmem_hb->add_child(vmem_total);
vmem_refresh = memnew(Button);
- vmem_refresh->set_flat(true);
vmem_hb->add_child(vmem_refresh);
vmem_vb->add_child(vmem_hb);
vmem_refresh->connect("pressed", this, "_video_mem_request");
@@ -1807,35 +1833,30 @@ ScriptEditorDebugger::ScriptEditorDebugger(EditorNode *p_editor) {
}
{ // misc
-
- GridContainer *grid_cont = memnew(GridContainer);
- grid_cont->set_h_size_flags(SIZE_EXPAND_FILL);
- grid_cont->set_name(TTR("Misc"));
- grid_cont->set_columns(2);
- tabs->add_child(grid_cont);
-
- grid_cont->add_child(memnew(Label(TTR("Clicked Control:"))));
+ VBoxContainer *info_left = memnew(VBoxContainer);
+ info_left->set_h_size_flags(SIZE_EXPAND_FILL);
+ info_left->set_name(TTR("Misc"));
+ tabs->add_child(info_left);
clicked_ctrl = memnew(LineEdit);
- grid_cont->add_child(clicked_ctrl);
-
- grid_cont->add_child(memnew(Label(TTR("Clicked Control Type:"))));
+ info_left->add_margin_child(TTR("Clicked Control:"), clicked_ctrl);
clicked_ctrl_type = memnew(LineEdit);
- grid_cont->add_child(clicked_ctrl_type);
+ info_left->add_margin_child(TTR("Clicked Control Type:"), clicked_ctrl_type);
live_edit_root = memnew(LineEdit);
- live_edit_root->set_h_size_flags(SIZE_EXPAND_FILL);
{
- grid_cont->add_child(memnew(Label(TTR("Live Edit Root:"))));
-
HBoxContainer *lehb = memnew(HBoxContainer);
- lehb->set_h_size_flags(SIZE_EXPAND_FILL);
- lehb->add_child(live_edit_root);
+ Label *l = memnew(Label(TTR("Live Edit Root:")));
+ lehb->add_child(l);
+ l->set_h_size_flags(SIZE_EXPAND_FILL);
le_set = memnew(Button(TTR("Set From Tree")));
lehb->add_child(le_set);
le_clear = memnew(Button(TTR("Clear")));
lehb->add_child(le_clear);
- grid_cont->add_child(lehb);
+ info_left->add_child(lehb);
+ MarginContainer *mc = memnew(MarginContainer);
+ mc->add_child(live_edit_root);
+ info_left->add_child(mc);
le_set->set_disabled(true);
le_clear->set_disabled(true);
}
diff --git a/editor/settings_config_dialog.cpp b/editor/settings_config_dialog.cpp
index 8c87857944..563de78415 100644
--- a/editor/settings_config_dialog.cpp
+++ b/editor/settings_config_dialog.cpp
@@ -148,7 +148,7 @@ void EditorSettingsDialog::_update_shortcuts() {
if (!sc->has_meta("original"))
continue;
- InputEvent original = sc->get_meta("original");
+ Ref<InputEvent> original = sc->get_meta("original");
String section_name = E->get().get_slice("/", 0);
@@ -170,7 +170,7 @@ void EditorSettingsDialog::_update_shortcuts() {
item->set_text(0, sc->get_name());
item->set_text(1, sc->get_as_text());
- if (!sc->is_shortcut(original) && !(sc->get_shortcut().type == InputEvent::NONE && original.type == InputEvent::NONE)) {
+ if (!sc->is_shortcut(original) && !(sc->get_shortcut().is_null() && original.is_null())) {
item->add_button(1, get_icon("Reload", "EditorIcons"), 2);
}
item->add_button(1, get_icon("Edit", "EditorIcons"), 0);
@@ -199,7 +199,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
if (p_idx == 0) {
press_a_key_label->set_text(TTR("Press a Key.."));
- last_wait_for_key = InputEvent();
+ last_wait_for_key = Ref<InputEventKey>();
press_a_key->popup_centered(Size2(250, 80) * EDSCALE);
press_a_key->grab_focus();
press_a_key->get_ok()->set_focus_mode(FOCUS_NONE);
@@ -212,7 +212,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action("Erase Shortcut");
- ur->add_do_method(sc.ptr(), "set_shortcut", InputEvent());
+ ur->add_do_method(sc.ptr(), "set_shortcut", Ref<InputEvent>());
ur->add_undo_method(sc.ptr(), "set_shortcut", sc->get_shortcut());
ur->add_do_method(this, "_update_shortcuts");
ur->add_undo_method(this, "_update_shortcuts");
@@ -223,7 +223,7 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
if (!sc.is_valid())
return; //pointless, there is nothing
- InputEvent original = sc->get_meta("original");
+ Ref<InputEvent> original = sc->get_meta("original");
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action("Restore Shortcut");
@@ -237,19 +237,21 @@ void EditorSettingsDialog::_shortcut_button_pressed(Object *p_item, int p_column
}
}
-void EditorSettingsDialog::_wait_for_key(const InputEvent &p_event) {
+void EditorSettingsDialog::_wait_for_key(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode != 0) {
+ Ref<InputEventKey> k = p_event;
- last_wait_for_key = p_event;
- String str = keycode_get_string(p_event.key.scancode).capitalize();
- if (p_event.key.mod.meta)
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() != 0) {
+
+ last_wait_for_key = k;
+ String str = keycode_get_string(k->get_scancode()).capitalize();
+ if (k->get_metakey())
str = TTR("Meta+") + str;
- if (p_event.key.mod.shift)
+ if (k->get_shift())
str = TTR("Shift+") + str;
- if (p_event.key.mod.alt)
+ if (k->get_alt())
str = TTR("Alt+") + str;
- if (p_event.key.mod.control)
+ if (k->get_control())
str = TTR("Control+") + str;
press_a_key_label->set_text(str);
@@ -259,13 +261,16 @@ void EditorSettingsDialog::_wait_for_key(const InputEvent &p_event) {
void EditorSettingsDialog::_press_a_key_confirm() {
- if (last_wait_for_key.type != InputEvent::KEY)
+ if (last_wait_for_key.is_null())
return;
- InputEvent ie;
- ie.type = InputEvent::KEY;
- ie.key.scancode = last_wait_for_key.key.scancode;
- ie.key.mod = last_wait_for_key.key.mod;
+ Ref<InputEventKey> ie;
+ ie.instance();
+ ie->set_scancode(last_wait_for_key->get_scancode());
+ ie->set_shift(last_wait_for_key->get_shift());
+ ie->set_control(last_wait_for_key->get_control());
+ ie->set_alt(last_wait_for_key->get_alt());
+ ie->set_metakey(last_wait_for_key->get_metakey());
Ref<ShortCut> sc = EditorSettings::get_singleton()->get_shortcut(shortcut_configured);
@@ -300,6 +305,7 @@ EditorSettingsDialog::EditorSettingsDialog() {
set_resizable(true);
tabs = memnew(TabContainer);
+ tabs->set_tab_align(TabContainer::ALIGN_LEFT);
add_child(tabs);
//set_child_rect(tabs);
diff --git a/editor/settings_config_dialog.h b/editor/settings_config_dialog.h
index 7b6e8862dc..cda191ac36 100644
--- a/editor/settings_config_dialog.h
+++ b/editor/settings_config_dialog.h
@@ -54,7 +54,7 @@ class EditorSettingsDialog : public AcceptDialog {
ConfirmationDialog *press_a_key;
Label *press_a_key_label;
- InputEvent last_wait_for_key;
+ Ref<InputEventKey> last_wait_for_key;
String shortcut_configured;
String shortcut_filter;
@@ -68,7 +68,7 @@ class EditorSettingsDialog : public AcceptDialog {
void _notification(int p_what);
void _press_a_key_confirm();
- void _wait_for_key(const InputEvent &p_event);
+ void _wait_for_key(const Ref<InputEvent> &p_event);
void _clear_shortcut_search_box();
void _clear_search_box();
diff --git a/editor/spatial_editor_gizmos.cpp b/editor/spatial_editor_gizmos.cpp
index 4781bb6a3b..76df9eb1ff 100644
--- a/editor/spatial_editor_gizmos.cpp
+++ b/editor/spatial_editor_gizmos.cpp
@@ -79,7 +79,7 @@ void EditorSpatialGizmo::Instance::create_instance(Spatial *p_base) {
VS::get_singleton()->instance_set_layer_mask(instance, 1 << SpatialEditorViewport::GIZMO_EDIT_LAYER); //gizmos are 26
}
-void EditorSpatialGizmo::add_mesh(const Ref<Mesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
+void EditorSpatialGizmo::add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard, const RID &p_skeleton) {
ERR_FAIL_COND(!spatial_node);
Instance ins;
@@ -100,7 +100,7 @@ void EditorSpatialGizmo::add_lines(const Vector<Vector3> &p_lines, const Ref<Mat
ERR_FAIL_COND(!spatial_node);
Instance ins;
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
@@ -162,7 +162,7 @@ void EditorSpatialGizmo::add_unscaled_billboard(const Ref<Material> &p_material,
uv.push_back(Vector2(0, 1));
uv.push_back(Vector2(1, 1));
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[Mesh::ARRAY_VERTEX] = vs;
@@ -219,7 +219,7 @@ void EditorSpatialGizmo::add_handles(const Vector<Vector3> &p_handles, bool p_bi
ERR_FAIL_COND(!spatial_node);
Instance ins;
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
#if 1
Array a;
@@ -1029,7 +1029,7 @@ CameraSpatialGizmo::CameraSpatialGizmo(Camera *p_camera) {
void MeshInstanceSpatialGizmo::redraw() {
- Ref<Mesh> m = mesh->get_mesh();
+ Ref<ArrayMesh> m = mesh->get_mesh();
if (!m.is_valid())
return; //none
@@ -1248,7 +1248,7 @@ void SkeletonSpatialGizmo::redraw() {
*/
}
- Ref<Mesh> m = surface_tool->commit();
+ Ref<ArrayMesh> m = surface_tool->commit();
add_mesh(m, false, skel->get_skeleton());
}
@@ -1439,20 +1439,6 @@ VehicleWheelSpatialGizmo::VehicleWheelSpatialGizmo(VehicleWheel *p_car_wheel) {
car_wheel = p_car_wheel;
}
-///
-
-void TestCubeSpatialGizmo::redraw() {
-
- clear();
- add_collision_triangles(SpatialEditorGizmos::singleton->test_cube_tm);
-}
-
-TestCubeSpatialGizmo::TestCubeSpatialGizmo(TestCube *p_tc) {
-
- tc = p_tc;
- set_spatial_node(p_tc);
-}
-
///////////
String CollisionShapeSpatialGizmo::get_handle_name(int p_idx) const {
@@ -1722,8 +1708,8 @@ void CollisionShapeSpatialGizmo::redraw() {
Ref<BoxShape> bs = s;
Vector<Vector3> lines;
Rect3 aabb;
- aabb.pos = -bs->get_extents();
- aabb.size = aabb.pos * -2;
+ aabb.position = -bs->get_extents();
+ aabb.size = aabb.position * -2;
for (int i = 0; i < 12; i++) {
Vector3 a, b;
@@ -1953,7 +1939,7 @@ void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Poin
Vector3 ray_dir = p_camera->project_ray_normal(p_point);
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
- Vector3 ofs = aabb.pos + aabb.size * 0.5;
+ Vector3 ofs = aabb.position + aabb.size * 0.5;
Vector3 axis;
axis[p_idx] = 1.0;
@@ -1964,7 +1950,7 @@ void VisibilityNotifierGizmo::set_handle(int p_idx, Camera *p_camera, const Poin
if (d < 0.001)
d = 0.001;
- aabb.pos[p_idx] = (aabb.pos[p_idx] + aabb.size[p_idx] * 0.5) - d;
+ aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
aabb.size[p_idx] = d * 2;
notifier->set_aabb(aabb);
}
@@ -2002,7 +1988,7 @@ void VisibilityNotifierGizmo::redraw() {
for (int i = 0; i < 3; i++) {
Vector3 ax;
- ax[i] = aabb.pos[i] + aabb.size[i];
+ ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
}
@@ -2053,7 +2039,7 @@ void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_poi
Vector3 sg[2] = { gi.xform(ray_from), gi.xform(ray_from + ray_dir * 4096) };
- Vector3 ofs = aabb.pos + aabb.size * 0.5;
+ Vector3 ofs = aabb.position + aabb.size * 0.5;
Vector3 axis;
axis[p_idx] = 1.0;
@@ -2065,7 +2051,7 @@ void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_poi
float d = ra[p_idx];
- aabb.pos[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
+ aabb.position[p_idx] = d - 1.0 - aabb.size[p_idx] * 0.5;
particles->set_visibility_aabb(aabb);
} else {
@@ -2076,7 +2062,7 @@ void ParticlesGizmo::set_handle(int p_idx, Camera *p_camera, const Point2 &p_poi
if (d < 0.001)
d = 0.001;
//resize
- aabb.pos[p_idx] = (aabb.pos[p_idx] + aabb.size[p_idx] * 0.5) - d;
+ aabb.position[p_idx] = (aabb.position[p_idx] + aabb.size[p_idx] * 0.5) - d;
aabb.size[p_idx] = d * 2;
particles->set_visibility_aabb(aabb);
}
@@ -2115,13 +2101,13 @@ void ParticlesGizmo::redraw() {
for (int i = 0; i < 3; i++) {
Vector3 ax;
- ax[i] = aabb.pos[i] + aabb.size[i];
- ax[(i + 1) % 3] = aabb.pos[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
- ax[(i + 2) % 3] = aabb.pos[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
+ ax[i] = aabb.position[i] + aabb.size[i];
+ ax[(i + 1) % 3] = aabb.position[(i + 1) % 3] + aabb.size[(i + 1) % 3] * 0.5;
+ ax[(i + 2) % 3] = aabb.position[(i + 2) % 3] + aabb.size[(i + 2) % 3] * 0.5;
handles.push_back(ax);
}
- Vector3 center = aabb.pos + aabb.size * 0.5;
+ Vector3 center = aabb.position + aabb.size * 0.5;
for (int i = 0; i < 3; i++) {
Vector3 ax;
@@ -2218,7 +2204,7 @@ void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bo
Rect3 restore = p_restore;
if (p_cancel) {
- probe->set_extents(restore.pos);
+ probe->set_extents(restore.position);
probe->set_origin_offset(restore.size);
return;
}
@@ -2227,7 +2213,7 @@ void ReflectionProbeGizmo::commit_handle(int p_idx, const Variant &p_restore, bo
ur->create_action(TTR("Change Probe Extents"));
ur->add_do_method(probe, "set_extents", probe->get_extents());
ur->add_do_method(probe, "set_origin_offset", probe->get_origin_offset());
- ur->add_undo_method(probe, "set_extents", restore.pos);
+ ur->add_undo_method(probe, "set_extents", restore.position);
ur->add_undo_method(probe, "set_origin_offset", restore.size);
ur->commit_action();
}
@@ -2241,7 +2227,7 @@ void ReflectionProbeGizmo::redraw() {
Vector3 extents = probe->get_extents();
Rect3 aabb;
- aabb.pos = -extents;
+ aabb.position = -extents;
aabb.size = extents * 2;
for (int i = 0; i < 12; i++) {
@@ -2262,7 +2248,7 @@ void ReflectionProbeGizmo::redraw() {
for (int i = 0; i < 3; i++) {
Vector3 ax;
- ax[i] = aabb.pos[i] + aabb.size[i];
+ ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
}
@@ -2392,7 +2378,7 @@ void GIProbeGizmo::redraw() {
for (int k = 0; k < 4; k++) {
- Vector3 from = aabb.pos, to = aabb.pos;
+ Vector3 from = aabb.position, to = aabb.position;
from[j] += cell_size * i;
to[j] += cell_size * i;
@@ -2421,7 +2407,7 @@ void GIProbeGizmo::redraw() {
for (int i = 0; i < 3; i++) {
Vector3 ax;
- ax[i] = aabb.pos[i] + aabb.size[i];
+ ax[i] = aabb.position[i] + aabb.size[i];
handles.push_back(ax);
}
@@ -2511,7 +2497,7 @@ void NavigationMeshSpatialGizmo::redraw() {
if (lines.size())
add_lines(lines, navmesh->is_enabled() ? SpatialEditorGizmos::singleton->navmesh_edge_material : SpatialEditorGizmos::singleton->navmesh_edge_material_disabled);
add_collision_triangles(tmesh);
- Ref<Mesh> m = memnew(Mesh);
+ Ref<ArrayMesh> m = memnew(ArrayMesh);
Array a;
a.resize(Mesh::ARRAY_MAX);
a[0] = tmeshfaces;
@@ -3045,12 +3031,6 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
return misg;
}
- if (p_spatial->cast_to<TestCube>()) {
-
- Ref<TestCubeSpatialGizmo> misg = memnew(TestCubeSpatialGizmo(p_spatial->cast_to<TestCube>()));
- return misg;
- }
-
if (p_spatial->cast_to<CollisionShape>()) {
Ref<CollisionShapeSpatialGizmo> misg = memnew(CollisionShapeSpatialGizmo(p_spatial->cast_to<CollisionShape>()));
@@ -3213,7 +3193,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
//position 3D Shared mesh
- pos3d_mesh = Ref<Mesh>(memnew(Mesh));
+ pos3d_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
{
PoolVector<Vector3> cursor_points;
@@ -3246,7 +3226,7 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
pos3d_mesh->surface_set_material(0, mat);
}
- listener_line_mesh = Ref<Mesh>(memnew(Mesh));
+ listener_line_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
{
PoolVector<Vector3> cursor_points;
diff --git a/editor/spatial_editor_gizmos.h b/editor/spatial_editor_gizmos.h
index 095586ab91..a8ace87530 100644
--- a/editor/spatial_editor_gizmos.h
+++ b/editor/spatial_editor_gizmos.h
@@ -46,7 +46,6 @@
#include "scene/3d/ray_cast.h"
#include "scene/3d/reflection_probe.h"
#include "scene/3d/room_instance.h"
-#include "scene/3d/test_cube.h"
#include "scene/3d/vehicle_body.h"
#include "scene/3d/visibility_notifier.h"
@@ -59,7 +58,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
struct Instance {
RID instance;
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
RID skeleton;
bool billboard;
bool unscaled;
@@ -97,7 +96,7 @@ class EditorSpatialGizmo : public SpatialEditorGizmo {
protected:
void add_lines(const Vector<Vector3> &p_lines, const Ref<Material> &p_material, bool p_billboard = false);
- void add_mesh(const Ref<Mesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
+ void add_mesh(const Ref<ArrayMesh> &p_mesh, bool p_billboard = false, const RID &p_skeleton = RID());
void add_collision_segments(const Vector<Vector3> &p_lines);
void add_collision_triangles(const Ref<TriangleMesh> &p_tmesh);
void add_unscaled_billboard(const Ref<Material> &p_material, float p_scale = 1);
@@ -187,17 +186,6 @@ public:
SkeletonSpatialGizmo(Skeleton *p_skel = NULL);
};
-class TestCubeSpatialGizmo : public EditorSpatialGizmo {
-
- GDCLASS(TestCubeSpatialGizmo, EditorSpatialGizmo);
-
- TestCube *tc;
-
-public:
- void redraw();
- TestCubeSpatialGizmo(TestCube *p_tc = NULL);
-};
-
class RoomSpatialGizmo : public EditorSpatialGizmo {
GDCLASS(RoomSpatialGizmo, EditorSpatialGizmo);
@@ -454,8 +442,8 @@ public:
Ref<SpatialMaterial> shape_material;
Ref<Texture> handle_t;
- Ref<Mesh> pos3d_mesh;
- Ref<Mesh> listener_line_mesh;
+ Ref<ArrayMesh> pos3d_mesh;
+ Ref<ArrayMesh> listener_line_mesh;
static SpatialEditorGizmos *singleton;
Ref<TriangleMesh> test_cube_tm;
diff --git a/editor/translations/ar.po b/editor/translations/ar.po
index 766d8f9676..867302b657 100644
--- a/editor/translations/ar.po
+++ b/editor/translations/ar.po
@@ -1,5 +1,6 @@
# Arabic translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# athomield <athomield@hotmail.com>, 2017.
diff --git a/editor/translations/bg.po b/editor/translations/bg.po
index b23fa3a8fb..f884b33773 100644
--- a/editor/translations/bg.po
+++ b/editor/translations/bg.po
@@ -1,5 +1,6 @@
# Bulgarian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Bojidar Marinov <bojidar.marinov.bg@gmail.com>, 2016.
diff --git a/editor/translations/bn.po b/editor/translations/bn.po
index 224c00cf5d..3e4dec7656 100644
--- a/editor/translations/bn.po
+++ b/editor/translations/bn.po
@@ -1,5 +1,6 @@
# Bengali translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Abu Md. Maruf Sarker <maruf.webdev@gmail.com>, 2016-2017.
diff --git a/editor/translations/ca.po b/editor/translations/ca.po
index 581e862716..6d7b245e58 100644
--- a/editor/translations/ca.po
+++ b/editor/translations/ca.po
@@ -1,5 +1,6 @@
# Catalan translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Roger BR <drai_kin@hotmail.com>, 2016.
diff --git a/editor/translations/cs.po b/editor/translations/cs.po
index 89d88a234f..4643a9ac21 100644
--- a/editor/translations/cs.po
+++ b/editor/translations/cs.po
@@ -1,5 +1,6 @@
# Czech translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Jan 'spl!te' Kondelík <j.kondelik@centrum.cz>, 2016.
diff --git a/editor/translations/da.po b/editor/translations/da.po
index b84be76247..ba9d018e5a 100644
--- a/editor/translations/da.po
+++ b/editor/translations/da.po
@@ -1,5 +1,6 @@
# Danish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# David Lamhauge <davidlamhauge@gmail.com>, 2016.
diff --git a/editor/translations/de.po b/editor/translations/de.po
index ba6805d1f1..a10eaefa29 100644
--- a/editor/translations/de.po
+++ b/editor/translations/de.po
@@ -1,5 +1,6 @@
# German translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Alexander Mahr <alex.mahr@gmail.com>, 2016.
diff --git a/editor/translations/de_CH.po b/editor/translations/de_CH.po
index aeae6a5537..183f09e9a6 100644
--- a/editor/translations/de_CH.po
+++ b/editor/translations/de_CH.po
@@ -1,5 +1,6 @@
# Swiss High German translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Christian Fisch <christian.fiesel@gmail.com>, 2016.
diff --git a/editor/translations/editor.pot b/editor/translations/editor.pot
index 5b62f132fa..5f50c159b8 100644
--- a/editor/translations/editor.pot
+++ b/editor/translations/editor.pot
@@ -1,5 +1,6 @@
# LANGUAGE translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/editor/translations/el.po b/editor/translations/el.po
index 292c5a6fd3..0879b693ff 100644
--- a/editor/translations/el.po
+++ b/editor/translations/el.po
@@ -1,5 +1,6 @@
# Greek translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# gtsiam <gtsiam@windowslive.com>, 2017.
diff --git a/editor/translations/es.po b/editor/translations/es.po
index a7b9553892..f01c84718b 100644
--- a/editor/translations/es.po
+++ b/editor/translations/es.po
@@ -1,5 +1,6 @@
# Spanish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Alejandro Alvarez <eliluminado00@gmail.com>, 2017.
diff --git a/editor/translations/es_AR.po b/editor/translations/es_AR.po
index 6c9579916f..f826517b27 100644
--- a/editor/translations/es_AR.po
+++ b/editor/translations/es_AR.po
@@ -1,5 +1,6 @@
# Spanish (Argentina) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Lisandro Lorea <lisandrolorea@gmail.com>, 2016-2017.
diff --git a/editor/translations/extract.py b/editor/translations/extract.py
index 616fec17a0..5e6c894936 100755
--- a/editor/translations/extract.py
+++ b/editor/translations/extract.py
@@ -38,7 +38,8 @@ unique_str = []
unique_loc = {}
main_po = """
# LANGUAGE translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
diff --git a/editor/translations/fa.po b/editor/translations/fa.po
index 2ec9b18d78..e8402fcb25 100644
--- a/editor/translations/fa.po
+++ b/editor/translations/fa.po
@@ -1,5 +1,6 @@
# Persian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# alabd14313 <alabd14313@yahoo.com>, 2016.
diff --git a/editor/translations/fr.po b/editor/translations/fr.po
index 1418e6f493..8db0cf2555 100644
--- a/editor/translations/fr.po
+++ b/editor/translations/fr.po
@@ -1,5 +1,6 @@
# French translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Brice <bbric@free.fr>, 2016.
diff --git a/editor/translations/hu.po b/editor/translations/hu.po
index 8cb6c2caf1..2d1b36d2ea 100644
--- a/editor/translations/hu.po
+++ b/editor/translations/hu.po
@@ -1,5 +1,6 @@
# Hungarian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Varga Dániel <danikah.danikah@gmail.com>, 2016.
diff --git a/editor/translations/id.po b/editor/translations/id.po
index 2126d324dd..2abf4090c8 100644
--- a/editor/translations/id.po
+++ b/editor/translations/id.po
@@ -1,5 +1,6 @@
# Indonesian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Abdul Aziz Muslim Alqudsy <abdul.aziz.muslim.alqudsy@gmail.com>, 2016.
diff --git a/editor/translations/it.po b/editor/translations/it.po
index e055c6996a..08d04d296b 100644
--- a/editor/translations/it.po
+++ b/editor/translations/it.po
@@ -1,5 +1,6 @@
# Italian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Dario Bonfanti <bonfi.96@hotmail.it>, 2016-2017.
diff --git a/editor/translations/ja.po b/editor/translations/ja.po
index f34e0d118b..beeaf264a2 100644
--- a/editor/translations/ja.po
+++ b/editor/translations/ja.po
@@ -1,5 +1,6 @@
# Japanese translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# akirakido <achts.y@gmail.com>, 2016.
diff --git a/editor/translations/ko.po b/editor/translations/ko.po
index 769089b860..08b10d2f7a 100644
--- a/editor/translations/ko.po
+++ b/editor/translations/ko.po
@@ -1,5 +1,6 @@
# Korean translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 박한얼 (volzhs) <volzhs@gmail.com>, 2016-2017.
diff --git a/editor/translations/nb.po b/editor/translations/nb.po
index e7a64f501a..7ce577ebfa 100644
--- a/editor/translations/nb.po
+++ b/editor/translations/nb.po
@@ -1,5 +1,6 @@
# Norwegian Bokmål translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Anonymous <GentleSaucepan@protonmail.com>, 2017.
diff --git a/editor/translations/nl.po b/editor/translations/nl.po
index 55407145d2..f0d54ebd9d 100644
--- a/editor/translations/nl.po
+++ b/editor/translations/nl.po
@@ -1,5 +1,6 @@
# Dutch translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Aram Nap <xyphex.aram@gmail.com>, 2017
diff --git a/editor/translations/pl.po b/editor/translations/pl.po
index 8eb2e9c884..ccee170c57 100644
--- a/editor/translations/pl.po
+++ b/editor/translations/pl.po
@@ -1,5 +1,6 @@
# Polish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 8-bit Pixel <dawdejw@gmail.com>, 2016.
diff --git a/editor/translations/pr.po b/editor/translations/pr.po
index 4df9c04664..4629c24f45 100644
--- a/editor/translations/pr.po
+++ b/editor/translations/pr.po
@@ -1,5 +1,6 @@
# Pirate translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Zion Nimchuk <zionnimchuk@gmail.com>, 2016-2017.
diff --git a/editor/translations/pt_BR.po b/editor/translations/pt_BR.po
index 75be59068c..25055a0b7b 100644
--- a/editor/translations/pt_BR.po
+++ b/editor/translations/pt_BR.po
@@ -1,5 +1,6 @@
# Portuguese (Brazil) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Allyson Souza <allyson_as@outlook.com>, 2017.
diff --git a/editor/translations/pt_PT.po b/editor/translations/pt_PT.po
index 913455b999..fa4629c5c1 100644
--- a/editor/translations/pt_PT.po
+++ b/editor/translations/pt_PT.po
@@ -1,5 +1,6 @@
# Portuguese (Portugal) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# António Sarmento <antonio.luis.sarmento@gmail.com>, 2016.
diff --git a/editor/translations/ru.po b/editor/translations/ru.po
index 9f7aa6e26a..0c4a29fb63 100644
--- a/editor/translations/ru.po
+++ b/editor/translations/ru.po
@@ -1,5 +1,6 @@
# Russian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# DimOkGamer <dimokgamer@gmail.com>, 2016-2017.
diff --git a/editor/translations/sk.po b/editor/translations/sk.po
index 697def1043..b0bee6aa6f 100644
--- a/editor/translations/sk.po
+++ b/editor/translations/sk.po
@@ -1,5 +1,6 @@
# Slovak translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# J08nY <johnenter@gmail.com>, 2016.
diff --git a/editor/translations/sl.po b/editor/translations/sl.po
index fad12d7f13..ea634658ce 100644
--- a/editor/translations/sl.po
+++ b/editor/translations/sl.po
@@ -1,5 +1,6 @@
# Slovenian translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# matevž lapajne <sivar.lapajne@gmail.com>, 2016.
diff --git a/editor/translations/th.po b/editor/translations/th.po
index 79cdaf6b10..b31532f3bf 100644
--- a/editor/translations/th.po
+++ b/editor/translations/th.po
@@ -1,5 +1,6 @@
# Thai translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Poommetee Ketson <poommetee@protonmail.com>, 2017.
diff --git a/editor/translations/tr.po b/editor/translations/tr.po
index 20a794b34a..b4d8975649 100644
--- a/editor/translations/tr.po
+++ b/editor/translations/tr.po
@@ -1,5 +1,6 @@
# Turkish translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Aprın Çor Tigin <kabusturk38@gmail.com>, 2016-2017.
diff --git a/editor/translations/ur_PK.po b/editor/translations/ur_PK.po
index 651aa62001..ef3e3b30ca 100644
--- a/editor/translations/ur_PK.po
+++ b/editor/translations/ur_PK.po
@@ -1,5 +1,6 @@
# Urdu (Pakistan) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Muhammad Ali <ali@codeonion.com>, 2016.
diff --git a/editor/translations/zh_CN.po b/editor/translations/zh_CN.po
index 87ca113ce2..f3afcab79d 100644
--- a/editor/translations/zh_CN.po
+++ b/editor/translations/zh_CN.po
@@ -1,5 +1,6 @@
# Chinese (China) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# 纯洁的坏蛋 <tqj.zyy@gmail.com>, 2016.
diff --git a/editor/translations/zh_HK.po b/editor/translations/zh_HK.po
index dfac75ecab..e49582e901 100644
--- a/editor/translations/zh_HK.po
+++ b/editor/translations/zh_HK.po
@@ -1,5 +1,6 @@
# Chinese (Honk Kong) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# Wesley (zx-wt) <ZX_WT@ymail.com>, 2016.
diff --git a/editor/translations/zh_TW.po b/editor/translations/zh_TW.po
index 48b76484e0..7836cd2f76 100644
--- a/editor/translations/zh_TW.po
+++ b/editor/translations/zh_TW.po
@@ -1,5 +1,6 @@
# Chinese (Taiwan) translation of the Godot Engine editor
-# Copyright (C) 2016-2017 Juan Linietsky, Ariel Manzur and the Godot community
+# Copyright (C) 2007-2017 Juan Linietsky, Ariel Manzur
+# Copyright (C) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)
# This file is distributed under the same license as the Godot source code.
#
# popcade <popcade@gmail.com>, 2016.
diff --git a/icon.png b/icon.png
index 7abb58ca7b..29c4a7b8fc 100644
--- a/icon.png
+++ b/icon.png
Binary files differ
diff --git a/icon.svg b/icon.svg
index 34747d34fe..5d075125e3 100644
--- a/icon.svg
+++ b/icon.svg
@@ -13,11 +13,11 @@
height="1024"
id="svg3030"
version="1.1"
- inkscape:version="0.91 r13725"
+ inkscape:version="0.92.1 r15371"
sodipodi:docname="icon.svg"
inkscape:export-filename="/home/akien/Projects/godot/godot.git/icon.png"
- inkscape:export-xdpi="22.5"
- inkscape:export-ydpi="22.5">
+ inkscape:export-xdpi="24"
+ inkscape:export-ydpi="24">
<defs
id="defs3032" />
<sodipodi:namedview
@@ -28,13 +28,13 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.35"
- inkscape:cx="-560.15123"
- inkscape:cy="190.62119"
+ inkscape:cx="707.24666"
+ inkscape:cy="14.063809"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1920"
- inkscape:window-height="1015"
+ inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
@@ -54,79 +54,86 @@
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
- transform="translate(0,-28.362183)">
+ transform="translate(0,-98.519719)">
<g
- id="g4149"
- transform="matrix(1.0688992,0,0,1.1334985,-45.061194,-81.689066)">
+ id="g78"
+ transform="matrix(4.162611,0,0,-4.162611,919.24059,771.67186)"
+ style="stroke-width:0.32031175">
<path
- sodipodi:nodetypes="cccccccccc"
- inkscape:connector-curvature="0"
- id="path3239"
- d="m 116.99388,715.36604 43.13957,-74.51381 75.99672,-171.42666 271.088,-13.63746 282.06373,14.1696 138.45065,255.56931 -25.0756,66.96734 -376.12685,53.39482 -367.70391,-40.32222 z"
- style="fill:#ffffff;fill-opacity:1;stroke:none" />
- <g
- transform="matrix(12.995388,0,0,-12.995388,898.37246,704.73082)"
- id="g3412">
- <path
- id="path3414"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 Z"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,140.10982,467.34929)"
- id="g3416">
- <path
- id="path3418"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 Z"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,411.4457,567.42812)"
- id="g3420">
- <path
- id="path3422"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,391.00655,572.46636)"
- id="g3424">
- <path
- id="path3426"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,526.30933,660.10985)"
- id="g3428">
- <path
- id="path3430"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,641.18731,567.42812)"
- id="g3432">
- <path
- id="path3434"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0"
- inkscape:connector-curvature="0" />
- </g>
- <g
- transform="matrix(12.995388,0,0,-12.995388,661.63165,572.46636)"
- id="g3436">
- <path
- id="path3438"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0"
- inkscape:connector-curvature="0" />
- </g>
+ d="m 0,0 c 0,0 -0.325,1.994 -0.515,1.976 l -36.182,-3.491 c -2.879,-0.278 -5.115,-2.574 -5.317,-5.459 l -0.994,-14.247 -27.992,-1.997 -1.904,12.912 c -0.424,2.872 -2.932,5.037 -5.835,5.037 h -38.188 c -2.902,0 -5.41,-2.165 -5.834,-5.037 l -1.905,-12.912 -27.992,1.997 -0.994,14.247 c -0.202,2.886 -2.438,5.182 -5.317,5.46 l -36.2,3.49 c -0.187,0.018 -0.324,-1.978 -0.511,-1.978 l -0.049,-7.83 30.658,-4.944 1.004,-14.374 c 0.203,-2.91 2.551,-5.263 5.463,-5.472 l 38.551,-2.75 c 0.146,-0.01 0.29,-0.016 0.434,-0.016 2.897,0 5.401,2.166 5.825,5.038 l 1.959,13.286 h 28.005 l 1.959,-13.286 c 0.423,-2.871 2.93,-5.037 5.831,-5.037 0.142,0 0.284,0.005 0.423,0.015 l 38.556,2.75 c 2.911,0.209 5.26,2.562 5.463,5.472 l 1.003,14.374 30.645,4.966 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path80"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g82-3"
+ transform="matrix(4.162611,0,0,-4.162611,104.69892,525.90697)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 v -47.514 -6.035 -5.492 c 0.108,-0.001 0.216,-0.005 0.323,-0.015 l 36.196,-3.49 c 1.896,-0.183 3.382,-1.709 3.514,-3.609 l 1.116,-15.978 31.574,-2.253 2.175,14.747 c 0.282,1.912 1.922,3.329 3.856,3.329 h 38.188 c 1.933,0 3.573,-1.417 3.855,-3.329 l 2.175,-14.747 31.575,2.253 1.115,15.978 c 0.133,1.9 1.618,3.425 3.514,3.609 l 36.182,3.49 c 0.107,0.01 0.214,0.014 0.322,0.015 v 4.711 l 0.015,0.005 V 0 h 0.134 c 4.795,6.12 9.232,12.569 13.487,19.449 -5.651,9.62 -12.575,18.217 -19.976,26.182 -6.864,-3.455 -13.531,-7.369 -19.828,-11.534 -3.151,3.132 -6.7,5.694 -10.186,8.372 -3.425,2.751 -7.285,4.768 -10.946,7.118 1.09,8.117 1.629,16.108 1.846,24.448 -9.446,4.754 -19.519,7.906 -29.708,10.17 -4.068,-6.837 -7.788,-14.241 -11.028,-21.479 -3.842,0.642 -7.702,0.88 -11.567,0.926 v 0.006 c -0.027,0 -0.052,-0.006 -0.075,-0.006 -0.024,0 -0.049,0.006 -0.073,0.006 V 63.652 C 93.903,63.606 90.046,63.368 86.203,62.726 82.965,69.964 79.247,77.368 75.173,84.205 64.989,81.941 54.915,78.789 45.47,74.035 45.686,65.695 46.225,57.704 47.318,49.587 43.65,47.237 39.795,45.22 36.369,42.469 32.888,39.791 29.333,37.229 26.181,34.097 19.884,38.262 13.219,42.176 6.353,45.631 -1.048,37.666 -7.968,29.069 -13.621,19.449 -9.368,12.569 -4.928,6.12 -0.134,0 Z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path84-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g86-7"
+ transform="matrix(4.162611,0,0,-4.162611,784.07144,817.24284)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 -1.121,-16.063 c -0.135,-1.936 -1.675,-3.477 -3.611,-3.616 l -38.555,-2.751 c -0.094,-0.007 -0.188,-0.01 -0.281,-0.01 -1.916,0 -3.569,1.406 -3.852,3.33 l -2.211,14.994 H -81.09 l -2.211,-14.994 c -0.297,-2.018 -2.101,-3.469 -4.133,-3.32 l -38.555,2.751 c -1.936,0.139 -3.476,1.68 -3.611,3.616 L -130.721,0 -163.268,3.138 c 0.015,-3.498 0.06,-7.33 0.06,-8.093 0,-34.374 43.605,-50.896 97.781,-51.086 h 0.066 0.067 c 54.176,0.19 97.766,16.712 97.766,51.086 0,0.777 0.047,4.593 0.063,8.093 z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path88-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g90-3"
+ transform="matrix(4.162611,0,0,-4.162611,389.21484,625.67104)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 c 0,-12.052 -9.765,-21.815 -21.813,-21.815 -12.042,0 -21.81,9.763 -21.81,21.815 0,12.044 9.768,21.802 21.81,21.802 C -9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path92-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g94-6"
+ transform="matrix(4.162611,0,0,-4.162611,367.36686,631.05679)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 c 0,-7.994 -6.479,-14.473 -14.479,-14.473 -7.996,0 -14.479,6.479 -14.479,14.473 0,7.994 6.483,14.479 14.479,14.479 C -6.479,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path96-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g98-9"
+ transform="matrix(4.162611,0,0,-4.162611,511.99336,724.73954)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 c -3.878,0 -7.021,2.858 -7.021,6.381 v 20.081 c 0,3.52 3.143,6.381 7.021,6.381 3.878,0 7.028,-2.861 7.028,-6.381 V 6.381 C 7.028,2.858 3.878,0 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path100-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g102-2"
+ transform="matrix(4.162611,0,0,-4.162611,634.78706,625.67104)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 c 0,-12.052 9.765,-21.815 21.815,-21.815 12.041,0 21.808,9.763 21.808,21.815 0,12.044 -9.767,21.802 -21.808,21.802 C 9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path104-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g106-0"
+ transform="matrix(4.162611,0,0,-4.162611,656.64056,631.05679)"
+ style="stroke-width:0.32031175">
+ <path
+ d="m 0,0 c 0,-7.994 6.477,-14.473 14.471,-14.473 8.002,0 14.479,6.479 14.479,14.473 0,7.994 -6.477,14.479 -14.479,14.479 C 6.477,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.32031175"
+ id="path108-9"
+ inkscape:connector-curvature="0" />
</g>
</g>
</svg>
diff --git a/logo.png b/logo.png
index d6cab7f11b..8cf3e15ebc 100644
--- a/logo.png
+++ b/logo.png
Binary files differ
diff --git a/logo.svg b/logo.svg
index 98dcddfd2b..865712b345 100644
--- a/logo.svg
+++ b/logo.svg
@@ -1,134 +1,219 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- viewBox="0 0 236.27499 84.6875"
- height="84.6875"
- width="236.27499"
- xml:space="preserve"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ id="svg2"
version="1.1"
- id="svg3336"><metadata
- id="metadata3342"><rdf:RDF><cc:Work
+ inkscape:version="0.92.1 r15371"
+ xml:space="preserve"
+ width="1024"
+ height="414"
+ viewBox="0 0 959.99998 388.125"
+ sodipodi:docname="logo.svg"
+ inkscape:export-filename="/home/akien/Projects/godot/godot.git/logo.png"
+ inkscape:export-xdpi="48"
+ inkscape:export-ydpi="48"><metadata
+ id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
- id="defs3340"><clipPath
- id="clipPath3350"
- clipPathUnits="userSpaceOnUse"><path
- id="path3352"
- d="m 0,67.75 189.02,0 L 189.02,0 0,0 0,67.75 Z" /></clipPath></defs><g
- transform="matrix(1.25,0,0,-1.25,0,84.6875)"
- id="g3344"><g
- id="g3346"><g
- clip-path="url(#clipPath3350)"
- id="g3348"><g
- transform="translate(112.7847,43.5176)"
- id="g3354"><path
- id="path3356"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -1.082,0 -1.989,-0.497 -2.724,-1.488 -0.732,-0.992 -1.099,-2.385 -1.099,-4.177 0,-1.796 0.349,-3.171 1.05,-4.129 0.699,-0.961 1.617,-1.439 2.756,-1.439 1.139,0 2.064,0.484 2.775,1.457 0.71,0.968 1.066,2.355 1.066,4.161 0,1.803 -0.367,3.192 -1.1,4.162 C 1.992,-0.484 1.083,0 0,0 m -0.017,-17.828 c -3.168,0 -5.752,1.037 -7.749,3.11 -1.994,2.075 -2.991,5.104 -2.991,9.084 0,3.984 1.008,6.999 3.027,9.053 2.018,2.051 4.624,3.077 7.815,3.077 3.191,0 5.769,-1.008 7.73,-3.029 1.964,-2.018 2.945,-5.076 2.945,-9.167 0,-4.094 -1.004,-7.139 -3.012,-9.137 -2.008,-1.994 -4.595,-2.991 -7.765,-2.991" /></g><g
- transform="translate(133.0269,43.2832)"
- id="g3358"><path
- id="path3360"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0,-10.119 c 0,-0.473 0.035,-0.771 0.103,-0.896 0.066,-0.124 0.27,-0.186 0.607,-0.186 1.242,0 2.183,0.464 2.826,1.388 0.645,0.924 0.964,2.462 0.964,4.617 0,2.155 -0.334,3.559 -0.997,4.212 C 2.837,-0.33 1.782,0 0.338,0 L 0,0 Z m -6.495,-15.7 0,20.298 c 0,0.564 0.14,1.009 0.423,1.34 0.281,0.325 0.648,0.49 1.1,0.49 l 5.65,0 c 3.586,0 6.309,-0.905 8.168,-2.709 1.862,-1.804 2.794,-4.645 2.794,-8.525 0,-8.3 -3.543,-12.45 -10.625,-12.45 l -5.785,0 c -1.149,0 -1.725,0.518 -1.725,1.556" /></g><g
- transform="translate(157.6558,43.5176)"
- id="g3362"><path
- id="path3364"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -1.083,0 -1.991,-0.497 -2.726,-1.488 -0.731,-0.992 -1.097,-2.385 -1.097,-4.177 0,-1.796 0.35,-3.171 1.049,-4.129 0.698,-0.961 1.617,-1.439 2.756,-1.439 1.14,0 2.065,0.484 2.775,1.457 0.711,0.968 1.067,2.355 1.067,4.161 0,1.803 -0.367,3.192 -1.1,4.162 C 1.99,-0.484 1.083,0 0,0 m -0.018,-17.828 c -3.169,0 -5.751,1.037 -7.746,3.11 -1.997,2.075 -2.995,5.104 -2.995,9.084 0,3.984 1.009,6.999 3.027,9.053 2.02,2.051 4.624,3.077 7.817,3.077 3.192,0 5.768,-1.008 7.73,-3.029 1.963,-2.018 2.944,-5.076 2.944,-9.167 0,-4.094 -1.004,-7.139 -3.012,-9.137 -2.007,-1.994 -4.596,-2.991 -7.765,-2.991" /></g><g
- transform="translate(181.0239,26.5664)"
- id="g3366"><path
- id="path3368"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-0.448 -1.115,-0.676 -3.349,-0.676 -2.232,0 -3.35,0.228 -3.35,0.676 l 0,16.985 -4.059,0 c -0.384,0 -0.655,0.518 -0.812,1.558 -0.068,0.495 -0.1,1.002 -0.1,1.521 0,0.517 0.032,1.026 0.1,1.522 0.157,1.037 0.428,1.559 0.812,1.559 l 14.717,0 c 0.383,0 0.653,-0.522 0.812,-1.559 0.067,-0.496 0.101,-1.005 0.101,-1.522 0,-0.519 -0.034,-1.026 -0.101,-1.521 C 4.612,17.503 4.342,16.985 3.959,16.985 L 0,16.985 0,0 Z" /></g><g
- transform="translate(96.0444,38.5889)"
- id="g3370"><path
- id="path3372"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -1.821,0.028 -3.906,-0.352 -3.906,-0.352 l 0,-3.554 2.096,0 -0.023,-1.585 c 0,-0.587 -0.582,-0.882 -1.743,-0.882 -1.162,0 -2.188,0.492 -3.078,1.474 -0.893,0.982 -1.337,2.419 -1.337,4.311 0,1.897 0.434,3.295 1.303,4.197 0.866,0.902 2.002,1.354 3.399,1.354 0.587,0 1.195,-0.095 1.827,-0.288 0.632,-0.192 1.055,-0.371 1.27,-0.539 0.214,-0.173 0.417,-0.255 0.609,-0.255 0.191,0 0.501,0.223 0.929,0.676 0.429,0.451 0.813,1.134 1.152,2.046 0.337,0.916 0.506,1.618 0.506,2.116 0,0.494 -0.01,0.835 -0.032,1.014 -0.474,0.519 -1.348,0.93 -2.624,1.236 -1.273,0.304 -2.7,0.456 -4.279,0.456 -3.474,0 -6.191,-1.094 -8.153,-3.281 -1.963,-2.189 -2.943,-5.03 -2.943,-8.527 0,-4.105 1.003,-7.218 3.008,-9.338 2.01,-2.12 4.648,-3.178 7.919,-3.178 1.759,0 3.321,0.151 4.684,0.456 1.366,0.303 2.274,0.615 2.726,0.93 L 3.445,-0.926 C 3.445,-0.311 1.821,-0.031 0,0" /></g><g
- transform="translate(88.9126,11.8398)"
- id="g3374"><path
- id="path3376"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -0.187,-0.384 -0.531,-0.735 -1.034,-1.054 -0.502,-0.32 -1.14,-0.479 -1.915,-0.479 -1.022,0 -1.844,0.322 -2.469,0.973 -0.622,0.647 -0.934,1.579 -0.934,2.794 l 0,3.032 c 0,1.189 0.294,2.101 0.883,2.738 0.588,0.632 1.376,0.952 2.359,0.952 0.962,0 1.707,-0.253 2.234,-0.753 C -0.35,7.701 -0.074,7 -0.05,6.104 l -0.013,-0.04 -0.785,0 C -0.876,6.751 -1.075,7.28 -1.45,7.654 -1.823,8.025 -2.377,8.213 -3.11,8.213 -3.851,8.213 -4.438,7.962 -4.868,7.459 -5.296,6.957 -5.51,6.229 -5.51,5.273 l 0,-3.048 c 0,-0.992 0.231,-1.747 0.693,-2.268 0.461,-0.517 1.083,-0.775 1.868,-0.775 0.574,0 1.034,0.101 1.379,0.309 0.346,0.205 0.587,0.455 0.722,0.752 l 0,2.655 -2.115,0 0,0.739 L 0,3.637 0,0 Z" /></g><g
- transform="translate(92.7988,11.0645)"
- id="g3378"><path
- id="path3380"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0.465,0 0.88,0.132 1.242,0.4 0.362,0.27 0.616,0.611 0.767,1.026 l 0,1.638 -1.346,0 C 0.091,3.064 -0.368,2.902 -0.711,2.578 -1.055,2.256 -1.225,1.854 -1.225,1.375 -1.225,0.971 -1.119,0.639 -0.903,0.383 -0.688,0.126 -0.387,0 0,0 M 2.135,-0.611 C 2.093,-0.349 2.06,-0.136 2.04,0.031 2.02,0.201 2.009,0.37 2.009,0.542 1.779,0.166 1.483,-0.146 1.116,-0.39 0.75,-0.636 0.343,-0.758 -0.105,-0.758 c -0.627,0 -1.109,0.195 -1.45,0.583 -0.34,0.391 -0.511,0.917 -0.511,1.581 0,0.702 0.247,1.266 0.741,1.684 0.494,0.418 1.166,0.627 2.011,0.627 l 1.323,0 0,0.93 C 2.009,5.183 1.873,5.604 1.604,5.909 1.331,6.21 0.954,6.362 0.468,6.362 0.017,6.362 -0.356,6.219 -0.649,5.928 -0.94,5.639 -1.085,5.285 -1.085,4.864 l -0.786,0.007 -0.014,0.041 c -0.022,0.571 0.194,1.076 0.65,1.524 0.454,0.446 1.036,0.668 1.745,0.668 0.701,0 1.265,-0.213 1.696,-0.638 0.428,-0.429 0.643,-1.04 0.643,-1.835 l 0,-3.715 c 0,-0.27 0.012,-0.533 0.036,-0.784 0.024,-0.254 0.063,-0.499 0.125,-0.743 l -0.875,0 z" /></g><g
- transform="translate(98.2871,18.0273)"
- id="g3382"><path
- id="path3384"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0.072,-1.176 c 0.199,0.421 0.466,0.745 0.796,0.976 0.332,0.227 0.722,0.341 1.171,0.341 0.457,0 0.843,-0.133 1.154,-0.403 0.311,-0.268 0.541,-0.675 0.687,-1.22 0.186,0.503 0.451,0.902 0.794,1.19 0.343,0.289 0.759,0.433 1.242,0.433 0.664,0 1.179,-0.269 1.544,-0.807 0.367,-0.539 0.55,-1.366 0.55,-2.483 l 0,-4.425 -0.846,0 0,4.439 c 0,0.929 -0.128,1.583 -0.378,1.959 -0.252,0.377 -0.612,0.567 -1.078,0.567 -0.491,0 -0.874,-0.207 -1.149,-0.628 C 4.285,-1.658 4.116,-2.185 4.054,-2.82 l 0,-0.197 0,-4.557 -0.842,0 0,4.434 c 0,0.908 -0.127,1.557 -0.387,1.945 -0.259,0.387 -0.619,0.58 -1.081,0.58 -0.442,0 -0.8,-0.135 -1.068,-0.403 C 0.407,-1.286 0.215,-1.654 0.099,-2.121 l 0,-5.453 -0.841,0 0,7.574 L 0,0 Z" /></g><g
- transform="translate(110.499,17.4268)"
- id="g3386"><path
- id="path3388"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -0.527,0 -0.959,-0.24 -1.299,-0.72 -0.339,-0.481 -0.514,-1.074 -0.529,-1.781 l 3.495,0 0,0.324 c 0,0.625 -0.147,1.146 -0.441,1.559 C 0.931,-0.205 0.523,0 0,0 m 0.119,-7.12 c -0.817,0 -1.485,0.307 -2.003,0.921 -0.517,0.612 -0.777,1.395 -0.777,2.349 l 0,1.258 c 0,0.956 0.26,1.753 0.78,2.387 0.521,0.631 1.147,0.946 1.881,0.946 0.793,0 1.408,-0.281 1.847,-0.845 0.44,-0.566 0.66,-1.326 0.66,-2.279 l 0,-0.831 -4.335,0 0,-0.63 c 0,-0.733 0.176,-1.344 0.525,-1.831 0.35,-0.488 0.826,-0.73 1.422,-0.73 0.414,0 0.775,0.073 1.075,0.217 0.301,0.147 0.558,0.353 0.773,0.624 L 2.311,-6.16 C 2.083,-6.45 1.786,-6.685 1.424,-6.858 1.063,-7.031 0.627,-7.12 0.119,-7.12" /></g><g
- transform="translate(119.8403,17.4268)"
- id="g3390"><path
- id="path3392"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -0.528,0 -0.962,-0.24 -1.301,-0.72 -0.337,-0.481 -0.513,-1.074 -0.528,-1.781 l 3.495,0 0,0.324 c 0,0.625 -0.146,1.146 -0.442,1.559 C 0.93,-0.205 0.522,0 0,0 m 0.118,-7.12 c -0.817,0 -1.484,0.307 -2.001,0.921 -0.52,0.612 -0.78,1.395 -0.78,2.349 l 0,1.258 c 0,0.956 0.262,1.753 0.78,2.387 C -1.36,0.426 -0.734,0.741 0,0.741 0.792,0.741 1.409,0.46 1.847,-0.104 2.286,-0.67 2.505,-1.43 2.505,-2.383 l 0,-0.831 -4.334,0 0,-0.63 c 0,-0.733 0.176,-1.344 0.527,-1.831 0.348,-0.488 0.822,-0.73 1.42,-0.73 0.416,0 0.775,0.073 1.074,0.217 0.302,0.147 0.559,0.353 0.776,0.624 L 2.31,-6.16 C 2.081,-6.45 1.786,-6.685 1.423,-6.858 1.063,-7.031 0.627,-7.12 0.118,-7.12" /></g><g
- transform="translate(124.5659,18.0273)"
- id="g3394"><path
- id="path3396"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0.069,-1.252 c 0.202,0.444 0.469,0.789 0.804,1.029 0.332,0.242 0.723,0.364 1.172,0.364 0.677,0 1.196,-0.25 1.556,-0.753 0.363,-0.502 0.544,-1.283 0.544,-2.341 l 0,-4.621 -0.847,0 0,4.613 c 0,0.865 -0.127,1.47 -0.379,1.82 -0.251,0.351 -0.619,0.526 -1.098,0.526 -0.43,0 -0.791,-0.14 -1.08,-0.424 C 0.451,-1.32 0.234,-1.695 0.09,-2.168 l 0,-5.406 -0.84,0 L -0.75,0 0,0 Z" /></g><g
- transform="translate(131.1768,13.5771)"
- id="g3398"><path
- id="path3400"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-0.769 0.146,-1.38 0.441,-1.835 0.292,-0.459 0.736,-0.686 1.33,-0.686 0.406,0 0.748,0.109 1.029,0.331 0.28,0.221 0.501,0.53 0.664,0.921 l 0,3.752 C 3.307,2.887 3.091,3.213 2.818,3.464 2.545,3.711 2.2,3.835 1.785,3.835 1.193,3.835 0.746,3.577 0.448,3.06 0.149,2.541 0,1.865 0,1.035 L 0,0 Z m -0.849,1.035 c 0,1.073 0.217,1.936 0.652,2.585 0.432,0.647 1.033,0.971 1.8,0.971 0.425,0 0.798,-0.104 1.117,-0.312 C 3.039,4.075 3.303,3.776 3.515,3.396 l 0.082,1.054 0.714,0 0,-7.581 c 0,-0.971 -0.226,-1.723 -0.678,-2.255 -0.452,-0.53 -1.095,-0.799 -1.926,-0.799 -0.298,0 -0.619,0.047 -0.962,0.138 -0.344,0.091 -0.648,0.21 -0.915,0.359 l 0.233,0.739 c 0.227,-0.148 0.481,-0.262 0.763,-0.342 0.279,-0.083 0.568,-0.123 0.867,-0.123 0.602,0 1.049,0.193 1.337,0.579 0.289,0.391 0.434,0.956 0.434,1.704 l 0,0.916 C 3.25,-2.556 2.986,-2.817 2.673,-2.998 2.362,-3.18 1.998,-3.271 1.588,-3.271 c -0.761,0 -1.358,0.298 -1.789,0.894 -0.431,0.595 -0.648,1.388 -0.648,2.377 l 0,1.035 z" /></g><path
- id="path3402"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 138.318,10.453 -0.848,0 0,7.574 0.848,0 0,-7.574 z m 0,9.731 -0.848,0 0,1.193 0.848,0 0,-1.193 z" /><g
- transform="translate(141.0552,18.0273)"
- id="g3404"><path
- id="path3406"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0.069,-1.252 c 0.202,0.444 0.468,0.789 0.803,1.029 0.334,0.242 0.725,0.364 1.173,0.364 0.677,0 1.197,-0.25 1.558,-0.753 0.363,-0.502 0.542,-1.283 0.542,-2.341 l 0,-4.621 -0.847,0 0,4.613 c 0,0.865 -0.127,1.47 -0.378,1.82 -0.253,0.351 -0.618,0.526 -1.099,0.526 -0.43,0 -0.79,-0.14 -1.079,-0.424 C 0.453,-1.32 0.235,-1.695 0.092,-2.168 l 0,-5.406 -0.842,0 L -0.75,0 0,0 Z" /></g><g
- transform="translate(149.4155,17.4268)"
- id="g3408"><path
- id="path3410"
- style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -0.528,0 -0.961,-0.24 -1.299,-0.72 -0.338,-0.481 -0.514,-1.074 -0.53,-1.781 l 3.495,0 0,0.324 c 0,0.625 -0.145,1.146 -0.44,1.559 C 0.932,-0.205 0.523,0 0,0 m 0.12,-7.12 c -0.819,0 -1.486,0.307 -2.002,0.921 -0.518,0.612 -0.778,1.395 -0.778,2.349 l 0,1.258 c 0,0.956 0.26,1.753 0.78,2.387 0.521,0.631 1.148,0.946 1.88,0.946 0.793,0 1.41,-0.281 1.85,-0.845 0.438,-0.566 0.657,-1.326 0.657,-2.279 l 0,-0.831 -4.336,0 0,-0.63 c 0,-0.733 0.177,-1.344 0.527,-1.831 0.349,-0.488 0.823,-0.73 1.422,-0.73 0.414,0 0.773,0.073 1.072,0.217 0.304,0.147 0.56,0.353 0.777,0.624 L 2.313,-6.16 C 2.082,-6.45 1.787,-6.685 1.425,-6.858 1.064,-7.031 0.628,-7.12 0.12,-7.12" /></g><g
- transform="translate(64.312,21.7949)"
- id="g3412"><path
- id="path3414"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0,-3.942 c 0,-0.39 -0.25,-0.734 -0.621,-0.852 L -6.835,-6.8 c -0.273,-0.091 -0.57,-0.042 -0.8,0.128 -0.232,0.168 -0.37,0.437 -0.37,0.721 l 0,4.305 -5.818,-1.108 0,-4.381 c 0,-0.447 -0.332,-0.824 -0.775,-0.885 l -8.41,-1.152 c -0.039,-0.003 -0.081,-0.008 -0.121,-0.008 -0.214,0 -0.424,0.078 -0.588,0.22 -0.195,0.172 -0.306,0.416 -0.306,0.676 l 0,4.638 -4.341,-0.018 0,-10e-4 -0.318,10e-4 -0.319,-10e-4 0,10e-4 -4.34,0.018 0,-4.638 c 0,-0.26 -0.112,-0.504 -0.307,-0.676 -0.164,-0.142 -0.374,-0.22 -0.587,-0.22 -0.041,0 -0.082,0.005 -0.123,0.008 l -8.41,1.152 c -0.442,0.061 -0.774,0.438 -0.774,0.885 l 0,4.381 -5.819,1.108 0,-4.305 c 0,-0.284 -0.137,-0.553 -0.368,-0.721 -0.232,-0.17 -0.529,-0.219 -0.802,-0.128 l -6.215,2.006 c -0.369,0.118 -0.619,0.462 -0.619,0.852 l 0,3.942 -3.837,1.29 c -0.19,-0.811 -0.295,-1.642 -0.295,-2.481 0,-10.301 14.512,-18.252 32.448,-18.309 l 0.022,0 0.023,0 c 17.936,0.057 32.448,8.008 32.448,18.309 0,0.766 -0.088,1.521 -0.247,2.266 L 0,0 Z" /></g><g
- transform="translate(5.9634,40.0615)"
- id="g3416"><path
- id="path3418"
- style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 0,-16.047 2.163,-0.729 c 0.364,-0.122 0.61,-0.462 0.61,-0.847 l 0,-3.936 4.426,-1.428 0,4.154 c 0,0.27 0.118,0.52 0.323,0.689 0.206,0.172 0.474,0.241 0.739,0.192 l 7.608,-1.452 c 0.422,-0.079 0.728,-0.448 0.728,-0.877 l 0,-4.338 6.62,-0.904 0,4.509 c 0,0.241 0.096,0.467 0.264,0.635 0.167,0.166 0.394,0.259 0.633,0.259 l 0.002,0 5.551,-0.022 5.549,0.022 c 0.245,-10e-4 0.468,-0.093 0.635,-0.259 0.169,-0.168 0.264,-0.394 0.264,-0.635 l 0,-4.509 6.621,0.904 0,4.338 c 0,0.429 0.304,0.798 0.726,0.877 l 7.609,1.452 c 0.262,0.049 0.533,-0.02 0.738,-0.192 0.205,-0.169 0.325,-0.419 0.325,-0.689 l 0,-4.154 4.425,1.428 0,3.936 c 0,0.385 0.245,0.725 0.609,0.847 l 1.475,0.497 0,16.279 0.04,0 c 1.437,1.834 2.767,3.767 4.042,5.828 -1.694,2.883 -3.768,5.459 -5.986,7.846 -2.057,-1.035 -4.055,-2.208 -5.942,-3.456 -0.944,0.938 -2.008,1.706 -3.052,2.509 -1.027,0.824 -2.183,1.428 -3.281,2.132 0.327,2.433 0.489,4.828 0.554,7.327 -2.831,1.424 -5.85,2.369 -8.903,3.047 -1.219,-2.048 -2.334,-4.267 -3.304,-6.436 -1.152,0.192 -2.309,0.264 -3.467,0.277 l 0,0.002 c -0.008,0 -0.015,-0.002 -0.022,-0.002 -0.008,0 -0.015,0.002 -0.022,0.002 l 0,-0.002 c -1.16,-0.013 -2.316,-0.085 -3.468,-0.277 -0.97,2.169 -2.084,4.388 -3.305,6.436 C 19.475,24.555 16.456,23.61 13.626,22.186 13.69,19.687 13.852,17.292 14.18,14.859 13.081,14.155 11.925,13.551 10.898,12.727 9.855,11.924 8.79,11.156 7.846,10.218 5.958,11.466 3.961,12.639 1.904,13.674 -0.314,11.287 -2.388,8.711 -4.082,5.828 -2.807,3.767 -1.477,1.834 -0.04,0 L 0,0 Z" /></g><g
- transform="translate(26.8428,32.3604)"
- id="g3420"><path
- id="path3422"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-3.611 -2.926,-6.537 -6.537,-6.537 -3.608,0 -6.535,2.926 -6.535,6.537 0,3.609 2.927,6.533 6.535,6.533 C -2.926,6.533 0,3.609 0,0" /></g><g
- transform="translate(25.27,31.9727)"
- id="g3424"><path
- id="path3426"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-2.396 -1.941,-4.337 -4.339,-4.337 -2.396,0 -4.339,1.941 -4.339,4.337 0,2.396 1.943,4.339 4.339,4.339 C -1.941,4.339 0,2.396 0,0" /></g><g
- transform="translate(35.6816,25.2285)"
- id="g3428"><path
- id="path3430"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c -1.162,0 -2.104,0.856 -2.104,1.912 l 0,6.018 c 0,1.054 0.942,1.912 2.104,1.912 1.162,0 2.106,-0.858 2.106,-1.912 l 0,-6.018 C 2.106,0.856 1.162,0 0,0" /></g><g
- transform="translate(44.5215,32.3604)"
- id="g3432"><path
- id="path3434"
- style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-3.611 2.926,-6.537 6.537,-6.537 3.609,0 6.535,2.926 6.535,6.537 0,3.609 -2.926,6.533 -6.535,6.533 C 2.926,6.533 0,3.609 0,0" /></g><g
- transform="translate(46.0947,31.9727)"
- id="g3436"><path
- id="path3438"
- style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none"
- d="m 0,0 c 0,-2.396 1.941,-4.337 4.336,-4.337 2.398,0 4.339,1.941 4.339,4.337 0,2.396 -1.941,4.339 -4.339,4.339 C 1.941,4.339 0,2.396 0,0" /></g></g></g></g></svg> \ No newline at end of file
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title /></cc:Work></rdf:RDF></metadata><defs
+ id="defs6"><clipPath
+ clipPathUnits="userSpaceOnUse"
+ id="clipPath16"><path
+ d="M 0,595.276 H 841.89 V 0 H 0 Z"
+ id="path18"
+ inkscape:connector-curvature="0" /></clipPath></defs><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="1920"
+ inkscape:window-height="1011"
+ id="namedview4"
+ showgrid="false"
+ inkscape:zoom="0.63432763"
+ inkscape:cx="166.44059"
+ inkscape:cy="101.14582"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g14"
+ fit-margin-top="48"
+ fit-margin-left="48"
+ fit-margin-right="48"
+ fit-margin-bottom="48" /><g
+ id="g10"
+ inkscape:groupmode="layer"
+ inkscape:label="godot_engine_logo_2017_curves-01"
+ transform="matrix(1.25,0,0,-1.25,-94.249997,597.49874)"><g
+ id="g12"><g
+ id="g14"
+ clip-path="url(#clipPath16)"><g
+ id="g20"
+ transform="matrix(1.1310535,0,0,1.1310535,531.44953,355.31567)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -3.611,0 -6.636,-1.659 -9.09,-4.967 -2.441,-3.311 -3.668,-7.958 -3.668,-13.938 0,-5.993 1.166,-10.581 3.503,-13.778 2.333,-3.207 5.398,-4.804 9.2,-4.804 3.8,0 6.887,1.617 9.258,4.862 2.371,3.233 3.559,7.861 3.559,13.886 0,6.02 -1.227,10.654 -3.673,13.89 C 6.646,-1.617 3.616,0 0,0 m -0.055,-59.493 c -10.573,0 -19.195,3.46 -25.859,10.379 -6.655,6.925 -9.984,17.03 -9.984,30.314 0,13.292 3.367,23.356 10.101,30.209 6.736,6.844 15.431,10.269 26.082,10.269 10.649,0 19.251,-3.363 25.794,-10.109 6.555,-6.733 9.827,-16.94 9.827,-30.591 0,-13.661 -3.348,-23.822 -10.05,-30.49 -6.702,-6.654 -15.333,-9.981 -25.911,-9.981"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path22"
+ inkscape:connector-curvature="0" /></g><g
+ id="g24"
+ transform="matrix(1.1310535,0,0,1.1310535,607.8515,354.43097)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 v -33.768 c 0,-1.577 0.116,-2.571 0.342,-2.988 0.224,-0.415 0.903,-0.623 2.029,-0.623 4.144,0 7.283,1.548 9.429,4.634 2.151,3.083 3.215,8.216 3.215,15.405 0,7.192 -1.113,11.878 -3.325,14.055 C 9.467,-1.102 5.946,0 1.129,0 Z m -21.675,-52.392 v 67.735 c 0,1.883 0.468,3.369 1.413,4.471 0.939,1.085 2.161,1.636 3.671,1.636 H 2.263 c 11.965,0 21.053,-3.018 27.257,-9.04 6.215,-6.02 9.322,-15.499 9.322,-28.447 0,-27.7 -11.821,-41.547 -35.456,-41.547 h -19.302 c -3.836,0 -5.759,1.727 -5.759,5.192"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path26"
+ inkscape:connector-curvature="0" /></g><g
+ id="g28"
+ transform="matrix(1.1310535,0,0,1.1310535,700.81066,355.31567)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -3.612,0 -6.645,-1.659 -9.095,-4.967 -2.44,-3.311 -3.662,-7.958 -3.662,-13.938 0,-5.993 1.169,-10.581 3.499,-13.778 2.33,-3.207 5.398,-4.804 9.2,-4.804 3.801,0 6.89,1.617 9.258,4.862 2.372,3.233 3.56,7.861 3.56,13.886 0,6.02 -1.225,10.654 -3.671,13.89 C 6.642,-1.617 3.616,0 0,0 m -0.058,-59.493 c -10.577,0 -19.193,3.46 -25.851,10.379 -6.663,6.925 -9.993,17.03 -9.993,30.314 0,13.292 3.367,23.356 10.1,30.209 6.741,6.844 15.431,10.269 26.086,10.269 10.651,0 19.246,-3.363 25.797,-10.109 6.55,-6.733 9.822,-16.94 9.822,-30.591 0,-13.661 -3.349,-23.822 -10.05,-30.49 -6.699,-6.654 -15.338,-9.981 -25.911,-9.981"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path30"
+ inkscape:connector-curvature="0" /></g><g
+ id="g32"
+ transform="matrix(1.1310535,0,0,1.1310535,789.01132,291.33514)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-1.496 -3.721,-2.255 -11.176,-2.255 -7.448,0 -11.18,0.759 -11.18,2.255 v 56.681 h -13.545 c -1.281,0 -2.185,1.727 -2.71,5.198 -0.226,1.652 -0.334,3.343 -0.334,5.077 0,1.724 0.108,3.422 0.334,5.077 0.525,3.462 1.429,5.202 2.71,5.202 h 49.112 c 1.279,0 2.179,-1.74 2.712,-5.202 0.221,-1.655 0.335,-3.353 0.335,-5.077 0,-1.734 -0.114,-3.425 -0.335,-5.077 C 15.39,58.408 14.49,56.681 13.211,56.681 H 0 Z"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path34"
+ inkscape:connector-curvature="0" /></g><g
+ id="g36"
+ transform="matrix(1.1310535,0,0,1.1310535,468.26549,336.71278)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -6.078,0.094 -13.034,-1.173 -13.034,-1.173 v -11.863 h 6.995 l -0.078,-5.288 c 0,-1.959 -1.942,-2.943 -5.815,-2.943 -3.878,0 -7.303,1.642 -10.274,4.917 -2.978,3.279 -4.459,8.072 -4.459,14.388 0,6.329 1.447,10.995 4.345,14.006 2.892,3.008 6.683,4.517 11.346,4.517 1.959,0 3.987,-0.316 6.096,-0.961 2.11,-0.639 3.519,-1.238 4.238,-1.799 0.713,-0.577 1.391,-0.85 2.032,-0.85 0.638,0 1.671,0.746 3.1,2.255 1.431,1.505 2.713,3.786 3.844,6.827 1.126,3.057 1.69,5.4 1.69,7.062 0,1.649 -0.036,2.786 -0.109,3.386 -1.581,1.73 -4.499,3.102 -8.755,4.122 -4.248,1.017 -9.011,1.522 -14.28,1.522 -11.594,0 -20.66,-3.65 -27.207,-10.95 -6.552,-7.303 -9.822,-16.783 -9.822,-28.452 0,-13.701 3.347,-24.087 10.041,-31.162 6.706,-7.074 15.51,-10.607 26.425,-10.607 5.87,0 11.08,0.505 15.632,1.522 4.557,1.013 7.586,2.053 9.093,3.105 l 0.452,35.33 C 11.496,-1.036 6.078,-0.104 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path38"
+ inkscape:connector-curvature="0" /></g><g
+ id="g40"
+ transform="matrix(1.1310535,0,0,1.1310535,441.34721,235.75121)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -0.624,-1.28 -1.771,-2.454 -3.449,-3.516 -1.676,-1.069 -3.805,-1.6 -6.391,-1.6 -3.412,0 -6.156,1.075 -8.24,3.249 -2.076,2.157 -3.116,5.266 -3.116,9.323 v 10.116 c 0,3.969 0.98,7.013 2.946,9.138 1.962,2.108 4.59,3.177 7.872,3.177 3.208,0 5.695,-0.844 7.455,-2.513 1.755,-1.675 2.677,-4.015 2.757,-7.003 L -0.21,20.238 h -2.619 c -0.094,2.29 -0.759,4.057 -2.01,5.305 -1.244,1.238 -3.095,1.864 -5.539,1.864 -2.473,0 -4.432,-0.837 -5.866,-2.516 -1.43,-1.675 -2.143,-4.103 -2.143,-7.293 V 7.424 c 0,-3.308 0.771,-5.83 2.311,-7.567 1.54,-1.724 3.616,-2.588 6.236,-2.588 1.913,0 3.451,0.339 4.602,1.033 1.155,0.684 1.956,1.519 2.409,2.51 v 8.861 h -7.06 v 2.463 H 0 Z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path42"
+ inkscape:connector-curvature="0" /></g><g
+ id="g44"
+ transform="matrix(1.1310535,0,0,1.1310535,456.01527,232.82495)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 1.553,0 2.936,0.44 4.144,1.336 1.21,0.9 2.058,2.037 2.561,3.422 v 5.468 H 2.213 c -1.91,0 -3.44,-0.541 -4.585,-1.623 C -3.52,7.528 -4.088,6.185 -4.088,4.588 -4.088,3.239 -3.733,2.131 -3.014,1.277 -2.296,0.42 -1.292,0 0,0 M 7.124,-2.04 C 6.984,-1.164 6.875,-0.453 6.806,0.104 6.739,0.671 6.705,1.235 6.705,1.808 5.938,0.554 4.948,-0.486 3.725,-1.301 2.504,-2.122 1.146,-2.529 -0.35,-2.529 c -2.092,0 -3.701,0.648 -4.84,1.946 -1.132,1.303 -1.704,3.059 -1.704,5.276 0,2.343 0.823,4.223 2.473,5.618 1.649,1.395 3.89,2.092 6.709,2.092 h 4.417 v 3.106 c 0,1.786 -0.456,3.193 -1.351,4.21 -0.914,1.004 -2.17,1.512 -3.791,1.512 -1.508,0 -2.752,-0.479 -3.728,-1.45 -0.973,-0.965 -1.456,-2.144 -1.456,-3.549 l -2.623,0.023 -0.046,0.137 c -0.074,1.906 0.647,3.591 2.168,5.084 1.515,1.489 3.459,2.229 5.825,2.229 2.338,0 4.22,-0.711 5.657,-2.128 1.429,-1.431 2.146,-3.471 2.146,-6.124 V 3.057 c 0,-0.903 0.042,-1.78 0.121,-2.617 0.081,-0.848 0.212,-1.665 0.417,-2.48 z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path46"
+ inkscape:connector-curvature="0" /></g><g
+ id="g48"
+ transform="matrix(1.1310535,0,0,1.1310535,476.7303,259.10521)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 0.24,-3.923 c 0.664,1.404 1.554,2.486 2.657,3.255 1.107,0.759 2.41,1.138 3.906,1.138 1.527,0 2.814,-0.444 3.852,-1.343 1.039,-0.896 1.805,-2.252 2.292,-4.074 0.623,1.682 1.505,3.011 2.65,3.973 1.145,0.964 2.534,1.444 4.143,1.444 2.217,0 3.937,-0.897 5.156,-2.692 1.224,-1.799 1.834,-4.559 1.834,-8.288 v -14.765 h -2.823 v 14.814 c 0,3.1 -0.429,5.283 -1.263,6.538 -0.839,1.257 -2.042,1.89 -3.598,1.89 -1.637,0 -2.915,-0.691 -3.834,-2.096 -0.914,-1.405 -1.478,-3.161 -1.683,-5.282 v -0.655 -15.209 H 10.72 v 14.798 c 0,3.027 -0.424,5.194 -1.292,6.488 -0.864,1.294 -2.066,1.936 -3.609,1.936 -1.475,0 -2.668,-0.45 -3.562,-1.342 -0.9,-0.897 -1.54,-2.125 -1.928,-3.683 V -25.275 H -2.477 V 0 Z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path50"
+ inkscape:connector-curvature="0" /></g><g
+ id="g52"
+ transform="matrix(1.1310535,0,0,1.1310535,522.82277,256.83868)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -1.758,0 -3.202,-0.802 -4.334,-2.402 -1.133,-1.606 -1.718,-3.585 -1.765,-5.944 h 11.66 v 1.082 c 0,2.086 -0.489,3.823 -1.469,5.201 C 3.106,-0.684 1.745,0 0,0 m 0.397,-23.76 c -2.725,0 -4.954,1.026 -6.685,3.073 -1.726,2.043 -2.591,4.657 -2.591,7.841 v 4.197 c 0,3.19 0.867,5.85 2.602,7.965 1.739,2.105 3.828,3.158 6.277,3.158 2.648,0 4.699,-0.939 6.164,-2.823 1.468,-1.887 2.201,-4.422 2.201,-7.603 v -2.773 H -6.099 v -2.102 c 0,-2.447 0.586,-4.484 1.752,-6.11 1.168,-1.63 2.755,-2.438 4.744,-2.438 1.382,0 2.585,0.244 3.588,0.724 1.003,0.491 1.863,1.179 2.578,2.082 l 1.149,-1.988 C 6.949,-21.525 5.96,-22.307 4.753,-22.887 3.549,-23.464 2.094,-23.76 0.397,-23.76"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path54"
+ inkscape:connector-curvature="0" /></g><g
+ id="g56"
+ transform="matrix(1.1310535,0,0,1.1310535,558.0805,256.83868)"
+ style="stroke-width:0.88413143"><path
+ d="M 0,0 C -1.763,0 -3.21,-0.802 -4.341,-2.402 -5.467,-4.008 -6.053,-5.987 -6.104,-8.346 H 5.559 v 1.082 c 0,2.086 -0.488,3.823 -1.474,5.201 C 3.104,-0.684 1.744,0 0,0 m 0.394,-23.76 c -2.726,0 -4.951,1.026 -6.679,3.073 -1.733,2.043 -2.6,4.657 -2.6,7.841 v 4.197 c 0,3.19 0.871,5.85 2.602,7.965 1.744,2.105 3.834,3.158 6.283,3.158 2.643,0 4.703,-0.939 6.164,-2.823 1.463,-1.887 2.197,-4.422 2.197,-7.603 v -2.773 H -6.104 v -2.102 c 0,-2.447 0.587,-4.484 1.76,-6.11 1.162,-1.63 2.742,-2.438 4.738,-2.438 1.387,0 2.585,0.244 3.585,0.724 1.007,0.491 1.866,1.179 2.589,2.082 l 1.141,-1.988 c -0.764,-0.968 -1.75,-1.75 -2.959,-2.33 -1.204,-0.577 -2.658,-0.873 -4.356,-0.873"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path58"
+ inkscape:connector-curvature="0" /></g><g
+ id="g60"
+ transform="matrix(1.1310535,0,0,1.1310535,575.91679,259.10521)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 0.23,-4.178 c 0.674,1.483 1.564,2.634 2.682,3.435 1.108,0.805 2.413,1.213 3.914,1.213 2.258,0 3.988,-0.835 5.189,-2.513 1.214,-1.675 1.815,-4.279 1.815,-7.812 v -15.42 h -2.825 v 15.394 c 0,2.888 -0.423,4.905 -1.264,6.075 -0.836,1.17 -2.065,1.753 -3.665,1.753 -1.435,0 -2.638,-0.466 -3.603,-1.414 C 1.504,-4.406 0.782,-5.657 0.301,-7.234 V -25.275 H -2.504 V 0 Z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path62"
+ inkscape:connector-curvature="0" /></g><g
+ id="g64"
+ transform="matrix(1.1310535,0,0,1.1310535,600.8685,242.30884)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-2.565 0.486,-4.605 1.472,-6.123 0.974,-1.532 2.457,-2.288 4.436,-2.288 1.356,0 2.498,0.361 3.435,1.101 0.934,0.74 1.672,1.77 2.218,3.077 v 12.52 c -0.525,1.346 -1.246,2.434 -2.157,3.272 -0.91,0.824 -2.062,1.238 -3.448,1.238 -1.975,0 -3.468,-0.86 -4.46,-2.587 C 0.497,8.48 0,6.224 0,3.454 Z m -2.833,3.454 c 0,3.582 0.723,6.459 2.177,8.627 1.442,2.157 3.448,3.239 6.004,3.239 1.419,0 2.664,-0.346 3.728,-1.04 1.066,-0.681 1.947,-1.678 2.654,-2.946 l 0.274,3.516 h 2.381 v -25.298 c 0,-3.239 -0.751,-5.749 -2.26,-7.525 -1.511,-1.769 -3.657,-2.665 -6.428,-2.665 -0.996,0 -2.067,0.156 -3.212,0.459 -1.147,0.303 -2.162,0.701 -3.052,1.2 l 0.776,2.463 c 0.759,-0.492 1.608,-0.873 2.548,-1.141 0.932,-0.277 1.895,-0.41 2.894,-0.41 2.009,0 3.498,0.645 4.46,1.932 0.966,1.304 1.45,3.19 1.45,5.687 v 3.057 c -0.717,-1.138 -1.597,-2.011 -2.64,-2.614 -1.039,-0.606 -2.253,-0.909 -3.622,-0.909 -2.539,0 -4.53,0.994 -5.968,2.982 C -2.11,-5.948 -2.833,-3.301 -2.833,0 Z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path66"
+ inkscape:connector-curvature="0" /></g><path
+ d="m 627.82321,230.5176 h -3.20089 v 28.58738 h 3.20089 z m 0,36.72644 h -3.20089 v 4.50385 h 3.20089 z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999994"
+ id="path68"
+ inkscape:connector-curvature="0" /><g
+ id="g70"
+ transform="matrix(1.1310535,0,0,1.1310535,638.15379,259.10521)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 0.23,-4.178 c 0.676,1.483 1.562,2.634 2.678,3.435 1.115,0.805 2.422,1.213 3.916,1.213 2.258,0 3.995,-0.835 5.199,-2.513 1.211,-1.675 1.807,-4.279 1.807,-7.812 v -15.42 h -2.825 v 15.394 c 0,2.888 -0.422,4.905 -1.261,6.075 -0.843,1.17 -2.063,1.753 -3.668,1.753 -1.434,0 -2.635,-0.466 -3.599,-1.414 C 1.51,-4.406 0.785,-5.657 0.306,-7.234 V -25.275 H -2.503 V 0 Z"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path72"
+ inkscape:connector-curvature="0" /></g><g
+ id="g74"
+ transform="matrix(1.1310535,0,0,1.1310535,669.70883,256.83868)"
+ style="stroke-width:0.88413143"><path
+ d="M 0,0 C -1.763,0 -3.208,-0.802 -4.334,-2.402 -5.463,-4.008 -6.052,-5.987 -6.102,-8.346 H 5.56 v 1.082 c 0,2.086 -0.486,3.823 -1.47,5.201 C 3.109,-0.684 1.747,0 0,0 m 0.401,-23.76 c -2.733,0 -4.958,1.026 -6.681,3.073 -1.73,2.043 -2.595,4.657 -2.595,7.841 v 4.197 c 0,3.19 0.865,5.85 2.6,7.965 1.739,2.105 3.831,3.158 6.275,3.158 2.646,0 4.706,-0.939 6.172,-2.823 1.462,-1.887 2.195,-4.422 2.195,-7.603 v -2.773 H -6.102 v -2.102 c 0,-2.447 0.59,-4.484 1.757,-6.11 1.166,-1.63 2.748,-2.438 4.746,-2.438 1.382,0 2.579,0.244 3.578,0.724 1.012,0.491 1.869,1.179 2.591,2.082 l 1.147,-1.988 c -0.769,-0.968 -1.755,-1.75 -2.962,-2.33 -1.203,-0.577 -2.658,-0.873 -4.354,-0.873"
+ style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path76"
+ inkscape:connector-curvature="0" /></g><g
+ id="g78"
+ transform="matrix(1.1310535,0,0,1.1310535,348.13109,279.2668)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,0 -0.325,1.994 -0.515,1.976 l -36.182,-3.491 c -2.879,-0.278 -5.115,-2.574 -5.317,-5.459 l -0.994,-14.247 -27.992,-1.997 -1.904,12.912 c -0.424,2.872 -2.932,5.037 -5.835,5.037 h -38.188 c -2.902,0 -5.41,-2.165 -5.834,-5.037 l -1.905,-12.912 -27.992,1.997 -0.994,14.247 c -0.202,2.886 -2.438,5.182 -5.317,5.46 l -36.2,3.49 c -0.187,0.018 -0.324,-1.978 -0.511,-1.978 l -0.049,-7.83 30.658,-4.944 1.004,-14.374 c 0.203,-2.91 2.551,-5.263 5.463,-5.472 l 38.551,-2.75 c 0.146,-0.01 0.29,-0.016 0.434,-0.016 2.897,0 5.401,2.166 5.825,5.038 l 1.959,13.286 h 28.005 l 1.959,-13.286 c 0.423,-2.871 2.93,-5.037 5.831,-5.037 0.142,0 0.284,0.005 0.423,0.015 l 38.556,2.75 c 2.911,0.209 5.26,2.562 5.463,5.472 l 1.003,14.374 30.645,4.966 z"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path80"
+ inkscape:connector-curvature="0" /></g><g
+ id="g82"
+ transform="matrix(1.1310535,0,0,1.1310535,126.80608,346.04533)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 v -47.514 -6.035 -5.492 c 0.108,-0.001 0.216,-0.005 0.323,-0.015 l 36.196,-3.49 c 1.896,-0.183 3.382,-1.709 3.514,-3.609 l 1.116,-15.978 31.574,-2.253 2.175,14.747 c 0.282,1.912 1.922,3.329 3.856,3.329 h 38.188 c 1.933,0 3.573,-1.417 3.855,-3.329 l 2.175,-14.747 31.575,2.253 1.115,15.978 c 0.133,1.9 1.618,3.425 3.514,3.609 l 36.182,3.49 c 0.107,0.01 0.214,0.014 0.322,0.015 v 4.711 l 0.015,0.005 V 0 h 0.134 c 4.795,6.12 9.232,12.569 13.487,19.449 -5.651,9.62 -12.575,18.217 -19.976,26.182 -6.864,-3.455 -13.531,-7.369 -19.828,-11.534 -3.151,3.132 -6.7,5.694 -10.186,8.372 -3.425,2.751 -7.285,4.768 -10.946,7.118 1.09,8.117 1.629,16.108 1.846,24.448 -9.446,4.754 -19.519,7.906 -29.708,10.17 -4.068,-6.837 -7.788,-14.241 -11.028,-21.479 -3.842,0.642 -7.702,0.88 -11.567,0.926 v 0.006 c -0.027,0 -0.052,-0.006 -0.075,-0.006 -0.024,0 -0.049,0.006 -0.073,0.006 V 63.652 C 93.903,63.606 90.046,63.368 86.203,62.726 82.965,69.964 79.247,77.368 75.173,84.205 64.989,81.941 54.915,78.789 45.47,74.035 45.686,65.695 46.225,57.704 47.318,49.587 43.65,47.237 39.795,45.22 36.369,42.469 32.888,39.791 29.333,37.229 26.181,34.097 19.884,38.262 13.219,42.176 6.353,45.631 -1.048,37.666 -7.968,29.069 -13.621,19.449 -9.368,12.569 -4.928,6.12 -0.134,0 Z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path84"
+ inkscape:connector-curvature="0" /></g><g
+ id="g86"
+ transform="matrix(1.1310535,0,0,1.1310535,311.40329,266.88437)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 -1.121,-16.063 c -0.135,-1.936 -1.675,-3.477 -3.611,-3.616 l -38.555,-2.751 c -0.094,-0.007 -0.188,-0.01 -0.281,-0.01 -1.916,0 -3.569,1.406 -3.852,3.33 l -2.211,14.994 H -81.09 l -2.211,-14.994 c -0.297,-2.018 -2.101,-3.469 -4.133,-3.32 l -38.555,2.751 c -1.936,0.139 -3.476,1.68 -3.611,3.616 L -130.721,0 -163.268,3.138 c 0.015,-3.498 0.06,-7.33 0.06,-8.093 0,-34.374 43.605,-50.896 97.781,-51.086 h 0.066 0.067 c 54.176,0.19 97.766,16.712 97.766,51.086 0,0.777 0.047,4.593 0.063,8.093 z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path88"
+ inkscape:connector-curvature="0" /></g><g
+ id="g90"
+ transform="matrix(1.1310535,0,0,1.1310535,204.11393,318.93771)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-12.052 -9.765,-21.815 -21.813,-21.815 -12.042,0 -21.81,9.763 -21.81,21.815 0,12.044 9.768,21.802 21.81,21.802 C -9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path92"
+ inkscape:connector-curvature="0" /></g><g
+ id="g94"
+ transform="matrix(1.1310535,0,0,1.1310535,198.17748,317.47435)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-7.994 -6.479,-14.473 -14.479,-14.473 -7.996,0 -14.479,6.479 -14.479,14.473 0,7.994 6.483,14.479 14.479,14.479 C -6.479,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path96"
+ inkscape:connector-curvature="0" /></g><g
+ id="g98"
+ transform="matrix(1.1310535,0,0,1.1310535,237.47503,292.01909)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c -3.878,0 -7.021,2.858 -7.021,6.381 v 20.081 c 0,3.52 3.143,6.381 7.021,6.381 3.878,0 7.028,-2.861 7.028,-6.381 V 6.381 C 7.028,2.858 3.878,0 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path100"
+ inkscape:connector-curvature="0" /></g><g
+ id="g102"
+ transform="matrix(1.1310535,0,0,1.1310535,270.84021,318.93771)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-12.052 9.765,-21.815 21.815,-21.815 12.041,0 21.808,9.763 21.808,21.815 0,12.044 -9.767,21.802 -21.808,21.802 C 9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path104"
+ inkscape:connector-curvature="0" /></g><g
+ id="g106"
+ transform="matrix(1.1310535,0,0,1.1310535,276.77813,317.47435)"
+ style="stroke-width:0.88413143"><path
+ d="m 0,0 c 0,-7.994 6.477,-14.473 14.471,-14.473 8.002,0 14.479,6.479 14.479,14.473 0,7.994 -6.477,14.479 -14.479,14.479 C 6.477,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.88413143"
+ id="path108"
+ inkscape:connector-curvature="0" /></g></g></g></g></svg> \ No newline at end of file
diff --git a/main/app_icon.png b/main/app_icon.png
index eafae08d59..1d75cdc710 100644
--- a/main/app_icon.png
+++ b/main/app_icon.png
Binary files differ
diff --git a/main/input_default.cpp b/main/input_default.cpp
index 8f0b8464eb..e488438059 100644
--- a/main/input_default.cpp
+++ b/main/input_default.cpp
@@ -115,19 +115,19 @@ bool InputDefault::is_action_pressed(const StringName &p_action) const {
case InputEvent::KEY: {
const InputEventKey &iek=E->get().key;
- if ((keys_pressed.has(iek.scancode)))
+ if ((keys_pressed.has(iek->get_scancode())))
return true;
} break;
case InputEvent::MOUSE_BUTTON: {
const InputEventMouseButton &iemb=E->get().mouse_button;
- if(mouse_button_mask&(1<<iemb.button_index))
+ if(mouse_button_mask&(1<<iemb->get_button_index()))
return true;
} break;
case InputEvent::JOYPAD_BUTTON: {
const InputEventJoypadButton &iejb=E->get().joy_button;
- int c = _combine_device(iejb.button_index,device);
+ int c = _combine_device(iejb->get_button_index(),device);
if (joy_buttons_pressed.has(c))
return true;
} break;
@@ -297,94 +297,86 @@ Vector3 InputDefault::get_gyroscope() const {
return gyroscope;
}
-void InputDefault::parse_input_event(const InputEvent &p_event) {
+void InputDefault::parse_input_event(const Ref<InputEvent> &p_event) {
_THREAD_SAFE_METHOD_
- switch (p_event.type) {
-
- case InputEvent::KEY: {
-
- if (p_event.key.echo)
- break;
- if (p_event.key.scancode == 0)
- break;
-
- //print_line(p_event);
-
- if (p_event.key.pressed)
- keys_pressed.insert(p_event.key.scancode);
- else
- keys_pressed.erase(p_event.key.scancode);
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- if (p_event.mouse_button.doubleclick)
- break;
-
- if (p_event.mouse_button.pressed)
- mouse_button_mask |= (1 << p_event.mouse_button.button_index);
- else
- mouse_button_mask &= ~(1 << p_event.mouse_button.button_index);
-
- if (main_loop && emulate_touch && p_event.mouse_button.button_index == 1) {
- InputEventScreenTouch touch_event;
- touch_event.index = 0;
- touch_event.pressed = p_event.mouse_button.pressed;
- touch_event.x = p_event.mouse_button.x;
- touch_event.y = p_event.mouse_button.y;
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch = touch_event;
- main_loop->input_event(ev);
- }
- Point2 pos = Point2(p_event.mouse_button.global_x, p_event.mouse_button.global_y);
- if (mouse_pos != pos) {
- set_mouse_position(pos);
- }
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- if (main_loop && emulate_touch && p_event.mouse_motion.button_mask & 1) {
- InputEventScreenDrag drag_event;
- drag_event.index = 0;
- drag_event.x = p_event.mouse_motion.x;
- drag_event.y = p_event.mouse_motion.y;
- drag_event.relative_x = p_event.mouse_motion.relative_x;
- drag_event.relative_y = p_event.mouse_motion.relative_y;
- drag_event.speed_x = p_event.mouse_motion.speed_x;
- drag_event.speed_y = p_event.mouse_motion.speed_y;
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.screen_drag = drag_event;
-
- main_loop->input_event(ev);
- }
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid() && !k->is_echo() && k->get_scancode() != 0) {
+
+ //print_line(p_event);
+
+ if (k->is_pressed())
+ keys_pressed.insert(k->get_scancode());
+ else
+ keys_pressed.erase(k->get_scancode());
+ }
+
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && !mb->is_doubleclick()) {
+
+ if (mb->is_pressed())
+ mouse_button_mask |= (1 << mb->get_button_index());
+ else
+ mouse_button_mask &= ~(1 << mb->get_button_index());
+
+ if (main_loop && emulate_touch && mb->get_button_index() == 1) {
+ Ref<InputEventScreenTouch> touch_event;
+ touch_event.instance();
+ touch_event->set_pressed(mb->is_pressed());
+ touch_event->set_position(mb->get_position());
+ main_loop->input_event(touch_event);
+ }
+
+ Point2 pos = mb->get_global_position();
+ if (mouse_pos != pos) {
+ set_mouse_position(pos);
+ }
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
+
+ if (main_loop && emulate_touch && mm->get_button_mask() & 1) {
+ Ref<InputEventScreenDrag> drag_event;
+ drag_event.instance();
- } break;
- case InputEvent::JOYPAD_BUTTON: {
+ drag_event->set_position(mm->get_position());
+ drag_event->set_relative(mm->get_relative());
+ drag_event->set_speed(mm->get_speed());
+
+ main_loop->input_event(drag_event);
+ }
+ }
+
+ Ref<InputEventJoypadButton> jb = p_event;
+
+ if (jb.is_valid()) {
+
+ int c = _combine_device(jb->get_button_index(), jb->get_device());
+
+ if (jb->is_pressed())
+ joy_buttons_pressed.insert(c);
+ else
+ joy_buttons_pressed.erase(c);
+ }
- int c = _combine_device(p_event.joy_button.button_index, p_event.device);
+ Ref<InputEventJoypadMotion> jm = p_event;
- if (p_event.joy_button.pressed)
- joy_buttons_pressed.insert(c);
- else
- joy_buttons_pressed.erase(c);
- } break;
- case InputEvent::JOYPAD_MOTION: {
- set_joy_axis(p_event.device, p_event.joy_motion.axis, p_event.joy_motion.axis_value);
- } break;
+ if (jm.is_valid()) {
+ set_joy_axis(jm->get_device(), jm->get_axis(), jm->get_axis_value());
}
- if (!p_event.is_echo()) {
+ if (!p_event->is_echo()) {
for (const Map<StringName, InputMap::Action>::Element *E = InputMap::get_singleton()->get_action_map().front(); E; E = E->next()) {
- if (InputMap::get_singleton()->event_is_action(p_event, E->key()) && is_action_pressed(E->key()) != p_event.is_pressed()) {
+ if (InputMap::get_singleton()->event_is_action(p_event, E->key()) && is_action_pressed(E->key()) != p_event->is_pressed()) {
Action action;
action.fixed_frame = Engine::get_singleton()->get_fixed_frames();
action.idle_frame = Engine::get_singleton()->get_idle_frames();
- action.pressed = p_event.is_pressed();
+ action.pressed = p_event->is_pressed();
action_state[E->key()] = action;
}
}
@@ -484,7 +476,7 @@ void InputDefault::warp_mouse_pos(const Vector2 &p_to) {
OS::get_singleton()->warp_mouse_pos(p_to);
}
-Point2i InputDefault::warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect) {
+Point2i InputDefault::warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect) {
// The relative distance reported for the next event after a warp is in the boundaries of the
// size of the rect on that axis, but it may be greater, in which case there's not problem as fmod()
@@ -495,16 +487,16 @@ Point2i InputDefault::warp_mouse_motion(const InputEventMouseMotion &p_motion, c
// detect the warp: if the relative distance is greater than the half of the size of the relevant rect
// (checked per each axis), it will be considered as the consequence of a former pointer warp.
- const Point2i rel_sgn(p_motion.relative_x >= 0.0f ? 1 : -1, p_motion.relative_y >= 0.0 ? 1 : -1);
+ const Point2i rel_sgn(p_motion->get_relative().x >= 0.0f ? 1 : -1, p_motion->get_relative().y >= 0.0 ? 1 : -1);
const Size2i warp_margin = p_rect.size * 0.5f;
const Point2i rel_warped(
- Math::fmod(p_motion.relative_x + rel_sgn.x * warp_margin.x, p_rect.size.x) - rel_sgn.x * warp_margin.x,
- Math::fmod(p_motion.relative_y + rel_sgn.y * warp_margin.y, p_rect.size.y) - rel_sgn.y * warp_margin.y);
+ Math::fmod(p_motion->get_relative().x + rel_sgn.x * warp_margin.x, p_rect.size.x) - rel_sgn.x * warp_margin.x,
+ Math::fmod(p_motion->get_relative().y + rel_sgn.y * warp_margin.y, p_rect.size.y) - rel_sgn.y * warp_margin.y);
- const Point2i pos_local = Point2i(p_motion.global_x, p_motion.global_y) - p_rect.pos;
+ const Point2i pos_local = p_motion->get_global_position() - p_rect.position;
const Point2i pos_warped(Math::fposmod(pos_local.x, p_rect.size.x), Math::fposmod(pos_local.y, p_rect.size.y));
if (pos_warped != pos_local) {
- OS::get_singleton()->warp_mouse_pos(pos_warped + p_rect.pos);
+ OS::get_singleton()->warp_mouse_pos(pos_warped + p_rect.position);
}
return rel_warped;
@@ -1020,22 +1012,22 @@ void InputDefault::joy_hat(int p_device, int p_val) {
void InputDefault::_button_event(int p_device, int p_index, bool p_pressed) {
- InputEvent ievent;
- ievent.type = InputEvent::JOYPAD_BUTTON;
- ievent.device = p_device;
- ievent.joy_button.button_index = p_index;
- ievent.joy_button.pressed = p_pressed;
+ Ref<InputEventJoypadButton> ievent;
+ ievent.instance();
+ ievent->set_device(p_device);
+ ievent->set_button_index(p_index);
+ ievent->set_pressed(p_pressed);
parse_input_event(ievent);
};
void InputDefault::_axis_event(int p_device, int p_axis, float p_value) {
- InputEvent ievent;
- ievent.type = InputEvent::JOYPAD_MOTION;
- ievent.device = p_device;
- ievent.joy_motion.axis = p_axis;
- ievent.joy_motion.axis_value = p_value;
+ Ref<InputEventJoypadMotion> ievent;
+ ievent.instance();
+ ievent->set_device(p_device);
+ ievent->set_axis(p_axis);
+ ievent->set_axis_value(p_value);
parse_input_event(ievent);
};
diff --git a/main/input_default.h b/main/input_default.h
index 55b7555ef9..35e841a488 100644
--- a/main/input_default.h
+++ b/main/input_default.h
@@ -201,9 +201,9 @@ public:
virtual int get_mouse_button_mask() const;
virtual void warp_mouse_pos(const Vector2 &p_to);
- virtual Point2i warp_mouse_motion(const InputEventMouseMotion &p_motion, const Rect2 &p_rect);
+ virtual Point2i warp_mouse_motion(const Ref<InputEventMouseMotion> &p_motion, const Rect2 &p_rect);
- virtual void parse_input_event(const InputEvent &p_event);
+ virtual void parse_input_event(const Ref<InputEvent> &p_event);
void set_gravity(const Vector3 &p_gravity);
void set_accelerometer(const Vector3 &p_accel);
diff --git a/main/main.cpp b/main/main.cpp
index 33095e8599..e00c136596 100644
--- a/main/main.cpp
+++ b/main/main.cpp
@@ -581,15 +581,15 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
GLOBAL_DEF("memory/multithread/thread_rid_pool_prealloc", 60);
GLOBAL_DEF("network/debug/max_remote_stdout_chars_per_second", 2048);
- GLOBAL_DEF("network/debug/remote_port", 6007);
if (debug_mode == "remote") {
ScriptDebuggerRemote *sdr = memnew(ScriptDebuggerRemote);
- uint16_t debug_port = GLOBAL_GET("network/debug/remote_port");
+ uint16_t debug_port = 6007;
if (debug_host.find(":") != -1) {
- debug_port = debug_host.get_slicec(':', 1).to_int();
- debug_host = debug_host.get_slicec(':', 0);
+ int sep_pos = debug_host.find_last(":");
+ debug_port = debug_host.substr(sep_pos + 1, debug_host.length()).to_int();
+ debug_host = debug_host.substr(0, sep_pos);
}
Error derr = sdr->connect_to_host(debug_host, debug_port);
@@ -916,18 +916,19 @@ Error Main::setup2() {
bool boot_logo_scale = GLOBAL_DEF("application/boot_splash_fullsize", true);
GlobalConfig::get_singleton()->set_custom_property_info("application/boot_splash", PropertyInfo(Variant::STRING, "application/boot_splash", PROPERTY_HINT_FILE, "*.png"));
- Image boot_logo;
+ Ref<Image> boot_logo;
boot_logo_path = boot_logo_path.strip_edges();
if (boot_logo_path != String() /*&& FileAccess::exists(boot_logo_path)*/) {
print_line("Boot splash path: " + boot_logo_path);
- Error err = boot_logo.load(boot_logo_path);
+ boot_logo.instance();
+ Error err = boot_logo->load(boot_logo_path);
if (err)
ERR_PRINTS("Non-existing or invalid boot splash at: " + boot_logo_path + ". Loading default splash.");
}
- if (!boot_logo.empty()) {
+ if (boot_logo.is_valid()) {
OS::get_singleton()->_msec_splash = OS::get_singleton()->get_ticks_msec();
Color boot_bg = GLOBAL_DEF("application/boot_bg_color", clear);
VisualServer::get_singleton()->set_boot_image(boot_logo, boot_bg, boot_logo_scale);
@@ -940,7 +941,7 @@ Error Main::setup2() {
#ifndef NO_DEFAULT_BOOT_LOGO
MAIN_PRINT("Main: Create bootsplash");
- Image splash(boot_splash_png);
+ Ref<Image> splash = memnew(Image(boot_splash_png));
MAIN_PRINT("Main: ClearColor");
VisualServer::get_singleton()->set_default_clear_color(boot_splash_bg_color);
@@ -949,7 +950,7 @@ Error Main::setup2() {
#endif
}
- Image icon(app_icon_png);
+ Ref<Image> icon = memnew(Image(app_icon_png));
OS::get_singleton()->set_icon(icon);
}
@@ -1463,8 +1464,8 @@ bool Main::start() {
String iconpath = GLOBAL_DEF("application/icon", "Variant()");
if (iconpath != "") {
- Image icon;
- if (icon.load(iconpath) == OK)
+ Ref<Image> icon;
+ if (icon->load(iconpath) == OK)
OS::get_singleton()->set_icon(icon);
}
}
diff --git a/main/splash.png b/main/splash.png
index 01ca2152ce..894a7d7aba 100644
--- a/main/splash.png
+++ b/main/splash.png
Binary files differ
diff --git a/main/tests/test_containers.cpp b/main/tests/test_containers.cpp
index 890599385a..956be5d169 100644
--- a/main/tests/test_containers.cpp
+++ b/main/tests/test_containers.cpp
@@ -55,18 +55,6 @@ MainLoop *test() {
{
- Image img;
- img.create(default_mouse_cursor_xpm);
-
- {
- for (int i = 0; i < 8; i++) {
-
- Image mipmap;
- //img.make_mipmap(mipmap);
- img = mipmap;
- if (img.get_width() <= 4) break;
- };
- };
};
#if 0
diff --git a/main/tests/test_gui.cpp b/main/tests/test_gui.cpp
index 3d0b96ae5b..291a557d04 100644
--- a/main/tests/test_gui.cpp
+++ b/main/tests/test_gui.cpp
@@ -53,7 +53,6 @@
#include "scene/main/scene_main_loop.h"
#include "scene/3d/camera.h"
-#include "scene/3d/test_cube.h"
#include "scene/main/viewport.h"
namespace TestGUI {
@@ -87,10 +86,6 @@ public:
vp->add_child(camera);
camera->make_current();
- TestCube *testcube = memnew( TestCube );
- vp->add_child(testcube);
- testcube->set_transform(Transform( Basis().rotated(Vector3(0,1,0),Math_PI*0.25), Vector3(0,0,-8)));
-
Sprite *sp = memnew( Sprite );
sp->set_texture( vp->get_render_target_texture() );
//sp->set_texture( ResourceLoader::load("res://ball.png") );
@@ -375,6 +370,6 @@ MainLoop *test() {
return memnew(TestMainLoop);
}
-}
+} // namespace TestGUI
#endif
diff --git a/main/tests/test_image.cpp b/main/tests/test_image.cpp
index aff3bae417..0b120f87d5 100644
--- a/main/tests/test_image.cpp
+++ b/main/tests/test_image.cpp
@@ -41,7 +41,7 @@ class TestMainLoop : public MainLoop {
bool quit;
public:
- virtual void input_event(const InputEvent &p_event) {
+ virtual void input_event(const Ref<InputEvent> &p_event) {
}
virtual void init() {
@@ -63,11 +63,6 @@ public:
MainLoop *test() {
- Image img;
- ImageLoader::load_image("as1.png", &img);
-
- img.resize(512, 512);
-
return memnew(TestMainLoop);
}
}
diff --git a/main/tests/test_math.cpp b/main/tests/test_math.cpp
index 95a1672e67..d21be24dab 100644
--- a/main/tests/test_math.cpp
+++ b/main/tests/test_math.cpp
@@ -462,6 +462,59 @@ uint32_t ihash3(uint32_t a) {
MainLoop *test() {
+ {
+ float r = 1;
+ float g = 0.5;
+ float b = 0.1;
+
+ const float pow2to9 = 512.0f;
+ const float B = 15.0f;
+ //const float Emax = 31.0f;
+ const float N = 9.0f;
+
+ float sharedexp = 65408.000f; //(( pow2to9 - 1.0f)/ pow2to9)*powf( 2.0f, 31.0f - 15.0f);
+
+ float cRed = MAX(0.0f, MIN(sharedexp, r));
+ float cGreen = MAX(0.0f, MIN(sharedexp, g));
+ float cBlue = MAX(0.0f, MIN(sharedexp, b));
+
+ float cMax = MAX(cRed, MAX(cGreen, cBlue));
+
+ // expp = MAX(-B - 1, log2(maxc)) + 1 + B
+
+ float expp = MAX(-B - 1.0f, floor(Math::log(cMax) / Math_LN2)) + 1.0f + B;
+
+ float sMax = (float)floor((cMax / Math::pow(2.0f, expp - B - N)) + 0.5f);
+
+ float exps = expp + 1.0f;
+
+ if (0.0 <= sMax && sMax < pow2to9) {
+ exps = expp;
+ }
+
+ float sRed = Math::floor((cRed / pow(2.0f, exps - B - N)) + 0.5f);
+ float sGreen = Math::floor((cGreen / pow(2.0f, exps - B - N)) + 0.5f);
+ float sBlue = Math::floor((cBlue / pow(2.0f, exps - B - N)) + 0.5f);
+
+ print_line("R: " + rtos(sRed) + " G: " + rtos(sGreen) + " B: " + rtos(sBlue) + " EXP: " + rtos(exps));
+
+ uint32_t rgbe = (Math::fast_ftoi(sRed) & 0x1FF) | ((Math::fast_ftoi(sGreen) & 0x1FF) << 9) | ((Math::fast_ftoi(sBlue) & 0x1FF) << 18) | ((Math::fast_ftoi(exps) & 0x1F) << 27);
+
+ float rb = rgbe & 0x1ff;
+ float gb = (rgbe >> 9) & 0x1ff;
+ float bb = (rgbe >> 18) & 0x1ff;
+ float eb = (rgbe >> 27);
+ float mb = Math::pow(2, eb - 15.0 - 9.0);
+ ;
+ float rd = rb * mb;
+ float gd = gb * mb;
+ float bd = bb * mb;
+
+ print_line("RGBE: " + Color(rd, gd, bd));
+
+ return NULL;
+ }
+
print_line("Dvectors: " + itos(MemoryPool::allocs_used));
print_line("Mem used: " + itos(MemoryPool::total_memory));
print_line("MAx mem used: " + itos(MemoryPool::max_memory));
diff --git a/main/tests/test_physics.cpp b/main/tests/test_physics.cpp
index d32756937a..5a233e818e 100644
--- a/main/tests/test_physics.cpp
+++ b/main/tests/test_physics.cpp
@@ -263,18 +263,19 @@ protected:
}
public:
- virtual void input_event(const InputEvent &p_event) {
+ virtual void input_event(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask & 4) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid() && mm->get_button_mask() & 4) {
- ofs_y -= p_event.mouse_motion.relative_y / 200.0;
- ofs_x += p_event.mouse_motion.relative_x / 200.0;
+ ofs_y -= mm->get_relative().y / 200.0;
+ ofs_x += mm->get_relative().x / 200.0;
}
- if (p_event.type == InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask & 1) {
+ if (mm.is_valid() && mm->get_button_mask() & 1) {
- float y = -p_event.mouse_motion.relative_y / 20.0;
- float x = p_event.mouse_motion.relative_x / 20.0;
+ float y = -mm->get_relative().y / 20.0;
+ float x = mm->get_relative().x / 20.0;
if (mover.is_valid()) {
@@ -285,19 +286,6 @@ public:
ps->body_set_state(mover, PhysicsServer::BODY_STATE_TRANSFORM, t);
}
}
-
- if (p_event.type == InputEvent::JOYPAD_MOTION) {
-
- if (p_event.joy_motion.axis == 0) {
-
- joy_direction.x = p_event.joy_motion.axis_value;
- };
-
- if (p_event.joy_motion.axis == 1) {
-
- joy_direction.y = p_event.joy_motion.axis_value;
- };
- };
}
virtual void request_quit() {
diff --git a/main/tests/test_physics_2d.cpp b/main/tests/test_physics_2d.cpp
index 1476e45fcc..2c9b51aadb 100644
--- a/main/tests/test_physics_2d.cpp
+++ b/main/tests/test_physics_2d.cpp
@@ -82,7 +82,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
- Image image(32, 2, 0, Image::FORMAT_LA8, pixels);
+ Ref<Image> image = memnew(Image(32, 2, 0, Image::FORMAT_LA8, pixels));
body_shape_data[Physics2DServer::SHAPE_SEGMENT].image = vs->texture_create_from_image(image);
@@ -109,7 +109,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
- Image image(32, 32, 0, Image::FORMAT_LA8, pixels);
+ Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
body_shape_data[Physics2DServer::SHAPE_CIRCLE].image = vs->texture_create_from_image(image);
@@ -136,7 +136,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
- Image image(32, 32, 0, Image::FORMAT_LA8, pixels);
+ Ref<Image> image = memnew(Image(32, 32, 0, Image::FORMAT_LA8, pixels));
body_shape_data[Physics2DServer::SHAPE_RECTANGLE].image = vs->texture_create_from_image(image);
@@ -164,7 +164,7 @@ class TestPhysics2DMainLoop : public MainLoop {
}
}
- Image image(32, 64, 0, Image::FORMAT_LA8, pixels);
+ Ref<Image> image = memnew(Image(32, 64, 0, Image::FORMAT_LA8, pixels));
body_shape_data[Physics2DServer::SHAPE_CAPSULE].image = vs->texture_create_from_image(image);
@@ -178,7 +178,7 @@ class TestPhysics2DMainLoop : public MainLoop {
{
- Image image(convex_png);
+ Ref<Image> image = memnew(Image(convex_png));
body_shape_data[Physics2DServer::SHAPE_CONVEX_POLYGON].image = vs->texture_create_from_image(image);
@@ -208,35 +208,36 @@ class TestPhysics2DMainLoop : public MainLoop {
}
protected:
- void input_event(const InputEvent &p_event) {
+ void input_event(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_event;
- const InputEventMouseButton &mb = p_event.mouse_button;
+ if (mb.is_valid()) {
- if (mb.pressed) {
+ if (mb->is_pressed()) {
- Point2 p(mb.x, mb.y);
+ Point2 p(mb->get_position().x, mb->get_position().y);
- if (mb.button_index == 1) {
+ if (mb->get_button_index() == 1) {
ray_to = p;
_do_ray_query();
- } else if (mb.button_index == 2) {
+ } else if (mb->get_button_index() == 2) {
ray_from = p;
_do_ray_query();
}
}
}
- if (p_event.type == InputEvent::MOUSE_MOTION) {
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ Ref<InputEventMouseMotion> mm = p_event;
- Point2 p(mm.x, mm.y);
+ if (mm.is_valid()) {
- if (mm.button_mask & BUTTON_MASK_LEFT) {
+ Point2 p = mm->get_position();
+
+ if (mm->get_button_mask() & BUTTON_MASK_LEFT) {
ray_to = p;
_do_ray_query();
- } else if (mm.button_mask & BUTTON_MASK_RIGHT) {
+ } else if (mm->get_button_mask() & BUTTON_MASK_RIGHT) {
ray_from = p;
_do_ray_query();
}
diff --git a/main/tests/test_render.cpp b/main/tests/test_render.cpp
index 89bd5db60f..74f7453d1b 100644
--- a/main/tests/test_render.cpp
+++ b/main/tests/test_render.cpp
@@ -64,9 +64,9 @@ class TestMainLoop : public MainLoop {
protected:
public:
- virtual void input_event(const InputEvent &p_event) {
+ virtual void input_event(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed)
+ if (p_event->is_pressed())
quit = true;
}
diff --git a/methods.py b/methods.py
index cad87ad775..5af6c6aed0 100644
--- a/methods.py
+++ b/methods.py
@@ -1594,34 +1594,69 @@ def detect_visual_c_compiler_version(tools_env):
vc_chosen_compiler_index = -1
vc_chosen_compiler_str = ""
- # find() works with -1 so big ifs bellow are needed... the simplest solution, in fact
- # First test if amd64 and amd64_x86 compilers are present in the path
- vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64;")
- if(vc_amd64_compiler_detection_index > -1):
- vc_chosen_compiler_index = vc_amd64_compiler_detection_index
- vc_chosen_compiler_str = "amd64"
-
- vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64_x86;")
- if(vc_amd64_x86_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index)):
- vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
- vc_chosen_compiler_str = "amd64_x86"
-
- # Now check the 32 bit compilers
- vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN;")
- if(vc_x86_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_x86_compiler_detection_index)):
- vc_chosen_compiler_index = vc_x86_compiler_detection_index
- vc_chosen_compiler_str = "x86"
-
- vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env['VCINSTALLDIR'] + "BIN\\x86_amd64;")
- if(vc_x86_amd64_compiler_detection_index > -1
- and (vc_chosen_compiler_index == -1
- or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index)):
- vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
- vc_chosen_compiler_str = "x86_amd64"
+ # Start with Pre VS 2017 checks which uses VCINSTALLDIR:
+ if 'VCINSTALLDIR' in tools_env:
+ # print "Checking VCINSTALLDIR"
+
+ # find() works with -1 so big ifs bellow are needed... the simplest solution, in fact
+ # First test if amd64 and amd64_x86 compilers are present in the path
+ vc_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64;")
+ if(vc_amd64_compiler_detection_index > -1):
+ vc_chosen_compiler_index = vc_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "amd64"
+
+ vc_amd64_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN\\amd64_x86;")
+ if(vc_amd64_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
+ vc_chosen_compiler_str = "amd64_x86"
+
+ # Now check the 32 bit compilers
+ vc_x86_compiler_detection_index = tools_env["PATH"].find(tools_env["VCINSTALLDIR"] + "BIN;")
+ if(vc_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_compiler_detection_index
+ vc_chosen_compiler_str = "x86"
+
+ vc_x86_amd64_compiler_detection_index = tools_env["PATH"].find(tools_env['VCINSTALLDIR'] + "BIN\\x86_amd64;")
+ if(vc_x86_amd64_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "x86_amd64"
+
+ # and for VS 2017 and newer we check VCTOOLSINSTALLDIR:
+ if 'VCTOOLSINSTALLDIR' in tools_env:
+ # print "Checking VCTOOLSINSTALLDIR"
+
+ # Newer versions have a different path available
+ vc_amd64_compiler_detection_index = tools_env["PATH"].upper().find(tools_env['VCTOOLSINSTALLDIR'].upper() + "BIN\\HOSTX64\\X64;")
+ if(vc_amd64_compiler_detection_index > -1):
+ vc_chosen_compiler_index = vc_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "amd64"
+
+ vc_amd64_x86_compiler_detection_index = tools_env["PATH"].upper().find(tools_env['VCTOOLSINSTALLDIR'].upper() + "BIN\\HOSTX64\\X86;")
+ if(vc_amd64_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_amd64_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_amd64_x86_compiler_detection_index
+ vc_chosen_compiler_str = "amd64_x86"
+
+ vc_x86_compiler_detection_index = tools_env["PATH"].upper().find(tools_env['VCTOOLSINSTALLDIR'].upper() + "BIN\\HOSTX86\\X86;")
+ if(vc_x86_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_compiler_detection_index
+ vc_chosen_compiler_str = "x86"
+
+ vc_x86_amd64_compiler_detection_index = tools_env["PATH"].upper().find(tools_env['VCTOOLSINSTALLDIR'].upper() + "BIN\\HOSTX86\\X64;")
+ if(vc_x86_amd64_compiler_detection_index > -1
+ and (vc_chosen_compiler_index == -1
+ or vc_chosen_compiler_index > vc_x86_amd64_compiler_detection_index)):
+ vc_chosen_compiler_index = vc_x86_amd64_compiler_detection_index
+ vc_chosen_compiler_str = "x86_amd64"
# debug help
# print vc_amd64_compiler_detection_index
diff --git a/misc/dist/osx_template.app/Contents/Resources/icon.icns b/misc/dist/osx_template.app/Contents/Resources/icon.icns
index 375f61437d..be9254630c 100644
--- a/misc/dist/osx_template.app/Contents/Resources/icon.icns
+++ b/misc/dist/osx_template.app/Contents/Resources/icon.icns
Binary files differ
diff --git a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns b/misc/dist/osx_tools.app/Contents/Resources/Godot.icns
index 375f61437d..be9254630c 100644
--- a/misc/dist/osx_tools.app/Contents/Resources/Godot.icns
+++ b/misc/dist/osx_tools.app/Contents/Resources/Godot.icns
Binary files differ
diff --git a/misc/dist/project_icon.svg b/misc/dist/project_icon.svg
new file mode 100644
index 0000000000..650c71fd12
--- /dev/null
+++ b/misc/dist/project_icon.svg
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="1024"
+ height="1024"
+ id="svg3030"
+ version="1.1"
+ inkscape:version="0.92.1 r15371"
+ sodipodi:docname="icon_default_project_icon.svg"
+ inkscape:export-filename="/home/akien/Projects/godot/godot.git/icon3.png"
+ inkscape:export-xdpi="6"
+ inkscape:export-ydpi="6">
+ <defs
+ id="defs3032" />
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.5"
+ inkscape:cx="601.35476"
+ inkscape:cy="346.09731"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ showgrid="false"
+ inkscape:window-width="1920"
+ inkscape:window-height="1011"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1" />
+ <metadata
+ id="metadata3035">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(0,-98.519719)">
+ <rect
+ style="fill:#1e1a21;fill-opacity:1;stroke:#2e2832;stroke-width:16;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect33"
+ width="1008"
+ height="1008"
+ x="8"
+ y="106.51972"
+ rx="176.28572"
+ ry="176.28572" />
+ <g
+ id="g82-3"
+ transform="matrix(4.2343801,0,0,-4.2343764,97.676491,522.86238)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 v -47.514 -6.035 -5.492 c 0.108,-0.001 0.216,-0.005 0.323,-0.015 l 36.196,-3.49 c 1.896,-0.183 3.382,-1.709 3.514,-3.609 l 1.116,-15.978 31.574,-2.253 2.175,14.747 c 0.282,1.912 1.922,3.329 3.856,3.329 h 38.188 c 1.933,0 3.573,-1.417 3.855,-3.329 l 2.175,-14.747 31.575,2.253 1.115,15.978 c 0.133,1.9 1.618,3.425 3.514,3.609 l 36.182,3.49 c 0.107,0.01 0.214,0.014 0.322,0.015 v 4.711 l 0.015,0.005 V 0 h 0.134 c 4.795,6.12 9.232,12.569 13.487,19.449 -5.651,9.62 -12.575,18.217 -19.976,26.182 -6.864,-3.455 -13.531,-7.369 -19.828,-11.534 -3.151,3.132 -6.7,5.694 -10.186,8.372 -3.425,2.751 -7.285,4.768 -10.946,7.118 1.09,8.117 1.629,16.108 1.846,24.448 -9.446,4.754 -19.519,7.906 -29.708,10.17 -4.068,-6.837 -7.788,-14.241 -11.028,-21.479 -3.842,0.642 -7.702,0.88 -11.567,0.926 v 0.006 c -0.027,0 -0.052,-0.006 -0.075,-0.006 -0.024,0 -0.049,0.006 -0.073,0.006 V 63.652 C 93.903,63.606 90.046,63.368 86.203,62.726 82.965,69.964 79.247,77.368 75.173,84.205 64.989,81.941 54.915,78.789 45.47,74.035 45.686,65.695 46.225,57.704 47.318,49.587 43.65,47.237 39.795,45.22 36.369,42.469 32.888,39.791 29.333,37.229 26.181,34.097 19.884,38.262 13.219,42.176 6.353,45.631 -1.048,37.666 -7.968,29.069 -13.621,19.449 -9.368,12.569 -4.928,6.12 -0.134,0 Z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path84-6"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g86-7"
+ transform="matrix(4.2343801,0,0,-4.2343764,788.7623,819.22103)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 -1.121,-16.063 c -0.135,-1.936 -1.675,-3.477 -3.611,-3.616 l -38.555,-2.751 c -0.094,-0.007 -0.188,-0.01 -0.281,-0.01 -1.916,0 -3.569,1.406 -3.852,3.33 l -2.211,14.994 H -81.09 l -2.211,-14.994 c -0.297,-2.018 -2.101,-3.469 -4.133,-3.32 l -38.555,2.751 c -1.936,0.139 -3.476,1.68 -3.611,3.616 L -130.721,0 -163.268,3.138 c 0.015,-3.498 0.06,-7.33 0.06,-8.093 0,-34.374 43.605,-50.896 97.781,-51.086 h 0.066 0.067 c 54.176,0.19 97.766,16.712 97.766,51.086 0,0.777 0.047,4.593 0.063,8.093 z"
+ style="fill:#478cbf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path88-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g90-3"
+ transform="matrix(4.2343801,0,0,-4.2343764,387.09785,624.34645)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 c 0,-12.052 -9.765,-21.815 -21.813,-21.815 -12.042,0 -21.81,9.763 -21.81,21.815 0,12.044 9.768,21.802 21.81,21.802 C -9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path92-5"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g94-6"
+ transform="matrix(4.2343801,0,0,-4.2343764,364.87318,629.82505)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 c 0,-7.994 -6.479,-14.473 -14.479,-14.473 -7.996,0 -14.479,6.479 -14.479,14.473 0,7.994 6.483,14.479 14.479,14.479 C -6.479,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path96-2"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g98-9"
+ transform="matrix(4.2343801,0,0,-4.2343764,511.99324,725.12292)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 c -3.878,0 -7.021,2.858 -7.021,6.381 v 20.081 c 0,3.52 3.143,6.381 7.021,6.381 3.878,0 7.028,-2.861 7.028,-6.381 V 6.381 C 7.028,2.858 3.878,0 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path100-1"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g102-2"
+ transform="matrix(4.2343801,0,0,-4.2343764,636.90407,624.34645)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 c 0,-12.052 9.765,-21.815 21.815,-21.815 12.041,0 21.808,9.763 21.808,21.815 0,12.044 -9.767,21.802 -21.808,21.802 C 9.765,21.802 0,12.044 0,0"
+ style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path104-7"
+ inkscape:connector-curvature="0" />
+ </g>
+ <g
+ id="g106-0"
+ transform="matrix(4.2343801,0,0,-4.2343764,659.13434,629.82505)"
+ style="stroke-width:0.31488276">
+ <path
+ d="m 0,0 c 0,-7.994 6.477,-14.473 14.471,-14.473 8.002,0 14.479,6.479 14.479,14.473 0,7.994 -6.477,14.479 -14.479,14.479 C 6.477,14.479 0,7.994 0,0"
+ style="fill:#414042;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.31488276"
+ id="path108-9"
+ inkscape:connector-curvature="0" />
+ </g>
+ </g>
+</svg>
diff --git a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png
index 6cff663eb5..6e307e5eb8 100644
--- a/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/Square150x150Logo.scale-100.png
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png
index 12ec232c87..cb2516d7a0 100644
--- a/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/Square310x310Logo.scale-100.png
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png
index ad059994ed..6e14223e87 100644
--- a/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/Square44x44Logo.scale-100.png
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png b/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png
index b1bf331365..0d4bd54da8 100644
--- a/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/Square71x71Logo.scale-100.png
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png b/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png
index 8d7a625c82..1501a09557 100644
--- a/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/StoreLogo.scale-100.png
Binary files differ
diff --git a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png b/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png
index b06f1ad50f..593568e980 100644
--- a/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png
+++ b/misc/dist/uwp_template/Assets/Wide310x150Logo.scale-100.png
Binary files differ
diff --git a/misc/scripts/svgs_2_pngs.py b/misc/scripts/svgs_2_pngs.py
index 0459f63bfa..b24324dcd7 100644
--- a/misc/scripts/svgs_2_pngs.py
+++ b/misc/scripts/svgs_2_pngs.py
@@ -16,7 +16,7 @@ last_svg_data = None
SCRIPT_FOLDER = dirname(realpath(__file__)) + '/'
theme_dir_base = SCRIPT_FOLDER + '../../scene/resources/default_theme/'
theme_dir_source = theme_dir_base + 'source/'
-icons_dir_base = SCRIPT_FOLDER + '../../editor/icons/'
+icons_dir_base = SCRIPT_FOLDER + '../editor/icons/'
icons_dir_2x = icons_dir_base + '2x/'
icons_dir_source = icons_dir_base + 'source/'
@@ -54,14 +54,14 @@ def export_icons():
out_icon_names = [name_only] # export to a png with the same file name
theme_out_icon_names = []
# special cases
- if special_icons.get(name_only):
+ if special_icons.has_key(name_only):
special_icon = special_icons[name_only]
if type(special_icon) is dict:
if special_icon.get('avoid_self'):
out_icon_names = []
- if special_icon.get('output_names'):
+ if special_icon.has_key('output_names'):
out_icon_names += special_icon['output_names']
- if special_icon.get('theme_output_names'):
+ if special_icon.has_key('theme_output_names'):
theme_out_icon_names += special_icon['theme_output_names']
source_path = '%s%s.svg' % (svgs_path, name_only)
@@ -83,10 +83,10 @@ def export_theme():
out_icon_names = [name_only] # export to a png with the same file name
# special cases
- if theme_icons.get(name_only):
+ if theme_icons.has_key(name_only):
special_icon = theme_icons[name_only]
if type(special_icon) is dict:
- if special_icon.get('output_names'):
+ if special_icon.has_key('output_names'):
out_icon_names += special_icon['output_names']
source_path = '%s%s.svg' % (svgs_path, name_only)
diff --git a/modules/dds/texture_loader_dds.cpp b/modules/dds/texture_loader_dds.cpp
index d79b7685d1..71593ebfa9 100644
--- a/modules/dds/texture_loader_dds.cpp
+++ b/modules/dds/texture_loader_dds.cpp
@@ -76,8 +76,6 @@ static const DDSFormatInfo dds_format_info[DDS_MAX] = {
{ "DXT1", true, false, 4, 8, Image::FORMAT_DXT1 },
{ "DXT3", true, false, 4, 16, Image::FORMAT_DXT3 },
{ "DXT5", true, false, 4, 16, Image::FORMAT_DXT5 },
- { "ATI1", true, false, 4, 8, Image::FORMAT_ATI1 },
- { "ATI2", true, false, 4, 16, Image::FORMAT_ATI2 },
{ "BGRA8", false, false, 1, 4, Image::FORMAT_RGBA8 },
{ "BGR8", false, false, 1, 3, Image::FORMAT_RGB8 },
{ "RGBA8", false, false, 1, 4, Image::FORMAT_RGBA8 },
@@ -441,7 +439,7 @@ RES ResourceFormatDDS::load(const String &p_path, const String &p_original_path,
wb = PoolVector<uint8_t>::Write();
}
- Image img(width, height, mipmaps - 1, info.format, src_data);
+ Ref<Image> img = memnew(Image(width, height, mipmaps - 1, info.format, src_data));
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(img);
diff --git a/modules/enet/networked_multiplayer_enet.cpp b/modules/enet/networked_multiplayer_enet.cpp
index c05c86d9ae..738bd27ed3 100644
--- a/modules/enet/networked_multiplayer_enet.cpp
+++ b/modules/enet/networked_multiplayer_enet.cpp
@@ -575,6 +575,9 @@ size_t NetworkedMultiplayerENet::enet_compress(void *context, const ENetBuffer *
case COMPRESS_ZLIB: {
mode = Compression::MODE_DEFLATE;
} break;
+ case COMPRESS_ZSTD: {
+ mode = Compression::MODE_ZSTD;
+ } break;
default: { ERR_FAIL_V(0); }
}
@@ -608,6 +611,10 @@ size_t NetworkedMultiplayerENet::enet_decompress(void *context, const enet_uint8
ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_DEFLATE);
} break;
+ case COMPRESS_ZSTD: {
+
+ ret = Compression::decompress(outData, outLimit, inData, inLimit, Compression::MODE_ZSTD);
+ } break;
default: {}
}
if (ret < 0) {
@@ -629,7 +636,8 @@ void NetworkedMultiplayerENet::_setup_compressor() {
enet_host_compress_with_range_coder(host);
} break;
case COMPRESS_FASTLZ:
- case COMPRESS_ZLIB: {
+ case COMPRESS_ZLIB:
+ case COMPRESS_ZSTD: {
enet_host_compress(host, &enet_compressor);
} break;
@@ -654,6 +662,7 @@ void NetworkedMultiplayerENet::_bind_methods() {
BIND_CONSTANT(COMPRESS_RANGE_CODER);
BIND_CONSTANT(COMPRESS_FASTLZ);
BIND_CONSTANT(COMPRESS_ZLIB);
+ BIND_CONSTANT(COMPRESS_ZSTD);
}
NetworkedMultiplayerENet::NetworkedMultiplayerENet() {
diff --git a/modules/enet/networked_multiplayer_enet.h b/modules/enet/networked_multiplayer_enet.h
index c20c1af68e..8b971adf55 100644
--- a/modules/enet/networked_multiplayer_enet.h
+++ b/modules/enet/networked_multiplayer_enet.h
@@ -43,7 +43,8 @@ public:
COMPRESS_NONE,
COMPRESS_RANGE_CODER,
COMPRESS_FASTLZ,
- COMPRESS_ZLIB
+ COMPRESS_ZLIB,
+ COMPRESS_ZSTD
};
private:
diff --git a/modules/etc/SCsub b/modules/etc/SCsub
new file mode 100644
index 0000000000..8f5937017e
--- /dev/null
+++ b/modules/etc/SCsub
@@ -0,0 +1,37 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_etc = env_modules.Clone()
+
+# Thirdparty source files
+# Not unbundled so far since not widespread as shared library
+thirdparty_dir = "#thirdparty/etc2comp/"
+thirdparty_sources = [
+ "EtcBlock4x4.cpp",
+ "EtcBlock4x4Encoding.cpp",
+ "EtcBlock4x4Encoding_ETC1.cpp",
+ "EtcBlock4x4Encoding_R11.cpp",
+ "EtcBlock4x4Encoding_RG11.cpp",
+ "EtcBlock4x4Encoding_RGB8A1.cpp",
+ "EtcBlock4x4Encoding_RGB8.cpp",
+ "EtcBlock4x4Encoding_RGBA8.cpp",
+ "Etc.cpp",
+ "EtcDifferentialTrys.cpp",
+ "EtcFilter.cpp",
+ "EtcImage.cpp",
+ "EtcIndividualTrys.cpp",
+ "EtcMath.cpp",
+ "EtcSortedBlockList.cpp",
+]
+thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+env_etc.add_source_files(env.modules_sources, thirdparty_sources)
+env_etc.Append(CPPPATH=[thirdparty_dir])
+
+# Godot source files
+env_etc.add_source_files(env.modules_sources, "*.cpp")
+
+# upstream uses c++11
+env_etc.Append(CXXFLAGS="-std=gnu++11")
diff --git a/modules/etc1/config.py b/modules/etc/config.py
index fb920482f5..fb920482f5 100644
--- a/modules/etc1/config.py
+++ b/modules/etc/config.py
diff --git a/modules/etc/image_etc.cpp b/modules/etc/image_etc.cpp
new file mode 100644
index 0000000000..d9daffc59e
--- /dev/null
+++ b/modules/etc/image_etc.cpp
@@ -0,0 +1,199 @@
+/*************************************************************************/
+/* image_etc.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 "image_etc.h"
+#include "Etc.h"
+#include "EtcFilter.h"
+#include "image.h"
+#include "os/copymem.h"
+#include "os/os.h"
+#include "print_string.h"
+
+static Image::Format _get_etc2_mode(Image::DetectChannels format) {
+ switch (format) {
+ case Image::DETECTED_L:
+ case Image::DETECTED_R:
+ return Image::FORMAT_ETC2_R11;
+
+ case Image::DETECTED_RG:
+ return Image::FORMAT_ETC2_RG11;
+
+ case Image::DETECTED_RGB:
+ return Image::FORMAT_ETC2_RGB8;
+
+ case Image::DETECTED_RGBA:
+ return Image::FORMAT_ETC2_RGBA8;
+
+ // TODO: would be nice if we could use FORMAT_ETC2_RGB8A1 for FORMAT_RGBA5551
+ }
+
+ ERR_FAIL_COND_V(true, Image::FORMAT_MAX);
+}
+
+static Etc::Image::Format _image_format_to_etc2comp_format(Image::Format format) {
+ switch (format) {
+ case Image::FORMAT_ETC:
+ return Etc::Image::Format::ETC1;
+
+ case Image::FORMAT_ETC2_R11:
+ return Etc::Image::Format::R11;
+
+ case Image::FORMAT_ETC2_R11S:
+ return Etc::Image::Format::SIGNED_R11;
+
+ case Image::FORMAT_ETC2_RG11:
+ return Etc::Image::Format::RG11;
+
+ case Image::FORMAT_ETC2_RG11S:
+ return Etc::Image::Format::SIGNED_RG11;
+
+ case Image::FORMAT_ETC2_RGB8:
+ return Etc::Image::Format::RGB8;
+
+ case Image::FORMAT_ETC2_RGBA8:
+ return Etc::Image::Format::RGBA8;
+
+ case Image::FORMAT_ETC2_RGB8A1:
+ return Etc::Image::Format::RGB8A1;
+ }
+
+ ERR_FAIL_COND_V(true, Etc::Image::Format::UNKNOWN);
+}
+
+static void _decompress_etc1(Image *p_img) {
+ // not implemented, to be removed
+}
+
+static void _decompress_etc2(Image *p_img) {
+ // not implemented, to be removed
+}
+
+static void _compress_etc(Image *p_img, float p_lossy_quality, bool force_etc1_format, Image::CompressSource p_source) {
+ Image::Format img_format = p_img->get_format();
+ Image::DetectChannels detected_channels = p_img->get_detected_channels();
+
+ if (p_source == Image::COMPRESS_SOURCE_SRGB && (detected_channels == Image::DETECTED_R || detected_channels == Image::DETECTED_RG)) {
+ //R and RG do not support SRGB
+ detected_channels = Image::DETECTED_RGB;
+ }
+
+ if (p_source == Image::COMPRESS_SOURCE_NORMAL) {
+ //use RG channels only for normal
+ detected_channels = Image::DETECTED_RG;
+ }
+
+ if (img_format >= Image::FORMAT_DXT1) {
+ return; //do not compress, already compressed
+ }
+
+ if (img_format > Image::FORMAT_RGBA8) {
+ // TODO: we should be able to handle FORMAT_RGBA4444 and FORMAT_RGBA5551 eventually
+ return;
+ }
+
+ int imgw = p_img->get_width(), imgh = p_img->get_height();
+ ERR_FAIL_COND(nearest_power_of_2(imgw) != imgw || nearest_power_of_2(imgh) != imgh);
+
+ Image::Format etc_format = force_etc1_format ? Image::FORMAT_ETC : _get_etc2_mode(detected_channels);
+
+ Ref<Image> img = p_img->duplicate();
+
+ if (img->get_format() != Image::FORMAT_RGBA8)
+ img->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
+
+ PoolVector<uint8_t>::Read r = img->get_data().read();
+
+ int target_size = Image::get_image_data_size(imgw, imgh, etc_format, p_img->has_mipmaps() ? -1 : 0);
+ int mmc = p_img->has_mipmaps() ? Image::get_image_required_mipmaps(imgw, imgh, etc_format) : 0;
+
+ PoolVector<uint8_t> dst_data;
+ dst_data.resize(target_size);
+
+ PoolVector<uint8_t>::Write w = dst_data.write();
+
+ // prepare parameters to be passed to etc2comp
+ int num_cpus = OS::get_singleton()->get_processor_count();
+ int encoding_time = 0;
+ float effort = 0.0; //default, reasonable time
+
+ if (p_lossy_quality > 0.75)
+ effort = 0.4;
+ else if (p_lossy_quality > 0.85)
+ effort = 0.6;
+ else if (p_lossy_quality > 0.95)
+ effort = 0.8;
+
+ Etc::ErrorMetric error_metric = Etc::ErrorMetric::RGBX; // NOTE: we can experiment with other error metrics
+ Etc::Image::Format etc2comp_etc_format = _image_format_to_etc2comp_format(etc_format);
+
+ int wofs = 0;
+ for (int i = 0; i < mmc + 1; i++) {
+ // convert source image to internal etc2comp format (which is equivalent to Image::FORMAT_RGBAF)
+ // NOTE: We can alternatively add a case to Image::convert to handle Image::FORMAT_RGBAF conversion.
+ int mipmap_ofs = 0, mipmap_size = 0, mipmap_w = 0, mipmap_h = 0;
+ img->get_mipmap_offset_size_and_dimensions(i, mipmap_ofs, mipmap_size, mipmap_w, mipmap_h);
+ const uint8_t *src = &r[mipmap_ofs];
+
+ Etc::ColorFloatRGBA *src_rgba_f = new Etc::ColorFloatRGBA[mipmap_w * mipmap_h];
+ for (int i = 0; i < mipmap_w * mipmap_h; i++) {
+ int si = i * 4; // RGBA8
+ src_rgba_f[i] = Etc::ColorFloatRGBA::ConvertFromRGBA8(src[si], src[si + 1], src[si + 2], src[si + 3]);
+ }
+
+ unsigned char *etc_data = NULL;
+ unsigned int etc_data_len = 0;
+ unsigned int extended_width = 0, extended_height = 0;
+ Etc::Encode((float *)src_rgba_f, mipmap_w, mipmap_h, etc2comp_etc_format, error_metric, effort, num_cpus, num_cpus, &etc_data, &etc_data_len, &extended_width, &extended_height, &encoding_time);
+
+ memcpy(&w[wofs], etc_data, etc_data_len);
+ wofs += etc_data_len;
+
+ delete[] etc_data;
+ delete[] src_rgba_f;
+ }
+
+ p_img->create(imgw, imgh, mmc > 1 ? true : false, etc_format, dst_data);
+}
+
+static void _compress_etc1(Image *p_img, float p_lossy_quality) {
+ _compress_etc(p_img, p_lossy_quality, true, Image::COMPRESS_SOURCE_GENERIC);
+}
+
+static void _compress_etc2(Image *p_img, float p_lossy_quality, Image::CompressSource p_source) {
+ _compress_etc(p_img, p_lossy_quality, false, p_source);
+}
+
+void _register_etc_compress_func() {
+
+ Image::_image_compress_etc1_func = _compress_etc1;
+ //Image::_image_decompress_etc1 = _decompress_etc1;
+
+ Image::_image_compress_etc2_func = _compress_etc2;
+ //Image::_image_decompress_etc2 = _decompress_etc2;
+}
diff --git a/modules/etc1/image_etc.h b/modules/etc/image_etc.h
index 69e082bb87..3cbadef6fa 100644
--- a/modules/etc1/image_etc.h
+++ b/modules/etc/image_etc.h
@@ -30,6 +30,6 @@
#ifndef IMAGE_ETC1_H
#define IMAGE_ETC1_H
-void _register_etc1_compress_func();
+void _register_etc_compress_func();
#endif // IMAGE_ETC_H
diff --git a/modules/etc1/register_types.cpp b/modules/etc/register_types.cpp
index 859486222f..e777859a8f 100644
--- a/modules/etc1/register_types.cpp
+++ b/modules/etc/register_types.cpp
@@ -34,15 +34,15 @@
static ResourceFormatPKM *resource_loader_pkm = NULL;
-void register_etc1_types() {
+void register_etc_types() {
resource_loader_pkm = memnew(ResourceFormatPKM);
ResourceLoader::add_resource_format_loader(resource_loader_pkm);
- _register_etc1_compress_func();
+ _register_etc_compress_func();
}
-void unregister_etc1_types() {
+void unregister_etc_types() {
memdelete(resource_loader_pkm);
}
diff --git a/modules/etc1/register_types.h b/modules/etc/register_types.h
index 0552b87d65..44399376f3 100644
--- a/modules/etc1/register_types.h
+++ b/modules/etc/register_types.h
@@ -27,5 +27,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_etc1_types();
-void unregister_etc1_types();
+void register_etc_types();
+void unregister_etc_types();
diff --git a/modules/etc1/texture_loader_pkm.cpp b/modules/etc/texture_loader_pkm.cpp
index 9817de3a0f..c04528d2a0 100644
--- a/modules/etc1/texture_loader_pkm.cpp
+++ b/modules/etc/texture_loader_pkm.cpp
@@ -85,7 +85,7 @@ RES ResourceFormatPKM::load(const String &p_path, const String &p_original_path,
int width = h.origWidth;
int height = h.origHeight;
- Image img(width, height, mipmaps, Image::FORMAT_ETC, src_data);
+ Ref<Image> img = memnew(Image(width, height, mipmaps, Image::FORMAT_ETC, src_data));
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(img);
diff --git a/modules/etc1/texture_loader_pkm.h b/modules/etc/texture_loader_pkm.h
index 8a0f06a51a..8a0f06a51a 100644
--- a/modules/etc1/texture_loader_pkm.h
+++ b/modules/etc/texture_loader_pkm.h
diff --git a/modules/etc1/SCsub b/modules/etc1/SCsub
deleted file mode 100644
index 0c5dc66d2e..0000000000
--- a/modules/etc1/SCsub
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-Import('env_modules')
-
-env_etc1 = env_modules.Clone()
-
-# Thirdparty source files
-# Not unbundled so far since not widespread as shared library
-thirdparty_dir = "#thirdparty/rg-etc1/"
-thirdparty_sources = [
- "rg_etc1.cpp",
-]
-thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
-
-env_etc1.add_source_files(env.modules_sources, thirdparty_sources)
-env_etc1.Append(CPPPATH=[thirdparty_dir])
-
-# Godot source files
-env_etc1.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/etc1/image_etc.cpp b/modules/etc1/image_etc.cpp
deleted file mode 100644
index 60544594f6..0000000000
--- a/modules/etc1/image_etc.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*************************************************************************/
-/* image_etc.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 "image_etc.h"
-#include "image.h"
-#include "os/copymem.h"
-#include "print_string.h"
-#include "rg_etc1.h"
-static void _decompress_etc(Image *p_img) {
-
- ERR_FAIL_COND(p_img->get_format() != Image::FORMAT_ETC);
-
- int imgw = p_img->get_width();
- int imgh = p_img->get_height();
- PoolVector<uint8_t> src = p_img->get_data();
- PoolVector<uint8_t> dst;
-
- PoolVector<uint8_t>::Read r = src.read();
-
- int mmc = p_img->get_mipmap_count();
-
- for (int i = 0; i <= mmc; i++) {
-
- dst.resize(dst.size() + imgw * imgh * 3);
- const uint8_t *srcbr = &r[p_img->get_mipmap_offset(i)];
- PoolVector<uint8_t>::Write w = dst.write();
-
- uint8_t *wptr = &w[dst.size() - imgw * imgh * 3];
-
- int bw = MAX(imgw / 4, 1);
- int bh = MAX(imgh / 4, 1);
-
- for (int y = 0; y < bh; y++) {
-
- for (int x = 0; x < bw; x++) {
-
- uint8_t block[4 * 4 * 4];
-
- rg_etc1::unpack_etc1_block(srcbr, (unsigned int *)block);
- srcbr += 8;
-
- int maxx = MIN(imgw, 4);
- int maxy = MIN(imgh, 4);
-
- for (int yy = 0; yy < maxy; yy++) {
-
- for (int xx = 0; xx < maxx; xx++) {
-
- uint32_t src_ofs = (yy * 4 + xx) * 4;
- uint32_t dst_ofs = ((y * 4 + yy) * imgw + x * 4 + xx) * 3;
- wptr[dst_ofs + 0] = block[src_ofs + 0];
- wptr[dst_ofs + 1] = block[src_ofs + 1];
- wptr[dst_ofs + 2] = block[src_ofs + 2];
- }
- }
- }
- }
-
- imgw = MAX(1, imgw / 2);
- imgh = MAX(1, imgh / 2);
- }
-
- r = PoolVector<uint8_t>::Read();
- //print_line("Re Creating ETC into regular image: w "+itos(p_img->get_width())+" h "+itos(p_img->get_height())+" mm "+itos(p_img->get_mipmaps()));
- *p_img = Image(p_img->get_width(), p_img->get_height(), p_img->has_mipmaps(), Image::FORMAT_RGB8, dst);
- if (p_img->has_mipmaps())
- p_img->generate_mipmaps();
-}
-
-static void _compress_etc(Image *p_img) {
-
- Image img = *p_img;
-
- int imgw = img.get_width(), imgh = img.get_height();
-
- ERR_FAIL_COND(nearest_power_of_2(imgw) != imgw || nearest_power_of_2(imgh) != imgh);
-
- if (img.get_format() != Image::FORMAT_RGB8)
- img.convert(Image::FORMAT_RGB8);
-
- PoolVector<uint8_t> res_data;
- PoolVector<uint8_t> dst_data;
- PoolVector<uint8_t>::Read r = img.get_data().read();
-
- int target_size = Image::get_image_data_size(p_img->get_width(), p_img->get_height(), Image::FORMAT_ETC, p_img->has_mipmaps() ? -1 : 0);
- int mmc = p_img->has_mipmaps() ? Image::get_image_required_mipmaps(p_img->get_width(), p_img->get_height(), Image::FORMAT_ETC) : 0;
-
- dst_data.resize(target_size);
- int mc = 0;
- int ofs = 0;
- PoolVector<uint8_t>::Write w = dst_data.write();
-
- rg_etc1::etc1_pack_params pp;
- pp.m_quality = rg_etc1::cLowQuality;
- for (int i = 0; i <= mmc; i++) {
-
- int bw = MAX(imgw / 4, 1);
- int bh = MAX(imgh / 4, 1);
- const uint8_t *src = &r[img.get_mipmap_offset(i)];
- int mmsize = MAX(bw, 1) * MAX(bh, 1) * 8;
-
- uint8_t *dst = &w[ofs];
- ofs += mmsize;
-
- //print_line("bh: "+itos(bh)+" bw: "+itos(bw));
-
- for (int y = 0; y < bh; y++) {
-
- for (int x = 0; x < bw; x++) {
-
- //print_line("x: "+itos(x)+" y: "+itos(y));
-
- uint8_t block[4 * 4 * 4];
- zeromem(block, 4 * 4 * 4);
- uint8_t cblock[8];
-
- int maxy = MIN(imgh, 4);
- int maxx = MIN(imgw, 4);
-
- for (int yy = 0; yy < maxy; yy++) {
-
- for (int xx = 0; xx < maxx; xx++) {
-
- uint32_t dst_ofs = (yy * 4 + xx) * 4;
- uint32_t src_ofs = ((y * 4 + yy) * imgw + x * 4 + xx) * 3;
- block[dst_ofs + 0] = src[src_ofs + 0];
- block[dst_ofs + 1] = src[src_ofs + 1];
- block[dst_ofs + 2] = src[src_ofs + 2];
- block[dst_ofs + 3] = 255;
- }
- }
-
- rg_etc1::pack_etc1_block(cblock, (const unsigned int *)block, pp);
- for (int j = 0; j < 8; j++) {
-
- dst[j] = cblock[j];
- }
-
- dst += 8;
- }
- }
-
- imgw = MAX(1, imgw / 2);
- imgh = MAX(1, imgh / 2);
- mc++;
- }
-
- *p_img = Image(p_img->get_width(), p_img->get_height(), (mc - 1) ? true : false, Image::FORMAT_ETC, dst_data);
-}
-
-void _register_etc1_compress_func() {
-
- rg_etc1::pack_etc1_block_init();
- Image::_image_compress_etc_func = _compress_etc;
- Image::_image_decompress_etc = _decompress_etc;
-}
diff --git a/modules/gdnative/gdnative.cpp b/modules/gdnative/gdnative.cpp
index 09859d95bd..706b81f7a3 100644
--- a/modules/gdnative/gdnative.cpp
+++ b/modules/gdnative/gdnative.cpp
@@ -99,15 +99,15 @@ Error NativeLibrary::terminate(NativeLibrary *&p_native_lib) {
Error error = OK;
void *library_terminate;
error = OS::get_singleton()->get_dynamic_library_symbol_handle(p_native_lib->handle, GDNativeScriptLanguage::get_terminate_symbol_name(), library_terminate);
- if (error)
- return OK; // no terminate? okay, not that important lol
+ if (!error) {
- void (*library_terminate_pointer)(godot_native_terminate_options *) = (void (*)(godot_native_terminate_options *))library_terminate;
+ void (*library_terminate_pointer)(godot_native_terminate_options *) = (void (*)(godot_native_terminate_options *))library_terminate;
- godot_native_terminate_options options;
- options.in_editor = SceneTree::get_singleton()->is_editor_hint();
+ godot_native_terminate_options options;
+ options.in_editor = SceneTree::get_singleton()->is_editor_hint();
- library_terminate_pointer(&options);
+ library_terminate_pointer(&options);
+ }
GDNativeScriptLanguage::get_singleton()->initialized_libraries.erase(p_native_lib->path);
@@ -515,11 +515,10 @@ static const char *_dl_platforms_info[] = {
"unix|x11|so|X11",
"unix|server|so|Server",
"unix|android|so|Android",
- "unix|blackberry|so|Blackberry 10",
"unix|haiku|so|Haiku", // Right?
- "|mac|dynlib|Mac",
- "mac|ios|dynlib|iOS",
- "mac|osx|dynlib|OSX",
+ "|mac|dylib|Mac",
+ "mac|ios|dylib|iOS",
+ "mac|osx|dylib|OSX",
"|html5|js|HTML5",
"|windows|dll|Windows",
"windows|uwp|dll|UWP",
@@ -615,7 +614,6 @@ Error GDNativeLibrary::_terminate() {
}
Error ret = NativeLibrary::terminate(native_library);
-
native_library->scripts.clear();
return ret;
@@ -1218,6 +1216,7 @@ void GDNativeReloadNode::_notification(int p_what) {
Set<GDNativeScript *> scripts;
for (Set<GDNativeScript *>::Element *S = GDNativeScriptLanguage::get_singleton()->script_list.front(); S; S = S->next()) {
+
if (lib->native_library->scripts.has(S->get()->get_script_name())) {
GDNativeScript *script = S->get();
script->script_data = lib->get_script_data(script->get_script_name());
diff --git a/modules/gdnative/gdnative.h b/modules/gdnative/gdnative.h
index 27e0c3788b..6716b684a0 100644
--- a/modules/gdnative/gdnative.h
+++ b/modules/gdnative/gdnative.h
@@ -40,7 +40,7 @@
#include "godot.h"
-class GDNativeScriptData;
+struct GDNativeScriptData;
class GDNativeLibrary;
struct NativeLibrary {
@@ -127,8 +127,6 @@ struct GDNativeScriptData {
}
};
-class GDNativeLibrary;
-
class GDNativeScript : public Script {
GDCLASS(GDNativeScript, Script);
@@ -208,7 +206,7 @@ class GDNativeLibrary : public Resource {
protected:
friend class GDNativeScript;
- friend class NativeLibrary;
+ friend struct NativeLibrary;
friend class GDNativeReloadNode;
GDNativeScriptData *get_script_data(const StringName p_name);
diff --git a/modules/gdnative/godot.cpp b/modules/gdnative/godot.cpp
index 7477a28db6..4dbb72bba1 100644
--- a/modules/gdnative/godot.cpp
+++ b/modules/gdnative/godot.cpp
@@ -30,6 +30,7 @@
#include "godot.h"
#include "class_db.h"
+#include "error_macros.h"
#include "gdnative.h"
#include "global_config.h"
#include "global_constants.h"
@@ -50,10 +51,8 @@ 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 _image_api_anchor();
extern "C" void _node_path_api_anchor();
extern "C" void _rid_api_anchor();
-extern "C" void _input_event_api_anchor();
extern "C" void _dictionary_api_anchor();
extern "C" void _array_api_anchor();
extern "C" void _pool_arrays_api_anchor();
@@ -72,10 +71,8 @@ void _api_anchor() {
_basis_api_anchor();
_transform_api_anchor();
_color_api_anchor();
- _image_api_anchor();
_node_path_api_anchor();
_rid_api_anchor();
- _input_event_api_anchor();
_dictionary_api_anchor();
_array_api_anchor();
_pool_arrays_api_anchor();
@@ -115,6 +112,28 @@ void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_obj
mb->ptrcall(o, p_args, p_ret);
}
+godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, godot_object *p_instance, const godot_variant **p_args, const int p_arg_count, godot_variant_call_error *p_call_error) {
+ MethodBind *mb = (MethodBind *)p_method_bind;
+ Object *o = (Object *)p_instance;
+ const Variant **args = (const Variant **)p_args;
+
+ godot_variant ret;
+ godot_variant_new_nil(&ret);
+
+ Variant *ret_val = (Variant *)&ret;
+
+ Variant::CallError r_error;
+ *ret_val = mb->call(o, args, p_arg_count, r_error);
+
+ if (p_call_error) {
+ p_call_error->error = (godot_variant_call_error_error)r_error.error;
+ p_call_error->argument = r_error.argument;
+ p_call_error->expected = (godot_variant_type)r_error.expected;
+ }
+
+ return ret;
+}
+
// @Todo
/*
void GDAPI godot_method_bind_varcall(godot_method_bind *p_method_bind)
@@ -215,6 +234,18 @@ void GDAPI godot_free(void *p_ptr) {
memfree(p_ptr);
}
+void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line) {
+ _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_ERROR);
+}
+
+void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line) {
+ _err_print_error(p_function, p_file, p_line, p_description, ERR_HANDLER_WARNING);
+}
+
+void GDAPI godot_print(const godot_string *p_message) {
+ print_line(*(String *)p_message);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/godot.h b/modules/gdnative/godot.h
index b05cafbe50..1d86998291 100644
--- a/modules/gdnative/godot.h
+++ b/modules/gdnative/godot.h
@@ -60,6 +60,13 @@ extern "C" {
#define GDAPI GDCALLINGCONV
#endif
+// This is for libraries *using* the header, NOT GODOT EXPOSING STUFF!!
+#ifdef _WIN32
+#define GDN_EXPORT __declspec(dllexport)
+#else
+#define GDN_EXPORT
+#endif
+
#include <stdbool.h>
#include <stdint.h>
@@ -139,6 +146,31 @@ typedef float godot_real;
/////// Object (forward declared)
typedef void godot_object;
+/////// Brute force forward declarations for the rest
+typedef struct godot_variant godot_variant;
+typedef struct godot_string godot_string;
+typedef struct godot_vector2 godot_vector2;
+typedef struct godot_rect2 godot_rect2;
+typedef struct godot_vector3 godot_vector3;
+typedef struct godot_transform2d godot_transform2d;
+typedef struct godot_plane godot_plane;
+typedef struct godot_quat godot_quat;
+typedef struct godot_rect3 godot_rect3;
+typedef struct godot_basis godot_basis;
+typedef struct godot_transform godot_transform;
+typedef struct godot_color godot_color;
+typedef struct godot_node_path godot_node_path;
+typedef struct godot_rid godot_rid;
+typedef struct godot_dictionary godot_dictionary;
+typedef struct godot_array godot_array;
+typedef struct godot_pool_byte_array godot_pool_byte_array;
+typedef struct godot_pool_int_array godot_pool_int_array;
+typedef struct godot_pool_real_array godot_pool_real_array;
+typedef struct godot_pool_string_array godot_pool_string_array;
+typedef struct godot_pool_vector2_array godot_pool_vector2_array;
+typedef struct godot_pool_vector3_array godot_pool_vector3_array;
+typedef struct godot_pool_color_array godot_pool_color_array;
+
/////// String
#include "godot/godot_string.h"
@@ -183,10 +215,6 @@ typedef void godot_object;
#include "godot/godot_color.h"
-/////// Image
-
-#include "godot/godot_image.h"
-
/////// NodePath
#include "godot/godot_node_path.h"
@@ -195,10 +223,6 @@ typedef void godot_object;
#include "godot/godot_rid.h"
-/////// InputEvent
-
-#include "godot/godot_input_event.h"
-
/////// Dictionary
#include "godot/godot_dictionary.h"
@@ -228,7 +252,7 @@ typedef struct godot_method_bind {
godot_method_bind GDAPI *godot_method_bind_get_method(const char *p_classname, const char *p_methodname);
void GDAPI godot_method_bind_ptrcall(godot_method_bind *p_method_bind, godot_object *p_instance, const void **p_args, void *p_ret);
-
+godot_variant GDAPI godot_method_bind_call(godot_method_bind *p_method_bind, godot_object *p_instance, const godot_variant **p_args, const int p_arg_count, godot_variant_call_error *p_call_error);
////// Script API
typedef struct godot_native_init_options {
@@ -404,6 +428,11 @@ void GDAPI *godot_alloc(int p_bytes);
void GDAPI *godot_realloc(void *p_ptr, int p_bytes);
void GDAPI godot_free(void *p_ptr);
+//print using Godot's error handler list
+void GDAPI godot_print_error(const char *p_description, const char *p_function, const char *p_file, int p_line);
+void GDAPI godot_print_warning(const char *p_description, const char *p_function, const char *p_file, int p_line);
+void GDAPI godot_print(const godot_string *p_message);
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/godot/godot_array.cpp b/modules/gdnative/godot/godot_array.cpp
index 6c55c5d048..5497dde520 100644
--- a/modules/gdnative/godot/godot_array.cpp
+++ b/modules/gdnative/godot/godot_array.cpp
@@ -44,255 +44,264 @@ extern "C" {
void _array_api_anchor() {
}
-void GDAPI godot_array_new(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- memnew_placement(a, Array);
+void GDAPI godot_array_new(godot_array *r_dest) {
+ Array *dest = (Array *)r_dest;
+ memnew_placement(dest, Array);
}
-void GDAPI godot_array_new_pool_color_array(godot_array *p_arr, const godot_pool_color_array *p_pca) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src) {
+ Array *dest = (Array *)r_dest;
+ const Array *src = (const Array *)p_src;
+ memnew_placement(dest, Array(*src));
+}
+
+void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca) {
+ Array *dest = (Array *)r_dest;
PoolVector<Color> *pca = (PoolVector<Color> *)p_pca;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_vector3_array(godot_array *p_arr, const godot_pool_vector3_array *p_pv3a) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_pool_vector3_array *p_pv3a) {
+ Array *dest = (Array *)r_dest;
PoolVector<Vector3> *pca = (PoolVector<Vector3> *)p_pv3a;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_vector2_array(godot_array *p_arr, const godot_pool_vector2_array *p_pv2a) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_pool_vector2_array *p_pv2a) {
+ Array *dest = (Array *)r_dest;
PoolVector<Vector2> *pca = (PoolVector<Vector2> *)p_pv2a;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_string_array(godot_array *p_arr, const godot_pool_string_array *p_psa) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_pool_string_array *p_psa) {
+ Array *dest = (Array *)r_dest;
PoolVector<String> *pca = (PoolVector<String> *)p_psa;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_real_array(godot_array *p_arr, const godot_pool_real_array *p_pra) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool_real_array *p_pra) {
+ Array *dest = (Array *)r_dest;
PoolVector<godot_real> *pca = (PoolVector<godot_real> *)p_pra;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_int_array(godot_array *p_arr, const godot_pool_int_array *p_pia) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_int_array *p_pia) {
+ Array *dest = (Array *)r_dest;
PoolVector<godot_int> *pca = (PoolVector<godot_int> *)p_pia;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_new_pool_byte_array(godot_array *p_arr, const godot_pool_byte_array *p_pba) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool_byte_array *p_pba) {
+ Array *dest = (Array *)r_dest;
PoolVector<uint8_t> *pca = (PoolVector<uint8_t> *)p_pba;
- memnew_placement(a, Array);
- a->resize(pca->size());
+ memnew_placement(dest, Array);
+ dest->resize(pca->size());
- for (size_t i = 0; i < a->size(); i++) {
+ for (size_t i = 0; i < dest->size(); i++) {
Variant v = pca->operator[](i);
- a->operator[](i) = v;
+ dest->operator[](i) = v;
}
}
-void GDAPI godot_array_set(godot_array *p_arr, const godot_int p_idx, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
Variant *val = (Variant *)p_value;
- a->operator[](p_idx) = *val;
+ self->operator[](p_idx) = *val;
+}
+
+godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx) {
+ godot_variant raw_dest;
+ Variant *dest = (Variant *)&raw_dest;
+ const Array *self = (const Array *)p_self;
+ memnew_placement(dest, Variant(self->operator[](p_idx)));
+ return raw_dest;
}
-godot_variant GDAPI *godot_array_get(godot_array *p_arr, const godot_int p_idx) {
- Array *a = (Array *)p_arr;
- return (godot_variant *)&a->operator[](p_idx);
+godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx) {
+ Array *self = (Array *)p_self;
+ return (godot_variant *)&self->operator[](p_idx);
}
-void GDAPI godot_array_append(godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
+void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
Variant *val = (Variant *)p_value;
- a->append(*val);
+ self->append(*val);
}
-void GDAPI godot_array_clear(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- a->clear();
+void GDAPI godot_array_clear(godot_array *p_self) {
+ Array *self = (Array *)p_self;
+ self->clear();
}
-godot_int GDAPI godot_array_count(godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- return a->count(*val);
+godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value) {
+ const Array *self = (const Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ return self->count(*val);
}
-godot_bool GDAPI godot_array_empty(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- return a->empty();
+godot_bool GDAPI godot_array_empty(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
+ return self->empty();
}
-void GDAPI godot_array_erase(godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- a->erase(*val);
+void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ self->erase(*val);
}
-godot_variant GDAPI godot_array_front(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
+godot_variant GDAPI godot_array_front(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
godot_variant v;
Variant *val = (Variant *)&v;
memnew_placement(val, Variant);
- *val = a->front();
+ *val = self->front();
return v;
}
-godot_variant GDAPI godot_array_back(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
+godot_variant GDAPI godot_array_back(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
godot_variant v;
Variant *val = (Variant *)&v;
memnew_placement(val, Variant);
- *val = a->back();
+ *val = self->back();
return v;
}
-godot_int GDAPI godot_array_find(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_what;
- return a->find(*val, p_from);
+godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
+ const Array *self = (const Array *)p_self;
+ const Variant *val = (const Variant *)p_what;
+ return self->find(*val, p_from);
}
-godot_int GDAPI godot_array_find_last(const godot_array *p_arr, const godot_variant *p_what) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_what;
- return a->find_last(*val);
+godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what) {
+ const Array *self = (const Array *)p_self;
+ const Variant *val = (const Variant *)p_what;
+ return self->find_last(*val);
}
-godot_bool GDAPI godot_array_has(const godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- return a->has(*val);
-}
-
-uint32_t GDAPI godot_array_hash(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- return a->hash();
+godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value) {
+ const Array *self = (const Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ return self->has(*val);
}
-void GDAPI godot_array_insert(godot_array *p_arr, const godot_int p_pos, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- a->insert(p_pos, *val);
+godot_int GDAPI godot_array_hash(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
+ return self->hash();
}
-void GDAPI godot_array_invert(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- a->invert();
+void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ self->insert(p_pos, *val);
}
-godot_bool GDAPI godot_array_is_shared(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- return false; // @Todo how do I do it?
+void GDAPI godot_array_invert(godot_array *p_self) {
+ Array *self = (Array *)p_self;
+ self->invert();
}
-godot_variant GDAPI godot_array_pop_back(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
+godot_variant GDAPI godot_array_pop_back(godot_array *p_self) {
+ Array *self = (Array *)p_self;
godot_variant v;
Variant *val = (Variant *)&v;
memnew_placement(val, Variant);
- *val = a->pop_back();
+ *val = self->pop_back();
return v;
}
-godot_variant GDAPI godot_array_pop_front(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
+godot_variant GDAPI godot_array_pop_front(godot_array *p_self) {
+ Array *self = (Array *)p_self;
godot_variant v;
Variant *val = (Variant *)&v;
memnew_placement(val, Variant);
- *val = a->pop_front();
+ *val = self->pop_front();
return v;
}
-void GDAPI godot_array_push_back(godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- a->push_back(*val);
+void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ self->push_back(*val);
}
-void GDAPI godot_array_push_front(godot_array *p_arr, const godot_variant *p_value) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_value;
- a->push_front(*val);
+void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value) {
+ Array *self = (Array *)p_self;
+ const Variant *val = (const Variant *)p_value;
+ self->push_front(*val);
}
-void GDAPI godot_array_remove(godot_array *p_arr, const godot_int p_idx) {
- Array *a = (Array *)p_arr;
- a->remove(p_idx);
+void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx) {
+ Array *self = (Array *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_array_resize(godot_array *p_arr, const godot_int p_size) {
- Array *a = (Array *)p_arr;
- a->resize(p_size);
+void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size) {
+ Array *self = (Array *)p_self;
+ self->resize(p_size);
}
-godot_int GDAPI godot_array_rfind(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from) {
- Array *a = (Array *)p_arr;
- Variant *val = (Variant *)p_what;
- return a->rfind(*val, p_from);
+godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from) {
+ const Array *self = (const Array *)p_self;
+ const Variant *val = (const Variant *)p_what;
+ return self->rfind(*val, p_from);
}
-godot_int GDAPI godot_array_size(const godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- return a->size();
+godot_int GDAPI godot_array_size(const godot_array *p_self) {
+ const Array *self = (const Array *)p_self;
+ return self->size();
}
-void GDAPI godot_array_sort(godot_array *p_arr) {
- Array *a = (Array *)p_arr;
- a->sort();
+void GDAPI godot_array_sort(godot_array *p_self) {
+ Array *self = (Array *)p_self;
+ self->sort();
}
-void GDAPI godot_array_sort_custom(godot_array *p_arr, godot_object *p_obj, const godot_string *p_func) {
- Array *a = (Array *)p_arr;
- String *func = (String *)p_func;
- a->sort_custom((Object *)p_obj, *func);
+void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func) {
+ Array *self = (Array *)p_self;
+ const String *func = (const String *)p_func;
+ self->sort_custom((Object *)p_obj, *func);
}
-void GDAPI godot_array_destroy(godot_array *p_arr) {
- ((Array *)p_arr)->~Array();
+void GDAPI godot_array_destroy(godot_array *p_self) {
+ ((Array *)p_self)->~Array();
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_array.h b/modules/gdnative/godot/godot_array.h
index b92ebb834f..bf8bc61977 100644
--- a/modules/gdnative/godot/godot_array.h
+++ b/modules/gdnative/godot/godot_array.h
@@ -43,73 +43,74 @@ typedef struct godot_array {
} godot_array;
#endif
-#include "../godot.h"
-
#include "godot_pool_arrays.h"
#include "godot_variant.h"
-void GDAPI godot_array_new(godot_array *p_arr);
-void GDAPI godot_array_new_pool_color_array(godot_array *p_arr, const godot_pool_color_array *p_pca);
-void GDAPI godot_array_new_pool_vector3_array(godot_array *p_arr, const godot_pool_vector3_array *p_pv3a);
-void GDAPI godot_array_new_pool_vector2_array(godot_array *p_arr, const godot_pool_vector2_array *p_pv2a);
-void GDAPI godot_array_new_pool_string_array(godot_array *p_arr, const godot_pool_string_array *p_psa);
-void GDAPI godot_array_new_pool_real_array(godot_array *p_arr, const godot_pool_real_array *p_pra);
-void GDAPI godot_array_new_pool_int_array(godot_array *p_arr, const godot_pool_int_array *p_pia);
-void GDAPI godot_array_new_pool_byte_array(godot_array *p_arr, const godot_pool_byte_array *p_pba);
+#include "../godot.h"
+
+void GDAPI godot_array_new(godot_array *r_dest);
+void GDAPI godot_array_new_copy(godot_array *r_dest, const godot_array *p_src);
+void GDAPI godot_array_new_pool_color_array(godot_array *r_dest, const godot_pool_color_array *p_pca);
+void GDAPI godot_array_new_pool_vector3_array(godot_array *r_dest, const godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_array_new_pool_vector2_array(godot_array *r_dest, const godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_array_new_pool_string_array(godot_array *r_dest, const godot_pool_string_array *p_psa);
+void GDAPI godot_array_new_pool_real_array(godot_array *r_dest, const godot_pool_real_array *p_pra);
+void GDAPI godot_array_new_pool_int_array(godot_array *r_dest, const godot_pool_int_array *p_pia);
+void GDAPI godot_array_new_pool_byte_array(godot_array *r_dest, const godot_pool_byte_array *p_pba);
-void GDAPI godot_array_set(godot_array *p_arr, const godot_int p_idx, const godot_variant *p_value);
+void GDAPI godot_array_set(godot_array *p_self, const godot_int p_idx, const godot_variant *p_value);
-godot_variant GDAPI *godot_array_get(godot_array *p_arr, const godot_int p_idx);
+godot_variant GDAPI godot_array_get(const godot_array *p_self, const godot_int p_idx);
-void GDAPI godot_array_append(godot_array *p_arr, const godot_variant *p_value);
+godot_variant GDAPI *godot_array_operator_index(godot_array *p_self, const godot_int p_idx);
-void GDAPI godot_array_clear(godot_array *p_arr);
+void GDAPI godot_array_append(godot_array *p_self, const godot_variant *p_value);
-godot_int GDAPI godot_array_count(godot_array *p_arr, const godot_variant *p_value);
+void GDAPI godot_array_clear(godot_array *p_self);
-godot_bool GDAPI godot_array_empty(const godot_array *p_arr);
+godot_int GDAPI godot_array_count(const godot_array *p_self, const godot_variant *p_value);
-void GDAPI godot_array_erase(godot_array *p_arr, const godot_variant *p_value);
+godot_bool GDAPI godot_array_empty(const godot_array *p_self);
-godot_variant GDAPI godot_array_front(const godot_array *p_arr);
+void GDAPI godot_array_erase(godot_array *p_self, const godot_variant *p_value);
-godot_variant GDAPI godot_array_back(const godot_array *p_arr);
+godot_variant GDAPI godot_array_front(const godot_array *p_self);
-godot_int GDAPI godot_array_find(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from);
+godot_variant GDAPI godot_array_back(const godot_array *p_self);
-godot_int GDAPI godot_array_find_last(const godot_array *p_arr, const godot_variant *p_what);
+godot_int GDAPI godot_array_find(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from);
-godot_bool GDAPI godot_array_has(const godot_array *p_arr, const godot_variant *p_value);
+godot_int GDAPI godot_array_find_last(const godot_array *p_self, const godot_variant *p_what);
-uint32_t GDAPI godot_array_hash(const godot_array *p_arr);
+godot_bool GDAPI godot_array_has(const godot_array *p_self, const godot_variant *p_value);
-void GDAPI godot_array_insert(godot_array *p_arr, const godot_int p_pos, const godot_variant *p_value);
+godot_int GDAPI godot_array_hash(const godot_array *p_self);
-void GDAPI godot_array_invert(godot_array *p_arr);
+void GDAPI godot_array_insert(godot_array *p_self, const godot_int p_pos, const godot_variant *p_value);
-godot_bool GDAPI godot_array_is_shared(const godot_array *p_arr);
+void GDAPI godot_array_invert(godot_array *p_self);
-godot_variant GDAPI godot_array_pop_back(godot_array *p_arr);
+godot_variant GDAPI godot_array_pop_back(godot_array *p_self);
-godot_variant GDAPI godot_array_pop_front(godot_array *p_arr);
+godot_variant GDAPI godot_array_pop_front(godot_array *p_self);
-void GDAPI godot_array_push_back(godot_array *p_arr, const godot_variant *p_value);
+void GDAPI godot_array_push_back(godot_array *p_self, const godot_variant *p_value);
-void GDAPI godot_array_push_front(godot_array *p_arr, const godot_variant *p_value);
+void GDAPI godot_array_push_front(godot_array *p_self, const godot_variant *p_value);
-void GDAPI godot_array_remove(godot_array *p_arr, const godot_int p_idx);
+void GDAPI godot_array_remove(godot_array *p_self, const godot_int p_idx);
-void GDAPI godot_array_resize(godot_array *p_arr, const godot_int p_size);
+void GDAPI godot_array_resize(godot_array *p_self, const godot_int p_size);
-godot_int GDAPI godot_array_rfind(const godot_array *p_arr, const godot_variant *p_what, const godot_int p_from);
+godot_int GDAPI godot_array_rfind(const godot_array *p_self, const godot_variant *p_what, const godot_int p_from);
-godot_int GDAPI godot_array_size(const godot_array *p_arr);
+godot_int GDAPI godot_array_size(const godot_array *p_self);
-void GDAPI godot_array_sort(godot_array *p_arr);
+void GDAPI godot_array_sort(godot_array *p_self);
-void GDAPI godot_array_sort_custom(godot_array *p_arr, godot_object *p_obj, const godot_string *p_func);
+void GDAPI godot_array_sort_custom(godot_array *p_self, godot_object *p_obj, const godot_string *p_func);
-void GDAPI godot_array_destroy(godot_array *p_arr);
+void GDAPI godot_array_destroy(godot_array *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_basis.cpp b/modules/gdnative/godot/godot_basis.cpp
index 474cd3d448..46464932c5 100644
--- a/modules/gdnative/godot/godot_basis.cpp
+++ b/modules/gdnative/godot/godot_basis.cpp
@@ -28,188 +28,245 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_basis.h"
+#include "core/variant.h"
-#include "math/matrix3.h"
+#include "core/math/matrix3.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _basis_api_anchor() {
+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;
+ const Vector3 *z_axis = (const Vector3 *)p_z_axis;
+ Basis *dest = (Basis *)r_dest;
+ *dest = Basis(*x_axis, *y_axis, *z_axis);
}
-void GDAPI godot_basis_new(godot_basis *p_v) {
- Basis *v = (Basis *)p_v;
- *v = Basis();
+void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi) {
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ Basis *dest = (Basis *)r_dest;
+ *dest = Basis(*axis, p_phi);
}
-void GDAPI godot_basis_new_with_euler_quat(godot_basis *p_v, const godot_quat *p_euler) {
- Basis *v = (Basis *)p_v;
- Quat *euler = (Quat *)p_euler;
- *v = Basis(*euler);
+void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler) {
+ const Vector3 *euler = (const Vector3 *)p_euler;
+ Basis *dest = (Basis *)r_dest;
+ *dest = Basis(*euler);
}
-void GDAPI godot_basis_new_with_euler(godot_basis *p_v, const godot_vector3 p_euler) {
- Basis *v = (Basis *)p_v;
- Vector3 *euler = (Vector3 *)&p_euler;
- *v = Basis(*euler);
+godot_string GDAPI godot_basis_as_string(const godot_basis *p_self) {
+ godot_string ret;
+ const Basis *self = (const Basis *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
}
-void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *p_v, const godot_vector3 p_axis, const godot_real p_phi) {
- Basis *v = (Basis *)p_v;
- const Vector3 *axis = (Vector3 *)&p_axis;
- *v = Basis(*axis, p_phi);
+godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self) {
+ godot_basis dest;
+ const Basis *self = (const Basis *)p_self;
+ *((Basis *)&dest) = self->inverse();
+ return dest;
}
-void GDAPI godot_basis_new_with_rows(godot_basis *p_v, const godot_vector3 p_row0, const godot_vector3 p_row1, const godot_vector3 p_row2) {
- Basis *v = (Basis *)p_v;
- const Vector3 *row0 = (Vector3 *)&p_row0;
- const Vector3 *row1 = (Vector3 *)&p_row1;
- const Vector3 *row2 = (Vector3 *)&p_row2;
- *v = Basis(*row0, *row1, *row2);
+godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self) {
+ godot_basis dest;
+ const Basis *self = (const Basis *)p_self;
+ *((Basis *)&dest) = self->transposed();
+ return dest;
}
-godot_quat GDAPI godot_basis_as_quat(const godot_basis *p_v) {
- const Basis *v = (const Basis *)p_v;
- godot_quat quat;
- Quat *p_quat = (Quat *)&quat;
- *p_quat = v->operator Quat();
- return quat;
+godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self) {
+ godot_basis dest;
+ const Basis *self = (const Basis *)p_self;
+ *((Basis *)&dest) = self->orthonormalized();
+ return dest;
}
-/*
- * p_elements is a pointer to an array of 3 (!!) vector3
- */
-void GDAPI godot_basis_get_elements(godot_basis *p_v, godot_vector3 *p_elements) {
- Basis *v = (Basis *)p_v;
- Vector3 *elements = (Vector3 *)p_elements;
- elements[0] = v->elements[0];
- elements[1] = v->elements[1];
- elements[2] = v->elements[2];
+godot_real GDAPI godot_basis_determinant(const godot_basis *p_self) {
+ const Basis *self = (const Basis *)p_self;
+ return self->determinant();
}
-godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_v, const godot_int p_axis) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- *d = v->get_axis(p_axis);
+godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
+ godot_basis dest;
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ *((Basis *)&dest) = self->rotated(*axis, p_phi);
return dest;
}
-void GDAPI godot_basis_set_axis(godot_basis *p_v, const godot_int p_axis, const godot_vector3 p_value) {
- Basis *v = (Basis *)p_v;
- const Vector3 *value = (Vector3 *)&p_value;
- v->set_axis(p_axis, *value);
+godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale) {
+ godot_basis dest;
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ *((Basis *)&dest) = self->scaled(*scale);
+ return dest;
}
-godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_v, const godot_int p_row) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- *d = v->get_row(p_row);
- return dest;
+void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ self->set_scale(*scale);
}
-void GDAPI godot_basis_set_row(godot_basis *p_v, const godot_int p_row, const godot_vector3 p_value) {
- Basis *v = (Basis *)p_v;
- const Vector3 *value = (Vector3 *)&p_value;
- v->set_row(p_row, *value);
+void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *euler = (const Vector3 *)p_euler;
+ self->set_rotation_euler(*euler);
}
-godot_real godot_basis_determinant(const godot_basis *p_v) {
- Basis *v = (Basis *)p_v;
- return v->determinant();
+void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ self->set_rotation_axis_angle(*axis, p_angle);
}
-godot_vector3 godot_basis_get_euler(const godot_basis *p_v) {
+godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- *d = v->get_euler();
+ const Basis *self = (const Basis *)p_self;
+ *((Vector3 *)&dest) = self->get_scale();
return dest;
}
-godot_int godot_basis_get_orthogonal_index(const godot_basis *p_v) {
- const Basis *v = (Basis *)p_v;
- return v->get_orthogonal_index();
-}
-
-godot_vector3 godot_basis_get_scale(const godot_basis *p_v) {
+godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- *d = v->get_scale();
+ const Basis *self = (const Basis *)p_self;
+ *((Vector3 *)&dest) = self->get_euler();
return dest;
}
-void godot_basis_inverse(godot_basis *p_dest, const godot_basis *p_v) {
- Basis *d = (Basis *)p_dest;
- const Basis *v = (Basis *)p_v;
- *d = v->inverse();
+godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with) {
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *with = (const Vector3 *)p_with;
+ return self->tdotx(*with);
+}
+
+godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with) {
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *with = (const Vector3 *)p_with;
+ return self->tdoty(*with);
}
-void godot_basis_orthonormalized(godot_basis *p_dest, const godot_basis *p_v) {
- Basis *d = (Basis *)p_dest;
- const Basis *v = (Basis *)p_v;
- *d = v->orthonormalized();
+godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with) {
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *with = (const Vector3 *)p_with;
+ return self->tdotz(*with);
}
-void godot_basis_rotated(godot_basis *p_dest, const godot_basis *p_v, const godot_vector3 p_axis, const godot_real p_phi) {
- Basis *d = (Basis *)p_dest;
- const Basis *v = (Basis *)p_v;
- const Vector3 *axis = (Vector3 *)&p_axis;
- *d = v->rotated(*axis, p_phi);
+godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v) {
+ godot_vector3 dest;
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ *((Vector3 *)&dest) = self->xform(*v);
+ return dest;
}
-void godot_basis_scaled(godot_basis *p_dest, const godot_basis *p_v, const godot_vector3 p_scale) {
- Basis *d = (Basis *)p_dest;
- const Basis *v = (Basis *)p_v;
- const Vector3 *scale = (Vector3 *)&p_scale;
- *d = v->scaled(*scale);
+godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v) {
+ godot_vector3 dest;
+ const Basis *self = (const Basis *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ *((Vector3 *)&dest) = self->xform_inv(*v);
+ return dest;
}
-godot_real godot_basis_tdotx(const godot_basis *p_v, const godot_vector3 p_with) {
- const Basis *v = (Basis *)p_v;
- const Vector3 *with = (Vector3 *)&p_with;
- return v->tdotx(*with);
+godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self) {
+ const Basis *self = (const Basis *)p_self;
+ return self->get_orthogonal_index();
}
-godot_real godot_basis_tdoty(const godot_basis *p_v, const godot_vector3 p_with) {
- const Basis *v = (Basis *)p_v;
- const Vector3 *with = (Vector3 *)&p_with;
- return v->tdoty(*with);
+void GDAPI godot_basis_new(godot_basis *r_dest) {
+ Basis *dest = (Basis *)r_dest;
+ *dest = Basis();
}
-godot_real godot_basis_tdotz(const godot_basis *p_v, const godot_vector3 p_with) {
- const Basis *v = (Basis *)p_v;
- const Vector3 *with = (Vector3 *)&p_with;
- return v->tdotz(*with);
+void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler) {
+ Basis *dest = (Basis *)r_dest;
+ const Quat *euler = (const Quat *)p_euler;
+ *dest = Basis(*euler);
}
-void godot_basis_transposed(godot_basis *p_dest, const godot_basis *p_v) {
- Basis *d = (Basis *)p_dest;
- const Basis *v = (Basis *)p_v;
- *d = v->transposed();
+// p_elements is a pointer to an array of 3 (!!) vector3
+void GDAPI godot_basis_get_elements(godot_basis *p_self, godot_vector3 *p_elements) {
+ const Basis *self = (const Basis *)p_self;
+ Vector3 *elements = (Vector3 *)p_elements;
+ elements[0] = self->elements[0];
+ elements[1] = self->elements[1];
+ elements[2] = self->elements[2];
}
-godot_vector3 godot_basis_xform(const godot_basis *p_v, const godot_vector3 p_vect) {
+godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis) {
godot_vector3 dest;
Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- const Vector3 *vect = (Vector3 *)&p_vect;
- *d = v->xform(*vect);
+ const Basis *self = (const Basis *)p_self;
+ *d = self->get_axis(p_axis);
return dest;
}
-godot_vector3 godot_basis_xform_inv(const godot_basis *p_v, const godot_vector3 p_vect) {
+void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *value = (const Vector3 *)p_value;
+ self->set_axis(p_axis, *value);
+}
+
+godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row) {
godot_vector3 dest;
Vector3 *d = (Vector3 *)&dest;
- const Basis *v = (Basis *)p_v;
- const Vector3 *vect = (Vector3 *)&p_vect;
- *d = v->xform_inv(*vect);
+ const Basis *self = (const Basis *)p_self;
+ *d = self->get_row(p_row);
return dest;
}
+void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value) {
+ Basis *self = (Basis *)p_self;
+ const Vector3 *value = (const Vector3 *)p_value;
+ self->set_row(p_row, *value);
+}
+
+godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b) {
+ const Basis *self = (const Basis *)p_self;
+ const Basis *b = (const Basis *)p_b;
+ return *self == *b;
+}
+
+godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b) {
+ godot_basis raw_dest;
+ Basis *dest = (Basis *)&raw_dest;
+ const Basis *self = (const Basis *)p_self;
+ const Basis *b = (const Basis *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
+}
+
+godot_basis GDAPI godot_basis_operator_substract(const godot_basis *p_self, const godot_basis *p_b) {
+ godot_basis raw_dest;
+ Basis *dest = (Basis *)&raw_dest;
+ const Basis *self = (const Basis *)p_self;
+ const Basis *b = (const Basis *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
+}
+
+godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b) {
+ godot_basis raw_dest;
+ Basis *dest = (Basis *)&raw_dest;
+ const Basis *self = (const Basis *)p_self;
+ const Basis *b = (const Basis *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
+}
+
+godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b) {
+ godot_basis raw_dest;
+ Basis *dest = (Basis *)&raw_dest;
+ const Basis *self = (const Basis *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/modules/gdnative/godot/godot_basis.h b/modules/gdnative/godot/godot_basis.h
index 2803396997..a096a8cc08 100644
--- a/modules/gdnative/godot/godot_basis.h
+++ b/modules/gdnative/godot/godot_basis.h
@@ -37,45 +37,79 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_BASIS_TYPE_DEFINED
typedef struct godot_basis {
uint8_t _dont_touch_that[36];
} godot_basis;
#endif
#include "../godot.h"
-#include "godot_quat.h"
-
-void GDAPI godot_basis_new(godot_basis *p_v);
-void GDAPI godot_basis_new_with_euler_quat(godot_basis *p_v, const godot_quat *p_euler);
-void GDAPI godot_basis_new_with_euler(godot_basis *p_v, const godot_vector3 p_euler);
-void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *p_v, const godot_vector3 p_axis, const godot_real p_phi);
-void GDAPI godot_basis_new_with_rows(godot_basis *p_v, const godot_vector3 p_row0, const godot_vector3 p_row1, const godot_vector3 p_row2);
-
-godot_quat GDAPI godot_basis_as_quat(const godot_basis *p_v);
-
-/*
- * p_elements is a pointer to an array of 3 (!!) vector3
- */
-void GDAPI godot_basis_get_elements(godot_basis *p_v, godot_vector3 *p_elements);
-godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_v, const godot_int p_axis);
-void GDAPI godot_basis_set_axis(godot_basis *p_v, const godot_int p_axis, const godot_vector3 p_value);
-godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_v, const godot_int p_row);
-void GDAPI godot_basis_set_row(godot_basis *p_v, const godot_int p_row, const godot_vector3 p_value);
-
-godot_real godot_basis_determinant(const godot_basis *p_v);
-godot_vector3 godot_basis_get_euler(const godot_basis *p_v);
-godot_int godot_basis_get_orthogonal_index(const godot_basis *p_v);
-godot_vector3 godot_basis_get_scale(const godot_basis *p_v);
-void godot_basis_inverse(godot_basis *p_dest, const godot_basis *p_v);
-void godot_basis_orthonormalized(godot_basis *p_dest, const godot_basis *p_v);
-void godot_basis_rotated(godot_basis *p_dest, const godot_basis *p_v, const godot_vector3 p_axis, const godot_real p_phi);
-void godot_basis_scaled(godot_basis *p_dest, const godot_basis *p_v, const godot_vector3 p_scale);
-godot_real godot_basis_tdotx(const godot_basis *p_v, const godot_vector3 p_with);
-godot_real godot_basis_tdoty(const godot_basis *p_v, const godot_vector3 p_with);
-godot_real godot_basis_tdotz(const godot_basis *p_v, const godot_vector3 p_with);
-void godot_basis_transposed(godot_basis *p_dest, const godot_basis *p_v);
-godot_vector3 godot_basis_xform(const godot_basis *p_v, const godot_vector3 p_vect);
-godot_vector3 godot_basis_xform_inv(const godot_basis *p_v, const godot_vector3 p_vect);
+#include "godot_vector3.h"
+
+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);
+void GDAPI godot_basis_new_with_axis_and_angle(godot_basis *r_dest, const godot_vector3 *p_axis, const godot_real p_phi);
+void GDAPI godot_basis_new_with_euler(godot_basis *r_dest, const godot_vector3 *p_euler);
+
+godot_string GDAPI godot_basis_as_string(const godot_basis *p_self);
+
+godot_basis GDAPI godot_basis_inverse(const godot_basis *p_self);
+
+godot_basis GDAPI godot_basis_transposed(const godot_basis *p_self);
+
+godot_basis GDAPI godot_basis_orthonormalized(const godot_basis *p_self);
+
+godot_real GDAPI godot_basis_determinant(const godot_basis *p_self);
+
+godot_basis GDAPI godot_basis_rotated(const godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
+
+godot_basis GDAPI godot_basis_scaled(const godot_basis *p_self, const godot_vector3 *p_scale);
+
+void GDAPI godot_basis_set_scale(godot_basis *p_self, const godot_vector3 *p_scale);
+
+void GDAPI godot_basis_set_rotation_euler(godot_basis *p_self, const godot_vector3 *p_euler);
+
+void GDAPI godot_basis_set_rotation_axis_angle(godot_basis *p_self, const godot_vector3 *p_axis, const godot_real p_angle);
+
+godot_vector3 GDAPI godot_basis_get_scale(const godot_basis *p_self);
+
+godot_vector3 GDAPI godot_basis_get_euler(const godot_basis *p_self);
+
+godot_real GDAPI godot_basis_tdotx(const godot_basis *p_self, const godot_vector3 *p_with);
+
+godot_real GDAPI godot_basis_tdoty(const godot_basis *p_self, const godot_vector3 *p_with);
+
+godot_real GDAPI godot_basis_tdotz(const godot_basis *p_self, const godot_vector3 *p_with);
+
+godot_vector3 GDAPI godot_basis_xform(const godot_basis *p_self, const godot_vector3 *p_v);
+
+godot_vector3 GDAPI godot_basis_xform_inv(const godot_basis *p_self, const godot_vector3 *p_v);
+
+godot_int GDAPI godot_basis_get_orthogonal_index(const godot_basis *p_self);
+
+void GDAPI godot_basis_new(godot_basis *r_dest);
+
+void GDAPI godot_basis_new_with_euler_quat(godot_basis *r_dest, const godot_quat *p_euler);
+
+// p_elements is a pointer to an array of 3 (!!) vector3
+void GDAPI godot_basis_get_elements(godot_basis *p_self, godot_vector3 *p_elements);
+
+godot_vector3 GDAPI godot_basis_get_axis(const godot_basis *p_self, const godot_int p_axis);
+
+void GDAPI godot_basis_set_axis(godot_basis *p_self, const godot_int p_axis, const godot_vector3 *p_value);
+
+godot_vector3 GDAPI godot_basis_get_row(const godot_basis *p_self, const godot_int p_row);
+
+void GDAPI godot_basis_set_row(godot_basis *p_self, const godot_int p_row, const godot_vector3 *p_value);
+
+godot_bool GDAPI godot_basis_operator_equal(const godot_basis *p_self, const godot_basis *p_b);
+
+godot_basis GDAPI godot_basis_operator_add(const godot_basis *p_self, const godot_basis *p_b);
+
+godot_basis GDAPI godot_basis_operator_substract(const godot_basis *p_self, const godot_basis *p_b);
+
+godot_basis GDAPI godot_basis_operator_multiply_vector(const godot_basis *p_self, const godot_basis *p_b);
+
+godot_basis GDAPI godot_basis_operator_multiply_scalar(const godot_basis *p_self, const godot_real p_b);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_color.cpp b/modules/gdnative/godot/godot_color.cpp
index 203ce672fa..6dedf2ab10 100644
--- a/modules/gdnative/godot/godot_color.cpp
+++ b/modules/gdnative/godot/godot_color.cpp
@@ -28,34 +28,153 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_color.h"
+#include "core/variant.h"
-#include "color.h"
+#include "core/color.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _color_api_anchor() {
+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;
+ *dest = Color(p_r, p_g, p_b, p_a);
+}
+
+void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b) {
+
+ Color *dest = (Color *)r_dest;
+ *dest = Color(p_r, p_g, p_b);
+}
+
+godot_real godot_color_get_r(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->r;
+}
+
+void godot_color_set_r(godot_color *p_self, const godot_real val) {
+ Color *self = (Color *)p_self;
+ self->r = val;
+}
+
+godot_real godot_color_get_g(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->g;
+}
+
+void godot_color_set_g(godot_color *p_self, const godot_real val) {
+ Color *self = (Color *)p_self;
+ self->g = val;
+}
+
+godot_real godot_color_get_b(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->b;
+}
+
+void godot_color_set_b(godot_color *p_self, const godot_real val) {
+ Color *self = (Color *)p_self;
+ self->b = val;
+}
+
+godot_real godot_color_get_a(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->a;
+}
+
+void godot_color_set_a(godot_color *p_self, const godot_real val) {
+ Color *self = (Color *)p_self;
+ self->a = val;
}
-void GDAPI godot_color_new(godot_color *p_color) {
- Color *color = (Color *)p_color;
- *color = Color();
+godot_real godot_color_get_h(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->get_h();
}
-void GDAPI godot_color_new_rgba(godot_color *p_color, const godot_real r, const godot_real g, const godot_real b, const godot_real a) {
- Color *color = (Color *)p_color;
- *color = Color(r, g, b, a);
+godot_real godot_color_get_s(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->get_s();
+}
+
+godot_real godot_color_get_v(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->get_v();
+}
+
+godot_string GDAPI godot_color_as_string(const godot_color *p_self) {
+ godot_string ret;
+ const Color *self = (const Color *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_int GDAPI godot_color_to_32(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_32();
+}
+
+godot_int GDAPI godot_color_to_ARGB32(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->to_ARGB32();
+}
+
+godot_real GDAPI godot_color_gray(const godot_color *p_self) {
+ const Color *self = (const Color *)p_self;
+ return self->gray();
+}
+
+godot_color GDAPI godot_color_inverted(const godot_color *p_self) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ *((Color *)&dest) = self->inverted();
+ return dest;
+}
+
+godot_color GDAPI godot_color_contrasted(const godot_color *p_self) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ *((Color *)&dest) = self->contrasted();
+ return dest;
+}
+
+godot_color GDAPI godot_color_linear_interpolate(const godot_color *p_self, const godot_color *p_b, const godot_real p_t) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ const Color *b = (const Color *)p_b;
+ *((Color *)&dest) = self->linear_interpolate(*b, p_t);
+ return dest;
+}
+
+godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over) {
+ godot_color dest;
+ const Color *self = (const Color *)p_self;
+ const Color *over = (const Color *)p_over;
+ *((Color *)&dest) = self->blend(*over);
+ return dest;
+}
+
+godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha) {
+ godot_string dest;
+ const Color *self = (const Color *)p_self;
+
+ memnew_placement(&dest, String(self->to_html(p_with_alpha)));
+ return dest;
}
-uint32_t GDAPI godot_color_get_32(const godot_color *p_color) {
- const Color *color = (const Color *)p_color;
- return color->to_32();
+godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b) {
+ const Color *self = (const Color *)p_self;
+ const Color *b = (const Color *)p_b;
+ return *self == *b;
}
-float GDAPI *godot_color_index(godot_color *p_color, const godot_int idx) {
- Color *color = (Color *)p_color;
- return &color->operator[](idx);
+godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b) {
+ const Color *self = (const Color *)p_self;
+ const Color *b = (const Color *)p_b;
+ return *self < *b;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_color.h b/modules/gdnative/godot/godot_color.h
index b99a062a66..10dc228b1c 100644
--- a/modules/gdnative/godot/godot_color.h
+++ b/modules/gdnative/godot/godot_color.h
@@ -37,19 +37,55 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_COLOR_TYPE_DEFINED
typedef struct godot_color {
uint8_t _dont_touch_that[16];
} godot_color;
#endif
#include "../godot.h"
+#include "godot_string.h"
-void GDAPI godot_color_new(godot_color *p_color);
-void GDAPI godot_color_new_rgba(godot_color *p_color, const godot_real r, const godot_real g, const godot_real b, const godot_real a);
+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);
+void GDAPI godot_color_new_rgb(godot_color *r_dest, const godot_real p_r, const godot_real p_g, const godot_real p_b);
-uint32_t GDAPI godot_color_get_32(const godot_color *p_color);
+godot_real godot_color_get_r(const godot_color *p_self);
+void godot_color_set_r(godot_color *p_self, const godot_real r);
-float GDAPI *godot_color_index(godot_color *p_color, const godot_int idx);
+godot_real godot_color_get_g(const godot_color *p_self);
+void godot_color_set_g(godot_color *p_self, const godot_real g);
+
+godot_real godot_color_get_b(const godot_color *p_self);
+void godot_color_set_b(godot_color *p_self, const godot_real b);
+
+godot_real godot_color_get_a(const godot_color *p_self);
+void godot_color_set_a(godot_color *p_self, const godot_real a);
+
+godot_real godot_color_get_h(const godot_color *p_self);
+godot_real godot_color_get_s(const godot_color *p_self);
+godot_real godot_color_get_v(const godot_color *p_self);
+
+godot_string GDAPI godot_color_as_string(const godot_color *p_self);
+
+godot_int GDAPI godot_color_to_32(const godot_color *p_self);
+
+godot_int GDAPI godot_color_to_ARGB32(const godot_color *p_self);
+
+godot_real GDAPI godot_color_gray(const godot_color *p_self);
+
+godot_color GDAPI godot_color_inverted(const godot_color *p_self);
+
+godot_color GDAPI godot_color_contrasted(const godot_color *p_self);
+
+godot_color GDAPI godot_color_linear_interpolate(const godot_color *p_self, const godot_color *p_b, const godot_real p_t);
+
+godot_color GDAPI godot_color_blend(const godot_color *p_self, const godot_color *p_over);
+
+godot_string GDAPI godot_color_to_html(const godot_color *p_self, const godot_bool p_with_alpha);
+
+godot_bool GDAPI godot_color_operator_equal(const godot_color *p_self, const godot_color *p_b);
+
+godot_bool GDAPI godot_color_operator_less(const godot_color *p_self, const godot_color *p_b);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_dictionary.cpp b/modules/gdnative/godot/godot_dictionary.cpp
index 16d08e58e2..12c40f0564 100644
--- a/modules/gdnative/godot/godot_dictionary.cpp
+++ b/modules/gdnative/godot/godot_dictionary.cpp
@@ -28,109 +28,119 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_dictionary.h"
+#include "core/variant.h"
#include "core/dictionary.h"
-
-#include "core/os/memory.h"
-
#include "core/io/json.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _dictionary_api_anchor() {
+void _dictionary_api_anchor() {}
+
+void GDAPI godot_dictionary_new(godot_dictionary *r_dest) {
+ Dictionary *dest = (Dictionary *)r_dest;
+ memnew_placement(dest, Dictionary);
}
-void GDAPI godot_dictionary_new(godot_dictionary *p_dict) {
- Dictionary *dict = (Dictionary *)p_dict;
- memnew_placement(dict, Dictionary);
+void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src) {
+ Dictionary *dest = (Dictionary *)r_dest;
+ const Dictionary *src = (const Dictionary *)p_src;
+ memnew_placement(dest, Dictionary(*src));
}
-void GDAPI godot_dictionary_clear(godot_dictionary *p_dict) {
- Dictionary *dict = (Dictionary *)p_dict;
- dict->clear();
+void GDAPI godot_dictionary_destroy(godot_dictionary *p_self) {
+ Dictionary *self = (Dictionary *)p_self;
+ self->~Dictionary();
}
-godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_dict) {
- const Dictionary *dict = (const Dictionary *)p_dict;
- return dict->empty();
+godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ return self->size();
}
-void GDAPI godot_dictionary_erase(godot_dictionary *p_dict, const godot_variant *p_key) {
- Dictionary *dict = (Dictionary *)p_dict;
- Variant *key = (Variant *)p_key;
- dict->erase(*key);
+godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_self) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ return self->empty();
}
-godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_dict, const godot_variant *p_key) {
- const Dictionary *dict = (const Dictionary *)p_dict;
+void GDAPI godot_dictionary_clear(godot_dictionary *p_self) {
+ Dictionary *self = (Dictionary *)p_self;
+ self->clear();
+}
+
+godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key) {
+ const Dictionary *self = (const Dictionary *)p_self;
const Variant *key = (const Variant *)p_key;
- return dict->has(*key);
+ return self->has(*key);
}
-godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_dict, const godot_array *p_keys) {
- const Dictionary *dict = (const Dictionary *)p_dict;
+godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys) {
+ const Dictionary *self = (const Dictionary *)p_self;
const Array *keys = (const Array *)p_keys;
- return dict->has_all(*keys);
+ return self->has_all(*keys);
}
-uint32_t GDAPI godot_dictionary_hash(const godot_dictionary *p_dict) {
- const Dictionary *dict = (const Dictionary *)p_dict;
- return dict->hash();
+void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key) {
+ Dictionary *self = (Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ self->erase(*key);
}
-godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_dict) {
- godot_array a;
- godot_array_new(&a);
- const Dictionary *dict = (const Dictionary *)p_dict;
- Array *array = (Array *)&a;
- *array = dict->keys();
- return a;
+godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ return self->hash();
}
-godot_int GDAPI godot_dictionary_parse_json(godot_dictionary *p_dict, const godot_string *p_json) {
- Dictionary *dict = (Dictionary *)p_dict;
- const String *json = (const String *)p_json;
- Variant ret;
- int err_line;
- String err_str;
- int err = (int)JSON::parse(*json, ret, err_str, err_line);
- *dict = ret;
- return err;
+godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self) {
+ godot_array dest;
+ const Dictionary *self = (const Dictionary *)p_self;
+ memnew_placement(&dest, Array(self->keys()));
+ return dest;
}
-godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_dict, const godot_variant *p_key) {
- Dictionary *dict = (Dictionary *)p_dict;
- Variant *key = (Variant *)p_key;
- return (godot_variant *)&dict->operator[](*key);
+godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self) {
+ godot_array dest;
+ const Dictionary *self = (const Dictionary *)p_self;
+ memnew_placement(&dest, Array(self->values()));
+ return dest;
}
-godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_dict) {
- const Dictionary *dict = (const Dictionary *)p_dict;
- return dict->size();
+godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key) {
+ godot_variant raw_dest;
+ Variant *dest = (Variant *)&raw_dest;
+ const Dictionary *self = (const Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ memnew_placement(dest, Variant(self->operator[](*key)));
+ return raw_dest;
}
-godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_dict) {
- const Dictionary *dict = (const Dictionary *)p_dict;
- godot_string str;
- godot_string_new(&str);
- String *s = (String *)&str;
- *s = JSON::print(Variant(*dict));
- return str;
+void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value) {
+ Dictionary *self = (Dictionary *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ const Variant *value = (const Variant *)p_value;
+ self->operator[](*key) = *value;
+}
+
+godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key) {
+ Array *self = (Array *)p_self;
+ const Variant *key = (const Variant *)p_key;
+ return (godot_variant *)&self->operator[](*key);
}
-godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_dict) {
- godot_array a;
- godot_array_new(&a);
- const Dictionary *dict = (const Dictionary *)p_dict;
- Array *array = (Array *)&a;
- *array = dict->values();
- return a;
+godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b) {
+ const Dictionary *self = (const Dictionary *)p_self;
+ const Dictionary *b = (const Dictionary *)p_b;
+ return *self == *b;
}
-void GDAPI godot_dictionary_destroy(godot_dictionary *p_dict) {
- ((Dictionary *)p_dict)->~Dictionary();
+godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self) {
+ godot_string raw_dest;
+ String *dest = (String *)&raw_dest;
+ const Dictionary *self = (const Dictionary *)p_self;
+ memnew_placement(dest, String(JSON::print(Variant(*self))));
+ return raw_dest;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_dictionary.h b/modules/gdnative/godot/godot_dictionary.h
index 3f7c504880..0325670b15 100644
--- a/modules/gdnative/godot/godot_dictionary.h
+++ b/modules/gdnative/godot/godot_dictionary.h
@@ -36,42 +36,47 @@ extern "C" {
#include <stdint.h>
-#ifndef GODOT_CORE_API_GODOT_DICITIONARY_TYPE_DEFINED
+#ifndef GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_DICTIONARY_TYPE_DEFINED
typedef struct godot_dictionary {
uint8_t _dont_touch_that[8];
} godot_dictionary;
#endif
+#include "../godot.h"
#include "godot_array.h"
#include "godot_variant.h"
-void GDAPI godot_dictionary_new(godot_dictionary *p_dict);
+void GDAPI godot_dictionary_new(godot_dictionary *r_dest);
+void GDAPI godot_dictionary_new_copy(godot_dictionary *r_dest, const godot_dictionary *p_src);
+void GDAPI godot_dictionary_destroy(godot_dictionary *p_self);
-void GDAPI godot_dictionary_clear(godot_dictionary *p_dict);
+godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_self);
-godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_dict);
+godot_bool GDAPI godot_dictionary_empty(const godot_dictionary *p_self);
-void GDAPI godot_dictionary_erase(godot_dictionary *p_dict, const godot_variant *p_key);
+void GDAPI godot_dictionary_clear(godot_dictionary *p_self);
-godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_dict, const godot_variant *p_key);
+godot_bool GDAPI godot_dictionary_has(const godot_dictionary *p_self, const godot_variant *p_key);
-godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_dict, const godot_array *p_keys);
+godot_bool GDAPI godot_dictionary_has_all(const godot_dictionary *p_self, const godot_array *p_keys);
-uint32_t GDAPI godot_dictionary_hash(const godot_dictionary *p_dict);
+void GDAPI godot_dictionary_erase(godot_dictionary *p_self, const godot_variant *p_key);
-godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_dict);
+godot_int GDAPI godot_dictionary_hash(const godot_dictionary *p_self);
-godot_int GDAPI godot_dictionary_parse_json(godot_dictionary *p_dict, const godot_string *p_json);
+godot_array GDAPI godot_dictionary_keys(const godot_dictionary *p_self);
-godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_dict, const godot_variant *p_key);
+godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_self);
-godot_int GDAPI godot_dictionary_size(const godot_dictionary *p_dict);
+godot_variant GDAPI godot_dictionary_get(const godot_dictionary *p_self, const godot_variant *p_key);
+void GDAPI godot_dictionary_set(godot_dictionary *p_self, const godot_variant *p_key, const godot_variant *p_value);
-godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_dict);
+godot_variant GDAPI *godot_dictionary_operator_index(godot_dictionary *p_self, const godot_variant *p_key);
-godot_array GDAPI godot_dictionary_values(const godot_dictionary *p_dict);
+godot_bool GDAPI godot_dictionary_operator_equal(const godot_dictionary *p_self, const godot_dictionary *p_b);
-void GDAPI godot_dictionary_destroy(godot_dictionary *p_dict);
+godot_string GDAPI godot_dictionary_to_json(const godot_dictionary *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_image.cpp b/modules/gdnative/godot/godot_image.cpp
deleted file mode 100644
index ae8290afc2..0000000000
--- a/modules/gdnative/godot/godot_image.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*************************************************************************/
-/* godot_image.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 "godot_image.h"
-
-#include "image.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void _image_api_anchor() {
-}
-
-#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
-
-void GDAPI godot_image_new(godot_image *p_img) {
- Image *img = (Image *)p_img;
- memnew_placement_custom(img, Image, Image());
-}
-
-void GDAPI godot_image_new_with_png_jpg(godot_image *p_img, const uint8_t *p_mem_png_jpg, int p_len) {
- Image *img = (Image *)p_img;
- memnew_placement_custom(img, Image, Image(p_mem_png_jpg, p_len));
-}
-
-void GDAPI godot_image_new_with_xpm(godot_image *p_img, const char **p_xpm) {
- Image *img = (Image *)p_img;
- memnew_placement_custom(img, Image, Image(p_xpm));
-}
-
-void GDAPI godot_image_new_with_size_format(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format) {
- Image *img = (Image *)p_img;
- memnew_placement_custom(img, Image, Image(p_width, p_height, p_use_mipmaps, (Image::Format)p_format));
-}
-
-void GDAPI godot_image_new_with_size_format_data(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format, godot_pool_byte_array *p_data) {
- Image *img = (Image *)p_img;
- PoolVector<uint8_t> *data = (PoolVector<uint8_t> *)p_data;
- memnew_placement_custom(img, Image, Image(p_width, p_height, p_use_mipmaps, (Image::Format)p_format, *data));
-}
-
-godot_pool_byte_array GDAPI godot_image_get_data(godot_image *p_img) {
- Image *img = (Image *)p_img;
- PoolVector<uint8_t> cpp_data = img->get_data();
- godot_pool_byte_array *data = (godot_pool_byte_array *)&cpp_data;
- return *data;
-}
-
-godot_error GDAPI godot_image_load(godot_image *p_img, const godot_string *p_path) {
- Image *img = (Image *)p_img;
- String *path = (String *)p_path;
- return (godot_error)img->load(*path);
-}
-
-godot_error GDAPI godot_image_save_png(godot_image *p_img, const godot_string *p_path) {
- Image *img = (Image *)p_img;
- String *path = (String *)p_path;
- return (godot_error)img->save_png(*path);
-}
-
-int GDAPI godot_image_get_width(const godot_image *p_img) {
- Image *img = (Image *)p_img;
- return img->get_width();
-}
-
-int GDAPI godot_image_get_height(const godot_image *p_img) {
- Image *img = (Image *)p_img;
- return img->get_height();
-}
-
-godot_bool GDAPI godot_image_has_mipmaps(const godot_image *p_img) {
- Image *img = (Image *)p_img;
- return img->has_mipmaps();
-}
-
-int GDAPI godot_image_get_mipmap_count(const godot_image *p_img) {
- Image *img = (Image *)p_img;
- return img->get_mipmap_count();
-}
-
-void GDAPI godot_image_destroy(godot_image *p_img) {
- ((Image *)p_img)->~Image();
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/modules/gdnative/godot/godot_image.h b/modules/gdnative/godot/godot_image.h
deleted file mode 100644
index c43dd45148..0000000000
--- a/modules/gdnative/godot/godot_image.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*************************************************************************/
-/* godot_image.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 GODOT_IMAGE_H
-#define GODOT_IMAGE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#ifndef GODOT_CORE_API_GODOT_IMAGE_TYPE_DEFINED
-typedef struct godot_image {
- uint8_t _dont_touch_that[32];
-} godot_image;
-#endif
-
-#include "godot_pool_arrays.h"
-
-#include "../godot.h"
-
-// This is a copypasta of the C++ enum inside the Image class
-// There's no neat way of automatically updating the C enum / using the C++ enum directly
-// if somebody knows a way feel free to open a PR or open an issue (or ask for Karroffel or bojidar-bg on IRC)
-
-enum godot_image_format {
-
- GODOT_IMAGE_FORMAT_L8, //luminance
- GODOT_IMAGE_FORMAT_LA8, //luminance-alpha
- GODOT_IMAGE_FORMAT_R8,
- GODOT_IMAGE_FORMAT_RG8,
- GODOT_IMAGE_FORMAT_RGB8,
- GODOT_IMAGE_FORMAT_RGBA8,
- GODOT_IMAGE_FORMAT_RGB565, //16 bit
- GODOT_IMAGE_FORMAT_RGBA4444,
- GODOT_IMAGE_FORMAT_RGBA5551,
- GODOT_IMAGE_FORMAT_RF, //float
- GODOT_IMAGE_FORMAT_RGF,
- GODOT_IMAGE_FORMAT_RGBF,
- GODOT_IMAGE_FORMAT_RGBAF,
- GODOT_IMAGE_FORMAT_RH, //half float
- GODOT_IMAGE_FORMAT_RGH,
- GODOT_IMAGE_FORMAT_RGBH,
- GODOT_IMAGE_FORMAT_RGBAH,
- GODOT_IMAGE_FORMAT_DXT1, //s3tc bc1
- GODOT_IMAGE_FORMAT_DXT3, //bc2
- GODOT_IMAGE_FORMAT_DXT5, //bc3
- GODOT_IMAGE_FORMAT_ATI1, //bc4
- GODOT_IMAGE_FORMAT_ATI2, //bc5
- GODOT_IMAGE_FORMAT_BPTC_RGBA, //btpc bc6h
- GODOT_IMAGE_FORMAT_BPTC_RGBF, //float /
- GODOT_IMAGE_FORMAT_BPTC_RGBFU, //unsigned float
- GODOT_IMAGE_FORMAT_PVRTC2, //pvrtc
- GODOT_IMAGE_FORMAT_PVRTC2A,
- GODOT_IMAGE_FORMAT_PVRTC4,
- GODOT_IMAGE_FORMAT_PVRTC4A,
- GODOT_IMAGE_FORMAT_ETC, //etc1
- GODOT_IMAGE_FORMAT_ETC2_R11, //etc2
- GODOT_IMAGE_FORMAT_ETC2_R11S, //signed, NOT srgb.
- GODOT_IMAGE_FORMAT_ETC2_RG11,
- GODOT_IMAGE_FORMAT_ETC2_RG11S,
- GODOT_IMAGE_FORMAT_ETC2_RGB8,
- GODOT_IMAGE_FORMAT_ETC2_RGBA8,
- GODOT_IMAGE_FORMAT_ETC2_RGB8A1,
- GODOT_IMAGE_FORMAT_MAX
-};
-typedef enum godot_image_format godot_image_format;
-
-void GDAPI godot_image_new(godot_image *p_img);
-// p_len can be -1
-void GDAPI godot_image_new_with_png_jpg(godot_image *p_img, const uint8_t *p_mem_png_jpg, int p_len);
-void GDAPI godot_image_new_with_xpm(godot_image *p_img, const char **p_xpm);
-
-void GDAPI godot_image_new_with_size_format(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format);
-void GDAPI godot_image_new_with_size_format_data(godot_image *p_img, int p_width, int p_height, bool p_use_mipmaps, godot_image_format p_format, godot_pool_byte_array *p_data);
-
-godot_pool_byte_array GDAPI godot_image_get_data(godot_image *p_img);
-
-godot_error GDAPI godot_image_load(godot_image *p_img, const godot_string *p_path);
-godot_error GDAPI godot_image_save_png(godot_image *p_img, const godot_string *p_path);
-
-int GDAPI godot_image_get_width(const godot_image *p_img);
-int GDAPI godot_image_get_height(const godot_image *p_img);
-godot_bool GDAPI godot_image_has_mipmaps(const godot_image *p_img);
-int GDAPI godot_image_get_mipmap_count(const godot_image *p_img);
-
-// @Incomplete
-// I think it's too complex for the binding authors to implement the image class anew, so we should definitely
-// export all methods here. That takes a while so it's on my @Todo list
-
-void GDAPI godot_image_destroy(godot_image *p_img);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // GODOT_IMAGE_H
diff --git a/modules/gdnative/godot/godot_input_event.cpp b/modules/gdnative/godot/godot_input_event.cpp
deleted file mode 100644
index 0401c96a88..0000000000
--- a/modules/gdnative/godot/godot_input_event.cpp
+++ /dev/null
@@ -1,309 +0,0 @@
-/*************************************************************************/
-/* godot_input_event.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 "godot_input_event.h"
-
-#include "os/input_event.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void _input_event_api_anchor() {
-}
-
-void GDAPI godot_input_event_new(godot_input_event *p_ie) {
- InputEvent *ie = (InputEvent *)p_ie;
- *ie = InputEvent();
-}
-
-godot_bool GDAPI godot_input_event_is_pressed(const godot_input_event *p_ie) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- return ie->is_pressed();
-}
-
-godot_bool GDAPI godot_input_event_is_action(const godot_input_event *p_ie, const godot_string *p_action) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- const String *action = (const String *)p_action;
- return ie->is_action(*action);
-}
-
-godot_bool GDAPI godot_input_event_is_action_pressed(const godot_input_event *p_ie, const godot_string *p_action) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- const String *action = (const String *)p_action;
- return ie->is_action_pressed(*action);
-}
-
-godot_bool GDAPI godot_input_event_is_action_released(const godot_input_event *p_ie, const godot_string *p_action) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- const String *action = (const String *)p_action;
- return ie->is_action_released(*action);
-}
-
-godot_bool GDAPI godot_input_event_is_echo(const godot_input_event *p_ie) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- return ie->is_echo();
-}
-
-void GDAPI godot_input_event_set_as_action(godot_input_event *p_ie, const godot_string *p_action, const godot_bool p_pressed) {
- InputEvent *ie = (InputEvent *)p_ie;
- const String *action = (const String *)p_action;
- return ie->set_as_action(*action, p_pressed);
-}
-
-godot_string GDAPI godot_input_event_as_string(const godot_input_event *p_ie) {
- const InputEvent *ie = (const InputEvent *)p_ie;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = (String)*ie;
- return str;
-}
-
-uint32_t GDAPI *godot_input_event_get_id(godot_input_event *p_ie) {
- InputEvent *ie = (InputEvent *)p_ie;
- return &ie->ID;
-}
-
-godot_input_event_type GDAPI *godot_input_event_get_type(godot_input_event *p_ie) {
- InputEvent *ie = (InputEvent *)p_ie;
- return (godot_input_event_type *)&ie->type;
-}
-
-godot_int GDAPI *godot_input_event_get_device(godot_input_event *p_ie) {
- InputEvent *ie = (InputEvent *)p_ie;
- return &ie->device;
-}
-
-static InputModifierState *_get_mod_for_type(InputEvent *ie) {
- switch (ie->type) {
- case InputEvent::MOUSE_BUTTON:
- return &ie->mouse_button.mod;
- case InputEvent::MOUSE_MOTION:
- return &ie->mouse_motion.mod;
- case InputEvent::KEY:
- return &ie->key.mod;
- default:
- return 0;
- }
-}
-
-godot_bool GDAPI *godot_input_event_mod_get_alt(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- InputModifierState *mod = _get_mod_for_type(ie);
- return &mod->alt;
-}
-
-godot_bool GDAPI *godot_input_event_mod_get_ctrl(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- InputModifierState *mod = _get_mod_for_type(ie);
- return &mod->control;
-}
-
-godot_bool GDAPI *godot_input_event_mod_get_command(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- InputModifierState *mod = _get_mod_for_type(ie);
- return &mod->command;
-}
-
-godot_bool GDAPI *godot_input_event_mod_get_shift(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- InputModifierState *mod = _get_mod_for_type(ie);
- return &mod->shift;
-}
-
-godot_bool GDAPI *godot_input_event_mod_get_meta(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- InputModifierState *mod = _get_mod_for_type(ie);
- return &mod->meta;
-}
-
-uint32_t GDAPI *godot_input_event_key_get_scancode(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->key.scancode;
-}
-
-uint32_t GDAPI *godot_input_event_key_get_unicode(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->key.unicode;
-}
-
-godot_bool GDAPI *godot_input_event_key_get_pressed(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->key.pressed;
-}
-
-godot_bool GDAPI *godot_input_event_key_get_echo(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->key.echo;
-}
-
-float GDAPI *godot_input_event_mouse_get_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.x;
-}
-
-float GDAPI *godot_input_event_mouse_get_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.y;
-}
-
-float GDAPI *godot_input_event_mouse_get_global_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.global_x;
-}
-
-float GDAPI *godot_input_event_mouse_get_global_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.global_y;
-}
-
-godot_int GDAPI *godot_input_event_mouse_get_button_mask(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.button_mask;
-}
-
-godot_int GDAPI *godot_input_event_mouse_button_get_button_index(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.button_index;
-}
-
-godot_bool GDAPI *godot_input_event_mouse_button_get_pressed(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.pressed;
-}
-
-godot_bool GDAPI *godot_input_event_mouse_button_get_doubleclick(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_button.doubleclick;
-}
-
-float GDAPI *godot_input_event_mouse_motion_get_relative_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_motion.relative_x;
-}
-
-float GDAPI *godot_input_event_mouse_motion_get_relative_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_motion.relative_y;
-}
-
-float GDAPI *godot_input_event_mouse_motion_get_speed_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_motion.speed_x;
-}
-
-float GDAPI *godot_input_event_mouse_motion_get_speed_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->mouse_motion.speed_y;
-}
-
-godot_int GDAPI *godot_input_event_joypad_motion_get_axis(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->joy_motion.axis;
-}
-
-float GDAPI *godot_input_event_joypad_motion_get_axis_value(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->joy_motion.axis_value;
-}
-
-godot_int GDAPI *godot_input_event_joypad_button_get_button_index(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->joy_button.button_index;
-}
-
-godot_bool GDAPI *godot_input_event_joypad_button_get_pressed(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->joy_button.pressed;
-}
-
-float GDAPI *godot_input_event_joypad_button_get_pressure(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->joy_button.pressure;
-}
-
-godot_int GDAPI *godot_input_event_screen_touch_get_index(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_touch.index;
-}
-
-float GDAPI *godot_input_event_screen_touch_get_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_touch.x;
-}
-
-float GDAPI *godot_input_event_screen_touch_get_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_touch.y;
-}
-
-godot_bool GDAPI *godot_input_event_screen_touch_get_pressed(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_touch.pressed;
-}
-
-godot_int GDAPI *godot_input_event_screen_drag_get_index(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.index;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.x;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.y;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_relative_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.relative_x;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_relative_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.relative_y;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_speed_x(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.speed_x;
-}
-
-float GDAPI *godot_input_event_screen_drag_get_speed_y(godot_input_event *p_event) {
- InputEvent *ie = (InputEvent *)p_event;
- return &ie->screen_drag.speed_y;
-}
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/modules/gdnative/godot/godot_input_event.h b/modules/gdnative/godot/godot_input_event.h
deleted file mode 100644
index b0a133e3d9..0000000000
--- a/modules/gdnative/godot/godot_input_event.h
+++ /dev/null
@@ -1,235 +0,0 @@
-/*************************************************************************/
-/* godot_input_event.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 GODOT_INPUT_EVENT_H
-#define GODOT_INPUT_EVENT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#ifndef GODOT_CORE_API_GODOT_INPUT_EVENT_TYPE_DEFINED
-typedef struct godot_input_event {
- uint8_t _dont_touch_that[56];
-} godot_input_event;
-#endif
-
-enum godot_input_event_type {
- GODOT_INPUT_EVENT_TYPE_NONE,
- GODOT_INPUT_EVENT_TYPE_KEY,
- GODOT_INPUT_EVENT_TYPE_MOUSE_MOTION,
- GODOT_INPUT_EVENT_TYPE_MOUSE_BUTTON,
- GODOT_INPUT_EVENT_TYPE_JOYPAD_MOTION,
- GODOT_INPUT_EVENT_TYPE_JOYPAD_BUTTON,
- GODOT_INPUT_EVENT_TYPE_SCREEN_TOUCH,
- GODOT_INPUT_EVENT_TYPE_SCREEN_DRAG,
- GODOT_INPUT_EVENT_TYPE_ACTION,
- GODOT_INPUT_EVENT_TYPE_TYPE_MAX
-};
-typedef enum godot_input_event_type godot_input_event_type;
-
-enum {
- GODOT_BUTTON_LEFT = 1,
- GODOT_BUTTON_RIGHT = 2,
- GODOT_BUTTON_MIDDLE = 3,
- GODOT_BUTTON_WHEEL_UP = 4,
- GODOT_BUTTON_WHEEL_DOWN = 5,
- GODOT_BUTTON_WHEEL_LEFT = 6,
- GODOT_BUTTON_WHEEL_RIGHT = 7,
- GODOT_BUTTON_MASK_LEFT = (1 << (GODOT_BUTTON_LEFT - 1)),
- GODOT_BUTTON_MASK_RIGHT = (1 << (GODOT_BUTTON_RIGHT - 1)),
- GODOT_BUTTON_MASK_MIDDLE = (1 << (GODOT_BUTTON_MIDDLE - 1)),
-
-};
-
-enum {
-
- GODOT_JOY_BUTTON_0 = 0,
- GODOT_JOY_BUTTON_1 = 1,
- GODOT_JOY_BUTTON_2 = 2,
- GODOT_JOY_BUTTON_3 = 3,
- GODOT_JOY_BUTTON_4 = 4,
- GODOT_JOY_BUTTON_5 = 5,
- GODOT_JOY_BUTTON_6 = 6,
- GODOT_JOY_BUTTON_7 = 7,
- GODOT_JOY_BUTTON_8 = 8,
- GODOT_JOY_BUTTON_9 = 9,
- GODOT_JOY_BUTTON_10 = 10,
- GODOT_JOY_BUTTON_11 = 11,
- GODOT_JOY_BUTTON_12 = 12,
- GODOT_JOY_BUTTON_13 = 13,
- GODOT_JOY_BUTTON_14 = 14,
- GODOT_JOY_BUTTON_15 = 15,
- GODOT_JOY_BUTTON_MAX = 16,
-
- GODOT_JOY_L = GODOT_JOY_BUTTON_4,
- GODOT_JOY_R = GODOT_JOY_BUTTON_5,
- GODOT_JOY_L2 = GODOT_JOY_BUTTON_6,
- GODOT_JOY_R2 = GODOT_JOY_BUTTON_7,
- GODOT_JOY_L3 = GODOT_JOY_BUTTON_8,
- GODOT_JOY_R3 = GODOT_JOY_BUTTON_9,
- GODOT_JOY_SELECT = GODOT_JOY_BUTTON_10,
- GODOT_JOY_START = GODOT_JOY_BUTTON_11,
- GODOT_JOY_DPAD_UP = GODOT_JOY_BUTTON_12,
- GODOT_JOY_DPAD_DOWN = GODOT_JOY_BUTTON_13,
- GODOT_JOY_DPAD_LEFT = GODOT_JOY_BUTTON_14,
- GODOT_JOY_DPAD_RIGHT = GODOT_JOY_BUTTON_15,
-
- // a little history about game controllers (who copied who)
-
- GODOT_JOY_SNES_B = GODOT_JOY_BUTTON_0,
- GODOT_JOY_SNES_A = GODOT_JOY_BUTTON_1,
- GODOT_JOY_SNES_Y = GODOT_JOY_BUTTON_2,
- GODOT_JOY_SNES_X = GODOT_JOY_BUTTON_3,
-
- GODOT_JOY_SONY_CIRCLE = GODOT_JOY_SNES_A,
- GODOT_JOY_SONY_X = GODOT_JOY_SNES_B,
- GODOT_JOY_SONY_SQUARE = GODOT_JOY_SNES_Y,
- GODOT_JOY_SONY_TRIANGLE = GODOT_JOY_SNES_X,
-
- GODOT_JOY_SEGA_B = GODOT_JOY_SNES_A,
- GODOT_JOY_SEGA_A = GODOT_JOY_SNES_B,
- GODOT_JOY_SEGA_X = GODOT_JOY_SNES_Y,
- GODOT_JOY_SEGA_Y = GODOT_JOY_SNES_X,
-
- GODOT_JOY_XBOX_B = GODOT_JOY_SEGA_B,
- GODOT_JOY_XBOX_A = GODOT_JOY_SEGA_A,
- GODOT_JOY_XBOX_X = GODOT_JOY_SEGA_X,
- GODOT_JOY_XBOX_Y = GODOT_JOY_SEGA_Y,
-
- GODOT_JOY_DS_A = GODOT_JOY_SNES_A,
- GODOT_JOY_DS_B = GODOT_JOY_SNES_B,
- GODOT_JOY_DS_X = GODOT_JOY_SNES_X,
- GODOT_JOY_DS_Y = GODOT_JOY_SNES_Y,
-
- GODOT_JOY_WII_C = GODOT_JOY_BUTTON_5,
- GODOT_JOY_WII_Z = GODOT_JOY_BUTTON_6,
-
- GODOT_JOY_WII_MINUS = GODOT_JOY_BUTTON_9,
- GODOT_JOY_WII_PLUS = GODOT_JOY_BUTTON_10,
-
- // end of history
-
- GODOT_JOY_AXIS_0 = 0,
- GODOT_JOY_AXIS_1 = 1,
- GODOT_JOY_AXIS_2 = 2,
- GODOT_JOY_AXIS_3 = 3,
- GODOT_JOY_AXIS_4 = 4,
- GODOT_JOY_AXIS_5 = 5,
- GODOT_JOY_AXIS_6 = 6,
- GODOT_JOY_AXIS_7 = 7,
- GODOT_JOY_AXIS_MAX = 8,
-
- GODOT_JOY_ANALOG_0_X = GODOT_JOY_AXIS_0,
- GODOT_JOY_ANALOG_0_Y = GODOT_JOY_AXIS_1,
-
- GODOT_JOY_ANALOG_1_X = GODOT_JOY_AXIS_2,
- GODOT_JOY_ANALOG_1_Y = GODOT_JOY_AXIS_3,
-
- GODOT_JOY_ANALOG_2_X = GODOT_JOY_AXIS_4,
- GODOT_JOY_ANALOG_2_Y = GODOT_JOY_AXIS_5,
-
- GODOT_JOY_ANALOG_L2 = GODOT_JOY_AXIS_6,
- GODOT_JOY_ANALOG_R2 = GODOT_JOY_AXIS_7,
-};
-
-#include "../godot.h"
-
-void GDAPI godot_input_event_new(godot_input_event *p_ie);
-
-godot_bool GDAPI godot_input_event_is_pressed(const godot_input_event *p_ie);
-godot_bool GDAPI godot_input_event_is_action(const godot_input_event *p_ie, const godot_string *p_action);
-godot_bool GDAPI godot_input_event_is_action_pressed(const godot_input_event *p_ie, const godot_string *p_action);
-godot_bool GDAPI godot_input_event_is_action_released(const godot_input_event *p_ie, const godot_string *p_action);
-godot_bool GDAPI godot_input_event_is_echo(const godot_input_event *p_ie);
-void GDAPI godot_input_event_set_as_action(godot_input_event *p_ie, const godot_string *p_action, const godot_bool p_pressed);
-
-godot_string GDAPI godot_input_event_as_string(const godot_input_event *p_ie);
-
-// Note:
-// We're returning pointers to the fields in the unions.
-// This is because I'm too lazy to write setter functions
-
-uint32_t GDAPI *godot_input_event_get_id(godot_input_event *p_ie);
-godot_input_event_type GDAPI *godot_input_event_get_type(godot_input_event *p_ie);
-godot_int GDAPI *godot_input_event_get_device(godot_input_event *p_ie);
-
-godot_bool GDAPI *godot_input_event_mod_get_alt(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mod_get_ctrl(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mod_get_command(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mod_get_shift(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mod_get_meta(godot_input_event *p_event);
-
-uint32_t GDAPI *godot_input_event_key_get_scancode(godot_input_event *p_event);
-uint32_t GDAPI *godot_input_event_key_get_unicode(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_key_get_pressed(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_key_get_echo(godot_input_event *p_event);
-
-float GDAPI *godot_input_event_mouse_get_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_get_y(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_get_global_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_get_global_y(godot_input_event *p_event);
-godot_int GDAPI *godot_input_event_mouse_get_button_mask(godot_input_event *p_event);
-
-godot_int GDAPI *godot_input_event_mouse_button_get_button_index(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mouse_button_get_pressed(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_mouse_button_get_doubleclick(godot_input_event *p_event);
-
-float GDAPI *godot_input_event_mouse_motion_get_relative_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_motion_get_relative_y(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_motion_get_speed_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_mouse_motion_get_speed_y(godot_input_event *p_event);
-
-godot_int GDAPI *godot_input_event_joypad_motion_get_axis(godot_input_event *p_event);
-float GDAPI *godot_input_event_joypad_motion_get_axis_value(godot_input_event *p_event);
-
-godot_int GDAPI *godot_input_event_joypad_button_get_button_index(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_joypad_button_get_pressed(godot_input_event *p_event);
-float GDAPI *godot_input_event_joypad_button_get_pressure(godot_input_event *p_event);
-
-godot_int GDAPI *godot_input_event_screen_touch_get_index(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_touch_get_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_touch_get_y(godot_input_event *p_event);
-godot_bool GDAPI *godot_input_event_screen_touch_get_pressed(godot_input_event *p_event);
-
-godot_int GDAPI *godot_input_event_screen_drag_get_index(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_y(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_relative_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_relative_y(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_speed_x(godot_input_event *p_event);
-float GDAPI *godot_input_event_screen_drag_get_speed_y(godot_input_event *p_event);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // GODOT_INPUT_EVENT_H
diff --git a/modules/gdnative/godot/godot_node_path.cpp b/modules/gdnative/godot/godot_node_path.cpp
index a2c9e11699..c8eacd05af 100644
--- a/modules/gdnative/godot/godot_node_path.cpp
+++ b/modules/gdnative/godot/godot_node_path.cpp
@@ -28,91 +28,87 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_node_path.h"
+#include "core/variant.h"
-#include "path_db.h"
+#include "core/path_db.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _node_path_api_anchor() {
-}
-
-#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
+void _node_path_api_anchor() {}
-// @Bug ?
-// Do I need to memnew_placement when returning strings?
+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;
+ memnew_placement(dest, NodePath(*from));
+}
-void GDAPI godot_node_path_new(godot_node_path *p_np, const godot_string *p_from) {
- NodePath *np = (NodePath *)p_np;
- String *from = (String *)p_from;
- memnew_placement_custom(np, NodePath, NodePath(*from));
+void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src) {
+ NodePath *dest = (NodePath *)r_dest;
+ const NodePath *src = (const NodePath *)p_src;
+ memnew_placement(dest, NodePath(*src));
}
-void GDAPI godot_node_path_copy(godot_node_path *p_np, const godot_node_path *p_from) {
- NodePath *np = (NodePath *)p_np;
- NodePath *from = (NodePath *)p_from;
- *np = *from;
+void GDAPI godot_node_path_destroy(godot_node_path *p_self) {
+ NodePath *self = (NodePath *)p_self;
+ self->~NodePath();
}
-godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_np, const godot_int p_idx) {
- const NodePath *np = (const NodePath *)p_np;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = np->get_name(p_idx);
- return str;
+godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self) {
+ godot_string ret;
+ const NodePath *self = (const NodePath *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
}
-godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- return np->get_name_count();
+godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self) {
+ const NodePath *self = (const NodePath *)p_self;
+ return self->is_absolute();
}
-godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = np->get_property();
- return str;
+godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self) {
+ const NodePath *self = (const NodePath *)p_self;
+ return self->get_name_count();
}
-godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_np, const godot_int p_idx) {
- const NodePath *np = (const NodePath *)p_np;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = np->get_subname(p_idx);
- return str;
+godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx) {
+ godot_string dest;
+ const NodePath *self = (const NodePath *)p_self;
+
+ memnew_placement(&dest, String(self->get_name(p_idx)));
+ return dest;
}
-godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- return np->get_subname_count();
+godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self) {
+ const NodePath *self = (const NodePath *)p_self;
+ return self->get_subname_count();
}
-godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- return np->is_absolute();
+godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx) {
+ godot_string dest;
+ const NodePath *self = (const NodePath *)p_self;
+
+ memnew_placement(&dest, String(self->get_subname(p_idx)));
+ return dest;
}
-godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- return np->is_empty();
+godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_self) {
+ godot_string dest;
+ const NodePath *self = (const NodePath *)p_self;
+ memnew_placement(&dest, String(self->get_property()));
+ return dest;
}
-godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_np) {
- const NodePath *np = (const NodePath *)p_np;
- godot_string str;
- String *s = (String *)&str;
- memnew_placement(s, String);
- *s = *np;
- return str;
+godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self) {
+ const NodePath *self = (const NodePath *)p_self;
+ return self->is_empty();
}
-void GDAPI godot_node_path_destroy(godot_node_path *p_np) {
- ((NodePath *)p_np)->~NodePath();
+godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b) {
+ const NodePath *self = (const NodePath *)p_self;
+ const NodePath *b = (const NodePath *)p_b;
+ return *self == *b;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_node_path.h b/modules/gdnative/godot/godot_node_path.h
index c5f313d190..b0c9d44859 100644
--- a/modules/gdnative/godot/godot_node_path.h
+++ b/modules/gdnative/godot/godot_node_path.h
@@ -37,29 +37,36 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_NODE_PATH_TYPE_DEFINED
typedef struct godot_node_path {
uint8_t _dont_touch_that[8];
} godot_node_path;
#endif
#include "../godot.h"
+#include "godot_string.h"
-void GDAPI godot_node_path_new(godot_node_path *p_np, const godot_string *p_from);
-void GDAPI godot_node_path_copy(godot_node_path *p_np, const godot_node_path *p_from);
+void GDAPI godot_node_path_new(godot_node_path *r_dest, const godot_string *p_from);
+void GDAPI godot_node_path_new_copy(godot_node_path *r_dest, const godot_node_path *p_src);
+void GDAPI godot_node_path_destroy(godot_node_path *p_self);
-godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_np, const godot_int p_idx);
-godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_np);
+godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_self);
-godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_np);
-godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_np, const godot_int p_idx);
-godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_np);
+godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_self);
-godot_bool GDAPI godot_node_path_is_absolute(const godot_node_path *p_np);
-godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_np);
+godot_int GDAPI godot_node_path_get_name_count(const godot_node_path *p_self);
-godot_string GDAPI godot_node_path_as_string(const godot_node_path *p_np);
+godot_string GDAPI godot_node_path_get_name(const godot_node_path *p_self, const godot_int p_idx);
-void GDAPI godot_node_path_destroy(godot_node_path *p_np);
+godot_int GDAPI godot_node_path_get_subname_count(const godot_node_path *p_self);
+
+godot_string GDAPI godot_node_path_get_subname(const godot_node_path *p_self, const godot_int p_idx);
+
+godot_string GDAPI godot_node_path_get_property(const godot_node_path *p_self);
+
+godot_bool GDAPI godot_node_path_is_empty(const godot_node_path *p_self);
+
+godot_bool GDAPI godot_node_path_operator_equal(const godot_node_path *p_self, const godot_node_path *p_b);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_plane.cpp b/modules/gdnative/godot/godot_plane.cpp
index 38329ef709..68adbd4a98 100644
--- a/modules/gdnative/godot/godot_plane.cpp
+++ b/modules/gdnative/godot/godot_plane.cpp
@@ -28,48 +28,149 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_plane.h"
+#include "core/variant.h"
-#include "math/plane.h"
+#include "core/math/plane.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _plane_api_anchor() {
+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;
+ *dest = Plane(p_a, p_b, p_c, p_d);
}
-void GDAPI godot_plane_new(godot_plane *p_pl) {
- Plane *pl = (Plane *)p_pl;
- *pl = Plane();
+void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3) {
+ const Vector3 *v1 = (const Vector3 *)p_v1;
+ const Vector3 *v2 = (const Vector3 *)p_v2;
+ const Vector3 *v3 = (const Vector3 *)p_v3;
+ Plane *dest = (Plane *)r_dest;
+ *dest = Plane(*v1, *v2, *v3);
}
-void GDAPI godot_plane_new_with_normal(godot_plane *p_pl, const godot_vector3 *p_normal, const godot_real p_d) {
- Plane *pl = (Plane *)p_pl;
+void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d) {
const Vector3 *normal = (const Vector3 *)p_normal;
- *pl = Plane(*normal, p_d);
+ Plane *dest = (Plane *)r_dest;
+ *dest = Plane(*normal, p_d);
+}
+
+godot_string GDAPI godot_plane_as_string(const godot_plane *p_self) {
+ godot_string ret;
+ const Plane *self = (const Plane *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self) {
+ godot_plane dest;
+ const Plane *self = (const Plane *)p_self;
+ *((Plane *)&dest) = self->normalized();
+ return dest;
+}
+
+godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self) {
+ godot_vector3 dest;
+ const Plane *self = (const Plane *)p_self;
+ *((Vector3 *)&dest) = self->center();
+ return dest;
+}
+
+godot_vector3 GDAPI godot_plane_get_any_point(const godot_plane *p_self) {
+ godot_vector3 dest;
+ const Plane *self = (const Plane *)p_self;
+ *((Vector3 *)&dest) = self->get_any_point();
+ return dest;
+}
+
+godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *point = (const Vector3 *)p_point;
+ return self->is_point_over(*point);
+}
+
+godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *point = (const Vector3 *)p_point;
+ return self->distance_to(*point);
+}
+
+godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *point = (const Vector3 *)p_point;
+ return self->has_point(*point, p_epsilon);
+}
+
+godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point) {
+ godot_vector3 dest;
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *point = (const Vector3 *)p_point;
+ *((Vector3 *)&dest) = self->project(*point);
+ return dest;
+}
+
+godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c) {
+ const Plane *self = (const Plane *)p_self;
+ const Plane *b = (const Plane *)p_b;
+ const Plane *c = (const Plane *)p_c;
+ Vector3 *dest = (Vector3 *)r_dest;
+ return self->intersect_3(*b, *c, dest);
+}
+
+godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *from = (const Vector3 *)p_from;
+ const Vector3 *dir = (const Vector3 *)p_dir;
+ Vector3 *dest = (Vector3 *)r_dest;
+ return self->intersects_ray(*from, *dir, dest);
+}
+
+godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 *begin = (const Vector3 *)p_begin;
+ const Vector3 *end = (const Vector3 *)p_end;
+ Vector3 *dest = (Vector3 *)r_dest;
+ return self->intersects_segment(*begin, *end, dest);
+}
+
+godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self) {
+ godot_plane raw_dest;
+ Plane *dest = (Plane *)&raw_dest;
+ const Plane *self = (const Plane *)p_self;
+ *dest = -(*self);
+ return raw_dest;
+}
+
+godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b) {
+ const Plane *self = (const Plane *)p_self;
+ const Plane *b = (const Plane *)p_b;
+ return *self == *b;
}
-void GDAPI godot_plane_set_normal(godot_plane *p_pl, const godot_vector3 *p_normal) {
- Plane *pl = (Plane *)p_pl;
+void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal) {
+ Plane *self = (Plane *)p_self;
const Vector3 *normal = (const Vector3 *)p_normal;
- pl->set_normal(*normal);
+ self->set_normal(*normal);
}
-godot_vector3 godot_plane_get_normal(const godot_plane *p_pl) {
- const Plane *pl = (const Plane *)p_pl;
- const Vector3 normal = pl->get_normal();
+godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self) {
+ const Plane *self = (const Plane *)p_self;
+ const Vector3 normal = self->get_normal();
godot_vector3 *v3 = (godot_vector3 *)&normal;
return *v3;
}
-void GDAPI godot_plane_set_d(godot_plane *p_pl, const godot_real p_d) {
- Plane *pl = (Plane *)p_pl;
- pl->d = p_d;
+godot_real GDAPI godot_plane_get_d(const godot_plane *p_self) {
+ const Plane *self = (const Plane *)p_self;
+ return self->d;
}
-godot_real GDAPI godot_plane_get_d(const godot_plane *p_pl) {
- const Plane *pl = (const Plane *)p_pl;
- return pl->d;
+void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d) {
+ Plane *self = (Plane *)p_self;
+ self->d = p_d;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_plane.h b/modules/gdnative/godot/godot_plane.h
index c98e45c9cb..cfc955f277 100644
--- a/modules/gdnative/godot/godot_plane.h
+++ b/modules/gdnative/godot/godot_plane.h
@@ -37,27 +37,52 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_PLANE_TYPE_DEFINED
typedef struct godot_plane {
uint8_t _dont_touch_that[16];
} godot_plane;
#endif
+#include "../godot.h"
#include "godot_vector3.h"
-void GDAPI godot_plane_new(godot_plane *p_pl);
-void GDAPI godot_plane_new_with_normal(godot_plane *p_pl, const godot_vector3 *p_normal, const godot_real p_d);
+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);
+void GDAPI godot_plane_new_with_vectors(godot_plane *r_dest, const godot_vector3 *p_v1, const godot_vector3 *p_v2, const godot_vector3 *p_v3);
+void GDAPI godot_plane_new_with_normal(godot_plane *r_dest, const godot_vector3 *p_normal, const godot_real p_d);
-// @Incomplete
-// These are additional valid constructors
-// _FORCE_INLINE_ Plane(const Vector3 &p_normal, real_t p_d);
-// _FORCE_INLINE_ Plane(const Vector3 &p_point, const Vector3& p_normal);
-// _FORCE_INLINE_ Plane(const Vector3 &p_point1, const Vector3 &p_point2,const Vector3 &p_point3,ClockDirection p_dir = CLOCKWISE);
+godot_string GDAPI godot_plane_as_string(const godot_plane *p_self);
-void GDAPI godot_plane_set_normal(godot_plane *p_pl, const godot_vector3 *p_normal);
-godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_pl);
+godot_plane GDAPI godot_plane_normalized(const godot_plane *p_self);
-godot_real GDAPI godot_plane_get_d(const godot_plane *p_pl);
-void GDAPI godot_plane_set_d(godot_plane *p_pl, const godot_real p_d);
+godot_vector3 GDAPI godot_plane_center(const godot_plane *p_self);
+
+godot_vector3 GDAPI godot_plane_get_any_point(const godot_plane *p_self);
+
+godot_bool GDAPI godot_plane_is_point_over(const godot_plane *p_self, const godot_vector3 *p_point);
+
+godot_real GDAPI godot_plane_distance_to(const godot_plane *p_self, const godot_vector3 *p_point);
+
+godot_bool GDAPI godot_plane_has_point(const godot_plane *p_self, const godot_vector3 *p_point, const godot_real p_epsilon);
+
+godot_vector3 GDAPI godot_plane_project(const godot_plane *p_self, const godot_vector3 *p_point);
+
+godot_bool GDAPI godot_plane_intersect_3(const godot_plane *p_self, godot_vector3 *r_dest, const godot_plane *p_b, const godot_plane *p_c);
+
+godot_bool GDAPI godot_plane_intersects_ray(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_from, const godot_vector3 *p_dir);
+
+godot_bool GDAPI godot_plane_intersects_segment(const godot_plane *p_self, godot_vector3 *r_dest, const godot_vector3 *p_begin, const godot_vector3 *p_end);
+
+godot_plane GDAPI godot_plane_operator_neg(const godot_plane *p_self);
+
+godot_bool GDAPI godot_plane_operator_equal(const godot_plane *p_self, const godot_plane *p_b);
+
+void GDAPI godot_plane_set_normal(godot_plane *p_self, const godot_vector3 *p_normal);
+
+godot_vector3 GDAPI godot_plane_get_normal(const godot_plane *p_self);
+
+godot_real GDAPI godot_plane_get_d(const godot_plane *p_self);
+
+void GDAPI godot_plane_set_d(godot_plane *p_self, const godot_real p_d);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_pool_arrays.cpp b/modules/gdnative/godot/godot_pool_arrays.cpp
index 93e9a9e9dc..ea9aceea81 100644
--- a/modules/gdnative/godot/godot_pool_arrays.cpp
+++ b/modules/gdnative/godot/godot_pool_arrays.cpp
@@ -44,542 +44,584 @@ void _pool_arrays_api_anchor() {
// byte
-void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *p_pba) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- memnew_placement(pba, PoolVector<uint8_t>);
+void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest) {
+ PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
+ memnew_placement(dest, PoolVector<uint8_t>);
}
-void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *p_pba, const godot_array *p_a) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+void GDAPI godot_pool_byte_array_new_copy(godot_pool_byte_array *r_dest, const godot_pool_byte_array *p_src) {
+ PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
+ const PoolVector<uint8_t> *src = (const PoolVector<uint8_t> *)p_src;
+ memnew_placement(dest, PoolVector<uint8_t>(*src));
+}
+
+void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, const godot_array *p_a) {
+ PoolVector<uint8_t> *dest = (PoolVector<uint8_t> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<uint8_t>);
+ memnew_placement(dest, PoolVector<uint8_t>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_pba, const uint8_t p_data) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->append(p_data);
+void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_self, const uint8_t p_data) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->append(p_data);
}
-void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_pba, const godot_pool_byte_array *p_array) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_self, const godot_pool_byte_array *p_array) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
PoolVector<uint8_t> *array = (PoolVector<uint8_t> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- return pba->insert(p_idx, p_data);
+godot_error GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_pba) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_self) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_pba, const uint8_t p_data) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->push_back(p_data);
+void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_self, const uint8_t p_data) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_pba, const godot_int p_idx) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_self, const godot_int p_idx) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_pba, const godot_int p_size) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const godot_int p_size) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- pba->set(p_idx, p_data);
+void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data) {
+ PoolVector<uint8_t> *self = (PoolVector<uint8_t> *)p_self;
+ self->set(p_idx, p_data);
}
-uint8_t GDAPI godot_pool_byte_array_get(godot_pool_byte_array *p_pba, const godot_int p_idx) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- return pba->get(p_idx);
+uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, const godot_int p_idx) {
+ const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+ return self->get(p_idx);
}
-godot_int GDAPI godot_pool_byte_array_size(godot_pool_byte_array *p_pba) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self) {
+ const PoolVector<uint8_t> *self = (const PoolVector<uint8_t> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_pba) {
- ((PoolVector<uint8_t> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self) {
+ ((PoolVector<uint8_t> *)p_self)->~PoolVector();
}
// int
-void GDAPI godot_pool_int_array_new(godot_pool_int_array *p_pba) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- memnew_placement(pba, PoolVector<uint8_t>);
+void GDAPI godot_pool_int_array_new(godot_pool_int_array *r_dest) {
+ PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
+ memnew_placement(dest, PoolVector<godot_int>);
+}
+
+void GDAPI godot_pool_int_array_new_copy(godot_pool_int_array *r_dest, const godot_pool_int_array *p_src) {
+ PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
+ const PoolVector<godot_int> *src = (const PoolVector<godot_int> *)p_src;
+ memnew_placement(dest, PoolVector<godot_int>(*src));
}
-void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *p_pba, const godot_array *p_a) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, const godot_array *p_a) {
+ PoolVector<godot_int> *dest = (PoolVector<godot_int> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<uint8_t>);
+ memnew_placement(dest, PoolVector<godot_int>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_pba, const godot_int p_data) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->append(p_data);
+void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_self, const godot_int p_data) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->append(p_data);
}
-void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_pba, const godot_pool_int_array *p_array) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
+void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_self, const godot_pool_int_array *p_array) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
PoolVector<godot_int> *array = (PoolVector<godot_int> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_pba, const godot_int p_idx, const godot_int p_data) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- return pba->insert(p_idx, p_data);
+godot_error GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_pba) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_self) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_pba, const godot_int p_data) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->push_back(p_data);
+void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_self, const godot_int p_data) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_pba, const godot_int p_idx) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_self, const godot_int p_idx) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_pba, const godot_int p_size) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot_int p_size) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_pba, const godot_int p_idx, const godot_int p_data) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->set(p_idx, p_data);
+void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->set(p_idx, p_data);
}
-godot_int GDAPI godot_pool_int_array_get(godot_pool_int_array *p_pba, const godot_int p_idx) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- return pba->get(p_idx);
+godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, const godot_int p_idx) {
+ const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+ return self->get(p_idx);
}
-godot_int GDAPI godot_pool_int_array_size(godot_pool_int_array *p_pba) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self) {
+ const PoolVector<godot_int> *self = (const PoolVector<godot_int> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_pba) {
- ((PoolVector<godot_int> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self) {
+ ((PoolVector<godot_int> *)p_self)->~PoolVector();
}
// real
-void GDAPI godot_pool_real_array_new(godot_pool_real_array *p_pba) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
- memnew_placement(pba, PoolVector<uint8_t>);
+void GDAPI godot_pool_real_array_new(godot_pool_real_array *r_dest) {
+ PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
+ memnew_placement(dest, PoolVector<godot_real>);
}
-void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *p_pba, const godot_array *p_a) {
- PoolVector<uint8_t> *pba = (PoolVector<uint8_t> *)p_pba;
+void GDAPI godot_pool_real_array_new_copy(godot_pool_real_array *r_dest, const godot_pool_real_array *p_src) {
+ PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
+ const PoolVector<godot_real> *src = (const PoolVector<godot_real> *)p_src;
+ memnew_placement(dest, PoolVector<godot_real>(*src));
+}
+
+void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, const godot_array *p_a) {
+ PoolVector<godot_real> *dest = (PoolVector<godot_real> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<uint8_t>);
+ memnew_placement(dest, PoolVector<godot_real>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_pba, const godot_real p_data) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- pba->append(p_data);
+void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_self, const godot_real p_data) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ self->append(p_data);
}
-void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_pba, const godot_pool_real_array *p_array) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
+void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_self, const godot_pool_real_array *p_array) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
PoolVector<godot_real> *array = (PoolVector<godot_real> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_pba, const godot_int p_idx, const godot_real p_data) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- return pba->insert(p_idx, p_data);
+godot_error GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ return (godot_error)self->insert(p_idx, p_data);
}
-void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_pba) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_self) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_pba, const godot_real p_data) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- pba->push_back(p_data);
+void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_self, const godot_real p_data) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ self->push_back(p_data);
}
-void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_pba, const godot_int p_idx) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const godot_int p_idx) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_pba, const godot_int p_size) {
- PoolVector<godot_int> *pba = (PoolVector<godot_int> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size) {
+ PoolVector<godot_int> *self = (PoolVector<godot_int> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_pba, const godot_int p_idx, const godot_real p_data) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- pba->set(p_idx, p_data);
+void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data) {
+ PoolVector<godot_real> *self = (PoolVector<godot_real> *)p_self;
+ self->set(p_idx, p_data);
}
-godot_real GDAPI godot_pool_real_array_get(godot_pool_real_array *p_pba, const godot_int p_idx) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- return pba->get(p_idx);
+godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self, const godot_int p_idx) {
+ const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+ return self->get(p_idx);
}
-godot_int GDAPI godot_pool_real_array_size(godot_pool_real_array *p_pba) {
- PoolVector<godot_real> *pba = (PoolVector<godot_real> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self) {
+ const PoolVector<godot_real> *self = (const PoolVector<godot_real> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_pba) {
- ((PoolVector<godot_real> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self) {
+ ((PoolVector<godot_real> *)p_self)->~PoolVector();
}
// string
-void GDAPI godot_pool_string_array_new(godot_pool_string_array *p_pba) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
- memnew_placement(pba, PoolVector<String>);
+void GDAPI godot_pool_string_array_new(godot_pool_string_array *r_dest) {
+ PoolVector<String> *dest = (PoolVector<String> *)r_dest;
+ memnew_placement(dest, PoolVector<String>);
+}
+
+void GDAPI godot_pool_string_array_new_copy(godot_pool_string_array *r_dest, const godot_pool_string_array *p_src) {
+ PoolVector<String> *dest = (PoolVector<String> *)r_dest;
+ const PoolVector<String> *src = (const PoolVector<String> *)p_src;
+ memnew_placement(dest, PoolVector<String>(*src));
}
-void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *p_pba, const godot_array *p_a) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_dest, const godot_array *p_a) {
+ PoolVector<String> *dest = (PoolVector<String> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<String>);
+ memnew_placement(dest, PoolVector<String>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_pba, const godot_string *p_data) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_self, const godot_string *p_data) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
String &s = *(String *)p_data;
- pba->append(s);
+ self->append(s);
}
-void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_pba, const godot_pool_string_array *p_array) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_self, const godot_pool_string_array *p_array) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
PoolVector<String> *array = (PoolVector<String> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_pba, const godot_int p_idx, const godot_string *p_data) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+godot_error GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
String &s = *(String *)p_data;
- return pba->insert(p_idx, s);
+ return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_pba) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_self) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_pba, const godot_string *p_data) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_self, const godot_string *p_data) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
String &s = *(String *)p_data;
- pba->push_back(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_pba, const godot_int p_idx) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_self, const godot_int p_idx) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_pba, const godot_int p_size) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const godot_int p_size) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_pba, const godot_int p_idx, const godot_string *p_data) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data) {
+ PoolVector<String> *self = (PoolVector<String> *)p_self;
String &s = *(String *)p_data;
- pba->set(p_idx, s);
+ self->set(p_idx, s);
}
-godot_string GDAPI godot_pool_string_array_get(godot_pool_string_array *p_pba, const godot_int p_idx) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
+godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_self, const godot_int p_idx) {
+ const PoolVector<String> *self = (const PoolVector<String> *)p_self;
godot_string str;
String *s = (String *)&str;
memnew_placement(s, String);
- *s = pba->get(p_idx);
+ *s = self->get(p_idx);
return str;
}
-godot_int GDAPI godot_pool_string_array_size(godot_pool_string_array *p_pba) {
- PoolVector<String> *pba = (PoolVector<String> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_self) {
+ const PoolVector<String> *self = (const PoolVector<String> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_pba) {
- ((PoolVector<String> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self) {
+ ((PoolVector<String> *)p_self)->~PoolVector();
}
// vector2
-void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *p_pba) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
- memnew_placement(pba, PoolVector<Vector2>);
+void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *r_dest) {
+ PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
+ memnew_placement(dest, PoolVector<Vector2>);
+}
+
+void GDAPI godot_pool_vector2_array_new_copy(godot_pool_vector2_array *r_dest, const godot_pool_vector2_array *p_src) {
+ PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
+ const PoolVector<Vector2> *src = (const PoolVector<Vector2> *)p_src;
+ memnew_placement(dest, PoolVector<Vector2>(*src));
}
-void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *p_pba, const godot_array *p_a) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_dest, const godot_array *p_a) {
+ PoolVector<Vector2> *dest = (PoolVector<Vector2> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<Vector2>);
+ memnew_placement(dest, PoolVector<Vector2>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_pba, const godot_vector2 *p_data) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_self, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
- pba->append(s);
+ self->append(s);
}
-void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_pba, const godot_pool_vector2_array *p_array) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_self, const godot_pool_vector2_array *p_array) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
PoolVector<Vector2> *array = (PoolVector<Vector2> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_pba, const godot_int p_idx, const godot_vector2 *p_data) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+godot_error GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
- return pba->insert(p_idx, s);
+ return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_pba) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_self) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_pba, const godot_vector2 *p_data) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_self, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
- pba->push_back(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_pba, const godot_int p_idx) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_self, const godot_int p_idx) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_pba, const godot_int p_size) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, const godot_int p_size) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_pba, const godot_int p_idx, const godot_vector2 *p_data) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data) {
+ PoolVector<Vector2> *self = (PoolVector<Vector2> *)p_self;
Vector2 &s = *(Vector2 *)p_data;
- pba->set(p_idx, s);
+ self->set(p_idx, s);
}
-godot_vector2 GDAPI godot_pool_vector2_array_get(godot_pool_vector2_array *p_pba, const godot_int p_idx) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
+godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array *p_self, const godot_int p_idx) {
+ const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
godot_vector2 v;
Vector2 *s = (Vector2 *)&v;
- *s = pba->get(p_idx);
+ *s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_vector2_array_size(godot_pool_vector2_array *p_pba) {
- PoolVector<Vector2> *pba = (PoolVector<Vector2> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_self) {
+ const PoolVector<Vector2> *self = (const PoolVector<Vector2> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_pba) {
- ((PoolVector<Vector2> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self) {
+ ((PoolVector<Vector2> *)p_self)->~PoolVector();
}
// vector3
-void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *p_pba) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
- memnew_placement(pba, PoolVector<Vector3>);
+void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *r_dest) {
+ PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
+ memnew_placement(dest, PoolVector<Vector3>);
}
-void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *p_pba, const godot_array *p_a) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+void GDAPI godot_pool_vector3_array_new_copy(godot_pool_vector3_array *r_dest, const godot_pool_vector3_array *p_src) {
+ PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
+ const PoolVector<Vector3> *src = (const PoolVector<Vector3> *)p_src;
+ memnew_placement(dest, PoolVector<Vector3>(*src));
+}
+
+void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_dest, const godot_array *p_a) {
+ PoolVector<Vector3> *dest = (PoolVector<Vector3> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<Vector3>);
+ memnew_placement(dest, PoolVector<Vector3>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_pba, const godot_vector3 *p_data) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_self, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
- pba->append(s);
+ self->append(s);
}
-void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_pba, const godot_pool_vector3_array *p_array) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_self, const godot_pool_vector3_array *p_array) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
PoolVector<Vector3> *array = (PoolVector<Vector3> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_pba, const godot_int p_idx, const godot_vector3 *p_data) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+godot_error GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
- return pba->insert(p_idx, s);
+ return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_pba) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_self) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_pba, const godot_vector3 *p_data) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_self, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
- pba->push_back(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_pba, const godot_int p_idx) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_self, const godot_int p_idx) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_pba, const godot_int p_size) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, const godot_int p_size) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_pba, const godot_int p_idx, const godot_vector3 *p_data) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data) {
+ PoolVector<Vector3> *self = (PoolVector<Vector3> *)p_self;
Vector3 &s = *(Vector3 *)p_data;
- pba->set(p_idx, s);
+ self->set(p_idx, s);
}
-godot_vector3 GDAPI godot_pool_vector3_array_get(godot_pool_vector3_array *p_pba, const godot_int p_idx) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
+godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array *p_self, const godot_int p_idx) {
+ const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
godot_vector3 v;
Vector3 *s = (Vector3 *)&v;
- *s = pba->get(p_idx);
+ *s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_vector3_array_size(godot_pool_vector3_array *p_pba) {
- PoolVector<Vector3> *pba = (PoolVector<Vector3> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_self) {
+ const PoolVector<Vector3> *self = (const PoolVector<Vector3> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_pba) {
- ((PoolVector<Vector3> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self) {
+ ((PoolVector<Vector3> *)p_self)->~PoolVector();
}
// color
-void GDAPI godot_pool_color_array_new(godot_pool_color_array *p_pba) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
- memnew_placement(pba, PoolVector<Color>);
+void GDAPI godot_pool_color_array_new(godot_pool_color_array *r_dest) {
+ PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
+ memnew_placement(dest, PoolVector<Color>);
+}
+
+void GDAPI godot_pool_color_array_new_copy(godot_pool_color_array *r_dest, const godot_pool_color_array *p_src) {
+ PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
+ const PoolVector<Color> *src = (const PoolVector<Color> *)p_src;
+ memnew_placement(dest, PoolVector<Color>(*src));
}
-void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *p_pba, const godot_array *p_a) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest, const godot_array *p_a) {
+ PoolVector<Color> *dest = (PoolVector<Color> *)r_dest;
Array *a = (Array *)p_a;
- memnew_placement(pba, PoolVector<Color>);
+ memnew_placement(dest, PoolVector<Color>);
- pba->resize(a->size());
+ dest->resize(a->size());
for (size_t i = 0; i < a->size(); i++) {
- pba->set(i, (*a)[i]);
+ dest->set(i, (*a)[i]);
}
}
-void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_pba, const godot_color *p_data) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_self, const godot_color *p_data) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
Color &s = *(Color *)p_data;
- pba->append(s);
+ self->append(s);
}
-void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_pba, const godot_pool_color_array *p_array) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_self, const godot_pool_color_array *p_array) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
PoolVector<Color> *array = (PoolVector<Color> *)p_array;
- pba->append_array(*array);
+ self->append_array(*array);
}
-int GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_pba, const godot_int p_idx, const godot_color *p_data) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+godot_error GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
Color &s = *(Color *)p_data;
- return pba->insert(p_idx, s);
+ return (godot_error)self->insert(p_idx, s);
}
-void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_pba) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
- pba->invert();
+void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_self) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+ self->invert();
}
-void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_pba, const godot_color *p_data) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_self, const godot_color *p_data) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
Color &s = *(Color *)p_data;
- pba->push_back(s);
+ self->push_back(s);
}
-void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_pba, const godot_int p_idx) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
- pba->remove(p_idx);
+void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_self, const godot_int p_idx) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+ self->remove(p_idx);
}
-void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_pba, const godot_int p_size) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
- pba->resize(p_size);
+void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const godot_int p_size) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
+ self->resize(p_size);
}
-void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_pba, const godot_int p_idx, const godot_color *p_data) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data) {
+ PoolVector<Color> *self = (PoolVector<Color> *)p_self;
Color &s = *(Color *)p_data;
- pba->set(p_idx, s);
+ self->set(p_idx, s);
}
-godot_color GDAPI godot_pool_color_array_get(godot_pool_color_array *p_pba, const godot_int p_idx) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
+godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_self, const godot_int p_idx) {
+ const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
godot_color v;
Color *s = (Color *)&v;
- *s = pba->get(p_idx);
+ *s = self->get(p_idx);
return v;
}
-godot_int GDAPI godot_pool_color_array_size(godot_pool_color_array *p_pba) {
- PoolVector<Color> *pba = (PoolVector<Color> *)p_pba;
- return pba->size();
+godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self) {
+ const PoolVector<Color> *self = (const PoolVector<Color> *)p_self;
+ return self->size();
}
-void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_pba) {
- ((PoolVector<Color> *)p_pba)->~PoolVector();
+void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self) {
+ ((PoolVector<Color> *)p_self)->~PoolVector();
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_pool_arrays.h b/modules/gdnative/godot/godot_pool_arrays.h
index ec9185f6f3..a794d03f01 100644
--- a/modules/gdnative/godot/godot_pool_arrays.h
+++ b/modules/gdnative/godot/godot_pool_arrays.h
@@ -92,191 +92,201 @@ typedef struct godot_pool_color_array {
} godot_pool_color_array;
#endif
-#include "../godot.h"
-
#include "godot_array.h"
+#include "godot_color.h"
+#include "godot_vector2.h"
+#include "godot_vector3.h"
+
+#include "../godot.h"
// byte
-void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *p_pba);
-void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *p_pba, const godot_array *p_a);
+void GDAPI godot_pool_byte_array_new(godot_pool_byte_array *r_dest);
+void GDAPI godot_pool_byte_array_new_copy(godot_pool_byte_array *r_dest, const godot_pool_byte_array *p_src);
+void GDAPI godot_pool_byte_array_new_with_array(godot_pool_byte_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_pba, const uint8_t p_data);
+void GDAPI godot_pool_byte_array_append(godot_pool_byte_array *p_self, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_pba, const godot_pool_byte_array *p_array);
+void GDAPI godot_pool_byte_array_append_array(godot_pool_byte_array *p_self, const godot_pool_byte_array *p_array);
-int GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data);
+godot_error GDAPI godot_pool_byte_array_insert(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_pba);
+void GDAPI godot_pool_byte_array_invert(godot_pool_byte_array *p_self);
-void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_pba, const uint8_t p_data);
+void GDAPI godot_pool_byte_array_push_back(godot_pool_byte_array *p_self, const uint8_t p_data);
-void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_pba, const godot_int p_idx);
+void GDAPI godot_pool_byte_array_remove(godot_pool_byte_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_pba, const godot_int p_size);
+void GDAPI godot_pool_byte_array_resize(godot_pool_byte_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_pba, const godot_int p_idx, const uint8_t p_data);
-uint8_t GDAPI godot_pool_byte_array_get(godot_pool_byte_array *p_pba, const godot_int p_idx);
+void GDAPI godot_pool_byte_array_set(godot_pool_byte_array *p_self, const godot_int p_idx, const uint8_t p_data);
+uint8_t GDAPI godot_pool_byte_array_get(const godot_pool_byte_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_byte_array_size(godot_pool_byte_array *p_pba);
+godot_int GDAPI godot_pool_byte_array_size(const godot_pool_byte_array *p_self);
-void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_pba);
+void GDAPI godot_pool_byte_array_destroy(godot_pool_byte_array *p_self);
// int
-void GDAPI godot_pool_int_array_new(godot_pool_int_array *p_pia);
-void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *p_pia, const godot_array *p_a);
+void GDAPI godot_pool_int_array_new(godot_pool_int_array *r_dest);
+void GDAPI godot_pool_int_array_new_copy(godot_pool_int_array *r_dest, const godot_pool_int_array *p_src);
+void GDAPI godot_pool_int_array_new_with_array(godot_pool_int_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_pia, const godot_int p_data);
+void GDAPI godot_pool_int_array_append(godot_pool_int_array *p_self, const godot_int p_data);
-void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_pia, const godot_pool_int_array *p_array);
+void GDAPI godot_pool_int_array_append_array(godot_pool_int_array *p_self, const godot_pool_int_array *p_array);
-int GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_pia, const godot_int p_idx, const godot_int p_data);
+godot_error GDAPI godot_pool_int_array_insert(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data);
-void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_pia);
+void GDAPI godot_pool_int_array_invert(godot_pool_int_array *p_self);
-void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_pia, const godot_int p_data);
+void GDAPI godot_pool_int_array_push_back(godot_pool_int_array *p_self, const godot_int p_data);
-void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_pia, const godot_int p_idx);
+void GDAPI godot_pool_int_array_remove(godot_pool_int_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_pia, const godot_int p_size);
+void GDAPI godot_pool_int_array_resize(godot_pool_int_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_pia, const godot_int p_idx, const godot_int p_data);
-godot_int GDAPI godot_pool_int_array_get(godot_pool_int_array *p_pia, const godot_int p_idx);
+void GDAPI godot_pool_int_array_set(godot_pool_int_array *p_self, const godot_int p_idx, const godot_int p_data);
+godot_int GDAPI godot_pool_int_array_get(const godot_pool_int_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_int_array_size(godot_pool_int_array *p_pia);
+godot_int GDAPI godot_pool_int_array_size(const godot_pool_int_array *p_self);
-void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_pia);
+void GDAPI godot_pool_int_array_destroy(godot_pool_int_array *p_self);
// real
-void GDAPI godot_pool_real_array_new(godot_pool_real_array *p_pra);
-void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *p_pra, const godot_array *p_a);
+void GDAPI godot_pool_real_array_new(godot_pool_real_array *r_dest);
+void GDAPI godot_pool_real_array_new_copy(godot_pool_real_array *r_dest, const godot_pool_real_array *p_src);
+void GDAPI godot_pool_real_array_new_with_array(godot_pool_real_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_pra, const godot_real p_data);
+void GDAPI godot_pool_real_array_append(godot_pool_real_array *p_self, const godot_real p_data);
-void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_pra, const godot_pool_real_array *p_array);
+void GDAPI godot_pool_real_array_append_array(godot_pool_real_array *p_self, const godot_pool_real_array *p_array);
-int GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_pra, const godot_int p_idx, const godot_real p_data);
+godot_error GDAPI godot_pool_real_array_insert(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data);
-void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_pra);
+void GDAPI godot_pool_real_array_invert(godot_pool_real_array *p_self);
-void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_pra, const godot_real p_data);
+void GDAPI godot_pool_real_array_push_back(godot_pool_real_array *p_self, const godot_real p_data);
-void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_pra, const godot_int p_idx);
+void GDAPI godot_pool_real_array_remove(godot_pool_real_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_pra, const godot_int p_size);
+void GDAPI godot_pool_real_array_resize(godot_pool_real_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_pra, const godot_int p_idx, const godot_real p_data);
-godot_real GDAPI godot_pool_real_array_get(godot_pool_real_array *p_pra, const godot_int p_idx);
+void GDAPI godot_pool_real_array_set(godot_pool_real_array *p_self, const godot_int p_idx, const godot_real p_data);
+godot_real GDAPI godot_pool_real_array_get(const godot_pool_real_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_real_array_size(godot_pool_real_array *p_pra);
+godot_int GDAPI godot_pool_real_array_size(const godot_pool_real_array *p_self);
-void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_pra);
+void GDAPI godot_pool_real_array_destroy(godot_pool_real_array *p_self);
// string
-void GDAPI godot_pool_string_array_new(godot_pool_string_array *p_psa);
-void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *p_psa, const godot_array *p_a);
+void GDAPI godot_pool_string_array_new(godot_pool_string_array *r_dest);
+void GDAPI godot_pool_string_array_new_copy(godot_pool_string_array *r_dest, const godot_pool_string_array *p_src);
+void GDAPI godot_pool_string_array_new_with_array(godot_pool_string_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_psa, const godot_string *p_data);
+void GDAPI godot_pool_string_array_append(godot_pool_string_array *p_self, const godot_string *p_data);
-void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_psa, const godot_pool_string_array *p_array);
+void GDAPI godot_pool_string_array_append_array(godot_pool_string_array *p_self, const godot_pool_string_array *p_array);
-int GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_psa, const godot_int p_idx, const godot_string *p_data);
+godot_error GDAPI godot_pool_string_array_insert(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
-void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_psa);
+void GDAPI godot_pool_string_array_invert(godot_pool_string_array *p_self);
-void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_psa, const godot_string *p_data);
+void GDAPI godot_pool_string_array_push_back(godot_pool_string_array *p_self, const godot_string *p_data);
-void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_psa, const godot_int p_idx);
+void GDAPI godot_pool_string_array_remove(godot_pool_string_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_psa, const godot_int p_size);
+void GDAPI godot_pool_string_array_resize(godot_pool_string_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_psa, const godot_int p_idx, const godot_string *p_data);
-godot_string GDAPI godot_pool_string_array_get(godot_pool_string_array *p_psa, const godot_int p_idx);
+void GDAPI godot_pool_string_array_set(godot_pool_string_array *p_self, const godot_int p_idx, const godot_string *p_data);
+godot_string GDAPI godot_pool_string_array_get(const godot_pool_string_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_string_array_size(godot_pool_string_array *p_psa);
+godot_int GDAPI godot_pool_string_array_size(const godot_pool_string_array *p_self);
-void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_psa);
+void GDAPI godot_pool_string_array_destroy(godot_pool_string_array *p_self);
// vector2
-void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *p_pv2a);
-void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *p_pv2a, const godot_array *p_a);
+void GDAPI godot_pool_vector2_array_new(godot_pool_vector2_array *r_dest);
+void GDAPI godot_pool_vector2_array_new_copy(godot_pool_vector2_array *r_dest, const godot_pool_vector2_array *p_src);
+void GDAPI godot_pool_vector2_array_new_with_array(godot_pool_vector2_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_pv2a, const godot_vector2 *p_data);
+void GDAPI godot_pool_vector2_array_append(godot_pool_vector2_array *p_self, const godot_vector2 *p_data);
-void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_pv2a, const godot_pool_vector2_array *p_array);
+void GDAPI godot_pool_vector2_array_append_array(godot_pool_vector2_array *p_self, const godot_pool_vector2_array *p_array);
-int GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_pv2a, const godot_int p_idx, const godot_vector2 *p_data);
+godot_error GDAPI godot_pool_vector2_array_insert(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
-void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_pool_vector2_array_invert(godot_pool_vector2_array *p_self);
-void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_pv2a, const godot_vector2 *p_data);
+void GDAPI godot_pool_vector2_array_push_back(godot_pool_vector2_array *p_self, const godot_vector2 *p_data);
-void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_pv2a, const godot_int p_idx);
+void GDAPI godot_pool_vector2_array_remove(godot_pool_vector2_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_pv2a, const godot_int p_size);
+void GDAPI godot_pool_vector2_array_resize(godot_pool_vector2_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_pv2a, const godot_int p_idx, const godot_vector2 *p_data);
-godot_vector2 GDAPI godot_pool_vector2_array_get(godot_pool_vector2_array *p_pv2a, const godot_int p_idx);
+void GDAPI godot_pool_vector2_array_set(godot_pool_vector2_array *p_self, const godot_int p_idx, const godot_vector2 *p_data);
+godot_vector2 GDAPI godot_pool_vector2_array_get(const godot_pool_vector2_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_vector2_array_size(godot_pool_vector2_array *p_pv2a);
+godot_int GDAPI godot_pool_vector2_array_size(const godot_pool_vector2_array *p_self);
-void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_pool_vector2_array_destroy(godot_pool_vector2_array *p_self);
// vector3
-void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *p_pv3a);
-void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *p_pv3a, const godot_array *p_a);
+void GDAPI godot_pool_vector3_array_new(godot_pool_vector3_array *r_dest);
+void GDAPI godot_pool_vector3_array_new_copy(godot_pool_vector3_array *r_dest, const godot_pool_vector3_array *p_src);
+void GDAPI godot_pool_vector3_array_new_with_array(godot_pool_vector3_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_pv3a, const godot_vector3 *p_data);
+void GDAPI godot_pool_vector3_array_append(godot_pool_vector3_array *p_self, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_pv3a, const godot_pool_vector3_array *p_array);
+void GDAPI godot_pool_vector3_array_append_array(godot_pool_vector3_array *p_self, const godot_pool_vector3_array *p_array);
-int GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_pv3a, const godot_int p_idx, const godot_vector3 *p_data);
+godot_error GDAPI godot_pool_vector3_array_insert(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_pool_vector3_array_invert(godot_pool_vector3_array *p_self);
-void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_pv3a, const godot_vector3 *p_data);
+void GDAPI godot_pool_vector3_array_push_back(godot_pool_vector3_array *p_self, const godot_vector3 *p_data);
-void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_pv3a, const godot_int p_idx);
+void GDAPI godot_pool_vector3_array_remove(godot_pool_vector3_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_pv3a, const godot_int p_size);
+void GDAPI godot_pool_vector3_array_resize(godot_pool_vector3_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_pv3a, const godot_int p_idx, const godot_vector3 *p_data);
-godot_vector3 GDAPI godot_pool_vector3_array_get(godot_pool_vector3_array *p_pv3a, const godot_int p_idx);
+void GDAPI godot_pool_vector3_array_set(godot_pool_vector3_array *p_self, const godot_int p_idx, const godot_vector3 *p_data);
+godot_vector3 GDAPI godot_pool_vector3_array_get(const godot_pool_vector3_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_vector3_array_size(godot_pool_vector3_array *p_pv3a);
+godot_int GDAPI godot_pool_vector3_array_size(const godot_pool_vector3_array *p_self);
-void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_pool_vector3_array_destroy(godot_pool_vector3_array *p_self);
// color
-void GDAPI godot_pool_color_array_new(godot_pool_color_array *p_pca);
-void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *p_pca, const godot_array *p_a);
+void GDAPI godot_pool_color_array_new(godot_pool_color_array *r_dest);
+void GDAPI godot_pool_color_array_new_copy(godot_pool_color_array *r_dest, const godot_pool_color_array *p_src);
+void GDAPI godot_pool_color_array_new_with_array(godot_pool_color_array *r_dest, const godot_array *p_a);
-void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_pca, const godot_color *p_data);
+void GDAPI godot_pool_color_array_append(godot_pool_color_array *p_self, const godot_color *p_data);
-void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_pca, const godot_pool_color_array *p_array);
+void GDAPI godot_pool_color_array_append_array(godot_pool_color_array *p_self, const godot_pool_color_array *p_array);
-int GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_pca, const godot_int p_idx, const godot_color *p_data);
+godot_error GDAPI godot_pool_color_array_insert(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
-void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_pca);
+void GDAPI godot_pool_color_array_invert(godot_pool_color_array *p_self);
-void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_pca, const godot_color *p_data);
+void GDAPI godot_pool_color_array_push_back(godot_pool_color_array *p_self, const godot_color *p_data);
-void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_pca, const godot_int p_idx);
+void GDAPI godot_pool_color_array_remove(godot_pool_color_array *p_self, const godot_int p_idx);
-void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_pca, const godot_int p_size);
+void GDAPI godot_pool_color_array_resize(godot_pool_color_array *p_self, const godot_int p_size);
-void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_pca, const godot_int p_idx, const godot_color *p_data);
-godot_color GDAPI godot_pool_color_array_get(godot_pool_color_array *p_pca, const godot_int p_idx);
+void GDAPI godot_pool_color_array_set(godot_pool_color_array *p_self, const godot_int p_idx, const godot_color *p_data);
+godot_color GDAPI godot_pool_color_array_get(const godot_pool_color_array *p_self, const godot_int p_idx);
-godot_int GDAPI godot_pool_color_array_size(godot_pool_color_array *p_pca);
+godot_int GDAPI godot_pool_color_array_size(const godot_pool_color_array *p_self);
-void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_pca);
+void GDAPI godot_pool_color_array_destroy(godot_pool_color_array *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_quat.cpp b/modules/gdnative/godot/godot_quat.cpp
index 7c3a71dfc0..7235e4fcec 100644
--- a/modules/gdnative/godot/godot_quat.cpp
+++ b/modules/gdnative/godot/godot_quat.cpp
@@ -28,77 +28,190 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_quat.h"
+#include "core/variant.h"
-#include "math/quat.h"
+#include "core/math/quat.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _quat_api_anchor() {
+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;
+ *dest = Quat(p_x, p_y, p_z, p_w);
}
-void GDAPI godot_quat_new(godot_quat *p_quat) {
- Quat *quat = (Quat *)p_quat;
- *quat = Quat();
+void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle) {
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ Quat *dest = (Quat *)r_dest;
+ *dest = Quat(*axis, p_angle);
}
-void GDAPI godot_quat_new_with_elements(godot_quat *p_quat, const godot_real x, const godot_real y, const godot_real z, const godot_real w) {
- Quat *quat = (Quat *)p_quat;
- *quat = Quat(x, y, z, w);
+godot_real GDAPI godot_quat_get_x(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->x;
}
-void GDAPI godot_quat_new_with_rotation(godot_quat *p_quat, const godot_vector3 *p_axis, const godot_real p_angle) {
- Quat *quat = (Quat *)p_quat;
- const Vector3 *axis = (const Vector3 *)p_axis;
- *quat = Quat(*axis, p_angle);
-}
-
-void GDAPI godot_quat_new_with_shortest_arc(godot_quat *p_quat, const godot_vector3 *p_v0, const godot_vector3 *p_v1) {
- Quat *quat = (Quat *)p_quat;
- const Vector3 *v0 = (const Vector3 *)p_v0;
- const Vector3 *v1 = (const Vector3 *)p_v1;
- *quat = Quat(*v0, *v1);
-}
-
-godot_vector3 GDAPI godot_quat_get_euler(const godot_quat *p_quat) {
- Quat *quat = (Quat *)p_quat;
- Vector3 euler = quat->get_euler();
- return *(godot_vector3 *)&euler;
-}
-
-void GDAPI godot_quat_set_euler(godot_quat *p_quat, const godot_vector3 *p_euler) {
- Quat *quat = (Quat *)p_quat;
- const Vector3 *euler = (const Vector3 *)p_euler;
- quat->set_euler(*euler);
-}
-
-godot_real GDAPI *godot_quat_index(godot_quat *p_quat, const godot_int p_idx) {
- Quat *quat = (Quat *)p_quat;
- switch (p_idx) {
- case 0:
- return &quat->x;
- case 1:
- return &quat->y;
- case 2:
- return &quat->z;
- default:
- return &quat->y;
- }
-}
-
-godot_real GDAPI godot_quat_const_index(const godot_quat *p_quat, const godot_int p_idx) {
- const Quat *quat = (const Quat *)p_quat;
- switch (p_idx) {
- case 0:
- return quat->x;
- case 1:
- return quat->y;
- case 2:
- return quat->z;
- default:
- return quat->y;
- }
+void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val) {
+ Quat *self = (Quat *)p_self;
+ self->x = val;
+}
+
+godot_real GDAPI godot_quat_get_y(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->y;
+}
+
+void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val) {
+ Quat *self = (Quat *)p_self;
+ self->y = val;
+}
+
+godot_real GDAPI godot_quat_get_z(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->z;
+}
+
+void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val) {
+ Quat *self = (Quat *)p_self;
+ self->z = val;
+}
+
+godot_real GDAPI godot_quat_get_w(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->w;
+}
+
+void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val) {
+ Quat *self = (Quat *)p_self;
+ self->w = val;
+}
+
+godot_string GDAPI godot_quat_as_string(const godot_quat *p_self) {
+ godot_string ret;
+ const Quat *self = (const Quat *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_real GDAPI godot_quat_length(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->length();
+}
+
+godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->length_squared();
+}
+
+godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self) {
+ godot_quat dest;
+ const Quat *self = (const Quat *)p_self;
+ *((Quat *)&dest) = self->normalized();
+ return dest;
+}
+
+godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self) {
+ const Quat *self = (const Quat *)p_self;
+ return self->is_normalized();
+}
+
+godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self) {
+ godot_quat dest;
+ const Quat *self = (const Quat *)p_self;
+ *((Quat *)&dest) = self->inverse();
+ return dest;
+}
+
+godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b) {
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ return self->dot(*b);
+}
+
+godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v) {
+ godot_vector3 dest;
+ const Quat *self = (const Quat *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ *((Vector3 *)&dest) = self->xform(*v);
+ return dest;
+}
+
+godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) {
+ godot_quat dest;
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ *((Quat *)&dest) = self->slerp(*b, p_t);
+ return dest;
+}
+
+godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t) {
+ godot_quat dest;
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ *((Quat *)&dest) = self->slerpni(*b, p_t);
+ return dest;
+}
+
+godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t) {
+ godot_quat dest;
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ const Quat *pre_a = (const Quat *)p_pre_a;
+ const Quat *post_b = (const Quat *)p_post_b;
+ *((Quat *)&dest) = self->cubic_slerp(*b, *pre_a, *post_b, p_t);
+ return dest;
+}
+
+godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b) {
+ godot_quat raw_dest;
+ Quat *dest = (Quat *)&raw_dest;
+ const Quat *self = (const Quat *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
+}
+
+godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b) {
+ godot_quat raw_dest;
+ Quat *dest = (Quat *)&raw_dest;
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
+}
+
+godot_quat GDAPI godot_quat_operator_substract(const godot_quat *p_self, const godot_quat *p_b) {
+ godot_quat raw_dest;
+ Quat *dest = (Quat *)&raw_dest;
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
+}
+
+godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b) {
+ godot_quat raw_dest;
+ Quat *dest = (Quat *)&raw_dest;
+ const Quat *self = (const Quat *)p_self;
+ *dest = *self / p_b;
+ return raw_dest;
+}
+
+godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b) {
+ const Quat *self = (const Quat *)p_self;
+ const Quat *b = (const Quat *)p_b;
+ return *self == *b;
+}
+
+godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self) {
+ godot_quat raw_dest;
+ Quat *dest = (Quat *)&raw_dest;
+ const Quat *self = (const Quat *)p_self;
+ *dest = -(*self);
+ return raw_dest;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_quat.h b/modules/gdnative/godot/godot_quat.h
index 35b1acd3ed..2289b6cbab 100644
--- a/modules/gdnative/godot/godot_quat.h
+++ b/modules/gdnative/godot/godot_quat.h
@@ -37,23 +37,63 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_QUAT_TYPE_DEFINED
typedef struct godot_quat {
uint8_t _dont_touch_that[16];
} godot_quat;
#endif
#include "../godot.h"
+#include "godot_vector3.h"
-void GDAPI godot_quat_new(godot_quat *p_quat);
-void GDAPI godot_quat_new_with_elements(godot_quat *p_quat, const godot_real x, const godot_real y, const godot_real z, const godot_real w);
-void GDAPI godot_quat_new_with_rotation(godot_quat *p_quat, const godot_vector3 *p_axis, const godot_real p_angle);
-void GDAPI godot_quat_new_with_shortest_arc(godot_quat *p_quat, const godot_vector3 *p_v0, const godot_vector3 *p_v1);
+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);
+void GDAPI godot_quat_new_with_axis_angle(godot_quat *r_dest, const godot_vector3 *p_axis, const godot_real p_angle);
-godot_vector3 GDAPI godot_quat_get_euler(const godot_quat *p_quat);
-void GDAPI godot_quat_set_euler(godot_quat *p_quat, const godot_vector3 *p_euler);
+godot_real GDAPI godot_quat_get_x(const godot_quat *p_self);
+void GDAPI godot_quat_set_x(godot_quat *p_self, const godot_real val);
-godot_real GDAPI *godot_quat_index(godot_quat *p_quat, const godot_int p_idx);
-godot_real GDAPI godot_quat_const_index(const godot_quat *p_quat, const godot_int p_idx);
+godot_real GDAPI godot_quat_get_y(const godot_quat *p_self);
+void GDAPI godot_quat_set_y(godot_quat *p_self, const godot_real val);
+
+godot_real GDAPI godot_quat_get_z(const godot_quat *p_self);
+void GDAPI godot_quat_set_z(godot_quat *p_self, const godot_real val);
+
+godot_real GDAPI godot_quat_get_w(const godot_quat *p_self);
+void GDAPI godot_quat_set_w(godot_quat *p_self, const godot_real val);
+
+godot_string GDAPI godot_quat_as_string(const godot_quat *p_self);
+
+godot_real GDAPI godot_quat_length(const godot_quat *p_self);
+
+godot_real GDAPI godot_quat_length_squared(const godot_quat *p_self);
+
+godot_quat GDAPI godot_quat_normalized(const godot_quat *p_self);
+
+godot_bool GDAPI godot_quat_is_normalized(const godot_quat *p_self);
+
+godot_quat GDAPI godot_quat_inverse(const godot_quat *p_self);
+
+godot_real GDAPI godot_quat_dot(const godot_quat *p_self, const godot_quat *p_b);
+
+godot_vector3 GDAPI godot_quat_xform(const godot_quat *p_self, const godot_vector3 *p_v);
+
+godot_quat GDAPI godot_quat_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t);
+
+godot_quat GDAPI godot_quat_slerpni(const godot_quat *p_self, const godot_quat *p_b, const godot_real p_t);
+
+godot_quat GDAPI godot_quat_cubic_slerp(const godot_quat *p_self, const godot_quat *p_b, const godot_quat *p_pre_a, const godot_quat *p_post_b, const godot_real p_t);
+
+godot_quat GDAPI godot_quat_operator_multiply(const godot_quat *p_self, const godot_real p_b);
+
+godot_quat GDAPI godot_quat_operator_add(const godot_quat *p_self, const godot_quat *p_b);
+
+godot_quat GDAPI godot_quat_operator_substract(const godot_quat *p_self, const godot_quat *p_b);
+
+godot_quat GDAPI godot_quat_operator_divide(const godot_quat *p_self, const godot_real p_b);
+
+godot_bool GDAPI godot_quat_operator_equal(const godot_quat *p_self, const godot_quat *p_b);
+
+godot_quat GDAPI godot_quat_operator_neg(const godot_quat *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_rect2.cpp b/modules/gdnative/godot/godot_rect2.cpp
index b19096b79e..0e456ea3ba 100644
--- a/modules/gdnative/godot/godot_rect2.cpp
+++ b/modules/gdnative/godot/godot_rect2.cpp
@@ -28,48 +28,128 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_rect2.h"
+#include "core/variant.h"
-#include "math/math_2d.h"
+#include "core/math/math_2d.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _rect2_api_anchor() {
+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;
+ Rect2 *dest = (Rect2 *)r_dest;
+ *dest = Rect2(*position, *size);
}
-void GDAPI godot_rect2_new(godot_rect2 *p_rect) {
- Rect2 *rect = (Rect2 *)p_rect;
- *rect = Rect2();
+void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height) {
+
+ Rect2 *dest = (Rect2 *)r_dest;
+ *dest = Rect2(p_x, p_y, p_width, p_height);
}
-void GDAPI godot_rect2_new_with_pos_and_size(godot_rect2 *p_rect, const godot_vector2 *p_pos, const godot_vector2 *p_size) {
- Rect2 *rect = (Rect2 *)p_rect;
- const Vector2 *pos = (const Vector2 *)p_pos;
- const Vector2 *size = (const Vector2 *)p_size;
- *rect = Rect2(*pos, *size);
+godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self) {
+ godot_string ret;
+ const Rect2 *self = (const Rect2 *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ return self->get_area();
+}
+
+godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Rect2 *b = (const Rect2 *)p_b;
+ return self->intersects(*b);
+}
+
+godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Rect2 *b = (const Rect2 *)p_b;
+ return self->encloses(*b);
+}
+
+godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ return self->has_no_area();
+}
+
+godot_rect2 GDAPI godot_rect2_clip(const godot_rect2 *p_self, const godot_rect2 *p_b) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Rect2 *b = (const Rect2 *)p_b;
+ *((Rect2 *)&dest) = self->clip(*b);
+ return dest;
+}
+
+godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Rect2 *b = (const Rect2 *)p_b;
+ *((Rect2 *)&dest) = self->merge(*b);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Vector2 *point = (const Vector2 *)p_point;
+ return self->has_point(*point);
+}
+
+godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+
+ *((Rect2 *)&dest) = self->grow(p_by);
+ return dest;
+}
+
+godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to) {
+ godot_rect2 dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ *((Rect2 *)&dest) = self->expand(*to);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b) {
+ const Rect2 *self = (const Rect2 *)p_self;
+ const Rect2 *b = (const Rect2 *)p_b;
+ return *self == *b;
}
-godot_vector2 GDAPI *godot_rect2_get_pos(godot_rect2 *p_rect) {
- Rect2 *rect = (Rect2 *)p_rect;
- return (godot_vector2 *)&rect->pos;
+godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self) {
+ godot_vector2 dest;
+ Vector2 *d = (Vector2 *)&dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *d = self->get_position();
+ return dest;
}
-void GDAPI godot_rect2_set_pos(godot_rect2 *p_rect, const godot_vector2 *p_pos) {
- Rect2 *rect = (Rect2 *)p_rect;
- const Vector2 *pos = (const Vector2 *)p_pos;
- rect->pos = *pos;
+godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self) {
+ godot_vector2 dest;
+ Vector2 *d = (Vector2 *)&dest;
+ const Rect2 *self = (const Rect2 *)p_self;
+ *d = self->get_size();
+ return dest;
}
-godot_vector2 GDAPI *godot_rect2_get_size(godot_rect2 *p_rect) {
- Rect2 *rect = (Rect2 *)p_rect;
- return (godot_vector2 *)&rect->size;
+void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos) {
+ Rect2 *self = (Rect2 *)p_self;
+ const Vector2 *position = (const Vector2 *)p_pos;
+ self->set_position(*position);
}
-void GDAPI godot_rect2_set_size(godot_rect2 *p_rect, const godot_vector2 *p_size) {
- Rect2 *rect = (Rect2 *)p_rect;
+void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size) {
+ Rect2 *self = (Rect2 *)p_self;
const Vector2 *size = (const Vector2 *)p_size;
- rect->size = *size;
+ self->set_size(*size);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_rect2.h b/modules/gdnative/godot/godot_rect2.h
index e9e4a26897..488a1204f7 100644
--- a/modules/gdnative/godot/godot_rect2.h
+++ b/modules/gdnative/godot/godot_rect2.h
@@ -37,24 +37,50 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_RECT2_TYPE_DEFINED
typedef struct godot_rect2 {
uint8_t _dont_touch_that[16];
} godot_rect2;
#endif
#include "../godot.h"
+#include "godot_vector2.h"
-void GDAPI godot_rect2_new(godot_rect2 *p_rect);
-void GDAPI godot_rect2_new_with_pos_and_size(godot_rect2 *p_rect, const godot_vector2 *p_pos, const godot_vector2 *p_size);
+void GDAPI godot_rect2_new_with_position_and_size(godot_rect2 *r_dest, const godot_vector2 *p_pos, const godot_vector2 *p_size);
+void GDAPI godot_rect2_new(godot_rect2 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_width, const godot_real p_height);
-godot_vector2 GDAPI *godot_rect2_get_pos(godot_rect2 *p_rect);
-void GDAPI godot_rect2_set_pos(godot_rect2 *p_rect, const godot_vector2 *p_pos);
+godot_string GDAPI godot_rect2_as_string(const godot_rect2 *p_self);
-godot_vector2 GDAPI *godot_rect2_get_size(godot_rect2 *p_rect);
-void GDAPI godot_rect2_set_size(godot_rect2 *p_rect, const godot_vector2 *p_size);
+godot_real GDAPI godot_rect2_get_area(const godot_rect2 *p_self);
+
+godot_bool GDAPI godot_rect2_intersects(const godot_rect2 *p_self, const godot_rect2 *p_b);
+
+godot_bool GDAPI godot_rect2_encloses(const godot_rect2 *p_self, const godot_rect2 *p_b);
+
+godot_bool GDAPI godot_rect2_has_no_area(const godot_rect2 *p_self);
+
+godot_rect2 GDAPI godot_rect2_clip(const godot_rect2 *p_self, const godot_rect2 *p_b);
+
+godot_rect2 GDAPI godot_rect2_merge(const godot_rect2 *p_self, const godot_rect2 *p_b);
+
+godot_bool GDAPI godot_rect2_has_point(const godot_rect2 *p_self, const godot_vector2 *p_point);
+
+godot_rect2 GDAPI godot_rect2_grow(const godot_rect2 *p_self, const godot_real p_by);
+
+godot_rect2 GDAPI godot_rect2_expand(const godot_rect2 *p_self, const godot_vector2 *p_to);
+
+godot_bool GDAPI godot_rect2_operator_equal(const godot_rect2 *p_self, const godot_rect2 *p_b);
+
+godot_vector2 GDAPI godot_rect2_get_position(const godot_rect2 *p_self);
+
+godot_vector2 GDAPI godot_rect2_get_size(const godot_rect2 *p_self);
+
+void GDAPI godot_rect2_set_position(godot_rect2 *p_self, const godot_vector2 *p_pos);
+
+void GDAPI godot_rect2_set_size(godot_rect2 *p_self, const godot_vector2 *p_size);
#ifdef __cplusplus
}
#endif
-#endif // GODOT_RECT3_H
+#endif // GODOT_RECT2_H
diff --git a/modules/gdnative/godot/godot_rect3.cpp b/modules/gdnative/godot/godot_rect3.cpp
index 96c5d17b1a..e524fa8463 100644
--- a/modules/gdnative/godot/godot_rect3.cpp
+++ b/modules/gdnative/godot/godot_rect3.cpp
@@ -28,48 +28,190 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_rect3.h"
+#include "core/variant.h"
-#include "math/rect3.h"
+#include "core/math/rect3.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _rect3_api_anchor() {
+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;
+ Rect3 *dest = (Rect3 *)r_dest;
+ *dest = Rect3(*pos, *size);
}
-void GDAPI godot_rect3_new(godot_rect3 *p_rect) {
- Rect3 *rect = (Rect3 *)p_rect;
- *rect = Rect3();
+godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self) {
+ godot_vector3 raw_ret;
+ const Rect3 *self = (const Rect3 *)p_self;
+ Vector3 *ret = (Vector3 *)&raw_ret;
+ *ret = self->position;
+ return raw_ret;
}
-void GDAPI godot_rect3_new_with_pos_and_size(godot_rect3 *p_rect, const godot_vector3 *p_pos, const godot_vector3 *p_size) {
- Rect3 *rect = (Rect3 *)p_rect;
- const Vector3 *pos = (const Vector3 *)p_pos;
- const Vector3 *size = (const Vector3 *)p_size;
- *rect = Rect3(*pos, *size);
+void GDAPI godot_rect3_set_position(const godot_rect3 *p_self, const godot_vector3 *p_v) {
+ Rect3 *self = (Rect3 *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ self->position = *v;
}
-godot_vector3 GDAPI *godot_rect3_get_pos(godot_rect3 *p_rect) {
- Rect3 *rect = (Rect3 *)p_rect;
- return (godot_vector3 *)&rect->pos;
+godot_vector3 GDAPI godot_rect3_get_size(const godot_rect3 *p_self) {
+ godot_vector3 raw_ret;
+ const Rect3 *self = (const Rect3 *)p_self;
+ Vector3 *ret = (Vector3 *)&raw_ret;
+ *ret = self->size;
+ return raw_ret;
}
-void GDAPI godot_rect3_set_pos(godot_rect3 *p_rect, const godot_vector3 *p_pos) {
- Rect3 *rect = (Rect3 *)p_rect;
- const Vector3 *pos = (const Vector3 *)p_pos;
- rect->pos = *pos;
+void GDAPI godot_rect3_set_size(const godot_rect3 *p_self, const godot_vector3 *p_v) {
+ Rect3 *self = (Rect3 *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ self->size = *v;
}
-godot_vector3 GDAPI *godot_rect3_get_size(godot_rect3 *p_rect) {
- Rect3 *rect = (Rect3 *)p_rect;
- return (godot_vector3 *)&rect->size;
+godot_string GDAPI godot_rect3_as_string(const godot_rect3 *p_self) {
+ godot_string ret;
+ const Rect3 *self = (const Rect3 *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
}
-void GDAPI godot_rect3_set_size(godot_rect3 *p_rect, const godot_vector3 *p_size) {
- Rect3 *rect = (Rect3 *)p_rect;
- const Vector3 *size = (const Vector3 *)p_size;
- rect->size = *size;
+godot_real GDAPI godot_rect3_get_area(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->get_area();
+}
+
+godot_bool GDAPI godot_rect3_has_no_area(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->has_no_area();
+}
+
+godot_bool GDAPI godot_rect3_has_no_surface(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->has_no_surface();
+}
+
+godot_bool GDAPI godot_rect3_intersects(const godot_rect3 *p_self, const godot_rect3 *p_with) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Rect3 *with = (const Rect3 *)p_with;
+ return self->intersects(*with);
+}
+
+godot_bool GDAPI godot_rect3_encloses(const godot_rect3 *p_self, const godot_rect3 *p_with) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Rect3 *with = (const Rect3 *)p_with;
+ return self->encloses(*with);
+}
+
+godot_rect3 GDAPI godot_rect3_merge(const godot_rect3 *p_self, const godot_rect3 *p_with) {
+ godot_rect3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Rect3 *with = (const Rect3 *)p_with;
+ *((Rect3 *)&dest) = self->merge(*with);
+ return dest;
+}
+
+godot_rect3 GDAPI godot_rect3_intersection(const godot_rect3 *p_self, const godot_rect3 *p_with) {
+ godot_rect3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Rect3 *with = (const Rect3 *)p_with;
+ *((Rect3 *)&dest) = self->intersection(*with);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect3_intersects_plane(const godot_rect3 *p_self, const godot_plane *p_plane) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Plane *plane = (const Plane *)p_plane;
+ return self->intersects_plane(*plane);
+}
+
+godot_bool GDAPI godot_rect3_intersects_segment(const godot_rect3 *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Vector3 *from = (const Vector3 *)p_from;
+ const Vector3 *to = (const Vector3 *)p_to;
+ return self->intersects_segment(*from, *to);
+}
+
+godot_bool GDAPI godot_rect3_has_point(const godot_rect3 *p_self, const godot_vector3 *p_point) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Vector3 *point = (const Vector3 *)p_point;
+ return self->has_point(*point);
+}
+
+godot_vector3 GDAPI godot_rect3_get_support(const godot_rect3 *p_self, const godot_vector3 *p_dir) {
+ godot_vector3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Vector3 *dir = (const Vector3 *)p_dir;
+ *((Vector3 *)&dest) = self->get_support(*dir);
+ return dest;
+}
+
+godot_vector3 GDAPI godot_rect3_get_longest_axis(const godot_rect3 *p_self) {
+ godot_vector3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ *((Vector3 *)&dest) = self->get_longest_axis();
+ return dest;
+}
+
+godot_int GDAPI godot_rect3_get_longest_axis_index(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->get_longest_axis_index();
+}
+
+godot_real GDAPI godot_rect3_get_longest_axis_size(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->get_longest_axis_size();
+}
+
+godot_vector3 GDAPI godot_rect3_get_shortest_axis(const godot_rect3 *p_self) {
+ godot_vector3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ *((Vector3 *)&dest) = self->get_shortest_axis();
+ return dest;
+}
+
+godot_int GDAPI godot_rect3_get_shortest_axis_index(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->get_shortest_axis_index();
+}
+
+godot_real GDAPI godot_rect3_get_shortest_axis_size(const godot_rect3 *p_self) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ return self->get_shortest_axis_size();
+}
+
+godot_rect3 GDAPI godot_rect3_expand(const godot_rect3 *p_self, const godot_vector3 *p_to_point) {
+ godot_rect3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Vector3 *to_point = (const Vector3 *)p_to_point;
+ *((Rect3 *)&dest) = self->expand(*to_point);
+ return dest;
+}
+
+godot_rect3 GDAPI godot_rect3_grow(const godot_rect3 *p_self, const godot_real p_by) {
+ godot_rect3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+
+ *((Rect3 *)&dest) = self->grow(p_by);
+ return dest;
+}
+
+godot_vector3 GDAPI godot_rect3_get_endpoint(const godot_rect3 *p_self, const godot_int p_idx) {
+ godot_vector3 dest;
+ const Rect3 *self = (const Rect3 *)p_self;
+
+ *((Vector3 *)&dest) = self->get_endpoint(p_idx);
+ return dest;
+}
+
+godot_bool GDAPI godot_rect3_operator_equal(const godot_rect3 *p_self, const godot_rect3 *p_b) {
+ const Rect3 *self = (const Rect3 *)p_self;
+ const Rect3 *b = (const Rect3 *)p_b;
+ return *self == *b;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_rect3.h b/modules/gdnative/godot/godot_rect3.h
index 562ac8379e..9e9a49ac27 100644
--- a/modules/gdnative/godot/godot_rect3.h
+++ b/modules/gdnative/godot/godot_rect3.h
@@ -37,21 +37,67 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_RECT3_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_RECT3_TYPE_DEFINED
typedef struct godot_rect3 {
uint8_t _dont_touch_that[24];
} godot_rect3;
#endif
#include "../godot.h"
+#include "godot_plane.h"
+#include "godot_vector3.h"
-void GDAPI godot_rect3_new(godot_rect3 *p_rect);
-void GDAPI godot_rect3_new_with_pos_and_size(godot_rect3 *p_rect, const godot_vector3 *p_pos, const godot_vector3 *p_size);
+void GDAPI godot_rect3_new(godot_rect3 *r_dest, const godot_vector3 *p_pos, const godot_vector3 *p_size);
-godot_vector3 GDAPI *godot_rect3_get_pos(godot_rect3 *p_rect);
-void GDAPI godot_rect3_set_pos(godot_rect3 *p_rect, const godot_vector3 *p_pos);
+godot_vector3 GDAPI godot_rect3_get_position(const godot_rect3 *p_self);
+void GDAPI godot_rect3_set_position(const godot_rect3 *p_self, const godot_vector3 *p_v);
-godot_vector3 GDAPI *godot_rect3_get_size(godot_rect3 *p_rect);
-void GDAPI godot_rect3_set_size(godot_rect3 *p_rect, const godot_vector3 *p_size);
+godot_vector3 GDAPI godot_rect3_get_size(const godot_rect3 *p_self);
+void GDAPI godot_rect3_set_size(const godot_rect3 *p_self, const godot_vector3 *p_v);
+
+godot_string GDAPI godot_rect3_as_string(const godot_rect3 *p_self);
+
+godot_real GDAPI godot_rect3_get_area(const godot_rect3 *p_self);
+
+godot_bool GDAPI godot_rect3_has_no_area(const godot_rect3 *p_self);
+
+godot_bool GDAPI godot_rect3_has_no_surface(const godot_rect3 *p_self);
+
+godot_bool GDAPI godot_rect3_intersects(const godot_rect3 *p_self, const godot_rect3 *p_with);
+
+godot_bool GDAPI godot_rect3_encloses(const godot_rect3 *p_self, const godot_rect3 *p_with);
+
+godot_rect3 GDAPI godot_rect3_merge(const godot_rect3 *p_self, const godot_rect3 *p_with);
+
+godot_rect3 GDAPI godot_rect3_intersection(const godot_rect3 *p_self, const godot_rect3 *p_with);
+
+godot_bool GDAPI godot_rect3_intersects_plane(const godot_rect3 *p_self, const godot_plane *p_plane);
+
+godot_bool GDAPI godot_rect3_intersects_segment(const godot_rect3 *p_self, const godot_vector3 *p_from, const godot_vector3 *p_to);
+
+godot_bool GDAPI godot_rect3_has_point(const godot_rect3 *p_self, const godot_vector3 *p_point);
+
+godot_vector3 GDAPI godot_rect3_get_support(const godot_rect3 *p_self, const godot_vector3 *p_dir);
+
+godot_vector3 GDAPI godot_rect3_get_longest_axis(const godot_rect3 *p_self);
+
+godot_int GDAPI godot_rect3_get_longest_axis_index(const godot_rect3 *p_self);
+
+godot_real GDAPI godot_rect3_get_longest_axis_size(const godot_rect3 *p_self);
+
+godot_vector3 GDAPI godot_rect3_get_shortest_axis(const godot_rect3 *p_self);
+
+godot_int GDAPI godot_rect3_get_shortest_axis_index(const godot_rect3 *p_self);
+
+godot_real GDAPI godot_rect3_get_shortest_axis_size(const godot_rect3 *p_self);
+
+godot_rect3 GDAPI godot_rect3_expand(const godot_rect3 *p_self, const godot_vector3 *p_to_point);
+
+godot_rect3 GDAPI godot_rect3_grow(const godot_rect3 *p_self, const godot_real p_by);
+
+godot_vector3 GDAPI godot_rect3_get_endpoint(const godot_rect3 *p_self, const godot_int p_idx);
+
+godot_bool GDAPI godot_rect3_operator_equal(const godot_rect3 *p_self, const godot_rect3 *p_b);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_rid.cpp b/modules/gdnative/godot/godot_rid.cpp
index fff31e3992..343c004bff 100644
--- a/modules/gdnative/godot/godot_rid.cpp
+++ b/modules/gdnative/godot/godot_rid.cpp
@@ -28,36 +28,46 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_rid.h"
+#include "core/variant.h"
-#include "object.h"
-#include "resource.h"
+#include "core/resource.h"
+#include "core/rid.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _rid_api_anchor() {
-}
-
-void GDAPI godot_rid_new(godot_rid *p_rid, godot_object *p_from) {
+void _rid_api_anchor() {}
- Resource *res_from = ((Object *)p_from)->cast_to<Resource>();
+void GDAPI godot_rid_new(godot_rid *r_dest) {
+ RID *dest = (RID *)r_dest;
+ memnew_placement(dest, RID);
+}
- RID *rid = (RID *)p_rid;
- memnew_placement(rid, RID);
+godot_int GDAPI godot_rid_get_id(const godot_rid *p_self) {
+ const RID *self = (const RID *)p_self;
+ return self->get_id();
+}
+void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from) {
+ const Resource *res_from = ((const Object *)p_from)->cast_to<Resource>();
+ godot_rid_new(r_dest);
if (res_from) {
- *rid = RID(res_from->get_rid());
+ RID *dest = (RID *)r_dest;
+ *dest = RID(res_from->get_rid());
}
}
-uint32_t GDAPI godot_rid_get_rid(const godot_rid *p_rid) {
- RID *rid = (RID *)p_rid;
- return rid->get_id();
+godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b) {
+ const RID *self = (const RID *)p_self;
+ const RID *b = (const RID *)p_b;
+ return *self == *b;
}
-void GDAPI godot_rid_destroy(godot_rid *p_rid) {
- ((RID *)p_rid)->~RID();
+godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b) {
+ const RID *self = (const RID *)p_self;
+ const RID *b = (const RID *)p_b;
+ return *self < *b;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_rid.h b/modules/gdnative/godot/godot_rid.h
index e00c8f89ad..25dc8d965e 100644
--- a/modules/gdnative/godot/godot_rid.h
+++ b/modules/gdnative/godot/godot_rid.h
@@ -37,6 +37,7 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_RID_TYPE_DEFINED
typedef struct godot_rid {
uint8_t _dont_touch_that[8];
} godot_rid;
@@ -44,11 +45,15 @@ typedef struct godot_rid {
#include "../godot.h"
-void GDAPI godot_rid_new(godot_rid *p_rid, godot_object *p_from);
+void GDAPI godot_rid_new(godot_rid *r_dest);
-uint32_t GDAPI godot_rid_get_rid(const godot_rid *p_rid);
+godot_int GDAPI godot_rid_get_id(const godot_rid *p_self);
-void GDAPI godot_rid_destroy(godot_rid *p_rid);
+void GDAPI godot_rid_new_with_resource(godot_rid *r_dest, const godot_object *p_from);
+
+godot_bool GDAPI godot_rid_operator_equal(const godot_rid *p_self, const godot_rid *p_b);
+
+godot_bool GDAPI godot_rid_operator_less(const godot_rid *p_self, const godot_rid *p_b);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_string.cpp b/modules/gdnative/godot/godot_string.cpp
index 92c0b04041..679011e715 100644
--- a/modules/gdnative/godot/godot_string.cpp
+++ b/modules/gdnative/godot/godot_string.cpp
@@ -41,75 +41,75 @@ extern "C" {
void _string_api_anchor() {
}
-void GDAPI godot_string_new(godot_string *p_str) {
- String *p = (String *)p_str;
- memnew_placement(p, String);
- // *p = String(); // useless here
+void GDAPI godot_string_new(godot_string *r_dest) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String);
}
-void GDAPI godot_string_new_data(godot_string *p_str, const char *p_contents, const int p_size) {
- String *p = (String *)p_str;
- memnew_placement(p, String);
- *p = String::utf8(p_contents, p_size);
+void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src) {
+ String *dest = (String *)r_dest;
+ const String *src = (const String *)p_src;
+ memnew_placement(dest, String(*src));
}
-void GDAPI godot_string_get_data(const godot_string *p_str, char *p_dest, int *p_size) {
- String *p = (String *)p_str;
- if (p_size != NULL) {
- *p_size = p->utf8().length();
- }
- if (p_dest != NULL) {
- memcpy(p_dest, p->utf8().get_data(), *p_size);
- }
+void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String(String::utf8(p_contents, p_size)));
}
-void GDAPI godot_string_copy_string(const godot_string *p_dest, const godot_string *p_src) {
- String *dest = (String *)p_dest;
- String *src = (String *)p_src;
-
- *dest = *src;
+void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_contents, const int p_size) {
+ String *dest = (String *)r_dest;
+ memnew_placement(dest, String(p_contents, p_size));
}
-wchar_t GDAPI *godot_string_operator_index(godot_string *p_str, const godot_int p_idx) {
- String *s = (String *)p_str;
- return &(s->operator[](p_idx));
+void GDAPI godot_string_get_data(const godot_string *p_self, char *r_dest, int *p_size) {
+ String *self = (String *)p_self;
+ if (p_size != NULL) {
+ *p_size = self->utf8().length();
+ }
+ if (r_dest != NULL) {
+ memcpy(r_dest, self->utf8().get_data(), *p_size);
+ }
}
-const char GDAPI *godot_string_c_str(const godot_string *p_str) {
- const String *s = (const String *)p_str;
- return s->utf8().get_data();
+wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx) {
+ String *self = (String *)p_self;
+ return &(self->operator[](p_idx));
}
-const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_str) {
- const String *s = (const String *)p_str;
- return s->c_str();
+const char GDAPI *godot_string_c_str(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+ return self->utf8().get_data();
}
-godot_bool GDAPI godot_string_operator_equal(const godot_string *p_a, const godot_string *p_b) {
- String *a = (String *)p_a;
- String *b = (String *)p_b;
- return *a == *b;
+const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self) {
+ const String *self = (const String *)p_self;
+ return self->c_str();
}
-godot_bool GDAPI godot_string_operator_less(const godot_string *p_a, const godot_string *p_b) {
- String *a = (String *)p_a;
- String *b = (String *)p_b;
- return *a < *b;
+godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b) {
+ const String *self = (const String *)p_self;
+ const String *b = (const String *)p_b;
+ return *self == *b;
}
-void GDAPI godot_string_operator_plus(godot_string *p_dest, const godot_string *p_a, const godot_string *p_b) {
- String *dest = (String *)p_dest;
- const String *a = (String *)p_a;
- const String *b = (String *)p_b;
+godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b) {
+ const String *self = (const String *)p_self;
+ const String *b = (const String *)p_b;
+ return *self < *b;
+}
- String tmp = *a + *b;
- godot_string_new(p_dest);
- *dest = tmp;
+godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b) {
+ godot_string ret;
+ const String *self = (const String *)p_self;
+ const String *b = (const String *)p_b;
+ memnew_placement(&ret, String(*self + *b));
+ return ret;
}
-void GDAPI godot_string_destroy(godot_string *p_str) {
- String *p = (String *)p_str;
- p->~String();
+void GDAPI godot_string_destroy(godot_string *p_self) {
+ String *self = (String *)p_self;
+ self->~String();
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_string.h b/modules/gdnative/godot/godot_string.h
index 83ed5d6ec1..df848abb76 100644
--- a/modules/gdnative/godot/godot_string.h
+++ b/modules/gdnative/godot/godot_string.h
@@ -45,26 +45,26 @@ typedef struct godot_string {
#include "../godot.h"
-void GDAPI godot_string_new(godot_string *p_str);
-void GDAPI godot_string_new_data(godot_string *p_str, const char *p_contents, const int p_size);
+void GDAPI godot_string_new(godot_string *r_dest);
+void GDAPI godot_string_new_copy(godot_string *r_dest, const godot_string *p_src);
+void GDAPI godot_string_new_data(godot_string *r_dest, const char *p_contents, const int p_size);
+void GDAPI godot_string_new_unicode_data(godot_string *r_dest, const wchar_t *p_contents, const int p_size);
-void GDAPI godot_string_get_data(const godot_string *p_str, char *p_dest, int *p_size);
+void GDAPI godot_string_get_data(const godot_string *p_self, char *p_dest, int *p_size);
-void GDAPI godot_string_copy_string(const godot_string *p_dest, const godot_string *p_src);
+wchar_t GDAPI *godot_string_operator_index(godot_string *p_self, const godot_int p_idx);
+const char GDAPI *godot_string_c_str(const godot_string *p_self);
+const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_self);
-wchar_t GDAPI *godot_string_operator_index(godot_string *p_str, const godot_int p_idx);
-const char GDAPI *godot_string_c_str(const godot_string *p_str);
-const wchar_t GDAPI *godot_string_unicode_str(const godot_string *p_str);
-
-godot_bool GDAPI godot_string_operator_equal(const godot_string *p_a, const godot_string *p_b);
-godot_bool GDAPI godot_string_operator_less(const godot_string *p_a, const godot_string *p_b);
-void GDAPI godot_string_operator_plus(godot_string *p_dest, const godot_string *p_a, const godot_string *p_b);
+godot_bool GDAPI godot_string_operator_equal(const godot_string *p_self, const godot_string *p_b);
+godot_bool GDAPI godot_string_operator_less(const godot_string *p_self, const godot_string *p_b);
+godot_string GDAPI godot_string_operator_plus(const godot_string *p_self, const godot_string *p_b);
// @Incomplete
// hmm, I guess exposing the whole API doesn't make much sense
// since the language used in the library has its own string funcs
-void GDAPI godot_string_destroy(godot_string *p_str);
+void GDAPI godot_string_destroy(godot_string *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_transform.cpp b/modules/gdnative/godot/godot_transform.cpp
index 681c2b049a..eb9e1e207b 100644
--- a/modules/gdnative/godot/godot_transform.cpp
+++ b/modules/gdnative/godot/godot_transform.cpp
@@ -28,42 +28,194 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_transform.h"
+#include "core/variant.h"
-#include "math/transform.h"
+#include "core/math/transform.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _transform_api_anchor() {
-}
+void _transform_api_anchor() {}
-void GDAPI godot_transform_new(godot_transform *p_trans) {
- Transform *trans = (Transform *)p_trans;
- *trans = Transform();
+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;
+ const Vector3 *z_axis = (const Vector3 *)p_z_axis;
+ const Vector3 *origin = (const Vector3 *)p_origin;
+ Transform *dest = (Transform *)r_dest;
+ dest->basis.set_axis(0, *x_axis);
+ dest->basis.set_axis(1, *y_axis);
+ dest->basis.set_axis(2, *z_axis);
+ dest->origin = *origin;
}
-void GDAPI godot_transform_new_with_basis(godot_transform *p_trans, const godot_basis *p_basis) {
- Transform *trans = (Transform *)p_trans;
+void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin) {
const Basis *basis = (const Basis *)p_basis;
- *trans = Transform(*basis);
+ const Vector3 *origin = (const Vector3 *)p_origin;
+ Transform *dest = (Transform *)r_dest;
+ *dest = Transform(*basis, *origin);
}
-void GDAPI godot_transform_new_with_basis_origin(godot_transform *p_trans, const godot_basis *p_basis, const godot_vector3 *p_origin) {
- Transform *trans = (Transform *)p_trans;
- const Basis *basis = (const Basis *)p_basis;
- const Vector3 *origin = (const Vector3 *)p_origin;
- *trans = Transform(*basis, *origin);
+godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self) {
+ godot_basis dest;
+ const Transform *self = (const Transform *)p_self;
+ *((Basis *)&dest) = self->basis;
+ return dest;
+}
+
+void GDAPI godot_transform_set_basis(godot_transform *p_self, godot_basis *p_v) {
+ Transform *self = (Transform *)p_self;
+ const Basis *v = (const Basis *)p_v;
+ self->basis = *v;
+}
+
+godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self) {
+ godot_vector3 dest;
+ const Transform *self = (const Transform *)p_self;
+ *((Vector3 *)&dest) = self->origin;
+ return dest;
+}
+
+void GDAPI godot_transform_set_origin(godot_transform *p_self, godot_vector3 *p_v) {
+ Transform *self = (Transform *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ self->origin = *v;
+}
+
+godot_string GDAPI godot_transform_as_string(const godot_transform *p_self) {
+ godot_string ret;
+ const Transform *self = (const Transform *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ *((Transform *)&dest) = self->inverse();
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ *((Transform *)&dest) = self->affine_inverse();
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ *((Transform *)&dest) = self->orthonormalized();
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ *((Transform *)&dest) = self->rotated(*axis, p_phi);
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *scale = (const Vector3 *)p_scale;
+ *((Transform *)&dest) = self->scaled(*scale);
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *ofs = (const Vector3 *)p_ofs;
+ *((Transform *)&dest) = self->translated(*ofs);
+ return dest;
+}
+
+godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up) {
+ godot_transform dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *target = (const Vector3 *)p_target;
+ const Vector3 *up = (const Vector3 *)p_up;
+ *((Transform *)&dest) = self->looking_at(*target, *up);
+ return dest;
+}
+
+godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v) {
+ godot_plane raw_dest;
+ Plane *dest = (Plane *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Plane *v = (const Plane *)p_v;
+ *dest = self->xform(*v);
+ return raw_dest;
+}
+
+godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v) {
+ godot_plane raw_dest;
+ Plane *dest = (Plane *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Plane *v = (const Plane *)p_v;
+ *dest = self->xform_inv(*v);
+ return raw_dest;
+}
+
+void GDAPI godot_transform_new_identity(godot_transform *r_dest) {
+ Transform *dest = (Transform *)r_dest;
+ *dest = Transform();
+}
+
+godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b) {
+ const Transform *self = (const Transform *)p_self;
+ const Transform *b = (const Transform *)p_b;
+ return *self == *b;
+}
+
+godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b) {
+ godot_transform raw_dest;
+ Transform *dest = (Transform *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Transform *b = (const Transform *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
+}
+
+godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ *dest = self->xform(*v);
+ return raw_dest;
+}
+
+godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Vector3 *v = (const Vector3 *)p_v;
+ *dest = self->xform_inv(*v);
+ return raw_dest;
}
-godot_basis GDAPI *godot_transform_get_basis(godot_transform *p_trans) {
- Transform *trans = (Transform *)p_trans;
- return (godot_basis *)&trans->basis;
+godot_rect3 GDAPI godot_transform_xform_rect3(const godot_transform *p_self, const godot_rect3 *p_v) {
+ godot_rect3 raw_dest;
+ Rect3 *dest = (Rect3 *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Rect3 *v = (const Rect3 *)p_v;
+ *dest = self->xform(*v);
+ return raw_dest;
}
-godot_vector3 GDAPI *godot_transform_get_origin(godot_transform *p_trans) {
- Transform *trans = (Transform *)p_trans;
- return (godot_vector3 *)&trans->origin;
+godot_rect3 GDAPI godot_transform_xform_inv_rect3(const godot_transform *p_self, const godot_rect3 *p_v) {
+ godot_rect3 raw_dest;
+ Rect3 *dest = (Rect3 *)&raw_dest;
+ const Transform *self = (const Transform *)p_self;
+ const Rect3 *v = (const Rect3 *)p_v;
+ *dest = self->xform_inv(*v);
+ return raw_dest;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_transform.h b/modules/gdnative/godot/godot_transform.h
index 93817ffbf2..ee87e1d33f 100644
--- a/modules/gdnative/godot/godot_transform.h
+++ b/modules/gdnative/godot/godot_transform.h
@@ -37,19 +37,59 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_TRANSFORM_TYPE_DEFINED
typedef struct godot_transform {
uint8_t _dont_touch_that[48];
} godot_transform;
#endif
#include "../godot.h"
+#include "godot_basis.h"
+#include "godot_variant.h"
+#include "godot_vector3.h"
-void GDAPI godot_transform_new(godot_transform *p_trans);
-void GDAPI godot_transform_new_with_basis(godot_transform *p_trans, const godot_basis *p_basis);
-void GDAPI godot_transform_new_with_basis_origin(godot_transform *p_trans, const godot_basis *p_basis, const godot_vector3 *p_origin);
+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);
+void GDAPI godot_transform_new(godot_transform *r_dest, const godot_basis *p_basis, const godot_vector3 *p_origin);
-godot_basis GDAPI *godot_transform_get_basis(godot_transform *p_trans);
-godot_vector3 GDAPI *godot_transform_get_origin(godot_transform *p_trans);
+godot_basis GDAPI godot_transform_get_basis(const godot_transform *p_self);
+void GDAPI godot_transform_set_basis(godot_transform *p_self, godot_basis *p_v);
+
+godot_vector3 GDAPI godot_transform_get_origin(const godot_transform *p_self);
+void GDAPI godot_transform_set_origin(godot_transform *p_self, godot_vector3 *p_v);
+
+godot_string GDAPI godot_transform_as_string(const godot_transform *p_self);
+
+godot_transform GDAPI godot_transform_inverse(const godot_transform *p_self);
+
+godot_transform GDAPI godot_transform_affine_inverse(const godot_transform *p_self);
+
+godot_transform GDAPI godot_transform_orthonormalized(const godot_transform *p_self);
+
+godot_transform GDAPI godot_transform_rotated(const godot_transform *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
+
+godot_transform GDAPI godot_transform_scaled(const godot_transform *p_self, const godot_vector3 *p_scale);
+
+godot_transform GDAPI godot_transform_translated(const godot_transform *p_self, const godot_vector3 *p_ofs);
+
+godot_transform GDAPI godot_transform_looking_at(const godot_transform *p_self, const godot_vector3 *p_target, const godot_vector3 *p_up);
+
+godot_plane GDAPI godot_transform_xform_plane(const godot_transform *p_self, const godot_plane *p_v);
+
+godot_plane GDAPI godot_transform_xform_inv_plane(const godot_transform *p_self, const godot_plane *p_v);
+
+void GDAPI godot_transform_new_identity(godot_transform *r_dest);
+
+godot_bool GDAPI godot_transform_operator_equal(const godot_transform *p_self, const godot_transform *p_b);
+
+godot_transform GDAPI godot_transform_operator_multiply(const godot_transform *p_self, const godot_transform *p_b);
+
+godot_vector3 GDAPI godot_transform_xform_vector3(const godot_transform *p_self, const godot_vector3 *p_v);
+
+godot_vector3 GDAPI godot_transform_xform_inv_vector3(const godot_transform *p_self, const godot_vector3 *p_v);
+
+godot_rect3 GDAPI godot_transform_xform_rect3(const godot_transform *p_self, const godot_rect3 *p_v);
+
+godot_rect3 GDAPI godot_transform_xform_inv_rect3(const godot_transform *p_self, const godot_rect3 *p_v);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_transform2d.cpp b/modules/gdnative/godot/godot_transform2d.cpp
index ffc7167559..bdb5476f7d 100644
--- a/modules/gdnative/godot/godot_transform2d.cpp
+++ b/modules/gdnative/godot/godot_transform2d.cpp
@@ -28,60 +28,182 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_transform2d.h"
+#include "core/variant.h"
-#include "../godot.h"
-
-#include "math/math_2d.h"
+#include "core/math/math_2d.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _transform2d_api_anchor() {
+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;
+ *dest = Transform2D(p_rot, *pos);
+}
+
+void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin) {
+ const Vector2 *x_axis = (const Vector2 *)p_x_axis;
+ const Vector2 *y_axis = (const Vector2 *)p_y_axis;
+ const Vector2 *origin = (const Vector2 *)p_origin;
+ Transform2D *dest = (Transform2D *)r_dest;
+ *dest = Transform2D(x_axis->x, x_axis->y, y_axis->x, y_axis->y, origin->x, origin->y);
+}
+
+godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self) {
+ godot_string ret;
+ const Transform2D *self = (const Transform2D *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
+}
+
+godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ *((Transform2D *)&dest) = self->inverse();
+ return dest;
+}
+
+godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ *((Transform2D *)&dest) = self->affine_inverse();
+ return dest;
+}
+
+godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self) {
+ const Transform2D *self = (const Transform2D *)p_self;
+ return self->get_rotation();
+}
+
+godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self) {
+ godot_vector2 dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ *((Vector2 *)&dest) = self->get_origin();
+ return dest;
+}
+
+godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self) {
+ godot_vector2 dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ *((Vector2 *)&dest) = self->get_scale();
+ return dest;
+}
+
+godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ *((Transform2D *)&dest) = self->orthonormalized();
+ return dest;
+}
+
+godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+
+ *((Transform2D *)&dest) = self->rotated(p_phi);
+ return dest;
+}
+
+godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *scale = (const Vector2 *)p_scale;
+ *((Transform2D *)&dest) = self->scaled(*scale);
+ return dest;
}
-void GDAPI godot_transform2d_new_identity(godot_transform2d *p_t) {
- Transform2D *t = (Transform2D *)p_t;
- *t = Transform2D();
+godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *offset = (const Vector2 *)p_offset;
+ *((Transform2D *)&dest) = self->translated(*offset);
+ return dest;
}
-void GDAPI godot_transform2d_new_elements(godot_transform2d *p_t, const godot_vector2 *p_a, const godot_vector2 *p_b, const godot_vector2 *p_c) {
- Transform2D *t = (Transform2D *)p_t;
- Vector2 *a = (Vector2 *)p_a;
- Vector2 *b = (Vector2 *)p_b;
- Vector2 *c = (Vector2 *)p_c;
- *t = Transform2D(a->x, a->y, b->x, b->y, c->x, c->y);
+godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *v = (const Vector2 *)p_v;
+ *dest = self->xform(*v);
+ return raw_dest;
}
-void GDAPI godot_transform2d_new(godot_transform2d *p_t, const godot_real p_rot, const godot_vector2 *p_pos) {
- Transform2D *t = (Transform2D *)p_t;
- Vector2 *pos = (Vector2 *)p_pos;
- *t = Transform2D(p_rot, *pos);
+godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *v = (const Vector2 *)p_v;
+ *dest = self->xform_inv(*v);
+ return raw_dest;
}
-godot_vector2 const GDAPI *godot_transform2d_const_index(const godot_transform2d *p_t, const godot_int p_idx) {
- const Transform2D *t = (const Transform2D *)p_t;
- const Vector2 *e = &t->operator[](p_idx);
- return (godot_vector2 const *)e;
+godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *v = (const Vector2 *)p_v;
+ *dest = self->basis_xform(*v);
+ return raw_dest;
}
-godot_vector2 GDAPI *godot_transform2d_index(godot_transform2d *p_t, const godot_int p_idx) {
- Transform2D *t = (Transform2D *)p_t;
- Vector2 *e = &t->operator[](p_idx);
- return (godot_vector2 *)e;
+godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Vector2 *v = (const Vector2 *)p_v;
+ *dest = self->basis_xform_inv(*v);
+ return raw_dest;
}
-godot_vector2 GDAPI godot_transform2d_get_axis(const godot_transform2d *p_t, const godot_int p_axis) {
- return *godot_transform2d_const_index(p_t, p_axis);
+godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c) {
+ godot_transform2d dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Transform2D *m = (const Transform2D *)p_m;
+ *((Transform2D *)&dest) = self->interpolate_with(*m, p_c);
+ return dest;
}
-void GDAPI godot_transform2d_set_axis(godot_transform2d *p_t, const godot_int p_axis, const godot_vector2 *p_vec) {
- godot_vector2 *origin_v = godot_transform2d_index(p_t, p_axis);
- *origin_v = *p_vec;
+godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b) {
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Transform2D *b = (const Transform2D *)p_b;
+ return *self == *b;
}
-// @Incomplete
-// See header file
+godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b) {
+ godot_transform2d raw_dest;
+ Transform2D *dest = (Transform2D *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Transform2D *b = (const Transform2D *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
+}
+
+void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest) {
+ Transform2D *dest = (Transform2D *)r_dest;
+ *dest = Transform2D();
+}
+
+godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) {
+ godot_rect2 raw_dest;
+ Rect2 *dest = (Rect2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Rect2 *v = (const Rect2 *)p_v;
+ *dest = self->xform(*v);
+ return raw_dest;
+}
+
+godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v) {
+ godot_rect2 raw_dest;
+ Rect2 *dest = (Rect2 *)&raw_dest;
+ const Transform2D *self = (const Transform2D *)p_self;
+ const Rect2 *v = (const Rect2 *)p_v;
+ *dest = self->xform_inv(*v);
+ return raw_dest;
+}
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_transform2d.h b/modules/gdnative/godot/godot_transform2d.h
index ae0569dbe8..c375e90af7 100644
--- a/modules/gdnative/godot/godot_transform2d.h
+++ b/modules/gdnative/godot/godot_transform2d.h
@@ -44,31 +44,51 @@ typedef struct godot_transform2d {
#endif
#include "../godot.h"
-
+#include "godot_variant.h"
#include "godot_vector2.h"
-void GDAPI godot_transform2d_new_identity(godot_transform2d *p_t);
-void GDAPI godot_transform2d_new_elements(godot_transform2d *p_t, const godot_vector2 *p_a, const godot_vector2 *p_b, const godot_vector2 *p_c);
-void GDAPI godot_transform2d_new(godot_transform2d *p_t, const godot_real p_rot, const godot_vector2 *p_pos);
+void GDAPI godot_transform2d_new(godot_transform2d *r_dest, const godot_real p_rot, const godot_vector2 *p_pos);
+void GDAPI godot_transform2d_new_axis_origin(godot_transform2d *r_dest, const godot_vector2 *p_x_axis, const godot_vector2 *p_y_axis, const godot_vector2 *p_origin);
+
+godot_string GDAPI godot_transform2d_as_string(const godot_transform2d *p_self);
+
+godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_self);
+
+godot_transform2d GDAPI godot_transform2d_affine_inverse(const godot_transform2d *p_self);
+
+godot_real GDAPI godot_transform2d_get_rotation(const godot_transform2d *p_self);
+
+godot_vector2 GDAPI godot_transform2d_get_origin(const godot_transform2d *p_self);
+
+godot_vector2 GDAPI godot_transform2d_get_scale(const godot_transform2d *p_self);
+
+godot_transform2d GDAPI godot_transform2d_orthonormalized(const godot_transform2d *p_self);
+
+godot_transform2d GDAPI godot_transform2d_rotated(const godot_transform2d *p_self, const godot_real p_phi);
+
+godot_transform2d GDAPI godot_transform2d_scaled(const godot_transform2d *p_self, const godot_vector2 *p_scale);
+
+godot_transform2d GDAPI godot_transform2d_translated(const godot_transform2d *p_self, const godot_vector2 *p_offset);
+
+godot_vector2 GDAPI godot_transform2d_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
+
+godot_vector2 GDAPI godot_transform2d_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
+
+godot_vector2 GDAPI godot_transform2d_basis_xform_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
+
+godot_vector2 GDAPI godot_transform2d_basis_xform_inv_vector2(const godot_transform2d *p_self, const godot_vector2 *p_v);
+
+godot_transform2d GDAPI godot_transform2d_interpolate_with(const godot_transform2d *p_self, const godot_transform2d *p_m, const godot_real p_c);
-/*
-godot_real GDAPI godot_transform2d_tdotx(const godot_transform2d *p_t, const godot_vector2 *p_v);
-godot_real GDAPI godot_transform2d_tdoty(const godot_transform2d *p_t, const godot_vector2 *p_v);
-*/
+godot_bool GDAPI godot_transform2d_operator_equal(const godot_transform2d *p_self, const godot_transform2d *p_b);
-godot_vector2 const GDAPI *godot_transform2d_const_index(const godot_transform2d *p_t, const godot_int p_idx);
-godot_vector2 GDAPI *godot_transform2d_index(godot_transform2d *p_t, const godot_int p_idx);
+godot_transform2d GDAPI godot_transform2d_operator_multiply(const godot_transform2d *p_self, const godot_transform2d *p_b);
-godot_vector2 GDAPI godot_transform2d_get_axis(const godot_transform2d *p_t, const godot_int p_axis);
-void GDAPI godot_transform2d_set_axis(godot_transform2d *p_t, const godot_int p_axis, const godot_vector2 *p_vec);
+void GDAPI godot_transform2d_new_identity(godot_transform2d *r_dest);
-/*
-void GDAPI godot_transform2d_invert(godot_transform2d *p_t);
-godot_transform2d GDAPI godot_transform2d_inverse(const godot_transform2d *p_t);
-*/
+godot_rect2 GDAPI godot_transform2d_xform_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v);
-// @Incomplete
-// I feel like it should be enough to expose get and set, the whole logic can be done in the bindings.
+godot_rect2 GDAPI godot_transform2d_xform_inv_rect2(const godot_transform2d *p_self, const godot_rect2 *p_v);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_variant.cpp b/modules/gdnative/godot/godot_variant.cpp
index 2214f85056..c9607fb21a 100644
--- a/modules/gdnative/godot/godot_variant.cpp
+++ b/modules/gdnative/godot/godot_variant.cpp
@@ -28,476 +28,452 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_variant.h"
-
-#include "../godot.h"
-
-#include "variant.h"
+#include "core/variant.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _variant_api_anchor() {
-}
+void _variant_api_anchor() {}
#define memnew_placement_custom(m_placement, m_class, m_constr) _post_initialize(new (m_placement, sizeof(m_class), "") m_constr)
-godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- return (godot_variant_type)v->get_type();
+// Constructors
+
+godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return (godot_variant_type)self->get_type();
}
-void GDAPI godot_variant_copy(godot_variant *p_dest, const godot_variant *p_src) {
+void GDAPI godot_variant_new_copy(godot_variant *p_dest, const godot_variant *p_src) {
Variant *dest = (Variant *)p_dest;
Variant *src = (Variant *)p_src;
- *dest = *src;
+ memnew_placement(dest, Variant(*src));
}
-void GDAPI godot_variant_new_nil(godot_variant *p_v) {
- Variant *v = (Variant *)p_v;
- memnew_placement(v, Variant);
+void GDAPI godot_variant_new_nil(godot_variant *r_dest) {
+ Variant *dest = (Variant *)r_dest;
+ memnew_placement(dest, Variant);
}
-void GDAPI godot_variant_new_bool(godot_variant *p_v, const godot_bool p_b) {
- Variant *v = (Variant *)p_v;
- memnew_placement_custom(v, Variant, Variant(p_b));
+void GDAPI godot_variant_new_bool(godot_variant *r_dest, const godot_bool p_b) {
+ Variant *dest = (Variant *)r_dest;
+ memnew_placement_custom(dest, Variant, Variant(p_b));
}
-void GDAPI godot_variant_new_uint(godot_variant *p_v, const uint64_t p_i) {
- Variant *v = (Variant *)p_v;
- memnew_placement_custom(v, Variant, Variant(p_i));
+void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i) {
+ Variant *dest = (Variant *)r_dest;
+ memnew_placement_custom(dest, Variant, Variant(p_i));
}
-void GDAPI godot_variant_new_int(godot_variant *p_v, const int64_t p_i) {
- Variant *v = (Variant *)p_v;
- memnew_placement_custom(v, Variant, Variant(p_i));
+void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i) {
+ Variant *dest = (Variant *)r_dest;
+ memnew_placement_custom(dest, Variant, Variant(p_i));
}
-void GDAPI godot_variant_new_real(godot_variant *p_v, const double p_r) {
- Variant *v = (Variant *)p_v;
- memnew_placement_custom(v, Variant, Variant(p_r));
+void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r) {
+ Variant *dest = (Variant *)r_dest;
+ memnew_placement_custom(dest, Variant, Variant(p_r));
}
-void GDAPI godot_variant_new_string(godot_variant *p_v, const godot_string *p_s) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s) {
+ Variant *dest = (Variant *)r_dest;
String *s = (String *)p_s;
- memnew_placement_custom(v, Variant, Variant(*s));
+ memnew_placement_custom(dest, Variant, Variant(*s));
}
-void GDAPI godot_variant_new_vector2(godot_variant *p_v, const godot_vector2 *p_v2) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2) {
+ Variant *dest = (Variant *)r_dest;
Vector2 *v2 = (Vector2 *)p_v2;
- memnew_placement_custom(v, Variant, Variant(*v2));
+ memnew_placement_custom(dest, Variant, Variant(*v2));
}
-void GDAPI godot_variant_new_rect2(godot_variant *p_v, const godot_rect2 *p_rect2) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2) {
+ Variant *dest = (Variant *)r_dest;
Rect2 *rect2 = (Rect2 *)p_rect2;
- memnew_placement_custom(v, Variant, Variant(*rect2));
+ memnew_placement_custom(dest, Variant, Variant(*rect2));
}
-void GDAPI godot_variant_new_vector3(godot_variant *p_v, const godot_vector3 *p_v3) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3) {
+ Variant *dest = (Variant *)r_dest;
Vector3 *v3 = (Vector3 *)p_v3;
- memnew_placement_custom(v, Variant, Variant(*v3));
+ memnew_placement_custom(dest, Variant, Variant(*v3));
}
-void GDAPI godot_variant_new_transform2d(godot_variant *p_v, const godot_transform2d *p_t2d) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d) {
+ Variant *dest = (Variant *)r_dest;
Transform2D *t2d = (Transform2D *)p_t2d;
- memnew_placement_custom(v, Variant, Variant(*t2d));
+ memnew_placement_custom(dest, Variant, Variant(*t2d));
}
-void GDAPI godot_variant_new_plane(godot_variant *p_v, const godot_plane *p_plane) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane) {
+ Variant *dest = (Variant *)r_dest;
Plane *plane = (Plane *)p_plane;
- memnew_placement_custom(v, Variant, Variant(*plane));
+ memnew_placement_custom(dest, Variant, Variant(*plane));
}
-void GDAPI godot_variant_new_quat(godot_variant *p_v, const godot_quat *p_quat) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat) {
+ Variant *dest = (Variant *)r_dest;
Quat *quat = (Quat *)p_quat;
- memnew_placement_custom(v, Variant, Variant(*quat));
+ memnew_placement_custom(dest, Variant, Variant(*quat));
}
-void GDAPI godot_variant_new_rect3(godot_variant *p_v, const godot_rect3 *p_rect3) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_rect3(godot_variant *r_dest, const godot_rect3 *p_rect3) {
+ Variant *dest = (Variant *)r_dest;
Rect3 *rect3 = (Rect3 *)p_rect3;
- memnew_placement_custom(v, Variant, Variant(*rect3));
+ memnew_placement_custom(dest, Variant, Variant(*rect3));
}
-void GDAPI godot_variant_new_basis(godot_variant *p_v, const godot_basis *p_basis) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis) {
+ Variant *dest = (Variant *)r_dest;
Basis *basis = (Basis *)p_basis;
- memnew_placement_custom(v, Variant, Variant(*basis));
+ memnew_placement_custom(dest, Variant, Variant(*basis));
}
-void GDAPI godot_variant_new_transform(godot_variant *p_v, const godot_transform *p_trans) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans) {
+ Variant *dest = (Variant *)r_dest;
Transform *trans = (Transform *)p_trans;
- memnew_placement_custom(v, Variant, Variant(*trans));
+ memnew_placement_custom(dest, Variant, Variant(*trans));
}
-void GDAPI godot_variant_new_color(godot_variant *p_v, const godot_color *p_color) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color) {
+ Variant *dest = (Variant *)r_dest;
Color *color = (Color *)p_color;
- memnew_placement_custom(v, Variant, Variant(*color));
+ memnew_placement_custom(dest, Variant, Variant(*color));
}
-void GDAPI godot_variant_new_image(godot_variant *p_v, const godot_image *p_img) {
- Variant *v = (Variant *)p_v;
- Image *img = (Image *)p_img;
- memnew_placement_custom(v, Variant, Variant(*img));
-}
-
-void GDAPI godot_variant_new_node_path(godot_variant *p_v, const godot_node_path *p_np) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np) {
+ Variant *dest = (Variant *)r_dest;
NodePath *np = (NodePath *)p_np;
- memnew_placement_custom(v, Variant, Variant(*np));
+ memnew_placement_custom(dest, Variant, Variant(*np));
}
-void GDAPI godot_variant_new_rid(godot_variant *p_v, const godot_rid *p_rid) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid) {
+ Variant *dest = (Variant *)r_dest;
RID *rid = (RID *)p_rid;
- memnew_placement_custom(v, Variant, Variant(*rid));
+ memnew_placement_custom(dest, Variant, Variant(*rid));
}
-void GDAPI godot_variant_new_object(godot_variant *p_v, const godot_object *p_obj) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj) {
+ Variant *dest = (Variant *)r_dest;
Object *obj = (Object *)p_obj;
- memnew_placement_custom(v, Variant, Variant(obj));
-}
-
-void GDAPI godot_variant_new_input_event(godot_variant *p_v, const godot_input_event *p_event) {
- Variant *v = (Variant *)p_v;
- InputEvent *event = (InputEvent *)p_event;
- memnew_placement_custom(v, Variant, Variant(*event));
+ memnew_placement_custom(dest, Variant, Variant(obj));
}
-void GDAPI godot_variant_new_dictionary(godot_variant *p_v, const godot_dictionary *p_dict) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict) {
+ Variant *dest = (Variant *)r_dest;
Dictionary *dict = (Dictionary *)p_dict;
- memnew_placement_custom(v, Variant, Variant(*dict));
+ memnew_placement_custom(dest, Variant, Variant(*dict));
}
-void GDAPI godot_variant_new_array(godot_variant *p_v, const godot_array *p_arr) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr) {
+ Variant *dest = (Variant *)r_dest;
Array *arr = (Array *)p_arr;
- memnew_placement_custom(v, Variant, Variant(*arr));
+ memnew_placement_custom(dest, Variant, Variant(*arr));
}
-void GDAPI godot_variant_new_pool_byte_array(godot_variant *p_v, const godot_pool_byte_array *p_pba) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_byte_array(godot_variant *r_dest, const godot_pool_byte_array *p_pba) {
+ Variant *dest = (Variant *)r_dest;
PoolByteArray *pba = (PoolByteArray *)p_pba;
- memnew_placement_custom(v, Variant, Variant(*pba));
+ memnew_placement_custom(dest, Variant, Variant(*pba));
}
-void GDAPI godot_variant_new_pool_int_array(godot_variant *p_v, const godot_pool_int_array *p_pia) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_int_array(godot_variant *r_dest, const godot_pool_int_array *p_pia) {
+ Variant *dest = (Variant *)r_dest;
PoolIntArray *pia = (PoolIntArray *)p_pia;
- memnew_placement_custom(v, Variant, Variant(*pia));
+ memnew_placement_custom(dest, Variant, Variant(*pia));
}
-void GDAPI godot_variant_new_pool_real_array(godot_variant *p_v, const godot_pool_real_array *p_pra) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_real_array(godot_variant *r_dest, const godot_pool_real_array *p_pra) {
+ Variant *dest = (Variant *)r_dest;
PoolRealArray *pra = (PoolRealArray *)p_pra;
- memnew_placement_custom(v, Variant, Variant(*pra));
+ memnew_placement_custom(dest, Variant, Variant(*pra));
}
-void GDAPI godot_variant_new_pool_string_array(godot_variant *p_v, const godot_pool_string_array *p_psa) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_string_array(godot_variant *r_dest, const godot_pool_string_array *p_psa) {
+ Variant *dest = (Variant *)r_dest;
PoolStringArray *psa = (PoolStringArray *)p_psa;
- memnew_placement_custom(v, Variant, Variant(*psa));
+ memnew_placement_custom(dest, Variant, Variant(*psa));
}
-void GDAPI godot_variant_new_pool_vector2_array(godot_variant *p_v, const godot_pool_vector2_array *p_pv2a) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_vector2_array(godot_variant *r_dest, const godot_pool_vector2_array *p_pv2a) {
+ Variant *dest = (Variant *)r_dest;
PoolVector2Array *pv2a = (PoolVector2Array *)p_pv2a;
- memnew_placement_custom(v, Variant, Variant(*pv2a));
+ memnew_placement_custom(dest, Variant, Variant(*pv2a));
}
-void GDAPI godot_variant_new_pool_vector3_array(godot_variant *p_v, const godot_pool_vector3_array *p_pv3a) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_vector3_array(godot_variant *r_dest, const godot_pool_vector3_array *p_pv3a) {
+ Variant *dest = (Variant *)r_dest;
PoolVector3Array *pv3a = (PoolVector3Array *)p_pv3a;
- memnew_placement_custom(v, Variant, Variant(*pv3a));
+ memnew_placement_custom(dest, Variant, Variant(*pv3a));
}
-void GDAPI godot_variant_new_pool_color_array(godot_variant *p_v, const godot_pool_color_array *p_pca) {
- Variant *v = (Variant *)p_v;
+void GDAPI godot_variant_new_pool_color_array(godot_variant *r_dest, const godot_pool_color_array *p_pca) {
+ Variant *dest = (Variant *)r_dest;
PoolColorArray *pca = (PoolColorArray *)p_pca;
- memnew_placement_custom(v, Variant, Variant(*pca));
+ memnew_placement_custom(dest, Variant, Variant(*pca));
}
-godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- return v->operator bool();
+godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->operator bool();
}
-uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- return v->operator uint64_t();
+uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->operator uint64_t();
}
-int64_t GDAPI godot_variant_as_int(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- return v->operator int64_t();
+int64_t GDAPI godot_variant_as_int(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->operator int64_t();
}
-double GDAPI godot_variant_as_real(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- return v->operator double();
+double GDAPI godot_variant_as_real(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ return self->operator double();
}
-godot_string GDAPI godot_variant_as_string(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_string s;
- godot_string_new(&s);
- String *str = (String *)&s;
- *str = v->operator String();
- return s;
+godot_string GDAPI godot_variant_as_string(const godot_variant *p_self) {
+ godot_string raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ String *dest = (String *)&raw_dest;
+ memnew_placement(dest, String(self->operator String())); // operator = is overloaded by String
+ return raw_dest;
}
-godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_vector2 v2;
- Vector2 *vec2 = (Vector2 *)&v2;
- *vec2 = *v;
- return v2;
+godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self) {
+ godot_vector2 raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_rect2 r2;
- Rect2 *rect2 = (Rect2 *)&r2;
- *rect2 = *v;
- return r2;
+godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self) {
+ godot_rect2 raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Rect2 *dest = (Rect2 *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_vector3 v3;
- Vector3 *vec3 = (Vector3 *)&v3;
- *vec3 = *v;
- return v3;
+godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self) {
+ godot_vector3 raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_transform2d t2;
- Transform2D *t = (Transform2D *)&t2;
- *t = *v;
- return t2;
+godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self) {
+ godot_transform2d raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Transform2D *dest = (Transform2D *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_plane p;
- Plane *pl = (Plane *)&p;
- *pl = *v;
- return p;
+godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self) {
+ godot_plane raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Plane *dest = (Plane *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_quat q;
- Quat *qt = (Quat *)&q;
- *qt = *v;
- return q;
+godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self) {
+ godot_quat raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Quat *dest = (Quat *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_rect3 r;
- Rect3 *r3 = (Rect3 *)&r;
- *r3 = *v;
- return r;
+godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_self) {
+ godot_rect3 raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Rect3 *dest = (Rect3 *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_basis b;
- Basis *bs = (Basis *)&b;
- *bs = *v;
- return b;
+godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self) {
+ godot_basis raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Basis *dest = (Basis *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_transform t;
- Transform *tr = (Transform *)&t;
- *tr = *v;
- return t;
+godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self) {
+ godot_transform raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Transform *dest = (Transform *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_color GDAPI godot_variant_as_color(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_color c;
- Color *col = (Color *)&c;
- *col = *v;
- return c;
+godot_color GDAPI godot_variant_as_color(const godot_variant *p_self) {
+ godot_color raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Color *dest = (Color *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
}
-godot_image GDAPI godot_variant_as_image(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_image img;
- godot_image_new(&img);
- Image *i = (Image *)&img;
- *i = *v;
- return img;
-}
-
-godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_node_path np;
- memnew_placement_custom((NodePath *)&np, NodePath, NodePath((String)*v));
- return np;
-}
-
-godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_rid rid;
- memnew_placement_custom((RID *)&rid, RID, RID(*v));
- return rid;
-}
-
-godot_object GDAPI *godot_variant_as_object(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_object *p = NULL;
- Object **op = (Object **)&p;
- *op = *v;
- return p;
-}
-
-godot_input_event GDAPI godot_variant_as_input_event(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_input_event ev;
- InputEvent *event = (InputEvent *)&ev;
- *event = *v;
- return ev;
-}
-
-godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_dictionary dict;
- godot_dictionary_new(&dict);
- Dictionary *d = (Dictionary *)&dict;
- *d = *v;
- return dict;
-}
-
-godot_array GDAPI godot_variant_as_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_array array;
- godot_array_new(&array);
- Array *a = (Array *)&array;
- *a = *v;
- return array;
-}
-
-godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_byte_array pba;
- godot_pool_byte_array_new(&pba);
- PoolByteArray *p = (PoolByteArray *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_int_array pba;
- godot_pool_int_array_new(&pba);
- PoolIntArray *p = (PoolIntArray *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_real_array pba;
- godot_pool_real_array_new(&pba);
- PoolRealArray *p = (PoolRealArray *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_string_array pba;
- godot_pool_string_array_new(&pba);
- PoolStringArray *p = (PoolStringArray *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_vector2_array pba;
- godot_pool_vector2_array_new(&pba);
- PoolVector2Array *p = (PoolVector2Array *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_vector3_array pba;
- godot_pool_vector3_array_new(&pba);
- PoolVector3Array *p = (PoolVector3Array *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_v) {
- const Variant *v = (const Variant *)p_v;
- godot_pool_color_array pba;
- godot_pool_color_array_new(&pba);
- PoolColorArray *p = (PoolColorArray *)&pba;
- *p = *v;
- return pba;
-}
-
-godot_variant GDAPI godot_variant_call(godot_variant *p_v, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount /*, godot_variant_call_error *r_error */) {
- Variant *v = (Variant *)p_v;
- String *method = (String *)p_method;
- Variant **args = (Variant **)p_args;
- godot_variant res;
- memnew_placement_custom((Variant *)&res, Variant, Variant(v->call(*method, args, p_argcount)));
- return res;
+godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self) {
+ godot_node_path raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ NodePath *dest = (NodePath *)&raw_dest;
+ memnew_placement(dest, NodePath(self->operator NodePath())); // operator = is overloaded by NodePath
+ return raw_dest;
+}
+
+godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self) {
+ godot_rid raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ RID *dest = (RID *)&raw_dest;
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self) {
+ const Variant *self = (const Variant *)p_self;
+ Object *dest;
+ dest = *self;
+ return (godot_object *)dest;
+}
+
+godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self) {
+ godot_dictionary raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Dictionary *dest = (Dictionary *)&raw_dest;
+ memnew_placement(dest, Dictionary(self->operator Dictionary())); // operator = is overloaded by Dictionary
+ return raw_dest;
+}
+
+godot_array GDAPI godot_variant_as_array(const godot_variant *p_self) {
+ godot_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ Array *dest = (Array *)&raw_dest;
+ memnew_placement(dest, Array(self->operator Array())); // operator = is overloaded by Array
+ return raw_dest;
+}
+
+godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_self) {
+ godot_pool_byte_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolByteArray *dest = (PoolByteArray *)&raw_dest;
+ memnew_placement(dest, PoolByteArray(self->operator PoolByteArray())); // operator = is overloaded by PoolByteArray
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_self) {
+ godot_pool_int_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolIntArray *dest = (PoolIntArray *)&raw_dest;
+ memnew_placement(dest, PoolIntArray(self->operator PoolIntArray())); // operator = is overloaded by PoolIntArray
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_self) {
+ godot_pool_real_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolRealArray *dest = (PoolRealArray *)&raw_dest;
+ memnew_placement(dest, PoolRealArray(self->operator PoolRealArray())); // operator = is overloaded by PoolRealArray
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_self) {
+ godot_pool_string_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolStringArray *dest = (PoolStringArray *)&raw_dest;
+ memnew_placement(dest, PoolStringArray(self->operator PoolStringArray())); // operator = is overloaded by PoolStringArray
+ *dest = *self;
+ return raw_dest;
}
-godot_bool GDAPI godot_variant_has_method(godot_variant *p_v, const godot_string *p_method) {
- Variant *v = (Variant *)p_v;
+godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_self) {
+ godot_pool_vector2_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolVector2Array *dest = (PoolVector2Array *)&raw_dest;
+ memnew_placement(dest, PoolVector2Array(self->operator PoolVector2Array())); // operator = is overloaded by PoolVector2Array
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_self) {
+ godot_pool_vector3_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolVector3Array *dest = (PoolVector3Array *)&raw_dest;
+ memnew_placement(dest, PoolVector3Array(self->operator PoolVector3Array())); // operator = is overloaded by PoolVector3Array
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_self) {
+ godot_pool_color_array raw_dest;
+ const Variant *self = (const Variant *)p_self;
+ PoolColorArray *dest = (PoolColorArray *)&raw_dest;
+ memnew_placement(dest, PoolColorArray(self->operator PoolColorArray())); // operator = is overloaded by PoolColorArray
+ *dest = *self;
+ return raw_dest;
+}
+
+godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error) {
+ Variant *self = (Variant *)p_self;
String *method = (String *)p_method;
- return v->has_method(*method);
+ const Variant **args = (const Variant **)p_args;
+ godot_variant raw_dest;
+ Variant *dest = (Variant *)&raw_dest;
+ Variant::CallError error;
+ memnew_placement_custom(dest, Variant, Variant(self->call(*method, args, p_argcount, error)));
+ *dest = self->call(StringName(*method), args, p_argcount, r_error);
+ if (r_error) {
+ r_error->error = (godot_variant_call_error_error)error.error;
+ r_error->argument = error.argument;
+ r_error->expected = (godot_variant_type)error.expected;
+ }
+ return raw_dest;
+}
+
+godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method) {
+ const Variant *self = (const Variant *)p_self;
+ const String *method = (const String *)p_method;
+ return self->has_method(*method);
}
-godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_a, const godot_variant *p_b) {
- const Variant *a = (const Variant *)p_a;
- const Variant *b = (const Variant *)p_b;
- return a->operator==(*b);
+godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other) {
+ const Variant *self = (const Variant *)p_self;
+ const Variant *other = (const Variant *)p_other;
+ return self->operator==(*other);
}
-godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_a, const godot_variant *p_b) {
- const Variant *a = (const Variant *)p_a;
- const Variant *b = (const Variant *)p_b;
- return a->operator<(*b);
+godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other) {
+ const Variant *self = (const Variant *)p_self;
+ const Variant *other = (const Variant *)p_other;
+ return self->operator<(*other);
}
-godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_a, const godot_variant *p_b) {
- const Variant *a = (const Variant *)p_a;
- const Variant *b = (const Variant *)p_b;
- return a->hash_compare(*b);
+godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other) {
+ const Variant *self = (const Variant *)p_self;
+ const Variant *other = (const Variant *)p_other;
+ return self->hash_compare(*other);
}
-godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_v, godot_bool *p_valid) {
- const Variant *v = (const Variant *)p_v;
- bool &valid = *p_valid;
- return v->booleanize(valid);
+godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self, godot_bool *r_valid) {
+ const Variant *self = (const Variant *)p_self;
+ bool &valid = *r_valid;
+ return self->booleanize(valid);
}
-void GDAPI godot_variant_destroy(godot_variant *p_v) {
- ((Variant *)p_v)->~Variant();
+void GDAPI godot_variant_destroy(godot_variant *p_self) {
+ Variant *self = (Variant *)p_self;
+ self->~Variant();
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_variant.h b/modules/gdnative/godot/godot_variant.h
index 6f98b32363..9b6d287249 100644
--- a/modules/gdnative/godot/godot_variant.h
+++ b/modules/gdnative/godot/godot_variant.h
@@ -42,16 +42,6 @@ typedef struct godot_variant {
} godot_variant;
#endif
-struct godot_transform2d;
-typedef struct godot_transform2d godot_transform2d;
-
-#include "godot_array.h"
-#include "godot_dictionary.h"
-#include "godot_input_event.h"
-#include "godot_node_path.h"
-#include "godot_rid.h"
-#include "godot_transform2d.h"
-
typedef enum godot_variant_type {
GODOT_VARIANT_TYPE_NIL,
@@ -69,108 +59,137 @@ typedef enum godot_variant_type {
GODOT_VARIANT_TYPE_TRANSFORM2D,
GODOT_VARIANT_TYPE_PLANE,
GODOT_VARIANT_TYPE_QUAT, // 10
- GODOT_VARIANT_TYPE_RECT3, //sorry naming convention fail :( not like it's used often
+ GODOT_VARIANT_TYPE_RECT3,
GODOT_VARIANT_TYPE_BASIS,
GODOT_VARIANT_TYPE_TRANSFORM,
// misc types
GODOT_VARIANT_TYPE_COLOR,
- GODOT_VARIANT_TYPE_IMAGE, // 15
- GODOT_VARIANT_TYPE_NODE_PATH,
+ GODOT_VARIANT_TYPE_NODE_PATH, // 15
GODOT_VARIANT_TYPE_RID,
GODOT_VARIANT_TYPE_OBJECT,
- GODOT_VARIANT_TYPE_INPUT_EVENT,
- GODOT_VARIANT_TYPE_DICTIONARY, // 20
- GODOT_VARIANT_TYPE_ARRAY,
+ GODOT_VARIANT_TYPE_DICTIONARY,
+ GODOT_VARIANT_TYPE_ARRAY, // 20
// arrays
GODOT_VARIANT_TYPE_POOL_BYTE_ARRAY,
GODOT_VARIANT_TYPE_POOL_INT_ARRAY,
GODOT_VARIANT_TYPE_POOL_REAL_ARRAY,
- GODOT_VARIANT_TYPE_POOL_STRING_ARRAY, // 25
- GODOT_VARIANT_TYPE_POOL_VECTOR2_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_STRING_ARRAY,
+ GODOT_VARIANT_TYPE_POOL_VECTOR2_ARRAY, // 25
GODOT_VARIANT_TYPE_POOL_VECTOR3_ARRAY,
GODOT_VARIANT_TYPE_POOL_COLOR_ARRAY,
} godot_variant_type;
+typedef enum godot_variant_call_error_error {
+ GODOT_CALL_ERROR_CALL_OK,
+ GODOT_CALL_ERROR_CALL_ERROR_INVALID_METHOD,
+ GODOT_CALL_ERROR_CALL_ERROR_INVALID_ARGUMENT,
+ GODOT_CALL_ERROR_CALL_ERROR_TOO_MANY_ARGUMENTS,
+ GODOT_CALL_ERROR_CALL_ERROR_TOO_FEW_ARGUMENTS,
+ GODOT_CALL_ERROR_CALL_ERROR_INSTANCE_IS_NULL,
+} godot_variant_call_error_error;
+
+typedef struct godot_variant_call_error {
+ godot_variant_call_error_error error;
+ int argument;
+ godot_variant_type expected;
+} godot_variant_call_error;
+
+#include "godot_array.h"
+#include "godot_basis.h"
+#include "godot_color.h"
+#include "godot_dictionary.h"
+#include "godot_node_path.h"
+#include "godot_plane.h"
+#include "godot_pool_arrays.h"
+#include "godot_quat.h"
+#include "godot_rect2.h"
+#include "godot_rect3.h"
+#include "godot_rid.h"
+#include "godot_string.h"
+#include "godot_transform.h"
+#include "godot_transform2d.h"
+#include "godot_variant.h"
+#include "godot_vector2.h"
+#include "godot_vector3.h"
+
+#include "../godot.h"
+
godot_variant_type GDAPI godot_variant_get_type(const godot_variant *p_v);
-void GDAPI godot_variant_copy(godot_variant *p_dest, const godot_variant *p_src);
+void GDAPI godot_variant_new_copy(godot_variant *r_dest, const godot_variant *p_src);
-void GDAPI godot_variant_new_nil(godot_variant *p_v);
+void GDAPI godot_variant_new_nil(godot_variant *r_dest);
void GDAPI godot_variant_new_bool(godot_variant *p_v, const godot_bool p_b);
-void GDAPI godot_variant_new_uint(godot_variant *p_v, const uint64_t p_i);
-void GDAPI godot_variant_new_int(godot_variant *p_v, const int64_t p_i);
-void GDAPI godot_variant_new_real(godot_variant *p_v, const double p_r);
-void GDAPI godot_variant_new_string(godot_variant *p_v, const godot_string *p_s);
-void GDAPI godot_variant_new_vector2(godot_variant *p_v, const godot_vector2 *p_v2);
-void GDAPI godot_variant_new_rect2(godot_variant *p_v, const godot_rect2 *p_rect2);
-void GDAPI godot_variant_new_vector3(godot_variant *p_v, const godot_vector3 *p_v3);
-void GDAPI godot_variant_new_transform2d(godot_variant *p_v, const godot_transform2d *p_t2d);
-void GDAPI godot_variant_new_plane(godot_variant *p_v, const godot_plane *p_plane);
-void GDAPI godot_variant_new_quat(godot_variant *p_v, const godot_quat *p_quat);
-void GDAPI godot_variant_new_rect3(godot_variant *p_v, const godot_rect3 *p_rect3);
-void GDAPI godot_variant_new_basis(godot_variant *p_v, const godot_basis *p_basis);
-void GDAPI godot_variant_new_transform(godot_variant *p_v, const godot_transform *p_trans);
-void GDAPI godot_variant_new_color(godot_variant *p_v, const godot_color *p_color);
-void GDAPI godot_variant_new_image(godot_variant *p_v, const godot_image *p_img);
-void GDAPI godot_variant_new_node_path(godot_variant *p_v, const godot_node_path *p_np);
-void GDAPI godot_variant_new_rid(godot_variant *p_v, const godot_rid *p_rid);
-void GDAPI godot_variant_new_object(godot_variant *p_v, const godot_object *p_obj);
-void GDAPI godot_variant_new_input_event(godot_variant *p_v, const godot_input_event *p_event);
-void GDAPI godot_variant_new_dictionary(godot_variant *p_v, const godot_dictionary *p_dict);
-void GDAPI godot_variant_new_array(godot_variant *p_v, const godot_array *p_arr);
-void GDAPI godot_variant_new_pool_byte_array(godot_variant *p_v, const godot_pool_byte_array *p_pba);
-void GDAPI godot_variant_new_pool_int_array(godot_variant *p_v, const godot_pool_int_array *p_pia);
-void GDAPI godot_variant_new_pool_real_array(godot_variant *p_v, const godot_pool_real_array *p_pra);
-void GDAPI godot_variant_new_pool_string_array(godot_variant *p_v, const godot_pool_string_array *p_psa);
-void GDAPI godot_variant_new_pool_vector2_array(godot_variant *p_v, const godot_pool_vector2_array *p_pv2a);
-void GDAPI godot_variant_new_pool_vector3_array(godot_variant *p_v, const godot_pool_vector3_array *p_pv3a);
-void GDAPI godot_variant_new_pool_color_array(godot_variant *p_v, const godot_pool_color_array *p_pca);
-
-godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_v);
-uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_v);
-int64_t GDAPI godot_variant_as_int(const godot_variant *p_v);
-double GDAPI godot_variant_as_real(const godot_variant *p_v);
-godot_string GDAPI godot_variant_as_string(const godot_variant *p_v);
-godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_v);
-godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_v);
-godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_v);
-godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_v);
-godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_v);
-godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_v);
-godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_v);
-godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_v);
-godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_v);
-godot_color GDAPI godot_variant_as_color(const godot_variant *p_v);
-godot_image GDAPI godot_variant_as_image(const godot_variant *p_v);
-godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_v);
-godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_v);
-godot_object GDAPI *godot_variant_as_object(const godot_variant *p_v);
-godot_input_event GDAPI godot_variant_as_input_event(const godot_variant *p_v);
-godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_v);
-godot_array GDAPI godot_variant_as_array(const godot_variant *p_v);
-godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_v);
-godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_v);
-godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_v);
-godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_v);
-godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_v);
-godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_v);
-godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_v);
-
-godot_variant GDAPI godot_variant_call(godot_variant *p_v, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount /*, godot_variant_call_error *r_error */);
-
-godot_bool GDAPI godot_variant_has_method(godot_variant *p_v, const godot_string *p_method);
-
-godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_a, const godot_variant *p_b);
-godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_a, const godot_variant *p_b);
-
-godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_a, const godot_variant *p_b);
-
-godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_v, godot_bool *p_valid);
-
-void GDAPI godot_variant_destroy(godot_variant *p_v);
+void GDAPI godot_variant_new_uint(godot_variant *r_dest, const uint64_t p_i);
+void GDAPI godot_variant_new_int(godot_variant *r_dest, const int64_t p_i);
+void GDAPI godot_variant_new_real(godot_variant *r_dest, const double p_r);
+void GDAPI godot_variant_new_string(godot_variant *r_dest, const godot_string *p_s);
+void GDAPI godot_variant_new_vector2(godot_variant *r_dest, const godot_vector2 *p_v2);
+void GDAPI godot_variant_new_rect2(godot_variant *r_dest, const godot_rect2 *p_rect2);
+void GDAPI godot_variant_new_vector3(godot_variant *r_dest, const godot_vector3 *p_v3);
+void GDAPI godot_variant_new_transform2d(godot_variant *r_dest, const godot_transform2d *p_t2d);
+void GDAPI godot_variant_new_plane(godot_variant *r_dest, const godot_plane *p_plane);
+void GDAPI godot_variant_new_quat(godot_variant *r_dest, const godot_quat *p_quat);
+void GDAPI godot_variant_new_rect3(godot_variant *r_dest, const godot_rect3 *p_rect3);
+void GDAPI godot_variant_new_basis(godot_variant *r_dest, const godot_basis *p_basis);
+void GDAPI godot_variant_new_transform(godot_variant *r_dest, const godot_transform *p_trans);
+void GDAPI godot_variant_new_color(godot_variant *r_dest, const godot_color *p_color);
+void GDAPI godot_variant_new_node_path(godot_variant *r_dest, const godot_node_path *p_np);
+void GDAPI godot_variant_new_rid(godot_variant *r_dest, const godot_rid *p_rid);
+void GDAPI godot_variant_new_object(godot_variant *r_dest, const godot_object *p_obj);
+void GDAPI godot_variant_new_dictionary(godot_variant *r_dest, const godot_dictionary *p_dict);
+void GDAPI godot_variant_new_array(godot_variant *r_dest, const godot_array *p_arr);
+void GDAPI godot_variant_new_pool_byte_array(godot_variant *r_dest, const godot_pool_byte_array *p_pba);
+void GDAPI godot_variant_new_pool_int_array(godot_variant *r_dest, const godot_pool_int_array *p_pia);
+void GDAPI godot_variant_new_pool_real_array(godot_variant *r_dest, const godot_pool_real_array *p_pra);
+void GDAPI godot_variant_new_pool_string_array(godot_variant *r_dest, const godot_pool_string_array *p_psa);
+void GDAPI godot_variant_new_pool_vector2_array(godot_variant *r_dest, const godot_pool_vector2_array *p_pv2a);
+void GDAPI godot_variant_new_pool_vector3_array(godot_variant *r_dest, const godot_pool_vector3_array *p_pv3a);
+void GDAPI godot_variant_new_pool_color_array(godot_variant *r_dest, const godot_pool_color_array *p_pca);
+
+godot_bool GDAPI godot_variant_as_bool(const godot_variant *p_self);
+uint64_t GDAPI godot_variant_as_uint(const godot_variant *p_self);
+int64_t GDAPI godot_variant_as_int(const godot_variant *p_self);
+double GDAPI godot_variant_as_real(const godot_variant *p_self);
+godot_string GDAPI godot_variant_as_string(const godot_variant *p_self);
+godot_vector2 GDAPI godot_variant_as_vector2(const godot_variant *p_self);
+godot_rect2 GDAPI godot_variant_as_rect2(const godot_variant *p_self);
+godot_vector3 GDAPI godot_variant_as_vector3(const godot_variant *p_self);
+godot_transform2d GDAPI godot_variant_as_transform2d(const godot_variant *p_self);
+godot_plane GDAPI godot_variant_as_plane(const godot_variant *p_self);
+godot_quat GDAPI godot_variant_as_quat(const godot_variant *p_self);
+godot_rect3 GDAPI godot_variant_as_rect3(const godot_variant *p_self);
+godot_basis GDAPI godot_variant_as_basis(const godot_variant *p_self);
+godot_transform GDAPI godot_variant_as_transform(const godot_variant *p_self);
+godot_color GDAPI godot_variant_as_color(const godot_variant *p_self);
+godot_node_path GDAPI godot_variant_as_node_path(const godot_variant *p_self);
+godot_rid GDAPI godot_variant_as_rid(const godot_variant *p_self);
+godot_object GDAPI *godot_variant_as_object(const godot_variant *p_self);
+godot_dictionary GDAPI godot_variant_as_dictionary(const godot_variant *p_self);
+godot_array GDAPI godot_variant_as_array(const godot_variant *p_self);
+godot_pool_byte_array GDAPI godot_variant_as_pool_byte_array(const godot_variant *p_self);
+godot_pool_int_array GDAPI godot_variant_as_pool_int_array(const godot_variant *p_self);
+godot_pool_real_array GDAPI godot_variant_as_pool_real_array(const godot_variant *p_self);
+godot_pool_string_array GDAPI godot_variant_as_pool_string_array(const godot_variant *p_self);
+godot_pool_vector2_array GDAPI godot_variant_as_pool_vector2_array(const godot_variant *p_self);
+godot_pool_vector3_array GDAPI godot_variant_as_pool_vector3_array(const godot_variant *p_self);
+godot_pool_color_array GDAPI godot_variant_as_pool_color_array(const godot_variant *p_self);
+
+godot_variant GDAPI godot_variant_call(godot_variant *p_self, const godot_string *p_method, const godot_variant **p_args, const godot_int p_argcount, godot_variant_call_error *r_error);
+
+godot_bool GDAPI godot_variant_has_method(const godot_variant *p_self, const godot_string *p_method);
+
+godot_bool GDAPI godot_variant_operator_equal(const godot_variant *p_self, const godot_variant *p_other);
+godot_bool GDAPI godot_variant_operator_less(const godot_variant *p_self, const godot_variant *p_other);
+
+godot_bool GDAPI godot_variant_hash_compare(const godot_variant *p_self, const godot_variant *p_other);
+
+godot_bool GDAPI godot_variant_booleanize(const godot_variant *p_self, godot_bool *r_valid);
+
+void GDAPI godot_variant_destroy(godot_variant *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_vector2.cpp b/modules/gdnative/godot/godot_vector2.cpp
index 87e60b6245..0ced800872 100644
--- a/modules/gdnative/godot/godot_vector2.cpp
+++ b/modules/gdnative/godot/godot_vector2.cpp
@@ -28,8 +28,9 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_vector2.h"
+#include "core/variant.h"
-#include "math/math_2d.h"
+#include "core/math/math_2d.h"
#ifdef __cplusplus
extern "C" {
@@ -37,258 +38,258 @@ extern "C" {
void _vector2_api_anchor() {}
-godot_vector2 GDAPI godot_vector2_new(const godot_real p_x, const godot_real p_y) {
- godot_vector2 value;
- Vector2 *v = (Vector2 *)&value;
- v->x = p_x;
- v->y = p_y;
- return value;
+void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y) {
+
+ Vector2 *dest = (Vector2 *)r_dest;
+ *dest = Vector2(p_x, p_y);
}
-void GDAPI godot_vector2_set_x(godot_vector2 *p_v, const godot_real p_x) {
- Vector2 *v = (Vector2 *)p_v;
- v->x = p_x;
+godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self) {
+ godot_string ret;
+ const Vector2 *self = (const Vector2 *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
}
-void GDAPI godot_vector2_set_y(godot_vector2 *p_v, const godot_real p_y) {
- Vector2 *v = (Vector2 *)p_v;
- v->y = p_y;
+godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2 *)&dest) = self->normalized();
+ return dest;
}
-godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->x;
+godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->length();
}
-godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->y;
+
+godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->angle();
}
-void GDAPI godot_vector2_normalize(godot_vector2 *p_v) {
- Vector2 *v = (Vector2 *)p_v;
- v->normalize();
+godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->length_squared();
}
-godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_v) {
- godot_vector2 dest;
- const Vector2 *v = (Vector2 *)p_v;
- Vector2 *d = (Vector2 *)&dest;
- *d = v->normalized();
- return dest;
+godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->is_normalized();
}
-godot_real GDAPI godot_vector2_length(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->length();
+godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ return self->distance_to(*to);
}
-godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->length_squared();
+godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ return self->distance_squared_to(*to);
}
-godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_v, const godot_vector2 p_b) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- return v->distance_to(*b);
+godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ return self->angle_to(*to);
}
-godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_v, const godot_vector2 p_b) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- return v->distance_squared_to(*b);
+godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *to = (const Vector2 *)p_to;
+ return self->angle_to_point(*to);
}
-godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_v, const godot_vector2 p_b) {
+godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- *d = *v + *b;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ *((Vector2 *)&dest) = self->linear_interpolate(*b, p_t);
return dest;
}
-godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_v, const godot_vector2 p_b) {
+godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- *d = *v - *b;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ const Vector2 *pre_a = (const Vector2 *)p_pre_a;
+ const Vector2 *post_b = (const Vector2 *)p_post_b;
+ *((Vector2 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t);
return dest;
}
-godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_v, const godot_vector2 p_b) {
+godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- *d = *v * *b;
+ const Vector2 *self = (const Vector2 *)p_self;
+
+ *((Vector2 *)&dest) = self->rotated(p_phi);
return dest;
}
-godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_v, const godot_real p_b) {
+godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = *v * p_b;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2 *)&dest) = self->tangent();
return dest;
}
-godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_v, const godot_vector2 p_b) {
+godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- *d = *v / *b;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2 *)&dest) = self->floor();
return dest;
}
-godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_v, const godot_real p_b) {
+godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = *v / p_b;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *by = (const Vector2 *)p_by;
+ *((Vector2 *)&dest) = self->snapped(*by);
return dest;
}
-godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_v, const godot_vector2 p_b) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- return *v == *b;
+godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->aspect();
}
-godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_v, const godot_vector2 p_b) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- return *v < *b;
+godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *with = (const Vector2 *)p_with;
+ return self->dot(*with);
}
-godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_v) {
+godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = v->abs();
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *n = (const Vector2 *)p_n;
+ *((Vector2 *)&dest) = self->slide(*n);
return dest;
}
-godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->angle();
-}
-
-godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_v, const godot_vector2 p_to) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *to = (Vector2 *)&p_to;
- return v->angle_to(*to);
+godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *n = (const Vector2 *)p_n;
+ *((Vector2 *)&dest) = self->bounce(*n);
+ return dest;
}
-godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_v, const godot_vector2 p_to) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *to = (Vector2 *)&p_to;
- return v->angle_to_point(*to);
+godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n) {
+ godot_vector2 dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *n = (const Vector2 *)p_n;
+ *((Vector2 *)&dest) = self->reflect(*n);
+ return dest;
}
-godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_v, const godot_real length) {
+godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = v->clamped(length);
+ const Vector2 *self = (const Vector2 *)p_self;
+ *((Vector2 *)&dest) = self->abs();
return dest;
}
-godot_vector2 GDAPI godot_vector2_cubic_interpolate(
- const godot_vector2 *p_v, const godot_vector2 p_b, const godot_vector2 p_pre_a,
- const godot_vector2 p_post_b, godot_real t) {
+godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length) {
godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- const Vector2 *pre_a = (Vector2 *)&p_pre_a;
- const Vector2 *post_b = (Vector2 *)&p_post_b;
- *d = v->cubic_interpolate(*b, *pre_a, *post_b, t);
+ const Vector2 *self = (const Vector2 *)p_self;
+
+ *((Vector2 *)&dest) = self->clamped(p_length);
return dest;
}
-godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_v, const godot_vector2 p_with) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *with = (Vector2 *)&p_with;
- return v->dot(*with);
+godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_v) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = v->floor();
- return dest;
+godot_vector2 GDAPI godot_vector2_operator_substract(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
}
-godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_v) {
- const Vector2 *v = (Vector2 *)p_v;
- return v->aspect();
+godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_linear_interpolate(
- const godot_vector2 *p_v,
- const godot_vector2 p_b,
- godot_real t) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *b = (Vector2 *)&p_b;
- *d = v->linear_interpolate(*b, t);
- return dest;
+godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_v, const godot_vector2 p_vec) {
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *vec = (Vector2 *)&p_vec;
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- *d = v->reflect(*vec);
- return dest;
+godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ *dest = *self / *b;
+ return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_v, godot_real phi) {
- const Vector2 *v = (Vector2 *)p_v;
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- *d = v->rotated(phi);
- return dest;
+godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *dest = *self / p_b;
+ return raw_dest;
}
-godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_v, godot_vector2 p_vec) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *vec = (Vector2 *)&p_vec;
- *d = v->slide(*vec);
- return dest;
+godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ return *self == *b;
}
-godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_v, godot_vector2 p_by) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- const Vector2 *by = (Vector2 *)&p_by;
- *d = v->snapped(*by);
- return dest;
+godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ const Vector2 *b = (const Vector2 *)p_b;
+ return *self < *b;
}
-godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_v) {
- godot_vector2 dest;
- Vector2 *d = (Vector2 *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = v->tangent();
- return dest;
+godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self) {
+ godot_vector2 raw_dest;
+ Vector2 *dest = (Vector2 *)&raw_dest;
+ const Vector2 *self = (const Vector2 *)p_self;
+ *dest = -(*self);
+ return raw_dest;
}
-godot_string GDAPI godot_vector2_to_string(const godot_vector2 *p_v) {
- godot_string dest;
- String *d = (String *)&dest;
- const Vector2 *v = (Vector2 *)p_v;
- *d = "(" + *v + ")";
- return dest;
+void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x) {
+ Vector2 *self = (Vector2 *)p_self;
+ self->x = p_x;
+}
+
+void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y) {
+ Vector2 *self = (Vector2 *)p_self;
+ self->y = p_y;
+}
+
+godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->x;
+}
+
+godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self) {
+ const Vector2 *self = (const Vector2 *)p_self;
+ return self->y;
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_vector2.h b/modules/gdnative/godot/godot_vector2.h
index 36a4f01d03..9c7590fedf 100644
--- a/modules/gdnative/godot/godot_vector2.h
+++ b/modules/gdnative/godot/godot_vector2.h
@@ -45,51 +45,79 @@ typedef struct godot_vector2 {
#include "../godot.h"
-godot_vector2 GDAPI godot_vector2_new(const godot_real p_x, const godot_real p_y);
-
-void GDAPI godot_vector2_set_x(godot_vector2 *p_v, const godot_real p_x);
-void GDAPI godot_vector2_set_y(godot_vector2 *p_v, const godot_real p_y);
-godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_v);
-godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_v);
-
-void GDAPI godot_vector2_normalize(godot_vector2 *p_v);
-godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_v);
-
-godot_real GDAPI godot_vector2_length(const godot_vector2 *p_v);
-godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_v);
-
-godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_v, const godot_vector2 p_b);
-
-godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_v);
-godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_v);
-godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_v, const godot_vector2 p_to);
-godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_v, const godot_vector2 p_to);
-godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_v, godot_real length);
-godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_v,
- const godot_vector2 p_b, const godot_vector2 p_pre_a,
- const godot_vector2 p_post_b, godot_real t);
-godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_v, const godot_vector2 p_with);
-godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_v);
-godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_v);
-godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_v,
- const godot_vector2 p_b, godot_real t);
-godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_v, const godot_vector2 p_vec);
-godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_v, godot_real phi);
-godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_v, godot_vector2 p_vec);
-godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_v, godot_vector2 p_by);
-godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_v);
-godot_string GDAPI godot_vector2_to_string(const godot_vector2 *p_v);
-
-godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_vector2 GDAPI godot_vector2_operator_subtract(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_v, const godot_real p_b);
-godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_v, const godot_real p_b);
-
-godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_v, const godot_vector2 p_b);
-godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_v, const godot_vector2 p_b);
+void GDAPI godot_vector2_new(godot_vector2 *r_dest, const godot_real p_x, const godot_real p_y);
+
+godot_string GDAPI godot_vector2_as_string(const godot_vector2 *p_self);
+
+godot_vector2 GDAPI godot_vector2_normalized(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_length(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_angle(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_length_squared(const godot_vector2 *p_self);
+
+godot_bool GDAPI godot_vector2_is_normalized(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_distance_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
+
+godot_real GDAPI godot_vector2_distance_squared_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
+
+godot_real GDAPI godot_vector2_angle_to(const godot_vector2 *p_self, const godot_vector2 *p_to);
+
+godot_real GDAPI godot_vector2_angle_to_point(const godot_vector2 *p_self, const godot_vector2 *p_to);
+
+godot_vector2 GDAPI godot_vector2_linear_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_real p_t);
+
+godot_vector2 GDAPI godot_vector2_cubic_interpolate(const godot_vector2 *p_self, const godot_vector2 *p_b, const godot_vector2 *p_pre_a, const godot_vector2 *p_post_b, const godot_real p_t);
+
+godot_vector2 GDAPI godot_vector2_rotated(const godot_vector2 *p_self, const godot_real p_phi);
+
+godot_vector2 GDAPI godot_vector2_tangent(const godot_vector2 *p_self);
+
+godot_vector2 GDAPI godot_vector2_floor(const godot_vector2 *p_self);
+
+godot_vector2 GDAPI godot_vector2_snapped(const godot_vector2 *p_self, const godot_vector2 *p_by);
+
+godot_real GDAPI godot_vector2_aspect(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_dot(const godot_vector2 *p_self, const godot_vector2 *p_with);
+
+godot_vector2 GDAPI godot_vector2_slide(const godot_vector2 *p_self, const godot_vector2 *p_n);
+
+godot_vector2 GDAPI godot_vector2_bounce(const godot_vector2 *p_self, const godot_vector2 *p_n);
+
+godot_vector2 GDAPI godot_vector2_reflect(const godot_vector2 *p_self, const godot_vector2 *p_n);
+
+godot_vector2 GDAPI godot_vector2_abs(const godot_vector2 *p_self);
+
+godot_vector2 GDAPI godot_vector2_clamped(const godot_vector2 *p_self, const godot_real p_length);
+
+godot_vector2 GDAPI godot_vector2_operator_add(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_substract(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_multiply_vector(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_multiply_scalar(const godot_vector2 *p_self, const godot_real p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_divide_vector(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_divide_scalar(const godot_vector2 *p_self, const godot_real p_b);
+
+godot_bool GDAPI godot_vector2_operator_equal(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_bool GDAPI godot_vector2_operator_less(const godot_vector2 *p_self, const godot_vector2 *p_b);
+
+godot_vector2 GDAPI godot_vector2_operator_neg(const godot_vector2 *p_self);
+
+void GDAPI godot_vector2_set_x(godot_vector2 *p_self, const godot_real p_x);
+
+void GDAPI godot_vector2_set_y(godot_vector2 *p_self, const godot_real p_y);
+
+godot_real GDAPI godot_vector2_get_x(const godot_vector2 *p_self);
+
+godot_real GDAPI godot_vector2_get_y(const godot_vector2 *p_self);
#ifdef __cplusplus
}
diff --git a/modules/gdnative/godot/godot_vector3.cpp b/modules/gdnative/godot/godot_vector3.cpp
index 5f71b9f7e4..f9942af6e5 100644
--- a/modules/gdnative/godot/godot_vector3.cpp
+++ b/modules/gdnative/godot/godot_vector3.cpp
@@ -28,313 +28,274 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "godot_vector3.h"
+#include "core/variant.h"
-#include "math/vector3.h"
+#include "core/vector.h"
#ifdef __cplusplus
extern "C" {
#endif
-void _vector3_api_anchor() {
-}
+void _vector3_api_anchor() {}
-godot_vector3 GDAPI godot_vector3_new(const godot_real p_x, const godot_real p_y, const godot_real p_z) {
- godot_vector3 value;
- Vector3 *v = (Vector3 *)&value;
- *v = Vector3(p_x, p_y, p_z);
- return value;
-}
+void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z) {
-void GDAPI godot_vector3_set_axis(godot_vector3 *p_v, const godot_int p_axis, const godot_real p_val) {
- Vector3 *v = (Vector3 *)p_v;
- v->set_axis(p_axis, p_val);
+ Vector3 *dest = (Vector3 *)r_dest;
+ *dest = Vector3(p_x, p_y, p_z);
}
-godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_v, const godot_int p_axis) {
- Vector3 *v = (Vector3 *)p_v;
- return v->get_axis(p_axis);
+godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self) {
+ godot_string ret;
+ const Vector3 *self = (const Vector3 *)p_self;
+ memnew_placement(&ret, String(*self));
+ return ret;
}
-godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- return v->min_axis();
+godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->min_axis();
}
-godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- return v->max_axis();
+godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->max_axis();
}
-godot_real GDAPI godot_vector3_length(const godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- return v->length();
+godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->length();
}
-godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- return v->length_squared();
+godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->length_squared();
}
-void GDAPI godot_vector3_normalize(godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- v->normalize();
+godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->is_normalized();
}
-godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_v) {
+godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- *d = v->normalized();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->normalized();
return dest;
}
-godot_vector3 godot_vector3_inverse(const godot_vector3 *p_v) {
+godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->inverse();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->inverse();
return dest;
}
-void godot_vector3_zero(godot_vector3 *p_v) {
- Vector3 *v = (Vector3 *)p_v;
- v->zero();
-}
-
-void godot_vector3_snap(godot_vector3 *p_v, const godot_real val) {
- Vector3 *v = (Vector3 *)p_v;
- v->snap(val);
-}
-
-godot_vector3 godot_vector3_snapped(const godot_vector3 *p_v, const godot_real val) {
+godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_real p_by) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->snapped(val);
- return dest;
-}
+ const Vector3 *self = (const Vector3 *)p_self;
-void godot_vector3_rotate(godot_vector3 *p_v, const godot_vector3 p_axis, const godot_real phi) {
- Vector3 *v = (Vector3 *)p_v;
- const Vector3 *axis = (Vector3 *)&p_axis;
- v->rotate(*axis, phi);
+ *((Vector3 *)&dest) = self->snapped(p_by);
+ return dest;
}
-godot_vector3 godot_vector3_rotated(const godot_vector3 *p_v, const godot_vector3 p_axis, const godot_real phi) {
+godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *axis = (Vector3 *)&p_axis;
- *d = v->rotated(*axis, phi);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *axis = (const Vector3 *)p_axis;
+ *((Vector3 *)&dest) = self->rotated(*axis, p_phi);
return dest;
}
-godot_vector3 godot_vector3_linear_interpolate(const godot_vector3 *p_v, const godot_vector3 p_b, const godot_real t) {
+godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- *d = v->linear_interpolate(*b, t);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *((Vector3 *)&dest) = self->linear_interpolate(*b, p_t);
return dest;
}
-godot_vector3 godot_vector3_cubic_interpolate(const godot_vector3 *p_v,
- const godot_vector3 p_b, const godot_vector3 p_pre_a,
- const godot_vector3 p_post_b, const godot_real t) {
+godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- const Vector3 *pre_a = (Vector3 *)&p_pre_a;
- const Vector3 *post_b = (Vector3 *)&p_post_b;
- *d = v->cubic_interpolate(*b, *pre_a, *post_b, t);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ const Vector3 *pre_a = (const Vector3 *)p_pre_a;
+ const Vector3 *post_b = (const Vector3 *)p_post_b;
+ *((Vector3 *)&dest) = self->cubic_interpolate(*b, *pre_a, *post_b, p_t);
return dest;
}
-godot_vector3 godot_vector3_cubic_interpolaten(const godot_vector3 *p_v,
- const godot_vector3 p_b, const godot_vector3 p_pre_a,
- const godot_vector3 p_post_b, const godot_real t) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- const Vector3 *pre_a = (Vector3 *)&p_pre_a;
- const Vector3 *post_b = (Vector3 *)&p_post_b;
- *d = v->cubic_interpolaten(*b, *pre_a, *post_b, t);
- return dest;
+godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ return self->dot(*b);
}
-godot_vector3 godot_vector3_cross(const godot_vector3 *p_v, const godot_vector3 p_b) {
+godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- *d = v->cross(*b);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *((Vector3 *)&dest) = self->cross(*b);
return dest;
}
-godot_real godot_vector3_dot(const godot_vector3 *p_v, const godot_vector3 p_b) {
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- return v->dot(*b);
-}
-
-godot_basis godot_vector3_outer(const godot_vector3 *p_v, const godot_vector3 p_b) {
+godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b) {
godot_basis dest;
- Basis *d = (Basis *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *b = (Vector3 *)&p_b;
- *d = v->outer(*b);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *((Basis *)&dest) = self->outer(*b);
return dest;
}
-godot_basis godot_vector3_to_diagonal_matrix(const godot_vector3 *p_v) {
+godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self) {
godot_basis dest;
- Basis *d = (Basis *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->to_diagonal_matrix();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Basis *)&dest) = self->to_diagonal_matrix();
return dest;
}
-godot_vector3 godot_vector3_abs(const godot_vector3 *p_v) {
+godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->abs();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->abs();
return dest;
}
-godot_vector3 godot_vector3_floor(const godot_vector3 *p_v) {
+godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->floor();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->floor();
return dest;
}
-godot_vector3 godot_vector3_ceil(const godot_vector3 *p_v) {
+godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = v->ceil();
+ const Vector3 *self = (const Vector3 *)p_self;
+ *((Vector3 *)&dest) = self->ceil();
return dest;
}
-godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_v, const godot_vector3 p_b) {
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- return v->distance_to(*b);
+godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ return self->distance_to(*b);
}
-godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_v, const godot_vector3 p_b) {
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- return v->distance_squared_to(*b);
+godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ return self->distance_squared_to(*b);
}
-godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_v, const godot_vector3 p_b) {
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- return v->angle_to(*b);
+godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *to = (const Vector3 *)p_to;
+ return self->angle_to(*to);
}
-godot_vector3 godot_vector3_slide(const godot_vector3 *p_v, const godot_vector3 p_vec) {
+godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *vec = (Vector3 *)&p_vec;
- *d = v->slide(*vec);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *n = (const Vector3 *)p_n;
+ *((Vector3 *)&dest) = self->slide(*n);
return dest;
}
-godot_vector3 godot_vector3_bounce(const godot_vector3 *p_v, const godot_vector3 p_vec) {
+godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *vec = (Vector3 *)&p_vec;
- *d = v->bounce(*vec);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *n = (const Vector3 *)p_n;
+ *((Vector3 *)&dest) = self->bounce(*n);
return dest;
}
-godot_vector3 godot_vector3_reflect(const godot_vector3 *p_v, const godot_vector3 p_vec) {
+godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n) {
godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- const Vector3 *vec = (Vector3 *)&p_vec;
- *d = v->reflect(*vec);
+ const Vector3 *self = (const Vector3 *)p_self;
+ const Vector3 *n = (const Vector3 *)p_n;
+ *((Vector3 *)&dest) = self->reflect(*n);
return dest;
}
-godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_v, const godot_vector3 p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- *d = *v + *b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *dest = *self + *b;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_v, const godot_vector3 p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- *d = *v - *b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_substract(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *dest = *self - *b;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_v, const godot_vector3 p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- *d = *v * *b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *dest = *self * *b;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_v, const godot_real p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- *d = *v * p_b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ *dest = *self * p_b;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_v, const godot_vector3 p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- *d = *v / *b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ *dest = *self / *b;
+ return raw_dest;
}
-godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_v, const godot_real p_b) {
- godot_vector3 dest;
- Vector3 *d = (Vector3 *)&dest;
- Vector3 *v = (Vector3 *)p_v;
- *d = *v / p_b;
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ Vector3 *self = (Vector3 *)p_self;
+ *dest = *self / p_b;
+ return raw_dest;
}
-godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_v, const godot_vector3 p_b) {
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- return *v == *b;
+godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ return *self == *b;
}
-godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_v, const godot_vector3 p_b) {
- Vector3 *v = (Vector3 *)p_v;
- Vector3 *b = (Vector3 *)&p_b;
- return *v < *b;
+godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b) {
+ Vector3 *self = (Vector3 *)p_self;
+ const Vector3 *b = (const Vector3 *)p_b;
+ return *self < *b;
}
-godot_string GDAPI godot_vector3_to_string(const godot_vector3 *p_v) {
- godot_string dest;
- String *d = (String *)&dest;
- const Vector3 *v = (Vector3 *)p_v;
- *d = "(" + *v + ")";
- return dest;
+godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self) {
+ godot_vector3 raw_dest;
+ Vector3 *dest = (Vector3 *)&raw_dest;
+ const Vector3 *self = (const Vector3 *)p_self;
+ *dest = -(*self);
+ return raw_dest;
+}
+
+void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val) {
+ Vector3 *self = (Vector3 *)p_self;
+ self->set_axis(p_axis, p_val);
+}
+
+godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis) {
+ const Vector3 *self = (const Vector3 *)p_self;
+ return self->get_axis(p_axis);
}
#ifdef __cplusplus
diff --git a/modules/gdnative/godot/godot_vector3.h b/modules/gdnative/godot/godot_vector3.h
index 654ddd7792..8e2aed8173 100644
--- a/modules/gdnative/godot/godot_vector3.h
+++ b/modules/gdnative/godot/godot_vector3.h
@@ -37,74 +37,94 @@ extern "C" {
#include <stdint.h>
#ifndef GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED
+#define GODOT_CORE_API_GODOT_VECTOR3_TYPE_DEFINED
typedef struct godot_vector3 {
uint8_t _dont_touch_that[12];
} godot_vector3;
#endif
-#define GODOT_VECTOR3_AXIX_X 0
-#define GODOT_VECTOR3_AXIX_Y 1
-#define GODOT_VECTOR3_AXIX_Z 2
-
#include "../godot.h"
#include "godot_basis.h"
-godot_vector3 GDAPI godot_vector3_new(const godot_real p_x, const godot_real p_y, const godot_real p_z);
-
-void GDAPI godot_vector3_set_axis(godot_vector3 *p_v, const godot_int p_axis, const godot_real p_val);
-godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_v, const godot_int p_axis);
-
-godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_v);
-godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_v);
-
-godot_real GDAPI godot_vector3_length(const godot_vector3 *p_v);
-godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_v);
-
-void GDAPI godot_vector3_normalize(godot_vector3 *p_v);
-godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_v);
-
-godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_v);
-void GDAPI godot_vector3_zero(godot_vector3 *p_v);
-void GDAPI godot_vector3_snap(godot_vector3 *p_v, const godot_real val);
-godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_v, const godot_real val);
-void GDAPI godot_vector3_rotate(godot_vector3 *p_v, const godot_vector3 p_axis, const godot_real phi);
-godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_v,
- const godot_vector3 p_axis, const godot_real phi);
-godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_v,
- const godot_vector3 p_b, const godot_real t);
-godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_v,
- const godot_vector3 p_b, const godot_vector3 p_pre_a,
- const godot_vector3 p_post_b, const godot_real t);
-godot_vector3 GDAPI godot_vector3_cubic_interpolaten(const godot_vector3 *p_v,
- const godot_vector3 p_b, const godot_vector3 p_pre_a,
- const godot_vector3 p_post_b, const godot_real t);
-godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_v);
-godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_v);
-godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_v);
-godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_v);
-
-godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_v, const godot_vector3 p_b);
-
-godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_v, const godot_vector3 p_vec);
-godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_v, const godot_vector3 p_vec);
-godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_v, const godot_vector3 p_vec);
-
-godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_vector3 GDAPI godot_vector3_operator_subtract(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_v, const godot_real p_b);
-godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_v, const godot_real p_b);
-
-godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_v, const godot_vector3 p_b);
-godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_v, const godot_vector3 p_b);
-
-godot_string GDAPI godot_vector3_to_string(const godot_vector3 *p_v);
+typedef enum {
+ GODOT_VECTOR3_AXIS_X,
+ GODOT_VECTOR3_AXIS_Y,
+ GODOT_VECTOR3_AXIS_Z,
+} godot_vector3_axis;
+
+void GDAPI godot_vector3_new(godot_vector3 *r_dest, const godot_real p_x, const godot_real p_y, const godot_real p_z);
+
+godot_string GDAPI godot_vector3_as_string(const godot_vector3 *p_self);
+
+godot_int GDAPI godot_vector3_min_axis(const godot_vector3 *p_self);
+
+godot_int GDAPI godot_vector3_max_axis(const godot_vector3 *p_self);
+
+godot_real GDAPI godot_vector3_length(const godot_vector3 *p_self);
+
+godot_real GDAPI godot_vector3_length_squared(const godot_vector3 *p_self);
+
+godot_bool GDAPI godot_vector3_is_normalized(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_normalized(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_inverse(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_snapped(const godot_vector3 *p_self, const godot_real p_by);
+
+godot_vector3 GDAPI godot_vector3_rotated(const godot_vector3 *p_self, const godot_vector3 *p_axis, const godot_real p_phi);
+
+godot_vector3 GDAPI godot_vector3_linear_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_real p_t);
+
+godot_vector3 GDAPI godot_vector3_cubic_interpolate(const godot_vector3 *p_self, const godot_vector3 *p_b, const godot_vector3 *p_pre_a, const godot_vector3 *p_post_b, const godot_real p_t);
+
+godot_real GDAPI godot_vector3_dot(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_cross(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_basis GDAPI godot_vector3_outer(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_basis GDAPI godot_vector3_to_diagonal_matrix(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_abs(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_floor(const godot_vector3 *p_self);
+
+godot_vector3 GDAPI godot_vector3_ceil(const godot_vector3 *p_self);
+
+godot_real GDAPI godot_vector3_distance_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_real GDAPI godot_vector3_distance_squared_to(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_real GDAPI godot_vector3_angle_to(const godot_vector3 *p_self, const godot_vector3 *p_to);
+
+godot_vector3 GDAPI godot_vector3_slide(const godot_vector3 *p_self, const godot_vector3 *p_n);
+
+godot_vector3 GDAPI godot_vector3_bounce(const godot_vector3 *p_self, const godot_vector3 *p_n);
+
+godot_vector3 GDAPI godot_vector3_reflect(const godot_vector3 *p_self, const godot_vector3 *p_n);
+
+godot_vector3 GDAPI godot_vector3_operator_add(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_substract(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_multiply_vector(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_multiply_scalar(const godot_vector3 *p_self, const godot_real p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_divide_vector(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_divide_scalar(const godot_vector3 *p_self, const godot_real p_b);
+
+godot_bool GDAPI godot_vector3_operator_equal(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_bool GDAPI godot_vector3_operator_less(const godot_vector3 *p_self, const godot_vector3 *p_b);
+
+godot_vector3 GDAPI godot_vector3_operator_neg(const godot_vector3 *p_self);
+
+void GDAPI godot_vector3_set_axis(godot_vector3 *p_self, const godot_vector3_axis p_axis, const godot_real p_val);
+
+godot_real GDAPI godot_vector3_get_axis(const godot_vector3 *p_self, const godot_vector3_axis p_axis);
#ifdef __cplusplus
}
diff --git a/modules/gdscript/gd_compiler.cpp b/modules/gdscript/gd_compiler.cpp
index 12b43d6060..d4ede4cb17 100644
--- a/modules/gdscript/gd_compiler.cpp
+++ b/modules/gdscript/gd_compiler.cpp
@@ -1014,7 +1014,7 @@ int GDCompiler::_parse_expression(CodeGen &codegen, const GDParser::Node *p_expr
}
} break;
- case GDParser::OperatorNode::OP_EXTENDS: {
+ case GDParser::OperatorNode::OP_IS: {
ERR_FAIL_COND_V(on->arguments.size() != 2, false);
diff --git a/modules/gdscript/gd_editor.cpp b/modules/gdscript/gd_editor.cpp
index 4667e541dd..5e3ce31dd6 100644
--- a/modules/gdscript/gd_editor.cpp
+++ b/modules/gdscript/gd_editor.cpp
@@ -69,6 +69,19 @@ Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const Str
return script;
}
+bool GDScriptLanguage::is_using_templates() {
+
+ return true;
+}
+
+void GDScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+
+ String src = p_script->get_source_code();
+ src = src.replace("%BASE%", p_base_class_name);
+ src = src.replace("%TS%", _get_indentation());
+ p_script->set_source_code(src);
+}
+
bool GDScriptLanguage::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 {
GDParser parser;
@@ -1321,7 +1334,7 @@ static void _find_identifiers(GDCompletionContext &context, int p_line, bool p_o
static const char *_type_names[Variant::VARIANT_MAX] = {
"null", "bool", "int", "float", "String", "Vector2", "Rect2", "Vector3", "Transform2D", "Plane", "Quat", "AABB", "Basis", "Transform",
- "Color", "Image", "NodePath", "RID", "Object", "InputEvent", "Dictionary", "Array", "RawArray", "IntArray", "FloatArray", "StringArray",
+ "Color", "NodePath", "RID", "Object", "Dictionary", "Array", "RawArray", "IntArray", "FloatArray", "StringArray",
"Vector2Array", "Vector3Array", "ColorArray"
};
@@ -1425,22 +1438,7 @@ void get_directory_contents(EditorFileSystemDirectory *p_dir, Set<String> &r_lis
static void _find_type_arguments(GDCompletionContext &context, const GDParser::Node *p_node, int p_line, const StringName &p_method, const GDCompletionIdentifier &id, int p_argidx, Set<String> &result, String &arghint) {
//print_line("find type arguments?");
- if (id.type == Variant::INPUT_EVENT && String(p_method) == "is_action" && p_argidx == 0) {
-
- List<PropertyInfo> pinfo;
- GlobalConfig::get_singleton()->get_property_list(&pinfo);
-
- for (List<PropertyInfo>::Element *E = pinfo.front(); E; E = E->next()) {
- const PropertyInfo &pi = E->get();
-
- if (!pi.name.begins_with("input/"))
- continue;
-
- String name = pi.name.substr(pi.name.find("/") + 1, pi.name.length());
- result.insert("\"" + name + "\"");
- }
-
- } else if (id.type == Variant::OBJECT && id.obj_type != StringName()) {
+ if (id.type == Variant::OBJECT && id.obj_type != StringName()) {
MethodBind *m = ClassDB::get_method(id.obj_type, p_method);
if (!m) {
@@ -2266,54 +2264,8 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
}
} else {
- if (t.type == Variant::INPUT_EVENT) {
-
- //this is hardcoded otherwise it's not obvious
- Set<String> exclude;
-
- for (int i = 0; i < InputEvent::TYPE_MAX; i++) {
-
- InputEvent ie;
- ie.type = InputEvent::Type(i);
- static const char *evnames[] = {
- "# Common",
- "# Key",
- "# MouseMotion",
- "# MouseButton",
- "# JoypadMotion",
- "# JoypadButton",
- "# ScreenTouch",
- "# ScreenDrag",
- "# Action"
- };
-
- r_options->push_back(evnames[i]);
-
- Variant v = ie;
-
- if (i == 0) {
- List<MethodInfo> mi;
- v.get_method_list(&mi);
- for (List<MethodInfo>::Element *E = mi.front(); E; E = E->next()) {
- r_options->push_back(E->get().name + "(");
- }
- }
-
- List<PropertyInfo> pi;
- v.get_property_list(&pi);
-
- for (List<PropertyInfo>::Element *E = pi.front(); E; E = E->next()) {
-
- if (i == 0)
- exclude.insert(E->get().name);
- else if (exclude.has(E->get().name))
- continue;
-
- r_options->push_back(E->get().name);
- }
- }
- return OK;
- } else {
+ //check InputEvent hint
+ {
if (t.value.get_type() == Variant::NIL) {
Variant::CallError ce;
t.value = Variant::construct(t.type, NULL, 0, ce);
@@ -2395,7 +2347,7 @@ Error GDScriptLanguage::complete_code(const String &p_code, const String &p_base
}
} break;
- case GDParser::COMPLETION_PRELOAD: {
+ case GDParser::COMPLETION_RESOURCE_PATH: {
if (EditorSettings::get_singleton()->get("text_editor/completion/complete_file_paths"))
get_directory_contents(EditorFileSystem::get_singleton()->get_filesystem(), options);
diff --git a/modules/gdscript/gd_function.cpp b/modules/gdscript/gd_function.cpp
index 608256c88a..e8a8e20927 100644
--- a/modules/gdscript/gd_function.cpp
+++ b/modules/gdscript/gd_function.cpp
@@ -358,12 +358,12 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
if (a->get_type() != Variant::OBJECT || a->operator Object *() == NULL) {
- err_text = "Left operand of 'extends' is not an instance of anything.";
+ err_text = "Left operand of 'is' is not an instance of anything.";
break;
}
if (b->get_type() != Variant::OBJECT || b->operator Object *() == NULL) {
- err_text = "Right operand of 'extends' is not a class.";
+ err_text = "Right operand of 'is' is not a class.";
break;
}
#endif
@@ -401,7 +401,7 @@ Variant GDFunction::call(GDInstance *p_instance, const Variant **p_args, int p_a
if (!nc) {
- err_text = "Right operand of 'extends' is not a class (type: '" + obj_B->get_class() + "').";
+ err_text = "Right operand of 'is' is not a class (type: '" + obj_B->get_class() + "').";
break;
}
@@ -1433,9 +1433,21 @@ Variant GDFunctionState::_signal_callback(const Variant **p_args, int p_argcount
return ret;
}
-bool GDFunctionState::is_valid() const {
+bool GDFunctionState::is_valid(bool p_extended_check) const {
- return function != NULL;
+ if (function == NULL)
+ return false;
+
+ if (p_extended_check) {
+ //class instance gone?
+ if (state.instance_id && !ObjectDB::get_instance(state.instance_id))
+ return false;
+ //script gone?
+ if (state.script_id && !ObjectDB::get_instance(state.script_id))
+ return false;
+ }
+
+ return true;
}
Variant GDFunctionState::resume(const Variant &p_arg) {
@@ -1464,7 +1476,7 @@ Variant GDFunctionState::resume(const Variant &p_arg) {
void GDFunctionState::_bind_methods() {
ClassDB::bind_method(D_METHOD("resume:Variant", "arg"), &GDFunctionState::resume, DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("is_valid"), &GDFunctionState::is_valid);
+ ClassDB::bind_method(D_METHOD("is_valid", "extended_check"), &GDFunctionState::is_valid, DEFVAL(false));
ClassDB::bind_vararg_method(METHOD_FLAGS_DEFAULT, "_signal_callback", &GDFunctionState::_signal_callback, MethodInfo("_signal_callback"));
}
diff --git a/modules/gdscript/gd_function.h b/modules/gdscript/gd_function.h
index f0bf33147b..6d20b19777 100644
--- a/modules/gdscript/gd_function.h
+++ b/modules/gdscript/gd_function.h
@@ -237,7 +237,7 @@ protected:
static void _bind_methods();
public:
- bool is_valid() const;
+ bool is_valid(bool p_extended_check = false) const;
Variant resume(const Variant &p_arg = Variant());
GDFunctionState();
~GDFunctionState();
diff --git a/modules/gdscript/gd_parser.cpp b/modules/gdscript/gd_parser.cpp
index b02d7f713b..d64cd86de6 100644
--- a/modules/gdscript/gd_parser.cpp
+++ b/modules/gdscript/gd_parser.cpp
@@ -387,15 +387,21 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
_set_error("Expected '(' after 'preload'");
return NULL;
}
- completion_cursor = StringName();
- completion_type = COMPLETION_PRELOAD;
- completion_class = current_class;
- completion_function = current_function;
- completion_line = tokenizer->get_token_line();
- completion_block = current_block;
- completion_found = true;
tokenizer->advance();
+ if (tokenizer->get_token() == GDTokenizer::TK_CURSOR) {
+ completion_cursor = StringName();
+ completion_node = p_parent;
+ completion_type = COMPLETION_RESOURCE_PATH;
+ completion_class = current_class;
+ completion_function = current_function;
+ completion_line = tokenizer->get_token_line();
+ completion_block = current_block;
+ completion_argument = 0;
+ completion_found = true;
+ tokenizer->advance();
+ }
+
String path;
bool found_constant = false;
bool valid = false;
@@ -467,10 +473,10 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
_set_error("Expected ')' after 'preload' path");
return NULL;
}
+ tokenizer->advance();
ConstantNode *constant = alloc_node<ConstantNode>();
constant->value = res;
- tokenizer->advance();
expr = constant;
} else if (tokenizer->get_token() == GDTokenizer::TK_PR_YIELD) {
@@ -1071,7 +1077,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
case GDTokenizer::TK_OP_BIT_AND: op = OperatorNode::OP_BIT_AND; break;
case GDTokenizer::TK_OP_BIT_OR: op = OperatorNode::OP_BIT_OR; break;
case GDTokenizer::TK_OP_BIT_XOR: op = OperatorNode::OP_BIT_XOR; break;
- case GDTokenizer::TK_PR_EXTENDS: op = OperatorNode::OP_EXTENDS; break;
+ case GDTokenizer::TK_PR_IS: op = OperatorNode::OP_IS; break;
case GDTokenizer::TK_CF_IF: op = OperatorNode::OP_TERNARY_IF; break;
case GDTokenizer::TK_CF_ELSE: op = OperatorNode::OP_TERNARY_ELSE; break;
default: valid = false; break;
@@ -1111,7 +1117,7 @@ GDParser::Node *GDParser::_parse_expression(Node *p_parent, bool p_static, bool
switch (expression[i].op) {
- case OperatorNode::OP_EXTENDS:
+ case OperatorNode::OP_IS:
priority = -1;
break; //before anything
@@ -1414,7 +1420,7 @@ GDParser::Node *GDParser::_reduce_expression(Node *p_node, bool p_to_const) {
}
}
- if (op->op == OperatorNode::OP_EXTENDS) {
+ if (op->op == OperatorNode::OP_IS) {
//nothing much
return op;
}
diff --git a/modules/gdscript/gd_parser.h b/modules/gdscript/gd_parser.h
index 4f3ca0dc5f..3ad3466624 100644
--- a/modules/gdscript/gd_parser.h
+++ b/modules/gdscript/gd_parser.h
@@ -216,7 +216,7 @@ public:
OP_CALL,
OP_PARENT_CALL,
OP_YIELD,
- OP_EXTENDS,
+ OP_IS,
//indexing operator
OP_INDEX,
OP_INDEX_NAMED,
@@ -437,7 +437,7 @@ public:
COMPLETION_PARENT_FUNCTION,
COMPLETION_METHOD,
COMPLETION_CALL_ARGUMENTS,
- COMPLETION_PRELOAD,
+ COMPLETION_RESOURCE_PATH,
COMPLETION_INDEX,
COMPLETION_VIRTUAL_FUNC,
COMPLETION_YIELD,
diff --git a/modules/gdscript/gd_script.cpp b/modules/gdscript/gd_script.cpp
index 173014b138..1dcc442234 100644
--- a/modules/gdscript/gd_script.cpp
+++ b/modules/gdscript/gd_script.cpp
@@ -615,6 +615,11 @@ Error GDScript::reload(bool p_keep_state) {
if (basedir != "")
basedir = basedir.get_base_dir();
+ if (basedir.find("res://") == -1 && basedir.find("user://") == -1) {
+ //loading a template, don't parse
+ return OK;
+ }
+
valid = false;
GDParser parser;
Error err = parser.parse(source, basedir, false, path);
@@ -1812,6 +1817,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"breakpoint",
"class",
"extends",
+ "is",
"func",
"preload",
"setget",
diff --git a/modules/gdscript/gd_script.h b/modules/gdscript/gd_script.h
index 00ae136790..ebef4fed74 100644
--- a/modules/gdscript/gd_script.h
+++ b/modules/gdscript/gd_script.h
@@ -381,6 +381,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool is_using_templates();
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
diff --git a/modules/gdscript/gd_tokenizer.cpp b/modules/gdscript/gd_tokenizer.cpp
index 13674f1f9a..f4e0cc8e29 100644
--- a/modules/gdscript/gd_tokenizer.cpp
+++ b/modules/gdscript/gd_tokenizer.cpp
@@ -90,6 +90,7 @@ const char *GDTokenizer::token_names[TK_MAX] = {
"func",
"class",
"extends",
+ "is",
"onready",
"tool",
"static",
@@ -800,10 +801,8 @@ void GDTokenizerText::_advance() {
{ Variant::BASIS, "Basis" },
{ Variant::TRANSFORM, "Transform" },
{ Variant::COLOR, "Color" },
- { Variant::IMAGE, "Image" },
{ Variant::_RID, "RID" },
{ Variant::OBJECT, "Object" },
- { Variant::INPUT_EVENT, "InputEvent" },
{ Variant::NODE_PATH, "NodePath" },
{ Variant::DICTIONARY, "Dictionary" },
{ Variant::ARRAY, "Array" },
@@ -866,6 +865,7 @@ void GDTokenizerText::_advance() {
{ TK_PR_FUNCTION, "func" },
{ TK_PR_CLASS, "class" },
{ TK_PR_EXTENDS, "extends" },
+ { TK_PR_IS, "is" },
{ TK_PR_ONREADY, "onready" },
{ TK_PR_TOOL, "tool" },
{ TK_PR_STATIC, "static" },
diff --git a/modules/gdscript/gd_tokenizer.h b/modules/gdscript/gd_tokenizer.h
index ea7629b661..c051176097 100644
--- a/modules/gdscript/gd_tokenizer.h
+++ b/modules/gdscript/gd_tokenizer.h
@@ -96,6 +96,7 @@ public:
TK_PR_FUNCTION,
TK_PR_CLASS,
TK_PR_EXTENDS,
+ TK_PR_IS,
TK_PR_ONREADY,
TK_PR_TOOL,
TK_PR_STATIC,
diff --git a/modules/gridmap/grid_map.cpp b/modules/gridmap/grid_map.cpp
index d1f54e021f..9d3da8227c 100644
--- a/modules/gridmap/grid_map.cpp
+++ b/modules/gridmap/grid_map.cpp
@@ -1057,12 +1057,12 @@ Error GridMap::create_area(int p_id, const Rect3 &p_bounds) {
// FIRST VALIDATE AREA
IndexKey from, to;
- from.x = p_bounds.pos.x;
- from.y = p_bounds.pos.y;
- from.z = p_bounds.pos.z;
- to.x = p_bounds.pos.x + p_bounds.size.x;
- to.y = p_bounds.pos.y + p_bounds.size.y;
- to.z = p_bounds.pos.z + p_bounds.size.z;
+ from.x = p_bounds.position.x;
+ from.y = p_bounds.position.y;
+ from.z = p_bounds.position.z;
+ to.x = p_bounds.position.x + p_bounds.size.x;
+ to.y = p_bounds.position.y + p_bounds.size.y;
+ to.z = p_bounds.position.z + p_bounds.size.z;
for (Map<int, Area *>::Element *E = area_map.front(); E; E = E->next()) {
//this should somehow be faster...
@@ -1101,8 +1101,8 @@ Rect3 GridMap::area_get_bounds(int p_area) const {
const Area *a = area_map[p_area];
Rect3 aabb;
- aabb.pos = Vector3(a->from.x, a->from.y, a->from.z);
- aabb.size = Vector3(a->to.x, a->to.y, a->to.z) - aabb.pos;
+ aabb.position = Vector3(a->from.x, a->from.y, a->from.z);
+ aabb.size = Vector3(a->to.x, a->to.y, a->to.z) - aabb.position;
return aabb;
}
diff --git a/modules/gridmap/grid_map_editor_plugin.cpp b/modules/gridmap/grid_map_editor_plugin.cpp
index 39fe0a1675..954e865bcd 100644
--- a/modules/gridmap/grid_map_editor_plugin.cpp
+++ b/modules/gridmap/grid_map_editor_plugin.cpp
@@ -508,146 +508,150 @@ void GridMapEditor::_duplicate_paste() {
}
}
-bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const InputEvent &p_event) {
+bool GridMapEditor::forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event) {
if (!node) {
return false;
}
if (edit_mode->get_selected() == 0) { // regular click
- switch (p_event.type) {
- case InputEvent::MOUSE_BUTTON: {
- if (p_event.mouse_button.button_index == BUTTON_WHEEL_UP && (p_event.mouse_button.mod.command || p_event.mouse_button.mod.shift)) {
- if (p_event.mouse_button.pressed)
- floor->set_value(floor->get_value() + 1);
+ Ref<InputEventMouseButton> mb = p_event;
- return true; //eaten
- } else if (p_event.mouse_button.button_index == BUTTON_WHEEL_DOWN && (p_event.mouse_button.mod.command || p_event.mouse_button.mod.shift)) {
- if (p_event.mouse_button.pressed)
- floor->set_value(floor->get_value() - 1);
- return true;
- }
+ if (mb.is_valid()) {
- if (p_event.mouse_button.pressed) {
+ if (mb->get_button_index() == BUTTON_WHEEL_UP && (mb->get_command() || mb->get_shift())) {
+ if (mb->is_pressed())
+ floor->set_value(floor->get_value() + mb->get_factor());
- if (p_event.mouse_button.button_index == BUTTON_LEFT) {
+ return true; //eaten
+ } else if (mb->get_button_index() == BUTTON_WHEEL_DOWN && (mb->get_command() || mb->get_shift())) {
+ if (mb->is_pressed())
+ floor->set_value(floor->get_value() - mb->get_factor());
+ return true;
+ }
- if (input_action == INPUT_DUPLICATE) {
+ if (mb->is_pressed()) {
- //paste
- _duplicate_paste();
- input_action = INPUT_NONE;
- _update_duplicate_indicator();
- } else if (p_event.mouse_button.mod.shift) {
- input_action = INPUT_SELECT;
- } else if (p_event.mouse_button.mod.command)
- input_action = INPUT_COPY;
- else {
- input_action = INPUT_PAINT;
- set_items.clear();
- }
- } else if (p_event.mouse_button.button_index == BUTTON_RIGHT)
- if (input_action == INPUT_DUPLICATE) {
-
- input_action = INPUT_NONE;
- _update_duplicate_indicator();
- } else {
- input_action = INPUT_ERASE;
- set_items.clear();
- }
- else
- return false;
+ if (mb->get_button_index() == BUTTON_LEFT) {
- return do_input_action(p_camera, Point2(p_event.mouse_button.x, p_event.mouse_button.y), true);
- } else {
+ if (input_action == INPUT_DUPLICATE) {
- if (
- (p_event.mouse_button.button_index == BUTTON_RIGHT && input_action == INPUT_ERASE) ||
- (p_event.mouse_button.button_index == BUTTON_LEFT && input_action == INPUT_PAINT)) {
+ //paste
+ _duplicate_paste();
+ input_action = INPUT_NONE;
+ _update_duplicate_indicator();
+ } else if (mb->get_shift()) {
+ input_action = INPUT_SELECT;
+ } else if (mb->get_command())
+ input_action = INPUT_COPY;
+ else {
+ input_action = INPUT_PAINT;
+ set_items.clear();
+ }
+ } else if (mb->get_button_index() == BUTTON_RIGHT)
+ if (input_action == INPUT_DUPLICATE) {
- if (set_items.size()) {
- undo_redo->create_action("GridMap Paint");
- for (List<SetItem>::Element *E = set_items.front(); E; E = E->next()) {
+ input_action = INPUT_NONE;
+ _update_duplicate_indicator();
+ } else {
+ input_action = INPUT_ERASE;
+ set_items.clear();
+ }
+ else
+ return false;
+
+ return do_input_action(p_camera, Point2(mb->get_position().x, mb->get_position().y), true);
+ } else {
- const SetItem &si = E->get();
- undo_redo->add_do_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.new_value, si.new_orientation);
- }
- for (List<SetItem>::Element *E = set_items.back(); E; E = E->prev()) {
+ if (
+ (mb->get_button_index() == BUTTON_RIGHT && input_action == INPUT_ERASE) ||
+ (mb->get_button_index() == BUTTON_LEFT && input_action == INPUT_PAINT)) {
- const SetItem &si = E->get();
- undo_redo->add_undo_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.old_value, si.old_orientation);
- }
+ if (set_items.size()) {
+ undo_redo->create_action("GridMap Paint");
+ for (List<SetItem>::Element *E = set_items.front(); E; E = E->next()) {
- undo_redo->commit_action();
+ const SetItem &si = E->get();
+ undo_redo->add_do_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.new_value, si.new_orientation);
}
- set_items.clear();
- input_action = INPUT_NONE;
- return true;
- }
+ for (List<SetItem>::Element *E = set_items.back(); E; E = E->prev()) {
- if (p_event.mouse_button.button_index == BUTTON_LEFT && input_action != INPUT_NONE) {
+ const SetItem &si = E->get();
+ undo_redo->add_undo_method(node, "set_cell_item", si.pos.x, si.pos.y, si.pos.z, si.old_value, si.old_orientation);
+ }
- set_items.clear();
- input_action = INPUT_NONE;
- return true;
- }
- if (p_event.mouse_button.button_index == BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_DUPLICATE)) {
- input_action = INPUT_NONE;
- return true;
+ undo_redo->commit_action();
}
+ set_items.clear();
+ input_action = INPUT_NONE;
+ return true;
+ }
+
+ if (mb->get_button_index() == BUTTON_LEFT && input_action != INPUT_NONE) {
+
+ set_items.clear();
+ input_action = INPUT_NONE;
+ return true;
+ }
+ if (mb->get_button_index() == BUTTON_RIGHT && (input_action == INPUT_ERASE || input_action == INPUT_DUPLICATE)) {
+ input_action = INPUT_NONE;
+ return true;
}
- } break;
- case InputEvent::MOUSE_MOTION: {
+ }
+ }
+
+ Ref<InputEventMouseMotion> mm = p_event;
- return do_input_action(p_camera, Point2(p_event.mouse_motion.x, p_event.mouse_motion.y), false);
- } break;
+ if (mm.is_valid()) {
+
+ return do_input_action(p_camera, mm->get_position(), false);
}
} else if (edit_mode->get_selected() == 1) {
//area mode, select an area
- switch (p_event.type) {
- case InputEvent::MOUSE_BUTTON: {
+ Ref<InputEventMouseButton> mb = p_event;
- if (p_event.mouse_button.button_index == BUTTON_LEFT && p_event.mouse_button.pressed) {
+ if (mb.is_valid()) {
- Point2 point = Point2(p_event.mouse_motion.x, p_event.mouse_motion.y);
+ if (mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
- Camera *camera = p_camera;
- Vector3 from = camera->project_ray_origin(point);
- Vector3 normal = camera->project_ray_normal(point);
- Transform local_xform = node->get_global_transform().affine_inverse();
- from = local_xform.xform(from);
- normal = local_xform.basis.xform(normal).normalized();
+ Point2 point = mb->get_position();
- List<int> areas;
- node->get_area_list(&areas);
+ Camera *camera = p_camera;
+ Vector3 from = camera->project_ray_origin(point);
+ Vector3 normal = camera->project_ray_normal(point);
+ Transform local_xform = node->get_global_transform().affine_inverse();
+ from = local_xform.xform(from);
+ normal = local_xform.basis.xform(normal).normalized();
- float min_d = 1e10;
- int min_area = -1;
+ List<int> areas;
+ node->get_area_list(&areas);
- for (List<int>::Element *E = areas.front(); E; E = E->next()) {
+ float min_d = 1e10;
+ int min_area = -1;
- int area = E->get();
- Rect3 aabb = node->area_get_bounds(area);
- aabb.pos *= node->get_cell_size();
- aabb.size *= node->get_cell_size();
+ for (List<int>::Element *E = areas.front(); E; E = E->next()) {
- Vector3 rclip, rnormal;
- if (!aabb.intersects_segment(from, from + normal * 10000, &rclip, &rnormal))
- continue;
+ int area = E->get();
+ Rect3 aabb = node->area_get_bounds(area);
+ aabb.position *= node->get_cell_size();
+ aabb.size *= node->get_cell_size();
- float d = normal.dot(rclip);
- if (d < min_d) {
- min_d = d;
- min_area = area;
- }
- }
+ Vector3 rclip, rnormal;
+ if (!aabb.intersects_segment(from, from + normal * 10000, &rclip, &rnormal))
+ continue;
- selected_area = min_area;
- update_areas();
+ float d = normal.dot(rclip);
+ if (d < min_d) {
+ min_d = d;
+ min_area = area;
+ }
}
- } break;
+
+ selected_area = min_area;
+ update_areas();
+ }
}
}
diff --git a/modules/gridmap/grid_map_editor_plugin.h b/modules/gridmap/grid_map_editor_plugin.h
index d928e6afac..1572f4fbe5 100644
--- a/modules/gridmap/grid_map_editor_plugin.h
+++ b/modules/gridmap/grid_map_editor_plugin.h
@@ -220,7 +220,7 @@ protected:
static void _bind_methods();
public:
- bool forward_spatial_input_event(Camera *p_camera, const InputEvent &p_event);
+ bool forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event);
void edit(GridMap *p_gridmap);
GridMapEditor() {}
@@ -236,7 +236,7 @@ class GridMapEditorPlugin : public EditorPlugin {
EditorNode *editor;
public:
- virtual bool forward_spatial_input_event(Camera *p_camera, const InputEvent &p_event) { return gridmap_editor->forward_spatial_input_event(p_camera, p_event); }
+ virtual bool forward_spatial_input_event(Camera *p_camera, const Ref<InputEvent> &p_event) { return gridmap_editor->forward_spatial_input_event(p_camera, p_event); }
virtual String get_name() const { return "GridMap"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
diff --git a/modules/hdr/SCsub b/modules/hdr/SCsub
new file mode 100644
index 0000000000..c960e8126b
--- /dev/null
+++ b/modules/hdr/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_hdr = env_modules.Clone()
+
+# Godot's own source files
+env_hdr.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/multiscript/config.py b/modules/hdr/config.py
index 5698a37295..fb920482f5 100644
--- a/modules/multiscript/config.py
+++ b/modules/hdr/config.py
@@ -1,5 +1,4 @@
-
def can_build(platform):
return True
diff --git a/modules/hdr/image_loader_hdr.cpp b/modules/hdr/image_loader_hdr.cpp
new file mode 100644
index 0000000000..19df27b962
--- /dev/null
+++ b/modules/hdr/image_loader_hdr.cpp
@@ -0,0 +1,161 @@
+/*************************************************************************/
+/* image_loader_jpegd.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 "image_loader_hdr.h"
+
+#include "os/os.h"
+#include "print_string.h"
+
+#include "thirdparty/tinyexr/tinyexr.h"
+
+Error ImageLoaderHDR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
+
+ String header = f->get_token();
+
+ print_line("HEADER: " + header);
+ ERR_FAIL_COND_V(header != "#?RADIANCE" && header != "#?RGBE", ERR_FILE_UNRECOGNIZED);
+
+ while (true) {
+ String format = f->get_token();
+ ERR_FAIL_COND_V(f->eof_reached(), ERR_FILE_UNRECOGNIZED);
+ if (format.begins_with("FORMAT=") && format != "FORMAT=32-bit_rle_rgbe") {
+ ERR_EXPLAIN("Only 32-bit_rle_rgbe is supported for .hdr files.");
+ return ERR_FILE_UNRECOGNIZED;
+ }
+ if (format == "FORMAT=32-bit_rle_rgbe")
+ break;
+ }
+
+ String token = f->get_token();
+
+ ERR_FAIL_COND_V(token != "-Y", ERR_FILE_CORRUPT);
+
+ int height = f->get_token().to_int();
+
+ token = f->get_token();
+
+ ERR_FAIL_COND_V(token != "+X", ERR_FILE_CORRUPT);
+
+ int width = f->get_line().to_int();
+
+ print_line("HDR w: " + itos(width) + " h:" + itos(height));
+
+ PoolVector<uint8_t> imgdata;
+
+ imgdata.resize(height * width * sizeof(uint32_t));
+
+ {
+
+ PoolVector<uint8_t>::Write w = imgdata.write();
+
+ uint8_t *ptr = (uint8_t *)w.ptr();
+
+ if (width < 8 || width >= 32768) {
+ // Read flat data
+
+ f->get_buffer(ptr, width * height * 4);
+ } else {
+ // Read RLE-encoded data
+
+ for (int j = 0; j < height; ++j) {
+ int c1 = f->get_8();
+ int c2 = f->get_8();
+ int len = f->get_8();
+ if (c1 != 2 || c2 != 2 || (len & 0x80)) {
+ // not run-length encoded, so we have to actually use THIS data as a decoded
+ // pixel (note this can't be a valid pixel--one of RGB must be >= 128)
+
+ ptr[(j * width) * 4 + 0] = uint8_t(c1);
+ ptr[(j * width) * 4 + 1] = uint8_t(c2);
+ ptr[(j * width) * 4 + 2] = uint8_t(len);
+ ptr[(j * width) * 4 + 3] = f->get_8();
+
+ f->get_buffer(&ptr[(j * width + 1) * 4], (width - 1) * 4);
+ continue;
+ }
+ len <<= 8;
+ len |= f->get_8();
+
+ print_line("line: " + itos(len));
+ if (len != width) {
+ ERR_EXPLAIN("invalid decoded scanline length, corrupt HDR");
+ ERR_FAIL_V(ERR_FILE_CORRUPT);
+ }
+
+ for (int k = 0; k < 4; ++k) {
+ int i = 0;
+ while (i < width) {
+ int count = f->get_8();
+ if (count > 128) {
+ // Run
+ int value = f->get_8();
+ count -= 128;
+ for (int z = 0; z < count; ++z)
+ ptr[(j * width + i++) * 4 + k] = uint8_t(value);
+ } else {
+ // Dump
+ for (int z = 0; z < count; ++z)
+ ptr[(j * width + i++) * 4 + k] = f->get_8();
+ }
+ }
+ }
+ }
+ }
+
+ //convert
+ for (int i = 0; i < width * height; i++) {
+
+ float exp = pow(2.0f, ptr[3] - 128.0f);
+
+ Color c(
+ ptr[0] * exp / 255.0,
+ ptr[1] * exp / 255.0,
+ ptr[2] * exp / 255.0);
+
+ if (p_force_linear) {
+ c = c.to_linear();
+ }
+
+ *(uint32_t *)ptr = c.to_rgbe9995();
+ ptr += 4;
+ }
+ }
+
+ p_image->create(width, height, false, Image::FORMAT_RGBE9995, imgdata);
+
+ return OK;
+}
+
+void ImageLoaderHDR::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("hdr");
+}
+
+ImageLoaderHDR::ImageLoaderHDR() {
+}
diff --git a/scene/3d/test_cube.h b/modules/hdr/image_loader_hdr.h
index db2bef67fe..127833ebd0 100644
--- a/scene/3d/test_cube.h
+++ b/modules/hdr/image_loader_hdr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* test_cube.h */
+/* image_loader_jpegd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,27 +27,20 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef TEST_CUBE_H
-#define TEST_CUBE_H
+#ifndef IMAGE_LOADER_HDR_H
+#define IMAGE_LOADER_HDR_H
-#include "rid.h"
-#include "scene/3d/visual_instance.h"
+#include "io/image_loader.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-class TestCube : public GeometryInstance {
-
- GDCLASS(TestCube, GeometryInstance);
-
- RID instance;
+class ImageLoaderHDR : public ImageFormatLoader {
public:
- virtual Rect3 get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
- TestCube();
- ~TestCube();
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ ImageLoaderHDR();
};
#endif
diff --git a/platform/osx/godot_osx.h b/modules/hdr/register_types.cpp
index 48784ab7d5..e4f7c14aa7 100644
--- a/platform/osx/godot_osx.h
+++ b/modules/hdr/register_types.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_osx.h */
+/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,12 +27,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef GODOT_OSX_H
-#define GODOT_OSX_H
+#include "register_types.h"
-#import <Cocoa/Cocoa.h>
+#include "image_loader_hdr.h"
-@interface GodotMain : NSObject
-@end
+static ImageLoaderHDR *image_loader_hdr = NULL;
-#endif
+void register_hdr_types() {
+
+ image_loader_hdr = memnew(ImageLoaderHDR);
+ ImageLoader::add_image_format_loader(image_loader_hdr);
+}
+
+void unregister_hdr_types() {
+
+ memdelete(image_loader_hdr);
+}
diff --git a/modules/multiscript/register_types.h b/modules/hdr/register_types.h
index b18d1adff2..3d901ea003 100644
--- a/modules/multiscript/register_types.h
+++ b/modules/hdr/register_types.h
@@ -27,5 +27,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_multiscript_types();
-void unregister_multiscript_types();
+void register_hdr_types();
+void unregister_hdr_types();
diff --git a/modules/jpg/image_loader_jpegd.cpp b/modules/jpg/image_loader_jpegd.cpp
index 83685d6446..8c73b69f1b 100644
--- a/modules/jpg/image_loader_jpegd.cpp
+++ b/modules/jpg/image_loader_jpegd.cpp
@@ -89,7 +89,7 @@ Error jpeg_load_image_from_buffer(Image *p_image, const uint8_t *p_buffer, int p
return OK;
}
-Error ImageLoaderJPG::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderJPG::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
PoolVector<uint8_t> src_image;
int src_image_len = f->get_len();
@@ -102,7 +102,7 @@ Error ImageLoaderJPG::load_image(Image *p_image, FileAccess *f) {
f->close();
- Error err = jpeg_load_image_from_buffer(p_image, w.ptr(), src_image_len);
+ Error err = jpeg_load_image_from_buffer(p_image.ptr(), w.ptr(), src_image_len);
w = PoolVector<uint8_t>::Write();
@@ -115,10 +115,11 @@ void ImageLoaderJPG::get_recognized_extensions(List<String> *p_extensions) const
p_extensions->push_back("jpeg");
}
-static Image _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
+static Ref<Image> _jpegd_mem_loader_func(const uint8_t *p_png, int p_size) {
- Image img;
- Error err = jpeg_load_image_from_buffer(&img, p_png, p_size);
+ Ref<Image> img;
+ img.instance();
+ Error err = jpeg_load_image_from_buffer(img.ptr(), p_png, p_size);
if (err)
ERR_PRINT("Couldn't initialize ImageLoaderJPG with the given resource.");
diff --git a/modules/jpg/image_loader_jpegd.h b/modules/jpg/image_loader_jpegd.h
index d23e8a7d48..aa073b493d 100644
--- a/modules/jpg/image_loader_jpegd.h
+++ b/modules/jpg/image_loader_jpegd.h
@@ -38,7 +38,7 @@
class ImageLoaderJPG : public ImageFormatLoader {
public:
- virtual Error load_image(Image *p_image, FileAccess *f);
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderJPG();
};
diff --git a/modules/multiscript/SCsub b/modules/multiscript/SCsub
deleted file mode 100644
index 0882406761..0000000000
--- a/modules/multiscript/SCsub
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-env.add_source_files(env.modules_sources, "*.cpp")
-
-Export('env')
diff --git a/modules/multiscript/multiscript.cpp b/modules/multiscript/multiscript.cpp
deleted file mode 100644
index b2633b7207..0000000000
--- a/modules/multiscript/multiscript.cpp
+++ /dev/null
@@ -1,750 +0,0 @@
-/*************************************************************************/
-/* multiscript.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 "multiscript.h"
-
-bool MultiScriptInstance::set(const StringName &p_name, const Variant &p_value) {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- bool found = sarr[i]->set(p_name, p_value);
- if (found)
- return true;
- }
-
- if (String(p_name).begins_with("script_")) {
- bool valid;
- owner->set(p_name, p_value, &valid);
- return valid;
- }
- return false;
-}
-
-bool MultiScriptInstance::get(const StringName &p_name, Variant &r_ret) const {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- bool found = sarr[i]->get(p_name, r_ret);
- if (found)
- return true;
- }
- if (String(p_name).begins_with("script_")) {
- bool valid;
- r_ret = owner->get(p_name, &valid);
- return valid;
- }
- return false;
-}
-void MultiScriptInstance::get_property_list(List<PropertyInfo> *p_properties) const {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- Set<String> existing;
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- List<PropertyInfo> pl;
- sarr[i]->get_property_list(&pl);
-
- for (List<PropertyInfo>::Element *E = pl.front(); E; E = E->next()) {
-
- if (existing.has(E->get().name))
- continue;
-
- p_properties->push_back(E->get());
- existing.insert(E->get().name);
- }
- }
-
- p_properties->push_back(PropertyInfo(Variant::NIL, "Scripts", PROPERTY_HINT_NONE, String(), PROPERTY_USAGE_CATEGORY));
-
- for (int i = 0; i < owner->scripts.size(); i++) {
-
- p_properties->push_back(PropertyInfo(Variant::OBJECT, "script_" + String::chr('a' + i), PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_EDITOR));
- }
-
- if (owner->scripts.size() < 25) {
-
- p_properties->push_back(PropertyInfo(Variant::OBJECT, "script_" + String::chr('a' + (owner->scripts.size())), PROPERTY_HINT_RESOURCE_TYPE, "Script", PROPERTY_USAGE_EDITOR));
- }
-}
-
-void MultiScriptInstance::get_method_list(List<MethodInfo> *p_list) const {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- Set<StringName> existing;
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- List<MethodInfo> ml;
- sarr[i]->get_method_list(&ml);
-
- for (List<MethodInfo>::Element *E = ml.front(); E; E = E->next()) {
-
- if (existing.has(E->get().name))
- continue;
-
- p_list->push_back(E->get());
- existing.insert(E->get().name);
- }
- }
-}
-bool MultiScriptInstance::has_method(const StringName &p_method) const {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- if (sarr[i]->has_method(p_method))
- return true;
- }
-
- return false;
-}
-
-Variant MultiScriptInstance::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- Variant r = sarr[i]->call(p_method, p_args, p_argcount, r_error);
- if (r_error.error == Variant::CallError::CALL_OK)
- return r;
- else if (r_error.error != Variant::CallError::CALL_ERROR_INVALID_METHOD)
- return r;
- }
-
- r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD;
- return Variant();
-}
-
-void MultiScriptInstance::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- sarr[i]->call_multilevel(p_method, p_args, p_argcount);
- }
-}
-void MultiScriptInstance::notification(int p_notification) {
-
- // ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- ScriptInstance *instance = instances[i];
-
- if (!instance)
- continue;
-
- instance->notification(p_notification);
- }
-}
-
-Ref<Script> MultiScriptInstance::get_script() const {
-
- return owner;
-}
-
-ScriptLanguage *MultiScriptInstance::get_language() {
-
- return MultiScriptLanguage::get_singleton();
-}
-
-MultiScriptInstance::~MultiScriptInstance() {
-
- owner->remove_instance(object);
-}
-
-Variant::Type MultiScriptInstance::get_property_type(const StringName &p_name, bool *r_is_valid) const {
- bool valid = false;
- Variant::Type type;
-
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- type = sarr[i]->get_property_type(p_name, &valid);
- if (valid) {
- *r_is_valid = valid;
- return type;
- }
- }
- *r_is_valid = false;
- return Variant::NIL;
-}
-
-ScriptInstance::RPCMode MultiScriptInstance::get_rpc_mode(const StringName &p_method) const {
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
- if (sarr[i]->has_method(p_method))
- return sarr[i]->get_rpc_mode(p_method);
- }
- return RPC_MODE_DISABLED;
-}
-
-ScriptInstance::RPCMode MultiScriptInstance::get_rset_mode(const StringName &p_variable) const {
- ScriptInstance **sarr = instances.ptr();
- int sc = instances.size();
-
- for (int i = 0; i < sc; i++) {
-
- if (!sarr[i])
- continue;
-
- List<PropertyInfo> properties;
- sarr[i]->get_property_list(&properties);
-
- for (List<PropertyInfo>::Element *P = properties.front(); P; P = P->next()) {
- if (P->get().name == p_variable) {
- return sarr[i]->get_rset_mode(p_variable);
- }
- }
- }
- return RPC_MODE_DISABLED;
-}
-
-///////////////////
-
-bool MultiScript::is_tool() const {
-
- for (int i = 0; i < scripts.size(); i++) {
-
- if (scripts[i]->is_tool())
- return true;
- }
-
- return false;
-}
-
-bool MultiScript::_set(const StringName &p_name, const Variant &p_value) {
-
- _THREAD_SAFE_METHOD_
-
- String s = String(p_name);
- if (s.begins_with("script_")) {
-
- int idx = s[7];
- if (idx == 0)
- return false;
- idx -= 'a';
-
- ERR_FAIL_COND_V(idx < 0, false);
-
- Ref<Script> s = p_value;
-
- if (idx < scripts.size()) {
-
- if (s.is_null())
- remove_script(idx);
- else
- set_script(idx, s);
- } else if (idx == scripts.size()) {
- if (s.is_null())
- return false;
- add_script(s);
- } else
- return false;
-
- return true;
- }
-
- return false;
-}
-
-bool MultiScript::_get(const StringName &p_name, Variant &r_ret) const {
-
- _THREAD_SAFE_METHOD_
-
- String s = String(p_name);
- if (s.begins_with("script_")) {
-
- int idx = s[7];
- if (idx == 0)
- return false;
- idx -= 'a';
-
- ERR_FAIL_COND_V(idx < 0, false);
-
- if (idx < scripts.size()) {
-
- r_ret = get_script(idx);
- return true;
- } else if (idx == scripts.size()) {
- r_ret = Ref<Script>();
- return true;
- }
- }
-
- return false;
-}
-void MultiScript::_get_property_list(List<PropertyInfo> *p_list) const {
-
- _THREAD_SAFE_METHOD_
-
- for (int i = 0; i < scripts.size(); i++) {
-
- p_list->push_back(PropertyInfo(Variant::OBJECT, "script_" + String::chr('a' + i), PROPERTY_HINT_RESOURCE_TYPE, "Script"));
- }
-
- if (scripts.size() < 25) {
-
- p_list->push_back(PropertyInfo(Variant::OBJECT, "script_" + String::chr('a' + (scripts.size())), PROPERTY_HINT_RESOURCE_TYPE, "Script"));
- }
-}
-
-void MultiScript::set_script(int p_idx, const Ref<Script> &p_script) {
-
- _THREAD_SAFE_METHOD_
-
- ERR_FAIL_INDEX(p_idx, scripts.size());
- ERR_FAIL_COND(p_script.is_null());
-
- scripts[p_idx] = p_script;
- Ref<Script> s = p_script;
-
- for (Map<Object *, MultiScriptInstance *>::Element *E = instances.front(); E; E = E->next()) {
-
- MultiScriptInstance *msi = E->get();
- ScriptInstance *si = msi->instances[p_idx];
- if (si) {
- msi->instances[p_idx] = NULL;
- memdelete(si);
- }
-
- if (p_script->can_instance())
- msi->instances[p_idx] = s->instance_create(msi->object);
- }
-}
-
-Ref<Script> MultiScript::get_script(int p_idx) const {
-
- _THREAD_SAFE_METHOD_
-
- ERR_FAIL_INDEX_V(p_idx, scripts.size(), Ref<Script>());
-
- return scripts[p_idx];
-}
-void MultiScript::add_script(const Ref<Script> &p_script) {
-
- _THREAD_SAFE_METHOD_
- ERR_FAIL_COND(p_script.is_null());
- Multi *script_owner = memnew(Multi);
- script_instances.push_back(script_owner);
- scripts.push_back(p_script);
- Ref<Script> s = p_script;
-
- for (Map<Object *, MultiScriptInstance *>::Element *E = instances.front(); E; E = E->next()) {
-
- MultiScriptInstance *msi = E->get();
-
- if (p_script->can_instance()) {
- script_owner->real_owner = msi->object;
- msi->instances.push_back(s->instance_create(script_owner));
- } else {
- msi->instances.push_back(NULL);
- }
-
- msi->object->_change_notify();
- }
-
- _change_notify();
-}
-
-void MultiScript::remove_script(int p_idx) {
-
- _THREAD_SAFE_METHOD_
-
- ERR_FAIL_INDEX(p_idx, scripts.size());
-
- scripts.remove(p_idx);
- script_instances.remove(p_idx);
-
- for (Map<Object *, MultiScriptInstance *>::Element *E = instances.front(); E; E = E->next()) {
-
- MultiScriptInstance *msi = E->get();
- ScriptInstance *si = msi->instances[p_idx];
- msi->instances.remove(p_idx);
- if (si) {
- memdelete(si);
- }
-
- msi->object->_change_notify();
- }
-}
-
-void MultiScript::remove_instance(Object *p_object) {
-
- _THREAD_SAFE_METHOD_
- instances.erase(p_object);
-}
-
-bool MultiScript::can_instance() const {
-
- return true;
-}
-
-StringName MultiScript::get_instance_base_type() const {
-
- return StringName();
-}
-ScriptInstance *MultiScript::instance_create(Object *p_this) {
-
- _THREAD_SAFE_METHOD_
- MultiScriptInstance *msi = memnew(MultiScriptInstance);
- msi->object = p_this;
- msi->owner = this;
-
- for (int i = 0; i < scripts.size(); i++) {
-
- ScriptInstance *si;
-
- if (scripts[i]->can_instance()) {
- script_instances[i]->real_owner = p_this;
- si = scripts[i]->instance_create(script_instances[i]);
- } else {
- si = NULL;
- }
-
- msi->instances.push_back(si);
- }
-
- instances[p_this] = msi;
- p_this->_change_notify();
- return msi;
-}
-bool MultiScript::instance_has(const Object *p_this) const {
-
- _THREAD_SAFE_METHOD_
- return instances.has((Object *)p_this);
-}
-
-bool MultiScript::has_source_code() const {
-
- return false;
-}
-String MultiScript::get_source_code() const {
-
- return "";
-}
-void MultiScript::set_source_code(const String &p_code) {
-}
-Error MultiScript::reload(bool p_keep_state) {
-
- for (int i = 0; i < scripts.size(); i++)
- scripts[i]->reload(p_keep_state);
-
- return OK;
-}
-
-String MultiScript::get_node_type() const {
-
- return "";
-}
-
-void MultiScript::_bind_methods() {
-}
-
-ScriptLanguage *MultiScript::get_language() const {
-
- return MultiScriptLanguage::get_singleton();
-}
-
-///////////////
-
-MultiScript::MultiScript() {
-}
-
-MultiScript::~MultiScript() {
- for (int i = 0; i < script_instances.size(); i++) {
- memdelete(script_instances[i]);
- }
-
- script_instances.resize(0);
-}
-
-Ref<Script> MultiScript::get_base_script() const {
- Ref<MultiScript> base_script;
- return base_script;
-}
-
-bool MultiScript::has_method(const StringName &p_method) const {
- for (int i = 0; i < scripts.size(); i++) {
- if (scripts[i]->has_method(p_method)) {
- return true;
- }
- }
- return false;
-}
-
-MethodInfo MultiScript::get_method_info(const StringName &p_method) const {
- for (int i = 0; i < scripts.size(); i++) {
- if (scripts[i]->has_method(p_method)) {
- return scripts[i]->get_method_info(p_method);
- }
- }
- return MethodInfo();
-}
-
-bool MultiScript::has_script_signal(const StringName &p_signal) const {
- for (int i = 0; i < scripts.size(); i++) {
- if (scripts[i]->has_script_signal(p_signal)) {
- return true;
- }
- }
- return false;
-}
-
-void MultiScript::get_script_signal_list(List<MethodInfo> *r_signals) const {
- for (int i = 0; i < scripts.size(); i++) {
- scripts[i]->get_script_signal_list(r_signals);
- }
-}
-
-bool MultiScript::get_property_default_value(const StringName &p_property, Variant &r_value) const {
- for (int i = 0; i < scripts.size(); i++) {
-
- if (scripts[i]->get_property_default_value(p_property, r_value)) {
- return true;
- }
- }
- return false;
-}
-
-void MultiScript::get_script_method_list(List<MethodInfo> *p_list) const {
- for (int i = 0; i < scripts.size(); i++) {
- scripts[i]->get_script_method_list(p_list);
- }
-}
-
-void MultiScript::get_script_property_list(List<PropertyInfo> *p_list) const {
- for (int i = 0; i < scripts.size(); i++) {
- scripts[i]->get_script_property_list(p_list);
- }
-}
-
-void MultiScript::update_exports() {
- for (int i = 0; i < scripts.size(); i++) {
- scripts[i]->update_exports();
- }
-}
-
-MultiScriptLanguage *MultiScriptLanguage::singleton = NULL;
-
-MultiScriptLanguage *MultiScriptLanguage::get_singleton() {
- return singleton;
-}
-
-String MultiScriptLanguage::get_name() const {
- return "MultiScript";
-}
-
-void MultiScriptLanguage::init() {}
-
-String MultiScriptLanguage::get_type() const {
- return "MultiScript";
-}
-
-String MultiScriptLanguage::get_extension() const {
- return "";
-}
-
-Error MultiScriptLanguage::execute_file(const String &p_path) {
- return OK;
-}
-
-void MultiScriptLanguage::finish() {}
-
-void MultiScriptLanguage::get_reserved_words(List<String> *p_words) const {}
-
-void MultiScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {}
-
-void MultiScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {}
-
-Ref<Script> MultiScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const {
- MultiScript *s = memnew(MultiScript);
- s->base_class_name = p_base_class_name;
- return Ref<MultiScript>(s);
-}
-
-bool MultiScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_fn) const {
- return true;
-}
-
-Script *MultiScriptLanguage::create_script() const {
- return memnew(MultiScript);
-}
-
-bool MultiScriptLanguage::has_named_classes() const {
- return false;
-}
-
-int MultiScriptLanguage::find_function(const String &p_function, const String &p_code) const {
- return -1;
-}
-
-String MultiScriptLanguage::make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const {
- return "";
-}
-
-String MultiScriptLanguage::debug_get_error() const {
- return "";
-}
-
-int MultiScriptLanguage::debug_get_stack_level_count() const {
- return 0;
-}
-
-int MultiScriptLanguage::debug_get_stack_level_line(int p_level) const {
- return 0;
-}
-
-String MultiScriptLanguage::debug_get_stack_level_function(int p_level) const {
- return "";
-}
-
-String MultiScriptLanguage::debug_get_stack_level_source(int p_level) const {
- return "";
-}
-
-void MultiScriptLanguage::debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
-
-void MultiScriptLanguage::debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
-
-void MultiScriptLanguage::debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems, int p_max_depth) {}
-
-String MultiScriptLanguage::debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems, int p_max_depth) {
- return "";
-}
-
-void MultiScriptLanguage::get_recognized_extensions(List<String> *p_extensions) const {}
-
-void MultiScriptLanguage::get_public_functions(List<MethodInfo> *p_functions) const {}
-
-MultiScriptLanguage::MultiScriptLanguage() {
- singleton = this;
-}
-
-MultiScriptLanguage::~MultiScriptLanguage() {}
-
-void MultiScriptLanguage::auto_indent_code(String &p_code, int p_from_line, int p_to_line) const {
-}
-
-void MultiScriptLanguage::add_global_constant(const StringName &p_variable, const Variant &p_value) {
-}
-
-void MultiScriptLanguage::reload_all_scripts() {
-}
-
-void MultiScriptLanguage::reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload) {
-}
-
-void MultiScriptLanguage::get_public_constants(List<Pair<String, Variant> > *p_constants) const {
-}
-
-void MultiScriptLanguage::profiling_start() {
-}
-
-void MultiScriptLanguage::profiling_stop() {
-}
-
-int MultiScriptLanguage::profiling_get_accumulated_data(ScriptLanguage::ProfilingInfo *p_info_arr, int p_info_max) {
- return 0;
-}
-
-int MultiScriptLanguage::profiling_get_frame_data(ScriptLanguage::ProfilingInfo *p_info_arr, int p_info_max) {
- return 0;
-}
-
-void Multi::_bind_methods() {
- // ClassDB::bind_method("call", &Multi::call);
- // ClassDB::bind_method("call_multilevel", &Multi::call_multilevel);
- // ClassDB::bind_method("call_multilevel_reversed", &Multi::call_multilevel_reversed);
-}
-
-Variant Multi::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) {
- if (real_owner)
- return real_owner->call(p_method, p_args, p_argcount, r_error);
- return Variant();
-}
-
-void Multi::call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount) {
- if (real_owner)
- real_owner->call_multilevel(p_method, p_args, p_argcount);
-}
-
-void Multi::call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount) {
- if (real_owner)
- real_owner->call_multilevel_reversed(p_method, p_args, p_argcount);
-}
diff --git a/modules/multiscript/multiscript.h b/modules/multiscript/multiscript.h
deleted file mode 100644
index 7ec1d5402f..0000000000
--- a/modules/multiscript/multiscript.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*************************************************************************/
-/* multiscript.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 MULTISCRIPT_H
-#define MULTISCRIPT_H
-
-#include "os/thread_safe.h"
-#include "script_language.h"
-
-class MultiScript;
-
-class Multi : public Object {
- GDCLASS(Multi, Object)
-
- friend class MultiScript;
-
- Object *real_owner;
-
-public:
- static void _bind_methods();
-
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
- virtual void call_multilevel_reversed(const StringName &p_method, const Variant **p_args, int p_argcount);
-};
-
-class MultiScriptInstance : public ScriptInstance {
- friend class MultiScript;
- mutable Vector<ScriptInstance *> instances;
- Object *object;
- mutable MultiScript *owner;
-
-public:
- virtual bool set(const StringName &p_name, const Variant &p_value);
- virtual bool get(const StringName &p_name, Variant &r_ret) const;
- virtual void get_property_list(List<PropertyInfo> *p_properties) const;
-
- virtual void get_method_list(List<MethodInfo> *p_list) const;
- virtual bool has_method(const StringName &p_method) const;
- virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error);
- virtual void call_multilevel(const StringName &p_method, const Variant **p_args, int p_argcount);
- virtual void notification(int p_notification);
-
- virtual Ref<Script> get_script() const;
-
- virtual ScriptLanguage *get_language();
- virtual ~MultiScriptInstance();
-
- // ScriptInstance interface
-public:
- Variant::Type get_property_type(const StringName &p_name, bool *r_is_valid) const;
- RPCMode get_rpc_mode(const StringName &p_method) const;
- RPCMode get_rset_mode(const StringName &p_variable) const;
-};
-
-class MultiScript : public Script {
-
- _THREAD_SAFE_CLASS_
- friend class MultiScriptInstance;
- friend class MultiScriptLanguage;
- GDCLASS(MultiScript, Script)
-
- StringName base_class_name;
-
- Vector<Ref<Script> > scripts;
- Vector<Multi *> script_instances;
-
- Map<Object *, MultiScriptInstance *> instances;
-
-protected:
- bool _set(const StringName &p_name, const Variant &p_value);
- bool _get(const StringName &p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
- static void _bind_methods();
-
-public:
- void remove_instance(Object *p_object);
- virtual bool can_instance() const;
-
- virtual StringName get_instance_base_type() const;
- virtual ScriptInstance *instance_create(Object *p_this);
- virtual bool instance_has(const Object *p_this) const;
-
- virtual bool has_source_code() const;
- virtual String get_source_code() const;
- virtual void set_source_code(const String &p_code);
- virtual Error reload(bool p_keep_state = false);
-
- virtual bool is_tool() const;
-
- virtual String get_node_type() const;
-
- void set_script(int p_idx, const Ref<Script> &p_script);
- Ref<Script> get_script(int p_idx) const;
- void remove_script(int p_idx);
- void add_script(const Ref<Script> &p_script);
-
- virtual ScriptLanguage *get_language() const;
-
- MultiScript();
- ~MultiScript();
-
- virtual Ref<Script> get_base_script() const;
- virtual bool has_method(const StringName &p_method) const;
- virtual MethodInfo get_method_info(const StringName &p_method) const;
- virtual bool has_script_signal(const StringName &p_signal) const;
- virtual void get_script_signal_list(List<MethodInfo> *r_signals) const;
- virtual bool get_property_default_value(const StringName &p_property, Variant &r_value) const;
- virtual void get_script_method_list(List<MethodInfo> *p_list) const;
- virtual void get_script_property_list(List<PropertyInfo> *p_list) const;
- virtual void update_exports();
-};
-
-class MultiScriptLanguage : public ScriptLanguage {
-
- static MultiScriptLanguage *singleton;
-
-public:
- static _FORCE_INLINE_ MultiScriptLanguage *get_singleton();
- virtual String get_name() const;
-
- /* LANGUAGE FUNCTIONS */
- virtual void init();
- virtual String get_type() const;
- virtual String get_extension() const;
- virtual Error execute_file(const String &p_path);
- virtual void finish();
-
- /* EDITOR FUNCTIONS */
- virtual void get_reserved_words(List<String> *p_words) const;
- virtual void get_comment_delimiters(List<String> *p_delimiters) const;
- virtual void get_string_delimiters(List<String> *p_delimiters) const;
- virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
- virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_fn = NULL) const;
- virtual Script *create_script() const;
- virtual bool has_named_classes() const;
- virtual int find_function(const String &p_function, const String &p_code) const;
- virtual String make_function(const String &p_class, const String &p_name, const PoolStringArray &p_args) const;
-
- /* DEBUGGER FUNCTIONS */
-
- virtual String debug_get_error() const;
- virtual int debug_get_stack_level_count() const;
- virtual int debug_get_stack_level_line(int p_level) const;
- virtual String debug_get_stack_level_function(int p_level) const;
- virtual String debug_get_stack_level_source(int p_level) const;
- virtual void debug_get_stack_level_locals(int p_level, List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
- virtual void debug_get_stack_level_members(int p_level, List<String> *p_members, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
- virtual void debug_get_globals(List<String> *p_locals, List<Variant> *p_values, int p_max_subitems = -1, int p_max_depth = -1);
- virtual String debug_parse_stack_level_expression(int p_level, const String &p_expression, int p_max_subitems = -1, int p_max_depth = -1);
-
- /* LOADER FUNCTIONS */
-
- virtual void get_recognized_extensions(List<String> *p_extensions) const;
- virtual void get_public_functions(List<MethodInfo> *p_functions) const;
-
- MultiScriptLanguage();
- virtual ~MultiScriptLanguage();
-
- // ScriptLanguage interface
-public:
- void auto_indent_code(String &p_code, int p_from_line, int p_to_line) const;
- void add_global_constant(const StringName &p_variable, const Variant &p_value);
- void reload_all_scripts();
- void reload_tool_script(const Ref<Script> &p_script, bool p_soft_reload);
- void get_public_constants(List<Pair<String, Variant> > *p_constants) const;
- void profiling_start();
- void profiling_stop();
- int profiling_get_accumulated_data(ProfilingInfo *p_info_arr, int p_info_max);
- int profiling_get_frame_data(ProfilingInfo *p_info_arr, int p_info_max);
-};
-
-#endif // MULTISCRIPT_H
diff --git a/modules/multiscript/register_types.cpp b/modules/multiscript/register_types.cpp
deleted file mode 100644
index 8170a2d9c1..0000000000
--- a/modules/multiscript/register_types.cpp
+++ /dev/null
@@ -1,51 +0,0 @@
-/*************************************************************************/
-/* 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"
-
-#include "multiscript.h"
-
-#include "core/script_language.h"
-
-static MultiScriptLanguage *script_multi_script = NULL;
-
-void register_multiscript_types() {
- script_multi_script = memnew(MultiScriptLanguage);
- ScriptServer::register_language(script_multi_script);
- ClassDB::register_class<MultiScript>();
-
- // ClassDB::register_class<Multi>();
-}
-
-void unregister_multiscript_types() {
- if (script_multi_script) {
- ScriptServer::unregister_language(script_multi_script);
- memdelete(script_multi_script);
- }
-}
diff --git a/modules/pvr/texture_loader_pvr.cpp b/modules/pvr/texture_loader_pvr.cpp
index 62cbd9cd8d..bdd4779e28 100644
--- a/modules/pvr/texture_loader_pvr.cpp
+++ b/modules/pvr/texture_loader_pvr.cpp
@@ -164,8 +164,8 @@ RES ResourceFormatPVR::load(const String &p_path, const String &p_original_path,
print_line("flip: " + itos(flags & PVR_VFLIP));
- Image image(width, height, mipmaps, format, data);
- ERR_FAIL_COND_V(image.empty(), RES());
+ Ref<Image> image = memnew(Image(width, height, mipmaps, format, data));
+ ERR_FAIL_COND_V(image->empty(), RES());
Ref<ImageTexture> texture = memnew(ImageTexture);
texture->create_from_image(image, tex_flags);
@@ -193,30 +193,32 @@ String ResourceFormatPVR::get_resource_type(const String &p_path) const {
static void _compress_pvrtc4(Image *p_img) {
- Image img = *p_img;
+ Ref<Image> img = p_img->duplicate();
bool make_mipmaps = false;
- if (img.get_width() % 8 || img.get_height() % 8) {
- make_mipmaps = img.has_mipmaps();
- img.resize(img.get_width() + (8 - (img.get_width() % 8)), img.get_height() + (8 - (img.get_height() % 8)));
+ if (img->get_width() % 8 || img->get_height() % 8) {
+ make_mipmaps = img->has_mipmaps();
+ img->resize(img->get_width() + (8 - (img->get_width() % 8)), img->get_height() + (8 - (img->get_height() % 8)));
}
- img.convert(Image::FORMAT_RGBA8);
- if (!img.has_mipmaps() && make_mipmaps)
- img.generate_mipmaps();
+ img->convert(Image::FORMAT_RGBA8);
+ if (!img->has_mipmaps() && make_mipmaps)
+ img->generate_mipmaps();
- bool use_alpha = img.detect_alpha();
+ bool use_alpha = img->detect_alpha();
- Image new_img;
- new_img.create(img.get_width(), img.get_height(), true, use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
- PoolVector<uint8_t> data = new_img.get_data();
+ Ref<Image> new_img;
+ new_img.instance();
+ new_img->create(img->get_width(), img->get_height(), true, use_alpha ? Image::FORMAT_PVRTC4A : Image::FORMAT_PVRTC4);
+
+ PoolVector<uint8_t> data = new_img->get_data();
{
PoolVector<uint8_t>::Write wr = data.write();
- PoolVector<uint8_t>::Read r = img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
- for (int i = 0; i <= new_img.get_mipmap_count(); i++) {
+ for (int i = 0; i <= new_img->get_mipmap_count(); i++) {
int ofs, size, w, h;
- img.get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
+ img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
Javelin::RgbaBitmap bm(w, h);
copymem(bm.GetData(), &r[ofs], size);
{
@@ -226,12 +228,12 @@ static void _compress_pvrtc4(Image *p_img) {
}
}
- new_img.get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
+ new_img->get_mipmap_offset_size_and_dimensions(i, ofs, size, w, h);
Javelin::PvrTcEncoder::EncodeRgba4Bpp(&wr[ofs], bm);
}
}
- *p_img = Image(new_img.get_width(), new_img.get_height(), new_img.has_mipmaps(), new_img.get_format(), data);
+ p_img->create(new_img->get_width(), new_img->get_height(), new_img->has_mipmaps(), new_img->get_format(), data);
}
ResourceFormatPVR::ResourceFormatPVR() {
@@ -676,8 +678,7 @@ static void _pvrtc_decompress(Image *p_img) {
r = PoolVector<uint8_t>::Read();
bool make_mipmaps = p_img->has_mipmaps();
- Image newimg(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
+ p_img->create(p_img->get_width(), p_img->get_height(), false, Image::FORMAT_RGBA8, newdata);
if (make_mipmaps)
- newimg.generate_mipmaps();
- *p_img = newimg;
+ p_img->generate_mipmaps();
}
diff --git a/modules/squish/image_compress_squish.cpp b/modules/squish/image_compress_squish.cpp
index 3f7ad8b2c2..efce76c805 100644
--- a/modules/squish/image_compress_squish.cpp
+++ b/modules/squish/image_compress_squish.cpp
@@ -39,63 +39,135 @@
#include <squish.h>
-void image_compress_squish(Image *p_image) {
-
+void image_decompress_squish(Image *p_image) {
int w = p_image->get_width();
int h = p_image->get_height();
- if (!p_image->has_mipmaps()) {
- ERR_FAIL_COND(!w || w % 4 != 0);
- ERR_FAIL_COND(!h || h % 4 != 0);
+ Image::Format target_format = Image::FORMAT_RGBA8;
+ PoolVector<uint8_t> data;
+ int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0);
+ int mm_count = p_image->get_mipmap_count();
+ data.resize(target_size);
+
+ PoolVector<uint8_t>::Read rb = p_image->get_data().read();
+ PoolVector<uint8_t>::Write wb = data.write();
+
+ int squish_flags = Image::FORMAT_MAX;
+ if (p_image->get_format() == Image::FORMAT_DXT1) {
+ squish_flags = squish::kDxt1;
+ } else if (p_image->get_format() == Image::FORMAT_DXT3) {
+ squish_flags = squish::kDxt3;
+ } else if (p_image->get_format() == Image::FORMAT_DXT5) {
+ squish_flags = squish::kDxt5;
+ } else if (p_image->get_format() == Image::FORMAT_RGTC_R) {
+ squish_flags = squish::kBc4;
+ } else if (p_image->get_format() == Image::FORMAT_RGTC_RG) {
+ squish_flags = squish::kBc5;
} else {
- ERR_FAIL_COND(!w || w != nearest_power_of_2(w));
- ERR_FAIL_COND(!h || h != nearest_power_of_2(h));
- };
+ print_line("wtf askd to decompress.. " + itos(p_image->get_format()));
+ ERR_FAIL_COND(true);
+ return;
+ }
+
+ int dst_ofs = 0;
+
+ for (int i = 0; i <= mm_count; i++) {
+ int src_ofs = 0, mipmap_size = 0, mipmap_w = 0, mipmap_h = 0;
+ p_image->get_mipmap_offset_size_and_dimensions(i, src_ofs, mipmap_size, mipmap_w, mipmap_h);
+ squish::DecompressImage(&wb[dst_ofs], mipmap_w, mipmap_h, &rb[src_ofs], squish_flags);
+ }
+
+ p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
+}
+
+void image_compress_squish(Image *p_image, Image::CompressSource p_source) {
if (p_image->get_format() >= Image::FORMAT_DXT1)
return; //do not compress, already compressed
- int shift = 0;
- int squish_comp = squish::kColourRangeFit;
- Image::Format target_format;
+ int w = p_image->get_width();
+ int h = p_image->get_height();
- if (p_image->get_format() == Image::FORMAT_LA8) {
- //compressed normalmap
- target_format = Image::FORMAT_DXT5;
- squish_comp |= squish::kDxt5;
- } else if (p_image->detect_alpha() != Image::ALPHA_NONE) {
+ if (p_image->get_format() <= Image::FORMAT_RGBA8) {
- target_format = Image::FORMAT_DXT3;
- squish_comp |= squish::kDxt3;
- } else {
- target_format = Image::FORMAT_DXT1;
- shift = 1;
- squish_comp |= squish::kDxt1;
- }
+ int squish_comp = squish::kColourRangeFit;
+ Image::Format target_format;
- p_image->convert(Image::FORMAT_RGBA8); //always expects rgba
+ Image::DetectChannels dc = p_image->get_detected_channels();
- PoolVector<uint8_t> data;
- int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0);
- int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0;
- data.resize(target_size);
+ p_image->convert(Image::FORMAT_RGBA8); //still uses RGBA to convert
- PoolVector<uint8_t>::Read rb = p_image->get_data().read();
- PoolVector<uint8_t>::Write wb = data.write();
+ if (p_source == Image::COMPRESS_SOURCE_SRGB && (dc == Image::DETECTED_R || dc == Image::DETECTED_RG)) {
+ //R and RG do not support SRGB
+ dc = Image::DETECTED_RGB;
+ }
- int dst_ofs = 0;
+ if (p_source == Image::COMPRESS_SOURCE_NORMAL) {
+ //R and RG do not support SRGB
+ dc = Image::DETECTED_RG;
+ }
- for (int i = 0; i <= mm_count; i++) {
+ switch (dc) {
+ case Image::DETECTED_L: {
- int src_ofs = p_image->get_mipmap_offset(i);
- squish::CompressImage(&rb[src_ofs], w, h, &wb[dst_ofs], squish_comp);
- dst_ofs += (MAX(4, w) * MAX(4, h)) >> shift;
- w >>= 1;
- h >>= 1;
- }
+ target_format = Image::FORMAT_DXT1;
+ squish_comp |= squish::kDxt1;
+ } break;
+ case Image::DETECTED_LA: {
- rb = PoolVector<uint8_t>::Read();
- wb = PoolVector<uint8_t>::Write();
+ target_format = Image::FORMAT_DXT5;
+ squish_comp |= squish::kDxt5;
+ } break;
+ case Image::DETECTED_R: {
- p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
+ target_format = Image::FORMAT_RGTC_R;
+ squish_comp |= squish::kBc4;
+ } break;
+ case Image::DETECTED_RG: {
+
+ target_format = Image::FORMAT_RGTC_RG;
+ squish_comp |= squish::kBc5;
+ } break;
+ case Image::DETECTED_RGB: {
+
+ target_format = Image::FORMAT_DXT1;
+ squish_comp |= squish::kDxt1;
+ } break;
+ case Image::DETECTED_RGBA: {
+
+ //TODO, should convert both, then measure which one does a better job
+ target_format = Image::FORMAT_DXT5;
+ squish_comp |= squish::kDxt5;
+
+ } break;
+ }
+
+ PoolVector<uint8_t> data;
+ int target_size = Image::get_image_data_size(w, h, target_format, p_image->has_mipmaps() ? -1 : 0);
+ int mm_count = p_image->has_mipmaps() ? Image::get_image_required_mipmaps(w, h, target_format) : 0;
+ data.resize(target_size);
+ int shift = Image::get_format_pixel_rshift(target_format);
+
+ PoolVector<uint8_t>::Read rb = p_image->get_data().read();
+ PoolVector<uint8_t>::Write wb = data.write();
+
+ int dst_ofs = 0;
+
+ for (int i = 0; i <= mm_count; i++) {
+
+ int bw = w % 4 != 0 ? w + (4 - w % 4) : w;
+ int bh = h % 4 != 0 ? h + (4 - h % 4) : h;
+
+ int src_ofs = p_image->get_mipmap_offset(i);
+ squish::CompressImage(&rb[src_ofs], w, h, &wb[dst_ofs], squish_comp);
+ dst_ofs += (MAX(4, bw) * MAX(4, bh)) >> shift;
+ w >>= 1;
+ h >>= 1;
+ }
+
+ rb = PoolVector<uint8_t>::Read();
+ wb = PoolVector<uint8_t>::Write();
+
+ p_image->create(p_image->get_width(), p_image->get_height(), p_image->has_mipmaps(), target_format, data);
+ }
}
diff --git a/modules/squish/image_compress_squish.h b/modules/squish/image_compress_squish.h
index 81f57c6822..68aaeefc30 100644
--- a/modules/squish/image_compress_squish.h
+++ b/modules/squish/image_compress_squish.h
@@ -32,6 +32,7 @@
#include "image.h"
-void image_compress_squish(Image *p_image);
+void image_compress_squish(Image *p_image, Image::CompressSource p_source);
+void image_decompress_squish(Image *p_image);
#endif // IMAGE_COMPRESS_SQUISH_H
diff --git a/modules/squish/register_types.cpp b/modules/squish/register_types.cpp
index 41341db93b..2eeea59836 100644
--- a/modules/squish/register_types.cpp
+++ b/modules/squish/register_types.cpp
@@ -36,6 +36,7 @@
void register_squish_types() {
Image::set_compress_bc_func(image_compress_squish);
+ Image::_image_decompress_bc = image_decompress_squish;
}
void unregister_squish_types() {}
diff --git a/modules/stb_vorbis/audio_stream_ogg_vorbis.h b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
index 287aa4ca47..46cdfd3f2d 100644
--- a/modules/stb_vorbis/audio_stream_ogg_vorbis.h
+++ b/modules/stb_vorbis/audio_stream_ogg_vorbis.h
@@ -77,7 +77,7 @@ class AudioStreamOGGVorbis : public AudioStream {
GDCLASS(AudioStreamOGGVorbis, AudioStream)
OBJ_SAVE_TYPE(AudioStream) //children are all saved as AudioStream, so they can be exchanged
- RES_BASE_EXTENSION("asogg");
+ RES_BASE_EXTENSION("oggstr");
friend class AudioStreamPlaybackOGGVorbis;
diff --git a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
index 9a3d5c2651..f0a7ee1ec6 100644
--- a/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
+++ b/modules/stb_vorbis/resource_importer_ogg_vorbis.cpp
@@ -48,7 +48,7 @@ void ResourceImporterOGGVorbis::get_recognized_extensions(List<String> *p_extens
}
String ResourceImporterOGGVorbis::get_save_extension() const {
- return "asogg";
+ return "oggstr";
}
String ResourceImporterOGGVorbis::get_resource_type() const {
@@ -99,7 +99,7 @@ Error ResourceImporterOGGVorbis::import(const String &p_source_file, const Strin
ogg_stream->set_data(data);
ogg_stream->set_loop(loop);
- return ResourceSaver::save(p_save_path + ".asogg", ogg_stream);
+ return ResourceSaver::save(p_save_path + ".oggstr", ogg_stream);
}
ResourceImporterOGGVorbis::ResourceImporterOGGVorbis() {
diff --git a/modules/tga/SCsub b/modules/tga/SCsub
new file mode 100644
index 0000000000..7e405f405c
--- /dev/null
+++ b/modules/tga/SCsub
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_tga = env_modules.Clone()
+
+# Godot's own source files
+env_tga.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/tga/config.py b/modules/tga/config.py
new file mode 100644
index 0000000000..fb920482f5
--- /dev/null
+++ b/modules/tga/config.py
@@ -0,0 +1,7 @@
+
+def can_build(platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/tga/image_loader_tga.cpp b/modules/tga/image_loader_tga.cpp
new file mode 100644
index 0000000000..5b8610b975
--- /dev/null
+++ b/modules/tga/image_loader_tga.cpp
@@ -0,0 +1,314 @@
+/*************************************************************************/
+/* image_loader_jpegd.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 "image_loader_tga.h"
+
+#include "os/os.h"
+#include "print_string.h"
+
+Error ImageLoaderTGA::decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size) {
+ Error error;
+
+ PoolVector<uint8_t> pixels;
+ error = pixels.resize(p_pixel_size);
+ if (error != OK)
+ return error;
+
+ PoolVector<uint8_t>::Write pixels_w = pixels.write();
+
+ size_t compressed_pos = 0;
+ size_t output_pos = 0;
+ size_t c = 0;
+ size_t count = 0;
+
+ while (output_pos < p_output_size) {
+ c = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ count = (c & 0x7f) + 1;
+
+ if (c & 0x80) {
+ for (int i = 0; i < p_pixel_size; i++) {
+ pixels_w.ptr()[i] = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ }
+ for (int i = 0; i < count; i++) {
+ for (int j = 0; j < p_pixel_size; j++) {
+ p_uncompressed_buffer[output_pos + j] = pixels_w.ptr()[j];
+ }
+ output_pos += p_pixel_size;
+ }
+ } else {
+ count *= p_pixel_size;
+ for (int i = 0; i < count; i++) {
+ p_uncompressed_buffer[output_pos] = p_compressed_buffer[compressed_pos];
+ compressed_pos += 1;
+ output_pos += 1;
+ }
+ }
+ }
+ return OK;
+}
+
+Error ImageLoaderTGA::convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome) {
+
+#define TGA_PUT_PIXEL(r, g, b, a) \
+ int image_data_ofs = ((y * width) + x); \
+ image_data_w[image_data_ofs * 4 + 0] = r; \
+ image_data_w[image_data_ofs * 4 + 1] = g; \
+ image_data_w[image_data_ofs * 4 + 2] = b; \
+ image_data_w[image_data_ofs * 4 + 3] = a;
+
+ uint32_t width = p_header.image_width;
+ uint32_t height = p_header.image_height;
+ tga_origin_e origin = static_cast<tga_origin_e>((p_header.image_descriptor & TGA_ORIGIN_MASK) >> TGA_ORIGIN_SHIFT);
+
+ uint32_t x_start;
+ int32_t x_step;
+ uint32_t x_end;
+ uint32_t y_start;
+ int32_t y_step;
+ uint32_t y_end;
+
+ if (origin == TGA_ORIGIN_TOP_LEFT || origin == TGA_ORIGIN_TOP_RIGHT) {
+ y_start = 0;
+ y_step = 1;
+ y_end = height;
+ } else {
+ y_start = height - 1;
+ y_step = -1;
+ y_end = -1;
+ }
+
+ if (origin == TGA_ORIGIN_TOP_LEFT || origin == TGA_ORIGIN_BOTTOM_LEFT) {
+ x_start = 0;
+ x_step = 1;
+ x_end = width;
+ } else {
+ x_start = width - 1;
+ x_step = -1;
+ x_end = -1;
+ }
+
+ PoolVector<uint8_t> image_data;
+ image_data.resize(width * height * sizeof(uint32_t));
+ PoolVector<uint8_t>::Write image_data_w = image_data.write();
+
+ size_t i = 0;
+ uint32_t x = x_start;
+ uint32_t y = y_start;
+
+ if (p_header.pixel_depth == 8) {
+ if (p_is_monochrome) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t shade = p_buffer[i];
+
+ TGA_PUT_PIXEL(shade, shade, shade, 0xff)
+
+ x += x_step;
+ i += 1;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ } else {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t index = p_buffer[i];
+ uint8_t r = 0x00;
+ uint8_t g = 0x00;
+ uint8_t b = 0x00;
+ uint8_t a = 0xff;
+
+ if (p_header.color_map_depth == 24) {
+ r = (p_palette[(index * 3) + 0]);
+ g = (p_palette[(index * 3) + 1]);
+ b = (p_palette[(index * 3) + 2]);
+ } else {
+ return ERR_INVALID_DATA;
+ }
+
+ TGA_PUT_PIXEL(r, g, b, a)
+
+ x += x_step;
+ i += 1;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ }
+ } else if (p_header.pixel_depth == 24) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t r = p_buffer[i + 2];
+ uint8_t g = p_buffer[i + 1];
+ uint8_t b = p_buffer[i + 0];
+
+ TGA_PUT_PIXEL(r, g, b, 0xff)
+
+ x += x_step;
+ i += 3;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ } else if (p_header.pixel_depth == 32) {
+ while (y != y_end) {
+ while (x != x_end) {
+ uint8_t a = p_buffer[i + 3];
+ uint8_t r = p_buffer[i + 2];
+ uint8_t g = p_buffer[i + 1];
+ uint8_t b = p_buffer[i + 0];
+
+ TGA_PUT_PIXEL(r, g, b, a)
+
+ x += x_step;
+ i += 4;
+ }
+ x = x_start;
+ y += y_step;
+ }
+ }
+
+ image_data_w = PoolVector<uint8_t>::Write();
+
+ p_image->create(width, height, 0, Image::FORMAT_RGBA8, image_data);
+
+ return OK;
+}
+
+Error ImageLoaderTGA::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
+
+ PoolVector<uint8_t> src_image;
+ int src_image_len = f->get_len();
+ ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(src_image_len < sizeof(tga_header_s), ERR_FILE_CORRUPT);
+ src_image.resize(src_image_len);
+
+ Error err = OK;
+
+ tga_header_s tga_header;
+ tga_header.id_length = f->get_8();
+ tga_header.color_map_type = f->get_8();
+ tga_header.image_type = static_cast<tga_type_e>(f->get_8());
+
+ tga_header.first_color_entry = f->get_16();
+ tga_header.color_map_length = f->get_16();
+ tga_header.color_map_depth = f->get_8();
+
+ tga_header.x_origin = f->get_16();
+ tga_header.y_origin = f->get_16();
+ tga_header.image_width = f->get_16();
+ tga_header.image_height = f->get_16();
+ tga_header.pixel_depth = f->get_8();
+ tga_header.image_descriptor = f->get_8();
+
+ bool is_encoded = (tga_header.image_type == TGA_TYPE_RLE_INDEXED || tga_header.image_type == TGA_TYPE_RLE_RGB || tga_header.image_type == TGA_TYPE_RLE_MONOCHROME);
+ bool has_color_map = (tga_header.image_type == TGA_TYPE_RLE_INDEXED || tga_header.image_type == TGA_TYPE_INDEXED);
+ bool is_monochrome = (tga_header.image_type == TGA_TYPE_RLE_MONOCHROME || tga_header.image_type == TGA_TYPE_MONOCHROME);
+
+ if (tga_header.image_type == TGA_TYPE_NO_DATA)
+ err = FAILED;
+
+ if (has_color_map) {
+ if (tga_header.color_map_length > 256 || (tga_header.color_map_depth != 24) || tga_header.color_map_type != 1) {
+ err = FAILED;
+ }
+ } else {
+ if (tga_header.color_map_type) {
+ err = FAILED;
+ }
+ }
+
+ if (tga_header.image_width <= 0 || tga_header.image_height <= 0)
+ err = FAILED;
+
+ if (tga_header.pixel_depth != 8 && tga_header.pixel_depth != 24 && tga_header.pixel_depth != 32)
+ err = FAILED;
+
+ if (err == OK) {
+ f->seek(f->get_pos() + tga_header.id_length);
+
+ PoolVector<uint8_t> palette;
+
+ if (has_color_map) {
+ size_t color_map_size = tga_header.color_map_length * (tga_header.color_map_depth >> 3);
+ err = palette.resize(color_map_size);
+ if (err == OK) {
+ PoolVector<uint8_t>::Write palette_w = palette.write();
+ f->get_buffer(&palette_w[0], color_map_size);
+ } else {
+ return OK;
+ }
+ }
+
+ PoolVector<uint8_t>::Write src_image_w = src_image.write();
+ f->get_buffer(&src_image_w[0], src_image_len - f->get_pos());
+
+ PoolVector<uint8_t>::Read src_image_r = src_image.read();
+
+ const size_t pixel_size = tga_header.pixel_depth >> 3;
+ const size_t buffer_size = (tga_header.image_width * tga_header.image_height) * pixel_size;
+
+ PoolVector<uint8_t> uncompressed_buffer;
+ uncompressed_buffer.resize(buffer_size);
+ PoolVector<uint8_t>::Write uncompressed_buffer_w = uncompressed_buffer.write();
+ PoolVector<uint8_t>::Read uncompressed_buffer_r;
+
+ const uint8_t *buffer = NULL;
+
+ if (is_encoded) {
+
+ err = decode_tga_rle(src_image_r.ptr(), pixel_size, uncompressed_buffer_w.ptr(), buffer_size);
+
+ if (err == OK) {
+ uncompressed_buffer_r = uncompressed_buffer.read();
+ buffer = uncompressed_buffer_r.ptr();
+ }
+ } else {
+ buffer = src_image_r.ptr();
+ };
+
+ if (err == OK) {
+ PoolVector<uint8_t>::Read palette_r = palette.read();
+ err = convert_to_image(p_image, buffer, tga_header, palette_r.ptr(), is_monochrome);
+ }
+ }
+
+ f->close();
+ return err;
+}
+
+void ImageLoaderTGA::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("tga");
+}
+
+ImageLoaderTGA::ImageLoaderTGA() {
+}
diff --git a/platform/osx/context_gl_osx.h b/modules/tga/image_loader_tga.h
index d0e2a2c0d3..11329ec68a 100644
--- a/platform/osx/context_gl_osx.h
+++ b/modules/tga/image_loader_tga.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* context_gl_osx.h */
+/* image_loader_jpegd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,38 +27,57 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef CONTEXT_GL_OSX_H
-#define CONTEXT_GL_OSX_H
+#ifndef IMAGE_LOADER_TGA_H
+#define IMAGE_LOADER_TGA_H
+
+#include "io/image_loader.h"
/**
- @author Juan Linietsky <reduzio@gmail.com>
+ @author SaracenOne
*/
-#ifdef OSX_ENABLED
+class ImageLoaderTGA : public ImageFormatLoader {
+ enum tga_type_e {
+ TGA_TYPE_NO_DATA = 0,
+ TGA_TYPE_INDEXED = 1,
+ TGA_TYPE_RGB = 2,
+ TGA_TYPE_MONOCHROME = 3,
+ TGA_TYPE_RLE_INDEXED = 9,
+ TGA_TYPE_RLE_RGB = 10,
+ TGA_TYPE_RLE_MONOCHROME = 11
+ };
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
+ enum tga_origin_e {
+ TGA_ORIGIN_BOTTOM_LEFT = 0x00,
+ TGA_ORIGIN_BOTTOM_RIGHT = 0x01,
+ TGA_ORIGIN_TOP_LEFT = 0x02,
+ TGA_ORIGIN_TOP_RIGHT = 0x03,
+ TGA_ORIGIN_SHIFT = 0x04,
+ TGA_ORIGIN_MASK = 0x30
+ };
-#include "drivers/gl_context/context_gl.h"
-#include "os/os.h"
-#include <AGL/agl.h>
-#include <Carbon/Carbon.h>
+ struct tga_header_s {
+ uint8_t id_length;
+ uint8_t color_map_type;
+ tga_type_e image_type;
-class ContextGL_OSX : public ContextGL {
+ uint16_t first_color_entry;
+ uint16_t color_map_length;
+ uint8_t color_map_depth;
- AGLContext context;
- WindowRef window;
+ uint16_t x_origin;
+ uint16_t y_origin;
+ uint16_t image_width;
+ uint16_t image_height;
+ uint8_t pixel_depth;
+ uint8_t image_descriptor;
+ };
+ static Error decode_tga_rle(const uint8_t *p_compressed_buffer, size_t p_pixel_size, uint8_t *p_uncompressed_buffer, size_t p_output_size);
+ static Error convert_to_image(Ref<Image> p_image, const uint8_t *p_buffer, const tga_header_s &p_header, const uint8_t *p_palette, const bool p_is_monochrome);
public:
- virtual void release_current();
- virtual void make_current();
- virtual void swap_buffers();
-
- virtual Error initialize();
-
- ContextGL_OSX(WindowRef window);
- ~ContextGL_OSX();
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ ImageLoaderTGA();
};
#endif
-
-#endif
-#endif
diff --git a/scene/resources/baked_light.h b/modules/tga/register_types.cpp
index 8d25c9caa2..6e120fa3bf 100644
--- a/scene/resources/baked_light.h
+++ b/modules/tga/register_types.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* baked_light.h */
+/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,10 +27,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef BAKED_LIGHT_H
-#define BAKED_LIGHT_H
+#include "register_types.h"
-#include "resource.h"
-#include "scene/resources/texture.h"
+#include "image_loader_tga.h"
-#endif // BAKED_LIGHT_H
+static ImageLoaderTGA *image_loader_tga = NULL;
+
+void register_tga_types() {
+
+ image_loader_tga = memnew(ImageLoaderTGA);
+ ImageLoader::add_image_format_loader(image_loader_tga);
+}
+
+void unregister_tga_types() {
+
+ memdelete(image_loader_tga);
+}
diff --git a/platform/bb10/platform_config.h b/modules/tga/register_types.h
index 48bcadcc29..079b7bf291 100644
--- a/platform/bb10/platform_config.h
+++ b/modules/tga/register_types.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* platform_config.h */
+/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,4 +27,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include <alloca.h>
+void register_tga_types();
+void unregister_tga_types();
diff --git a/modules/theora/video_stream_theora.cpp b/modules/theora/video_stream_theora.cpp
index 61112f20b4..d895f60280 100644
--- a/modules/theora/video_stream_theora.cpp
+++ b/modules/theora/video_stream_theora.cpp
@@ -138,7 +138,7 @@ void VideoStreamPlaybackTheora::video_write(void) {
format = Image::FORMAT_RGBA8;
}
- Image img(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data); //zero copy image creation
+ Ref<Image> img = memnew(Image(size.x, size.y, 0, Image::FORMAT_RGBA8, frame_data)); //zero copy image creation
texture->set_data(img); //zero copy send to visual server
diff --git a/modules/tinyexr/SCsub b/modules/tinyexr/SCsub
new file mode 100644
index 0000000000..38fd00cc65
--- /dev/null
+++ b/modules/tinyexr/SCsub
@@ -0,0 +1,20 @@
+#!/usr/bin/env python
+
+Import('env')
+Import('env_modules')
+
+env_tinyexr = env_modules.Clone()
+
+# Thirdparty source files
+# Not unbundled for now as they are not commonly available as shared library
+thirdparty_dir = "#thirdparty/tinyexr/"
+thirdparty_sources = [
+ "tinyexr.cc",
+]
+thirdparty_sources = [thirdparty_dir + file for file in thirdparty_sources]
+
+env_tinyexr.add_source_files(env.modules_sources, thirdparty_sources)
+env_tinyexr.Append(CPPPATH=[thirdparty_dir])
+
+# Godot's own source files
+env_tinyexr.add_source_files(env.modules_sources, "*.cpp")
diff --git a/modules/tinyexr/config.py b/modules/tinyexr/config.py
new file mode 100644
index 0000000000..fb920482f5
--- /dev/null
+++ b/modules/tinyexr/config.py
@@ -0,0 +1,7 @@
+
+def can_build(platform):
+ return True
+
+
+def configure(env):
+ pass
diff --git a/modules/tinyexr/image_loader_tinyexr.cpp b/modules/tinyexr/image_loader_tinyexr.cpp
new file mode 100644
index 0000000000..4eb91da10b
--- /dev/null
+++ b/modules/tinyexr/image_loader_tinyexr.cpp
@@ -0,0 +1,168 @@
+/*************************************************************************/
+/* image_loader_jpegd.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 "image_loader_tinyexr.h"
+
+#include "os/os.h"
+#include "print_string.h"
+
+#include "thirdparty/tinyexr/tinyexr.h"
+
+Error ImageLoaderTinyEXR::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
+
+ PoolVector<uint8_t> src_image;
+ int src_image_len = f->get_len();
+ ERR_FAIL_COND_V(src_image_len == 0, ERR_FILE_CORRUPT);
+ src_image.resize(src_image_len);
+
+ PoolVector<uint8_t>::Write w = src_image.write();
+
+ f->get_buffer(&w[0], src_image_len);
+
+ f->close();
+
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+ const char *err = NULL;
+
+ InitEXRHeader(&exr_header);
+
+ int ret = ParseEXRVersionFromMemory(&exr_version, w.ptr(), src_image_len);
+ if (ret != TINYEXR_SUCCESS) {
+
+ return ERR_FILE_CORRUPT;
+ }
+
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, w.ptr(), src_image_len, &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ ERR_PRINTS(String(err));
+ }
+ return ERR_FILE_CORRUPT;
+ }
+
+ InitEXRImage(&exr_image);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, w.ptr(), src_image_len, &err);
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ ERR_PRINTS(String(err));
+ }
+ return ERR_FILE_CORRUPT;
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ int idxA = -1;
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ if (strcmp(exr_header.channels[c].name, "R") == 0) {
+ idxR = c;
+ } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
+ idxG = c;
+ } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
+ idxB = c;
+ } else if (strcmp(exr_header.channels[c].name, "A") == 0) {
+ idxA = c;
+ }
+ }
+
+ if (idxR == -1) {
+ ERR_PRINT("R channel not found");
+ // @todo { free exr_image }
+ return ERR_FILE_CORRUPT;
+ }
+
+ if (idxG == -1) {
+ ERR_PRINT("G channel not found\n")
+ // @todo { free exr_image }
+ return ERR_FILE_CORRUPT;
+ }
+
+ if (idxB == -1) {
+ ERR_PRINT("B channel not found\n")
+ // @todo { free exr_image }
+ return ERR_FILE_CORRUPT;
+ }
+
+ PoolVector<uint8_t> imgdata;
+ Image::Format format;
+
+ if (idxA > 0) {
+
+ imgdata.resize(exr_image.width * exr_image.height * 8); //RGBA16
+ format = Image::FORMAT_RGBAH;
+ } else {
+
+ imgdata.resize(exr_image.width * exr_image.height * 6); //RGB16
+ format = Image::FORMAT_RGBH;
+ }
+
+ {
+
+ PoolVector<uint8_t>::Write wd = imgdata.write();
+ uint16_t *iw = (uint16_t *)wd.ptr();
+
+ // Assume `out_rgba` have enough memory allocated.
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+
+ Color color(
+ reinterpret_cast<float **>(exr_image.images)[idxR][i],
+ reinterpret_cast<float **>(exr_image.images)[idxG][i],
+ reinterpret_cast<float **>(exr_image.images)[idxB][i]);
+
+ if (p_force_linear)
+ color = color.to_linear();
+
+ *iw++ = Math::make_half_float(color.r);
+ *iw++ = Math::make_half_float(color.g);
+ *iw++ = Math::make_half_float(color.b);
+
+ if (idxA > 0) {
+ *iw++ = Math::make_half_float(reinterpret_cast<float **>(exr_image.images)[idxA][i]);
+ }
+ }
+ }
+
+ print_line("EXR w: " + itos(exr_image.width) + " h:" + itos(exr_image.height) + " format " + Image::get_format_name(format));
+ p_image->create(exr_image.width, exr_image.height, false, format, imgdata);
+
+ w = PoolVector<uint8_t>::Write();
+
+ return OK;
+}
+
+void ImageLoaderTinyEXR::get_recognized_extensions(List<String> *p_extensions) const {
+
+ p_extensions->push_back("exr");
+}
+
+ImageLoaderTinyEXR::ImageLoaderTinyEXR() {
+}
diff --git a/platform/bb10/power_bb10.h b/modules/tinyexr/image_loader_tinyexr.h
index c5c18d5f69..a52894b12b 100644
--- a/platform/bb10/power_bb10.h
+++ b/modules/tinyexr/image_loader_tinyexr.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* power_bb10.h */
+/* image_loader_jpegd.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,25 +27,20 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#ifndef IMAGE_LOADER_TINYEXR_H
+#define IMAGE_LOADER_TINYEXR_H
-#ifndef PLATFORM_BB10_POWER_BB10_H_
-#define PLATFORM_BB10_POWER_BB10_H_
+#include "io/image_loader.h"
-class PowerBB10 {
-private:
- int nsecs_left;
- int percent_left;
- PowerState power_state;
-
- bool UpdatePowerInfo();
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class ImageLoaderTinyEXR : public ImageFormatLoader {
public:
- PowerBB10();
- virtual ~PowerBB10();
-
- PowerState get_power_state();
- int get_power_seconds_left();
- int get_power_percent_left();
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
+ virtual void get_recognized_extensions(List<String> *p_extensions) const;
+ ImageLoaderTinyEXR();
};
-#endif /* PLATFORM_BB10_POWER_BB10_H_ */
+#endif
diff --git a/platform/bb10/godot_bb10.cpp b/modules/tinyexr/register_types.cpp
index 4d382ddd15..73f3131276 100644
--- a/platform/bb10/godot_bb10.cpp
+++ b/modules/tinyexr/register_types.cpp
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* godot_bb10.cpp */
+/* register_types.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,22 +27,19 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "main/main.h"
-#include "os_bb10.h"
+#include "register_types.h"
-#include <unistd.h>
+#include "image_loader_tinyexr.h"
-int main(int argc, char *argv[]) {
+static ImageLoaderTinyEXR *image_loader_tinyexr = NULL;
- OSBB10 os;
+void register_tinyexr_types() {
- Error err = Main::setup(argv[0], argc - 1, &argv[1]);
- if (err != OK)
- return 255;
+ image_loader_tinyexr = memnew(ImageLoaderTinyEXR);
+ ImageLoader::add_image_format_loader(image_loader_tinyexr);
+}
- if (Main::start())
- os.run(); // it is actually the OS that decides how to run
- Main::cleanup();
+void unregister_tinyexr_types() {
- return os.get_exit_code();
+ memdelete(image_loader_tinyexr);
}
diff --git a/platform/bb10/export/export.h b/modules/tinyexr/register_types.h
index 7939754bfa..f3c7372359 100644
--- a/platform/bb10/export/export.h
+++ b/modules/tinyexr/register_types.h
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* export.h */
+/* register_types.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -27,4 +27,5 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_bb10_exporter();
+void register_tinyexr_types();
+void unregister_tinyexr_types();
diff --git a/modules/visual_script/register_types.cpp b/modules/visual_script/register_types.cpp
index 4006ad3428..c0467a901b 100644
--- a/modules/visual_script/register_types.cpp
+++ b/modules/visual_script/register_types.cpp
@@ -88,7 +88,7 @@ void register_visual_script_types() {
ClassDB::register_class<VisualScriptWhile>();
ClassDB::register_class<VisualScriptIterator>();
ClassDB::register_class<VisualScriptSequence>();
- ClassDB::register_class<VisualScriptInputFilter>();
+ //ClassDB::register_class<VisualScriptInputFilter>();
ClassDB::register_class<VisualScriptSwitch>();
ClassDB::register_class<VisualScriptYield>();
diff --git a/modules/visual_script/visual_script.cpp b/modules/visual_script/visual_script.cpp
index aec60391d3..bb8111ce99 100644
--- a/modules/visual_script/visual_script.cpp
+++ b/modules/visual_script/visual_script.cpp
@@ -2369,6 +2369,17 @@ Ref<Script> VisualScriptLanguage::get_template(const String &p_class_name, const
script->set_instance_base_type(p_base_class_name);
return script;
}
+
+bool VisualScriptLanguage::is_using_templates() {
+
+ return true;
+}
+
+void VisualScriptLanguage::make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script) {
+ Ref<VisualScript> script = p_script;
+ script->set_instance_base_type(p_base_class_name);
+}
+
bool VisualScriptLanguage::validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path, List<String> *r_functions) const {
return false;
diff --git a/modules/visual_script/visual_script.h b/modules/visual_script/visual_script.h
index 273a819611..1ccc358342 100644
--- a/modules/visual_script/visual_script.h
+++ b/modules/visual_script/visual_script.h
@@ -89,13 +89,11 @@ public:
struct TypeGuess {
Variant::Type type;
- InputEvent::Type ev_type;
StringName GDCLASS;
Ref<Script> script;
TypeGuess() {
type = Variant::NIL;
- ev_type = InputEvent::NONE;
}
};
@@ -566,6 +564,8 @@ public:
virtual void get_comment_delimiters(List<String> *p_delimiters) const;
virtual void get_string_delimiters(List<String> *p_delimiters) const;
virtual Ref<Script> get_template(const String &p_class_name, const String &p_base_class_name) const;
+ virtual bool is_using_templates();
+ virtual void make_template(const String &p_class_name, const String &p_base_class_name, Ref<Script> &p_script);
virtual bool validate(const String &p_script, int &r_line_error, int &r_col_error, String &r_test_error, const String &p_path = "", List<String> *r_functions = NULL) const;
virtual Script *create_script() const;
virtual bool has_named_classes() const;
diff --git a/modules/visual_script/visual_script_editor.cpp b/modules/visual_script/visual_script_editor.cpp
index d515f301ce..941668d474 100644
--- a/modules/visual_script/visual_script_editor.cpp
+++ b/modules/visual_script/visual_script_editor.cpp
@@ -346,11 +346,9 @@ static Color _color_from_type(Variant::Type p_type) {
case Variant::TRANSFORM: color = Color::html("f6a86e"); break;
case Variant::COLOR: color = Color::html("9dff70"); break;
- case Variant::IMAGE: color = Color::html("93f1b9"); break;
case Variant::NODE_PATH: color = Color::html("6993ec"); break;
case Variant::_RID: color = Color::html("69ec9a"); break;
case Variant::OBJECT: color = Color::html("79f3e8"); break;
- case Variant::INPUT_EVENT: color = Color::html("adf18f"); break;
case Variant::DICTIONARY: color = Color::html("77edb1"); break;
case Variant::ARRAY: color = Color::html("e0e0e0"); break;
@@ -451,11 +449,9 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
Control::get_icon("MiniBasis", "EditorIcons"),
Control::get_icon("MiniTransform", "EditorIcons"),
Control::get_icon("MiniColor", "EditorIcons"),
- Control::get_icon("MiniImage", "EditorIcons"),
Control::get_icon("MiniPath", "EditorIcons"),
Control::get_icon("MiniRid", "EditorIcons"),
Control::get_icon("MiniObject", "EditorIcons"),
- Control::get_icon("MiniInput", "EditorIcons"),
Control::get_icon("MiniDictionary", "EditorIcons"),
Control::get_icon("MiniArray", "EditorIcons"),
Control::get_icon("MiniRawArray", "EditorIcons"),
@@ -490,7 +486,7 @@ void VisualScriptEditor::_update_graph(int p_only_id) {
}
if (EditorSettings::get_singleton()->has("editors/visual_script/color_" + node->get_category())) {
- gnode->set_self_modulate(EditorSettings::get_singleton()->get("editors/visual_script/color_" + node->get_category()));
+ gnode->set_modulate(EditorSettings::get_singleton()->get("editors/visual_script/color_" + node->get_category()));
}
gnode->set_meta("__vnode", node);
@@ -735,11 +731,9 @@ void VisualScriptEditor::_update_members() {
Control::get_icon("MiniMatrix3", "EditorIcons"),
Control::get_icon("MiniTransform", "EditorIcons"),
Control::get_icon("MiniColor", "EditorIcons"),
- Control::get_icon("MiniImage", "EditorIcons"),
Control::get_icon("MiniPath", "EditorIcons"),
Control::get_icon("MiniRid", "EditorIcons"),
Control::get_icon("MiniObject", "EditorIcons"),
- Control::get_icon("MiniInput", "EditorIcons"),
Control::get_icon("MiniDictionary", "EditorIcons"),
Control::get_icon("MiniArray", "EditorIcons"),
Control::get_icon("MiniRawArray", "EditorIcons"),
@@ -1017,7 +1011,7 @@ void VisualScriptEditor::_member_button(Object *p_item, int p_column, int p_butt
}
Rect2 pos = members->get_item_rect(ti);
- new_function_menu->set_position(members->get_global_position() + pos.pos + Vector2(0, pos.size.y));
+ new_function_menu->set_position(members->get_global_position() + pos.position + Vector2(0, pos.size.y));
new_function_menu->popup();
return;
} else if (p_button == 0) {
@@ -1422,9 +1416,11 @@ void VisualScriptEditor::_on_nodes_duplicate() {
}
}
-void VisualScriptEditor::_input(const InputEvent &p_event) {
+void VisualScriptEditor::_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
revert_on_drag = String(); //so we can still drag functions
}
}
@@ -2244,6 +2240,10 @@ void VisualScriptEditor::add_callback(const String &p_function, PoolStringArray
//undo_redo->clear_history();
}
+bool VisualScriptEditor::show_members_overview() {
+ return false;
+}
+
void VisualScriptEditor::update_settings() {
_update_graph();
@@ -2643,7 +2643,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
} else {
n->set_call_mode(VisualScriptPropertySet::CALL_MODE_BASIC_TYPE);
n->set_basic_type(tg.type);
- new_connect_node_select->select_property_from_basic_type(tg.type, tg.ev_type);
+ new_connect_node_select->select_property_from_basic_type(tg.type);
}
} break;
case CREATE_GET: {
@@ -2673,7 +2673,7 @@ void VisualScriptEditor::_port_action_menu(int p_option) {
} else {
n->set_call_mode(VisualScriptPropertyGet::CALL_MODE_BASIC_TYPE);
n->set_basic_type(tg.type);
- new_connect_node_select->select_property_from_basic_type(tg.type, tg.ev_type);
+ new_connect_node_select->select_property_from_basic_type(tg.type);
}
} break;
@@ -2833,7 +2833,7 @@ void VisualScriptEditor::_node_filter_changed(const String &p_text) {
void VisualScriptEditor::_notification(int p_what) {
if (p_what == NOTIFICATION_READY) {
- node_filter_icon->set_texture(Control::get_icon("Search", "EditorIcons"));
+ node_filter_icon->set_texture(Control::get_icon("Zoom", "EditorIcons"));
}
}
diff --git a/modules/visual_script/visual_script_editor.h b/modules/visual_script/visual_script_editor.h
index 1fd97cc1bc..92f31f20da 100644
--- a/modules/visual_script/visual_script_editor.h
+++ b/modules/visual_script/visual_script_editor.h
@@ -196,7 +196,7 @@ class VisualScriptEditor : public ScriptEditorBase {
String revert_on_drag;
- void _input(const InputEvent &p_event);
+ void _input(const Ref<InputEvent> &p_event);
void _on_nodes_delete();
void _on_nodes_duplicate();
@@ -248,6 +248,7 @@ public:
virtual void get_breakpoints(List<int> *p_breakpoints);
virtual void add_callback(const String &p_function, PoolStringArray p_args);
virtual void update_settings();
+ virtual bool show_members_overview();
virtual void set_debugger_active(bool p_active);
virtual void set_tooltip_request_func(String p_method, Object *p_obj);
virtual Control *get_edit_menu();
diff --git a/modules/visual_script/visual_script_flow_control.cpp b/modules/visual_script/visual_script_flow_control.cpp
index 2deb6064d3..07d69db207 100644
--- a/modules/visual_script/visual_script_flow_control.cpp
+++ b/modules/visual_script/visual_script_flow_control.cpp
@@ -734,6 +734,7 @@ VisualScriptSwitch::VisualScriptSwitch() {
////////////////EVENT ACTION FILTER///////////
//////////////////////////////////////////
+#if 0
int VisualScriptInputFilter::get_output_sequence_port_count() const {
return filters.size();
@@ -758,86 +759,86 @@ String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const
String text;
switch (filters[p_port].type) {
- case InputEvent::NONE: {
+ case Ref<InputEvent>::NONE: {
text = "None";
} break;
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
InputEventKey k = filters[p_port].key;
- if (k.scancode == 0 && k.unicode == 0) {
+ if (k->get_scancode() == 0 && k.unicode == 0) {
text = "No Key";
} else {
- if (k.scancode != 0) {
- text = "KeyCode: " + keycode_get_string(k.scancode);
+ if (k->get_scancode() != 0) {
+ text = "KeyCode: " + keycode_get_string(k->get_scancode());
} else if (k.unicode != 0) {
text = "Uniode: " + String::chr(k.unicode);
}
- if (k.pressed)
+ if (k->is_pressed())
text += ", Pressed";
else
text += ", Released";
if (k.echo)
text += ", Echo";
- if (k.mod.alt)
+ if (k->get_alt())
text = "Alt+" + text;
- if (k.mod.shift)
+ if (k->get_shift())
text = "Shift+" + text;
- if (k.mod.control)
+ if (k->get_control())
text = "Ctrl+" + text;
- if (k.mod.meta)
+ if (k->get_metakey())
text = "Meta+" + text;
}
} break;
- case InputEvent::MOUSE_MOTION: {
+ case Ref<InputEvent>::MOUSE_MOTION: {
InputEventMouseMotion mm = filters[p_port].mouse_motion;
text = "Mouse Motion";
String b = "Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight";
for (int i = 0; i < 7; i++) {
- if (mm.button_mask & (1 << i)) {
+ if (mm->get_button_mask() & (1 << i)) {
text = b.get_slice(",", i) + "+" + text;
}
}
- if (mm.mod.alt)
+ if (mm->get_alt())
text = "Alt+" + text;
- if (mm.mod.shift)
+ if (mm->get_shift())
text = "Shift+" + text;
- if (mm.mod.control)
+ if (mm->get_control())
text = "Ctrl+" + text;
- if (mm.mod.meta)
+ if (mm->get_metakey())
text = "Meta+" + text;
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
InputEventMouseButton mb = filters[p_port].mouse_button;
String b = "Any,Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight";
- text = b.get_slice(",", mb.button_index) + " Mouse Button";
+ text = b.get_slice(",", mb->get_button_index()) + " Mouse Button";
- if (mb.pressed)
+ if (mb->is_pressed())
text += ", Pressed";
else
text += ", Released";
if (mb.doubleclick)
text += ", DblClick";
- if (mb.mod.alt)
+ if (mb->get_alt())
text = "Alt+" + text;
- if (mb.mod.shift)
+ if (mb->get_shift())
text = "Shift+" + text;
- if (mb.mod.control)
+ if (mb->get_control())
text = "Ctrl+" + text;
- if (mb.mod.meta)
+ if (mb->get_metakey())
text = "Meta+" + text;
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
InputEventJoypadMotion jm = filters[p_port].joy_motion;
@@ -848,29 +849,29 @@ String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const
text += " < " + rtos(-jm.axis_value);
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
InputEventJoypadButton jb = filters[p_port].joy_button;
- text = "JoyButton " + itos(jb.button_index);
- if (jb.pressed)
+ text = "JoyButton " + itos(jb->get_button_index());
+ if (jb->is_pressed())
text += ", Pressed";
else
text += ", Released";
} break;
- case InputEvent::SCREEN_TOUCH: {
+ case Ref<InputEvent>::SCREEN_TOUCH: {
InputEventScreenTouch sd = filters[p_port].screen_touch;
text = "Touch Finger " + itos(sd.index);
- if (sd.pressed)
+ if (sd->is_pressed())
text += ", Pressed";
else
text += ", Released";
} break;
- case InputEvent::SCREEN_DRAG: {
+ case Ref<InputEvent>::SCREEN_DRAG: {
InputEventScreenDrag sd = filters[p_port].screen_drag;
text = "Drag Finger " + itos(sd.index);
} break;
- case InputEvent::ACTION: {
+ case Ref<InputEvent>::ACTION: {
List<PropertyInfo> pinfo;
GlobalConfig::get_singleton()->get_property_list(&pinfo);
@@ -890,7 +891,7 @@ String VisualScriptInputFilter::get_output_sequence_port_text(int p_port) const
index++;
}
- if (filters[p_port].action.pressed)
+ if (filters[p_port].action->is_pressed())
text += ", Pressed";
else
text += ", Released";
@@ -939,20 +940,20 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
String what = String(p_name).get_slice("/", 1);
if (what == "type") {
- filters[idx] = InputEvent();
- filters[idx].type = InputEvent::Type(int(p_value));
- if (filters[idx].type == InputEvent::JOYPAD_MOTION) {
+ filters[idx] = Ref<InputEvent>();
+ filters[idx].type = Ref<InputEvent>::Type(int(p_value));
+ if (filters[idx].type == Ref<InputEvent>::JOYPAD_MOTION) {
filters[idx].joy_motion.axis_value = 0.5; //for treshold
- } else if (filters[idx].type == InputEvent::KEY) {
- filters[idx].key.pressed = true; //put these as true to make it more user friendly
- } else if (filters[idx].type == InputEvent::MOUSE_BUTTON) {
- filters[idx].mouse_button.pressed = true;
- } else if (filters[idx].type == InputEvent::JOYPAD_BUTTON) {
- filters[idx].joy_button.pressed = true;
- } else if (filters[idx].type == InputEvent::SCREEN_TOUCH) {
- filters[idx].screen_touch.pressed = true;
- } else if (filters[idx].type == InputEvent::ACTION) {
- filters[idx].action.pressed = true;
+ } else if (filters[idx].type == Ref<InputEvent>::KEY) {
+ filters[idx]->is_pressed() = true; //put these as true to make it more user friendly
+ } else if (filters[idx].type == Ref<InputEvent>::MOUSE_BUTTON) {
+ filters[idx]->is_pressed() = true;
+ } else if (filters[idx].type == Ref<InputEvent>::JOYPAD_BUTTON) {
+ filters[idx].joy_button->is_pressed() = true;
+ } else if (filters[idx].type == Ref<InputEvent>::SCREEN_TOUCH) {
+ filters[idx].screen_touch->is_pressed() = true;
+ } else if (filters[idx].type == Ref<InputEvent>::ACTION) {
+ filters[idx].action->is_pressed() = true;
}
_change_notify();
ports_changed_notify();
@@ -967,14 +968,14 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
switch (filters[idx].type) {
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
if (what == "scancode") {
String sc = p_value;
if (sc == String()) {
- filters[idx].key.scancode = 0;
+ filters[idx]->get_scancode() = 0;
} else {
- filters[idx].key.scancode = find_keycode(p_value);
+ filters[idx]->get_scancode() = find_keycode(p_value);
}
} else if (what == "unicode") {
@@ -989,22 +990,22 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
} else if (what == "pressed") {
- filters[idx].key.pressed = p_value;
+ filters[idx]->is_pressed() = p_value;
} else if (what == "echo") {
- filters[idx].key.echo = p_value;
+ filters[idx]->is_echo() = p_value;
} else if (what == "mod_alt") {
- filters[idx].key.mod.alt = p_value;
+ filters[idx]->get_alt() = p_value;
} else if (what == "mod_shift") {
- filters[idx].key.mod.shift = p_value;
+ filters[idx]->get_shift() = p_value;
} else if (what == "mod_ctrl") {
- filters[idx].key.mod.control = p_value;
+ filters[idx]->get_control() = p_value;
} else if (what == "mod_meta") {
- filters[idx].key.mod.meta = p_value;
+ filters[idx]->get_metakey() = p_value;
} else {
return false;
}
@@ -1012,22 +1013,22 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
return true;
} break;
- case InputEvent::MOUSE_MOTION: {
+ case Ref<InputEvent>::MOUSE_MOTION: {
if (what == "button_mask") {
- filters[idx].mouse_motion.button_mask = p_value;
+ filters[idx]->get_button_mask() = p_value;
} else if (what == "mod_alt") {
- filters[idx].mouse_motion.mod.alt = p_value;
+ filters[idx].mouse_motion->get_alt() = p_value;
} else if (what == "mod_shift") {
- filters[idx].mouse_motion.mod.shift = p_value;
+ filters[idx].mouse_motion->get_shift() = p_value;
} else if (what == "mod_ctrl") {
- filters[idx].mouse_motion.mod.control = p_value;
+ filters[idx].mouse_motion->get_control() = p_value;
} else if (what == "mod_meta") {
- filters[idx].mouse_motion.mod.meta = p_value;
+ filters[idx].mouse_motion->get_metakey() = p_value;
} else {
return false;
}
@@ -1036,26 +1037,26 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
return true;
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
if (what == "button_index") {
- filters[idx].mouse_button.button_index = p_value;
+ filters[idx]->get_button_index() = p_value;
} else if (what == "pressed") {
- filters[idx].mouse_button.pressed = p_value;
+ filters[idx]->is_pressed() = p_value;
} else if (what == "doubleclicked") {
filters[idx].mouse_button.doubleclick = p_value;
} else if (what == "mod_alt") {
- filters[idx].mouse_button.mod.alt = p_value;
+ filters[idx].mouse_button->get_alt() = p_value;
} else if (what == "mod_shift") {
- filters[idx].mouse_button.mod.shift = p_value;
+ filters[idx].mouse_button->get_shift() = p_value;
} else if (what == "mod_ctrl") {
- filters[idx].mouse_button.mod.control = p_value;
+ filters[idx].mouse_button->get_control() = p_value;
} else if (what == "mod_meta") {
- filters[idx].mouse_button.mod.meta = p_value;
+ filters[idx].mouse_button->get_metakey() = p_value;
} else {
return false;
}
@@ -1063,7 +1064,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
return true;
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
if (what == "axis") {
filters[idx].joy_motion.axis = int(p_value) << 1 | filters[idx].joy_motion.axis;
@@ -1078,12 +1079,12 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
return true;
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
if (what == "button_index") {
- filters[idx].joy_button.button_index = p_value;
+ filters[idx].joy_button->get_button_index() = p_value;
} else if (what == "pressed") {
- filters[idx].joy_button.pressed = p_value;
+ filters[idx].joy_button->is_pressed() = p_value;
} else {
return false;
}
@@ -1091,19 +1092,19 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
return true;
} break;
- case InputEvent::SCREEN_TOUCH: {
+ case Ref<InputEvent>::SCREEN_TOUCH: {
if (what == "finger_index") {
filters[idx].screen_touch.index = p_value;
} else if (what == "pressed") {
- filters[idx].screen_touch.pressed = p_value;
+ filters[idx].screen_touch->is_pressed() = p_value;
} else {
return false;
}
ports_changed_notify();
return true;
} break;
- case InputEvent::SCREEN_DRAG: {
+ case Ref<InputEvent>::SCREEN_DRAG: {
if (what == "finger_index") {
filters[idx].screen_drag.index = p_value;
} else {
@@ -1112,7 +1113,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
ports_changed_notify();
return true;
} break;
- case InputEvent::ACTION: {
+ case Ref<InputEvent>::ACTION: {
if (what == "action_name") {
@@ -1144,7 +1145,7 @@ bool VisualScriptInputFilter::_set(const StringName &p_name, const Variant &p_va
} else if (what == "pressed") {
- filters[idx].action.pressed = p_value;
+ filters[idx].action->is_pressed() = p_value;
ports_changed_notify();
return true;
}
@@ -1181,14 +1182,14 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
switch (filters[idx].type) {
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
if (what == "scancode") {
- if (filters[idx].key.scancode == 0)
+ if (filters[idx]->get_scancode() == 0)
r_ret = String();
else {
- r_ret = keycode_get_string(filters[idx].key.scancode);
+ r_ret = keycode_get_string(filters[idx]->get_scancode());
}
} else if (what == "unicode") {
@@ -1202,44 +1203,44 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
} else if (what == "pressed") {
- r_ret = filters[idx].key.pressed;
+ r_ret = filters[idx]->is_pressed();
} else if (what == "echo") {
- r_ret = filters[idx].key.echo;
+ r_ret = filters[idx]->is_echo();
} else if (what == "mod_alt") {
- r_ret = filters[idx].key.mod.alt;
+ r_ret = filters[idx]->get_alt();
} else if (what == "mod_shift") {
- r_ret = filters[idx].key.mod.shift;
+ r_ret = filters[idx]->get_shift();
} else if (what == "mod_ctrl") {
- r_ret = filters[idx].key.mod.control;
+ r_ret = filters[idx]->get_control();
} else if (what == "mod_meta") {
- r_ret = filters[idx].key.mod.meta;
+ r_ret = filters[idx]->get_metakey();
} else {
return false;
}
return true;
} break;
- case InputEvent::MOUSE_MOTION: {
+ case Ref<InputEvent>::MOUSE_MOTION: {
if (what == "button_mask") {
- r_ret = filters[idx].mouse_motion.button_mask;
+ r_ret = filters[idx]->get_button_mask();
} else if (what == "mod_alt") {
- r_ret = filters[idx].mouse_motion.mod.alt;
+ r_ret = filters[idx].mouse_motion->get_alt();
} else if (what == "mod_shift") {
- r_ret = filters[idx].mouse_motion.mod.shift;
+ r_ret = filters[idx].mouse_motion->get_shift();
} else if (what == "mod_ctrl") {
- r_ret = filters[idx].mouse_motion.mod.control;
+ r_ret = filters[idx].mouse_motion->get_control();
} else if (what == "mod_meta") {
- r_ret = filters[idx].mouse_motion.mod.meta;
+ r_ret = filters[idx].mouse_motion->get_metakey();
} else {
return false;
}
@@ -1247,33 +1248,33 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
return true;
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
if (what == "button_index") {
- r_ret = filters[idx].mouse_button.button_index;
+ r_ret = filters[idx]->get_button_index();
} else if (what == "pressed") {
- r_ret = filters[idx].mouse_button.pressed;
+ r_ret = filters[idx]->is_pressed();
} else if (what == "doubleclicked") {
r_ret = filters[idx].mouse_button.doubleclick;
} else if (what == "mod_alt") {
- r_ret = filters[idx].mouse_button.mod.alt;
+ r_ret = filters[idx].mouse_button->get_alt();
} else if (what == "mod_shift") {
- r_ret = filters[idx].mouse_button.mod.shift;
+ r_ret = filters[idx].mouse_button->get_shift();
} else if (what == "mod_ctrl") {
- r_ret = filters[idx].mouse_button.mod.control;
+ r_ret = filters[idx].mouse_button->get_control();
} else if (what == "mod_meta") {
- r_ret = filters[idx].mouse_button.mod.meta;
+ r_ret = filters[idx].mouse_button->get_metakey();
} else {
return false;
}
return true;
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
if (what == "axis_index") {
r_ret = filters[idx].joy_motion.axis >> 1;
@@ -1287,30 +1288,30 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
return true;
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
if (what == "button_index") {
- r_ret = filters[idx].joy_button.button_index;
+ r_ret = filters[idx].joy_button->get_button_index();
} else if (what == "pressed") {
- r_ret = filters[idx].joy_button.pressed;
+ r_ret = filters[idx].joy_button->is_pressed();
} else {
return false;
}
return true;
} break;
- case InputEvent::SCREEN_TOUCH: {
+ case Ref<InputEvent>::SCREEN_TOUCH: {
if (what == "finger_index") {
r_ret = filters[idx].screen_touch.index;
} else if (what == "pressed") {
- r_ret = filters[idx].screen_touch.pressed;
+ r_ret = filters[idx].screen_touch->is_pressed();
} else {
return false;
}
return true;
} break;
- case InputEvent::SCREEN_DRAG: {
+ case Ref<InputEvent>::SCREEN_DRAG: {
if (what == "finger_index") {
r_ret = filters[idx].screen_drag.index;
} else {
@@ -1318,7 +1319,7 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
}
return true;
} break;
- case InputEvent::ACTION: {
+ case Ref<InputEvent>::ACTION: {
if (what == "action_name") {
@@ -1344,7 +1345,7 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
} else if (what == "pressed") {
- r_ret = filters[idx].action.pressed;
+ r_ret = filters[idx].action->is_pressed();
return true;
}
@@ -1354,7 +1355,7 @@ bool VisualScriptInputFilter::_get(const StringName &p_name, Variant &r_ret) con
return false;
}
-static const char *event_type_names[InputEvent::TYPE_MAX] = {
+static const char *event_type_names[Ref<InputEvent>::TYPE_MAX] = {
"None",
"Key",
"MouseMotion",
@@ -1371,7 +1372,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::INT, "filter_count", PROPERTY_HINT_RANGE, "0,64"));
String et;
- for (int i = 0; i < InputEvent::TYPE_MAX; i++) {
+ for (int i = 0; i < Ref<InputEvent>::TYPE_MAX; i++) {
if (i > 0)
et += ",";
@@ -1388,10 +1389,10 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::INT, base + "device"));
switch (filters[i].type) {
- case InputEvent::NONE: {
+ case Ref<InputEvent>::NONE: {
} break;
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
if (kc == String()) {
int kcc = keycode_get_count();
kc = "None";
@@ -1410,7 +1411,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
} break;
- case InputEvent::MOUSE_MOTION: {
+ case Ref<InputEvent>::MOUSE_MOTION: {
p_list->push_back(PropertyInfo(Variant::INT, base + "button_mask", PROPERTY_HINT_FLAGS, "Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_alt"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_shift"));
@@ -1418,7 +1419,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
p_list->push_back(PropertyInfo(Variant::INT, base + "button_index", PROPERTY_HINT_ENUM, "Any,Left,Right,Middle,WheelUp,WheelDown,WheelLeft,WheelRight"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "doubleclicked"));
@@ -1428,26 +1429,26 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
p_list->push_back(PropertyInfo(Variant::BOOL, base + "mod_meta"));
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
p_list->push_back(PropertyInfo(Variant::INT, base + "axis_index"));
p_list->push_back(PropertyInfo(Variant::INT, base + "mode", PROPERTY_HINT_ENUM, "Min,Max"));
p_list->push_back(PropertyInfo(Variant::REAL, base + "treshold", PROPERTY_HINT_RANGE, "0,1,0.01"));
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
p_list->push_back(PropertyInfo(Variant::INT, base + "button_index"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
} break;
- case InputEvent::SCREEN_TOUCH: {
+ case Ref<InputEvent>::SCREEN_TOUCH: {
p_list->push_back(PropertyInfo(Variant::INT, base + "finger_index"));
p_list->push_back(PropertyInfo(Variant::BOOL, base + "pressed"));
} break;
- case InputEvent::SCREEN_DRAG: {
+ case Ref<InputEvent>::SCREEN_DRAG: {
p_list->push_back(PropertyInfo(Variant::INT, base + "finger_index"));
} break;
- case InputEvent::ACTION: {
+ case Ref<InputEvent>::ACTION: {
if (actions == String()) {
@@ -1485,7 +1486,7 @@ void VisualScriptInputFilter::_get_property_list(List<PropertyInfo> *p_list) con
class VisualScriptNodeInstanceInputFilter : public VisualScriptNodeInstance {
public:
VisualScriptInstance *instance;
- Vector<InputEvent> filters;
+ Vector<Ref<InputEvent>> filters;
//virtual int get_working_memory_size() const { return 0; }
//virtual bool is_output_port_unsequenced(int p_idx) const { return false; }
@@ -1499,11 +1500,11 @@ public:
return 0;
}
- InputEvent event = *p_inputs[0];
+ Ref<InputEvent> event = *p_inputs[0];
for (int i = 0; i < filters.size(); i++) {
- const InputEvent &ie = filters[i];
+ const Ref<InputEvent> &ie = filters[i];
if (ie.type != event.type)
continue;
@@ -1511,25 +1512,25 @@ public:
switch (ie.type) {
- case InputEvent::NONE: {
+ case Ref<InputEvent>::NONE: {
match = true;
} break;
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
InputEventKey k = ie.key;
InputEventKey k2 = event.key;
- if (k.scancode == 0 && k.unicode == 0 && k2.scancode == 0 && k2.unicode == 0) {
+ if (k->get_scancode() == 0 && k.unicode == 0 && k2->get_scancode() == 0 && k2.unicode == 0) {
match = true;
} else {
- if ((k.scancode != 0 && k.scancode == k2.scancode) || (k.unicode != 0 && k.unicode == k2.unicode)) {
+ if ((k->get_scancode() != 0 && k->get_scancode() == k2->get_scancode()) || (k.unicode != 0 && k.unicode == k2.unicode)) {
//key valid
if (
- k.pressed == k2.pressed &&
+ k->is_pressed() == k2->is_pressed() &&
k.echo == k2.echo &&
k.mod == k2.mod) {
match = true;
@@ -1538,30 +1539,30 @@ public:
}
} break;
- case InputEvent::MOUSE_MOTION: {
+ case Ref<InputEvent>::MOUSE_MOTION: {
InputEventMouseMotion mm = ie.mouse_motion;
InputEventMouseMotion mm2 = event.mouse_motion;
- if (mm.button_mask == mm2.button_mask &&
+ if (mm->get_button_mask() == mm2->get_button_mask() &&
mm.mod == mm2.mod) {
match = true;
}
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
InputEventMouseButton mb = ie.mouse_button;
InputEventMouseButton mb2 = event.mouse_button;
- if (mb.button_index == mb2.button_index &&
- mb.pressed == mb2.pressed &&
+ if (mb->get_button_index() == mb2->get_button_index() &&
+ mb->is_pressed() == mb2->is_pressed() &&
mb.doubleclick == mb2.doubleclick &&
mb.mod == mb2.mod) {
match = true;
}
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
InputEventJoypadMotion jm = ie.joy_motion;
InputEventJoypadMotion jm2 = event.joy_motion;
@@ -1584,26 +1585,26 @@ public:
}
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
InputEventJoypadButton jb = ie.joy_button;
InputEventJoypadButton jb2 = event.joy_button;
- if (jb.button_index == jb2.button_index &&
- jb.pressed == jb2.pressed) {
+ if (jb->get_button_index() == jb2->get_button_index() &&
+ jb->is_pressed() == jb2->is_pressed()) {
match = true;
}
} break;
- case InputEvent::SCREEN_TOUCH: {
+ case Ref<InputEvent>::SCREEN_TOUCH: {
InputEventScreenTouch st = ie.screen_touch;
InputEventScreenTouch st2 = event.screen_touch;
if (st.index == st2.index &&
- st.pressed == st2.pressed) {
+ st->is_pressed() == st2->is_pressed()) {
match = true;
}
} break;
- case InputEvent::SCREEN_DRAG: {
+ case Ref<InputEvent>::SCREEN_DRAG: {
InputEventScreenDrag sd = ie.screen_drag;
InputEventScreenDrag sd2 = event.screen_drag;
@@ -1611,13 +1612,13 @@ public:
match = true;
}
} break;
- case InputEvent::ACTION: {
+ case Ref<InputEvent>::ACTION: {
InputEventAction ia = ie.action;
InputEventAction ia2 = event.action;
if (ia.action == ia2.action &&
- ia.pressed == ia2.pressed) {
+ ia->is_pressed() == ia2->is_pressed()) {
match = true;
}
} break;
@@ -1643,7 +1644,7 @@ VisualScriptNodeInstance *VisualScriptInputFilter::instance(VisualScriptInstance
VisualScriptInputFilter::VisualScriptInputFilter() {
}
-
+#endif
//////////////////////////////////////////
////////////////TYPE CAST///////////
//////////////////////////////////////////
@@ -1832,6 +1833,6 @@ void register_visual_script_flow_control_nodes() {
VisualScriptLanguage::singleton->add_register_func("flow_control/iterator", create_node_generic<VisualScriptIterator>);
VisualScriptLanguage::singleton->add_register_func("flow_control/sequence", create_node_generic<VisualScriptSequence>);
VisualScriptLanguage::singleton->add_register_func("flow_control/switch", create_node_generic<VisualScriptSwitch>);
- VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>);
+ //VisualScriptLanguage::singleton->add_register_func("flow_control/input_filter", create_node_generic<VisualScriptInputFilter>);
VisualScriptLanguage::singleton->add_register_func("flow_control/type_cast", create_node_generic<VisualScriptTypeCast>);
}
diff --git a/modules/visual_script/visual_script_flow_control.h b/modules/visual_script/visual_script_flow_control.h
index e3936da9e5..314804602e 100644
--- a/modules/visual_script/visual_script_flow_control.h
+++ b/modules/visual_script/visual_script_flow_control.h
@@ -228,11 +228,12 @@ public:
VisualScriptSwitch();
};
+#if 0
class VisualScriptInputFilter : public VisualScriptNode {
GDCLASS(VisualScriptInputFilter, VisualScriptNode)
- Vector<InputEvent> filters;
+ Vector<Ref<InputEvent>> filters;
protected:
bool _set(const StringName &p_name, const Variant &p_value);
@@ -259,7 +260,7 @@ public:
VisualScriptInputFilter();
};
-
+#endif
class VisualScriptTypeCast : public VisualScriptNode {
GDCLASS(VisualScriptTypeCast, VisualScriptNode)
diff --git a/modules/visual_script/visual_script_func_nodes.cpp b/modules/visual_script/visual_script_func_nodes.cpp
index 84224dfcbe..b466e64aec 100644
--- a/modules/visual_script/visual_script_func_nodes.cpp
+++ b/modules/visual_script/visual_script_func_nodes.cpp
@@ -943,18 +943,6 @@ static Ref<VisualScriptNode> create_function_call_node(const String &p_name) {
////////////////SET//////////////////////
//////////////////////////////////////////
-static const char *event_type_names[InputEvent::TYPE_MAX] = {
- "None",
- "Key",
- "MouseMotion",
- "MouseButton",
- "JoypadMotion",
- "JoypadButton",
- "ScreenTouch",
- "ScreenDrag",
- "Action"
-};
-
int VisualScriptPropertySet::get_output_sequence_port_count() const {
return call_mode != CALL_MODE_BASIC_TYPE ? 1 : 0;
@@ -1119,24 +1107,6 @@ Variant::Type VisualScriptPropertySet::get_basic_type() const {
return basic_type;
}
-void VisualScriptPropertySet::set_event_type(InputEvent::Type p_type) {
-
- if (event_type == p_type)
- return;
- event_type = p_type;
- if (call_mode == CALL_MODE_BASIC_TYPE) {
- _update_cache();
- }
- _change_notify();
- _update_base_type();
- ports_changed_notify();
-}
-
-InputEvent::Type VisualScriptPropertySet::get_event_type() const {
-
- return event_type;
-}
-
void VisualScriptPropertySet::set_base_type(const StringName &p_type) {
if (base_type == p_type)
@@ -1182,14 +1152,8 @@ void VisualScriptPropertySet::_update_cache() {
//not super efficient..
Variant v;
- if (basic_type == Variant::INPUT_EVENT) {
- InputEvent ev;
- ev.type = event_type;
- v = ev;
- } else {
- Variant::CallError ce;
- v = Variant::construct(basic_type, NULL, 0, ce);
- }
+ Variant::CallError ce;
+ v = Variant::construct(basic_type, NULL, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -1341,12 +1305,6 @@ void VisualScriptPropertySet::_validate_property(PropertyInfo &property) const {
}
}
- if (property.name == "property/event_type") {
- if (call_mode != CALL_MODE_BASIC_TYPE || basic_type != Variant::INPUT_EVENT) {
- property.usage = 0;
- }
- }
-
if (property.name == "property/node_path") {
if (call_mode != CALL_MODE_NODE_PATH) {
property.usage = 0;
@@ -1418,9 +1376,6 @@ void VisualScriptPropertySet::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertySet::_set_type_cache);
ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertySet::_get_type_cache);
- ClassDB::bind_method(D_METHOD("set_event_type", "event_type"), &VisualScriptPropertySet::set_event_type);
- ClassDB::bind_method(D_METHOD("get_event_type"), &VisualScriptPropertySet::get_event_type);
-
ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertySet::set_property);
ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertySet::get_property);
@@ -1438,14 +1393,6 @@ void VisualScriptPropertySet::_bind_methods() {
bt += Variant::get_type_name(Variant::Type(i));
}
- String et;
- for (int i = 0; i < InputEvent::TYPE_MAX; i++) {
- if (i > 0)
- et += ",";
-
- et += event_type_names[i];
- }
-
List<String> script_extensions;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
@@ -1463,7 +1410,6 @@ void VisualScriptPropertySet::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "property/base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
ADD_PROPERTY(PropertyInfo(Variant::INT, "property/type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache");
ADD_PROPERTY(PropertyInfo(Variant::INT, "property/basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "property/event_type", PROPERTY_HINT_ENUM, et), "set_event_type", "get_event_type");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "property/node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "property/property"), "set_property", "get_property");
@@ -1574,7 +1520,6 @@ VisualScriptPropertySet::VisualScriptPropertySet() {
call_mode = CALL_MODE_SELF;
base_type = "Object";
basic_type = Variant::NIL;
- event_type = InputEvent::NONE;
}
template <VisualScriptPropertySet::CallMode cmode>
@@ -1764,14 +1709,8 @@ void VisualScriptPropertyGet::_update_cache() {
//not super efficient..
Variant v;
- if (basic_type == Variant::INPUT_EVENT) {
- InputEvent ev;
- ev.type = event_type;
- v = ev;
- } else {
- Variant::CallError ce;
- v = Variant::construct(basic_type, NULL, 0, ce);
- }
+ Variant::CallError ce;
+ v = Variant::construct(basic_type, NULL, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -1919,24 +1858,6 @@ Variant::Type VisualScriptPropertyGet::get_basic_type() const {
return basic_type;
}
-void VisualScriptPropertyGet::set_event_type(InputEvent::Type p_type) {
-
- if (event_type == p_type)
- return;
- event_type = p_type;
- if (call_mode == CALL_MODE_BASIC_TYPE) {
- _update_cache();
- }
- _change_notify();
- _update_base_type();
- ports_changed_notify();
-}
-
-InputEvent::Type VisualScriptPropertyGet::get_event_type() const {
-
- return event_type;
-}
-
void VisualScriptPropertyGet::_set_type_cache(Variant::Type p_type) {
type_cache = p_type;
}
@@ -1965,11 +1886,6 @@ void VisualScriptPropertyGet::_validate_property(PropertyInfo &property) const {
property.usage = 0;
}
}
- if (property.name == "property/event_type") {
- if (call_mode != CALL_MODE_BASIC_TYPE || basic_type != Variant::INPUT_EVENT) {
- property.usage = 0;
- }
- }
if (property.name == "property/node_path") {
if (call_mode != CALL_MODE_NODE_PATH) {
@@ -2041,9 +1957,6 @@ void VisualScriptPropertyGet::_bind_methods() {
ClassDB::bind_method(D_METHOD("_set_type_cache", "type_cache"), &VisualScriptPropertyGet::_set_type_cache);
ClassDB::bind_method(D_METHOD("_get_type_cache"), &VisualScriptPropertyGet::_get_type_cache);
- ClassDB::bind_method(D_METHOD("set_event_type", "event_type"), &VisualScriptPropertyGet::set_event_type);
- ClassDB::bind_method(D_METHOD("get_event_type"), &VisualScriptPropertyGet::get_event_type);
-
ClassDB::bind_method(D_METHOD("set_property", "property"), &VisualScriptPropertyGet::set_property);
ClassDB::bind_method(D_METHOD("get_property"), &VisualScriptPropertyGet::get_property);
@@ -2061,14 +1974,6 @@ void VisualScriptPropertyGet::_bind_methods() {
bt += Variant::get_type_name(Variant::Type(i));
}
- String et;
- for (int i = 0; i < InputEvent::TYPE_MAX; i++) {
- if (i > 0)
- et += ",";
-
- et += event_type_names[i];
- }
-
List<String> script_extensions;
for (int i = 0; i < ScriptServer::get_language_count(); i++) {
ScriptServer::get_language(i)->get_recognized_extensions(&script_extensions);
@@ -2086,7 +1991,6 @@ void VisualScriptPropertyGet::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "property/base_script", PROPERTY_HINT_FILE, script_ext_hint), "set_base_script", "get_base_script");
ADD_PROPERTY(PropertyInfo(Variant::INT, "property/type_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_type_cache", "_get_type_cache");
ADD_PROPERTY(PropertyInfo(Variant::INT, "property/basic_type", PROPERTY_HINT_ENUM, bt), "set_basic_type", "get_basic_type");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "property/event_type", PROPERTY_HINT_ENUM, et), "set_event_type", "get_event_type");
ADD_PROPERTY(PropertyInfo(Variant::NODE_PATH, "property/node_path", PROPERTY_HINT_NODE_PATH_TO_EDITED_NODE), "set_base_path", "get_base_path");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "property/property"), "set_property", "get_property");
@@ -2184,7 +2088,6 @@ VisualScriptPropertyGet::VisualScriptPropertyGet() {
call_mode = CALL_MODE_SELF;
base_type = "Object";
basic_type = Variant::NIL;
- event_type = InputEvent::NONE;
type_cache = Variant::NIL;
}
diff --git a/modules/visual_script/visual_script_func_nodes.h b/modules/visual_script/visual_script_func_nodes.h
index b56a3c2bcc..3b284952c5 100644
--- a/modules/visual_script/visual_script_func_nodes.h
+++ b/modules/visual_script/visual_script_func_nodes.h
@@ -155,7 +155,6 @@ private:
String base_script;
NodePath base_path;
StringName property;
- InputEvent::Type event_type;
Node *_get_base_node() const;
StringName _get_base_type() const;
@@ -197,9 +196,6 @@ public:
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
- void set_event_type(InputEvent::Type p_type);
- InputEvent::Type get_event_type() const;
-
void set_property(const StringName &p_type);
StringName get_property() const;
@@ -238,7 +234,6 @@ private:
String base_script;
NodePath base_path;
StringName property;
- InputEvent::Type event_type;
void _update_base_type();
Node *_get_base_node() const;
@@ -279,9 +274,6 @@ public:
void set_basic_type(Variant::Type p_type);
Variant::Type get_basic_type() const;
- void set_event_type(InputEvent::Type p_type);
- InputEvent::Type get_event_type() const;
-
void set_property(const StringName &p_type);
StringName get_property() const;
diff --git a/modules/visual_script/visual_script_nodes.cpp b/modules/visual_script/visual_script_nodes.cpp
index 08f4191d3d..8ea3b8098d 100644
--- a/modules/visual_script/visual_script_nodes.cpp
+++ b/modules/visual_script/visual_script_nodes.cpp
@@ -3460,14 +3460,8 @@ void VisualScriptDeconstruct::_update_elements() {
elements.clear();
Variant v;
- if (type == Variant::INPUT_EVENT) {
- InputEvent ie;
- ie.type = input_type;
- v = ie;
- } else {
- Variant::CallError ce;
- v = Variant::construct(type, NULL, 0, ce);
- }
+ Variant::CallError ce;
+ v = Variant::construct(type, NULL, 0, ce);
List<PropertyInfo> pinfo;
v.get_property_list(&pinfo);
@@ -3497,21 +3491,6 @@ Variant::Type VisualScriptDeconstruct::get_deconstruct_type() const {
return type;
}
-void VisualScriptDeconstruct::set_deconstruct_input_type(InputEvent::Type p_input_type) {
-
- if (input_type == p_input_type)
- return;
-
- input_type = p_input_type;
- _update_elements();
- ports_changed_notify();
-}
-
-InputEvent::Type VisualScriptDeconstruct::get_deconstruct_input_type() const {
-
- return input_type;
-}
-
void VisualScriptDeconstruct::_set_elem_cache(const Array &p_elements) {
ERR_FAIL_COND(p_elements.size() % 2 == 1);
@@ -3570,12 +3549,6 @@ VisualScriptNodeInstance *VisualScriptDeconstruct::instance(VisualScriptInstance
}
void VisualScriptDeconstruct::_validate_property(PropertyInfo &property) const {
-
- if (property.name == "input_type") {
- if (type != Variant::INPUT_EVENT) {
- property.usage = 0;
- }
- }
}
void VisualScriptDeconstruct::_bind_methods() {
@@ -3583,9 +3556,6 @@ void VisualScriptDeconstruct::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_deconstruct_type", "type"), &VisualScriptDeconstruct::set_deconstruct_type);
ClassDB::bind_method(D_METHOD("get_deconstruct_type"), &VisualScriptDeconstruct::get_deconstruct_type);
- ClassDB::bind_method(D_METHOD("set_deconstruct_input_type", "input_type"), &VisualScriptDeconstruct::set_deconstruct_input_type);
- ClassDB::bind_method(D_METHOD("get_deconstruct_input_type"), &VisualScriptDeconstruct::get_deconstruct_input_type);
-
ClassDB::bind_method(D_METHOD("_set_elem_cache", "_cache"), &VisualScriptDeconstruct::_set_elem_cache);
ClassDB::bind_method(D_METHOD("_get_elem_cache"), &VisualScriptDeconstruct::_get_elem_cache);
@@ -3594,17 +3564,13 @@ void VisualScriptDeconstruct::_bind_methods() {
argt += "," + Variant::get_type_name(Variant::Type(i));
}
- String iet = "None,Key,MouseMotion,MouseButton,JoypadMotion,JoypadButton,ScreenTouch,ScreenDrag,Action";
-
ADD_PROPERTY(PropertyInfo(Variant::INT, "type", PROPERTY_HINT_ENUM, argt), "set_deconstruct_type", "get_deconstruct_type");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "input_type", PROPERTY_HINT_ENUM, iet), "set_deconstruct_input_type", "get_deconstruct_input_type");
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "elem_cache", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_elem_cache", "_get_elem_cache");
}
VisualScriptDeconstruct::VisualScriptDeconstruct() {
type = Variant::NIL;
- input_type = InputEvent::NONE;
}
void register_visual_script_nodes() {
diff --git a/modules/visual_script/visual_script_nodes.h b/modules/visual_script/visual_script_nodes.h
index c0933d1a78..402093fa80 100644
--- a/modules/visual_script/visual_script_nodes.h
+++ b/modules/visual_script/visual_script_nodes.h
@@ -923,7 +923,6 @@ class VisualScriptDeconstruct : public VisualScriptNode {
void _update_elements();
Variant::Type type;
- InputEvent::Type input_type;
void _set_elem_cache(const Array &p_elements);
Array _get_elem_cache() const;
@@ -952,9 +951,6 @@ public:
void set_deconstruct_type(Variant::Type p_type);
Variant::Type get_deconstruct_type() const;
- void set_deconstruct_input_type(InputEvent::Type p_input_type);
- InputEvent::Type get_deconstruct_input_type() const;
-
virtual VisualScriptNodeInstance *instance(VisualScriptInstance *p_instance);
VisualScriptDeconstruct();
diff --git a/modules/webm/libvpx/SCsub b/modules/webm/libvpx/SCsub
index 241d6e30cd..0ee2ed45b8 100644
--- a/modules/webm/libvpx/SCsub
+++ b/modules/webm/libvpx/SCsub
@@ -273,7 +273,7 @@ else:
webm_cpu_x86 = True
else:
webm_cpu_x86 = not is_x11_or_server_arm and (cpu_bits == '32' or cpu_bits == '64') and (env["platform"] == 'windows' or env["platform"] == 'x11' or env["platform"] == 'osx' or env["platform"] == 'haiku' or is_android_x86 or is_ios_x86)
- webm_cpu_arm = is_x11_or_server_arm or (not is_ios_x86 and env["platform"] == 'iphone') or env["platform"] == 'bb10' or (not is_android_x86 and env["platform"] == 'android')
+ webm_cpu_arm = is_x11_or_server_arm or (not is_ios_x86 and env["platform"] == 'iphone') or (not is_android_x86 and env["platform"] == 'android')
if webm_cpu_x86:
import subprocess
diff --git a/modules/webp/image_loader_webp.cpp b/modules/webp/image_loader_webp.cpp
index 889eac71a7..87c2e811b3 100644
--- a/modules/webp/image_loader_webp.cpp
+++ b/modules/webp/image_loader_webp.cpp
@@ -37,23 +37,23 @@
#include <webp/decode.h>
#include <webp/encode.h>
-static PoolVector<uint8_t> _webp_lossy_pack(const Image &p_image, float p_quality) {
+static PoolVector<uint8_t> _webp_lossy_pack(const Ref<Image> &p_image, float p_quality) {
- ERR_FAIL_COND_V(p_image.empty(), PoolVector<uint8_t>());
+ ERR_FAIL_COND_V(p_image.is_null() || p_image->empty(), PoolVector<uint8_t>());
- Image img = p_image;
- if (img.detect_alpha())
- img.convert(Image::FORMAT_RGBA8);
+ Ref<Image> img = p_image->duplicate();
+ if (img->detect_alpha())
+ img->convert(Image::FORMAT_RGBA8);
else
- img.convert(Image::FORMAT_RGB8);
+ img->convert(Image::FORMAT_RGB8);
- Size2 s(img.get_width(), img.get_height());
- PoolVector<uint8_t> data = img.get_data();
+ Size2 s(img->get_width(), img->get_height());
+ PoolVector<uint8_t> data = img->get_data();
PoolVector<uint8_t>::Read r = data.read();
uint8_t *dst_buff = NULL;
size_t dst_size = 0;
- if (img.get_format() == Image::FORMAT_RGB8) {
+ if (img->get_format() == Image::FORMAT_RGB8) {
dst_size = WebPEncodeRGB(r.ptr(), s.width, s.height, 3 * s.width, CLAMP(p_quality * 100.0, 0, 100.0), &dst_buff);
} else {
@@ -74,17 +74,17 @@ static PoolVector<uint8_t> _webp_lossy_pack(const Image &p_image, float p_qualit
return dst;
}
-static Image _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
+static Ref<Image> _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
int size = p_buffer.size() - 4;
- ERR_FAIL_COND_V(size <= 0, Image());
+ ERR_FAIL_COND_V(size <= 0, Ref<Image>());
PoolVector<uint8_t>::Read r = p_buffer.read();
- ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Image());
+ ERR_FAIL_COND_V(r[0] != 'W' || r[1] != 'E' || r[2] != 'B' || r[3] != 'P', Ref<Image>());
WebPBitstreamFeatures features;
if (WebPGetFeatures(&r[4], size, &features) != VP8_STATUS_OK) {
ERR_EXPLAIN("Error unpacking WEBP image:");
- ERR_FAIL_V(Image());
+ ERR_FAIL_V(Ref<Image>());
}
/*
@@ -107,14 +107,15 @@ static Image _webp_lossy_unpack(const PoolVector<uint8_t> &p_buffer) {
}
//ERR_EXPLAIN("Error decoding webp! - "+p_file);
- ERR_FAIL_COND_V(errdec, Image());
+ ERR_FAIL_COND_V(errdec, Ref<Image>());
dst_w = PoolVector<uint8_t>::Write();
- return Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
+ Ref<Image> img = memnew(Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image));
+ return img;
}
-Error ImageLoaderWEBP::load_image(Image *p_image, FileAccess *f) {
+Error ImageLoaderWEBP::load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear) {
uint32_t size = f->get_len();
PoolVector<uint8_t> src_image;
@@ -160,7 +161,7 @@ Error ImageLoaderWEBP::load_image(Image *p_image, FileAccess *f) {
src_r = PoolVector<uint8_t>::Read();
dst_w = PoolVector<uint8_t>::Write();
- *p_image = Image(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
+ p_image->create(features.width, features.height, 0, features.has_alpha ? Image::FORMAT_RGBA8 : Image::FORMAT_RGB8, dst_image);
return OK;
}
diff --git a/modules/webp/image_loader_webp.h b/modules/webp/image_loader_webp.h
index 2d0ac796d3..1ac2196a71 100644
--- a/modules/webp/image_loader_webp.h
+++ b/modules/webp/image_loader_webp.h
@@ -38,7 +38,7 @@
class ImageLoaderWEBP : public ImageFormatLoader {
public:
- virtual Error load_image(Image *p_image, FileAccess *f);
+ virtual Error load_image(Ref<Image> p_image, FileAccess *f, bool p_force_linear);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
ImageLoaderWEBP();
};
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 8dfb006c00..fd0907f820 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0'
+ classpath 'com.android.tools.build:gradle:2.3.1'
$$GRADLE_CLASSPATH$$
}
}
@@ -31,7 +31,7 @@ android {
}
compileSdkVersion 23
- buildToolsVersion "23.0.3"
+ buildToolsVersion "25.0.3"
useLibrary 'org.apache.http.legacy'
packagingOptions {
@@ -56,7 +56,6 @@ android {
'res'
$$GRADLE_RES_DIRS$$
]
- // libs.srcDirs = ['libs']
aidl.srcDirs = [
'aidl'
$$GRADLE_AIDL_DIRS$$
@@ -65,9 +64,6 @@ android {
'assets'
$$GRADLE_ASSET_DIRS$$
]
- jniLibs.srcDirs = [
- $$GRADLE_JNI_DIRS$$
- ]
}
debug.jniLibs.srcDirs = [
'libs/debug'
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 8d2ed59f17..ce44ffbf74 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -232,7 +232,7 @@ def configure(env):
elif (env["target"] == "debug"):
env.Append(LINKFLAGS=['-O0'])
env.Append(CPPFLAGS=['-O0', '-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED',
- '-DDEBUG_MEMORY_ALLOC', '-g', '-fno-limit-debug-info'])
+ '-DDEBUG_MEMORY_ENABLED', '-g', '-fno-limit-debug-info'])
env.Append(CPPFLAGS=['-DANDROID_ENABLED',
'-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT'])
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 72d665329e..51597526ab 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -1714,7 +1714,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
args.push_back("--remove-all");
err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
- int port = GlobalConfig::get_singleton()->get("network/debug/remote_port");
+ int port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
args.clear();
args.push_back("reverse");
args.push_back("tcp:"+itos(port));
@@ -2993,7 +2993,7 @@ public:
args.push_back("--remove-all");
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
- int port = GlobalConfig::get_singleton()->get("network/debug/remote_port");
+ int port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
args.clear();
args.push_back("reverse");
args.push_back("tcp:" + itos(port));
@@ -3523,7 +3523,7 @@ public:
EditorExportAndroid() {
- Image img(_android_logo);
+ Ref<Image> img = memnew(Image(_android_logo));
logo = Ref<ImageTexture>(memnew(ImageTexture));
logo->create_from_image(img);
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index d57051703e..a11cc1b825 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,7 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Fri May 12 08:50:03 KST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip
+org.gradle.jvmargs=-Xmx1536M
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
index a0a0f4af25..29c4a7b8fc 100644
--- a/platform/android/java/res/drawable/icon.png
+++ b/platform/android/java/res/drawable/icon.png
Binary files differ
diff --git a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
index d90d6eac7b..63720999a7 100644
--- a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
+++ b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
@@ -1,4 +1,20 @@
/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicenseResultListener.aidl
*/
diff --git a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
index 95599544e4..36afc0537d 100644
--- a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
+++ b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
@@ -1,4 +1,20 @@
/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicensingService.aidl
*/
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
index 627bf3eedd..e83faa2756 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
@@ -569,10 +569,10 @@ public abstract class DownloaderService extends CustomIntentService implements I
*/
void pollNetworkState() {
if (null == mConnectivityManager) {
- mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ mConnectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
if (null == mWifiManager) {
- mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
if (mConnectivityManager == null) {
Log.w(Constants.TAG,
diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
index 044efba1f3..6f308af360 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -355,36 +355,35 @@ public class PaymentsManager {
tempList.add(s);
}
packs.add(tempList);
-
- for (ArrayList<String> skuPartList : packs) {
- Bundle querySkus = new Bundle();
- querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList);
- Bundle skuDetails = null;
- try {
- skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus);
- if (!skuDetails.containsKey("DETAILS_LIST")) {
- int response = getResponseCodeFromBundle(skuDetails);
- if (response != BILLING_RESPONSE_RESULT_OK) {
- godotPaymentV3.errorSkuDetail(getResponseDesc(response));
- } else {
- godotPaymentV3.errorSkuDetail("No error but no detail list.");
- }
- return;
+ }
+ for (ArrayList<String> skuPartList : packs) {
+ Bundle querySkus = new Bundle();
+ querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList);
+ Bundle skuDetails = null;
+ try {
+ skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus);
+ if (!skuDetails.containsKey("DETAILS_LIST")) {
+ int response = getResponseCodeFromBundle(skuDetails);
+ if (response != BILLING_RESPONSE_RESULT_OK) {
+ godotPaymentV3.errorSkuDetail(getResponseDesc(response));
+ } else {
+ godotPaymentV3.errorSkuDetail("No error but no detail list.");
}
+ return;
+ }
- ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
+ ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
- for (String thisResponse : responseList) {
- Log.d("godot", "response = "+thisResponse);
- godotPaymentV3.addSkuDetail(thisResponse);
- }
- } catch (RemoteException e) {
- e.printStackTrace();
- godotPaymentV3.errorSkuDetail("RemoteException error!");
+ for (String thisResponse : responseList) {
+ Log.d("godot", "response = "+thisResponse);
+ godotPaymentV3.addSkuDetail(thisResponse);
}
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ godotPaymentV3.errorSkuDetail("RemoteException error!");
}
- godotPaymentV3.completeSkuDetail();
}
+ godotPaymentV3.completeSkuDetail();
}
})).start();
}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 6882dad4f0..d4bd443689 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -610,7 +610,7 @@ struct JAndroidPointerEvent {
};
static List<JAndroidPointerEvent> pointer_events;
-static List<InputEvent> key_events;
+static List<Ref<InputEvent> > key_events;
static List<OS_Android::JoypadEvent> joy_events;
static bool initialized = false;
static Mutex *input_mutex = NULL;
@@ -1036,7 +1036,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
while (key_events.size()) {
- InputEvent event = key_events.front()->get();
+ Ref<InputEvent> event = key_events.front()->get();
os_android->process_event(event);
key_events.pop_front();
@@ -1419,30 +1419,23 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
- InputEvent ievent;
- ievent.type = InputEvent::KEY;
- ievent.device = 0;
+ Ref<InputEventKey> ievent;
int val = p_unicode_char;
int scancode = android_get_keysym(p_scancode);
- ievent.key.scancode = scancode;
- ievent.key.unicode = val;
- ievent.key.pressed = p_pressed;
+ ievent->set_scancode(scancode);
+ ievent->set_unicode(val);
+ ievent->set_pressed(p_pressed);
- print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent.key.scancode) + " Unicode: " + String::num(val));
-
- ievent.key.mod.shift = false;
- ievent.key.mod.alt = false;
- ievent.key.mod.control = false;
- ievent.key.echo = false;
+ print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent->get_scancode()) + " Unicode: " + String::num(val));
if (val == '\n') {
- ievent.key.scancode = KEY_ENTER;
+ ievent->set_scancode(KEY_ENTER);
} else if (val == 61448) {
- ievent.key.scancode = KEY_BACKSPACE;
- ievent.key.unicode = KEY_BACKSPACE;
+ ievent->set_scancode(KEY_BACKSPACE);
+ ievent->set_unicode(KEY_BACKSPACE);
} else if (val == 61453) {
- ievent.key.scancode = KEY_ENTER;
- ievent.key.unicode = KEY_ENTER;
+ ievent->set_scancode(KEY_ENTER);
+ ievent->set_unicode(KEY_ENTER);
} else if (p_scancode == 4) {
go_back_request = true;
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 6772964c2f..9010b9e7da 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -360,7 +360,7 @@ void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) {
}
}
-void OS_Android::process_event(InputEvent p_event) {
+void OS_Android::process_event(Ref<InputEvent> p_event) {
input->parse_input_event(p_event);
}
@@ -374,25 +374,24 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
+ {
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(false);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
+ input->parse_input_event(ev);
+ }
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
}
@@ -405,15 +404,14 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
{
//send mouse
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ // ev.type = Ref<InputEvent>::MOUSE_BUTTON;
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(true);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
last_mouse = touch[0].pos;
input->parse_input_event(ev);
@@ -422,12 +420,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
//send touch
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(true);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
@@ -436,16 +433,13 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (p_points.size()) {
//send mouse, should look for point 0?
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_motion.x = p_points[0].pos.x;
- ev.mouse_motion.y = p_points[0].pos.y;
- input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x;
- ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y;
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_position(p_points[0].pos);
+ input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y));
+ ev->set_speed(input->get_last_mouse_speed());
+ ev->set_relative(p_points[0].pos - last_mouse);
last_mouse = p_points[0].pos;
input->parse_input_event(ev);
}
@@ -468,13 +462,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch[i].pos == p_points[idx].pos)
continue; //no move unncesearily
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.screen_drag.index = touch[i].id;
- ev.screen_drag.x = p_points[idx].pos.x;
- ev.screen_drag.y = p_points[idx].pos.y;
- ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x;
- ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y;
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_position(p_points[idx].pos);
+ ev->set_relative(p_points[idx].pos - touch[i].pos);
input->parse_input_event(ev);
touch[i].pos = p_points[idx].pos;
}
@@ -484,26 +476,23 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(false);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
input->parse_input_event(ev);
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
touch.clear();
@@ -517,12 +506,12 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
TouchPos tp = p_points[p_pointer];
touch.push_back(tp);
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = tp.id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = tp.pos.x;
- ev.screen_touch.y = tp.pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(tp.id);
+ ev->set_pressed(true);
+ ev->set_position(tp.pos);
input->parse_input_event(ev);
} break;
@@ -531,12 +520,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
for (int i = 0; i < touch.size(); i++) {
if (touch[i].id == p_pointer) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
touch.remove(i);
i--;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index f1da2867f0..897c71a7df 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -231,7 +231,7 @@ public:
void process_gyroscope(const Vector3 &p_gyroscope);
void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
void process_joy_event(JoypadEvent p_event);
- void process_event(InputEvent p_event);
+ void process_event(Ref<InputEvent> p_event);
void init_video_mode(int p_video_width, int p_video_height);
virtual Error native_video_play(String p_path, float p_volume);
diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp
index 57977dd4b9..bb5a1db250 100644
--- a/platform/android/power_android.cpp
+++ b/platform/android/power_android.cpp
@@ -28,10 +28,35 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/error_macros.h"
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
#include "power_android.h"
+#include "core/error_macros.h"
+
static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) {
if (refholder->m_env) {
JNIEnv *env = refholder->m_env;
diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub
deleted file mode 100644
index c19f46d579..0000000000
--- a/platform/bb10/SCsub
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-bb10_lib = [
-
- 'bbutil.c',
- 'os_bb10.cpp',
- 'audio_driver_bb10.cpp',
- 'godot_bb10.cpp',
- 'payment_service.cpp',
-]
-
-env_bps = env.Clone()
-if env['bb10_payment_service'] == "yes":
- env_bps.Append(CPPFLAGS=['-DPAYMENT_SERVICE_ENABLED'])
-
-if env['bb10_lgles_override'] == "yes":
- env_bps.Append(CPPFLAGS=['-DBB10_LGLES_OVERRIDE'])
-
-
-prog = None
-prog = env_bps.Program('#bin/godot', bb10_lib)
diff --git a/platform/bb10/audio_driver_bb10.cpp b/platform/bb10/audio_driver_bb10.cpp
deleted file mode 100644
index 5658dc5334..0000000000
--- a/platform/bb10/audio_driver_bb10.cpp
+++ /dev/null
@@ -1,254 +0,0 @@
-/*************************************************************************/
-/* audio_driver_bb10.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 "audio_driver_bb10.h"
-
-#include <errno.h>
-
-Error AudioDriverBB10::init() {
- return init(NULL);
-};
-
-Error AudioDriverBB10::init(const char *p_name) {
-
- active = false;
- thread_exited = false;
- exit_thread = false;
- pcm_open = false;
- samples_in = NULL;
- samples_out = NULL;
-
- mix_rate = 44100;
- speaker_mode = SPEAKER_MODE_STEREO;
-
- char *dev_name;
- if (p_name == NULL) {
- dev_name = "pcmPreferred";
- } else {
- dev_name = (char *)p_name;
- }
- printf("******** reconnecting to device %s\n", dev_name);
- int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
- ERR_FAIL_COND_V(ret < 0, FAILED);
- pcm_open = true;
-
- snd_pcm_channel_info_t cinfo;
- zeromem(&cinfo, sizeof(cinfo));
- cinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
- snd_pcm_plugin_info(pcm_handle, &cinfo);
-
- printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate);
-
- mix_rate = cinfo.max_rate;
-
- printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE);
- ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED);
-
- printf("voices %i\n", cinfo.max_voices);
- speaker_mode = SPEAKER_MODE_STEREO;
-
- snd_pcm_channel_params_t cp;
- zeromem(&cp, sizeof(cp));
- cp.mode = SND_PCM_MODE_BLOCK;
- cp.channel = SND_PCM_CHANNEL_PLAYBACK;
- cp.start_mode = SND_PCM_START_DATA;
- cp.stop_mode = SND_PCM_STOP_STOP;
- //cp.buf.block.frag_size = cinfo.max_fragment_size;
- cp.buf.block.frag_size = 512;
- cp.buf.block.frags_max = 1;
- cp.buf.block.frags_min = 1;
- cp.format.interleave = 1;
- cp.format.rate = mix_rate;
- cp.format.voices = speaker_mode;
- cp.format.format = SND_PCM_SFMT_S16_LE;
-
- ret = snd_pcm_plugin_params(pcm_handle, &cp);
- printf("ret is %i, %i\n", ret, cp.why_failed);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- snd_mixer_group_t group;
- zeromem(&group, sizeof(group));
- snd_pcm_channel_setup_t setup;
- zeromem(&setup, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_PLAYBACK;
- setup.mode = SND_PCM_MODE_BLOCK;
- setup.mixer_gid = &group.gid;
- ret = snd_pcm_plugin_setup(pcm_handle, &setup);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- pcm_frag_size = setup.buf.block.frag_size;
- pcm_max_frags = 1;
-
- sample_buf_count = pcm_frag_size * pcm_max_frags / 2;
- printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags);
- samples_in = memnew_arr(int32_t, sample_buf_count);
- samples_out = memnew_arr(int16_t, sample_buf_count);
-
- thread = Thread::create(AudioDriverBB10::thread_func, this);
-
- return OK;
-};
-
-void AudioDriverBB10::thread_func(void *p_udata) {
-
- AudioDriverBB10 *ad = (AudioDriverBB10 *)p_udata;
-
- int channels = speaker_mode;
- int frame_count = ad->sample_buf_count / channels;
- int bytes_out = frame_count * channels * 2;
-
- while (!ad->exit_thread) {
-
- if (!ad->active) {
-
- for (int i = 0; i < ad->sample_buf_count; i++) {
-
- ad->samples_out[i] = 0;
- };
- } else {
-
- ad->lock();
-
- ad->audio_server_process(frame_count, ad->samples_in);
-
- ad->unlock();
-
- for (int i = 0; i < frame_count * channels; i++) {
-
- ad->samples_out[i] = ad->samples_in[i] >> 16;
- }
- };
-
- int todo = bytes_out;
- int total = 0;
-
- while (todo) {
-
- uint8_t *src = (uint8_t *)ad->samples_out;
- int wrote = snd_pcm_plugin_write(ad->pcm_handle, (void *)(src + total), todo);
- if (wrote < 0) {
- // error?
- break;
- };
- total += wrote;
- todo -= wrote;
- if (wrote < todo) {
- if (ad->thread_exited) {
- break;
- };
- printf("pcm_write underrun %i, errno %i\n", (int)ad->thread_exited, errno);
- snd_pcm_channel_status_t status;
- zeromem(&status, sizeof(status));
- // put in non-blocking mode
- snd_pcm_nonblock_mode(ad->pcm_handle, 1);
- status.channel = SND_PCM_CHANNEL_PLAYBACK;
- int ret = snd_pcm_plugin_status(ad->pcm_handle, &status);
- //printf("status return %i, %i, %i, %i, %i\n", ret, errno, status.status, SND_PCM_STATUS_READY, SND_PCM_STATUS_UNDERRUN);
- snd_pcm_nonblock_mode(ad->pcm_handle, 0);
- if (ret < 0) {
- break;
- };
- if (status.status == SND_PCM_STATUS_READY ||
- status.status == SND_PCM_STATUS_UNDERRUN) {
- snd_pcm_plugin_prepare(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
- } else {
- break;
- };
- };
- };
- };
-
- snd_pcm_plugin_flush(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
-
- ad->thread_exited = true;
- printf("**************** audio thread exit\n");
-};
-
-void AudioDriverBB10::start() {
-
- active = true;
-};
-
-int AudioDriverBB10::get_mix_rate() const {
-
- return mix_rate;
-};
-
-AudioDriver::SpeakerMode AudioDriverBB10::get_speaker_mode() const {
-
- return speaker_mode;
-};
-
-void AudioDriverBB10::lock() {
-
- if (!thread)
- return;
- mutex->lock();
-};
-
-void AudioDriverBB10::unlock() {
-
- if (!thread)
- return;
- mutex->unlock();
-};
-
-void AudioDriverBB10::finish() {
-
- if (!thread)
- return;
-
- exit_thread = true;
- Thread::wait_to_finish(thread);
-
- if (pcm_open)
- snd_pcm_close(pcm_handle);
-
- if (samples_in) {
- memdelete_arr(samples_in);
- memdelete_arr(samples_out);
- };
-
- memdelete(thread);
- thread = NULL;
-};
-
-AudioDriverBB10::AudioDriverBB10() {
-
- mutex = Mutex::create();
-};
-
-AudioDriverBB10::~AudioDriverBB10() {
-
- memdelete(mutex);
- mutex = NULL;
-};
diff --git a/platform/bb10/audio_driver_bb10.h b/platform/bb10/audio_driver_bb10.h
deleted file mode 100644
index c5d64236b8..0000000000
--- a/platform/bb10/audio_driver_bb10.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*************************************************************************/
-/* audio_driver_bb10.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. */
-/*************************************************************************/
-#include "servers/audio_server.h"
-
-#include "core/os/mutex.h"
-#include "core/os/thread.h"
-
-#include <sys/asoundlib.h>
-
-class AudioDriverBB10 : public AudioDriver {
-
- Thread *thread;
- Mutex *mutex;
-
- snd_pcm_t *pcm_handle;
-
- int32_t *samples_in;
- int16_t *samples_out;
- int sample_buf_count;
-
- static void thread_func(void *p_udata);
-
- int mix_rate;
- SpeakerMode speaker_mode;
-
- int pcm_frag_size;
- int pcm_max_frags;
-
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
- bool pcm_open;
-
-public:
- const char *get_name() const {
- return "BB10";
- };
-
- virtual Error init();
- virtual Error init(const char *p_name);
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- AudioDriverBB10();
- ~AudioDriverBB10();
-};
diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml
deleted file mode 100644
index 0ba70b7180..0000000000
--- a/platform/bb10/bar/bar-descriptor.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='no'?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
- <!-- BlackBerry® 10 application descriptor file.
-
- Specifies parameters for identifying, installing, and launching native applications on BlackBerry® 10 OS.
--->
- <!-- A universally unique application identifier. Must be unique across all BlackBerry applications.
- Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
- <id>com.godot.game</id>
- <!-- The name that is displayed in the BlackBerry application installer.
- May have multiple values for each language. See samples or xsd schema file. Optional. -->
- <name>Godot Game</name>
- <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade.
- Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
- An updated version of application must have a versionNumber value higher than the previous version. Required. -->
- <versionNumber>0.0.1</versionNumber>
- <!-- Fourth digit segment of the package version. First three segments are taken from the
- <versionNumber> element. Must be an integer from 0 to 2^16-1 -->
- <buildId>0</buildId>
- <!-- Description, displayed in the BlackBerry application installer.
- May have multiple values for each language. See samples or xsd schema file. Optional. -->
- <description>Game made with Godot Engine</description>
- <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
- <author>You Name or Company</author>
- <authorId>authorIDherePlease</authorId>
- <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
- <!-- <authorId>ABC1234YjsnUk235h</authorId> -->
- <initialWindow>
- <aspectRatio>landscape</aspectRatio>
- <autoOrients>false</autoOrients>
- <systemChrome>none</systemChrome>
- <transparent>false</transparent>
- </initialWindow>
- <!-- The category where the application appears. Either core.games or core.media. -->
- <category>core.games</category>
- <permission>read_device_identifying_information</permission>
- <permission>access_internet</permission>
- <asset path="data.pck">data.pck</asset>
- <configuration name="Device-Debug">
- <platformArchitecture>armle-v7</platformArchitecture>
- <asset type="Qnx/Elf" path="godot.bb10.debug.qnx.armle" entry="true">godot.bb10.debug.qnx.armle</asset>
- </configuration>
- <configuration name="Device-Release">
- <platformArchitecture>armle-v7</platformArchitecture>
- <asset type="Qnx/Elf" path="godot.bb10.opt.qnx.armle" entry="true">godot.bb10.opt.qnx.armle</asset>
- </configuration>
- <!-- The icon for the application. -->
- <icon>
- <image>icon.png</image>
- </icon>
- <!-- Ensure that shared libraries in the package are found at run-time. -->
- <env value="app/native/lib:/usr/lib/qt4/lib" var="LD_LIBRARY_PATH"/>
-</qnx>
diff --git a/platform/bb10/bar/icon.png b/platform/bb10/bar/icon.png
deleted file mode 100644
index 2161402438..0000000000
--- a/platform/bb10/bar/icon.png
+++ /dev/null
Binary files differ
diff --git a/platform/bb10/bbutil.c b/platform/bb10/bbutil.c
deleted file mode 100644
index ab3dcf69b2..0000000000
--- a/platform/bb10/bbutil.c
+++ /dev/null
@@ -1,513 +0,0 @@
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/keycodes.h>
-#include <time.h>
-
-#include "bbutil.h"
-
-EGLDisplay egl_disp;
-EGLSurface egl_surf;
-
-static EGLConfig egl_conf;
-static EGLContext egl_ctx;
-
-static screen_context_t screen_ctx;
-static screen_window_t screen_win;
-static screen_display_t screen_disp;
-
-
-static void
-bbutil_egl_perror(const char *msg) {
- static const char *errmsg[] = {
- "function succeeded",
- "EGL is not initialized, or could not be initialized, for the specified display",
- "cannot access a requested resource",
- "failed to allocate resources for the requested operation",
- "an unrecognized attribute or attribute value was passed in an attribute list",
- "an EGLConfig argument does not name a valid EGLConfig",
- "an EGLContext argument does not name a valid EGLContext",
- "the current surface of the calling thread is no longer valid",
- "an EGLDisplay argument does not name a valid EGLDisplay",
- "arguments are inconsistent",
- "an EGLNativePixmapType argument does not refer to a valid native pixmap",
- "an EGLNativeWindowType argument does not refer to a valid native window",
- "one or more argument values are invalid",
- "an EGLSurface argument does not name a valid surface configured for rendering",
- "a power management event has occurred",
- };
-
- fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]);
-}
-EGLConfig bbutil_choose_config(EGLDisplay egl_disp, enum RENDERING_API api) {
- EGLConfig egl_conf = (EGLConfig)0;
- EGLConfig *egl_configs;
- EGLint egl_num_configs;
- EGLint val;
- EGLBoolean rc;
- EGLint i;
-
- rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglGetConfigs");
- return egl_conf;
- }
- if (egl_num_configs == 0) {
- fprintf(stderr, "eglGetConfigs: could not find a configuration\n");
- return egl_conf;
- }
-
- egl_configs = malloc(egl_num_configs * sizeof(*egl_configs));
- if (egl_configs == NULL) {
- fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs);
- return egl_conf;
- }
-
- rc = eglGetConfigs(egl_disp, egl_configs,
- egl_num_configs, &egl_num_configs);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglGetConfigs");
- free(egl_configs);
- return egl_conf;
- }
-
- for (i = 0; i < egl_num_configs; i++) {
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
- if (!(val & EGL_WINDOW_BIT)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
- if (!(val & api)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
- if ((api & (GL_ES_1|GL_ES_2)) && (val == 0)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RED_SIZE, &val);
- if (val != 8) {
- continue;
- }
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_GREEN_SIZE, &val);
- if (val != 8) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BLUE_SIZE, &val);
- if (val != 8) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BUFFER_SIZE, &val);
- if (val != 32) {
- continue;
- }
-
- egl_conf = egl_configs[i];
- break;
- }
-
- free(egl_configs);
-
- if (egl_conf == (EGLConfig)0) {
- fprintf(stderr, "bbutil_choose_config: could not find a matching configuration\n");
- }
-
- return egl_conf;
-}
-
-int
-bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api) {
- int usage;
- int format = SCREEN_FORMAT_RGBX8888;
- int nbuffers = 2;
- EGLint interval = 1;
- int rc;
- EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
- if (api == GL_ES_1) {
- usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION;
- } else if (api == GL_ES_2) {
- usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;
- } else if (api == VG) {
- usage = SCREEN_USAGE_OPENVG | SCREEN_USAGE_ROTATION;
- } else {
- fprintf(stderr, "invalid api setting\n");
- return EXIT_FAILURE;
- }
-
- //Simple egl initialization
- screen_ctx = ctx;
-
- egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (egl_disp == EGL_NO_DISPLAY) {
- bbutil_egl_perror("eglGetDisplay");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglInitialize(egl_disp, NULL, NULL);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglInitialize");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- if ((api == GL_ES_1) || (api == GL_ES_2)) {
- rc = eglBindAPI(EGL_OPENGL_ES_API);
- } else if (api == VG) {
- rc = eglBindAPI(EGL_OPENVG_API);
- }
-
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglBindApi");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- egl_conf = bbutil_choose_config(egl_disp, api);
- if (egl_conf == (EGLConfig)0) {
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- if (api == GL_ES_2) {
- egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes);
- } else {
- egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL);
- }
-
- if (egl_ctx == EGL_NO_CONTEXT) {
- bbutil_egl_perror("eglCreateContext");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window(&screen_win, screen_ctx);
- if (rc) {
- perror("screen_create_window");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format);
- if (rc) {
- perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
- if (rc) {
- perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp);
- if (rc) {
- perror("screen_get_window_property_pv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int screen_resolution[2];
-
- rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution);
- if (rc) {
- perror("screen_get_display_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int angle = atoi(getenv("ORIENTATION"));
-
- screen_display_mode_t screen_mode;
- rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
- if (rc) {
- perror("screen_get_display_property_pv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int size[2];
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_get_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int buffer_size[2] = {size[0], size[1]};
-
- if ((angle == 0) || (angle == 180)) {
- if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
- ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) {
- buffer_size[1] = size[0];
- buffer_size[0] = size[1];
- }
- } else if ((angle == 90) || (angle == 270)){
- if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
- ((screen_mode.width < screen_mode.height && size[0] < size[1]))) {
- buffer_size[1] = size[0];
- buffer_size[0] = size[1];
- }
- } else {
- fprintf(stderr, "Navigator returned an unexpected orientation angle.\n");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size);
- if (rc) {
- perror("screen_set_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
- if (rc) {
- perror("screen_set_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window_buffers(screen_win, nbuffers);
- if (rc) {
- perror("screen_create_window_buffers");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window_group(screen_win, get_window_group_id());
- if (rc) {
- perror("screen_create_window_group");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
- /* if (screen_create_window_group(screen_win, get_window_group_id()) != 0) goto fail; */
-
- int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
- screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode);
-
- egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
- if (egl_surf == EGL_NO_SURFACE) {
- bbutil_egl_perror("eglCreateWindowSurface");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglSwapInterval(egl_disp, interval);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapInterval");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-int
-bbutil_init_gl2d() {
-#if 0
- EGLint surface_width, surface_height;
-
- if ((egl_disp == EGL_NO_DISPLAY) || (egl_surf == EGL_NO_SURFACE) ){
- return EXIT_FAILURE;
- }
-
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
-
- glShadeModel(GL_SMOOTH);
-
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-
- glViewport(0, 0, surface_width, surface_height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glOrthof(0.0f, (float)(surface_width) / (float)(surface_height), 0.0f, 1.0f, -1.0f, 1.0f);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-#endif
-
- return EXIT_SUCCESS;
-}
-
-int
-bbutil_init(screen_context_t ctx, enum RENDERING_API api) {
- if (EXIT_SUCCESS != bbutil_init_egl(ctx, api)) {
- return EXIT_FAILURE;
- }
-
- if ((GL_ES_1 == api) && (EXIT_SUCCESS != bbutil_init_gl2d())) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-int bbutil_is_flipped() {
-
- int ret;
- screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_FLIP, &ret);
- return ret;
-};
-
-int bbutil_get_rotation() {
-
- int ret;
- screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &ret);
- return ret;
-};
-
-
-void
-bbutil_terminate() {
- //Typical EGL cleanup
- if (egl_disp != EGL_NO_DISPLAY) {
- eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (egl_surf != EGL_NO_SURFACE) {
- eglDestroySurface(egl_disp, egl_surf);
- egl_surf = EGL_NO_SURFACE;
- }
- if (egl_ctx != EGL_NO_CONTEXT) {
- eglDestroyContext(egl_disp, egl_ctx);
- egl_ctx = EGL_NO_CONTEXT;
- }
- if (screen_win != NULL) {
- screen_destroy_window(screen_win);
- screen_win = NULL;
- }
- eglTerminate(egl_disp);
- egl_disp = EGL_NO_DISPLAY;
- }
- eglReleaseThread();
-}
-
-void
-bbutil_swap() {
- int rc = eglSwapBuffers(egl_disp, egl_surf);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapBuffers");
- }
-}
-
-void
-bbutil_clear() {
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-char *
-get_window_group_id()
-{
- static char s_window_group_id[16] = "";
-
- if (s_window_group_id[0] == '\0') {
- snprintf(s_window_group_id, sizeof(s_window_group_id), "%d", getpid());
- }
-
- return s_window_group_id;
-}
-
-
-int bbutil_rotate_screen_surface(int angle) {
- int rc, rotation, skip = 1, temp;
- EGLint interval = 1;
- int size[2];
-
- if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) {
- fprintf(stderr, "Invalid angle\n");
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- switch (angle - rotation) {
- case -270:
- case -90:
- case 90:
- case 270:
- temp = size[0];
- size[0] = size[1];
- size[1] = temp;
- skip = 0;
- break;
- }
-
- if (!skip) {
- rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = eglDestroySurface(egl_disp, egl_surf);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
- egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
- if (egl_surf == EGL_NO_SURFACE) {
- bbutil_egl_perror("eglCreateWindowSurface");
- return EXIT_FAILURE;
- }
-
- rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = eglSwapInterval(egl_disp, interval);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapInterval");
- return EXIT_FAILURE;
- }
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
diff --git a/platform/bb10/bbutil.h b/platform/bb10/bbutil.h
deleted file mode 100644
index 77f4402fbd..0000000000
--- a/platform/bb10/bbutil.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _UTILITY_H_INCLUDED
-#define _UTILITY_H_INCLUDED
-
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <screen/screen.h>
-#include <sys/platform.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern EGLDisplay egl_disp;
-extern EGLSurface egl_surf;
-
-enum RENDERING_API {
- GL_ES_1 = EGL_OPENGL_ES_BIT,
- GL_ES_2 = EGL_OPENGL_ES2_BIT,
- VG = EGL_OPENVG_BIT
-};
-
-/**
- * Initializes EGL, GL and loads a default font
- *
- * \param libscreen context that will be used for EGL setup
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init(screen_context_t ctx, enum RENDERING_API api);
-
-/**
- * Initializes EGL
- *
- * \param libscreen context that will be used for EGL setup
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api);
-
-/**
- * Initializes GL 1.1 for simple 2D rendering. GL2 initialization will be added at a later point.
- *
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init_gl2d();
-
-int bbutil_is_flipped();
-int bbutil_get_rotation();
-
-char *get_window_group_id();
-
-int bbutil_rotate_screen_surface(int angle);
-
-/**
- * Terminates EGL
- */
-void bbutil_terminate();
-
-/**
- * Swaps default bbutil window surface to the screen
- */
-void bbutil_swap();
-
-/**
- * Clears the screen of any existing text.
- * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call
- */
-void bbutil_clear();
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py
deleted file mode 100644
index d3ee9f0124..0000000000
--- a/platform/bb10/detect.py
+++ /dev/null
@@ -1,92 +0,0 @@
-import os
-import sys
-import string
-import methods
-
-
-def is_active():
- return True
-
-
-def get_name():
- return "BlackBerry 10"
-
-
-def can_build():
-
- import os
- if (not os.environ.has_key("QNX_TARGET")):
- return False
- return True
-
-
-def get_opts():
-
- return [
- ('QNX_HOST', 'path to qnx host', os.environ.get("QNX_HOST", 0)),
- ('QNX_TARGET', 'path to qnx target', os.environ.get("QNX_TARGET", 0)),
- ('QNX_CONFIGURATION', 'path to qnx configuration', os.environ.get("QNX_CONFIGURATION", 0)),
- ('qnx_target', 'Qnx target (armle or x86', 'armle'),
- ('bb10_payment_service', 'Enable Payment Service for BlackBerry10', 'yes'),
- ('bb10_lgles_override', 'Force legacy GLES (1.1) on iOS', 'no'),
- ('bb10_exceptions', 'Use exceptions when compiling on bb10', 'no'),
- ]
-
-
-def get_flags():
-
- return [
- ('tools', 'no'),
- ('module_theora_enabled', 'no'),
- ]
-
-
-def configure(env):
-
- if env['PLATFORM'] == 'win32':
- env.Tool('mingw')
- env['SPAWN'] = methods.win32_spawn
-
- env['qnx_target_ver'] = env['qnx_target']
- if env['qnx_target'] == "armle":
- env['qnx_prefix'] = 'ntoarmv7'
- env['qnx_target_ver'] = 'armle-v7'
- else:
- env['qnx_prefix'] = 'ntox86'
-
- env['OBJSUFFIX'] = ".qnx.${qnx_target}.o"
- env['LIBSUFFIX'] = ".qnx.${qnx_target}.a"
- env['PROGSUFFIX'] = ".qnx.${qnx_target}"
- print("PROGSUFFIX: " + env['PROGSUFFIX'] + " target: " + env['qnx_target'])
-
- env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/bin')
- env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/usr/bin')
- env['ENV']['QNX_HOST'] = env['QNX_HOST']
- env['ENV']['QNX_TARGET'] = env['QNX_TARGET']
- env['ENV']['QNX_CONFIGURATION'] = env['QNX_CONFIGURATION']
-
- env['CC'] = '$qnx_prefix-gcc'
- env['CXX'] = '$qnx_prefix-g++'
- env['AR'] = '$qnx_prefix-ar'
- env['RANLIB'] = '$qnx_prefix-ranlib'
-
- env.Append(CPPPATH=['#platform/bb10'])
- env.Append(LIBPATH=['#platform/bb10/lib/$qnx_target', '#platform/bb10/lib/$qnx_target_ver'])
- env.Append(CCFLAGS=string.split('-DBB10_ENABLED -DUNIX_ENABLED -DGLES2_ENABLED -DGLES1_ENABLED -D_LITTLE_ENDIAN -DNO_THREADS -DNO_FCNTL'))
- if env['bb10_exceptions'] == "yes":
- env.Append(CCFLAGS=['-fexceptions'])
- else:
- env.Append(CCFLAGS=['-fno-exceptions'])
-
- # env.Append(LINKFLAGS = string.split()
-
- if (env["target"] == "release"):
-
- env.Append(CCFLAGS=['-O3', '-DRELEASE_BUILD'])
-
- elif (env["target"] == "debug"):
-
- env.Append(CCFLAGS=['-g', '-O0', '-DDEBUG_ENABLED', '-D_DEBUG'])
- env.Append(LINKFLAGS=['-g'])
-
- env.Append(LIBS=['bps', 'pps', 'screen', 'socket', 'EGL', 'GLESv2', 'GLESv1_CM', 'm', 'asound'])
diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp
deleted file mode 100644
index b620cea230..0000000000
--- a/platform/bb10/export/export.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-/*************************************************************************/
-/* export.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 "export.h"
-#include "editor/editor_export.h"
-#include "editor/editor_node.h"
-#include "editor/editor_settings.h"
-#include "global_config.h"
-#include "io/marshalls.h"
-#include "io/xml_parser.h"
-#include "io/zip_io.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "platform/bb10/logo.h"
-#include "version.h"
-
-#define MAX_DEVICES 5
-#if 0
-class EditorExportPlatformBB10 : public EditorExportPlatform {
-
- GDCLASS( EditorExportPlatformBB10,EditorExportPlatform );
-
- String custom_package;
-
- int version_code;
- String version_name;
- String package;
- String name;
- String category;
- String description;
- String author_name;
- String author_id;
- String icon;
-
-
-
- struct Device {
-
- int index;
- String name;
- String description;
- };
-
- Vector<Device> devices;
- bool devices_changed;
- Mutex *device_lock;
- Thread *device_thread;
- Ref<ImageTexture> logo;
-
- volatile bool quit_request;
-
-
- static void _device_poll_thread(void *ud);
-
- void _fix_descriptor(Vector<uint8_t>& p_manifest);
-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;
-
-public:
-
- virtual String get_name() const { return "BlackBerry 10"; }
- virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; }
- virtual Ref<Texture> get_logo() const { return logo; }
-
-
- virtual bool poll_devices();
- virtual int get_device_count() const;
- virtual String get_device_name(int p_device) const;
- virtual String get_device_info(int p_device) const;
- virtual Error run(int p_device,int p_flags=0);
-
- virtual bool requires_password(bool p_debug) const { return !p_debug; }
- virtual String get_binary_extension() const { return "bar"; }
- virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0);
-
- virtual bool can_export(String *r_error=NULL) const;
-
- EditorExportPlatformBB10();
- ~EditorExportPlatformBB10();
-};
-
-bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) {
-
- String n=p_name;
-
- if (n=="version/code")
- version_code=p_value;
- else if (n=="version/name")
- version_name=p_value;
- else if (n=="package/unique_name")
- package=p_value;
- else if (n=="package/category")
- category=p_value;
- else if (n=="package/name")
- name=p_value;
- else if (n=="package/description")
- description=p_value;
- else if (n=="package/icon")
- icon=p_value;
- else if (n=="package/custom_template")
- custom_package=p_value;
- else if (n=="release/author")
- author_name=p_value;
- else if (n=="release/author_id")
- author_id=p_value;
- else
- return false;
-
- return true;
-}
-
-bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{
-
- String n=p_name;
-
- if (n=="version/code")
- r_ret=version_code;
- else if (n=="version/name")
- r_ret=version_name;
- else if (n=="package/unique_name")
- r_ret=package;
- else if (n=="package/category")
- r_ret=category;
- else if (n=="package/name")
- r_ret=name;
- else if (n=="package/description")
- r_ret=description;
- else if (n=="package/icon")
- r_ret=icon;
- else if (n=="package/custom_template")
- r_ret=custom_package;
- else if (n=="release/author")
- r_ret=author_name;
- else if (n=="release/author_id")
- r_ret=author_id;
- else
- return false;
-
- return true;
-}
-void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{
-
- p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1"));
- p_list->push_back( PropertyInfo( Variant::STRING, "version/name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/category") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_GLOBAL_FILE,"zip"));
- p_list->push_back( PropertyInfo( Variant::STRING, "release/author") );
- p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") );
-
- //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
-
-}
-
-void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
-
- String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml");
- {
- FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE);
- f->store_buffer(p_descriptor.ptr(),p_descriptor.size());
- }
-
- Ref<XMLParser> parser = memnew( XMLParser );
- Error err = parser->open(fpath);
- ERR_FAIL_COND(err!=OK);
-
- String txt;
- err = parser->read();
- Vector<String> depth;
-
- while(err!=ERR_FILE_EOF) {
-
- ERR_FAIL_COND(err!=OK);
-
- switch(parser->get_node_type()) {
-
- case XMLParser::NODE_NONE: {
- print_line("???");
- } break;
- case XMLParser::NODE_ELEMENT: {
- String e="<";
- e+=parser->get_node_name();
- for(int i=0;i<parser->get_attribute_count();i++) {
- e+=" ";
- e+=parser->get_attribute_name(i)+"=\"";
- e+=parser->get_attribute_value(i)+"\" ";
- }
-
-
-
- if (parser->is_empty()) {
- e+="/";
- } else {
- depth.push_back(parser->get_node_name());
- }
-
- e+=">";
- txt+=e;
-
- } break;
- case XMLParser::NODE_ELEMENT_END: {
-
- txt+="</"+parser->get_node_name()+">";
- if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) {
- depth.resize(depth.size()-1);
- }
-
-
- } break;
- case XMLParser::NODE_TEXT: {
- if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") {
-
- txt+=package;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") {
-
- String aname;
- if (this->name!="") {
- aname=this->name;
- } else {
- aname = GlobalConfig::get_singleton()->get("application/name");
-
- }
-
- if (aname=="") {
- aname=_MKSTR(VERSION_NAME);
- }
-
- txt+=aname;
-
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") {
- txt+=itos(version_code);
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") {
- txt+=description;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") {
- txt+=author_name;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") {
- txt+=author_id;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") {
- txt+=category;
- } else {
- txt+=parser->get_node_data();
- }
- } break;
- case XMLParser::NODE_COMMENT: {
- txt+="<!--"+parser->get_node_name()+"-->";
- } break;
- case XMLParser::NODE_CDATA: {
- //ignore
- //print_line("cdata");
- } break;
- case XMLParser::NODE_UNKNOWN: {
- //ignore
- txt+="<"+parser->get_node_name()+">";
- } break;
- }
-
- err = parser->read();
- }
-
-
- CharString cs = txt.utf8();
- p_descriptor.resize(cs.length());
- for(int i=0;i<cs.length();i++)
- p_descriptor[i]=cs[i];
-
-}
-
-
-
-Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, int p_flags) {
-
-
- EditorProgress ep("export","Exporting for BlackBerry 10",104);
-
- String src_template=custom_package;
-
- if (src_template=="") {
- String err;
- src_template = find_export_template("bb10.zip", &err);
- if (src_template=="") {
- EditorNode::add_io_error(err);
- return ERR_FILE_NOT_FOUND;
- }
- }
-
- FileAccess *src_f=NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
-
- ep.step("Creating FileSystem for BAR",0);
-
- unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
- if (!pkg) {
-
- EditorNode::add_io_error("Could not find template zip to export:\n"+src_template);
- return ERR_FILE_NOT_FOUND;
- }
-
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->change_dir(EditorSettings::get_singleton()->get_settings_path());
-
-
- if (da->change_dir("tmp")!=OK) {
- da->make_dir("tmp");
- if (da->change_dir("tmp")!=OK)
- return ERR_CANT_CREATE;
- }
-
- if (da->change_dir("bb10_export")!=OK) {
- da->make_dir("bb10_export");
- if (da->change_dir("bb10_export")!=OK) {
- return ERR_CANT_CREATE;
- }
- }
-
-
- String bar_dir = da->get_current_dir();
- if (bar_dir.ends_with("/")) {
- bar_dir=bar_dir.substr(0,bar_dir.length()-1);
- }
-
- //THIS IS SUPER, SUPER DANGEROUS!!!!
- //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR
- //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL....
- //BE SUPER CAREFUL WITH THIS PLEASE!!!
- //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!
-
- bool berr = bar_dir.ends_with("bb10_export");
- if (berr) {
- if (da->list_dir_begin()) {
- EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
- ERR_FAIL_COND_V(berr,FAILED);
- };
-
- String f = da->get_next();
- while (f != "") {
-
- if (f == "." || f == "..") {
- f = da->get_next();
- continue;
- };
- Error err = da->remove(bar_dir + "/" + f);
- if (err != OK) {
- EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
- ERR_FAIL_COND_V(err!=OK,err);
- };
- f = da->get_next();
- };
-
- da->list_dir_end();
-
- } else {
- print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
- ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD);
- }
-
-
- ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
- int ret = unzGoToFirstFile(pkg);
-
-
-
- while(ret==UNZ_OK) {
-
- //get filename
- unz_file_info info;
- char fname[16384];
- ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
-
- String file=fname;
-
- Vector<uint8_t> data;
- data.resize(info.uncompressed_size);
-
- //read
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg,data.ptr(),data.size());
- unzCloseCurrentFile(pkg);
-
- //write
-
- if (file=="bar-descriptor.xml") {
-
- _fix_descriptor(data);
- }
-
- if (file=="icon.png") {
- bool found=false;
-
- if (this->icon!="" && this->icon.ends_with(".png")) {
-
- FileAccess *f = FileAccess::open(this->icon,FileAccess::READ);
- if (f) {
-
- data.resize(f->get_len());
- f->get_buffer(data.ptr(),data.size());
- memdelete(f);
- found=true;
- }
-
- }
-
- if (!found) {
-
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
- if (appicon!="" && appicon.ends_with(".png")) {
- FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
- if (f) {
- data.resize(f->get_len());
- f->get_buffer(data.ptr(),data.size());
- memdelete(f);
- }
- }
- }
- }
-
-
- if (file.find("/")) {
-
- da->make_dir_recursive(file.get_base_dir());
- }
-
- FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE);
- wf->store_buffer(data.ptr(),data.size());
-
- ret = unzGoToNextFile(pkg);
- }
-
- ep.step("Adding Files..",2);
-
- FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE);
- if (!dst) {
- EditorNode::add_io_error("Can't copy executable file to:\n "+p_path);
- return ERR_FILE_CANT_WRITE;
- }
- save_pack(dst, false, 1024);
- dst->close();
- memdelete(dst);
-
- ep.step("Creating BAR Package..",104);
-
- String bb_packager=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_packager=bb_packager.plus_file("blackberry-nativepackager");
- if (OS::get_singleton()->get_name()=="Windows")
- bb_packager+=".bat";
-
-
- if (!FileAccess::exists(bb_packager)) {
- EditorNode::add_io_error("Can't find packager:\n"+bb_packager);
- return ERR_CANT_OPEN;
- }
-
- List<String> args;
- args.push_back("-package");
- args.push_back(p_path);
- if (p_debug) {
-
- String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token");
- if (!FileAccess::exists(debug_token)) {
- EditorNode::add_io_error("Debug token not found!");
- } else {
- args.push_back("-debugToken");
- args.push_back(debug_token);
- }
- args.push_back("-devMode");
- args.push_back("-configuration");
- args.push_back("Device-Debug");
- } else {
-
- args.push_back("-configuration");
- args.push_back("Device-Release");
- }
- args.push_back(bar_dir.plus_file("bar-descriptor.xml"));
-
- int ec;
-
- Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
-
- if (err!=OK)
- return err;
- if (ec!=0)
- return ERR_CANT_CREATE;
-
- return OK;
-
-}
-
-bool EditorExportPlatformBB10::poll_devices() {
-
- bool dc=devices_changed;
- devices_changed=false;
- return dc;
-}
-
-int EditorExportPlatformBB10::get_device_count() const {
-
- device_lock->lock();
- int dc=devices.size();
- device_lock->unlock();
-
- return dc;
-
-}
-String EditorExportPlatformBB10::get_device_name(int p_device) const {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),"");
- device_lock->lock();
- String s=devices[p_device].name;
- device_lock->unlock();
- return s;
-}
-String EditorExportPlatformBB10::get_device_info(int p_device) const {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),"");
- device_lock->lock();
- String s=devices[p_device].description;
- device_lock->unlock();
- return s;
-}
-
-void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
-
- EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud;
-
- while(!ea->quit_request) {
-
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_deploy=bb_deploy.plus_file("blackberry-deploy");
- bool windows = OS::get_singleton()->get_name()=="Windows";
- if (windows)
- bb_deploy+=".bat";
-
- if (FileAccess::exists(bb_deploy)) {
-
- Vector<Device> devices;
-
-
- for (int i=0;i<MAX_DEVICES;i++) {
-
- String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/host");
- if (host==String())
- continue;
- String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/password");
- if (pass==String())
- continue;
-
- List<String> args;
- args.push_back("-listDeviceInfo");
- args.push_back(host);
- args.push_back("-password");
- args.push_back(pass);
-
-
- int ec;
- String dp;
-
- Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec);
-
- if (err==OK && ec==0) {
-
- Device dev;
- dev.index=i;
- String descr;
- Vector<String> ls=dp.split("\n");
-
- for(int i=0;i<ls.size();i++) {
-
- String l = ls[i].strip_edges();
- if (l.begins_with("modelfullname::")) {
- dev.name=l.get_slice("::",1);
- descr+="Model: "+dev.name+"\n";
- }
- if (l.begins_with("modelnumber::")) {
- String s = l.get_slice("::",1);
- dev.name+=" ("+s+")";
- descr+="Model Number: "+s+"\n";
- }
- if (l.begins_with("scmbundle::"))
- descr+="OS Version: "+l.get_slice("::",1)+"\n";
- if (l.begins_with("[n]debug_token_expiration::"))
- descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n";
-
- }
-
- dev.description=descr;
- devices.push_back(dev);
- }
-
- }
-
- bool changed=false;
-
-
- ea->device_lock->lock();
-
- if (ea->devices.size()!=devices.size()) {
- changed=true;
- } else {
-
- for(int i=0;i<ea->devices.size();i++) {
-
- if (ea->devices[i].index!=devices[i].index) {
- changed=true;
- break;
- }
- }
- }
-
- if (changed) {
-
- ea->devices=devices;
- ea->devices_changed=true;
- }
-
- ea->device_lock->unlock();
- }
-
-
- uint64_t wait = 3000000;
- uint64_t time = OS::get_singleton()->get_ticks_usec();
- while(OS::get_singleton()->get_ticks_usec() - time < wait ) {
- OS::get_singleton()->delay_usec(1000);
- if (ea->quit_request)
- break;
- }
- }
-
-}
-
-Error EditorExportPlatformBB10::run(int p_device, int p_flags) {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
-
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_deploy=bb_deploy.plus_file("blackberry-deploy");
- if (OS::get_singleton()->get_name()=="Windows")
- bb_deploy+=".bat";
-
- if (!FileAccess::exists(bb_deploy)) {
- EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy);
- return ERR_FILE_NOT_FOUND;
- }
-
-
- device_lock->lock();
-
-
- EditorProgress ep("run","Running on "+devices[p_device].name,3);
-
- //export_temp
- ep.step("Exporting APK",0);
-
- String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar");
- Error err = export_project(export_to,true,p_flags);
- if (err) {
- device_lock->unlock();
- return err;
- }
-#if 0
- ep.step("Uninstalling..",1);
-
- print_line("Uninstalling previous version: "+devices[p_device].name);
- List<String> args;
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("uninstall");
- args.push_back(package);
- int rv;
- err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
-
- if (err || rv!=0) {
- EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
- }
-
- print_line("Installing into device (please wait..): "+devices[p_device].name);
-
-#endif
- ep.step("Installing to Device (please wait..)..",2);
-
- List<String> args;
- args.clear();
- args.push_back("-installApp");
- args.push_back("-launchApp");
- args.push_back("-device");
- String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/host");
- String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/password");
- args.push_back(host);
- args.push_back("-password");
- args.push_back(pass);
- args.push_back(export_to);
-
- int rv;
- err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv);
- if (err || rv!=0) {
- EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
- }
-
- device_lock->unlock();
- return OK;
-
-
-}
-
-
-EditorExportPlatformBB10::EditorExportPlatformBB10() {
-
- version_code=1;
- version_name="1.0";
- package="com.godot.noname";
- category="core.games";
- name="";
- author_name="Cert. Name";
- author_id="Cert. ID";
- description="Game made with Godot Engine";
-
- device_lock = Mutex::create();
- quit_request=false;
-
- device_thread=Thread::create(_device_poll_thread,this);
- devices_changed=true;
-
- Image img( _bb10_logo );
- logo = Ref<ImageTexture>( memnew( ImageTexture ));
- logo->create_from_image(img);
-}
-
-bool EditorExportPlatformBB10::can_export(String *r_error) const {
-
- bool valid=true;
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- String err;
-
- if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) {
-
- valid=false;
- err+="Blackberry host tools not configured in editor settings.\n";
- }
-
- if (!exists_export_template("bb10.zip")) {
- valid=false;
- err+="No export template found.\nDownload and install export templates.\n";
- }
-
- String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token");
-
- if (!FileAccess::exists(debug_token)) {
- valid=false;
- err+="No debug token set, will not be able to test on device.\n";
- }
-
-
- if (custom_package!="" && !FileAccess::exists(custom_package)) {
- valid=false;
- err+="Custom release package not found.\n";
- }
-
- if (r_error)
- *r_error=err;
-
- return valid;
-}
-
-
-EditorExportPlatformBB10::~EditorExportPlatformBB10() {
-
- quit_request=true;
- Thread::wait_to_finish(device_thread);
- memdelete(device_lock);
- memdelete(device_thread);
-}
-
-#endif
-void register_bb10_exporter() {
-#if 0
- EDITOR_DEF("export/blackberry/host_tools","");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR));
- EDITOR_DEF("export/blackberry/debug_token","");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar"));
- EDITOR_DEF("export/blackberry/device_1/host","");
- EDITOR_DEF("export/blackberry/device_1/password","");
- EDITOR_DEF("export/blackberry/device_2/host","");
- EDITOR_DEF("export/blackberry/device_2/password","");
- EDITOR_DEF("export/blackberry/device_3/host","");
- EDITOR_DEF("export/blackberry/device_3/password","");
- EDITOR_DEF("export/blackberry/device_4/host","");
- EDITOR_DEF("export/blackberry/device_4/password","");
- EDITOR_DEF("export/blackberry/device_5/host","");
- EDITOR_DEF("export/blackberry/device_5/password","");
-
- Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) );
- EditorImportExport::get_singleton()->add_export_platform(exporter);
-
-#endif
-}
diff --git a/platform/bb10/logo.png b/platform/bb10/logo.png
deleted file mode 100644
index abf0d2cc69..0000000000
--- a/platform/bb10/logo.png
+++ /dev/null
Binary files differ
diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp
deleted file mode 100644
index b571d1640c..0000000000
--- a/platform/bb10/os_bb10.cpp
+++ /dev/null
@@ -1,608 +0,0 @@
-/*************************************************************************/
-/* os_bb10.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 "os_bb10.h"
-
-#include "bbutil.h"
-#include "core/global_config.h"
-#include "core/os/dir_access.h"
-#include "core/os/keyboard.h"
-#include "drivers/gles2/rasterizer_gles2.h"
-#include "main/main.h"
-#include "servers/visual/visual_server_raster.h"
-
-#include <assert.h>
-#include <bps/accelerometer.h>
-#include <bps/audiodevice.h>
-#include <bps/bps.h>
-#include <bps/navigator.h>
-#include <bps/orientation.h>
-#include <bps/screen.h>
-#include <bps/virtualkeyboard.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#ifdef BB10_SCORELOOP_ENABLED
-#include "modules/scoreloop/scoreloop_bb10.h"
-#endif
-
-static char launch_dir[512];
-char *launch_dir_ptr;
-
-int OSBB10::get_video_driver_count() const {
-
- return 1;
-}
-const char *OSBB10::get_video_driver_name(int p_driver) const {
-
- return "GLES2";
-}
-
-OS::VideoMode OSBB10::get_default_video_mode() const {
-
- return OS::VideoMode();
-}
-
-int OSBB10::get_audio_driver_count() const {
-
- return 1;
-}
-const char *OSBB10::get_audio_driver_name(int p_driver) const {
-
- return "BB10";
-}
-
-void OSBB10::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
- data_dir = getenv("HOME");
-
- //Create a screen context that will be used to create an EGL surface to to receive libscreen events
- screen_create_context(&screen_cxt, 0);
-
- //Initialize BPS library
- bps_initialize();
-
- //Use utility code to initialize EGL for 2D rendering with GL ES 1.1
- enum RENDERING_API api = GL_ES_2;
-#ifdef BB10_LGLES_OVERRIDE
- api = GL_ES_1;
-#endif
- if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) {
- bbutil_terminate();
- screen_destroy_context(screen_cxt);
- return;
- };
-
- EGLint surface_width, surface_height;
-
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
- printf("screen size: %ix%i\n", surface_width, surface_height);
- VideoMode mode;
- mode.width = surface_width;
- mode.height = surface_height;
- mode.fullscreen = true;
- mode.resizable = false;
- set_video_mode(mode);
-
- //Signal BPS library that navigator and screen events will be requested
- screen_request_events(screen_cxt);
- navigator_request_events(0);
- virtualkeyboard_request_events(0);
- audiodevice_request_events(0);
-
-#ifdef DEBUG_ENABLED
- bps_set_verbosity(3);
-#endif
-
- accel_supported = accelerometer_is_supported();
- if (accel_supported)
- accelerometer_set_update_frequency(FREQ_40_HZ);
- pitch = 0;
- roll = 0;
-
-#ifdef BB10_LGLES_OVERRIDE
- rasterizer = memnew(RasterizerGLES1(false));
-#else
- rasterizer = memnew(RasterizerGLES2(false, false));
-#endif
-
- visual_server = memnew(VisualServerRaster(rasterizer));
- visual_server->init();
- visual_server->cursor_set_visible(false, 0);
-
- audio_driver = memnew(AudioDriverBB10);
- audio_driver->set_singleton();
- audio_driver->init(NULL);
-
- physics_server = memnew(PhysicsServerSW);
- physics_server->init();
- physics_2d_server = memnew(Physics2DServerSW);
- physics_2d_server->init();
-
- input = memnew(InputDefault);
-
- power_manager = memnew(PowerBB10);
-
-#ifdef PAYMENT_SERVICE_ENABLED
- payment_service = memnew(PaymentService);
- Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service));
-#endif
-}
-
-void OSBB10::set_main_loop(MainLoop *p_main_loop) {
-
- input->set_main_loop(p_main_loop);
- main_loop = p_main_loop;
-}
-
-void OSBB10::delete_main_loop() {
-
- memdelete(main_loop);
- main_loop = NULL;
-}
-
-void OSBB10::finalize() {
-
- if (main_loop)
- memdelete(main_loop);
- main_loop = NULL;
-
- /*
- if (debugger_connection_console) {
- memdelete(debugger_connection_console);
- }
- */
-
- visual_server->finish();
- memdelete(visual_server);
- memdelete(rasterizer);
-
- physics_server->finish();
- memdelete(physics_server);
-
- physics_2d_server->finish();
- memdelete(physics_2d_server);
-
-#ifdef PAYMENT_SERVICE_ENABLED
- memdelete(payment_service);
-#endif
-
- memdelete(input);
-
- bbutil_terminate();
- screen_destroy_context(screen_cxt);
-
- bps_shutdown();
-}
-
-void OSBB10::set_mouse_show(bool p_show) {
-
- //android has no mouse...
-}
-
-void OSBB10::set_mouse_grab(bool p_grab) {
-
- //it really has no mouse...!
-}
-
-bool OSBB10::is_mouse_grab_enabled() const {
-
- //*sigh* technology has evolved so much since i was a kid..
- return false;
-}
-Point2 OSBB10::get_mouse_position() const {
-
- return Point2();
-}
-int OSBB10::get_mouse_button_state() const {
-
- return 0;
-}
-void OSBB10::set_window_title(const String &p_title) {
-}
-
-//interesting byt not yet
-//void set_clipboard(const String& p_text);
-//String get_clipboard() const;
-
-void OSBB10::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-
- default_videomode = p_video_mode;
-}
-
-OS::VideoMode OSBB10::get_video_mode(int p_screen) const {
-
- return default_videomode;
-}
-void OSBB10::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
- p_list->push_back(default_videomode);
-}
-
-String OSBB10::get_name() {
-
- return "BlackBerry 10";
-}
-
-MainLoop *OSBB10::get_main_loop() const {
-
- return main_loop;
-}
-
-bool OSBB10::can_draw() const {
-
- return !minimized;
-}
-
-void OSBB10::set_cursor_shape(CursorShape p_shape) {
-
- //android really really really has no mouse.. how amazing..
-}
-
-void OSBB10::handle_screen_event(bps_event_t *event) {
-
- screen_event_t screen_event = screen_event_get_event(event);
-
- int screen_val;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
-
- int pos[2];
-
- switch (screen_val) {
- case SCREEN_EVENT_MTOUCH_TOUCH:
- case SCREEN_EVENT_MTOUCH_RELEASE: {
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
-
- InputEvent ievent;
- ievent.type = InputEvent::SCREEN_TOUCH;
- ievent.device = 0;
- ievent.screen_touch.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
- ievent.screen_touch.x = pos[0];
- ievent.screen_touch.y = pos[1];
- Point2 mpos(ievent.screen_touch.x, ievent.screen_touch.y);
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
- ievent.screen_touch.index = pos[0];
-
- last_touch_x[pos[0]] = ievent.screen_touch.x;
- last_touch_y[pos[0]] = ievent.screen_touch.y;
-
- input->parse_input_event(ievent);
-
- if (ievent.screen_touch.index == 0) {
-
- InputEvent ievent;
- ievent.type = InputEvent::MOUSE_BUTTON;
- ievent.device = 0;
- ievent.mouse_button.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
- ievent.mouse_button.button_index = BUTTON_LEFT;
- ievent.mouse_button.doubleclick = 0;
- ievent.mouse_button.x = ievent.mouse_button.global_x = mpos.x;
- ievent.mouse_button.y = ievent.mouse_button.global_y = mpos.y;
- input->parse_input_event(ievent);
- };
-
- } break;
- case SCREEN_EVENT_MTOUCH_MOVE: {
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
-
- InputEvent ievent;
- ievent.type = InputEvent::SCREEN_DRAG;
- ievent.device = 0;
- ievent.screen_drag.x = pos[0];
- ievent.screen_drag.y = pos[1];
-
- /*
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pos);
- ievent.screen_drag.relative_x = ievent.screen_drag.x - pos[0];
- ievent.screen_drag.relative_y = ievent.screen_drag.y - pos[1];
- */
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
- ievent.screen_drag.index = pos[0];
-
- ievent.screen_drag.relative_x = ievent.screen_drag.x - last_touch_x[ievent.screen_drag.index];
- ievent.screen_drag.relative_y = ievent.screen_drag.y - last_touch_y[ievent.screen_drag.index];
-
- last_touch_x[ievent.screen_drag.index] = ievent.screen_drag.x;
- last_touch_y[ievent.screen_drag.index] = ievent.screen_drag.y;
-
- Point2 mpos(ievent.screen_drag.x, ievent.screen_drag.y);
- Point2 mrel(ievent.screen_drag.relative_x, ievent.screen_drag.relative_y);
-
- input->parse_input_event(ievent);
-
- if (ievent.screen_touch.index == 0) {
-
- InputEvent ievent;
- ievent.type = InputEvent::MOUSE_MOTION;
- ievent.device = 0;
- ievent.mouse_motion.x = ievent.mouse_motion.global_x = mpos.x;
- ievent.mouse_motion.y = ievent.mouse_motion.global_y = mpos.y;
- input->set_mouse_position(Point2(ievent.mouse_motion.x, ievent.mouse_motion.y));
- ievent.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ievent.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ievent.mouse_motion.relative_x = mrel.x;
- ievent.mouse_motion.relative_y = mrel.y;
- ievent.mouse_motion.button_mask = 1; // pressed
-
- input->parse_input_event(ievent);
- };
- } break;
-
- case SCREEN_EVENT_KEYBOARD: {
-
- InputEvent ievent;
- ievent.type = InputEvent::KEY;
- ievent.device = 0;
- int val = 0;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SCAN, &val);
- ievent.key.scancode = val;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &val);
- ievent.key.unicode = val;
- if (val == 61448) {
- ievent.key.scancode = KEY_BACKSPACE;
- ievent.key.unicode = KEY_BACKSPACE;
- };
- if (val == 61453) {
- ievent.key.scancode = KEY_ENTER;
- ievent.key.unicode = KEY_ENTER;
- };
-
- int flags;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
- ievent.key.pressed = flags & 1; // bit 1 is pressed apparently
-
- int mod;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
-
- input->parse_input_event(ievent);
- } break;
-
- default:
- break;
- }
-};
-
-void OSBB10::handle_accelerometer() {
-
- if (!accel_supported)
- return;
-
- if (!fullscreen)
- return;
-
- double force_x, force_y, force_z;
- accelerometer_read_forces(&force_x, &force_y, &force_z);
- Vector3 accel = Vector3(force_x, flip_accelerometer ? force_y : -force_y, force_z);
- input->set_accelerometer(accel);
- // rotate 90 degrees
- //input->set_accelerometer(Vector3(force_y, flip_accelerometer?force_x:(-force_x), force_z));
-};
-
-void OSBB10::_resize(bps_event_t *event) {
-
- int angle = navigator_event_get_orientation_angle(event);
- bbutil_rotate_screen_surface(angle);
-
- EGLint surface_width, surface_height;
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
-
- VideoMode mode;
- mode.width = surface_width;
- mode.height = surface_height;
- mode.fullscreen = true;
- mode.resizable = false;
- set_video_mode(mode);
-};
-
-void OSBB10::process_events() {
-
- handle_accelerometer();
-
- bps_event_t *event = NULL;
-
- do {
- int rc = bps_get_event(&event, 0);
- assert(rc == BPS_SUCCESS);
-
- if (!event) break;
-
-#ifdef BB10_SCORELOOP_ENABLED
- ScoreloopBB10 *sc = Globals::get_singleton()->get_singleton_object("Scoreloop")->cast_to<ScoreloopBB10>();
- if (sc->handle_event(event))
- continue;
-#endif
-
-#ifdef PAYMENT_SERVICE_ENABLED
- if (payment_service->handle_event(event))
- continue;
-#endif
-
- int domain = bps_event_get_domain(event);
- if (domain == screen_get_domain()) {
-
- handle_screen_event(event);
-
- } else if (domain == navigator_get_domain()) {
-
- if (NAVIGATOR_EXIT == bps_event_get_code(event)) {
- if (main_loop)
- main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
- bps_event_destroy(event);
- exit(0);
- return;
- /*
- } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION_CHECK) {
-
- int angle = navigator_event_get_orientation_angle(event);
- navigator_orientation_check_response(event, false);
-
- } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION) {
-
- _resize(event);
- */
- } else if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE) {
-
- int state = navigator_event_get_window_state(event);
- bool was_fullscreen = fullscreen;
- minimized = state == NAVIGATOR_WINDOW_INVISIBLE;
- fullscreen = state == NAVIGATOR_WINDOW_FULLSCREEN;
- set_low_processor_usage_mode(!fullscreen);
- if (fullscreen != was_fullscreen) {
- if (fullscreen) {
- audio_server->set_fx_global_volume_scale(fullscreen_mixer_volume);
- audio_server->set_stream_global_volume_scale(fullscreen_stream_volume);
- } else {
- fullscreen_mixer_volume = audio_server->get_fx_global_volume_scale();
- fullscreen_stream_volume = audio_server->get_stream_global_volume_scale();
- audio_server->set_fx_global_volume_scale(0);
- audio_server->set_stream_global_volume_scale(0);
- };
- };
- };
- } else if (domain == audiodevice_get_domain()) {
-
- const char *audiodevice_path = audiodevice_event_get_path(event);
- printf("************* got audiodevice event, path %s\n", audiodevice_path);
- audio_driver->finish();
- audio_driver->init(audiodevice_path);
- audio_driver->start();
- };
-
- //bps_event_destroy(event);
- } while (event);
-};
-
-bool OSBB10::has_virtual_keyboard() const {
-
- return true;
-};
-
-void OSBB10::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
-
- virtualkeyboard_show();
-};
-
-void OSBB10::hide_virtual_keyboard() {
-
- virtualkeyboard_hide();
-};
-
-void OSBB10::run() {
-
- if (!main_loop)
- return;
-
- main_loop->init();
-
- int flip = bbutil_is_flipped();
- int rot = bbutil_get_rotation();
- flip_accelerometer = rot == 90;
- printf("**************** rot is %i, flip %i\n", rot, (int)flip_accelerometer);
- /*
- orientation_direction_t orientation;
- int angle;
- orientation_get(&orientation, &angle);
- printf("******************** orientation %i, %i, %i\n", orientation, ORIENTATION_BOTTOM_UP, ORIENTATION_TOP_UP);
- if (orientation == ORIENTATION_BOTTOM_UP) {
- flip_accelerometer = true;
- };
- */
-
- while (true) {
-
- process_events(); // get rid of pending events
- if (Main::iteration() == true)
- break;
- bbutil_swap();
- //#ifdef DEBUG_ENABLED
- fflush(stdout);
- //#endif
- };
-
- main_loop->finish();
-};
-
-bool OSBB10::has_touchscreen_ui_hint() const {
-
- return true;
-}
-
-Error OSBB10::shell_open(String p_uri) {
-
- char *msg = NULL;
- int ret = navigator_invoke(p_uri.utf8().get_data(), &msg);
-
- return ret == BPS_SUCCESS ? OK : FAILED;
-};
-
-String OSBB10::get_data_dir() const {
-
- return data_dir;
-};
-
-Size2 OSBB10::get_window_size() const {
- return Vector2(default_videomode.width, default_videomode.height);
-}
-
-PowerState OSBB10::get_power_state() {
- return power_manager->get_power_state();
-}
-
-int OSBB10::get_power_seconds_left() {
- return power_manager->get_power_seconds_left();
-}
-
-int OSBB10::get_power_percent_left() {
- return power_manager->get_power_percent_left();
-}
-
-OSBB10::OSBB10() {
-
- main_loop = NULL;
- minimized = false;
- fullscreen = true;
- flip_accelerometer = true;
- fullscreen_mixer_volume = 1;
- fullscreen_stream_volume = 1;
-
- printf("godot bb10!\n");
- getcwd(launch_dir, sizeof(launch_dir));
- printf("launch dir %s\n", launch_dir);
- chdir("app/native");
- launch_dir_ptr = launch_dir;
-}
-
-OSBB10::~OSBB10() {
-}
diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h
deleted file mode 100644
index 91149b6f68..0000000000
--- a/platform/bb10/os_bb10.h
+++ /dev/null
@@ -1,153 +0,0 @@
-/*************************************************************************/
-/* os_bb10.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 OS_BB10_H
-#define OS_BB10_H
-
-#include "audio_driver_bb10.h"
-#include "drivers/unix/os_unix.h"
-#include "main/input_default.h"
-#include "os/input.h"
-#include "os/main_loop.h"
-#include "payment_service.h"
-#include "power_bb10.h"
-#include "servers/audio_server.h"
-#include "servers/physics/physics_server_sw.h"
-#include "servers/physics_2d/physics_2d_server_sw.h"
-#include "servers/visual/rasterizer.h"
-
-#include <bps/event.h>
-#include <screen/screen.h>
-#include <stdint.h>
-#include <sys/platform.h>
-
-class OSBB10 : public OS_Unix {
-
- screen_context_t screen_cxt;
- float fullscreen_mixer_volume;
- float fullscreen_stream_volume;
-
- Rasterizer *rasterizer;
- VisualServer *visual_server;
- PhysicsServer *physics_server;
- Physics2DServer *physics_2d_server;
- AudioDriverBB10 *audio_driver;
- PowerBB10 *power_manager;
-
-#ifdef PAYMENT_SERVICE_ENABLED
- PaymentService *payment_service;
-#endif
-
- VideoMode default_videomode;
- MainLoop *main_loop;
-
- void process_events();
-
- void _resize(bps_event_t *event);
- void handle_screen_event(bps_event_t *event);
- void handle_accelerometer();
-
- int last_touch_x[16];
- int last_touch_y[16];
-
- bool accel_supported;
- float pitch;
- float roll;
-
- bool minimized;
- bool fullscreen;
- bool flip_accelerometer;
- String data_dir;
-
- InputDefault *input;
-
-public:
- // functions used by main to initialize/deintialize the OS
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
- virtual VideoMode get_default_video_mode() const;
-
- virtual String get_data_dir() const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
-
- virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
-
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
-
- virtual void finalize();
-
- typedef int64_t ProcessID;
-
- static OS *get_singleton();
-
- virtual void set_mouse_show(bool p_show);
- virtual void set_mouse_grab(bool p_grab);
- virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_position() const;
- virtual int get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- //virtual void set_clipboard(const String& p_text);
- //virtual String get_clipboard() const;
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect);
- virtual void hide_virtual_keyboard();
-
- virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
- virtual VideoMode get_video_mode(int p_screen = 0) const;
- virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
-
- virtual Size2 get_window_size() const;
- virtual String get_name();
- virtual MainLoop *get_main_loop() const;
-
- virtual bool can_draw() const;
-
- virtual void set_cursor_shape(CursorShape p_shape);
-
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual Error shell_open(String p_uri);
-
- void run();
-
- virtual PowerState get_power_state();
- virtual int get_power_seconds_left();
- virtual int get_power_percent_left();
-
- OSBB10();
- ~OSBB10();
-};
-
-#endif
diff --git a/platform/bb10/payment_service.cpp b/platform/bb10/payment_service.cpp
deleted file mode 100644
index 353845583f..0000000000
--- a/platform/bb10/payment_service.cpp
+++ /dev/null
@@ -1,149 +0,0 @@
-/*************************************************************************/
-/* payment_service.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifdef PAYMENT_SERVICE_ENABLED
-
-#include "payment_service.h"
-
-#include "bbutil.h"
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-extern char *launch_dir_ptr;
-
-void PaymentService::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("request_product_info"), &PaymentService::request_product_info);
- ClassDB::bind_method(D_METHOD("purchase"), &PaymentService::purchase);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"), &PaymentService::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"), &PaymentService::pop_pending_event);
-};
-
-Error PaymentService::request_product_info(Variant p_params) {
-
- return ERR_UNAVAILABLE;
-};
-
-Error PaymentService::purchase(Variant p_params) {
-
- Dictionary params = p_params;
- ERR_FAIL_COND_V((!params.has("product_id")) && (!params.has("product_sku")), ERR_INVALID_PARAMETER);
-
- char *id = NULL;
- char *sku = NULL;
-
- CharString p_id = params.has("product_id") ? String(params["product_id"]).ascii() : CharString();
- CharString p_sku = params.has("product_sku") ? String(params["product_sku"]).ascii() : CharString();
- unsigned int request_id;
- chdir(launch_dir_ptr);
- int ret = paymentservice_purchase_request(params.has("product_sku") ? NULL : p_id.get_data(),
- params.has("product_sku") ? p_sku.get_data() : NULL,
- NULL, NULL, NULL, NULL, get_window_group_id(), &request_id);
- chdir("app/native");
-
- if (ret != BPS_SUCCESS) {
- int eret = errno;
- printf("purchase error %i, %x, %i, %x\n", ret, ret, eret, eret);
- ERR_FAIL_V((Error)eret);
- return (Error)eret;
- };
- return OK;
-};
-
-bool PaymentService::handle_event(bps_event_t *p_event) {
-
- if (bps_event_get_domain(p_event) != paymentservice_get_domain()) {
- return false;
- };
-
- Dictionary dict;
- int res = paymentservice_event_get_response_code(p_event);
- if (res == SUCCESS_RESPONSE) {
- dict["result"] = "ok";
-
- res = bps_event_get_code(p_event);
- if (res == PURCHASE_RESPONSE) {
- dict["type"] = "purchase";
- const char *pid = paymentservice_event_get_digital_good_id(p_event, 0);
- dict["product_id"] = String(pid ? pid : "");
- };
-
- } else {
- const char *desc = paymentservice_event_get_error_text(p_event);
- if (strcmp(desc, "alreadyPurchased") == 0) {
- dict["result"] = "ok";
- } else {
- dict["result"] = "error";
- dict["error_description"] = paymentservice_event_get_error_text(p_event);
- dict["error_code"] = paymentservice_event_get_error_id(p_event);
- printf("error code is %i\n", paymentservice_event_get_error_id(p_event));
- printf("error description is %s\n", paymentservice_event_get_error_text(p_event));
- };
- dict["product_id"] = "";
- };
-
- res = bps_event_get_code(p_event);
- if (res == PURCHASE_RESPONSE) {
- dict["type"] = "purchase";
- };
-
- printf("********** adding event with result %ls\n", String(dict["result"]).c_str());
- pending_events.push_back(dict);
-
- return true;
-};
-
-int PaymentService::get_pending_event_count() {
- return pending_events.size();
-};
-
-Variant PaymentService::pop_pending_event() {
-
- Variant front = pending_events.front()->get();
- pending_events.pop_front();
-
- return front;
-};
-
-PaymentService::PaymentService() {
-
- paymentservice_request_events(0);
-#ifdef DEBUG_ENABLED
- paymentservice_set_connection_mode(true);
-#else
- paymentservice_set_connection_mode(false);
-#endif
-};
-
-PaymentService::~PaymentService(){
-
-};
-
-#endif
diff --git a/platform/bb10/payment_service.h b/platform/bb10/payment_service.h
deleted file mode 100644
index 64dc982ab2..0000000000
--- a/platform/bb10/payment_service.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*************************************************************************/
-/* payment_service.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. */
-/*************************************************************************/
-#ifdef PAYMENT_SERVICE_ENABLED
-
-#ifndef PAYMENT_SERVICE_H
-#define PAYMENT_SERVICE_H
-
-#include <bps/bps.h>
-#include <bps/event.h>
-#include <bps/paymentservice.h>
-
-#include "core/object.h"
-
-class PaymentService : public Object {
-
- GDCLASS(PaymentService, Object);
-
- static void _bind_methods();
-
- List<Variant> pending_events;
-
-public:
- Error request_product_info(Variant p_params);
- Error purchase(Variant p_params);
-
- int get_pending_event_count();
- Variant pop_pending_event();
-
- bool handle_event(bps_event_t *p_event);
-
- PaymentService();
- ~PaymentService();
-};
-
-#endif
-
-#endif
diff --git a/platform/bb10/power_bb10.cpp b/platform/bb10/power_bb10.cpp
deleted file mode 100644
index a683b61376..0000000000
--- a/platform/bb10/power_bb10.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*************************************************************************/
-/* power_bb10.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 "power_bb10.h"
-
-#include "core/error_macros.h"
-
-bool PowerBB10::UpdatePowerInfo() {
-
- return false;
-}
-
-PowerState PowerBB10::get_power_state() {
- if (UpdatePowerInfo()) {
- return power_state;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN");
- return POWERSTATE_UNKNOWN;
- }
-}
-
-int PowerBB10::get_power_seconds_left() {
- if (UpdatePowerInfo()) {
- return nsecs_left;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
- return -1;
- }
-}
-
-int PowerBB10::get_power_percent_left() {
- if (UpdatePowerInfo()) {
- return percent_left;
- } else {
- WARN_PRINT("Power management is not implemented on this platform, defaulting to -1");
- return -1;
- }
-}
-
-PowerBB10::PowerBB10()
- : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) {
-}
-
-PowerBB10::~PowerBB10() {
-}
diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp
index fb6d9afd85..4a9f8c780d 100644
--- a/platform/haiku/haiku_direct_window.cpp
+++ b/platform/haiku/haiku_direct_window.cpp
@@ -151,35 +151,35 @@ void HaikuDirectWindow::HandleMouseButton(BMessage *message) {
}
*/
- InputEvent mouse_event;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
+ Ref<InputEvent> mouse_event;
+ mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON;
mouse_event.device = 0;
mouse_event.mouse_button.mod = GetKeyModifierState(modifiers);
- mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons);
- mouse_event.mouse_button.x = where.x;
- mouse_event.mouse_button.y = where.y;
+ mouse_event->get_button_mask() = GetMouseButtonState(buttons);
+ mouse_event->get_pos().x = where.x;
+ mouse_event->get_pos().y = where.y;
mouse_event.mouse_button.global_x = where.x;
mouse_event.mouse_button.global_y = where.y;
switch (button) {
default:
case B_PRIMARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 1;
+ mouse_event->get_button_index() = 1;
break;
case B_SECONDARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 2;
+ mouse_event->get_button_index() = 2;
break;
case B_TERTIARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 3;
+ mouse_event->get_button_index() = 3;
break;
}
- mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
+ mouse_event->is_pressed() = (message->what == B_MOUSE_DOWN);
- if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
+ if (message->what == B_MOUSE_DOWN && mouse_event->get_button_index() == 1) {
int32 clicks = message->FindInt32("clicks");
if (clicks > 1) {
@@ -207,12 +207,12 @@ void HaikuDirectWindow::HandleMouseMoved(BMessage *message) {
Point2i rel = pos - last_mouse_position;
- InputEvent motion_event;
- motion_event.type = InputEvent::MOUSE_MOTION;
+ Ref<InputEvent> motion_event;
+ motion_event.type = Ref<InputEvent>::MOUSE_MOTION;
motion_event.device = 0;
motion_event.mouse_motion.mod = GetKeyModifierState(modifiers);
- motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons);
+ motion_event->get_button_mask() = GetMouseButtonState(buttons);
motion_event.mouse_motion.x = pos.x;
motion_event.mouse_motion.y = pos.y;
input->set_mouse_position(pos);
@@ -221,8 +221,8 @@ void HaikuDirectWindow::HandleMouseMoved(BMessage *message) {
motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x;
motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- motion_event.mouse_motion.relative_x = rel.x;
- motion_event.mouse_motion.relative_y = rel.y;
+ motion_event->get_relative().x = rel.x;
+ motion_event->get_relative().y = rel.y;
last_mouse_position = pos;
@@ -235,22 +235,22 @@ void HaikuDirectWindow::HandleMouseWheelChanged(BMessage *message) {
return;
}
- InputEvent mouse_event;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
+ Ref<InputEvent> mouse_event;
+ mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON;
mouse_event.device = 0;
- mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5;
+ mouse_event->get_button_index() = wheel_delta_y < 0 ? 4 : 5;
mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state);
- mouse_event.mouse_button.button_mask = last_button_mask;
- mouse_event.mouse_button.x = last_mouse_position.x;
- mouse_event.mouse_button.y = last_mouse_position.y;
+ mouse_event->get_button_mask() = last_button_mask;
+ mouse_event->get_pos().x = last_mouse_position.x;
+ mouse_event->get_pos().y = last_mouse_position.y;
mouse_event.mouse_button.global_x = last_mouse_position.x;
mouse_event.mouse_button.global_y = last_mouse_position.y;
- mouse_event.mouse_button.pressed = true;
+ mouse_event->is_pressed() = true;
input->parse_input_event(mouse_event);
- mouse_event.mouse_button.pressed = false;
+ mouse_event->is_pressed() = false;
input->parse_input_event(mouse_event);
}
@@ -271,13 +271,13 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) {
return;
}
- InputEvent event;
- event.type = InputEvent::KEY;
+ Ref<InputEvent> event;
+ event.type = Ref<InputEvent>::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
- event.key.pressed = (message->what == B_KEY_DOWN);
- event.key.scancode = KeyMappingHaiku::get_keysym(raw_char, key);
- event.key.echo = message->HasInt32("be:key_repeat");
+ event->is_pressed() = (message->what == B_KEY_DOWN);
+ event->get_scancode() = KeyMappingHaiku::get_keysym(raw_char, key);
+ event->is_echo() = message->HasInt32("be:key_repeat");
event.key.unicode = 0;
const char *bytes = NULL;
@@ -286,9 +286,9 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) {
}
//make it consistent across platforms.
- if (event.key.scancode == KEY_BACKTAB) {
- event.key.scancode = KEY_TAB;
- event.key.mod.shift = true;
+ if (event->get_scancode() == KEY_BACKTAB) {
+ event->get_scancode() = KEY_TAB;
+ event->get_shift() = true;
}
input->parse_input_event(event);
@@ -308,13 +308,13 @@ void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage *message) {
int32 key = old_modifiers ^ modifiers;
- InputEvent event;
- event.type = InputEvent::KEY;
+ Ref<InputEvent> event;
+ event.type = Ref<InputEvent>::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
- event.key.pressed = ((modifiers & key) != 0);
- event.key.scancode = KeyMappingHaiku::get_modifier_keysym(key);
- event.key.echo = false;
+ event->is_pressed() = ((modifiers & key) != 0);
+ event->get_scancode() = KeyMappingHaiku::get_modifier_keysym(key);
+ event->is_echo() = false;
event.key.unicode = 0;
input->parse_input_event(event);
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 5d3267cff3..466b8241de 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -5,7 +5,6 @@ Import('env')
iphone_lib = [
'os_iphone.cpp',
- #'rasterizer_iphone.cpp',
'audio_driver_iphone.cpp',
'sem_iphone.cpp',
'gl_view.mm',
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index e075941d36..1f81f0f86e 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -33,6 +33,7 @@
#import "gl_view.h"
#include "main/main.h"
#include "os_iphone.h"
+#include "audio_driver_iphone.h"
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
#include "modules/FacebookScorer_ios/FacebookScorer.h"
@@ -49,6 +50,8 @@
#import <Parse/Parse.h>
#endif
+#import "GameController/GameController.h"
+
#define kFilteringFactor 0.1
#define kRenderingFrequency 60
#define kAccelerometerFrequency 100.0 // Hz
@@ -89,6 +92,282 @@ static ViewController *mainViewController = nil;
return mainViewController;
}
+NSMutableDictionary *ios_joysticks = nil;
+
+- (GCControllerPlayerIndex)getFreePlayerIndex {
+ bool have_player_1 = false;
+ bool have_player_2 = false;
+ bool have_player_3 = false;
+ bool have_player_4 = false;
+
+ if (ios_joysticks == nil) {
+ NSArray *keys = [ios_joysticks allKeys];
+ for (NSNumber *key in keys) {
+ GCController *controller = [ios_joysticks objectForKey:key];
+ if (controller.playerIndex == GCControllerPlayerIndex1) {
+ have_player_1 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex2) {
+ have_player_2 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex3) {
+ have_player_3 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex4) {
+ have_player_4 = true;
+ };
+ };
+ };
+
+ if (!have_player_1) {
+ return GCControllerPlayerIndex1;
+ } else if (!have_player_2) {
+ return GCControllerPlayerIndex2;
+ } else if (!have_player_3) {
+ return GCControllerPlayerIndex3;
+ } else if (!have_player_4) {
+ return GCControllerPlayerIndex4;
+ } else {
+ return GCControllerPlayerIndexUnset;
+ };
+};
+
+- (void)controllerWasConnected:(NSNotification *)notification {
+ // create our dictionary if we don't have one yet
+ if (ios_joysticks == nil) {
+ ios_joysticks = [[NSMutableDictionary alloc] init];
+ };
+
+ // get our controller
+ GCController *controller = (GCController *)notification.object;
+ if (controller == nil) {
+ printf("Couldn't retrieve new controller\n");
+ } else if ([[ios_joysticks allKeysForObject:controller] count] != 0) {
+ printf("Controller is already registered\n");
+ } else {
+ // get a new id for our controller
+ int joy_id = OSIPhone::get_singleton()->get_unused_joy_id();
+ if (joy_id != -1) {
+ // assign our player index
+ if (controller.playerIndex == GCControllerPlayerIndexUnset) {
+ controller.playerIndex = [self getFreePlayerIndex];
+ };
+
+ // tell Godot about our new controller
+ OSIPhone::get_singleton()->joy_connection_changed(
+ joy_id, true, [controller.vendorName UTF8String]);
+
+ // add it to our dictionary, this will retain our controllers
+ [ios_joysticks setObject:controller
+ forKey:[NSNumber numberWithInt:joy_id]];
+
+ // set our input handler
+ [self setControllerInputHandler:controller];
+ } else {
+ printf("Couldn't retrieve new joy id\n");
+ };
+ };
+};
+
+- (void)controllerWasDisconnected:(NSNotification *)notification {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ GCController *controller = (GCController *)notification.object;
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ // tell Godot this joystick is no longer there
+ int joy_id = [key intValue];
+ OSIPhone::get_singleton()->joy_connection_changed(joy_id, false, "");
+
+ // and remove it from our dictionary
+ [ios_joysticks removeObjectForKey:key];
+ };
+ };
+};
+
+- (int)getJoyIdForController:(GCController *)controller {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ int joy_id = [key intValue];
+ return joy_id;
+ };
+ };
+
+ return -1;
+};
+
+- (void)setControllerInputHandler:(GCController *)controller {
+ // Hook in the callback handler for the correct gamepad profile.
+ // This is a bit of a weird design choice on Apples part.
+ // You need to select the most capable gamepad profile for the
+ // gamepad attached.
+ if (controller.extendedGamepad != nil) {
+ // The extended gamepad profile has all the input you could possibly find on
+ // a gamepad but will only be active if your gamepad actually has all of
+ // these...
+ controller.extendedGamepad.valueChangedHandler = ^(
+ GCExtendedGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.leftTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L2,
+ gamepad.leftTrigger.isPressed);
+ } else if (element == gamepad.rightTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R2,
+ gamepad.rightTrigger.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+
+ InputDefault::JoyAxis jx;
+ jx.min = -1;
+ if (element == gamepad.leftThumbstick) {
+ jx.value = gamepad.leftThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx);
+ jx.value = -gamepad.leftThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx);
+ } else if (element == gamepad.rightThumbstick) {
+ jx.value = gamepad.rightThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx);
+ jx.value = -gamepad.rightThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx);
+ } else if (element == gamepad.leftTrigger) {
+ jx.value = gamepad.leftTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx);
+ } else if (element == gamepad.rightTrigger) {
+ jx.value = gamepad.rightTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx);
+ };
+ };
+ } else if (controller.gamepad != nil) {
+ // gamepad is the standard profile with 4 buttons, shoulder buttons and a
+ // D-pad
+ controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad,
+ GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#ifdef ADD_MICRO_GAMEPAD // disabling this for now, only available on iOS 9+,
+ // while we are setting that as the minimum, seems our
+ // build environment doesn't like it
+ } else if (controller.microGamepad != nil) {
+ // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
+ controller.microGamepad.valueChangedHandler =
+ ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#endif
+ };
+
+ ///@TODO need to add support for controller.motion which gives us access to
+ /// the orientation of the device (if supported)
+
+ ///@TODO need to add support for controllerPausedHandler which should be a
+ /// toggle
+};
+
+- (void)initGameControllers {
+ // get told when controllers connect, this will be called right away for
+ // already connected controllers
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasConnected:)
+ name:GCControllerDidConnectNotification
+ object:nil];
+
+ // get told when controllers disconnect
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasDisconnected:)
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+};
+
+- (void)deinitGameControllers {
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidConnectNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+
+ if (ios_joysticks != nil) {
+ [ios_joysticks dealloc];
+ ios_joysticks = nil;
+ };
+};
+
static int frame_count = 0;
- (void)drawView:(GLView *)view;
{
@@ -97,8 +376,10 @@ static int frame_count = 0;
case 0: {
int backingWidth;
int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
OS::VideoMode vm;
vm.fullscreen = true;
@@ -112,25 +393,34 @@ static int frame_count = 0;
};
++frame_count;
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
+ NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
- //NSString *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
- OSIPhone::get_singleton()->set_data_dir(String::utf8([documentsDirectory UTF8String]));
+ // NSString *documentsDirectory = [[[NSFileManager defaultManager]
+ // URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
+ // lastObject];
+ OSIPhone::get_singleton()->set_data_dir(
+ String::utf8([documentsDirectory UTF8String]));
- NSString *locale_code = [[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2];
- OSIPhone::get_singleton()->set_locale(String::utf8([locale_code UTF8String]));
+ NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ OSIPhone::get_singleton()->set_locale(
+ String::utf8([locale_code UTF8String]));
NSString *uuid;
- if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
+ if ([[UIDevice currentDevice]
+ respondsToSelector:@selector(identifierForVendor)]) {
uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
} else {
// before iOS 6, so just generate an identifier and store it
- uuid = [[NSUserDefaults standardUserDefaults] objectForKey:@"identiferForVendor"];
+ uuid = [[NSUserDefaults standardUserDefaults]
+ objectForKey:@"identiferForVendor"];
if (!uuid) {
CFUUIDRef cfuuid = CFUUIDCreate(NULL);
uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid);
CFRelease(cfuuid);
- [[NSUserDefaults standardUserDefaults] setObject:uuid forKey:@"identifierForVendor"];
+ [[NSUserDefaults standardUserDefaults]
+ setObject:uuid
+ forKey:@"identifierForVendor"];
}
}
@@ -138,9 +428,9 @@ static int frame_count = 0;
}; break;
/*
- case 1: {
- ++frame_count;
- }; break;
+ case 1: {
+ ++frame_count;
+ }; break;
*/
case 1: {
@@ -173,9 +463,9 @@ static int frame_count = 0;
}; break;
/*
- case 3: {
- ++frame_count;
- }; break;
+ case 3: {
+ ++frame_count;
+ }; break;
*/
case 2: {
@@ -186,53 +476,85 @@ static int frame_count = 0;
default: {
if (OSIPhone::get_singleton()) {
- //OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]);
+ // OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1],
+ // accel[2]);
if (motionInitialised) {
- // Just using polling approach for now, we can set this up so it sends data to us in intervals, might be better.
- // See Apple reference pages for more details:
+ // Just using polling approach for now, we can set this up so it sends
+ // data to us in intervals, might be better. See Apple reference pages
+ // for more details:
// https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc
- // Apple splits our accelerometer date into a gravity and user movement component. We add them back together
+ // Apple splits our accelerometer date into a gravity and user movement
+ // component. We add them back together
CMAcceleration gravity = motionManager.deviceMotion.gravity;
- CMAcceleration acceleration = motionManager.deviceMotion.userAcceleration;
+ CMAcceleration acceleration =
+ motionManager.deviceMotion.userAcceleration;
- ///@TODO We don't seem to be getting data here, is my device broken or is this code incorrect?
- CMMagneticField magnetic = motionManager.deviceMotion.magneticField.field;
+ ///@TODO We don't seem to be getting data here, is my device broken or
+ /// is this code incorrect?
+ CMMagneticField magnetic =
+ motionManager.deviceMotion.magneticField.field;
- ///@TODO we can access rotationRate as a CMRotationRate variable (processed date) or CMGyroData (raw data), have to see what works best
+ ///@TODO we can access rotationRate as a CMRotationRate variable
+ ///(processed date) or CMGyroData (raw data), have to see what works
+ /// best
CMRotationRate rotation = motionManager.deviceMotion.rotationRate;
// Adjust for screen orientation.
- // [[UIDevice currentDevice] orientation] changes even if we've fixed our orientation which is not
- // a good thing when you're trying to get your user to move the screen in all directions and want consistent output
-
- ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation] is a bit of a hack. Godot obviously knows the orientation so maybe we
+ // [[UIDevice currentDevice] orientation] changes even if we've fixed
+ // our orientation which is not a good thing when you're trying to get
+ // your user to move the screen in all directions and want consistent
+ // output
+
+ ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation]
+ /// is a bit of a hack. Godot obviously knows the orientation so maybe
+ /// we
// can use that instead? (note that left and right seem swapped)
switch ([[UIApplication sharedApplication] statusBarOrientation]) {
case UIDeviceOrientationLandscapeLeft: {
- OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.y + gravity.y), (acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.y, magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x,
+ rotation.z);
}; break;
case UIDeviceOrientationLandscapeRight: {
- OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ (acceleration.y + gravity.y), -(acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ magnetic.y, -magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x,
+ rotation.z);
}; break;
case UIDeviceOrientationPortraitUpsideDown: {
- OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.x + gravity.x), (acceleration.y + gravity.y),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.x, magnetic.y, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y,
+ rotation.z);
}; break;
default: { // assume portrait
- OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
+ OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ acceleration.x + gravity.x, acceleration.y + gravity.y,
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y,
+ magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y,
+ rotation.z);
}; break;
};
}
@@ -247,7 +569,8 @@ static int frame_count = 0;
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
printf("****************** did receive memory warning!\n");
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
- (void)applicationDidFinishLaunching:(UIApplication *)application {
@@ -257,53 +580,66 @@ static int frame_count = 0;
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
// disable idle timer
- //application.idleTimerDisabled = YES;
+ // application.idleTimerDisabled = YES;
- //Create a full-screen window
+ // Create a full-screen window
window = [[UIWindow alloc] initWithFrame:rect];
- //window.autoresizesSubviews = YES;
- //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // window.autoresizesSubviews = YES;
+ //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
- //Create the OpenGL ES view and add it to the window
+ // Create the OpenGL ES view and add it to the window
GLView *glView = [[GLView alloc] initWithFrame:rect];
printf("glview is %p\n", glView);
//[window addSubview:glView];
glView.delegate = self;
- //glView.autoresizesSubviews = YES;
- //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // glView.autoresizesSubviews = YES;
+ //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
int backingWidth;
int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
-
- iphone_main(backingWidth, backingHeight, gargc, gargv);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+
+ int err = iphone_main(backingWidth, backingHeight, gargc, gargv);
+ if (err != 0) {
+ // bail, things did not go very well for us, should probably output a message on screen with our error code...
+ exit(0);
+ return;
+ };
view_controller = [[ViewController alloc] init];
view_controller.view = glView;
window.rootViewController = view_controller;
_set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on", true)) ? YES : NO);
- glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
+ glView.useCADisplayLink =
+ bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
glView.animationInterval = 1.0 / kRenderingFrequency;
[glView startAnimation];
- //Show the window
+ // Show the window
[window makeKeyAndVisible];
- //Configure and start accelerometer
+ // Configure and start accelerometer
if (!motionInitialised) {
motionManager = [[CMMotionManager alloc] init];
if (motionManager.deviceMotionAvailable) {
motionManager.deviceMotionUpdateInterval = 1.0 / 70.0;
- [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
+ [motionManager startDeviceMotionUpdatesUsingReferenceFrame:
+ CMAttitudeReferenceFrameXMagneticNorthZVertical];
motionInitialised = YES;
};
};
- //OSIPhone::screen_width = rect.size.width - rect.origin.x;
- //OSIPhone::screen_height = rect.size.height - rect.origin.y;
+ [self initGameControllers];
+
+ // OSIPhone::screen_width = rect.size.width - rect.origin.x;
+ // OSIPhone::screen_height = rect.size.height - rect.origin.y;
mainViewController = view_controller;
@@ -319,24 +655,33 @@ static int frame_count = 0;
String adid = GLOBAL_DEF("mobileapptracker/advertiser_id", "");
String convkey = GLOBAL_DEF("mobileapptracker/conversion_key", "");
- NSString *advertiser_id = [NSString stringWithUTF8String:adid.utf8().get_data()];
- NSString *conversion_key = [NSString stringWithUTF8String:convkey.utf8().get_data()];
+ NSString *advertiser_id =
+ [NSString stringWithUTF8String:adid.utf8().get_data()];
+ NSString *conversion_key =
+ [NSString stringWithUTF8String:convkey.utf8().get_data()];
// Account Configuration info - must be set
- [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id MATConversionKey:conversion_key];
+ [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id
+ MATConversionKey:conversion_key];
// Used to pass us the IFA, enables highly accurate 1-to-1 attribution.
// Required for many advertising networks.
- [MobileAppTracker setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] advertisingIdentifier]
- advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]];
+ [MobileAppTracker
+ setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager]
+ advertisingIdentifier]
+ advertisingTrackingEnabled:[[ASIdentifierManager sharedManager]
+ isAdvertisingTrackingEnabled]];
#endif
+
};
- (void)applicationWillTerminate:(UIApplication *)application {
printf("********************* will terminate\n");
+ [self deinitGameControllers];
+
if (motionInitialised) {
///@TODO is this the right place to clean this up?
[motionManager stopDeviceMotionUpdates];
@@ -353,7 +698,8 @@ static int frame_count = 0;
///@TODO maybe add pause motionManager? and where would we unpause it?
if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT);
[view_controller.view stopAnimation];
if (OS::get_singleton()->native_video_is_playing()) {
@@ -363,14 +709,15 @@ static int frame_count = 0;
- (void)applicationWillEnterForeground:(UIApplication *)application {
printf("********************* did enter foreground\n");
- //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
[view_controller.view startAnimation];
}
- (void)applicationWillResignActive:(UIApplication *)application {
printf("********************* will resign active\n");
- //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
- [view_controller.view stopAnimation]; // FIXME: pause seems to be recommended elsewhere
+ // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ [view_controller.view
+ stopAnimation]; // FIXME: pause seems to be recommended elsewhere
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
@@ -380,12 +727,18 @@ static int frame_count = 0;
[MobileAppTracker measureSession];
#endif
if (OS::get_singleton()->get_main_loop())
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_IN);
- [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere
+ [view_controller.view
+ startAnimation]; // FIXME: resume seems to be recommended elsewhere
if (OSIPhone::get_singleton()->native_video_is_playing()) {
OSIPhone::get_singleton()->native_video_unpause();
};
+
+ // Fixed audio can not resume if it is interrupted cause by an incoming phone call
+ if(AudioDriverIphone::get_singleton() != NULL)
+ AudioDriverIphone::get_singleton()->start();
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
@@ -397,14 +750,17 @@ static int frame_count = 0;
}
// For 4.2+ support
-- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
+- (BOOL)application:(UIApplication *)application
+ openURL:(NSURL *)url
+ sourceApplication:(NSString *)sourceApplication
+ annotation:(id)annotation {
#ifdef MODULE_PARSE_ENABLED
NSLog(@"Handling application openURL");
- return [[FBSDKApplicationDelegate sharedInstance]
- application:application
- openURL:url
- sourceApplication:sourceApplication
- annotation:annotation];
+ return
+ [[FBSDKApplicationDelegate sharedInstance] application:application
+ openURL:url
+ sourceApplication:sourceApplication
+ annotation:annotation];
#endif
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
@@ -414,21 +770,25 @@ static int frame_count = 0;
#endif
}
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+- (void)application:(UIApplication *)application
+ didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
#ifdef MODULE_PARSE_ENABLED
// Store the deviceToken in the current installation and save it to Parse.
PFInstallation *currentInstallation = [PFInstallation currentInstallation];
- //NSString* token = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding];
+ // NSString* token = [[NSString alloc] initWithData:deviceToken
+ // encoding:NSUTF8StringEncoding];
NSLog(@"Device Token : %@ ", deviceToken);
[currentInstallation setDeviceTokenFromData:deviceToken];
[currentInstallation saveInBackground];
#endif
}
-- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
+- (void)application:(UIApplication *)application
+ didReceiveRemoteNotification:(NSDictionary *)userInfo {
#ifdef MODULE_PARSE_ENABLED
[PFPush handlePush:userInfo];
- NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
+ NSDictionary *aps =
+ [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"Push Notification Payload (app active) %@", aps);
diff --git a/platform/iphone/audio_driver_iphone.cpp b/platform/iphone/audio_driver_iphone.cpp
index dea1ce405d..57b6388016 100644
--- a/platform/iphone/audio_driver_iphone.cpp
+++ b/platform/iphone/audio_driver_iphone.cpp
@@ -148,6 +148,11 @@ OSStatus AudioDriverIphone::output_callback(void *inRefCon,
void AudioDriverIphone::start() {
active = true;
+ // Resume audio
+ // iOS audio-thread stoped if it is interrupted cause by an incoming phone call
+ // Use AudioOutputUnitStart to re-create audio-thread
+ OSStatus result = AudioOutputUnitStart(audio_unit);
+ ERR_FAIL_COND(result != noErr);
};
int AudioDriverIphone::get_mix_rate() const {
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 248c73982b..c20d8e90f4 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -30,7 +30,7 @@ def get_opts():
('store_kit', 'Support for in-app store', 'yes'),
('icloud', 'Support for iCloud', 'yes'),
('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'),
- ('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'),
+ ('ios_exceptions', 'Enable exceptions', 'no'),
('ios_triple', 'Triple for ios toolchain', ''),
('ios_sim', 'Build simulator binary', 'no'),
]
@@ -58,16 +58,17 @@ def configure(env):
if (env["ios_sim"] == "yes" or env["arch"] == "x86"): # i386, simulator
env["arch"] = "x86"
env["bits"] = "32"
- env['CCFLAGS'] = string.split('-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fasm-blocks -D__IPHONE_OS_VERSION_MIN_REQUIRED=40100 -isysroot $IPHONESDK -mios-simulator-version-min=4.3 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"')
- elif (env["arch"] == "arm64"): # arm64
+ env.Append(CCFLAGS=string.split('-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -D__IPHONE_OS_VERSION_MIN_REQUIRED=40100 -isysroot $IPHONESDK -mios-simulator-version-min=4.3 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"'))
+ elif (env["arch"] == "arm" or env["arch"] == "arm32" or env["arch"] == "armv7" or env["bits"] == "32"): # arm
+ env["arch"] = "arm"
+ env["bits"] = "32"
+ env.Append(CCFLAGS=string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=9.0 -MMD -MT dependencies'))
+ else: # armv64
+ env["arch"] = "arm64"
env["bits"] = "64"
- env['CCFLAGS'] = string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=7.0 -isysroot $IPHONESDK')
+ env.Append(CCFLAGS=string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=9.0 -isysroot $IPHONESDK'))
env.Append(CPPFLAGS=['-DNEED_LONG_INT'])
env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON'])
- else: # armv7
- env["arch"] = "arm"
- env["bits"] = "32"
- env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=7.0 -MMD -MT dependencies -isysroot $IPHONESDK')
if (env["arch"] == "x86"):
env['IPHONEPLATFORM'] = 'iPhoneSimulator'
@@ -90,10 +91,11 @@ def configure(env):
'-framework', 'OpenGLES',
'-framework', 'QuartzCore',
'-framework', 'SystemConfiguration',
+ '-framework', 'GameController',
'-F$IPHONESDK',
])
elif (env["arch"] == "arm64"):
- env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=7.0',
+ env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=9.0',
'-isysroot', '$IPHONESDK',
#'-stdlib=libc++',
'-framework', 'Foundation',
@@ -110,9 +112,10 @@ def configure(env):
'-framework', 'AVFoundation',
'-framework', 'CoreMedia',
'-framework', 'CoreMotion',
+ '-framework', 'GameController',
])
else:
- env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=7.0',
+ env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=9.0',
'-isysroot', '$IPHONESDK',
'-framework', 'Foundation',
'-framework', 'UIKit',
@@ -128,10 +131,11 @@ def configure(env):
'-framework', 'AVFoundation',
'-framework', 'CoreMedia',
'-framework', 'CoreMotion',
+ '-framework', 'GameController',
])
if env['game_center'] == 'yes':
- env.Append(CPPFLAGS=['-fblocks', '-DGAME_CENTER_ENABLED'])
+ env.Append(CPPFLAGS=['-DGAME_CENTER_ENABLED'])
env.Append(LINKFLAGS=['-framework', 'GameKit'])
if env['store_kit'] == 'yes':
@@ -143,26 +147,20 @@ def configure(env):
env.Append(CPPPATH=['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers'])
- if (env["target"] == "release"):
+ if (env["target"].startswith("release")):
- env.Append(CCFLAGS=['-O3', '-DNS_BLOCK_ASSERTIONS=1', '-gdwarf-2']) # removed -ffast-math
- env.Append(LINKFLAGS=['-O3'])
+ env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1'])
+ env.Append(CPPFLAGS=['-O2', '-flto', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations'])
+ env.Append(LINKFLAGS=['-O2', '-flto'])
- elif env["target"] == "release_debug":
- env.Append(CCFLAGS=['-Os', '-DNS_BLOCK_ASSERTIONS=1', '-DDEBUG_ENABLED'])
- env.Append(LINKFLAGS=['-Os'])
- env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED'])
+ if env["target"] == "release_debug":
+ env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-O0', '-DDEBUG_ENABLED'])
+ env.Append(CPPFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-O0', '-DDEBUG_ENABLED'])
env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED'])
- elif (env["target"] == "profile"):
-
- env.Append(CCFLAGS=['-g', '-pg', '-Os'])
- env.Append(LINKFLAGS=['-pg'])
-
if (env["ios_sim"] == "yes"): # TODO: Check if needed?
env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate'
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index 5329d4f02a..2572d626d2 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -39,6 +39,8 @@ class iOS : public Object {
static void _bind_methods();
public:
+ static void alert(const char *p_alert, const char *p_title);
+
String get_rate_url(int p_app_id) const;
iOS();
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index cd64bbfafc..e9c164393b 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -36,6 +36,11 @@ void iOS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url);
};
+void iOS::alert(const char* p_alert, const char* p_title) {
+ UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:p_title] message:[NSString stringWithUTF8String:p_alert] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease];
+ [alert show];
+}
+
String iOS::get_rate_url(int p_app_id) const {
String templ = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
String templ_iOS7 = "itms-apps://itunes.apple.com/app/idAPP_ID";
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index bc25afabea..b244edbff6 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -195,24 +195,24 @@ bool OSIPhone::iterate() {
void OSIPhone::key(uint32_t p_key, bool p_pressed) {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.key.echo = false;
- ev.key.pressed = p_pressed;
- ev.key.scancode = p_key;
- ev.key.unicode = p_key;
+ Ref<InputEventKey> ev;
+ ev.instance();
+ ev->set_echo(false);
+ ev->set_pressed(p_pressed);
+ ev->set_scancode(p_key);
+ ev->set_unicode(p_key);
queue_event(ev);
};
void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.screen_touch.index = p_idx;
- ev.screen_touch.pressed = p_pressed;
- ev.screen_touch.x = p_x;
- ev.screen_touch.y = p_y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(p_idx);
+ ev->set_pressed(p_pressed);
+ ev->set_position(Vector2(p_x, p_y));
queue_event(ev);
};
@@ -220,23 +220,20 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
if (p_use_as_mouse) {
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.device = 0;
- ev.mouse_button.pointer_index = p_idx;
-
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
// swaped it for tilted screen
- //ev.mouse_button.x = ev.mouse_button.global_x = video_mode.height - p_y;
- //ev.mouse_button.y = ev.mouse_button.global_y = p_x;
- ev.mouse_button.x = ev.mouse_button.global_x = p_x;
- ev.mouse_button.y = ev.mouse_button.global_y = p_y;
+ //ev->get_pos().x = ev.mouse_button.global_x = video_mode.height - p_y;
+ //ev->get_pos().y = ev.mouse_button.global_y = p_x;
+ ev->set_position(Vector2(video_mode.height - p_y, p_x));
+ ev->set_global_position(Vector2(video_mode.height - p_y, p_x));
//mouse_list.pressed[p_idx] = p_pressed;
- input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.doubleclick = p_doubleclick;
- ev.mouse_button.pressed = p_pressed;
+ input->set_mouse_position(ev->get_position());
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_doubleclick(p_doubleclick);
+ ev->set_pressed(p_pressed);
queue_event(ev);
};
@@ -246,46 +243,31 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_
if (!GLOBAL_DEF("debug/disable_touch", false)) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.screen_drag.index = p_idx;
- ev.screen_drag.x = p_x;
- ev.screen_drag.y = p_y;
- ev.screen_drag.relative_x = p_x - p_prev_x;
- ev.screen_drag.relative_y = p_y - p_prev_y;
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(p_idx);
+ ev->set_position(Vector2(p_x, p_y));
+ ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
queue_event(ev);
};
if (p_use_as_mouse) {
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.device = 0;
- ev.mouse_motion.pointer_index = p_idx;
-
- if (true) { // vertical
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
- ev.mouse_motion.x = ev.mouse_button.global_x = p_x;
- ev.mouse_motion.y = ev.mouse_button.global_y = p_y;
- ev.mouse_motion.relative_x = ev.mouse_motion.x - p_prev_x;
- ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_y;
-
- } else { // horizontal?
- ev.mouse_motion.x = ev.mouse_button.global_x = video_mode.height - p_y;
- ev.mouse_motion.y = ev.mouse_button.global_y = p_x;
- ev.mouse_motion.relative_x = ev.mouse_motion.x - (video_mode.height - p_prev_x);
- ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_x;
- };
+ ev->set_position(Vector2(p_x, p_y));
+ ev->set_global_position(Vector2(p_x, p_y));
+ ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
- input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.button_mask = 1; // pressed
+ input->set_mouse_position(ev->get_position());
+ ev->set_speed(input->get_last_mouse_speed());
+ ev->set_button_mask(BUTTON_LEFT); // pressed
queue_event(ev);
};
};
-void OSIPhone::queue_event(const InputEvent &p_event) {
+void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
ERR_FAIL_INDEX(event_count, MAX_EVENTS);
@@ -357,6 +339,22 @@ void OSIPhone::update_gyroscope(float p_x, float p_y, float p_z) {
input->set_gyroscope(Vector3(p_x, p_y, p_z));
};
+int OSIPhone::get_unused_joy_id() {
+ return input->get_unused_joy_id();
+};
+
+void OSIPhone::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
+ input->joy_connection_changed(p_idx, p_connected, p_name);
+};
+
+void OSIPhone::joy_button(int p_device, int p_button, bool p_pressed) {
+ input->joy_button(p_device, p_button, p_pressed);
+};
+
+void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value) {
+ input->joy_axis(p_device, p_axis, p_value);
+};
+
void OSIPhone::delete_main_loop() {
if (main_loop) {
@@ -405,6 +403,13 @@ int OSIPhone::get_mouse_button_state() const {
void OSIPhone::set_window_title(const String &p_title){};
+void OSIPhone::alert(const String &p_alert, const String &p_title) {
+
+ const CharString utf8_alert = p_alert.utf8();
+ const CharString utf8_title = p_title.utf8();
+ iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
+}
+
void OSIPhone::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
video_mode = p_video_mode;
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 754dea073f..4031b7524c 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -118,9 +118,9 @@ private:
Vector3 last_accel;
- InputEvent event_queue[MAX_EVENTS];
+ Ref<InputEvent> event_queue[MAX_EVENTS];
int event_count;
- void queue_event(const InputEvent &p_event);
+ void queue_event(const Ref<InputEvent> &p_event);
String data_dir;
String unique_ID;
@@ -145,6 +145,11 @@ public:
void update_magnetometer(float p_x, float p_y, float p_z);
void update_gyroscope(float p_x, float p_y, float p_z);
+ int get_unused_joy_id();
+ void joy_connection_changed(int p_idx, bool p_connected, String p_name);
+ void joy_button(int p_device, int p_button, bool p_pressed);
+ void joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value);
+
static OSIPhone *get_singleton();
virtual void set_mouse_show(bool p_show);
@@ -154,6 +159,8 @@ public:
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
+ virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
+
virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0);
virtual VideoMode get_video_mode(int p_screen = 0) const;
virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const;
diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp
deleted file mode 100644
index ff13ff1b89..0000000000
--- a/platform/iphone/rasterizer_iphone.cpp
+++ /dev/null
@@ -1,2585 +0,0 @@
-/*************************************************************************/
-/* rasterizer_iphone.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
-#ifdef IPHONE_ENABLED
-
-#include "rasterizer_iphone.h"
-#include "global_config.h"
-#include "os/os.h"
-#include <stdio.h>
-
-_FORCE_INLINE_ static void _gl_load_transform(const Transform &tr) {
-
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
- };
-
- glLoadMatrixf(matrix);
-};
-
-_FORCE_INLINE_ static void _gl_mult_transform(const Transform &tr) {
-
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
- };
-
- glMultMatrixf(matrix);
-};
-
-static const GLenum prim_type[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
-
-static void _draw_primitive(int p_points, const float *p_vertices, const float *p_normals, const float *p_colors, const float *p_uvs, const Plane *p_tangents = NULL, int p_instanced = 1) {
-
- ERR_FAIL_COND(!p_vertices);
- ERR_FAIL_COND(p_points < 1 || p_points > 4);
-
- GLenum type = prim_type[p_points - 1];
-
- if (!p_colors) {
- glColor4f(1, 1, 1, 1);
- };
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, (GLvoid *)p_vertices);
-
- if (p_normals) {
-
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, (GLvoid *)p_normals);
- };
-
- if (p_colors) {
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4, GL_FLOAT, 0, p_colors);
- };
-
- if (p_uvs) {
-
- glClientActiveTexture(GL_TEXTURE0);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, p_uvs);
- };
-
- glDrawArrays(type, 0, p_points);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-};
-
-/* TEXTURE API */
-
-static Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, int &r_gl_components, bool &r_has_alpha_cache) {
-
- r_has_alpha_cache = false;
- Image image = p_image;
-
- switch (p_format) {
-
- case Image::FORMAT_L8: {
- r_gl_components = 1;
- r_gl_format = GL_LUMINANCE;
-
- } break;
- case Image::FORMAT_INTENSITY: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
- case Image::FORMAT_LA8: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
-
- case Image::FORMAT_INDEXED: {
-
- image.convert(Image::FORMAT_RGB8);
- r_gl_components = 3;
- r_gl_format = GL_RGB;
-
- } break;
-
- case Image::FORMAT_INDEXED_ALPHA: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGB;
- r_has_alpha_cache = true;
-
- } break;
- case Image::FORMAT_RGB8: {
-
- r_gl_components = 3;
- r_gl_format = GL_RGB;
- } break;
- case Image::FORMAT_RGBA8: {
-
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
- default: {
-
- ERR_FAIL_V(Image());
- }
- }
-
- return image;
-}
-
-RID RasterizerIPhone::texture_create() {
-
- Texture *texture = memnew(Texture);
- ERR_FAIL_COND_V(!texture, RID());
- glGenTextures(1, &texture->tex_id);
- texture->active = false;
-
- return texture_owner.make_rid(texture);
-}
-
-void RasterizerIPhone::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
-
- bool has_alpha_cache;
- int components;
- GLenum format;
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
- texture->width = p_width;
- texture->height = p_height;
- texture->format = p_format;
- texture->flags = p_flags;
- //texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
- texture->target = GL_TEXTURE_2D;
-
- _get_gl_image_and_format(Image(), texture->format, texture->flags, format, components, has_alpha_cache);
-
- texture->gl_components_cache = components;
- texture->gl_format_cache = format;
- texture->format_has_alpha = has_alpha_cache;
- texture->has_alpha = false; //by default it doesn't have alpha unless something with alpha is blitteds
-
- glBindTexture(texture->target, texture->tex_id);
-
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
- }
-
- if (texture->target == GL_TEXTURE_2D) {
- glTexImage2D(texture->target, 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, NULL);
- }
-
- /*
- else {
- //cubemappor
- for (int i=0;i<6;i++)
- glTexImage2D(_cube_side_enum[i], 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE,NULL);
- }
- */
-
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
-
- if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
- //glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
- };
- }
-
- if (texture->flags & VS::TEXTURE_FLAG_REPEAT /* && texture->target != GL_TEXTURE_CUBE_MAP*/) {
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- } else {
-
- //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- texture->active = true;
-}
-
-void RasterizerIPhone::texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side) {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND(!texture);
- ERR_FAIL_COND(!texture->active);
- ERR_FAIL_COND(texture->format != p_image.get_format());
-
- int components;
- GLenum format;
- bool alpha;
-
- Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, components, alpha);
-
- if (img.detect_alpha())
- texture->has_alpha = true;
-
- GLenum blit_target = GL_TEXTURE_2D; //(texture->target == GL_TEXTURE_CUBE_MAP)?_cube_side_enum[p_cube_side]:GL_TEXTURE_2D;
-
- PoolVector<uint8_t>::Read read = img.get_data().read();
-
- glBindTexture(texture->target, texture->tex_id);
- glTexSubImage2D(blit_target, 0, p_x, p_y, img.get_width(), img.get_height(), format, GL_UNSIGNED_BYTE, read.ptr());
-
- //glGenerateMipmap( texture->target );
-}
-
-Image RasterizerIPhone::texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side) const {
-
- return Image();
-}
-void RasterizerIPhone::texture_set_flags(RID p_texture, uint32_t p_flags) {
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
-
- glBindTexture(texture->target, texture->tex_id);
- uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
- texture->flags = p_flags | cube; // can't remove a cube from being a cube
-
- if (texture->flags & VS::TEXTURE_FLAG_REPEAT /*&& texture->target != GL_TEXTURE_CUBE_MAP*/) {
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- } else {
- //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS)
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-
- } else {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // nearest
- }
-}
-uint32_t RasterizerIPhone::texture_get_flags(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->flags;
-}
-Image::Format RasterizerIPhone::texture_get_format(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, Image::FORMAT_L8);
-
- return texture->format;
-}
-uint32_t RasterizerIPhone::texture_get_width(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->width;
-}
-uint32_t RasterizerIPhone::texture_get_height(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->height;
-}
-
-bool RasterizerIPhone::texture_has_alpha(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->has_alpha;
-}
-
-/* SHADER API */
-
-RID RasterizerIPhone::shader_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id) {
-}
-void RasterizerIPhone::shader_node_remove(RID p_shader, int p_id) {
-}
-void RasterizerIPhone::shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type) {
-}
-void RasterizerIPhone::shader_node_set_param(RID p_shader, int p_id, const Variant &p_value) {
-}
-
-void RasterizerIPhone::shader_get_node_list(RID p_shader, List<int> *p_node_list) const {
-}
-VS::ShaderNodeType RasterizerIPhone::shader_node_get_type(RID p_shader, int p_id) const {
-
- return VS::NODE_ADD;
-}
-Variant RasterizerIPhone::shader_node_get_param(RID p_shader, int p_id) const {
-
- return Variant();
-}
-
-void RasterizerIPhone::shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
-}
-bool RasterizerIPhone::shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const {
-
- return false;
-}
-
-void RasterizerIPhone::shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
-}
-
-void RasterizerIPhone::shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const {
-}
-
-void RasterizerIPhone::shader_clear(RID p_shader) {
-}
-
-/* COMMON MATERIAL API */
-
-void RasterizerIPhone::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
-}
-Variant RasterizerIPhone::material_get_param(RID p_material, const StringName &p_param) const {
-
- return Variant();
-}
-void RasterizerIPhone::material_get_param_list(RID p_material, List<String> *p_param_list) const {
-}
-
-void RasterizerIPhone::material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled) {
-}
-bool RasterizerIPhone::material_get_flag(RID p_material, VS::MaterialFlag p_flag) const {
-
- return false;
-}
-
-void RasterizerIPhone::material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
-}
-VS::MaterialBlendMode RasterizerIPhone::material_get_blend_mode(RID p_material) const {
-
- return VS::MATERIAL_BLEND_MODE_ADD;
-}
-
-void RasterizerIPhone::material_set_line_width(RID p_material, float p_line_width) {
-}
-float RasterizerIPhone::material_get_line_width(RID p_material) const {
-
- return 0;
-}
-
-/* FIXED MATERIAL */
-
-RID RasterizerIPhone::material_create() {
-
- return material_owner.make_rid(memnew(Material));
-}
-
-void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant &p_value) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->parameters[p_parameter] = p_value;
-}
-Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::SpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, Variant());
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
-
- return m->parameters[p_parameter];
-}
-
-void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::SpatialMaterialParam p_parameter, RID p_texture) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->textures[p_parameter] = p_texture;
-}
-RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::SpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, RID());
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
-
- return m->textures[p_parameter];
-}
-
-void RasterizerIPhone::fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->detail_blend_mode = p_mode;
-}
-VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::MATERIAL_BLEND_MODE_MIX);
-
- return m->detail_blend_mode;
-}
-
-void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->texcoord_mode[p_parameter] = p_mode;
-}
-VS::SpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, VS::FIXED_MATERIAL_TEXCOORD_UV);
-
- return m->texcoord_mode[p_parameter]; // for now
-}
-
-void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::SpatialMaterialTexGenMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->texgen_mode = p_mode;
-};
-
-VS::SpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);
-
- return m->texgen_mode;
-};
-
-void RasterizerIPhone::fixed_material_set_uv_transform(RID p_material, const Transform &p_transform) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->uv_transform = p_transform;
-}
-Transform RasterizerIPhone::fixed_material_get_uv_transform(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, Transform());
-
- return m->uv_transform;
-}
-
-/* SHADER MATERIAL */
-
-RID RasterizerIPhone::shader_material_create() const {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned) {
-}
-RID RasterizerIPhone::shader_material_get_vertex_shader(RID p_material) const {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned) {
-}
-RID RasterizerIPhone::shader_material_get_fragment_shader(RID p_material) const {
-
- return RID();
-}
-
-/* MESH API */
-
-RID RasterizerIPhone::mesh_create() {
-
- return mesh_owner.make_rid(memnew(Mesh));
-}
-
-void RasterizerIPhone::mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
-
- ERR_FAIL_COND((p_format & VS::ARRAY_FORMAT_VERTEX) == 0); // mandatory
- ERR_FAIL_COND(p_array_len <= 0);
- ERR_FAIL_COND(p_index_array_len == 0);
- ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
-
- Surface *surface = memnew(Surface);
- ERR_FAIL_COND(!surface);
-
- int total_elem_size = 0;
-
- bool use_VBO = true; //glGenBuffersARB!=NULL; // TODO detect if it's in there
- if (p_format & VS::ARRAY_FORMAT_WEIGHTS) {
-
- use_VBO = false;
- }
-
- for (int i = 0; i < VS::ARRAY_MAX; i++) {
-
- Surface::ArrayData &ad = surface->array[i];
- ad.size = 0;
- ad.configured = false;
- ad.ofs = 0;
- int elem_size = 0;
- int elem_count = 0;
-
- if (!(p_format & (1 << i))) // no array
- continue;
-
- switch (i) {
-
- case VS::ARRAY_VERTEX:
- case VS::ARRAY_NORMAL: {
-
- elem_size = 3 * sizeof(GLfloat); // vertex
- elem_count = 3;
- } break;
- case VS::ARRAY_TANGENT: {
- elem_size = 4 * sizeof(GLfloat); // vertex
- elem_count = 4;
-
- } break;
- case VS::ARRAY_COLOR: {
-
- elem_size = 4; /* RGBA */
- elem_count = 4;
- } break;
- case VS::ARRAY_TEX_UV: {
- elem_size = 2 * sizeof(GLfloat);
- elem_count = 2;
-
- } break;
- case VS::ARRAY_WEIGHTS:
- case VS::ARRAY_BONES: {
-
- elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLfloat);
- elem_count = VS::ARRAY_WEIGHTS_SIZE;
-
- } break;
- case VS::ARRAY_INDEX: {
-
- if (p_index_array_len <= 0) {
- ERR_PRINT("p_index_array_len==NO_INDEX_ARRAY");
- break;
- }
- /* determine wether using 8 or 16 bits indices */
- if (p_index_array_len > (1 << 8)) {
-
- elem_size = 2;
- } else {
- elem_size = 1;
- }
-
- if (use_VBO) {
-
- glGenBuffers(1, &surface->index_id);
- ERR_FAIL_COND(surface->index_id == 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_index_array_len * elem_size, NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
- } else {
- surface->index_array_local = (uint8_t *)memalloc(p_index_array_len * elem_size);
- };
-
- surface->index_array_len = p_index_array_len; // only way it can exist
- ad.ofs = 0;
- ad.size = elem_size;
- ad.configured = false;
- ad.components = 1;
-
- continue;
- } break;
- default: {
- ERR_FAIL();
- }
- }
-
- ad.ofs = total_elem_size;
- ad.size = elem_size;
- ad.components = elem_count;
- total_elem_size += elem_size;
- ad.configured = false;
- }
-
- surface->stride = total_elem_size;
- surface->array_len = p_array_len;
- surface->format = p_format;
- surface->primitive = p_primitive;
-
- /* bind the bigass buffers */
- if (use_VBO) {
-
- glGenBuffers(1, &surface->vertex_id);
- ERR_FAIL_COND(surface->vertex_id == 0);
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, surface->array_len * surface->stride, NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- } else {
- surface->array_local = (uint8_t *)memalloc(surface->array_len * surface->stride);
- };
-
- mesh->surfaces.push_back(surface);
-}
-
-Error RasterizerIPhone::mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array) {
-
- ERR_FAIL_INDEX_V(p_type, VS::ARRAY_MAX, ERR_INVALID_PARAMETER);
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, ERR_INVALID_PARAMETER);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), ERR_INVALID_PARAMETER);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, ERR_INVALID_PARAMETER);
-
- ERR_FAIL_COND_V(surface->array[p_type].size == 0, ERR_INVALID_PARAMETER);
-
- Surface::ArrayData &a = surface->array[p_type];
-
- switch (p_type) {
-
- case VS::ARRAY_INDEX: {
- ERR_FAIL_COND_V(surface->index_array_len <= 0, ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_array.get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<int> indices = p_array;
- ERR_FAIL_COND_V(indices.size() == 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(indices.size() != surface->index_array_len, ERR_INVALID_PARAMETER);
-
- /* determine wether using 16 or 32 bits indices */
-
- if (surface->index_array_local == 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- };
-
- PoolVector<int>::Read read = indices.read();
- const int *src = read.ptr();
-
- for (int i = 0; i < surface->index_array_len; i++) {
-
- if (surface->index_array_local) {
-
- if (a.size <= (1 << 8)) {
- uint8_t v = src[i];
-
- copymem(&surface->array_local[i * a.size], &v, a.size);
- } else {
- uint16_t v = src[i];
-
- copymem(&surface->array_local[i * a.size], &v, a.size);
- }
-
- } else {
- if (a.size <= (1 << 8)) {
- uint8_t v = src[i];
-
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
- } else {
- uint16_t v = src[i];
-
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
- }
- };
- }
- if (surface->index_array_local == 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- };
- a.configured = true;
- return OK;
- } break;
- case VS::ARRAY_VERTEX:
- case VS::ARRAY_NORMAL: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Vector3> array = p_array;
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- };
-
- PoolVector<Vector3>::Read read = array.read();
- const Vector3 *src = read.ptr();
-
- // setting vertices means regenerating the AABB
- if (p_type == VS::ARRAY_VERTEX)
- surface->aabb = AABB();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat vector[3] = { src[i].x, src[i].y, src[i].z };
-
- if (surface->array_local == 0) {
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, vector);
- } else {
- copymem(&surface->array_local[a.ofs + i * surface->stride], vector, a.size);
- }
-
- if (p_type == VS::ARRAY_VERTEX) {
-
- if (i == 0) {
-
- surface->aabb = AABB(src[i], Vector3());
- } else {
-
- surface->aabb.expand_to(src[i]);
- }
- }
- }
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- };
-
- } break;
- case VS::ARRAY_TANGENT: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<real_t> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len * 4, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- };
-
- PoolVector<real_t>::Read read = array.read();
- const real_t *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat xyzw[4] = {
- src[i * 4 + 0],
- src[i * 4 + 1],
- src[i * 4 + 2],
- src[i * 4 + 3]
- };
-
- if (surface->array_local == 0) {
-
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, xyzw);
- } else {
-
- copymem(&surface->array_local[a.ofs + i * surface->stride], xyzw, a.size);
- };
- }
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- };
- } break;
- case VS::ARRAY_COLOR: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::COLOR_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Color> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<Color>::Read read = array.read();
- const Color *src = read.ptr();
- surface->has_alpha_cache = false;
-
- for (int i = 0; i < surface->array_len; i++) {
-
- if (src[i].a < 0.98) // tolerate alpha a bit, for crappy exporters
- surface->has_alpha_cache = true;
- uint8_t colors[4] = { src[i].r * 255.0, src[i].g * 255.0, src[i].b * 255.0, src[i].a * 255.0 };
- // I'm not sure if this is correct, endianness-wise, i should re-check the GL spec
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, colors);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], colors, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } break;
- case VS::ARRAY_TEX_UV: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Vector3> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<Vector3>::Read read = array.read();
-
- const Vector3 *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat uv[2] = { src[i].x, src[i].y };
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, uv);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], uv, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } break;
- case VS::ARRAY_BONES:
- case VS::ARRAY_WEIGHTS: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<real_t> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<real_t>::Read read = array.read();
-
- const real_t *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat data[VS::ARRAY_WEIGHTS_SIZE];
- for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++)
- data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j];
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, data);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], data, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- } break;
- default: { ERR_FAIL_V(ERR_INVALID_PARAMETER); }
- }
-
- a.configured = true;
-
- return OK;
-}
-Variant RasterizerIPhone::mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const {
-
- return Variant();
-}
-
-void RasterizerIPhone::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND(!surface);
-
- if (surface->material_owned && surface->material.is_valid())
- free(surface->material);
-
- surface->material_owned = p_owned;
-
- surface->material = p_material;
-}
-
-RID RasterizerIPhone::mesh_surface_get_material(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, RID());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID());
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, RID());
-
- return surface->material;
-}
-
-int RasterizerIPhone::mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, -1);
-
- return surface->array_len;
-}
-int RasterizerIPhone::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, -1);
-
- return surface->index_array_len;
-}
-uint32_t RasterizerIPhone::mesh_surface_get_format(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, 0);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, 0);
-
- return surface->format;
-}
-VS::PrimitiveType RasterizerIPhone::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_POINTS);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, VS::PRIMITIVE_POINTS);
-
- return surface->primitive;
-}
-
-void RasterizerIPhone::mesh_erase_surface(RID p_mesh, int p_index) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_index, mesh->surfaces.size());
- Surface *surface = mesh->surfaces[p_index];
- ERR_FAIL_COND(!surface);
-
- memdelete(mesh->surfaces[p_index]);
- mesh->surfaces.remove(p_index);
-}
-int RasterizerIPhone::mesh_get_surface_count(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
-
- return mesh->surfaces.size();
-}
-
-AABB RasterizerIPhone::mesh_get_aabb(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, AABB());
-
- AABB aabb;
-
- for (int i = 0; i < mesh->surfaces.size(); i++) {
-
- if (i == 0)
- aabb = mesh->surfaces[i]->aabb;
- else
- aabb.merge_with(mesh->surfaces[i]->aabb);
- }
-
- return aabb;
-}
-
-/* MULTIMESH API */
-
-RID RasterizerIPhone::multimesh_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::multimesh_set_instance_count(RID p_multimesh, int p_count) {
-}
-int RasterizerIPhone::multimesh_get_instance_count(RID p_multimesh) const {
-
- return 0;
-}
-
-void RasterizerIPhone::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
-}
-void RasterizerIPhone::multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb) {
-}
-void RasterizerIPhone::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
-}
-void RasterizerIPhone::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
-}
-
-RID RasterizerIPhone::multimesh_get_mesh(RID p_multimesh) const {
-
- return RID();
-}
-AABB RasterizerIPhone::multimesh_get_aabb(RID p_multimesh) const {
-
- return AABB();
-}
-
-Transform RasterizerIPhone::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
-
- return Transform();
-}
-Color RasterizerIPhone::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
-
- return Color();
-}
-
-/* POLY API */
-
-RID RasterizerIPhone::poly_create() {
-
- return RID();
-}
-void RasterizerIPhone::poly_set_material(RID p_poly, RID p_material, bool p_owned) {
-}
-void RasterizerIPhone::poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs) {
-}
-void RasterizerIPhone::poly_clear(RID p_poly) {
-}
-
-AABB RasterizerIPhone::poly_get_aabb(RID p_poly) const {
-
- return AABB();
-}
-
-/* PARTICLES API */
-
-RID RasterizerIPhone::particles_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::particles_set_amount(RID p_particles, int p_amount) {
-}
-int RasterizerIPhone::particles_get_amount(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_emitting(RID p_particles, bool p_emitting) {
-}
-
-bool RasterizerIPhone::particles_is_emitting(RID p_particles) const {
-
- return false;
-}
-
-void RasterizerIPhone::particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility) {
-}
-AABB RasterizerIPhone::particles_get_visibility_aabb(RID p_particles) const {
-
- return AABB();
-}
-
-void RasterizerIPhone::particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents) {
-}
-Vector3 RasterizerIPhone::particles_get_emission_half_extents(RID p_particles) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal) {
-}
-Vector3 RasterizerIPhone::particles_get_gravity_normal(RID p_particles) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value) {
-}
-float RasterizerIPhone::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness) {
-}
-float RasterizerIPhone::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) {
-}
-float RasterizerIPhone::particles_get_color_phase_pos(RID p_particles, int p_phase) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phases(RID p_particles, int p_phases) {
-}
-int RasterizerIPhone::particles_get_color_phases(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color) {
-}
-Color RasterizerIPhone::particles_get_color_phase_color(RID p_particles, int p_phase) const {
-
- return Color();
-}
-
-void RasterizerIPhone::particles_set_attractors(RID p_particles, int p_attractors) {
-}
-int RasterizerIPhone::particles_get_attractors(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos) {
-}
-Vector3 RasterizerIPhone::particles_get_attractor_pos(RID p_particles, int p_attractor) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) {
-}
-float RasterizerIPhone::particles_get_attractor_strength(RID p_particles, int p_attractor) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_material(RID p_particles, RID p_material, bool p_owned) {
-}
-
-RID RasterizerIPhone::particles_get_material(RID p_particles) const {
-
- return RID();
-}
-
-AABB RasterizerIPhone::particles_get_aabb(RID p_particles) const {
-
- return AABB();
-}
-/* BEAM API */
-
-RID RasterizerIPhone::beam_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::beam_set_point_count(RID p_beam, int p_count) {
-}
-int RasterizerIPhone::beam_get_point_count(RID p_beam) const {
-
- return 0;
-}
-void RasterizerIPhone::beam_clear(RID p_beam) {
-}
-
-void RasterizerIPhone::beam_set_point(RID p_beam, int p_point, Vector3 &p_pos) {
-}
-Vector3 RasterizerIPhone::beam_get_point(RID p_beam, int p_point) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive) {
-}
-
-VS::BeamPrimitive RasterizerIPhone::beam_get_primitive(RID p_beam) const {
-
- return VS::BEAM_CUBIC;
-}
-
-void RasterizerIPhone::beam_set_material(RID p_beam, RID p_material) {
-}
-RID RasterizerIPhone::beam_get_material(RID p_beam) const {
-
- return RID();
-}
-
-AABB RasterizerIPhone::beam_get_aabb(RID p_particles) const {
-
- return AABB();
-}
-/* SKELETON API */
-
-RID RasterizerIPhone::skeleton_create() {
-
- Skeleton *skeleton = memnew(Skeleton);
- ERR_FAIL_COND_V(!skeleton, RID());
- return skeleton_owner.make_rid(skeleton);
-}
-void RasterizerIPhone::skeleton_resize(RID p_skeleton, int p_bones) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND(!skeleton);
- if (p_bones == skeleton->bones.size()) {
- return;
- };
- ERR_FAIL_COND(p_bones < 0 || p_bones > 256);
-
- skeleton->bones.resize(p_bones);
-}
-int RasterizerIPhone::skeleton_get_bone_count(RID p_skeleton) const {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND_V(!skeleton, -1);
- return skeleton->bones.size();
-}
-void RasterizerIPhone::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND(!skeleton);
- ERR_FAIL_INDEX(p_bone, skeleton->bones.size());
-
- skeleton->bones[p_bone] = p_transform;
-}
-Transform RasterizerIPhone::skeleton_bone_get_transform(RID p_skeleton, int p_bone) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND_V(!skeleton, Transform());
- ERR_FAIL_INDEX_V(p_bone, skeleton->bones.size(), Transform());
-
- // something
- return skeleton->bones[p_bone];
-}
-
-/* LIGHT API */
-
-RID RasterizerIPhone::light_create(VS::LightType p_type) {
-
- Light *light = memnew(Light);
- light->type = p_type;
- return light_owner.make_rid(light);
-}
-
-VS::LightType RasterizerIPhone::light_get_type(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI);
- return light->type;
-}
-
-void RasterizerIPhone::light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX(p_type, 3);
- light->colors[p_type] = p_color;
-}
-Color RasterizerIPhone::light_get_color(RID p_light, VS::LightColor p_type) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, Color());
- ERR_FAIL_INDEX_V(p_type, 3, Color());
- return light->colors[p_type];
-}
-
-void RasterizerIPhone::light_set_shadow(RID p_light, bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->shadow_enabled = p_enabled;
-}
-
-bool RasterizerIPhone::light_has_shadow(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, false);
- return light->shadow_enabled;
-}
-
-void RasterizerIPhone::light_set_volumetric(RID p_light, bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->volumetric_enabled = p_enabled;
-}
-bool RasterizerIPhone::light_is_volumetric(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, false);
- return light->volumetric_enabled;
-}
-
-void RasterizerIPhone::light_set_projector(RID p_light, RID p_texture) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->projector = p_texture;
-}
-RID RasterizerIPhone::light_get_projector(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, RID());
- return light->projector;
-}
-
-void RasterizerIPhone::light_set_var(RID p_light, VS::LightParam p_var, float p_value) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX(p_var, VS::LIGHT_PARAM_MAX);
-
- light->vars[p_var] = p_value;
-}
-float RasterizerIPhone::light_get_var(RID p_light, VS::LightParam p_var) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, 0);
-
- ERR_FAIL_INDEX_V(p_var, VS::LIGHT_PARAM_MAX, 0);
-
- return light->vars[p_var];
-}
-
-AABB RasterizerIPhone::light_get_aabb(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, AABB());
-
- switch (light->type) {
-
- case VS::LIGHT_SPOT: {
-
- float len = light->vars[VS::LIGHT_PARAM_RADIUS];
- float size = Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
- return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
- } break;
- case VS::LIGHT_OMNI: {
-
- float r = light->vars[VS::LIGHT_PARAM_RADIUS];
- return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
- } break;
- case VS::LIGHT_DIRECTIONAL: {
-
- return AABB();
- } break;
- default: {}
- }
-
- ERR_FAIL_V(AABB());
-}
-
-RID RasterizerIPhone::light_instance_create(RID p_light) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, RID());
-
- LightInstance *light_instance = memnew(LightInstance);
-
- light_instance->light = p_light;
- light_instance->base = light;
- light_instance->last_pass = 0;
-
- return light_instance_owner.make_rid(light_instance);
-}
-void RasterizerIPhone::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
-
- LightInstance *lighti = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!lighti);
- lighti->transform = p_transform;
-}
-
-void RasterizerIPhone::light_instance_set_active_hint(RID p_light_instance) {
-
- LightInstance *lighti = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!lighti);
- lighti->last_pass = frame;
-}
-bool RasterizerIPhone::light_instance_has_shadow(RID p_light_instance) const {
-
- return false;
-}
-bool RasterizerIPhone::light_instance_assign_shadow(RID p_light_instance) {
-
- return false;
-}
-Rasterizer::ShadowType RasterizerIPhone::light_instance_get_shadow_type(RID p_light_instance) const {
-
- return Rasterizer::SHADOW_CUBE;
-}
-int RasterizerIPhone::light_instance_get_shadow_passes(RID p_light_instance) const {
-
- return 0;
-}
-void RasterizerIPhone::light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform) {
-}
-
-/* PARTICLES INSTANCE */
-
-RID RasterizerIPhone::particles_instance_create(RID p_particles) {
-
- return RID();
-}
-void RasterizerIPhone::particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform) {
-}
-
-/* RENDER API */
-/* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
-static GLfloat rtri; // Angle For The Triangle ( NEW )
-static GLfloat rquad; // Angle For The Quad ( NEW )
-
-void RasterizerIPhone::begin_frame() {
-
- window_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height);
-
- double time = (OS::get_singleton()->get_ticks_usec() / 1000); // get msec
- time /= 1000.0; // make secs
- time_delta = time - last_time;
- last_time = time;
- frame++;
- glClearColor(0, 0, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
-
-/* nehe ?*/
-
-#if 0
- glViewport(0,0,window_size.width,window_size.height); // Reset The Current Viewport
-
- glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
- glLoadIdentity(); // Reset The Projection Matrix
-
- // Calculate The Aspect Ratio Of The Window
- gluPerspective(45.0f,(GLfloat)window_size.width/(GLfloat)window_size.height,0.1f,100.0f);
-
- glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
- glLoadIdentity(); // Reset The Modelview Matrix
-
-
-
- glShadeModel(GL_SMOOTH); // Enable Smooth Shading
- glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
- glClearDepth(1.0f); // Depth Buffer Setup
- glEnable(GL_DEPTH_TEST); // Enables Depth Testing
- glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
- glLoadIdentity(); // Reset The Current Modelview Matrix
- glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
- glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW )
- glBegin(GL_TRIANGLES); // Start Drawing A Triangle
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
- glEnd(); // Done Drawing The Pyramid
-
- glLoadIdentity(); // Reset The Current Modelview Matrix
- glTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0
- glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW )
- glBegin(GL_QUADS); // Draw A Quad
- glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
- glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
- glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
- glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
- glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
- glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
- glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
- glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
- glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
- glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
- glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
- glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
- glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
- glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
- glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
- glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
- glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
- glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
- glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
- glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
- glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
- glEnd(); // Done Drawing The Quad
-
- rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
- rquad-=0.15f; // Decrease The Rotation Variable For The Quad ( NEW )
-
-#endif
-}
-
-void RasterizerIPhone::set_viewport(const VS::ViewportRect &p_viewport) {
-
- viewport = p_viewport;
- canvas_transform = Transform();
- canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
- canvas_transform.scale(Vector3(2.0f / viewport.width, -2.0f / viewport.height, 1.0f));
-
- glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
-}
-
-void RasterizerIPhone::begin_scene(RID p_fx, VS::ScenarioDebugMode p_debug) {
-
- opaque_render_list.clear();
- alpha_render_list.clear();
- light_instance_count = 0;
- scene_fx = p_fx.is_valid() ? fx_owner.get(p_fx) : NULL;
-};
-
-void RasterizerIPhone::begin_shadow_map(RID p_light_instance, int p_shadow_pass) {
-}
-
-void RasterizerIPhone::set_camera(const Transform &p_world, const CameraMatrix &p_projection) {
-
- camera_transform = p_world;
- camera_transform_inverse = camera_transform.inverse();
- camera_projection = p_projection;
- camera_plane = Plane(camera_transform.origin, camera_transform.basis.get_axis(2));
- camera_z_near = camera_projection.get_z_near();
- camera_z_far = camera_projection.get_z_far();
- camera_projection.get_viewport_size(camera_vp_size.x, camera_vp_size.y);
-}
-
-void RasterizerIPhone::add_light(RID p_light_instance) {
-
-#define LIGHT_FADE_TRESHOLD 0.05
-
- ERR_FAIL_COND(light_instance_count >= MAX_LIGHTS);
-
- LightInstance *li = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!li);
-
- /* make light hash */
-
- // actually, not really a hash, but helps to sort the lights
- // and avoid recompiling redudant shader versions
-
- li->hash_aux = li->base->type;
-
- if (li->base->shadow_enabled)
- li->hash_aux |= (1 << 3);
-
- if (li->base->projector.is_valid())
- li->hash_aux |= (1 << 4);
-
- if (li->base->shadow_enabled && li->base->volumetric_enabled)
- li->hash_aux |= (1 << 5);
-
- switch (li->base->type) {
-
- case VisualServer::LIGHT_DIRECTIONAL: {
-
- Vector3 dir = li->transform.basis.get_axis(2);
- li->light_vector.x = dir.x;
- li->light_vector.y = dir.y;
- li->light_vector.z = dir.z;
-
- } break;
- case VisualServer::LIGHT_OMNI: {
-
- float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
- if (radius == 0)
- radius = 0.0001;
- li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
- li->light_vector.x = li->transform.origin.x;
- li->light_vector.y = li->transform.origin.y;
- li->light_vector.z = li->transform.origin.z;
-
- } break;
- case VisualServer::LIGHT_SPOT: {
-
- float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
- if (radius == 0)
- radius = 0.0001;
- li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
- li->light_vector.x = li->transform.origin.x;
- li->light_vector.y = li->transform.origin.y;
- li->light_vector.z = li->transform.origin.z;
- Vector3 dir = -li->transform.basis.get_axis(2);
- li->spot_vector.x = dir.x;
- li->spot_vector.y = dir.y;
- li->spot_vector.z = dir.z;
-
- } break;
- }
-
- light_instances[light_instance_count++] = li;
-}
-
-void RasterizerIPhone::_add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner) {
-
- Material *m = NULL;
-
- if (p_geometry->material.is_valid())
- m = material_owner.get(p_geometry->material);
-
- if (!m) {
- m = material_owner.get(default_material);
- }
-
- ERR_FAIL_COND(!m);
-
- LightInstance *lights[RenderList::MAX_LIGHTS];
- int light_count = 0;
-
- RenderList *render_list = &opaque_render_list;
- if (p_geometry->has_alpha || m->detail_blend_mode != VS::MATERIAL_BLEND_MODE_MIX) {
- render_list = &alpha_render_list;
- };
-
- if (!m->flags[VS::MATERIAL_FLAG_UNSHADED]) {
-
- light_count = p_light_count;
- for (int i = 0; i < light_count; i++) {
- lights[i] = light_instance_owner.get(p_light_instances[i]);
- }
- }
-
- render_list->add_element(p_geometry, m, p_world, lights, light_count, p_material_overrides, p_skeleton, camera_plane.distance(p_world.origin), p_owner);
-}
-
-void RasterizerIPhone::add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, RID p_skeleton) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
-
- int ssize = mesh->surfaces.size();
-
- for (int i = 0; i < ssize; i++) {
-
- Surface *s = mesh->surfaces[i];
- Skeleton *sk = p_skeleton.is_valid() ? skeleton_owner.get(p_skeleton) : NULL;
-
- _add_geometry(s, *p_world, s->format, p_light_instances, p_light_count, p_material_overrides, sk, NULL);
- }
-
- mesh->last_pass = frame;
-}
-
-void RasterizerIPhone::add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-
- Poly *p = poly_owner.get(p_poly);
- if (!p->primitives.empty()) {
- const Poly::Primitive *pp = &p->primitives[0];
-
- uint32_t format = VisualServer::ARRAY_FORMAT_VERTEX;
-
- if (!pp->normals.empty())
- format |= VisualServer::ARRAY_FORMAT_NORMAL;
- if (!pp->colors.empty())
- format |= VisualServer::ARRAY_FORMAT_COLOR;
- if (!pp->uvs.empty())
- format |= VisualServer::ARRAY_TEX_UV;
-
- _add_geometry(p, *p_world, format, p_light_instances, p_light_count, p_material_overrides, NULL, NULL);
- }
-}
-
-void RasterizerIPhone::add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::_setup_material(const Geometry *p_geometry, const Material *p_material) {
-
- if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED])
- glDisable(GL_CULL_FACE);
- else {
- glEnable(GL_CULL_FACE);
- glCullFace((p_material->flags[VS::MATERIAL_FLAG_INVERT_FACES]) ? GL_FRONT : GL_BACK);
- }
-
- glEnable(GL_COLOR_MATERIAL); /* unused, unless color array */
- //glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE );
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- ///ambient @TODO offer global ambient group option
- float ambient_rgba[4] = {
- 1,
- 1,
- 1,
- 1.0
- };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient_rgba);
-
- ///diffuse
- const Color &diffuse_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE];
- float diffuse_rgba[4] = {
- (float)diffuse_color.r,
- (float)diffuse_color.g,
- (float)diffuse_color.b,
- (float)diffuse_color.a
- };
-
- glColor4f(diffuse_rgba[0], diffuse_rgba[1], diffuse_rgba[2], diffuse_rgba[3]);
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse_rgba);
-
- //specular
-
- const Color &specular_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR];
- float specular_rgba[4] = {
- (float)specular_color.r,
- (float)specular_color.g,
- (float)specular_color.b,
- 1.0
- };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_rgba);
-
- const Color &emission_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_EMISSION];
- float emission_rgba[4] = {
- (float)emission_color.r,
- (float)emission_color.g,
- (float)emission_color.b,
- 1.0
- };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission_rgba);
-
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]);
-
- if (p_material->flags[VS::MATERIAL_FLAG_UNSHADED]) {
- glDisable(GL_LIGHTING);
- } else {
- glEnable(GL_LIGHTING);
- glDisable(GL_LIGHTING);
- }
-
- //depth test?
- /*
- if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME])
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- else
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- */
- if (p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]) {
-
- Texture *texture = texture_owner.get(p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]);
- ERR_FAIL_COND(!texture);
- glActiveTexture(GL_TEXTURE0);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
- };
-};
-
-void RasterizerIPhone::_setup_light(LightInstance *p_instance, int p_idx) {
-
- Light *ld = p_instance->base;
-
- int glid = GL_LIGHT0 + p_idx;
- glLightfv(glid, GL_AMBIENT, ld->colors[VS::LIGHT_COLOR_AMBIENT].components);
- glLightfv(glid, GL_DIFFUSE, ld->colors[VS::LIGHT_COLOR_DIFFUSE].components);
- glLightfv(glid, GL_SPECULAR, ld->colors[VS::LIGHT_COLOR_SPECULAR].components);
-
- switch (ld->type) {
-
- case VS::LIGHT_DIRECTIONAL: {
- /* This doesn't have attenuation */
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
- v = p_instance->transform.get_basis().xform(v);
- v = camera_transform_inverse.get_basis().xform(v);
- v.normalize(); // this sucks, so it will be optimized at some point
- v = -v;
- float lightpos[4] = { v.x, v.y, v.z, 0.0 };
-
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- case VS::LIGHT_OMNI: {
-
- glLightf(glid, GL_SPOT_CUTOFF, 180.0);
- glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
- glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
- glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- Vector3 pos = p_instance->transform.get_origin();
- pos = camera_transform_inverse.xform(pos);
- float lightpos[4] = { pos.x, pos.y, pos.z, 1.0 };
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- case VS::LIGHT_SPOT: {
-
- glLightf(glid, GL_SPOT_CUTOFF, ld->vars[VS::LIGHT_PARAM_SPOT_ANGLE]);
- glLightf(glid, GL_SPOT_EXPONENT, ld->vars[VS::LIGHT_PARAM_SPOT_ATTENUATION]);
- glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
- glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
- glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
- v = p_instance->transform.get_basis().xform(v);
- v = camera_transform_inverse.get_basis().xform(v);
- v.normalize(); // this sucks, so it will be optimized at some point
- float lightdir[4] = { v.x, v.y, v.z, 1.0 };
- glLightfv(glid, GL_SPOT_DIRECTION, lightdir); //at modelview
-
- v = p_instance->transform.get_origin();
- v = camera_transform_inverse.xform(v);
- float lightpos[4] = { v.x, v.y, v.z, 1.0 };
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- default: break;
- }
-};
-
-void RasterizerIPhone::_setup_lights(LightInstance **p_lights, int p_light_count) {
-
- for (int i = 0; i < MAX_LIGHTS; i++) {
-
- if (i < p_light_count) {
- glEnable(GL_LIGHT0 + i);
- _setup_light(p_lights[i], i);
- } else {
- glDisable(GL_LIGHT0 + i);
- }
- }
-}
-
-static const int gl_client_states[] = {
-
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- -1, // ARRAY_TANGENT
- GL_COLOR_ARRAY,
- GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV
- GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV2
- -1, // ARRAY_BONES
- -1, // ARRAY_WEIGHTS
- -1, // ARRAY_INDEX
-};
-
-void RasterizerIPhone::_setup_geometry(const Geometry *p_geometry, const Material *p_material) {
-
- switch (p_geometry->type) {
-
- case Geometry::GEOMETRY_SURFACE: {
-
- Surface *surf = (Surface *)p_geometry;
- uint8_t *base = 0;
- bool use_VBO = (surf->array_local == 0);
-
- if (!use_VBO) {
-
- base = surf->array_local;
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } else {
-
- glBindBuffer(GL_ARRAY_BUFFER, surf->vertex_id);
- };
-
- const Surface::ArrayData *a = surf->array;
- for (int i = 0; i < VS::ARRAY_MAX; i++) {
-
- const Surface::ArrayData &ad = surf->array[i];
- if (ad.size == 0) {
- if (gl_client_states[i] != -1) {
- glDisableClientState(gl_client_states[i]);
- };
- continue; // this one is disabled.
- }
- ERR_CONTINUE(!ad.configured);
-
- if (gl_client_states[i] != -1) {
- glEnableClientState(gl_client_states[i]);
- };
-
- switch (i) {
-
- case VS::ARRAY_VERTEX:
- if (!use_VBO)
- glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
- else if (surf->array[VS::ARRAY_BONES].size)
- glVertexPointer(3, GL_FLOAT, 0, skinned_buffer);
- else
- glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- break;
-
- case VS::ARRAY_NORMAL:
- if (use_VBO)
- glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- else
- glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
- break;
- case VS::ARRAY_TANGENT:
- break;
- case VS::ARRAY_COLOR:
- if (use_VBO)
- glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)a->ofs);
- else
- glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)&base[a->ofs]);
- break;
- case VS::ARRAY_TEX_UV:
- case VS::ARRAY_TEX_UV2:
- if (use_VBO)
- glTexCoordPointer(2, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- else
- glTexCoordPointer(2, GL_FLOAT, surf->stride, &base[a->ofs]);
- break;
- case VS::ARRAY_BONES:
- case VS::ARRAY_WEIGHTS:
- case VS::ARRAY_INDEX:
- break;
- };
- }
-
- // process skeleton here
-
- } break;
-
- default: break;
- };
-};
-
-static const GLenum gl_primitive[] = {
- GL_POINTS,
- GL_LINES,
- GL_LINE_STRIP,
- GL_LINE_LOOP,
- GL_TRIANGLES,
- GL_TRIANGLE_STRIP,
- GL_TRIANGLE_FAN
-};
-
-void RasterizerIPhone::_render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton) {
-
- switch (p_geometry->type) {
-
- case Geometry::GEOMETRY_SURFACE: {
-
- Surface *s = (Surface *)p_geometry;
-
- if (s->index_array_len > 0) {
-
- if (s->index_array_local) {
-
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, s->index_array_local);
-
- } else {
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, 0);
- }
-
- } else {
-
- glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
- };
- } break;
-
- default: break;
- };
-};
-
-void RasterizerIPhone::_render_list_forward(RenderList *p_render_list) {
-
- const Material *prev_material = NULL;
- uint64_t prev_light_hash = 0;
- const Skeleton *prev_skeleton = NULL;
- const Geometry *prev_geometry = NULL;
- const ParamOverrideMap *prev_overrides = NULL; // make it different than NULL
-
- Geometry::Type prev_geometry_type = Geometry::GEOMETRY_INVALID;
-
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(&camera_projection.matrix[0][0]);
-
- for (int i = 0; i < p_render_list->element_count; i++) {
-
- RenderList::Element *e = p_render_list->elements[i];
- const Material *material = e->material;
- uint64_t light_hash = e->light_hash;
- const Skeleton *skeleton = e->skeleton;
- const Geometry *geometry = e->geometry;
- const ParamOverrideMap *material_overrides = e->material_overrides;
-
- if (material != prev_material || geometry->type != prev_geometry_type) {
- _setup_material(e->geometry, material);
- //_setup_material_overrides(e->material,NULL,material_overrides);
- //_setup_material_skeleton(material,skeleton);
- } else {
-
- if (material_overrides != prev_overrides) {
-
- //_setup_material_overrides(e->material,prev_overrides,material_overrides);
- }
-
- if (prev_skeleton != skeleton) {
- //_setup_material_skeleton(material,skeleton);
- };
- }
-
- if (geometry != prev_geometry || geometry->type != prev_geometry_type) {
-
- _setup_geometry(geometry, material);
- };
-
- if (i == 0 || light_hash != prev_light_hash)
- _setup_lights(e->lights, e->light_count);
-
- glMatrixMode(GL_MODELVIEW);
- _gl_load_transform(camera_transform_inverse);
- _gl_mult_transform(e->transform);
-
- _render(geometry, material, skeleton);
-
- prev_material = material;
- prev_skeleton = skeleton;
- prev_geometry = geometry;
- prev_light_hash = e->light_hash;
- prev_geometry_type = geometry->type;
- prev_overrides = material_overrides;
- }
-};
-
-void RasterizerIPhone::end_scene() {
-
- glEnable(GL_BLEND);
- glDepthMask(GL_FALSE);
-
- opaque_render_list.sort_mat_light();
- _render_list_forward(&opaque_render_list);
-
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
-
- alpha_render_list.sort_z();
- _render_list_forward(&alpha_render_list);
-}
-void RasterizerIPhone::end_shadow_map() {
-}
-
-void RasterizerIPhone::end_frame() {
-
- //ContextGL::get_singleton()->swap_buffers();
-}
-
-/* CANVAS API */
-
-void RasterizerIPhone::canvas_begin() {
-
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glLineWidth(1.0);
- glDisable(GL_LIGHTING);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-}
-void RasterizerIPhone::canvas_set_transparency(float p_transparency) {
-}
-
-void RasterizerIPhone::canvas_set_rect(const Rect2 &p_rect, bool p_clip) {
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glScalef(2.0 / window_size.x, -2.0 / window_size.y, 0);
- glTranslatef((-(window_size.x / 2.0)) + p_rect.pos.x, (-(window_size.y / 2.0)) + p_rect.pos.y, 0);
-
- if (p_clip) {
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(viewport.x + p_rect.pos.x, viewport.y + (viewport.height - (p_rect.pos.y + p_rect.size.height)),
- p_rect.size.width, p_rect.size.height);
- } else {
-
- glDisable(GL_SCISSOR_TEST);
- }
-}
-void RasterizerIPhone::canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
-
- glColor4f(1, 1, 1, 1);
-
- float verts[6] = {
- p_from.x, p_from.y, 0,
- p_to.x, p_to.y, 0
- };
-
- float colors[] = {
- p_color.r, p_color.g, p_color.b, p_color.a,
- p_color.r, p_color.g, p_color.b, p_color.a,
- };
- glLineWidth(p_width);
- _draw_primitive(2, verts, 0, colors, 0);
-}
-
-static void _draw_textured_quad(const Rect2 &p_rect, const Rect2 &p_src_region, const Size2 &p_tex_size) {
-
- float texcoords[] = {
- p_src_region.pos.x / p_tex_size.width,
- p_src_region.pos.y / p_tex_size.height,
-
- (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
- p_src_region.pos.y / p_tex_size.height,
-
- (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
- (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
-
- p_src_region.pos.x / p_tex_size.width,
- (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
- };
-
- float coords[] = {
- p_rect.pos.x, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
- p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
- };
-
- _draw_primitive(4, coords, 0, 0, texcoords);
-}
-
-static void _draw_quad(const Rect2 &p_rect) {
-
- float coords[] = {
- p_rect.pos.x, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
- p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
- };
-
- _draw_primitive(4, coords, 0, 0, 0);
-}
-
-void RasterizerIPhone::canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate) {
-
- glColor4f(p_modulate.r, p_modulate.g, p_modulate.b, p_modulate.a);
-
- if (p_texture.is_valid()) {
-
- glEnable(GL_TEXTURE_2D);
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
-
- if (!p_region) {
-
- Rect2 region = Rect2(0, 0, texture->width, texture->height);
- _draw_textured_quad(p_rect, region, region.size);
-
- } else {
-
- _draw_textured_quad(p_rect, p_source, Size2(texture->width, texture->height));
- }
- } else {
-
- _draw_quad(p_rect);
- }
-}
-void RasterizerIPhone::canvas_draw_style_box(const Rect2 &p_rect, const Rect2 &p_src_region, RID p_texture, const float *p_margin, bool p_draw_center) {
-
- glColor4f(1, 1, 1, 1);
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
-
- glEnable(GL_TEXTURE_2D);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
-
- Rect2 region = p_src_region;
- if (region.size.width <= 0)
- region.size.width = texture->width;
- if (region.size.height <= 0)
- region.size.height = texture->height;
- /* CORNERS */
- _draw_textured_quad( // top left
- Rect2(p_rect.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
- Rect2(region.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // top right
- Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
- Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom left
- Rect2(Point2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(region.pos.x, region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom right
- Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- Rect2 rect_center(p_rect.pos + Point2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2(p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
-
- Rect2 src_center(Point2(region.pos.x + p_margin[MARGIN_LEFT], region.pos.y + p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
-
- _draw_textured_quad( // top
- Rect2(Point2(rect_center.pos.x, p_rect.pos.y), Size2(rect_center.size.width, p_margin[MARGIN_TOP])),
- Rect2(Point2(src_center.pos.x, region.pos.y), Size2(src_center.size.width, p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom
- Rect2(Point2(rect_center.pos.x, rect_center.pos.y + rect_center.size.height), Size2(rect_center.size.width, p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(src_center.pos.x, src_center.pos.y + src_center.size.height), Size2(src_center.size.width, p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // left
- Rect2(Point2(p_rect.pos.x, rect_center.pos.y), Size2(p_margin[MARGIN_LEFT], rect_center.size.height)),
- Rect2(Point2(region.pos.x, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT], src_center.size.height)),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // right
- Rect2(Point2(rect_center.pos.x + rect_center.size.width, rect_center.pos.y), Size2(p_margin[MARGIN_RIGHT], rect_center.size.height)),
- Rect2(Point2(src_center.pos.x + src_center.size.width, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT], src_center.size.height)),
- Size2(texture->width, texture->height));
-
- if (p_draw_center) {
-
- _draw_textured_quad(
- rect_center,
- src_center,
- Size2(texture->width, texture->height));
- }
-}
-void RasterizerIPhone::canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
-
- ERR_FAIL_COND(p_points.size() < 1);
- float verts[12];
- float uvs[8];
- float colors[16];
-
- glColor4f(1, 1, 1, 1);
-
- int idx = 0;
- for (int i = 0; i < p_points.size(); i++) {
-
- verts[idx++] = p_points[i].x;
- verts[idx++] = p_points[i].y;
- verts[idx++] = 0;
- }
-
- idx = 0;
- for (int i = 0; i < p_uvs.size(); i++) {
-
- uvs[idx++] = p_uvs[i].x;
- uvs[idx++] = p_uvs[i].y;
- }
-
- idx = 0;
- for (int i = 0; i < p_colors.size(); i++) {
-
- colors[idx++] = p_colors[i].r;
- colors[idx++] = p_colors[i].g;
- colors[idx++] = p_colors[i].b;
- colors[idx++] = p_colors[i].a;
- };
-
- if (p_texture.is_valid()) {
- glEnable(GL_TEXTURE_2D);
- Texture *texture = texture_owner.get(p_texture);
- if (texture) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
- }
- }
-
- _draw_primitive(p_points.size(), &verts[0], NULL, p_colors.size() ? &colors[0] : NULL, p_uvs.size() ? uvs : NULL);
-}
-
-/* FX */
-
-RID RasterizerIPhone::fx_create() {
-
- return RID();
-}
-void RasterizerIPhone::fx_get_effects(RID p_fx, List<String> *p_effects) const {
-}
-void RasterizerIPhone::fx_set_active(RID p_fx, const String &p_effect, bool p_active) {
-}
-bool RasterizerIPhone::fx_is_active(RID p_fx, const String &p_effect) const {
-
- return false;
-}
-void RasterizerIPhone::fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const {
-}
-Variant RasterizerIPhone::fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const {
-
- return Variant();
-}
-void RasterizerIPhone::fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue) {
-}
-
-/*MISC*/
-
-bool RasterizerIPhone::is_texture(const RID &p_rid) const {
-
- return texture_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_material(const RID &p_rid) const {
-
- return material_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_mesh(const RID &p_rid) const {
-
- return mesh_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_multimesh(const RID &p_rid) const {
-
- return false;
-}
-bool RasterizerIPhone::is_poly(const RID &p_rid) const {
-
- return poly_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_particles(const RID &p_beam) const {
-
- return false;
-}
-
-bool RasterizerIPhone::is_beam(const RID &p_beam) const {
-
- return false;
-}
-
-bool RasterizerIPhone::is_light(const RID &p_rid) const {
-
- return light_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_light_instance(const RID &p_rid) const {
-
- return light_instance_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_particles_instance(const RID &p_rid) const {
-
- return false;
-}
-bool RasterizerIPhone::is_skeleton(const RID &p_rid) const {
-
- return skeleton_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_fx(const RID &p_rid) const {
-
- return fx_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_shader(const RID &p_rid) const {
-
- return false;
-}
-
-void RasterizerIPhone::free(const RID &p_rid) const {
-
- if (texture_owner.owns(p_rid)) {
-
- // delete the texture
- Texture *texture = texture_owner.get(p_rid);
-
- glDeleteTextures(1, &texture->tex_id);
-
- texture_owner.free(p_rid);
- memdelete(texture);
-
- } else if (material_owner.owns(p_rid)) {
-
- Material *material = material_owner.get(p_rid);
- ERR_FAIL_COND(!material);
-
- material_owner.free(p_rid);
- memdelete(material);
-
- } else if (mesh_owner.owns(p_rid)) {
-
- Mesh *mesh = mesh_owner.get(p_rid);
- ERR_FAIL_COND(!mesh);
- for (int i = 0; i < mesh->surfaces.size(); i++) {
-
- Surface *surface = mesh->surfaces[i];
- if (surface->array_local != 0) {
- memfree(surface->array_local);
- };
- if (surface->index_array_local != 0) {
- memfree(surface->index_array_local);
- };
-
- if (surface->vertex_id)
- glDeleteBuffers(1, &surface->vertex_id);
- if (surface->index_id)
- glDeleteBuffers(1, &surface->index_id);
-
- memdelete(surface);
- };
-
- mesh->surfaces.clear();
-
- mesh_owner.free(p_rid);
- memdelete(mesh);
-
- } else if (skeleton_owner.owns(p_rid)) {
-
- Skeleton *skeleton = skeleton_owner.get(p_rid);
- ERR_FAIL_COND(!skeleton)
-
- skeleton_owner.free(p_rid);
- memdelete(skeleton);
-
- } else if (light_owner.owns(p_rid)) {
-
- Light *light = light_owner.get(p_rid);
- ERR_FAIL_COND(!light)
-
- light_owner.free(p_rid);
- memdelete(light);
-
- } else if (light_instance_owner.owns(p_rid)) {
-
- LightInstance *light_instance = light_instance_owner.get(p_rid);
- ERR_FAIL_COND(!light_instance);
-
- light_instance_owner.free(p_rid);
- memdelete(light_instance);
-
- } else if (fx_owner.owns(p_rid)) {
-
- FX *fx = fx_owner.get(p_rid);
- ERR_FAIL_COND(!fx);
-
- fx_owner.free(p_rid);
- memdelete(fx);
- };
-}
-
-void RasterizerIPhone::init() {
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glFrontFace(GL_CW);
-
- glEnable(GL_TEXTURE_2D);
-}
-
-void RasterizerIPhone::finish() {
-}
-
-int RasterizerIPhone::get_render_info(VS::RenderInfo p_info) {
-
- return false;
-}
-
-RasterizerIPhone::RasterizerIPhone() {
-
- frame = 0;
-};
-
-RasterizerIPhone::~RasterizerIPhone(){
-
-};
-
-#endif
diff --git a/platform/iphone/rasterizer_iphone.h b/platform/iphone/rasterizer_iphone.h
deleted file mode 100644
index f886738da9..0000000000
--- a/platform/iphone/rasterizer_iphone.h
+++ /dev/null
@@ -1,881 +0,0 @@
-/*************************************************************************/
-/* rasterizer_iphone.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. */
-/*************************************************************************/
-#ifdef IPHONE_ENABLED
-
-#ifndef RASTERIZER_IPHONE_H
-#define RASTERIZER_IPHONE_H
-
-#include "servers/visual/rasterizer.h"
-
-#include "camera_matrix.h"
-#include "image.h"
-#include "list.h"
-#include "map.h"
-#include "rid.h"
-#include "servers/visual_server.h"
-#include "sort.h"
-#include <ES1/gl.h>
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class RasterizerIPhone : public Rasterizer {
-
- enum {
- SKINNED_BUFFER_SIZE = 1024 * 128, // 10k vertices
- MAX_LIGHTS = 8,
- };
-
- uint8_t skinned_buffer[SKINNED_BUFFER_SIZE];
-
- struct Texture {
-
- uint32_t flags;
- int width, height;
- Image::Format format;
-
- GLenum target;
- GLenum gl_format_cache;
- int gl_components_cache;
- bool has_alpha;
- bool format_has_alpha;
-
- bool active;
- GLuint tex_id;
- bool mipmap_dirty;
-
- Texture() {
-
- flags = width = height = 0;
- tex_id = 0;
- format = Image::FORMAT_L8;
- gl_components_cache = 0;
- format_has_alpha = false;
- has_alpha = false;
- active = false;
- mipmap_dirty = true;
- }
-
- ~Texture() {
-
- if (tex_id != 0) {
-
- glDeleteTextures(1, &tex_id);
- }
- }
- };
-
- mutable RID_Owner<Texture> texture_owner;
-
- struct Material {
-
- bool flags[VS::MATERIAL_FLAG_MAX];
- Variant parameters[VisualServer::FIXED_MATERIAL_PARAM_MAX];
- RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX];
-
- Transform uv_transform;
- VS::SpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
-
- VS::MaterialBlendMode detail_blend_mode;
-
- VS::SpatialMaterialTexGenMode texgen_mode;
-
- Material() {
-
- flags[VS::MATERIAL_FLAG_VISIBLE] = true;
- flags[VS::MATERIAL_FLAG_DOUBLE_SIDED] = false;
- flags[VS::MATERIAL_FLAG_INVERT_FACES] = false;
- flags[VS::MATERIAL_FLAG_UNSHADED] = false;
- flags[VS::MATERIAL_FLAG_WIREFRAME] = false;
-
- parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE] = Color(0.8, 0.8, 0.8);
- parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP] = 12;
-
- for (int i = 0; i < VisualServer::FIXED_MATERIAL_PARAM_MAX; i++) {
- texcoord_mode[i] = VS::FIXED_MATERIAL_TEXCOORD_UV;
- };
- detail_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
- texgen_mode = VS::FIXED_MATERIAL_TEXGEN_SPHERE;
- }
- };
- mutable RID_Owner<Material> material_owner;
-
- struct Geometry {
-
- enum Type {
- GEOMETRY_INVALID,
- GEOMETRY_SURFACE,
- GEOMETRY_POLY,
- GEOMETRY_PARTICLES,
- GEOMETRY_BEAM,
- GEOMETRY_DETAILER,
- };
-
- Type type;
- RID material;
- bool has_alpha;
- bool material_owned;
-
- Vector3 scale;
- Vector3 uv_scale;
-
- Geometry()
- : scale(1, 1, 1) {
- has_alpha = false;
- material_owned = false;
- }
- virtual ~Geometry(){};
- };
-
- struct GeometryOwner {
-
- virtual ~GeometryOwner() {}
- };
-
- struct Surface : public Geometry {
-
- struct ArrayData {
-
- uint32_t ofs, size;
- bool configured;
- int components;
- ArrayData() {
- ofs = 0;
- size = 0;
- configured = false;
- }
- };
-
- ArrayData array[VS::ARRAY_MAX];
- // support for vertex array objects
- GLuint array_object_id;
- // support for vertex buffer object
- GLuint vertex_id; // 0 means, unconfigured
- GLuint index_id; // 0 means, unconfigured
- // no support for the above, array in localmem.
- uint8_t *array_local;
- uint8_t *index_array_local;
-
- AABB aabb;
-
- int array_len;
- int index_array_len;
-
- VS::PrimitiveType primitive;
-
- uint32_t format;
-
- int stride;
-
- bool active;
-
- Point2 uv_min;
- Point2 uv_max;
-
- bool has_alpha_cache;
-
- Surface() {
-
- array_len = 0;
- type = GEOMETRY_SURFACE;
- primitive = VS::PRIMITIVE_POINTS;
- index_array_len = VS::NO_INDEX_ARRAY;
- format = 0;
- stride = 0;
-
- array_local = index_array_local = 0;
- vertex_id = index_id = 0;
-
- active = false;
- }
-
- ~Surface() {
- }
- };
-
- struct Mesh {
-
- bool active;
- Vector<Surface *> surfaces;
-
- mutable uint64_t last_pass;
- Mesh() {
- last_pass = 0;
- active = false;
- }
- };
- mutable RID_Owner<Mesh> mesh_owner;
-
- struct Poly : public Geometry {
-
- struct Primitive {
-
- Vector<Vector3> vertices;
- Vector<Vector3> normals;
- Vector<Vector3> uvs;
- Vector<Color> colors;
- };
-
- AABB aabb;
- List<Primitive> primitives;
- Poly() {
-
- type = GEOMETRY_POLY;
- }
- };
-
- mutable RID_Owner<Poly> poly_owner;
-
- struct Skeleton {
-
- Vector<Transform> bones;
- };
-
- mutable RID_Owner<Skeleton> skeleton_owner;
-
- struct Light {
-
- VS::LightType type;
- float vars[VS::LIGHT_PARAM_MAX];
- Color colors[3];
- bool shadow_enabled;
- RID projector;
- bool volumetric_enabled;
- Color volumetric_color;
-
- Light() {
-
- vars[VS::LIGHT_PARAM_SPOT_ATTENUATION] = 1;
- vars[VS::LIGHT_PARAM_SPOT_ANGLE] = 45;
- vars[VS::LIGHT_PARAM_ATTENUATION] = 1.0;
- vars[VS::LIGHT_PARAM_ENERGY] = 1.0;
- vars[VS::LIGHT_PARAM_RADIUS] = 1.0;
- colors[VS::LIGHT_COLOR_AMBIENT] = Color(0, 0, 0);
- colors[VS::LIGHT_COLOR_DIFFUSE] = Color(1, 1, 1);
- colors[VS::LIGHT_COLOR_SPECULAR] = Color(1, 1, 1);
- shadow_enabled = false;
- volumetric_enabled = false;
- }
- };
-
- struct ShadowBuffer;
-
- struct LightInstance {
-
- struct SplitInfo {
-
- CameraMatrix camera;
- Transform transform;
- float near;
- float far;
- };
-
- RID light;
- Light *base;
- uint64_t last_pass;
- Transform transform;
-
- CameraMatrix projection;
- Vector<SplitInfo> splits;
-
- Vector3 light_vector;
- Vector3 spot_vector;
- float linear_att;
-
- uint64_t hash_aux;
- };
- mutable RID_Owner<Light> light_owner;
- mutable RID_Owner<LightInstance> light_instance_owner;
-
- LightInstance *light_instances[MAX_LIGHTS];
- int light_instance_count;
-
- struct RenderList {
-
- enum {
- MAX_ELEMENTS = 4096,
- MAX_LIGHTS = 4
- };
-
- struct Element {
-
- float depth;
- const Skeleton *skeleton;
- Transform transform;
- LightInstance *lights[MAX_LIGHTS];
- int light_count;
- const Geometry *geometry;
- const Material *material;
- uint64_t light_hash;
- GeometryOwner *owner;
- const ParamOverrideMap *material_overrides;
- };
-
- Element _elements[MAX_ELEMENTS];
- Element *elements[MAX_ELEMENTS];
- int element_count;
-
- void clear() {
-
- element_count = 0;
- }
-
- struct SortZ {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- return A->depth > B->depth;
- }
- };
-
- void sort_z() {
-
- SortArray<Element *, SortZ> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortSkel {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry < B->geometry)
- return true;
- else if (A->geometry > B->geometry)
- return false;
- else
- return (!A->skeleton && B->skeleton);
- }
- };
-
- void sort_skel() {
-
- SortArray<Element *, SortSkel> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortMat {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry == B->geometry) {
-
- if (A->material == B->material) {
-
- return (A->material_overrides < B->material_overrides);
- } else {
-
- return (A->material < B->material);
- }
- } else {
-
- return (A->geometry < B->geometry);
- }
- }
- };
-
- void sort_mat() {
-
- SortArray<Element *, SortMat> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortMatLight {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry == B->geometry) {
-
- if (A->material == B->material) {
-
- if (A->light_hash == B->light_hash)
- return (A->material_overrides < B->material_overrides);
- else
- return A->light_hash < B->light_hash;
- } else {
-
- return (A->material < B->material);
- }
- } else {
-
- return (A->geometry < B->geometry);
- }
- }
- };
-
- void sort_mat_light() {
-
- SortArray<Element *, SortMatLight> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct LISort {
-
- _FORCE_INLINE_ bool operator()(const LightInstance *A, const LightInstance *B) const {
-
- return (A->hash_aux < B->hash_aux);
- }
- };
-
- _FORCE_INLINE_ void add_element(const Geometry *p_geometry, const Material *p_material, const Transform &p_transform, LightInstance **p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, float p_depth, GeometryOwner *p_owner = NULL) {
-
- ERR_FAIL_COND(element_count >= MAX_ELEMENTS);
- Element *e = elements[element_count++];
-
- e->geometry = p_geometry;
- e->material = p_material;
- e->transform = p_transform;
- e->skeleton = p_skeleton;
- e->light_hash = 0;
- e->light_count = p_light_count;
- e->owner = p_owner;
- e->material_overrides = p_material_overrides;
-
- if (e->light_count > 0) {
-
- SortArray<LightInstance *, LISort> light_sort;
- light_sort.sort(p_light_instances, p_light_count);
- //@TODO OPTIOMIZE
-
- for (int i = 0; i < p_light_count; i++) {
-
- e->lights[i] = p_light_instances[i];
-
- if (i == 0)
- e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i]));
- else
- e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i]), e->light_hash);
- }
- }
- }
-
- RenderList() {
-
- for (int i = 0; i < MAX_ELEMENTS; i++)
- elements[i] = &_elements[i]; // assign elements
- }
- };
-
- RenderList opaque_render_list;
- RenderList alpha_render_list;
-
- RID default_material;
-
- struct FX {
-
- bool bgcolor_active;
- Color bgcolor;
-
- bool skybox_active;
- RID skybox_cubemap;
-
- bool antialias_active;
- float antialias_tolerance;
-
- bool glow_active;
- int glow_passes;
- float glow_attenuation;
- float glow_bloom;
-
- bool ssao_active;
- float ssao_attenuation;
- float ssao_radius;
- float ssao_max_distance;
- float ssao_range_max;
- float ssao_range_min;
- bool ssao_only;
-
- bool fog_active;
- float fog_distance;
- float fog_attenuation;
- Color fog_color_near;
- Color fog_color_far;
- bool fog_bg;
-
- bool toon_active;
- float toon_treshold;
- float toon_soft;
-
- bool edge_active;
- Color edge_color;
- float edge_size;
-
- FX();
- };
- mutable RID_Owner<FX> fx_owner;
-
- FX *scene_fx;
- CameraMatrix camera_projection;
- Transform camera_transform;
- Transform camera_transform_inverse;
- float camera_z_near;
- float camera_z_far;
- Size2 camera_vp_size;
-
- Plane camera_plane;
-
- void _add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner);
- void _render_list_forward(RenderList *p_render_list);
-
- void _setup_light(LightInstance *p_instance, int p_idx);
- void _setup_lights(LightInstance **p_lights, int p_light_count);
- void _setup_material(const Geometry *p_geometry, const Material *p_material);
-
- void _setup_geometry(const Geometry *p_geometry, const Material *p_material);
- void _render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton);
-
- /*********/
- /* FRAME */
- /*********/
-
- Size2 window_size;
- VS::ViewportRect viewport;
- Transform canvas_transform;
- double last_time;
- double time_delta;
- uint64_t frame;
-
-public:
- /* TEXTURE API */
-
- virtual RID texture_create();
- virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
- virtual void texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
- virtual Image texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
- virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
- virtual uint32_t texture_get_flags(RID p_texture) const;
- virtual Image::Format texture_get_format(RID p_texture) const;
- virtual uint32_t texture_get_width(RID p_texture) const;
- virtual uint32_t texture_get_height(RID p_texture) const;
- virtual bool texture_has_alpha(RID p_texture) const;
-
- /* SHADER API */
-
- virtual RID shader_create();
-
- virtual void shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id);
- virtual void shader_node_remove(RID p_shader, int p_id);
- virtual void shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type);
- virtual void shader_node_set_param(RID p_shader, int p_id, const Variant &p_value);
-
- virtual void shader_get_node_list(RID p_shader, List<int> *p_node_list) const;
- virtual VS::ShaderNodeType shader_node_get_type(RID p_shader, int p_id) const;
- virtual Variant shader_node_get_param(RID p_shader, int p_id) const;
-
- virtual void shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot);
- virtual bool shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const;
- virtual void shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot);
-
- virtual void shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const;
-
- virtual void shader_clear(RID p_shader);
-
- /* COMMON MATERIAL API */
-
- virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value);
- virtual Variant material_get_param(RID p_material, const StringName &p_param) const;
- virtual void material_get_param_list(RID p_material, List<String> *p_param_list) const;
-
- virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled);
- virtual bool material_get_flag(RID p_material, VS::MaterialFlag p_flag) const;
-
- virtual void material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode);
- virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const;
-
- virtual void material_set_line_width(RID p_material, float p_line_width);
- virtual float material_get_line_width(RID p_material) const;
-
- /* FIXED MATERIAL */
-
- virtual RID material_create();
-
- virtual void fixed_material_set_parameter(RID p_material, VS::SpatialMaterialParam p_parameter, const Variant &p_value);
- virtual Variant fixed_material_get_parameter(RID p_material, VS::SpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_texture(RID p_material, VS::SpatialMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material, VS::SpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode);
- virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const;
-
- virtual void fixed_material_set_texgen_mode(RID p_material, VS::SpatialMaterialTexGenMode p_mode);
- virtual VS::SpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
-
- virtual void fixed_material_set_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter, VS::SpatialMaterialTexCoordMode p_mode);
- virtual VS::SpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material, VS::SpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_uv_transform(RID p_material, const Transform &p_transform);
- virtual Transform fixed_material_get_uv_transform(RID p_material) const;
-
- /* SHADER MATERIAL */
-
- virtual RID shader_material_create() const;
-
- virtual void shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned = false);
- virtual RID shader_material_get_vertex_shader(RID p_material) const;
-
- virtual void shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned = false);
- virtual RID shader_material_get_fragment_shader(RID p_material) const;
-
- /* MESH API */
-
- virtual RID mesh_create();
-
- virtual void mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len = VS::NO_INDEX_ARRAY);
-
- virtual Error mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array);
- virtual Variant mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const;
-
- virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned = false);
- virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
-
- virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const;
- virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const;
- virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
- virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
-
- virtual void mesh_erase_surface(RID p_mesh, int p_index);
- virtual int mesh_get_surface_count(RID p_mesh) const;
-
- virtual AABB mesh_get_aabb(RID p_mesh) const;
-
- /* MULTIMESH API */
-
- virtual RID multimesh_create();
-
- virtual void multimesh_set_instance_count(RID p_multimesh, int p_count);
- virtual int multimesh_get_instance_count(RID p_multimesh) const;
-
- virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh);
- virtual void multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb);
- virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
- virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
-
- virtual RID multimesh_get_mesh(RID p_multimesh) const;
- virtual AABB multimesh_get_aabb(RID p_multimesh) const;
-
- virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const;
- virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const;
-
- /* POLY API */
-
- virtual RID poly_create();
- virtual void poly_set_material(RID p_poly, RID p_material, bool p_owned = false);
- virtual void poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs);
- virtual void poly_clear(RID p_poly);
-
- virtual AABB poly_get_aabb(RID p_poly) const;
-
- /* PARTICLES API */
-
- virtual RID particles_create();
-
- virtual void particles_set_amount(RID p_particles, int p_amount);
- virtual int particles_get_amount(RID p_particles) const;
-
- virtual void particles_set_emitting(RID p_particles, bool p_emitting);
- virtual bool particles_is_emitting(RID p_particles) const;
-
- virtual void particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility);
- virtual AABB particles_get_visibility_aabb(RID p_particles) const;
-
- virtual void particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents);
- virtual Vector3 particles_get_emission_half_extents(RID p_particles) const;
-
- virtual void particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal);
- virtual Vector3 particles_get_gravity_normal(RID p_particles) const;
-
- virtual void particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value);
- virtual float particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness);
- virtual float particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos);
- virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const;
-
- virtual void particles_set_color_phases(RID p_particles, int p_phases);
- virtual int particles_get_color_phases(RID p_particles) const;
-
- virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color);
- virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const;
-
- virtual void particles_set_attractors(RID p_particles, int p_attractors);
- virtual int particles_get_attractors(RID p_particles) const;
-
- virtual void particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos);
- virtual Vector3 particles_get_attractor_pos(RID p_particles, int p_attractor) const;
-
- virtual void particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force);
- virtual float particles_get_attractor_strength(RID p_particles, int p_attractor) const;
-
- virtual void particles_set_material(RID p_particles, RID p_material, bool p_owned = false);
- virtual RID particles_get_material(RID p_particles) const;
-
- virtual AABB particles_get_aabb(RID p_particles) const;
- /* BEAM API */
-
- virtual RID beam_create();
-
- virtual void beam_set_point_count(RID p_beam, int p_count);
- virtual int beam_get_point_count(RID p_beam) const;
- virtual void beam_clear(RID p_beam);
-
- virtual void beam_set_point(RID p_beam, int p_point, Vector3 &p_pos);
- virtual Vector3 beam_get_point(RID p_beam, int p_point) const;
-
- virtual void beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive);
- virtual VS::BeamPrimitive beam_get_primitive(RID p_beam) const;
-
- virtual void beam_set_material(RID p_beam, RID p_material);
- virtual RID beam_get_material(RID p_beam) const;
-
- virtual AABB beam_get_aabb(RID p_particles) const;
- /* SKELETON API */
-
- virtual RID skeleton_create();
- virtual void skeleton_resize(RID p_skeleton, int p_bones);
- virtual int skeleton_get_bone_count(RID p_skeleton) const;
- virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform);
- virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone);
-
- /* LIGHT API */
-
- virtual RID light_create(VS::LightType p_type);
- virtual VS::LightType light_get_type(RID p_light) const;
-
- virtual void light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color);
- virtual Color light_get_color(RID p_light, VS::LightColor p_type) const;
-
- virtual void light_set_shadow(RID p_light, bool p_enabled);
- virtual bool light_has_shadow(RID p_light) const;
-
- virtual void light_set_volumetric(RID p_light, bool p_enabled);
- virtual bool light_is_volumetric(RID p_light) const;
-
- virtual void light_set_projector(RID p_light, RID p_texture);
- virtual RID light_get_projector(RID p_light) const;
-
- virtual void light_set_var(RID p_light, VS::LightParam p_var, float p_value);
- virtual float light_get_var(RID p_light, VS::LightParam p_var) const;
-
- virtual AABB light_get_aabb(RID p_poly) const;
-
- virtual RID light_instance_create(RID p_light);
- virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
-
- virtual void light_instance_set_active_hint(RID p_light_instance);
- virtual bool light_instance_has_shadow(RID p_light_instance) const;
- virtual bool light_instance_assign_shadow(RID p_light_instance);
- virtual ShadowType light_instance_get_shadow_type(RID p_light_instance) const;
- virtual int light_instance_get_shadow_passes(RID p_light_instance) const;
- virtual void light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform);
-
- /* PARTICLES INSTANCE */
-
- virtual RID particles_instance_create(RID p_particles);
- virtual void particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform);
-
- /* RENDER API */
- /* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
- virtual void begin_frame();
-
- virtual void set_viewport(const VS::ViewportRect &p_viewport);
-
- virtual void begin_scene(RID p_fx = RID(), VS::ScenarioDebugMode p_debug = VS::SCENARIO_DEBUG_DISABLED);
- virtual void begin_shadow_map(RID p_light_instance, int p_shadow_pass);
-
- virtual void set_camera(const Transform &p_world, const CameraMatrix &p_projection);
-
- virtual void add_light(RID p_light_instance); ///< all "add_light" calls happen before add_geometry calls
-
- typedef Map<StringName, Variant> ParamOverrideMap;
-
- virtual void add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL, RID p_skeleton = RID());
- virtual void add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
-
- virtual void end_scene();
- virtual void end_shadow_map();
-
- virtual void end_frame();
-
- /* CANVAS API */
-
- virtual void canvas_begin();
- virtual void canvas_set_transparency(float p_transparency);
- virtual void canvas_set_rect(const Rect2 &p_rect, bool p_clip);
- virtual void canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width);
- virtual void canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate);
- virtual void canvas_draw_style_box(const Rect2 &p_rect, RID p_texture, const float *p_margins, bool p_draw_center = true);
- virtual void canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture);
-
- /* FX */
-
- virtual RID fx_create();
- virtual void fx_get_effects(RID p_fx, List<String> *p_effects) const;
- virtual void fx_set_active(RID p_fx, const String &p_effect, bool p_active);
- virtual bool fx_is_active(RID p_fx, const String &p_effect) const;
- virtual void fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const;
- virtual Variant fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const;
- virtual void fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue);
-
- /*MISC*/
-
- virtual bool is_texture(const RID &p_rid) const;
- virtual bool is_material(const RID &p_rid) const;
- virtual bool is_mesh(const RID &p_rid) const;
- virtual bool is_multimesh(const RID &p_rid) const;
- virtual bool is_poly(const RID &p_rid) const;
- virtual bool is_particles(const RID &p_beam) const;
- virtual bool is_beam(const RID &p_beam) const;
-
- virtual bool is_light(const RID &p_rid) const;
- virtual bool is_light_instance(const RID &p_rid) const;
- virtual bool is_particles_instance(const RID &p_rid) const;
- virtual bool is_skeleton(const RID &p_rid) const;
- virtual bool is_fx(const RID &p_rid) const;
- virtual bool is_shader(const RID &p_rid) const;
-
- virtual void free(const RID &p_rid) const;
-
- virtual void init();
- virtual void finish();
-
- virtual int get_render_info(VS::RenderInfo p_info);
-
- RasterizerIPhone();
- virtual ~RasterizerIPhone();
-};
-
-#endif
-#endif
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 1a3c5f3e8f..ea388072c5 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -316,7 +316,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese
EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
- Image img(_javascript_logo);
+ Ref<Image> img = memnew(Image(_javascript_logo));
logo.instance();
logo->create_from_image(img);
}
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 1cd1991608..9df26f1471 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -46,14 +46,12 @@
#define DOM_BUTTON_RIGHT 2
template <typename T>
-static InputModifierState dom2godot_mod(T emscripten_event_ptr) {
+static void dom2godot_mod(T emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) {
- InputModifierState mod;
- mod.shift = emscripten_event_ptr->shiftKey;
- mod.alt = emscripten_event_ptr->altKey;
- mod.control = emscripten_event_ptr->ctrlKey;
- mod.meta = emscripten_event_ptr->metaKey;
- return mod;
+ godot_event->set_shift(emscripten_event_ptr->shiftKey);
+ godot_event->set_alt(emscripten_event_ptr->altKey);
+ godot_event->set_control(emscripten_event_ptr->ctrlKey);
+ godot_event->set_metakey(emscripten_event_ptr->metaKey);
}
int OS_JavaScript::get_video_driver_count() const {
@@ -151,26 +149,26 @@ static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEDOWN && event_type != EMSCRIPTEN_EVENT_MOUSEUP, false);
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.pressed = event_type == EMSCRIPTEN_EVENT_MOUSEDOWN;
- ev.mouse_button.global_x = ev.mouse_button.x = mouse_event->canvasX;
- ev.mouse_button.global_y = ev.mouse_button.y = mouse_event->canvasY;
- ev.mouse_button.mod = dom2godot_mod(mouse_event);
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_pressed(event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
+ ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY));
+ ev->set_global_position(ev->get_position());
+ dom2godot_mod(mouse_event, ev);
switch (mouse_event->button) {
- case DOM_BUTTON_LEFT: ev.mouse_button.button_index = BUTTON_LEFT; break;
- case DOM_BUTTON_MIDDLE: ev.mouse_button.button_index = BUTTON_MIDDLE; break;
- case DOM_BUTTON_RIGHT: ev.mouse_button.button_index = BUTTON_RIGHT; break;
+ case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break;
+ case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break;
+ case DOM_BUTTON_RIGHT: ev->set_button_index(BUTTON_RIGHT); break;
default: return false;
}
- ev.mouse_button.button_mask = _input->get_mouse_button_mask();
- if (ev.mouse_button.pressed)
- ev.mouse_button.button_mask |= 1 << ev.mouse_button.button_index;
+ int mask = _input->get_mouse_button_mask();
+ if (ev->is_pressed())
+ mask |= 1 << ev->get_button_index();
else
- ev.mouse_button.button_mask &= ~(1 << ev.mouse_button.button_index);
- ev.mouse_button.button_mask >>= 1;
+ mask &= ~(1 << ev->get_button_index());
+ ev->set_button_mask(mask >> 1);
_input->parse_input_event(ev);
return true;
@@ -180,20 +178,17 @@ static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *m
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEMOVE, false);
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.mod = dom2godot_mod(mouse_event);
- ev.mouse_motion.button_mask = _input->get_mouse_button_mask() >> 1;
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ dom2godot_mod(mouse_event, ev);
+ ev->set_button_mask(_input->get_mouse_button_mask() >> 1);
- ev.mouse_motion.global_x = ev.mouse_motion.x = mouse_event->canvasX;
- ev.mouse_motion.global_y = ev.mouse_motion.y = mouse_event->canvasY;
+ ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY));
+ ev->set_global_position(ev->get_position());
- ev.mouse_motion.relative_x = _input->get_mouse_position().x - ev.mouse_motion.x;
- ev.mouse_motion.relative_y = _input->get_mouse_position().y - ev.mouse_motion.y;
-
- _input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = _input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = _input->get_last_mouse_speed().y;
+ ev->set_relative(_input->get_mouse_position() - ev->get_position());
+ _input->set_mouse_position(ev->get_position());
+ ev->set_speed(_input->get_last_mouse_speed());
_input->parse_input_event(ev);
return true;
@@ -203,31 +198,35 @@ static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false);
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_mask = _input->get_mouse_button_mask() >> 1;
- ev.mouse_button.global_x = ev.mouse_button.x = _input->get_mouse_position().x;
- ev.mouse_button.global_y = ev.mouse_button.y = _input->get_mouse_position().y;
- ev.mouse_button.mod.shift = _input->is_key_pressed(KEY_SHIFT);
- ev.mouse_button.mod.alt = _input->is_key_pressed(KEY_ALT);
- ev.mouse_button.mod.control = _input->is_key_pressed(KEY_CONTROL);
- ev.mouse_button.mod.meta = _input->is_key_pressed(KEY_META);
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_mask(_input->get_mouse_button_mask() >> 1);
+ ev->set_position(_input->get_mouse_position());
+ ev->set_global_position(ev->get_position());
+
+ ev->set_shift(_input->is_key_pressed(KEY_SHIFT));
+ ev->set_alt(_input->is_key_pressed(KEY_ALT));
+ ev->set_control(_input->is_key_pressed(KEY_CONTROL));
+ ev->set_metakey(_input->is_key_pressed(KEY_META));
if (wheel_event->deltaY < 0)
- ev.mouse_button.button_index = BUTTON_WHEEL_UP;
+ ev->set_button_index(BUTTON_WHEEL_UP);
else if (wheel_event->deltaY > 0)
- ev.mouse_button.button_index = BUTTON_WHEEL_DOWN;
+ ev->set_button_index(BUTTON_WHEEL_DOWN);
else if (wheel_event->deltaX > 0)
- ev.mouse_button.button_index = BUTTON_WHEEL_LEFT;
+ ev->set_button_index(BUTTON_WHEEL_LEFT);
else if (wheel_event->deltaX < 0)
- ev.mouse_button.button_index = BUTTON_WHEEL_RIGHT;
+ ev->set_button_index(BUTTON_WHEEL_RIGHT);
else
return false;
- ev.mouse_button.pressed = true;
+ // Different browsers give wildly different delta values, and we can't
+ // interpret deltaMode, so use default value for wheel events' factor
+
+ ev->set_pressed(true);
_input->parse_input_event(ev);
- ev.mouse_button.pressed = false;
+ ev->set_pressed(false);
_input->parse_input_event(ev);
return true;
@@ -243,8 +242,8 @@ static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *
event_type != EMSCRIPTEN_EVENT_TOUCHCANCEL,
false);
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
int lowest_id_index = -1;
for (int i = 0; i < touch_event->numTouches; ++i) {
@@ -253,25 +252,29 @@ static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *
lowest_id_index = i;
if (!touch.isChanged)
continue;
- ev.screen_touch.index = touch.identifier;
- _prev_touches[i].x = ev.screen_touch.x = touch.canvasX;
- _prev_touches[i].y = ev.screen_touch.y = touch.canvasY;
- ev.screen_touch.pressed = event_type == EMSCRIPTEN_EVENT_TOUCHSTART;
+ ev->set_index(touch.identifier);
+ ev->set_position(Point2(touch.canvasX, touch.canvasY));
+ _prev_touches[i] = ev->get_position();
+ ev->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
_input->parse_input_event(ev);
}
if (touch_event->touches[lowest_id_index].isChanged) {
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.mod = dom2godot_mod(touch_event);
- ev.mouse_button.button_mask = _input->get_mouse_button_mask() >> 1;
- ev.mouse_button.global_x = ev.mouse_button.x = touch_event->touches[lowest_id_index].canvasX;
- ev.mouse_button.global_y = ev.mouse_button.y = touch_event->touches[lowest_id_index].canvasY;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.pressed = event_type == EMSCRIPTEN_EVENT_TOUCHSTART;
+ Ref<InputEventMouseButton> ev_mouse;
+ ev_mouse.instance();
+ ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1);
+ dom2godot_mod(touch_event, ev_mouse);
- _input->parse_input_event(ev);
+ const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
+ ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
+ ev_mouse->set_global_position(ev_mouse->get_position());
+
+ ev_mouse->set_button_index(BUTTON_LEFT);
+ ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
+
+ _input->parse_input_event(ev_mouse);
}
return true;
}
@@ -280,8 +283,8 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_TOUCHMOVE, false);
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
int lowest_id_index = -1;
for (int i = 0; i < touch_event->numTouches; ++i) {
@@ -290,44 +293,42 @@ static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *t
lowest_id_index = i;
if (!touch.isChanged)
continue;
- ev.screen_drag.index = touch.identifier;
- ev.screen_drag.x = touch.canvasX;
- ev.screen_drag.y = touch.canvasY;
+ ev->set_index(touch.identifier);
+ ev->set_position(Point2(touch.canvasX, touch.canvasY));
Point2 &prev = _prev_touches[i];
- ev.screen_drag.relative_x = touch.canvasX - prev.x;
- ev.screen_drag.relative_y = touch.canvasY - prev.y;
- prev.x = ev.screen_drag.x;
- prev.y = ev.screen_drag.y;
+ ev->set_relative(ev->get_position() - prev);
+ prev = ev->get_position();
_input->parse_input_event(ev);
}
if (touch_event->touches[lowest_id_index].isChanged) {
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.mod = dom2godot_mod(touch_event);
- ev.mouse_motion.button_mask = _input->get_mouse_button_mask() >> 1;
- ev.mouse_motion.global_x = ev.mouse_motion.x = touch_event->touches[lowest_id_index].canvasX;
- ev.mouse_motion.global_y = ev.mouse_motion.y = touch_event->touches[lowest_id_index].canvasY;
- ev.mouse_motion.relative_x = _input->get_mouse_position().x - ev.mouse_motion.x;
- ev.mouse_motion.relative_y = _input->get_mouse_position().y - ev.mouse_motion.y;
+ Ref<InputEventMouseMotion> ev_mouse;
+ ev_mouse.instance();
+ dom2godot_mod(touch_event, ev_mouse);
+ ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1);
- _input->set_mouse_position(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = _input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = _input->get_last_mouse_speed().y;
+ const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
+ ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
+ ev_mouse->set_global_position(ev_mouse->get_position());
- _input->parse_input_event(ev);
+ ev_mouse->set_relative(_input->get_mouse_position() - ev_mouse->get_position());
+ _input->set_mouse_position(ev_mouse->get_position());
+ ev_mouse->set_speed(_input->get_last_mouse_speed());
+
+ _input->parse_input_event(ev_mouse);
}
return true;
}
-static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
+static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.key.echo = emscripten_event->repeat;
- ev.key.mod = dom2godot_mod(emscripten_event);
- ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode);
+ Ref<InputEventKey> ev;
+ ev.instance();
+ ev->set_echo(emscripten_event->repeat);
+ dom2godot_mod(emscripten_event, ev);
+ ev->set_scancode(dom2godot_scancode(emscripten_event->keyCode));
String unicode = String::utf8(emscripten_event->key);
// check if empty or multi-character (e.g. `CapsLock`)
@@ -336,21 +337,21 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve
unicode = String::utf8(emscripten_event->charValue);
}
if (unicode.length() == 1) {
- ev.key.unicode = unicode[0];
+ ev->set_unicode(unicode[0]);
}
return ev;
}
-static InputEvent deferred_key_event;
+static Ref<InputEventKey> deferred_key_event;
static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) {
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYDOWN, false);
- InputEvent ev = _setup_key_event(key_event);
- ev.key.pressed = true;
- if (ev.key.unicode == 0 && keycode_has_unicode(ev.key.scancode)) {
+ Ref<InputEventKey> ev = _setup_key_event(key_event);
+ ev->set_pressed(true);
+ if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_scancode())) {
// defer to keypress event for legacy unicode retrieval
deferred_key_event = ev;
return false; // do not suppress keypress event
@@ -363,7 +364,7 @@ static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false);
- deferred_key_event.key.unicode = key_event->charCode;
+ deferred_key_event->set_unicode(key_event->charCode);
_input->parse_input_event(deferred_key_event);
return true;
}
@@ -372,10 +373,10 @@ static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *ke
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYUP, false);
- InputEvent ev = _setup_key_event(key_event);
- ev.key.pressed = false;
+ Ref<InputEventKey> ev = _setup_key_event(key_event);
+ ev->set_pressed(false);
_input->parse_input_event(ev);
- return ev.key.scancode != KEY_UNKNOWN && ev.key.scancode != 0;
+ return ev->get_scancode() != KEY_UNKNOWN && ev->get_scancode() != 0;
}
static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_event, void *p_user) {
@@ -517,6 +518,31 @@ void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
/* clang-format on */
}
+static const char *godot2dom_cursor(OS::CursorShape p_shape) {
+
+ switch (p_shape) {
+ case OS::CURSOR_ARROW:
+ default:
+ return "auto";
+ case OS::CURSOR_IBEAM: return "text";
+ case OS::CURSOR_POINTING_HAND: return "pointer";
+ case OS::CURSOR_CROSS: return "crosshair";
+ case OS::CURSOR_WAIT: return "progress";
+ case OS::CURSOR_BUSY: return "wait";
+ case OS::CURSOR_DRAG: return "grab";
+ case OS::CURSOR_CAN_DROP: return "grabbing";
+ case OS::CURSOR_FORBIDDEN: return "no-drop";
+ case OS::CURSOR_VSIZE: return "ns-resize";
+ case OS::CURSOR_HSIZE: return "ew-resize";
+ case OS::CURSOR_BDIAGSIZE: return "nesw-resize";
+ case OS::CURSOR_FDIAGSIZE: return "nwse-resize";
+ case OS::CURSOR_MOVE: return "move";
+ case OS::CURSOR_VSPLIT: return "row-resize";
+ case OS::CURSOR_HSPLIT: return "col-resize";
+ case OS::CURSOR_HELP: return "help";
+ }
+}
+
void OS_JavaScript::set_css_cursor(const char *p_cursor) {
/* clang-format off */
@@ -547,7 +573,7 @@ void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
if (p_mode == MOUSE_MODE_VISIBLE) {
- set_css_cursor("auto");
+ set_css_cursor(godot2dom_cursor(cursor_shape));
emscripten_exit_pointerlock();
} else if (p_mode == MOUSE_MODE_HIDDEN) {
@@ -561,7 +587,7 @@ void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
ERR_EXPLAIN("MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback");
ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED);
ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS);
- set_css_cursor("auto");
+ set_css_cursor(godot2dom_cursor(cursor_shape));
}
}
@@ -706,7 +732,11 @@ bool OS_JavaScript::can_draw() const {
void OS_JavaScript::set_cursor_shape(CursorShape p_shape) {
- //javascript really really really has no mouse.. how amazing..
+ ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
+
+ cursor_shape = p_shape;
+ if (get_mouse_mode() != MOUSE_MODE_HIDDEN)
+ set_css_cursor(godot2dom_cursor(cursor_shape));
}
void OS_JavaScript::main_loop_begin() {
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index ffd269b512..65269148ec 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -61,6 +61,7 @@ class OS_JavaScript : public OS_Unix {
InputDefault *input;
bool window_maximized;
VideoMode video_mode;
+ CursorShape cursor_shape;
MainLoop *main_loop;
GetDataDirFunc get_data_dir_func;
@@ -153,7 +154,7 @@ public:
virtual String get_resource_dir() const;
void process_accelerometer(const Vector3 &p_accelerometer);
- void push_input(const InputEvent &p_ev);
+ void push_input(const Ref<InputEvent> &p_ev);
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device) const;
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 1427c2e00d..27117c2e8d 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -7,7 +7,6 @@ files = [
'godot_main_osx.mm',
'audio_driver_osx.cpp',
'sem_osx.cpp',
- # 'context_gl_osx.cpp',
'dir_access_osx.mm',
'joypad_osx.cpp',
'power_osx.cpp',
diff --git a/platform/osx/context_gl_osx.cpp b/platform/osx/context_gl_osx.cpp
deleted file mode 100644
index 1377d829b0..0000000000
--- a/platform/osx/context_gl_osx.cpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*************************************************************************/
-/* context_gl_osx.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 "context_gl_osx.h"
-
-#ifdef OSX_ENABLED
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-
-void ContextGL_OSX::release_current() {
-
- aglSetCurrentContext(context);
-}
-
-void ContextGL_OSX::make_current() {
-
- aglSetCurrentContext(NULL);
-}
-void ContextGL_OSX::swap_buffers() {
-
- aglSwapBuffers(context);
-}
-
-Error ContextGL_OSX::initialize() {
-
- if ((Ptr)kUnresolvedCFragSymbolAddress == (Ptr)aglChoosePixelFormat)
- return FAILED;
-
- GLint attributes[] = { AGL_RGBA,
- AGL_DOUBLEBUFFER,
- AGL_DEPTH_SIZE, 32,
- AGL_NO_RECOVERY,
- AGL_NONE,
- AGL_NONE };
-
- AGLPixelFormat format = NULL;
-
- format = aglChoosePixelFormat(NULL, 0, attributes);
-
- if (!format)
- return FAILED;
-
- context = aglCreateContext(format, 0);
-
- if (!context)
- return FAILED;
-
- aglDestroyPixelFormat(format);
-
- aglSetWindowRef(context, window);
-
- GLint swapInterval = 1;
- aglSetInteger(context, AGL_SWAP_INTERVAL, &swapInterval);
-
- aglSetCurrentContext(context);
-
- return OK;
-}
-
-ContextGL_OSX::ContextGL_OSX(WindowRef p_window) {
-
- window = p_window;
-}
-
-ContextGL_OSX::~ContextGL_OSX() {
-
- if (context)
- aglDestroyContext(context);
-}
-
-#endif
-#endif
diff --git a/platform/osx/godot_osx.mm b/platform/osx/godot_osx.mm
deleted file mode 100644
index 626406ad1d..0000000000
--- a/platform/osx/godot_osx.mm
+++ /dev/null
@@ -1,208 +0,0 @@
-/*************************************************************************/
-/* godot_osx.mm */
-/*************************************************************************/
-/* 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 "godot_osx.h"
-
-#include <sys/param.h> /* for MAXPATHLEN */
-#include <unistd.h>
-
-/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
- but the method still is there and works. To avoid warnings, we declare
- it ourselves here. */
-@interface NSApplication ()
-- (void)setAppleMenu:(NSMenu *)menu;
-@end
-
-static int global_argc;
-static char **global_argv;
-static BOOL gCalledAppMainline = FALSE;
-
-static NSString *getApplicationName(void) {
- const NSDictionary *dict;
- NSString *appName = 0;
-
- /* Determine the application name */
- dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
- if (dict)
- appName = [dict objectForKey:@"CFBundleName"];
-
- if (![appName length])
- appName = [[NSProcessInfo processInfo] processName];
-
- return appName;
-}
-
-/* The main class of the application, the application's delegate */
-@implementation GodotMain
-
-static void setApplicationMenu(void) {
- /* warning: this code is very odd */
- NSMenu *appleMenu;
- NSMenuItem *menuItem;
- NSString *title;
- NSString *appName;
-
- appName = getApplicationName();
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
- /* Add menu items */
- title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Hide " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
-
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
-
- [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
- /* Put menu into the menubar */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [[NSApp mainMenu] addItem:menuItem];
-
- /* Tell the application object that this is now the application menu */
- [NSApp setAppleMenu:appleMenu];
-
- /* Finally give up our references to the objects */
- [appleMenu release];
- [menuItem release];
-}
-
-/* Create a window menu */
-static void setupWindowMenu(void) {
- NSMenu *windowMenu;
- NSMenuItem *windowMenuItem;
- NSMenuItem *menuItem;
-
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- /* "Minimize" item */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [windowMenu addItem:menuItem];
- [menuItem release];
-
- /* Put menu into the menubar */
- windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [[NSApp mainMenu] addItem:windowMenuItem];
-
- /* Tell the application object that this is now the window menu */
- [NSApp setWindowsMenu:windowMenu];
-
- /* Finally give up our references to the objects */
- [windowMenu release];
- [windowMenuItem release];
-}
-
-/* Replacement for NSApplicationMain */
-static void CustomApplicationMain(int argc, char **argv) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GodotMain *main;
-
- /* Ensure the application object is initialised */
- [NSApplication sharedApplication];
-
- /* Set up the menubar */
- [NSApp setMainMenu:[[NSMenu alloc] init]];
- setApplicationMenu();
- setupWindowMenu();
-
- main = [[main alloc] init];
- [NSApp setDelegate:main];
-
- /* Start the main event loop */
- [NSApp run];
-
- [main release];
- [pool release];
-}
-
-extern int godot_main(int argc, char **argv);
-
-/* Called when the internal event loop has just started running */
-- (void)applicationDidFinishLaunching:(NSNotification *)note {
- int status;
-
- /* Hand off to main application code */
- gCalledAppMainline = TRUE;
-
- int ret = godot_main(global_argc, global_argv);
-
- exit(ret);
-}
-@end
-
-#ifdef main
-#undef main
-#endif
-
-int main(int argc, char **argv) {
- /* Copy the arguments into a global variable */
- /* This is passed if we are launched by double-clicking */
- if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) {
- global_argv = (char **)malloc(sizeof(char *) * 2);
- global_argv[0] = argv[0];
- global_argv[1] = NULL;
- global_argc = 1;
-
- // chdir to binary's dir when launched from finder
- int len = strlen(global_argv[0]);
-
- while (len--) {
- if (global_argv[0][len] == '/') break;
- }
-
- if (len >= 0) {
- char *path = (char *)malloc(len + 1);
- memcpy(path, global_argv[0], len);
- path[len] = 0;
- printf("Path: %s\n", path);
- chdir(path);
- }
-
- } else {
- int i;
- global_argc = argc;
- global_argv = (char **)malloc(sizeof(char *) * (argc + 1));
- for (i = 0; i <= argc; i++)
- global_argv[i] = argv[i];
- }
-
- CustomApplicationMain(argc, argv);
- return 0;
-}
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 2ecc379a7f..123816b22d 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -30,21 +30,21 @@
#ifndef OS_OSX_H
#define OS_OSX_H
+#include "drivers/alsa/audio_driver_alsa.h"
+#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/unix/os_unix.h"
#include "joypad_osx.h"
#include "main/input_default.h"
#include "os/input.h"
-#include "power_osx.h"
-#include "servers/visual_server.h"
-// #include "servers/visual/visual_server_wrap_mt.h"
-#include "drivers/alsa/audio_driver_alsa.h"
-#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "platform/osx/audio_driver_osx.h"
+#include "power_osx.h"
#include "servers/audio_server.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/physics_server.h"
#include "servers/visual/rasterizer.h"
+#include "servers/visual/visual_server_wrap_mt.h"
+#include "servers/visual_server.h"
#include <ApplicationServices/ApplicationServices.h>
//bitch
@@ -151,7 +151,7 @@ public:
virtual Size2 get_window_size() const;
- virtual void set_icon(const Image &p_icon);
+ virtual void set_icon(const Ref<Image> &p_icon);
virtual MainLoop *get_main_loop() const;
@@ -165,7 +165,7 @@ public:
virtual void swap_buffers();
Error shell_open(String p_uri);
- void push_input(const InputEvent &p_event);
+ void push_input(const Ref<InputEvent> &p_event);
String get_locale() const;
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index c6c2e6dab1..1070de724b 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -53,35 +53,6 @@
#include <sys/types.h>
#include <unistd.h>
-//uses portions of glfw
-
-//========================================================================
-// GLFW 3.0 - www.glfw.org
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Marcus Geelnard
-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would
-// be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-// be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-// distribution.
-//
-//========================================================================
-
static NSRect convertRectToBacking(NSRect contentRect) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
@@ -92,15 +63,12 @@ static NSRect convertRectToBacking(NSRect contentRect) {
return contentRect;
}
-static InputModifierState translateFlags(NSUInteger flags) {
- InputModifierState mod;
+static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) {
- mod.shift = (flags & NSShiftKeyMask);
- mod.control = (flags & NSControlKeyMask);
- mod.alt = (flags & NSAlternateKeyMask);
- mod.meta = (flags & NSCommandKeyMask);
-
- return mod;
+ state->set_shift((p_osx_state & NSShiftKeyMask));
+ state->set_control((p_osx_state & NSControlKeyMask));
+ state->set_alt((p_osx_state & NSAlternateKeyMask));
+ state->set_metakey((p_osx_state & NSCommandKeyMask));
}
static int mouse_x = 0;
@@ -249,14 +217,7 @@ static int button_mask = 0;
+ (void)initialize {
if (self == [GodotContentView class]) {
- /*
- if (_glfw.ns.cursor == nil) {
- NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(1, 1)];
- _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data
- hotSpot:NSZeroPoint];
- [data release];
- }
-*/
+ // nothing left to do here at the moment..
}
}
@@ -322,27 +283,19 @@ static int button_mask = 0;
- (void)mouseDown:(NSEvent *)event {
- //print_line("mouse down:");
button_mask |= BUTTON_MASK_LEFT;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.doubleclick = [event clickCount] == 2;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /*
- _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_LEFT,
- GLFW_PRESS,
- translateFlags([event modifierFlags]));
-*/
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_LEFT);
+ mb->set_pressed(true);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)mouseDragged:(NSEvent *)event {
@@ -352,81 +305,58 @@ static int button_mask = 0;
- (void)mouseUp:(NSEvent *)event {
button_mask &= ~BUTTON_MASK_LEFT;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
- /*
- _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_LEFT,
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));
-*/
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_LEFT);
+ mb->set_pressed(false);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)mouseMoved:(NSEvent *)event {
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.button_mask = button_mask;
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_button_mask(button_mask);
prev_mouse_x = mouse_x;
prev_mouse_y = mouse_y;
const NSRect contentRect = [OS_OSX::singleton->window_view frame];
const NSPoint p = [event locationInWindow];
mouse_x = p.x * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
mouse_y = (contentRect.size.height - p.y) * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- ev.mouse_motion.x = mouse_x;
- ev.mouse_motion.y = mouse_y;
- ev.mouse_motion.global_x = mouse_x;
- ev.mouse_motion.global_y = mouse_y;
- ev.mouse_motion.relative_x = [event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- ev.mouse_motion.relative_y = [event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- ev.mouse_motion.mod = translateFlags([event modifierFlags]);
+ mm->set_position(Vector2(mouse_x, mouse_y));
+ mm->set_global_position(Vector2(mouse_x, mouse_y));
+ Vector2 relativeMotion = Vector2();
+ relativeMotion.x = [event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
+ relativeMotion.y = [event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
+ mm->set_relative(relativeMotion);
+ get_key_modifier_state([event modifierFlags], mm);
OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y));
- OS_OSX::singleton->push_input(ev);
-
- /*
- if (window->cursorMode == GLFW_CURSOR_DISABLED)
- _glfwInputCursorMotion(window, [event deltaX], [event deltaY]);
- else {
- const NSRect contentRect = [window->ns.view frame];
- const NSPoint p = [event locationInWindow];
-
- _glfwInputCursorMotion(window, p.x, contentRect.size.height - p.y);
- }
-*/
+ OS_OSX::singleton->push_input(mm);
}
- (void)rightMouseDown:(NSEvent *)event {
button_mask |= BUTTON_MASK_RIGHT;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_RIGHT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /*
- _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_RIGHT,
- GLFW_PRESS,
- translateFlags([event modifierFlags]));
-*/
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_RIGHT);
+ mb->set_pressed(true);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)rightMouseDragged:(NSEvent *)event {
@@ -436,24 +366,18 @@ static int button_mask = 0;
- (void)rightMouseUp:(NSEvent *)event {
button_mask &= ~BUTTON_MASK_RIGHT;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_RIGHT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /*
- _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_RIGHT,
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));
-*/
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_RIGHT);
+ mb->set_pressed(false);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)otherMouseDown:(NSEvent *)event {
@@ -462,24 +386,18 @@ static int button_mask = 0;
return;
button_mask |= BUTTON_MASK_MIDDLE;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_MIDDLE;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /*
- _glfwInputMouseClick(window,
- (int) [event buttonNumber],
- GLFW_PRESS,
- translateFlags([event modifierFlags]));
-*/
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_MIDDLE);
+ mb->set_pressed(true);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)otherMouseDragged:(NSEvent *)event {
@@ -492,24 +410,18 @@ static int button_mask = 0;
return;
button_mask &= ~BUTTON_MASK_MIDDLE;
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = BUTTON_MIDDLE;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /*
- _glfwInputMouseClick(window,
- (int) [event buttonNumber],
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));
-*/
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(BUTTON_MIDDLE);
+ mb->set_pressed(false);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ mb->set_doubleclick([event clickCount] == 2);
+ OS_OSX::singleton->push_input(mb);
}
- (void)mouseExited:(NSEvent *)event {
@@ -520,11 +432,9 @@ static int button_mask = 0;
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(false);
- //_glfwInputCursorEnter(window, GL_FALSE);
}
- (void)mouseEntered:(NSEvent *)event {
- //_glfwInputCursorEnter(window, GL_TRUE);
if (!OS_OSX::singleton)
return;
if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
@@ -534,12 +444,7 @@ static int button_mask = 0;
}
- (void)viewDidChangeBackingProperties {
- /*
- const NSRect contentRect = [window->ns.view frame];
- const NSRect fbRect = convertRectToBacking(window, contentRect);
-
- _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
-*/
+ // nothing left to do here
}
- (void)updateTrackingAreas {
@@ -706,86 +611,102 @@ static int translateKey(unsigned int key) {
}
- (void)keyDown:(NSEvent *)event {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.key.pressed = true;
- ev.key.mod = translateFlags([event modifierFlags]);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
- ev.key.echo = [event isARepeat];
+
+ Ref<InputEventKey> k;
+ k.instance();
+
+ get_key_modifier_state([event modifierFlags], k);
+ k->set_pressed(true);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode])));
+ k->set_echo([event isARepeat]);
NSString *characters = [event characters];
NSUInteger i, length = [characters length];
- if (length > 0 && keycode_has_unicode(ev.key.scancode)) {
+ if (length > 0 && keycode_has_unicode(k->get_scancode())) {
for (i = 0; i < length; i++) {
- ev.key.unicode = [characters characterAtIndex:i];
- OS_OSX::singleton->push_input(ev);
- ev.key.scancode = 0;
+ k->set_unicode([characters characterAtIndex:i]);
+ OS_OSX::singleton->push_input(k);
+ k->set_scancode(0);
}
} else {
- OS_OSX::singleton->push_input(ev);
+ OS_OSX::singleton->push_input(k);
}
}
- (void)flagsChanged:(NSEvent *)event {
- InputEvent ev;
+ Ref<InputEventKey> k;
+ k.instance();
+
int key = [event keyCode];
int mod = [event modifierFlags];
- ev.type = InputEvent::KEY;
-
if (key == 0x36 || key == 0x37) {
if (mod & NSCommandKeyMask) {
mod &= ~NSCommandKeyMask;
- ev.key.pressed = true;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x38 || key == 0x3c) {
if (mod & NSShiftKeyMask) {
mod &= ~NSShiftKeyMask;
- ev.key.pressed = true;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x3a || key == 0x3d) {
if (mod & NSAlternateKeyMask) {
mod &= ~NSAlternateKeyMask;
- ev.key.pressed = true;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x3b || key == 0x3e) {
if (mod & NSControlKeyMask) {
mod &= ~NSControlKeyMask;
- ev.key.pressed = true;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else {
return;
}
- ev.key.mod = translateFlags(mod);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey(key));
+ get_key_modifier_state(mod, k);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey(key)));
- OS_OSX::singleton->push_input(ev);
+ OS_OSX::singleton->push_input(k);
}
- (void)keyUp:(NSEvent *)event {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.key.pressed = false;
- ev.key.mod = translateFlags([event modifierFlags]);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
- OS_OSX::singleton->push_input(ev);
+ Ref<InputEventKey> k;
+ k.instance();
- /*
- const int key = translateKey([event keyCode]);
- const int mods = translateFlags([event modifierFlags]);
- _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);
-*/
+ get_key_modifier_state([event modifierFlags], k);
+ k->set_pressed(false);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode])));
+
+ OS_OSX::singleton->push_input(k);
+}
+
+inline void sendScrollEvent(int button, double factor, int modifierFlags) {
+
+ Ref<InputEventMouseButton> sc;
+ sc.instance();
+
+ get_key_modifier_state(modifierFlags, sc);
+ sc->set_button_index(button);
+ sc->set_factor(factor);
+ sc->set_pressed(true);
+ Vector2 mouse_pos = Vector2(mouse_x, mouse_y);
+ sc->set_position(mouse_pos);
+ sc->set_global_position(mouse_pos);
+ sc->set_button_mask(button_mask);
+ OS_OSX::singleton->push_input(sc);
+ sc->set_pressed(false);
+ OS_OSX::singleton->push_input(sc);
}
- (void)scrollWheel:(NSEvent *)event {
@@ -797,48 +718,20 @@ static int translateKey(unsigned int key) {
deltaY = [event scrollingDeltaY];
if ([event hasPreciseScrollingDeltas]) {
- deltaX *= 0.1;
- deltaY *= 0.1;
+ deltaX *= 0.03;
+ deltaY *= 0.03;
}
- } else {
+ } else
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED
+ {
deltaX = [event deltaX];
deltaY = [event deltaY];
}
-#else
- deltaX = [event deltaX];
- deltaY = [event deltaY];
-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
-
- if (fabs(deltaY)) {
-
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = deltaY > 0 ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- OS_OSX::singleton->push_input(ev);
- ev.mouse_button.pressed = false;
- OS_OSX::singleton->push_input(ev);
- }
-
if (fabs(deltaX)) {
-
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index = deltaX < 0 ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = mouse_x;
- ev.mouse_button.y = mouse_y;
- ev.mouse_button.global_x = mouse_x;
- ev.mouse_button.global_y = mouse_y;
- ev.mouse_button.button_mask = button_mask;
- OS_OSX::singleton->push_input(ev);
- ev.mouse_button.pressed = false;
- OS_OSX::singleton->push_input(ev);
+ sendScrollEvent(0 > deltaX ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]);
+ }
+ if (fabs(deltaY)) {
+ sendScrollEvent(0 < deltaY ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]);
}
}
@@ -923,7 +816,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0);
window_object = [[GodotWindow alloc]
- initWithContentRect:NSMakeRect(0, 0, p_desired.width / display_scale, p_desired.height / display_scale)
+ initWithContentRect:NSMakeRect(0, 0, p_desired.width, p_desired.height)
styleMask:styleMask
backing:NSBackingStoreBuffered
defer:NO];
@@ -932,8 +825,8 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
window_view = [[GodotContentView alloc] init];
- window_size.width = p_desired.width;
- window_size.height = p_desired.height;
+ window_size.width = p_desired.width * display_scale;
+ window_size.height = p_desired.height * display_scale;
if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && display_scale > 1) {
[window_view setWantsBestResolutionOpenGLSurface:YES];
@@ -1039,12 +932,10 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
//visual_server = memnew( VisualServerRaster(rasterizer) );
visual_server = memnew(VisualServerRaster);
- // FIXME: Reimplement threaded rendering? Or remove?
- /*
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+
+ visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
-*/
visual_server->init();
visual_server->cursor_set_visible(false, 0);
@@ -1081,7 +972,7 @@ void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
NSRect nsrect = [[screenArray objectAtIndex:i] visibleFrame];
Rect2 rect = Rect2(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height);
- rect.pos *= displayScale;
+ rect.position *= displayScale;
rect.size *= displayScale;
screens.push_back(rect);
@@ -1238,26 +1129,27 @@ void OS_OSX::set_window_title(const String &p_title) {
[window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
}
-void OS_OSX::set_icon(const Image &p_icon) {
+void OS_OSX::set_icon(const Ref<Image> &p_icon) {
- Image img = p_icon;
- img.convert(Image::FORMAT_RGBA8);
+ Ref<Image> img = p_icon;
+ img = img->duplicate();
+ img->convert(Image::FORMAT_RGBA8);
NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
initWithBitmapDataPlanes:NULL
- pixelsWide:p_icon.get_width()
- pixelsHigh:p_icon.get_height()
+ pixelsWide:img->get_width()
+ pixelsHigh:img->get_height()
bitsPerSample:8
samplesPerPixel:4
hasAlpha:YES
isPlanar:NO
colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:p_icon.get_width() * 4
+ bytesPerRow:img->get_width() * 4
bitsPerPixel:32] autorelease];
ERR_FAIL_COND(imgrep == nil);
uint8_t *pixels = [imgrep bitmapData];
- int len = img.get_width() * img.get_height();
- PoolVector<uint8_t> data = img.get_data();
+ int len = img->get_width() * img->get_height();
+ PoolVector<uint8_t> data = img->get_data();
PoolVector<uint8_t>::Read r = data.read();
/* Premultiply the alpha channel */
@@ -1269,7 +1161,7 @@ void OS_OSX::set_icon(const Image &p_icon) {
pixels[i * 4 + 3] = alpha;
}
- NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img.get_width(), img.get_height())] autorelease];
+ NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())] autorelease];
ERR_FAIL_COND(nsimg == nil);
[nsimg addRepresentation:imgrep];
@@ -1334,8 +1226,8 @@ Error OS_OSX::shell_open(String p_uri) {
}
String OS_OSX::get_locale() const {
- NSString *preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
- return [preferredLang UTF8String];
+ NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ return [locale_code UTF8String];
}
void OS_OSX::swap_buffers() {
@@ -1381,7 +1273,7 @@ void OS_OSX::set_current_screen(int p_screen) {
Point2 OS_OSX::get_screen_position(int p_screen) const {
ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
- return screens[p_screen].pos;
+ return screens[p_screen].position;
};
int OS_OSX::get_screen_dpi(int p_screen) const {
@@ -1490,7 +1382,7 @@ void OS_OSX::set_window_maximized(bool p_enabled) {
[window_object setFrame:[[[NSScreen screens] objectAtIndex:current_screen] visibleFrame] display:YES];
} else {
set_window_size(restore_rect.size);
- set_window_position(restore_rect.pos);
+ set_window_position(restore_rect.position);
};
maximized = p_enabled;
};
@@ -1627,10 +1519,9 @@ void OS_OSX::process_events() {
autoreleasePool = [[NSAutoreleasePool alloc] init];
}
-void OS_OSX::push_input(const InputEvent &p_event) {
+void OS_OSX::push_input(const Ref<InputEvent> &p_event) {
- InputEvent ev = p_event;
- //print_line("EV: "+String(ev));
+ Ref<InputEvent> ev = p_event;
input->parse_input_event(ev);
}
diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp
index 0057fe8acc..2ef1a65ff1 100644
--- a/platform/osx/power_osx.cpp
+++ b/platform/osx/power_osx.cpp
@@ -27,6 +27,32 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_osx.h"
#include <CoreFoundation/CoreFoundation.h>
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index 2946aa1eae..c773c0b746 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -259,45 +259,48 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
int but = _get_button(point);
if (_is_touch(point)) {
- InputEvent event;
- event.type = InputEvent::SCREEN_TOUCH;
- event.device = 0;
- event.screen_touch.pressed = p_pressed;
- event.screen_touch.x = pos.X;
- event.screen_touch.y = pos.Y;
- event.screen_touch.index = _get_finger(point->PointerId);
-
- last_touch_x[event.screen_touch.index] = pos.X;
- last_touch_y[event.screen_touch.index] = pos.Y;
-
- os->input_event(event);
+ Ref<InputEventScreenTouch> screen_touch;
+ screen_touch.instance();
+ screen_touch->set_device(0);
+ screen_touch->set_pressed(p_pressed);
+ screen_touch->set_position(Vector2(pos.X, pos.Y));
+ screen_touch->set_index(_get_finger(point->PointerId));
+
+ last_touch_x[screen_touch->get_index()] = pos.X;
+ last_touch_y[screen_touch->get_index()] = pos.Y;
+
+ os->input_event(screen_touch);
if (number_of_contacts > 1)
return;
}; // fallthrought of sorts
- InputEvent event;
- event.type = InputEvent::MOUSE_BUTTON;
- event.device = 0;
- event.mouse_button.pressed = p_pressed;
- event.mouse_button.button_index = but;
- event.mouse_button.x = pos.X;
- event.mouse_button.y = pos.Y;
- event.mouse_button.global_x = pos.X;
- event.mouse_button.global_y = pos.Y;
+ Ref<InputEventMouseButton> mouse_button;
+ mouse_button.instance();
+ mouse_button->set_device(0);
+ mouse_button->set_pressed(p_pressed);
+ mouse_button->set_button_index(but);
+ mouse_button->set_position(Vector2(pos.X, pos.Y));
+ mouse_button->set_global_position(Vector2(pos.X, pos.Y));
if (p_is_wheel) {
if (point->Properties->MouseWheelDelta > 0) {
- event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP;
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP);
} else if (point->Properties->MouseWheelDelta < 0) {
- event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN;
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN);
}
}
last_touch_x[31] = pos.X;
last_touch_y[31] = pos.Y;
- os->input_event(event);
+ os->input_event(mouse_button);
+
+ if (p_is_wheel) {
+ // Send release for mouse wheel
+ mouse_button->set_pressed(false);
+ os->input_event(mouse_button);
+ }
};
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
@@ -349,16 +352,14 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
if (point->IsInContact && _is_touch(point)) {
- InputEvent event;
- event.type = InputEvent::SCREEN_DRAG;
- event.device = 0;
- event.screen_drag.x = pos.X;
- event.screen_drag.y = pos.Y;
- event.screen_drag.index = _get_finger(point->PointerId);
- event.screen_drag.relative_x = event.screen_drag.x - last_touch_x[event.screen_drag.index];
- event.screen_drag.relative_y = event.screen_drag.y - last_touch_y[event.screen_drag.index];
+ Ref<InputEventScreenDrag> screen_drag;
+ screen_drag.instance();
+ screen_drag->set_device(0);
+ screen_drag->set_position(Vector2(pos.X, pos.Y));
+ screen_drag->set_index(_get_finger(point->PointerId));
+ screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
- os->input_event(event);
+ os->input_event(screen_drag);
if (number_of_contacts > 1)
return;
@@ -368,19 +369,16 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
return;
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- event.device = 0;
- event.mouse_motion.x = pos.X;
- event.mouse_motion.y = pos.Y;
- event.mouse_motion.global_x = pos.X;
- event.mouse_motion.global_y = pos.Y;
- event.mouse_motion.relative_x = pos.X - last_touch_x[31];
- event.mouse_motion.relative_y = pos.Y - last_touch_y[31];
+ Ref<InputEventMouseMotion> mouse_motion;
+ mouse_motion.instance();
+ mouse_motion->set_device(0);
+ mouse_motion->set_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
last_mouse_pos = pos;
- os->input_event(event);
+ os->input_event(mouse_motion);
}
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
@@ -393,32 +391,25 @@ void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
pos.X = last_mouse_pos.X + args->MouseDelta.X;
pos.Y = last_mouse_pos.Y + args->MouseDelta.Y;
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- event.device = 0;
- event.mouse_motion.x = pos.X;
- event.mouse_motion.y = pos.Y;
- event.mouse_motion.global_x = pos.X;
- event.mouse_motion.global_y = pos.Y;
- event.mouse_motion.relative_x = args->MouseDelta.X;
- event.mouse_motion.relative_y = args->MouseDelta.Y;
+ Ref<InputEventMouseMotion> mouse_motion;
+ mouse_motion.instance();
+ mouse_motion->set_device(0);
+ mouse_motion->set_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_relative(Vector2(args->MouseDelta.X, args->MouseDelta.Y));
last_mouse_pos = pos;
- os->input_event(event);
+ os->input_event(mouse_motion);
}
void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) {
OSUWP::KeyEvent ke;
- InputModifierState mod;
- mod.meta = false;
- mod.command = false;
- mod.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
- mod.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
- mod.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
- ke.mod_state = mod;
+ ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
+ ke.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
+ ke.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
ke.pressed = p_pressed;
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index f1e0716241..baff7f9788 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -49,6 +49,8 @@ def configure(env):
arch = ""
env['ENV'] = os.environ
+ vc_base_path = os.environ['VCTOOLSINSTALLDIR'] if "VCTOOLSINSTALLDIR" in os.environ else os.environ['VCINSTALLDIR']
+
# ANGLE
angle_root = os.getenv("ANGLE_SRC_PATH")
env.Append(CPPPATH=[angle_root + '/include'])
@@ -65,7 +67,7 @@ def configure(env):
arch = "arm"
env["bits"] = "32"
env.Append(LINKFLAGS=['/MACHINE:ARM'])
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/arm'])
+ env.Append(LIBPATH=[vc_base_path + 'lib/store/arm'])
angle_build_cmd += "ARM"
@@ -92,7 +94,7 @@ def configure(env):
env.Append(CPPFLAGS=['/DPNG_ABORT=abort'])
env.Append(LINKFLAGS=['/MACHINE:X86'])
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store'])
+ env.Append(LIBPATH=[vc_base_path + 'lib/store'])
env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_Win32/lib'])
else:
@@ -107,10 +109,9 @@ def configure(env):
env.Append(CPPPATH=['#platform/uwp', '#drivers/windows'])
env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', '/WINMD', '/APPCONTAINER', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1', '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"'])
env.Append(CPPFLAGS=['/D', '__WRL_NO_DEFAULT_LIB__', '/D', 'WIN32'])
- env.Append(CPPFLAGS=['/FU', os.environ['VCINSTALLDIR'] + 'lib/store/references/platform.winmd'])
- env.Append(CPPFLAGS=['/AI', os.environ['VCINSTALLDIR'] + 'lib/store/references'])
-
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/references'])
+
+ env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/store/references'])
+ env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/x86/store/references'])
if (env["target"] == "release"):
@@ -133,7 +134,7 @@ def configure(env):
env.Append(CCFLAGS=string.split('/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'))
env.Append(CXXFLAGS=string.split('/ZW /FS'))
- env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR'] + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral'])
+ env.Append(CCFLAGS=['/AI', vc_base_path + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral'])
env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"]
env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"]
diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp
index d79ce75db5..57c4c5d572 100644
--- a/platform/uwp/gl_context_egl.cpp
+++ b/platform/uwp/gl_context_egl.cpp
@@ -97,7 +97,7 @@ Error ContextEGL::initialize() {
EGLContext context = EGL_NO_CONTEXT;
EGLSurface surface = EGL_NO_SURFACE;
EGLConfig config = nullptr;
- EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
+ EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE, EGL_NONE };
try {
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 818b827e83..28aaf9161b 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -330,16 +330,9 @@ String OSUWP::get_clipboard() const {
return "";
};
-void OSUWP::input_event(InputEvent &p_event) {
+void OSUWP::input_event(const Ref<InputEvent> &p_event) {
input->parse_input_event(p_event);
-
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index > 3) {
-
- //send release for mouse wheel
- p_event.mouse_button.pressed = false;
- input->parse_input_event(p_event);
- }
};
void OSUWP::delete_main_loop() {
@@ -663,16 +656,18 @@ void OSUWP::process_key_events() {
for (int i = 0; i < key_event_pos; i++) {
KeyEvent &kev = key_event_buffer[i];
- InputEvent iev;
-
- iev.type = InputEvent::KEY;
- iev.key.mod = kev.mod_state;
- iev.key.echo = kev.echo;
- iev.key.scancode = kev.scancode;
- iev.key.unicode = kev.unicode;
- iev.key.pressed = kev.pressed;
- input_event(iev);
+ Ref<InputEventKey> key_event;
+ key_event.instance();
+ key_event->set_alt(kev.alt);
+ key_event->set_shift(kev.shift);
+ key_event->set_control(kev.control);
+ key_event->set_echo(kev.echo);
+ key_event->set_scancode(kev.scancode);
+ key_event->set_unicode(kev.unicode);
+ key_event->set_pressed(kev.pressed);
+
+ input_event(key_event);
}
key_event_pos = 0;
}
@@ -746,7 +741,7 @@ String OSUWP::get_executable_path() const {
return "";
}
-void OSUWP::set_icon(const Image &p_icon) {
+void OSUWP::set_icon(const Ref<Image> &p_icon) {
}
bool OSUWP::has_environment(const String &p_var) const {
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 7d9e681da1..45b8eefdee 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -63,7 +63,7 @@ public:
CHAR_EVENT_MESSAGE
};
- InputModifierState mod_state;
+ bool alt, shift, control;
MessageType type;
bool pressed;
unsigned int scancode;
@@ -227,7 +227,7 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
- void set_icon(const Image &p_icon);
+ void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
@@ -257,7 +257,7 @@ public:
virtual bool get_swap_ok_cancel() { return true; }
- void input_event(InputEvent &p_event);
+ void input_event(const Ref<InputEvent> &p_event);
virtual PowerState get_power_state();
virtual int get_power_seconds_left();
diff --git a/platform/uwp/power_uwp.cpp b/platform/uwp/power_uwp.cpp
index a8f0f5ba6d..ece07f84ad 100644
--- a/platform/uwp/power_uwp.cpp
+++ b/platform/uwp/power_uwp.cpp
@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/uwp/power_uwp.h b/platform/uwp/power_uwp.h
index 465473bc1d..c23d712980 100644
--- a/platform/uwp/power_uwp.h
+++ b/platform/uwp/power_uwp.h
@@ -5,7 +5,8 @@
/* GODOT ENGINE */
/* http://www.godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index 2d11bfe4d8..3802e7e784 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -35,7 +35,7 @@ void register_windows_exporter() {
Ref<EditorExportPlatformPC> platform;
platform.instance();
- Image img(_windows_logo);
+ Ref<Image> img = memnew(Image(_windows_logo));
Ref<ImageTexture> logo;
logo.instance();
logo->create_from_image(img);
diff --git a/platform/windows/godot.ico b/platform/windows/godot.ico
index 3e52f2e52f..fd5c28944f 100644
--- a/platform/windows/godot.ico
+++ b/platform/windows/godot.ico
Binary files differ
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 99b6890913..e94529dd94 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -37,15 +37,15 @@
#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
#include "drivers/windows/thread_windows.h"
-#include "servers/audio_server.h"
-#include "servers/visual/visual_server_raster.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
#include "global_config.h"
#include "io/marshalls.h"
#include "joypad.h"
#include "lang_table.h"
#include "main/main.h"
#include "packet_peer_udp_winsock.h"
+#include "servers/audio_server.h"
+#include "servers/visual/visual_server_raster.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#include "stream_peer_winsock.h"
#include "tcp_server_winsock.h"
@@ -215,14 +215,11 @@ bool OS_Windows::can_draw() const {
void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
- InputEvent event;
- event.type = InputEvent::SCREEN_TOUCH;
- event.screen_touch.index = idx;
-
- event.screen_touch.pressed = p_pressed;
-
- event.screen_touch.x = p_x;
- event.screen_touch.y = p_y;
+ Ref<InputEventScreenTouch> event;
+ event.instance();
+ event->set_index(idx);
+ event->set_pressed(p_pressed);
+ event->set_position(Vector2(p_x, p_y));
if (main_loop) {
input->parse_input_event(event);
@@ -231,12 +228,10 @@ void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
void OS_Windows::_drag_event(int p_x, int p_y, int idx) {
- InputEvent event;
- event.type = InputEvent::SCREEN_DRAG;
- event.screen_drag.index = idx;
-
- event.screen_drag.x = p_x;
- event.screen_drag.y = p_y;
+ Ref<InputEventScreenDrag> event;
+ event.instance();
+ event->set_index(idx);
+ event->set_position(Vector2(p_x, p_y));
if (main_loop)
input->parse_input_event(event);
@@ -367,22 +362,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
};
*/
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- InputEventMouseMotion &mm = event.mouse_motion;
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
+
+ mm->set_control((wParam & MK_CONTROL) != 0);
+ mm->set_shift((wParam & MK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
- mm.mod.control = (wParam & MK_CONTROL) != 0;
- mm.mod.shift = (wParam & MK_SHIFT) != 0;
- mm.mod.alt = alt_mem;
+ int bmask = 0;
+ bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
+ bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
+ bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
+ mm->set_button_mask(bmask);
- mm.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
- mm.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
- mm.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
- last_button_state = mm.button_mask;
- /*mm.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
- mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
- mm.x = GET_X_LPARAM(lParam);
- mm.y = GET_Y_LPARAM(lParam);
+ last_button_state = mm->get_button_mask();
+ /*mm->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mm->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
@@ -390,35 +386,33 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
old_x = c.x;
old_y = c.y;
- if (Point2i(mm.x, mm.y) == c) {
+ if (mm->get_position() == c) {
center = c;
return 0;
}
- Point2i ncenter(mm.x, mm.y);
+ Point2i ncenter = mm->get_position();
center = ncenter;
POINT pos = { (int)c.x, (int)c.y };
ClientToScreen(hWnd, &pos);
SetCursorPos(pos.x, pos.y);
}
- input->set_mouse_position(Point2(mm.x, mm.y));
- mm.speed_x = input->get_last_mouse_speed().x;
- mm.speed_y = input->get_last_mouse_speed().y;
+ input->set_mouse_position(mm->get_position());
+ mm->set_speed(input->get_last_mouse_speed());
if (old_invalid) {
- old_x = mm.x;
- old_y = mm.y;
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
old_invalid = false;
}
- mm.relative_x = mm.x - old_x;
- mm.relative_y = mm.y - old_y;
- old_x = mm.x;
- old_y = mm.y;
+ mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
if (window_has_focus && main_loop)
- input->parse_input_event(event);
+ input->parse_input_event(mm);
} break;
case WM_LBUTTONDOWN:
@@ -447,111 +441,110 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
};
*/
- InputEvent event;
- event.type = InputEvent::MOUSE_BUTTON;
- InputEventMouseButton &mb = event.mouse_button;
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
switch (uMsg) {
case WM_LBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 1;
+ mb->set_pressed(true);
+ mb->set_button_index(1);
} break;
case WM_LBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 1;
+ mb->set_pressed(false);
+ mb->set_button_index(1);
} break;
case WM_MBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 3;
+ mb->set_pressed(true);
+ mb->set_button_index(3);
} break;
case WM_MBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 3;
+ mb->set_pressed(false);
+ mb->set_button_index(3);
} break;
case WM_RBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 2;
+ mb->set_pressed(true);
+ mb->set_button_index(2);
} break;
case WM_RBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 2;
+ mb->set_pressed(false);
+ mb->set_button_index(2);
} break;
case WM_LBUTTONDBLCLK: {
- mb.pressed = true;
- mb.button_index = 1;
- mb.doubleclick = true;
+ mb->set_pressed(true);
+ mb->set_button_index(1);
+ mb->set_doubleclick(true);
} break;
case WM_RBUTTONDBLCLK: {
- mb.pressed = true;
- mb.button_index = 2;
- mb.doubleclick = true;
+ mb->set_pressed(true);
+ mb->set_button_index(2);
+ mb->set_doubleclick(true);
} break;
case WM_MOUSEWHEEL: {
- mb.pressed = true;
+ mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
return 0;
if (motion > 0)
- mb.button_index = BUTTON_WHEEL_UP;
+ mb->set_button_index(BUTTON_WHEEL_UP);
else
- mb.button_index = BUTTON_WHEEL_DOWN;
+ mb->set_button_index(BUTTON_WHEEL_DOWN);
} break;
case WM_MOUSEHWHEEL: {
- mb.pressed = true;
+ mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
return 0;
- if (motion < 0)
- mb.button_index = BUTTON_WHEEL_LEFT;
- else
- mb.button_index = BUTTON_WHEEL_RIGHT;
+ if (motion < 0) {
+ mb->set_button_index(BUTTON_WHEEL_LEFT);
+ mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
+ } else {
+ mb->set_button_index(BUTTON_WHEEL_RIGHT);
+ mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
+ }
} break;
/*
case WM_XBUTTONDOWN: {
- mb.pressed=true;
- mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ mb->is_pressed()=true;
+ mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
} break;
case WM_XBUTTONUP:
- mb.pressed=true;
- mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ mb->is_pressed()=true;
+ mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
} break;*/
default: { return 0; }
}
- mb.mod.control = (wParam & MK_CONTROL) != 0;
- mb.mod.shift = (wParam & MK_SHIFT) != 0;
- mb.mod.alt = alt_mem;
- //mb.mod.alt=(wParam&MK_MENU)!=0;
- mb.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
- mb.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
- mb.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
-
- last_button_state = mb.button_mask;
+ mb->set_control((wParam & MK_CONTROL) != 0);
+ mb->set_shift((wParam & MK_SHIFT) != 0);
+ mb->set_alt(alt_mem);
+ //mb->get_alt()=(wParam&MK_MENU)!=0;
+ int bmask = 0;
+ bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
+ bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
+ bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
+ mb->set_button_mask(bmask);
+
+ last_button_state = mb->get_button_mask();
/*
- mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
- mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
- mb.x = GET_X_LPARAM(lParam);
- mb.y = GET_Y_LPARAM(lParam);
+ mb->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mb->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
- mb.x = old_x;
- mb.y = old_y;
+ mb->set_position(Vector2(old_x, old_y));
}
- mb.global_x = mb.x;
- mb.global_y = mb.y;
-
if (uMsg != WM_MOUSEWHEEL) {
- if (mb.pressed) {
+ if (mb->is_pressed()) {
if (++pressrc > 0)
SetCapture(hWnd);
@@ -565,21 +558,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (mouse_mode != MOUSE_MODE_CAPTURED) {
// for reasons unknown to mankind, wheel comes in screen cordinates
POINT coords;
- coords.x = mb.x;
- coords.y = mb.y;
+ coords.x = mb->get_position().x;
+ coords.y = mb->get_position().y;
ScreenToClient(hWnd, &coords);
- mb.x = coords.x;
- mb.y = coords.y;
+ mb->set_position(Vector2(coords.x, coords.y));
}
+ mb->set_global_position(mb->get_position());
+
if (main_loop) {
- input->parse_input_event(event);
- if (mb.pressed && mb.button_index > 3) {
+ input->parse_input_event(mb);
+ if (mb->is_pressed() && mb->get_button_index() > 3) {
//send release for mouse wheel
- mb.pressed = false;
- input->parse_input_event(event);
+ Ref<InputEventMouseButton> mbd = mb->duplicate();
+ mbd->set_pressed(false);
+ input->parse_input_event(mbd);
}
}
}
@@ -635,10 +630,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Make sure we don't include modifiers for the modifier key itself.
KeyEvent ke;
- ke.mod_state.shift = (wParam != VK_SHIFT) ? shift_mem : false;
- ke.mod_state.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
- ke.mod_state.control = (wParam != VK_CONTROL) ? control_mem : false;
- ke.mod_state.meta = meta_mem;
+ ke.shift = (wParam != VK_SHIFT) ? shift_mem : false;
+ ke.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
+ ke.control = (wParam != VK_CONTROL) ? control_mem : false;
+ ke.meta = meta_mem;
ke.uMsg = uMsg;
if (ke.uMsg == WM_SYSKEYDOWN)
@@ -774,23 +769,25 @@ void OS_Windows::process_key_events() {
case WM_CHAR: {
if ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR)) {
- InputEvent event;
- event.type = InputEvent::KEY;
- InputEventKey &k = event.key;
-
- k.mod = ke.mod_state;
- k.pressed = true;
- k.scancode = KeyMappingWindows::get_keysym(ke.wParam);
- k.unicode = ke.wParam;
- if (k.unicode && gr_mem) {
- k.mod.alt = false;
- k.mod.control = false;
+ Ref<InputEventKey> k;
+ k.instance();
+
+ k->set_shift(ke.shift);
+ k->set_alt(ke.alt);
+ k->set_control(ke.control);
+ k->set_metakey(ke.meta);
+ k->set_pressed(true);
+ k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
+ k->set_unicode(ke.wParam);
+ if (k->get_unicode() && gr_mem) {
+ k->set_alt(false);
+ k->set_control(false);
}
- if (k.unicode < 32)
- k.unicode = 0;
+ if (k->get_unicode() < 32)
+ k->set_unicode(0);
- input->parse_input_event(event);
+ input->parse_input_event(k);
}
//do nothing
@@ -798,27 +795,32 @@ void OS_Windows::process_key_events() {
case WM_KEYUP:
case WM_KEYDOWN: {
- InputEvent event;
- event.type = InputEvent::KEY;
- InputEventKey &k = event.key;
+ Ref<InputEventKey> k;
+ k.instance();
+
+ k->set_shift(ke.shift);
+ k->set_alt(ke.alt);
+ k->set_control(ke.control);
+ k->set_metakey(ke.meta);
+
+ k->set_pressed(ke.uMsg == WM_KEYDOWN);
- k.mod = ke.mod_state;
- k.pressed = (ke.uMsg == WM_KEYDOWN);
+ k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
- k.scancode = KeyMappingWindows::get_keysym(ke.wParam);
- if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR)
- k.unicode = key_event_buffer[i + 1].wParam;
- if (k.unicode && gr_mem) {
- k.mod.alt = false;
- k.mod.control = false;
+ if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) {
+ k->set_unicode(key_event_buffer[i + 1].wParam);
+ }
+ if (k->get_unicode() && gr_mem) {
+ k->set_alt(false);
+ k->set_control(false);
}
- if (k.unicode < 32)
- k.unicode = 0;
+ if (k->get_unicode() < 32)
+ k->set_unicode(0);
- k.echo = (ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)));
+ k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))));
- input->parse_input_event(event);
+ input->parse_input_event(k);
} break;
}
@@ -887,8 +889,8 @@ BOOL CALLBACK OS_Windows::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPR
MonitorInfo minfo;
minfo.hMonitor = hMonitor;
minfo.hdcMonitor = hdcMonitor;
- minfo.rect.pos.x = lprcMonitor->left;
- minfo.rect.pos.y = lprcMonitor->top;
+ minfo.rect.position.x = lprcMonitor->left;
+ minfo.rect.position.y = lprcMonitor->top;
minfo.rect.size.x = lprcMonitor->right - lprcMonitor->left;
minfo.rect.size.y = lprcMonitor->bottom - lprcMonitor->top;
@@ -1027,12 +1029,10 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
#endif
visual_server = memnew(VisualServerRaster);
- // FIXME: Reimplement threaded rendering? Or remove?
- /*
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+
+ visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- */
physics_server = memnew(PhysicsServerSW);
physics_server->init();
@@ -1368,7 +1368,7 @@ void OS_Windows::set_current_screen(int p_screen) {
Point2 OS_Windows::get_screen_position(int p_screen) const {
ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), Point2());
- return Vector2(monitor_info[p_screen].rect.pos);
+ return Vector2(monitor_info[p_screen].rect.position);
}
Size2 OS_Windows::get_screen_size(int p_screen) const {
@@ -1993,13 +1993,14 @@ String OS_Windows::get_executable_path() const {
return s;
}
-void OS_Windows::set_icon(const Image &p_icon) {
+void OS_Windows::set_icon(const Ref<Image> &p_icon) {
- Image icon = p_icon;
- if (icon.get_format() != Image::FORMAT_RGBA8)
- icon.convert(Image::FORMAT_RGBA8);
- int w = icon.get_width();
- int h = icon.get_height();
+ ERR_FAIL_COND(!p_icon.is_valid());
+ Ref<Image> icon = p_icon->duplicate();
+ if (icon->get_format() != Image::FORMAT_RGBA8)
+ icon->convert(Image::FORMAT_RGBA8);
+ int w = icon->get_width();
+ int h = icon->get_height();
/* Create temporary bitmap buffer */
int icon_len = 40 + h * w * 4;
@@ -2020,7 +2021,7 @@ void OS_Windows::set_icon(const Image &p_icon) {
encode_uint32(0, &icon_bmp[36]);
uint8_t *wr = &icon_bmp[40];
- PoolVector<uint8_t>::Read r = icon.get_data().read();
+ PoolVector<uint8_t>::Read r = icon->get_data().read();
for (int i = 0; i < h; i++) {
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 87eceafa02..6cbdd58830 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -68,7 +68,7 @@ class OS_Windows : public OS {
struct KeyEvent {
- InputModifierState mod_state;
+ bool alt, shift, control, meta;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
@@ -254,7 +254,7 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
- void set_icon(const Image &p_icon);
+ void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
index f69c0bd2ed..f3b91c1b56 100644
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ b/platform/windows/packet_peer_udp_winsock.cpp
@@ -203,6 +203,8 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
len = sizeof(struct sockaddr_storage);
++queue_count;
+ if (p_wait)
+ break;
};
if (ret == SOCKET_ERROR) {
diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp
index 1d9756f68b..428bc5dcc2 100644
--- a/platform/windows/power_windows.cpp
+++ b/platform/windows/power_windows.cpp
@@ -28,6 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_windows.h"
// CODE CHUNK IMPORTED FROM SDL 2.0
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 34306c8d0f..0ba0f68393 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -141,6 +141,15 @@ def configure(env):
env.ParseConfig('pkg-config xrandr --cflags --libs')
if (env['builtin_openssl'] == 'no'):
+ # Currently not compatible with OpenSSL 1.1.0+
+ # https://github.com/godotengine/godot/issues/8624
+ import subprocess
+ openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n')
+ if (openssl_version >= "1.1.0"):
+ print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version)
+ print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n")
+ sys.exit(255)
+
env.ParseConfig('pkg-config openssl --cflags --libs')
if (env['builtin_libwebp'] == 'no'):
diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp
index b9ded188bf..d6bad95e5b 100644
--- a/platform/x11/export/export.cpp
+++ b/platform/x11/export/export.cpp
@@ -37,7 +37,7 @@ void register_x11_exporter() {
Ref<EditorExportPlatformPC> platform;
platform.instance();
- Image img(_x11_logo);
+ Ref<Image> img = memnew(Image(_x11_logo));
Ref<ImageTexture> logo;
logo.instance();
logo->create_from_image(img);
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 2e2fe3ba8a..2eebc96d2c 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -34,6 +34,7 @@
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/visual/visual_server_raster.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -206,12 +207,12 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
#endif
visual_server = memnew(VisualServerRaster);
-#if 0
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+
+ visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
-#endif
+
// borderless fullscreen window mode
if (current_videomode.fullscreen) {
// needed for lxde/openbox, possibly others
@@ -336,7 +337,9 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
cursor_theme = XcursorGetTheme(x11_display);
if (!cursor_theme) {
- WARN_PRINT("Could not find cursor theme");
+ if (is_stdout_verbose()) {
+ print_line("XcursorGetTheme could not get cursor theme");
+ }
cursor_theme = "default";
}
@@ -958,16 +961,12 @@ void OS_X11::request_attention() {
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
-InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
-
- InputModifierState state;
-
- state.shift = (p_x11_state & ShiftMask);
- state.control = (p_x11_state & ControlMask);
- state.alt = (p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/); //altgr should not count as alt
- state.meta = (p_x11_state & Mod4Mask);
+void OS_X11::get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) {
- return state;
+ state->set_shift((p_x11_state & ShiftMask));
+ state->set_control((p_x11_state & ControlMask));
+ state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt
+ state->set_metakey((p_x11_state & Mod4Mask));
}
unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) {
@@ -1099,7 +1098,10 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
//print_line("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask));
- InputModifierState state = get_key_modifier_state(xkeyevent->state);
+ Ref<InputEventKey> k;
+ k.instance();
+
+ get_key_modifier_state(xkeyevent->state, k);
/* Phase 6, determine echo character */
@@ -1142,40 +1144,36 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
/* Phase 7, send event to Window */
- InputEvent event;
- event.type = InputEvent::KEY;
- event.device = 0;
- event.key.mod = state;
- event.key.pressed = keypress;
+ k->set_pressed(keypress);
if (keycode >= 'a' && keycode <= 'z')
keycode -= 'a' - 'A';
- event.key.scancode = keycode;
- event.key.unicode = unicode;
- event.key.echo = p_echo;
+ k->set_scancode(keycode);
+ k->set_unicode(unicode);
+ k->set_echo(p_echo);
- if (event.key.scancode == KEY_BACKTAB) {
+ if (k->get_scancode() == KEY_BACKTAB) {
//make it consistent across platforms.
- event.key.scancode = KEY_TAB;
- event.key.mod.shift = true;
+ k->set_scancode(KEY_TAB);
+ k->set_shift(true);
}
//don't set mod state if modifier keys are released by themselves
//else event.is_action() will not work correctly here
- if (!event.key.pressed) {
- if (event.key.scancode == KEY_SHIFT)
- event.key.mod.shift = false;
- else if (event.key.scancode == KEY_CONTROL)
- event.key.mod.control = false;
- else if (event.key.scancode == KEY_ALT)
- event.key.mod.alt = false;
- else if (event.key.scancode == KEY_META)
- event.key.mod.meta = false;
+ if (!k->is_pressed()) {
+ if (k->get_scancode() == KEY_SHIFT)
+ k->set_shift(false);
+ else if (k->get_scancode() == KEY_CONTROL)
+ k->set_control(false);
+ else if (k->get_scancode() == KEY_ALT)
+ k->set_alt(false);
+ else if (k->get_scancode() == KEY_META)
+ k->set_metakey(false);
}
- //printf("key: %x\n",event.key.scancode);
- input->parse_input_event(event);
+ //printf("key: %x\n",k->get_scancode());
+ input->parse_input_event(k);
}
struct Property {
@@ -1332,22 +1330,20 @@ void OS_X11::process_xevents() {
event.xbutton.y = last_mouse_pos.y;
}
- InputEvent mouse_event;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
- mouse_event.device = 0;
- mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state);
- mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state);
- mouse_event.mouse_button.x = event.xbutton.x;
- mouse_event.mouse_button.y = event.xbutton.y;
- mouse_event.mouse_button.global_x = event.xbutton.x;
- mouse_event.mouse_button.global_y = event.xbutton.y;
- mouse_event.mouse_button.button_index = event.xbutton.button;
- if (mouse_event.mouse_button.button_index == 2)
- mouse_event.mouse_button.button_index = 3;
- else if (mouse_event.mouse_button.button_index == 3)
- mouse_event.mouse_button.button_index = 2;
-
- mouse_event.mouse_button.pressed = (event.type == ButtonPress);
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state(event.xbutton.state, mb);
+ mb->set_button_mask(get_mouse_button_state(event.xbutton.state));
+ mb->set_position(Vector2(event.xbutton.x, event.xbutton.y));
+ mb->set_global_position(mb->get_position());
+ mb->set_button_index(event.xbutton.button);
+ if (mb->get_button_index() == 2)
+ mb->set_button_index(3);
+ else if (mb->get_button_index() == 3)
+ mb->set_button_index(2);
+
+ mb->set_pressed((event.type == ButtonPress));
if (event.type == ButtonPress && event.xbutton.button == 1) {
@@ -1357,7 +1353,7 @@ void OS_X11::process_xevents() {
last_click_ms = 0;
last_click_pos = Point2(-100, -100);
- mouse_event.mouse_button.doubleclick = true;
+ mb->set_doubleclick(true);
} else {
last_click_ms += diff;
@@ -1365,7 +1361,7 @@ void OS_X11::process_xevents() {
}
}
- input->parse_input_event(mouse_event);
+ input->parse_input_event(mb);
} break;
case MotionNotify: {
@@ -1443,22 +1439,16 @@ void OS_X11::process_xevents() {
Point2i rel = pos - last_mouse_pos;
- InputEvent motion_event;
- motion_event.type = InputEvent::MOUSE_MOTION;
- motion_event.device = 0;
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
- motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state);
- motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state);
- motion_event.mouse_motion.x = pos.x;
- motion_event.mouse_motion.y = pos.y;
+ get_key_modifier_state(event.xmotion.state, mm);
+ mm->set_button_mask(get_mouse_button_state(event.xmotion.state));
+ mm->set_position(pos);
+ mm->set_global_position(pos);
input->set_mouse_position(pos);
- motion_event.mouse_motion.global_x = pos.x;
- motion_event.mouse_motion.global_y = pos.y;
- motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y;
-
- motion_event.mouse_motion.relative_x = rel.x;
- motion_event.mouse_motion.relative_y = rel.y;
+ mm->set_speed(input->get_last_mouse_speed());
+ mm->set_relative(rel);
last_mouse_pos = pos;
@@ -1467,7 +1457,7 @@ void OS_X11::process_xevents() {
// this is so that the relative motion doesn't get messed up
// after we regain focus.
if (window_has_focus || !mouse_mode_grab)
- input->parse_input_event(motion_event);
+ input->parse_input_event(mm);
} break;
case KeyPress:
@@ -1857,15 +1847,15 @@ void OS_X11::alert(const String &p_alert, const String &p_title) {
execute("/usr/bin/xmessage", args, true);
}
-void OS_X11::set_icon(const Image &p_icon) {
+void OS_X11::set_icon(const Ref<Image> &p_icon) {
Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
- if (!p_icon.empty()) {
- Image img = p_icon;
- img.convert(Image::FORMAT_RGBA8);
+ if (p_icon.is_valid()) {
+ Ref<Image> img = p_icon->duplicate();
+ img->convert(Image::FORMAT_RGBA8);
- int w = img.get_width();
- int h = img.get_height();
+ int w = img->get_width();
+ int h = img->get_height();
// We're using long to have wordsize (32Bit build -> 32 Bits, 64 Bit build -> 64 Bits
Vector<long> pd;
@@ -1875,7 +1865,7 @@ void OS_X11::set_icon(const Image &p_icon) {
pd[0] = w;
pd[1] = h;
- PoolVector<uint8_t>::Read r = img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
long *wr = &pd[2];
uint8_t const *pr = r.ptr();
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 44994e40ec..d62186e5bd 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -121,7 +121,7 @@ class OS_X11 : public OS_Unix {
PhysicsServer *physics_server;
unsigned int get_mouse_button_state(unsigned int p_x11_state);
- InputModifierState get_key_modifier_state(unsigned int p_x11_state);
+ void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
Physics2DServer *physics_2d_server;
MouseMode mouse_mode;
@@ -206,7 +206,7 @@ public:
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
- virtual void set_icon(const Image &p_icon);
+ virtual void set_icon(const Ref<Image> &p_icon);
virtual MainLoop *get_main_loop() const;
diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp
index 3454a6313e..093d24f406 100644
--- a/platform/x11/power_x11.cpp
+++ b/platform/x11/power_x11.cpp
@@ -28,6 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_x11.h"
#include <stdio.h>
diff --git a/scene/2d/animated_sprite.cpp b/scene/2d/animated_sprite.cpp
index eba638b0f5..6a3238b64e 100644
--- a/scene/2d/animated_sprite.cpp
+++ b/scene/2d/animated_sprite.cpp
@@ -32,6 +32,8 @@
#include "scene/scene_string_names.h"
#include "scene/scene_string_names.h"
+#define NORMAL_SUFFIX "_normal"
+
////////////////////////////
void SpriteFrames::add_frame(const StringName &p_anim, const Ref<Texture> &p_frame, int p_at_pos) {
@@ -82,6 +84,7 @@ void SpriteFrames::add_animation(const StringName &p_anim) {
ERR_FAIL_COND(animations.has(p_anim));
animations[p_anim] = Anim();
+ animations[p_anim].normal_name = String(p_anim) + NORMAL_SUFFIX;
}
bool SpriteFrames::has_animation(const StringName &p_anim) const {
@@ -101,6 +104,7 @@ void SpriteFrames::rename_animation(const StringName &p_prev, const StringName &
Anim anim = animations[p_prev];
animations.erase(p_prev);
animations[p_next] = anim;
+ animations[p_next].normal_name = String(p_next) + NORMAL_SUFFIX;
}
Vector<String> SpriteFrames::_get_animation_list() const {
@@ -374,6 +378,8 @@ void AnimatedSprite::_notification(int p_what) {
return;
}
+ Ref<Texture> normal = frames->get_normal_frame(animation, frame);
+
//print_line("DECIDED TO DRAW");
RID ci = get_canvas_item();
@@ -400,7 +406,7 @@ void AnimatedSprite::_notification(int p_what) {
dst_rect.size.y = -dst_rect.size.y;
//texture->draw_rect(ci,dst_rect,false,modulate);
- texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()));
+ texture->draw_rect_region(ci, dst_rect, Rect2(Vector2(), texture->get_size()), Color(1, 1, 1), false, normal);
//VisualServer::get_singleton()->canvas_item_add_texture_rect_region(ci,dst_rect,texture->get_rid(),src_rect,modulate);
} break;
diff --git a/scene/2d/animated_sprite.h b/scene/2d/animated_sprite.h
index 64794b0ca3..2274450647 100644
--- a/scene/2d/animated_sprite.h
+++ b/scene/2d/animated_sprite.h
@@ -47,6 +47,8 @@ class SpriteFrames : public Resource {
loop = true;
speed = 5;
}
+
+ StringName normal_name;
};
Map<StringName, Anim> animations;
@@ -89,6 +91,20 @@ public:
return E->get().frames[p_idx];
}
+ _FORCE_INLINE_ Ref<Texture> get_normal_frame(const StringName &p_anim, int p_idx) const {
+
+ const Map<StringName, Anim>::Element *E = animations.find(p_anim);
+ ERR_FAIL_COND_V(!E, Ref<Texture>());
+ ERR_FAIL_COND_V(p_idx < 0, Ref<Texture>());
+
+ const Map<StringName, Anim>::Element *EN = animations.find(E->get().normal_name);
+
+ if (p_idx >= EN->get().frames.size())
+ return Ref<Texture>();
+
+ return EN->get().frames[p_idx];
+ }
+
void set_frame(const StringName &p_anim, int p_idx, const Ref<Texture> &p_frame) {
Map<StringName, Anim>::Element *E = animations.find(p_anim);
ERR_FAIL_COND(!E);
diff --git a/scene/2d/area_2d.cpp b/scene/2d/area_2d.cpp
index 8bce489624..db22a38cec 100644
--- a/scene/2d/area_2d.cpp
+++ b/scene/2d/area_2d.cpp
@@ -29,7 +29,9 @@
/*************************************************************************/
#include "area_2d.h"
#include "scene/scene_string_names.h"
+#include "servers/audio_server.h"
#include "servers/physics_2d_server.h"
+
void Area2D::set_space_override_mode(SpaceOverride p_mode) {
space_override = p_mode;
@@ -501,15 +503,15 @@ uint32_t Area2D::get_collision_mask() const {
return collision_mask;
}
-void Area2D::set_layer_mask(uint32_t p_mask) {
+void Area2D::set_collision_layer(uint32_t p_layer) {
- layer_mask = p_mask;
- Physics2DServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask);
+ collision_layer = p_layer;
+ Physics2DServer::get_singleton()->area_set_collision_layer(get_rid(), p_layer);
}
-uint32_t Area2D::get_layer_mask() const {
+uint32_t Area2D::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void Area2D::set_collision_mask_bit(int p_bit, bool p_value) {
@@ -527,19 +529,60 @@ bool Area2D::get_collision_mask_bit(int p_bit) const {
return get_collision_mask() & (1 << p_bit);
}
-void Area2D::set_layer_mask_bit(int p_bit, bool p_value) {
+void Area2D::set_collision_layer_bit(int p_bit, bool p_value) {
- uint32_t mask = get_layer_mask();
+ uint32_t layer = get_collision_layer();
if (p_value)
- mask |= 1 << p_bit;
+ layer |= 1 << p_bit;
else
- mask &= ~(1 << p_bit);
- set_layer_mask(mask);
+ layer &= ~(1 << p_bit);
+ set_collision_layer(layer);
+}
+
+bool Area2D::get_collision_layer_bit(int p_bit) const {
+
+ return get_collision_layer() & (1 << p_bit);
+}
+
+void Area2D::set_audio_bus_override(bool p_override) {
+
+ audio_bus_override = p_override;
}
-bool Area2D::get_layer_mask_bit(int p_bit) const {
+bool Area2D::is_overriding_audio_bus() const {
- return get_layer_mask() & (1 << p_bit);
+ return audio_bus_override;
+}
+
+void Area2D::set_audio_bus(const StringName &p_audio_bus) {
+
+ audio_bus = p_audio_bus;
+}
+
+StringName Area2D::get_audio_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == audio_bus) {
+ return audio_bus;
+ }
+ }
+ return "Master";
+}
+
+void Area2D::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "audio_bus_name") {
+
+ String options;
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (i > 0)
+ options += ",";
+ String name = AudioServer::get_singleton()->get_bus_name(i);
+ options += name;
+ }
+
+ property.hint_string = options;
+ }
}
void Area2D::_bind_methods() {
@@ -577,14 +620,14 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &Area2D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &Area2D::get_collision_mask);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Area2D::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &Area2D::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Area2D::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &Area2D::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &Area2D::set_collision_mask_bit);
ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &Area2D::get_collision_mask_bit);
- ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "bit", "value"), &Area2D::set_layer_mask_bit);
- ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "bit"), &Area2D::get_layer_mask_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &Area2D::set_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &Area2D::get_collision_layer_bit);
ClassDB::bind_method(D_METHOD("set_monitoring", "enable"), &Area2D::set_monitoring);
ClassDB::bind_method(D_METHOD("is_monitoring"), &Area2D::is_monitoring);
@@ -598,6 +641,12 @@ void Area2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("overlaps_body", "body"), &Area2D::overlaps_body);
ClassDB::bind_method(D_METHOD("overlaps_area", "area"), &Area2D::overlaps_area);
+ ClassDB::bind_method(D_METHOD("set_audio_bus", "name"), &Area2D::set_audio_bus);
+ ClassDB::bind_method(D_METHOD("get_audio_bus"), &Area2D::get_audio_bus);
+
+ ClassDB::bind_method(D_METHOD("set_audio_bus_override", "enable"), &Area2D::set_audio_bus_override);
+ ClassDB::bind_method(D_METHOD("is_overriding_audio_bus"), &Area2D::is_overriding_audio_bus);
+
ClassDB::bind_method(D_METHOD("_body_inout"), &Area2D::_body_inout);
ClassDB::bind_method(D_METHOD("_area_inout"), &Area2D::_area_inout);
@@ -622,8 +671,12 @@ void Area2D::_bind_methods() {
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
ADD_GROUP("Collision", "collision_");
- ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_layer_mask", "get_layer_mask");
+ ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTYNO(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
+
+ ADD_GROUP("Audio Bus", "audio_bus_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "audio_bus_override"), "set_audio_bus_override", "is_overriding_audio_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "audio_bus_name", PROPERTY_HINT_ENUM, ""), "set_audio_bus", "get_audio_bus");
}
Area2D::Area2D()
@@ -641,7 +694,8 @@ Area2D::Area2D()
monitoring = false;
monitorable = false;
collision_mask = 1;
- layer_mask = 1;
+ collision_layer = 1;
+ audio_bus_override = false;
set_monitoring(true);
set_monitorable(true);
}
diff --git a/scene/2d/area_2d.h b/scene/2d/area_2d.h
index 3efc1abbd4..12d71f3911 100644
--- a/scene/2d/area_2d.h
+++ b/scene/2d/area_2d.h
@@ -55,7 +55,7 @@ private:
real_t linear_damp;
real_t angular_damp;
uint32_t collision_mask;
- uint32_t layer_mask;
+ uint32_t collision_layer;
int priority;
bool monitoring;
bool monitorable;
@@ -126,9 +126,13 @@ private:
Map<ObjectID, AreaState> area_map;
void _clear_monitoring();
+ bool audio_bus_override;
+ StringName audio_bus;
+
protected:
void _notification(int p_what);
static void _bind_methods();
+ void _validate_property(PropertyInfo &property) const;
public:
void set_space_override_mode(SpaceOverride p_mode);
@@ -164,14 +168,14 @@ public:
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
- void set_layer_mask(uint32_t p_mask);
- uint32_t get_layer_mask() const;
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
- void set_layer_mask_bit(int p_bit, bool p_value);
- bool get_layer_mask_bit(int p_bit) const;
+ void set_collision_layer_bit(int p_bit, bool p_value);
+ bool get_collision_layer_bit(int p_bit) const;
Array get_overlapping_bodies() const; //function for script
Array get_overlapping_areas() const; //function for script
@@ -179,6 +183,12 @@ public:
bool overlaps_area(Node *p_area) const;
bool overlaps_body(Node *p_body) const;
+ void set_audio_bus_override(bool p_override);
+ bool is_overriding_audio_bus() const;
+
+ void set_audio_bus(const StringName &p_audio_bus);
+ StringName get_audio_bus() const;
+
Area2D();
~Area2D();
};
diff --git a/scene/2d/audio_stream_player_2d.cpp b/scene/2d/audio_stream_player_2d.cpp
new file mode 100644
index 0000000000..3d9e64ae79
--- /dev/null
+++ b/scene/2d/audio_stream_player_2d.cpp
@@ -0,0 +1,463 @@
+
+#include "audio_stream_player_2d.h"
+#include "scene/2d/area_2d.h"
+#include "scene/main/viewport.h"
+void AudioStreamPlayer2D::_mix_audio() {
+
+ if (!stream_playback.is_valid()) {
+ return;
+ }
+
+ if (!active) {
+ return;
+ }
+
+ if (setseek >= 0.0) {
+ stream_playback->start(setseek);
+ setseek = -1.0; //reset seek
+ }
+
+ //get data
+ AudioFrame *buffer = mix_buffer.ptr();
+ int buffer_size = mix_buffer.size();
+
+ //mix
+ stream_playback->mix(buffer, 1.0, buffer_size);
+
+ //write all outputs
+ for (int i = 0; i < output_count; i++) {
+
+ Output current = outputs[i];
+
+ //see if current output exists, to keep volume ramp
+ bool found = false;
+ for (int j = i; j < prev_output_count; j++) {
+ if (prev_outputs[j].viewport == current.viewport) {
+ if (j != i) {
+ SWAP(prev_outputs[j], prev_outputs[i]);
+ }
+ found = true;
+ break;
+ }
+ }
+
+ if (!found) {
+ //create new if was not used before
+ if (prev_output_count < MAX_OUTPUTS) {
+ prev_outputs[prev_output_count] = prev_outputs[i]; //may be owned by another viewport
+ prev_output_count++;
+ }
+ prev_outputs[i] = current;
+ }
+
+ //mix!
+ AudioFrame vol_inc = (current.vol - prev_outputs[i].vol) / float(buffer_size);
+ AudioFrame vol = current.vol;
+
+ switch (AudioServer::get_singleton()->get_speaker_mode()) {
+
+ case AudioServer::SPEAKER_MODE_STEREO: {
+ AudioFrame *target = AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 0);
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ target[j] = buffer[j] * vol;
+ vol += vol_inc;
+ }
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_51: {
+
+ AudioFrame *targets[2] = {
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2),
+ };
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ AudioFrame frame = buffer[j] * vol;
+ targets[0][j] = frame;
+ targets[1][j] = frame;
+ vol += vol_inc;
+ }
+
+ } break;
+ case AudioServer::SPEAKER_SURROUND_71: {
+
+ AudioFrame *targets[3] = {
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 1),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 2),
+ AudioServer::get_singleton()->thread_get_channel_mix_buffer(current.bus_index, 3)
+ };
+
+ for (int j = 0; j < buffer_size; j++) {
+
+ AudioFrame frame = buffer[j] * vol;
+ targets[0][j] = frame;
+ targets[1][j] = frame;
+ targets[2][j] = frame;
+ vol += vol_inc;
+ }
+
+ } break;
+ }
+
+ prev_outputs[i] = current;
+ }
+
+ prev_output_count = output_count;
+
+ //stream is no longer active, disable this.
+ if (!stream_playback->is_playing()) {
+ active = false;
+ }
+
+ output_ready = false;
+}
+
+void AudioStreamPlayer2D::_notification(int p_what) {
+
+ if (p_what == NOTIFICATION_ENTER_TREE) {
+
+ AudioServer::get_singleton()->add_callback(_mix_audios, this);
+ if (autoplay && !get_tree()->is_editor_hint()) {
+ play();
+ }
+ }
+
+ if (p_what == NOTIFICATION_EXIT_TREE) {
+
+ AudioServer::get_singleton()->remove_callback(_mix_audios, this);
+ }
+
+ if (p_what == NOTIFICATION_INTERNAL_FIXED_PROCESS) {
+
+ //update anything related to position first, if possible of course
+
+ if (!output_ready) {
+ List<Viewport *> viewports;
+ Ref<World2D> world_2d = get_world_2d();
+ ERR_FAIL_COND(world_2d.is_null());
+
+ int new_output_count = 0;
+
+ Vector2 global_pos = get_global_position();
+
+ int bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus);
+
+ //check if any area is diverting sound into a bus
+
+ Physics2DDirectSpaceState *space_state = Physics2DServer::get_singleton()->space_get_direct_state(world_2d->get_space());
+
+ Physics2DDirectSpaceState::ShapeResult sr[MAX_INTERSECT_AREAS];
+
+ int areas = space_state->intersect_point(global_pos, sr, MAX_INTERSECT_AREAS, Set<RID>(), area_mask, Physics2DDirectSpaceState::TYPE_MASK_AREA);
+
+ for (int i = 0; i < areas; i++) {
+ if (!sr[i].collider)
+ continue;
+
+ Area2D *area2d = sr[i].collider->cast_to<Area2D>();
+ if (!area2d)
+ continue;
+
+ if (!area2d->is_overriding_audio_bus())
+ continue;
+
+ StringName bus_name = area2d->get_audio_bus();
+ bus_index = AudioServer::get_singleton()->thread_find_bus_index(bus_name);
+ break;
+ }
+
+ world_2d->get_viewport_list(&viewports);
+ for (List<Viewport *>::Element *E = viewports.front(); E; E = E->next()) {
+
+ Viewport *vp = E->get();
+ if (vp->is_audio_listener_2d()) {
+
+ //compute matrix to convert to screen
+ Transform2D to_screen = vp->get_global_canvas_transform() * vp->get_canvas_transform();
+ Vector2 screen_size = vp->get_visible_rect().size;
+
+ //screen in global is used for attenuation
+ Vector2 screen_in_global = to_screen.affine_inverse().xform(screen_size * 0.5);
+
+ float dist = global_pos.distance_to(screen_in_global); //distance to screen center
+
+ if (dist > max_distance)
+ continue; //cant hear this sound in this viewport
+
+ float multiplier = Math::pow(1.0f - dist / max_distance, attenuation);
+ multiplier *= Math::db2linear(volume_db); //also apply player volume!
+
+ //point in screen is used for panning
+ Vector2 point_in_screen = to_screen.xform(global_pos);
+
+ float pan = CLAMP(point_in_screen.x / screen_size.width, 0.0, 1.0);
+
+ float l = 1.0 - pan;
+ float r = pan;
+
+ outputs[new_output_count].vol = AudioFrame(l, r) * multiplier;
+ outputs[new_output_count].bus_index = bus_index;
+ outputs[new_output_count].viewport = vp; //keep pointer only for reference
+ new_output_count++;
+ if (new_output_count == MAX_OUTPUTS)
+ break;
+ }
+ }
+
+ output_count = new_output_count;
+ output_ready = true;
+ }
+
+ //start playing if requested
+ if (setplay >= 0.0) {
+ setseek = setplay;
+ active = true;
+ setplay = -1;
+ _change_notify("playing"); //update property in editor
+ }
+
+ //stop playing if no longer active
+ if (!active) {
+ set_fixed_process_internal(false);
+ _change_notify("playing"); //update property in editor
+ }
+ }
+}
+
+void AudioStreamPlayer2D::set_stream(Ref<AudioStream> p_stream) {
+
+ ERR_FAIL_COND(!p_stream.is_valid());
+ AudioServer::get_singleton()->lock();
+
+ mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
+
+ if (stream_playback.is_valid()) {
+ stream_playback.unref();
+ stream.unref();
+ active = false;
+ setseek = -1;
+ }
+
+ stream = p_stream;
+ stream_playback = p_stream->instance_playback();
+
+ if (stream_playback.is_null()) {
+ stream.unref();
+ ERR_FAIL_COND(stream_playback.is_null());
+ }
+
+ AudioServer::get_singleton()->unlock();
+}
+
+Ref<AudioStream> AudioStreamPlayer2D::get_stream() const {
+
+ return stream;
+}
+
+void AudioStreamPlayer2D::set_volume_db(float p_volume) {
+
+ volume_db = p_volume;
+}
+float AudioStreamPlayer2D::get_volume_db() const {
+
+ return volume_db;
+}
+
+void AudioStreamPlayer2D::play(float p_from_pos) {
+
+ if (stream_playback.is_valid()) {
+ setplay = p_from_pos;
+ output_ready = false;
+ set_fixed_process_internal(true);
+ }
+}
+
+void AudioStreamPlayer2D::seek(float p_seconds) {
+
+ if (stream_playback.is_valid()) {
+ setseek = p_seconds;
+ }
+}
+
+void AudioStreamPlayer2D::stop() {
+
+ if (stream_playback.is_valid()) {
+ active = false;
+ set_fixed_process_internal(false);
+ setplay = -1;
+ }
+}
+
+bool AudioStreamPlayer2D::is_playing() const {
+
+ if (stream_playback.is_valid()) {
+ return active; // && stream_playback->is_playing();
+ }
+
+ return false;
+}
+
+float AudioStreamPlayer2D::get_pos() {
+
+ if (stream_playback.is_valid()) {
+ return stream_playback->get_pos();
+ }
+
+ return 0;
+}
+
+void AudioStreamPlayer2D::set_bus(const StringName &p_bus) {
+
+ //if audio is active, must lock this
+ AudioServer::get_singleton()->lock();
+ bus = p_bus;
+ AudioServer::get_singleton()->unlock();
+}
+StringName AudioStreamPlayer2D::get_bus() const {
+
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
+ return bus;
+ }
+ }
+ return "Master";
+}
+
+void AudioStreamPlayer2D::set_autoplay(bool p_enable) {
+
+ autoplay = p_enable;
+}
+bool AudioStreamPlayer2D::is_autoplay_enabled() {
+
+ return autoplay;
+}
+
+void AudioStreamPlayer2D::_set_playing(bool p_enable) {
+
+ if (p_enable)
+ play();
+ else
+ stop();
+}
+bool AudioStreamPlayer2D::_is_active() const {
+
+ return active;
+}
+
+void AudioStreamPlayer2D::_validate_property(PropertyInfo &property) const {
+
+ if (property.name == "bus") {
+
+ String options;
+ for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
+ if (i > 0)
+ options += ",";
+ String name = AudioServer::get_singleton()->get_bus_name(i);
+ options += name;
+ }
+
+ property.hint_string = options;
+ }
+}
+
+void AudioStreamPlayer2D::_bus_layout_changed() {
+
+ _change_notify();
+}
+
+void AudioStreamPlayer2D::set_max_distance(float p_pixels) {
+
+ ERR_FAIL_COND(p_pixels <= 0.0);
+ max_distance = p_pixels;
+}
+
+float AudioStreamPlayer2D::get_max_distance() const {
+
+ return max_distance;
+}
+
+void AudioStreamPlayer2D::set_attenuation(float p_curve) {
+
+ attenuation = p_curve;
+}
+float AudioStreamPlayer2D::get_attenuation() const {
+
+ return attenuation;
+}
+
+void AudioStreamPlayer2D::set_area_mask(uint32_t p_mask) {
+
+ area_mask = p_mask;
+}
+
+uint32_t AudioStreamPlayer2D::get_area_mask() const {
+
+ return area_mask;
+}
+
+void AudioStreamPlayer2D::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioStreamPlayer2D::set_stream);
+ ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer2D::get_stream);
+
+ ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer2D::set_volume_db);
+ ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer2D::get_volume_db);
+
+ ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioStreamPlayer2D::play, DEFVAL(0.0));
+ ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioStreamPlayer2D::seek);
+ ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer2D::stop);
+
+ ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer2D::is_playing);
+ ClassDB::bind_method(D_METHOD("get_pos"), &AudioStreamPlayer2D::get_pos);
+
+ ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer2D::set_bus);
+ ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer2D::get_bus);
+
+ ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer2D::set_autoplay);
+ ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer2D::is_autoplay_enabled);
+
+ ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer2D::_set_playing);
+ ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer2D::_is_active);
+
+ ClassDB::bind_method(D_METHOD("set_max_distance", "pixels"), &AudioStreamPlayer2D::set_max_distance);
+ ClassDB::bind_method(D_METHOD("get_max_distance"), &AudioStreamPlayer2D::get_max_distance);
+
+ ClassDB::bind_method(D_METHOD("set_attenuation", "curve"), &AudioStreamPlayer2D::set_attenuation);
+ ClassDB::bind_method(D_METHOD("get_attenuation"), &AudioStreamPlayer2D::get_attenuation);
+
+ ClassDB::bind_method(D_METHOD("set_area_mask", "mask"), &AudioStreamPlayer2D::set_area_mask);
+ ClassDB::bind_method(D_METHOD("get_area_mask"), &AudioStreamPlayer2D::get_area_mask);
+
+ ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer2D::_bus_layout_changed);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "playing", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "_set_playing", "_is_active");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "autoplay"), "set_autoplay", "is_autoplay_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "max_distance", PROPERTY_HINT_RANGE, "1,65536,1"), "set_max_distance", "get_max_distance");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "attenuation", PROPERTY_HINT_EXP_EASING), "set_attenuation", "get_attenuation");
+ ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "area_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_area_mask", "get_area_mask");
+}
+
+AudioStreamPlayer2D::AudioStreamPlayer2D() {
+
+ volume_db = 0;
+ autoplay = false;
+ setseek = -1;
+ active = false;
+ output_count = 0;
+ prev_output_count = 0;
+ max_distance = 2000;
+ attenuation = 1;
+ setplay = -1;
+ output_ready = false;
+ area_mask = 1;
+ AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
+}
+
+AudioStreamPlayer2D::~AudioStreamPlayer2D() {
+}
diff --git a/scene/2d/audio_stream_player_2d.h b/scene/2d/audio_stream_player_2d.h
new file mode 100644
index 0000000000..25eff61b76
--- /dev/null
+++ b/scene/2d/audio_stream_player_2d.h
@@ -0,0 +1,96 @@
+#ifndef AUDIO_STREAM_PLAYER_2D_H
+#define AUDIO_STREAM_PLAYER_2D_H
+
+#include "scene/2d/node_2d.h"
+#include "servers/audio/audio_stream.h"
+#include "servers/audio_server.h"
+
+class AudioStreamPlayer2D : public Node2D {
+
+ GDCLASS(AudioStreamPlayer2D, Node2D)
+
+private:
+ enum {
+ MAX_OUTPUTS = 8,
+ MAX_INTERSECT_AREAS = 32
+
+ };
+
+ struct Output {
+
+ AudioFrame vol;
+ int bus_index;
+ Viewport *viewport; //pointer only used for reference to previous mix
+ };
+
+ Output outputs[MAX_OUTPUTS];
+ volatile int output_count;
+ volatile bool output_ready;
+
+ //these are used by audio thread to have a reference of previous volumes (for ramping volume and avoiding clicks)
+ Output prev_outputs[MAX_OUTPUTS];
+ int prev_output_count;
+
+ Ref<AudioStreamPlayback> stream_playback;
+ Ref<AudioStream> stream;
+ Vector<AudioFrame> mix_buffer;
+
+ volatile float setseek;
+ volatile bool active;
+ volatile float setplay;
+
+ float volume_db;
+ bool autoplay;
+ StringName bus;
+
+ void _mix_audio();
+ static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer2D *>(self)->_mix_audio(); }
+
+ void _set_playing(bool p_enable);
+ bool _is_active() const;
+
+ void _bus_layout_changed();
+
+ uint32_t area_mask;
+
+ float max_distance;
+ float attenuation;
+
+protected:
+ void _validate_property(PropertyInfo &property) const;
+ void _notification(int p_what);
+ static void _bind_methods();
+
+public:
+ void set_stream(Ref<AudioStream> p_stream);
+ Ref<AudioStream> get_stream() const;
+
+ void set_volume_db(float p_volume);
+ float get_volume_db() const;
+
+ void play(float p_from_pos = 0.0);
+ void seek(float p_seconds);
+ void stop();
+ bool is_playing() const;
+ float get_pos();
+
+ void set_bus(const StringName &p_bus);
+ StringName get_bus() const;
+
+ void set_autoplay(bool p_enable);
+ bool is_autoplay_enabled();
+
+ void set_max_distance(float p_pixels);
+ float get_max_distance() const;
+
+ void set_attenuation(float p_curve);
+ float get_attenuation() const;
+
+ void set_area_mask(uint32_t p_mask);
+ uint32_t get_area_mask() const;
+
+ AudioStreamPlayer2D();
+ ~AudioStreamPlayer2D();
+};
+
+#endif
diff --git a/scene/2d/camera_2d.cpp b/scene/2d/camera_2d.cpp
index 71f651b0a4..9d8b5da366 100644
--- a/scene/2d/camera_2d.cpp
+++ b/scene/2d/camera_2d.cpp
@@ -120,20 +120,20 @@ Transform2D Camera2D::get_camera_transform() {
Rect2 screen_rect(-screen_offset + camera_pos, screen_size * zoom);
if (offset != Vector2())
- screen_rect.pos += offset;
+ screen_rect.position += offset;
if (limit_smoothing_enabled) {
- if (screen_rect.pos.x < limit[MARGIN_LEFT])
- camera_pos.x -= screen_rect.pos.x - limit[MARGIN_LEFT];
+ if (screen_rect.position.x < limit[MARGIN_LEFT])
+ camera_pos.x -= screen_rect.position.x - limit[MARGIN_LEFT];
- if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT])
- camera_pos.x -= screen_rect.pos.x + screen_rect.size.x - limit[MARGIN_RIGHT];
+ if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ camera_pos.x -= screen_rect.position.x + screen_rect.size.x - limit[MARGIN_RIGHT];
- if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
- camera_pos.y -= screen_rect.pos.y + screen_rect.size.y - limit[MARGIN_BOTTOM];
+ if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ camera_pos.y -= screen_rect.position.y + screen_rect.size.y - limit[MARGIN_BOTTOM];
- if (screen_rect.pos.y < limit[MARGIN_TOP])
- camera_pos.y -= screen_rect.pos.y - limit[MARGIN_TOP];
+ if (screen_rect.position.y < limit[MARGIN_TOP])
+ camera_pos.y -= screen_rect.position.y - limit[MARGIN_TOP];
}
if (smoothing_enabled && !get_tree()->is_editor_hint()) {
@@ -160,42 +160,42 @@ Transform2D Camera2D::get_camera_transform() {
}
Rect2 screen_rect(-screen_offset + ret_camera_pos, screen_size * zoom);
- if (screen_rect.pos.x < limit[MARGIN_LEFT])
- screen_rect.pos.x = limit[MARGIN_LEFT];
+ if (screen_rect.position.x < limit[MARGIN_LEFT])
+ screen_rect.position.x = limit[MARGIN_LEFT];
- if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT])
- screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
+ if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ screen_rect.position.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
- if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
- screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
+ if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
- if (screen_rect.pos.y < limit[MARGIN_TOP])
- screen_rect.pos.y = limit[MARGIN_TOP];
+ if (screen_rect.position.y < limit[MARGIN_TOP])
+ screen_rect.position.y = limit[MARGIN_TOP];
if (offset != Vector2()) {
- screen_rect.pos += offset;
- if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT])
- screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
+ screen_rect.position += offset;
+ if (screen_rect.position.x + screen_rect.size.x > limit[MARGIN_RIGHT])
+ screen_rect.position.x = limit[MARGIN_RIGHT] - screen_rect.size.x;
- if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
- screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
+ if (screen_rect.position.y + screen_rect.size.y > limit[MARGIN_BOTTOM])
+ screen_rect.position.y = limit[MARGIN_BOTTOM] - screen_rect.size.y;
- if (screen_rect.pos.x < limit[MARGIN_LEFT])
- screen_rect.pos.x = limit[MARGIN_LEFT];
+ if (screen_rect.position.x < limit[MARGIN_LEFT])
+ screen_rect.position.x = limit[MARGIN_LEFT];
- if (screen_rect.pos.y < limit[MARGIN_TOP])
- screen_rect.pos.y = limit[MARGIN_TOP];
+ if (screen_rect.position.y < limit[MARGIN_TOP])
+ screen_rect.position.y = limit[MARGIN_TOP];
}
- camera_screen_center = screen_rect.pos + screen_rect.size * 0.5;
+ camera_screen_center = screen_rect.position + screen_rect.size * 0.5;
Transform2D xform;
if (rotating) {
xform.set_rotation(angle);
}
xform.scale_basis(zoom);
- xform.set_origin(screen_rect.pos /*.floor()*/);
+ xform.set_origin(screen_rect.position /*.floor()*/);
/*
if (0) {
diff --git a/scene/2d/canvas_item.cpp b/scene/2d/canvas_item.cpp
index f699c8f0e8..471f529713 100644
--- a/scene/2d/canvas_item.cpp
+++ b/scene/2d/canvas_item.cpp
@@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "canvas_item.h"
+#include "core/method_bind_ext.inc"
#include "message_queue.h"
#include "os/input.h"
#include "scene/main/canvas_layer.h"
@@ -436,7 +437,7 @@ void CanvasItem::draw_circle(const Point2 &p_pos, float p_radius, const Color &p
VisualServer::get_singleton()->canvas_item_add_circle(canvas_item, p_pos, p_radius, p_color);
}
-void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate) {
+void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate, const Ref<Texture> &p_normal_map) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -448,7 +449,7 @@ void CanvasItem::draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos
p_texture->draw(canvas_item, p_pos, p_modulate);
}
-void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) {
+void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -456,16 +457,16 @@ void CanvasItem::draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p
}
ERR_FAIL_COND(p_texture.is_null());
- p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose);
+ p_texture->draw_rect(canvas_item, p_rect, p_tile, p_modulate, p_transpose, p_normal_map);
}
-void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) {
+void CanvasItem::draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
ERR_FAIL();
}
ERR_FAIL_COND(p_texture.is_null());
- p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose);
+ p_texture->draw_rect_region(canvas_item, p_rect, p_src_rect, p_modulate, p_transpose, p_normal_map, p_clip_uv);
}
void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect) {
@@ -478,7 +479,7 @@ void CanvasItem::draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p
p_style_box->draw(canvas_item, p_rect);
}
-void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width) {
+void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, float p_width, const Ref<Texture> &p_normal_map) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -486,8 +487,9 @@ void CanvasItem::draw_primitive(const Vector<Point2> &p_points, const Vector<Col
}
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width);
+ VisualServer::get_singleton()->canvas_item_add_primitive(canvas_item, p_points, p_colors, p_uvs, rid, p_width, rid_normal);
}
void CanvasItem::draw_set_transform(const Point2 &p_offset, float p_rot, const Size2 &p_scale) {
@@ -511,7 +513,7 @@ void CanvasItem::draw_set_transform_matrix(const Transform2D &p_matrix) {
VisualServer::get_singleton()->canvas_item_add_set_transform(canvas_item, p_matrix);
}
-void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) {
+void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -519,11 +521,12 @@ void CanvasItem::draw_polygon(const Vector<Point2> &p_points, const Vector<Color
}
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid);
+ VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, p_colors, p_uvs, rid, rid_normal);
}
-void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture) {
+void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs, Ref<Texture> p_texture, const Ref<Texture> &p_normal_map) {
if (!drawing) {
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
@@ -533,8 +536,9 @@ void CanvasItem::draw_colored_polygon(const Vector<Point2> &p_points, const Colo
Vector<Color> colors;
colors.push_back(p_color);
RID rid = p_texture.is_valid() ? p_texture->get_rid() : RID();
+ RID rid_normal = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
- VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid);
+ VisualServer::get_singleton()->canvas_item_add_polygon(canvas_item, p_points, colors, p_uvs, rid, rid_normal);
}
void CanvasItem::draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate, int p_clip_w) {
@@ -688,11 +692,11 @@ Vector2 CanvasItem::make_canvas_pos_local(const Vector2 &screen_point) const {
return local_matrix.xform(screen_point);
}
-InputEvent CanvasItem::make_input_local(const InputEvent &p_event) const {
+Ref<InputEvent> CanvasItem::make_input_local(const Ref<InputEvent> &p_event) const {
ERR_FAIL_COND_V(!is_inside_tree(), p_event);
- return p_event.xform_by((get_canvas_transform() * get_global_transform()).affine_inverse());
+ return p_event->xformed_by((get_canvas_transform() * get_global_transform()).affine_inverse());
}
Vector2 CanvasItem::get_global_mouse_position() const {
@@ -752,13 +756,13 @@ void CanvasItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_line", "from", "to", "color", "width", "antialiased"), &CanvasItem::draw_line, DEFVAL(1.0), DEFVAL(false));
ClassDB::bind_method(D_METHOD("draw_rect", "rect", "color"), &CanvasItem::draw_rect);
ClassDB::bind_method(D_METHOD("draw_circle", "pos", "radius", "color"), &CanvasItem::draw_circle);
- ClassDB::bind_method(D_METHOD("draw_texture", "texture:Texture", "pos", "modulate"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)));
- ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw_texture", "texture:Texture", "pos", "modulate", "normal_map:Texture"), &CanvasItem::draw_texture, DEFVAL(Color(1, 1, 1, 1)), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_texture_rect", "texture:Texture", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &CanvasItem::draw_texture_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_texture_rect_region", "texture:Texture", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &CanvasItem::draw_texture_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
ClassDB::bind_method(D_METHOD("draw_style_box", "style_box:StyleBox", "rect"), &CanvasItem::draw_style_box);
- ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0));
- ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture:Texture"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()));
- ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture:Texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_primitive", "points", "colors", "uvs", "texture:Texture", "width", "normal_map:Texture"), &CanvasItem::draw_primitive, DEFVAL(Variant()), DEFVAL(1.0), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_polygon", "points", "colors", "uvs", "texture:Texture", "normal_map:Texture"), &CanvasItem::draw_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_colored_polygon", "points", "color", "uvs", "texture:Texture", "normal_map:Texture"), &CanvasItem::draw_colored_polygon, DEFVAL(PoolVector2Array()), DEFVAL(Variant()), DEFVAL(Variant()));
ClassDB::bind_method(D_METHOD("draw_string", "font:Font", "pos", "text", "modulate", "clip_w"), &CanvasItem::draw_string, DEFVAL(Color(1, 1, 1)), DEFVAL(-1));
ClassDB::bind_method(D_METHOD("draw_char", "font:Font", "pos", "char", "next", "modulate"), &CanvasItem::draw_char, DEFVAL(Color(1, 1, 1)));
diff --git a/scene/2d/canvas_item.h b/scene/2d/canvas_item.h
index 72fe5b93da..595dd03057 100644
--- a/scene/2d/canvas_item.h
+++ b/scene/2d/canvas_item.h
@@ -158,13 +158,13 @@ public:
void draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void draw_rect(const Rect2 &p_rect, const Color &p_color);
void draw_circle(const Point2 &p_pos, float p_radius, const Color &p_color);
- void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1));
- void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
- void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
+ void draw_texture(const Ref<Texture> &p_texture, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1, 1), const Ref<Texture> &p_normal_map = Ref<Texture>());
+ void draw_texture_rect(const Ref<Texture> &p_texture, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>());
+ void draw_texture_rect_region(const Ref<Texture> &p_texture, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true);
void draw_style_box(const Ref<StyleBox> &p_style_box, const Rect2 &p_rect);
- void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1);
- void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>());
- void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>());
+ void draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, Ref<Texture> p_texture = Ref<Texture>(), float p_width = 1, const Ref<Texture> &p_normal_map = Ref<Texture>());
+ void draw_polygon(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>());
+ void draw_colored_polygon(const Vector<Point2> &p_points, const Color &p_color, const Vector<Point2> &p_uvs = Vector<Point2>(), Ref<Texture> p_texture = Ref<Texture>(), const Ref<Texture> &p_normal_map = Ref<Texture>());
void draw_string(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_text, const Color &p_modulate = Color(1, 1, 1), int p_clip_w = -1);
float draw_char(const Ref<Font> &p_font, const Point2 &p_pos, const String &p_char, const String &p_next = "", const Color &p_modulate = Color(1, 1, 1));
@@ -209,7 +209,7 @@ public:
void set_use_parent_material(bool p_use_parent_material);
bool get_use_parent_material() const;
- InputEvent make_input_local(const InputEvent &pevent) const;
+ Ref<InputEvent> make_input_local(const Ref<InputEvent> &pevent) const;
Vector2 make_canvas_pos_local(const Vector2 &screen_point) const;
Vector2 get_global_mouse_position() const;
diff --git a/scene/2d/collision_object_2d.cpp b/scene/2d/collision_object_2d.cpp
index afbdfec45e..caf9cf201a 100644
--- a/scene/2d/collision_object_2d.cpp
+++ b/scene/2d/collision_object_2d.cpp
@@ -180,7 +180,7 @@ bool CollisionObject2D::is_pickable() const {
return pickable;
}
-void CollisionObject2D::_input_event(Node *p_viewport, const InputEvent &p_input_event, int p_shape) {
+void CollisionObject2D::_input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape) {
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_viewport, p_input_event, p_shape);
@@ -231,9 +231,9 @@ void CollisionObject2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_pickable", "enabled"), &CollisionObject2D::set_pickable);
ClassDB::bind_method(D_METHOD("is_pickable"), &CollisionObject2D::is_pickable);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "viewport"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::INT, "shape_idx")));
+ BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "viewport"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx")));
- ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "viewport"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::INT, "shape_idx")));
+ ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "viewport"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("mouse_entered"));
ADD_SIGNAL(MethodInfo("mouse_exited"));
diff --git a/scene/2d/collision_object_2d.h b/scene/2d/collision_object_2d.h
index e3dc39feae..4d4611afd1 100644
--- a/scene/2d/collision_object_2d.h
+++ b/scene/2d/collision_object_2d.h
@@ -70,7 +70,7 @@ protected:
void _update_pickable();
friend class Viewport;
- void _input_event(Node *p_viewport, const InputEvent &p_input_event, int p_shape);
+ void _input_event(Node *p_viewport, const Ref<InputEvent> &p_input_event, int p_shape);
void _mouse_enter();
void _mouse_exit();
diff --git a/scene/2d/collision_polygon_2d.cpp b/scene/2d/collision_polygon_2d.cpp
index 39eef89274..6b603c6473 100644
--- a/scene/2d/collision_polygon_2d.cpp
+++ b/scene/2d/collision_polygon_2d.cpp
@@ -233,7 +233,7 @@ void CollisionPolygon2D::set_polygon(const Vector<Point2> &p_polygon) {
aabb = Rect2(-10, -10, 20, 20);
} else {
- aabb.pos -= aabb.size * 0.3;
+ aabb.position -= aabb.size * 0.3;
aabb.size += aabb.size * 0.6;
}
_update_parent();
diff --git a/scene/2d/light_2d.cpp b/scene/2d/light_2d.cpp
index 34413074c1..e8c2122bd1 100644
--- a/scene/2d/light_2d.cpp
+++ b/scene/2d/light_2d.cpp
@@ -336,6 +336,17 @@ String Light2D::get_configuration_warning() const {
return String();
}
+void Light2D::set_shadow_smooth(float p_amount) {
+
+ shadow_smooth = p_amount;
+ VS::get_singleton()->canvas_light_set_shadow_smooth(canvas_light, shadow_smooth);
+}
+
+float Light2D::get_shadow_smooth() const {
+
+ return shadow_smooth;
+}
+
void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &Light2D::set_enabled);
@@ -389,6 +400,9 @@ void Light2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_shadow_buffer_size", "size"), &Light2D::set_shadow_buffer_size);
ClassDB::bind_method(D_METHOD("get_shadow_buffer_size"), &Light2D::get_shadow_buffer_size);
+ ClassDB::bind_method(D_METHOD("set_shadow_smooth", "smooth"), &Light2D::set_shadow_smooth);
+ ClassDB::bind_method(D_METHOD("get_shadow_smooth"), &Light2D::get_shadow_smooth);
+
ClassDB::bind_method(D_METHOD("set_shadow_gradient_length", "multiplier"), &Light2D::set_shadow_gradient_length);
ClassDB::bind_method(D_METHOD("get_shadow_gradient_length"), &Light2D::get_shadow_gradient_length);
@@ -420,6 +434,7 @@ void Light2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_buffer_size", PROPERTY_HINT_RANGE, "32,16384,1"), "set_shadow_buffer_size", "get_shadow_buffer_size");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_gradient_length", PROPERTY_HINT_RANGE, "1,4096,0.1"), "set_shadow_gradient_length", "get_shadow_gradient_length");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter", PROPERTY_HINT_ENUM, "None,PCF3,PCF5,PCF9,PCF13"), "set_shadow_filter", "get_shadow_filter");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "shadow_filter_smooth", PROPERTY_HINT_RANGE, "0,64,0.1"), "set_shadow_smooth", "get_shadow_smooth");
ADD_PROPERTY(PropertyInfo(Variant::INT, "shadow_item_cull_mask", PROPERTY_HINT_LAYERS_2D_RENDER), "set_item_shadow_cull_mask", "get_item_shadow_cull_mask");
BIND_CONSTANT(MODE_ADD);
@@ -449,6 +464,7 @@ Light2D::Light2D() {
energy = 1.0;
shadow_color = Color(0, 0, 0, 0);
shadow_filter = SHADOW_FILTER_NONE;
+ shadow_smooth = 0;
set_notify_transform(true);
}
diff --git a/scene/2d/light_2d.h b/scene/2d/light_2d.h
index 9b09d54dd8..90e55aeda4 100644
--- a/scene/2d/light_2d.h
+++ b/scene/2d/light_2d.h
@@ -69,6 +69,7 @@ private:
int item_mask;
int item_shadow_mask;
int shadow_buffer_size;
+ float shadow_smooth;
float shadow_gradient_length;
Mode mode;
Ref<Texture> texture;
@@ -146,6 +147,9 @@ public:
void set_shadow_color(const Color &p_shadow_color);
Color get_shadow_color() const;
+ void set_shadow_smooth(float p_amount);
+ float get_shadow_smooth() const;
+
virtual Rect2 get_item_rect() const;
String get_configuration_warning() const;
diff --git a/scene/2d/line_2d.cpp b/scene/2d/line_2d.cpp
index c782968ea0..1a57d24342 100644
--- a/scene/2d/line_2d.cpp
+++ b/scene/2d/line_2d.cpp
@@ -99,7 +99,7 @@ Color Line2D::get_default_color() const {
return _default_color;
}
-void Line2D::set_gradient(const Ref<ColorRamp> &gradient) {
+void Line2D::set_gradient(const Ref<Gradient> &gradient) {
// Cleanup previous connection if any
if (_gradient.is_valid()) {
@@ -116,7 +116,7 @@ void Line2D::set_gradient(const Ref<ColorRamp> &gradient) {
update();
}
-Ref<ColorRamp> Line2D::get_gradient() const {
+Ref<Gradient> Line2D::get_gradient() const {
return _gradient;
}
@@ -310,7 +310,7 @@ void Line2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "points"), "set_points", "get_points");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "width"), "set_width", "get_width");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "default_color"), "set_default_color", "get_default_color");
- ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "ColorRamp"), "set_gradient", "get_gradient");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "gradient", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "texture_mode", PROPERTY_HINT_ENUM, "None,Tile"), "set_texture_mode", "get_texture_mode");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "joint_mode", PROPERTY_HINT_ENUM, "Sharp,Bevel,Round"), "set_joint_mode", "get_joint_mode");
diff --git a/scene/2d/line_2d.h b/scene/2d/line_2d.h
index fee1cad942..e8ca5e6e7c 100644
--- a/scene/2d/line_2d.h
+++ b/scene/2d/line_2d.h
@@ -57,8 +57,8 @@ public:
void set_default_color(Color color);
Color get_default_color() const;
- void set_gradient(const Ref<ColorRamp> &gradient);
- Ref<ColorRamp> get_gradient() const;
+ void set_gradient(const Ref<Gradient> &gradient);
+ Ref<Gradient> get_gradient() const;
void set_texture(const Ref<Texture> &texture);
Ref<Texture> get_texture() const;
@@ -97,7 +97,7 @@ private:
LineCapMode _end_cap_mode;
float _width;
Color _default_color;
- Ref<ColorRamp> _gradient;
+ Ref<Gradient> _gradient;
Ref<Texture> _texture;
LineTextureMode _texture_mode;
float _sharp_limit;
diff --git a/scene/2d/line_builder.cpp b/scene/2d/line_builder.cpp
index add476ae0f..3c1410edbb 100644
--- a/scene/2d/line_builder.cpp
+++ b/scene/2d/line_builder.cpp
@@ -83,8 +83,8 @@ static inline Vector2 rotate90(const Vector2 &v) {
static inline Vector2 interpolate(const Rect2 &r, const Vector2 &v) {
return Vector2(
- Math::lerp(r.get_pos().x, r.get_pos().x + r.get_size().x, v.x),
- Math::lerp(r.get_pos().y, r.get_pos().y + r.get_size().y, v.y));
+ Math::lerp(r.position.x, r.position.x + r.get_size().x, v.x),
+ Math::lerp(r.position.y, r.position.y + r.get_size().y, v.y));
}
//----------------------------------------------------------------------------
@@ -337,7 +337,7 @@ void LineBuilder::build() {
} else if (current_joint_mode == LINE_JOINT_ROUND) {
Vector2 vbegin = cbegin - pos1;
Vector2 vend = cend - pos1;
- strip_add_arc(pos1, vend.angle_to(vbegin), orientation);
+ strip_add_arc(pos1, vbegin.angle_to(vend), orientation);
}
if (intersection_result != SEGMENT_INTERSECT)
@@ -498,7 +498,7 @@ void LineBuilder::strip_add_arc(Vector2 center, float angle_delta, Orientation o
if (angle_delta < 0.f)
angle_step = -angle_step;
- float t = vbegin.angle_to(Vector2(1, 0));
+ float t = Vector2(1, 0).angle_to(vbegin);
float end_angle = t + angle_delta;
Vector2 rpos(0, 0);
@@ -525,7 +525,7 @@ void LineBuilder::new_arc(Vector2 center, Vector2 vbegin, float angle_delta, Col
if (angle_delta < 0.f)
angle_step = -angle_step;
- float t = vbegin.angle_to(Vector2(1, 0));
+ float t = Vector2(1, 0).angle_to(vbegin);
float end_angle = t + angle_delta;
Vector2 rpos(0, 0);
float tt_begin = -Math_PI / 2.f;
diff --git a/scene/2d/line_builder.h b/scene/2d/line_builder.h
index eed9cac0aa..0e1a2aaf50 100644
--- a/scene/2d/line_builder.h
+++ b/scene/2d/line_builder.h
@@ -62,7 +62,7 @@ public:
LineCapMode end_cap_mode;
float width;
Color default_color;
- ColorRamp *gradient;
+ Gradient *gradient;
LineTextureMode texture_mode;
float sharp_limit;
int round_precision;
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp
index ec286b1d54..6fe1dd73fe 100644
--- a/scene/2d/node_2d.cpp
+++ b/scene/2d/node_2d.cpp
@@ -76,9 +76,9 @@ void Node2D::edit_set_rect(const Rect2 &p_edit_rect) {
Vector2 zero_offset;
if (r.size.x != 0)
- zero_offset.x = -r.pos.x / r.size.x;
+ zero_offset.x = -r.position.x / r.size.x;
if (r.size.y != 0)
- zero_offset.y = -r.pos.y / r.size.y;
+ zero_offset.y = -r.position.y / r.size.y;
Size2 new_scale(1, 1);
@@ -87,7 +87,7 @@ void Node2D::edit_set_rect(const Rect2 &p_edit_rect) {
if (r.size.y != 0)
new_scale.y = p_edit_rect.size.y / r.size.y;
- Point2 new_pos = p_edit_rect.pos + p_edit_rect.size * zero_offset; //p_edit_rect.pos - r.pos;
+ Point2 new_pos = p_edit_rect.position + p_edit_rect.size * zero_offset; //p_edit_rect.pos - r.pos;
Transform2D postxf;
postxf.set_rotation_and_scale(angle, _scale);
diff --git a/scene/2d/particles_2d.cpp b/scene/2d/particles_2d.cpp
index b91d9b835c..21d64c5d64 100644
--- a/scene/2d/particles_2d.cpp
+++ b/scene/2d/particles_2d.cpp
@@ -505,8 +505,8 @@ void Particles2D::_notification(int p_what) {
Color color;
- if (color_ramp.is_valid()) {
- color = color_ramp->get_color_at_offset(ptime);
+ if (gradient.is_valid()) {
+ color = gradient->get_color_at_offset(ptime);
} else {
color = default_color;
}
@@ -568,8 +568,8 @@ void Particles2D::_notification(int p_what) {
if (total_frames > 1) {
int frame = Math::fast_ftoi(Math::floor(p.frame * total_frames)) % total_frames;
- src_rect.pos.x = size.x * (frame % h_frames);
- src_rect.pos.y = size.y * (frame / h_frames);
+ src_rect.position.x = size.x * (frame % h_frames);
+ src_rect.position.y = size.y * (frame / h_frames);
}
Rect2 dst_rect(Point2(), size);
if (flip_h)
@@ -774,14 +774,14 @@ Color Particles2D::get_color() const {
return default_color;
}
-void Particles2D::set_color_ramp(const Ref<ColorRamp> &p_color_ramp) {
+void Particles2D::set_gradient(const Ref<Gradient> &p_gradient) {
- color_ramp = p_color_ramp;
+ gradient = p_gradient;
}
-Ref<ColorRamp> Particles2D::get_color_ramp() const {
+Ref<Gradient> Particles2D::get_gradient() const {
- return color_ramp;
+ return gradient;
}
void Particles2D::set_emissor_offset(const Point2 &p_offset) {
@@ -809,19 +809,19 @@ void Particles2D::set_color_phases(int p_phases) {
//Create color ramp if we have 2 or more phases.
//Otherwise first phase phase will be assigned to default color.
- if (p_phases > 1 && color_ramp.is_null()) {
- color_ramp = Ref<ColorRamp>(memnew(ColorRamp()));
+ if (p_phases > 1 && gradient.is_null()) {
+ gradient = Ref<Gradient>(memnew(Gradient()));
}
- if (color_ramp.is_valid()) {
- color_ramp->get_points().resize(p_phases);
+ if (gradient.is_valid()) {
+ gradient->get_points().resize(p_phases);
}
}
//Deprecated.
int Particles2D::get_color_phases() const {
- if (color_ramp.is_valid()) {
- return color_ramp->get_points_count();
+ if (gradient.is_valid()) {
+ return gradient->get_points_count();
}
return 0;
}
@@ -830,9 +830,9 @@ int Particles2D::get_color_phases() const {
void Particles2D::set_color_phase_color(int p_phase, const Color &p_color) {
ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES);
- if (color_ramp.is_valid()) {
- if (color_ramp->get_points_count() > p_phase)
- color_ramp->set_color(p_phase, p_color);
+ if (gradient.is_valid()) {
+ if (gradient->get_points_count() > p_phase)
+ gradient->set_color(p_phase, p_color);
} else {
if (p_phase == 0)
default_color = p_color;
@@ -843,8 +843,8 @@ void Particles2D::set_color_phase_color(int p_phase, const Color &p_color) {
Color Particles2D::get_color_phase_color(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, Color());
- if (color_ramp.is_valid()) {
- return color_ramp->get_color(p_phase);
+ if (gradient.is_valid()) {
+ return gradient->get_color(p_phase);
}
return Color(0, 0, 0, 1);
}
@@ -853,8 +853,8 @@ Color Particles2D::get_color_phase_color(int p_phase) const {
void Particles2D::set_color_phase_pos(int p_phase, float p_pos) {
ERR_FAIL_INDEX(p_phase, MAX_COLOR_PHASES);
ERR_FAIL_COND(p_pos < 0.0 || p_pos > 1.0);
- if (color_ramp.is_valid() && color_ramp->get_points_count() > p_phase) {
- return color_ramp->set_offset(p_phase, p_pos);
+ if (gradient.is_valid() && gradient->get_points_count() > p_phase) {
+ return gradient->set_offset(p_phase, p_pos);
}
}
@@ -862,8 +862,8 @@ void Particles2D::set_color_phase_pos(int p_phase, float p_pos) {
float Particles2D::get_color_phase_pos(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase, MAX_COLOR_PHASES, 0);
- if (color_ramp.is_valid()) {
- return color_ramp->get_offset(p_phase);
+ if (gradient.is_valid()) {
+ return gradient->get_offset(p_phase);
}
return 0;
}
@@ -996,8 +996,8 @@ void Particles2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_color", "color"), &Particles2D::set_color);
ClassDB::bind_method(D_METHOD("get_color"), &Particles2D::get_color);
- ClassDB::bind_method(D_METHOD("set_color_ramp:ColorRamp", "color_ramp"), &Particles2D::set_color_ramp);
- ClassDB::bind_method(D_METHOD("get_color_ramp:ColorRamp"), &Particles2D::get_color_ramp);
+ ClassDB::bind_method(D_METHOD("set_gradient:Gradient", "gradient"), &Particles2D::set_gradient);
+ ClassDB::bind_method(D_METHOD("get_gradient:Gradient"), &Particles2D::get_gradient);
ClassDB::bind_method(D_METHOD("set_emissor_offset", "offset"), &Particles2D::set_emissor_offset);
ClassDB::bind_method(D_METHOD("get_emissor_offset"), &Particles2D::get_emissor_offset);
@@ -1078,7 +1078,7 @@ void Particles2D::_bind_methods() {
}
ADD_PROPERTYNO(PropertyInfo(Variant::COLOR, "color/color"), "set_color", "get_color");
- ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "color/color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "ColorRamp"), "set_color_ramp", "get_color_ramp");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "color/color_ramp", PROPERTY_HINT_RESOURCE_TYPE, "Gradient"), "set_gradient", "get_gradient");
ADD_PROPERTYNZ(PropertyInfo(Variant::POOL_VECTOR2_ARRAY, "emission_points", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "set_emission_points", "get_emission_points");
diff --git a/scene/2d/particles_2d.h b/scene/2d/particles_2d.h
index 4b87a26195..856beaa836 100644
--- a/scene/2d/particles_2d.h
+++ b/scene/2d/particles_2d.h
@@ -169,7 +169,7 @@ private:
//If no color ramp is set then default color is used. Created as simple alternative to color_ramp.
Color default_color;
- Ref<ColorRamp> color_ramp;
+ Ref<Gradient> gradient;
void _process_particles(float p_delta);
friend class ParticleAttractor2D;
@@ -241,8 +241,8 @@ public:
void set_color(const Color &p_color);
Color get_color() const;
- void set_color_ramp(const Ref<ColorRamp> &p_texture);
- Ref<ColorRamp> get_color_ramp() const;
+ void set_gradient(const Ref<Gradient> &p_texture);
+ Ref<Gradient> get_gradient() const;
void set_emissor_offset(const Point2 &p_offset);
Point2 get_emissor_offset() const;
diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp
index 626ea10515..68270ed771 100644
--- a/scene/2d/physics_body_2d.cpp
+++ b/scene/2d/physics_body_2d.cpp
@@ -79,7 +79,7 @@ uint32_t PhysicsBody2D::_get_layers() const {
void PhysicsBody2D::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_collision_layer", "mask"), &PhysicsBody2D::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &PhysicsBody2D::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsBody2D::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &PhysicsBody2D::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &PhysicsBody2D::get_collision_mask);
@@ -108,15 +108,15 @@ void PhysicsBody2D::_bind_methods() {
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL, "one_way_collision/max_depth"), "set_one_way_collision_max_depth", "get_one_way_collision_max_depth");
}
-void PhysicsBody2D::set_collision_layer(uint32_t p_mask) {
+void PhysicsBody2D::set_collision_layer(uint32_t p_layer) {
- mask = p_mask;
- Physics2DServer::get_singleton()->body_set_layer_mask(get_rid(), p_mask);
+ collision_layer = p_layer;
+ Physics2DServer::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
}
uint32_t PhysicsBody2D::get_collision_layer() const {
- return mask;
+ return collision_layer;
}
void PhysicsBody2D::set_collision_mask(uint32_t p_mask) {
@@ -146,12 +146,12 @@ bool PhysicsBody2D::get_collision_mask_bit(int p_bit) const {
void PhysicsBody2D::set_collision_layer_bit(int p_bit, bool p_value) {
- uint32_t mask = get_collision_layer();
+ uint32_t collision_layer = get_collision_layer();
if (p_value)
- mask |= 1 << p_bit;
+ collision_layer |= 1 << p_bit;
else
- mask &= ~(1 << p_bit);
- set_collision_layer(mask);
+ collision_layer &= ~(1 << p_bit);
+ set_collision_layer(collision_layer);
}
bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const {
@@ -162,7 +162,7 @@ bool PhysicsBody2D::get_collision_layer_bit(int p_bit) const {
PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode)
: CollisionObject2D(Physics2DServer::get_singleton()->body_create(p_mode), false) {
- mask = 1;
+ collision_layer = 1;
collision_mask = 1;
set_one_way_collision_max_depth(0);
set_pickable(false);
diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h
index f706111e7e..50c9865f18 100644
--- a/scene/2d/physics_body_2d.h
+++ b/scene/2d/physics_body_2d.h
@@ -38,7 +38,7 @@ class PhysicsBody2D : public CollisionObject2D {
GDCLASS(PhysicsBody2D, CollisionObject2D);
- uint32_t mask;
+ uint32_t collision_layer;
uint32_t collision_mask;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
@@ -53,7 +53,7 @@ protected:
static void _bind_methods();
public:
- void set_collision_layer(uint32_t p_mask);
+ void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
void set_collision_mask(uint32_t p_mask);
diff --git a/scene/2d/polygon_2d.cpp b/scene/2d/polygon_2d.cpp
index cb3e67f895..5c1c953a37 100644
--- a/scene/2d/polygon_2d.cpp
+++ b/scene/2d/polygon_2d.cpp
@@ -38,7 +38,7 @@ Rect2 Polygon2D::get_item_rect() const {
for (int i = 0; i < l; i++) {
Vector2 pos = r[i] + offset;
if (i == 0)
- item_rect.pos = pos;
+ item_rect.position = pos;
else
item_rect.expand_to(pos);
}
@@ -95,7 +95,7 @@ void Polygon2D::_notification(int p_what) {
for (int i = 0; i < len; i++) {
if (i == 0)
- bounds.pos = points[i];
+ bounds.position = points[i];
else
bounds.expand_to(points[i]);
if (points[i].y > highest_y) {
@@ -110,10 +110,10 @@ void Polygon2D::_notification(int p_what) {
Vector2 ep[7] = {
Vector2(points[highest_idx].x, points[highest_idx].y + invert_border),
- Vector2(bounds.pos + bounds.size),
- Vector2(bounds.pos + Vector2(bounds.size.x, 0)),
- Vector2(bounds.pos),
- Vector2(bounds.pos + Vector2(0, bounds.size.y)),
+ Vector2(bounds.position + bounds.size),
+ Vector2(bounds.position + Vector2(bounds.size.x, 0)),
+ Vector2(bounds.position),
+ Vector2(bounds.position + Vector2(0, bounds.size.y)),
Vector2(points[highest_idx].x - CMP_EPSILON, points[highest_idx].y + invert_border),
Vector2(points[highest_idx].x - CMP_EPSILON, points[highest_idx].y),
};
diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp
index 792861cbf3..cfb4059714 100644
--- a/scene/2d/ray_cast_2d.cpp
+++ b/scene/2d/ray_cast_2d.cpp
@@ -44,14 +44,14 @@ Vector2 RayCast2D::get_cast_to() const {
return cast_to;
}
-void RayCast2D::set_layer_mask(uint32_t p_mask) {
+void RayCast2D::set_collision_layer(uint32_t p_layer) {
- layer_mask = p_mask;
+ collision_layer = p_layer;
}
-uint32_t RayCast2D::get_layer_mask() const {
+uint32_t RayCast2D::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void RayCast2D::set_type_mask(uint32_t p_mask) {
@@ -157,16 +157,16 @@ void RayCast2D::_notification(int p_what) {
break;
Transform2D xf;
xf.rotate(cast_to.angle());
- xf.translate(Vector2(0, cast_to.length()));
+ xf.translate(Vector2(cast_to.length(), 0));
//Vector2 tip = Vector2(0,s->get_length());
Color dcol = get_tree()->get_debug_collisions_color(); //0.9,0.2,0.2,0.4);
draw_line(Vector2(), cast_to, dcol, 3);
Vector<Vector2> pts;
float tsize = 4;
- pts.push_back(xf.xform(Vector2(0, tsize)));
- pts.push_back(xf.xform(Vector2(0.707 * tsize, 0)));
- pts.push_back(xf.xform(Vector2(-0.707 * tsize, 0)));
+ pts.push_back(xf.xform(Vector2(tsize, 0)));
+ pts.push_back(xf.xform(Vector2(0, 0.707 * tsize)));
+ pts.push_back(xf.xform(Vector2(0, -0.707 * tsize)));
Vector<Color> cols;
for (int i = 0; i < 3; i++)
cols.push_back(dcol);
@@ -201,7 +201,7 @@ void RayCast2D::_update_raycast_state() {
Physics2DDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) {
+ if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_layer, type_mask)) {
collided = true;
against = rr.collider_id;
@@ -274,8 +274,8 @@ void RayCast2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast2D::clear_exceptions);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast2D::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast2D::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &RayCast2D::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &RayCast2D::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast2D::set_type_mask);
ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast2D::get_type_mask);
@@ -286,7 +286,7 @@ void RayCast2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "exclude_parent"), "set_exclude_parent_body", "get_exclude_parent_body");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "cast_to"), "set_cast_to", "get_cast_to");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_layer_mask", "get_layer_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask");
}
@@ -296,7 +296,7 @@ RayCast2D::RayCast2D() {
against = 0;
collided = false;
against_shape = 0;
- layer_mask = 1;
+ collision_layer = 1;
type_mask = Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
cast_to = Vector2(0, 50);
exclude_parent_body = true;
diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h
index cfecfa2585..244f4302ad 100644
--- a/scene/2d/ray_cast_2d.h
+++ b/scene/2d/ray_cast_2d.h
@@ -43,7 +43,7 @@ class RayCast2D : public Node2D {
Vector2 collision_point;
Vector2 collision_normal;
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t type_mask;
bool exclude_parent_body;
@@ -61,8 +61,8 @@ public:
void set_cast_to(const Vector2 &p_point);
Vector2 get_cast_to() const;
- void set_layer_mask(uint32_t p_mask);
- uint32_t get_layer_mask() const;
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
void set_type_mask(uint32_t p_mask);
uint32_t get_type_mask() const;
diff --git a/scene/2d/screen_button.cpp b/scene/2d/screen_button.cpp
index 7712108488..37139b2b93 100644
--- a/scene/2d/screen_button.cpp
+++ b/scene/2d/screen_button.cpp
@@ -148,11 +148,6 @@ void TouchScreenButton::_notification(int p_what) {
if (!get_tree()->is_editor_hint())
set_process_input(is_visible_in_tree());
- if (action.operator String() != "" && InputMap::get_singleton()->has_action(action)) {
- action_id = InputMap::get_singleton()->get_action_id(action);
- } else {
- action_id = -1;
- }
} break;
case NOTIFICATION_EXIT_TREE: {
if (is_pressed())
@@ -184,11 +179,6 @@ bool TouchScreenButton::is_pressed() const {
void TouchScreenButton::set_action(const String &p_action) {
action = p_action;
- if (action.operator String() != "" && InputMap::get_singleton()->has_action(action)) {
- action_id = InputMap::get_singleton()->get_action_id(action);
- } else {
- action_id = -1;
- }
}
String TouchScreenButton::get_action() const {
@@ -196,44 +186,37 @@ String TouchScreenButton::get_action() const {
return action;
}
-void TouchScreenButton::_input(const InputEvent &p_event) {
+void TouchScreenButton::_input(const Ref<InputEvent> &p_event) {
if (!get_tree())
return;
- if (p_event.device != 0)
+ if (p_event->get_device() != 0)
return;
- if (passby_press) {
-
- if (p_event.type == InputEvent::SCREEN_TOUCH && !p_event.screen_touch.pressed && finger_pressed == p_event.screen_touch.index) {
+ ERR_FAIL_COND(!is_visible_in_tree());
- _release();
- }
+ const InputEventScreenTouch *st = p_event->cast_to<InputEventScreenTouch>();
- if ((p_event.type == InputEvent::SCREEN_TOUCH && p_event.screen_touch.pressed) || p_event.type == InputEvent::SCREEN_DRAG) {
+ if (passby_press) {
- if (finger_pressed == -1 || p_event.screen_touch.index == finger_pressed) {
+ const InputEventScreenDrag *sd = p_event->cast_to<InputEventScreenDrag>();
- Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(Point2(p_event.screen_touch.x, p_event.screen_touch.y));
+ if (st && !st->is_pressed() && finger_pressed == st->get_index()) {
- bool touched = false;
- if (bitmask.is_valid()) {
+ _release();
+ }
- if (Rect2(Point2(), bitmask->get_size()).has_point(coord)) {
+ if ((st && st->is_pressed()) || sd) {
- if (bitmask->get_bit(coord))
- touched = true;
- }
- } else {
+ int index = st ? st->get_index() : sd->get_index();
+ Point2 coord = st ? st->get_position() : sd->get_position();
- if (texture.is_valid())
- touched = Rect2(Point2(), texture->get_size()).has_point(coord);
- }
+ if (finger_pressed == -1 || index == finger_pressed) {
- if (touched) {
+ if (_is_point_inside(coord)) {
if (finger_pressed == -1) {
- _press(p_event.screen_touch.index);
+ _press(index);
}
} else {
if (finger_pressed != -1) {
@@ -245,69 +228,71 @@ void TouchScreenButton::_input(const InputEvent &p_event) {
} else {
- if (p_event.type == InputEvent::SCREEN_TOUCH) {
-
- if (p_event.screen_touch.pressed) {
+ if (st) {
- if (!is_visible_in_tree())
- return;
+ if (st->is_pressed()) {
const bool can_press = finger_pressed == -1;
if (!can_press)
return; //already fingering
- Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(Point2(p_event.screen_touch.x, p_event.screen_touch.y));
- Rect2 item_rect = get_item_rect();
+ if (_is_point_inside(st->get_position())) {
+ _press(st->get_index());
+ }
+ } else {
+ if (st->get_index() == finger_pressed) {
+ _release();
+ }
+ }
+ }
+ }
+}
+
+bool TouchScreenButton::_is_point_inside(const Point2 &p_point) {
- bool touched = false;
- bool check_rect = true;
- if (shape.is_valid()) {
+ Point2 coord = (get_global_transform_with_canvas()).affine_inverse().xform(p_point);
+ Rect2 item_rect = get_item_rect();
- check_rect = false;
- Transform2D xform = shape_centered ? Transform2D().translated(get_item_rect().size * 0.5f) : Transform2D();
- touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
- }
+ bool touched = false;
+ bool check_rect = true;
- if (bitmask.is_valid()) {
+ if (shape.is_valid()) {
- check_rect = false;
- if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) {
+ check_rect = false;
+ Transform2D xform = shape_centered ? Transform2D().translated(item_rect.size * 0.5f) : Transform2D();
+ touched = shape->collide(xform, unit_rect, Transform2D(0, coord + Vector2(0.5, 0.5)));
+ }
- if (bitmask->get_bit(coord))
- touched = true;
- }
- }
+ if (bitmask.is_valid()) {
- if (!touched && check_rect) {
- if (!texture.is_null())
- touched = item_rect.has_point(coord);
- }
+ check_rect = false;
+ if (!touched && Rect2(Point2(), bitmask->get_size()).has_point(coord)) {
- if (touched) {
- _press(p_event.screen_touch.index);
- }
- } else {
- if (p_event.screen_touch.index == finger_pressed) {
- _release();
- }
- }
+ if (bitmask->get_bit(coord))
+ touched = true;
}
}
+
+ if (!touched && check_rect) {
+ if (texture.is_valid())
+ touched = item_rect.has_point(coord);
+ }
+
+ return touched;
}
void TouchScreenButton::_press(int p_finger_pressed) {
finger_pressed = p_finger_pressed;
- if (action_id != -1) {
+ if (action != StringName()) {
Input::get_singleton()->action_press(action);
- InputEvent ie;
- ie.type = InputEvent::ACTION;
- ie.ID = 0;
- ie.action.action = action_id;
- ie.action.pressed = true;
- get_tree()->input_event(ie);
+ Ref<InputEventAction> iea;
+ iea.instance();
+ iea->set_action(action);
+ iea->set_pressed(true);
+ get_tree()->input_event(iea);
}
emit_signal("pressed");
@@ -318,16 +303,16 @@ void TouchScreenButton::_release(bool p_exiting_tree) {
finger_pressed = -1;
- if (action_id != -1) {
+ if (action != StringName()) {
Input::get_singleton()->action_release(action);
if (!p_exiting_tree) {
- InputEvent ie;
- ie.type = InputEvent::ACTION;
- ie.ID = 0;
- ie.action.action = action_id;
- ie.action.pressed = false;
- get_tree()->input_event(ie);
+
+ Ref<InputEventAction> iea;
+ iea.instance();
+ iea->set_action(action);
+ iea->set_pressed(false);
+ get_tree()->input_event(iea);
}
}
@@ -419,7 +404,6 @@ void TouchScreenButton::_bind_methods() {
TouchScreenButton::TouchScreenButton() {
finger_pressed = -1;
- action_id = -1;
passby_press = false;
visibility = VISIBILITY_ALWAYS;
shape_centered = true;
diff --git a/scene/2d/screen_button.h b/scene/2d/screen_button.h
index 0cfaf681dd..8923da2ae4 100644
--- a/scene/2d/screen_button.h
+++ b/scene/2d/screen_button.h
@@ -58,11 +58,12 @@ private:
StringName action;
bool passby_press;
int finger_pressed;
- int action_id;
VisibilityMode visibility;
- void _input(const InputEvent &p_Event);
+ void _input(const Ref<InputEvent> &p_Event);
+
+ bool _is_point_inside(const Point2 &p_point);
void _press(int p_finger_pressed);
void _release(bool p_exiting_tree = false);
diff --git a/scene/2d/sprite.cpp b/scene/2d/sprite.cpp
index 1735bf3b91..ff574a6bd6 100644
--- a/scene/2d/sprite.cpp
+++ b/scene/2d/sprite.cpp
@@ -65,18 +65,20 @@ void Sprite::_notification(int p_what) {
Size2 s;
Rect2 src_rect;
+ bool filter_clip = false;
if (region) {
s = region_rect.size;
src_rect = region_rect;
+ filter_clip = region_filter_clip;
} else {
s = Size2(texture->get_size());
s = s / Size2(hframes, vframes);
src_rect.size = s;
- src_rect.pos.x += float(frame % hframes) * s.x;
- src_rect.pos.y += float(frame / hframes) * s.y;
+ src_rect.position.x += float(frame % hframes) * s.x;
+ src_rect.position.y += float(frame / hframes) * s.y;
}
Point2 ofs = offset;
@@ -93,7 +95,7 @@ void Sprite::_notification(int p_what) {
if (vflip)
dst_rect.size.y = -dst_rect.size.y;
- texture->draw_rect_region(ci, dst_rect, src_rect);
+ texture->draw_rect_region(ci, dst_rect, src_rect, Color(1, 1, 1), false, normal_map, filter_clip);
} break;
}
@@ -109,17 +111,30 @@ void Sprite::set_texture(const Ref<Texture> &p_texture) {
}
#endif
texture = p_texture;
+ /* this should no longer be needed in 3.0
#ifdef DEBUG_ENABLED
if (texture.is_valid()) {
texture->set_flags(texture->get_flags()); //remove repeat from texture, it looks bad in sprites
texture->connect(CoreStringNames::get_singleton()->changed, this, SceneStringNames::get_singleton()->update);
}
#endif
+*/
update();
emit_signal("texture_changed");
item_rect_changed();
}
+void Sprite::set_normal_map(const Ref<Texture> &p_texture) {
+
+ normal_map = p_texture;
+ update();
+}
+
+Ref<Texture> Sprite::get_normal_map() const {
+
+ return normal_map;
+}
+
Ref<Texture> Sprite::get_texture() const {
return texture;
@@ -201,6 +216,15 @@ Rect2 Sprite::get_region_rect() const {
return region_rect;
}
+void Sprite::set_region_filter_clip(bool p_enable) {
+ region_filter_clip = p_enable;
+ update();
+}
+
+bool Sprite::is_region_filter_clip_enabled() const {
+ return region_filter_clip;
+}
+
void Sprite::set_frame(int p_frame) {
ERR_FAIL_INDEX(p_frame, vframes * hframes);
@@ -289,6 +313,9 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &Sprite::set_texture);
ClassDB::bind_method(D_METHOD("get_texture:Texture"), &Sprite::get_texture);
+ ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map:Texture"), &Sprite::set_normal_map);
+ ClassDB::bind_method(D_METHOD("get_normal_map:Texture"), &Sprite::get_normal_map);
+
ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Sprite::set_centered);
ClassDB::bind_method(D_METHOD("is_centered"), &Sprite::is_centered);
@@ -307,6 +334,9 @@ void Sprite::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_region_rect", "rect"), &Sprite::set_region_rect);
ClassDB::bind_method(D_METHOD("get_region_rect"), &Sprite::get_region_rect);
+ ClassDB::bind_method(D_METHOD("set_region_filter_clip", "enabled"), &Sprite::set_region_filter_clip);
+ ClassDB::bind_method(D_METHOD("is_region_filter_clip_enabled"), &Sprite::is_region_filter_clip_enabled);
+
ClassDB::bind_method(D_METHOD("set_frame", "frame"), &Sprite::set_frame);
ClassDB::bind_method(D_METHOD("get_frame"), &Sprite::get_frame);
@@ -320,6 +350,7 @@ void Sprite::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
ADD_PROPERTYNO(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "flip_h"), "set_flip_h", "is_flipped_h");
@@ -327,8 +358,11 @@ void Sprite::_bind_methods() {
ADD_PROPERTYNO(PropertyInfo(Variant::INT, "vframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_vframes", "get_vframes");
ADD_PROPERTYNO(PropertyInfo(Variant::INT, "hframes", PROPERTY_HINT_RANGE, "1,16384,1"), "set_hframes", "get_hframes");
ADD_PROPERTYNZ(PropertyInfo(Variant::INT, "frame", PROPERTY_HINT_SPRITE_FRAME), "set_frame", "get_frame");
- ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region"), "set_region", "is_region");
+
+ ADD_GROUP("Region", "region_");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_enabled"), "set_region", "is_region");
ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
+ ADD_PROPERTYNZ(PropertyInfo(Variant::BOOL, "region_filter_clip"), "set_region_filter_clip", "is_region_filter_clip_enabled");
}
Sprite::Sprite() {
@@ -337,6 +371,7 @@ Sprite::Sprite() {
hflip = false;
vflip = false;
region = false;
+ region_filter_clip = false;
frame = 0;
diff --git a/scene/2d/sprite.h b/scene/2d/sprite.h
index 86ef335d42..d3f9a5f032 100644
--- a/scene/2d/sprite.h
+++ b/scene/2d/sprite.h
@@ -38,6 +38,7 @@ class Sprite : public Node2D {
GDCLASS(Sprite, Node2D);
Ref<Texture> texture;
+ Ref<Texture> normal_map;
bool centered;
Point2 offset;
@@ -46,6 +47,7 @@ class Sprite : public Node2D {
bool vflip;
bool region;
Rect2 region_rect;
+ bool region_filter_clip;
int frame;
@@ -67,6 +69,9 @@ public:
void set_texture(const Ref<Texture> &p_texture);
Ref<Texture> get_texture() const;
+ void set_normal_map(const Ref<Texture> &p_texture);
+ Ref<Texture> get_normal_map() const;
+
void set_centered(bool p_center);
bool is_centered() const;
@@ -82,6 +87,9 @@ public:
void set_region(bool p_region);
bool is_region() const;
+ void set_region_filter_clip(bool p_enable);
+ bool is_region_filter_clip_enabled() const;
+
void set_region_rect(const Rect2 &p_region_rect);
Rect2 get_region_rect() const;
diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp
index 080276eb25..4f892a31fc 100644
--- a/scene/2d/tile_map.cpp
+++ b/scene/2d/tile_map.cpp
@@ -370,14 +370,14 @@ void TileMap::_update_dirty_quadrants() {
s = tex->get_size();
else {
s = r.size;
- r.pos.x += fp_adjust;
- r.pos.y += fp_adjust;
+ r.position.x += fp_adjust;
+ r.position.y += fp_adjust;
r.size.x -= fp_adjust * 2.0;
r.size.y -= fp_adjust * 2.0;
}
Rect2 rect;
- rect.pos = offset.floor();
+ rect.position = offset.floor();
rect.size = s;
if (rect.size.y > rect.size.x) {
@@ -406,39 +406,39 @@ void TileMap::_update_dirty_quadrants() {
Vector2 center_ofs;
if (tile_origin == TILE_ORIGIN_TOP_LEFT) {
- rect.pos += tile_ofs;
+ rect.position += tile_ofs;
} else if (tile_origin == TILE_ORIGIN_BOTTOM_LEFT) {
- rect.pos += tile_ofs;
+ rect.position += tile_ofs;
if (c.transpose) {
if (c.flip_h)
- rect.pos.x -= cell_size.x;
+ rect.position.x -= cell_size.x;
else
- rect.pos.x += cell_size.x;
+ rect.position.x += cell_size.x;
} else {
if (c.flip_v)
- rect.pos.y -= cell_size.y;
+ rect.position.y -= cell_size.y;
else
- rect.pos.y += cell_size.y;
+ rect.position.y += cell_size.y;
}
} else if (tile_origin == TILE_ORIGIN_CENTER) {
- rect.pos += tcenter;
+ rect.position += tcenter;
Vector2 center = (s / 2) - tile_ofs;
center_ofs = tcenter - (s / 2);
if (c.flip_h)
- rect.pos.x -= s.x - center.x;
+ rect.position.x -= s.x - center.x;
else
- rect.pos.x -= center.x;
+ rect.position.x -= center.x;
if (c.flip_v)
- rect.pos.y -= s.y - center.y;
+ rect.position.y -= s.y - center.y;
else
- rect.pos.y -= center.y;
+ rect.position.y -= center.y;
}
Color modulate = tile_set->tile_get_modulate(c.id);
@@ -549,7 +549,7 @@ void TileMap::_recompute_rect_cache() {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Rect2 r;
- r.pos = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size());
+ r.position = _map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size());
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size()));
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size() + _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
r.expand_to(_map_to_world(E->key().x * _get_quadrant_size(), E->key().y * _get_quadrant_size() + _get_quadrant_size()));
@@ -587,7 +587,7 @@ Map<TileMap::PosKey, TileMap::Quadrant>::Element *TileMap::_create_quadrant(cons
//q.canvas_item = VisualServer::get_singleton()->canvas_item_create();
q.body = Physics2DServer::get_singleton()->body_create(use_kinematic ? Physics2DServer::BODY_MODE_KINEMATIC : Physics2DServer::BODY_MODE_STATIC);
Physics2DServer::get_singleton()->body_attach_object_instance_ID(q.body, get_instance_ID());
- Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer);
+ Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer);
Physics2DServer::get_singleton()->body_set_collision_mask(q.body, collision_mask);
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_FRICTION, friction);
Physics2DServer::get_singleton()->body_set_param(q.body, Physics2DServer::BODY_PARAM_BOUNCE, bounce);
@@ -863,7 +863,7 @@ void TileMap::set_collision_layer(uint32_t p_layer) {
for (Map<PosKey, Quadrant>::Element *E = quadrant_map.front(); E; E = E->next()) {
Quadrant &q = E->get();
- Physics2DServer::get_singleton()->body_set_layer_mask(q.body, collision_layer);
+ Physics2DServer::get_singleton()->body_set_collision_layer(q.body, collision_layer);
}
}
@@ -1286,7 +1286,7 @@ void TileMap::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "collision_use_kinematic", PROPERTY_HINT_NONE, ""), "set_collision_use_kinematic", "get_collision_use_kinematic");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_friction", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_friction", "get_collision_friction");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "collision_bounce", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_collision_bounce", "get_collision_bounce");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_2D_PHYSICS), "set_collision_mask", "get_collision_mask");
ADD_GROUP("Occluder", "occluder_");
diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp
index 8dae078e5b..39a4e926b2 100644
--- a/scene/3d/area.cpp
+++ b/scene/3d/area.cpp
@@ -489,15 +489,15 @@ uint32_t Area::get_collision_mask() const {
return collision_mask;
}
-void Area::set_layer_mask(uint32_t p_mask) {
+void Area::set_collision_layer(uint32_t p_layer) {
- layer_mask = p_mask;
- PhysicsServer::get_singleton()->area_set_layer_mask(get_rid(), p_mask);
+ collision_layer = p_layer;
+ PhysicsServer::get_singleton()->area_set_collision_layer(get_rid(), p_layer);
}
-uint32_t Area::get_layer_mask() const {
+uint32_t Area::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void Area::set_collision_mask_bit(int p_bit, bool p_value) {
@@ -515,19 +515,19 @@ bool Area::get_collision_mask_bit(int p_bit) const {
return get_collision_mask() & (1 << p_bit);
}
-void Area::set_layer_mask_bit(int p_bit, bool p_value) {
+void Area::set_collision_layer_bit(int p_bit, bool p_value) {
- uint32_t mask = get_layer_mask();
+ uint32_t layer = get_collision_layer();
if (p_value)
- mask |= 1 << p_bit;
+ layer |= 1 << p_bit;
else
- mask &= ~(1 << p_bit);
- set_layer_mask(mask);
+ layer &= ~(1 << p_bit);
+ set_collision_layer(layer);
}
-bool Area::get_layer_mask_bit(int p_bit) const {
+bool Area::get_collision_layer_bit(int p_bit) const {
- return get_layer_mask() & (1 << p_bit);
+ return get_collision_layer() & (1 << p_bit);
}
void Area::_bind_methods() {
@@ -565,14 +565,14 @@ void Area::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_collision_mask", "collision_mask"), &Area::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &Area::get_collision_mask);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Area::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &Area::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Area::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &Area::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_mask_bit", "bit", "value"), &Area::set_collision_mask_bit);
ClassDB::bind_method(D_METHOD("get_collision_mask_bit", "bit"), &Area::get_collision_mask_bit);
- ClassDB::bind_method(D_METHOD("set_layer_mask_bit", "bit", "value"), &Area::set_layer_mask_bit);
- ClassDB::bind_method(D_METHOD("get_layer_mask_bit", "bit"), &Area::get_layer_mask_bit);
+ ClassDB::bind_method(D_METHOD("set_collision_layer_bit", "bit", "value"), &Area::set_collision_layer_bit);
+ ClassDB::bind_method(D_METHOD("get_collision_layer_bit", "bit"), &Area::get_collision_layer_bit);
ClassDB::bind_method(D_METHOD("set_monitorable", "enable"), &Area::set_monitorable);
ClassDB::bind_method(D_METHOD("is_monitorable"), &Area::is_monitorable);
@@ -610,7 +610,7 @@ void Area::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitoring"), "set_monitoring", "is_monitoring");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "monitorable"), "set_monitorable", "is_monitorable");
ADD_GROUP("Collision", "collision_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layers", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_mask", "get_collision_mask");
}
@@ -628,7 +628,7 @@ Area::Area()
priority = 0;
monitoring = false;
collision_mask = 1;
- layer_mask = 1;
+ collision_layer = 1;
set_ray_pickable(false);
set_monitoring(true);
set_monitorable(true);
diff --git a/scene/3d/area.h b/scene/3d/area.h
index 64bbae9236..279a52ee69 100644
--- a/scene/3d/area.h
+++ b/scene/3d/area.h
@@ -55,7 +55,7 @@ private:
real_t angular_damp;
real_t linear_damp;
uint32_t collision_mask;
- uint32_t layer_mask;
+ uint32_t collision_layer;
int priority;
bool monitoring;
bool monitorable;
@@ -164,14 +164,14 @@ public:
void set_collision_mask(uint32_t p_mask);
uint32_t get_collision_mask() const;
- void set_layer_mask(uint32_t p_mask);
- uint32_t get_layer_mask() const;
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
void set_collision_mask_bit(int p_bit, bool p_value);
bool get_collision_mask_bit(int p_bit) const;
- void set_layer_mask_bit(int p_bit, bool p_value);
- bool get_layer_mask_bit(int p_bit) const;
+ void set_collision_layer_bit(int p_bit, bool p_value);
+ bool get_collision_layer_bit(int p_bit) const;
Array get_overlapping_bodies() const;
Array get_overlapping_areas() const; //function for script
diff --git a/scene/3d/baked_light_instance.cpp b/scene/3d/baked_light_instance.cpp
deleted file mode 100644
index ffa7597113..0000000000
--- a/scene/3d/baked_light_instance.cpp
+++ /dev/null
@@ -1,1754 +0,0 @@
-/*************************************************************************/
-/* baked_light_instance.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 "baked_light_instance.h"
-#include "light.h"
-#include "math.h"
-#include "mesh_instance.h"
-#include "scene/scene_string_names.h"
-
-#define FINDMINMAX(x0, x1, x2, min, max) \
- min = max = x0; \
- if (x1 < min) min = x1; \
- if (x1 > max) max = x1; \
- if (x2 < min) min = x2; \
- if (x2 > max) max = x2;
-
-static bool planeBoxOverlap(Vector3 normal, float d, Vector3 maxbox) {
- int q;
- Vector3 vmin, vmax;
- for (q = 0; q <= 2; q++) {
- if (normal[q] > 0.0f) {
- vmin[q] = -maxbox[q];
- vmax[q] = maxbox[q];
- } else {
- vmin[q] = maxbox[q];
- vmax[q] = -maxbox[q];
- }
- }
- if (normal.dot(vmin) + d > 0.0f) return false;
- if (normal.dot(vmax) + d >= 0.0f) return true;
-
- return false;
-}
-
-/*======================== X-tests ========================*/
-#define AXISTEST_X01(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p2 = a * v2.y - b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_X2(a, b, fa, fb) \
- p0 = a * v0.y - b * v0.z; \
- p1 = a * v1.y - b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.y + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Y-tests ========================*/
-#define AXISTEST_Y02(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p2 = -a * v2.x + b * v2.z; \
- if (p0 < p2) { \
- min = p0; \
- max = p2; \
- } else { \
- min = p2; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Y1(a, b, fa, fb) \
- p0 = -a * v0.x + b * v0.z; \
- p1 = -a * v1.x + b * v1.z; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.z; \
- if (min > rad || max < -rad) return false;
-
-/*======================== Z-tests ========================*/
-
-#define AXISTEST_Z12(a, b, fa, fb) \
- p1 = a * v1.x - b * v1.y; \
- p2 = a * v2.x - b * v2.y; \
- if (p2 < p1) { \
- min = p2; \
- max = p1; \
- } else { \
- min = p1; \
- max = p2; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-#define AXISTEST_Z0(a, b, fa, fb) \
- p0 = a * v0.x - b * v0.y; \
- p1 = a * v1.x - b * v1.y; \
- if (p0 < p1) { \
- min = p0; \
- max = p1; \
- } else { \
- min = p1; \
- max = p0; \
- } \
- rad = fa * boxhalfsize.x + fb * boxhalfsize.y; \
- if (min > rad || max < -rad) return false;
-
-static bool fast_tri_box_overlap(const Vector3 &boxcenter, const Vector3 boxhalfsize, const Vector3 *triverts) {
-
- /* use separating axis theorem to test overlap between triangle and box */
- /* need to test for overlap in these directions: */
- /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */
- /* we do not even need to test these) */
- /* 2) normal of the triangle */
- /* 3) crossproduct(edge from tri, {x,y,z}-directin) */
- /* this gives 3x3=9 more tests */
- Vector3 v0, v1, v2;
- float min, max, d, p0, p1, p2, rad, fex, fey, fez;
- Vector3 normal, e0, e1, e2;
-
- /* This is the fastest branch on Sun */
- /* move everything so that the boxcenter is in (0,0,0) */
-
- v0 = triverts[0] - boxcenter;
- v1 = triverts[1] - boxcenter;
- v2 = triverts[2] - boxcenter;
-
- /* compute triangle edges */
- e0 = v1 - v0; /* tri edge 0 */
- e1 = v2 - v1; /* tri edge 1 */
- e2 = v0 - v2; /* tri edge 2 */
-
- /* Bullet 3: */
- /* test the 9 tests first (this was faster) */
- fex = Math::abs(e0.x);
- fey = Math::abs(e0.y);
- fez = Math::abs(e0.z);
- AXISTEST_X01(e0.z, e0.y, fez, fey);
- AXISTEST_Y02(e0.z, e0.x, fez, fex);
- AXISTEST_Z12(e0.y, e0.x, fey, fex);
-
- fex = Math::abs(e1.x);
- fey = Math::abs(e1.y);
- fez = Math::abs(e1.z);
- AXISTEST_X01(e1.z, e1.y, fez, fey);
- AXISTEST_Y02(e1.z, e1.x, fez, fex);
- AXISTEST_Z0(e1.y, e1.x, fey, fex);
-
- fex = Math::abs(e2.x);
- fey = Math::abs(e2.y);
- fez = Math::abs(e2.z);
- AXISTEST_X2(e2.z, e2.y, fez, fey);
- AXISTEST_Y1(e2.z, e2.x, fez, fex);
- AXISTEST_Z12(e2.y, e2.x, fey, fex);
-
- /* Bullet 1: */
- /* first test overlap in the {x,y,z}-directions */
- /* find min, max of the triangle each direction, and test for overlap in */
- /* that direction -- this is equivalent to testing a minimal AABB around */
- /* the triangle against the AABB */
-
- /* test in X-direction */
- FINDMINMAX(v0.x, v1.x, v2.x, min, max);
- if (min > boxhalfsize.x || max < -boxhalfsize.x) return false;
-
- /* test in Y-direction */
- FINDMINMAX(v0.y, v1.y, v2.y, min, max);
- if (min > boxhalfsize.y || max < -boxhalfsize.y) return false;
-
- /* test in Z-direction */
- FINDMINMAX(v0.z, v1.z, v2.z, min, max);
- if (min > boxhalfsize.z || max < -boxhalfsize.z) return false;
-
- /* Bullet 2: */
- /* test if the box intersects the plane of the triangle */
- /* compute plane equation of triangle: normal*x+d=0 */
- normal = e0.cross(e1);
- d = -normal.dot(v0); /* plane eq: normal.x+d=0 */
- if (!planeBoxOverlap(normal, d, boxhalfsize)) return false;
-
- return true; /* box and triangle overlaps */
-}
-
-Vector<Color> BakedLight::_get_bake_texture(Image &p_image, const Color &p_color) {
-
- Vector<Color> ret;
-
- if (p_image.empty()) {
-
- ret.resize(bake_texture_size * bake_texture_size);
- for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
- ret[i] = p_color;
- }
-
- return ret;
- }
-
- p_image.convert(Image::FORMAT_RGBA8);
- p_image.resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
-
- PoolVector<uint8_t>::Read r = p_image.get_data().read();
- ret.resize(bake_texture_size * bake_texture_size);
-
- for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
- Color c;
- c.r = r[i * 4 + 0] / 255.0;
- c.g = r[i * 4 + 1] / 255.0;
- c.b = r[i * 4 + 2] / 255.0;
- c.a = r[i * 4 + 3] / 255.0;
- ret[i] = c;
- }
-
- return ret;
-}
-
-BakedLight::MaterialCache BakedLight::_get_material_cache(Ref<Material> p_material) {
-
- //this way of obtaining materials is inaccurate and also does not support some compressed formats very well
- Ref<SpatialMaterial> mat = p_material;
-
- Ref<Material> material = mat; //hack for now
-
- if (material_cache.has(material)) {
- return material_cache[material];
- }
-
- MaterialCache mc;
-
- if (mat.is_valid()) {
-
- Ref<ImageTexture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
-
- Image img_albedo;
- if (albedo_tex.is_valid()) {
-
- img_albedo = albedo_tex->get_data();
- }
-
- mc.albedo = _get_bake_texture(img_albedo, mat->get_albedo());
-
- Ref<ImageTexture> emission_tex = mat->get_texture(SpatialMaterial::TEXTURE_EMISSION);
-
- Color emission_col = mat->get_emission();
- emission_col.r *= mat->get_emission_energy();
- emission_col.g *= mat->get_emission_energy();
- emission_col.b *= mat->get_emission_energy();
-
- Image img_emission;
-
- if (emission_tex.is_valid()) {
-
- img_emission = emission_tex->get_data();
- }
-
- mc.emission = _get_bake_texture(img_emission, emission_col);
-
- } else {
- Image empty;
-
- mc.albedo = _get_bake_texture(empty, Color(0.7, 0.7, 0.7));
- mc.emission = _get_bake_texture(empty, Color(0, 0, 0));
- }
-
- material_cache[p_material] = mc;
- return mc;
-}
-
-static _FORCE_INLINE_ Vector2 get_uv(const Vector3 &p_pos, const Vector3 *p_vtx, const Vector2 *p_uv) {
-
- if (p_pos.distance_squared_to(p_vtx[0]) < CMP_EPSILON2)
- return p_uv[0];
- if (p_pos.distance_squared_to(p_vtx[1]) < CMP_EPSILON2)
- return p_uv[1];
- if (p_pos.distance_squared_to(p_vtx[2]) < CMP_EPSILON2)
- return p_uv[2];
-
- Vector3 v0 = p_vtx[1] - p_vtx[0];
- Vector3 v1 = p_vtx[2] - p_vtx[0];
- Vector3 v2 = p_pos - p_vtx[0];
-
- float d00 = v0.dot(v0);
- float d01 = v0.dot(v1);
- float d11 = v1.dot(v1);
- float d20 = v2.dot(v0);
- float d21 = v2.dot(v1);
- float denom = (d00 * d11 - d01 * d01);
- if (denom == 0)
- return p_uv[0];
- float v = (d11 * d20 - d01 * d21) / denom;
- float w = (d00 * d21 - d01 * d20) / denom;
- float u = 1.0f - v - w;
-
- return p_uv[0] * u + p_uv[1] * v + p_uv[2] * w;
-}
-
-void BakedLight::_plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2 *p_uv, const MaterialCache &p_material, const Rect3 &p_aabb) {
-
- if (p_level == cell_subdiv - 1) {
- //plot the face by guessing it's albedo and emission value
-
- //find best axis to map to, for scanning values
- int closest_axis;
- float closest_dot;
-
- Vector3 normal = Plane(p_vtx[0], p_vtx[1], p_vtx[2]).normal;
-
- for (int i = 0; i < 3; i++) {
-
- Vector3 axis;
- axis[i] = 1.0;
- float dot = ABS(normal.dot(axis));
- if (i == 0 || dot > closest_dot) {
- closest_axis = i;
- closest_dot = dot;
- }
- }
-
- Vector3 axis;
- axis[closest_axis] = 1.0;
- Vector3 t1;
- t1[(closest_axis + 1) % 3] = 1.0;
- Vector3 t2;
- t2[(closest_axis + 2) % 3] = 1.0;
-
- t1 *= p_aabb.size[(closest_axis + 1) % 3] / float(color_scan_cell_width);
- t2 *= p_aabb.size[(closest_axis + 2) % 3] / float(color_scan_cell_width);
-
- Color albedo_accum;
- Color emission_accum;
- float alpha = 0.0;
-
- //map to a grid average in the best axis for this face
- for (int i = 0; i < color_scan_cell_width; i++) {
-
- Vector3 ofs_i = float(i) * t1;
-
- for (int j = 0; j < color_scan_cell_width; j++) {
-
- Vector3 ofs_j = float(j) * t2;
-
- Vector3 from = p_aabb.pos + ofs_i + ofs_j;
- Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
- Vector3 half = (to - from) * 0.5;
-
- //is in this cell?
- if (!fast_tri_box_overlap(from + half, half, p_vtx)) {
- continue; //face does not span this cell
- }
-
- //go from -size to +size*2 to avoid skipping collisions
- Vector3 ray_from = from + (t1 + t2) * 0.5 - axis * p_aabb.size[closest_axis];
- Vector3 ray_to = ray_from + axis * p_aabb.size[closest_axis] * 2;
-
- Vector3 intersection;
-
- if (!Geometry::ray_intersects_triangle(ray_from, ray_to, p_vtx[0], p_vtx[1], p_vtx[2], &intersection)) {
- //no intersect? look in edges
-
- float closest_dist = 1e20;
- for (int j = 0; j < 3; j++) {
- Vector3 c;
- Vector3 inters;
- Geometry::get_closest_points_between_segments(p_vtx[j], p_vtx[(j + 1) % 3], ray_from, ray_to, inters, c);
- float d = c.distance_to(intersection);
- if (j == 0 || d < closest_dist) {
- closest_dist = d;
- intersection = inters;
- }
- }
- }
-
- Vector2 uv = get_uv(intersection, p_vtx, p_uv);
-
- int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
- int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-
- int ofs = uv_y * bake_texture_size + uv_x;
- albedo_accum.r += p_material.albedo[ofs].r;
- albedo_accum.g += p_material.albedo[ofs].g;
- albedo_accum.b += p_material.albedo[ofs].b;
- albedo_accum.a += p_material.albedo[ofs].a;
-
- emission_accum.r += p_material.emission[ofs].r;
- emission_accum.g += p_material.emission[ofs].g;
- emission_accum.b += p_material.emission[ofs].b;
- alpha += 1.0;
- }
- }
-
- if (alpha == 0) {
- //could not in any way get texture information.. so use closest point to center
-
- Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
- Vector3 inters = f.get_closest_point_to(p_aabb.pos + p_aabb.size * 0.5);
-
- Vector2 uv = get_uv(inters, p_vtx, p_uv);
-
- int uv_x = CLAMP(Math::fposmod(uv.x, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
- int uv_y = CLAMP(Math::fposmod(uv.y, 1.0f) * bake_texture_size, 0, bake_texture_size - 1);
-
- int ofs = uv_y * bake_texture_size + uv_x;
-
- alpha = 1.0 / (color_scan_cell_width * color_scan_cell_width);
-
- albedo_accum.r = p_material.albedo[ofs].r * alpha;
- albedo_accum.g = p_material.albedo[ofs].g * alpha;
- albedo_accum.b = p_material.albedo[ofs].b * alpha;
- albedo_accum.a = p_material.albedo[ofs].a * alpha;
-
- emission_accum.r = p_material.emission[ofs].r * alpha;
- emission_accum.g = p_material.emission[ofs].g * alpha;
- emission_accum.b = p_material.emission[ofs].b * alpha;
-
- zero_alphas++;
- } else {
-
- float accdiv = 1.0 / (color_scan_cell_width * color_scan_cell_width);
- alpha *= accdiv;
-
- albedo_accum.r *= accdiv;
- albedo_accum.g *= accdiv;
- albedo_accum.b *= accdiv;
- albedo_accum.a *= accdiv;
-
- emission_accum.r *= accdiv;
- emission_accum.g *= accdiv;
- emission_accum.b *= accdiv;
- }
-
- //put this temporarily here, corrected in a later step
- bake_cells_write[p_idx].albedo[0] += albedo_accum.r;
- bake_cells_write[p_idx].albedo[1] += albedo_accum.g;
- bake_cells_write[p_idx].albedo[2] += albedo_accum.b;
- bake_cells_write[p_idx].light[0] += emission_accum.r;
- bake_cells_write[p_idx].light[1] += emission_accum.g;
- bake_cells_write[p_idx].light[2] += emission_accum.b;
- bake_cells_write[p_idx].alpha += alpha;
-
- static const Vector3 side_normals[6] = {
- Vector3(-1, 0, 0),
- Vector3(1, 0, 0),
- Vector3(0, -1, 0),
- Vector3(0, 1, 0),
- Vector3(0, 0, -1),
- Vector3(0, 0, 1),
- };
-
- for (int i = 0; i < 6; i++) {
- if (normal.dot(side_normals[i]) > CMP_EPSILON) {
- bake_cells_write[p_idx].used_sides |= (1 << i);
- }
- }
-
- } else {
- //go down
- for (int i = 0; i < 8; i++) {
-
- Rect3 aabb = p_aabb;
- aabb.size *= 0.5;
-
- if (i & 1)
- aabb.pos.x += aabb.size.x;
- if (i & 2)
- aabb.pos.y += aabb.size.y;
- if (i & 4)
- aabb.pos.z += aabb.size.z;
-
- {
- Rect3 test_aabb = aabb;
- //test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
- Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
-
- if (!fast_tri_box_overlap(test_aabb.pos + qsize, qsize, p_vtx)) {
- //if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
- //does not fit in child, go on
- continue;
- }
- }
-
- if (bake_cells_write[p_idx].childs[i] == CHILD_EMPTY) {
- //sub cell must be created
-
- if (bake_cells_used == (1 << bake_cells_alloc)) {
- //exhausted cells, creating more space
- bake_cells_alloc++;
- bake_cells_write = PoolVector<BakeCell>::Write();
- bake_cells.resize(1 << bake_cells_alloc);
- bake_cells_write = bake_cells.write();
- }
-
- bake_cells_write[p_idx].childs[i] = bake_cells_used;
- bake_cells_level_used[p_level + 1]++;
- bake_cells_used++;
- }
-
- _plot_face(bake_cells_write[p_idx].childs[i], p_level + 1, p_vtx, p_uv, p_material, aabb);
- }
- }
-}
-
-void BakedLight::_fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z) {
-
- if (p_level == cell_subdiv - 1) {
-
- float alpha = bake_cells_write[p_idx].alpha;
-
- bake_cells_write[p_idx].albedo[0] /= alpha;
- bake_cells_write[p_idx].albedo[1] /= alpha;
- bake_cells_write[p_idx].albedo[2] /= alpha;
-
- //transfer emission to light
- bake_cells_write[p_idx].light[0] /= alpha;
- bake_cells_write[p_idx].light[1] /= alpha;
- bake_cells_write[p_idx].light[2] /= alpha;
-
- bake_cells_write[p_idx].alpha = 1.0;
-
- //remove neighbours from used sides
-
- for (int n = 0; n < 6; n++) {
-
- int ofs[3] = { 0, 0, 0 };
-
- ofs[n / 2] = (n & 1) ? 1 : -1;
-
- //convert to x,y,z on this level
- int x = p_x;
- int y = p_y;
- int z = p_z;
-
- x += ofs[0];
- y += ofs[1];
- z += ofs[2];
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
- int size = 1 << p_level;
- int half = size / 2;
-
- if (x < 0 || x >= size || y < 0 || y >= size || z < 0 || z >= size) {
- //neighbour is out, can't use it
- bake_cells_write[p_idx].used_sides &= ~(1 << uint32_t(n));
- continue;
- }
-
- uint32_t neighbour = 0;
-
- for (int i = 0; i < cell_subdiv - 1; i++) {
-
- BakeCell *bc = &bake_cells_write[neighbour];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- neighbour = bc->childs[child];
- if (neighbour == CHILD_EMPTY) {
- break;
- }
-
- half >>= 1;
- }
-
- if (neighbour != CHILD_EMPTY) {
- bake_cells_write[p_idx].used_sides &= ~(1 << uint32_t(n));
- }
- }
- } else {
-
- //go down
-
- float alpha_average = 0;
- int half = cells_per_axis >> (p_level + 1);
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells_write[p_idx].childs[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- int nx = p_x;
- int ny = p_y;
- int nz = p_z;
-
- if (i & 1)
- nx += half;
- if (i & 2)
- ny += half;
- if (i & 4)
- nz += half;
-
- _fixup_plot(child, p_level + 1, nx, ny, nz);
- alpha_average += bake_cells_write[child].alpha;
- }
-
- bake_cells_write[p_idx].alpha = alpha_average / 8.0;
- bake_cells_write[p_idx].light[0] = 0;
- bake_cells_write[p_idx].light[1] = 0;
- bake_cells_write[p_idx].light[2] = 0;
- bake_cells_write[p_idx].albedo[0] = 0;
- bake_cells_write[p_idx].albedo[1] = 0;
- bake_cells_write[p_idx].albedo[2] = 0;
- }
-
- //clean up light
- bake_cells_write[p_idx].light_pass = 0;
- //find neighbours
-}
-
-void BakedLight::_bake_add_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh) {
-
- for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
- continue; //only triangles
-
- MaterialCache material = _get_material_cache(p_mesh->surface_get_material(i));
-
- Array a = p_mesh->surface_get_arrays(i);
-
- PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
- PoolVector<Vector3>::Read vr = vertices.read();
- PoolVector<Vector2> uv = a[Mesh::ARRAY_TEX_UV];
- PoolVector<Vector2>::Read uvr;
- PoolVector<int> index = a[Mesh::ARRAY_INDEX];
-
- bool read_uv = false;
-
- if (uv.size()) {
-
- uvr = uv.read();
- read_uv = true;
- }
-
- if (index.size()) {
-
- int facecount = index.size() / 3;
- PoolVector<int>::Read ir = index.read();
-
- for (int j = 0; j < facecount; j++) {
-
- Vector3 vtxs[3];
- Vector2 uvs[3];
-
- for (int k = 0; k < 3; k++) {
- vtxs[k] = p_xform.xform(vr[ir[j * 3 + k]]);
- }
-
- if (read_uv) {
- for (int k = 0; k < 3; k++) {
- uvs[k] = uvr[ir[j * 3 + k]];
- }
- }
-
- //plot face
- _plot_face(0, 0, vtxs, uvs, material, bounds);
- }
-
- } else {
-
- int facecount = vertices.size() / 3;
-
- for (int j = 0; j < facecount; j++) {
-
- Vector3 vtxs[3];
- Vector2 uvs[3];
-
- for (int k = 0; k < 3; k++) {
- vtxs[k] = p_xform.xform(vr[j * 3 + k]);
- }
-
- if (read_uv) {
- for (int k = 0; k < 3; k++) {
- uvs[k] = uvr[j * 3 + k];
- }
- }
-
- //plot face
- _plot_face(0, 0, vtxs, uvs, material, bounds);
- }
- }
- }
-}
-
-void BakedLight::_bake_add_to_aabb(const Transform &p_xform, Ref<Mesh> &p_mesh, bool &first) {
-
- for (int i = 0; i < p_mesh->get_surface_count(); i++) {
-
- if (p_mesh->surface_get_primitive_type(i) != Mesh::PRIMITIVE_TRIANGLES)
- continue; //only triangles
-
- Array a = p_mesh->surface_get_arrays(i);
- PoolVector<Vector3> vertices = a[Mesh::ARRAY_VERTEX];
- int vc = vertices.size();
- PoolVector<Vector3>::Read vr = vertices.read();
-
- if (first) {
- bounds.pos = p_xform.xform(vr[0]);
- first = false;
- }
-
- for (int j = 0; j < vc; j++) {
- bounds.expand_to(p_xform.xform(vr[j]));
- }
- }
-}
-
-void BakedLight::bake() {
-
- bake_cells_alloc = 16;
- bake_cells.resize(1 << bake_cells_alloc);
- bake_cells_used = 1;
- cells_per_axis = (1 << (cell_subdiv - 1));
- zero_alphas = 0;
-
- bool aabb_first = true;
- print_line("Generating AABB");
-
- bake_cells_level_used.resize(cell_subdiv);
- for (int i = 0; i < cell_subdiv; i++) {
- bake_cells_level_used[i] = 0;
- }
-
- int count = 0;
- for (Set<GeometryInstance *>::Element *E = geometries.front(); E; E = E->next()) {
-
- print_line("aabb geom " + itos(count) + "/" + itos(geometries.size()));
-
- GeometryInstance *geom = E->get();
-
- if (geom->cast_to<MeshInstance>()) {
-
- MeshInstance *mesh_instance = geom->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mesh_instance->get_mesh();
- if (mesh.is_valid()) {
-
- _bake_add_to_aabb(geom->get_relative_transform(this), mesh, aabb_first);
- }
- }
- count++;
- }
-
- print_line("AABB: " + bounds);
- ERR_FAIL_COND(aabb_first);
-
- bake_cells_write = bake_cells.write();
- count = 0;
-
- for (Set<GeometryInstance *>::Element *E = geometries.front(); E; E = E->next()) {
-
- GeometryInstance *geom = E->get();
- print_line("plot geom " + itos(count) + "/" + itos(geometries.size()));
-
- if (geom->cast_to<MeshInstance>()) {
-
- MeshInstance *mesh_instance = geom->cast_to<MeshInstance>();
- Ref<Mesh> mesh = mesh_instance->get_mesh();
- if (mesh.is_valid()) {
-
- _bake_add_mesh(geom->get_relative_transform(this), mesh);
- }
- }
-
- count++;
- }
-
- _fixup_plot(0, 0, 0, 0, 0);
-
- bake_cells_write = PoolVector<BakeCell>::Write();
-
- bake_cells.resize(bake_cells_used);
-
- print_line("total bake cells used: " + itos(bake_cells_used));
- for (int i = 0; i < cell_subdiv; i++) {
- print_line("level " + itos(i) + ": " + itos(bake_cells_level_used[i]));
- }
- print_line("zero alphas: " + itos(zero_alphas));
-}
-
-void BakedLight::_bake_directional(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 &p_dir, const Color &p_color, int p_sign) {
-
- if (p_level == cell_subdiv - 1) {
-
- Vector3 end;
- end.x = float(p_x + 0.5) / cells_per_axis;
- end.y = float(p_y + 0.5) / cells_per_axis;
- end.z = float(p_z + 0.5) / cells_per_axis;
-
- end = bounds.pos + bounds.size * end;
-
- float max_ray_len = (bounds.size).length() * 1.2;
-
- Vector3 begin = end + max_ray_len * -p_dir;
-
- //clip begin
-
- for (int i = 0; i < 3; i++) {
-
- if (ABS(p_dir[i]) < CMP_EPSILON) {
- continue; // parallel to axis, don't clip
- }
-
- Plane p;
- p.normal[i] = 1.0;
- p.d = bounds.pos[i];
- if (p_dir[i] < 0) {
- p.d += bounds.size[i];
- }
-
- Vector3 inters;
- if (p.intersects_segment(end, begin, &inters)) {
- begin = inters;
- }
- }
-
- int idx = _plot_ray(begin, end);
-
- if (idx >= 0 && light_pass != bake_cells_write[idx].light_pass) {
- //hit something, add or remove light to it
-
- Color albedo = Color(bake_cells_write[idx].albedo[0], bake_cells_write[idx].albedo[1], bake_cells_write[idx].albedo[2]);
- bake_cells_write[idx].light[0] += albedo.r * p_color.r * p_sign;
- bake_cells_write[idx].light[1] += albedo.g * p_color.g * p_sign;
- bake_cells_write[idx].light[2] += albedo.b * p_color.b * p_sign;
- bake_cells_write[idx].light_pass = light_pass;
- }
-
- } else {
-
- int half = cells_per_axis >> (p_level + 1);
-
- //go down
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells_write[p_idx].childs[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- int nx = p_x;
- int ny = p_y;
- int nz = p_z;
-
- if (i & 1)
- nx += half;
- if (i & 2)
- ny += half;
- if (i & 4)
- nz += half;
-
- _bake_directional(child, p_level + 1, nx, ny, nz, p_dir, p_color, p_sign);
- }
- }
-}
-
-void BakedLight::_bake_light(Light *p_light) {
-
- if (p_light->cast_to<DirectionalLight>()) {
-
- DirectionalLight *dl = p_light->cast_to<DirectionalLight>();
-
- Transform rel_xf = dl->get_relative_transform(this);
-
- Vector3 light_dir = -rel_xf.basis.get_axis(2);
-
- Color color = dl->get_color();
- float nrg = dl->get_param(Light::PARAM_ENERGY);
- color.r *= nrg;
- color.g *= nrg;
- color.b *= nrg;
-
- light_pass++;
- _bake_directional(0, 0, 0, 0, 0, light_dir, color, 1);
- }
-}
-
-void BakedLight::_upscale_light(int p_idx, int p_level) {
-
- //go down
-
- float light_accum[3] = { 0, 0, 0 };
- float alpha_accum = 0;
-
- bool check_children = p_level < (cell_subdiv - 2);
-
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells_write[p_idx].childs[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- if (check_children) {
- _upscale_light(child, p_level + 1);
- }
-
- light_accum[0] += bake_cells_write[child].light[0];
- light_accum[1] += bake_cells_write[child].light[1];
- light_accum[2] += bake_cells_write[child].light[2];
- alpha_accum += bake_cells_write[child].alpha;
- }
-
- bake_cells_write[p_idx].light[0] = light_accum[0] / 8.0;
- bake_cells_write[p_idx].light[1] = light_accum[1] / 8.0;
- bake_cells_write[p_idx].light[2] = light_accum[2] / 8.0;
- bake_cells_write[p_idx].alpha = alpha_accum / 8.0;
-}
-
-void BakedLight::bake_lights() {
-
- ERR_FAIL_COND(bake_cells.size() == 0);
-
- bake_cells_write = bake_cells.write();
-
- for (Set<Light *>::Element *E = lights.front(); E; E = E->next()) {
-
- _bake_light(E->get());
- }
-
- _upscale_light(0, 0);
-
- bake_cells_write = PoolVector<BakeCell>::Write();
-}
-
-Color BakedLight::_cone_trace(const Vector3 &p_from, const Vector3 &p_dir, float p_half_angle) {
-
- Color color(0, 0, 0, 0);
- float tha = Math::tan(p_half_angle); //tan half angle
- Vector3 from = (p_from - bounds.pos) / bounds.size; //convert to 0..1
- from /= cells_per_axis; //convert to voxels of size 1
- Vector3 dir = (p_dir / bounds.size).normalized();
-
- float max_dist = Vector3(cells_per_axis, cells_per_axis, cells_per_axis).length();
-
- float dist = 1.0;
- // self occlusion in flat surfaces
-
- float alpha = 0;
-
- while (dist < max_dist && alpha < 0.95) {
-
-#if 0
- // smallest sample diameter possible is the voxel size
- float diameter = MAX(1.0, 2.0 * tha * dist);
- float lod = log2(diameter);
-
- Vector3 sample_pos = from + dist * dir;
-
-
- Color samples_base[2][8]={{Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)},
- {Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0),Color(0,0,0,0)}};
-
- float levelf = Math::fposmod(lod,1.0);
- float fx = Math::fposmod(sample_pos.x,1.0);
- float fy = Math::fposmod(sample_pos.y,1.0);
- float fz = Math::fposmod(sample_pos.z,1.0);
-
- for(int l=0;l<2;l++){
-
- int bx = Math::floor(sample_pos.x);
- int by = Math::floor(sample_pos.y);
- int bz = Math::floor(sample_pos.z);
-
- int lodn=int(Math::floor(lod))-l;
-
- bx>>=lodn;
- by>>=lodn;
- bz>>=lodn;
-
- int limit = MAX(0,cell_subdiv-lodn-1);
-
- for(int c=0;c<8;c++) {
-
- int x = bx;
- int y = by;
- int z = bz;
-
- if (c&1) {
- x+=1;
- }
- if (c&2) {
- y+=1;
- }
- if (c&4) {
- z+=1;
- }
-
- int ofs_x=0;
- int ofs_y=0;
- int ofs_z=0;
- int size = cells_per_axis>>lodn;
- int half=size/2;
-
- bool outside=x<0 || x>=size || y<0 || y>=size || z<0 || z>=size;
-
- if (outside)
- continue;
-
-
- uint32_t cell=0;
-
- for(int i=0;i<limit;i++) {
-
- BakeCell *bc = &bake_cells_write[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child|=1;
- ofs_x+=half;
- }
- if (y >= ofs_y + half) {
- child|=2;
- ofs_y+=half;
- }
- if (z >= ofs_z + half) {
- child|=4;
- ofs_z+=half;
- }
-
- cell = bc->childs[child];
- if (cell==CHILD_EMPTY)
- break;
-
- half>>=1;
- }
-
- if (cell!=CHILD_EMPTY) {
-
- samples_base[l][c].r=bake_cells_write[cell].light[0];
- samples_base[l][c].g=bake_cells_write[cell].light[1];
- samples_base[l][c].b=bake_cells_write[cell].light[2];
- samples_base[l][c].a=bake_cells_write[cell].alpha;
- }
-
- }
-
-
- }
-
- Color m0x0 = samples_base[0][0].linear_interpolate(samples_base[0][1],fx);
- Color m0x1 = samples_base[0][2].linear_interpolate(samples_base[0][3],fx);
- Color m0y0 = m0x0.linear_interpolate(m0x1,fy);
- m0x0 = samples_base[0][4].linear_interpolate(samples_base[0][5],fx);
- m0x1 = samples_base[0][6].linear_interpolate(samples_base[0][7],fx);
- Color m0y1 = m0x0.linear_interpolate(m0x1,fy);
- Color m0z = m0y0.linear_interpolate(m0y1,fz);
-
- Color m1x0 = samples_base[1][0].linear_interpolate(samples_base[1][1],fx);
- Color m1x1 = samples_base[1][2].linear_interpolate(samples_base[1][3],fx);
- Color m1y0 = m1x0.linear_interpolate(m1x1,fy);
- m1x0 = samples_base[1][4].linear_interpolate(samples_base[1][5],fx);
- m1x1 = samples_base[1][6].linear_interpolate(samples_base[1][7],fx);
- Color m1y1 = m1x0.linear_interpolate(m1x1,fy);
- Color m1z = m1y0.linear_interpolate(m1y1,fz);
-
- Color m = m0z.linear_interpolate(m1z,levelf);
-#else
- float diameter = 1.0;
- Vector3 sample_pos = from + dist * dir;
-
- Color m(0, 0, 0, 0);
- {
- int x = Math::floor(sample_pos.x);
- int y = Math::floor(sample_pos.y);
- int z = Math::floor(sample_pos.z);
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
- int size = cells_per_axis;
- int half = size / 2;
-
- bool outside = x < 0 || x >= size || y < 0 || y >= size || z < 0 || z >= size;
-
- if (!outside) {
-
- uint32_t cell = 0;
-
- for (int i = 0; i < cell_subdiv - 1; i++) {
-
- BakeCell *bc = &bake_cells_write[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- cell = bc->childs[child];
- if (cell == CHILD_EMPTY)
- break;
-
- half >>= 1;
- }
-
- if (cell != CHILD_EMPTY) {
-
- m.r = bake_cells_write[cell].light[0];
- m.g = bake_cells_write[cell].light[1];
- m.b = bake_cells_write[cell].light[2];
- m.a = bake_cells_write[cell].alpha;
- }
- }
- }
-
-#endif
- // front-to-back compositing
- float a = (1.0 - alpha);
- color.r += a * m.r;
- color.g += a * m.g;
- color.b += a * m.b;
- alpha += a * m.a;
- //occlusion += a * voxelColor.a;
- //occlusion += (a * voxelColor.a) / (1.0 + 0.03 * diameter);
- dist += diameter * 0.5; // smoother
- //dist += diameter; // faster but misses more voxels
- }
-
- return color;
-}
-
-void BakedLight::_bake_radiance(int p_idx, int p_level, int p_x, int p_y, int p_z) {
-
- if (p_level == cell_subdiv - 1) {
-
- const int NUM_CONES = 6;
- Vector3 cone_directions[6] = {
- Vector3(1, 0, 0),
- Vector3(0.5, 0.866025, 0),
- Vector3(0.5, 0.267617, 0.823639),
- Vector3(0.5, -0.700629, 0.509037),
- Vector3(0.5, -0.700629, -0.509037),
- Vector3(0.5, 0.267617, -0.823639)
- };
- float coneWeights[6] = { 0.25, 0.15, 0.15, 0.15, 0.15, 0.15 };
-
- Vector3 pos = (Vector3(p_x, p_y, p_z) / float(cells_per_axis)) * bounds.size + bounds.pos;
- Vector3 voxel_size = bounds.size / float(cells_per_axis);
- pos += voxel_size * 0.5;
-
- Color accum;
-
- bake_cells_write[p_idx].light[0] = 0;
- bake_cells_write[p_idx].light[1] = 0;
- bake_cells_write[p_idx].light[2] = 0;
-
- int freepix = 0;
- for (int i = 0; i < 6; i++) {
-
- if (!(bake_cells_write[p_idx].used_sides & (1 << i)))
- continue;
-
- if ((i & 1) == 0)
- bake_cells_write[p_idx].light[i / 2] = 1.0;
- freepix++;
- continue;
-
- int ofs = i / 2;
-
- Vector3 dir;
- if ((i & 1) == 0)
- dir[ofs] = 1.0;
- else
- dir[ofs] = -1.0;
-
- for (int j = 0; j < 1; j++) {
-
- Vector3 cone_dir;
- cone_dir.x = cone_directions[j][(ofs + 0) % 3];
- cone_dir.y = cone_directions[j][(ofs + 1) % 3];
- cone_dir.z = cone_directions[j][(ofs + 2) % 3];
-
- cone_dir[ofs] *= dir[ofs];
-
- Color res = _cone_trace(pos + dir * voxel_size, cone_dir, Math::deg2rad(29.9849));
- accum.r += res.r; //*coneWeights[j];
- accum.g += res.g; //*coneWeights[j];
- accum.b += res.b; //*coneWeights[j];
- }
- }
-#if 0
- if (freepix==0) {
- bake_cells_write[p_idx].light[0]=0;
- bake_cells_write[p_idx].light[1]=0;
- bake_cells_write[p_idx].light[2]=0;
- }
-
- if (freepix==1) {
- bake_cells_write[p_idx].light[0]=1;
- bake_cells_write[p_idx].light[1]=0;
- bake_cells_write[p_idx].light[2]=0;
- }
-
- if (freepix==2) {
- bake_cells_write[p_idx].light[0]=0;
- bake_cells_write[p_idx].light[1]=1;
- bake_cells_write[p_idx].light[2]=0;
- }
-
- if (freepix==3) {
- bake_cells_write[p_idx].light[0]=1;
- bake_cells_write[p_idx].light[1]=1;
- bake_cells_write[p_idx].light[2]=0;
- }
-
- if (freepix==4) {
- bake_cells_write[p_idx].light[0]=0;
- bake_cells_write[p_idx].light[1]=0;
- bake_cells_write[p_idx].light[2]=1;
- }
-
- if (freepix==5) {
- bake_cells_write[p_idx].light[0]=1;
- bake_cells_write[p_idx].light[1]=0;
- bake_cells_write[p_idx].light[2]=1;
- }
-
- if (freepix==6) {
- bake_cells_write[p_idx].light[0]=0;
- bake_cells_write[p_idx].light[0]=1;
- bake_cells_write[p_idx].light[0]=1;
- }
-#endif
- //bake_cells_write[p_idx].radiance[0]=accum.r;
- //bake_cells_write[p_idx].radiance[1]=accum.g;
- //bake_cells_write[p_idx].radiance[2]=accum.b;
-
- } else {
-
- int half = cells_per_axis >> (p_level + 1);
-
- //go down
- for (int i = 0; i < 8; i++) {
-
- uint32_t child = bake_cells_write[p_idx].childs[i];
-
- if (child == CHILD_EMPTY)
- continue;
-
- int nx = p_x;
- int ny = p_y;
- int nz = p_z;
-
- if (i & 1)
- nx += half;
- if (i & 2)
- ny += half;
- if (i & 4)
- nz += half;
-
- _bake_radiance(child, p_level + 1, nx, ny, nz);
- }
- }
-}
-
-void BakedLight::bake_radiance() {
-
- ERR_FAIL_COND(bake_cells.size() == 0);
-
- bake_cells_write = bake_cells.write();
-
- _bake_radiance(0, 0, 0, 0, 0);
-
- bake_cells_write = PoolVector<BakeCell>::Write();
-}
-int BakedLight::_find_cell(int x, int y, int z) {
-
- uint32_t cell = 0;
-
- int ofs_x = 0;
- int ofs_y = 0;
- int ofs_z = 0;
- int size = cells_per_axis;
- int half = size / 2;
-
- if (x < 0 || x >= size)
- return -1;
- if (y < 0 || y >= size)
- return -1;
- if (z < 0 || z >= size)
- return -1;
-
- for (int i = 0; i < cell_subdiv - 1; i++) {
-
- BakeCell *bc = &bake_cells_write[cell];
-
- int child = 0;
- if (x >= ofs_x + half) {
- child |= 1;
- ofs_x += half;
- }
- if (y >= ofs_y + half) {
- child |= 2;
- ofs_y += half;
- }
- if (z >= ofs_z + half) {
- child |= 4;
- ofs_z += half;
- }
-
- cell = bc->childs[child];
- if (cell == CHILD_EMPTY)
- return -1;
-
- half >>= 1;
- }
-
- return cell;
-}
-
-int BakedLight::_plot_ray(const Vector3 &p_from, const Vector3 &p_to) {
-
- Vector3 from = (p_from - bounds.pos) / bounds.size;
- Vector3 to = (p_to - bounds.pos) / bounds.size;
-
- int x1 = Math::floor(from.x * cells_per_axis);
- int y1 = Math::floor(from.y * cells_per_axis);
- int z1 = Math::floor(from.z * cells_per_axis);
-
- int x2 = Math::floor(to.x * cells_per_axis);
- int y2 = Math::floor(to.y * cells_per_axis);
- int z2 = Math::floor(to.z * cells_per_axis);
-
- int i, dx, dy, dz, l, m, n, x_inc, y_inc, z_inc, err_1, err_2, dx2, dy2, dz2;
- int point[3];
-
- point[0] = x1;
- point[1] = y1;
- point[2] = z1;
- dx = x2 - x1;
- dy = y2 - y1;
- dz = z2 - z1;
- x_inc = (dx < 0) ? -1 : 1;
- l = ABS(dx);
- y_inc = (dy < 0) ? -1 : 1;
- m = ABS(dy);
- z_inc = (dz < 0) ? -1 : 1;
- n = ABS(dz);
- dx2 = l << 1;
- dy2 = m << 1;
- dz2 = n << 1;
-
- if ((l >= m) && (l >= n)) {
- err_1 = dy2 - l;
- err_2 = dz2 - l;
- for (i = 0; i < l; i++) {
- int cell = _find_cell(point[0], point[1], point[2]);
- if (cell >= 0)
- return cell;
-
- if (err_1 > 0) {
- point[1] += y_inc;
- err_1 -= dx2;
- }
- if (err_2 > 0) {
- point[2] += z_inc;
- err_2 -= dx2;
- }
- err_1 += dy2;
- err_2 += dz2;
- point[0] += x_inc;
- }
- } else if ((m >= l) && (m >= n)) {
- err_1 = dx2 - m;
- err_2 = dz2 - m;
- for (i = 0; i < m; i++) {
- int cell = _find_cell(point[0], point[1], point[2]);
- if (cell >= 0)
- return cell;
- if (err_1 > 0) {
- point[0] += x_inc;
- err_1 -= dy2;
- }
- if (err_2 > 0) {
- point[2] += z_inc;
- err_2 -= dy2;
- }
- err_1 += dx2;
- err_2 += dz2;
- point[1] += y_inc;
- }
- } else {
- err_1 = dy2 - n;
- err_2 = dx2 - n;
- for (i = 0; i < n; i++) {
- int cell = _find_cell(point[0], point[1], point[2]);
- if (cell >= 0)
- return cell;
-
- if (err_1 > 0) {
- point[1] += y_inc;
- err_1 -= dz2;
- }
- if (err_2 > 0) {
- point[0] += x_inc;
- err_2 -= dz2;
- }
- err_1 += dy2;
- err_2 += dx2;
- point[2] += z_inc;
- }
- }
- return _find_cell(point[0], point[1], point[2]);
-}
-
-void BakedLight::set_cell_subdiv(int p_subdiv) {
-
- cell_subdiv = p_subdiv;
-
- //VS::get_singleton()->baked_light_set_subdivision(baked_light,p_subdiv);
-}
-
-int BakedLight::get_cell_subdiv() const {
-
- return cell_subdiv;
-}
-
-Rect3 BakedLight::get_aabb() const {
-
- return Rect3(Vector3(0, 0, 0), Vector3(1, 1, 1));
-}
-PoolVector<Face3> BakedLight::get_faces(uint32_t p_usage_flags) const {
-
- return PoolVector<Face3>();
-}
-
-String BakedLight::get_configuration_warning() const {
- return String();
-}
-
-void BakedLight::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, DebugMode p_mode, Ref<MultiMesh> &p_multimesh, int &idx) {
-
- if (p_level == cell_subdiv - 1) {
-
- Vector3 center = p_aabb.pos + p_aabb.size * 0.5;
- Transform xform;
- xform.origin = center;
- xform.basis.scale(p_aabb.size * 0.5);
- p_multimesh->set_instance_transform(idx, xform);
- Color col;
- switch (p_mode) {
- case DEBUG_ALBEDO: {
- col = Color(bake_cells_write[p_idx].albedo[0], bake_cells_write[p_idx].albedo[1], bake_cells_write[p_idx].albedo[2]);
- } break;
- case DEBUG_LIGHT: {
- col = Color(bake_cells_write[p_idx].light[0], bake_cells_write[p_idx].light[1], bake_cells_write[p_idx].light[2]);
- Color colr = Color(bake_cells_write[p_idx].radiance[0], bake_cells_write[p_idx].radiance[1], bake_cells_write[p_idx].radiance[2]);
- col.r += colr.r;
- col.g += colr.g;
- col.b += colr.b;
- } break;
- }
- p_multimesh->set_instance_color(idx, col);
-
- idx++;
-
- } else {
-
- for (int i = 0; i < 8; i++) {
-
- if (bake_cells_write[p_idx].childs[i] == CHILD_EMPTY)
- continue;
-
- Rect3 aabb = p_aabb;
- aabb.size *= 0.5;
-
- if (i & 1)
- aabb.pos.x += aabb.size.x;
- if (i & 2)
- aabb.pos.y += aabb.size.y;
- if (i & 4)
- aabb.pos.z += aabb.size.z;
-
- _debug_mesh(bake_cells_write[p_idx].childs[i], p_level + 1, aabb, p_mode, p_multimesh, idx);
- }
- }
-}
-
-void BakedLight::create_debug_mesh(DebugMode p_mode) {
-
- Ref<MultiMesh> mm;
- mm.instance();
-
- mm->set_transform_format(MultiMesh::TRANSFORM_3D);
- mm->set_color_format(MultiMesh::COLOR_8BIT);
- mm->set_instance_count(bake_cells_level_used[cell_subdiv - 1]);
-
- Ref<Mesh> mesh;
- mesh.instance();
-
- {
- Array arr;
- arr.resize(Mesh::ARRAY_MAX);
-
- PoolVector<Vector3> vertices;
- PoolVector<Color> colors;
-
- int vtx_idx = 0;
-#define ADD_VTX(m_idx) \
- ; \
- vertices.push_back(face_points[m_idx]); \
- colors.push_back(Color(1, 1, 1, 1)); \
- vtx_idx++;
-
- for (int i = 0; i < 6; i++) {
-
- Vector3 face_points[4];
-
- for (int j = 0; j < 4; j++) {
-
- float v[3];
- v[0] = 1.0;
- v[1] = 1 - 2 * ((j >> 1) & 1);
- v[2] = v[1] * (1 - 2 * (j & 1));
-
- for (int k = 0; k < 3; k++) {
-
- if (i < 3)
- face_points[j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
- else
- face_points[3 - j][(i + k) % 3] = v[k] * (i >= 3 ? -1 : 1);
- }
- }
-
- //tri 1
- ADD_VTX(0);
- ADD_VTX(1);
- ADD_VTX(2);
- //tri 2
- ADD_VTX(2);
- ADD_VTX(3);
- ADD_VTX(0);
- }
-
- arr[Mesh::ARRAY_VERTEX] = vertices;
- arr[Mesh::ARRAY_COLOR] = colors;
- mesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr);
- }
-
- {
- Ref<SpatialMaterial> fsm;
- fsm.instance();
- fsm->set_flag(SpatialMaterial::FLAG_SRGB_VERTEX_COLOR, true);
- fsm->set_flag(SpatialMaterial::FLAG_ALBEDO_FROM_VERTEX_COLOR, true);
- fsm->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
- fsm->set_albedo(Color(1, 1, 1, 1));
-
- mesh->surface_set_material(0, fsm);
- }
-
- mm->set_mesh(mesh);
-
- bake_cells_write = bake_cells.write();
-
- int idx = 0;
- _debug_mesh(0, 0, bounds, p_mode, mm, idx);
-
- print_line("written: " + itos(idx) + " total: " + itos(bake_cells_level_used[cell_subdiv - 1]));
-
- MultiMeshInstance *mmi = memnew(MultiMeshInstance);
- mmi->set_multimesh(mm);
- add_child(mmi);
-#ifdef TOOLS_ENABLED
- if (get_tree()->get_edited_scene_root() == this) {
- mmi->set_owner(this);
- } else {
- mmi->set_owner(get_owner());
- }
-#else
- mmi->set_owner(get_owner());
-#endif
-}
-
-void BakedLight::_debug_mesh_albedo() {
- create_debug_mesh(DEBUG_ALBEDO);
-}
-
-void BakedLight::_debug_mesh_light() {
- create_debug_mesh(DEBUG_LIGHT);
-}
-
-void BakedLight::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_cell_subdiv", "steps"), &BakedLight::set_cell_subdiv);
- ClassDB::bind_method(D_METHOD("get_cell_subdiv"), &BakedLight::get_cell_subdiv);
-
- ClassDB::bind_method(D_METHOD("bake"), &BakedLight::bake);
- ClassDB::set_method_flags(get_class_static(), _scs_create("bake"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("bake_lights"), &BakedLight::bake_lights);
- ClassDB::set_method_flags(get_class_static(), _scs_create("bake_lights"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("bake_radiance"), &BakedLight::bake_radiance);
- ClassDB::set_method_flags(get_class_static(), _scs_create("bake_radiance"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("debug_mesh_albedo"), &BakedLight::_debug_mesh_albedo);
- ClassDB::set_method_flags(get_class_static(), _scs_create("debug_mesh_albedo"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ClassDB::bind_method(D_METHOD("debug_mesh_light"), &BakedLight::_debug_mesh_light);
- ClassDB::set_method_flags(get_class_static(), _scs_create("debug_mesh_light"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "cell_subdiv"), "set_cell_subdiv", "get_cell_subdiv");
- ADD_SIGNAL(MethodInfo("baked_light_changed"));
-}
-
-BakedLight::BakedLight() {
-
- //baked_light=VisualServer::get_singleton()->baked_light_create();
- VS::get_singleton()->instance_set_base(get_instance(), baked_light);
-
- cell_subdiv = 8;
- bake_texture_size = 128;
- color_scan_cell_width = 8;
- light_pass = 0;
-}
-
-BakedLight::~BakedLight() {
-
- VS::get_singleton()->free(baked_light);
-}
-
-/////////////////////////
-
-#if 0
-void BakedLightSampler::set_param(Param p_param,float p_value) {
- ERR_FAIL_INDEX(p_param,PARAM_MAX);
- params[p_param]=p_value;
- VS::get_singleton()->baked_light_sampler_set_param(base,VS::BakedLightSamplerParam(p_param),p_value);
-}
-
-float BakedLightSampler::get_param(Param p_param) const{
-
- ERR_FAIL_INDEX_V(p_param,PARAM_MAX,0);
- return params[p_param];
-
-}
-
-void BakedLightSampler::set_resolution(int p_resolution){
-
- ERR_FAIL_COND(p_resolution<4 || p_resolution>32);
- resolution=p_resolution;
- VS::get_singleton()->baked_light_sampler_set_resolution(base,resolution);
-}
-int BakedLightSampler::get_resolution() const {
-
- return resolution;
-}
-
-AABB BakedLightSampler::get_aabb() const {
-
- float r = get_param(PARAM_RADIUS);
- return AABB( Vector3(-r,-r,-r),Vector3(r*2,r*2,r*2));
-}
-DVector<Face3> BakedLightSampler::get_faces(uint32_t p_usage_flags) const {
- return DVector<Face3>();
-}
-
-void BakedLightSampler::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_param","param","value"),&BakedLightSampler::set_param);
- ClassDB::bind_method(D_METHOD("get_param","param"),&BakedLightSampler::get_param);
-
- ClassDB::bind_method(D_METHOD("set_resolution","resolution"),&BakedLightSampler::set_resolution);
- ClassDB::bind_method(D_METHOD("get_resolution"),&BakedLightSampler::get_resolution);
-
-
- BIND_CONSTANT( PARAM_RADIUS );
- BIND_CONSTANT( PARAM_STRENGTH );
- BIND_CONSTANT( PARAM_ATTENUATION );
- BIND_CONSTANT( PARAM_DETAIL_RATIO );
- BIND_CONSTANT( PARAM_MAX );
-
- ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/radius",PROPERTY_HINT_RANGE,"0.01,1024,0.01"),"set_param","get_param",PARAM_RADIUS);
- ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/strength",PROPERTY_HINT_RANGE,"0.01,16,0.01"),"set_param","get_param",PARAM_STRENGTH);
- ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/attenuation",PROPERTY_HINT_EXP_EASING),"set_param","get_param",PARAM_ATTENUATION);
- ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),"set_param","get_param",PARAM_DETAIL_RATIO);
- //ADD_PROPERTYI( PropertyInfo(Variant::REAL,"params/detail_ratio",PROPERTY_HINT_RANGE,"0,20,1"),"set_param","get_param",PARAM_DETAIL_RATIO);
- ADD_PROPERTY( PropertyInfo(Variant::REAL,"params/resolution",PROPERTY_HINT_RANGE,"4,32,1"),"set_resolution","get_resolution");
-
-}
-
-BakedLightSampler::BakedLightSampler() {
-
- base = VS::get_singleton()->baked_light_sampler_create();
- set_base(base);
-
- params[PARAM_RADIUS]=1.0;
- params[PARAM_STRENGTH]=1.0;
- params[PARAM_ATTENUATION]=1.0;
- params[PARAM_DETAIL_RATIO]=0.1;
- resolution=16;
-
-
-}
-
-BakedLightSampler::~BakedLightSampler(){
-
- VS::get_singleton()->free(base);
-}
-#endif
diff --git a/scene/3d/baked_light_instance.h b/scene/3d/baked_light_instance.h
deleted file mode 100644
index 63a5fa7255..0000000000
--- a/scene/3d/baked_light_instance.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*************************************************************************/
-/* baked_light_instance.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 BAKED_LIGHT_INSTANCE_H
-#define BAKED_LIGHT_INSTANCE_H
-
-#include "scene/3d/multimesh_instance.h"
-#include "scene/3d/visual_instance.h"
-#include "scene/resources/baked_light.h"
-
-class BakedLightBaker;
-class Light;
-
-class BakedLight : public VisualInstance {
- GDCLASS(BakedLight, VisualInstance);
-
-public:
- enum DebugMode {
- DEBUG_ALBEDO,
- DEBUG_LIGHT
- };
-
-private:
- RID baked_light;
- int cell_subdiv;
- Rect3 bounds;
- int cells_per_axis;
-
- enum {
- CHILD_EMPTY = 0xFFFFFFFF,
- };
-
- /* BAKE DATA */
-
- struct BakeCell {
-
- uint32_t childs[8];
- float albedo[3]; //albedo in RGB24
- float light[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
- float radiance[3]; //accumulated light in 16:16 fixed point (needs to be integer for moving lights fast)
- uint32_t used_sides;
- float alpha; //used for upsampling
- uint32_t light_pass; //used for baking light
-
- BakeCell() {
- for (int i = 0; i < 8; i++) {
- childs[i] = 0xFFFFFFFF;
- }
-
- for (int i = 0; i < 3; i++) {
- light[i] = 0;
- albedo[i] = 0;
- radiance[i] = 0;
- }
- alpha = 0;
- light_pass = 0;
- used_sides = 0;
- }
- };
-
- int bake_texture_size;
- int color_scan_cell_width;
-
- struct MaterialCache {
- //128x128 textures
- Vector<Color> albedo;
- Vector<Color> emission;
- };
-
- Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
-
- Map<Ref<Material>, MaterialCache> material_cache;
- MaterialCache _get_material_cache(Ref<Material> p_material);
-
- int bake_cells_alloc;
- int bake_cells_used;
- int zero_alphas;
- Vector<int> bake_cells_level_used;
- PoolVector<BakeCell> bake_cells;
- PoolVector<BakeCell>::Write bake_cells_write;
-
- void _plot_face(int p_idx, int p_level, const Vector3 *p_vtx, const Vector2 *p_uv, const MaterialCache &p_material, const Rect3 &p_aabb);
- void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z);
- void _bake_add_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh);
- void _bake_add_to_aabb(const Transform &p_xform, Ref<Mesh> &p_mesh, bool &first);
-
- void _debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, DebugMode p_mode, Ref<MultiMesh> &p_multimesh, int &idx);
- void _debug_mesh_albedo();
- void _debug_mesh_light();
-
- _FORCE_INLINE_ int _find_cell(int x, int y, int z);
- int _plot_ray(const Vector3 &p_from, const Vector3 &p_to);
-
- uint32_t light_pass;
-
- void _bake_directional(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 &p_dir, const Color &p_color, int p_sign);
- void _upscale_light(int p_idx, int p_level);
- void _bake_light(Light *p_light);
-
- Color _cone_trace(const Vector3 &p_from, const Vector3 &p_dir, float p_half_angle);
- void _bake_radiance(int p_idx, int p_level, int p_x, int p_y, int p_z);
-
- friend class GeometryInstance;
-
- Set<GeometryInstance *> geometries;
- friend class Light;
-
- Set<Light *> lights;
-
-protected:
- static void _bind_methods();
-
-public:
- void set_cell_subdiv(int p_subdiv);
- int get_cell_subdiv() const;
-
- void bake();
- void bake_lights();
- void bake_radiance();
-
- void create_debug_mesh(DebugMode p_mode);
-
- virtual Rect3 get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
- String get_configuration_warning() const;
-
- BakedLight();
- ~BakedLight();
-};
-
-#if 0
-class BakedLightSampler : public VisualInstance {
- GDCLASS(BakedLightSampler,VisualInstance);
-
-
-public:
-
- enum Param {
- PARAM_RADIUS=VS::BAKED_LIGHT_SAMPLER_RADIUS,
- PARAM_STRENGTH=VS::BAKED_LIGHT_SAMPLER_STRENGTH,
- PARAM_ATTENUATION=VS::BAKED_LIGHT_SAMPLER_ATTENUATION,
- PARAM_DETAIL_RATIO=VS::BAKED_LIGHT_SAMPLER_DETAIL_RATIO,
- PARAM_MAX=VS::BAKED_LIGHT_SAMPLER_MAX
- };
-
-
-
-protected:
-
- RID base;
- float params[PARAM_MAX];
- int resolution;
- static void _bind_methods();
-public:
-
- virtual AABB get_aabb() const;
- virtual PoolVector<Face3> get_faces(uint32_t p_usage_flags) const;
-
- void set_param(Param p_param,float p_value);
- float get_param(Param p_param) const;
-
- void set_resolution(int p_resolution);
- int get_resolution() const;
-
- BakedLightSampler();
- ~BakedLightSampler();
-};
-
-VARIANT_ENUM_CAST( BakedLightSampler::Param );
-
-#endif
-#endif // BAKED_LIGHT_H
diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp
index d648ff078c..0f4378acdd 100644
--- a/scene/3d/camera.cpp
+++ b/scene/3d/camera.cpp
@@ -626,7 +626,7 @@ Camera::Camera() {
current = false;
force_change = false;
mode = PROJECTION_PERSPECTIVE;
- set_perspective(60.0, 0.1, 100.0);
+ set_perspective(65.0, 0.1, 100.0);
keep_aspect = KEEP_HEIGHT;
layers = 0xfffff;
v_offset = 0;
diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp
index 4dc01975b8..1b27313d3b 100644
--- a/scene/3d/collision_object.cpp
+++ b/scene/3d/collision_object.cpp
@@ -172,7 +172,7 @@ void CollisionObject::_get_property_list(List<PropertyInfo> *p_list) const {
}
}
-void CollisionObject::_input_event(Node *p_camera, const InputEvent &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
+void CollisionObject::_input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape) {
if (get_script_instance()) {
get_script_instance()->call(SceneStringNames::get_singleton()->_input_event, p_camera, p_input_event, p_pos, p_normal, p_shape);
@@ -235,9 +235,9 @@ void CollisionObject::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_capture_input_on_drag", "enable"), &CollisionObject::set_capture_input_on_drag);
ClassDB::bind_method(D_METHOD("get_capture_input_on_drag"), &CollisionObject::get_capture_input_on_drag);
ClassDB::bind_method(D_METHOD("get_rid"), &CollisionObject::get_rid);
- BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
+ BIND_VMETHOD(MethodInfo("_input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
- ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::INPUT_EVENT, "event"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
+ ADD_SIGNAL(MethodInfo("input_event", PropertyInfo(Variant::OBJECT, "camera"), PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), PropertyInfo(Variant::VECTOR3, "click_pos"), PropertyInfo(Variant::VECTOR3, "click_normal"), PropertyInfo(Variant::INT, "shape_idx")));
ADD_SIGNAL(MethodInfo("mouse_entered"));
ADD_SIGNAL(MethodInfo("mouse_exited"));
diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h
index abe0b804bf..3822fb0d5a 100644
--- a/scene/3d/collision_object.h
+++ b/scene/3d/collision_object.h
@@ -70,7 +70,7 @@ protected:
void _get_property_list(List<PropertyInfo> *p_list) const;
static void _bind_methods();
friend class Viewport;
- virtual void _input_event(Node *p_camera, const InputEvent &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
+ virtual void _input_event(Node *p_camera, const Ref<InputEvent> &p_input_event, const Vector3 &p_pos, const Vector3 &p_normal, int p_shape);
virtual void _mouse_enter();
virtual void _mouse_exit();
diff --git a/scene/3d/collision_polygon.cpp b/scene/3d/collision_polygon.cpp
index a9a693f370..d9321f7134 100644
--- a/scene/3d/collision_polygon.cpp
+++ b/scene/3d/collision_polygon.cpp
@@ -208,7 +208,7 @@ void CollisionPolygon::set_polygon(const Vector<Point2> &p_polygon) {
aabb = Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
} else {
- aabb.pos -= aabb.size * 0.3;
+ aabb.position -= aabb.size * 0.3;
aabb.size += aabb.size * 0.6;
}
_update_parent();
diff --git a/scene/3d/gi_probe.cpp b/scene/3d/gi_probe.cpp
index 7370e1330c..adca1492c3 100644
--- a/scene/3d/gi_probe.cpp
+++ b/scene/3d/gi_probe.cpp
@@ -564,7 +564,7 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
Vector3 ofs_j = float(j) * t2;
- Vector3 from = p_aabb.pos + ofs_i + ofs_j;
+ Vector3 from = p_aabb.position + ofs_i + ofs_j;
Vector3 to = from + t1 + t2 + axis * p_aabb.size[closest_axis];
Vector3 half = (to - from) * 0.5;
@@ -619,7 +619,7 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
//could not in any way get texture information.. so use closest point to center
Face3 f(p_vtx[0], p_vtx[1], p_vtx[2]);
- Vector3 inters = f.get_closest_point_to(p_aabb.pos + p_aabb.size * 0.5);
+ Vector3 inters = f.get_closest_point_to(p_aabb.position + p_aabb.size * 0.5);
Vector2 uv = get_uv(inters, p_vtx, p_uv);
@@ -700,15 +700,15 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
int nz = p_z;
if (i & 1) {
- aabb.pos.x += aabb.size.x;
+ aabb.position.x += aabb.size.x;
nx += half;
}
if (i & 2) {
- aabb.pos.y += aabb.size.y;
+ aabb.position.y += aabb.size.y;
ny += half;
}
if (i & 4) {
- aabb.pos.z += aabb.size.z;
+ aabb.position.z += aabb.size.z;
nz += half;
}
//make sure to not plot beyond limits
@@ -720,7 +720,7 @@ void GIProbe::_plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, cons
//test_aabb.grow_by(test_aabb.get_longest_axis_size()*0.05); //grow a bit to avoid numerical error in real-time
Vector3 qsize = test_aabb.size * 0.5; //quarter size, for fast aabb test
- if (!fast_tri_box_overlap(test_aabb.pos + qsize, qsize, p_vtx)) {
+ if (!fast_tri_box_overlap(test_aabb.position + qsize, qsize, p_vtx)) {
//if (!Face3(p_vtx[0],p_vtx[1],p_vtx[2]).intersects_aabb2(aabb)) {
//does not fit in child, go on
continue;
@@ -881,11 +881,11 @@ void GIProbe::_fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, Bak
}
}
-Vector<Color> GIProbe::_get_bake_texture(Image &p_image, const Color &p_color) {
+Vector<Color> GIProbe::_get_bake_texture(Ref<Image> p_image, const Color &p_color) {
Vector<Color> ret;
- if (p_image.empty()) {
+ if (p_image.is_null() || p_image->empty()) {
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
@@ -894,23 +894,26 @@ Vector<Color> GIProbe::_get_bake_texture(Image &p_image, const Color &p_color) {
return ret;
}
+ p_image = p_image->duplicate();
- if (p_image.is_compressed()) {
+ if (p_image->is_compressed()) {
print_line("DECOMPRESSING!!!!");
- p_image.decompress();
+
+ p_image->decompress();
}
- p_image.convert(Image::FORMAT_RGBA8);
- p_image.resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
+ p_image->convert(Image::FORMAT_RGBA8);
+ p_image->resize(bake_texture_size, bake_texture_size, Image::INTERPOLATE_CUBIC);
- PoolVector<uint8_t>::Read r = p_image.get_data().read();
+ PoolVector<uint8_t>::Read r = p_image->get_data().read();
ret.resize(bake_texture_size * bake_texture_size);
for (int i = 0; i < bake_texture_size * bake_texture_size; i++) {
Color c;
- c.r = r[i * 4 + 0] / 255.0;
- c.g = r[i * 4 + 1] / 255.0;
- c.b = r[i * 4 + 2] / 255.0;
+ c.r = (r[i * 4 + 0] / 255.0) * p_color.r;
+ c.g = (r[i * 4 + 1] / 255.0) * p_color.g;
+ c.b = (r[i * 4 + 2] / 255.0) * p_color.b;
c.a = r[i * 4 + 3] / 255.0;
+
ret[i] = c;
}
@@ -934,7 +937,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
Ref<Texture> albedo_tex = mat->get_texture(SpatialMaterial::TEXTURE_ALBEDO);
- Image img_albedo;
+ Ref<Image> img_albedo;
if (albedo_tex.is_valid()) {
img_albedo = albedo_tex->get_data();
@@ -950,7 +953,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
emission_col.g *= mat->get_emission_energy();
emission_col.b *= mat->get_emission_energy();
- Image img_emission;
+ Ref<Image> img_emission;
if (emission_tex.is_valid()) {
@@ -960,7 +963,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
mc.emission = _get_bake_texture(img_emission, emission_col);
} else {
- Image empty;
+ Ref<Image> empty;
mc.albedo = _get_bake_texture(empty, Color(0.7, 0.7, 0.7));
mc.emission = _get_bake_texture(empty, Color(0, 0, 0));
@@ -970,7 +973,7 @@ GIProbe::Baker::MaterialCache GIProbe::_get_material_cache(Ref<Material> p_mater
return mc;
}
-void GIProbe::_plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) {
+void GIProbe::_plot_mesh(const Transform &p_xform, Ref<ArrayMesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material) {
for (int i = 0; i < p_mesh->get_surface_count(); i++) {
@@ -1064,7 +1067,7 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) {
MeshInstance *mi = p_at_node->cast_to<MeshInstance>();
if (mi && mi->get_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT)) {
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
Rect3 aabb = mesh->get_aabb();
@@ -1091,7 +1094,7 @@ void GIProbe::_find_meshes(Node *p_at_node, Baker *p_baker) {
for (int i = 0; i < meshes.size(); i += 2) {
Transform mxf = meshes[i];
- Ref<Mesh> mesh = meshes[i + 1];
+ Ref<ArrayMesh> mesh = meshes[i + 1];
if (!mesh.is_valid())
continue;
@@ -1152,7 +1155,7 @@ void GIProbe::bake(Node *p_from_node, bool p_create_visual_debug) {
Transform to_bounds;
to_bounds.basis.scale(Vector3(baker.po2_bounds.size[longest_axis], baker.po2_bounds.size[longest_axis], baker.po2_bounds.size[longest_axis]));
- to_bounds.origin = baker.po2_bounds.pos;
+ to_bounds.origin = baker.po2_bounds.position;
Transform to_grid;
to_grid.basis.scale(Vector3(baker.axis_cell_size[longest_axis], baker.axis_cell_size[longest_axis], baker.axis_cell_size[longest_axis]));
@@ -1271,12 +1274,13 @@ void GIProbe::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<Multi
if (p_level == p_baker->cell_subdiv - 1) {
- Vector3 center = p_aabb.pos + p_aabb.size * 0.5;
+ Vector3 center = p_aabb.position + p_aabb.size * 0.5;
Transform xform;
xform.origin = center;
xform.basis.scale(p_aabb.size * 0.5);
p_multimesh->set_instance_transform(idx, xform);
Color col = Color(p_baker->bake_cells[p_idx].albedo[0], p_baker->bake_cells[p_idx].albedo[1], p_baker->bake_cells[p_idx].albedo[2]);
+ //Color col = Color(p_baker->bake_cells[p_idx].emission[0], p_baker->bake_cells[p_idx].emission[1], p_baker->bake_cells[p_idx].emission[2]);
p_multimesh->set_instance_color(idx, col);
idx++;
@@ -1292,11 +1296,11 @@ void GIProbe::_debug_mesh(int p_idx, int p_level, const Rect3 &p_aabb, Ref<Multi
aabb.size *= 0.5;
if (i & 1)
- aabb.pos.x += aabb.size.x;
+ aabb.position.x += aabb.size.x;
if (i & 2)
- aabb.pos.y += aabb.size.y;
+ aabb.position.y += aabb.size.y;
if (i & 4)
- aabb.pos.z += aabb.size.z;
+ aabb.position.z += aabb.size.z;
_debug_mesh(p_baker->bake_cells[p_idx].childs[i], p_level + 1, aabb, p_multimesh, idx, p_baker);
}
@@ -1313,7 +1317,7 @@ void GIProbe::_create_debug_mesh(Baker *p_baker) {
print_line("leaf voxels: " + itos(p_baker->leaf_voxel_count));
mm->set_instance_count(p_baker->leaf_voxel_count);
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
mesh.instance();
{
@@ -1464,7 +1468,7 @@ GIProbe::GIProbe() {
subdiv = SUBDIV_128;
dynamic_range = 4;
energy = 1.0;
- bias = 0.4;
+ bias = 1.8;
propagation = 1.0;
extents = Vector3(10, 10, 10);
color_scan_cell_width = 4;
diff --git a/scene/3d/gi_probe.h b/scene/3d/gi_probe.h
index ae89a6f068..b5ee86455e 100644
--- a/scene/3d/gi_probe.h
+++ b/scene/3d/gi_probe.h
@@ -134,7 +134,7 @@ private:
Vector<Color> emission;
};
- Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
+ Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color);
Map<Ref<Material>, MaterialCache> material_cache;
MaterialCache _get_material_cache(Ref<Material> p_material);
int leaf_voxel_count;
@@ -145,7 +145,7 @@ private:
struct PlotMesh {
Ref<Material> override_material;
Vector<Ref<Material> > instance_materials;
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
Transform local_xform;
};
@@ -170,10 +170,10 @@ private:
int color_scan_cell_width;
int bake_texture_size;
- Vector<Color> _get_bake_texture(Image &p_image, const Color &p_color);
+ Vector<Color> _get_bake_texture(Ref<Image> p_image, const Color &p_color);
Baker::MaterialCache _get_material_cache(Ref<Material> p_material, Baker *p_baker);
void _plot_face(int p_idx, int p_level, int p_x, int p_y, int p_z, const Vector3 *p_vtx, const Vector2 *p_uv, const Baker::MaterialCache &p_material, const Rect3 &p_aabb, Baker *p_baker);
- void _plot_mesh(const Transform &p_xform, Ref<Mesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material);
+ void _plot_mesh(const Transform &p_xform, Ref<ArrayMesh> &p_mesh, Baker *p_baker, const Vector<Ref<Material> > &p_materials, const Ref<Material> &p_override_material);
void _find_meshes(Node *p_at_node, Baker *p_baker);
void _fixup_plot(int p_idx, int p_level, int p_x, int p_y, int p_z, Baker *p_baker);
diff --git a/scene/3d/immediate_geometry.cpp b/scene/3d/immediate_geometry.cpp
index 8c1ad1d052..128c8b44c3 100644
--- a/scene/3d/immediate_geometry.cpp
+++ b/scene/3d/immediate_geometry.cpp
@@ -65,7 +65,7 @@ void ImmediateGeometry::add_vertex(const Vector3 &p_vertex) {
VS::get_singleton()->immediate_vertex(im, p_vertex);
if (empty) {
- aabb.pos = p_vertex;
+ aabb.position = p_vertex;
aabb.size = Vector3();
empty = false;
} else {
diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp
index bb14ad5108..9c87acec6e 100644
--- a/scene/3d/light.cpp
+++ b/scene/3d/light.cpp
@@ -29,7 +29,6 @@
/*************************************************************************/
#include "light.h"
-#include "baked_light_instance.h"
#include "global_config.h"
#include "scene/resources/surface_tool.h"
@@ -166,26 +165,9 @@ void Light::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
_update_visibility();
-
- Node *node = this;
-
- while (node) {
-
- baked_light = node->cast_to<BakedLight>();
- if (baked_light) {
- baked_light->lights.insert(this);
- break;
- }
-
- node = node->get_parent();
- }
}
if (p_what == NOTIFICATION_EXIT_TREE) {
-
- if (baked_light) {
- baked_light->lights.erase(this);
- }
}
}
@@ -252,7 +234,7 @@ void Light::_bind_methods() {
BIND_CONSTANT(PARAM_SHADOW_SPLIT_3_OFFSET);
BIND_CONSTANT(PARAM_SHADOW_NORMAL_BIAS);
BIND_CONSTANT(PARAM_SHADOW_BIAS);
- BIND_CONSTANT(PARAM_SHADOW_BIAS_SPLIT_SCALE);
+
BIND_CONSTANT(PARAM_MAX);
}
@@ -262,8 +244,6 @@ Light::Light(VisualServer::LightType p_type) {
light = VisualServer::get_singleton()->light_create(p_type);
VS::get_singleton()->instance_set_base(get_instance(), light);
- baked_light = NULL;
-
editor_only = false;
set_color(Color(1, 1, 1, 1));
set_shadow(false);
@@ -281,9 +261,8 @@ Light::Light(VisualServer::LightType p_type) {
set_param(PARAM_SHADOW_SPLIT_1_OFFSET, 0.1);
set_param(PARAM_SHADOW_SPLIT_2_OFFSET, 0.2);
set_param(PARAM_SHADOW_SPLIT_3_OFFSET, 0.5);
- set_param(PARAM_SHADOW_NORMAL_BIAS, 0.1);
- set_param(PARAM_SHADOW_BIAS, 0.1);
- set_param(PARAM_SHADOW_BIAS_SPLIT_SCALE, 0.1);
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 0.0);
+ set_param(PARAM_SHADOW_BIAS, 0.15);
}
Light::Light() {
@@ -338,7 +317,6 @@ void DirectionalLight::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "directional_shadow_blend_splits"), "set_blend_splits", "is_blend_splits_enabled");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_normal_bias", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_NORMAL_BIAS);
- ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_bias_split_scale", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_param", "get_param", PARAM_SHADOW_BIAS_SPLIT_SCALE);
BIND_CONSTANT(SHADOW_ORTHOGONAL);
BIND_CONSTANT(SHADOW_PARALLEL_2_SPLITS);
@@ -348,7 +326,11 @@ void DirectionalLight::_bind_methods() {
DirectionalLight::DirectionalLight()
: Light(VisualServer::LIGHT_DIRECTIONAL) {
+ set_param(PARAM_SHADOW_NORMAL_BIAS, 0.2);
+ set_param(PARAM_SHADOW_BIAS, 1.0);
+ set_param(PARAM_SHADOW_MAX_DISTANCE, 200);
set_shadow_mode(SHADOW_PARALLEL_4_SPLITS);
+
blend_splits = false;
}
@@ -391,7 +373,7 @@ void OmniLight::_bind_methods() {
OmniLight::OmniLight()
: Light(VisualServer::LIGHT_OMNI) {
- set_shadow_mode(SHADOW_DUAL_PARABOLOID);
+ set_shadow_mode(SHADOW_CUBE);
set_shadow_detail(SHADOW_DETAIL_HORIZONTAL);
}
diff --git a/scene/3d/light.h b/scene/3d/light.h
index ed8758b09b..22ff5c0763 100644
--- a/scene/3d/light.h
+++ b/scene/3d/light.h
@@ -60,7 +60,6 @@ public:
PARAM_SHADOW_SPLIT_3_OFFSET = VS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
PARAM_SHADOW_NORMAL_BIAS = VS::LIGHT_PARAM_SHADOW_NORMAL_BIAS,
PARAM_SHADOW_BIAS = VS::LIGHT_PARAM_SHADOW_BIAS,
- PARAM_SHADOW_BIAS_SPLIT_SCALE = VS::LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
PARAM_MAX = VS::LIGHT_PARAM_MAX
};
@@ -75,7 +74,6 @@ private:
bool editor_only;
void _update_visibility();
- BakedLight *baked_light;
// bind helpers
protected:
diff --git a/scene/3d/listener.cpp b/scene/3d/listener.cpp
index 148afbffa2..c7d3bac2f8 100644
--- a/scene/3d/listener.cpp
+++ b/scene/3d/listener.cpp
@@ -152,7 +152,7 @@ bool Listener::_can_gizmo_scale() const {
}
RES Listener::_get_gizmo_geometry() const {
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
return mesh;
}
diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp
index 13fd852fe7..82f6f665db 100644
--- a/scene/3d/navigation_mesh.cpp
+++ b/scene/3d/navigation_mesh.cpp
@@ -187,7 +187,7 @@ Ref<Mesh> NavigationMesh::get_debug_mesh() {
}
}
- debug_mesh = Ref<Mesh>(memnew(Mesh));
+ debug_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Array arr;
arr.resize(Mesh::ARRAY_MAX);
diff --git a/scene/3d/navigation_mesh.h b/scene/3d/navigation_mesh.h
index c8f6d936aa..e5a3dc7b43 100644
--- a/scene/3d/navigation_mesh.h
+++ b/scene/3d/navigation_mesh.h
@@ -44,7 +44,7 @@ class NavigationMesh : public Resource {
Vector<int> indices;
};
Vector<Polygon> polygons;
- Ref<Mesh> debug_mesh;
+ Ref<ArrayMesh> debug_mesh;
struct _EdgeKey {
diff --git a/scene/3d/particles.cpp b/scene/3d/particles.cpp
index 038ca33a41..71079ea780 100644
--- a/scene/3d/particles.cpp
+++ b/scene/3d/particles.cpp
@@ -48,11 +48,13 @@ void Particles::set_emitting(bool p_emitting) {
void Particles::set_amount(int p_amount) {
+ ERR_FAIL_COND(p_amount < 1);
amount = p_amount;
VS::get_singleton()->particles_set_amount(particles, amount);
}
void Particles::set_lifetime(float p_lifetime) {
+ ERR_FAIL_COND(p_lifetime <= 0);
lifetime = p_lifetime;
VS::get_singleton()->particles_set_lifetime(particles, lifetime);
}
diff --git a/scene/3d/path.cpp b/scene/3d/path.cpp
index d535c545a8..5c29918118 100644
--- a/scene/3d/path.cpp
+++ b/scene/3d/path.cpp
@@ -108,40 +108,58 @@ void PathFollow::_update_transform() {
Vector3 pos = c->interpolate_baked(o, cubic);
Transform t = get_transform();
- if (rotation_mode != ROTATION_NONE) {
-
- Vector3 n = (c->interpolate_baked(o + lookahead, cubic) - pos).normalized();
-
- if (rotation_mode == ROTATION_Y) {
+ t.origin = pos;
+ Vector3 pos_offset = Vector3(h_offset, v_offset, 0);
- n.y = 0;
- n.normalize();
- }
+ if (rotation_mode != ROTATION_NONE) {
+ // perform parallel transport
+ //
+ // see C. Dougan, The Parallel Transport Frame, Game Programming Gems 2 for example
+ // for a discussion about why not Frenet frame.
+
+ Vector3 t_prev = pos - c->interpolate_baked(o - lookahead, cubic);
+ Vector3 t_cur = c->interpolate_baked(o + lookahead, cubic) - pos;
+
+ Vector3 axis = t_prev.cross(t_cur);
+ float dot = t_prev.normalized().dot(t_cur.normalized());
+ float angle = Math::acos(CLAMP(dot, -1, 1));
+
+ if (axis.length() > CMP_EPSILON && angle > CMP_EPSILON) {
+ if (rotation_mode == ROTATION_Y) {
+ // assuming we're referring to global Y-axis. is this correct?
+ axis.x = 0;
+ axis.z = 0;
+ } else if (rotation_mode == ROTATION_XY) {
+ axis.z = 0;
+ } else if (rotation_mode == ROTATION_XYZ) {
+ // all components are OK
+ }
- if (n.length() < CMP_EPSILON) { //nothing, use previous
- n = -t.get_basis().get_axis(2).normalized();
+ t.rotate_basis(axis.normalized(), angle);
}
- Vector3 up = Vector3(0, 1, 0);
-
- if (rotation_mode == ROTATION_XYZ) {
-
- float tilt = c->interpolate_baked_tilt(o);
- if (tilt != 0) {
-
- Basis rot(-n, tilt); //remember.. lookat will be znegative.. znegative!! we abide by opengl clan.
- up = rot.xform(up);
+ // do the additional tilting
+ float tilt_angle = c->interpolate_baked_tilt(o);
+ Vector3 tilt_axis = t_cur; // is this correct??
+
+ if (tilt_axis.length() > CMP_EPSILON && tilt_angle > CMP_EPSILON) {
+ if (rotation_mode == ROTATION_Y) {
+ tilt_axis.x = 0;
+ tilt_axis.z = 0;
+ } else if (rotation_mode == ROTATION_XY) {
+ tilt_axis.z = 0;
+ } else if (rotation_mode == ROTATION_XYZ) {
+ // all components are OK
}
- }
- t.set_look_at(pos, pos + n, up);
+ t.rotate_basis(tilt_axis.normalized(), tilt_angle);
+ }
+ t.translate(pos_offset);
} else {
-
- t.origin = pos;
+ t.origin += pos_offset;
}
- t.origin += t.basis.get_axis(0) * h_offset + t.basis.get_axis(1) * v_offset;
set_transform(t);
}
diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp
index 98babedf0d..3a55a2bc32 100644
--- a/scene/3d/physics_body.cpp
+++ b/scene/3d/physics_body.cpp
@@ -59,15 +59,15 @@ float PhysicsBody::get_inverse_mass() const {
return 0;
}
-void PhysicsBody::set_collision_layer(uint32_t p_mask) {
+void PhysicsBody::set_collision_layer(uint32_t p_layer) {
- layer_mask = p_mask;
- PhysicsServer::get_singleton()->body_set_layer_mask(get_rid(), p_mask);
+ collision_layer = p_layer;
+ PhysicsServer::get_singleton()->body_set_collision_layer(get_rid(), p_layer);
}
uint32_t PhysicsBody::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void PhysicsBody::set_collision_mask(uint32_t p_mask) {
@@ -167,7 +167,7 @@ void PhysicsBody::_bind_methods() {
PhysicsBody::PhysicsBody(PhysicsServer::BodyMode p_mode)
: CollisionObject(PhysicsServer::get_singleton()->body_create(p_mode), false) {
- layer_mask = 1;
+ collision_layer = 1;
collision_mask = 1;
}
diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h
index d13f84dc15..db4147f8f6 100644
--- a/scene/3d/physics_body.h
+++ b/scene/3d/physics_body.h
@@ -38,7 +38,7 @@ class PhysicsBody : public CollisionObject {
GDCLASS(PhysicsBody, CollisionObject);
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t collision_mask;
void _set_layers(uint32_t p_mask);
@@ -54,7 +54,7 @@ public:
virtual Vector3 get_angular_velocity() const;
virtual float get_inverse_mass() const;
- void set_collision_layer(uint32_t p_mask);
+ void set_collision_layer(uint32_t p_layer);
uint32_t get_collision_layer() const;
void set_collision_mask(uint32_t p_mask);
diff --git a/scene/3d/quad.cpp b/scene/3d/quad.cpp
deleted file mode 100644
index c3d83ad50d..0000000000
--- a/scene/3d/quad.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-/*************************************************************************/
-/* quad.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 "quad.h"
-#include "servers/visual_server.h"
-
-void Quad::_update() {
-
- if (!is_inside_tree())
- return;
-
- Vector3 normal;
- normal[axis] = 1.0;
-
- const int axis_order_1[3] = { 1, 2, 0 };
- const int axis_order_2[3] = { 2, 0, 1 };
- const int a1 = axis_order_1[axis];
- const int a2 = axis_order_2[axis];
-
- PoolVector<Vector3> points;
- points.resize(4);
- PoolVector<Vector3>::Write pointsw = points.write();
-
- Vector2 s2 = size * 0.5;
- Vector2 o = offset;
- if (!centered)
- o += s2;
-
- pointsw[0][a1] = -s2.x + offset.x;
- pointsw[0][a2] = s2.y + offset.y;
-
- pointsw[1][a1] = s2.x + offset.x;
- pointsw[1][a2] = s2.y + offset.y;
-
- pointsw[2][a1] = s2.x + offset.x;
- pointsw[2][a2] = -s2.y + offset.y;
-
- pointsw[3][a1] = -s2.x + offset.x;
- pointsw[3][a2] = -s2.y + offset.y;
-
- aabb = Rect3(pointsw[0], Vector3());
- for (int i = 1; i < 4; i++)
- aabb.expand_to(pointsw[i]);
-
- pointsw = PoolVector<Vector3>::Write();
-
- PoolVector<Vector3> normals;
- normals.resize(4);
- PoolVector<Vector3>::Write normalsw = normals.write();
-
- for (int i = 0; i < 4; i++)
- normalsw[i] = normal;
-
- normalsw = PoolVector<Vector3>::Write();
-
- PoolVector<Vector2> uvs;
- uvs.resize(4);
- PoolVector<Vector2>::Write uvsw = uvs.write();
-
- uvsw[0] = Vector2(0, 0);
- uvsw[1] = Vector2(1, 0);
- uvsw[2] = Vector2(1, 1);
- uvsw[3] = Vector2(0, 1);
-
- uvsw = PoolVector<Vector2>::Write();
-
- PoolVector<int> indices;
- indices.resize(6);
-
- PoolVector<int>::Write indicesw = indices.write();
- indicesw[0] = 0;
- indicesw[1] = 1;
- indicesw[2] = 2;
- indicesw[3] = 2;
- indicesw[4] = 3;
- indicesw[5] = 0;
-
- indicesw = PoolVector<int>::Write();
-
- Array arr;
- arr.resize(VS::ARRAY_MAX);
- arr[VS::ARRAY_VERTEX] = points;
- arr[VS::ARRAY_NORMAL] = normals;
- arr[VS::ARRAY_TEX_UV] = uvs;
- arr[VS::ARRAY_INDEX] = indices;
-
- if (configured) {
- VS::get_singleton()->mesh_remove_surface(mesh, 0);
- } else {
- configured = true;
- }
- VS::get_singleton()->mesh_add_surface_from_arrays(mesh, VS::PRIMITIVE_TRIANGLES, arr);
-
- pending_update = false;
-}
-
-void Quad::set_axis(Vector3::Axis p_axis) {
-
- axis = p_axis;
- _update();
-}
-
-Vector3::Axis Quad::get_axis() const {
-
- return axis;
-}
-
-void Quad::set_size(const Vector2 &p_size) {
-
- size = p_size;
- _update();
-}
-Vector2 Quad::get_size() const {
-
- return size;
-}
-
-void Quad::set_offset(const Vector2 &p_offset) {
-
- offset = p_offset;
- _update();
-}
-Vector2 Quad::get_offset() const {
-
- return offset;
-}
-
-void Quad::set_centered(bool p_enabled) {
-
- centered = p_enabled;
- _update();
-}
-bool Quad::is_centered() const {
-
- return centered;
-}
-
-void Quad::_notification(int p_what) {
-
- switch (p_what) {
-
- case NOTIFICATION_ENTER_TREE: {
-
- if (pending_update)
- _update();
-
- } break;
- case NOTIFICATION_EXIT_TREE: {
-
- pending_update = true;
-
- } break;
- }
-}
-
-PoolVector<Face3> Quad::get_faces(uint32_t p_usage_flags) const {
-
- return PoolVector<Face3>();
-}
-
-Rect3 Quad::get_aabb() const {
-
- return aabb;
-}
-
-void Quad::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_axis", "axis"), &Quad::set_axis);
- ClassDB::bind_method(D_METHOD("get_axis"), &Quad::get_axis);
-
- ClassDB::bind_method(D_METHOD("set_size", "size"), &Quad::set_size);
- ClassDB::bind_method(D_METHOD("get_size"), &Quad::get_size);
-
- ClassDB::bind_method(D_METHOD("set_centered", "centered"), &Quad::set_centered);
- ClassDB::bind_method(D_METHOD("is_centered"), &Quad::is_centered);
-
- ClassDB::bind_method(D_METHOD("set_offset", "offset"), &Quad::set_offset);
- ClassDB::bind_method(D_METHOD("get_offset"), &Quad::get_offset);
-
- ADD_PROPERTY(PropertyInfo(Variant::INT, "axis", PROPERTY_HINT_ENUM, "X,Y,Z"), "set_axis", "get_axis");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
- ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "offset"), "set_offset", "get_offset");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "centered"), "set_centered", "is_centered");
-}
-
-Quad::Quad() {
-
- pending_update = true;
- centered = true;
- //offset=0;
- size = Vector2(1, 1);
- axis = Vector3::AXIS_Z;
- mesh = VisualServer::get_singleton()->mesh_create();
- set_base(mesh);
- configured = false;
-}
-
-Quad::~Quad() {
- VisualServer::get_singleton()->free(mesh);
-}
diff --git a/scene/3d/ray_cast.cpp b/scene/3d/ray_cast.cpp
index d24aa6ae2a..67e7fb0e12 100644
--- a/scene/3d/ray_cast.cpp
+++ b/scene/3d/ray_cast.cpp
@@ -46,14 +46,14 @@ Vector3 RayCast::get_cast_to() const {
return cast_to;
}
-void RayCast::set_layer_mask(uint32_t p_mask) {
+void RayCast::set_collision_layer(uint32_t p_layer) {
- layer_mask = p_mask;
+ collision_layer = p_layer;
}
-uint32_t RayCast::get_layer_mask() const {
+uint32_t RayCast::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void RayCast::set_type_mask(uint32_t p_mask) {
@@ -170,7 +170,7 @@ void RayCast::_update_raycast_state() {
PhysicsDirectSpaceState::RayResult rr;
- if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) {
+ if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, collision_layer, type_mask)) {
collided = true;
against = rr.collider_id;
@@ -243,15 +243,15 @@ void RayCast::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast::clear_exceptions);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &RayCast::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &RayCast::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast::set_type_mask);
ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast::get_type_mask);
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask");
}
@@ -266,7 +266,7 @@ void RayCast::_create_debug_shape() {
line_material->set_albedo(Color(1.0, 0.8, 0.6));
}
- Ref<Mesh> mesh = memnew(Mesh);
+ Ref<ArrayMesh> mesh = memnew(ArrayMesh);
MeshInstance *mi = memnew(MeshInstance);
mi->set_mesh(mesh);
@@ -287,7 +287,7 @@ void RayCast::_update_debug_shape() {
if (!mi->get_mesh().is_valid())
return;
- Ref<Mesh> mesh = mi->get_mesh();
+ Ref<ArrayMesh> mesh = mi->get_mesh();
if (mesh->get_surface_count() > 0)
mesh->surface_remove(0);
@@ -323,7 +323,7 @@ RayCast::RayCast() {
against = 0;
collided = false;
against_shape = 0;
- layer_mask = 1;
+ collision_layer = 1;
type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
cast_to = Vector3(0, -1, 0);
debug_shape = NULL;
diff --git a/scene/3d/ray_cast.h b/scene/3d/ray_cast.h
index 63a53d724f..e9b34c4f75 100644
--- a/scene/3d/ray_cast.h
+++ b/scene/3d/ray_cast.h
@@ -47,7 +47,7 @@ class RayCast : public Spatial {
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t type_mask;
Node *debug_shape;
@@ -69,8 +69,8 @@ public:
void set_cast_to(const Vector3 &p_point);
Vector3 get_cast_to() const;
- void set_layer_mask(uint32_t p_mask);
- uint32_t get_layer_mask() const;
+ void set_collision_layer(uint32_t p_layer);
+ uint32_t get_collision_layer() const;
void set_type_mask(uint32_t p_mask);
uint32_t get_type_mask() const;
diff --git a/scene/3d/reflection_probe.cpp b/scene/3d/reflection_probe.cpp
index 845245b090..86a62bec97 100644
--- a/scene/3d/reflection_probe.cpp
+++ b/scene/3d/reflection_probe.cpp
@@ -181,7 +181,7 @@ ReflectionProbe::UpdateMode ReflectionProbe::get_update_mode() const {
Rect3 ReflectionProbe::get_aabb() const {
Rect3 aabb;
- aabb.pos = -origin_offset;
+ aabb.position = -origin_offset;
aabb.size = origin_offset + extents;
return aabb;
}
diff --git a/scene/3d/sprite_3d.cpp b/scene/3d/sprite_3d.cpp
index c37ce98be8..b6c59ba277 100644
--- a/scene/3d/sprite_3d.cpp
+++ b/scene/3d/sprite_3d.cpp
@@ -337,8 +337,8 @@ void Sprite3D::_draw() {
s = s / Size2i(hframes, vframes);
src_rect.size = s;
- src_rect.pos.x += (frame % hframes) * s.x;
- src_rect.pos.y += (frame / hframes) * s.y;
+ src_rect.position.x += (frame % hframes) * s.x;
+ src_rect.position.y += (frame / hframes) * s.y;
}
Point2i ofs = get_offset();
@@ -362,17 +362,17 @@ void Sprite3D::_draw() {
Vector2 vertices[4] = {
- (final_rect.pos + Vector2(0, final_rect.size.y)) * pixel_size,
- (final_rect.pos + final_rect.size) * pixel_size,
- (final_rect.pos + Vector2(final_rect.size.x, 0)) * pixel_size,
- final_rect.pos * pixel_size,
+ (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
+ (final_rect.position + final_rect.size) * pixel_size,
+ (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
+ final_rect.position * pixel_size,
};
Vector2 uvs[4] = {
- final_src_rect.pos / tsize,
- (final_src_rect.pos + Vector2(final_src_rect.size.x, 0)) / tsize,
- (final_src_rect.pos + final_src_rect.size) / tsize,
- (final_src_rect.pos + Vector2(0, final_src_rect.size.y)) / tsize,
+ final_src_rect.position / tsize,
+ (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / tsize,
+ (final_src_rect.position + final_src_rect.size) / tsize,
+ (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / tsize,
};
if (is_flipped_h()) {
@@ -423,7 +423,7 @@ void Sprite3D::_draw() {
vtx[y_axis] = vertices[i][1];
VS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) {
- aabb.pos = vtx;
+ aabb.position = vtx;
aabb.size = Vector3();
} else {
aabb.expand_to(vtx);
@@ -863,17 +863,17 @@ void AnimatedSprite3D::_draw() {
Vector2 vertices[4] = {
- (final_rect.pos + Vector2(0, final_rect.size.y)) * pixel_size,
- (final_rect.pos + final_rect.size) * pixel_size,
- (final_rect.pos + Vector2(final_rect.size.x, 0)) * pixel_size,
- final_rect.pos * pixel_size,
+ (final_rect.position + Vector2(0, final_rect.size.y)) * pixel_size,
+ (final_rect.position + final_rect.size) * pixel_size,
+ (final_rect.position + Vector2(final_rect.size.x, 0)) * pixel_size,
+ final_rect.position * pixel_size,
};
Vector2 uvs[4] = {
- final_src_rect.pos / tsize,
- (final_src_rect.pos + Vector2(final_src_rect.size.x, 0)) / tsize,
- (final_src_rect.pos + final_src_rect.size) / tsize,
- (final_src_rect.pos + Vector2(0, final_src_rect.size.y)) / tsize,
+ final_src_rect.position / tsize,
+ (final_src_rect.position + Vector2(final_src_rect.size.x, 0)) / tsize,
+ (final_src_rect.position + final_src_rect.size) / tsize,
+ (final_src_rect.position + Vector2(0, final_src_rect.size.y)) / tsize,
};
if (is_flipped_h()) {
@@ -924,7 +924,7 @@ void AnimatedSprite3D::_draw() {
vtx[y_axis] = vertices[i][1];
VS::get_singleton()->immediate_vertex(immediate, vtx);
if (i == 0) {
- aabb.pos = vtx;
+ aabb.position = vtx;
aabb.size = Vector3();
} else {
aabb.expand_to(vtx);
diff --git a/scene/3d/test_cube.cpp b/scene/3d/test_cube.cpp
deleted file mode 100644
index af09bef7a7..0000000000
--- a/scene/3d/test_cube.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*************************************************************************/
-/* test_cube.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 "test_cube.h"
-#include "servers/visual_server.h"
-
-Rect3 TestCube::get_aabb() const {
-
- return Rect3(Vector3(-1, -1, -1), Vector3(2, 2, 2));
-}
-PoolVector<Face3> TestCube::get_faces(uint32_t p_usage_flags) const {
-
- return PoolVector<Face3>();
-}
-
-TestCube::TestCube() {
-
- set_base(VisualServer::get_singleton()->get_test_cube());
-}
-
-TestCube::~TestCube() {
-}
diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp
index 38e1ba1cd5..8d927e529e 100644
--- a/scene/3d/vehicle_body.cpp
+++ b/scene/3d/vehicle_body.cpp
@@ -214,6 +214,18 @@ float VehicleWheel::get_friction_slip() const {
return m_frictionSlip;
}
+void VehicleWheel::set_roll_influence(float p_value) {
+ m_rollInfluence = p_value;
+}
+
+float VehicleWheel::get_roll_influence() const {
+ return m_rollInfluence;
+}
+
+bool VehicleWheel::is_in_contact() const {
+ return m_raycastInfo.m_isInContact;
+}
+
void VehicleWheel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_radius", "length"), &VehicleWheel::set_radius);
@@ -246,9 +258,15 @@ void VehicleWheel::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_friction_slip", "length"), &VehicleWheel::set_friction_slip);
ClassDB::bind_method(D_METHOD("get_friction_slip"), &VehicleWheel::get_friction_slip);
+ ClassDB::bind_method(D_METHOD("is_in_contact"), &VehicleWheel::is_in_contact);
+
+ ClassDB::bind_method(D_METHOD("set_roll_influence", "roll_influence"), &VehicleWheel::set_roll_influence);
+ ClassDB::bind_method(D_METHOD("get_roll_influence"), &VehicleWheel::get_roll_influence);
+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_traction"), "set_use_as_traction", "is_used_as_traction");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_as_steering"), "set_use_as_steering", "is_used_as_steering");
ADD_GROUP("Wheel", "wheel_");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_roll_influence"), "set_roll_influence", "get_roll_influence");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_radius"), "set_radius", "get_radius");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_rest_length"), "set_suspension_rest_length", "get_suspension_rest_length");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "wheel_friction_slip"), "set_friction_slip", "get_friction_slip");
diff --git a/scene/3d/vehicle_body.h b/scene/3d/vehicle_body.h
index cdb2ebc0be..7ed9bce730 100644
--- a/scene/3d/vehicle_body.h
+++ b/scene/3d/vehicle_body.h
@@ -126,6 +126,11 @@ public:
void set_use_as_steering(bool p_enabled);
bool is_used_as_steering() const;
+ bool is_in_contact() const;
+
+ void set_roll_influence(float p_value);
+ float get_roll_influence() const;
+
VehicleWheel();
};
diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp
index c4ea42d461..543b64bd15 100644
--- a/scene/animation/animation_player.cpp
+++ b/scene/animation/animation_player.cpp
@@ -202,6 +202,7 @@ void AnimationPlayer::_notification(int p_what) {
if (!get_tree()->is_editor_hint() && animation_set.has(autoplay)) {
play(autoplay);
set_autoplay(""); //this line is the fix for autoplay issues with animatio
+ _animation_process(0);
}
} break;
case NOTIFICATION_INTERNAL_PROCESS: {
diff --git a/scene/animation/tween.cpp b/scene/animation/tween.cpp
index 2a6ffb5628..67920d177e 100644
--- a/scene/animation/tween.cpp
+++ b/scene/animation/tween.cpp
@@ -421,9 +421,9 @@ Variant Tween::_run_equation(InterpolateData &p_data) {
Rect3 d = delta_val;
Rect3 r;
- APPLY_EQUATION(pos.x);
- APPLY_EQUATION(pos.y);
- APPLY_EQUATION(pos.z);
+ APPLY_EQUATION(position.x);
+ APPLY_EQUATION(position.y);
+ APPLY_EQUATION(position.z);
APPLY_EQUATION(size.x);
APPLY_EQUATION(size.y);
APPLY_EQUATION(size.z);
@@ -963,7 +963,7 @@ bool Tween::_calc_delta_val(const Variant &p_initial_val, const Variant &p_final
case Variant::RECT3: {
Rect3 i = initial_val;
Rect3 f = final_val;
- delta_val = Rect3(f.pos - i.pos, f.size - i.size);
+ delta_val = Rect3(f.position - i.position, f.size - i.size);
} break;
case Variant::TRANSFORM: {
Transform i = initial_val;
diff --git a/scene/audio/audio_player.cpp b/scene/audio/audio_player.cpp
index a320a30e8a..bcca834642 100644
--- a/scene/audio/audio_player.cpp
+++ b/scene/audio/audio_player.cpp
@@ -29,7 +29,7 @@
/*************************************************************************/
#include "audio_player.h"
-void AudioPlayer::_mix_audio() {
+void AudioStreamPlayer::_mix_audio() {
if (!stream_playback.is_valid()) {
return;
@@ -95,7 +95,7 @@ void AudioPlayer::_mix_audio() {
}
}
-void AudioPlayer::_notification(int p_what) {
+void AudioStreamPlayer::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
@@ -111,8 +111,9 @@ void AudioPlayer::_notification(int p_what) {
}
}
-void AudioPlayer::set_stream(Ref<AudioStream> p_stream) {
+void AudioStreamPlayer::set_stream(Ref<AudioStream> p_stream) {
+ ERR_FAIL_COND(!p_stream.is_valid());
AudioServer::get_singleton()->lock();
mix_buffer.resize(AudioServer::get_singleton()->thread_get_mix_buffer_size());
@@ -135,21 +136,21 @@ void AudioPlayer::set_stream(Ref<AudioStream> p_stream) {
AudioServer::get_singleton()->unlock();
}
-Ref<AudioStream> AudioPlayer::get_stream() const {
+Ref<AudioStream> AudioStreamPlayer::get_stream() const {
return stream;
}
-void AudioPlayer::set_volume_db(float p_volume) {
+void AudioStreamPlayer::set_volume_db(float p_volume) {
volume_db = p_volume;
}
-float AudioPlayer::get_volume_db() const {
+float AudioStreamPlayer::get_volume_db() const {
return volume_db;
}
-void AudioPlayer::play(float p_from_pos) {
+void AudioStreamPlayer::play(float p_from_pos) {
if (stream_playback.is_valid()) {
mix_volume_db = volume_db; //reset volume ramp
@@ -158,21 +159,21 @@ void AudioPlayer::play(float p_from_pos) {
}
}
-void AudioPlayer::seek(float p_seconds) {
+void AudioStreamPlayer::seek(float p_seconds) {
if (stream_playback.is_valid()) {
setseek = p_seconds;
}
}
-void AudioPlayer::stop() {
+void AudioStreamPlayer::stop() {
if (stream_playback.is_valid()) {
active = false;
}
}
-bool AudioPlayer::is_playing() const {
+bool AudioStreamPlayer::is_playing() const {
if (stream_playback.is_valid()) {
return active && stream_playback->is_playing();
@@ -181,7 +182,7 @@ bool AudioPlayer::is_playing() const {
return false;
}
-float AudioPlayer::get_pos() {
+float AudioStreamPlayer::get_pos() {
if (stream_playback.is_valid()) {
return stream_playback->get_pos();
@@ -190,14 +191,14 @@ float AudioPlayer::get_pos() {
return 0;
}
-void AudioPlayer::set_bus(const StringName &p_bus) {
+void AudioStreamPlayer::set_bus(const StringName &p_bus) {
//if audio is active, must lock this
AudioServer::get_singleton()->lock();
bus = p_bus;
AudioServer::get_singleton()->unlock();
}
-StringName AudioPlayer::get_bus() const {
+StringName AudioStreamPlayer::get_bus() const {
for (int i = 0; i < AudioServer::get_singleton()->get_bus_count(); i++) {
if (AudioServer::get_singleton()->get_bus_name(i) == bus) {
@@ -207,38 +208,38 @@ StringName AudioPlayer::get_bus() const {
return "Master";
}
-void AudioPlayer::set_autoplay(bool p_enable) {
+void AudioStreamPlayer::set_autoplay(bool p_enable) {
autoplay = p_enable;
}
-bool AudioPlayer::is_autoplay_enabled() {
+bool AudioStreamPlayer::is_autoplay_enabled() {
return autoplay;
}
-void AudioPlayer::set_mix_target(MixTarget p_target) {
+void AudioStreamPlayer::set_mix_target(MixTarget p_target) {
mix_target = p_target;
}
-AudioPlayer::MixTarget AudioPlayer::get_mix_target() const {
+AudioStreamPlayer::MixTarget AudioStreamPlayer::get_mix_target() const {
return mix_target;
}
-void AudioPlayer::_set_playing(bool p_enable) {
+void AudioStreamPlayer::_set_playing(bool p_enable) {
if (p_enable)
play();
else
stop();
}
-bool AudioPlayer::_is_active() const {
+bool AudioStreamPlayer::_is_active() const {
return active;
}
-void AudioPlayer::_validate_property(PropertyInfo &property) const {
+void AudioStreamPlayer::_validate_property(PropertyInfo &property) const {
if (property.name == "bus") {
@@ -254,39 +255,39 @@ void AudioPlayer::_validate_property(PropertyInfo &property) const {
}
}
-void AudioPlayer::_bus_layout_changed() {
+void AudioStreamPlayer::_bus_layout_changed() {
_change_notify();
}
-void AudioPlayer::_bind_methods() {
+void AudioStreamPlayer::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioPlayer::set_stream);
- ClassDB::bind_method(D_METHOD("get_stream"), &AudioPlayer::get_stream);
+ ClassDB::bind_method(D_METHOD("set_stream", "stream:AudioStream"), &AudioStreamPlayer::set_stream);
+ ClassDB::bind_method(D_METHOD("get_stream"), &AudioStreamPlayer::get_stream);
- ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioPlayer::set_volume_db);
- ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioPlayer::get_volume_db);
+ ClassDB::bind_method(D_METHOD("set_volume_db", "volume_db"), &AudioStreamPlayer::set_volume_db);
+ ClassDB::bind_method(D_METHOD("get_volume_db"), &AudioStreamPlayer::get_volume_db);
- ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioPlayer::play, DEFVAL(0.0));
- ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioPlayer::seek);
- ClassDB::bind_method(D_METHOD("stop"), &AudioPlayer::stop);
+ ClassDB::bind_method(D_METHOD("play", "from_pos"), &AudioStreamPlayer::play, DEFVAL(0.0));
+ ClassDB::bind_method(D_METHOD("seek", "to_pos"), &AudioStreamPlayer::seek);
+ ClassDB::bind_method(D_METHOD("stop"), &AudioStreamPlayer::stop);
- ClassDB::bind_method(D_METHOD("is_playing"), &AudioPlayer::is_playing);
- ClassDB::bind_method(D_METHOD("get_pos"), &AudioPlayer::get_pos);
+ ClassDB::bind_method(D_METHOD("is_playing"), &AudioStreamPlayer::is_playing);
+ ClassDB::bind_method(D_METHOD("get_pos"), &AudioStreamPlayer::get_pos);
- ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioPlayer::set_bus);
- ClassDB::bind_method(D_METHOD("get_bus"), &AudioPlayer::get_bus);
+ ClassDB::bind_method(D_METHOD("set_bus", "bus"), &AudioStreamPlayer::set_bus);
+ ClassDB::bind_method(D_METHOD("get_bus"), &AudioStreamPlayer::get_bus);
- ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioPlayer::set_autoplay);
- ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioPlayer::is_autoplay_enabled);
+ ClassDB::bind_method(D_METHOD("set_autoplay", "enable"), &AudioStreamPlayer::set_autoplay);
+ ClassDB::bind_method(D_METHOD("is_autoplay_enabled"), &AudioStreamPlayer::is_autoplay_enabled);
- ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioPlayer::set_mix_target);
- ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioPlayer::get_mix_target);
+ ClassDB::bind_method(D_METHOD("set_mix_target", "mix_target"), &AudioStreamPlayer::set_mix_target);
+ ClassDB::bind_method(D_METHOD("get_mix_target"), &AudioStreamPlayer::get_mix_target);
- ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioPlayer::_set_playing);
- ClassDB::bind_method(D_METHOD("_is_active"), &AudioPlayer::_is_active);
+ ClassDB::bind_method(D_METHOD("_set_playing", "enable"), &AudioStreamPlayer::_set_playing);
+ ClassDB::bind_method(D_METHOD("_is_active"), &AudioStreamPlayer::_is_active);
- ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioPlayer::_bus_layout_changed);
+ ClassDB::bind_method(D_METHOD("_bus_layout_changed"), &AudioStreamPlayer::_bus_layout_changed);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "stream", PROPERTY_HINT_RESOURCE_TYPE, "AudioStream"), "set_stream", "get_stream");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "volume_db", PROPERTY_HINT_RANGE, "-80,24"), "set_volume_db", "get_volume_db");
@@ -296,7 +297,7 @@ void AudioPlayer::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::STRING, "bus", PROPERTY_HINT_ENUM, ""), "set_bus", "get_bus");
}
-AudioPlayer::AudioPlayer() {
+AudioStreamPlayer::AudioStreamPlayer() {
mix_volume_db = 0;
volume_db = 0;
@@ -308,5 +309,5 @@ AudioPlayer::AudioPlayer() {
AudioServer::get_singleton()->connect("bus_layout_changed", this, "_bus_layout_changed");
}
-AudioPlayer::~AudioPlayer() {
+AudioStreamPlayer::~AudioStreamPlayer() {
}
diff --git a/scene/audio/audio_player.h b/scene/audio/audio_player.h
index 5a8a8494e1..8bd6844dec 100644
--- a/scene/audio/audio_player.h
+++ b/scene/audio/audio_player.h
@@ -33,9 +33,9 @@
#include "scene/main/node.h"
#include "servers/audio/audio_stream.h"
-class AudioPlayer : public Node {
+class AudioStreamPlayer : public Node {
- GDCLASS(AudioPlayer, Node)
+ GDCLASS(AudioStreamPlayer, Node)
public:
enum MixTarget {
@@ -60,7 +60,7 @@ private:
MixTarget mix_target;
void _mix_audio();
- static void _mix_audios(void *self) { reinterpret_cast<AudioPlayer *>(self)->_mix_audio(); }
+ static void _mix_audios(void *self) { reinterpret_cast<AudioStreamPlayer *>(self)->_mix_audio(); }
void _set_playing(bool p_enable);
bool _is_active() const;
@@ -94,9 +94,9 @@ public:
void set_mix_target(MixTarget p_target);
MixTarget get_mix_target() const;
- AudioPlayer();
- ~AudioPlayer();
+ AudioStreamPlayer();
+ ~AudioStreamPlayer();
};
-VARIANT_ENUM_CAST(AudioPlayer::MixTarget)
+VARIANT_ENUM_CAST(AudioStreamPlayer::MixTarget)
#endif // AUDIOPLAYER_H
diff --git a/scene/gui/base_button.cpp b/scene/gui/base_button.cpp
index 839dcc3678..c1dbc82f3c 100644
--- a/scene/gui/base_button.cpp
+++ b/scene/gui/base_button.cpp
@@ -48,188 +48,185 @@ void BaseButton::_unpress_group() {
}
}
-void BaseButton::_gui_input(InputEvent p_event) {
+void BaseButton::_gui_input(Ref<InputEvent> p_event) {
if (status.disabled) // no interaction with disabled button
return;
- switch (p_event.type) {
+ Ref<InputEventMouseButton> b = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (b.is_valid()) {
+ if (status.disabled || b->get_button_index() != 1)
+ return;
- const InputEventMouseButton &b = p_event.mouse_button;
+ if (status.pressing_button)
+ return;
- if (status.disabled || b.button_index != 1)
- return;
+ if (action_mode == ACTION_MODE_BUTTON_PRESS) {
- if (status.pressing_button)
- break;
+ if (b->is_pressed()) {
- if (action_mode == ACTION_MODE_BUTTON_PRESS) {
-
- if (b.pressed) {
-
- emit_signal("button_down");
-
- if (!toggle_mode) { //mouse press attempt
+ emit_signal("button_down");
- status.press_attempt = true;
- status.pressing_inside = true;
+ if (!toggle_mode) { //mouse press attempt
- pressed();
- if (get_script_instance()) {
- Variant::CallError ce;
- get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
- }
+ status.press_attempt = true;
+ status.pressing_inside = true;
- emit_signal("pressed");
- _unpress_group();
+ pressed();
+ if (get_script_instance()) {
+ Variant::CallError ce;
+ get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
+ }
- } else {
+ emit_signal("pressed");
+ _unpress_group();
- status.pressed = !status.pressed;
- pressed();
- if (get_script_instance()) {
- Variant::CallError ce;
- get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
- }
- emit_signal("pressed");
- _unpress_group();
+ } else {
- toggled(status.pressed);
- emit_signal("toggled", status.pressed);
+ status.pressed = !status.pressed;
+ pressed();
+ if (get_script_instance()) {
+ Variant::CallError ce;
+ get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
}
+ emit_signal("pressed");
+ _unpress_group();
- } else {
+ toggled(status.pressed);
+ emit_signal("toggled", status.pressed);
+ }
+
+ } else {
- emit_signal("button_up");
+ emit_signal("button_up");
- /* this is pointless if (status.press_attempt && status.pressing_inside) {
- //released();
- emit_signal("released");
- }
-*/
- status.press_attempt = false;
+ /* this is pointless if (status.press_attempt && status.pressing_inside) {
+ //released();
+ emit_signal("released");
}
- update();
- break;
+*/
+ status.press_attempt = false;
}
+ update();
+ return;
+ }
- if (b.pressed) {
+ if (b->is_pressed()) {
- status.press_attempt = true;
- status.pressing_inside = true;
- emit_signal("button_down");
+ status.press_attempt = true;
+ status.pressing_inside = true;
+ emit_signal("button_down");
- } else {
+ } else {
- emit_signal("button_up");
+ emit_signal("button_up");
- if (status.press_attempt && status.pressing_inside) {
+ if (status.press_attempt && status.pressing_inside) {
- if (!toggle_mode) { //mouse press attempt
+ if (!toggle_mode) { //mouse press attempt
- pressed();
- if (get_script_instance()) {
- Variant::CallError ce;
- get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
- }
+ pressed();
+ if (get_script_instance()) {
+ Variant::CallError ce;
+ get_script_instance()->call(SceneStringNames::get_singleton()->_pressed, NULL, 0, ce);
+ }
- emit_signal("pressed");
+ emit_signal("pressed");
- } else {
+ } else {
- status.pressed = !status.pressed;
+ status.pressed = !status.pressed;
- pressed();
- emit_signal("pressed");
+ pressed();
+ emit_signal("pressed");
- toggled(status.pressed);
- emit_signal("toggled", status.pressed);
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed);
- }
+ toggled(status.pressed);
+ emit_signal("toggled", status.pressed);
+ if (get_script_instance()) {
+ get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed);
}
-
- _unpress_group();
}
- status.press_attempt = false;
+ _unpress_group();
}
- update();
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- if (status.press_attempt && status.pressing_button == 0) {
- bool last_press_inside = status.pressing_inside;
- status.pressing_inside = has_point(Point2(p_event.mouse_motion.x, p_event.mouse_motion.y));
- if (last_press_inside != status.pressing_inside)
- update();
- }
- } break;
- case InputEvent::ACTION:
- case InputEvent::JOYPAD_BUTTON:
- case InputEvent::KEY: {
+ status.press_attempt = false;
+ }
- if (p_event.is_echo()) {
- break;
- }
+ update();
+ }
- if (status.disabled) {
- break;
- }
+ Ref<InputEventMouseMotion> mm = p_event;
- if (status.press_attempt && status.pressing_button == 0) {
- break;
- }
+ if (mm.is_valid()) {
+ if (status.press_attempt && status.pressing_button == 0) {
+ bool last_press_inside = status.pressing_inside;
+ status.pressing_inside = has_point(mm->get_position());
+ if (last_press_inside != status.pressing_inside)
+ update();
+ }
+ }
- if (p_event.is_action("ui_accept")) {
+ if (!mm.is_valid() && !b.is_valid()) {
- if (p_event.is_pressed()) {
+ if (p_event->is_echo()) {
+ return;
+ }
- status.pressing_button++;
- status.press_attempt = true;
- status.pressing_inside = true;
- emit_signal("button_down");
+ if (status.disabled) {
+ return;
+ }
- } else if (status.press_attempt) {
+ if (status.press_attempt && status.pressing_button == 0) {
+ return;
+ }
- if (status.pressing_button)
- status.pressing_button--;
+ if (p_event->is_action("ui_accept")) {
- if (status.pressing_button)
- break;
+ if (p_event->is_pressed()) {
- status.press_attempt = false;
- status.pressing_inside = false;
+ status.pressing_button++;
+ status.press_attempt = true;
+ status.pressing_inside = true;
+ emit_signal("button_down");
- emit_signal("button_up");
+ } else if (status.press_attempt) {
- if (!toggle_mode) { //mouse press attempt
+ if (status.pressing_button)
+ status.pressing_button--;
- pressed();
- emit_signal("pressed");
- } else {
+ if (status.pressing_button)
+ return;
- status.pressed = !status.pressed;
+ status.press_attempt = false;
+ status.pressing_inside = false;
- pressed();
- emit_signal("pressed");
+ emit_signal("button_up");
- toggled(status.pressed);
- if (get_script_instance()) {
- get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed);
- }
- emit_signal("toggled", status.pressed);
- }
+ if (!toggle_mode) { //mouse press attempt
- _unpress_group();
+ pressed();
+ emit_signal("pressed");
+ } else {
+
+ status.pressed = !status.pressed;
+
+ pressed();
+ emit_signal("pressed");
+
+ toggled(status.pressed);
+ if (get_script_instance()) {
+ get_script_instance()->call(SceneStringNames::get_singleton()->_toggled, status.pressed);
+ }
+ emit_signal("toggled", status.pressed);
}
- accept_event();
- update();
+ _unpress_group();
}
+
+ accept_event();
+ update();
}
}
}
@@ -430,9 +427,9 @@ Ref<ShortCut> BaseButton::get_shortcut() const {
return shortcut;
}
-void BaseButton::_unhandled_input(InputEvent p_event) {
+void BaseButton::_unhandled_input(Ref<InputEvent> p_event) {
- if (!is_disabled() && is_visible_in_tree() && p_event.is_pressed() && !p_event.is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
+ if (!is_disabled() && is_visible_in_tree() && p_event->is_pressed() && !p_event->is_echo() && shortcut.is_valid() && shortcut->is_shortcut(p_event)) {
if (get_viewport()->get_modal_stack_top() && !get_viewport()->get_modal_stack_top()->is_a_parent_of(this))
return; //ignore because of modal window
diff --git a/scene/gui/base_button.h b/scene/gui/base_button.h
index 62b6633bfc..dfcf3b0f8a 100644
--- a/scene/gui/base_button.h
+++ b/scene/gui/base_button.h
@@ -73,8 +73,8 @@ protected:
virtual void pressed();
virtual void toggled(bool p_pressed);
static void _bind_methods();
- virtual void _gui_input(InputEvent p_event);
- virtual void _unhandled_input(InputEvent p_event);
+ virtual void _gui_input(Ref<InputEvent> p_event);
+ virtual void _unhandled_input(Ref<InputEvent> p_event);
void _notification(int p_what);
public:
diff --git a/scene/gui/box_container.cpp b/scene/gui/box_container.cpp
index e7f4a274d5..16b2cfa083 100644
--- a/scene/gui/box_container.cpp
+++ b/scene/gui/box_container.cpp
@@ -308,6 +308,7 @@ MarginContainer *VBoxContainer::add_margin_child(const String &p_label, Control
l->set_text(p_label);
add_child(l);
MarginContainer *mc = memnew(MarginContainer);
+ mc->add_constant_override("margin_left", 0);
mc->add_child(p_control);
add_child(mc);
if (p_expand)
diff --git a/scene/gui/button.cpp b/scene/gui/button.cpp
index f57b3d0fd1..a456759281 100644
--- a/scene/gui/button.cpp
+++ b/scene/gui/button.cpp
@@ -69,48 +69,58 @@ void Button::_notification(int p_what) {
RID ci = get_canvas_item();
Size2 size = get_size();
Color color;
- Color icon_color = Color(1, 1, 1);
+ Color color_icon(1, 1, 1, 1);
//print_line(get_text()+": "+itos(is_flat())+" hover "+itos(get_draw_mode()));
- String style_name = "";
+ Ref<StyleBox> style = get_stylebox("normal");
+
switch (get_draw_mode()) {
case DRAW_NORMAL: {
- style_name = "normal";
+ style = get_stylebox("normal");
+ if (!flat)
+ style->draw(ci, Rect2(Point2(0, 0), size));
color = get_color("font_color");
-
+ if (has_color("icon_color_normal"))
+ color_icon = get_color("icon_color_normal");
} break;
case DRAW_PRESSED: {
- style_name = "pressed";
- if (has_color("font_color_pressed")) {
+ style = get_stylebox("pressed");
+ style->draw(ci, Rect2(Point2(0, 0), size));
+ if (has_color("font_color_pressed"))
color = get_color("font_color_pressed");
- icon_color = color;
- } else
+ else
color = get_color("font_color");
+ if (has_color("icon_color_pressed"))
+ color_icon = get_color("icon_color_pressed");
} break;
case DRAW_HOVER: {
- style_name = "hover";
+ style = get_stylebox("hover");
+ style->draw(ci, Rect2(Point2(0, 0), size));
color = get_color("font_color_hover");
+ if (has_color("icon_color_hover"))
+ color_icon = get_color("icon_color_hover");
} break;
case DRAW_DISABLED: {
- style_name = "disabled";
+ style = get_stylebox("disabled");
+ style->draw(ci, Rect2(Point2(0, 0), size));
color = get_color("font_color_disabled");
+ if (has_color("icon_color_disabled"))
+ color_icon = get_color("icon_color_disabled");
} break;
}
- if (style_name != "" && !flat) get_stylebox(style_name)->draw(ci, Rect2(Point2(0, 0), size));
-
- Ref<StyleBox> style = get_stylebox(style_name);
if (has_focus()) {
+ Ref<StyleBox> style = get_stylebox("focus");
style->draw(ci, Rect2(Point2(), size));
}
@@ -147,8 +157,9 @@ void Button::_notification(int p_what) {
if (!_icon.is_null()) {
int valign = size.height - style->get_minimum_size().y;
-
- _icon->draw(ci, style->get_offset() + Point2(0, Math::floor((valign - _icon->get_height()) / 2.0)), is_disabled() ? Color(1, 1, 1, 0.4) : icon_color);
+ if (is_disabled())
+ color_icon.a = 0.4;
+ _icon->draw(ci, style->get_offset() + Point2(0, Math::floor((valign - _icon->get_height()) / 2.0)), color_icon);
}
}
}
diff --git a/scene/gui/button_array.cpp b/scene/gui/button_array.cpp
deleted file mode 100644
index eccf3ea64a..0000000000
--- a/scene/gui/button_array.cpp
+++ /dev/null
@@ -1,542 +0,0 @@
-/*************************************************************************/
-/* button_array.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 "button_array.h"
-
-bool ButtonArray::_set(const StringName &p_name, const Variant &p_value) {
-
- String n = String(p_name);
- if (n.begins_with("button/")) {
-
- String what = n.get_slicec('/', 1);
- if (what == "count") {
- int new_size = p_value;
- if (new_size > 0 && buttons.size() == 0) {
- selected = 0;
- }
-
- if (new_size < buttons.size()) {
- if (selected >= new_size)
- selected = new_size - 1;
- }
- buttons.resize(new_size);
- _change_notify();
- minimum_size_changed();
- } else if (what == "align") {
- set_align(Align(p_value.operator int()));
- } else if (what == "selected") {
- set_selected(p_value);
- } else if (what == "min_button_size") {
- min_button_size = p_value;
- } else {
- int idx = what.to_int();
- ERR_FAIL_INDEX_V(idx, buttons.size(), false);
- String f = n.get_slicec('/', 2);
- if (f == "text") {
- buttons[idx].text = p_value;
- buttons[idx].xl_text = XL_MESSAGE(p_value);
- } else if (f == "tooltip")
- buttons[idx].tooltip = p_value;
- else if (f == "icon")
- buttons[idx].icon = p_value;
- else
- return false;
- }
-
- update();
- return true;
- }
-
- return false;
-}
-
-bool ButtonArray::_get(const StringName &p_name, Variant &r_ret) const {
-
- String n = String(p_name);
- if (n.begins_with("button/")) {
-
- String what = n.get_slicec('/', 1);
- if (what == "count") {
- r_ret = buttons.size();
- } else if (what == "align") {
- r_ret = get_align();
- } else if (what == "selected") {
- r_ret = get_selected();
- } else if (what == "min_button_size") {
- r_ret = min_button_size;
- } else {
- int idx = what.to_int();
- ERR_FAIL_INDEX_V(idx, buttons.size(), false);
- String f = n.get_slicec('/', 2);
- if (f == "text")
- r_ret = buttons[idx].text;
- else if (f == "tooltip")
- r_ret = buttons[idx].tooltip;
- else if (f == "icon")
- r_ret = buttons[idx].icon;
- else
- return false;
- }
-
- return true;
- }
-
- return false;
-}
-void ButtonArray::_get_property_list(List<PropertyInfo> *p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::INT, "button/count", PROPERTY_HINT_RANGE, "0,512,1"));
- p_list->push_back(PropertyInfo(Variant::INT, "button/min_button_size", PROPERTY_HINT_RANGE, "0,1024,1"));
- p_list->push_back(PropertyInfo(Variant::INT, "button/align", PROPERTY_HINT_ENUM, "Begin,Center,End,Fill,Expand"));
- for (int i = 0; i < buttons.size(); i++) {
- String base = "button/" + itos(i) + "/";
- p_list->push_back(PropertyInfo(Variant::STRING, base + "text"));
- p_list->push_back(PropertyInfo(Variant::STRING, base + "tooltip"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, base + "icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture"));
- }
- if (buttons.size() > 0) {
- p_list->push_back(PropertyInfo(Variant::INT, "button/selected", PROPERTY_HINT_RANGE, "0," + itos(buttons.size() - 1) + ",1"));
- }
-}
-
-Size2 ButtonArray::get_minimum_size() const {
-
- Ref<StyleBox> style_normal = get_stylebox("normal");
- Ref<StyleBox> style_selected = get_stylebox("selected");
- Ref<Font> font_normal = get_font("font");
- Ref<Font> font_selected = get_font("font_selected");
- int icon_sep = get_constant("icon_separator");
- int button_sep = get_constant("button_separator");
-
- Size2 minsize;
-
- for (int i = 0; i < buttons.size(); i++) {
-
- Ref<StyleBox> sb = i == selected ? style_selected : style_normal;
- Ref<Font> f = i == selected ? font_selected : font_normal;
-
- Size2 ms;
- ms = f->get_string_size(buttons[i].xl_text);
- if (buttons[i].icon.is_valid()) {
-
- Size2 bs = buttons[i].icon->get_size();
- ms.height = MAX(ms.height, bs.height);
- ms.width += bs.width + icon_sep;
- }
-
- ms += sb->get_minimum_size();
-
- buttons[i]._ms_cache = ms[orientation];
-
- minsize[orientation] += ms[orientation];
- if (i > 0)
- minsize[orientation] += button_sep;
- minsize[!orientation] = MAX(minsize[!orientation], ms[!orientation]);
- }
-
- return minsize;
-}
-
-void ButtonArray::_notification(int p_what) {
-
- switch (p_what) {
- case NOTIFICATION_MOUSE_EXIT: {
- hover = -1;
- update();
- } break;
- case NOTIFICATION_READY: {
- MethodInfo mi;
- mi.name = "mouse_sub_enter";
-
- add_user_signal(mi);
-
- } break;
- case NOTIFICATION_DRAW: {
-
- Size2 size = get_size();
- Size2 minsize = get_combined_minimum_size();
- Ref<StyleBox> style_normal = get_stylebox("normal");
- Ref<StyleBox> style_selected = get_stylebox("selected");
- Ref<StyleBox> style_focus = get_stylebox("focus");
- Ref<StyleBox> style_hover = get_stylebox("hover");
- Ref<Font> font_normal = get_font("font");
- Ref<Font> font_selected = get_font("font_selected");
- int icon_sep = get_constant("icon_separator");
- int button_sep = get_constant("button_separator");
- Color color_normal = get_color("font_color");
- Color color_selected = get_color("font_color_selected");
-
- int sep = button_sep;
- int ofs = 0;
- int expand = 0;
-
- switch (align) {
- case ALIGN_BEGIN: {
-
- ofs = 0;
- } break;
- case ALIGN_CENTER: {
-
- ofs = Math::floor((size[orientation] - minsize[orientation]) / 2);
- } break;
- case ALIGN_END: {
-
- ofs = Math::floor((size[orientation] - minsize[orientation]));
- } break;
- case ALIGN_FILL: {
-
- if (buttons.size() > 1)
- sep += Math::floor((size[orientation] - minsize[orientation]) / (buttons.size() - 1.0));
- ofs = 0;
- } break;
- case ALIGN_EXPAND_FILL: {
-
- ofs = 0;
- expand = size[orientation] - minsize[orientation];
- } break;
- }
-
- int op_size = orientation == VERTICAL ? size.width : size.height;
-
- for (int i = 0; i < buttons.size(); i++) {
-
- int ms = buttons[i]._ms_cache;
- int s = ms;
- if (expand > 0) {
- s += expand / buttons.size();
- }
- if (min_button_size != -1 && s < min_button_size) {
- s = min_button_size;
- }
-
- Rect2 r;
- r.pos[orientation] = ofs;
- r.pos[!orientation] = 0;
- r.size[orientation] = s;
- r.size[!orientation] = op_size;
-
- Ref<Font> f;
- Color c;
- Point2 sbsize;
- Point2 sbofs;
- if (i == selected) {
- draw_style_box(style_selected, r);
- sbsize = style_selected->get_minimum_size();
- sbofs = style_selected->get_offset();
- f = font_selected;
- c = color_selected;
- if (has_focus())
- draw_style_box(style_focus, r);
- } else {
- if (hover == i)
- draw_style_box(style_hover, r);
- else if (!flat)
- draw_style_box(style_normal, r);
- sbsize = style_normal->get_minimum_size();
- sbofs = style_normal->get_offset();
- f = font_normal;
- c = color_normal;
- }
-
- Size2 ssize = f->get_string_size(buttons[i].xl_text);
- if (buttons[i].icon.is_valid()) {
-
- ssize.x += buttons[i].icon->get_width();
- }
- Point2 text_ofs = ((r.size - ssize - sbsize) / 2.0 + Point2(0, f->get_ascent())).floor() + sbofs;
- if (buttons[i].icon.is_valid()) {
-
- draw_texture(buttons[i].icon, r.pos + Point2(text_ofs.x, Math::floor((r.size.height - buttons[i].icon->get_height()) / 2.0)));
- text_ofs.x += buttons[i].icon->get_width() + icon_sep;
- }
- draw_string(f, text_ofs + r.pos, buttons[i].xl_text, c);
- buttons[i]._pos_cache = ofs;
- buttons[i]._size_cache = s;
-
- ofs += s;
- ofs += sep;
- }
-
- } break;
- }
-}
-
-void ButtonArray::_gui_input(const InputEvent &p_event) {
-
- if (
- ((orientation == HORIZONTAL && p_event.is_action("ui_left")) ||
- (orientation == VERTICAL && p_event.is_action("ui_up"))) &&
- p_event.is_pressed() && selected > 0) {
- set_selected(selected - 1);
- accept_event();
- emit_signal("button_selected", selected);
- return;
- }
-
- if (
- ((orientation == HORIZONTAL && p_event.is_action("ui_right")) ||
- (orientation == VERTICAL && p_event.is_action("ui_down"))) &&
- p_event.is_pressed() && selected < (buttons.size() - 1)) {
- set_selected(selected + 1);
- accept_event();
- emit_signal("button_selected", selected);
- return;
- }
-
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index == BUTTON_LEFT) {
-
- int ofs = orientation == HORIZONTAL ? p_event.mouse_button.x : p_event.mouse_button.y;
-
- for (int i = 0; i < buttons.size(); i++) {
-
- if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache) {
-
- set_selected(i);
- emit_signal("button_selected", i);
- return;
- }
- }
- }
-
- if (p_event.type == InputEvent::MOUSE_MOTION) {
-
- int ofs = orientation == HORIZONTAL ? p_event.mouse_motion.x : p_event.mouse_motion.y;
- int new_hover = -1;
- for (int i = 0; i < buttons.size(); i++) {
-
- if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache) {
-
- new_hover = i;
- break;
- }
- }
-
- if (new_hover != hover) {
- hover = new_hover;
- emit_signal("mouse_sub_enter");
- update();
- }
- }
-}
-
-String ButtonArray::get_tooltip(const Point2 &p_pos) const {
-
- int ofs = orientation == HORIZONTAL ? p_pos.x : p_pos.y;
- for (int i = 0; i < buttons.size(); i++) {
-
- if (ofs >= buttons[i]._pos_cache && ofs < buttons[i]._pos_cache + buttons[i]._size_cache)
- return buttons[i].tooltip;
- }
- return Control::get_tooltip(p_pos);
-}
-
-void ButtonArray::set_align(Align p_align) {
-
- align = p_align;
- update();
-}
-
-ButtonArray::Align ButtonArray::get_align() const {
-
- return align;
-}
-
-void ButtonArray::set_flat(bool p_flat) {
-
- flat = p_flat;
- update();
-}
-
-bool ButtonArray::is_flat() const {
-
- return flat;
-}
-
-void ButtonArray::add_button(const String &p_text, const String &p_tooltip) {
-
- Button button;
- button.text = p_text;
- button.xl_text = XL_MESSAGE(p_text);
- button.tooltip = p_tooltip;
- buttons.push_back(button);
- update();
-
- if (selected == -1)
- selected = 0;
-
- minimum_size_changed();
-}
-
-void ButtonArray::add_icon_button(const Ref<Texture> &p_icon, const String &p_text, const String &p_tooltip) {
-
- Button button;
- button.text = p_text;
- button.xl_text = XL_MESSAGE(p_text);
- button.icon = p_icon;
- button.tooltip = p_tooltip;
- buttons.push_back(button);
- if (selected == -1)
- selected = 0;
-
- update();
-}
-
-void ButtonArray::set_button_text(int p_button, const String &p_text) {
-
- ERR_FAIL_INDEX(p_button, buttons.size());
- buttons[p_button].text = p_text;
- buttons[p_button].xl_text = XL_MESSAGE(p_text);
- update();
- minimum_size_changed();
-}
-
-void ButtonArray::set_button_tooltip(int p_button, const String &p_text) {
-
- ERR_FAIL_INDEX(p_button, buttons.size());
- buttons[p_button].tooltip = p_text;
-}
-
-void ButtonArray::set_button_icon(int p_button, const Ref<Texture> &p_icon) {
-
- ERR_FAIL_INDEX(p_button, buttons.size());
- buttons[p_button].icon = p_icon;
- update();
- minimum_size_changed();
-}
-
-String ButtonArray::get_button_text(int p_button) const {
-
- ERR_FAIL_INDEX_V(p_button, buttons.size(), "");
- return buttons[p_button].text;
-}
-
-String ButtonArray::get_button_tooltip(int p_button) const {
-
- ERR_FAIL_INDEX_V(p_button, buttons.size(), "");
- return buttons[p_button].tooltip;
-}
-
-Ref<Texture> ButtonArray::get_button_icon(int p_button) const {
-
- ERR_FAIL_INDEX_V(p_button, buttons.size(), Ref<Texture>());
- return buttons[p_button].icon;
-}
-
-int ButtonArray::get_selected() const {
-
- return selected;
-}
-
-int ButtonArray::get_hovered() const {
-
- return hover;
-}
-
-void ButtonArray::set_selected(int p_selected) {
-
- ERR_FAIL_INDEX(p_selected, buttons.size());
- selected = p_selected;
- update();
-}
-
-void ButtonArray::erase_button(int p_button) {
-
- ERR_FAIL_INDEX(p_button, buttons.size());
- buttons.remove(p_button);
- if (p_button >= selected)
- selected--;
- if (selected < 0)
- selected = 0;
- if (selected >= buttons.size())
- selected = buttons.size() - 1;
-
- update();
-}
-
-void ButtonArray::clear() {
-
- buttons.clear();
- selected = -1;
- update();
-}
-
-int ButtonArray::get_button_count() const {
-
- return buttons.size();
-}
-
-void ButtonArray::get_translatable_strings(List<String> *p_strings) const {
-
- for (int i = 0; i < buttons.size(); i++) {
- p_strings->push_back(buttons[i].text);
- p_strings->push_back(buttons[i].tooltip);
- }
-}
-
-void ButtonArray::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("add_button", "text", "tooltip"), &ButtonArray::add_button, DEFVAL(""));
- ClassDB::bind_method(D_METHOD("add_icon_button", "icon:Texture", "text", "tooltip"), &ButtonArray::add_icon_button, DEFVAL(""), DEFVAL(""));
- ClassDB::bind_method(D_METHOD("set_button_text", "button_idx", "text"), &ButtonArray::set_button_text);
- ClassDB::bind_method(D_METHOD("set_button_tooltip", "button_idx", "text"), &ButtonArray::set_button_tooltip);
- ClassDB::bind_method(D_METHOD("set_button_icon", "button_idx", "icon:Texture"), &ButtonArray::set_button_icon);
- ClassDB::bind_method(D_METHOD("get_button_text", "button_idx"), &ButtonArray::get_button_text);
- ClassDB::bind_method(D_METHOD("get_button_tooltip", "button_idx"), &ButtonArray::get_button_tooltip);
- ClassDB::bind_method(D_METHOD("get_button_icon:Texture", "button_idx"), &ButtonArray::get_button_icon);
- ClassDB::bind_method(D_METHOD("get_button_count"), &ButtonArray::get_button_count);
- ClassDB::bind_method(D_METHOD("set_flat", "enabled"), &ButtonArray::set_flat);
- ClassDB::bind_method(D_METHOD("is_flat"), &ButtonArray::is_flat);
- ClassDB::bind_method(D_METHOD("get_selected"), &ButtonArray::get_selected);
- ClassDB::bind_method(D_METHOD("get_hovered"), &ButtonArray::get_hovered);
- ClassDB::bind_method(D_METHOD("set_selected", "button_idx"), &ButtonArray::set_selected);
- ClassDB::bind_method(D_METHOD("erase_button", "button_idx"), &ButtonArray::erase_button);
- ClassDB::bind_method(D_METHOD("clear"), &ButtonArray::clear);
-
- ClassDB::bind_method(D_METHOD("_gui_input"), &ButtonArray::_gui_input);
-
- BIND_CONSTANT(ALIGN_BEGIN);
- BIND_CONSTANT(ALIGN_CENTER);
- BIND_CONSTANT(ALIGN_END);
- BIND_CONSTANT(ALIGN_FILL);
- BIND_CONSTANT(ALIGN_EXPAND_FILL);
-
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "flat"), "set_flat", "is_flat");
-
- ADD_SIGNAL(MethodInfo("button_selected", PropertyInfo(Variant::INT, "button_idx")));
-}
-
-ButtonArray::ButtonArray(Orientation p_orientation) {
-
- orientation = p_orientation;
- selected = -1;
- set_focus_mode(FOCUS_ALL);
- hover = -1;
- flat = false;
- min_button_size = -1;
-}
diff --git a/scene/gui/button_array.h b/scene/gui/button_array.h
deleted file mode 100644
index f2f7bea9c6..0000000000
--- a/scene/gui/button_array.h
+++ /dev/null
@@ -1,131 +0,0 @@
-/*************************************************************************/
-/* button_array.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 BUTTON_ARRAY_H
-#define BUTTON_ARRAY_H
-
-#include "scene/gui/control.h"
-
-class ButtonArray : public Control {
-
- GDCLASS(ButtonArray, Control);
-
-public:
- enum Align {
- ALIGN_BEGIN,
- ALIGN_CENTER,
- ALIGN_END,
- ALIGN_FILL,
- ALIGN_EXPAND_FILL
- };
-
-private:
- Orientation orientation;
- Align align;
-
- struct Button {
-
- String text;
- String xl_text;
- String tooltip;
- Ref<Texture> icon;
- mutable int _ms_cache;
- mutable int _pos_cache;
- mutable int _size_cache;
- };
-
- int selected;
- int hover;
- bool flat;
- double min_button_size;
-
- Vector<Button> buttons;
-
-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;
-
- void _notification(int p_what);
- static void _bind_methods();
-
-public:
- void _gui_input(const InputEvent &p_event);
-
- void set_align(Align p_align);
- Align get_align() const;
-
- void set_flat(bool p_flat);
- bool is_flat() const;
-
- void add_button(const String &p_button, const String &p_tooltip = "");
- void add_icon_button(const Ref<Texture> &p_icon, const String &p_button = "", const String &p_tooltip = "");
-
- void set_button_text(int p_button, const String &p_text);
- void set_button_tooltip(int p_button, const String &p_text);
- void set_button_icon(int p_button, const Ref<Texture> &p_icon);
-
- String get_button_text(int p_button) const;
- String get_button_tooltip(int p_button) const;
- Ref<Texture> get_button_icon(int p_button) const;
-
- int get_selected() const;
- int get_hovered() const;
- void set_selected(int p_selected);
-
- int get_button_count() const;
-
- void erase_button(int p_button);
- void clear();
-
- virtual Size2 get_minimum_size() const;
-
- virtual void get_translatable_strings(List<String> *p_strings) const;
- virtual String get_tooltip(const Point2 &p_pos) const;
-
- ButtonArray(Orientation p_orientation = HORIZONTAL);
-};
-
-class HButtonArray : public ButtonArray {
- GDCLASS(HButtonArray, ButtonArray);
-
-public:
- HButtonArray()
- : ButtonArray(HORIZONTAL){};
-};
-
-class VButtonArray : public ButtonArray {
- GDCLASS(VButtonArray, ButtonArray);
-
-public:
- VButtonArray()
- : ButtonArray(VERTICAL){};
-};
-
-#endif // BUTTON_ARRAY_H
diff --git a/scene/gui/color_picker.cpp b/scene/gui/color_picker.cpp
index adb5e2f0b6..ee6af21dbd 100644
--- a/scene/gui/color_picker.cpp
+++ b/scene/gui/color_picker.cpp
@@ -48,7 +48,15 @@ void ColorPicker::_notification(int p_what) {
btn_pick->set_icon(get_icon("screen_picker", "ColorPicker"));
_update_color();
- }
+ } break;
+
+ case MainLoop::NOTIFICATION_WM_QUIT_REQUEST: {
+ if (screen != NULL) {
+ if (screen->is_visible()) {
+ screen->hide();
+ }
+ }
+ } break;
}
}
@@ -84,9 +92,6 @@ void ColorPicker::set_pick_color(const Color &p_color) {
if (!is_inside_tree())
return;
- return; //it crashes, so returning
- uv_edit->get_child(0)->cast_to<Control>()->update();
- w_edit->get_child(0)->cast_to<Control>()->update();
_update_color();
}
@@ -156,6 +161,8 @@ void ColorPicker::_update_color() {
_update_text_value();
sample->update();
+ uv_edit->update();
+ w_edit->update();
updating = false;
}
@@ -178,7 +185,7 @@ void ColorPicker::_update_presets() {
}
}
- Image i(size.x * presets.size(), size.y, false, Image::FORMAT_RGB8, img);
+ Ref<Image> i = memnew(Image(size.x * presets.size(), size.y, false, Image::FORMAT_RGB8, img));
Ref<ImageTexture> t;
t.instance();
@@ -263,10 +270,10 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) {
points.push_back(c->get_size());
points.push_back(Vector2(0, c->get_size().y));
Vector<Color> colors;
- colors.push_back(Color(1, 1, 1));
- colors.push_back(Color(1, 1, 1));
- colors.push_back(Color());
- colors.push_back(Color());
+ colors.push_back(Color(1, 1, 1, 1));
+ colors.push_back(Color(1, 1, 1, 1));
+ colors.push_back(Color(0, 0, 0, 1));
+ colors.push_back(Color(0, 0, 0, 1));
c->draw_polygon(points, colors);
Vector<Color> colors2;
Color col = color;
@@ -279,7 +286,7 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) {
colors2.push_back(col);
col.a = 0;
colors2.push_back(col);
- c->draw_polygon(points, colors);
+ c->draw_polygon(points, colors2);
int x = CLAMP(c->get_size().x * s, 0, c->get_size().x);
int y = CLAMP(c->get_size().y - c->get_size().y * v, 0, c->get_size().y);
col = color;
@@ -290,20 +297,22 @@ void ColorPicker::_hsv_draw(int p_wich, Control *c) {
} else if (p_wich == 1) {
Ref<Texture> hue = get_icon("color_hue", "ColorPicker");
c->draw_texture_rect(hue, Rect2(Point2(), c->get_size()));
- int y = c->get_size().y - c->get_size().y * h;
+ int y = c->get_size().y - c->get_size().y * (1.0 - h);
Color col = Color();
col.set_hsv(h, 1, 1);
c->draw_line(Point2(0, y), Point2(c->get_size().x, y), col.inverted());
}
}
-void ColorPicker::_uv_input(const InputEvent &ev) {
- if (ev.type == InputEvent::MOUSE_BUTTON) {
- const InputEventMouseButton &bev = ev.mouse_button;
- if (bev.pressed && bev.button_index == BUTTON_LEFT) {
+void ColorPicker::_uv_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> bev = ev;
+
+ if (bev.is_valid()) {
+ if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
changing_color = true;
- float x = CLAMP((float)bev.x, 0, 256);
- float y = CLAMP((float)bev.y, 0, 256);
+ float x = CLAMP((float)bev->get_position().x, 0, 256);
+ float y = CLAMP((float)bev->get_position().y, 0, 256);
s = x / 256;
v = 1.0 - y / 256.0;
color.set_hsv(h, s, v, color.a);
@@ -314,12 +323,15 @@ void ColorPicker::_uv_input(const InputEvent &ev) {
} else {
changing_color = false;
}
- } else if (ev.type == InputEvent::MOUSE_MOTION) {
- const InputEventMouse &bev = ev.mouse_motion;
+ }
+
+ Ref<InputEventMouseMotion> mev = ev;
+
+ if (mev.is_valid()) {
if (!changing_color)
return;
- float x = CLAMP((float)bev.x, 0, 256);
- float y = CLAMP((float)bev.y, 0, 256);
+ float x = CLAMP((float)mev->get_position().x, 0, 256);
+ float y = CLAMP((float)mev->get_position().y, 0, 256);
s = x / 256;
v = 1.0 - y / 256.0;
color.set_hsv(h, s, v, color.a);
@@ -330,12 +342,15 @@ void ColorPicker::_uv_input(const InputEvent &ev) {
}
}
-void ColorPicker::_w_input(const InputEvent &ev) {
- if (ev.type == InputEvent::MOUSE_BUTTON) {
- const InputEventMouseButton &bev = ev.mouse_button;
- if (bev.pressed && bev.button_index == BUTTON_LEFT) {
+void ColorPicker::_w_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> bev = ev;
+
+ if (bev.is_valid()) {
+
+ if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
changing_color = true;
- h = 1 - ((float)bev.y) / 256.0;
+ h = 1 - (256.0 - (float)bev->get_position().y) / 256.0;
} else {
changing_color = false;
@@ -345,12 +360,17 @@ void ColorPicker::_w_input(const InputEvent &ev) {
set_pick_color(color);
_update_color();
emit_signal("color_changed", color);
- } else if (ev.type == InputEvent::MOUSE_MOTION) {
- const InputEventMouse &bev = ev.mouse_motion;
+ }
+
+ Ref<InputEventMouseMotion> mev = ev;
+
+ if (mev.is_valid()) {
+
if (!changing_color)
return;
- float y = CLAMP((float)bev.y, 0, 256);
- h = 1.0 - y / 256.0;
+ float y = CLAMP((float)mev->get_position().y, 0, 256);
+ //h = 1.0 - y / 256.0;
+ h = y / 256.0;
color.set_hsv(h, s, v, color.a);
last_hsv = color;
set_pick_color(color);
@@ -359,23 +379,30 @@ void ColorPicker::_w_input(const InputEvent &ev) {
}
}
-void ColorPicker::_preset_input(const InputEvent &ev) {
- if (ev.type == InputEvent::MOUSE_BUTTON) {
- const InputEventMouseButton &bev = ev.mouse_button;
- if (bev.pressed && bev.button_index == BUTTON_LEFT) {
- int index = bev.x / (preset->get_size().x / presets.size());
+void ColorPicker::_preset_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> bev = ev;
+
+ if (bev.is_valid()) {
+
+ if (bev->is_pressed() && bev->get_button_index() == BUTTON_LEFT) {
+ int index = bev->get_position().x / (preset->get_size().x / presets.size());
set_pick_color(presets[index]);
- } else if (bev.pressed && bev.button_index == BUTTON_RIGHT) {
- int index = bev.x / (preset->get_size().x / presets.size());
+ } else if (bev->is_pressed() && bev->get_button_index() == BUTTON_RIGHT) {
+ int index = bev->get_position().x / (preset->get_size().x / presets.size());
presets.erase(presets[index]);
_update_presets();
bt_add_preset->show();
}
_update_color();
emit_signal("color_changed", color);
- } else if (ev.type == InputEvent::MOUSE_MOTION) {
- const InputEventMouse &mev = ev.mouse_motion;
- int index = mev.x * presets.size();
+ }
+
+ Ref<InputEventMouseMotion> mev = ev;
+
+ if (mev.is_valid()) {
+
+ int index = mev->get_position().x * presets.size();
if (preset->get_size().x != 0) {
index /= preset->get_size().x;
}
@@ -387,31 +414,30 @@ void ColorPicker::_preset_input(const InputEvent &ev) {
}
}
-void ColorPicker::_screen_input(const InputEvent &ev) {
- if (ev.type == InputEvent::MOUSE_BUTTON) {
- const InputEventMouseButton &bev = ev.mouse_button;
- if (bev.button_index == BUTTON_LEFT && !bev.pressed) {
+void ColorPicker::_screen_input(const Ref<InputEvent> &ev) {
+
+ Ref<InputEventMouseButton> bev = ev;
+
+ if (bev.is_valid()) {
+
+ if (bev->get_button_index() == BUTTON_LEFT && !bev->is_pressed()) {
emit_signal("color_changed", color);
screen->hide();
}
- } else if (ev.type == InputEvent::MOUSE_MOTION) {
- const InputEventMouse &mev = ev.mouse_motion;
- Viewport *r = get_tree()->get_root();
- if (!r->get_visible_rect().has_point(Point2(mev.global_x, mev.global_y)))
- return;
- Image img = r->get_screen_capture();
- if (!img.empty()) {
- last_capture = img;
- r->queue_screen_capture();
- }
- if (!last_capture.empty()) {
- int pw = last_capture.get_format() == Image::FORMAT_RGBA8 ? 4 : 3;
- int ofs = (mev.global_y * last_capture.get_width() + mev.global_x) * pw;
-
- PoolVector<uint8_t>::Read r = last_capture.get_data().read();
+ }
- Color c(r[ofs + 0] / 255.0, r[ofs + 1] / 255.0, r[ofs + 2] / 255.0);
+ Ref<InputEventMouseMotion> mev = ev;
+ if (mev.is_valid()) {
+ Viewport *r = get_tree()->get_root();
+ if (!r->get_visible_rect().has_point(Point2(mev->get_global_position().x, mev->get_global_position().y)))
+ return;
+ Ref<Image> img = r->get_texture()->get_data();
+ if (img.is_valid() && !img->empty()) {
+ img->lock();
+ Vector2 ofs = mev->get_global_position() - r->get_visible_rect().get_position();
+ Color c = img->get_pixel(ofs.x, r->get_visible_rect().size.height - ofs.y);
+ img->unlock();
set_pick_color(c);
}
}
@@ -428,11 +454,11 @@ void ColorPicker::_screen_pick_pressed() {
r->add_child(screen);
screen->set_as_toplevel(true);
screen->set_area_as_parent_rect();
+ screen->set_default_cursor_shape(CURSOR_POINTING_HAND);
screen->connect("gui_input", this, "_screen_input");
}
screen->raise();
screen->show_modal();
- r->queue_screen_capture();
}
void ColorPicker::_bind_methods() {
@@ -604,6 +630,10 @@ void ColorPickerButton::_notification(int p_what) {
Ref<StyleBox> normal = get_stylebox("normal");
draw_rect(Rect2(normal->get_offset(), get_size() - normal->get_minimum_size()), picker->get_pick_color());
}
+
+ if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
+ popup->hide();
+ }
}
void ColorPickerButton::set_pick_color(const Color &p_color) {
diff --git a/scene/gui/color_picker.h b/scene/gui/color_picker.h
index bce1ae07f7..de624fd029 100644
--- a/scene/gui/color_picker.h
+++ b/scene/gui/color_picker.h
@@ -47,7 +47,6 @@ class ColorPicker : public BoxContainer {
private:
Control *screen;
- Image last_capture;
Control *uv_edit;
Control *w_edit;
TextureRect *sample;
@@ -82,10 +81,10 @@ private:
void _sample_draw();
void _hsv_draw(int p_wich, Control *c);
- void _uv_input(const InputEvent &p_input);
- void _w_input(const InputEvent &p_input);
- void _preset_input(const InputEvent &p_input);
- void _screen_input(const InputEvent &p_input);
+ void _uv_input(const Ref<InputEvent> &p_input);
+ void _w_input(const Ref<InputEvent> &p_input);
+ void _preset_input(const Ref<InputEvent> &p_input);
+ void _screen_input(const Ref<InputEvent> &p_input);
void _add_preset_pressed();
void _screen_pick_pressed();
diff --git a/scene/gui/container.cpp b/scene/gui/container.cpp
index c428d524a4..92bb5d43a7 100644
--- a/scene/gui/container.cpp
+++ b/scene/gui/container.cpp
@@ -96,18 +96,18 @@ void Container::fit_child_in_rect(Control *p_child, const Rect2 &p_rect) {
if (!(p_child->get_h_size_flags() & SIZE_FILL)) {
r.size.x = minsize.x;
- r.pos.x += Math::floor((p_rect.size.x - minsize.x) / 2);
+ r.position.x += Math::floor((p_rect.size.x - minsize.x) / 2);
}
if (!(p_child->get_v_size_flags() & SIZE_FILL)) {
r.size.y = minsize.y;
- r.pos.y += Math::floor((p_rect.size.y - minsize.y) / 2);
+ r.position.y += Math::floor((p_rect.size.y - minsize.y) / 2);
}
for (int i = 0; i < 4; i++)
p_child->set_anchor(Margin(i), ANCHOR_BEGIN);
- p_child->set_position(r.pos);
+ p_child->set_position(r.position);
p_child->set_size(r.size);
p_child->set_rotation(0);
p_child->set_scale(Vector2(1, 1));
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index e62a993651..45485b768e 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -58,7 +58,7 @@ void Control::edit_set_state(const Variant &p_state) {
Dictionary s = p_state;
Rect2 state = s["rect"];
- set_position(state.pos);
+ set_position(state.position);
set_size(state.size);
set_rotation(s["rot"]);
set_scale(s["scale"]);
@@ -94,15 +94,15 @@ void Control::edit_set_rect(const Rect2 &p_edit_rect) {
Transform2D postxf;
postxf.set_rotation_and_scale(data.rotation, data.scale);
- Vector2 new_pos = postxf.xform(p_edit_rect.pos);
+ Vector2 new_pos = postxf.xform(p_edit_rect.position);
Vector2 pos = get_position() + new_pos;
Rect2 new_rect = get_rect();
- new_rect.pos = pos.snapped(Vector2(1, 1));
+ new_rect.position = pos.snapped(Vector2(1, 1));
new_rect.size = p_edit_rect.size.snapped(Vector2(1, 1));
- set_position(new_rect.pos);
+ set_position(new_rect.position);
set_size(new_rect.size);
}
@@ -1184,6 +1184,7 @@ Size2 Control::get_parent_area_size() const {
parent_size = get_viewport()->get_visible_rect().size;
}
+
return parent_size;
}
@@ -1352,7 +1353,7 @@ void Control::_change_notify_margins() {
_change_notify("margin_top");
_change_notify("margin_right");
_change_notify("margin_bottom");
- _change_notify("rect_pos");
+ _change_notify("rect_position");
_change_notify("rect_size");
}
@@ -1477,7 +1478,7 @@ Rect2 Control::get_global_rect() const {
Rect2 Control::get_window_rect() const {
ERR_FAIL_COND_V(!is_inside_tree(), Rect2());
Rect2 gr = get_global_rect();
- gr.pos += get_viewport()->get_visible_rect().pos;
+ gr.position += get_viewport()->get_visible_rect().position;
return gr;
}
@@ -1949,10 +1950,10 @@ Control *Control::_get_focus_neighbour(Margin p_margin, int p_count) {
Transform2D xform = get_global_transform();
Rect2 rect = get_item_rect();
- points[0] = xform.xform(rect.pos);
- points[1] = xform.xform(rect.pos + Point2(rect.size.x, 0));
- points[2] = xform.xform(rect.pos + rect.size);
- points[3] = xform.xform(rect.pos + Point2(0, rect.size.y));
+ points[0] = xform.xform(rect.position);
+ points[1] = xform.xform(rect.position + Point2(rect.size.x, 0));
+ points[2] = xform.xform(rect.position + rect.size);
+ points[3] = xform.xform(rect.position + Point2(0, rect.size.y));
const Vector2 dir[4] = {
Vector2(-1, 0),
@@ -2008,10 +2009,10 @@ void Control::_window_find_focus_neighbour(const Vector2 &p_dir, Node *p_at, con
Transform2D xform = c->get_global_transform();
Rect2 rect = c->get_item_rect();
- points[0] = xform.xform(rect.pos);
- points[1] = xform.xform(rect.pos + Point2(rect.size.x, 0));
- points[2] = xform.xform(rect.pos + rect.size);
- points[3] = xform.xform(rect.pos + Point2(0, rect.size.y));
+ points[0] = xform.xform(rect.position);
+ points[1] = xform.xform(rect.position + Point2(rect.size.x, 0));
+ points[2] = xform.xform(rect.position + rect.size);
+ points[3] = xform.xform(rect.position + Point2(0, rect.size.y));
float min = 1e7;
@@ -2419,7 +2420,7 @@ void Control::_bind_methods() {
ClassDB::bind_method(D_METHOD("_font_changed"), &Control::_font_changed);
- BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::INPUT_EVENT, "event")));
+ BIND_VMETHOD(MethodInfo("_gui_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
BIND_VMETHOD(MethodInfo(Variant::VECTOR2, "_get_minimum_size"));
BIND_VMETHOD(MethodInfo(Variant::OBJECT, "get_drag_data", PropertyInfo(Variant::VECTOR2, "pos")));
BIND_VMETHOD(MethodInfo(Variant::BOOL, "can_drop_data", PropertyInfo(Variant::VECTOR2, "pos"), PropertyInfo(Variant::NIL, "data")));
@@ -2507,7 +2508,7 @@ void Control::_bind_methods() {
BIND_CONSTANT(MOUSE_FILTER_IGNORE);
ADD_SIGNAL(MethodInfo("resized"));
- ADD_SIGNAL(MethodInfo("gui_input", PropertyInfo(Variant::INPUT_EVENT, "ev")));
+ ADD_SIGNAL(MethodInfo("gui_input", PropertyInfo(Variant::OBJECT, "ev", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
ADD_SIGNAL(MethodInfo("mouse_entered"));
ADD_SIGNAL(MethodInfo("mouse_exited"));
ADD_SIGNAL(MethodInfo("focus_entered"));
diff --git a/scene/gui/dialogs.cpp b/scene/gui/dialogs.cpp
index cf5321e907..60d1350405 100644
--- a/scene/gui/dialogs.cpp
+++ b/scene/gui/dialogs.cpp
@@ -53,25 +53,34 @@ void WindowDialog::_fix_size() {
Size2i viewport_size = get_viewport_rect().size;
// Windows require additional padding to keep the window chrome visible.
- Ref<StyleBoxTexture> panel = get_stylebox("panel", "WindowDialog");
-
+ Ref<StyleBox> panel = get_stylebox("panel", "WindowDialog");
+ float top = 0;
+ float left = 0;
+ float bottom = 0;
+ float right = 0;
// Check validity, because the theme could contain a different type of StyleBox
- if (panel.is_valid()) {
- float top = panel->get_expand_margin_size(MARGIN_TOP);
- float left = panel->get_expand_margin_size(MARGIN_LEFT);
- float bottom = panel->get_expand_margin_size(MARGIN_BOTTOM);
- float right = panel->get_expand_margin_size(MARGIN_RIGHT);
-
- pos.x = MAX(left, MIN(pos.x, viewport_size.x - size.x - right));
- pos.y = MAX(top, MIN(pos.y, viewport_size.y - size.y - bottom));
- set_global_position(pos);
-
- // Also resize the window to fit if a resize should be possible at all.
- if (resizable) {
- size.x = MIN(size.x, viewport_size.x - left - right);
- size.y = MIN(size.y, viewport_size.y - top - bottom);
- set_size(size);
- }
+ if (panel->get_class() == "StyleBoxTexture") {
+ Ref<StyleBoxTexture> panel_texture = panel->cast_to<StyleBoxTexture>();
+ top = panel_texture->get_expand_margin_size(MARGIN_TOP);
+ left = panel_texture->get_expand_margin_size(MARGIN_LEFT);
+ bottom = panel_texture->get_expand_margin_size(MARGIN_BOTTOM);
+ right = panel_texture->get_expand_margin_size(MARGIN_RIGHT);
+ } else if (panel->get_class() == "StyleBoxFlat") {
+ Ref<StyleBoxFlat> panel_flat = panel->cast_to<StyleBoxFlat>();
+ top = panel_flat->_get_additional_border_size(MARGIN_TOP);
+ left = panel_flat->_get_additional_border_size(MARGIN_LEFT);
+ bottom = panel_flat->_get_additional_border_size(MARGIN_BOTTOM);
+ right = panel_flat->_get_additional_border_size(MARGIN_RIGHT);
+ }
+
+ pos.x = MAX(left, MIN(pos.x, viewport_size.x - size.x - right));
+ pos.y = MAX(top, MIN(pos.y, viewport_size.y - size.y - bottom));
+ set_global_position(pos);
+
+ if (resizable) {
+ size.x = MIN(size.x, viewport_size.x - left - right);
+ size.y = MIN(size.y, viewport_size.y - top - bottom);
+ set_size(size);
}
}
@@ -81,44 +90,48 @@ bool WindowDialog::has_point(const Point2 &p_point) const {
// Enlarge upwards for title bar.
int title_height = get_constant("title_height", "WindowDialog");
- r.pos.y -= title_height;
+ r.position.y -= title_height;
r.size.y += title_height;
// Inflate by the resizable border thickness.
if (resizable) {
int scaleborder_size = get_constant("scaleborder_size", "WindowDialog");
- r.pos.x -= scaleborder_size;
+ r.position.x -= scaleborder_size;
r.size.width += scaleborder_size * 2;
- r.pos.y -= scaleborder_size;
+ r.position.y -= scaleborder_size;
r.size.height += scaleborder_size * 2;
}
return r.has_point(p_point);
}
-void WindowDialog::_gui_input(const InputEvent &p_event) {
+void WindowDialog::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
- if (p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT) {
+
+ if (mb->is_pressed()) {
// Begin a possible dragging operation.
- drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y));
+ drag_type = _drag_hit_test(Point2(mb->get_position().x, mb->get_position().y));
if (drag_type != DRAG_NONE)
drag_offset = get_global_mouse_position() - get_position();
drag_offset_far = get_position() + get_size() - get_global_mouse_position();
- } else if (drag_type != DRAG_NONE && !p_event.mouse_button.pressed) {
+ } else if (drag_type != DRAG_NONE && !mb->is_pressed()) {
// End a dragging operation.
drag_type = DRAG_NONE;
}
}
- if (p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid()) {
if (drag_type == DRAG_NONE) {
// Update the cursor while moving along the borders.
CursorShape cursor = CURSOR_ARROW;
if (resizable) {
- int preview_drag_type = _drag_hit_test(Point2(p_event.mouse_button.x, p_event.mouse_button.y));
+ int preview_drag_type = _drag_hit_test(Point2(mm->get_position().x, mm->get_position().y));
switch (preview_drag_type) {
case DRAG_RESIZE_TOP:
case DRAG_RESIZE_BOTTOM:
@@ -149,28 +162,28 @@ void WindowDialog::_gui_input(const InputEvent &p_event) {
Size2 min_size = get_minimum_size();
if (drag_type == DRAG_MOVE) {
- rect.pos = global_pos - drag_offset;
+ rect.position = global_pos - drag_offset;
} else {
if (drag_type & DRAG_RESIZE_TOP) {
- int bottom = rect.pos.y + rect.size.height;
+ int bottom = rect.position.y + rect.size.height;
int max_y = bottom - min_size.height;
- rect.pos.y = MIN(global_pos.y - drag_offset.y, max_y);
- rect.size.height = bottom - rect.pos.y;
+ rect.position.y = MIN(global_pos.y - drag_offset.y, max_y);
+ rect.size.height = bottom - rect.position.y;
} else if (drag_type & DRAG_RESIZE_BOTTOM) {
- rect.size.height = global_pos.y - rect.pos.y + drag_offset_far.y;
+ rect.size.height = global_pos.y - rect.position.y + drag_offset_far.y;
}
if (drag_type & DRAG_RESIZE_LEFT) {
- int right = rect.pos.x + rect.size.width;
+ int right = rect.position.x + rect.size.width;
int max_x = right - min_size.width;
- rect.pos.x = MIN(global_pos.x - drag_offset.x, max_x);
- rect.size.width = right - rect.pos.x;
+ rect.position.x = MIN(global_pos.x - drag_offset.x, max_x);
+ rect.size.width = right - rect.position.x;
} else if (drag_type & DRAG_RESIZE_RIGHT) {
- rect.size.width = global_pos.x - rect.pos.x + drag_offset_far.x;
+ rect.size.width = global_pos.x - rect.position.x + drag_offset_far.x;
}
}
set_size(rect.size);
- set_position(rect.pos);
+ set_position(rect.position);
}
}
}
@@ -200,7 +213,7 @@ void WindowDialog::_notification(int p_what) {
case NOTIFICATION_ENTER_TREE: {
close_button->set_normal_texture(get_icon("close", "WindowDialog"));
close_button->set_pressed_texture(get_icon("close", "WindowDialog"));
- close_button->set_hover_texture(get_icon("close_hilite", "WindowDialog"));
+ close_button->set_hover_texture(get_icon("close_highlight", "WindowDialog"));
close_button->set_anchor(MARGIN_LEFT, ANCHOR_END);
close_button->set_begin(Point2(get_constant("close_h_ofs", "WindowDialog"), -get_constant("close_v_ofs", "WindowDialog")));
} break;
diff --git a/scene/gui/dialogs.h b/scene/gui/dialogs.h
index 2365df3d79..9d8f113caa 100644
--- a/scene/gui/dialogs.h
+++ b/scene/gui/dialogs.h
@@ -60,7 +60,7 @@ class WindowDialog : public Popup {
Point2 drag_offset_far;
bool resizable;
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _closed();
int _drag_hit_test(const Point2 &pos) const;
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 2f1af318e9..3527b834c7 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -61,21 +61,20 @@ void FileDialog::_notification(int p_what) {
}
}
-void FileDialog::_unhandled_input(const InputEvent &p_event) {
+void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && is_window_modal_on_top()) {
+ Ref<InputEventKey> k = p_event;
+ if (k.is_valid() && is_window_modal_on_top()) {
- const InputEventKey &k = p_event.key;
-
- if (k.pressed) {
+ if (k->is_pressed()) {
bool handled = true;
- switch (k.scancode) {
+ switch (k->get_scancode()) {
case KEY_H: {
- if (k.mod.command) {
+ if (k->get_command()) {
set_show_hidden_files(!show_hidden_files);
} else {
handled = false;
@@ -336,8 +335,8 @@ void FileDialog::update_file_list() {
dirs.push_back("..");
}
- dirs.sort_custom<NoCaseComparator>();
- files.sort_custom<NoCaseComparator>();
+ dirs.sort_custom<NaturalNoCaseComparator>();
+ files.sort_custom<NaturalNoCaseComparator>();
while (!dirs.empty()) {
String &dir_name = dirs.front()->get();
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 2afd0227c6..9873a677b2 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -115,7 +115,7 @@ private:
void _update_drives();
- void _unhandled_input(const InputEvent &p_event);
+ void _unhandled_input(const Ref<InputEvent> &p_event);
virtual void _post_popup();
diff --git a/scene/gui/color_ramp_edit.cpp b/scene/gui/gradient_edit.cpp
index c6f73fe6e6..58bce57580 100644
--- a/scene/gui/color_ramp_edit.cpp
+++ b/scene/gui/gradient_edit.cpp
@@ -27,10 +27,10 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "color_ramp_edit.h"
+#include "gradient_edit.h"
#include "os/keyboard.h"
-ColorRampEdit::ColorRampEdit() {
+GradientEdit::GradientEdit() {
grabbed = -1;
grabbing = false;
set_focus_mode(FOCUS_ALL);
@@ -42,10 +42,11 @@ ColorRampEdit::ColorRampEdit() {
add_child(popup);
checker = Ref<ImageTexture>(memnew(ImageTexture));
- checker->create_from_image(Image(checker_bg_png), ImageTexture::FLAG_REPEAT);
+ Ref<Image> img = memnew(Image(checker_bg_png));
+ checker->create_from_image(img, ImageTexture::FLAG_REPEAT);
}
-int ColorRampEdit::_get_point_from_pos(int x) {
+int GradientEdit::_get_point_from_pos(int x) {
int result = -1;
int total_w = get_size().width - get_size().height - 3;
for (int i = 0; i < points.size(); i++) {
@@ -57,7 +58,7 @@ int ColorRampEdit::_get_point_from_pos(int x) {
return result;
}
-void ColorRampEdit::_show_color_picker() {
+void GradientEdit::_show_color_picker() {
if (grabbed == -1)
return;
Size2 ms = Size2(350, picker->get_combined_minimum_size().height + 10);
@@ -67,12 +68,14 @@ void ColorRampEdit::_show_color_picker() {
popup->popup();
}
-ColorRampEdit::~ColorRampEdit() {
+GradientEdit::~GradientEdit() {
}
-void ColorRampEdit::_gui_input(const InputEvent &p_event) {
+void GradientEdit::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::KEY && p_event.key.pressed && p_event.key.scancode == KEY_DELETE && grabbed != -1) {
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid() && k->is_pressed() && k->get_scancode() == KEY_DELETE && grabbed != -1) {
points.remove(grabbed);
grabbed = -1;
@@ -82,16 +85,17 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
accept_event();
}
+ Ref<InputEventMouseButton> mb = p_event;
//Show color picker on double click.
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
- grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_doubleclick() && mb->is_pressed()) {
+ grabbed = _get_point_from_pos(mb->get_position().x);
_show_color_picker();
accept_event();
}
//Delete point on right click
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 2 && p_event.mouse_button.pressed) {
- grabbed = _get_point_from_pos(p_event.mouse_button.x);
+ if (mb.is_valid() && mb->get_button_index() == 2 && mb->is_pressed()) {
+ grabbed = _get_point_from_pos(mb->get_position().x);
if (grabbed != -1) {
points.remove(grabbed);
grabbed = -1;
@@ -103,14 +107,14 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
}
//Hold alt key to duplicate selected color
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed && p_event.key.mod.alt) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed() && mb->get_alt()) {
- int x = p_event.mouse_button.x;
+ int x = mb->get_position().x;
grabbed = _get_point_from_pos(x);
if (grabbed != -1) {
int total_w = get_size().width - get_size().height - 3;
- ColorRamp::Point newPoint = points[grabbed];
+ Gradient::Point newPoint = points[grabbed];
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
points.push_back(newPoint);
@@ -127,10 +131,10 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
update();
- int x = p_event.mouse_button.x;
+ int x = mb->get_position().x;
int total_w = get_size().width - get_size().height - 3;
//Check if color selector was clicked.
@@ -148,11 +152,11 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
}
//insert
- ColorRamp::Point newPoint;
+ Gradient::Point newPoint;
newPoint.offset = CLAMP(x / float(total_w), 0, 1);
- ColorRamp::Point prev;
- ColorRamp::Point next;
+ Gradient::Point prev;
+ Gradient::Point next;
int pos = -1;
for (int i = 0; i < points.size(); i++) {
@@ -195,7 +199,7 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
emit_signal("ramp_changed");
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == 1 && !p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
if (grabbing) {
grabbing = false;
@@ -204,15 +208,18 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
update();
}
- if (p_event.type == InputEvent::MOUSE_MOTION && grabbing) {
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid() && grabbing) {
int total_w = get_size().width - get_size().height - 3;
- int x = p_event.mouse_motion.x;
+ int x = mm->get_position().x;
+
float newofs = CLAMP(x / float(total_w), 0, 1);
//Snap to nearest point if holding shift
- if (p_event.key.mod.shift) {
+ if (mm->get_shift()) {
float snap_treshhold = 0.03;
float smallest_ofs = snap_treshhold;
bool founded = false;
@@ -265,7 +272,7 @@ void ColorRampEdit::_gui_input(const InputEvent &p_event) {
}
}
-void ColorRampEdit::_notification(int p_what) {
+void GradientEdit::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
if (!picker->is_connected("color_changed", this, "_color_changed")) {
@@ -286,7 +293,7 @@ void ColorRampEdit::_notification(int p_what) {
_draw_checker(0, 0, total_w, h);
//Draw color ramp
- ColorRamp::Point prev;
+ Gradient::Point prev;
prev.offset = 0;
if (points.size() == 0)
prev.color = Color(0, 0, 0); //Draw black rectangle if we have no points
@@ -295,7 +302,7 @@ void ColorRampEdit::_notification(int p_what) {
for (int i = -1; i < points.size(); i++) {
- ColorRamp::Point next;
+ Gradient::Point next;
//If there is no next point
if (i + 1 == points.size()) {
if (points.size() == 0)
@@ -363,7 +370,7 @@ void ColorRampEdit::_notification(int p_what) {
}
}
-void ColorRampEdit::_draw_checker(int x, int y, int w, int h) {
+void GradientEdit::_draw_checker(int x, int y, int w, int h) {
//Draw it with polygon to insert UVs for scale
Vector<Vector2> backPoints;
backPoints.push_back(Vector2(x, y));
@@ -384,12 +391,12 @@ void ColorRampEdit::_draw_checker(int x, int y, int w, int h) {
draw_polygon(backPoints, colorPoints, uvPoints, checker);
}
-Size2 ColorRampEdit::get_minimum_size() const {
+Size2 GradientEdit::get_minimum_size() const {
return Vector2(0, 16);
}
-void ColorRampEdit::_color_changed(const Color &p_color) {
+void GradientEdit::_color_changed(const Color &p_color) {
if (grabbed == -1)
return;
@@ -398,12 +405,12 @@ void ColorRampEdit::_color_changed(const Color &p_color) {
emit_signal("ramp_changed");
}
-void ColorRampEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
+void GradientEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors) {
ERR_FAIL_COND(p_offsets.size() != p_colors.size());
points.clear();
for (int i = 0; i < p_offsets.size(); i++) {
- ColorRamp::Point p;
+ Gradient::Point p;
p.offset = p_offsets[i];
p.color = p_colors[i];
points.push_back(p);
@@ -413,33 +420,33 @@ void ColorRampEdit::set_ramp(const Vector<float> &p_offsets, const Vector<Color>
update();
}
-Vector<float> ColorRampEdit::get_offsets() const {
+Vector<float> GradientEdit::get_offsets() const {
Vector<float> ret;
for (int i = 0; i < points.size(); i++)
ret.push_back(points[i].offset);
return ret;
}
-Vector<Color> ColorRampEdit::get_colors() const {
+Vector<Color> GradientEdit::get_colors() const {
Vector<Color> ret;
for (int i = 0; i < points.size(); i++)
ret.push_back(points[i].color);
return ret;
}
-void ColorRampEdit::set_points(Vector<ColorRamp::Point> &p_points) {
+void GradientEdit::set_points(Vector<Gradient::Point> &p_points) {
if (points.size() != p_points.size())
grabbed = -1;
points.clear();
points = p_points;
}
-Vector<ColorRamp::Point> &ColorRampEdit::get_points() {
+Vector<Gradient::Point> &GradientEdit::get_points() {
return points;
}
-void ColorRampEdit::_bind_methods() {
- ClassDB::bind_method(D_METHOD("_gui_input"), &ColorRampEdit::_gui_input);
- ClassDB::bind_method(D_METHOD("_color_changed"), &ColorRampEdit::_color_changed);
+void GradientEdit::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_gui_input"), &GradientEdit::_gui_input);
+ ClassDB::bind_method(D_METHOD("_color_changed"), &GradientEdit::_color_changed);
ADD_SIGNAL(MethodInfo("ramp_changed"));
}
diff --git a/scene/gui/color_ramp_edit.h b/scene/gui/gradient_edit.h
index 38176d2e77..6c4ae6fd15 100644
--- a/scene/gui/color_ramp_edit.h
+++ b/scene/gui/gradient_edit.h
@@ -37,9 +37,9 @@
#define POINT_WIDTH 8
-class ColorRampEdit : public Control {
+class GradientEdit : public Control {
- GDCLASS(ColorRampEdit, Control);
+ GDCLASS(GradientEdit, Control);
PopupPanel *popup;
ColorPicker *picker;
@@ -48,7 +48,7 @@ class ColorRampEdit : public Control {
bool grabbing;
int grabbed;
- Vector<ColorRamp::Point> points;
+ Vector<Gradient::Point> points;
void _draw_checker(int x, int y, int w, int h);
void _color_changed(const Color &p_color);
@@ -56,7 +56,7 @@ class ColorRampEdit : public Control {
void _show_color_picker();
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
static void _bind_methods();
@@ -64,12 +64,12 @@ public:
void set_ramp(const Vector<float> &p_offsets, const Vector<Color> &p_colors);
Vector<float> get_offsets() const;
Vector<Color> get_colors() const;
- void set_points(Vector<ColorRamp::Point> &p_points);
- Vector<ColorRamp::Point> &get_points();
+ void set_points(Vector<Gradient::Point> &p_points);
+ Vector<Gradient::Point> &get_points();
virtual Size2 get_minimum_size() const;
- ColorRampEdit();
- virtual ~ColorRampEdit();
+ GradientEdit();
+ virtual ~GradientEdit();
};
/*class ColorRampEditPanel : public Panel
diff --git a/scene/gui/graph_edit.cpp b/scene/gui/graph_edit.cpp
index 0bc48677dd..8d085d5399 100644
--- a/scene/gui/graph_edit.cpp
+++ b/scene/gui/graph_edit.cpp
@@ -168,24 +168,24 @@ void GraphEdit::_update_scroll() {
continue;
Rect2 r;
- r.pos = gn->get_offset() * zoom;
+ r.position = gn->get_offset() * zoom;
r.size = gn->get_size() * zoom;
screen = screen.merge(r);
}
- screen.pos -= get_size();
+ screen.position -= get_size();
screen.size += get_size() * 2.0;
- h_scroll->set_min(screen.pos.x);
- h_scroll->set_max(screen.pos.x + screen.size.x);
+ h_scroll->set_min(screen.position.x);
+ h_scroll->set_max(screen.position.x + screen.size.x);
h_scroll->set_page(get_size().x);
if (h_scroll->get_max() - h_scroll->get_min() <= h_scroll->get_page())
h_scroll->hide();
else
h_scroll->show();
- v_scroll->set_min(screen.pos.y);
- v_scroll->set_max(screen.pos.y + screen.size.y);
+ v_scroll->set_min(screen.position.y);
+ v_scroll->set_max(screen.position.y + screen.size.y);
v_scroll->set_page(get_size().y);
if (v_scroll->get_max() - v_scroll->get_min() <= v_scroll->get_page())
@@ -367,13 +367,14 @@ bool GraphEdit::_filter_input(const Point2 &p_point) {
return false;
}
-void GraphEdit::_top_layer_input(const InputEvent &p_ev) {
+void GraphEdit::_top_layer_input(const Ref<InputEvent> &p_ev) {
float grab_r_extend = 2.0;
- if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT && p_ev.mouse_button.pressed) {
+ Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && mb->is_pressed()) {
Ref<Texture> port = get_icon("port", "GraphNode");
- Vector2 mpos(p_ev.mouse_button.x, p_ev.mouse_button.y);
+ Vector2 mpos(mb->get_position().x, mb->get_position().y);
float grab_r = port->get_width() * 0.5 * grab_r_extend;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -479,14 +480,15 @@ void GraphEdit::_top_layer_input(const InputEvent &p_ev) {
}
}
- if (p_ev.type == InputEvent::MOUSE_MOTION && connecting) {
+ Ref<InputEventMouseMotion> mm = p_ev;
+ if (mm.is_valid() && connecting) {
- connecting_to = Vector2(p_ev.mouse_motion.x, p_ev.mouse_motion.y);
+ connecting_to = mm->get_position();
connecting_target = false;
top_layer->update();
Ref<Texture> port = get_icon("port", "GraphNode");
- Vector2 mpos(p_ev.mouse_button.x, p_ev.mouse_button.y);
+ Vector2 mpos = mm->get_position();
float grab_r = port->get_width() * 0.5 * grab_r_extend;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -526,7 +528,7 @@ void GraphEdit::_top_layer_input(const InputEvent &p_ev) {
}
}
- if (p_ev.type == InputEvent::MOUSE_BUTTON && p_ev.mouse_button.button_index == BUTTON_LEFT && !p_ev.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
if (connecting && connecting_target) {
@@ -544,7 +546,7 @@ void GraphEdit::_top_layer_input(const InputEvent &p_ev) {
} else if (!just_disconected) {
String from = connecting_from;
int from_slot = connecting_index;
- Vector2 ofs = Vector2(p_ev.mouse_button.x, p_ev.mouse_button.y);
+ Vector2 ofs = Vector2(mb->get_position().x, mb->get_position().y);
emit_signal("connection_to_empty", from, from_slot, ofs);
}
connecting = false;
@@ -579,7 +581,7 @@ void GraphEdit::_bake_segment2d(CanvasItem *p_where, float p_begin, float p_end,
if (p_depth >= p_min_depth && (dp < p_tol || p_depth >= p_max_depth)) {
- p_where->draw_line(beg, end, p_color.linear_interpolate(p_to_color, mp), 4, true);
+ p_where->draw_line(beg, end, p_color.linear_interpolate(p_to_color, mp), 2, true);
lines++;
} else {
_bake_segment2d(p_where, p_begin, mp, p_a, p_out, p_b, p_in, p_depth + 1, p_min_depth, p_max_depth, p_tol, p_color, p_to_color, lines);
@@ -598,7 +600,7 @@ void GraphEdit::_draw_cos_line(CanvasItem *p_where, const Vector2 &p_from, const
int cp_neg_len = get_constant("bezier_len_neg");
if (diff > 0) {
- cp_offset = MIN(cp_len, diff * 0.5);
+ cp_offset = MAX(cp_len, diff * 0.5);
} else {
cp_offset = MAX(MIN(cp_len - diff, cp_neg_len), -diff * 0.5);
}
@@ -739,18 +741,19 @@ void GraphEdit::set_selected(Node *p_child) {
}
}
-void GraphEdit::_gui_input(const InputEvent &p_ev) {
+void GraphEdit::_gui_input(const Ref<InputEvent> &p_ev) {
- if (p_ev.type == InputEvent::MOUSE_MOTION && (p_ev.mouse_motion.button_mask & BUTTON_MASK_MIDDLE || (p_ev.mouse_motion.button_mask & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
- h_scroll->set_value(h_scroll->get_value() - p_ev.mouse_motion.relative_x);
- v_scroll->set_value(v_scroll->get_value() - p_ev.mouse_motion.relative_y);
+ Ref<InputEventMouseMotion> mm = p_ev;
+ if (mm.is_valid() && (mm->get_button_mask() & BUTTON_MASK_MIDDLE || (mm->get_button_mask() & BUTTON_MASK_LEFT && Input::get_singleton()->is_key_pressed(KEY_SPACE)))) {
+ h_scroll->set_value(h_scroll->get_value() - mm->get_relative().x);
+ v_scroll->set_value(v_scroll->get_value() - mm->get_relative().y);
}
- if (p_ev.type == InputEvent::MOUSE_MOTION && dragging) {
+ if (mm.is_valid() && dragging) {
just_selected = true;
// TODO: Remove local mouse pos hack if/when InputEventMouseMotion is fixed to support floats
- //drag_accum+=Vector2(p_ev.mouse_motion.relative_x,p_ev.mouse_motion.relative_y);
+ //drag_accum+=Vector2(mm->get_relative().x,mm->get_relative().y);
drag_accum = get_local_mouse_pos() - drag_origin;
for (int i = get_child_count() - 1; i >= 0; i--) {
GraphNode *gn = get_child(i)->cast_to<GraphNode>();
@@ -767,7 +770,7 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
}
}
- if (p_ev.type == InputEvent::MOUSE_MOTION && box_selecting) {
+ if (mm.is_valid() && box_selecting) {
box_selecting_to = get_local_mouse_pos();
box_selecting_rect = Rect2(MIN(box_selecting_from.x, box_selecting_to.x),
@@ -794,11 +797,10 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
top_layer->update();
}
- if (p_ev.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> b = p_ev;
+ if (b.is_valid()) {
- const InputEventMouseButton &b = p_ev.mouse_button;
-
- if (b.button_index == BUTTON_RIGHT && b.pressed) {
+ if (b->get_button_index() == BUTTON_RIGHT && b->is_pressed()) {
if (box_selecting) {
box_selecting = false;
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -815,12 +817,12 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
connecting = false;
top_layer->update();
} else {
- emit_signal("popup_request", Vector2(b.global_x, b.global_y));
+ emit_signal("popup_request", b->get_global_position());
}
}
}
- if (b.button_index == BUTTON_LEFT && !b.pressed && dragging) {
+ if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && dragging) {
if (!just_selected && drag_accum == Vector2() && Input::get_singleton()->is_key_pressed(KEY_CONTROL)) {
//deselect current node
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -855,7 +857,7 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
connections_layer->update();
}
- if (b.button_index == BUTTON_LEFT && b.pressed) {
+ if (b->get_button_index() == BUTTON_LEFT && b->is_pressed()) {
GraphNode *gn = NULL;
GraphNode *gn_selected = NULL;
@@ -878,7 +880,7 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
if (gn) {
- if (_filter_input(Vector2(b.x, b.y)))
+ if (_filter_input(b->get_position()))
return;
dragging = true;
@@ -903,14 +905,14 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
}
} else {
- if (_filter_input(Vector2(b.x, b.y)))
+ if (_filter_input(b->get_position()))
return;
if (Input::get_singleton()->is_key_pressed(KEY_SPACE))
return;
box_selecting = true;
box_selecting_from = get_local_mouse_pos();
- if (b.mod.control) {
+ if (b->get_control()) {
box_selection_mode_aditive = true;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -921,7 +923,7 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
previus_selected.push_back(gn);
}
- } else if (b.mod.shift) {
+ } else if (b->get_shift()) {
box_selection_mode_aditive = false;
previus_selected.clear();
for (int i = get_child_count() - 1; i >= 0; i--) {
@@ -947,29 +949,42 @@ void GraphEdit::_gui_input(const InputEvent &p_ev) {
}
}
- if (b.button_index == BUTTON_LEFT && !b.pressed && box_selecting) {
+ if (b->get_button_index() == BUTTON_LEFT && !b->is_pressed() && box_selecting) {
box_selecting = false;
previus_selected.clear();
top_layer->update();
}
- if (b.button_index == BUTTON_WHEEL_UP && b.pressed) {
+ if (b->get_button_index() == BUTTON_WHEEL_UP && b->is_pressed()) {
//too difficult to get right
//set_zoom(zoom*ZOOM_SCALE);
}
- if (b.button_index == BUTTON_WHEEL_DOWN && b.pressed) {
+ if (b->get_button_index() == BUTTON_WHEEL_DOWN && b->is_pressed()) {
//too difficult to get right
//set_zoom(zoom/ZOOM_SCALE);
}
+ if (b->get_button_index() == BUTTON_WHEEL_UP) {
+ h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * b->get_factor() / 8);
+ }
+ if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
+ h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * b->get_factor() / 8);
+ }
+ if (b->get_button_index() == BUTTON_WHEEL_RIGHT) {
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
+ }
+ if (b->get_button_index() == BUTTON_WHEEL_LEFT) {
+ v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
+ }
}
- if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_D && p_ev.key.pressed && p_ev.key.mod.command) {
+ Ref<InputEventKey> k = p_ev;
+ if (k.is_valid() && k->get_scancode() == KEY_D && k->is_pressed() && k->get_command()) {
emit_signal("duplicate_nodes_request");
accept_event();
}
- if (p_ev.type == InputEvent::KEY && p_ev.key.scancode == KEY_DELETE && p_ev.key.pressed) {
+ if (k.is_valid() && k->get_scancode() == KEY_DELETE && k->is_pressed()) {
emit_signal("delete_nodes_request");
accept_event();
}
diff --git a/scene/gui/graph_edit.h b/scene/gui/graph_edit.h
index ff3867a059..22d053d312 100644
--- a/scene/gui/graph_edit.h
+++ b/scene/gui/graph_edit.h
@@ -119,11 +119,11 @@ private:
void _update_scroll();
void _scroll_moved(double);
- void _gui_input(const InputEvent &p_ev);
+ void _gui_input(const Ref<InputEvent> &p_ev);
Control *connections_layer;
GraphEditFilter *top_layer;
- void _top_layer_input(const InputEvent &p_ev);
+ void _top_layer_input(const Ref<InputEvent> &p_ev);
void _top_layer_draw();
void _connections_layer_draw();
void _update_scroll_offset();
diff --git a/scene/gui/graph_node.cpp b/scene/gui/graph_node.cpp
index f7bb866f6f..95f65f31d6 100644
--- a/scene/gui/graph_node.cpp
+++ b/scene/gui/graph_node.cpp
@@ -239,7 +239,7 @@ void GraphNode::_notification(int p_what) {
if (show_close) {
Vector2 cpos = Point2(w + sb->get_margin(MARGIN_LEFT), -close->get_height() + close_offset);
draw_texture(close, cpos);
- close_rect.pos = cpos;
+ close_rect.position = cpos;
close_rect.size = close->get_size();
} else {
close_rect = Rect2();
@@ -574,18 +574,17 @@ Color GraphNode::get_connection_output_color(int p_idx) {
return conn_output_cache[p_idx].color;
}
-void GraphNode::_gui_input(const InputEvent &p_ev) {
+void GraphNode::_gui_input(const Ref<InputEvent> &p_ev) {
- if (p_ev.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_ev;
+ if (mb.is_valid()) {
ERR_EXPLAIN("GraphNode must be the child of a GraphEdit node.");
ERR_FAIL_COND(get_parent_control() == NULL);
- print_line("INPUT EVENT BUTTON");
+ if (mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
- if (p_ev.mouse_button.pressed && p_ev.mouse_button.button_index == BUTTON_LEFT) {
-
- Vector2 mpos = Vector2(p_ev.mouse_button.x, p_ev.mouse_button.y);
+ Vector2 mpos = Vector2(mb->get_position().x, mb->get_position().y);
if (close_rect.size != Size2() && close_rect.has_point(mpos)) {
emit_signal("close_request");
accept_event();
@@ -608,13 +607,14 @@ void GraphNode::_gui_input(const InputEvent &p_ev) {
get_parent_control()->grab_focus();
}
- if (!p_ev.mouse_button.pressed && p_ev.mouse_button.button_index == BUTTON_LEFT) {
+ if (!mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
resizing = false;
}
}
- if (resizing && p_ev.type == InputEvent::MOUSE_MOTION) {
- Vector2 mpos = Vector2(p_ev.mouse_motion.x, p_ev.mouse_motion.y);
+ Ref<InputEventMouseMotion> mm = p_ev;
+ if (resizing && mm.is_valid()) {
+ Vector2 mpos = mm->get_position();
Vector2 diff = mpos - resizing_from;
diff --git a/scene/gui/graph_node.h b/scene/gui/graph_node.h
index e98d0b3d07..056b699aa6 100644
--- a/scene/gui/graph_node.h
+++ b/scene/gui/graph_node.h
@@ -102,7 +102,7 @@ private:
bool has_point(const Point2 &p_point) const;
protected:
- void _gui_input(const InputEvent &p_ev);
+ void _gui_input(const Ref<InputEvent> &p_ev);
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/input_action.cpp b/scene/gui/input_action.cpp
index 5b03338286..311cb4ab13 100644
--- a/scene/gui/input_action.cpp
+++ b/scene/gui/input_action.cpp
@@ -30,95 +30,73 @@
#include "input_action.h"
#include "os/keyboard.h"
-void ShortCut::set_shortcut(const InputEvent &p_shortcut) {
+void ShortCut::set_shortcut(const Ref<InputEvent> &p_shortcut) {
shortcut = p_shortcut;
emit_changed();
}
-InputEvent ShortCut::get_shortcut() const {
+Ref<InputEvent> ShortCut::get_shortcut() const {
return shortcut;
}
-bool ShortCut::is_shortcut(const InputEvent &p_event) const {
+bool ShortCut::is_shortcut(const Ref<InputEvent> &p_event) const {
- bool same = false;
-
- switch (p_event.type) {
-
- case InputEvent::KEY: {
-
- same = (shortcut.key.scancode == p_event.key.scancode && shortcut.key.mod == p_event.key.mod);
-
- } break;
- case InputEvent::JOYPAD_BUTTON: {
-
- same = (shortcut.joy_button.button_index == p_event.joy_button.button_index);
-
- } break;
- case InputEvent::MOUSE_BUTTON: {
-
- same = (shortcut.mouse_button.button_index == p_event.mouse_button.button_index);
-
- } break;
- case InputEvent::JOYPAD_MOTION: {
-
- same = (shortcut.joy_motion.axis == p_event.joy_motion.axis && (shortcut.joy_motion.axis_value < 0) == (p_event.joy_motion.axis_value < 0));
-
- } break;
- default: {};
- }
-
- return same;
+ return shortcut.is_valid() && shortcut->action_match(p_event);
}
String ShortCut::get_as_text() const {
+ if (shortcut.is_valid())
+ return shortcut->as_text();
+ else
+ return "None";
+#if 0
switch (shortcut.type) {
- case InputEvent::NONE: {
+ case Ref<InputEvent>::NONE: {
return "None";
} break;
- case InputEvent::KEY: {
+ case Ref<InputEvent>::KEY: {
String str;
- if (shortcut.key.mod.shift)
+ if (shortcut->get_shift())
str += RTR("Shift+");
- if (shortcut.key.mod.alt)
+ if (shortcut->get_alt())
str += RTR("Alt+");
- if (shortcut.key.mod.control)
+ if (shortcut->get_control())
str += RTR("Ctrl+");
- if (shortcut.key.mod.meta)
+ if (shortcut->get_metakey())
str += RTR("Meta+");
- str += keycode_get_string(shortcut.key.scancode).capitalize();
+ str += keycode_get_string(shortcut->get_scancode()).capitalize();
return str;
} break;
- case InputEvent::JOYPAD_BUTTON: {
+ case Ref<InputEvent>::JOYPAD_BUTTON: {
- String str = RTR("Device") + " " + itos(shortcut.device) + ", " + RTR("Button") + " " + itos(shortcut.joy_button.button_index);
+ String str = RTR("Device") + " " + itos(shortcut.device) + ", " + RTR("Button") + " " + itos(shortcut.joy_button->get_button_index());
str += ".";
return str;
} break;
- case InputEvent::MOUSE_BUTTON: {
+ case Ref<InputEvent>::MOUSE_BUTTON: {
String str = RTR("Device") + " " + itos(shortcut.device) + ", ";
- switch (shortcut.mouse_button.button_index) {
+ switch (shortcut->get_button_index()) {
case BUTTON_LEFT: str += RTR("Left Button."); break;
case BUTTON_RIGHT: str += RTR("Right Button."); break;
case BUTTON_MIDDLE: str += RTR("Middle Button."); break;
case BUTTON_WHEEL_UP: str += RTR("Wheel Up."); break;
case BUTTON_WHEEL_DOWN: str += RTR("Wheel Down."); break;
- default: str += RTR("Button") + " " + itos(shortcut.mouse_button.button_index) + ".";
+ default: str += RTR("Button") + " " + itos(shortcut->get_button_index()) + ".";
}
return str;
} break;
- case InputEvent::JOYPAD_MOTION: {
+ case Ref<InputEvent>::JOYPAD_MOTION: {
int ax = shortcut.joy_motion.axis;
String str = RTR("Device") + " " + itos(shortcut.device) + ", " + RTR("Axis") + " " + itos(ax) + ".";
@@ -128,24 +106,25 @@ String ShortCut::get_as_text() const {
}
return "";
+#endif
}
bool ShortCut::is_valid() const {
- return shortcut.type != InputEvent::NONE;
+ return shortcut.is_valid();
}
void ShortCut::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_shortcut", "event"), &ShortCut::set_shortcut);
- ClassDB::bind_method(D_METHOD("get_shortcut"), &ShortCut::get_shortcut);
+ ClassDB::bind_method(D_METHOD("set_shortcut", "event:InputEvent"), &ShortCut::set_shortcut);
+ ClassDB::bind_method(D_METHOD("get_shortcut:InputEvent"), &ShortCut::get_shortcut);
ClassDB::bind_method(D_METHOD("is_valid"), &ShortCut::is_valid);
- ClassDB::bind_method(D_METHOD("is_shortcut", "event"), &ShortCut::is_shortcut);
+ ClassDB::bind_method(D_METHOD("is_shortcut", "event:InputEvent"), &ShortCut::is_shortcut);
ClassDB::bind_method(D_METHOD("get_as_text"), &ShortCut::get_as_text);
- ADD_PROPERTY(PropertyInfo(Variant::INPUT_EVENT, "shortcut"), "set_shortcut", "get_shortcut");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "shortcut", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent"), "set_shortcut", "get_shortcut");
}
ShortCut::ShortCut() {
diff --git a/scene/gui/input_action.h b/scene/gui/input_action.h
index c33490ae1d..6d13d8bd40 100644
--- a/scene/gui/input_action.h
+++ b/scene/gui/input_action.h
@@ -30,21 +30,22 @@
#ifndef INPUTACTION_H
#define INPUTACTION_H
+#include "os/input_event.h"
#include "resource.h"
class ShortCut : public Resource {
GDCLASS(ShortCut, Resource);
- InputEvent shortcut;
+ Ref<InputEvent> shortcut;
protected:
static void _bind_methods();
public:
- void set_shortcut(const InputEvent &p_shortcut);
- InputEvent get_shortcut() const;
- bool is_shortcut(const InputEvent &p_Event) const;
+ void set_shortcut(const Ref<InputEvent> &p_shortcut);
+ Ref<InputEvent> get_shortcut() const;
+ bool is_shortcut(const Ref<InputEvent> &p_Event) const;
bool is_valid() const;
String get_as_text() const;
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 1dc4230d2a..2f0c7b9aaf 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -42,7 +42,6 @@ void ItemList::add_item(const String &p_item, const Ref<Texture> &p_texture, boo
item.disabled = false;
item.tooltip_enabled = true;
item.custom_bg = Color(0, 0, 0, 0);
- item.custom_font_color = get_color("font_color");
items.push_back(item);
update();
@@ -152,20 +151,6 @@ Color ItemList::get_item_custom_bg_color(int p_idx) const {
return items[p_idx].custom_bg;
}
-void ItemList::set_item_custom_font_color(int p_idx, const Color &p_custom_font_color) {
-
- ERR_FAIL_INDEX(p_idx, items.size());
-
- items[p_idx].custom_font_color = p_custom_font_color;
-}
-
-Color ItemList::get_item_custom_font_color(int p_idx) const {
-
- ERR_FAIL_INDEX_V(p_idx, items.size(), Color());
-
- return items[p_idx].custom_font_color;
-}
-
void ItemList::set_item_tag_icon(int p_idx, const Ref<Texture> &p_tag_icon) {
ERR_FAIL_INDEX(p_idx, items.size());
@@ -424,14 +409,17 @@ Size2 ItemList::Item::get_icon_size() const {
return icon_region.size;
}
-void ItemList::_gui_input(const InputEvent &p_event) {
+void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
- if (defer_select_single >= 0 && p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (defer_select_single >= 0 && mm.is_valid()) {
defer_select_single = -1;
return;
}
- if (defer_select_single >= 0 && p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_LEFT && !p_event.mouse_button.pressed) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (defer_select_single >= 0 && mb.is_valid() && mb->get_button_index() == BUTTON_LEFT && !mb->is_pressed()) {
select(defer_select_single, true);
@@ -440,12 +428,10 @@ void ItemList::_gui_input(const InputEvent &p_event) {
return;
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && (p_event.mouse_button.button_index == BUTTON_LEFT || (allow_rmb_select && p_event.mouse_button.button_index == BUTTON_RIGHT)) && p_event.mouse_button.pressed) {
-
- const InputEventMouseButton &mb = p_event.mouse_button;
+ if (mb.is_valid() && (mb->get_button_index() == BUTTON_LEFT || (allow_rmb_select && mb->get_button_index() == BUTTON_RIGHT)) && mb->is_pressed()) {
search_string = ""; //any mousepress cancels
- Vector2 pos(mb.x, mb.y);
+ Vector2 pos(mb->get_position().x, mb->get_position().y);
Ref<StyleBox> bg = get_stylebox("bg");
pos -= bg->get_offset();
pos.y += scroll_bar->get_value();
@@ -469,11 +455,11 @@ void ItemList::_gui_input(const InputEvent &p_event) {
int i = closest;
- if (select_mode == SELECT_MULTI && items[i].selected && mb.mod.command) {
+ if (select_mode == SELECT_MULTI && items[i].selected && mb->get_command()) {
unselect(i);
emit_signal("multi_selected", i, false);
- } else if (select_mode == SELECT_MULTI && mb.mod.shift && current >= 0 && current < items.size() && current != i) {
+ } else if (select_mode == SELECT_MULTI && mb->get_shift() && current >= 0 && current < items.size() && current != i) {
int from = current;
int to = i;
@@ -487,24 +473,24 @@ void ItemList::_gui_input(const InputEvent &p_event) {
emit_signal("multi_selected", i, true);
}
- if (p_event.mouse_button.button_index == BUTTON_RIGHT) {
+ if (mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, Vector2(mb.x, mb.y));
+ emit_signal("item_rmb_selected", i, Vector2(mb->get_position().x, mb->get_position().y));
}
} else {
- if (!mb.doubleclick && !mb.mod.command && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ if (!mb->is_doubleclick() && !mb->get_command() && select_mode == SELECT_MULTI && items[i].selectable && !items[i].disabled && items[i].selected && mb->get_button_index() == BUTTON_LEFT) {
defer_select_single = i;
return;
}
- if (items[i].selected && p_event.mouse_button.button_index == BUTTON_RIGHT) {
+ if (items[i].selected && mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, Vector2(mb.x, mb.y));
+ emit_signal("item_rmb_selected", i, Vector2(mb->get_position().x, mb->get_position().y));
} else {
bool selected = !items[i].selected;
- select(i, select_mode == SELECT_SINGLE || !mb.mod.command);
+ select(i, select_mode == SELECT_SINGLE || !mb->get_command());
if (selected) {
if (select_mode == SELECT_SINGLE) {
@@ -513,10 +499,10 @@ void ItemList::_gui_input(const InputEvent &p_event) {
emit_signal("multi_selected", i, true);
}
- if (p_event.mouse_button.button_index == BUTTON_RIGHT) {
+ if (mb->get_button_index() == BUTTON_RIGHT) {
- emit_signal("item_rmb_selected", i, Vector2(mb.x, mb.y));
- } else if (/*select_mode==SELECT_SINGLE &&*/ mb.doubleclick) {
+ emit_signal("item_rmb_selected", i, Vector2(mb->get_position().x, mb->get_position().y));
+ } else if (/*select_mode==SELECT_SINGLE &&*/ mb->is_doubleclick()) {
emit_signal("item_activated", i);
}
@@ -531,17 +517,17 @@ void ItemList::_gui_input(const InputEvent &p_event) {
}
}
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_WHEEL_UP && p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
- scroll_bar->set_value(scroll_bar->get_value() - scroll_bar->get_page() / 8);
+ scroll_bar->set_value(scroll_bar->get_value() - scroll_bar->get_page() * mb->get_factor() / 8);
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index == BUTTON_WHEEL_DOWN && p_event.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
- scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() / 8);
+ scroll_bar->set_value(scroll_bar->get_value() + scroll_bar->get_page() * mb->get_factor() / 8);
}
- if (p_event.is_pressed() && items.size() > 0) {
- if (p_event.is_action("ui_up")) {
+ if (p_event->is_pressed() && items.size() > 0) {
+ if (p_event->is_action("ui_up")) {
if (search_string != "") {
@@ -576,7 +562,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
}
accept_event();
}
- } else if (p_event.is_action("ui_down")) {
+ } else if (p_event->is_action("ui_down")) {
if (search_string != "") {
@@ -610,7 +596,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
}
accept_event();
}
- } else if (p_event.is_action("ui_page_up")) {
+ } else if (p_event->is_action("ui_page_up")) {
search_string = ""; //any mousepress cancels
@@ -625,7 +611,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
break;
}
}
- } else if (p_event.is_action("ui_page_down")) {
+ } else if (p_event->is_action("ui_page_down")) {
search_string = ""; //any mousepress cancels
@@ -641,7 +627,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
break;
}
}
- } else if (p_event.is_action("ui_left")) {
+ } else if (p_event->is_action("ui_left")) {
search_string = ""; //any mousepress cancels
@@ -653,7 +639,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
}
accept_event();
}
- } else if (p_event.is_action("ui_right")) {
+ } else if (p_event->is_action("ui_right")) {
search_string = ""; //any mousepress cancels
@@ -665,9 +651,9 @@ void ItemList::_gui_input(const InputEvent &p_event) {
}
accept_event();
}
- } else if (p_event.is_action("ui_cancel")) {
+ } else if (p_event->is_action("ui_cancel")) {
search_string = "";
- } else if (p_event.is_action("ui_select")) {
+ } else if (p_event->is_action("ui_select")) {
if (select_mode == SELECT_MULTI && current >= 0 && current < items.size()) {
if (items[current].selectable && !items[current].disabled && !items[current].selected) {
@@ -678,15 +664,17 @@ void ItemList::_gui_input(const InputEvent &p_event) {
emit_signal("multi_selected", current, false);
}
}
- } else if (p_event.is_action("ui_accept")) {
+ } else if (p_event->is_action("ui_accept")) {
search_string = ""; //any mousepress cance
if (current >= 0 && current < items.size()) {
emit_signal("item_activated", current);
}
- } else if (p_event.type == InputEvent::KEY) {
+ } else {
+
+ Ref<InputEventKey> k = p_event;
- if (p_event.key.unicode) {
+ if (k.is_valid() && k->get_unicode()) {
uint64_t now = OS::get_singleton()->get_ticks_msec();
uint64_t diff = now - search_time_msec;
@@ -697,7 +685,7 @@ void ItemList::_gui_input(const InputEvent &p_event) {
search_string = "";
}
- search_string += String::chr(p_event.key.unicode);
+ search_string += String::chr(k->get_unicode());
for (int i = 0; i < items.size(); i++) {
if (items[i].text.begins_with(search_string)) {
set_current(i);
@@ -869,7 +857,7 @@ void ItemList::_notification(int p_what) {
items[i].rect_cache = items[i].min_rect_cache;
if (same_column_width)
items[i].rect_cache.size.x = max_column_width;
- items[i].rect_cache.pos = ofs;
+ items[i].rect_cache.position = ofs;
max_h = MAX(max_h, items[i].rect_cache.size.y);
ofs.x += items[i].rect_cache.size.x + hseparation;
//print_line("item "+itos(i)+" ofs "+rtos(items[i].rect_cache.size.x));
@@ -918,10 +906,10 @@ void ItemList::_notification(int p_what) {
int from = scroll_bar->get_value();
int to = from + scroll_bar->get_page();
- if (r.pos.y < from) {
- scroll_bar->set_value(r.pos.y);
- } else if (r.pos.y + r.size.y > to) {
- scroll_bar->set_value(r.pos.y + r.size.y - (to - from));
+ if (r.position.y < from) {
+ scroll_bar->set_value(r.position.y);
+ } else if (r.position.y + r.size.y > to) {
+ scroll_bar->set_value(r.position.y + r.size.y - (to - from));
}
}
@@ -940,26 +928,29 @@ void ItemList::_notification(int p_what) {
continue;
if (current_columns == 1) {
- rcache.size.width = width - rcache.pos.x;
+ rcache.size.width = width - rcache.position.x;
}
- Rect2 r = rcache;
- r.pos += base_ofs;
-
- // Use stylebox to dimension potential bg color, even if not selected
- r.pos.x -= sbsel->get_margin(MARGIN_LEFT);
- r.size.x += sbsel->get_margin(MARGIN_LEFT) + sbsel->get_margin(MARGIN_RIGHT);
- r.pos.y -= sbsel->get_margin(MARGIN_TOP);
- r.size.y += sbsel->get_margin(MARGIN_TOP) + sbsel->get_margin(MARGIN_BOTTOM);
-
if (items[i].selected) {
+ Rect2 r = rcache;
+ r.position += base_ofs;
+
+ // Use stylebox to dimension potential bg color
+ r.position.x -= sbsel->get_margin(MARGIN_LEFT);
+ r.size.x += sbsel->get_margin(MARGIN_LEFT) + sbsel->get_margin(MARGIN_RIGHT);
+ r.position.y -= sbsel->get_margin(MARGIN_TOP);
+ r.size.y += sbsel->get_margin(MARGIN_TOP) + sbsel->get_margin(MARGIN_BOTTOM);
draw_style_box(sbsel, r);
}
+
if (items[i].custom_bg.a > 0.001) {
- r.pos.x += 2;
- r.size.x -= 4;
- r.pos.y += 2;
- r.size.y -= 4;
+
+ Rect2 r = rcache;
+ r.position += base_ofs;
+
+ // Size rect to make the align the temperature colors
+ r.position.y -= vseparation / 2;
+ r.size.y += vseparation;
draw_rect(r, items[i].custom_bg);
}
@@ -977,7 +968,7 @@ void ItemList::_notification(int p_what) {
Vector2 icon_ofs;
- Point2 pos = items[i].rect_cache.pos + icon_ofs + base_ofs;
+ Point2 pos = items[i].rect_cache.position + icon_ofs + base_ofs;
if (icon_mode == ICON_MODE_TOP) {
@@ -997,7 +988,7 @@ void ItemList::_notification(int p_what) {
if (fixed_icon_size.x > 0 && fixed_icon_size.y > 0) {
Rect2 adj = _adjust_to_max_size(items[i].get_icon_size() * icon_scale, icon_size);
- draw_rect.pos += adj.pos;
+ draw_rect.position += adj.position;
draw_rect.size = adj.size;
}
@@ -1013,7 +1004,7 @@ void ItemList::_notification(int p_what) {
if (items[i].tag_icon.is_valid()) {
- draw_texture(items[i].tag_icon, items[i].rect_cache.pos + base_ofs);
+ draw_texture(items[i].tag_icon, items[i].rect_cache.position + base_ofs);
}
if (items[i].text != "") {
@@ -1028,8 +1019,7 @@ void ItemList::_notification(int p_what) {
else
max_len = size.x;
- Color font_color_2 = items[i].custom_font_color;
- Color modulate = items[i].selected ? font_color_selected : font_color_2;
+ Color modulate = items[i].selected ? font_color_selected : font_color;
if (items[i].disabled)
modulate.a *= 0.5;
@@ -1059,7 +1049,7 @@ void ItemList::_notification(int p_what) {
text_ofs.y += font->get_ascent();
text_ofs = text_ofs.floor();
text_ofs += base_ofs;
- text_ofs += items[i].rect_cache.pos;
+ text_ofs += items[i].rect_cache.position;
for (int j = 0; j < ss; j++) {
@@ -1087,7 +1077,7 @@ void ItemList::_notification(int p_what) {
text_ofs.y += font->get_ascent();
text_ofs = text_ofs.floor();
text_ofs += base_ofs;
- text_ofs += items[i].rect_cache.pos;
+ text_ofs += items[i].rect_cache.position;
draw_string(font, text_ofs, items[i].text, modulate, max_len + 1);
}
@@ -1096,7 +1086,7 @@ void ItemList::_notification(int p_what) {
if (select_mode == SELECT_MULTI && i == current) {
Rect2 r = rcache;
- r.pos += base_ofs;
+ r.position += base_ofs;
draw_style_box(cursor, r);
}
}
@@ -1154,7 +1144,7 @@ bool ItemList::is_pos_at_end_of_items(const Point2 &p_pos) const {
pos.y += scroll_bar->get_value();
Rect2 endrect = items[items.size() - 1].rect_cache;
- return (pos.y > endrect.pos.y + endrect.size.y);
+ return (pos.y > endrect.position.y + endrect.size.y);
}
String ItemList::get_tooltip(const Point2 &p_pos) const {
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index 96a894d3fd..c7abc2990f 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -62,7 +62,6 @@ private:
Variant metadata;
String tooltip;
Color custom_bg;
- Color custom_font_color;
Rect2 rect_cache;
Rect2 min_rect_cache;
@@ -105,7 +104,7 @@ private:
real_t icon_scale;
void _scroll_changed(double);
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
protected:
void _notification(int p_what);
@@ -145,9 +144,6 @@ public:
void set_item_custom_bg_color(int p_idx, const Color &p_custom_bg_color);
Color get_item_custom_bg_color(int p_idx) const;
- void set_item_custom_font_color(int p_idx, const Color &p_custom_font_color);
- Color get_item_custom_font_color(int p_idx) const;
-
void select(int p_idx, bool p_single = true);
void unselect(int p_idx);
bool is_selected(int p_idx) const;
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp
index 0acb7265e3..bc579020bd 100644
--- a/scene/gui/line_edit.cpp
+++ b/scene/gui/line_edit.cpp
@@ -42,445 +42,442 @@ static bool _is_text_char(CharType c) {
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_';
}
-void LineEdit::_gui_input(InputEvent p_event) {
+void LineEdit::_gui_input(Ref<InputEvent> p_event) {
- switch (p_event.type) {
+ Ref<InputEventMouseButton> b = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (b.is_valid()) {
- const InputEventMouseButton &b = p_event.mouse_button;
-
- if (b.pressed && b.button_index == BUTTON_RIGHT) {
- menu->set_position(get_global_transform().xform(get_local_mouse_pos()));
- menu->set_size(Vector2(1, 1));
- menu->popup();
- grab_focus();
- return;
- }
+ if (b->is_pressed() && b->get_button_index() == BUTTON_RIGHT) {
+ menu->set_position(get_global_transform().xform(get_local_mouse_pos()));
+ menu->set_size(Vector2(1, 1));
+ menu->popup();
+ grab_focus();
+ return;
+ }
- if (b.button_index != BUTTON_LEFT)
- break;
+ if (b->get_button_index() != BUTTON_LEFT)
+ return;
- _reset_caret_blink_timer();
- if (b.pressed) {
+ _reset_caret_blink_timer();
+ if (b->is_pressed()) {
- shift_selection_check_pre(b.mod.shift);
+ shift_selection_check_pre(b->get_shift());
- set_cursor_at_pixel_pos(b.x);
+ set_cursor_at_pixel_pos(b->get_position().x);
- if (b.mod.shift) {
+ if (b->get_shift()) {
- selection_fill_at_cursor();
- selection.creating = true;
+ selection_fill_at_cursor();
+ selection.creating = true;
- } else {
+ } else {
- if (b.doubleclick) {
+ if (b->is_doubleclick()) {
- selection.enabled = true;
- selection.begin = 0;
- selection.end = text.length();
- selection.doubleclick = true;
- }
+ selection.enabled = true;
+ selection.begin = 0;
+ selection.end = text.length();
+ selection.doubleclick = true;
+ }
- selection.drag_attempt = false;
+ selection.drag_attempt = false;
- if ((cursor_pos < selection.begin) || (cursor_pos > selection.end) || !selection.enabled) {
+ if ((cursor_pos < selection.begin) || (cursor_pos > selection.end) || !selection.enabled) {
- selection_clear();
- selection.cursor_start = cursor_pos;
- selection.creating = true;
- } else if (selection.enabled) {
+ selection_clear();
+ selection.cursor_start = cursor_pos;
+ selection.creating = true;
+ } else if (selection.enabled) {
- selection.drag_attempt = true;
- }
+ selection.drag_attempt = true;
}
+ }
- update();
-
- } else {
+ update();
- if ((!selection.creating) && (!selection.doubleclick)) {
- selection_clear();
- }
- selection.creating = false;
- selection.doubleclick = false;
+ } else {
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
+ if ((!selection.creating) && (!selection.doubleclick)) {
+ selection_clear();
}
+ selection.creating = false;
+ selection.doubleclick = false;
- update();
- } break;
- case InputEvent::MOUSE_MOTION: {
+ if (OS::get_singleton()->has_virtual_keyboard())
+ OS::get_singleton()->show_virtual_keyboard(text, get_global_rect());
+ }
- const InputEventMouseMotion &m = p_event.mouse_motion;
+ update();
+ }
- if (m.button_mask & BUTTON_LEFT) {
+ Ref<InputEventMouseMotion> m = p_event;
- if (selection.creating) {
- set_cursor_at_pixel_pos(m.x);
- selection_fill_at_cursor();
- }
- }
+ if (m.is_valid()) {
- } break;
- case InputEvent::KEY: {
+ if (m->get_button_mask() & BUTTON_LEFT) {
- const InputEventKey &k = p_event.key;
+ if (selection.creating) {
+ set_cursor_at_pixel_pos(m->get_position().x);
+ selection_fill_at_cursor();
+ }
+ }
+ }
- if (!k.pressed)
- return;
- unsigned int code = k.scancode;
+ Ref<InputEventKey> k = p_event;
- if (k.mod.command) {
+ if (k.is_valid()) {
- bool handled = true;
+ if (!k->is_pressed())
+ return;
+ unsigned int code = k->get_scancode();
- switch (code) {
+ if (k->get_command()) {
- case (KEY_X): { // CUT
+ bool handled = true;
- if (editable) {
- cut_text();
- }
+ switch (code) {
- } break;
+ case (KEY_X): { // CUT
- case (KEY_C): { // COPY
+ if (editable) {
+ cut_text();
+ }
- copy_text();
+ } break;
- } break;
+ case (KEY_C): { // COPY
- case (KEY_V): { // PASTE
+ copy_text();
- if (editable) {
+ } break;
- paste_text();
- }
+ case (KEY_V): { // PASTE
- } break;
+ if (editable) {
- case (KEY_Z): { // Simple One level undo
+ paste_text();
+ }
- if (editable) {
+ } break;
- undo();
- }
+ case (KEY_Z): { // Simple One level undo
- } break;
+ if (editable) {
+
+ undo();
+ }
- case (KEY_U): { // Delete from start to cursor
+ } break;
- if (editable) {
+ case (KEY_U): { // Delete from start to cursor
- selection_clear();
- undo_text = text;
- text = text.substr(cursor_pos, text.length() - cursor_pos);
+ if (editable) {
- Ref<Font> font = get_font("font");
+ selection_clear();
+ undo_text = text;
+ text = text.substr(cursor_pos, text.length() - cursor_pos);
- cached_width = 0;
- if (font != NULL) {
- for (int i = 0; i < text.length(); i++)
- cached_width += font->get_char_size(text[i]).width;
- }
+ Ref<Font> font = get_font("font");
- set_cursor_pos(0);
- _text_changed();
+ cached_width = 0;
+ if (font != NULL) {
+ for (int i = 0; i < text.length(); i++)
+ cached_width += font->get_char_size(text[i]).width;
}
- } break;
+ set_cursor_pos(0);
+ _text_changed();
+ }
- case (KEY_Y): { // PASTE (Yank for unix users)
+ } break;
- if (editable) {
+ case (KEY_Y): { // PASTE (Yank for unix users)
- paste_text();
- }
+ if (editable) {
- } break;
- case (KEY_K): { // Delete from cursor_pos to end
+ paste_text();
+ }
- if (editable) {
+ } break;
+ case (KEY_K): { // Delete from cursor_pos to end
- selection_clear();
- undo_text = text;
- text = text.substr(0, cursor_pos);
- _text_changed();
- }
+ if (editable) {
- } break;
- case (KEY_A): { //Select All
- select();
- } break;
- default: { handled = false; }
- }
+ selection_clear();
+ undo_text = text;
+ text = text.substr(0, cursor_pos);
+ _text_changed();
+ }
- if (handled) {
- accept_event();
- return;
- }
+ } break;
+ case (KEY_A): { //Select All
+ select();
+ } break;
+ default: { handled = false; }
}
- _reset_caret_blink_timer();
- if (!k.mod.meta) {
+ if (handled) {
+ accept_event();
+ return;
+ }
+ }
- bool handled = true;
- switch (code) {
+ _reset_caret_blink_timer();
+ if (!k->get_metakey()) {
- case KEY_ENTER:
- case KEY_RETURN: {
+ bool handled = true;
+ switch (code) {
- emit_signal("text_entered", text);
- if (OS::get_singleton()->has_virtual_keyboard())
- OS::get_singleton()->hide_virtual_keyboard();
+ case KEY_ENTER:
+ case KEY_RETURN: {
- return;
- } break;
+ emit_signal("text_entered", text);
+ if (OS::get_singleton()->has_virtual_keyboard())
+ OS::get_singleton()->hide_virtual_keyboard();
- case KEY_BACKSPACE: {
+ return;
+ } break;
- if (!editable)
- break;
+ case KEY_BACKSPACE: {
- if (selection.enabled) {
- undo_text = text;
- selection_delete();
- break;
- }
+ if (!editable)
+ break;
+
+ if (selection.enabled) {
+ undo_text = text;
+ selection_delete();
+ break;
+ }
#ifdef APPLE_STYLE_KEYS
- if (k.mod.alt) {
+ if (k->get_alt()) {
#else
- if (k.mod.alt) {
- handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- int cc = cursor_pos;
- bool prev_char = false;
+ int cc = cursor_pos;
+ bool prev_char = false;
- while (cc > 0) {
- bool ischar = _is_text_char(text[cc - 1]);
+ while (cc > 0) {
+ bool ischar = _is_text_char(text[cc - 1]);
- if (prev_char && !ischar)
- break;
+ if (prev_char && !ischar)
+ break;
- prev_char = ischar;
- cc--;
- }
+ prev_char = ischar;
+ cc--;
+ }
- delete_text(cc, cursor_pos);
+ delete_text(cc, cursor_pos);
- set_cursor_pos(cc);
+ set_cursor_pos(cc);
- } else {
- undo_text = text;
- delete_char();
- }
+ } else {
+ undo_text = text;
+ delete_char();
+ }
- } break;
- case KEY_KP_4: {
- if (k.unicode != 0) {
- handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_left
+ } break;
+ case KEY_KP_4: {
+ if (k->get_unicode() != 0) {
+ handled = false;
+ break;
}
- case KEY_LEFT: {
+ // numlock disabled. fallthrough to key_left
+ }
+ case KEY_LEFT: {
#ifndef APPLE_STYLE_KEYS
- if (!k.mod.alt)
+ if (!k->get_alt())
#endif
- shift_selection_check_pre(k.mod.shift);
+ shift_selection_check_pre(k->get_shift());
#ifdef APPLE_STYLE_KEYS
- if (k.mod.command) {
- set_cursor_pos(0);
- } else if (k.mod.alt) {
+ if (k->get_command()) {
+ set_cursor_pos(0);
+ } else if (k->get_alt()) {
#else
- if (k.mod.alt) {
- handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- bool prev_char = false;
- int cc = cursor_pos;
+ bool prev_char = false;
+ int cc = cursor_pos;
- while (cc > 0) {
- bool ischar = _is_text_char(text[cc - 1]);
+ while (cc > 0) {
+ bool ischar = _is_text_char(text[cc - 1]);
- if (prev_char && !ischar)
- break;
+ if (prev_char && !ischar)
+ break;
- prev_char = ischar;
- cc--;
- }
+ prev_char = ischar;
+ cc--;
+ }
- set_cursor_pos(cc);
+ set_cursor_pos(cc);
- } else {
- set_cursor_pos(get_cursor_pos() - 1);
- }
+ } else {
+ set_cursor_pos(get_cursor_pos() - 1);
+ }
- shift_selection_check_post(k.mod.shift);
+ shift_selection_check_post(k->get_shift());
- } break;
- case KEY_KP_6: {
- if (k.unicode != 0) {
- handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_right
+ } break;
+ case KEY_KP_6: {
+ if (k->get_unicode() != 0) {
+ handled = false;
+ break;
}
- case KEY_RIGHT: {
+ // numlock disabled. fallthrough to key_right
+ }
+ case KEY_RIGHT: {
- shift_selection_check_pre(k.mod.shift);
+ shift_selection_check_pre(k->get_shift());
#ifdef APPLE_STYLE_KEYS
- if (k.mod.command) {
- set_cursor_pos(text.length());
- } else if (k.mod.alt) {
+ if (k->get_command()) {
+ set_cursor_pos(text.length());
+ } else if (k->get_alt()) {
#else
- if (k.mod.alt) {
- handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- bool prev_char = false;
- int cc = cursor_pos;
+ bool prev_char = false;
+ int cc = cursor_pos;
- while (cc < text.length()) {
- bool ischar = _is_text_char(text[cc]);
+ while (cc < text.length()) {
+ bool ischar = _is_text_char(text[cc]);
- if (prev_char && !ischar)
- break;
+ if (prev_char && !ischar)
+ break;
- prev_char = ischar;
- cc++;
- }
+ prev_char = ischar;
+ cc++;
+ }
- set_cursor_pos(cc);
+ set_cursor_pos(cc);
- } else {
- set_cursor_pos(get_cursor_pos() + 1);
- }
+ } else {
+ set_cursor_pos(get_cursor_pos() + 1);
+ }
- shift_selection_check_post(k.mod.shift);
+ shift_selection_check_post(k->get_shift());
- } break;
- case KEY_DELETE: {
+ } break;
+ case KEY_DELETE: {
- if (!editable)
- break;
+ if (!editable)
+ break;
- if (k.mod.shift && !k.mod.command && !k.mod.alt) {
- cut_text();
- break;
- }
+ if (k->get_shift() && !k->get_command() && !k->get_alt()) {
+ cut_text();
+ break;
+ }
- if (selection.enabled) {
- undo_text = text;
- selection_delete();
- break;
- }
+ if (selection.enabled) {
+ undo_text = text;
+ selection_delete();
+ break;
+ }
- int text_len = text.length();
+ int text_len = text.length();
- if (cursor_pos == text_len)
- break; // nothing to do
+ if (cursor_pos == text_len)
+ break; // nothing to do
#ifdef APPLE_STYLE_KEYS
- if (k.mod.alt) {
+ if (k->get_alt()) {
#else
- if (k.mod.alt) {
- handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- int cc = cursor_pos;
-
- bool prev_char = false;
+ int cc = cursor_pos;
- while (cc < text.length()) {
+ bool prev_char = false;
- bool ischar = _is_text_char(text[cc]);
+ while (cc < text.length()) {
- if (prev_char && !ischar)
- break;
- prev_char = ischar;
- cc++;
- }
+ bool ischar = _is_text_char(text[cc]);
- delete_text(cursor_pos, cc);
-
- } else {
- undo_text = text;
- set_cursor_pos(cursor_pos + 1);
- delete_char();
+ if (prev_char && !ischar)
+ break;
+ prev_char = ischar;
+ cc++;
}
- } break;
- case KEY_KP_7: {
- if (k.unicode != 0) {
- handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_home
- }
- case KEY_HOME: {
+ delete_text(cursor_pos, cc);
- shift_selection_check_pre(k.mod.shift);
- set_cursor_pos(0);
- shift_selection_check_post(k.mod.shift);
- } break;
- case KEY_KP_1: {
- if (k.unicode != 0) {
- handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_end
+ } else {
+ undo_text = text;
+ set_cursor_pos(cursor_pos + 1);
+ delete_char();
}
- case KEY_END: {
- shift_selection_check_pre(k.mod.shift);
- set_cursor_pos(text.length());
- shift_selection_check_post(k.mod.shift);
- } break;
-
- default: {
+ } break;
+ case KEY_KP_7: {
+ if (k->get_unicode() != 0) {
+ handled = false;
+ break;
+ }
+ // numlock disabled. fallthrough to key_home
+ }
+ case KEY_HOME: {
+ shift_selection_check_pre(k->get_shift());
+ set_cursor_pos(0);
+ shift_selection_check_post(k->get_shift());
+ } break;
+ case KEY_KP_1: {
+ if (k->get_unicode() != 0) {
handled = false;
- } break;
+ break;
+ }
+ // numlock disabled. fallthrough to key_end
}
+ case KEY_END: {
- if (handled) {
- accept_event();
- } else if (!k.mod.alt && !k.mod.command) {
- if (k.unicode >= 32 && k.scancode != KEY_DELETE) {
-
- if (editable) {
- selection_delete();
- CharType ucodestr[2] = { (CharType)k.unicode, 0 };
- append_at_cursor(ucodestr);
- _text_changed();
- accept_event();
- }
+ shift_selection_check_pre(k->get_shift());
+ set_cursor_pos(text.length());
+ shift_selection_check_post(k->get_shift());
+ } break;
- } else {
- return;
+ default: {
+
+ handled = false;
+ } break;
+ }
+
+ if (handled) {
+ accept_event();
+ } else if (!k->get_alt() && !k->get_command()) {
+ if (k->get_unicode() >= 32 && k->get_scancode() != KEY_DELETE) {
+
+ if (editable) {
+ selection_delete();
+ CharType ucodestr[2] = { (CharType)k->get_unicode(), 0 };
+ append_at_cursor(ucodestr);
+ _text_changed();
+ accept_event();
}
- }
- update();
+ } else {
+ return;
+ }
}
- return;
+ update();
+ }
- } break;
+ return;
}
}
@@ -576,7 +573,7 @@ void LineEdit::_notification(int p_what) {
RID ci = get_canvas_item();
- Ref<StyleBox> style = has_focus() ? get_stylebox("active") : get_stylebox("normal");
+ Ref<StyleBox> style = get_stylebox("normal");
if (!is_editable())
style = get_stylebox("read_only");
@@ -617,7 +614,7 @@ void LineEdit::_notification(int p_what) {
int font_ascent = font->get_ascent();
Color selection_color = get_color("selection_color");
- Color font_color = is_editable() ? has_focus() ? get_color("font_color_active") : get_color("font_color") : get_color("font_color_read_only");
+ Color font_color = get_color("font_color");
Color font_color_selected = get_color("font_color_selected");
Color cursor_color = get_color("cursor_color");
@@ -633,8 +630,8 @@ void LineEdit::_notification(int p_what) {
if (char_ofs >= t.length())
break;
- CharType cchar = pass ? '*' : t[char_ofs];
- CharType next = pass ? '*' : t[char_ofs + 1];
+ CharType cchar = (pass && !text.empty()) ? '*' : t[char_ofs];
+ CharType next = (pass && !text.empty()) ? '*' : t[char_ofs + 1];
int char_width = font->get_char_size(cchar, next).width;
// end of widget, break!
diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h
index a969095947..1167cfb6d0 100644
--- a/scene/gui/line_edit.h
+++ b/scene/gui/line_edit.h
@@ -119,7 +119,7 @@ private:
void _editor_settings_changed();
#endif
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
protected:
diff --git a/scene/gui/menu_button.cpp b/scene/gui/menu_button.cpp
index cf468f2257..fe76b16460 100644
--- a/scene/gui/menu_button.cpp
+++ b/scene/gui/menu_button.cpp
@@ -31,9 +31,9 @@
#include "os/keyboard.h"
#include "scene/main/viewport.h"
-void MenuButton::_unhandled_key_input(InputEvent p_event) {
+void MenuButton::_unhandled_key_input(Ref<InputEvent> p_event) {
- if (p_event.is_pressed() && !p_event.is_echo() && (p_event.type == InputEvent::KEY || p_event.type == InputEvent::ACTION || p_event.type == InputEvent::JOYPAD_BUTTON)) {
+ if (p_event->is_pressed() && !p_event->is_echo() && (p_event->cast_to<InputEventKey>() || p_event->cast_to<InputEventJoypadButton>() || p_event->cast_to<InputEventAction>())) {
if (!get_parent() || !is_visible_in_tree() || is_disabled())
return;
@@ -59,10 +59,10 @@ void MenuButton::pressed() {
popup->set_invalidate_click_until_motion();
}
-void MenuButton::_gui_input(InputEvent p_event) {
+void MenuButton::_gui_input(Ref<InputEvent> p_event) {
- /*if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==BUTTON_LEFT) {
- clicked=p_event.mouse_button.pressed;
+ /*if (p_event.type==InputEvent::MOUSE_BUTTON && p_event->get_button_index()==BUTTON_LEFT) {
+ clicked=p_event->is_pressed();
}
if (clicked && p_event.type==InputEvent::MOUSE_MOTION && popup->is_visible_in_tree()) {
diff --git a/scene/gui/menu_button.h b/scene/gui/menu_button.h
index e07627c07c..6bb23452dd 100644
--- a/scene/gui/menu_button.h
+++ b/scene/gui/menu_button.h
@@ -43,11 +43,11 @@ class MenuButton : public Button {
PopupMenu *popup;
virtual void pressed();
- void _unhandled_key_input(InputEvent p_event);
+ void _unhandled_key_input(Ref<InputEvent> p_event);
Array _get_items() const;
void _set_items(const Array &p_items);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
protected:
static void _bind_methods();
diff --git a/scene/gui/option_button.cpp b/scene/gui/option_button.cpp
index b967a1a7ce..0806d35d48 100644
--- a/scene/gui/option_button.cpp
+++ b/scene/gui/option_button.cpp
@@ -56,24 +56,7 @@ void OptionButton::_notification(int p_what) {
Size2 size = get_size();
Point2 ofs(size.width - arrow->get_width() - get_constant("arrow_margin"), int(Math::abs((size.height - arrow->get_height()) / 2)));
-
- Color arrow_color = get_color("font_color");
- switch (get_draw_mode()) {
- case DRAW_NORMAL: {
- arrow_color = get_color("font_color");
- } break;
- case DRAW_PRESSED: {
- arrow_color = get_color("font_color_pressed");
- } break;
- case DRAW_HOVER: {
- arrow_color = get_color("font_color_hover");
- } break;
- case DRAW_DISABLED: {
- arrow_color = get_color("font_color_disabled");
- } break;
- }
-
- arrow->draw(ci, ofs, arrow_color);
+ arrow->draw(ci, ofs);
} break;
}
diff --git a/scene/gui/popup.cpp b/scene/gui/popup.cpp
index 7d0b91a366..8979e0f111 100644
--- a/scene/gui/popup.cpp
+++ b/scene/gui/popup.cpp
@@ -30,7 +30,7 @@
#include "popup.h"
#include "os/keyboard.h"
-void Popup::_gui_input(InputEvent p_event) {
+void Popup::_gui_input(Ref<InputEvent> p_event) {
}
void Popup::_notification(int p_what) {
@@ -170,8 +170,8 @@ void Popup::popup_centered(const Size2 &p_size) {
Rect2 rect;
rect.size = p_size == Size2() ? get_size() : p_size;
- rect.pos = ((window_size - rect.size) / 2.0).floor();
- set_position(rect.pos);
+ rect.position = ((window_size - rect.size) / 2.0).floor();
+ set_position(rect.position);
set_size(rect.size);
show_modal(exclusive);
@@ -193,8 +193,8 @@ void Popup::popup_centered_ratio(float p_screen_ratio) {
Rect2 rect;
Point2 window_size = get_viewport_rect().size;
rect.size = (window_size * p_screen_ratio).floor();
- rect.pos = ((window_size - rect.size) / 2.0).floor();
- set_position(rect.pos);
+ rect.position = ((window_size - rect.size) / 2.0).floor();
+ set_position(rect.position);
set_size(rect.size);
show_modal(exclusive);
@@ -216,7 +216,7 @@ void Popup::popup(const Rect2 &bounds) {
// Fit the popup into the optionally provided bounds.
if (!bounds.has_no_area()) {
- set_position(bounds.pos);
+ set_position(bounds.position);
set_size(bounds.size);
}
_fix_size();
diff --git a/scene/gui/popup.h b/scene/gui/popup.h
index 950aa65fa4..0543ae1937 100644
--- a/scene/gui/popup.h
+++ b/scene/gui/popup.h
@@ -45,7 +45,7 @@ class Popup : public Control {
protected:
virtual void _post_popup() {}
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
virtual void _fix_size();
static void _bind_methods();
diff --git a/scene/gui/popup_menu.cpp b/scene/gui/popup_menu.cpp
index 6ac6eac655..c4991700aa 100644
--- a/scene/gui/popup_menu.cpp
+++ b/scene/gui/popup_menu.cpp
@@ -108,6 +108,11 @@ Size2 PopupMenu::get_minimum_size() const {
accel_max_w = MAX(accel_w, accel_max_w);
}
+ if (items[i].submenu != "") {
+
+ size.width += get_icon("submenu")->get_width();
+ }
+
minsize.height += size.height;
max_w = MAX(max_w, size.width);
}
@@ -185,12 +190,12 @@ void PopupMenu::_activate_submenu(int over) {
PopupMenu *pum = pm->cast_to<PopupMenu>();
if (pum) {
- pr.pos -= pum->get_global_position();
+ pr.position -= pum->get_global_position();
pum->clear_autohide_areas();
- pum->add_autohide_area(Rect2(pr.pos.x, pr.pos.y, pr.size.x, items[over]._ofs_cache));
+ pum->add_autohide_area(Rect2(pr.position.x, pr.position.y, pr.size.x, items[over]._ofs_cache));
if (over < items.size() - 1) {
int from = items[over + 1]._ofs_cache;
- pum->add_autohide_area(Rect2(pr.pos.x, pr.pos.y + from, pr.size.x, pr.size.y - from));
+ pum->add_autohide_area(Rect2(pr.position.x, pr.position.y + from, pr.size.x, pr.size.y - from));
}
}
}
@@ -203,171 +208,170 @@ void PopupMenu::_submenu_timeout() {
}
}
-void PopupMenu::_gui_input(const InputEvent &p_event) {
+void PopupMenu::_gui_input(const Ref<InputEvent> &p_event) {
- switch (p_event.type) {
+ Ref<InputEventKey> k = p_event;
- case InputEvent::KEY: {
+ if (k.is_valid()) {
- if (!p_event.key.pressed)
- break;
+ if (!k->is_pressed())
+ return;
- switch (p_event.key.scancode) {
+ switch (k->get_scancode()) {
- case KEY_DOWN: {
+ case KEY_DOWN: {
- for (int i = mouse_over + 1; i < items.size(); i++) {
+ for (int i = mouse_over + 1; i < items.size(); i++) {
- if (i < 0 || i >= items.size())
- continue;
+ if (i < 0 || i >= items.size())
+ continue;
- if (!items[i].separator && !items[i].disabled) {
+ if (!items[i].separator && !items[i].disabled) {
- mouse_over = i;
- update();
- break;
- }
+ mouse_over = i;
+ update();
+ break;
}
- } break;
- case KEY_UP: {
+ }
+ } break;
+ case KEY_UP: {
- for (int i = mouse_over - 1; i >= 0; i--) {
+ for (int i = mouse_over - 1; i >= 0; i--) {
- if (i < 0 || i >= items.size())
- continue;
+ if (i < 0 || i >= items.size())
+ continue;
- if (!items[i].separator && !items[i].disabled) {
+ if (!items[i].separator && !items[i].disabled) {
- mouse_over = i;
- update();
- break;
- }
+ mouse_over = i;
+ update();
+ break;
}
- } break;
- case KEY_RETURN:
- case KEY_ENTER: {
+ }
+ } break;
+ case KEY_RETURN:
+ case KEY_ENTER: {
- if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
+ if (mouse_over >= 0 && mouse_over < items.size() && !items[mouse_over].separator) {
- activate_item(mouse_over);
- }
- } break;
- }
+ activate_item(mouse_over);
+ }
+ } break;
+ }
+ }
- } break;
+ Ref<InputEventMouseButton> b = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (b.is_valid()) {
- const InputEventMouseButton &b = p_event.mouse_button;
- if (b.pressed)
- break;
+ if (b->is_pressed())
+ return;
- switch (b.button_index) {
+ switch (b->get_button_index()) {
- case BUTTON_WHEEL_DOWN: {
+ case BUTTON_WHEEL_DOWN: {
- if (get_global_position().y + get_size().y > get_viewport_rect().size.y) {
+ if (get_global_position().y + get_size().y > get_viewport_rect().size.y) {
- int vseparation = get_constant("vseparation");
- Ref<Font> font = get_font("font");
+ int vseparation = get_constant("vseparation");
+ Ref<Font> font = get_font("font");
- Point2 pos = get_position();
- int s = (vseparation + font->get_height()) * 3;
- pos.y -= s;
- set_position(pos);
+ Point2 pos = get_position();
+ int s = (vseparation + font->get_height()) * 3;
+ pos.y -= (s * b->get_factor());
+ set_position(pos);
- //update hover
- InputEvent ie;
- ie.type = InputEvent::MOUSE_MOTION;
- ie.mouse_motion.x = b.x;
- ie.mouse_motion.y = b.y + s;
- _gui_input(ie);
- }
- } break;
- case BUTTON_WHEEL_UP: {
+ //update hover
+ Ref<InputEventMouseMotion> ie;
+ ie.instance();
+ ie->set_position(b->get_position() + Vector2(0, s));
+ _gui_input(ie);
+ }
+ } break;
+ case BUTTON_WHEEL_UP: {
- if (get_global_position().y < 0) {
+ if (get_global_position().y < 0) {
- int vseparation = get_constant("vseparation");
- Ref<Font> font = get_font("font");
+ int vseparation = get_constant("vseparation");
+ Ref<Font> font = get_font("font");
- Point2 pos = get_position();
- int s = (vseparation + font->get_height()) * 3;
- pos.y += s;
- set_position(pos);
+ Point2 pos = get_position();
+ int s = (vseparation + font->get_height()) * 3;
+ pos.y += (s * b->get_factor());
+ set_position(pos);
- //update hover
- InputEvent ie;
- ie.type = InputEvent::MOUSE_MOTION;
- ie.mouse_motion.x = b.x;
- ie.mouse_motion.y = b.y - s;
- _gui_input(ie);
- }
- } break;
- case BUTTON_LEFT: {
+ //update hover
+ Ref<InputEventMouseMotion> ie;
+ ie.instance();
+ ie->set_position(b->get_position() - Vector2(0, s));
+ _gui_input(ie);
+ }
+ } break;
+ case BUTTON_LEFT: {
- int over = _get_mouse_over(Point2(b.x, b.y));
+ int over = _get_mouse_over(b->get_position());
- if (invalidated_click) {
- invalidated_click = false;
- break;
- }
- if (over < 0) {
- hide();
- break; //non-activable
- }
+ if (invalidated_click) {
+ invalidated_click = false;
+ break;
+ }
+ if (over < 0) {
+ hide();
+ break; //non-activable
+ }
- if (items[over].separator || items[over].disabled)
- break;
+ if (items[over].separator || items[over].disabled)
+ break;
- if (items[over].submenu != "") {
+ if (items[over].submenu != "") {
- _activate_submenu(over);
- return;
- }
- activate_item(over);
+ _activate_submenu(over);
+ return;
+ }
+ activate_item(over);
- } break;
- }
+ } break;
+ }
- //update();
- } break;
- case InputEvent::MOUSE_MOTION: {
+ //update();
+ }
- if (invalidated_click) {
- moved += Vector2(p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y);
- if (moved.length() > 4)
- invalidated_click = false;
- }
+ Ref<InputEventMouseMotion> m = p_event;
- const InputEventMouseMotion &m = p_event.mouse_motion;
- for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
+ if (m.is_valid()) {
- if (!Rect2(Point2(), get_size()).has_point(Point2(m.x, m.y)) && E->get().has_point(Point2(m.x, m.y))) {
- call_deferred("hide");
- return;
- }
- }
+ if (invalidated_click) {
+ moved += m->get_relative();
+ if (moved.length() > 4)
+ invalidated_click = false;
+ }
- int over = _get_mouse_over(Point2(m.x, m.y));
- int id = (over < 0 || items[over].separator || items[over].disabled) ? -1 : (items[over].ID >= 0 ? items[over].ID : over);
+ for (List<Rect2>::Element *E = autohide_areas.front(); E; E = E->next()) {
- if (id < 0) {
- mouse_over = -1;
- update();
- break;
+ if (!Rect2(Point2(), get_size()).has_point(m->get_position()) && E->get().has_point(m->get_position())) {
+ call_deferred("hide");
+ return;
}
+ }
- if (items[over].submenu != "" && submenu_over != over) {
- submenu_over = over;
- submenu_timer->start();
- }
+ int over = _get_mouse_over(m->get_position());
+ int id = (over < 0 || items[over].separator || items[over].disabled) ? -1 : (items[over].ID >= 0 ? items[over].ID : over);
- if (over != mouse_over) {
- mouse_over = over;
- update();
- }
- } break;
+ if (id < 0) {
+ mouse_over = -1;
+ update();
+ return;
+ }
+
+ if (items[over].submenu != "" && submenu_over != over) {
+ submenu_over = over;
+ submenu_timer->start();
+ }
+
+ if (over != mouse_over) {
+ mouse_over = over;
+ update();
+ }
}
}
@@ -815,20 +819,22 @@ int PopupMenu::get_item_count() const {
return items.size();
}
-bool PopupMenu::activate_item_by_event(const InputEvent &p_event, bool p_for_global_only) {
+bool PopupMenu::activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only) {
uint32_t code = 0;
- if (p_event.type == InputEvent::KEY) {
- code = p_event.key.scancode;
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid()) {
+ code = k->get_scancode();
if (code == 0)
- code = p_event.key.unicode;
- if (p_event.key.mod.control)
+ code = k->get_unicode();
+ if (k->get_control())
code |= KEY_MASK_CTRL;
- if (p_event.key.mod.alt)
+ if (k->get_alt())
code |= KEY_MASK_ALT;
- if (p_event.key.mod.meta)
+ if (k->get_metakey())
code |= KEY_MASK_META;
- if (p_event.key.mod.shift)
+ if (k->get_shift())
code |= KEY_MASK_SHIFT;
}
diff --git a/scene/gui/popup_menu.h b/scene/gui/popup_menu.h
index de809f29d3..7ef532453d 100644
--- a/scene/gui/popup_menu.h
+++ b/scene/gui/popup_menu.h
@@ -79,7 +79,7 @@ class PopupMenu : public Popup {
String _get_accel_text(int p_item) const;
int _get_mouse_over(const Point2 &p_over) const;
virtual Size2 get_minimum_size() const;
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _activate_submenu(int over);
void _submenu_timeout();
@@ -146,7 +146,7 @@ public:
int get_item_count() const;
- bool activate_item_by_event(const InputEvent &p_event, bool p_for_global_only = false);
+ bool activate_item_by_event(const Ref<InputEvent> &p_event, bool p_for_global_only = false);
void activate_item(int p_item);
void remove_item(int p_idx);
diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp
index e5a17298e4..0b8595de42 100644
--- a/scene/gui/rich_text_label.cpp
+++ b/scene/gui/rich_text_label.cpp
@@ -734,158 +734,155 @@ Control::CursorShape RichTextLabel::get_cursor_shape(const Point2 &p_pos) const
return CURSOR_ARROW;
}
-void RichTextLabel::_gui_input(InputEvent p_event) {
+void RichTextLabel::_gui_input(Ref<InputEvent> p_event) {
- switch (p_event.type) {
+ Ref<InputEventMouseButton> b = p_event;
- case InputEvent::MOUSE_BUTTON: {
-
- if (main->first_invalid_line < main->lines.size())
- return;
-
- const InputEventMouseButton &b = p_event.mouse_button;
+ if (b.is_valid()) {
+ if (main->first_invalid_line < main->lines.size())
+ return;
- if (b.button_index == BUTTON_LEFT) {
+ if (b->get_button_index() == BUTTON_LEFT) {
- if (true) {
+ if (true) {
- if (b.pressed && !b.doubleclick) {
- int line = 0;
- Item *item = NULL;
+ if (b->is_pressed() && !b->is_doubleclick()) {
+ int line = 0;
+ Item *item = NULL;
- bool outside;
- _find_click(main, Point2i(b.x, b.y), &item, &line, &outside);
+ bool outside;
+ _find_click(main, b->get_position(), &item, &line, &outside);
- if (item) {
+ if (item) {
- Variant meta;
- if (!outside && _find_meta(item, &meta)) {
- //meta clicked
+ Variant meta;
+ if (!outside && _find_meta(item, &meta)) {
+ //meta clicked
- emit_signal("meta_clicked", meta);
- } else if (selection.enabled) {
+ emit_signal("meta_clicked", meta);
+ } else if (selection.enabled) {
- selection.click = item;
- selection.click_char = line;
- }
+ selection.click = item;
+ selection.click_char = line;
}
+ }
- } else if (!b.pressed) {
+ } else if (!b->is_pressed()) {
- selection.click = NULL;
- }
+ selection.click = NULL;
}
}
+ }
- if (b.button_index == BUTTON_WHEEL_UP) {
+ if (b->get_button_index() == BUTTON_WHEEL_UP) {
- if (scroll_active)
- vscroll->set_value(vscroll->get_value() - vscroll->get_page() / 8);
- }
- if (b.button_index == BUTTON_WHEEL_DOWN) {
+ if (scroll_active)
- if (scroll_active)
- vscroll->set_value(vscroll->get_value() + vscroll->get_page() / 8);
- }
- } break;
- case InputEvent::KEY: {
-
- const InputEventKey &k = p_event.key;
- if (k.pressed && !k.mod.alt && !k.mod.shift && !k.mod.meta) {
- bool handled = true;
- switch (k.scancode) {
- case KEY_PAGEUP: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(vscroll->get_value() - vscroll->get_page());
- } break;
- case KEY_PAGEDOWN: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(vscroll->get_value() + vscroll->get_page());
- } break;
- case KEY_UP: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(vscroll->get_value() - get_font("normal_font")->get_height());
- } break;
- case KEY_DOWN: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(vscroll->get_value() + get_font("normal_font")->get_height());
- } break;
- case KEY_HOME: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(0);
- } break;
- case KEY_END: {
-
- if (vscroll->is_visible_in_tree())
- vscroll->set_value(vscroll->get_max());
- } break;
- case KEY_INSERT:
- case KEY_C: {
-
- if (k.mod.command) {
- selection_copy();
- } else {
- handled = false;
- }
+ vscroll->set_value(vscroll->get_value() - vscroll->get_page() * b->get_factor() * 0.5 / 8);
+ }
+ if (b->get_button_index() == BUTTON_WHEEL_DOWN) {
- } break;
- default: handled = false;
- }
+ if (scroll_active)
+
+ vscroll->set_value(vscroll->get_value() + vscroll->get_page() * b->get_factor() * 0.5 / 8);
+ }
+ }
- if (handled)
- accept_event();
+ Ref<InputEventKey> k = p_event;
+
+ if (k.is_valid()) {
+ if (k->is_pressed() && !k->get_alt() && !k->get_shift() && !k->get_metakey()) {
+ bool handled = true;
+ switch (k->get_scancode()) {
+ case KEY_PAGEUP: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(vscroll->get_value() - vscroll->get_page());
+ } break;
+ case KEY_PAGEDOWN: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(vscroll->get_value() + vscroll->get_page());
+ } break;
+ case KEY_UP: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(vscroll->get_value() - get_font("normal_font")->get_height());
+ } break;
+ case KEY_DOWN: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(vscroll->get_value() + get_font("normal_font")->get_height());
+ } break;
+ case KEY_HOME: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(0);
+ } break;
+ case KEY_END: {
+
+ if (vscroll->is_visible_in_tree())
+ vscroll->set_value(vscroll->get_max());
+ } break;
+ case KEY_INSERT:
+ case KEY_C: {
+
+ if (k->get_command()) {
+ selection_copy();
+ } else {
+ handled = false;
+ }
+
+ } break;
+ default: handled = false;
}
- } break;
- case InputEvent::MOUSE_MOTION: {
+ if (handled)
+ accept_event();
+ }
+ }
- if (main->first_invalid_line < main->lines.size())
- return;
+ Ref<InputEventMouseMotion> m = p_event;
- const InputEventMouseMotion &m = p_event.mouse_motion;
+ if (m.is_valid()) {
+ if (main->first_invalid_line < main->lines.size())
+ return;
- if (selection.click) {
+ if (selection.click) {
- int line = 0;
- Item *item = NULL;
- _find_click(main, Point2i(m.x, m.y), &item, &line);
- if (!item)
- return; // do not update
+ int line = 0;
+ Item *item = NULL;
+ _find_click(main, m->get_position(), &item, &line);
+ if (!item)
+ return; // do not update
- selection.from = selection.click;
- selection.from_char = selection.click_char;
+ selection.from = selection.click;
+ selection.from_char = selection.click_char;
- selection.to = item;
- selection.to_char = line;
+ selection.to = item;
+ selection.to_char = line;
- bool swap = false;
- if (selection.from->index > selection.to->index)
+ bool swap = false;
+ if (selection.from->index > selection.to->index)
+ swap = true;
+ else if (selection.from->index == selection.to->index) {
+ if (selection.from_char > selection.to_char)
swap = true;
- else if (selection.from->index == selection.to->index) {
- if (selection.from_char > selection.to_char)
- swap = true;
- else if (selection.from_char == selection.to_char) {
-
- selection.active = false;
- return;
- }
- }
+ else if (selection.from_char == selection.to_char) {
- if (swap) {
- SWAP(selection.from, selection.to);
- SWAP(selection.from_char, selection.to_char);
+ selection.active = false;
+ return;
}
+ }
- selection.active = true;
- update();
+ if (swap) {
+ SWAP(selection.from, selection.to);
+ SWAP(selection.from_char, selection.to_char);
}
- } break;
+ selection.active = true;
+ update();
+ }
}
}
diff --git a/scene/gui/rich_text_label.h b/scene/gui/rich_text_label.h
index 05d98b3ee8..eedb7e54db 100644
--- a/scene/gui/rich_text_label.h
+++ b/scene/gui/rich_text_label.h
@@ -272,7 +272,7 @@ private:
void _update_scroll();
void _scroll_changed(double);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
Item *_get_next_item(Item *p_item, bool p_free = false);
bool use_bbcode;
diff --git a/scene/gui/scroll_bar.cpp b/scene/gui/scroll_bar.cpp
index 6475371eb9..bd66cd2745 100644
--- a/scene/gui/scroll_bar.cpp
+++ b/scene/gui/scroll_bar.cpp
@@ -38,191 +38,188 @@ void ScrollBar::set_can_focus_by_default(bool p_can_focus) {
focus_by_default = p_can_focus;
}
-void ScrollBar::_gui_input(InputEvent p_event) {
+void ScrollBar::_gui_input(Ref<InputEvent> p_event) {
- switch (p_event.type) {
+ Ref<InputEventMouseButton> b = p_event;
- case InputEvent::MOUSE_BUTTON: {
+ if (b.is_valid()) {
+ accept_event();
- const InputEventMouseButton &b = p_event.mouse_button;
- accept_event();
-
- if (b.button_index == 5 && b.pressed) {
-
- /*
- if (orientation==VERTICAL)
- set_val( get_val() + get_page() / 4.0 );
- else
- */
- set_value(get_value() + get_page() / 4.0);
- accept_event();
- }
-
- if (b.button_index == 4 && b.pressed) {
+ if (b->get_button_index() == 5 && b->is_pressed()) {
- /*
- if (orientation==HORIZONTAL)
- set_val( get_val() - get_page() / 4.0 );
- else
- */
- set_value(get_value() - get_page() / 4.0);
- accept_event();
- }
+ /*
+ if (orientation==VERTICAL)
+ set_val( get_val() + get_page() / 4.0 );
+ else
+ */
+ set_value(get_value() + get_page() / 4.0);
+ accept_event();
+ }
- if (b.button_index != 1)
- return;
+ if (b->get_button_index() == 4 && b->is_pressed()) {
- if (b.pressed) {
+ /*
+ if (orientation==HORIZONTAL)
+ set_val( get_val() - get_page() / 4.0 );
+ else
+ */
+ set_value(get_value() - get_page() / 4.0);
+ accept_event();
+ }
- double ofs = orientation == VERTICAL ? b.y : b.x;
- Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr = get_icon("increment");
+ if (b->get_button_index() != 1)
+ return;
- double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
- double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
- double grabber_ofs = get_grabber_offset();
- double grabber_size = get_grabber_size();
- double total = orientation == VERTICAL ? get_size().height : get_size().width;
+ if (b->is_pressed()) {
- if (ofs < decr_size) {
+ double ofs = orientation == VERTICAL ? b->get_position().y : b->get_position().x;
+ Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture> incr = get_icon("increment");
- set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
- break;
- }
+ double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
+ double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
+ double grabber_ofs = get_grabber_offset();
+ double grabber_size = get_grabber_size();
+ double total = orientation == VERTICAL ? get_size().height : get_size().width;
- if (ofs > total - incr_size) {
+ if (ofs < decr_size) {
- set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
- break;
- }
+ set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
+ return;
+ }
- ofs -= decr_size;
+ if (ofs > total - incr_size) {
- if (ofs < grabber_ofs) {
+ set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
+ return;
+ }
- set_value(get_value() - get_page());
- break;
- }
+ ofs -= decr_size;
- ofs -= grabber_ofs;
+ if (ofs < grabber_ofs) {
- if (ofs < grabber_size) {
+ set_value(get_value() - get_page());
+ return;
+ }
- drag.active = true;
- drag.pos_at_click = grabber_ofs + ofs;
- drag.value_at_click = get_as_ratio();
- update();
- } else {
+ ofs -= grabber_ofs;
- set_value(get_value() + get_page());
- }
+ if (ofs < grabber_size) {
+ drag.active = true;
+ drag.pos_at_click = grabber_ofs + ofs;
+ drag.value_at_click = get_as_ratio();
+ update();
} else {
- drag.active = false;
- update();
+ set_value(get_value() + get_page());
}
- } break;
- case InputEvent::MOUSE_MOTION: {
+ } else {
- const InputEventMouseMotion &m = p_event.mouse_motion;
+ drag.active = false;
+ update();
+ }
+ }
- accept_event();
+ Ref<InputEventMouseMotion> m = p_event;
- if (drag.active) {
+ if (m.is_valid()) {
- double ofs = orientation == VERTICAL ? m.y : m.x;
- Ref<Texture> decr = get_icon("decrement");
+ accept_event();
- double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
- ofs -= decr_size;
+ if (drag.active) {
- double diff = (ofs - drag.pos_at_click) / get_area_size();
+ double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
+ Ref<Texture> decr = get_icon("decrement");
- set_as_ratio(drag.value_at_click + diff);
- } else {
+ double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
+ ofs -= decr_size;
- double ofs = orientation == VERTICAL ? m.y : m.x;
- Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr = get_icon("increment");
+ double diff = (ofs - drag.pos_at_click) / get_area_size();
- double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
- double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
- double total = orientation == VERTICAL ? get_size().height : get_size().width;
+ set_as_ratio(drag.value_at_click + diff);
+ } else {
- HiliteStatus new_hilite;
+ double ofs = orientation == VERTICAL ? m->get_position().y : m->get_position().x;
+ Ref<Texture> decr = get_icon("decrement");
+ Ref<Texture> incr = get_icon("increment");
- if (ofs < decr_size) {
+ double decr_size = orientation == VERTICAL ? decr->get_height() : decr->get_width();
+ double incr_size = orientation == VERTICAL ? incr->get_height() : incr->get_width();
+ double total = orientation == VERTICAL ? get_size().height : get_size().width;
- new_hilite = HILITE_DECR;
+ HighlightStatus new_hilite;
- } else if (ofs > total - incr_size) {
+ if (ofs < decr_size) {
- new_hilite = HILITE_INCR;
+ new_hilite = HIGHLIGHT_DECR;
- } else {
+ } else if (ofs > total - incr_size) {
- new_hilite = HILITE_RANGE;
- }
+ new_hilite = HIGHLIGHT_INCR;
- if (new_hilite != hilite) {
+ } else {
- hilite = new_hilite;
- update();
- }
+ new_hilite = HIGHLIGHT_RANGE;
}
- } break;
- case InputEvent::KEY: {
- const InputEventKey &k = p_event.key;
+ if (new_hilite != highlight) {
- if (!k.pressed)
- return;
+ highlight = new_hilite;
+ update();
+ }
+ }
+ }
- switch (k.scancode) {
+ Ref<InputEventKey> k = p_event;
- case KEY_LEFT: {
+ if (k.is_valid()) {
- if (orientation != HORIZONTAL)
- return;
- set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
+ if (!k->is_pressed())
+ return;
- } break;
- case KEY_RIGHT: {
+ switch (k->get_scancode()) {
- if (orientation != HORIZONTAL)
- return;
- set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
+ case KEY_LEFT: {
- } break;
- case KEY_UP: {
+ if (orientation != HORIZONTAL)
+ return;
+ set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
- if (orientation != VERTICAL)
- return;
+ } break;
+ case KEY_RIGHT: {
- set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
+ if (orientation != HORIZONTAL)
+ return;
+ set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
- } break;
- case KEY_DOWN: {
+ } break;
+ case KEY_UP: {
- if (orientation != VERTICAL)
- return;
- set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
+ if (orientation != VERTICAL)
+ return;
- } break;
- case KEY_HOME: {
+ set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
- set_value(get_min());
+ } break;
+ case KEY_DOWN: {
- } break;
- case KEY_END: {
+ if (orientation != VERTICAL)
+ return;
+ set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
- set_value(get_max());
+ } break;
+ case KEY_HOME: {
- } break;
- }
- break;
+ set_value(get_min());
+
+ } break;
+ case KEY_END: {
+
+ set_value(get_max());
+
+ } break;
}
}
}
@@ -233,10 +230,10 @@ void ScrollBar::_notification(int p_what) {
RID ci = get_canvas_item();
- Ref<Texture> decr = hilite == HILITE_DECR ? get_icon("decrement_hilite") : get_icon("decrement");
- Ref<Texture> incr = hilite == HILITE_INCR ? get_icon("increment_hilite") : get_icon("increment");
+ Ref<Texture> decr = highlight == HIGHLIGHT_DECR ? get_icon("decrement_highlight") : get_icon("decrement");
+ Ref<Texture> incr = highlight == HIGHLIGHT_INCR ? get_icon("increment_highlight") : get_icon("increment");
Ref<StyleBox> bg = has_focus() ? get_stylebox("scroll_focus") : get_stylebox("scroll");
- Ref<StyleBox> grabber = (drag.active || hilite == HILITE_RANGE) ? get_stylebox("grabber_hilite") : get_stylebox("grabber");
+ Ref<StyleBox> grabber = (drag.active || highlight == HIGHLIGHT_RANGE) ? get_stylebox("grabber_highlight") : get_stylebox("grabber");
Point2 ofs;
@@ -270,14 +267,14 @@ void ScrollBar::_notification(int p_what) {
grabber_rect.size.width = get_grabber_size();
grabber_rect.size.height = get_size().height;
- grabber_rect.pos.y = 0;
- grabber_rect.pos.x = get_grabber_offset() + decr->get_width() + bg->get_margin(MARGIN_LEFT);
+ grabber_rect.position.y = 0;
+ grabber_rect.position.x = get_grabber_offset() + decr->get_width() + bg->get_margin(MARGIN_LEFT);
} else {
grabber_rect.size.width = get_size().width;
grabber_rect.size.height = get_grabber_size();
- grabber_rect.pos.y = get_grabber_offset() + decr->get_height() + bg->get_margin(MARGIN_TOP);
- grabber_rect.pos.x = 0;
+ grabber_rect.position.y = get_grabber_offset() + decr->get_height() + bg->get_margin(MARGIN_TOP);
+ grabber_rect.position.x = 0;
}
grabber->draw(ci, grabber_rect);
@@ -386,7 +383,7 @@ void ScrollBar::_notification(int p_what) {
if (p_what == NOTIFICATION_MOUSE_EXIT) {
- hilite = HILITE_NONE;
+ highlight = HIGHLIGHT_NONE;
update();
}
}
@@ -522,87 +519,84 @@ void ScrollBar::_drag_slave_exit() {
drag_slave = NULL;
}
-void ScrollBar::_drag_slave_input(const InputEvent &p_input) {
+void ScrollBar::_drag_slave_input(const Ref<InputEvent> &p_input) {
- switch (p_input.type) {
+ Ref<InputEventMouseButton> mb = p_input;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb = p_input.mouse_button;
+ if (mb->get_button_index() != 1)
+ return;
- if (mb.button_index != 1)
- break;
+ if (mb->is_pressed()) {
+
+ if (drag_slave_touching) {
+ set_fixed_process(false);
+ drag_slave_touching_deaccel = false;
+ drag_slave_touching = false;
+ drag_slave_speed = Vector2();
+ drag_slave_accum = Vector2();
+ last_drag_slave_accum = Vector2();
+ drag_slave_from = Vector2();
+ }
- if (mb.pressed) {
+ if (true) {
+ drag_slave_speed = Vector2();
+ drag_slave_accum = Vector2();
+ last_drag_slave_accum = Vector2();
+ //drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val());
+ drag_slave_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
+ drag_slave_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_slave_touching_deaccel = false;
+ time_since_motion = 0;
if (drag_slave_touching) {
- set_fixed_process(false);
- drag_slave_touching_deaccel = false;
- drag_slave_touching = false;
- drag_slave_speed = Vector2();
- drag_slave_accum = Vector2();
- last_drag_slave_accum = Vector2();
- drag_slave_from = Vector2();
+ set_fixed_process(true);
+ time_since_motion = 0;
}
+ }
+
+ } else {
- if (true) {
- drag_slave_speed = Vector2();
- drag_slave_accum = Vector2();
- last_drag_slave_accum = Vector2();
- //drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val());
- drag_slave_from = Vector2(orientation == HORIZONTAL ? get_value() : 0, orientation == VERTICAL ? get_value() : 0);
+ if (drag_slave_touching) {
- drag_slave_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ if (drag_slave_speed == Vector2()) {
drag_slave_touching_deaccel = false;
- time_since_motion = 0;
- if (drag_slave_touching) {
- set_fixed_process(true);
- time_since_motion = 0;
- }
+ drag_slave_touching = false;
+ set_fixed_process(false);
+ } else {
+
+ drag_slave_touching_deaccel = true;
}
+ }
+ }
+ }
- } else {
+ Ref<InputEventMouseMotion> mm = p_input;
- if (drag_slave_touching) {
+ if (mm.is_valid()) {
- if (drag_slave_speed == Vector2()) {
- drag_slave_touching_deaccel = false;
- drag_slave_touching = false;
- set_fixed_process(false);
- } else {
+ if (drag_slave_touching && !drag_slave_touching_deaccel) {
- drag_slave_touching_deaccel = true;
- }
- }
- }
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- const InputEventMouseMotion &mm = p_input.mouse_motion;
-
- if (drag_slave_touching && !drag_slave_touching_deaccel) {
-
- Vector2 motion = Vector2(mm.relative_x, mm.relative_y);
-
- drag_slave_accum -= motion;
- Vector2 diff = drag_slave_from + drag_slave_accum;
-
- if (orientation == HORIZONTAL)
- set_value(diff.x);
- /*
- else
- drag_slave_accum.x=0;
- */
- if (orientation == VERTICAL)
- set_value(diff.y);
- /*
- else
- drag_slave_accum.y=0;
- */
- time_since_motion = 0;
- }
+ Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
- } break;
+ drag_slave_accum -= motion;
+ Vector2 diff = drag_slave_from + drag_slave_accum;
+
+ if (orientation == HORIZONTAL)
+ set_value(diff.x);
+ /*
+ else
+ drag_slave_accum.x=0;
+ */
+ if (orientation == VERTICAL)
+ set_value(diff.y);
+ /*
+ else
+ drag_slave_accum.y=0;
+ */
+ time_since_motion = 0;
+ }
}
}
@@ -640,11 +634,11 @@ NodePath ScrollBar::get_drag_slave() const {
#if 0
-void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pressed,int p_modifier_mask) {
+void ScrollBar::mouse_button(const Point2& p_pos, int b->get_button_index(),bool b->is_pressed(),int p_modifier_mask) {
// wheel!
- if (b.button_index==BUTTON_WHEEL_UP && b.pressed) {
+ if (b->get_button_index()==BUTTON_WHEEL_UP && b->is_pressed()) {
if (orientation==VERTICAL)
set_val( get_val() - get_page() / 4.0 );
@@ -652,7 +646,7 @@ void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pres
set_val( get_val() + get_page() / 4.0 );
}
- if (b.button_index==BUTTON_WHEEL_DOWN && b.pressed) {
+ if (b->get_button_index()==BUTTON_WHEEL_DOWN && b->is_pressed()) {
if (orientation==HORIZONTAL)
set_val( get_val() - get_page() / 4.0 );
@@ -660,10 +654,10 @@ void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pres
set_val( get_val() + get_page() / 4.0 );
}
- if (b.button_index!=BUTTON_LEFT)
+ if (b->get_button_index()!=BUTTON_LEFT)
return;
- if (b.pressed) {
+ if (b->is_pressed()) {
int ofs = orientation==VERTICAL ? p_pos.y : p_pos.x ;
int grabber_ofs = get_grabber_offset();
@@ -692,7 +686,7 @@ void ScrollBar::mouse_button(const Point2& p_pos, int b.button_index,bool b.pres
}
}
-void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.button_index_mask) {
+void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b->get_button_index()_mask) {
if (!drag.active)
return;
@@ -712,9 +706,9 @@ void ScrollBar::mouse_motion(const Point2& p_pos, const Point2& p_rel, int b.but
}
-bool ScrollBar::key(unsigned long p_unicode, unsigned long p_scan_code,bool b.pressed,bool p_repeat,int p_modifier_mask) {
+bool ScrollBar::key(unsigned long p_unicode, unsigned long p_scan_code,bool b->is_pressed(),bool p_repeat,int p_modifier_mask) {
- if (!b.pressed)
+ if (!b->is_pressed())
return false;
switch (p_scan_code) {
@@ -784,7 +778,7 @@ void ScrollBar::_bind_methods() {
ScrollBar::ScrollBar(Orientation p_orientation) {
orientation = p_orientation;
- hilite = HILITE_NONE;
+ highlight = HIGHLIGHT_NONE;
custom_step = -1;
drag_slave = NULL;
diff --git a/scene/gui/scroll_bar.h b/scene/gui/scroll_bar.h
index 9f035b4901..8310e12590 100644
--- a/scene/gui/scroll_bar.h
+++ b/scene/gui/scroll_bar.h
@@ -39,11 +39,11 @@ class ScrollBar : public Range {
GDCLASS(ScrollBar, Range);
- enum HiliteStatus {
- HILITE_NONE,
- HILITE_DECR,
- HILITE_RANGE,
- HILITE_INCR,
+ enum HighlightStatus {
+ HIGHLIGHT_NONE,
+ HIGHLIGHT_DECR,
+ HIGHLIGHT_RANGE,
+ HIGHLIGHT_INCR,
};
static bool focus_by_default;
@@ -52,7 +52,7 @@ class ScrollBar : public Range {
Size2 size;
float custom_step;
- HiliteStatus hilite;
+ HighlightStatus highlight;
struct Drag {
@@ -84,9 +84,9 @@ class ScrollBar : public Range {
bool click_handled;
void _drag_slave_exit();
- void _drag_slave_input(const InputEvent &p_input);
+ void _drag_slave_input(const Ref<InputEvent> &p_input);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
protected:
void _notification(int p_what);
diff --git a/scene/gui/scroll_container.cpp b/scene/gui/scroll_container.cpp
index 9146fa9393..cc1a637d2b 100644
--- a/scene/gui/scroll_container.cpp
+++ b/scene/gui/scroll_container.cpp
@@ -76,101 +76,109 @@ void ScrollContainer::_cancel_drag() {
drag_from = Vector2();
}
-void ScrollContainer::_gui_input(const InputEvent &p_gui_input) {
+void ScrollContainer::_gui_input(const Ref<InputEvent> &p_gui_input) {
- switch (p_gui_input.type) {
+ Ref<InputEventMouseButton> mb = p_gui_input;
- case InputEvent::MOUSE_BUTTON: {
+ if (mb.is_valid()) {
- const InputEventMouseButton &mb = p_gui_input.mouse_button;
+ if (mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
+ // only horizontal is enabled, scroll horizontally
+ if (h_scroll->is_visible() && !v_scroll->is_visible()) {
+ h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() / 8 * mb->get_factor());
+ } else if (v_scroll->is_visible_in_tree()) {
+ v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8 * mb->get_factor());
+ }
+ }
- if (mb.button_index == BUTTON_WHEEL_UP && mb.pressed) {
- if (h_scroll->is_visible_in_tree() && !v_scroll->is_visible_in_tree()) {
- // only horizontal is enabled, scroll horizontally
- h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() / 8);
- } else if (v_scroll->is_visible_in_tree()) {
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8);
- }
+ if (mb->get_button_index() == BUTTON_WHEEL_DOWN && mb->is_pressed()) {
+ // only horizontal is enabled, scroll horizontally
+ if (h_scroll->is_visible() && !v_scroll->is_visible()) {
+ h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() / 8 * mb->get_factor());
+ } else if (v_scroll->is_visible()) {
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8 * mb->get_factor());
}
+ }
- if (mb.button_index == BUTTON_WHEEL_DOWN && mb.pressed) {
- if (h_scroll->is_visible_in_tree() && !v_scroll->is_visible_in_tree()) {
- // only horizontal is enabled, scroll horizontally
- h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() / 8);
- } else if (v_scroll->is_visible_in_tree()) {
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8);
- }
+ if (mb->get_button_index() == BUTTON_WHEEL_LEFT && mb->is_pressed()) {
+ if (h_scroll->is_visible_in_tree()) {
+ h_scroll->set_value(h_scroll->get_value() - h_scroll->get_page() * mb->get_factor() / 8);
}
+ }
- if (!OS::get_singleton()->has_touchscreen_ui_hint())
- return;
+ if (mb->get_button_index() == BUTTON_WHEEL_RIGHT && mb->is_pressed()) {
+ if (h_scroll->is_visible_in_tree()) {
+ h_scroll->set_value(h_scroll->get_value() + h_scroll->get_page() * mb->get_factor() / 8);
+ }
+ }
- if (mb.button_index != BUTTON_LEFT)
- break;
+ if (!OS::get_singleton()->has_touchscreen_ui_hint())
+ return;
- if (mb.pressed) {
+ if (mb->get_button_index() != BUTTON_LEFT)
+ return;
- if (drag_touching) {
- set_fixed_process(false);
- drag_touching_deaccel = false;
- drag_touching = false;
- drag_speed = Vector2();
- drag_accum = Vector2();
- last_drag_accum = Vector2();
- drag_from = Vector2();
- }
+ if (mb->is_pressed()) {
- if (true) {
- drag_speed = Vector2();
- drag_accum = Vector2();
- last_drag_accum = Vector2();
- drag_from = Vector2(h_scroll->get_value(), v_scroll->get_value());
- drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
- drag_touching_deaccel = false;
+ if (drag_touching) {
+ set_fixed_process(false);
+ drag_touching_deaccel = false;
+ drag_touching = false;
+ drag_speed = Vector2();
+ drag_accum = Vector2();
+ last_drag_accum = Vector2();
+ drag_from = Vector2();
+ }
+
+ if (true) {
+ drag_speed = Vector2();
+ drag_accum = Vector2();
+ last_drag_accum = Vector2();
+ drag_from = Vector2(h_scroll->get_value(), v_scroll->get_value());
+ drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_touching_deaccel = false;
+ time_since_motion = 0;
+ if (drag_touching) {
+ set_fixed_process(true);
time_since_motion = 0;
- if (drag_touching) {
- set_fixed_process(true);
- time_since_motion = 0;
- }
}
+ }
- } else {
- if (drag_touching) {
+ } else {
+ if (drag_touching) {
- if (drag_speed == Vector2()) {
- drag_touching_deaccel = false;
- drag_touching = false;
- set_fixed_process(false);
- } else {
+ if (drag_speed == Vector2()) {
+ drag_touching_deaccel = false;
+ drag_touching = false;
+ set_fixed_process(false);
+ } else {
- drag_touching_deaccel = true;
- }
+ drag_touching_deaccel = true;
}
}
+ }
+ }
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- const InputEventMouseMotion &mm = p_gui_input.mouse_motion;
+ Ref<InputEventMouseMotion> mm = p_gui_input;
- if (drag_touching && !drag_touching_deaccel) {
+ if (mm.is_valid()) {
- Vector2 motion = Vector2(mm.relative_x, mm.relative_y);
- drag_accum -= motion;
- Vector2 diff = drag_from + drag_accum;
+ if (drag_touching && !drag_touching_deaccel) {
- if (scroll_h)
- h_scroll->set_value(diff.x);
- else
- drag_accum.x = 0;
- if (scroll_v)
- v_scroll->set_value(diff.y);
- else
- drag_accum.y = 0;
- time_since_motion = 0;
- }
+ Vector2 motion = Vector2(mm->get_relative().x, mm->get_relative().y);
+ drag_accum -= motion;
+ Vector2 diff = drag_from + drag_accum;
- } break;
+ if (scroll_h)
+ h_scroll->set_value(diff.x);
+ else
+ drag_accum.x = 0;
+ if (scroll_v)
+ v_scroll->set_value(diff.y);
+ else
+ drag_accum.y = 0;
+ time_since_motion = 0;
+ }
}
}
@@ -225,14 +233,14 @@ void ScrollContainer::_notification(int p_what) {
Rect2 r = Rect2(-scroll, minsize);
if (!scroll_h || (!h_scroll->is_visible_in_tree() && c->get_h_size_flags() & SIZE_EXPAND)) {
- r.pos.x = 0;
+ r.position.x = 0;
if (c->get_h_size_flags() & SIZE_EXPAND)
r.size.width = MAX(size.width, minsize.width);
else
r.size.width = minsize.width;
}
if (!scroll_v || (!v_scroll->is_visible_in_tree() && c->get_v_size_flags() & SIZE_EXPAND)) {
- r.pos.y = 0;
+ r.position.y = 0;
r.size.height = size.height;
if (c->get_v_size_flags() & SIZE_EXPAND)
r.size.height = MAX(size.height, minsize.height);
diff --git a/scene/gui/scroll_container.h b/scene/gui/scroll_container.h
index bbc6d829ef..e5df3e5e1c 100644
--- a/scene/gui/scroll_container.h
+++ b/scene/gui/scroll_container.h
@@ -64,7 +64,7 @@ class ScrollContainer : public Container {
protected:
Size2 get_minimum_size() const;
- void _gui_input(const InputEvent &p_gui_input);
+ void _gui_input(const Ref<InputEvent> &p_gui_input);
void _notification(int p_what);
void _scroll_moved(float);
diff --git a/scene/gui/slider.cpp b/scene/gui/slider.cpp
index d2a2ff7966..d0e708bf73 100644
--- a/scene/gui/slider.cpp
+++ b/scene/gui/slider.cpp
@@ -37,16 +37,17 @@ Size2 Slider::get_minimum_size() const {
return ms;
}
-void Slider::_gui_input(InputEvent p_event) {
+void Slider::_gui_input(Ref<InputEvent> p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_event;
- InputEventMouseButton &mb = p_event.mouse_button;
- if (mb.button_index == BUTTON_LEFT) {
+ if (mb.is_valid()) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
+
+ if (mb->is_pressed()) {
+ Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
+ grab.pos = orientation == VERTICAL ? mb->get_position().y : mb->get_position().x;
- if (mb.pressed) {
- Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_hilite" : "grabber");
- grab.pos = orientation == VERTICAL ? mb.y : mb.x;
double grab_width = (double)grabber->get_size().width;
double grab_height = (double)grabber->get_size().height;
double max = orientation == VERTICAL ? get_size().height - grab_height : get_size().width - grab_width;
@@ -59,20 +60,22 @@ void Slider::_gui_input(InputEvent p_event) {
} else {
grab.active = false;
}
- } else if (mb.pressed && mb.button_index == BUTTON_WHEEL_UP) {
+ } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_UP) {
set_value(get_value() + get_step());
- } else if (mb.pressed && mb.button_index == BUTTON_WHEEL_DOWN) {
+ } else if (mb->is_pressed() && mb->get_button_index() == BUTTON_WHEEL_DOWN) {
set_value(get_value() - get_step());
}
+ }
- } else if (p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_event;
+ if (mm.is_valid()) {
if (grab.active) {
Size2i size = get_size();
Ref<Texture> grabber = get_icon("grabber");
- float motion = (orientation == VERTICAL ? p_event.mouse_motion.y : p_event.mouse_motion.x) - grab.pos;
+ float motion = (orientation == VERTICAL ? mm->get_position().y : mm->get_position().x) - grab.pos;
if (orientation == VERTICAL)
motion = -motion;
float areasize = orientation == VERTICAL ? size.height - grabber->get_size().height : size.width - grabber->get_size().width;
@@ -81,42 +84,44 @@ void Slider::_gui_input(InputEvent p_event) {
float umotion = motion / float(areasize);
set_as_ratio(grab.uvalue + umotion);
}
- } else {
+ }
- if (p_event.is_action("ui_left") && p_event.is_pressed()) {
+ if (!mm.is_valid() && !mb.is_valid()) {
+
+ if (p_event->is_action("ui_left") && p_event->is_pressed()) {
if (orientation != HORIZONTAL)
return;
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event.is_action("ui_right") && p_event.is_pressed()) {
+ } else if (p_event->is_action("ui_right") && p_event->is_pressed()) {
if (orientation != HORIZONTAL)
return;
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event.is_action("ui_up") && p_event.is_pressed()) {
+ } else if (p_event->is_action("ui_up") && p_event->is_pressed()) {
if (orientation != VERTICAL)
return;
set_value(get_value() + (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event.is_action("ui_down") && p_event.is_pressed()) {
+ } else if (p_event->is_action("ui_down") && p_event->is_pressed()) {
if (orientation != VERTICAL)
return;
set_value(get_value() - (custom_step >= 0 ? custom_step : get_step()));
accept_event();
- } else if (p_event.type == InputEvent::KEY) {
+ } else {
- const InputEventKey &k = p_event.key;
+ Ref<InputEventKey> k = p_event;
- if (!k.pressed)
+ if (!k.is_valid() || !k->is_pressed())
return;
- switch (k.scancode) {
+ switch (k->get_scancode()) {
case KEY_HOME: {
@@ -129,7 +134,7 @@ void Slider::_gui_input(InputEvent p_event) {
accept_event();
} break;
- };
+ }
}
}
}
@@ -153,7 +158,7 @@ void Slider::_notification(int p_what) {
Size2i size = get_size();
Ref<StyleBox> style = get_stylebox("slider");
Ref<StyleBox> focus = get_stylebox("focus");
- Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_hilite" : "grabber");
+ Ref<Texture> grabber = get_icon(mouse_inside || has_focus() ? "grabber_highlight" : "grabber");
Ref<Texture> tick = get_icon("tick");
if (orientation == VERTICAL) {
diff --git a/scene/gui/slider.h b/scene/gui/slider.h
index 61ad76e31e..7194484058 100644
--- a/scene/gui/slider.h
+++ b/scene/gui/slider.h
@@ -48,7 +48,7 @@ class Slider : public Range {
float custom_step;
protected:
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
static void _bind_methods();
bool ticks_on_borders;
diff --git a/scene/gui/spin_box.cpp b/scene/gui/spin_box.cpp
index ba8ca63721..c5b9df15b9 100644
--- a/scene/gui/spin_box.cpp
+++ b/scene/gui/spin_box.cpp
@@ -65,7 +65,7 @@ LineEdit *SpinBox::get_line_edit() {
return line_edit;
}
-void SpinBox::_line_edit_input(const InputEvent &p_event) {
+void SpinBox::_line_edit_input(const Ref<InputEvent> &p_event) {
}
void SpinBox::_range_click_timeout() {
@@ -86,17 +86,19 @@ void SpinBox::_range_click_timeout() {
}
}
-void SpinBox::_gui_input(const InputEvent &p_event) {
+void SpinBox::_gui_input(const Ref<InputEvent> &p_event) {
if (!is_editable()) {
return;
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed) {
- const InputEventMouseButton &mb = p_event.mouse_button;
- bool up = mb.y < (get_size().height / 2);
+ Ref<InputEventMouseButton> mb = p_event;
- switch (mb.button_index) {
+ if (mb.is_valid() && mb->is_pressed()) {
+
+ bool up = mb->get_position().y < (get_size().height / 2);
+
+ switch (mb->get_button_index()) {
case BUTTON_LEFT: {
@@ -115,27 +117,29 @@ void SpinBox::_gui_input(const InputEvent &p_event) {
} break;
case BUTTON_WHEEL_UP: {
if (line_edit->has_focus()) {
- set_value(get_value() + get_step());
+
+ set_value(get_value() + get_step() * mb->get_factor());
accept_event();
}
} break;
case BUTTON_WHEEL_DOWN: {
if (line_edit->has_focus()) {
- set_value(get_value() - get_step());
+
+ set_value(get_value() - get_step() * mb->get_factor());
accept_event();
}
} break;
}
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index == 1) {
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == 1) {
//set_default_cursor_shape(CURSOR_VSIZE);
- Vector2 cpos = Vector2(p_event.mouse_button.x, p_event.mouse_button.y);
+ Vector2 cpos = Vector2(mb->get_position().x, mb->get_position().y);
drag.mouse_pos = cpos;
}
- if (p_event.type == InputEvent::MOUSE_BUTTON && !p_event.mouse_button.pressed && p_event.mouse_button.button_index == 1) {
+ if (mb.is_valid() && !mb->is_pressed() && mb->get_button_index() == 1) {
//set_default_cursor_shape(CURSOR_ARROW);
range_click_timer->stop();
@@ -147,9 +151,12 @@ void SpinBox::_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::MOUSE_MOTION && p_event.mouse_button.button_mask & 1) {
+ Ref<InputEventMouseMotion> mm = p_event;
+
+ if (mm.is_valid() && mm->get_button_mask() & 1) {
+
+ Vector2 cpos = mm->get_position();
- Vector2 cpos = Vector2(p_event.mouse_motion.x, p_event.mouse_motion.y);
if (drag.enabled) {
float diff_y = drag.mouse_pos.y - cpos.y;
@@ -192,12 +199,7 @@ void SpinBox::_notification(int p_what) {
RID ci = get_canvas_item();
Size2i size = get_size();
- Color color = has_focus() ? line_edit->get_color("font_color_active") : line_edit->get_color("font_color");
- if (!is_editable())
- color = line_edit->get_color("font_color_read_only");
- updown->draw(ci, Point2i(size.width - updown->get_width(), (size.height - updown->get_height()) / 2), color);
-
- } else if (p_what == NOTIFICATION_FOCUS_EXIT) {
+ updown->draw(ci, Point2i(size.width - updown->get_width(), (size.height - updown->get_height()) / 2));
} else if (p_what == NOTIFICATION_FOCUS_EXIT) {
diff --git a/scene/gui/spin_box.h b/scene/gui/spin_box.h
index 338ae875f0..683ed0c344 100644
--- a/scene/gui/spin_box.h
+++ b/scene/gui/spin_box.h
@@ -49,7 +49,7 @@ class SpinBox : public Range {
String prefix;
String suffix;
- void _line_edit_input(const InputEvent &p_event);
+ void _line_edit_input(const Ref<InputEvent> &p_event);
struct Drag {
float base_val;
@@ -62,7 +62,7 @@ class SpinBox : public Range {
void _line_edit_focus_exit();
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
diff --git a/scene/gui/split_container.cpp b/scene/gui/split_container.cpp
index df24fa84d8..31236fa277 100644
--- a/scene/gui/split_container.cpp
+++ b/scene/gui/split_container.cpp
@@ -270,32 +270,32 @@ void SplitContainer::_notification(int p_what) {
}
}
-void SplitContainer::_gui_input(const InputEvent &p_event) {
+void SplitContainer::_gui_input(const Ref<InputEvent> &p_event) {
if (collapsed || !_getch(0) || !_getch(1) || dragger_visibility != DRAGGER_VISIBLE)
return;
- if (p_event.type == InputEvent::MOUSE_BUTTON) {
+ Ref<InputEventMouseButton> mb = p_event;
- const InputEventMouseButton &mb = p_event.mouse_button;
+ if (mb.is_valid()) {
- if (mb.button_index == BUTTON_LEFT) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
- if (mb.pressed) {
+ if (mb->is_pressed()) {
int sep = get_constant("separation");
if (vertical) {
- if (mb.y > middle_sep && mb.y < middle_sep + sep) {
+ if (mb->get_position().y > middle_sep && mb->get_position().y < middle_sep + sep) {
dragging = true;
- drag_from = mb.y;
+ drag_from = mb->get_position().y;
drag_ofs = expand_ofs;
}
} else {
- if (mb.x > middle_sep && mb.x < middle_sep + sep) {
+ if (mb->get_position().x > middle_sep && mb->get_position().x < middle_sep + sep) {
dragging = true;
- drag_from = mb.x;
+ drag_from = mb->get_position().x;
drag_ofs = expand_ofs;
}
}
@@ -306,13 +306,13 @@ void SplitContainer::_gui_input(const InputEvent &p_event) {
}
}
- if (p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_event;
- const InputEventMouseMotion &mm = p_event.mouse_motion;
+ if (mm.is_valid()) {
if (dragging) {
- expand_ofs = drag_ofs + ((vertical ? mm.y : mm.x) - drag_from);
+ expand_ofs = drag_ofs + ((vertical ? mm->get_position().y : mm->get_position().x) - drag_from);
queue_sort();
emit_signal("dragged", get_split_offset());
}
diff --git a/scene/gui/split_container.h b/scene/gui/split_container.h
index 12722c9f95..87a210f24c 100644
--- a/scene/gui/split_container.h
+++ b/scene/gui/split_container.h
@@ -34,7 +34,7 @@
class SplitContainer : public Container {
- GDCLASS(SplitContainer, Container);
+ GDCLASS(SplitContainer, Container)
public:
enum DraggerVisibility {
@@ -59,7 +59,7 @@ private:
void _resort();
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
static void _bind_methods();
diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp
index 952f2a9710..5ebcef3e8d 100644
--- a/scene/gui/tab_container.cpp
+++ b/scene/gui/tab_container.cpp
@@ -63,11 +63,13 @@ int TabContainer::_get_top_margin() const {
return tab_height + content_height;
}
-void TabContainer::_gui_input(const InputEvent &p_event) {
+void TabContainer::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
- Point2 pos(p_event.mouse_button.x, p_event.mouse_button.y);
+ if (mb.is_valid() && mb->is_pressed() && mb->get_button_index() == BUTTON_LEFT) {
+
+ Point2 pos(mb->get_position().x, mb->get_position().y);
Size2 size = get_size();
// Click must be on tabs in the tab header area.
@@ -206,9 +208,6 @@ void TabContainer::_notification(int p_what) {
break;
}
- // Draw the tab area.
- panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height));
-
// Draw all visible tabs.
int x = 0;
for (int i = 0; i < tab_widths.size(); i++) {
@@ -227,14 +226,14 @@ void TabContainer::_notification(int p_what) {
// Draw the tab background.
int tab_width = tab_widths[i];
- Rect2 tab_rect(tabs_ofs_cache + x, 2, tab_width, header_height);
+ Rect2 tab_rect(tabs_ofs_cache + x, 0, tab_width, header_height);
tab_style->draw(canvas, tab_rect);
// Draw the tab contents.
Control *control = tabs[i + first_tab_cache]->cast_to<Control>();
String text = control->has_meta("_tab_name") ? String(XL_MESSAGE(String(control->get_meta("_tab_name")))) : String(control->get_name());
- int x_content = tab_rect.pos.x + tab_style->get_margin(MARGIN_LEFT);
+ int x_content = tab_rect.position.x + tab_style->get_margin(MARGIN_LEFT);
int top_margin = tab_style->get_margin(MARGIN_TOP);
int y_center = top_margin + (tab_rect.size.y - tab_style->get_minimum_size().y) / 2;
@@ -282,6 +281,8 @@ void TabContainer::_notification(int p_what) {
Color(1, 1, 1, first_tab_cache > 0 ? 1.0 : 0.5));
}
+ // Draw the tab area.
+ panel->draw(canvas, Rect2(0, header_height, size.width, size.height - header_height));
} break;
case NOTIFICATION_THEME_CHANGED: {
if (get_tab_count() > 0) {
@@ -660,7 +661,7 @@ TabContainer::TabContainer() {
current = 0;
previous = 0;
mouse_x_cache = 0;
- align = ALIGN_LEFT;
+ align = ALIGN_CENTER;
tabs_visible = true;
popup = NULL;
-} \ No newline at end of file
+}
diff --git a/scene/gui/tab_container.h b/scene/gui/tab_container.h
index 87a99c82b8..1105c6b298 100644
--- a/scene/gui/tab_container.h
+++ b/scene/gui/tab_container.h
@@ -63,7 +63,7 @@ private:
protected:
void _child_renamed_callback();
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
virtual void add_child_notify(Node *p_child);
virtual void remove_child_notify(Node *p_child);
diff --git a/scene/gui/tabs.cpp b/scene/gui/tabs.cpp
index fb27f3b017..600493b439 100644
--- a/scene/gui/tabs.cpp
+++ b/scene/gui/tabs.cpp
@@ -79,13 +79,15 @@ Size2 Tabs::get_minimum_size() const {
return ms;
}
-void Tabs::_gui_input(const InputEvent &p_event) {
+void Tabs::_gui_input(const Ref<InputEvent> &p_event) {
- if (p_event.type == InputEvent::MOUSE_MOTION) {
+ Ref<InputEventMouseMotion> mm = p_event;
- Point2 pos(p_event.mouse_motion.x, p_event.mouse_motion.y);
+ if (mm.is_valid()) {
- hilite_arrow = -1;
+ Point2 pos = mm->get_position();
+
+ highlight_arrow = -1;
if (buttons_visible) {
Ref<Texture> incr = get_icon("increment");
@@ -94,20 +96,24 @@ void Tabs::_gui_input(const InputEvent &p_event) {
int limit = get_size().width - incr->get_width() - decr->get_width();
if (pos.x > limit + decr->get_width()) {
- hilite_arrow = 1;
+ highlight_arrow = 1;
} else if (pos.x > limit) {
- hilite_arrow = 0;
+ highlight_arrow = 0;
}
}
// test hovering to display right or close button
+ int hover_now = -1;
int hover_buttons = -1;
- hover = -1;
for (int i = 0; i < tabs.size(); i++) {
if (i < offset)
continue;
+ Rect2 rect = get_tab_rect(i);
+ if (rect.has_point(pos)) {
+ hover_now = i;
+ }
if (tabs[i].rb_rect.has_point(pos)) {
rb_hover = i;
cb_hover = -1;
@@ -120,6 +126,10 @@ void Tabs::_gui_input(const InputEvent &p_event) {
break;
}
}
+ if (hover != hover_now) {
+ hover = hover_now;
+ emit_signal("tab_hover", hover);
+ }
if (hover_buttons == -1) { // no hover
rb_hover = hover_buttons;
@@ -130,9 +140,11 @@ void Tabs::_gui_input(const InputEvent &p_event) {
return;
}
- if (rb_pressing && p_event.type == InputEvent::MOUSE_BUTTON &&
- !p_event.mouse_button.pressed &&
- p_event.mouse_button.button_index == BUTTON_LEFT) {
+ Ref<InputEventMouseButton> mb = p_event;
+
+ if (rb_pressing && mb.is_valid() &&
+ !mb->is_pressed() &&
+ mb->get_button_index() == BUTTON_LEFT) {
if (rb_hover != -1) {
//pressed
@@ -143,9 +155,9 @@ void Tabs::_gui_input(const InputEvent &p_event) {
update();
}
- if (cb_pressing && p_event.type == InputEvent::MOUSE_BUTTON &&
- !p_event.mouse_button.pressed &&
- p_event.mouse_button.button_index == BUTTON_LEFT) {
+ if (cb_pressing && mb.is_valid() &&
+ !mb->is_pressed() &&
+ mb->get_button_index() == BUTTON_LEFT) {
if (cb_hover != -1) {
//pressed
@@ -156,12 +168,12 @@ void Tabs::_gui_input(const InputEvent &p_event) {
update();
}
- if (p_event.type == InputEvent::MOUSE_BUTTON &&
- p_event.mouse_button.pressed &&
- p_event.mouse_button.button_index == BUTTON_LEFT) {
+ if (mb.is_valid() &&
+ mb->is_pressed() &&
+ mb->get_button_index() == BUTTON_LEFT) {
// clicks
- Point2 pos(p_event.mouse_button.x, p_event.mouse_button.y);
+ Point2 pos(mb->get_position().x, mb->get_position().y);
if (buttons_visible) {
@@ -230,11 +242,13 @@ void Tabs::_notification(int p_what) {
update();
} break;
case NOTIFICATION_RESIZED: {
-
+ _update_cache();
_ensure_no_over_offset();
+ ensure_tab_visible(current);
+
} break;
case NOTIFICATION_DRAW: {
-
+ _update_cache();
RID ci = get_canvas_item();
Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
@@ -268,8 +282,8 @@ void Tabs::_notification(int p_what) {
Ref<Texture> incr = get_icon("increment");
Ref<Texture> decr = get_icon("decrement");
- Ref<Texture> incr_hl = get_icon("increment_hilite");
- Ref<Texture> decr_hl = get_icon("decrement_hilite");
+ Ref<Texture> incr_hl = get_icon("increment_highlight");
+ Ref<Texture> decr_hl = get_icon("decrement_highlight");
int limit = get_size().width - incr->get_size().width - decr->get_size().width;
@@ -282,18 +296,7 @@ void Tabs::_notification(int p_what) {
tabs[i].ofs_cache = w;
- int lsize = get_tab_width(i);
-
- String text = tabs[i].text;
- int slen = font->get_string_size(text).width;
-
- if (w + lsize > limit) {
- max_drawn_tab = i - 1;
- missing_right = true;
- break;
- } else {
- max_drawn_tab = i;
- }
+ int lsize = tabs[i].size_cache;
Ref<StyleBox> sb;
Color col;
@@ -309,7 +312,15 @@ void Tabs::_notification(int p_what) {
col = color_bg;
}
- Rect2 sb_rect = Rect2(w, 0, lsize, h);
+ if (w + lsize > limit) {
+ max_drawn_tab = i - 1;
+ missing_right = true;
+ break;
+ } else {
+ max_drawn_tab = i;
+ }
+
+ Rect2 sb_rect = Rect2(w, 0, tabs[i].size_cache, h);
sb->draw(ci, sb_rect);
w += sb->get_margin(MARGIN_LEFT);
@@ -319,13 +330,13 @@ void Tabs::_notification(int p_what) {
if (icon.is_valid()) {
icon->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - icon->get_height()) / 2));
- if (text != "")
+ if (tabs[i].text != "")
w += icon->get_width() + get_constant("hseparation");
}
- font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), text, col);
+ font->draw(ci, Point2i(w, sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - font->get_height()) / 2 + font->get_ascent()), tabs[i].text, col, tabs[i].size_text);
- w += slen;
+ w += tabs[i].size_text;
if (tabs[i].right_button.is_valid()) {
@@ -336,8 +347,8 @@ void Tabs::_notification(int p_what) {
Rect2 rb_rect;
rb_rect.size = style->get_minimum_size() + rb->get_size();
- rb_rect.pos.x = w;
- rb_rect.pos.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2;
+ rb_rect.position.x = w;
+ rb_rect.position.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (rb_rect.size.y)) / 2;
if (rb_hover == i) {
if (rb_pressing)
@@ -346,7 +357,7 @@ void Tabs::_notification(int p_what) {
style->draw(ci, rb_rect);
}
- rb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), rb_rect.pos.y + style->get_margin(MARGIN_TOP)));
+ rb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), rb_rect.position.y + style->get_margin(MARGIN_TOP)));
w += rb->get_width();
tabs[i].rb_rect = rb_rect;
}
@@ -360,8 +371,8 @@ void Tabs::_notification(int p_what) {
Rect2 cb_rect;
cb_rect.size = style->get_minimum_size() + cb->get_size();
- cb_rect.pos.x = w;
- cb_rect.pos.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2;
+ cb_rect.position.x = w;
+ cb_rect.position.y = sb->get_margin(MARGIN_TOP) + ((sb_rect.size.y - sb_ms.y) - (cb_rect.size.y)) / 2;
if (!tabs[i].disabled && cb_hover == i) {
if (cb_pressing)
@@ -370,14 +381,12 @@ void Tabs::_notification(int p_what) {
style->draw(ci, cb_rect);
}
- cb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), cb_rect.pos.y + style->get_margin(MARGIN_TOP)));
+ cb->draw(ci, Point2i(w + style->get_margin(MARGIN_LEFT), cb_rect.position.y + style->get_margin(MARGIN_TOP)));
w += cb->get_width();
tabs[i].cb_rect = cb_rect;
}
w += sb->get_margin(MARGIN_RIGHT);
-
- tabs[i].size_cache = w - tabs[i].ofs_cache;
}
if (offset > 0 || missing_right) {
@@ -385,12 +394,12 @@ void Tabs::_notification(int p_what) {
int vofs = (get_size().height - incr->get_size().height) / 2;
if (offset > 0)
- draw_texture(hilite_arrow == 0 ? decr_hl : decr, Point2(limit, vofs));
+ draw_texture(highlight_arrow == 0 ? decr_hl : decr, Point2(limit, vofs));
else
draw_texture(decr, Point2(limit, vofs), Color(1, 1, 1, 0.5));
if (missing_right)
- draw_texture(hilite_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs));
+ draw_texture(highlight_arrow == 1 ? incr_hl : incr, Point2(limit + decr->get_size().width, vofs));
else
draw_texture(incr, Point2(limit + decr->get_size().width, vofs), Color(1, 1, 1, 0.5));
@@ -415,6 +424,7 @@ void Tabs::set_current_tab(int p_current) {
current = p_current;
_change_notify("current_tab");
+ _update_cache();
update();
}
@@ -423,6 +433,10 @@ int Tabs::get_current_tab() const {
return current;
}
+int Tabs::get_hovered_tab() const {
+ return hover;
+}
+
void Tabs::set_tab_title(int p_tab, const String &p_title) {
ERR_FAIL_INDEX(p_tab, tabs.size());
@@ -476,15 +490,81 @@ Ref<Texture> Tabs::get_tab_right_button(int p_tab) const {
return tabs[p_tab].right_button;
}
+void Tabs::_update_cache() {
+ Ref<StyleBox> tab_disabled = get_stylebox("tab_disabled");
+ Ref<StyleBox> tab_bg = get_stylebox("tab_bg");
+ Ref<StyleBox> tab_fg = get_stylebox("tab_fg");
+ Ref<Font> font = get_font("font");
+ Ref<Texture> incr = get_icon("increment");
+ Ref<Texture> decr = get_icon("decrement");
+ int limit = get_size().width - incr->get_width() - decr->get_width();
+
+ int w = 0;
+ int mw = 0;
+ int size_fixed = 0;
+ int count_resize = 0;
+ for (int i = 0; i < tabs.size(); i++) {
+ tabs[i].ofs_cache = mw;
+ tabs[i].size_cache = get_tab_width(i);
+ tabs[i].size_text = font->get_string_size(tabs[i].text).width;
+ mw += tabs[i].size_cache;
+ if (tabs[i].size_cache <= min_width || i == current) {
+ size_fixed += tabs[i].size_cache;
+ } else {
+ count_resize++;
+ }
+ }
+ int m_width = min_width;
+ if (count_resize > 0) {
+ m_width = MAX((limit - size_fixed) / count_resize, min_width);
+ }
+ for (int i = 0; i < tabs.size(); i++) {
+ if (i < offset)
+ continue;
+ Ref<StyleBox> sb;
+ if (tabs[i].disabled) {
+ sb = tab_disabled;
+ } else if (i == current) {
+ sb = tab_fg;
+ } else {
+ sb = tab_bg;
+ }
+ int lsize = tabs[i].size_cache;
+ int slen = tabs[i].size_text;
+ if (min_width > 0 && mw > limit && i != current) {
+ if (lsize > m_width) {
+ slen = m_width - (sb->get_margin(MARGIN_LEFT) + sb->get_margin(MARGIN_RIGHT));
+ if (tabs[i].icon.is_valid()) {
+ slen -= tabs[i].icon->get_width();
+ slen -= get_constant("hseparation");
+ }
+ if (cb_displaypolicy == CLOSE_BUTTON_SHOW_ALWAYS || (cb_displaypolicy == CLOSE_BUTTON_SHOW_ACTIVE_ONLY && i == current)) {
+ Ref<Texture> cb = get_icon("close");
+ slen -= cb->get_width();
+ slen -= get_constant("hseparation");
+ }
+ slen = MAX(slen, 1);
+ lsize = m_width;
+ }
+ }
+ tabs[i].ofs_cache = w;
+ tabs[i].size_cache = lsize;
+ tabs[i].size_text = slen;
+ w += lsize;
+ }
+}
+
void Tabs::add_tab(const String &p_str, const Ref<Texture> &p_icon) {
Tab t;
t.text = p_str;
t.icon = p_icon;
t.disabled = false;
+ t.ofs_cache = 0;
+ t.size_cache = 0;
tabs.push_back(t);
-
+ _update_cache();
update();
minimum_size_changed();
}
@@ -501,6 +581,7 @@ void Tabs::remove_tab(int p_idx) {
tabs.remove(p_idx);
if (current >= p_idx)
current--;
+ _update_cache();
update();
minimum_size_changed();
@@ -583,7 +664,7 @@ void Tabs::_ensure_no_over_offset() {
if (i < offset - 1)
continue;
- total_w += get_tab_width(i);
+ total_w += tabs[i].size_cache;
}
if (total_w < limit) {
@@ -600,37 +681,35 @@ void Tabs::ensure_tab_visible(int p_idx) {
if (!is_inside_tree())
return;
+ if (tabs.size() == 0) return;
ERR_FAIL_INDEX(p_idx, tabs.size());
- _ensure_no_over_offset();
-
- if (p_idx <= offset) {
+ if (p_idx == offset) {
+ return;
+ }
+ if (p_idx < offset) {
offset = p_idx;
update();
return;
}
+ int prev_offset = offset;
Ref<Texture> incr = get_icon("increment");
Ref<Texture> decr = get_icon("decrement");
int limit = get_size().width - incr->get_width() - decr->get_width();
-
- int x = 0;
- for (int i = 0; i < tabs.size(); i++) {
-
- if (i < offset)
- continue;
-
- int sz = get_tab_width(i);
- tabs[i].x_cache = x;
- tabs[i].x_size_cache = sz;
- x += sz;
+ for (int i = offset; i <= p_idx; i++) {
+ if (tabs[i].ofs_cache + tabs[i].size_cache > limit) {
+ offset++;
+ }
}
- while (offset < tabs.size() && ((tabs[p_idx].x_cache + tabs[p_idx].x_size_cache) - tabs[offset].x_cache) > limit) {
- offset++;
+ if (prev_offset != offset) {
+ update();
}
+}
- update();
+Rect2 Tabs::get_tab_rect(int p_tab) {
+ return Rect2(tabs[p_tab].ofs_cache, 0, tabs[p_tab].size_cache, get_size().height);
}
void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
@@ -638,6 +717,10 @@ void Tabs::set_tab_close_display_policy(CloseButtonDisplayPolicy p_policy) {
update();
}
+void Tabs::set_min_width(int p_width) {
+ min_width = p_width;
+}
+
void Tabs::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"), &Tabs::_gui_input);
@@ -659,6 +742,7 @@ void Tabs::_bind_methods() {
ADD_SIGNAL(MethodInfo("tab_changed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("right_button_pressed", PropertyInfo(Variant::INT, "tab")));
ADD_SIGNAL(MethodInfo("tab_close", PropertyInfo(Variant::INT, "tab")));
+ ADD_SIGNAL(MethodInfo("tab_hover", PropertyInfo(Variant::INT, "tab")));
ADD_PROPERTY(PropertyInfo(Variant::INT, "current_tab", PROPERTY_HINT_RANGE, "-1,4096,1", PROPERTY_USAGE_EDITOR), "set_current_tab", "get_current_tab");
@@ -677,11 +761,13 @@ Tabs::Tabs() {
tab_align = ALIGN_CENTER;
rb_hover = -1;
rb_pressing = false;
- hilite_arrow = -1;
+ highlight_arrow = -1;
cb_hover = -1;
cb_pressing = false;
cb_displaypolicy = CLOSE_BUTTON_SHOW_NEVER;
offset = 0;
max_drawn_tab = 0;
+
+ min_width = 0;
}
diff --git a/scene/gui/tabs.h b/scene/gui/tabs.h
index 2392327206..65d409c410 100644
--- a/scene/gui/tabs.h
+++ b/scene/gui/tabs.h
@@ -59,6 +59,7 @@ private:
int ofs_cache;
bool disabled;
int size_cache;
+ int size_text;
int x_cache;
int x_size_cache;
@@ -69,12 +70,11 @@ private:
int offset;
int max_drawn_tab;
- int hilite_arrow;
+ int highlight_arrow;
bool buttons_visible;
bool missing_right;
Vector<Tab> tabs;
int current;
- Control *_get_tab(int idx) const;
int _get_top_margin() const;
TabAlign tab_align;
int rb_hover;
@@ -85,12 +85,14 @@ private:
CloseButtonDisplayPolicy cb_displaypolicy;
int hover; // hovered tab
+ int min_width;
int get_tab_width(int p_idx) const;
void _ensure_no_over_offset();
+ void _update_cache();
protected:
- void _gui_input(const InputEvent &p_event);
+ void _gui_input(const Ref<InputEvent> &p_event);
void _notification(int p_what);
static void _bind_methods();
@@ -117,13 +119,16 @@ public:
int get_tab_count() const;
void set_current_tab(int p_current);
int get_current_tab() const;
+ int get_hovered_tab() const;
void remove_tab(int p_idx);
void clear_tabs();
void ensure_tab_visible(int p_idx);
+ void set_min_width(int p_width);
+ Rect2 get_tab_rect(int p_tab);
Size2 get_minimum_size() const;
Tabs();
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index 3c8545bd75..936a9b77f8 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -334,7 +334,10 @@ void TextEdit::_update_scrollbars() {
v_scroll->show();
v_scroll->set_max(total_rows);
v_scroll->set_page(visible_rows);
- v_scroll->set_value(cursor.line_ofs);
+
+ if (fabs(v_scroll->get_value() - (double)cursor.line_ofs) >= 1) {
+ v_scroll->set_value(cursor.line_ofs);
+ }
} else {
cursor.line_ofs = 0;
@@ -346,7 +349,9 @@ void TextEdit::_update_scrollbars() {
h_scroll->show();
h_scroll->set_max(total_width);
h_scroll->set_page(visible_width);
- h_scroll->set_value(cursor.x_ofs);
+ if (fabs(h_scroll->get_value() - (double)cursor.x_ofs) >= 1) {
+ h_scroll->set_value(cursor.x_ofs);
+ }
} else {
@@ -1064,16 +1069,16 @@ void TextEdit::_notification(int p_what) {
int th = h + csb->get_minimum_size().y;
if (cursor_pos.y + get_row_height() + th > get_size().height) {
- completion_rect.pos.y = cursor_pos.y - th;
+ completion_rect.position.y = cursor_pos.y - th;
} else {
- completion_rect.pos.y = cursor_pos.y + get_row_height() + csb->get_offset().y;
+ completion_rect.position.y = cursor_pos.y + get_row_height() + csb->get_offset().y;
completion_below = true;
}
if (cursor_pos.x - nofs + w + scrollw > get_size().width) {
- completion_rect.pos.x = get_size().width - w - scrollw;
+ completion_rect.position.x = get_size().width - w - scrollw;
} else {
- completion_rect.pos.x = cursor_pos.x - nofs;
+ completion_rect.position.x = cursor_pos.x - nofs;
}
completion_rect.size.width = w + 2;
@@ -1081,14 +1086,14 @@ void TextEdit::_notification(int p_what) {
if (completion_options.size() <= maxlines)
scrollw = 0;
- draw_style_box(csb, Rect2(completion_rect.pos - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0)));
+ draw_style_box(csb, Rect2(completion_rect.position - csb->get_offset(), completion_rect.size + csb->get_minimum_size() + Size2(scrollw, 0)));
if (cache.completion_background_color.a > 0.01) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.pos, completion_rect.size + Size2(scrollw, 0)), cache.completion_background_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(completion_rect.position, completion_rect.size + Size2(scrollw, 0)), cache.completion_background_color);
}
int line_from = CLAMP(completion_index - lines / 2, 0, completion_options.size() - lines);
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.pos.x, completion_rect.pos.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color);
- draw_rect(Rect2(completion_rect.pos, Size2(nofs, completion_rect.size.height)), cache.completion_existing_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(completion_rect.position.x, completion_rect.position.y + (completion_index - line_from) * get_row_height()), Size2(completion_rect.size.width, get_row_height())), cache.completion_selected_color);
+ draw_rect(Rect2(completion_rect.position, Size2(nofs, completion_rect.size.height)), cache.completion_existing_color);
for (int i = 0; i < lines; i++) {
@@ -1100,14 +1105,14 @@ void TextEdit::_notification(int p_what) {
text_color = color_regions[j].color;
}
}
- draw_string(cache.font, Point2(completion_rect.pos.x, completion_rect.pos.y + i * get_row_height() + cache.font->get_ascent()), completion_options[l], text_color, completion_rect.size.width);
+ draw_string(cache.font, Point2(completion_rect.position.x, completion_rect.position.y + i * get_row_height() + cache.font->get_ascent()), completion_options[l], text_color, completion_rect.size.width);
}
if (scrollw) {
//draw a small scroll rectangle to show a position in the options
float r = maxlines / (float)completion_options.size();
float o = line_from / (float)completion_options.size();
- draw_rect(Rect2(completion_rect.pos.x + completion_rect.size.width, completion_rect.pos.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc);
+ draw_rect(Rect2(completion_rect.position.x + completion_rect.size.width, completion_rect.position.y + o * completion_rect.size.y, scrollw, completion_rect.size.y * r), scrollc);
}
completion_line_ofs = line_from;
@@ -1435,1270 +1440,1266 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
r_col = col;
}
-void TextEdit::_gui_input(const InputEvent &p_gui_input) {
-
- switch (p_gui_input.type) {
-
- case InputEvent::MOUSE_BUTTON: {
+void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) {
- const InputEventMouseButton &mb = p_gui_input.mouse_button;
+ Ref<InputEventMouseButton> mb = p_gui_input;
- if (completion_active && completion_rect.has_point(Point2(mb.x, mb.y))) {
+ if (mb.is_valid()) {
+ if (completion_active && completion_rect.has_point(mb->get_position())) {
- if (!mb.pressed)
- return;
+ if (!mb->is_pressed())
+ return;
- if (mb.button_index == BUTTON_WHEEL_UP) {
- if (completion_index > 0) {
- completion_index--;
- completion_current = completion_options[completion_index];
- update();
- }
+ if (mb->get_button_index() == BUTTON_WHEEL_UP) {
+ if (completion_index > 0) {
+ completion_index--;
+ completion_current = completion_options[completion_index];
+ update();
}
- if (mb.button_index == BUTTON_WHEEL_DOWN) {
+ }
+ if (mb->get_button_index() == BUTTON_WHEEL_DOWN) {
- if (completion_index < completion_options.size() - 1) {
- completion_index++;
- completion_current = completion_options[completion_index];
- update();
- }
+ if (completion_index < completion_options.size() - 1) {
+ completion_index++;
+ completion_current = completion_options[completion_index];
+ update();
}
+ }
- if (mb.button_index == BUTTON_LEFT) {
+ if (mb->get_button_index() == BUTTON_LEFT) {
- completion_index = CLAMP(completion_line_ofs + (mb.y - completion_rect.pos.y) / get_row_height(), 0, completion_options.size() - 1);
+ completion_index = CLAMP(completion_line_ofs + (mb->get_position().y - completion_rect.position.y) / get_row_height(), 0, completion_options.size() - 1);
- completion_current = completion_options[completion_index];
- update();
- if (mb.doubleclick)
- _confirm_completion();
- }
- return;
- } else {
- _cancel_completion();
- _cancel_code_hint();
+ completion_current = completion_options[completion_index];
+ update();
+ if (mb->is_doubleclick())
+ _confirm_completion();
}
+ return;
+ } else {
+ _cancel_completion();
+ _cancel_code_hint();
+ }
- if (mb.pressed) {
- if (mb.button_index == BUTTON_WHEEL_UP && !mb.mod.command) {
- v_scroll->set_value(v_scroll->get_value() - 3);
- }
- if (mb.button_index == BUTTON_WHEEL_DOWN && !mb.mod.command) {
- v_scroll->set_value(v_scroll->get_value() + 3);
- }
- if (mb.button_index == BUTTON_WHEEL_LEFT) {
- h_scroll->set_value(h_scroll->get_value() - 3);
- }
- if (mb.button_index == BUTTON_WHEEL_RIGHT) {
- h_scroll->set_value(h_scroll->get_value() + 3);
- }
- if (mb.button_index == BUTTON_LEFT) {
+ if (mb->is_pressed()) {
- _reset_caret_blink_timer();
+ if (mb->get_button_index() == BUTTON_WHEEL_UP && !mb->get_command()) {
+ v_scroll->set_value(v_scroll->get_value() - (3 * mb->get_factor()));
+ }
+ if (mb->get_button_index() == BUTTON_WHEEL_DOWN && !mb->get_command()) {
+ v_scroll->set_value(v_scroll->get_value() + (3 * mb->get_factor()));
+ }
+ if (mb->get_button_index() == BUTTON_WHEEL_LEFT) {
+ h_scroll->set_value(h_scroll->get_value() - (100 * mb->get_factor()));
+ }
+ if (mb->get_button_index() == BUTTON_WHEEL_RIGHT) {
+ h_scroll->set_value(h_scroll->get_value() + (100 * mb->get_factor()));
+ }
+ if (mb->get_button_index() == BUTTON_LEFT) {
- int row, col;
- _get_mouse_pos(Point2i(mb.x, mb.y), row, col);
+ _reset_caret_blink_timer();
+
+ int row, col;
+ _get_mouse_pos(Point2i(mb->get_position().x, mb->get_position().y), row, col);
+
+ if (mb->get_command() && highlighted_word != String()) {
- if (mb.mod.command && highlighted_word != String()) {
+ emit_signal("symbol_lookup", highlighted_word, row, col);
+ return;
+ }
- emit_signal("symbol_lookup", highlighted_word, row, col);
+ // toggle breakpoint on gutter click
+ if (draw_breakpoint_gutter) {
+ int gutter = cache.style_normal->get_margin(MARGIN_LEFT);
+ if (mb->get_position().x > gutter && mb->get_position().x <= gutter + cache.breakpoint_gutter_width + 3) {
+ set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row));
+ emit_signal("breakpoint_toggled", row);
return;
}
+ }
- // toggle breakpoint on gutter click
- if (draw_breakpoint_gutter) {
- int gutter = cache.style_normal->get_margin(MARGIN_LEFT);
- if (mb.x > gutter && mb.x <= gutter + cache.breakpoint_gutter_width + 3) {
- set_line_as_breakpoint(row, !is_line_set_as_breakpoint(row));
- emit_signal("breakpoint_toggled", row);
- return;
- }
- }
+ int prev_col = cursor.column;
+ int prev_line = cursor.line;
- int prev_col = cursor.column;
- int prev_line = cursor.line;
+ cursor_set_line(row);
+ cursor_set_column(col);
- cursor_set_line(row);
- cursor_set_column(col);
+ if (mb->get_shift() && (cursor.column != prev_col || cursor.line != prev_line)) {
- if (mb.mod.shift && (cursor.column != prev_col || cursor.line != prev_line)) {
+ if (!selection.active) {
+ selection.active = true;
+ selection.selecting_mode = Selection::MODE_POINTER;
+ selection.from_column = prev_col;
+ selection.from_line = prev_line;
+ selection.to_column = cursor.column;
+ selection.to_line = cursor.line;
+
+ if (selection.from_line > selection.to_line || (selection.from_line == selection.to_line && selection.from_column > selection.to_column)) {
+ SWAP(selection.from_column, selection.to_column);
+ SWAP(selection.from_line, selection.to_line);
+ selection.shiftclick_left = false;
+ } else {
+ selection.shiftclick_left = true;
+ }
+ selection.selecting_line = prev_line;
+ selection.selecting_column = prev_col;
+ update();
+ } else {
- if (!selection.active) {
- selection.active = true;
- selection.selecting_mode = Selection::MODE_POINTER;
- selection.from_column = prev_col;
- selection.from_line = prev_line;
- selection.to_column = cursor.column;
- selection.to_line = cursor.line;
+ if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
- if (selection.from_line > selection.to_line || (selection.from_line == selection.to_line && selection.from_column > selection.to_column)) {
+ if (selection.shiftclick_left) {
SWAP(selection.from_column, selection.to_column);
SWAP(selection.from_line, selection.to_line);
- selection.shiftclick_left = false;
- } else {
- selection.shiftclick_left = true;
+ selection.shiftclick_left = !selection.shiftclick_left;
}
- selection.selecting_line = prev_line;
- selection.selecting_column = prev_col;
- update();
- } else {
-
- if (cursor.line < selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column < selection.selecting_column)) {
+ selection.from_column = cursor.column;
+ selection.from_line = cursor.line;
- if (selection.shiftclick_left) {
- SWAP(selection.from_column, selection.to_column);
- SWAP(selection.from_line, selection.to_line);
- selection.shiftclick_left = !selection.shiftclick_left;
- }
- selection.from_column = cursor.column;
- selection.from_line = cursor.line;
-
- } else if (cursor.line > selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column > selection.selecting_column)) {
+ } else if (cursor.line > selection.selecting_line || (cursor.line == selection.selecting_line && cursor.column > selection.selecting_column)) {
- if (!selection.shiftclick_left) {
- SWAP(selection.from_column, selection.to_column);
- SWAP(selection.from_line, selection.to_line);
- selection.shiftclick_left = !selection.shiftclick_left;
- }
- selection.to_column = cursor.column;
- selection.to_line = cursor.line;
-
- } else {
- selection.active = false;
+ if (!selection.shiftclick_left) {
+ SWAP(selection.from_column, selection.to_column);
+ SWAP(selection.from_line, selection.to_line);
+ selection.shiftclick_left = !selection.shiftclick_left;
}
+ selection.to_column = cursor.column;
+ selection.to_line = cursor.line;
- update();
+ } else {
+ selection.active = false;
}
- } else {
-
- //if sel active and dblick last time < something
-
- //else
- selection.active = false;
- selection.selecting_mode = Selection::MODE_POINTER;
- selection.selecting_line = row;
- selection.selecting_column = col;
+ update();
}
- if (!mb.doubleclick && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
- //tripleclick select line
- select(cursor.line, 0, cursor.line, text[cursor.line].length());
- selection.selecting_column = 0;
- last_dblclk = 0;
+ } else {
- } else if (mb.doubleclick && text[cursor.line].length()) {
+ //if sel active and dblick last time < something
- //doubleclick select world
- String s = text[cursor.line];
- int beg = CLAMP(cursor.column, 0, s.length());
- int end = beg;
+ //else
+ selection.active = false;
+ selection.selecting_mode = Selection::MODE_POINTER;
+ selection.selecting_line = row;
+ selection.selecting_column = col;
+ }
- if (s[beg] > 32 || beg == s.length()) {
+ if (!mb->is_doubleclick() && (OS::get_singleton()->get_ticks_msec() - last_dblclk) < 600 && cursor.line == prev_line) {
+ //tripleclick select line
+ select(cursor.line, 0, cursor.line, text[cursor.line].length());
+ selection.selecting_column = 0;
+ last_dblclk = 0;
- bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
+ } else if (mb->is_doubleclick() && text[cursor.line].length()) {
- while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) {
- beg--;
- }
- while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) {
- end++;
- }
+ //doubleclick select world
+ String s = text[cursor.line];
+ int beg = CLAMP(cursor.column, 0, s.length());
+ int end = beg;
- if (end < s.length())
- end += 1;
+ if (s[beg] > 32 || beg == s.length()) {
- select(cursor.line, beg, cursor.line, end);
+ bool symbol = beg < s.length() && _is_symbol(s[beg]); //not sure if right but most editors behave like this
- selection.selecting_column = beg;
+ while (beg > 0 && s[beg - 1] > 32 && (symbol == _is_symbol(s[beg - 1]))) {
+ beg--;
+ }
+ while (end < s.length() && s[end + 1] > 32 && (symbol == _is_symbol(s[end + 1]))) {
+ end++;
}
- last_dblclk = OS::get_singleton()->get_ticks_msec();
- }
+ if (end < s.length())
+ end += 1;
- update();
- }
+ select(cursor.line, beg, cursor.line, end);
- if (mb.button_index == BUTTON_RIGHT && context_menu_enabled) {
+ selection.selecting_column = beg;
+ }
- menu->set_position(get_global_transform().xform(get_local_mouse_pos()));
- menu->set_size(Vector2(1, 1));
- menu->popup();
- grab_focus();
+ last_dblclk = OS::get_singleton()->get_ticks_msec();
}
- } else {
- if (mb.button_index == BUTTON_LEFT)
- click_select_held->stop();
+ update();
+ }
- // notify to show soft keyboard
- notification(NOTIFICATION_FOCUS_ENTER);
+ if (mb->get_button_index() == BUTTON_RIGHT && context_menu_enabled) {
+
+ menu->set_position(get_global_transform().xform(get_local_mouse_pos()));
+ menu->set_size(Vector2(1, 1));
+ menu->popup();
+ grab_focus();
}
+ } else {
- } break;
- case InputEvent::MOUSE_MOTION: {
+ if (mb->get_button_index() == BUTTON_LEFT)
+ click_select_held->stop();
- const InputEventMouseMotion &mm = p_gui_input.mouse_motion;
+ // notify to show soft keyboard
+ notification(NOTIFICATION_FOCUS_ENTER);
+ }
+ }
- if (select_identifiers_enabled) {
- if (mm.mod.command && mm.button_mask == 0) {
+ Ref<InputEventMouseMotion> mm = p_gui_input;
- String new_word = get_word_at_pos(Vector2(mm.x, mm.y));
- if (new_word != highlighted_word) {
- highlighted_word = new_word;
- update();
- }
- } else {
- if (highlighted_word != String()) {
- highlighted_word = String();
- update();
- }
+ if (mm.is_valid()) {
+
+ if (select_identifiers_enabled) {
+ if (mm->get_command() && mm->get_button_mask() == 0) {
+
+ String new_word = get_word_at_pos(mm->get_position());
+ if (new_word != highlighted_word) {
+ highlighted_word = new_word;
+ update();
+ }
+ } else {
+ if (highlighted_word != String()) {
+ highlighted_word = String();
+ update();
}
}
+ }
- if (mm.button_mask & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging
+ if (mm->get_button_mask() & BUTTON_MASK_LEFT && get_viewport()->gui_get_drag_data() == Variant()) { //ignore if dragging
- if (selection.selecting_mode != Selection::MODE_NONE) {
+ if (selection.selecting_mode != Selection::MODE_NONE) {
- _reset_caret_blink_timer();
+ _reset_caret_blink_timer();
- int row, col;
- _get_mouse_pos(Point2i(mm.x, mm.y), row, col);
+ int row, col;
+ _get_mouse_pos(mm->get_position(), row, col);
- select(selection.selecting_line, selection.selecting_column, row, col);
+ select(selection.selecting_line, selection.selecting_column, row, col);
- cursor_set_line(row);
- cursor_set_column(col);
- update();
+ cursor_set_line(row);
+ cursor_set_column(col);
+ update();
- click_select_held->start();
- }
+ click_select_held->start();
}
+ }
+ }
- } break;
+ Ref<InputEventKey> k = p_gui_input;
- case InputEvent::KEY: {
+ if (k.is_valid()) {
- InputEventKey k = p_gui_input.key;
+ k = k->duplicate(); //it will be modified later on
#ifdef OSX_ENABLED
- if (k.scancode == KEY_META) {
+ if (k->get_scancode() == KEY_META) {
#else
- if (k.scancode == KEY_CONTROL) {
+ if (k->get_scancode() == KEY_CONTROL) {
#endif
- if (select_identifiers_enabled) {
+ if (select_identifiers_enabled) {
- if (k.pressed) {
+ if (k->is_pressed()) {
- highlighted_word = get_word_at_pos(get_local_mouse_pos());
- update();
+ highlighted_word = get_word_at_pos(get_local_mouse_pos());
+ update();
- } else {
- highlighted_word = String();
- update();
- }
+ } else {
+ highlighted_word = String();
+ update();
}
}
+ }
- if (!k.pressed)
- return;
-
- if (completion_active) {
- if (readonly)
- break;
-
- bool valid = true;
- if (k.mod.command || k.mod.meta)
- valid = false;
-
- if (valid) {
-
- if (!k.mod.alt) {
- if (k.scancode == KEY_UP) {
+ if (!k->is_pressed())
+ return;
- if (completion_index > 0) {
- completion_index--;
- completion_current = completion_options[completion_index];
- update();
- }
- accept_event();
- return;
- }
+ if (completion_active) {
+ if (readonly)
+ return;
- if (k.scancode == KEY_DOWN) {
+ bool valid = true;
+ if (k->get_command() || k->get_metakey())
+ valid = false;
- if (completion_index < completion_options.size() - 1) {
- completion_index++;
- completion_current = completion_options[completion_index];
- update();
- }
- accept_event();
- return;
- }
+ if (valid) {
- if (k.scancode == KEY_PAGEUP) {
+ if (!k->get_alt()) {
+ if (k->get_scancode() == KEY_UP) {
- completion_index -= get_constant("completion_lines");
- if (completion_index < 0)
- completion_index = 0;
+ if (completion_index > 0) {
+ completion_index--;
completion_current = completion_options[completion_index];
update();
- accept_event();
- return;
}
+ accept_event();
+ return;
+ }
- if (k.scancode == KEY_PAGEDOWN) {
+ if (k->get_scancode() == KEY_DOWN) {
- completion_index += get_constant("completion_lines");
- if (completion_index >= completion_options.size())
- completion_index = completion_options.size() - 1;
+ if (completion_index < completion_options.size() - 1) {
+ completion_index++;
completion_current = completion_options[completion_index];
update();
- accept_event();
- return;
}
+ accept_event();
+ return;
+ }
- if (k.scancode == KEY_HOME && completion_index > 0) {
+ if (k->get_scancode() == KEY_PAGEUP) {
+ completion_index -= get_constant("completion_lines");
+ if (completion_index < 0)
completion_index = 0;
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
+ }
- if (k.scancode == KEY_END && completion_index < completion_options.size() - 1) {
+ if (k->get_scancode() == KEY_PAGEDOWN) {
+ completion_index += get_constant("completion_lines");
+ if (completion_index >= completion_options.size())
completion_index = completion_options.size() - 1;
- completion_current = completion_options[completion_index];
- update();
- accept_event();
- return;
- }
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
+ }
- if (k.scancode == KEY_DOWN) {
+ if (k->get_scancode() == KEY_HOME && completion_index > 0) {
- if (completion_index < completion_options.size() - 1) {
- completion_index++;
- completion_current = completion_options[completion_index];
- update();
- }
- accept_event();
- return;
- }
-
- if (k.scancode == KEY_ENTER || k.scancode == KEY_RETURN || k.scancode == KEY_TAB) {
+ completion_index = 0;
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
+ }
- _confirm_completion();
- accept_event();
- return;
- }
+ if (k->get_scancode() == KEY_END && completion_index < completion_options.size() - 1) {
- if (k.scancode == KEY_BACKSPACE) {
+ completion_index = completion_options.size() - 1;
+ completion_current = completion_options[completion_index];
+ update();
+ accept_event();
+ return;
+ }
- _reset_caret_blink_timer();
+ if (k->get_scancode() == KEY_DOWN) {
- backspace_at_cursor();
- _update_completion_candidates();
- accept_event();
- return;
+ if (completion_index < completion_options.size() - 1) {
+ completion_index++;
+ completion_current = completion_options[completion_index];
+ update();
}
+ accept_event();
+ return;
+ }
- if (k.scancode == KEY_SHIFT) {
- accept_event();
- return;
- }
+ if (k->get_scancode() == KEY_ENTER || k->get_scancode() == KEY_RETURN || k->get_scancode() == KEY_TAB) {
+
+ _confirm_completion();
+ accept_event();
+ return;
}
- if (k.unicode > 32) {
+ if (k->get_scancode() == KEY_BACKSPACE) {
_reset_caret_blink_timer();
- const CharType chr[2] = { (CharType)k.unicode, 0 };
- if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
- _consume_pair_symbol(chr[0]);
- } else {
+ backspace_at_cursor();
+ _update_completion_candidates();
+ accept_event();
+ return;
+ }
- // remove the old character if in insert mode
- if (insert_mode) {
- begin_complex_operation();
+ if (k->get_scancode() == KEY_SHIFT) {
+ accept_event();
+ return;
+ }
+ }
- // make sure we don't try and remove empty space
- if (cursor.column < get_line(cursor.line).length()) {
- _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
- }
- }
+ if (k->get_unicode() > 32) {
- _insert_text_at_cursor(chr);
+ _reset_caret_blink_timer();
- if (insert_mode) {
- end_complex_operation();
+ const CharType chr[2] = { (CharType)k->get_unicode(), 0 };
+ if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
+ _consume_pair_symbol(chr[0]);
+ } else {
+
+ // remove the old character if in insert mode
+ if (insert_mode) {
+ begin_complex_operation();
+
+ // make sure we don't try and remove empty space
+ if (cursor.column < get_line(cursor.line).length()) {
+ _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
}
- _update_completion_candidates();
- accept_event();
- return;
+ _insert_text_at_cursor(chr);
+
+ if (insert_mode) {
+ end_complex_operation();
+ }
}
- }
+ _update_completion_candidates();
+ accept_event();
- _cancel_completion();
+ return;
+ }
}
- /* TEST CONTROL FIRST!! */
+ _cancel_completion();
+ }
- // some remaps for duplicate functions..
- if (k.mod.command && !k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode == KEY_INSERT) {
+ /* TEST CONTROL FIRST!! */
- k.scancode = KEY_C;
- }
- if (!k.mod.command && k.mod.shift && !k.mod.alt && !k.mod.meta && k.scancode == KEY_INSERT) {
+ // some remaps for duplicate functions..
+ if (k->get_command() && !k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) {
- k.scancode = KEY_V;
- k.mod.command = true;
- k.mod.shift = false;
- }
+ k->set_scancode(KEY_C);
+ }
+ if (!k->get_command() && k->get_shift() && !k->get_alt() && !k->get_metakey() && k->get_scancode() == KEY_INSERT) {
- if (!k.mod.command) {
- _reset_caret_blink_timer();
- }
+ k->set_scancode(KEY_V);
+ k->set_command(true);
+ k->set_shift(false);
+ }
- // save here for insert mode, just in case it is cleared in the following section
- bool had_selection = selection.active;
+ if (!k->get_command()) {
+ _reset_caret_blink_timer();
+ }
- // stuff to do when selection is active..
- if (selection.active) {
+ // save here for insert mode, just in case it is cleared in the following section
+ bool had_selection = selection.active;
- if (readonly)
- break;
+ // stuff to do when selection is active..
+ if (selection.active) {
- bool clear = false;
- bool unselect = false;
- bool dobreak = false;
+ if (readonly)
+ return;
- switch (k.scancode) {
+ bool clear = false;
+ bool unselect = false;
+ bool dobreak = false;
- case KEY_TAB: {
- if (k.mod.shift) {
- indent_selection_left();
- } else {
- indent_selection_right();
- }
- dobreak = true;
- accept_event();
- } break;
- case KEY_X:
- case KEY_C:
- //special keys often used with control, wait...
- clear = (!k.mod.command || k.mod.shift || k.mod.alt);
- break;
- case KEY_DELETE:
- if (!k.mod.shift) {
- accept_event();
- clear = true;
- dobreak = true;
- } else if (k.mod.command || k.mod.alt) {
- dobreak = true;
- }
- break;
- case KEY_BACKSPACE:
+ switch (k->get_scancode()) {
+
+ case KEY_TAB: {
+ if (k->get_shift()) {
+ indent_selection_left();
+ } else {
+ indent_selection_right();
+ }
+ dobreak = true;
+ accept_event();
+ } break;
+ case KEY_X:
+ case KEY_C:
+ //special keys often used with control, wait...
+ clear = (!k->get_command() || k->get_shift() || k->get_alt());
+ break;
+ case KEY_DELETE:
+ if (!k->get_shift()) {
accept_event();
clear = true;
dobreak = true;
+ } else if (k->get_command() || k->get_alt()) {
+ dobreak = true;
+ }
+ break;
+ case KEY_BACKSPACE:
+ accept_event();
+ clear = true;
+ dobreak = true;
+ break;
+ case KEY_LEFT:
+ case KEY_RIGHT:
+ case KEY_UP:
+ case KEY_DOWN:
+ case KEY_PAGEUP:
+ case KEY_PAGEDOWN:
+ case KEY_HOME:
+ case KEY_END:
+ // ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys)
+ if (k->get_command() || k->get_shift() || k->get_alt())
break;
- case KEY_LEFT:
- case KEY_RIGHT:
- case KEY_UP:
- case KEY_DOWN:
- case KEY_PAGEUP:
- case KEY_PAGEDOWN:
- case KEY_HOME:
- case KEY_END:
- // ignore arrows if any modifiers are held (shift = selecting, others may be used for editor hotkeys)
- if (k.mod.command || k.mod.shift || k.mod.alt)
- break;
- unselect = true;
- break;
+ unselect = true;
+ break;
- default:
- if (k.unicode >= 32 && !k.mod.command && !k.mod.alt && !k.mod.meta)
- clear = true;
- if (auto_brace_completion_enabled && _is_pair_left_symbol(k.unicode))
- clear = false;
- }
+ default:
+ if (k->get_unicode() >= 32 && !k->get_command() && !k->get_alt() && !k->get_metakey())
+ clear = true;
+ if (auto_brace_completion_enabled && _is_pair_left_symbol(k->get_unicode()))
+ clear = false;
+ }
- if (unselect) {
- selection.active = false;
- selection.selecting_mode = Selection::MODE_NONE;
- update();
- }
- if (clear) {
+ if (unselect) {
+ selection.active = false;
+ selection.selecting_mode = Selection::MODE_NONE;
+ update();
+ }
+ if (clear) {
- if (!dobreak) {
- begin_complex_operation();
- }
- selection.active = false;
- update();
- _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
- cursor_set_line(selection.from_line);
- cursor_set_column(selection.from_column);
- update();
+ if (!dobreak) {
+ begin_complex_operation();
}
- if (dobreak)
- break;
+ selection.active = false;
+ update();
+ _remove_text(selection.from_line, selection.from_column, selection.to_line, selection.to_column);
+ cursor_set_line(selection.from_line);
+ cursor_set_column(selection.from_column);
+ update();
}
+ if (dobreak)
+ return;
+ }
- selection.selecting_text = false;
+ selection.selecting_text = false;
- bool scancode_handled = true;
+ bool scancode_handled = true;
- // special scancode test...
+ // special scancode test...
- switch (k.scancode) {
+ switch (k->get_scancode()) {
- case KEY_ENTER:
- case KEY_RETURN: {
+ case KEY_ENTER:
+ case KEY_RETURN: {
- if (readonly)
- break;
+ if (readonly)
+ break;
- String ins = "\n";
+ String ins = "\n";
+
+ //keep indentation
+ int space_count = 0;
+ for (int i = 0; i < text[cursor.line].length(); i++) {
+ if (text[cursor.line][i] == '\t') {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
+ }
+ space_count = 0;
+ } else if (text[cursor.line][i] == ' ') {
+ space_count++;
- //keep indentation
- int space_count = 0;
- for (int i = 0; i < text[cursor.line].length(); i++) {
- if (text[cursor.line][i] == '\t') {
+ if (space_count == indent_size) {
if (indent_using_spaces) {
ins += space_indent;
} else {
ins += "\t";
}
space_count = 0;
- } else if (text[cursor.line][i] == ' ') {
- space_count++;
-
- if (space_count == indent_size) {
- if (indent_using_spaces) {
- ins += space_indent;
- } else {
- ins += "\t";
- }
- space_count = 0;
- }
- } else {
- break;
}
+ } else {
+ break;
}
- if (auto_indent) {
- // indent once again if previous line will end with ':'
- // (i.e. colon precedes current cursor position)
- if (cursor.column > 0 && text[cursor.line][cursor.column - 1] == ':') {
- if (indent_using_spaces) {
- ins += space_indent;
- } else {
- ins += "\t";
- }
+ }
+ if (auto_indent) {
+ // indent once again if previous line will end with ':'
+ // (i.e. colon precedes current cursor position)
+ if (cursor.column > 0 && text[cursor.line][cursor.column - 1] == ':') {
+ if (indent_using_spaces) {
+ ins += space_indent;
+ } else {
+ ins += "\t";
}
}
+ }
- bool first_line = false;
- if (k.mod.command) {
- if (k.mod.shift) {
- if (cursor.line > 0) {
- cursor_set_line(cursor.line - 1);
- cursor_set_column(text[cursor.line].length());
- } else {
- cursor_set_column(0);
- first_line = true;
- }
- } else {
+ bool first_line = false;
+ if (k->get_command()) {
+ if (k->get_shift()) {
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
cursor_set_column(text[cursor.line].length());
+ } else {
+ cursor_set_column(0);
+ first_line = true;
}
+ } else {
+ cursor_set_column(text[cursor.line].length());
}
+ }
- _insert_text_at_cursor(ins);
- _push_current_op();
+ _insert_text_at_cursor(ins);
+ _push_current_op();
- if (first_line) {
- cursor_set_line(0);
- }
+ if (first_line) {
+ cursor_set_line(0);
+ }
- } break;
- case KEY_ESCAPE: {
- if (completion_hint != "") {
- completion_hint = "";
- update();
- } else {
- scancode_handled = false;
- }
- } break;
- case KEY_TAB: {
- if (k.mod.command) break; // avoid tab when command
+ } break;
+ case KEY_ESCAPE: {
+ if (completion_hint != "") {
+ completion_hint = "";
+ update();
+ } else {
+ scancode_handled = false;
+ }
+ } break;
+ case KEY_TAB: {
+ if (k->get_command()) break; // avoid tab when command
- if (readonly)
- break;
+ if (readonly)
+ break;
- if (selection.active) {
+ if (selection.active) {
- } else {
- if (k.mod.shift) {
-
- //simple unindent
- int cc = cursor.column;
- if (cc > 0 && cc <= text[cursor.line].length()) {
- if (text[cursor.line][cursor.column - 1] == '\t') {
- backspace_at_cursor();
- } else {
- if (cursor.column - indent_size >= 0) {
-
- bool unindent = true;
- for (int i = 1; i <= indent_size; i++) {
- if (text[cursor.line][cursor.column - i] != ' ') {
- unindent = false;
- break;
- }
- }
+ } else {
+ if (k->get_shift()) {
+
+ //simple unindent
+ int cc = cursor.column;
+ if (cc > 0 && cc <= text[cursor.line].length()) {
+ if (text[cursor.line][cursor.column - 1] == '\t') {
+ backspace_at_cursor();
+ } else {
+ if (cursor.column - indent_size >= 0) {
- if (unindent) {
- _remove_text(cursor.line, cursor.column - indent_size, cursor.line, cursor.column);
- cursor_set_column(cursor.column - indent_size);
+ bool unindent = true;
+ for (int i = 1; i <= indent_size; i++) {
+ if (text[cursor.line][cursor.column - i] != ' ') {
+ unindent = false;
+ break;
}
}
+
+ if (unindent) {
+ _remove_text(cursor.line, cursor.column - indent_size, cursor.line, cursor.column);
+ cursor_set_column(cursor.column - indent_size);
+ }
}
}
+ }
+ } else {
+ //simple indent
+ if (indent_using_spaces) {
+ _insert_text_at_cursor(space_indent);
} else {
- //simple indent
- if (indent_using_spaces) {
- _insert_text_at_cursor(space_indent);
- } else {
- _insert_text_at_cursor("\t");
- }
+ _insert_text_at_cursor("\t");
}
}
+ }
- } break;
- case KEY_BACKSPACE: {
- if (readonly)
- break;
+ } break;
+ case KEY_BACKSPACE: {
+ if (readonly)
+ break;
#ifdef APPLE_STYLE_KEYS
- if (k.mod.alt) {
+ if (k->get_alt()) {
#else
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- int line = cursor.line;
- int column = cursor.column;
-
- bool prev_char = false;
- bool only_whitespace = true;
-
- while (only_whitespace && line > 0) {
-
- while (column > 0) {
- CharType c = text[line][column - 1];
+ int line = cursor.line;
+ int column = cursor.column;
- if (c != '\t' && c != ' ') {
- only_whitespace = false;
- break;
- }
+ bool prev_char = false;
+ bool only_whitespace = true;
- column--;
- }
-
- if (only_whitespace) {
- line--;
- column = text[line].length();
- }
- }
+ while (only_whitespace && line > 0) {
while (column > 0) {
- bool ischar = _is_text_char(text[line][column - 1]);
+ CharType c = text[line][column - 1];
- if (prev_char && !ischar)
+ if (c != '\t' && c != ' ') {
+ only_whitespace = false;
break;
+ }
- prev_char = ischar;
column--;
}
- _remove_text(line, column, cursor.line, cursor.column);
+ if (only_whitespace) {
+ line--;
+ column = text[line].length();
+ }
+ }
- cursor_set_line(line);
- cursor_set_column(column);
+ while (column > 0) {
+ bool ischar = _is_text_char(text[line][column - 1]);
- } else {
- backspace_at_cursor();
- }
+ if (prev_char && !ischar)
+ break;
- } break;
- case KEY_KP_4: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
+ prev_char = ischar;
+ column--;
}
- // numlock disabled. fallthrough to key_left
+
+ _remove_text(line, column, cursor.line, cursor.column);
+
+ cursor_set_line(line);
+ cursor_set_column(column);
+
+ } else {
+ backspace_at_cursor();
+ }
+
+ } break;
+ case KEY_KP_4: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_LEFT: {
+ // numlock disabled. fallthrough to key_left
+ }
+ case KEY_LEFT: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
#ifdef APPLE_STYLE_KEYS
- else
+ else
#else
- else if (!k.mod.alt)
+ else if (!k->get_alt())
#endif
- deselect();
+ deselect();
#ifdef APPLE_STYLE_KEYS
- if (k.mod.command) {
- cursor_set_column(0);
- } else if (k.mod.alt) {
+ if (k->get_command()) {
+ cursor_set_column(0);
+ } else if (k->get_alt()) {
#else
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- bool prev_char = false;
- int cc = cursor.column;
- while (cc > 0) {
+ bool prev_char = false;
+ int cc = cursor.column;
+ while (cc > 0) {
- bool ischar = _is_text_char(text[cursor.line][cc - 1]);
+ bool ischar = _is_text_char(text[cursor.line][cc - 1]);
- if (prev_char && !ischar)
- break;
+ if (prev_char && !ischar)
+ break;
- prev_char = ischar;
- cc--;
- }
+ prev_char = ischar;
+ cc--;
+ }
- cursor_set_column(cc);
+ cursor_set_column(cc);
- } else if (cursor.column == 0) {
+ } else if (cursor.column == 0) {
- if (cursor.line > 0) {
- cursor_set_line(cursor.line - 1);
- cursor_set_column(text[cursor.line].length());
- }
- } else {
- cursor_set_column(cursor_get_column() - 1);
+ if (cursor.line > 0) {
+ cursor_set_line(cursor.line - 1);
+ cursor_set_column(text[cursor.line].length());
}
+ } else {
+ cursor_set_column(cursor_get_column() - 1);
+ }
- if (k.mod.shift)
- _post_shift_selection();
+ if (k->get_shift())
+ _post_shift_selection();
- } break;
- case KEY_KP_6: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_right
+ } break;
+ case KEY_KP_6: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_RIGHT: {
+ // numlock disabled. fallthrough to key_right
+ }
+ case KEY_RIGHT: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
#ifdef APPLE_STYLE_KEYS
- else
+ else
#else
- else if (!k.mod.alt)
+ else if (!k->get_alt())
#endif
- deselect();
+ deselect();
#ifdef APPLE_STYLE_KEYS
- if (k.mod.command) {
- cursor_set_column(text[cursor.line].length());
- } else if (k.mod.alt) {
+ if (k->get_command()) {
+ cursor_set_column(text[cursor.line].length());
+ } else if (k->get_alt()) {
#else
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- bool prev_char = false;
- int cc = cursor.column;
- while (cc < text[cursor.line].length()) {
+ bool prev_char = false;
+ int cc = cursor.column;
+ while (cc < text[cursor.line].length()) {
- bool ischar = _is_text_char(text[cursor.line][cc]);
+ bool ischar = _is_text_char(text[cursor.line][cc]);
- if (prev_char && !ischar)
- break;
- prev_char = ischar;
- cc++;
- }
+ if (prev_char && !ischar)
+ break;
+ prev_char = ischar;
+ cc++;
+ }
- cursor_set_column(cc);
+ cursor_set_column(cc);
- } else if (cursor.column == text[cursor.line].length()) {
+ } else if (cursor.column == text[cursor.line].length()) {
- if (cursor.line < text.size() - 1) {
- cursor_set_line(cursor.line + 1);
- cursor_set_column(0);
- }
- } else {
- cursor_set_column(cursor_get_column() + 1);
+ if (cursor.line < text.size() - 1) {
+ cursor_set_line(cursor.line + 1);
+ cursor_set_column(0);
}
+ } else {
+ cursor_set_column(cursor_get_column() + 1);
+ }
- if (k.mod.shift)
- _post_shift_selection();
+ if (k->get_shift())
+ _post_shift_selection();
- } break;
- case KEY_KP_8: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_up
+ } break;
+ case KEY_KP_8: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_UP: {
+ // numlock disabled. fallthrough to key_up
+ }
+ case KEY_UP: {
- if (k.mod.shift)
- _pre_shift_selection();
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ if (k->get_shift())
+ _pre_shift_selection();
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
#ifndef APPLE_STYLE_KEYS
- if (k.mod.command) {
- _scroll_lines_up();
- break;
- }
+ if (k->get_command()) {
+ _scroll_lines_up();
+ break;
+ }
#else
- if (k.mod.command && k.mod.alt) {
- _scroll_lines_up();
- break;
- }
+ if (k->get_command() && k->get_alt()) {
+ _scroll_lines_up();
+ break;
+ }
- if (k.mod.command)
- cursor_set_line(0);
- else
+ if (k->get_command())
+ cursor_set_line(0);
+ else
#endif
- cursor_set_line(cursor_get_line() - 1);
+ cursor_set_line(cursor_get_line() - 1);
- if (k.mod.shift)
- _post_shift_selection();
- _cancel_code_hint();
+ if (k->get_shift())
+ _post_shift_selection();
+ _cancel_code_hint();
- } break;
- case KEY_KP_2: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_down
+ } break;
+ case KEY_KP_2: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_DOWN: {
+ // numlock disabled. fallthrough to key_down
+ }
+ case KEY_DOWN: {
- if (k.mod.shift)
- _pre_shift_selection();
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ if (k->get_shift())
+ _pre_shift_selection();
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
#ifndef APPLE_STYLE_KEYS
- if (k.mod.command) {
- _scroll_lines_down();
- break;
- }
+ if (k->get_command()) {
+ _scroll_lines_down();
+ break;
+ }
#else
- if (k.mod.command && k.mod.alt) {
- _scroll_lines_down();
- break;
- }
+ if (k->get_command() && k->get_alt()) {
+ _scroll_lines_down();
+ break;
+ }
- if (k.mod.command)
- cursor_set_line(text.size() - 1);
- else
+ if (k->get_command())
+ cursor_set_line(text.size() - 1);
+ else
#endif
- cursor_set_line(cursor_get_line() + 1);
+ cursor_set_line(cursor_get_line() + 1);
- if (k.mod.shift)
- _post_shift_selection();
- _cancel_code_hint();
+ if (k->get_shift())
+ _post_shift_selection();
+ _cancel_code_hint();
- } break;
+ } break;
- case KEY_DELETE: {
+ case KEY_DELETE: {
- if (readonly)
- break;
+ if (readonly)
+ break;
- if (k.mod.shift && !k.mod.command && !k.mod.alt) {
- cut();
- break;
- }
+ if (k->get_shift() && !k->get_command() && !k->get_alt()) {
+ cut();
+ break;
+ }
- int curline_len = text[cursor.line].length();
+ int curline_len = text[cursor.line].length();
- if (cursor.line == text.size() - 1 && cursor.column == curline_len)
- break; //nothing to do
+ if (cursor.line == text.size() - 1 && cursor.column == curline_len)
+ break; //nothing to do
- int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
- int next_column;
+ int next_line = cursor.column < curline_len ? cursor.line : cursor.line + 1;
+ int next_column;
#ifdef APPLE_STYLE_KEYS
- if (k.mod.alt) {
+ if (k->get_alt()) {
#else
- if (k.mod.alt) {
- scancode_handled = false;
- break;
- } else if (k.mod.command) {
+ if (k->get_alt()) {
+ scancode_handled = false;
+ break;
+ } else if (k->get_command()) {
#endif
- int last_line = text.size() - 1;
-
- int line = cursor.line;
- int column = cursor.column;
+ int last_line = text.size() - 1;
- bool prev_char = false;
- bool only_whitespace = true;
+ int line = cursor.line;
+ int column = cursor.column;
- while (only_whitespace && line < last_line) {
+ bool prev_char = false;
+ bool only_whitespace = true;
- while (column < text[line].length()) {
- CharType c = text[line][column];
+ while (only_whitespace && line < last_line) {
- if (c != '\t' && c != ' ') {
- only_whitespace = false;
- break;
- }
+ while (column < text[line].length()) {
+ CharType c = text[line][column];
- column++;
+ if (c != '\t' && c != ' ') {
+ only_whitespace = false;
+ break;
}
- if (only_whitespace) {
- line++;
- column = 0;
- }
+ column++;
}
- while (column < text[line].length()) {
+ if (only_whitespace) {
+ line++;
+ column = 0;
+ }
+ }
- bool ischar = _is_text_char(text[line][column]);
+ while (column < text[line].length()) {
- if (prev_char && !ischar)
- break;
- prev_char = ischar;
- column++;
- }
+ bool ischar = _is_text_char(text[line][column]);
- next_line = line;
- next_column = column;
- } else {
- next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
+ if (prev_char && !ischar)
+ break;
+ prev_char = ischar;
+ column++;
}
- _remove_text(cursor.line, cursor.column, next_line, next_column);
- update();
+ next_line = line;
+ next_column = column;
+ } else {
+ next_column = cursor.column < curline_len ? (cursor.column + 1) : 0;
+ }
- } break;
- case KEY_KP_7: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_home
+ _remove_text(cursor.line, cursor.column, next_line, next_column);
+ update();
+
+ } break;
+ case KEY_KP_7: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
+ // numlock disabled. fallthrough to key_home
+ }
#ifdef APPLE_STYLE_KEYS
- case KEY_HOME: {
+ case KEY_HOME: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
- cursor_set_line(0);
+ cursor_set_line(0);
- if (k.mod.shift)
- _post_shift_selection();
- else if (k.mod.command || k.mod.control)
- deselect();
+ if (k->get_shift())
+ _post_shift_selection();
+ else if (k->get_command() || k->get_control())
+ deselect();
- } break;
+ } break;
#else
- case KEY_HOME: {
-
- if (k.mod.shift)
- _pre_shift_selection();
+ case KEY_HOME: {
- if (k.mod.command) {
- cursor_set_line(0);
- cursor_set_column(0);
- } else {
- // compute whitespace symbols seq length
- int current_line_whitespace_len = 0;
- while (current_line_whitespace_len < text[cursor.line].length()) {
- CharType c = text[cursor.line][current_line_whitespace_len];
- if (c != '\t' && c != ' ')
- break;
- current_line_whitespace_len++;
- }
+ if (k->get_shift())
+ _pre_shift_selection();
- if (cursor_get_column() == current_line_whitespace_len)
- cursor_set_column(0);
- else
- cursor_set_column(current_line_whitespace_len);
+ if (k->get_command()) {
+ cursor_set_line(0);
+ cursor_set_column(0);
+ } else {
+ // compute whitespace symbols seq length
+ int current_line_whitespace_len = 0;
+ while (current_line_whitespace_len < text[cursor.line].length()) {
+ CharType c = text[cursor.line][current_line_whitespace_len];
+ if (c != '\t' && c != ' ')
+ break;
+ current_line_whitespace_len++;
}
- if (k.mod.shift)
- _post_shift_selection();
- else if (k.mod.command || k.mod.control)
- deselect();
- _cancel_completion();
- completion_hint = "";
+ if (cursor_get_column() == current_line_whitespace_len)
+ cursor_set_column(0);
+ else
+ cursor_set_column(current_line_whitespace_len);
+ }
- } break;
+ if (k->get_shift())
+ _post_shift_selection();
+ else if (k->get_command() || k->get_control())
+ deselect();
+ _cancel_completion();
+ completion_hint = "";
+
+ } break;
#endif
- case KEY_KP_1: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_end
+ case KEY_KP_1: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
+ // numlock disabled. fallthrough to key_end
+ }
#ifdef APPLE_STYLE_KEYS
- case KEY_END: {
+ case KEY_END: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
- cursor_set_line(text.size() - 1);
+ cursor_set_line(text.size() - 1);
- if (k.mod.shift)
- _post_shift_selection();
- else if (k.mod.command || k.mod.control)
- deselect();
+ if (k->get_shift())
+ _post_shift_selection();
+ else if (k->get_command() || k->get_control())
+ deselect();
- } break;
+ } break;
#else
- case KEY_END: {
+ case KEY_END: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
- if (k.mod.command)
- cursor_set_line(text.size() - 1);
- cursor_set_column(text[cursor.line].length());
+ if (k->get_command())
+ cursor_set_line(text.size() - 1);
+ cursor_set_column(text[cursor.line].length());
- if (k.mod.shift)
- _post_shift_selection();
- else if (k.mod.command || k.mod.control)
- deselect();
+ if (k->get_shift())
+ _post_shift_selection();
+ else if (k->get_command() || k->get_control())
+ deselect();
- _cancel_completion();
- completion_hint = "";
+ _cancel_completion();
+ completion_hint = "";
- } break;
+ } break;
#endif
- case KEY_KP_9: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_pageup
+ case KEY_KP_9: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_PAGEUP: {
+ // numlock disabled. fallthrough to key_pageup
+ }
+ case KEY_PAGEUP: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
- cursor_set_line(cursor_get_line() - get_visible_rows());
+ cursor_set_line(cursor_get_line() - get_visible_rows());
- if (k.mod.shift)
- _post_shift_selection();
+ if (k->get_shift())
+ _post_shift_selection();
- _cancel_completion();
- completion_hint = "";
+ _cancel_completion();
+ completion_hint = "";
- } break;
- case KEY_KP_3: {
- if (k.unicode != 0) {
- scancode_handled = false;
- break;
- }
- // numlock disabled. fallthrough to key_pageup
+ } break;
+ case KEY_KP_3: {
+ if (k->get_unicode() != 0) {
+ scancode_handled = false;
+ break;
}
- case KEY_PAGEDOWN: {
+ // numlock disabled. fallthrough to key_pageup
+ }
+ case KEY_PAGEDOWN: {
- if (k.mod.shift)
- _pre_shift_selection();
+ if (k->get_shift())
+ _pre_shift_selection();
- cursor_set_line(cursor_get_line() + get_visible_rows());
+ cursor_set_line(cursor_get_line() + get_visible_rows());
- if (k.mod.shift)
- _post_shift_selection();
+ if (k->get_shift())
+ _post_shift_selection();
- _cancel_completion();
- completion_hint = "";
+ _cancel_completion();
+ completion_hint = "";
- } break;
- case KEY_A: {
+ } break;
+ case KEY_A: {
- if (!k.mod.command || k.mod.shift || k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ if (!k->get_command() || k->get_shift() || k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
- select_all();
+ select_all();
- } break;
- case KEY_X: {
- if (readonly) {
- break;
- }
- if (!k.mod.command || k.mod.shift || k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ } break;
+ case KEY_X: {
+ if (readonly) {
+ break;
+ }
+ if (!k->get_command() || k->get_shift() || k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
- cut();
+ cut();
- } break;
- case KEY_C: {
+ } break;
+ case KEY_C: {
- if (!k.mod.command || k.mod.shift || k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ if (!k->get_command() || k->get_shift() || k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
- copy();
+ copy();
- } break;
- case KEY_Z: {
+ } break;
+ case KEY_Z: {
- if (!k.mod.command) {
- scancode_handled = false;
- break;
- }
+ if (!k->get_command()) {
+ scancode_handled = false;
+ break;
+ }
- if (k.mod.shift)
- redo();
- else
- undo();
- } break;
- case KEY_V: {
- if (readonly) {
- break;
- }
- if (!k.mod.command || k.mod.shift || k.mod.alt) {
- scancode_handled = false;
- break;
- }
+ if (k->get_shift())
+ redo();
+ else
+ undo();
+ } break;
+ case KEY_V: {
+ if (readonly) {
+ break;
+ }
+ if (!k->get_command() || k->get_shift() || k->get_alt()) {
+ scancode_handled = false;
+ break;
+ }
- paste();
+ paste();
- } break;
- case KEY_SPACE: {
+ } break;
+ case KEY_SPACE: {
#ifdef OSX_ENABLED
- if (completion_enabled && k.mod.meta) { //cmd-space is spotlight shortcut in OSX
+ if (completion_enabled && k->get_metakey()) { //cmd-space is spotlight shortcut in OSX
#else
- if (completion_enabled && k.mod.command) {
+ if (completion_enabled && k->get_command()) {
#endif
- query_code_comple();
- scancode_handled = true;
- } else {
- scancode_handled = false;
- }
+ query_code_comple();
+ scancode_handled = true;
+ } else {
+ scancode_handled = false;
+ }
- } break;
+ } break;
- case KEY_U: {
- if (!k.mod.command || k.mod.shift) {
- scancode_handled = false;
- break;
- } else {
- if (selection.active) {
- int ini = selection.from_line;
- int end = selection.to_line;
- for (int i = ini; i <= end; i++) {
- if (text[i][0] == '#')
- _remove_text(i, 0, i, 1);
- }
- } else {
- if (text[cursor.line][0] == '#')
- _remove_text(cursor.line, 0, cursor.line, 1);
+ case KEY_U: {
+ if (!k->get_command() || k->get_shift()) {
+ scancode_handled = false;
+ break;
+ } else {
+ if (selection.active) {
+ int ini = selection.from_line;
+ int end = selection.to_line;
+ for (int i = ini; i <= end; i++) {
+ if (text[i][0] == '#')
+ _remove_text(i, 0, i, 1);
}
- update();
+ } else {
+ if (text[cursor.line][0] == '#')
+ _remove_text(cursor.line, 0, cursor.line, 1);
}
- } break;
+ update();
+ }
+ } break;
- default: {
+ default: {
- scancode_handled = false;
- } break;
- }
+ scancode_handled = false;
+ } break;
+ }
- if (scancode_handled)
- accept_event();
- /*
- if (!scancode_handled && !k.mod.command && !k.mod.alt) {
+ if (scancode_handled)
+ accept_event();
+ /*
+ if (!scancode_handled && !k->get_command() && !k->get_alt()) {
- if (k.unicode>=32) {
+ if (k->get_unicode()>=32) {
- if (readonly)
- break;
+ if (readonly)
+ break;
- accept_event();
- } else {
+ accept_event();
+ } else {
- break;
- }
- }
+ break;
+ }
+ }
*/
- if (k.scancode == KEY_INSERT) {
- set_insert_mode(!insert_mode);
- accept_event();
- return;
- }
-
- if (!scancode_handled && !k.mod.command) { //for german kbds
+ if (k->get_scancode() == KEY_INSERT) {
+ set_insert_mode(!insert_mode);
+ accept_event();
+ return;
+ }
- if (k.unicode >= 32) {
+ if (!scancode_handled && !k->get_command()) { //for german kbds
- if (readonly)
- break;
+ if (k->get_unicode() >= 32) {
- // remove the old character if in insert mode and no selection
- if (insert_mode && !had_selection) {
- begin_complex_operation();
-
- // make sure we don't try and remove empty space
- if (cursor.column < get_line(cursor.line).length()) {
- _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
- }
- }
+ if (readonly)
+ return;
- const CharType chr[2] = { (CharType)k.unicode, 0 };
+ // remove the old character if in insert mode and no selection
+ if (insert_mode && !had_selection) {
+ begin_complex_operation();
- if (completion_hint != "" && k.unicode == ')') {
- completion_hint = "";
- }
- if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
- _consume_pair_symbol(chr[0]);
- } else {
- _insert_text_at_cursor(chr);
+ // make sure we don't try and remove empty space
+ if (cursor.column < get_line(cursor.line).length()) {
+ _remove_text(cursor.line, cursor.column, cursor.line, cursor.column + 1);
}
+ }
- if (insert_mode && !had_selection) {
- end_complex_operation();
- }
+ const CharType chr[2] = { (CharType)k->get_unicode(), 0 };
- if (selection.active != had_selection) {
- end_complex_operation();
- }
- accept_event();
+ if (completion_hint != "" && k->get_unicode() == ')') {
+ completion_hint = "";
+ }
+ if (auto_brace_completion_enabled && _is_pair_symbol(chr[0])) {
+ _consume_pair_symbol(chr[0]);
} else {
+ _insert_text_at_cursor(chr);
+ }
- break;
+ if (insert_mode && !had_selection) {
+ end_complex_operation();
+ }
+
+ if (selection.active != had_selection) {
+ end_complex_operation();
}
+ accept_event();
+ } else {
}
+ }
- return;
- } break;
+ return;
}
}
diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h
index 905ea46bd7..f8f60d2b03 100644
--- a/scene/gui/text_edit.h
+++ b/scene/gui/text_edit.h
@@ -337,7 +337,7 @@ protected:
void _insert_text(int p_line, int p_column, const String &p_text, int *r_end_line = NULL, int *r_end_char = NULL);
void _remove_text(int p_from_line, int p_from_column, int p_to_line, int p_to_column);
void _insert_text_at_cursor(const String &p_text);
- void _gui_input(const InputEvent &p_input);
+ void _gui_input(const Ref<InputEvent> &p_input);
void _notification(int p_what);
void _consume_pair_symbol(CharType ch);
diff --git a/scene/gui/tool_button.cpp b/scene/gui/tool_button.cpp
index 7e8a426d15..5fc4b6ecf8 100644
--- a/scene/gui/tool_button.cpp
+++ b/scene/gui/tool_button.cpp
@@ -29,10 +29,6 @@
/*************************************************************************/
#include "tool_button.h"
-void ToolButton::_notification(int p_what) {
- // set_self_modulate(get_color("pressed"));
-}
-
ToolButton::ToolButton() {
set_flat(true);
}
diff --git a/scene/gui/tool_button.h b/scene/gui/tool_button.h
index 58948f798f..d243b5559f 100644
--- a/scene/gui/tool_button.h
+++ b/scene/gui/tool_button.h
@@ -37,9 +37,6 @@ class ToolButton : public Button {
public:
ToolButton();
-
-protected:
- void _notification(int p_what);
};
#endif // TOOL_BUTTON_H
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 6f2d725353..d864d9fce7 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -610,6 +610,18 @@ Color TreeItem::get_custom_bg_color(int p_column) const {
return cells[p_column].bg_color;
}
+void TreeItem::set_custom_as_button(int p_column, bool p_button) {
+
+ ERR_FAIL_INDEX(p_column, cells.size());
+ cells[p_column].custom_button = p_button;
+}
+
+bool TreeItem::is_custom_set_as_button(int p_column) const {
+
+ ERR_FAIL_INDEX_V(p_column, cells.size(), false);
+ return cells[p_column].custom_button;
+}
+
void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_cell_mode", "column", "mode"), &TreeItem::set_cell_mode);
@@ -670,6 +682,9 @@ void TreeItem::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_custom_bg_color", "column"), &TreeItem::clear_custom_bg_color);
ClassDB::bind_method(D_METHOD("get_custom_bg_color", "column"), &TreeItem::get_custom_bg_color);
+ ClassDB::bind_method(D_METHOD("set_custom_as_button", "column", "enable"), &TreeItem::set_custom_as_button);
+ ClassDB::bind_method(D_METHOD("is_custom_set_as_button", "column"), &TreeItem::is_custom_set_as_button);
+
ClassDB::bind_method(D_METHOD("add_button", "column", "button:Texture", "button_idx", "disabled", "tooltip"), &TreeItem::add_button, DEFVAL(-1), DEFVAL(false), DEFVAL(""));
ClassDB::bind_method(D_METHOD("get_button_count", "column"), &TreeItem::get_button_count);
ClassDB::bind_method(D_METHOD("get_button:Texture", "column", "button_idx"), &TreeItem::get_button);
@@ -732,6 +747,10 @@ TreeItem::~TreeItem() {
tree->pressing_for_editor = false;
}
+ if (tree && tree->cache.hover_item == this) {
+ tree->cache.hover_item = NULL;
+ }
+
if (tree && tree->selected_item == this)
tree->selected_item = NULL;
@@ -772,6 +791,11 @@ void Tree::update_cache() {
cache.select_arrow = get_icon("select_arrow");
cache.updown = get_icon("updown");
+ cache.custom_button = get_stylebox("custom_button");
+ cache.custom_button_hover = get_stylebox("custom_button_hover");
+ cache.custom_button_pressed = get_stylebox("custom_button_pressed");
+ cache.custom_button_font_highlight = get_color("custom_button_font_highlight");
+
cache.font_color = get_color("font_color");
cache.font_color_selected = get_color("font_color_selected");
cache.guide_color = get_color("guide_color");
@@ -833,6 +857,9 @@ int Tree::compute_item_height(TreeItem *p_item) const {
if (s.height > height)
height = s.height;
}
+ if (p_item->cells[i].mode == TreeItem::CELL_MODE_CUSTOM && p_item->cells[i].custom_button) {
+ height += cache.custom_button->get_minimum_size().height;
+ }
} break;
default: {}
@@ -877,8 +904,8 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co
bmsize.width = p_cell.icon_max_w;
}
- p_cell.draw_icon(ci, rect.pos + Size2i(0, Math::floor((real_t)(rect.size.y - bmsize.y) / 2)), bmsize);
- rect.pos.x += bmsize.x + cache.hseparation;
+ p_cell.draw_icon(ci, rect.position + Size2i(0, Math::floor((real_t)(rect.size.y - bmsize.y) / 2)), bmsize);
+ rect.position.x += bmsize.x + cache.hseparation;
rect.size.x -= bmsize.x + cache.hseparation;
}
@@ -893,8 +920,8 @@ void Tree::draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, co
if (p_cell.suffix != String())
text += " " + p_cell.suffix;
- rect.pos.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent();
- font->draw(ci, rect.pos, text, p_color, rect.size.x);
+ rect.position.y += Math::floor((rect.size.y - font->get_height()) / 2.0) + font->get_ascent();
+ font->draw(ci, rect.position, text, p_color, rect.size.x);
}
#if 0
@@ -1007,16 +1034,16 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Rect2i item_rect = Rect2i(Point2i(ofs, p_pos.y) - cache.offset + p_draw_ofs, Size2i(w, label_h));
Rect2i cell_rect = item_rect;
if (i != 0) {
- cell_rect.pos.x -= cache.hseparation;
+ cell_rect.position.x -= cache.hseparation;
cell_rect.size.x += cache.hseparation;
}
- VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.pos.x, cell_rect.pos.y + cell_rect.size.height), cell_rect.pos + cell_rect.size, cache.guide_color, 1);
+ VisualServer::get_singleton()->canvas_item_add_line(ci, Point2i(cell_rect.position.x, cell_rect.position.y + cell_rect.size.height), cell_rect.position + cell_rect.size, cache.guide_color, 1);
if (i == 0) {
if (p_item->cells[0].selected && select_mode == SELECT_ROW) {
- Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(MARGIN_LEFT), item_rect.pos.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y));
+ Rect2i row_rect = Rect2i(Point2i(cache.bg->get_margin(MARGIN_LEFT), item_rect.position.y), Size2i(get_size().width - cache.bg->get_minimum_size().width, item_rect.size.y));
//Rect2 r = Rect2i(row_rect.pos,row_rect.size);
//r.grow(cache.selected->get_margin(MARGIN_LEFT));
if (has_focus())
@@ -1028,34 +1055,34 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (p_item->cells[i].selected && select_mode != SELECT_ROW) {
- Rect2i r(item_rect.pos, item_rect.size);
+ Rect2i r(item_rect.position, item_rect.size);
if (p_item->cells[i].text.size() > 0) {
float icon_width = p_item->cells[i].get_icon_size().width;
- r.pos.x += icon_width;
+ r.position.x += icon_width;
r.size.x -= icon_width;
}
//r.grow(cache.selected->get_margin(MARGIN_LEFT));
if (has_focus()) {
cache.selected_focus->draw(ci, r);
- p_item->set_meta("__focus_rect", Rect2(r.pos, r.size));
+ p_item->set_meta("__focus_rect", Rect2(r.position, r.size));
} else {
cache.selected->draw(ci, r);
}
if (text_editor->is_visible_in_tree()) {
- text_editor->set_position(get_global_position() + r.pos);
+ text_editor->set_position(get_global_position() + r.position);
}
}
if (p_item->cells[i].custom_bg_color) {
Rect2 r = cell_rect;
- r.pos.x -= cache.hseparation;
+ r.position.x -= cache.hseparation;
r.size.x += cache.hseparation;
if (p_item->cells[i].custom_bg_outline) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, r.size.x, 1), p_item->cells[i].bg_color);
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y + r.size.y - 1, r.size.x, 1), p_item->cells[i].bg_color);
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, 1, r.size.y), p_item->cells[i].bg_color);
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x + r.size.x - 1, r.pos.y, 1, r.size.y), p_item->cells[i].bg_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), p_item->cells[i].bg_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y - 1, r.size.x, 1), p_item->cells[i].bg_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), p_item->cells[i].bg_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), p_item->cells[i].bg_color);
} else {
VisualServer::get_singleton()->canvas_item_add_rect(ci, r, p_item->cells[i].bg_color);
}
@@ -1066,22 +1093,22 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Rect2 r = cell_rect;
if (drop_mode_section == -1 || drop_mode_section == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, r.size.x, 1), cache.drop_position_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, r.size.x, 1), cache.drop_position_color);
}
if (drop_mode_section == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y, 1, r.size.y), cache.drop_position_color);
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x + r.size.x - 1, r.pos.y, 1, r.size.y), cache.drop_position_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y, 1, r.size.y), cache.drop_position_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x + r.size.x - 1, r.position.y, 1, r.size.y), cache.drop_position_color);
}
if (drop_mode_section == 1 || drop_mode_section == 0) {
- VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.pos.x, r.pos.y + r.size.y, r.size.x, 1), cache.drop_position_color);
+ VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(r.position.x, r.position.y + r.size.y, r.size.x, 1), cache.drop_position_color);
}
}
Color col = p_item->cells[i].custom_color ? p_item->cells[i].color : get_color(p_item->cells[i].selected ? "font_color_selected" : "font_color");
- Point2i text_pos = item_rect.pos;
+ Point2i text_pos = item_rect.position;
text_pos.y += Math::floor((item_rect.size.y - font->get_height()) / 2) + font_ascent;
switch (p_item->cells[i].mode) {
@@ -1094,7 +1121,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Ref<Texture> checked = cache.checked;
Ref<Texture> unchecked = cache.unchecked;
- Point2i check_ofs = item_rect.pos;
+ Point2i check_ofs = item_rect.position;
check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2);
if (p_item->cells[i].checked) {
@@ -1109,7 +1136,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
text_pos.x += check_w;
item_rect.size.x -= check_w;
- item_rect.pos.x += check_w;
+ item_rect.position.x += check_w;
draw_item_rect(p_item->cells[i], item_rect, col);
@@ -1137,7 +1164,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
font->draw(ci, text_pos, s, col, item_rect.size.x - downarrow->get_width());
//?
- Point2i arrow_pos = item_rect.pos;
+ Point2i arrow_pos = item_rect.position;
arrow_pos.x += item_rect.size.x - downarrow->get_width();
arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0);
@@ -1157,7 +1184,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
if (!p_item->cells[i].editable)
break;
- Point2i updown_pos = item_rect.pos;
+ Point2i updown_pos = item_rect.position;
updown_pos.x += item_rect.size.x - updown->get_width();
updown_pos.y += Math::floor(((item_rect.size.y - updown->get_height())) / 2.0);
@@ -1176,7 +1203,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
}
Point2i icon_ofs = (item_rect.size - icon_size) / 2;
- icon_ofs += item_rect.pos;
+ icon_ofs += item_rect.position;
draw_texture_rect(p_item->cells[i].icon, Rect2(icon_ofs, icon_size));
//p_item->cells[i].icon->draw(ci, icon_ofs);
@@ -1202,12 +1229,28 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2
Ref<Texture> downarrow = cache.select_arrow;
Rect2i ir = item_rect;
- ir.size.width -= downarrow->get_width();
- draw_item_rect(p_item->cells[i], ir, col);
- Point2i arrow_pos = item_rect.pos;
+ Point2i arrow_pos = item_rect.position;
arrow_pos.x += item_rect.size.x - downarrow->get_width();
arrow_pos.y += Math::floor(((item_rect.size.y - downarrow->get_height())) / 2.0);
+ ir.size.width -= downarrow->get_width();
+
+ if (p_item->cells[i].custom_button) {
+ if (cache.hover_item == p_item && cache.hover_cell == i) {
+ if (Input::get_singleton()->is_mouse_button_pressed(BUTTON_LEFT)) {
+ draw_style_box(cache.custom_button_pressed, ir);
+ } else {
+ draw_style_box(cache.custom_button_hover, ir);
+ col = cache.custom_button_font_highlight;
+ }
+ } else {
+ draw_style_box(cache.custom_button, ir);
+ }
+ ir.size -= cache.custom_button->get_minimum_size();
+ ir.position += cache.custom_button->get_offset();
+ }
+
+ draw_item_rect(p_item->cells[i], ir, col);
downarrow->draw(ci, arrow_pos);
@@ -1410,10 +1453,12 @@ void Tree::_range_click_timeout() {
}
click_handled = false;
- InputModifierState mod = InputModifierState(); // should be irrelevant..
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+ ;
blocked++;
- propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mod);
+ propagate_mouse_event(pos + cache.offset, 0, 0, false, root, BUTTON_LEFT, mb);
blocked--;
if (range_click_timer->is_one_shot()) {
@@ -1430,7 +1475,7 @@ void Tree::_range_click_timeout() {
}
}
-int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const InputModifierState &p_mod) {
+int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod) {
int item_h = compute_item_height(p_item) + cache.vseparation;
@@ -1518,10 +1563,11 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
if (p_doubleclick && (!c.editable || c.mode == TreeItem::CELL_MODE_CUSTOM || c.mode == TreeItem::CELL_MODE_ICON /*|| c.mode==TreeItem::CELL_MODE_CHECK*/)) { //it' s confusing for check
emit_signal("item_activated");
+ incr_search.clear();
return -1;
}
- if (select_mode == SELECT_MULTI && p_mod.command && c.selectable) {
+ if (select_mode == SELECT_MULTI && p_mod->get_command() && c.selectable) {
if (!c.selected || p_button == BUTTON_RIGHT) {
@@ -1543,7 +1589,7 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
if (c.selectable) {
- if (select_mode == SELECT_MULTI && p_mod.shift && selected_item && selected_item != p_item) {
+ if (select_mode == SELECT_MULTI && p_mod->get_shift() && selected_item && selected_item != p_item) {
bool inrange = false;
@@ -1694,11 +1740,18 @@ int Tree::propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool
case TreeItem::CELL_MODE_CUSTOM: {
edited_item = p_item;
edited_col = col;
- custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h));
- emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2))));
+ bool on_arrow = x > col_width - cache.select_arrow->get_width();
bring_up_editor = false;
- item_edited(col, p_item);
+
+ if (on_arrow || !p_item->cells[col].custom_button) {
+ custom_popup_rect = Rect2i(get_global_position() + Point2i(col_ofs, _get_title_button_height() + y_ofs + item_h - cache.offset.y), Size2(get_column_width(col), item_h));
+ emit_signal("custom_popup_edited", ((bool)(x >= (col_width - item_h / 2))));
+ }
+
+ if (!p_item->cells[col].custom_button || !on_arrow) {
+ item_edited(col, p_item);
+ }
click_handled = true;
return -1;
} break;
@@ -1838,516 +1891,540 @@ void Tree::popup_select(int p_option) {
item_edited(popup_edited_item_col, popup_edited_item);
}
-void Tree::_gui_input(InputEvent p_event) {
+void Tree::_gui_input(Ref<InputEvent> p_event) {
- switch (p_event.type) {
+ Ref<InputEventKey> k = p_event;
- case InputEvent::KEY: {
+ if (k.is_valid()) {
- if (!p_event.key.pressed)
- break;
- if (p_event.key.mod.alt || p_event.key.mod.command || (p_event.key.mod.shift && p_event.key.unicode == 0) || p_event.key.mod.meta)
- break;
- if (!root)
- return;
+ if (!k->is_pressed())
+ return;
+ if (k->get_alt() || k->get_command() || (k->get_shift() && k->get_unicode() == 0) || k->get_metakey())
+ return;
+ if (!root)
+ return;
- if (hide_root && !root->get_next_visible())
- return;
+ if (hide_root && !root->get_next_visible())
+ return;
- switch (p_event.key.scancode) {
+ switch (k->get_scancode()) {
#define EXIT_BREAK \
{ \
if (!cursor_can_exit_tree) accept_event(); \
break; \
}
- case KEY_RIGHT: {
-
- //TreeItem *next = NULL;
- if (!selected_item)
- break;
- if (select_mode == SELECT_ROW)
- EXIT_BREAK;
- if (selected_col >= (columns.size() - 1))
- EXIT_BREAK;
- if (select_mode == SELECT_MULTI) {
- selected_col++;
- emit_signal("cell_selected");
- } else {
-
- selected_item->select(selected_col + 1);
- }
+ case KEY_RIGHT: {
+
+ //TreeItem *next = NULL;
+ if (!selected_item)
+ break;
+ if (select_mode == SELECT_ROW)
+ EXIT_BREAK;
+ if (selected_col >= (columns.size() - 1))
+ EXIT_BREAK;
+ if (select_mode == SELECT_MULTI) {
+ selected_col++;
+ emit_signal("cell_selected");
+ } else {
- update();
- ensure_cursor_is_visible();
- accept_event();
+ selected_item->select(selected_col + 1);
+ }
- } break;
- case KEY_LEFT: {
+ update();
+ ensure_cursor_is_visible();
+ accept_event();
- //TreeItem *next = NULL;
- if (!selected_item)
- break;
- if (select_mode == SELECT_ROW)
- EXIT_BREAK;
- if (selected_col <= 0)
- EXIT_BREAK;
- if (select_mode == SELECT_MULTI) {
- selected_col--;
- emit_signal("cell_selected");
- } else {
+ } break;
+ case KEY_LEFT: {
+
+ //TreeItem *next = NULL;
+ if (!selected_item)
+ break;
+ if (select_mode == SELECT_ROW)
+ EXIT_BREAK;
+ if (selected_col <= 0)
+ EXIT_BREAK;
+ if (select_mode == SELECT_MULTI) {
+ selected_col--;
+ emit_signal("cell_selected");
+ } else {
- selected_item->select(selected_col - 1);
- }
+ selected_item->select(selected_col - 1);
+ }
- update();
- accept_event();
+ update();
+ accept_event();
- } break;
- case KEY_DOWN: {
+ } break;
+ case KEY_DOWN: {
- TreeItem *next = NULL;
- if (!selected_item) {
+ TreeItem *next = NULL;
+ if (!selected_item) {
- next = hide_root ? root->get_next_visible() : root;
- selected_item = 0;
- } else {
+ next = hide_root ? root->get_next_visible() : root;
+ selected_item = 0;
+ } else {
- next = selected_item->get_next_visible();
+ next = selected_item->get_next_visible();
- //if (diff < uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000))) {
- if (last_keypress != 0) {
- //incr search next
- int col;
- next = _search_item_text(next, incr_search, &col, true);
- if (!next) {
- accept_event();
- return;
- }
+ //if (diff < uint64_t(GLOBAL_DEF("gui/incr_search_max_interval_msec",2000))) {
+ if (last_keypress != 0) {
+ //incr search next
+ int col;
+ next = _search_item_text(next, incr_search, &col, true);
+ if (!next) {
+ accept_event();
+ return;
}
}
+ }
- if (select_mode == SELECT_MULTI) {
+ if (select_mode == SELECT_MULTI) {
- if (!next)
- EXIT_BREAK;
+ if (!next)
+ EXIT_BREAK;
- selected_item = next;
- emit_signal("cell_selected");
- update();
- } else {
+ selected_item = next;
+ emit_signal("cell_selected");
+ update();
+ } else {
- int col = selected_col < 0 ? 0 : selected_col;
+ int col = selected_col < 0 ? 0 : selected_col;
- while (next && !next->cells[col].selectable)
- next = next->get_next_visible();
- if (!next)
- EXIT_BREAK; // do nothing..
- next->select(col);
- }
+ while (next && !next->cells[col].selectable)
+ next = next->get_next_visible();
+ if (!next)
+ EXIT_BREAK; // do nothing..
+ next->select(col);
+ }
- ensure_cursor_is_visible();
- accept_event();
+ ensure_cursor_is_visible();
+ accept_event();
- } break;
- case KEY_UP: {
+ } break;
+ case KEY_UP: {
- TreeItem *prev = NULL;
- if (!selected_item) {
- prev = get_last_item();
- selected_col = 0;
- } else {
+ TreeItem *prev = NULL;
+ if (!selected_item) {
+ prev = get_last_item();
+ selected_col = 0;
+ } else {
- prev = selected_item->get_prev_visible();
- if (last_keypress != 0) {
- //incr search next
- int col;
- prev = _search_item_text(prev, incr_search, &col, true, true);
- if (!prev) {
- accept_event();
- return;
- }
+ prev = selected_item->get_prev_visible();
+ if (last_keypress != 0) {
+ //incr search next
+ int col;
+ prev = _search_item_text(prev, incr_search, &col, true, true);
+ if (!prev) {
+ accept_event();
+ return;
}
}
+ }
- if (select_mode == SELECT_MULTI) {
+ if (select_mode == SELECT_MULTI) {
- if (!prev)
- break;
- selected_item = prev;
- emit_signal("cell_selected");
- update();
- } else {
+ if (!prev)
+ break;
+ selected_item = prev;
+ emit_signal("cell_selected");
+ update();
+ } else {
- int col = selected_col < 0 ? 0 : selected_col;
- while (prev && !prev->cells[col].selectable)
- prev = prev->get_prev_visible();
- if (!prev)
- break; // do nothing..
- prev->select(col);
- }
+ int col = selected_col < 0 ? 0 : selected_col;
+ while (prev && !prev->cells[col].selectable)
+ prev = prev->get_prev_visible();
+ if (!prev)
+ break; // do nothing..
+ prev->select(col);
+ }
- ensure_cursor_is_visible();
- accept_event();
+ ensure_cursor_is_visible();
+ accept_event();
- } break;
- case KEY_PAGEDOWN: {
+ } break;
+ case KEY_PAGEDOWN: {
- TreeItem *next = NULL;
- if (!selected_item)
- break;
- next = selected_item;
+ TreeItem *next = NULL;
+ if (!selected_item)
+ break;
+ next = selected_item;
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 10; i++) {
- TreeItem *_n = next->get_next_visible();
- if (_n) {
- next = _n;
- } else {
+ TreeItem *_n = next->get_next_visible();
+ if (_n) {
+ next = _n;
+ } else {
- break;
- }
- }
- if (next == selected_item)
break;
+ }
+ }
+ if (next == selected_item)
+ break;
- if (select_mode == SELECT_MULTI) {
+ if (select_mode == SELECT_MULTI) {
- selected_item = next;
- emit_signal("cell_selected");
- update();
- } else {
+ selected_item = next;
+ emit_signal("cell_selected");
+ update();
+ } else {
- while (next && !next->cells[selected_col].selectable)
- next = next->get_next_visible();
- if (!next)
- EXIT_BREAK; // do nothing..
- next->select(selected_col);
- }
+ while (next && !next->cells[selected_col].selectable)
+ next = next->get_next_visible();
+ if (!next)
+ EXIT_BREAK; // do nothing..
+ next->select(selected_col);
+ }
- ensure_cursor_is_visible();
- } break;
- case KEY_PAGEUP: {
+ ensure_cursor_is_visible();
+ } break;
+ case KEY_PAGEUP: {
- TreeItem *prev = NULL;
- if (!selected_item)
- break;
- prev = selected_item;
+ TreeItem *prev = NULL;
+ if (!selected_item)
+ break;
+ prev = selected_item;
- for (int i = 0; i < 10; i++) {
+ for (int i = 0; i < 10; i++) {
- TreeItem *_n = prev->get_prev_visible();
- if (_n) {
- prev = _n;
- } else {
+ TreeItem *_n = prev->get_prev_visible();
+ if (_n) {
+ prev = _n;
+ } else {
- break;
- }
- }
- if (prev == selected_item)
break;
+ }
+ }
+ if (prev == selected_item)
+ break;
- if (select_mode == SELECT_MULTI) {
+ if (select_mode == SELECT_MULTI) {
- selected_item = prev;
- emit_signal("cell_selected");
- update();
- } else {
+ selected_item = prev;
+ emit_signal("cell_selected");
+ update();
+ } else {
- while (prev && !prev->cells[selected_col].selectable)
- prev = prev->get_prev_visible();
- if (!prev)
- EXIT_BREAK; // do nothing..
- prev->select(selected_col);
- }
+ while (prev && !prev->cells[selected_col].selectable)
+ prev = prev->get_prev_visible();
+ if (!prev)
+ EXIT_BREAK; // do nothing..
+ prev->select(selected_col);
+ }
- ensure_cursor_is_visible();
+ ensure_cursor_is_visible();
- } break;
- case KEY_F2:
- case KEY_RETURN:
- case KEY_ENTER: {
-
- if (selected_item) {
- //bring up editor if possible
- if (!edit_selected()) {
- emit_signal("item_activated");
- }
+ } break;
+ case KEY_F2:
+ case KEY_RETURN:
+ case KEY_ENTER: {
+
+ if (selected_item) {
+ //bring up editor if possible
+ if (!edit_selected()) {
+ emit_signal("item_activated");
+ incr_search.clear();
}
- accept_event();
+ }
+ accept_event();
- } break;
- case KEY_SPACE: {
- if (select_mode == SELECT_MULTI) {
- if (!selected_item)
- break;
- if (selected_item->is_selected(selected_col)) {
- selected_item->deselect(selected_col);
- emit_signal("multi_selected", selected_item, selected_col, false);
- } else if (selected_item->is_selectable(selected_col)) {
- selected_item->select(selected_col);
- emit_signal("multi_selected", selected_item, selected_col, true);
- }
+ } break;
+ case KEY_SPACE: {
+ if (select_mode == SELECT_MULTI) {
+ if (!selected_item)
+ break;
+ if (selected_item->is_selected(selected_col)) {
+ selected_item->deselect(selected_col);
+ emit_signal("multi_selected", selected_item, selected_col, false);
+ } else if (selected_item->is_selectable(selected_col)) {
+ selected_item->select(selected_col);
+ emit_signal("multi_selected", selected_item, selected_col, true);
}
- accept_event();
+ }
+ accept_event();
- } break;
- default: {
+ } break;
+ default: {
- if (p_event.key.unicode > 0) {
+ if (k->get_unicode() > 0) {
- _do_incr_search(String::chr(p_event.key.unicode));
- accept_event();
+ _do_incr_search(String::chr(k->get_unicode()));
+ accept_event();
- return;
- } else {
- if (p_event.key.scancode != KEY_SHIFT)
- last_keypress = 0;
- }
- } break;
+ return;
+ } else {
+ if (k->get_scancode() != KEY_SHIFT)
+ last_keypress = 0;
+ }
+ } break;
- last_keypress = 0;
- }
+ last_keypress = 0;
+ }
+ }
- } break;
+ Ref<InputEventMouseMotion> mm = p_event;
- case InputEvent::MOUSE_MOTION: {
+ if (mm.is_valid()) {
- if (cache.font.is_null()) // avoid a strange case that may fuckup stuff
- update_cache();
- const InputEventMouseMotion &b = p_event.mouse_motion;
+ if (cache.font.is_null()) // avoid a strange case that may fuckup stuff
+ update_cache();
- Ref<StyleBox> bg = cache.bg;
+ Ref<StyleBox> bg = cache.bg;
- Point2 pos = Point2(b.x, b.y) - bg->get_offset();
+ Point2 pos = mm->get_position() - bg->get_offset();
- Cache::ClickType old_hover = cache.hover_type;
- int old_index = cache.hover_index;
+ Cache::ClickType old_hover = cache.hover_type;
+ int old_index = cache.hover_index;
- cache.hover_type = Cache::CLICK_NONE;
- cache.hover_index = 0;
- if (show_column_titles) {
- pos.y -= _get_title_button_height();
- if (pos.y < 0) {
- pos.x += cache.offset.x;
- int len = 0;
- for (int i = 0; i < columns.size(); i++) {
-
- len += get_column_width(i);
- if (pos.x < len) {
-
- cache.hover_type = Cache::CLICK_TITLE;
- cache.hover_index = i;
- update();
- break;
- }
+ cache.hover_type = Cache::CLICK_NONE;
+ cache.hover_index = 0;
+ if (show_column_titles) {
+ pos.y -= _get_title_button_height();
+ if (pos.y < 0) {
+ pos.x += cache.offset.x;
+ int len = 0;
+ for (int i = 0; i < columns.size(); i++) {
+
+ len += get_column_width(i);
+ if (pos.x < len) {
+
+ cache.hover_type = Cache::CLICK_TITLE;
+ cache.hover_index = i;
+ update();
+ break;
}
}
}
+ }
- if (drop_mode_flags && root) {
+ if (root) {
- Point2 mpos = Point2(b.x, b.y);
- mpos -= cache.bg->get_offset();
- mpos.y -= _get_title_button_height();
- if (mpos.y >= 0) {
+ Point2 mpos = mm->get_position();
+ mpos -= cache.bg->get_offset();
+ mpos.y -= _get_title_button_height();
+ if (mpos.y >= 0) {
- if (h_scroll->is_visible_in_tree())
- mpos.x += h_scroll->get_value();
- if (v_scroll->is_visible_in_tree())
- mpos.y += v_scroll->get_value();
+ if (h_scroll->is_visible_in_tree())
+ mpos.x += h_scroll->get_value();
+ if (v_scroll->is_visible_in_tree())
+ mpos.y += v_scroll->get_value();
- int col, h, section;
- TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
+ int col, h, section;
+ TreeItem *it = _find_item_at_pos(root, mpos, col, h, section);
- if (it != drop_mode_over || section != drop_mode_section) {
- drop_mode_over = it;
- drop_mode_section = section;
- update();
- }
+ if (drop_mode_flags && it != drop_mode_over || section != drop_mode_section) {
+ drop_mode_over = it;
+ drop_mode_section = section;
+ update();
}
- }
- if (cache.hover_type != old_hover || cache.hover_index != old_index) {
- update();
+ if (it != cache.hover_item || col != cache.hover_cell) {
+ cache.hover_item = it;
+ cache.hover_cell = col;
+ update();
+ }
}
+ }
- if (pressing_for_editor && popup_edited_item && (popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE || popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE_EXPRESSION)) {
- //range drag
+ if (cache.hover_type != old_hover || cache.hover_index != old_index) {
+ update();
+ }
- if (!range_drag_enabled) {
+ if (pressing_for_editor && popup_edited_item && (popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE || popup_edited_item->get_cell_mode(popup_edited_item_col) == TreeItem::CELL_MODE_RANGE_EXPRESSION)) {
+ //range drag
- Vector2 cpos = Vector2(b.x, b.y);
- if (cpos.distance_to(pressing_pos) > 2) {
- range_drag_enabled = true;
- range_drag_capture_pos = cpos;
- range_drag_base = popup_edited_item->get_range(popup_edited_item_col);
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
- }
- } else {
+ if (!range_drag_enabled) {
- TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
- float diff_y = -b.relative_y;
- diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y);
- diff_y *= 0.1;
- range_drag_base = CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
- popup_edited_item->set_range(popup_edited_item_col, range_drag_base);
- item_edited(popup_edited_item_col, popup_edited_item);
+ Vector2 cpos = mm->get_position();
+ if (cpos.distance_to(pressing_pos) > 2) {
+ range_drag_enabled = true;
+ range_drag_capture_pos = cpos;
+ range_drag_base = popup_edited_item->get_range(popup_edited_item_col);
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_CAPTURED);
}
+ } else {
+
+ TreeItem::Cell &c = popup_edited_item->cells[popup_edited_item_col];
+ float diff_y = -mm->get_relative().y;
+ diff_y = Math::pow(ABS(diff_y), 1.8f) * SGN(diff_y);
+ diff_y *= 0.1;
+ range_drag_base = CLAMP(range_drag_base + c.step * diff_y, c.min, c.max);
+ popup_edited_item->set_range(popup_edited_item_col, range_drag_base);
+ item_edited(popup_edited_item_col, popup_edited_item);
}
+ }
- if (drag_touching && !drag_touching_deaccel) {
+ if (drag_touching && !drag_touching_deaccel) {
- drag_accum -= b.relative_y;
- v_scroll->set_value(drag_from + drag_accum);
- drag_speed = -b.speed_y;
- }
- } break;
- case InputEvent::MOUSE_BUTTON: {
+ drag_accum -= mm->get_relative().y;
+ v_scroll->set_value(drag_from + drag_accum);
+ drag_speed = -mm->get_speed().y;
+ }
+ }
+
+ Ref<InputEventMouseButton> b = p_event;
+
+ if (b.is_valid()) {
+ if (cache.font.is_null()) // avoid a strange case that may fuckup stuff
+ update_cache();
+
+ if (!b->is_pressed()) {
- if (cache.font.is_null()) // avoid a strange case that may fuckup stuff
- update_cache();
- const InputEventMouseButton &b = p_event.mouse_button;
+ if (b->get_button_index() == BUTTON_LEFT) {
- if (!b.pressed) {
+ Point2 pos = b->get_position() - cache.bg->get_offset();
+ if (show_column_titles) {
+ pos.y -= _get_title_button_height();
- if (b.button_index == BUTTON_LEFT) {
+ if (pos.y < 0) {
+ pos.x += cache.offset.x;
+ int len = 0;
+ for (int i = 0; i < columns.size(); i++) {
- if (single_select_defer) {
- select_single_item(single_select_defer, root, single_select_defer_column);
- single_select_defer = NULL;
+ len += get_column_width(i);
+ if (pos.x < len) {
+ emit_signal("column_title_pressed", i);
+ break;
+ }
+ }
}
+ }
+
+ if (single_select_defer) {
+ select_single_item(single_select_defer, root, single_select_defer_column);
+ single_select_defer = NULL;
+ }
- range_click_timer->stop();
+ range_click_timer->stop();
- if (pressing_for_editor) {
+ if (pressing_for_editor) {
- if (range_drag_enabled) {
+ if (range_drag_enabled) {
- range_drag_enabled = false;
- Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
- warp_mouse(range_drag_capture_pos);
+ range_drag_enabled = false;
+ Input::get_singleton()->set_mouse_mode(Input::MOUSE_MODE_VISIBLE);
+ warp_mouse(range_drag_capture_pos);
+ } else {
+ Rect2 rect = get_selected()->get_meta("__focus_rect");
+ if (rect.has_point(Point2(b->get_position().x, b->get_position().y))) {
+ edit_selected();
} else {
- Rect2 rect = get_selected()->get_meta("__focus_rect");
- if (rect.has_point(Point2(p_event.mouse_button.x, p_event.mouse_button.y))) {
- edit_selected();
- } else {
- emit_signal("item_double_clicked");
- }
+ emit_signal("item_double_clicked");
}
- pressing_for_editor = false;
}
+ pressing_for_editor = false;
+ }
- if (cache.click_type == Cache::CLICK_BUTTON) {
- // make sure in case of wrong reference after reconstructing whole TreeItems
- cache.click_item = get_item_at_pos(cache.click_pos);
- emit_signal("button_pressed", cache.click_item, cache.click_column, cache.click_id);
- }
- cache.click_type = Cache::CLICK_NONE;
- cache.click_index = -1;
- cache.click_id = -1;
- cache.click_item = NULL;
- cache.click_column = 0;
+ if (cache.click_type == Cache::CLICK_BUTTON) {
+ // make sure in case of wrong reference after reconstructing whole TreeItems
+ cache.click_item = get_item_at_pos(cache.click_pos);
+ emit_signal("button_pressed", cache.click_item, cache.click_column, cache.click_id);
+ }
+ cache.click_type = Cache::CLICK_NONE;
+ cache.click_index = -1;
+ cache.click_id = -1;
+ cache.click_item = NULL;
+ cache.click_column = 0;
- if (drag_touching) {
+ if (drag_touching) {
- if (drag_speed == 0) {
- drag_touching_deaccel = false;
- drag_touching = false;
- set_fixed_process(false);
- } else {
+ if (drag_speed == 0) {
+ drag_touching_deaccel = false;
+ drag_touching = false;
+ set_fixed_process(false);
+ } else {
- drag_touching_deaccel = true;
- }
+ drag_touching_deaccel = true;
}
- update();
}
- break;
+ update();
}
+ return;
+ }
- if (range_drag_enabled)
- break;
-
- switch (b.button_index) {
- case BUTTON_RIGHT:
- case BUTTON_LEFT: {
- Ref<StyleBox> bg = cache.bg;
+ if (range_drag_enabled)
+ return;
- Point2 pos = Point2(b.x, b.y) - bg->get_offset();
- cache.click_type = Cache::CLICK_NONE;
- if (show_column_titles && b.button_index == BUTTON_LEFT) {
- pos.y -= _get_title_button_height();
-
- if (pos.y < 0) {
- pos.x += cache.offset.x;
- int len = 0;
- for (int i = 0; i < columns.size(); i++) {
-
- len += get_column_width(i);
- if (pos.x < len) {
-
- cache.click_type = Cache::CLICK_TITLE;
- cache.click_index = i;
- //cache.click_id=;
- update();
- break;
- }
+ switch (b->get_button_index()) {
+ case BUTTON_RIGHT:
+ case BUTTON_LEFT: {
+ Ref<StyleBox> bg = cache.bg;
+
+ Point2 pos = b->get_position() - bg->get_offset();
+ cache.click_type = Cache::CLICK_NONE;
+ if (show_column_titles && b->get_button_index() == BUTTON_LEFT) {
+ pos.y -= _get_title_button_height();
+
+ if (pos.y < 0) {
+ pos.x += cache.offset.x;
+ int len = 0;
+ for (int i = 0; i < columns.size(); i++) {
+
+ len += get_column_width(i);
+ if (pos.x < len) {
+
+ cache.click_type = Cache::CLICK_TITLE;
+ cache.click_index = i;
+ //cache.click_id=;
+ update();
+ break;
}
- break;
- }
- }
- if (!root || (!root->get_children() && hide_root)) {
- if (b.button_index == BUTTON_RIGHT && allow_rmb_select) {
- emit_signal("empty_tree_rmb_selected", get_local_mouse_pos());
}
break;
}
+ }
+ if (!root || (!root->get_children() && hide_root)) {
+ if (b->get_button_index() == BUTTON_RIGHT && allow_rmb_select) {
+ emit_signal("empty_tree_rmb_selected", get_local_mouse_pos());
+ }
+ break;
+ }
- click_handled = false;
- pressing_for_editor = false;
+ click_handled = false;
+ pressing_for_editor = false;
- blocked++;
- bool handled = propagate_mouse_event(pos + cache.offset, 0, 0, b.doubleclick, root, b.button_index, b.mod);
- blocked--;
+ blocked++;
+ bool handled = propagate_mouse_event(pos + cache.offset, 0, 0, b->is_doubleclick(), root, b->get_button_index(), b);
+ blocked--;
- if (pressing_for_editor) {
- pressing_pos = Point2(b.x, b.y);
- }
+ if (pressing_for_editor) {
+ pressing_pos = b->get_position();
+ }
- if (b.button_index == BUTTON_RIGHT)
- break;
+ if (b->get_button_index() == BUTTON_RIGHT)
+ break;
- if (drag_touching) {
- set_fixed_process(false);
- drag_touching_deaccel = false;
- drag_touching = false;
- drag_speed = 0;
- drag_from = 0;
- }
+ if (drag_touching) {
+ set_fixed_process(false);
+ drag_touching_deaccel = false;
+ drag_touching = false;
+ drag_speed = 0;
+ drag_from = 0;
+ }
- if (!click_handled) {
- drag_speed = 0;
- drag_accum = 0;
- //last_drag_accum=0;
- drag_from = v_scroll->get_value();
- drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
- drag_touching_deaccel = false;
- if (drag_touching) {
- set_fixed_process(true);
- }
+ if (!click_handled) {
+ drag_speed = 0;
+ drag_accum = 0;
+ //last_drag_accum=0;
+ drag_from = v_scroll->get_value();
+ drag_touching = OS::get_singleton()->has_touchscreen_ui_hint();
+ drag_touching_deaccel = false;
+ if (drag_touching) {
+ set_fixed_process(true);
}
+ }
- } break;
- case BUTTON_WHEEL_UP: {
-
- v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() / 8);
- } break;
- case BUTTON_WHEEL_DOWN: {
+ } break;
+ case BUTTON_WHEEL_UP: {
- v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() / 8);
- } break;
- }
+ v_scroll->set_value(v_scroll->get_value() - v_scroll->get_page() * b->get_factor() / 8);
+ } break;
+ case BUTTON_WHEEL_DOWN: {
- } break;
+ v_scroll->set_value(v_scroll->get_value() + v_scroll->get_page() * b->get_factor() / 8);
+ } break;
+ }
}
}
@@ -2380,7 +2457,7 @@ bool Tree::edit_selected() {
edited_item = s;
edited_col = col;
- custom_popup_rect = Rect2i(get_global_position() + rect.pos, rect.size);
+ custom_popup_rect = Rect2i(get_global_position() + rect.position, rect.size);
emit_signal("custom_popup_edited", false);
item_edited(col, s);
@@ -2395,7 +2472,7 @@ bool Tree::edit_selected() {
}
popup_menu->set_size(Size2(rect.size.width, 0));
- popup_menu->set_position(get_global_position() + rect.pos + Point2i(0, rect.size.height));
+ popup_menu->set_position(get_global_position() + rect.position + Point2i(0, rect.size.height));
popup_menu->popup();
popup_edited_item = s;
popup_edited_item_col = col;
@@ -2403,7 +2480,7 @@ bool Tree::edit_selected() {
} else if (c.mode == TreeItem::CELL_MODE_STRING || c.mode == TreeItem::CELL_MODE_RANGE || c.mode == TreeItem::CELL_MODE_RANGE_EXPRESSION) {
- Point2i textedpos = get_global_position() + rect.pos;
+ Point2i textedpos = get_global_position() + rect.position;
text_editor->set_position(textedpos);
text_editor->set_size(rect.size);
text_editor->clear();
@@ -2650,7 +2727,7 @@ void Tree::_notification(int p_what) {
ofs += tbrect.size.width;
//text
int clip_w = tbrect.size.width - sb->get_minimum_size().width;
- f->draw_halign(ci, tbrect.pos + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color);
+ f->draw_halign(ci, tbrect.position + Point2i(sb->get_offset().x, (tbrect.size.height - f->get_height()) / 2 + f->get_ascent()), HALIGN_CENTER, clip_w, columns[i].title, cache.title_button_color);
}
}
}
@@ -3011,7 +3088,7 @@ void Tree::ensure_cursor_is_visible() {
int screenh = get_size().height - h_scroll->get_combined_minimum_size().height;
if (ofs + h > v_scroll->get_value() + screenh)
- v_scroll->call_deferred("set_val", ofs - screenh + h);
+ v_scroll->call_deferred("set_value", ofs - screenh + h);
else if (ofs < v_scroll->get_value())
v_scroll->set_value(ofs);
}
@@ -3032,11 +3109,11 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const {
int ofs = get_item_offset(p_item);
int height = compute_item_height(p_item);
Rect2 r;
- r.pos.y = ofs;
+ r.position.y = ofs;
r.size.height = height;
if (p_column == -1) {
- r.pos.x = 0;
+ r.position.x = 0;
r.size.x = get_size().width;
} else {
@@ -3044,7 +3121,7 @@ Rect2 Tree::get_item_rect(TreeItem *p_item, int p_column) const {
for (int i = 0; i < p_column; i++) {
accum += get_column_width(i);
}
- r.pos.x = accum;
+ r.position.x = accum;
r.size.x = get_column_width(p_column);
}
@@ -3448,12 +3525,14 @@ void Tree::_bind_methods() {
ADD_SIGNAL(MethodInfo("item_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos")));
ADD_SIGNAL(MethodInfo("empty_tree_rmb_selected", PropertyInfo(Variant::VECTOR2, "pos")));
ADD_SIGNAL(MethodInfo("item_edited"));
+ ADD_SIGNAL(MethodInfo("item_custom_button_pressed"));
ADD_SIGNAL(MethodInfo("item_double_clicked"));
ADD_SIGNAL(MethodInfo("item_collapsed", PropertyInfo(Variant::OBJECT, "item")));
//ADD_SIGNAL( MethodInfo("item_doubleclicked" ) );
ADD_SIGNAL(MethodInfo("button_pressed", PropertyInfo(Variant::OBJECT, "item"), PropertyInfo(Variant::INT, "column"), PropertyInfo(Variant::INT, "id")));
ADD_SIGNAL(MethodInfo("custom_popup_edited", PropertyInfo(Variant::BOOL, "arrow_clicked")));
ADD_SIGNAL(MethodInfo("item_activated"));
+ ADD_SIGNAL(MethodInfo("column_title_pressed", PropertyInfo(Variant::INT, "column")));
BIND_CONSTANT(SELECT_SINGLE);
BIND_CONSTANT(SELECT_ROW);
@@ -3553,6 +3632,9 @@ Tree::Tree() {
force_edit_checkbox_only_on_checkbox = false;
set_clip_contents(true);
+
+ cache.hover_item = NULL;
+ cache.hover_cell = -1;
}
Tree::~Tree() {
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 4bee1adc4b..097e0110e8 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -81,6 +81,7 @@ private:
bool custom_bg_color;
bool custom_bg_outline;
Color bg_color;
+ bool custom_button;
Variant meta;
String tooltip;
@@ -107,6 +108,7 @@ private:
Cell() {
custom_draw_obj = 0;
+ custom_button = false;
mode = TreeItem::CELL_MODE_STRING;
min = 0;
max = 100;
@@ -238,6 +240,9 @@ public:
void clear_custom_bg_color(int p_column);
Color get_custom_bg_color(int p_column) const;
+ void set_custom_as_button(int p_column, bool p_button);
+ bool is_custom_set_as_button(int p_column) const;
+
void set_tooltip(int p_column, const String &p_tooltip);
String get_tooltip(int p_column) const;
@@ -337,14 +342,14 @@ private:
void draw_item_rect(const TreeItem::Cell &p_cell, const Rect2i &p_rect, const Color &p_color);
int draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 &p_draw_size, TreeItem *p_item);
void select_single_item(TreeItem *p_selected, TreeItem *p_current, int p_col, TreeItem *p_prev = NULL, bool *r_in_range = NULL, bool p_force_deselect = false);
- int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const InputModifierState &p_mod);
+ int propagate_mouse_event(const Point2i &p_pos, int x_ofs, int y_ofs, bool p_doubleclick, TreeItem *p_item, int p_button, const Ref<InputEventWithModifiers> &p_mod);
void text_editor_enter(String p_text);
void _text_editor_modal_close();
void value_editor_changed(double p_value);
void popup_select(int p_option);
- void _gui_input(InputEvent p_event);
+ void _gui_input(Ref<InputEvent> p_event);
void _notification(int p_what);
Size2 get_minimum_size() const;
@@ -369,6 +374,10 @@ private:
Ref<StyleBox> title_button;
Ref<StyleBox> title_button_hover;
Ref<StyleBox> title_button_pressed;
+ Ref<StyleBox> custom_button;
+ Ref<StyleBox> custom_button_hover;
+ Ref<StyleBox> custom_button_pressed;
+
Color title_button_color;
Ref<Texture> checked;
@@ -383,6 +392,7 @@ private:
Color guide_color;
Color drop_position_color;
Color relationship_line_color;
+ Color custom_button_font_highlight;
int hseparation;
int vseparation;
@@ -410,6 +420,9 @@ private:
int hover_index;
Point2 click_pos;
+ TreeItem *hover_item;
+ int hover_cell;
+
} cache;
int _get_title_button_height() const;
diff --git a/scene/gui/video_player.h b/scene/gui/video_player.h
index c3a839c514..1d70718a6a 100644
--- a/scene/gui/video_player.h
+++ b/scene/gui/video_player.h
@@ -59,7 +59,7 @@ class VideoPlayer : public Control {
RID stream_rid;
Ref<ImageTexture> texture;
- Image last_frame;
+ Ref<Image> last_frame;
AudioRBResampler resampler;
diff --git a/scene/main/node.cpp b/scene/main/node.cpp
index cfee5066b4..0c65c44392 100755
--- a/scene/main/node.cpp
+++ b/scene/main/node.cpp
@@ -463,7 +463,7 @@ Node::PauseMode Node::get_pause_mode() const {
void Node::_propagate_pause_owner(Node *p_owner) {
- if (data.pause_mode != PAUSE_MODE_INHERIT)
+ if (this != p_owner && data.pause_mode != PAUSE_MODE_INHERIT)
return;
data.pause_owner = p_owner;
for (int i = 0; i < data.children.size(); i++) {
@@ -2938,9 +2938,9 @@ void Node::_bind_methods() {
BIND_VMETHOD(MethodInfo("_enter_tree"));
BIND_VMETHOD(MethodInfo("_exit_tree"));
BIND_VMETHOD(MethodInfo("_ready"));
- BIND_VMETHOD(MethodInfo("_input", PropertyInfo(Variant::INPUT_EVENT, "event")));
- BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::INPUT_EVENT, "event")));
- BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::INPUT_EVENT, "key_event")));
+ BIND_VMETHOD(MethodInfo("_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
+ BIND_VMETHOD(MethodInfo("_unhandled_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEvent")));
+ BIND_VMETHOD(MethodInfo("_unhandled_key_input", PropertyInfo(Variant::OBJECT, "event", PROPERTY_HINT_RESOURCE_TYPE, "InputEventKey")));
//ClassDB::bind_method(D_METHOD("get_child",&Node::get_child,PH("index")));
//ClassDB::bind_method(D_METHOD("get_node",&Node::get_node,PH("path")));
diff --git a/scene/main/scene_main_loop.cpp b/scene/main/scene_main_loop.cpp
index a43938c661..f7a255cd33 100644
--- a/scene/main/scene_main_loop.cpp
+++ b/scene/main/scene_main_loop.cpp
@@ -37,6 +37,7 @@
#include "print_string.h"
#include <stdio.h>
//#include "servers/spatial_sound_2d_server.h"
+
#include "io/marshalls.h"
#include "io/resource_loader.h"
#include "scene/resources/material.h"
@@ -379,9 +380,9 @@ bool SceneTree::is_input_handled() {
return input_handled;
}
-void SceneTree::input_event(const InputEvent &p_event) {
+void SceneTree::input_event(const Ref<InputEvent> &p_event) {
- if (is_editor_hint() && (p_event.type == InputEvent::JOYPAD_MOTION || p_event.type == InputEvent::JOYPAD_BUTTON))
+ if (is_editor_hint() && (p_event->cast_to<InputEventJoypadButton>() || p_event->cast_to<InputEventJoypadMotion>()))
return; //avoid joy input on editor
root_lock++;
@@ -389,8 +390,8 @@ void SceneTree::input_event(const InputEvent &p_event) {
input_handled = false;
- InputEvent ev = p_event;
- ev.ID = ++last_id; //this should work better
+ Ref<InputEvent> ev = p_event;
+ ev->set_id(++last_id); //this should work better
#if 0
switch(ev.type) {
@@ -398,9 +399,9 @@ void SceneTree::input_event(const InputEvent &p_event) {
Matrix32 ai = root->get_final_transform().affine_inverse();
Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
- Vector2 l = ai.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
- ev.mouse_button.x=l.x;
- ev.mouse_button.y=l.y;
+ Vector2 l = ai.xform(Vector2(ev->get_pos().x,ev->get_pos().y));
+ ev->get_pos().x=l.x;
+ ev->get_pos().y=l.y;
ev.mouse_button.global_x=g.x;
ev.mouse_button.global_y=g.y;
@@ -410,13 +411,13 @@ void SceneTree::input_event(const InputEvent &p_event) {
Matrix32 ai = root->get_final_transform().affine_inverse();
Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
Vector2 l = ai.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
- Vector2 r = ai.xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
+ Vector2 r = ai.xform(Vector2(ev->get_relative().x,ev->get_relative().y));
ev.mouse_motion.x=l.x;
ev.mouse_motion.y=l.y;
ev.mouse_motion.global_x=g.x;
ev.mouse_motion.global_y=g.y;
- ev.mouse_motion.relative_x=r.x;
- ev.mouse_motion.relative_y=r.y;
+ ev->get_relative().x=r.x;
+ ev->get_relative().y=r.y;
} break;
case InputEvent::SCREEN_TOUCH: {
@@ -453,12 +454,12 @@ void SceneTree::input_event(const InputEvent &p_event) {
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"input","_input",ev);
/*
- if (ev.type==InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode==KEY_F12) {
+ if (ev.type==InputEvent::KEY && ev->is_pressed() && !ev->is_echo() && ev->get_scancode()==KEY_F12) {
print_line("RAM: "+itos(Memory::get_static_mem_usage()));
print_line("DRAM: "+itos(Memory::get_dynamic_mem_usage()));
}
- if (ev.type==InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode==KEY_F11) {
+ if (ev.type==InputEvent::KEY && ev->is_pressed() && !ev->is_echo() && ev->get_scancode()==KEY_F11) {
Memory::dump_static_mem_to_file("memdump.txt");
}
@@ -470,9 +471,13 @@ void SceneTree::input_event(const InputEvent &p_event) {
call_group_flags(GROUP_CALL_REALTIME, "_viewports", "_vp_input", ev); //special one for GUI, as controls use their own process check
#endif
- if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote() && ev.type == InputEvent::KEY && ev.key.pressed && !ev.key.echo && ev.key.scancode == KEY_F8) {
- ScriptDebugger::get_singleton()->request_quit();
+ if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_remote()) {
+ //quit from game window using F8
+ Ref<InputEventKey> k = ev;
+ if (k.is_valid() && k->is_pressed() && !k->is_echo() && k->get_scancode() == KEY_F8) {
+ ScriptDebugger::get_singleton()->request_quit();
+ }
}
_flush_ugc();
@@ -605,6 +610,30 @@ bool SceneTree::idle(float p_time) {
_call_idle_callbacks();
+#ifdef TOOLS_ENABLED
+
+ if (is_editor_hint()) {
+ //simple hack to reload fallback environment if it changed from editor
+ String env_path = GlobalConfig::get_singleton()->get("rendering/viewport/default_environment");
+ env_path = env_path.strip_edges(); //user may have added a space or two
+ String cpath;
+ Ref<Environment> fallback = get_root()->get_world()->get_fallback_environment();
+ if (fallback.is_valid()) {
+ cpath = fallback->get_path();
+ }
+ if (cpath != env_path) {
+
+ if (env_path != String()) {
+ fallback = ResourceLoader::load(env_path);
+ } else {
+ fallback.unref();
+ }
+ get_root()->get_world()->set_fallback_environment(fallback);
+ }
+ }
+
+#endif
+
return _quit;
}
@@ -810,12 +839,12 @@ Ref<Material> SceneTree::get_debug_collision_material() {
return collision_material;
}
-Ref<Mesh> SceneTree::get_debug_contact_mesh() {
+Ref<ArrayMesh> SceneTree::get_debug_contact_mesh() {
if (debug_contact_mesh.is_valid())
return debug_contact_mesh;
- debug_contact_mesh = Ref<Mesh>(memnew(Mesh));
+ debug_contact_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
Ref<SpatialMaterial> mat = memnew(SpatialMaterial);
/*mat->set_flag(Material::FLAG_UNSHADED,true);
@@ -878,7 +907,7 @@ bool SceneTree::is_paused() const {
return pause;
}
-void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const InputEvent &p_input) {
+void SceneTree::_call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input) {
Map<StringName, Group>::Element *E = group_map.find(p_group);
if (!E)
@@ -2297,7 +2326,9 @@ SceneTree::SceneTree() {
root = memnew(Viewport);
root->set_name("root");
- root->set_world(Ref<World>(memnew(World)));
+ if (!root->get_world().is_valid())
+ root->set_world(Ref<World>(memnew(World)));
+
//root->set_world_2d( Ref<World2D>( memnew( World2D )));
root->set_as_audio_listener(true);
root->set_as_audio_listener_2d(true);
@@ -2313,6 +2344,37 @@ SceneTree::SceneTree() {
VS::get_singleton()->scenario_set_reflection_atlas_size(root->get_world()->get_scenario(), ref_atlas_size, ref_atlas_subdiv);
+ { //load default fallback environment
+ //get possible extensions
+ List<String> exts;
+ ResourceLoader::get_recognized_extensions_for_type("Environment", &exts);
+ String ext_hint;
+ for (List<String>::Element *E = exts.front(); E; E = E->next()) {
+ if (ext_hint != String())
+ ext_hint += ",";
+ ext_hint += "*." + E->get();
+ }
+ //get path
+ String env_path = GLOBAL_DEF("rendering/viewport/default_environment", "");
+ //setup property
+ GlobalConfig::get_singleton()->set_custom_property_info("rendering/viewport/default_environment", PropertyInfo(Variant::STRING, "rendering/viewport/default_environment", PROPERTY_HINT_FILE, ext_hint));
+ env_path = env_path.strip_edges();
+ if (env_path != String()) {
+ Ref<Environment> env = ResourceLoader::load(env_path);
+ if (env.is_valid()) {
+ root->get_world()->set_fallback_environment(env);
+ } else {
+ if (is_editor_hint()) {
+ //file was erased, clear the field.
+ GlobalConfig::get_singleton()->set("rendering/viewport/default_environment", "");
+ } else {
+ //file was erased, notify user.
+ ERR_PRINTS(RTR("Default Environment as specified in Project Setings (Rendering -> Viewport -> Default Environment) could not be loaded."));
+ }
+ }
+ }
+ }
+
stretch_mode = STRETCH_MODE_DISABLED;
stretch_aspect = STRETCH_ASPECT_IGNORE;
diff --git a/scene/main/scene_main_loop.h b/scene/main/scene_main_loop.h
index 52d5f5c88c..2ea79bf945 100644
--- a/scene/main/scene_main_loop.h
+++ b/scene/main/scene_main_loop.h
@@ -33,6 +33,7 @@
#include "io/networked_multiplayer_peer.h"
#include "os/main_loop.h"
#include "os/thread_safe.h"
+#include "scene/resources/mesh.h"
#include "scene/resources/world.h"
#include "scene/resources/world_2d.h"
#include "self_list.h"
@@ -169,7 +170,7 @@ private:
Color debug_collision_contact_color;
Color debug_navigation_color;
Color debug_navigation_disabled_color;
- Ref<Mesh> debug_contact_mesh;
+ Ref<ArrayMesh> debug_contact_mesh;
Ref<Material> navigation_material;
Ref<Material> navigation_disabled_material;
Ref<Material> collision_material;
@@ -237,7 +238,7 @@ private:
void remove_from_group(const StringName &p_group, Node *p_node);
void _notify_group_pause(const StringName &p_group, int p_notification);
- void _call_input_pause(const StringName &p_group, const StringName &p_method, const InputEvent &p_input);
+ void _call_input_pause(const StringName &p_group, const StringName &p_method, const Ref<InputEvent> &p_input);
Variant _call_group_flags(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
Variant _call_group(const Variant **p_args, int p_argcount, Variant::CallError &r_error);
@@ -341,7 +342,7 @@ public:
void set_group(const StringName &p_group, const String &p_name, const Variant &p_value);
virtual void input_text(const String &p_text);
- virtual void input_event(const InputEvent &p_event);
+ virtual void input_event(const Ref<InputEvent> &p_event);
virtual void init();
virtual bool iteration(float p_time);
@@ -406,7 +407,7 @@ public:
Ref<Material> get_debug_navigation_material();
Ref<Material> get_debug_navigation_disabled_material();
Ref<Material> get_debug_collision_material();
- Ref<Mesh> get_debug_contact_mesh();
+ Ref<ArrayMesh> get_debug_contact_mesh();
int get_collision_debug_contact_count() { return collision_debug_contacts; }
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index 406640275c..714327c5b7 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -117,7 +117,11 @@ bool ViewportTexture::has_alpha() const {
return false;
}
+Ref<Image> ViewportTexture::get_data() const {
+ ERR_FAIL_COND_V(!vp, Ref<Image>());
+ return VS::get_singleton()->texture_get_data(vp->texture_rid);
+}
void ViewportTexture::set_flags(uint32_t p_flags) {
if (!vp)
@@ -503,30 +507,36 @@ void Viewport::_notification(int p_what) {
while (physics_picking_events.size()) {
- InputEvent ev = physics_picking_events.front()->get();
+ Ref<InputEvent> ev = physics_picking_events.front()->get();
physics_picking_events.pop_front();
Vector2 pos;
- switch (ev.type) {
- case InputEvent::MOUSE_MOTION: {
- pos.x = ev.mouse_motion.x;
- pos.y = ev.mouse_motion.y;
- motion_tested = true;
- physics_last_mousepos = pos;
- } break;
- case InputEvent::MOUSE_BUTTON: {
- pos.x = ev.mouse_button.x;
- pos.y = ev.mouse_button.y;
-
- } break;
- case InputEvent::SCREEN_DRAG: {
- pos.x = ev.screen_drag.x;
- pos.y = ev.screen_drag.y;
- } break;
- case InputEvent::SCREEN_TOUCH: {
- pos.x = ev.screen_touch.x;
- pos.y = ev.screen_touch.y;
- } break;
+
+ Ref<InputEventMouseMotion> mm = ev;
+
+ if (mm.is_valid()) {
+
+ pos = mm->get_position();
+ motion_tested = true;
+ physics_last_mousepos = pos;
+ }
+
+ Ref<InputEventMouseButton> mb = ev;
+
+ if (mb.is_valid()) {
+ pos = mb->get_position();
+ }
+
+ Ref<InputEventScreenDrag> sd = ev;
+
+ if (sd.is_valid()) {
+ pos = sd->get_position();
+ }
+
+ Ref<InputEventScreenTouch> st = ev;
+
+ if (st.is_valid()) {
+ pos = st->get_position();
}
if (ss2d) {
@@ -589,7 +599,7 @@ void Viewport::_notification(int p_what) {
if (co) {
co->_input_event(camera, ev, Vector3(), Vector3(), 0);
captured = true;
- if (ev.type == InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index == 1 && !ev.mouse_button.pressed) {
+ if (mb.is_valid() && mb->get_button_index() == 1 && !mb->is_pressed()) {
physics_object_capture = 0;
}
@@ -609,7 +619,7 @@ void Viewport::_notification(int p_what) {
if (ObjectDB::get_instance(last_id)) {
//good, exists
last_object->_input_event(camera, ev, result.position, result.normal, result.shape);
- if (last_object->get_capture_input_on_drag() && ev.type == InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index == 1 && ev.mouse_button.pressed) {
+ if (last_object->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
physics_object_capture = last_id;
}
}
@@ -637,14 +647,14 @@ void Viewport::_notification(int p_what) {
last_object = co;
last_id = result.collider_id;
new_collider = last_id;
- if (co->get_capture_input_on_drag() && ev.type == InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index == 1 && ev.mouse_button.pressed) {
+ if (co->get_capture_input_on_drag() && mb.is_valid() && mb->get_button_index() == 1 && mb->is_pressed()) {
physics_object_capture = last_id;
}
}
}
}
- if (ev.type == InputEvent::MOUSE_MOTION) {
+ if (mm.is_valid()) {
_test_new_mouseover(new_collider);
}
}
@@ -1146,6 +1156,7 @@ void Viewport::set_size_override(bool p_enable, const Size2 &p_size, const Vecto
size_override_margin = p_margin;
_update_rect();
_update_stretch_transform();
+ emit_signal("size_changed");
}
Size2 Viewport::get_size_override() const {
@@ -1222,16 +1233,6 @@ Viewport::UpdateMode Viewport::get_update_mode() const {
}
//RID get_texture() const;
-void Viewport::queue_screen_capture() {
-
- //VS::get_singleton()->viewport_queue_screen_capture(viewport);
-}
-Image Viewport::get_screen_capture() const {
-
- //return VS::get_singleton()->viewport_get_screen_capture(viewport);
- return Image();
-}
-
Ref<ViewportTexture> Viewport::get_texture() const {
return default_texture;
@@ -1304,7 +1305,7 @@ Transform2D Viewport::_get_input_pre_xform() const {
if (to_screen_rect != Rect2()) {
- pre_xf.elements[2] = -to_screen_rect.pos;
+ pre_xf.elements[2] = -to_screen_rect.position;
pre_xf.scale(size / to_screen_rect.size);
}
@@ -1322,71 +1323,12 @@ Vector2 Viewport::_get_window_offset() const {
return Vector2();
}
-void Viewport::_make_input_local(InputEvent &ev) {
-
- switch (ev.type) {
-
- case InputEvent::MOUSE_BUTTON: {
-
- Vector2 vp_ofs = _get_window_offset();
-
- Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
- Vector2 g = ai.xform(Vector2(ev.mouse_button.global_x, ev.mouse_button.global_y));
- Vector2 l = ai.xform(Vector2(ev.mouse_button.x, ev.mouse_button.y) - vp_ofs);
-
- ev.mouse_button.x = l.x;
- ev.mouse_button.y = l.y;
- ev.mouse_button.global_x = g.x;
- ev.mouse_button.global_y = g.y;
-
- } break;
- case InputEvent::MOUSE_MOTION: {
-
- Vector2 vp_ofs = _get_window_offset();
-
- Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
- Vector2 g = ai.xform(Vector2(ev.mouse_motion.global_x, ev.mouse_motion.global_y));
- Vector2 l = ai.xform(Vector2(ev.mouse_motion.x, ev.mouse_motion.y) - vp_ofs);
- Vector2 r = ai.basis_xform(Vector2(ev.mouse_motion.relative_x, ev.mouse_motion.relative_y));
- Vector2 s = ai.basis_xform(Vector2(ev.mouse_motion.speed_x, ev.mouse_motion.speed_y));
-
- ev.mouse_motion.x = l.x;
- ev.mouse_motion.y = l.y;
- ev.mouse_motion.global_x = g.x;
- ev.mouse_motion.global_y = g.y;
- ev.mouse_motion.relative_x = r.x;
- ev.mouse_motion.relative_y = r.y;
- ev.mouse_motion.speed_x = s.x;
- ev.mouse_motion.speed_y = s.y;
-
- } break;
- case InputEvent::SCREEN_TOUCH: {
-
- Vector2 vp_ofs = _get_window_offset();
-
- Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
- Vector2 t = ai.xform(Vector2(ev.screen_touch.x, ev.screen_touch.y) - vp_ofs);
+Ref<InputEvent> Viewport::_make_input_local(const Ref<InputEvent> &ev) {
- ev.screen_touch.x = t.x;
- ev.screen_touch.y = t.y;
+ Vector2 vp_ofs = _get_window_offset();
+ Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
- } break;
- case InputEvent::SCREEN_DRAG: {
-
- Vector2 vp_ofs = _get_window_offset();
-
- Transform2D ai = get_final_transform().affine_inverse() * _get_input_pre_xform();
- Vector2 t = ai.xform(Vector2(ev.screen_drag.x, ev.screen_drag.y) - vp_ofs);
- Vector2 r = ai.basis_xform(Vector2(ev.screen_drag.relative_x, ev.screen_drag.relative_y));
- Vector2 s = ai.basis_xform(Vector2(ev.screen_drag.speed_x, ev.screen_drag.speed_y));
- ev.screen_drag.x = t.x;
- ev.screen_drag.y = t.y;
- ev.screen_drag.relative_x = r.x;
- ev.screen_drag.relative_y = r.y;
- ev.screen_drag.speed_x = s.x;
- ev.screen_drag.speed_y = s.y;
- } break;
- }
+ return ev->xformed_by(ai, -vp_ofs);
}
void Viewport::_vp_input_text(const String &p_text) {
@@ -1396,7 +1338,7 @@ void Viewport::_vp_input_text(const String &p_text) {
}
}
-void Viewport::_vp_input(const InputEvent &p_ev) {
+void Viewport::_vp_input(const Ref<InputEvent> &p_ev) {
if (disable_input)
return;
@@ -1413,12 +1355,11 @@ void Viewport::_vp_input(const InputEvent &p_ev) {
//this one handles system input, p_ev are in system coordinates
//they are converted to viewport coordinates
- InputEvent ev = p_ev;
- _make_input_local(ev);
+ Ref<InputEvent> ev = _make_input_local(p_ev);
input(ev);
}
-void Viewport::_vp_unhandled_input(const InputEvent &p_ev) {
+void Viewport::_vp_unhandled_input(const Ref<InputEvent> &p_ev) {
if (disable_input)
return;
@@ -1439,8 +1380,7 @@ void Viewport::_vp_unhandled_input(const InputEvent &p_ev) {
//this one handles system input, p_ev are in system coordinates
//they are converted to viewport coordinates
- InputEvent ev = p_ev;
- _make_input_local(ev);
+ Ref<InputEvent> ev = _make_input_local(p_ev);
unhandled_input(ev);
}
@@ -1528,35 +1468,39 @@ void Viewport::_gui_show_tooltip() {
gui.tooltip_label->set_text(tooltip);
Rect2 r(gui.tooltip_pos + Point2(10, 10), gui.tooltip_label->get_combined_minimum_size() + ttp->get_minimum_size());
Rect2 vr = gui.tooltip_label->get_viewport_rect();
- if (r.size.x + r.pos.x > vr.size.x)
- r.pos.x = vr.size.x - r.size.x;
- else if (r.pos.x < 0)
- r.pos.x = 0;
+ if (r.size.x + r.position.x > vr.size.x)
+ r.position.x = vr.size.x - r.size.x;
+ else if (r.position.x < 0)
+ r.position.x = 0;
- if (r.size.y + r.pos.y > vr.size.y)
- r.pos.y = vr.size.y - r.size.y;
- else if (r.pos.y < 0)
- r.pos.y = 0;
+ if (r.size.y + r.position.y > vr.size.y)
+ r.position.y = vr.size.y - r.size.y;
+ else if (r.position.y < 0)
+ r.position.y = 0;
- gui.tooltip_popup->set_global_position(r.pos);
+ gui.tooltip_popup->set_global_position(r.position);
gui.tooltip_popup->set_size(r.size);
gui.tooltip_popup->raise();
gui.tooltip_popup->show();
}
-void Viewport::_gui_call_input(Control *p_control, const InputEvent &p_input) {
+void Viewport::_gui_call_input(Control *p_control, const Ref<InputEvent> &p_input) {
//_block();
- InputEvent ev = p_input;
+ Ref<InputEvent> ev = p_input;
//mouse wheel events can't be stopped
- bool cant_stop_me_now = (ev.type == InputEvent::MOUSE_BUTTON &&
- (ev.mouse_button.button_index == BUTTON_WHEEL_DOWN ||
- ev.mouse_button.button_index == BUTTON_WHEEL_UP ||
- ev.mouse_button.button_index == BUTTON_WHEEL_LEFT ||
- ev.mouse_button.button_index == BUTTON_WHEEL_RIGHT));
+ Ref<InputEventMouseButton> mb = p_input;
+
+ bool cant_stop_me_now = (mb.is_valid() &&
+ (mb->get_button_index() == BUTTON_WHEEL_DOWN ||
+ mb->get_button_index() == BUTTON_WHEEL_UP ||
+ mb->get_button_index() == BUTTON_WHEEL_LEFT ||
+ mb->get_button_index() == BUTTON_WHEEL_RIGHT));
+
+ bool ismouse = ev.is_valid() || p_input->cast_to<InputEventMouseMotion>() != NULL;
CanvasItem *ci = p_control;
while (ci) {
@@ -1573,14 +1517,14 @@ void Viewport::_gui_call_input(Control *p_control, const InputEvent &p_input) {
break;
if (gui.key_event_accepted)
break;
- if (!cant_stop_me_now && control->data.mouse_filter == Control::MOUSE_FILTER_STOP && (ev.type == InputEvent::MOUSE_BUTTON || ev.type == InputEvent::MOUSE_MOTION))
+ if (!cant_stop_me_now && control->data.mouse_filter == Control::MOUSE_FILTER_STOP && ismouse)
break;
}
if (ci->is_set_as_toplevel())
break;
- ev = ev.xform_by(ci->get_transform()); //transform event upwards
+ ev = ev->xformed_by(ci->get_transform()); //transform event upwards
ci = ci->get_parent_item();
}
@@ -1718,9 +1662,9 @@ bool Viewport::_gui_drop(Control *p_at_control, Point2 p_at_pos, bool p_just_che
return false;
}
-void Viewport::_gui_input_event(InputEvent p_event) {
+void Viewport::_gui_input_event(Ref<InputEvent> p_event) {
- if (p_event.ID == gui.cancelled_input_ID) {
+ if (p_event->get_id() == gui.cancelled_input_ID) {
return;
}
//?
@@ -1730,430 +1674,427 @@ void Viewport::_gui_input_event(InputEvent p_event) {
}
*/
- switch (p_event.type) {
-
- case InputEvent::MOUSE_BUTTON: {
+ Ref<InputEventMouseButton> mb = p_event;
- gui.key_event_accepted = false;
+ if (mb.is_valid()) {
- Point2 mpos = Point2(p_event.mouse_button.x, p_event.mouse_button.y);
- if (p_event.mouse_button.pressed) {
+ gui.key_event_accepted = false;
- Size2 pos = mpos;
- if (gui.mouse_focus && p_event.mouse_button.button_index != gui.mouse_focus_button) {
+ Point2 mpos = mb->get_position();
+ if (mb->is_pressed()) {
- //do not steal mouse focus and stuff
+ Size2 pos = mpos;
+ if (gui.mouse_focus && mb->get_button_index() != gui.mouse_focus_button) {
- } else {
+ //do not steal mouse focus and stuff
- _gui_sort_modal_stack();
- while (!gui.modal_stack.empty()) {
+ } else {
- Control *top = gui.modal_stack.back()->get();
- Vector2 pos = top->get_global_transform_with_canvas().affine_inverse().xform(mpos);
- if (!top->has_point(pos)) {
+ _gui_sort_modal_stack();
+ while (!gui.modal_stack.empty()) {
- if (top->data.modal_exclusive || top->data.modal_frame == Engine::get_singleton()->get_frames_drawn()) {
- //cancel event, sorry, modal exclusive EATS UP ALL
- //alternative, you can't pop out a window the same frame it was made modal (fixes many issues)
- get_tree()->set_input_as_handled();
- return; // no one gets the event if exclusive NO ONE
- }
+ Control *top = gui.modal_stack.back()->get();
+ Vector2 pos = top->get_global_transform_with_canvas().affine_inverse().xform(mpos);
+ if (!top->has_point(pos)) {
- top->notification(Control::NOTIFICATION_MODAL_CLOSE);
- top->_modal_stack_remove();
- top->hide();
- } else {
- break;
+ if (top->data.modal_exclusive || top->data.modal_frame == Engine::get_singleton()->get_frames_drawn()) {
+ //cancel event, sorry, modal exclusive EATS UP ALL
+ //alternative, you can't pop out a window the same frame it was made modal (fixes many issues)
+ get_tree()->set_input_as_handled();
+ return; // no one gets the event if exclusive NO ONE
}
+
+ top->notification(Control::NOTIFICATION_MODAL_CLOSE);
+ top->_modal_stack_remove();
+ top->hide();
+ } else {
+ break;
}
+ }
- //Matrix32 parent_xform;
+ //Matrix32 parent_xform;
- /*
- if (data.parent_canvas_item)
- parent_xform=data.parent_canvas_item->get_global_transform();
- */
+ /*
+ if (data.parent_canvas_item)
+ parent_xform=data.parent_canvas_item->get_global_transform();
+ */
- gui.mouse_focus = _gui_find_control(pos);
- //print_line("has mf "+itos(gui.mouse_focus!=NULL));
- gui.mouse_focus_button = p_event.mouse_button.button_index;
+ gui.mouse_focus = _gui_find_control(pos);
+ //print_line("has mf "+itos(gui.mouse_focus!=NULL));
+ gui.mouse_focus_button = mb->get_button_index();
- if (!gui.mouse_focus) {
- break;
- }
+ if (!gui.mouse_focus) {
+ return;
+ }
- if (p_event.mouse_button.button_index == BUTTON_LEFT) {
- gui.drag_accum = Vector2();
- gui.drag_attempted = false;
- }
+ if (mb->get_button_index() == BUTTON_LEFT) {
+ gui.drag_accum = Vector2();
+ gui.drag_attempted = false;
}
+ }
- p_event.mouse_button.global_x = pos.x;
- p_event.mouse_button.global_y = pos.y;
+ mb = mb->xformed_by(Transform2D()); // make a copy of the event
- pos = gui.focus_inv_xform.xform(pos);
- p_event.mouse_button.x = pos.x;
- p_event.mouse_button.y = pos.y;
+ mb->set_global_position(pos);
+
+ pos = gui.focus_inv_xform.xform(pos);
+
+ mb->set_position(pos);
#ifdef DEBUG_ENABLED
- if (ScriptDebugger::get_singleton()) {
+ if (ScriptDebugger::get_singleton()) {
- Array arr;
- arr.push_back(gui.mouse_focus->get_path());
- arr.push_back(gui.mouse_focus->get_class());
- ScriptDebugger::get_singleton()->send_message("click_ctrl", arr);
- }
+ Array arr;
+ arr.push_back(gui.mouse_focus->get_path());
+ arr.push_back(gui.mouse_focus->get_class());
+ ScriptDebugger::get_singleton()->send_message("click_ctrl", arr);
+ }
/*if (bool(GLOBAL_DEF("debug/print_clicked_control",false))) {
- print_line(String(gui.mouse_focus->get_path())+" - "+pos);
- }*/
+ print_line(String(gui.mouse_focus->get_path())+" - "+pos);
+ }*/
#endif
- if (p_event.mouse_button.button_index == BUTTON_LEFT) { //assign focus
- CanvasItem *ci = gui.mouse_focus;
- while (ci) {
+ if (mb->get_button_index() == BUTTON_LEFT) { //assign focus
+ CanvasItem *ci = gui.mouse_focus;
+ while (ci) {
- Control *control = ci->cast_to<Control>();
- if (control) {
- if (control->get_focus_mode() != Control::FOCUS_NONE) {
- if (control != gui.key_focus) {
- control->grab_focus();
- }
- break;
+ Control *control = ci->cast_to<Control>();
+ if (control) {
+ if (control->get_focus_mode() != Control::FOCUS_NONE) {
+ if (control != gui.key_focus) {
+ control->grab_focus();
}
-
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
- break;
+ break;
}
- if (ci->is_set_as_toplevel())
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
break;
-
- ci = ci->get_parent_item();
}
- }
- if (gui.mouse_focus->can_process()) {
- _gui_call_input(gui.mouse_focus, p_event);
- }
+ if (ci->is_set_as_toplevel())
+ break;
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", p_event.ID);
- get_tree()->set_input_as_handled();
+ ci = ci->get_parent_item();
+ }
+ }
- if (gui.drag_data.get_type() != Variant::NIL && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ if (gui.mouse_focus->can_process()) {
+ _gui_call_input(gui.mouse_focus, mb);
+ }
- //alternate drop use (when using force_drag(), as proposed by #5342
- if (gui.mouse_focus) {
- _gui_drop(gui.mouse_focus, pos, false);
- }
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", mb->get_id());
+ get_tree()->set_input_as_handled();
- gui.drag_data = Variant();
+ if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
- if (gui.drag_preview) {
- memdelete(gui.drag_preview);
- gui.drag_preview = NULL;
- }
- _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ //alternate drop use (when using force_drag(), as proposed by #5342
+ if (gui.mouse_focus) {
+ _gui_drop(gui.mouse_focus, pos, false);
}
- _gui_cancel_tooltip();
- //gui.tooltip_popup->hide();
+ gui.drag_data = Variant();
- } else {
+ if (gui.drag_preview) {
+ memdelete(gui.drag_preview);
+ gui.drag_preview = NULL;
+ }
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
+ //change mouse accordingly
+ }
- if (gui.drag_data.get_type() != Variant::NIL && p_event.mouse_button.button_index == BUTTON_LEFT) {
+ _gui_cancel_tooltip();
+ //gui.tooltip_popup->hide();
- if (gui.mouse_over) {
- Size2 pos = mpos;
- pos = gui.focus_inv_xform.xform(pos);
+ } else {
- _gui_drop(gui.mouse_over, pos, false);
- }
+ if (gui.drag_data.get_type() != Variant::NIL && mb->get_button_index() == BUTTON_LEFT) {
- if (gui.drag_preview && p_event.mouse_button.button_index == BUTTON_LEFT) {
- memdelete(gui.drag_preview);
- gui.drag_preview = NULL;
- }
+ if (gui.mouse_over) {
+ Size2 pos = mpos;
+ pos = gui.focus_inv_xform.xform(pos);
- gui.drag_data = Variant();
- _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
- //change mouse accordingly
+ _gui_drop(gui.mouse_over, pos, false);
}
- if (!gui.mouse_focus) {
- //release event is only sent if a mouse focus (previously pressed button) exists
- break;
+ if (gui.drag_preview && mb->get_button_index() == BUTTON_LEFT) {
+ memdelete(gui.drag_preview);
+ gui.drag_preview = NULL;
}
- Size2 pos = mpos;
- p_event.mouse_button.global_x = pos.x;
- p_event.mouse_button.global_y = pos.y;
- pos = gui.focus_inv_xform.xform(pos);
- p_event.mouse_button.x = pos.x;
- p_event.mouse_button.y = pos.y;
+ gui.drag_data = Variant();
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_END);
+ //change mouse accordingly
+ }
- if (gui.mouse_focus->can_process()) {
- _gui_call_input(gui.mouse_focus, p_event);
- }
+ if (!gui.mouse_focus) {
+ //release event is only sent if a mouse focus (previously pressed button) exists
+ return;
+ }
- if (p_event.mouse_button.button_index == gui.mouse_focus_button) {
- gui.mouse_focus = NULL;
- gui.mouse_focus_button = -1;
- }
+ Size2 pos = mpos;
- /*if (gui.drag_data.get_type()!=Variant::NIL && p_event.mouse_button.button_index==BUTTON_LEFT) {
- _propagate_viewport_notification(this,NOTIFICATION_DRAG_END);
- gui.drag_data=Variant(); //always clear
- }*/
+ mb = mb->xformed_by(Transform2D()); //make a copy
+ mb->set_global_position(pos);
+ pos = gui.focus_inv_xform.xform(pos);
+ mb->set_position(pos);
- get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", p_event.ID);
- get_tree()->set_input_as_handled();
+ if (gui.mouse_focus->can_process()) {
+ _gui_call_input(gui.mouse_focus, mb);
}
- } break;
- case InputEvent::MOUSE_MOTION: {
- gui.key_event_accepted = false;
- Point2 mpos = Point2(p_event.mouse_motion.x, p_event.mouse_motion.y);
+ if (mb->get_button_index() == gui.mouse_focus_button) {
+ gui.mouse_focus = NULL;
+ gui.mouse_focus_button = -1;
+ }
- gui.last_mouse_pos = mpos;
+ /*if (gui.drag_data.get_type()!=Variant::NIL && mb->get_button_index()==BUTTON_LEFT) {
+ _propagate_viewport_notification(this,NOTIFICATION_DRAG_END);
+ gui.drag_data=Variant(); //always clear
+ }*/
- Control *over = NULL;
+ get_tree()->call_group_flags(SceneTree::GROUP_CALL_REALTIME, "windows", "_cancel_input_ID", mb->get_id());
+ get_tree()->set_input_as_handled();
+ }
+ }
- // D&D
- if (!gui.drag_attempted && gui.mouse_focus && p_event.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ Ref<InputEventMouseMotion> mm = p_event;
- gui.drag_accum += Point2(p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y);
- float len = gui.drag_accum.length();
- if (len > 10) {
+ if (mm.is_valid()) {
- { //attempt grab, try parent controls too
- CanvasItem *ci = gui.mouse_focus;
- while (ci) {
+ gui.key_event_accepted = false;
+ Point2 mpos = mm->get_position();
- Control *control = ci->cast_to<Control>();
- if (control) {
+ gui.last_mouse_pos = mpos;
- gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos) - gui.drag_accum);
- if (gui.drag_data.get_type() != Variant::NIL) {
+ Control *over = NULL;
- gui.mouse_focus = NULL;
- }
+ // D&D
+ if (!gui.drag_attempted && gui.mouse_focus && mm->get_button_mask() & BUTTON_MASK_LEFT) {
- if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
- break;
+ gui.drag_accum += mm->get_relative();
+ float len = gui.drag_accum.length();
+ if (len > 10) {
+
+ { //attempt grab, try parent controls too
+ CanvasItem *ci = gui.mouse_focus;
+ while (ci) {
+
+ Control *control = ci->cast_to<Control>();
+ if (control) {
+
+ gui.drag_data = control->get_drag_data(control->get_global_transform_with_canvas().affine_inverse().xform(mpos) - gui.drag_accum);
+ if (gui.drag_data.get_type() != Variant::NIL) {
+
+ gui.mouse_focus = NULL;
}
- if (ci->is_set_as_toplevel())
+ if (control->data.mouse_filter == Control::MOUSE_FILTER_STOP)
break;
-
- ci = ci->get_parent_item();
}
- }
- gui.drag_attempted = true;
- if (gui.drag_data.get_type() != Variant::NIL) {
+ if (ci->is_set_as_toplevel())
+ break;
- _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
+ ci = ci->get_parent_item();
}
}
+
+ gui.drag_attempted = true;
+ if (gui.drag_data.get_type() != Variant::NIL) {
+
+ _propagate_viewport_notification(this, NOTIFICATION_DRAG_BEGIN);
+ }
}
+ }
- if (gui.mouse_focus) {
- over = gui.mouse_focus;
- //recompute focus_inv_xform again here
+ if (gui.mouse_focus) {
+ over = gui.mouse_focus;
+ //recompute focus_inv_xform again here
- } else {
+ } else {
- over = _gui_find_control(mpos);
- }
+ over = _gui_find_control(mpos);
+ }
- if (gui.drag_data.get_type() == Variant::NIL && over && !gui.modal_stack.empty()) {
+ if (gui.drag_data.get_type() == Variant::NIL && over && !gui.modal_stack.empty()) {
- Control *top = gui.modal_stack.back()->get();
- if (over != top && !top->is_a_parent_of(over)) {
+ Control *top = gui.modal_stack.back()->get();
+ if (over != top && !top->is_a_parent_of(over)) {
- break; // don't send motion event to anything below modal stack top
- }
+ return; // don't send motion event to anything below modal stack top
}
+ }
- if (over != gui.mouse_over) {
+ if (over != gui.mouse_over) {
- if (gui.mouse_over)
- gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT);
+ if (gui.mouse_over)
+ gui.mouse_over->notification(Control::NOTIFICATION_MOUSE_EXIT);
- _gui_cancel_tooltip();
+ _gui_cancel_tooltip();
- if (over)
- over->notification(Control::NOTIFICATION_MOUSE_ENTER);
- }
+ if (over)
+ over->notification(Control::NOTIFICATION_MOUSE_ENTER);
+ }
- gui.mouse_over = over;
+ gui.mouse_over = over;
- if (gui.drag_preview) {
- gui.drag_preview->set_position(mpos);
- }
+ if (gui.drag_preview) {
+ gui.drag_preview->set_position(mpos);
+ }
- if (!over) {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_ARROW);
- break;
- }
+ if (!over) {
+ OS::get_singleton()->set_cursor_shape(OS::CURSOR_ARROW);
+ return;
+ }
- Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
- Size2 pos = localizer.xform(mpos);
- Vector2 speed = localizer.basis_xform(Point2(p_event.mouse_motion.speed_x, p_event.mouse_motion.speed_y));
- Vector2 rel = localizer.basis_xform(Point2(p_event.mouse_motion.relative_x, p_event.mouse_motion.relative_y));
+ Transform2D localizer = over->get_global_transform_with_canvas().affine_inverse();
+ Size2 pos = localizer.xform(mpos);
+ Vector2 speed = localizer.basis_xform(mm->get_speed());
+ Vector2 rel = localizer.basis_xform(mm->get_relative());
- p_event.mouse_motion.global_x = mpos.x;
- p_event.mouse_motion.global_y = mpos.y;
- p_event.mouse_motion.speed_x = speed.x;
- p_event.mouse_motion.speed_y = speed.y;
- p_event.mouse_motion.relative_x = rel.x;
- p_event.mouse_motion.relative_y = rel.y;
+ mm = mm->xformed_by(Transform2D()); //make a copy
- if (p_event.mouse_motion.button_mask == 0) {
- //nothing pressed
+ mm->set_global_position(mpos);
+ mm->set_speed(speed);
+ mm->set_relative(rel);
- bool can_tooltip = true;
+ if (mm->get_button_mask() == 0) {
+ //nothing pressed
- if (!gui.modal_stack.empty()) {
- if (gui.modal_stack.back()->get() != over && !gui.modal_stack.back()->get()->is_a_parent_of(over))
- can_tooltip = false;
- }
+ bool can_tooltip = true;
+
+ if (!gui.modal_stack.empty()) {
+ if (gui.modal_stack.back()->get() != over && !gui.modal_stack.back()->get()->is_a_parent_of(over))
+ can_tooltip = false;
+ }
- bool is_tooltip_shown = false;
+ bool is_tooltip_shown = false;
- if (gui.tooltip_popup) {
- if (can_tooltip) {
- String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos));
+ if (gui.tooltip_popup) {
+ if (can_tooltip) {
+ String tooltip = over->get_tooltip(gui.tooltip->get_global_transform().xform_inv(mpos));
- if (tooltip.length() == 0)
- _gui_cancel_tooltip();
- else if (tooltip == gui.tooltip_label->get_text())
- is_tooltip_shown = true;
- } else
+ if (tooltip.length() == 0)
_gui_cancel_tooltip();
- }
+ else if (tooltip == gui.tooltip_label->get_text())
+ is_tooltip_shown = true;
+ } else
+ _gui_cancel_tooltip();
+ }
- if (can_tooltip && !is_tooltip_shown) {
+ if (can_tooltip && !is_tooltip_shown) {
- gui.tooltip = over;
- gui.tooltip_pos = mpos; //(parent_xform * get_transform()).affine_inverse().xform(pos);
- gui.tooltip_timer = gui.tooltip_delay;
- }
+ gui.tooltip = over;
+ gui.tooltip_pos = mpos; //(parent_xform * get_transform()).affine_inverse().xform(pos);
+ gui.tooltip_timer = gui.tooltip_delay;
}
+ }
- //pos = gui.focus_inv_xform.xform(pos);
+ //pos = gui.focus_inv_xform.xform(pos);
- p_event.mouse_motion.x = pos.x;
- p_event.mouse_motion.y = pos.y;
+ mm->set_position(pos);
- Control::CursorShape cursor_shape = over->get_cursor_shape(pos);
- OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape);
+ Control::CursorShape cursor_shape = over->get_cursor_shape(pos);
+ OS::get_singleton()->set_cursor_shape((OS::CursorShape)cursor_shape);
- if (over->can_process()) {
- _gui_call_input(over, p_event);
- }
+ if (over->can_process()) {
+ _gui_call_input(over, mm);
+ }
- get_tree()->set_input_as_handled();
+ get_tree()->set_input_as_handled();
- if (gui.drag_data.get_type() != Variant::NIL && p_event.mouse_motion.button_mask & BUTTON_MASK_LEFT) {
+ if (gui.drag_data.get_type() != Variant::NIL && mm->get_button_mask() & BUTTON_MASK_LEFT) {
- bool can_drop = _gui_drop(over, pos, true);
+ bool can_drop = _gui_drop(over, pos, true);
- if (!can_drop) {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_FORBIDDEN);
- } else {
- OS::get_singleton()->set_cursor_shape(OS::CURSOR_CAN_DROP);
- }
- //change mouse accordingly i guess
+ if (!can_drop) {
+ OS::get_singleton()->set_cursor_shape(OS::CURSOR_FORBIDDEN);
+ } else {
+ OS::get_singleton()->set_cursor_shape(OS::CURSOR_CAN_DROP);
}
+ //change mouse accordingly i guess
+ }
+ }
- } break;
- case InputEvent::ACTION:
- case InputEvent::JOYPAD_BUTTON:
- case InputEvent::JOYPAD_MOTION:
- case InputEvent::KEY: {
+ if (mm.is_null() && mb.is_null() && p_event->is_action_type()) {
- if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) {
- gui.key_focus->release_focus();
- }
+ if (gui.key_focus && !gui.key_focus->is_visible_in_tree()) {
+ gui.key_focus->release_focus();
+ }
- if (gui.key_focus) {
+ if (gui.key_focus) {
- gui.key_event_accepted = false;
- if (gui.key_focus->can_process()) {
- gui.key_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, p_event);
- if (gui.key_focus) //maybe lost it
- gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event);
- }
+ gui.key_event_accepted = false;
+ if (gui.key_focus->can_process()) {
+ gui.key_focus->call_multilevel(SceneStringNames::get_singleton()->_gui_input, p_event);
+ if (gui.key_focus) //maybe lost it
+ gui.key_focus->emit_signal(SceneStringNames::get_singleton()->gui_input, p_event);
+ }
- if (gui.key_event_accepted) {
+ if (gui.key_event_accepted) {
- get_tree()->set_input_as_handled();
- break;
- }
+ get_tree()->set_input_as_handled();
+ return;
}
+ }
- if (p_event.is_pressed() && p_event.is_action("ui_cancel") && !gui.modal_stack.empty()) {
+ if (p_event->is_pressed() && p_event->is_action("ui_cancel") && !gui.modal_stack.empty()) {
- _gui_sort_modal_stack();
- Control *top = gui.modal_stack.back()->get();
- if (!top->data.modal_exclusive) {
+ _gui_sort_modal_stack();
+ Control *top = gui.modal_stack.back()->get();
+ if (!top->data.modal_exclusive) {
- top->notification(Control::NOTIFICATION_MODAL_CLOSE);
- top->_modal_stack_remove();
- top->hide();
- }
+ top->notification(Control::NOTIFICATION_MODAL_CLOSE);
+ top->_modal_stack_remove();
+ top->hide();
}
+ }
- Control *from = gui.key_focus ? gui.key_focus : NULL; //hmm
+ Control *from = gui.key_focus ? gui.key_focus : NULL; //hmm
- //keyboard focus
- //if (from && p_event.key.pressed && !p_event.key.mod.alt && !p_event.key.mod.meta && !p_event.key.mod.command) {
+ //keyboard focus
+ //if (from && p_event->is_pressed() && !p_event->get_alt() && !p_event->get_metakey() && !p_event->key->get_command()) {
- if (from && p_event.is_pressed()) {
- Control *next = NULL;
+ if (from && p_event->is_pressed()) {
+ Control *next = NULL;
- if (p_event.is_action("ui_focus_next")) {
+ if (p_event->is_action("ui_focus_next")) {
- next = from->find_next_valid_focus();
- }
+ next = from->find_next_valid_focus();
+ }
- if (p_event.is_action("ui_focus_prev")) {
+ if (p_event->is_action("ui_focus_prev")) {
- next = from->find_prev_valid_focus();
- }
-
- if (p_event.is_action("ui_up")) {
+ next = from->find_prev_valid_focus();
+ }
- next = from->_get_focus_neighbour(MARGIN_TOP);
- }
+ if (p_event->is_action("ui_up")) {
- if (p_event.is_action("ui_left")) {
+ next = from->_get_focus_neighbour(MARGIN_TOP);
+ }
- next = from->_get_focus_neighbour(MARGIN_LEFT);
- }
+ if (p_event->is_action("ui_left")) {
- if (p_event.is_action("ui_right")) {
+ next = from->_get_focus_neighbour(MARGIN_LEFT);
+ }
- next = from->_get_focus_neighbour(MARGIN_RIGHT);
- }
+ if (p_event->is_action("ui_right")) {
- if (p_event.is_action("ui_down")) {
+ next = from->_get_focus_neighbour(MARGIN_RIGHT);
+ }
- next = from->_get_focus_neighbour(MARGIN_BOTTOM);
- }
+ if (p_event->is_action("ui_down")) {
- if (next) {
- next->grab_focus();
- get_tree()->set_input_as_handled();
- }
+ next = from->_get_focus_neighbour(MARGIN_BOTTOM);
}
- } break;
+ if (next) {
+ next->grab_focus();
+ get_tree()->set_input_as_handled();
+ }
+ }
}
}
@@ -2366,33 +2307,30 @@ void Viewport::_gui_grab_click_focus(Control *p_control) {
if (gui.mouse_focus == p_control)
return;
- InputEvent ie;
- ie.type = InputEvent::MOUSE_BUTTON;
- InputEventMouseButton &mb = ie.mouse_button;
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
//send unclic
Point2 click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
- mb.x = click.x;
- mb.y = click.y;
- mb.button_index = gui.mouse_focus_button;
- mb.pressed = false;
- gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, ie);
+ mb->set_position(click);
+ mb->set_button_index(gui.mouse_focus_button);
+ mb->set_pressed(false);
+ gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb);
gui.mouse_focus = p_control;
gui.focus_inv_xform = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse();
click = gui.mouse_focus->get_global_transform_with_canvas().affine_inverse().xform(gui.last_mouse_pos);
- mb.x = click.x;
- mb.y = click.y;
- mb.button_index = gui.mouse_focus_button;
- mb.pressed = true;
- gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, ie);
+ mb->set_position(click);
+ mb->set_button_index(gui.mouse_focus_button);
+ mb->set_pressed(true);
+ gui.mouse_focus->call_deferred(SceneStringNames::get_singleton()->_gui_input, mb);
}
}
///////////////////////////////
-void Viewport::input(const InputEvent &p_event) {
+void Viewport::input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(!is_inside_tree());
@@ -2401,20 +2339,20 @@ void Viewport::input(const InputEvent &p_event) {
//get_tree()->call_group(SceneTree::GROUP_CALL_REVERSE|SceneTree::GROUP_CALL_REALTIME|SceneTree::GROUP_CALL_MULIILEVEL,gui_input_group,"_gui_input",p_event); //special one for GUI, as controls use their own process check
}
-void Viewport::unhandled_input(const InputEvent &p_event) {
+void Viewport::unhandled_input(const Ref<InputEvent> &p_event) {
ERR_FAIL_COND(!is_inside_tree());
get_tree()->_call_input_pause(unhandled_input_group, "_unhandled_input", p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_input","_unhandled_input",ev);
- if (!get_tree()->input_handled && p_event.type == InputEvent::KEY) {
+ if (!get_tree()->input_handled && p_event->cast_to<InputEventKey>() != NULL) {
get_tree()->_call_input_pause(unhandled_key_input_group, "_unhandled_key_input", p_event);
//call_group(GROUP_CALL_REVERSE|GROUP_CALL_REALTIME|GROUP_CALL_MULIILEVEL,"unhandled_key_input","_unhandled_key_input",ev);
}
if (physics_object_picking && !get_tree()->input_handled) {
- if (p_event.type == InputEvent::MOUSE_BUTTON || p_event.type == InputEvent::MOUSE_MOTION || p_event.type == InputEvent::SCREEN_DRAG || p_event.type == InputEvent::SCREEN_TOUCH) {
+ if (p_event->cast_to<InputEventMouseButton>() || p_event->cast_to<InputEventMouseMotion>() || p_event->cast_to<InputEventScreenDrag>() || p_event->cast_to<InputEventScreenTouch>()) {
physics_picking_events.push_back(p_event);
}
}
@@ -2573,6 +2511,32 @@ bool Viewport::get_hdr() const {
return hdr;
}
+void Viewport::set_usage(Usage p_usage) {
+
+ usage = p_usage;
+ VS::get_singleton()->viewport_set_usage(viewport, VS::ViewportUsage(p_usage));
+}
+
+Viewport::Usage Viewport::get_usage() const {
+ return usage;
+}
+
+void Viewport::set_debug_draw(DebugDraw p_debug_draw) {
+
+ debug_draw = p_debug_draw;
+ VS::get_singleton()->viewport_set_debug_draw(viewport, VS::ViewportDebugDraw(p_debug_draw));
+}
+
+Viewport::DebugDraw Viewport::get_debug_draw() const {
+
+ return debug_draw;
+}
+
+int Viewport::get_render_info(RenderInfo p_info) {
+
+ return VS::get_singleton()->viewport_get_render_info(viewport, VS::ViewportRenderInfo(p_info));
+}
+
void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_size", "size"), &Viewport::set_size);
@@ -2607,8 +2571,6 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("is_size_override_enabled"), &Viewport::is_size_override_enabled);
ClassDB::bind_method(D_METHOD("set_size_override_stretch", "enabled"), &Viewport::set_size_override_stretch);
ClassDB::bind_method(D_METHOD("is_size_override_stretch_enabled"), &Viewport::is_size_override_stretch_enabled);
- ClassDB::bind_method(D_METHOD("queue_screen_capture"), &Viewport::queue_screen_capture);
- ClassDB::bind_method(D_METHOD("get_screen_capture"), &Viewport::get_screen_capture);
ClassDB::bind_method(D_METHOD("set_vflip", "enable"), &Viewport::set_vflip);
ClassDB::bind_method(D_METHOD("get_vflip"), &Viewport::get_vflip);
@@ -2626,6 +2588,14 @@ void Viewport::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_hdr", "enable"), &Viewport::set_hdr);
ClassDB::bind_method(D_METHOD("get_hdr"), &Viewport::get_hdr);
+ ClassDB::bind_method(D_METHOD("set_usage", "usage"), &Viewport::set_usage);
+ ClassDB::bind_method(D_METHOD("get_usage"), &Viewport::get_usage);
+
+ ClassDB::bind_method(D_METHOD("set_debug_draw", "debug_draw"), &Viewport::set_debug_draw);
+ ClassDB::bind_method(D_METHOD("get_debug_draw"), &Viewport::get_debug_draw);
+
+ ClassDB::bind_method(D_METHOD("get_render_info", "info"), &Viewport::get_render_info);
+
ClassDB::bind_method(D_METHOD("get_texture:ViewportTexture"), &Viewport::get_texture);
ClassDB::bind_method(D_METHOD("set_physics_object_picking", "enable"), &Viewport::set_physics_object_picking);
@@ -2679,6 +2649,8 @@ void Viewport::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT, "msaa", PROPERTY_HINT_ENUM, "Disabled,2x,4x,8x,16x"), "set_msaa", "get_msaa");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "hdr"), "set_hdr", "get_hdr");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "disable_3d"), "set_disable_3d", "is_3d_disabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "usage", PROPERTY_HINT_ENUM, "2D,2D No-Sampling,3D,3D No-Effects"), "set_usage", "get_usage");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "debug_draw", PROPERTY_HINT_ENUM, "Disabled,Unshaded,Overdraw,Wireframe"), "set_debug_draw", "get_debug_draw");
ADD_GROUP("Render Target", "render_target_");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_v_flip"), "set_vflip", "get_vflip");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "render_target_clear_on_new_frame"), "set_clear_on_new_frame", "get_clear_on_new_frame");
@@ -2713,6 +2685,19 @@ void Viewport::_bind_methods() {
BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_1024);
BIND_CONSTANT(SHADOW_ATLAS_QUADRANT_SUBDIV_MAX);
+ BIND_CONSTANT(RENDER_INFO_OBJECTS_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_VERTICES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_MATERIAL_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_SHADER_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_SURFACE_CHANGES_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_DRAW_CALLS_IN_FRAME);
+ BIND_CONSTANT(RENDER_INFO_MAX);
+
+ BIND_CONSTANT(DEBUG_DRAW_DISABLED);
+ BIND_CONSTANT(DEBUG_DRAW_UNSHADED);
+ BIND_CONSTANT(DEBUG_DRAW_OVERDRAW);
+ BIND_CONSTANT(DEBUG_DRAW_WIREFRAME);
+
BIND_CONSTANT(MSAA_DISABLED);
BIND_CONSTANT(MSAA_2X);
BIND_CONSTANT(MSAA_4X);
@@ -2787,6 +2772,9 @@ Viewport::Viewport() {
msaa = MSAA_DISABLED;
hdr = false;
+
+ usage = USAGE_3D;
+ debug_draw = DEBUG_DRAW_DISABLED;
}
Viewport::~Viewport() {
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index d784fc8ee9..bd9747d878 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -77,6 +77,8 @@ public:
virtual void set_flags(uint32_t p_flags);
virtual uint32_t get_flags() const;
+ virtual Ref<Image> get_data() const;
+
ViewportTexture();
~ViewportTexture();
};
@@ -113,6 +115,31 @@ public:
MSAA_16X,
};
+ enum Usage {
+ USAGE_2D,
+ USAGE_2D_NO_SAMPLING,
+ USAGE_3D,
+ USAGE_3D_NO_EFFECTS,
+ };
+
+ enum RenderInfo {
+
+ RENDER_INFO_OBJECTS_IN_FRAME,
+ RENDER_INFO_VERTICES_IN_FRAME,
+ RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
+ RENDER_INFO_SHADER_CHANGES_IN_FRAME,
+ RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
+ RENDER_INFO_DRAW_CALLS_IN_FRAME,
+ RENDER_INFO_MAX
+ };
+
+ enum DebugDraw {
+ DEBUG_DRAW_DISABLED,
+ DEBUG_DRAW_UNSHADED,
+ DEBUG_DRAW_OVERDRAW,
+ DEBUG_DRAW_WIREFRAME,
+ };
+
private:
friend class ViewportTexture;
@@ -158,7 +185,7 @@ private:
bool gen_mipmaps;
bool physics_object_picking;
- List<InputEvent> physics_picking_events;
+ List<Ref<InputEvent> > physics_picking_events;
ObjectID physics_object_capture;
ObjectID physics_object_over;
Vector2 physics_last_mousepos;
@@ -195,6 +222,10 @@ private:
RID texture_rid;
uint32_t texture_flags;
+ DebugDraw debug_draw;
+
+ Usage usage;
+
int shadow_atlas_size;
ShadowAtlasQuadrantSubdiv shadow_atlas_quadrant_subdiv[4];
@@ -237,14 +268,14 @@ private:
bool disable_input;
- void _gui_call_input(Control *p_control, const InputEvent &p_input);
+ void _gui_call_input(Control *p_control, const Ref<InputEvent> &p_input);
void _gui_sort_subwindows();
void _gui_sort_roots();
void _gui_sort_modal_stack();
Control *_gui_find_control(const Point2 &p_global);
Control *_gui_find_control_at_pos(CanvasItem *p_node, const Point2 &p_global, const Transform2D &p_xform, Transform2D &r_inv_xform);
- void _gui_input_event(InputEvent p_event);
+ void _gui_input_event(Ref<InputEvent> p_event);
void update_worlds();
@@ -253,10 +284,10 @@ private:
void _vp_enter_tree();
void _vp_exit_tree();
- void _vp_input(const InputEvent &p_ev);
+ void _vp_input(const Ref<InputEvent> &p_ev);
void _vp_input_text(const String &p_text);
- void _vp_unhandled_input(const InputEvent &p_ev);
- void _make_input_local(InputEvent &ev);
+ void _vp_unhandled_input(const Ref<InputEvent> &p_ev);
+ Ref<InputEvent> _make_input_local(const Ref<InputEvent> &ev);
friend class Control;
@@ -382,14 +413,11 @@ public:
Vector2 get_camera_coords(const Vector2 &p_viewport_coords) const;
Vector2 get_camera_rect_size() const;
- void queue_screen_capture();
- Image get_screen_capture() const;
-
void set_use_own_world(bool p_world);
bool is_using_own_world() const;
- void input(const InputEvent &p_event);
- void unhandled_input(const InputEvent &p_event);
+ void input(const Ref<InputEvent> &p_event);
+ void unhandled_input(const Ref<InputEvent> &p_event);
void set_disable_input(bool p_disable);
bool is_input_disabled() const;
@@ -416,6 +444,14 @@ public:
virtual String get_configuration_warning() const;
+ void set_usage(Usage p_usage);
+ Usage get_usage() const;
+
+ void set_debug_draw(DebugDraw p_debug_draw);
+ DebugDraw get_debug_draw() const;
+
+ int get_render_info(RenderInfo p_info);
+
Viewport();
~Viewport();
};
@@ -423,5 +459,8 @@ public:
VARIANT_ENUM_CAST(Viewport::UpdateMode);
VARIANT_ENUM_CAST(Viewport::ShadowAtlasQuadrantSubdiv);
VARIANT_ENUM_CAST(Viewport::MSAA);
+VARIANT_ENUM_CAST(Viewport::Usage);
+VARIANT_ENUM_CAST(Viewport::DebugDraw);
+VARIANT_ENUM_CAST(Viewport::RenderInfo);
#endif
diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp
index 513aa8153d..b2737353fb 100644
--- a/scene/register_scene_types.cpp
+++ b/scene/register_scene_types.cpp
@@ -42,7 +42,7 @@
#include "scene/2d/path_2d.h"
#include "scene/gui/box_container.h"
#include "scene/gui/button.h"
-#include "scene/gui/button_array.h"
+
#include "scene/gui/button_group.h"
#include "scene/gui/center_container.h"
#include "scene/gui/check_box.h"
@@ -74,7 +74,6 @@
#include "scene/gui/separator.h"
#include "scene/gui/slider.h"
#include "scene/gui/spin_box.h"
-#include "scene/gui/spin_box.h"
#include "scene/gui/split_container.h"
#include "scene/gui/tab_container.h"
#include "scene/gui/tabs.h"
@@ -112,6 +111,7 @@
#include "scene/2d/ray_cast_2d.h"
//#include "scene/2d/sound_player_2d.h"
//#include "scene/2d/sample_player_2d.h"
+#include "scene/2d/audio_stream_player_2d.h"
#include "scene/2d/canvas_modulate.h"
#include "scene/2d/navigation2d.h"
#include "scene/2d/remote_transform_2d.h"
@@ -130,7 +130,6 @@
#include "scene/animation/tween.h"
#include "scene/main/resource_preloader.h"
#include "scene/main/scene_main_loop.h"
-#include "scene/main/scene_main_loop.h"
#include "scene/resources/packed_scene.h"
#include "scene/resources/mesh_data_tool.h"
@@ -172,6 +171,8 @@
#include "scene/resources/sky_box.h"
#include "scene/resources/texture.h"
+#include "scene/resources/primitive_meshes.h"
+
#include "scene/resources/shader_graph.h"
#include "scene/resources/world.h"
@@ -206,13 +207,11 @@
#include "scene/3d/physics_body.h"
#include "scene/3d/portal.h"
#include "scene/3d/position_3d.h"
-#include "scene/3d/quad.h"
#include "scene/3d/reflection_probe.h"
-#include "scene/3d/test_cube.h"
#include "scene/resources/environment.h"
#include "scene/3d/area.h"
-#include "scene/3d/baked_light_instance.h"
+
#include "scene/3d/body_shape.h"
#include "scene/3d/immediate_geometry.h"
#include "scene/3d/multimesh_instance.h"
@@ -276,7 +275,7 @@ void register_scene_types() {
String theme_path = GLOBAL_DEF("gui/theme/custom", "");
GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom", PropertyInfo(Variant::STRING, "gui/theme/custom", PROPERTY_HINT_FILE, "*.tres,*.res", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
String font_path = GLOBAL_DEF("gui/theme/custom_font", "");
- GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.fnt", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
+ GlobalConfig::get_singleton()->set_custom_property_info("gui/theme/custom_font", PropertyInfo(Variant::STRING, "gui/theme/custom_font", PROPERTY_HINT_FILE, "*.tres,*.res,*.font", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_RESTART_IF_CHANGED));
if (theme_path != String()) {
Ref<Theme> theme = ResourceLoader::load(theme_path);
@@ -360,9 +359,6 @@ void register_scene_types() {
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_virtual_class<ButtonArray>();
- ClassDB::register_class<HButtonArray>();
- ClassDB::register_class<VButtonArray>();
ClassDB::register_class<TextureProgress>();
ClassDB::register_class<ItemList>();
@@ -410,7 +406,6 @@ void register_scene_types() {
ClassDB::register_class<Camera>();
ClassDB::register_class<Listener>();
ClassDB::register_class<InterpolatedCamera>();
- ClassDB::register_class<TestCube>();
ClassDB::register_class<MeshInstance>();
ClassDB::register_class<ImmediateGeometry>();
ClassDB::register_class<Sprite3D>();
@@ -426,7 +421,6 @@ void register_scene_types() {
ClassDB::register_class<Portal>();
ClassDB::register_class<Particles>();
ClassDB::register_class<Position3D>();
- ClassDB::register_class<Quad>();
ClassDB::register_class<NavigationMeshInstance>();
ClassDB::register_class<NavigationMesh>();
ClassDB::register_class<Navigation>();
@@ -452,7 +446,7 @@ void register_scene_types() {
ClassDB::register_class<PathFollow>();
ClassDB::register_class<VisibilityNotifier>();
ClassDB::register_class<VisibilityEnabler>();
- ClassDB::register_class<BakedLight>();
+ // ClassDB::register_class<BakedLight>();
//ClassDB::register_type<BakedLightSampler>();
ClassDB::register_class<WorldEnvironment>();
ClassDB::register_class<RemoteTransform>();
@@ -523,11 +517,20 @@ void register_scene_types() {
ClassDB::register_virtual_class<Shader>();
#ifndef _3D_DISABLED
- ClassDB::register_class<Mesh>();
+ ClassDB::register_virtual_class<Mesh>();
+ ClassDB::register_class<ArrayMesh>();
+ ClassDB::register_virtual_class<PrimitiveMesh>();
+ ClassDB::register_class<CapsuleMesh>();
+ ClassDB::register_class<CubeMesh>();
+ ClassDB::register_class<CylinderMesh>();
+ ClassDB::register_class<PlaneMesh>();
+ ClassDB::register_class<PrismMesh>();
ClassDB::register_class<QuadMesh>();
+ ClassDB::register_class<SphereMesh>();
ClassDB::register_virtual_class<Material>();
ClassDB::register_class<SpatialMaterial>();
ClassDB::add_compatibility_class("FixedSpatialMaterial", "SpatialMaterial");
+ ClassDB::add_compatibility_class("Mesh", "ArrayMesh");
SceneTree::add_idle_callback(SpatialMaterial::flush_changes);
SpatialMaterial::init_shaders();
@@ -561,8 +564,9 @@ void register_scene_types() {
ClassDB::register_class<Environment>();
ClassDB::register_class<World2D>();
ClassDB::register_virtual_class<Texture>();
- ClassDB::register_virtual_class<SkyBox>();
- ClassDB::register_class<ImageSkyBox>();
+ ClassDB::register_virtual_class<Sky>();
+ ClassDB::register_class<PanoramaSky>();
+ ClassDB::register_class<ProceduralSky>();
ClassDB::register_class<StreamTexture>();
ClassDB::register_class<ImageTexture>();
ClassDB::register_class<AtlasTexture>();
@@ -584,11 +588,12 @@ void register_scene_types() {
ClassDB::register_class<PolygonPathFinder>();
ClassDB::register_class<BitMap>();
- ClassDB::register_class<ColorRamp>();
+ ClassDB::register_class<Gradient>();
OS::get_singleton()->yield(); //may take time to init
- ClassDB::register_class<AudioPlayer>();
+ ClassDB::register_class<AudioStreamPlayer>();
+ ClassDB::register_class<AudioStreamPlayer2D>();
ClassDB::register_virtual_class<VideoStream>();
ClassDB::register_class<AudioStreamSample>();
diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp
index 545c700354..459d3ffe41 100644
--- a/scene/resources/animation.cpp
+++ b/scene/resources/animation.cpp
@@ -1133,7 +1133,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
Rect2 pb = p_post_b;
return Rect2(
- a.pos.cubic_interpolate(b.pos, pa.pos, pb.pos, p_c),
+ a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
} break;
@@ -1165,7 +1165,7 @@ Variant Animation::_cubic_interpolate(const Variant &p_pre_a, const Variant &p_a
Rect3 pb = p_post_b;
return Rect3(
- a.pos.cubic_interpolate(b.pos, pa.pos, pb.pos, p_c),
+ a.position.cubic_interpolate(b.position, pa.position, pb.position, p_c),
a.size.cubic_interpolate(b.size, pa.size, pb.size, p_c));
} break;
default: {
diff --git a/scene/resources/animation.h b/scene/resources/animation.h
index ef5befac65..b363f2b666 100644
--- a/scene/resources/animation.h
+++ b/scene/resources/animation.h
@@ -37,7 +37,7 @@
class Animation : public Resource {
GDCLASS(Animation, Resource);
- RES_BASE_EXTENSION("anm");
+ RES_BASE_EXTENSION("anim");
public:
enum TrackType {
diff --git a/scene/resources/audio_stream_sample.h b/scene/resources/audio_stream_sample.h
index 84d450e3f2..cd02df512f 100644
--- a/scene/resources/audio_stream_sample.h
+++ b/scene/resources/audio_stream_sample.h
@@ -84,7 +84,7 @@ public:
class AudioStreamSample : public AudioStream {
GDCLASS(AudioStreamSample, AudioStream)
- RES_BASE_EXTENSION("smp")
+ RES_BASE_EXTENSION("sample")
public:
enum Format {
diff --git a/scene/resources/baked_light.cpp b/scene/resources/baked_light.cpp
deleted file mode 100644
index 1d896e640a..0000000000
--- a/scene/resources/baked_light.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/*************************************************************************/
-/* baked_light.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 "baked_light.h"
-#include "servers/visual_server.h"
diff --git a/scene/resources/bit_mask.cpp b/scene/resources/bit_mask.cpp
index b8a9ea3361..a473067937 100644
--- a/scene/resources/bit_mask.cpp
+++ b/scene/resources/bit_mask.cpp
@@ -41,16 +41,16 @@ void BitMap::create(const Size2 &p_size) {
zeromem(bitmask.ptr(), bitmask.size());
}
-void BitMap::create_from_image_alpha(const Image &p_image) {
+void BitMap::create_from_image_alpha(const Ref<Image> &p_image) {
- ERR_FAIL_COND(p_image.empty());
- Image img = p_image;
- img.convert(Image::FORMAT_LA8);
- ERR_FAIL_COND(img.get_format() != Image::FORMAT_LA8);
+ ERR_FAIL_COND(p_image.is_null() || p_image->empty());
+ Ref<Image> img = p_image->duplicate();
+ img->convert(Image::FORMAT_LA8);
+ ERR_FAIL_COND(img->get_format() != Image::FORMAT_LA8);
- create(Size2(img.get_width(), img.get_height()));
+ create(Size2(img->get_width(), img->get_height()));
- PoolVector<uint8_t>::Read r = img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
uint8_t *w = bitmask.ptr();
for (int i = 0; i < width * height; i++) {
@@ -67,9 +67,9 @@ void BitMap::set_bit_rect(const Rect2 &p_rect, bool p_value) {
Rect2i current = Rect2i(0, 0, width, height).clip(p_rect);
uint8_t *data = bitmask.ptr();
- for (int i = current.pos.x; i < current.pos.x + current.size.x; i++) {
+ for (int i = current.position.x; i < current.position.x + current.size.x; i++) {
- for (int j = current.pos.y; j < current.pos.y + current.size.y; j++) {
+ for (int j = current.position.y; j < current.position.y + current.size.y; j++) {
int ofs = width * j + i;
int bbyte = ofs / 8;
diff --git a/scene/resources/bit_mask.h b/scene/resources/bit_mask.h
index 78da6ce0d8..5ab7a3134d 100644
--- a/scene/resources/bit_mask.h
+++ b/scene/resources/bit_mask.h
@@ -30,6 +30,7 @@
#ifndef BIT_MASK_H
#define BIT_MASK_H
+#include "image.h"
#include "io/resource_loader.h"
#include "resource.h"
@@ -51,7 +52,7 @@ protected:
public:
void create(const Size2 &p_size);
- void create_from_image_alpha(const Image &p_image);
+ void create_from_image_alpha(const Ref<Image> &p_image);
void set_bit(const Point2 &p_pos, bool p_value);
bool get_bit(const Point2 &p_pos) const;
diff --git a/scene/resources/box_shape.cpp b/scene/resources/box_shape.cpp
index fedfc71313..d5c25b718e 100644
--- a/scene/resources/box_shape.cpp
+++ b/scene/resources/box_shape.cpp
@@ -34,8 +34,8 @@ Vector<Vector3> BoxShape::_gen_debug_mesh_lines() {
Vector<Vector3> lines;
Rect3 aabb;
- aabb.pos = -get_extents();
- aabb.size = aabb.pos * -2;
+ aabb.position = -get_extents();
+ aabb.size = aabb.position * -2;
for (int i = 0; i < 12; i++) {
Vector3 a, b;
diff --git a/scene/resources/capsule_shape_2d.cpp b/scene/resources/capsule_shape_2d.cpp
index 3f41526bcb..20177692a1 100644
--- a/scene/resources/capsule_shape_2d.cpp
+++ b/scene/resources/capsule_shape_2d.cpp
@@ -80,7 +80,7 @@ Rect2 CapsuleShape2D::get_rect() const {
Vector2 he = Point2(get_radius(), get_radius() + get_height() * 0.5);
Rect2 rect;
- rect.pos = -he;
+ rect.position = -he;
rect.size = he * 2.0;
return rect;
}
diff --git a/scene/resources/circle_shape_2d.cpp b/scene/resources/circle_shape_2d.cpp
index 4512e1c4a9..1b7e09ddfb 100644
--- a/scene/resources/circle_shape_2d.cpp
+++ b/scene/resources/circle_shape_2d.cpp
@@ -58,7 +58,7 @@ void CircleShape2D::_bind_methods() {
Rect2 CircleShape2D::get_rect() const {
Rect2 rect;
- rect.pos = -Point2(get_radius(), get_radius());
+ rect.position = -Point2(get_radius(), get_radius());
rect.size = Point2(get_radius(), get_radius()) * 2.0;
return rect;
}
diff --git a/scene/resources/color_ramp.cpp b/scene/resources/color_ramp.cpp
index 3c58a76998..3cf8845189 100644
--- a/scene/resources/color_ramp.cpp
+++ b/scene/resources/color_ramp.cpp
@@ -36,7 +36,7 @@
#define COLOR_RAMP_SET_OFFSETS "set_offsets"
#define COLOR_RAMP_SET_COLORS "set_colors"
-ColorRamp::ColorRamp() {
+Gradient::Gradient() {
//Set initial color ramp transition from black to white
points.resize(2);
points[0].color = Color(0, 0, 0, 1);
@@ -46,35 +46,35 @@ ColorRamp::ColorRamp() {
is_sorted = true;
}
-ColorRamp::~ColorRamp() {
+Gradient::~Gradient() {
}
-void ColorRamp::_bind_methods() {
+void Gradient::_bind_methods() {
- ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &ColorRamp::add_point);
- ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &ColorRamp::remove_point);
+ ClassDB::bind_method(D_METHOD("add_point", "offset", "color"), &Gradient::add_point);
+ ClassDB::bind_method(D_METHOD("remove_point", "offset", "color"), &Gradient::remove_point);
- ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &ColorRamp::set_offset);
- ClassDB::bind_method(D_METHOD("get_offset", "point"), &ColorRamp::get_offset);
+ ClassDB::bind_method(D_METHOD("set_offset", "point", "offset"), &Gradient::set_offset);
+ ClassDB::bind_method(D_METHOD("get_offset", "point"), &Gradient::get_offset);
- ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &ColorRamp::set_color);
- ClassDB::bind_method(D_METHOD("get_color", "point"), &ColorRamp::get_color);
+ ClassDB::bind_method(D_METHOD("set_color", "point", "color"), &Gradient::set_color);
+ ClassDB::bind_method(D_METHOD("get_color", "point"), &Gradient::get_color);
- ClassDB::bind_method(D_METHOD("interpolate", "offset"), &ColorRamp::get_color_at_offset);
+ ClassDB::bind_method(D_METHOD("interpolate", "offset"), &Gradient::get_color_at_offset);
- ClassDB::bind_method(D_METHOD("get_point_count"), &ColorRamp::get_points_count);
+ ClassDB::bind_method(D_METHOD("get_point_count"), &Gradient::get_points_count);
- ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &ColorRamp::set_offsets);
- ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &ColorRamp::get_offsets);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_OFFSETS, "offsets"), &Gradient::set_offsets);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_OFFSETS), &Gradient::get_offsets);
- ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &ColorRamp::set_colors);
- ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &ColorRamp::get_colors);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_SET_COLORS, "colors"), &Gradient::set_colors);
+ ClassDB::bind_method(D_METHOD(COLOR_RAMP_GET_COLORS), &Gradient::get_colors);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "offsets"), COLOR_RAMP_SET_OFFSETS, COLOR_RAMP_GET_OFFSETS);
ADD_PROPERTY(PropertyInfo(Variant::REAL, "colors"), COLOR_RAMP_SET_COLORS, COLOR_RAMP_GET_COLORS);
}
-Vector<float> ColorRamp::get_offsets() const {
+Vector<float> Gradient::get_offsets() const {
Vector<float> offsets;
offsets.resize(points.size());
for (int i = 0; i < points.size(); i++) {
@@ -83,7 +83,7 @@ Vector<float> ColorRamp::get_offsets() const {
return offsets;
}
-Vector<Color> ColorRamp::get_colors() const {
+Vector<Color> Gradient::get_colors() const {
Vector<Color> colors;
colors.resize(points.size());
for (int i = 0; i < points.size(); i++) {
@@ -92,7 +92,7 @@ Vector<Color> ColorRamp::get_colors() const {
return colors;
}
-void ColorRamp::set_offsets(const Vector<float> &p_offsets) {
+void Gradient::set_offsets(const Vector<float> &p_offsets) {
points.resize(p_offsets.size());
for (int i = 0; i < points.size(); i++) {
points[i].offset = p_offsets[i];
@@ -101,7 +101,7 @@ void ColorRamp::set_offsets(const Vector<float> &p_offsets) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void ColorRamp::set_colors(const Vector<Color> &p_colors) {
+void Gradient::set_colors(const Vector<Color> &p_colors) {
if (points.size() < p_colors.size())
is_sorted = false;
points.resize(p_colors.size());
@@ -111,11 +111,11 @@ void ColorRamp::set_colors(const Vector<Color> &p_colors) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Vector<ColorRamp::Point> &ColorRamp::get_points() {
+Vector<Gradient::Point> &Gradient::get_points() {
return points;
}
-void ColorRamp::add_point(float p_offset, const Color &p_color) {
+void Gradient::add_point(float p_offset, const Color &p_color) {
Point p;
p.offset = p_offset;
@@ -126,7 +126,7 @@ void ColorRamp::add_point(float p_offset, const Color &p_color) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void ColorRamp::remove_point(int p_index) {
+void Gradient::remove_point(int p_index) {
ERR_FAIL_INDEX(p_index, points.size());
ERR_FAIL_COND(points.size() <= 2);
@@ -134,13 +134,13 @@ void ColorRamp::remove_point(int p_index) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void ColorRamp::set_points(Vector<ColorRamp::Point> &p_points) {
+void Gradient::set_points(Vector<Gradient::Point> &p_points) {
points = p_points;
is_sorted = false;
emit_signal(CoreStringNames::get_singleton()->changed);
}
-void ColorRamp::set_offset(int pos, const float offset) {
+void Gradient::set_offset(int pos, const float offset) {
if (points.size() <= pos)
points.resize(pos + 1);
points[pos].offset = offset;
@@ -148,13 +148,13 @@ void ColorRamp::set_offset(int pos, const float offset) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-float ColorRamp::get_offset(int pos) const {
+float Gradient::get_offset(int pos) const {
if (points.size() > pos)
return points[pos].offset;
return 0; //TODO: Maybe throw some error instead?
}
-void ColorRamp::set_color(int pos, const Color &color) {
+void Gradient::set_color(int pos, const Color &color) {
if (points.size() <= pos) {
points.resize(pos + 1);
is_sorted = false;
@@ -163,12 +163,12 @@ void ColorRamp::set_color(int pos, const Color &color) {
emit_signal(CoreStringNames::get_singleton()->changed);
}
-Color ColorRamp::get_color(int pos) const {
+Color Gradient::get_color(int pos) const {
if (points.size() > pos)
return points[pos].color;
return Color(0, 0, 0, 1); //TODO: Maybe throw some error instead?
}
-int ColorRamp::get_points_count() const {
+int Gradient::get_points_count() const {
return points.size();
}
diff --git a/scene/resources/color_ramp.h b/scene/resources/color_ramp.h
index e231e9fc52..d7ec20b324 100644
--- a/scene/resources/color_ramp.h
+++ b/scene/resources/color_ramp.h
@@ -32,9 +32,9 @@
#include "resource.h"
-class ColorRamp : public Resource {
- GDCLASS(ColorRamp, Resource);
- OBJ_SAVE_TYPE(ColorRamp);
+class Gradient : public Resource {
+ GDCLASS(Gradient, Resource);
+ OBJ_SAVE_TYPE(Gradient);
public:
struct Point {
@@ -54,8 +54,8 @@ protected:
static void _bind_methods();
public:
- ColorRamp();
- virtual ~ColorRamp();
+ Gradient();
+ virtual ~Gradient();
void add_point(float p_offset, const Color &p_color);
void remove_point(int p_index);
diff --git a/scene/resources/concave_polygon_shape_2d.cpp b/scene/resources/concave_polygon_shape_2d.cpp
index 653540a663..b8c931421e 100644
--- a/scene/resources/concave_polygon_shape_2d.cpp
+++ b/scene/resources/concave_polygon_shape_2d.cpp
@@ -68,7 +68,7 @@ Rect2 ConcavePolygonShape2D::get_rect() const {
PoolVector<Vector2>::Read r = s.read();
for (int i = 0; i < len; i++) {
if (i == 0)
- rect.pos = r[i];
+ rect.position = r[i];
else
rect.expand_to(r[i]);
}
diff --git a/scene/resources/convex_polygon_shape_2d.cpp b/scene/resources/convex_polygon_shape_2d.cpp
index fcbf66c8cd..e13f7faf70 100644
--- a/scene/resources/convex_polygon_shape_2d.cpp
+++ b/scene/resources/convex_polygon_shape_2d.cpp
@@ -78,7 +78,7 @@ Rect2 ConvexPolygonShape2D::get_rect() const {
Rect2 rect;
for (int i = 0; i < points.size(); i++) {
if (i == 0)
- rect.pos = points[i];
+ rect.position = points[i];
else
rect.expand_to(points[i]);
}
diff --git a/scene/resources/default_theme/arrow_down.png b/scene/resources/default_theme/arrow_down.png
index 4ef7b41de6..fc837d120a 100644
--- a/scene/resources/default_theme/arrow_down.png
+++ b/scene/resources/default_theme/arrow_down.png
Binary files differ
diff --git a/scene/resources/default_theme/arrow_right.png b/scene/resources/default_theme/arrow_right.png
index 13a42f730d..ebe6e26ace 100644
--- a/scene/resources/default_theme/arrow_right.png
+++ b/scene/resources/default_theme/arrow_right.png
Binary files differ
diff --git a/scene/resources/default_theme/button_disabled.png b/scene/resources/default_theme/button_disabled.png
index 1ee7be0674..d75e76989d 100644
--- a/scene/resources/default_theme/button_disabled.png
+++ b/scene/resources/default_theme/button_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/button_hover.png b/scene/resources/default_theme/button_hover.png
index 5c6c434042..6e609f435f 100644
--- a/scene/resources/default_theme/button_hover.png
+++ b/scene/resources/default_theme/button_hover.png
Binary files differ
diff --git a/scene/resources/default_theme/button_normal.png b/scene/resources/default_theme/button_normal.png
index 3e6c509f5b..92482aaf28 100644
--- a/scene/resources/default_theme/button_normal.png
+++ b/scene/resources/default_theme/button_normal.png
Binary files differ
diff --git a/scene/resources/default_theme/button_pressed.png b/scene/resources/default_theme/button_pressed.png
index 9559126eba..19a7e237aa 100644
--- a/scene/resources/default_theme/button_pressed.png
+++ b/scene/resources/default_theme/button_pressed.png
Binary files differ
diff --git a/scene/resources/default_theme/checked.png b/scene/resources/default_theme/checked.png
index aa5e7f6bdb..93e291a29e 100644
--- a/scene/resources/default_theme/checked.png
+++ b/scene/resources/default_theme/checked.png
Binary files differ
diff --git a/scene/resources/default_theme/close.png b/scene/resources/default_theme/close.png
index b6973740e7..5ac6357dcd 100644
--- a/scene/resources/default_theme/close.png
+++ b/scene/resources/default_theme/close.png
Binary files differ
diff --git a/scene/resources/default_theme/close_hl.png b/scene/resources/default_theme/close_hl.png
index b6973740e7..5ac6357dcd 100644
--- a/scene/resources/default_theme/close_hl.png
+++ b/scene/resources/default_theme/close_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/default_theme.cpp b/scene/resources/default_theme/default_theme.cpp
index 7d134a2c20..668a8ff66f 100644
--- a/scene/resources/default_theme/default_theme.cpp
+++ b/scene/resources/default_theme/default_theme.cpp
@@ -53,20 +53,20 @@ static Ref<StyleBoxTexture> make_stylebox(T p_src, float p_left, float p_top, fl
} else {
texture = Ref<ImageTexture>(memnew(ImageTexture));
- Image img(p_src);
+ Ref<Image> img = memnew(Image(p_src));
if (scale > 1) {
- Size2 orig_size = Size2(img.get_width(), img.get_height());
+ Size2 orig_size = Size2(img->get_width(), img->get_height());
- img.convert(Image::FORMAT_RGBA8);
- img.expand_x2_hq2x();
+ img->convert(Image::FORMAT_RGBA8);
+ img->expand_x2_hq2x();
if (scale != 2.0) {
- img.resize(orig_size.x * scale, orig_size.y * scale);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
}
} else if (scale < 1) {
- Size2 orig_size = Size2(img.get_width(), img.get_height());
- img.convert(Image::FORMAT_RGBA8);
- img.resize(orig_size.x * scale, orig_size.y * scale);
+ Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
}
texture->create_from_image(img, ImageTexture::FLAG_FILTER);
@@ -97,27 +97,23 @@ static Ref<StyleBoxTexture> sb_expand(Ref<StyleBoxTexture> p_sbox, float p_left,
return p_sbox;
}
-static Ref<StyleBoxTexture> sb_expand_default(Ref<StyleBoxTexture> p_sbox) {
- return sb_expand(p_sbox, 0, 0, 0, 0);
-}
-
template <class T>
static Ref<Texture> make_icon(T p_src) {
Ref<ImageTexture> texture(memnew(ImageTexture));
- Image img = Image(p_src);
+ Ref<Image> img = memnew(Image(p_src));
if (scale > 1) {
- Size2 orig_size = Size2(img.get_width(), img.get_height());
+ Size2 orig_size = Size2(img->get_width(), img->get_height());
- img.convert(Image::FORMAT_RGBA8);
- img.expand_x2_hq2x();
+ img->convert(Image::FORMAT_RGBA8);
+ img->expand_x2_hq2x();
if (scale != 2.0) {
- img.resize(orig_size.x * scale, orig_size.y * scale);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
}
} else if (scale < 1) {
- Size2 orig_size = Size2(img.get_width(), img.get_height());
- img.convert(Image::FORMAT_RGBA8);
- img.resize(orig_size.x * scale, orig_size.y * scale);
+ Size2 orig_size = Size2(img->get_width(), img->get_height());
+ img->convert(Image::FORMAT_RGBA8);
+ img->resize(orig_size.x * scale, orig_size.y * scale);
}
texture->create_from_image(img, ImageTexture::FLAG_FILTER);
@@ -142,8 +138,8 @@ static Ref<BitmapFont> make_font(int p_height, int p_ascent, int p_valign, int p
int chr = c[0];
Rect2 frect;
- frect.pos.x = c[1];
- frect.pos.y = c[2];
+ frect.position.x = c[1];
+ frect.position.y = c[2];
frect.size.x = c[3];
frect.size.y = c[4];
Point2 align(c[5], c[6] + p_valign);
@@ -162,7 +158,7 @@ static Ref<BitmapFont> make_font2(int p_height, int p_ascent, int p_charcount, c
Ref<BitmapFont> font(memnew(BitmapFont));
- Image image(p_img);
+ Ref<Image> image = memnew(Image(p_img));
Ref<ImageTexture> tex = memnew(ImageTexture);
tex->create_from_image(image);
@@ -174,8 +170,8 @@ static Ref<BitmapFont> make_font2(int p_height, int p_ascent, int p_charcount, c
int chr = c[0];
Rect2 frect;
- frect.pos.x = c[1];
- frect.pos.y = c[2];
+ frect.position.x = c[1];
+ frect.position.y = c[2];
frect.size.x = c[3];
frect.size.y = c[4];
Point2 align(c[6], c[5]);
@@ -217,16 +213,14 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// Font Colors
- Color control_font_color = Color(1, 1, 1, 0.8);
- Color control_font_color_lower = Color(1, 1, 1, 0.32);
- Color control_font_color_low = Color(1, 1, 1, 0.58);
+ Color control_font_color = Color::html("e0e0e0");
+ Color control_font_color_lower = Color::html("a0a0a0");
+ Color control_font_color_low = Color::html("b0b0b0");
Color control_font_color_hover = Color::html("f0f0f0");
- Color control_font_color_disabled = Color::html("425468");
+ Color control_font_color_disabled = Color(0.9, 0.9, 0.9, 0.2);
Color control_font_color_pressed = Color::html("ffffff");
Color font_color_selection = Color::html("7d7d7d");
- Color accent_color = Color::html("7eff8a");
-
// Panel
t->set_stylebox("panel", "Panel", make_stylebox(panel_bg_png, 0, 0, 0, 0));
@@ -240,15 +234,11 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// Button
- Color button_font_color = Color::html("9fb4ca");
- Color button_font_color_hover = Color::html("70b1ff");
- Color button_font_color_disabled = Color::html("425468");
-
- Ref<StyleBox> sb_button_normal = sb_expand_default(make_stylebox(button_normal_png, 6, 6, 6, 6, 6, 4, 6, 4));
- Ref<StyleBox> sb_button_pressed = sb_expand_default(make_stylebox(button_pressed_png, 6, 6, 6, 6, 6, 4, 6, 4));
- Ref<StyleBox> sb_button_hover = sb_expand_default(make_stylebox(button_hover_png, 6, 6, 6, 6, 6, 4, 6, 4));
- Ref<StyleBox> sb_button_disabled = sb_expand_default(make_stylebox(button_disabled_png, 6, 6, 6, 6, 6, 4, 6, 4));
- Ref<StyleBox> sb_button_focus = make_stylebox(focus_png, 6, 6, 6, 6, 6, 2, 6, 2);
+ Ref<StyleBox> sb_button_normal = sb_expand(make_stylebox(button_normal_png, 4, 4, 4, 4, 6, 3, 6, 3), 2, 2, 2, 2);
+ Ref<StyleBox> sb_button_pressed = sb_expand(make_stylebox(button_pressed_png, 4, 4, 4, 4, 6, 3, 6, 3), 2, 2, 2, 2);
+ Ref<StyleBox> sb_button_hover = sb_expand(make_stylebox(button_hover_png, 4, 4, 4, 4, 6, 2, 6, 2), 2, 2, 2, 2);
+ Ref<StyleBox> sb_button_disabled = sb_expand(make_stylebox(button_disabled_png, 4, 4, 4, 4, 6, 2, 6, 2), 2, 2, 2, 2);
+ Ref<StyleBox> sb_button_focus = sb_expand(make_stylebox(button_focus_png, 4, 4, 4, 4, 6, 2, 6, 2), 2, 2, 2, 2);
t->set_stylebox("normal", "Button", sb_button_normal);
t->set_stylebox("pressed", "Button", sb_button_pressed);
@@ -258,14 +248,12 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_font("font", "Button", default_font);
- t->set_color("font_color", "Button", button_font_color);
- t->set_color("font_color_pressed", "Button", accent_color);
- t->set_color("font_color_hover", "Button", button_font_color_hover);
- t->set_color("font_color_disabled", "Button", button_font_color_disabled);
+ t->set_color("font_color", "Button", control_font_color);
+ t->set_color("font_color_pressed", "Button", control_font_color_pressed);
+ t->set_color("font_color_hover", "Button", control_font_color_hover);
+ t->set_color("font_color_disabled", "Button", control_font_color_disabled);
- t->set_constant("side_margin", "Button", 4 * scale);
- t->set_constant("bottom_margin", "Button", 4 * scale);
- t->set_constant("hseparation", "Button", 4 * scale);
+ t->set_constant("hseparation", "Button", 2 * scale);
// LinkButton
@@ -296,73 +284,66 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// ToolButton
- Ref<StyleBox> tb_empty = memnew(StyleBoxEmpty);
- tb_empty->set_default_margin(MARGIN_LEFT, 6 * scale);
- tb_empty->set_default_margin(MARGIN_RIGHT, 6 * scale);
- tb_empty->set_default_margin(MARGIN_TOP, 4 * scale);
- tb_empty->set_default_margin(MARGIN_BOTTOM, 4 * scale);
-
- t->set_stylebox("normal", "ToolButton", tb_empty);
- t->set_stylebox("pressed", "ToolButton", tb_empty);
- t->set_stylebox("hover", "ToolButton", tb_empty);
- t->set_stylebox("disabled", "ToolButton", tb_empty);
- t->set_stylebox("focus", "ToolButton", tb_empty);
+ t->set_stylebox("normal", "ToolButton", make_empty_stylebox(6, 4, 6, 4));
+ t->set_stylebox("pressed", "ToolButton", make_stylebox(button_pressed_png, 4, 4, 4, 4, 6, 4, 6, 4));
+ t->set_stylebox("hover", "ToolButton", make_stylebox(button_normal_png, 4, 4, 4, 4, 6, 4, 6, 4));
+ t->set_stylebox("disabled", "ToolButton", make_empty_stylebox(6, 4, 6, 4));
+ t->set_stylebox("focus", "ToolButton", focus);
t->set_font("font", "ToolButton", default_font);
t->set_color("font_color", "ToolButton", control_font_color);
- t->set_color("font_color_pressed", "ToolButton", accent_color);
+ t->set_color("font_color_pressed", "ToolButton", control_font_color_pressed);
t->set_color("font_color_hover", "ToolButton", control_font_color_hover);
- t->set_color("font_color_disabled", "ToolButton", button_font_color_disabled);
+ t->set_color("font_color_disabled", "ToolButton", Color(0.9, 0.95, 1, 0.3));
t->set_constant("hseparation", "ToolButton", 3);
// OptionButton
- Ref<StyleBox> sb_optbutton_normal = sb_expand_default(make_stylebox(button_normal_png, 6, 6, 6, 6, 6, 4, 16, 4));
- Ref<StyleBox> sb_optbutton_pressed = sb_expand_default(make_stylebox(button_pressed_png, 6, 6, 6, 6, 6, 4, 16, 4));
- Ref<StyleBox> sb_optbutton_hover = sb_expand_default(make_stylebox(button_hover_png, 6, 6, 6, 6, 6, 4, 16, 4));
- Ref<StyleBox> sb_optbutton_disabled = sb_expand_default(make_stylebox(button_disabled_png, 6, 6, 6, 6, 6, 4, 16, 4));
- Ref<StyleBox> sb_optbutton_focus = focus;
+ Ref<StyleBox> sb_optbutton_normal = sb_expand(make_stylebox(option_button_normal_png, 4, 4, 21, 4, 6, 3, 21, 3), 2, 2, 2, 2);
+ Ref<StyleBox> sb_optbutton_pressed = sb_expand(make_stylebox(option_button_pressed_png, 4, 4, 21, 4, 6, 3, 21, 3), 2, 2, 2, 2);
+ Ref<StyleBox> sb_optbutton_hover = sb_expand(make_stylebox(option_button_hover_png, 4, 4, 21, 4, 6, 2, 21, 2), 2, 2, 2, 2);
+ Ref<StyleBox> sb_optbutton_disabled = sb_expand(make_stylebox(option_button_disabled_png, 4, 4, 21, 4, 6, 2, 21, 2), 2, 2, 2, 2);
+ Ref<StyleBox> sb_optbutton_focus = sb_expand(make_stylebox(button_focus_png, 4, 4, 4, 4, 6, 2, 6, 2), 2, 2, 2, 2);
t->set_stylebox("normal", "OptionButton", sb_optbutton_normal);
t->set_stylebox("pressed", "OptionButton", sb_optbutton_pressed);
t->set_stylebox("hover", "OptionButton", sb_optbutton_hover);
t->set_stylebox("disabled", "OptionButton", sb_optbutton_disabled);
- t->set_stylebox("focus", "OptionButton", sb_optbutton_focus);
+ t->set_stylebox("focus", "OptionButton", sb_button_focus);
t->set_icon("arrow", "OptionButton", make_icon(option_arrow_png));
t->set_font("font", "OptionButton", default_font);
- t->set_color("font_color", "OptionButton", button_font_color);
- t->set_color("font_color_pressed", "OptionButton", accent_color);
- t->set_color("font_color_hover", "OptionButton", button_font_color_hover);
- t->set_color("font_color_disabled", "OptionButton", button_font_color_disabled);
+ t->set_color("font_color", "OptionButton", control_font_color);
+ t->set_color("font_color_pressed", "OptionButton", control_font_color_pressed);
+ t->set_color("font_color_hover", "OptionButton", control_font_color_hover);
+ t->set_color("font_color_disabled", "OptionButton", control_font_color_disabled);
t->set_constant("hseparation", "OptionButton", 2 * scale);
- t->set_constant("arrow_margin", "OptionButton", 8 * scale);
+ t->set_constant("arrow_margin", "OptionButton", 2 * scale);
// MenuButton
- t->set_stylebox("normal", "MenuButton", tb_empty);
- t->set_stylebox("pressed", "MenuButton", tb_empty);
- t->set_stylebox("hover", "MenuButton", tb_empty);
+ t->set_stylebox("normal", "MenuButton", sb_button_normal);
+ t->set_stylebox("pressed", "MenuButton", sb_button_pressed);
+ t->set_stylebox("hover", "MenuButton", sb_button_pressed);
t->set_stylebox("disabled", "MenuButton", make_empty_stylebox(0, 0, 0, 0));
- t->set_stylebox("focus", "MenuButton", tb_empty);
+ t->set_stylebox("focus", "MenuButton", sb_button_focus);
t->set_font("font", "MenuButton", default_font);
t->set_color("font_color", "MenuButton", control_font_color);
- t->set_color("font_color_pressed", "MenuButton", accent_color);
+ t->set_color("font_color_pressed", "MenuButton", control_font_color_pressed);
t->set_color("font_color_hover", "MenuButton", control_font_color_hover);
- t->set_color("font_color_disabled", "MenuButton", button_font_color_disabled);
- t->set_color("font_color_focus", "MenuButton", accent_color);
+ t->set_color("font_color_disabled", "MenuButton", Color(1, 1, 1, 0.3));
t->set_constant("hseparation", "MenuButton", 3 * scale);
// ButtonGroup
- t->set_stylebox("panel", "ButtonGroup", make_stylebox(button_group_png, 16, 16, 16, 16, 8, 4, 8, 4));
+ t->set_stylebox("panel", "ButtonGroup", memnew(StyleBoxEmpty));
// CheckBox
@@ -429,7 +410,7 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_font("font", "Label", default_font);
- t->set_color("font_color", "Label", control_font_color_low);
+ t->set_color("font_color", "Label", Color(1, 1, 1));
t->set_color("font_color_shadow", "Label", Color(0, 0, 0, 0));
t->set_constant("shadow_offset_x", "Label", 1 * scale);
@@ -439,21 +420,15 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// LineEdit
- Ref<StyleBoxTexture> sb_line_edit = sb_expand_default(make_stylebox(line_edit_png, 6, 6, 6, 6, 6, 4, 6, 4));
- t->set_stylebox("normal", "LineEdit", sb_line_edit);
- Ref<StyleBoxTexture> sb_line_edit_active = sb_expand_default(make_stylebox(line_edit_active_png, 6, 6, 6, 6, 6, 4, 6, 4));
- t->set_stylebox("active", "LineEdit", sb_line_edit_active);
+ t->set_stylebox("normal", "LineEdit", make_stylebox(line_edit_png, 5, 5, 5, 5));
t->set_stylebox("focus", "LineEdit", focus);
- Ref<StyleBoxTexture> sb_line_edit_disabled = sb_expand_default(make_stylebox(line_edit_disabled_png, 6, 6, 6, 6, 6, 4, 6, 4));
- t->set_stylebox("read_only", "LineEdit", sb_line_edit_disabled);
+ t->set_stylebox("read_only", "LineEdit", make_stylebox(line_edit_disabled_png, 6, 6, 6, 6));
t->set_font("font", "LineEdit", default_font);
- t->set_color("font_color", "LineEdit", button_font_color);
- t->set_color("font_color_selected", "LineEdit", button_font_color);
- t->set_color("font_color_active", "LineEdit", accent_color);
- t->set_color("font_color_read_only", "LineEdit", button_font_color_disabled);
- t->set_color("cursor_color", "LineEdit", button_font_color);
+ t->set_color("font_color", "LineEdit", control_font_color);
+ t->set_color("font_color_selected", "LineEdit", Color(0, 0, 0));
+ t->set_color("cursor_color", "LineEdit", control_font_color_hover);
t->set_color("selection_color", "LineEdit", font_color_selection);
t->set_constant("minimum_spaces", "LineEdit", 12 * scale);
@@ -470,9 +445,9 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// TextEdit
- t->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 6, 6, 6, 6));
+ t->set_stylebox("normal", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
t->set_stylebox("focus", "TextEdit", focus);
- t->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 6, 6, 6, 6));
+ t->set_stylebox("completion", "TextEdit", make_stylebox(tree_bg_png, 3, 3, 3, 3));
t->set_icon("tab", "TextEdit", make_icon(tab_png));
@@ -512,43 +487,43 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_stylebox("scroll", "HScrollBar", make_stylebox(scroll_bg_png, 5, 5, 5, 5, 0, 0, 0, 0));
t->set_stylebox("scroll_focus", "HScrollBar", make_stylebox(scroll_bg_png, 5, 5, 5, 5, 0, 0, 0, 0));
t->set_stylebox("grabber", "HScrollBar", make_stylebox(scroll_grabber_png, 5, 5, 5, 5, 2, 2, 2, 2));
- t->set_stylebox("grabber_hilite", "HScrollBar", make_stylebox(scroll_grabber_hl_png, 5, 5, 5, 5, 2, 2, 2, 2));
+ t->set_stylebox("grabber_highlight", "HScrollBar", make_stylebox(scroll_grabber_hl_png, 5, 5, 5, 5, 2, 2, 2, 2));
t->set_icon("increment", "HScrollBar", empty_icon);
- t->set_icon("increment_hilite", "HScrollBar", empty_icon);
+ t->set_icon("increment_highlight", "HScrollBar", empty_icon);
t->set_icon("decrement", "HScrollBar", empty_icon);
- t->set_icon("decrement_hilite", "HScrollBar", empty_icon);
+ t->set_icon("decrement_highlight", "HScrollBar", empty_icon);
// VScrollBar
t->set_stylebox("scroll", "VScrollBar", make_stylebox(scroll_bg_png, 5, 5, 5, 5, 0, 0, 0, 0));
t->set_stylebox("scroll_focus", "VScrollBar", make_stylebox(scroll_bg_png, 5, 5, 5, 5, 0, 0, 0, 0));
t->set_stylebox("grabber", "VScrollBar", make_stylebox(scroll_grabber_png, 5, 5, 5, 5, 2, 2, 2, 2));
- t->set_stylebox("grabber_hilite", "VScrollBar", make_stylebox(scroll_grabber_hl_png, 5, 5, 5, 5, 2, 2, 2, 2));
+ t->set_stylebox("grabber_highlight", "VScrollBar", make_stylebox(scroll_grabber_hl_png, 5, 5, 5, 5, 2, 2, 2, 2));
t->set_icon("increment", "VScrollBar", empty_icon);
- t->set_icon("increment_hilite", "VScrollBar", empty_icon);
+ t->set_icon("increment_highlight", "VScrollBar", empty_icon);
t->set_icon("decrement", "VScrollBar", empty_icon);
- t->set_icon("decrement_hilite", "VScrollBar", empty_icon);
+ t->set_icon("decrement_highlight", "VScrollBar", empty_icon);
// HSlider
t->set_stylebox("slider", "HSlider", make_stylebox(hslider_bg_png, 4, 4, 4, 4));
- t->set_stylebox("grabber_hilite", "HSlider", make_stylebox(hslider_grabber_hl_png, 6, 6, 6, 6));
+ t->set_stylebox("grabber_highlight", "HSlider", make_stylebox(hslider_grabber_hl_png, 6, 6, 6, 6));
t->set_stylebox("focus", "HSlider", focus);
t->set_icon("grabber", "HSlider", make_icon(hslider_grabber_png));
- t->set_icon("grabber_hilite", "HSlider", make_icon(hslider_grabber_hl_png));
+ t->set_icon("grabber_highlight", "HSlider", make_icon(hslider_grabber_hl_png));
t->set_icon("tick", "HSlider", make_icon(hslider_tick_png));
// VSlider
t->set_stylebox("slider", "VSlider", make_stylebox(vslider_bg_png, 4, 4, 4, 4));
- t->set_stylebox("grabber_hilite", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6));
+ t->set_stylebox("grabber_highlight", "VSlider", make_stylebox(vslider_grabber_hl_png, 6, 6, 6, 6));
t->set_stylebox("focus", "HSlider", focus);
t->set_icon("grabber", "VSlider", make_icon(vslider_grabber_png));
- t->set_icon("grabber_hilite", "VSlider", make_icon(vslider_grabber_hl_png));
+ t->set_icon("grabber_highlight", "VSlider", make_icon(vslider_grabber_hl_png));
t->set_icon("tick", "VSlider", make_icon(vslider_tick_png));
// SpinBox
@@ -557,25 +532,17 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// WindowDialog
- Ref<StyleBoxTexture> style_pp_win = make_stylebox(popup_window_png, 8, 8, 8, 8, 8, 30, 8, 8);
-
- t->set_stylebox("panel", "WindowDialog", style_pp_win);
+ t->set_stylebox("panel", "WindowDialog", sb_expand(make_stylebox(popup_window_png, 10, 26, 10, 8), 8, 24, 8, 6));
t->set_constant("scaleborder_size", "WindowDialog", 4 * scale);
- t->set_icon("close", "WindowDialog", make_icon(close_png));
- t->set_icon("close_hilite", "WindowDialog", make_icon(close_hl_png));
-
t->set_font("title_font", "WindowDialog", large_font);
-
- t->set_color("title_color", "WindowDialog", Color::html("dae0e6"));
-
- t->set_constant("close_h_ofs", "WindowDialog", 20 * scale);
- t->set_constant("close_v_ofs", "WindowDialog", 20 * scale);
- t->set_constant("titlebar_height", "WindowDialog", 20 * scale);
+ t->set_color("title_color", "WindowDialog", Color(0, 0, 0));
t->set_constant("title_height", "WindowDialog", 20 * scale);
t->set_icon("close", "WindowDialog", make_icon(close_png));
- t->set_icon("close_hilite", "WindowDialog", make_icon(close_hl_png));
+ t->set_icon("close_highlight", "WindowDialog", make_icon(close_hl_png));
+ t->set_constant("close_h_ofs", "WindowDialog", 18 * scale);
+ t->set_constant("close_v_ofs", "WindowDialog", 18 * scale);
// File Dialog
@@ -583,9 +550,9 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// Popup
- Ref<StyleBoxTexture> style_pp = sb_expand(make_stylebox(popup_bg_png, 6, 6, 6, 6, 4, 4, 4, 4), 2, 2, 2, 2);
+ Ref<StyleBoxTexture> style_pp = sb_expand(make_stylebox(popup_bg_png, 5, 5, 5, 5, 4, 4, 4, 4), 2, 2, 2, 2);
- Ref<StyleBoxTexture> selected = make_stylebox(selection_png, 6, 7, 6, 7);
+ Ref<StyleBoxTexture> selected = make_stylebox(selection_png, 6, 6, 6, 6);
for (int i = 0; i < 4; i++) {
selected->set_expand_margin_size(Margin(i), 2 * scale);
}
@@ -646,19 +613,22 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// Tree
- Ref<StyleBoxTexture> tree_selected = make_stylebox(selection_png, 6, 7, 6, 7, 8, 0, 8, 0);
- Ref<StyleBoxTexture> tree_selected_oof = make_stylebox(selection_oof_png, 6, 6, 6, 6, 8, 0, 8, 0);
+ Ref<StyleBoxTexture> tree_selected = make_stylebox(selection_png, 4, 4, 4, 4, 8, 0, 8, 0);
+ Ref<StyleBoxTexture> tree_selected_oof = make_stylebox(selection_oof_png, 4, 4, 4, 4, 8, 0, 8, 0);
- t->set_stylebox("bg", "Tree", make_stylebox(tree_bg_png, 6, 6, 6, 6));
+ t->set_stylebox("bg", "Tree", make_stylebox(tree_bg_png, 4, 4, 4, 5));
t->set_stylebox("bg_focus", "Tree", focus);
t->set_stylebox("selected", "Tree", tree_selected_oof);
t->set_stylebox("selected_focus", "Tree", tree_selected);
t->set_stylebox("cursor", "Tree", focus);
t->set_stylebox("cursor_unfocused", "Tree", focus);
- t->set_stylebox("button_pressed", "Tree", make_stylebox(button_pressed_png, 6, 6, 6, 6));
+ t->set_stylebox("button_pressed", "Tree", make_stylebox(button_pressed_png, 4, 4, 4, 4));
t->set_stylebox("title_button_normal", "Tree", make_stylebox(tree_title_png, 4, 4, 4, 4));
t->set_stylebox("title_button_pressed", "Tree", make_stylebox(tree_title_pressed_png, 4, 4, 4, 4));
t->set_stylebox("title_button_hover", "Tree", make_stylebox(tree_title_png, 4, 4, 4, 4));
+ t->set_stylebox("custom_button", "Tree", sb_button_normal);
+ t->set_stylebox("custom_button_pressed", "Tree", sb_button_pressed);
+ t->set_stylebox("custom_button_hover", "Tree", sb_button_hover);
t->set_icon("checked", "Tree", make_icon(checked_png));
t->set_icon("unchecked", "Tree", make_icon(unchecked_png));
@@ -673,12 +643,12 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_color("title_button_color", "Tree", control_font_color);
t->set_color("font_color", "Tree", control_font_color_low);
t->set_color("font_color_selected", "Tree", control_font_color_pressed);
- t->set_color("button_pressed", "Tree", accent_color);
- t->set_color("selection_color", "Tree", Color(0, 0, 0, 0.8));
+ t->set_color("selection_color", "Tree", Color(0.1, 0.1, 1, 0.8));
t->set_color("cursor_color", "Tree", Color(0, 0, 0));
t->set_color("guide_color", "Tree", Color(0, 0, 0, 0.1));
- t->set_color("drop_position_color", "Tree", Color(0, 0, 0, 0.2));
- t->set_color("relationship_line_color", "Tree", Color(0, 0, 0, 0.1));
+ t->set_color("drop_position_color", "Tree", Color(1, 0.3, 0.2));
+ t->set_color("relationship_line_color", "Tree", Color::html("464646"));
+ t->set_color("custom_button_font_highlight", "Tree", control_font_color_hover);
t->set_constant("hseparation", "Tree", 4 * scale);
t->set_constant("vseparation", "Tree", 4 * scale);
@@ -690,10 +660,10 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_constant("scroll_speed", "Tree", 12);
// ItemList
- Ref<StyleBoxTexture> item_selected = make_stylebox(selection_png, 6, 7, 6, 7, 8, 2, 4, 2);
- Ref<StyleBoxTexture> item_selected_oof = make_stylebox(selection_oof_png, 6, 6, 6, 6, 8, 2, 4, 2);
+ Ref<StyleBoxTexture> item_selected = make_stylebox(selection_png, 4, 4, 4, 4, 8, 2, 8, 2);
+ Ref<StyleBoxTexture> item_selected_oof = make_stylebox(selection_oof_png, 4, 4, 4, 4, 8, 2, 8, 2);
- t->set_stylebox("bg", "ItemList", make_stylebox(tree_bg_png, 6, 6, 6, 6));
+ t->set_stylebox("bg", "ItemList", make_stylebox(tree_bg_png, 4, 4, 4, 5));
t->set_stylebox("bg_focus", "ItemList", focus);
t->set_constant("hseparation", "ItemList", 4);
t->set_constant("vseparation", "ItemList", 2);
@@ -710,25 +680,25 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// TabContainer
- Ref<StyleBoxTexture> tc_sb = sb_expand(make_stylebox(tab_container_bg_png, 6, 6, 6, 6, 4, 4, 4, 4), 3, 3, 3, 3);
+ Ref<StyleBoxTexture> tc_sb = sb_expand(make_stylebox(tab_container_bg_png, 4, 4, 4, 4, 4, 4, 4, 4), 3, 3, 3, 3);
tc_sb->set_expand_margin_size(MARGIN_TOP, 2 * scale);
tc_sb->set_default_margin(MARGIN_TOP, 8 * scale);
- t->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 6, 6, 6, 0, 16, 8, 16, 8), 2, 2, 2, 2));
- t->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 8, 16, 8), 3, 0, 3, 3));
+ t->set_stylebox("tab_fg", "TabContainer", sb_expand(make_stylebox(tab_current_png, 4, 4, 4, 1, 16, 4, 16, 4), 2, 2, 2, 2));
+ t->set_stylebox("tab_bg", "TabContainer", sb_expand(make_stylebox(tab_behind_png, 5, 5, 5, 1, 16, 6, 16, 4), 3, 0, 3, 3));
t->set_stylebox("panel", "TabContainer", tc_sb);
t->set_icon("increment", "TabContainer", make_icon(scroll_button_right_png));
- t->set_icon("increment_hilite", "TabContainer", make_icon(scroll_button_right_hl_png));
+ t->set_icon("increment_highlight", "TabContainer", make_icon(scroll_button_right_hl_png));
t->set_icon("decrement", "TabContainer", make_icon(scroll_button_left_png));
- t->set_icon("decrement_hilite", "TabContainer", make_icon(scroll_button_left_hl_png));
+ t->set_icon("decrement_highlight", "TabContainer", make_icon(scroll_button_left_hl_png));
t->set_icon("menu", "TabContainer", make_icon(tab_menu_png));
- t->set_icon("menu_hilite", "TabContainer", make_icon(tab_menu_hl_png));
+ t->set_icon("menu_highlight", "TabContainer", make_icon(tab_menu_hl_png));
t->set_font("font", "TabContainer", default_font);
- t->set_color("font_color_fg", "TabContainer", control_font_color);
+ t->set_color("font_color_fg", "TabContainer", control_font_color_hover);
t->set_color("font_color_bg", "TabContainer", control_font_color_low);
t->set_color("font_color_disabled", "TabContainer", control_font_color_disabled);
@@ -740,30 +710,21 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
// Tabs
- t->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 6, 6, 6, 0, 16, 8, 16, 8), 2, 2, 2, 2));
- // tc_sb->set_expand_margin_size(MARGIN_TOP,2 *scale);
- t->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 8, 16, 8), 2, 2, 2, 2));
+ t->set_stylebox("tab_fg", "Tabs", sb_expand(make_stylebox(tab_current_png, 4, 3, 4, 1, 16, 3, 16, 2), 2, 2, 2, 2));
+ t->set_stylebox("tab_bg", "Tabs", sb_expand(make_stylebox(tab_behind_png, 5, 4, 5, 1, 16, 5, 16, 2), 3, 3, 3, 3));
t->set_stylebox("panel", "Tabs", tc_sb);
- t->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 6, 6, 6, 6));
- t->set_stylebox("button", "Tabs", make_stylebox(button_normal_png, 6, 6, 6, 6));
+ t->set_stylebox("button_pressed", "Tabs", make_stylebox(button_pressed_png, 4, 4, 4, 4));
+ t->set_stylebox("button", "Tabs", make_stylebox(button_normal_png, 4, 4, 4, 4));
t->set_icon("increment", "Tabs", make_icon(scroll_button_right_png));
- t->set_icon("increment_hilite", "Tabs", make_icon(scroll_button_right_hl_png));
+ t->set_icon("increment_highlight", "Tabs", make_icon(scroll_button_right_hl_png));
t->set_icon("decrement", "Tabs", make_icon(scroll_button_left_png));
- t->set_icon("decrement_hilite", "Tabs", make_icon(scroll_button_left_hl_png));
+ t->set_icon("decrement_highlight", "Tabs", make_icon(scroll_button_left_hl_png));
t->set_icon("close", "Tabs", make_icon(tab_close_png));
t->set_font("font", "Tabs", default_font);
- t->set_icon("increment", "Tabs", make_icon(scroll_button_right_png));
- t->set_icon("increment_hilite", "Tabs", make_icon(scroll_button_right_hl_png));
- t->set_icon("decrement", "Tabs", make_icon(scroll_button_left_png));
- t->set_icon("decrement_hilite", "Tabs", make_icon(scroll_button_left_hl_png));
- t->set_icon("close", "Tabs", make_icon(tab_close_png));
-
- t->set_font("font", "Tabs", default_font);
-
- t->set_color("font_color_fg", "Tabs", control_font_color);
+ t->set_color("font_color_fg", "Tabs", control_font_color_hover);
t->set_color("font_color_bg", "Tabs", control_font_color_low);
t->set_color("font_color_disabled", "Tabs", control_font_color_disabled);
@@ -781,8 +742,8 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_font("normal", "Fonts", default_font);
t->set_font("large", "Fonts", large_font);
- t->set_constant("separation", "HSeparator", 16 * scale);
- t->set_constant("separation", "VSeparator", 16 * scale);
+ t->set_constant("separation", "HSeparator", 4 * scale);
+ t->set_constant("separation", "VSeparator", 4 * scale);
// Dialogs
@@ -851,12 +812,12 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_constant("separation", "HBoxContainer", 4 * scale);
t->set_constant("separation", "VBoxContainer", 4 * scale);
- t->set_constant("margin_left", "MarginContainer", 0 * scale);
+ t->set_constant("margin_left", "MarginContainer", 8 * scale);
t->set_constant("margin_top", "MarginContainer", 0 * scale);
t->set_constant("margin_right", "MarginContainer", 0 * scale);
t->set_constant("margin_bottom", "MarginContainer", 0 * scale);
- t->set_constant("hseparation", "GridContainer", 14 * scale);
- t->set_constant("vseparation", "GridContainer", 8 * scale);
+ t->set_constant("hseparation", "GridContainer", 4 * scale);
+ t->set_constant("vseparation", "GridContainer", 4 * scale);
t->set_constant("separation", "HSplitContainer", 12 * scale);
t->set_constant("separation", "VSplitContainer", 12 * scale);
t->set_constant("autohide", "HSplitContainer", 1 * scale);
@@ -904,19 +865,8 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_stylebox("panelnc", "Panel", ttnc);
t->set_stylebox("panelf", "Panel", tc_sb);
- Ref<StyleBoxTexture> sb_pc = make_stylebox(tab_container_bg_png, 6, 6, 6, 6, 7, 7, 7, 7);
+ Ref<StyleBoxTexture> sb_pc = make_stylebox(tab_container_bg_png, 4, 4, 4, 4, 7, 7, 7, 7);
t->set_stylebox("panel", "PanelContainer", sb_pc);
- t->set_stylebox("panel_full", "PanelContainer", make_stylebox(tab_container_bg_png, 4, 4, 4, 4, 2, 7, 2, 0));
-
- t->set_icon("minus", "GraphEdit", make_icon(icon_zoom_less_png));
- t->set_icon("reset", "GraphEdit", make_icon(icon_zoom_reset_png));
- t->set_icon("more", "GraphEdit", make_icon(icon_zoom_more_png));
- t->set_icon("snap", "GraphEdit", make_icon(icon_snap_png));
- t->set_stylebox("bg", "GraphEdit", make_stylebox(tree_bg_png, 6, 6, 6, 6));
- t->set_color("grid_minor", "GraphEdit", Color(1, 1, 1, 0.05));
- t->set_color("grid_major", "GraphEdit", Color(1, 1, 1, 0.2));
- t->set_constant("bezier_len_pos", "GraphEdit", 80 * scale);
- t->set_constant("bezier_len_neg", "GraphEdit", 160 * scale);
t->set_icon("minus", "GraphEdit", make_icon(icon_zoom_less_png));
t->set_icon("reset", "GraphEdit", make_icon(icon_zoom_reset_png));
@@ -930,18 +880,6 @@ void fill_default_theme(Ref<Theme> &t, const Ref<Font> &default_font, const Ref<
t->set_icon("logo", "Icons", make_icon(logo_png));
- // Editor
- t->set_color("prop_category", "Editor", Color::html("232b33"));
- t->set_color("prop_section", "Editor", Color(0, 0, 0, 0.1));
- t->set_color("prop_subsection", "Editor", Color::html("272f39"));
- t->set_color("fg_selected", "Editor", Color::html("ffbd8e8e"));
- t->set_color("fg_error", "Editor", Color::html("ffbd8e8e"));
-
- t->set_color("animation_editor_track_pos", "Editor", accent_color);
- t->set_color("animation_editor_time", "Editor", Color(1, 1, 1, 0.1));
- t->set_color("animation_editor_selection_rect", "Editor", Color(1, 1, 1, 0.5));
- t->set_color("animation_editor_line", "Editor", Color(1, 1, 1, 0.1));
-
// Theme
default_icon = make_icon(error_icon_png);
diff --git a/scene/resources/default_theme/dropdown.png b/scene/resources/default_theme/dropdown.png
index b9a324be7c..3a6a2ed778 100644
--- a/scene/resources/default_theme/dropdown.png
+++ b/scene/resources/default_theme/dropdown.png
Binary files differ
diff --git a/scene/resources/default_theme/focus.png b/scene/resources/default_theme/focus.png
index 1908fd8aee..5d37028f2d 100644
--- a/scene/resources/default_theme/focus.png
+++ b/scene/resources/default_theme/focus.png
Binary files differ
diff --git a/scene/resources/default_theme/frame_focus.png b/scene/resources/default_theme/frame_focus.png
index 1908fd8aee..9170db38ed 100644
--- a/scene/resources/default_theme/frame_focus.png
+++ b/scene/resources/default_theme/frame_focus.png
Binary files differ
diff --git a/scene/resources/default_theme/full_panel_bg.png b/scene/resources/default_theme/full_panel_bg.png
index c6e59b747c..7f02dc7259 100644
--- a/scene/resources/default_theme/full_panel_bg.png
+++ b/scene/resources/default_theme/full_panel_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/graph_node.png b/scene/resources/default_theme/graph_node.png
index c7e374693c..d4b4dd3c1f 100644
--- a/scene/resources/default_theme/graph_node.png
+++ b/scene/resources/default_theme/graph_node.png
Binary files differ
diff --git a/scene/resources/default_theme/graph_node_comment.png b/scene/resources/default_theme/graph_node_comment.png
index 0452cb1b1d..f2d6daa259 100644
--- a/scene/resources/default_theme/graph_node_comment.png
+++ b/scene/resources/default_theme/graph_node_comment.png
Binary files differ
diff --git a/scene/resources/default_theme/graph_node_comment_focus.png b/scene/resources/default_theme/graph_node_comment_focus.png
index 49127da092..a4b7b5a618 100644
--- a/scene/resources/default_theme/graph_node_comment_focus.png
+++ b/scene/resources/default_theme/graph_node_comment_focus.png
Binary files differ
diff --git a/scene/resources/default_theme/graph_node_position.png b/scene/resources/default_theme/graph_node_position.png
index 76a213be72..7ec15e2ff4 100644
--- a/scene/resources/default_theme/graph_node_position.png
+++ b/scene/resources/default_theme/graph_node_position.png
Binary files differ
diff --git a/scene/resources/default_theme/graph_node_selected.png b/scene/resources/default_theme/graph_node_selected.png
index 0e22312e6a..f76c9703dd 100644
--- a/scene/resources/default_theme/graph_node_selected.png
+++ b/scene/resources/default_theme/graph_node_selected.png
Binary files differ
diff --git a/scene/resources/default_theme/hseparator.png b/scene/resources/default_theme/hseparator.png
index 88165ea6b2..99609ac118 100644
--- a/scene/resources/default_theme/hseparator.png
+++ b/scene/resources/default_theme/hseparator.png
Binary files differ
diff --git a/scene/resources/default_theme/hslider_bg.png b/scene/resources/default_theme/hslider_bg.png
index a66e136813..9c2a2df62a 100644
--- a/scene/resources/default_theme/hslider_bg.png
+++ b/scene/resources/default_theme/hslider_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/hslider_grabber.png b/scene/resources/default_theme/hslider_grabber.png
index c8be897e07..2acd33879a 100644
--- a/scene/resources/default_theme/hslider_grabber.png
+++ b/scene/resources/default_theme/hslider_grabber.png
Binary files differ
diff --git a/scene/resources/default_theme/hslider_grabber_hl.png b/scene/resources/default_theme/hslider_grabber_hl.png
index 1639776a28..f8a011e64b 100644
--- a/scene/resources/default_theme/hslider_grabber_hl.png
+++ b/scene/resources/default_theme/hslider_grabber_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/hsplit_bg.png b/scene/resources/default_theme/hsplit_bg.png
index cfb76f7dc7..7dd1d48b29 100644
--- a/scene/resources/default_theme/hsplit_bg.png
+++ b/scene/resources/default_theme/hsplit_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/hsplitter.png b/scene/resources/default_theme/hsplitter.png
index 3ac1dddf90..71a3914d7e 100644
--- a/scene/resources/default_theme/hsplitter.png
+++ b/scene/resources/default_theme/hsplitter.png
Binary files differ
diff --git a/scene/resources/default_theme/icon_close.png b/scene/resources/default_theme/icon_close.png
index b6973740e7..5ac6357dcd 100644
--- a/scene/resources/default_theme/icon_close.png
+++ b/scene/resources/default_theme/icon_close.png
Binary files differ
diff --git a/scene/resources/default_theme/line_edit.png b/scene/resources/default_theme/line_edit.png
index 339a796390..bf2b91f1be 100644
--- a/scene/resources/default_theme/line_edit.png
+++ b/scene/resources/default_theme/line_edit.png
Binary files differ
diff --git a/scene/resources/default_theme/line_edit_active.png b/scene/resources/default_theme/line_edit_active.png
deleted file mode 100644
index b6bebde925..0000000000
--- a/scene/resources/default_theme/line_edit_active.png
+++ /dev/null
Binary files differ
diff --git a/scene/resources/default_theme/line_edit_disabled.png b/scene/resources/default_theme/line_edit_disabled.png
index 1fce186f3d..a0fa505e4c 100644
--- a/scene/resources/default_theme/line_edit_disabled.png
+++ b/scene/resources/default_theme/line_edit_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/line_edit_focus.png b/scene/resources/default_theme/line_edit_focus.png
new file mode 100644
index 0000000000..e66d7b60e3
--- /dev/null
+++ b/scene/resources/default_theme/line_edit_focus.png
Binary files differ
diff --git a/scene/resources/default_theme/line_edit_selected.png b/scene/resources/default_theme/line_edit_selected.png
deleted file mode 100644
index b6bebde925..0000000000
--- a/scene/resources/default_theme/line_edit_selected.png
+++ /dev/null
Binary files differ
diff --git a/scene/resources/default_theme/option_arrow.png b/scene/resources/default_theme/option_arrow.png
index b7bc38e03f..007de16bfa 100644
--- a/scene/resources/default_theme/option_arrow.png
+++ b/scene/resources/default_theme/option_arrow.png
Binary files differ
diff --git a/scene/resources/default_theme/option_button_disabled.png b/scene/resources/default_theme/option_button_disabled.png
index d8e7942eaa..ce727d56e1 100644
--- a/scene/resources/default_theme/option_button_disabled.png
+++ b/scene/resources/default_theme/option_button_disabled.png
Binary files differ
diff --git a/scene/resources/default_theme/option_button_focus.png b/scene/resources/default_theme/option_button_focus.png
new file mode 100644
index 0000000000..c76d91287e
--- /dev/null
+++ b/scene/resources/default_theme/option_button_focus.png
Binary files differ
diff --git a/scene/resources/default_theme/option_button_hover.png b/scene/resources/default_theme/option_button_hover.png
index 2f67922f92..fd1e987ceb 100644
--- a/scene/resources/default_theme/option_button_hover.png
+++ b/scene/resources/default_theme/option_button_hover.png
Binary files differ
diff --git a/scene/resources/default_theme/option_button_normal.png b/scene/resources/default_theme/option_button_normal.png
index 6f14414b41..9d7fb98d1c 100644
--- a/scene/resources/default_theme/option_button_normal.png
+++ b/scene/resources/default_theme/option_button_normal.png
Binary files differ
diff --git a/scene/resources/default_theme/option_button_pressed.png b/scene/resources/default_theme/option_button_pressed.png
index 7ca71c44db..28b1d93468 100644
--- a/scene/resources/default_theme/option_button_pressed.png
+++ b/scene/resources/default_theme/option_button_pressed.png
Binary files differ
diff --git a/scene/resources/default_theme/panel_bg.png b/scene/resources/default_theme/panel_bg.png
index c6db700766..320819ad6d 100644
--- a/scene/resources/default_theme/panel_bg.png
+++ b/scene/resources/default_theme/panel_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/popup_bg.png b/scene/resources/default_theme/popup_bg.png
index d8c633974a..63f5994441 100644
--- a/scene/resources/default_theme/popup_bg.png
+++ b/scene/resources/default_theme/popup_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/popup_hover.png b/scene/resources/default_theme/popup_hover.png
new file mode 100644
index 0000000000..85d4e48475
--- /dev/null
+++ b/scene/resources/default_theme/popup_hover.png
Binary files differ
diff --git a/scene/resources/default_theme/popup_unchecked.png b/scene/resources/default_theme/popup_unchecked.png
new file mode 100644
index 0000000000..c1137e6fbf
--- /dev/null
+++ b/scene/resources/default_theme/popup_unchecked.png
Binary files differ
diff --git a/scene/resources/default_theme/popup_window.png b/scene/resources/default_theme/popup_window.png
index e667c93d2f..59362a8ffd 100644
--- a/scene/resources/default_theme/popup_window.png
+++ b/scene/resources/default_theme/popup_window.png
Binary files differ
diff --git a/scene/resources/default_theme/progress_bar.png b/scene/resources/default_theme/progress_bar.png
index d3e1838248..bf81e3adea 100644
--- a/scene/resources/default_theme/progress_bar.png
+++ b/scene/resources/default_theme/progress_bar.png
Binary files differ
diff --git a/scene/resources/default_theme/progress_fill.png b/scene/resources/default_theme/progress_fill.png
index c211b0a74d..3a34dfdda6 100644
--- a/scene/resources/default_theme/progress_fill.png
+++ b/scene/resources/default_theme/progress_fill.png
Binary files differ
diff --git a/scene/resources/default_theme/radio_checked.png b/scene/resources/default_theme/radio_checked.png
index 963cf76e98..95d472022f 100644
--- a/scene/resources/default_theme/radio_checked.png
+++ b/scene/resources/default_theme/radio_checked.png
Binary files differ
diff --git a/scene/resources/default_theme/radio_unchecked.png b/scene/resources/default_theme/radio_unchecked.png
index 0b90989037..7f0535c3a4 100644
--- a/scene/resources/default_theme/radio_unchecked.png
+++ b/scene/resources/default_theme/radio_unchecked.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_bg.png b/scene/resources/default_theme/scroll_bg.png
index 1908fd8aee..cefadb2c08 100644
--- a/scene/resources/default_theme/scroll_bg.png
+++ b/scene/resources/default_theme/scroll_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_down.png b/scene/resources/default_theme/scroll_button_down.png
index a901bc8c70..caeac9b286 100644
--- a/scene/resources/default_theme/scroll_button_down.png
+++ b/scene/resources/default_theme/scroll_button_down.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_down_hl.png b/scene/resources/default_theme/scroll_button_down_hl.png
index 4e36bb924a..48036e0297 100644
--- a/scene/resources/default_theme/scroll_button_down_hl.png
+++ b/scene/resources/default_theme/scroll_button_down_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_left.png b/scene/resources/default_theme/scroll_button_left.png
index ab32b9deb1..3b50938d97 100644
--- a/scene/resources/default_theme/scroll_button_left.png
+++ b/scene/resources/default_theme/scroll_button_left.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_left_hl.png b/scene/resources/default_theme/scroll_button_left_hl.png
index 7a9ff6ac0a..b3d348c24f 100644
--- a/scene/resources/default_theme/scroll_button_left_hl.png
+++ b/scene/resources/default_theme/scroll_button_left_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_right.png b/scene/resources/default_theme/scroll_button_right.png
index 3699c2cdf7..1c622a41ad 100644
--- a/scene/resources/default_theme/scroll_button_right.png
+++ b/scene/resources/default_theme/scroll_button_right.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_right_hl.png b/scene/resources/default_theme/scroll_button_right_hl.png
index 37195daadd..108796ca02 100644
--- a/scene/resources/default_theme/scroll_button_right_hl.png
+++ b/scene/resources/default_theme/scroll_button_right_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_up.png b/scene/resources/default_theme/scroll_button_up.png
index a88d17e1c5..2c8238ae4c 100644
--- a/scene/resources/default_theme/scroll_button_up.png
+++ b/scene/resources/default_theme/scroll_button_up.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_button_up_hl.png b/scene/resources/default_theme/scroll_button_up_hl.png
index 04ce402964..4283bd114a 100644
--- a/scene/resources/default_theme/scroll_button_up_hl.png
+++ b/scene/resources/default_theme/scroll_button_up_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_grabber.png b/scene/resources/default_theme/scroll_grabber.png
index 4be7f4e6cc..1d625a9b7b 100644
--- a/scene/resources/default_theme/scroll_grabber.png
+++ b/scene/resources/default_theme/scroll_grabber.png
Binary files differ
diff --git a/scene/resources/default_theme/scroll_grabber_hl.png b/scene/resources/default_theme/scroll_grabber_hl.png
index 8d0a15ac58..99eb24b7e7 100644
--- a/scene/resources/default_theme/scroll_grabber_hl.png
+++ b/scene/resources/default_theme/scroll_grabber_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/selection.png b/scene/resources/default_theme/selection.png
index 1aa4ffa86f..501877a8b4 100644
--- a/scene/resources/default_theme/selection.png
+++ b/scene/resources/default_theme/selection.png
Binary files differ
diff --git a/scene/resources/default_theme/selection_oof.png b/scene/resources/default_theme/selection_oof.png
index 7b485eec3b..9594fe0913 100644
--- a/scene/resources/default_theme/selection_oof.png
+++ b/scene/resources/default_theme/selection_oof.png
Binary files differ
diff --git a/scene/resources/default_theme/source/arrow_down.svg b/scene/resources/default_theme/source/arrow_down.svg
index 1dd209720f..354040b548 100644
--- a/scene/resources/default_theme/source/arrow_down.svg
+++ b/scene/resources/default_theme/source/arrow_down.svg
@@ -14,7 +14,7 @@
viewBox="0 0 12 12"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="22.627417"
- inkscape:cx="1.7981958"
- inkscape:cy="7.5815407"
+ inkscape:zoom="64"
+ inkscape:cx="5.7299355"
+ inkscape:cy="6.6875366"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -71,10 +71,10 @@
id="layer1"
transform="translate(0,-1040.3622)">
<path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
- d="m 3,1045.3622 3,3 3,-3"
- id="path814"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 2,1043.3622 0,3 4,3 4,-3 0,-3 z"
+ id="rect4174"
inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
+ sodipodi:nodetypes="cccccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/arrow_right.svg b/scene/resources/default_theme/source/arrow_right.svg
index 43134ba1b1..4c4bc05e28 100644
--- a/scene/resources/default_theme/source/arrow_right.svg
+++ b/scene/resources/default_theme/source/arrow_right.svg
@@ -14,7 +14,7 @@
viewBox="0 0 12 12"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="45.254836"
- inkscape:cx="4.0845752"
- inkscape:cy="5.8802612"
+ inkscape:cx="3.0018179"
+ inkscape:cy="6.0349408"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -71,10 +71,10 @@
id="layer1"
transform="translate(0,-1040.3622)">
<path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.39215687"
- d="m 4,1049.3622 3.0000202,-3 -3.0000202,-3"
- id="path814"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 3,1050.3622 3,0 3,-4 -3,-4 -3,0 z"
+ id="rect4174"
inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccc" />
+ sodipodi:nodetypes="cccccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/button_disabled.svg b/scene/resources/default_theme/source/button_disabled.svg
deleted file mode 100644
index eb4ce87e36..0000000000
--- a/scene/resources/default_theme/source/button_disabled.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="button_disabled.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_disabled.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="3.3006706"
- inkscape:cy="10.701568"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#425468;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/button_hover.svg b/scene/resources/default_theme/source/button_hover.svg
deleted file mode 100644
index 46a58b1917..0000000000
--- a/scene/resources/default_theme/source/button_hover.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="button_hover.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_hover.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="3.6900507"
- inkscape:cy="7.7665583"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#70b1ff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/button_normal.svg b/scene/resources/default_theme/source/button_normal.svg
deleted file mode 100644
index c0fc1f2c5a..0000000000
--- a/scene/resources/default_theme/source/button_normal.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="button_normal.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_hover.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="3.0075667"
- inkscape:cy="8.2242067"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#788da3;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/button_pressed.svg b/scene/resources/default_theme/source/button_pressed.svg
deleted file mode 100644
index e761b07eb1..0000000000
--- a/scene/resources/default_theme/source/button_pressed.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="button_pressed.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_pressed.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="5.7152485"
- inkscape:cy="9.8535758"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#7eff8a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/focus.svg b/scene/resources/default_theme/source/focus.svg
deleted file mode 100644
index 4fd463b206..0000000000
--- a/scene/resources/default_theme/source/focus.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="focus.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="64.000003"
- inkscape:cx="3.8318954"
- inkscape:cy="6.6190751"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)" />
-</svg>
diff --git a/scene/resources/default_theme/source/frame_focus.svg b/scene/resources/default_theme/source/frame_focus.svg
deleted file mode 100644
index fba950091a..0000000000
--- a/scene/resources/default_theme/source/frame_focus.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="frame_focus.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="64.000003"
- inkscape:cx="3.8318954"
- inkscape:cy="6.6190751"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)" />
-</svg>
diff --git a/scene/resources/default_theme/source/full_panel_bg.svg b/scene/resources/default_theme/source/full_panel_bg.svg
deleted file mode 100644
index 4adceb5254..0000000000
--- a/scene/resources/default_theme/source/full_panel_bg.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="full_panel_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="11.313708"
- inkscape:cx="7.9626269"
- inkscape:cy="2.5437896"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#232a32;fill-opacity:1;stroke:#2e3842;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/graph_node.svg b/scene/resources/default_theme/source/graph_node.svg
deleted file mode 100644
index f309f29d9a..0000000000
--- a/scene/resources/default_theme/source/graph_node.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="70"
- viewBox="0 0 16 69.999996"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="graph_node.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.9999996"
- inkscape:cx="7.4490379"
- inkscape:cy="37.697586"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-982.3623)">
- <path
- style="opacity:1;fill:#afabf1;fill-opacity:0.78431374;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 3 1 C 1.3380048 1 0 2.3380048 0 4 L 0 66 C 0 67.661995 1.3380048 69 3 69 L 13 69 C 14.661995 69 16 67.661995 16 66 L 16 4 C 16 2.3380048 14.661995 1 13 1 L 3 1 z M 2 23 L 14 23 L 14 66 C 14 66.554 13.554 67 13 67 L 3 67 C 2.446 67 2 66.554 2 66 L 2 23 z "
- id="rect4144"
- transform="translate(0,982.3623)" />
- <path
- style="opacity:1;fill:#1d1836;fill-opacity:0.58823532;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1005.3623 0,43 c 0,0.554 0.446,1 1,1 l 10,0 c 0.554,0 1,-0.446 1,-1 l 0,-43 z"
- id="rect4194"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csssscc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/graph_node_comment.svg b/scene/resources/default_theme/source/graph_node_comment.svg
deleted file mode 100644
index 4b41b9b3d0..0000000000
--- a/scene/resources/default_theme/source/graph_node_comment.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="70"
- viewBox="0 0 16 69.999996"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="graph_node_comment.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.9999996"
- inkscape:cx="7.9593685"
- inkscape:cy="41.411006"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-982.3623)">
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.58823532;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 3 1 C 1.3380048 1 0 2.3380048 0 4 L 0 66 C 0 67.661995 1.3380048 69 3 69 L 13 69 C 14.661995 69 16 67.661995 16 66 L 16 4 C 16 2.3380048 14.661995 1 13 1 L 3 1 z M 2 23 L 14 23 L 14 66 C 14 66.554 13.554 67 13 67 L 3 67 C 2.446 67 2 66.554 2 66 L 2 23 z "
- transform="translate(0,982.3623)"
- id="rect4144" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.19607843;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1005.3623 0,43 c 0,0.554 0.446,1 1,1 l 10,0 c 0.554,0 1,-0.446 1,-1 l 0,-43 z"
- id="rect4194"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csssscc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/graph_node_comment_focus.svg b/scene/resources/default_theme/source/graph_node_comment_focus.svg
deleted file mode 100644
index af60130ea0..0000000000
--- a/scene/resources/default_theme/source/graph_node_comment_focus.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="70"
- viewBox="0 0 16 69.999996"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="graph_node_comment_focus.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.9999997"
- inkscape:cx="13.69465"
- inkscape:cy="33.350792"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-982.3623)">
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.88235295;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 3 1 C 1.3380048 1 0 2.3380048 0 4 L 0 66 C 0 67.661995 1.3380048 69 3 69 L 13 69 C 14.661995 69 16 67.661995 16 66 L 16 4 C 16 2.3380048 14.661995 1 13 1 L 3 1 z M 2 23 L 14 23 L 14 66 C 14 66.554 13.554 67 13 67 L 3 67 C 2.446 67 2 66.554 2 66 L 2 23 z "
- transform="translate(0,982.3623)"
- id="rect4144" />
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.19607843;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1005.3623 0,43 c 0,0.554 0.446,1 1,1 l 10,0 c 0.554,0 1,-0.446 1,-1 l 0,-43 z"
- id="rect4194"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csssscc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/graph_node_position.svg b/scene/resources/default_theme/source/graph_node_position.svg
deleted file mode 100644
index 6d98d8b115..0000000000
--- a/scene/resources/default_theme/source/graph_node_position.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="70"
- viewBox="0 0 16 69.999996"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="graph_node_position.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="11.313708"
- inkscape:cx="17.794895"
- inkscape:cy="40.559851"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-982.3623)">
- <path
- style="opacity:1;fill:#ff8484;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 3 1 C 1.3380048 1 0 2.3380048 0 4 L 0 66 C 0 67.661995 1.3380048 69 3 69 L 13 69 C 14.661995 69 16 67.661995 16 66 L 16 4 C 16 2.3380048 14.661995 1 13 1 L 3 1 z M 3 3 L 13 3 C 13.554 3 14 3.446 14 4 L 14 23 L 14 47 L 14 66 C 14 66.554 13.554 67 13 67 L 3 67 C 2.446 67 2 66.554 2 66 L 2 47 L 2 23 L 2 4 C 2 3.446 2.446 3 3 3 z "
- transform="translate(0,982.3623)"
- id="rect4144" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/graph_node_selected.svg b/scene/resources/default_theme/source/graph_node_selected.svg
deleted file mode 100644
index a480cb8ab8..0000000000
--- a/scene/resources/default_theme/source/graph_node_selected.svg
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="70"
- viewBox="0 0 16 69.999996"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="graph_node_selected.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="7.9999996"
- inkscape:cx="29.199039"
- inkscape:cy="37.947586"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-982.3623)">
- <path
- style="opacity:1;fill:#cac8f6;fill-opacity:0.88235295;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 3 1 C 1.3380048 1 0 2.3380048 0 4 L 0 66 C 0 67.661995 1.3380048 69 3 69 L 13 69 C 14.661995 69 16 67.661995 16 66 L 16 4 C 16 2.3380048 14.661995 1 13 1 L 3 1 z M 2 23 L 14 23 L 14 66 C 14 66.554 13.554 67 13 67 L 3 67 C 2.446 67 2 66.554 2 66 L 2 23 z "
- id="rect4144"
- transform="translate(0,982.3623)" />
- <path
- style="opacity:1;fill:#1d1836;fill-opacity:0.58823532;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1005.3623 0,43 c 0,0.554 0.446,1 1,1 l 10,0 c 0.554,0 1,-0.446 1,-1 l 0,-43 z"
- id="rect4194"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="csssscc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/icon_close.svg b/scene/resources/default_theme/source/icon_close.svg
index f0eb83f54d..6e6ec16638 100644
--- a/scene/resources/default_theme/source/icon_close.svg
+++ b/scene/resources/default_theme/source/icon_close.svg
@@ -14,7 +14,7 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="7.6258883"
- inkscape:cy="7.576455"
+ inkscape:zoom="22.627418"
+ inkscape:cx="1.8501874"
+ inkscape:cy="8.0543329"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
@@ -69,15 +69,26 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
- <path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 4,1040.3622 8,8"
- id="path814"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 4,1048.3622 8,-8"
- id="path816"
- inkscape:connector-curvature="0" />
+ <g
+ id="layer1-4"
+ inkscape:label="Layer 1"
+ transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-736.13242,311.54347)"
+ style="fill:#080808;fill-opacity:1">
+ <rect
+ y="1043.3622"
+ x="1"
+ height="1.9999478"
+ width="14"
+ id="rect4137"
+ style="fill:#080808;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#080808;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4158"
+ width="13.999966"
+ height="2.0000017"
+ x="1037.3622"
+ y="-9" />
+ </g>
</g>
</svg>
diff --git a/scene/resources/default_theme/source/line_edit.svg b/scene/resources/default_theme/source/line_edit.svg
deleted file mode 100644
index bcddf8bf7f..0000000000
--- a/scene/resources/default_theme/source/line_edit.svg
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="line_edit.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_container_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="3.5104007"
- inkscape:cy="4.8259288"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-nodes="false"
- inkscape:snap-bbox-midpoints="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#303b46;fill-opacity:1;stroke:#2c3640;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- <path
- style="fill:none;fill-opacity:1;stroke:#788da3;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,11 c 0,1.661997 1.3380026,3 3,3 h 6 c 1.661997,0 3,-1.338003 3,-3"
- id="rect4503"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cssc"
- transform="translate(0,1036.3623)" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/line_edit_active.svg b/scene/resources/default_theme/source/line_edit_active.svg
deleted file mode 100644
index e823138141..0000000000
--- a/scene/resources/default_theme/source/line_edit_active.svg
+++ /dev/null
@@ -1,89 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="line_edit_selected.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_container_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="6.0294685"
- inkscape:cy="5.7319094"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-nodes="false"
- inkscape:snap-bbox-midpoints="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#303b46;fill-opacity:1;stroke:#2c3640;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- <path
- style="fill:none;fill-opacity:1;stroke:#7eff8a;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,11 c 0,1.661997 1.3380026,3 3,3 h 6 c 1.661997,0 3,-1.338003 3,-3"
- id="rect4503"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cssc"
- transform="translate(0,1036.3623)" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/line_edit_disabled.svg b/scene/resources/default_theme/source/line_edit_disabled.svg
deleted file mode 100644
index 9e60d7ccbd..0000000000
--- a/scene/resources/default_theme/source/line_edit_disabled.svg
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="line_edit_disabled.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_container_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="2.2717731"
- inkscape:cy="8.8637422"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#303b46;fill-opacity:1;stroke:#2c3640;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- <path
- style="fill:none;fill-opacity:1;stroke:#425468;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 2,1047.3623 c 0,1.662 1.338003,3 3,3 h 6 c 1.661997,0 3,-1.338 3,-3"
- id="rect4503"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cssc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/option_arrow.svg b/scene/resources/default_theme/source/option_arrow.svg
index 5cd943e9e3..cd78404ff1 100644
--- a/scene/resources/default_theme/source/option_arrow.svg
+++ b/scene/resources/default_theme/source/option_arrow.svg
@@ -14,7 +14,7 @@
viewBox="0 0 12 12"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="3.1667338"
- inkscape:cy="5.9875884"
+ inkscape:zoom="45.254836"
+ inkscape:cx="6.0969578"
+ inkscape:cy="7.5632913"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -61,7 +61,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -71,10 +71,16 @@
id="layer1"
transform="translate(0,-1040.3622)">
<path
+ style="fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 3,1045.3622 6,0 -3,-4 z"
+ id="path4158"
inkscape:connector-curvature="0"
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 9.9999996,1043.3583 c -0.2637796,0.01 -0.5144012,0.1165 -0.697265,0.3067 l -3.292969,3.2929 -3.2929688,-3.2929 C 2.5285367,1043.4714 2.2700113,1043.3622 2,1043.3622 c -0.8974208,2e-4 -1.34038281,1.0909 -0.6972656,1.7168 l 4,4 c 0.3905299,0.3904 1.0235325,0.3904 1.4140624,0 l 4.0000002,-4 c 0.657344,-0.6321 0.194906,-1.7422 -0.7167974,-1.7207 z"
- id="path4484"
- sodipodi:nodetypes="cccccccccc" />
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4160"
+ d="m 3,1047.3622 6,0 -3,4 z"
+ style="fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/panel_bg.svg b/scene/resources/default_theme/source/panel_bg.svg
deleted file mode 100644
index 5115d3d0ac..0000000000
--- a/scene/resources/default_theme/source/panel_bg.svg
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="8"
- height="8"
- viewBox="0 0 8 7.9999995"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="panel_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="6.4834446"
- inkscape:cy="3.3875925"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1044.3623)">
- <rect
- style="opacity:1;fill:#232a32;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect4213"
- width="8"
- height="7.999999"
- x="0"
- y="1044.3623" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/popup_bg.svg b/scene/resources/default_theme/source/popup_bg.svg
deleted file mode 100644
index cbf356aec0..0000000000
--- a/scene/resources/default_theme/source/popup_bg.svg
+++ /dev/null
@@ -1,87 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="popup_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/popup_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="6.6514997"
- inkscape:cy="9.5440638"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="false">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#000000;fill-opacity:0.19607843;fill-rule:nonzero;stroke:none;stroke-width:1.77777672;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="M 4.4453125,1036.3633 C 1.9984702,1036.3633 0,1038.3598 0,1040.8066 v 7.1114 c 0,2.4468 1.9984702,4.4453 4.4453125,4.4453 H 11.554688 C 14.00153,1052.3633 16,1050.3648 16,1047.918 v -7.1114 c 0,-2.4468 -1.99847,-4.4433 -4.445312,-4.4433 z"
- id="rect4497"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="sssssssss" />
- <rect
- style="fill:#394653;fill-opacity:1;stroke:#455463;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/popup_window.svg b/scene/resources/default_theme/source/popup_window.svg
deleted file mode 100644
index 43aabb3ca2..0000000000
--- a/scene/resources/default_theme/source/popup_window.svg
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="20"
- height="36"
- viewBox="0 0 20 35.999998"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="popup_window.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/full_panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="22.627416"
- inkscape:cx="10.268488"
- inkscape:cy="24.750533"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1016.3623)">
- <rect
- style="fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:1.8106823;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4499"
- width="18"
- height="33.999996"
- x="1"
- y="1017.3623"
- ry="5.9999952" />
- <rect
- ry="4.9999952"
- y="1018.3623"
- x="2"
- height="31.999996"
- width="16"
- id="rect4497"
- style="fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:1.65615714;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- <rect
- style="fill:#394653;fill-opacity:1;stroke:#455463;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484"
- width="12"
- height="27.999996"
- x="4"
- y="1020.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/progress_bar.svg b/scene/resources/default_theme/source/progress_bar.svg
deleted file mode 100644
index ddaac73547..0000000000
--- a/scene/resources/default_theme/source/progress_bar.svg
+++ /dev/null
@@ -1,72 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="progress_bar.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/popup_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="6.2769476"
- inkscape:cy="8.8116358"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="false">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)" />
-</svg>
diff --git a/scene/resources/default_theme/source/progress_fill.svg b/scene/resources/default_theme/source/progress_fill.svg
deleted file mode 100644
index 99b6a45bf5..0000000000
--- a/scene/resources/default_theme/source/progress_fill.svg
+++ /dev/null
@@ -1,82 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="progress_fill.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/popup_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="5.2752007"
- inkscape:cy="7.6135176"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="false"
- inkscape:snap-midpoints="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <circle
- style="fill:#7eff8a;fill-opacity:1;stroke:none;stroke-width:1.0285722;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="path816"
- cx="8"
- cy="1044.3623"
- r="6.0000048" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/radio_checked.svg b/scene/resources/default_theme/source/radio_checked.svg
deleted file mode 100644
index cbfb407bf2..0000000000
--- a/scene/resources/default_theme/source/radio_checked.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="radio_checked.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="4.875052"
- inkscape:cy="10.187321"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="opacity:1;fill:#e0e0e0;fill-opacity:0.78431374;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 8 2 A 6 6 0 0 0 2 8 A 6 6 0 0 0 8 14 A 6 6 0 0 0 14 8 A 6 6 0 0 0 8 2 z M 8 4 A 4 4 0 0 1 12 8 A 4 4 0 0 1 8 12 A 4 4 0 0 1 4 8 A 4 4 0 0 1 8 4 z "
- transform="translate(0,1036.3623)"
- id="path4154" />
- <circle
- style="opacity:1;fill:#e0e0e0;fill-opacity:0.78431374;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="circle4158"
- cx="8"
- cy="1044.3623"
- r="3" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/radio_unchecked.svg b/scene/resources/default_theme/source/radio_unchecked.svg
deleted file mode 100644
index 0e3aaae6d9..0000000000
--- a/scene/resources/default_theme/source/radio_unchecked.svg
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="radio_unchecked.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="22.627417"
- inkscape:cx="-0.63112348"
- inkscape:cy="10.614735"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="opacity:1;fill:#e0e0e0;fill-opacity:0.78431374;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 8 2 A 6 6 0 0 0 2 8 A 6 6 0 0 0 8 14 A 6 6 0 0 0 14 8 A 6 6 0 0 0 8 2 z M 8 4 A 4 4 0 0 1 12 8 A 4 4 0 0 1 8 12 A 4 4 0 0 1 4 8 A 4 4 0 0 1 8 4 z "
- transform="translate(0,1036.3623)"
- id="path4154" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_down_hl.svg b/scene/resources/default_theme/source/scroll_button_down_hl.svg
deleted file mode 100644
index f0b461f037..0000000000
--- a/scene/resources/default_theme/source/scroll_button_down_hl.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_down_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="5.8513188"
- inkscape:cy="5.8532653"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#7eff8a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 10.023438,1044.3535 a 1.0001,1.0001 0 0 0 -0.6230474,0.209 L 6,1047.1113 2.5996094,1044.5625 a 1.0001,1.0001 0 1 0 -1.1992188,1.5996 l 4,3 a 1.0001,1.0001 0 0 0 1.1992188,0 l 3.9999996,-3 a 1.0001,1.0001 0 0 0 -0.576171,-1.8086 z"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_left.svg b/scene/resources/default_theme/source/scroll_button_left.svg
deleted file mode 100644
index 22d7f42001..0000000000
--- a/scene/resources/default_theme/source/scroll_button_left.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_left.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="4.5296015"
- inkscape:cy="7.0872243"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.27450982"
- d="m 6.999975,1042.3623 -3,4 3,4"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_left_hl.svg b/scene/resources/default_theme/source/scroll_button_left_hl.svg
deleted file mode 100644
index 22c24aae22..0000000000
--- a/scene/resources/default_theme/source/scroll_button_left_hl.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_left_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="4.238333"
- inkscape:cy="6.998836"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="fill:none;stroke:#7eff8a;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 6.999975,1042.3623 -3,4 3,4"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_right.svg b/scene/resources/default_theme/source/scroll_button_right.svg
deleted file mode 100644
index 95afabf006..0000000000
--- a/scene/resources/default_theme/source/scroll_button_right.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_right.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="3.1153879"
- inkscape:cy="6.4685059"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.2745098;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 5.0332031,1041.3516 a 1.0001,1.0001 0 0 0 -0.8339843,1.6113 l 2.5507812,3.3984 -2.5507812,3.4004 a 1.000985,1.000985 0 1 0 1.6015624,1.2012 l 3,-4 a 1.0001,1.0001 0 0 0 0,-1.2012 l -3,-4 a 1.0001,1.0001 0 0 0 -0.7675781,-0.4101 z"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_right_hl.svg b/scene/resources/default_theme/source/scroll_button_right_hl.svg
deleted file mode 100644
index c836c2975b..0000000000
--- a/scene/resources/default_theme/source/scroll_button_right_hl.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_right_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="3.1153879"
- inkscape:cy="6.4685059"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#7eff8a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 5.0332031,1041.3516 a 1.0001,1.0001 0 0 0 -0.8339843,1.6113 l 2.5507812,3.3984 -2.5507812,3.4004 a 1.000985,1.000985 0 1 0 1.6015624,1.2012 l 3,-4 a 1.0001,1.0001 0 0 0 0,-1.2012 l -3,-4 a 1.0001,1.0001 0 0 0 -0.7675781,-0.4101 z"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_up.svg b/scene/resources/default_theme/source/scroll_button_up.svg
deleted file mode 100644
index 90107666c9..0000000000
--- a/scene/resources/default_theme/source/scroll_button_up.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_up.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="1.4098045"
- inkscape:cy="5.764877"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:0.27450982;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 10.023438,1048.3706 a 1.0001,1.0001 0 0 1 -0.6230474,-0.209 L 6,1045.6128 l -3.4003906,2.5488 a 1.0001,1.0001 0 1 1 -1.1992188,-1.5996 l 4,-3 a 1.0001,1.0001 0 0 1 1.1992188,0 l 3.9999996,3 a 1.0001,1.0001 0 0 1 -0.576171,1.8086 z"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/scroll_button_up_hl.svg b/scene/resources/default_theme/source/scroll_button_up_hl.svg
deleted file mode 100644
index b5f92e0f8a..0000000000
--- a/scene/resources/default_theme/source/scroll_button_up_hl.svg
+++ /dev/null
@@ -1,77 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="12"
- height="12"
- viewBox="0 0 12 11.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="scroll_button_up_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="1.4098045"
- inkscape:cy="5.764877"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1040.3623)">
- <path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#7eff8a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="m 10.023438,1048.3706 a 1.0001,1.0001 0 0 1 -0.6230474,-0.209 L 6,1045.6128 l -3.4003906,2.5488 a 1.0001,1.0001 0 1 1 -1.1992188,-1.5996 l 4,-3 a 1.0001,1.0001 0 0 1 1.1992188,0 l 3.9999996,3 a 1.0001,1.0001 0 0 1 -0.576171,1.8086 z"
- id="path4511"
- inkscape:connector-curvature="0" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/selection.svg b/scene/resources/default_theme/source/selection.svg
deleted file mode 100644
index 7346191195..0000000000
--- a/scene/resources/default_theme/source/selection.svg
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="selection.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_pressed.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="9.5458029"
- inkscape:cy="7.3443927"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294119"
- id="rect823"
- width="14"
- height="9.9999952"
- x="1"
- y="1039.3623"
- ry="3.9999952" />
- <rect
- ry="2.9999952"
- y="1040.3623"
- x="1.9999952"
- height="7.9999952"
- width="12.00001"
- id="rect825"
- style="fill:#ffffff;fill-opacity:0.19607843;stroke:none;stroke-width:1.71428704;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/selection_oof.svg b/scene/resources/default_theme/source/selection_oof.svg
deleted file mode 100644
index f12b066a52..0000000000
--- a/scene/resources/default_theme/source/selection_oof.svg
+++ /dev/null
@@ -1,88 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="selection_oof.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_pressed.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="16"
- inkscape:cx="-2.3310576"
- inkscape:cy="4.9359914"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:none;fill-opacity:0.19607843;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294119"
- id="rect823"
- width="14"
- height="14"
- x="1"
- y="1037.3623"
- ry="3.9999952" />
- <rect
- ry="2.9999952"
- y="1038.3623"
- x="1.9999954"
- height="12.00001"
- width="12.00001"
- id="rect825"
- style="fill:#ffffff;fill-opacity:0.19607843;stroke:none;stroke-width:1.71428704;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/spinbox_updown.svg b/scene/resources/default_theme/source/spinbox_updown.svg
index e29d7fe0d2..5b8e0a83eb 100644
--- a/scene/resources/default_theme/source/spinbox_updown.svg
+++ b/scene/resources/default_theme/source/spinbox_updown.svg
@@ -14,7 +14,7 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,11 +28,11 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="16"
- inkscape:cx="-1.901723"
- inkscape:cy="9.1326297"
+ inkscape:zoom="45.254834"
+ inkscape:cx="5.7914867"
+ inkscape:cy="9.8174296"
inkscape:document-units="px"
- inkscape:current-layer="layer1-5"
+ inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:snap-bbox="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -71,13 +71,16 @@
id="layer1"
transform="translate(0,-1036.3622)">
<path
- style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#e0e0e0;fill-opacity:0.78431374;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
- d="M 7.984375 1.0019531 A 1.0001 1.0001 0 0 0 7.2929688 1.2929688 L 3.2929688 5.2929688 A 1.0001 1.0001 0 1 0 4.7070312 6.7070312 L 8 3.4140625 L 11.292969 6.7070312 A 1.0001 1.0001 0 1 0 12.707031 5.2929688 L 8.7070312 1.2929688 A 1.0001 1.0001 0 0 0 7.984375 1.0019531 z M 11.990234 8.9863281 A 1.0001 1.0001 0 0 0 11.292969 9.2929688 L 8 12.585938 L 4.7070312 9.2929688 A 1.0001 1.0001 0 0 0 3.9902344 8.9902344 A 1.0001 1.0001 0 0 0 3.2929688 10.707031 L 7.2929688 14.707031 A 1.0001 1.0001 0 0 0 8.7070312 14.707031 L 12.707031 10.707031 A 1.0001 1.0001 0 0 0 11.990234 8.9863281 z "
- transform="translate(0,1036.3622)"
- id="path4484" />
- <g
- id="layer1-5"
- inkscape:label="Layer 1"
- transform="translate(14.210182,-5.3664)" />
+ style="fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 4,1042.3622 8,0 -4,-5 z"
+ id="path4158"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccc" />
+ <path
+ inkscape:connector-curvature="0"
+ id="path4160"
+ d="m 4,1046.3622 8,0 -4,5 z"
+ style="fill:#e0e0e0;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ sodipodi:nodetypes="cccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/submenu.svg b/scene/resources/default_theme/source/submenu.svg
index 927338d9bb..ef7f696571 100644
--- a/scene/resources/default_theme/source/submenu.svg
+++ b/scene/resources/default_theme/source/submenu.svg
@@ -14,7 +14,7 @@
viewBox="0 0 8 8"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="64.000003"
- inkscape:cx="5.7489132"
- inkscape:cy="3.1277668"
+ inkscape:cx="1.4039962"
+ inkscape:cy="5.6866955"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -71,9 +71,10 @@
id="layer1"
transform="translate(0,-1044.3622)">
<path
- style="fill:none;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:0.78431374;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 3,1045.3622 3,3 -3,3"
- id="path814"
- inkscape:connector-curvature="0" />
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 1,1052.3622 3,0 3,-4 -3,-4 -3,0 z"
+ id="rect4174"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/tab_behind.svg b/scene/resources/default_theme/source/tab_behind.svg
deleted file mode 100644
index 5fa84ffda5..0000000000
--- a/scene/resources/default_theme/source/tab_behind.svg
+++ /dev/null
@@ -1,71 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tab_behind.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_behind.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="10.899138"
- inkscape:cy="7.5918468"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)" />
-</svg>
diff --git a/scene/resources/default_theme/source/tab_close.svg b/scene/resources/default_theme/source/tab_close.svg
index f85518665b..65b71ae860 100644
--- a/scene/resources/default_theme/source/tab_close.svg
+++ b/scene/resources/default_theme/source/tab_close.svg
@@ -14,11 +14,11 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_add_track.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
- sodipodi:docname="tab_close.svg">
+ sodipodi:docname="icon_close.svg">
<defs
id="defs4" />
<sodipodi:namedview
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="45.254836"
- inkscape:cx="9.2858482"
- inkscape:cy="8.0181058"
+ inkscape:zoom="22.627418"
+ inkscape:cx="3.3969834"
+ inkscape:cy="11.678255"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1">
@@ -60,7 +60,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
+ <dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -69,15 +69,25 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
- <path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 4,1048.3622 8,-8"
- id="path819"
- inkscape:connector-curvature="0" />
- <path
- style="fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:0.39215687;stroke-miterlimit:4;stroke-dasharray:none"
- d="m 4,1040.3622 8,8"
- id="path821"
- inkscape:connector-curvature="0" />
+ <g
+ id="layer1-4"
+ inkscape:label="Layer 1"
+ transform="matrix(0.70710678,-0.70710678,0.70710678,0.70710678,-736.13242,311.54347)">
+ <rect
+ y="1043.3622"
+ x="1"
+ height="1.9999478"
+ width="14"
+ id="rect4137"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+ <rect
+ transform="matrix(0,1,-1,0,0,0)"
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect4158"
+ width="13.999966"
+ height="2.0000017"
+ x="1037.3622"
+ y="-9" />
+ </g>
</g>
</svg>
diff --git a/scene/resources/default_theme/source/tab_container_bg.svg b/scene/resources/default_theme/source/tab_container_bg.svg
deleted file mode 100644
index d19cb7cfa1..0000000000
--- a/scene/resources/default_theme/source/tab_container_bg.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tab_container_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_container_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="5.1997709"
- inkscape:cy="8.5220258"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#36424e;fill-opacity:1;stroke:#323d48;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tab_current.svg b/scene/resources/default_theme/source/tab_current.svg
deleted file mode 100644
index e43a83c3ec..0000000000
--- a/scene/resources/default_theme/source/tab_current.svg
+++ /dev/null
@@ -1,79 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tab_current.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/tab_current.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="45.254834"
- inkscape:cx="9.2059746"
- inkscape:cy="6.5875113"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="fill:#36424e;fill-opacity:1;stroke:#323d48;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 14,16 V 5 C 14,3.3380026 12.661997,2 11,2 H 5 C 3.3380026,2 2,3.3380026 2,5 v 11"
- transform="translate(0,1036.3623)"
- id="rect4484-6"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="ccsscc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tab_menu.svg b/scene/resources/default_theme/source/tab_menu.svg
index 39e0d1f261..84f7c8095a 100644
--- a/scene/resources/default_theme/source/tab_menu.svg
+++ b/scene/resources/default_theme/source/tab_menu.svg
@@ -14,7 +14,7 @@
viewBox="0 0 16 16"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -28,9 +28,9 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
- inkscape:zoom="32.000001"
- inkscape:cx="4.0814179"
- inkscape:cy="8.4695645"
+ inkscape:zoom="45.254836"
+ inkscape:cx="6.2944765"
+ inkscape:cy="7.7343939"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -70,23 +70,11 @@
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
- <circle
- style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
- id="path819"
- cx="8"
- cy="1038.3622"
- r="2" />
- <circle
- r="2"
- cy="1044.3622"
- cx="8"
- id="circle821"
- style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118" />
- <circle
- style="fill:#ffffff;fill-opacity:0.39215687;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.35294118"
- id="circle823"
- cx="8"
- cy="1050.3622"
- r="2" />
+ <path
+ style="fill:#e0e0e0;fill-opacity:1;stroke:none;stroke-width:6;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 4,1044.3622 0,3 4,3 4,-3 0,-3 z"
+ id="rect4174"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/toggle_off.svg b/scene/resources/default_theme/source/toggle_off.svg
deleted file mode 100644
index e5bf0e9809..0000000000
--- a/scene/resources/default_theme/source/toggle_off.svg
+++ /dev/null
@@ -1,86 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="64"
- height="32"
- viewBox="0 0 64 31.999998"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="toggle_off.svg"
- inkscape:export-filename="/home/djrm/Projects/gd_theme/assets/check_btn_off.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="11.313709"
- inkscape:cx="35.30642"
- inkscape:cy="10.306683"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1020.3623)">
- <path
- style="fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="M 24 6 A 10.000006 10.000006 0 0 0 14 16 A 10.000006 10.000006 0 0 0 24 26 L 40 26 A 9.9999943 9.9999943 0 0 0 50 16 A 9.9999943 9.9999943 0 0 0 40 6 L 24 6 z "
- transform="translate(0,1020.3623)"
- id="circle4160" />
- <circle
- r="7.9999924"
- cy="1036.3623"
- cx="-24.000006"
- id="circle4138"
- style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- transform="scale(-1,1)" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/toggle_on.svg b/scene/resources/default_theme/source/toggle_on.svg
deleted file mode 100644
index f8b55a853d..0000000000
--- a/scene/resources/default_theme/source/toggle_on.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="64"
- height="32"
- viewBox="0 0 64 31.999998"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="toggle_on.svg"
- inkscape:export-filename="/home/djrm/Projects/gd_theme/assets/check_btn_on.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="16.000001"
- inkscape:cx="31.866725"
- inkscape:cy="13.213395"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1020.3623)">
- <path
- inkscape:connector-curvature="0"
- style="fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- d="m 40.000015,1026.3623 a 10.000006,10.000006 0 0 1 10,10 10.000006,10.000006 0 0 1 -10,10 h -16 a 9.9999943,9.9999943 0 0 1 -10,-10 9.9999943,9.9999943 0 0 1 10,-10 z"
- id="circle4160" />
- <circle
- r="7.9999924"
- cy="1036.3623"
- cx="40.000008"
- id="circle4138"
- style="fill:#7eff8a;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tooltip_bg.svg b/scene/resources/default_theme/source/tooltip_bg.svg
deleted file mode 100644
index 84da6fe984..0000000000
--- a/scene/resources/default_theme/source/tooltip_bg.svg
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tooltip_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/button_pressed.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="1.4290295"
- inkscape:cy="8.0937882"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.78431373;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="m 3,1036.3623 c -1.661997,0 -3,1.338 -3,3 v 10 c 0,1.662 1.338003,3 3,3 h 10 c 1.661997,0 3,-1.338 3,-3 v -10 c 0,-1.662 -1.338003,-3 -3,-3 z m 0,2 h 10 c 0.553997,0 1,0.446 1,1 v 10 c 0,0.554 -0.446003,1 -1,1 H 3 c -0.553997,0 -1,-0.446 -1,-1 v -10 c 0,-0.554 0.446003,-1 1,-1 z"
- id="rect4166"
- inkscape:connector-curvature="0" />
- <rect
- style="opacity:1;fill:#ffffff;fill-opacity:0.68627451;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- id="rect4137"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="0.99999481" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tree_bg.svg b/scene/resources/default_theme/source/tree_bg.svg
deleted file mode 100644
index ba39010421..0000000000
--- a/scene/resources/default_theme/source/tree_bg.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tree_bg.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/panel_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32.000002"
- inkscape:cx="1.8744117"
- inkscape:cy="8.3113002"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="true"
- inkscape:snap-intersection-paths="true"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title></dc:title>
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="fill:#2b353f;fill-opacity:1;stroke:#252e37;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4484-6"
- width="12"
- height="12"
- x="2"
- y="1038.3623"
- ry="2.9999952" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tree_title.svg b/scene/resources/default_theme/source/tree_title.svg
deleted file mode 100644
index f7140f3aff..0000000000
--- a/scene/resources/default_theme/source/tree_title.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tree_title.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/popup_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="11.133501"
- inkscape:cy="7.000622"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="false">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="opacity:1;fill:#000000;fill-opacity:0.19607843;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4158"
- width="16"
- height="16"
- x="0"
- y="1036.3623" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/tree_title_pressed.svg b/scene/resources/default_theme/source/tree_title_pressed.svg
deleted file mode 100644
index a1a6cd5a89..0000000000
--- a/scene/resources/default_theme/source/tree_title_pressed.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="tree_title_pressed.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/popup_bg.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="3.414751"
- inkscape:cy="7.219372"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- showguides="false">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <rect
- style="opacity:1;fill:#000000;fill-opacity:0.27450982;stroke:none;stroke-width:3;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
- id="rect4158"
- width="16"
- height="16"
- x="0"
- y="1036.3623" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/updown.svg b/scene/resources/default_theme/source/updown.svg
index 24e4ed0f23..adc72b405d 100644
--- a/scene/resources/default_theme/source/updown.svg
+++ b/scene/resources/default_theme/source/updown.svg
@@ -14,7 +14,7 @@
viewBox="0 0 8 16"
id="svg2"
version="1.1"
- inkscape:version="0.92.1 r"
+ inkscape:version="0.91 r13725"
inkscape:export-filename="/home/djrm/Projects/godot/tools/editor/icons/icon_collapse.png"
inkscape:export-xdpi="45"
inkscape:export-ydpi="45"
@@ -29,8 +29,8 @@
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="32.000001"
- inkscape:cx="-0.193656"
- inkscape:cy="9.787299"
+ inkscape:cx="-3.4436559"
+ inkscape:cy="10.099799"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
@@ -42,8 +42,8 @@
inkscape:snap-bbox-midpoints="false"
inkscape:snap-object-midpoints="true"
inkscape:snap-center="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
+ inkscape:window-width="1920"
+ inkscape:window-height="1016"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
@@ -71,7 +71,7 @@
id="layer1"
transform="translate(0,-1036.3622)">
<path
- style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.78431374"
+ style="fill:none;fill-rule:evenodd;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 1,1042.3565 3,-2.9943 3,2.9943"
id="path4155"
inkscape:connector-curvature="0"
@@ -80,7 +80,7 @@
inkscape:connector-curvature="0"
id="path4159"
d="m 1,1046.3622 3,3 3,-3"
- style="fill:none;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.78431374"
+ style="fill:none;fill-rule:evenodd;stroke:#e0e0e0;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
sodipodi:nodetypes="ccc" />
</g>
</svg>
diff --git a/scene/resources/default_theme/source/vslider_grabber.svg b/scene/resources/default_theme/source/vslider_grabber.svg
deleted file mode 100644
index 76703daa54..0000000000
--- a/scene/resources/default_theme/source/vslider_grabber.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="vslider_grabber.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="8.8922186"
- inkscape:cy="6.4674144"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <circle
- r="6.9999943"
- cy="1044.3623"
- cx="8.0000057"
- id="circle4262"
- style="fill:#d3d3d3;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/vslider_grabber_hl.svg b/scene/resources/default_theme/source/vslider_grabber_hl.svg
deleted file mode 100644
index b688130f24..0000000000
--- a/scene/resources/default_theme/source/vslider_grabber_hl.svg
+++ /dev/null
@@ -1,80 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.92.1 r"
- sodipodi:docname="vslider_grabber_hl.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/checked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="7.0748113"
- inkscape:cy="6.0432589"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1600"
- inkscape:window-height="836"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <circle
- r="6.9999943"
- cy="1044.3623"
- cx="8.0000057"
- id="circle4262"
- style="fill:#7eff8a;fill-opacity:1;stroke:none;stroke-width:20;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/source/window_resizer.svg b/scene/resources/default_theme/source/window_resizer.svg
deleted file mode 100644
index ef92d64be0..0000000000
--- a/scene/resources/default_theme/source/window_resizer.svg
+++ /dev/null
@@ -1,81 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
- xmlns:svg="http://www.w3.org/2000/svg"
- xmlns="http://www.w3.org/2000/svg"
- xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
- xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
- width="16"
- height="16"
- viewBox="0 0 16 15.999999"
- id="svg2"
- version="1.1"
- inkscape:version="0.91 r13725"
- sodipodi:docname="window_resizer.svg"
- inkscape:export-filename="/home/djrm/Projects/godot/scene/resources/default_theme/unchecked.png"
- inkscape:export-xdpi="90"
- inkscape:export-ydpi="90">
- <defs
- id="defs4" />
- <sodipodi:namedview
- id="base"
- pagecolor="#ffffff"
- bordercolor="#666666"
- borderopacity="1.0"
- inkscape:pageopacity="0.0"
- inkscape:pageshadow="2"
- inkscape:zoom="32"
- inkscape:cx="-3.1015509"
- inkscape:cy="9.5660349"
- inkscape:document-units="px"
- inkscape:current-layer="layer1"
- showgrid="true"
- units="px"
- inkscape:object-paths="false"
- inkscape:snap-intersection-paths="false"
- inkscape:snap-bbox="true"
- inkscape:bbox-paths="true"
- inkscape:bbox-nodes="true"
- inkscape:snap-bbox-edge-midpoints="true"
- inkscape:window-width="1920"
- inkscape:window-height="1016"
- inkscape:window-x="0"
- inkscape:window-y="27"
- inkscape:window-maximized="1"
- inkscape:snap-midpoints="true"
- inkscape:snap-smooth-nodes="true"
- inkscape:object-nodes="true">
- <inkscape:grid
- type="xygrid"
- id="grid4136"
- empspacing="4" />
- </sodipodi:namedview>
- <metadata
- id="metadata7">
- <rdf:RDF>
- <cc:Work
- rdf:about="">
- <dc:format>image/svg+xml</dc:format>
- <dc:type
- rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
- <dc:title />
- </cc:Work>
- </rdf:RDF>
- </metadata>
- <g
- inkscape:label="Layer 1"
- inkscape:groupmode="layer"
- id="layer1"
- transform="translate(0,-1036.3623)">
- <path
- style="opacity:1;fill:#ffffff;fill-opacity:0.78431373;stroke:none;stroke-width:2;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
- d="m 2.0000005,1047.3623 8.9999995,0 0,-9 z"
- id="circle4178"
- inkscape:connector-curvature="0"
- sodipodi:nodetypes="cccc" />
- </g>
-</svg>
diff --git a/scene/resources/default_theme/spinbox_updown.png b/scene/resources/default_theme/spinbox_updown.png
index ff65df801b..b40b1e9fd2 100644
--- a/scene/resources/default_theme/spinbox_updown.png
+++ b/scene/resources/default_theme/spinbox_updown.png
Binary files differ
diff --git a/scene/resources/default_theme/submenu.png b/scene/resources/default_theme/submenu.png
index 465afe7786..ec727eecf1 100644
--- a/scene/resources/default_theme/submenu.png
+++ b/scene/resources/default_theme/submenu.png
Binary files differ
diff --git a/scene/resources/default_theme/tab.png b/scene/resources/default_theme/tab.png
index 951a4a3e76..3e4d792a48 100644
--- a/scene/resources/default_theme/tab.png
+++ b/scene/resources/default_theme/tab.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_behind.png b/scene/resources/default_theme/tab_behind.png
index d3e1838248..12f07c3a91 100644
--- a/scene/resources/default_theme/tab_behind.png
+++ b/scene/resources/default_theme/tab_behind.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_close.png b/scene/resources/default_theme/tab_close.png
index b6973740e7..20d9b5c810 100644
--- a/scene/resources/default_theme/tab_close.png
+++ b/scene/resources/default_theme/tab_close.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_container_backup.png b/scene/resources/default_theme/tab_container_backup.png
deleted file mode 100644
index f87905b1da..0000000000
--- a/scene/resources/default_theme/tab_container_backup.png
+++ /dev/null
Binary files differ
diff --git a/scene/resources/default_theme/tab_container_bg.png b/scene/resources/default_theme/tab_container_bg.png
index 1b62e2690c..92482aaf28 100644
--- a/scene/resources/default_theme/tab_container_bg.png
+++ b/scene/resources/default_theme/tab_container_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_current.png b/scene/resources/default_theme/tab_current.png
index c1f0ba24d4..7289e032da 100644
--- a/scene/resources/default_theme/tab_current.png
+++ b/scene/resources/default_theme/tab_current.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_menu.png b/scene/resources/default_theme/tab_menu.png
index ffc63f2d41..148b64b8aa 100644
--- a/scene/resources/default_theme/tab_menu.png
+++ b/scene/resources/default_theme/tab_menu.png
Binary files differ
diff --git a/scene/resources/default_theme/tab_menu_hl.png b/scene/resources/default_theme/tab_menu_hl.png
index ffc63f2d41..148b64b8aa 100644
--- a/scene/resources/default_theme/tab_menu_hl.png
+++ b/scene/resources/default_theme/tab_menu_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/theme_data.h b/scene/resources/default_theme/theme_data.h
index eba925cfe0..b9c401525a 100644
--- a/scene/resources/default_theme/theme_data.h
+++ b/scene/resources/default_theme/theme_data.h
@@ -3,11 +3,11 @@
// png image block
static const unsigned char arrow_down_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x5f, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xd5, 0x8f, 0x31, 0xa, 0x80, 0x40, 0x10, 0x3, 0x27, 0x9e, 0x8d, 0xa5, 0xe0, 0x9f, 0x84, 0xc3, 0xe7, 0x8a, 0xe0, 0xab, 0x2c, 0x6d, 0x84, 0xb5, 0xd9, 0x95, 0xe3, 0xbc, 0x7, 0x68, 0xaa, 0x10, 0x32, 0x64, 0x17, 0xfe, 0x2f, 0x85, 0x31, 0xb3, 0x5, 0xe8, 0x81, 0x5d, 0xd2, 0xe9, 0xd9, 0x0, 0xcc, 0xc0, 0x25, 0x69, 0x5, 0xe8, 0xa, 0x38, 0x1, 0x13, 0x90, 0xcd, 0x6c, 0xf0, 0x72, 0xf6, 0x2c, 0xb5, 0x16, 0xa2, 0x30, 0x2, 0x87, 0xc7, 0xe1, 0xb7, 0x58, 0x7d, 0x80, 0x6, 0x44, 0x5d, 0x7e, 0x1, 0xd5, 0xdd, 0x94, 0xff, 0x7c, 0x58, 0x37, 0xd0, 0xd, 0x22, 0xd5, 0xdc, 0x5c, 0xa1, 0xab, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6d, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0x18, 0x74, 0x80, 0x11, 0xc6, 0x78, 0xf0, 0xe0, 0xc1, 0x7f, 0x7c, 0xa, 0x15, 0x14, 0x14, 0x18, 0x19, 0x18, 0x18, 0x18, 0x98, 0x48, 0xb5, 0x81, 0x7c, 0xd, 0x8c, 0x8c, 0x8c, 0xf1, 0xc, 0xc, 0xc, 0x5f, 0xb1, 0xa8, 0xf9, 0xce, 0xc8, 0xc8, 0x98, 0xe, 0x57, 0x87, 0x2c, 0x73, 0xff, 0xfe, 0x7d, 0xd, 0x6, 0x6, 0x86, 0x55, 0x8c, 0x8c, 0x8c, 0xba, 0x50, 0xa1, 0x1b, 0xcc, 0xcc, 0xcc, 0x61, 0xb2, 0xb2, 0xb2, 0x97, 0xb1, 0x6a, 0x60, 0x60, 0x60, 0x60, 0x78, 0xf1, 0xe2, 0x5, 0xf7, 0xcf, 0x9f, 0x3f, 0xa7, 0x30, 0x30, 0x30, 0x30, 0xb0, 0xb3, 0xb3, 0xe7, 0x48, 0x48, 0x48, 0x60, 0xb3, 0x75, 0x30, 0x1, 0x0, 0x28, 0x20, 0x14, 0xc2, 0x1b, 0xd0, 0x7c, 0xca, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char arrow_right_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x72, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xb5, 0xd0, 0xb1, 0xe, 0x1, 0x61, 0x14, 0x44, 0xe1, 0xef, 0xb2, 0x5, 0x2a, 0xc4, 0x2b, 0x89, 0x58, 0x9e, 0x97, 0xac, 0x67, 0x12, 0x74, 0x34, 0x72, 0x35, 0x5b, 0xf0, 0x67, 0xb3, 0xab, 0xd9, 0xe9, 0x4e, 0x71, 0x32, 0x93, 0x61, 0xec, 0xc4, 0x37, 0x64, 0xe6, 0x11, 0x15, 0x9a, 0x88, 0x78, 0x76, 0x9, 0x93, 0x82, 0xa7, 0xd8, 0xa0, 0xce, 0xcc, 0xf9, 0x3f, 0x42, 0x83, 0x1b, 0x56, 0x38, 0x64, 0xe6, 0xa2, 0x57, 0x88, 0x88, 0x17, 0xce, 0xb8, 0x63, 0x89, 0xed, 0x50, 0xc3, 0x60, 0x7e, 0x84, 0xcc, 0x9c, 0x61, 0xdf, 0x4e, 0x7a, 0xe0, 0x52, 0xa, 0x55, 0xc1, 0x3b, 0xac, 0xdb, 0x49, 0xa7, 0xae, 0xa7, 0x4a, 0xe1, 0x8d, 0xab, 0x9e, 0x5b, 0xc7, 0xcf, 0x7, 0xea, 0x5d, 0x1c, 0x18, 0xd, 0xc6, 0x18, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6c, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0xa0, 0x35, 0x60, 0x44, 0xe6, 0x3c, 0x78, 0xf0, 0xe0, 0x3f, 0x8c, 0xfd, 0xff, 0xff, 0xff, 0x44, 0x45, 0x45, 0xc5, 0x5, 0xe8, 0x1a, 0x98, 0x70, 0x9a, 0xc4, 0xc8, 0x38, 0xe5, 0xe1, 0xc3, 0x87, 0xda, 0x44, 0x6b, 0x60, 0x60, 0x60, 0xe0, 0xfe, 0xff, 0xff, 0xff, 0xaa, 0x17, 0x2f, 0x5e, 0x70, 0x13, 0xab, 0x81, 0x81, 0x81, 0x81, 0x41, 0xeb, 0xe7, 0xcf, 0x9f, 0x53, 0x48, 0xd1, 0x80, 0x1, 0x8, 0x69, 0xb8, 0xc6, 0xce, 0xce, 0x9e, 0x43, 0xac, 0x86, 0xaf, 0x8c, 0x8c, 0x8c, 0x61, 0x12, 0x12, 0x12, 0x5f, 0x89, 0xd2, 0xf0, 0xff, 0xff, 0xff, 0x1c, 0x79, 0x79, 0xf9, 0xab, 0x84, 0x1d, 0x49, 0x6d, 0x0, 0x0, 0x8f, 0x30, 0x1e, 0x10, 0x6e, 0x79, 0xda, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char background_png[] = {
@@ -19,31 +19,27 @@ static const unsigned char base_green_png[] = {
};
static const unsigned char button_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0x4e, 0x2, 0x61, 0x10, 0x85, 0xbf, 0xf9, 0xc3, 0x15, 0x54, 0x94, 0xc2, 0x6a, 0x2b, 0xee, 0x40, 0x1, 0xd9, 0x8e, 0x82, 0x8, 0xb6, 0x62, 0xc9, 0x66, 0xb, 0xaf, 0xf0, 0x1f, 0x2, 0x1, 0x3b, 0xa4, 0x5, 0xb, 0x63, 0xb9, 0x71, 0x4d, 0xf6, 0xc, 0x50, 0x6d, 0x65, 0x1, 0x1, 0xbd, 0xc3, 0x8e, 0xc5, 0x2e, 0x68, 0x8, 0xb0, 0x24, 0xb4, 0xbe, 0x6a, 0x32, 0x99, 0xef, 0x65, 0x26, 0x79, 0x3, 0x27, 0x4a, 0xfe, 0xd6, 0xd5, 0x96, 0x77, 0xf, 0xea, 0xaa, 0x70, 0xb6, 0x73, 0x58, 0xf9, 0x6, 0x9, 0xc2, 0x49, 0x7f, 0x8, 0xe8, 0xc6, 0xc0, 0x5a, 0x6b, 0xa2, 0xe9, 0xf2, 0x15, 0xa8, 0x3, 0xb1, 0xa, 0x9f, 0x7b, 0xc, 0xae, 0x1, 0x7, 0x91, 0xb7, 0x4a, 0xf9, 0xa2, 0x61, 0xad, 0x4d, 0xa, 0x0, 0xd1, 0x74, 0xd5, 0x6, 0xea, 0x8a, 0xfa, 0x1f, 0x93, 0xa7, 0xde, 0xa1, 0x95, 0x6b, 0x4d, 0xcf, 0x57, 0xb4, 0x1b, 0xcd, 0x96, 0x77, 0xc0, 0xd0, 0xa4, 0x6d, 0x75, 0x81, 0x38, 0xf, 0x6, 0x78, 0x7f, 0xe9, 0x3f, 0x2, 0x31, 0x9, 0x2e, 0x40, 0x81, 0xf4, 0x98, 0x4b, 0x60, 0x9e, 0x7, 0xaf, 0xa5, 0x30, 0x47, 0xb8, 0x2, 0x30, 0xc7, 0x42, 0xfb, 0xf4, 0x6f, 0x90, 0x19, 0x88, 0xb2, 0x10, 0x28, 0x1d, 0xb, 0x9, 0x94, 0x44, 0x59, 0xfc, 0x6e, 0x60, 0x8, 0x0, 0xa7, 0xd6, 0xf4, 0xfc, 0x3c, 0x38, 0x9b, 0x71, 0x32, 0x26, 0xcd, 0x41, 0xa5, 0x5c, 0x1c, 0x45, 0xb3, 0xd5, 0x8d, 0xa2, 0xdd, 0x6a, 0xab, 0xf3, 0x70, 0x28, 0xca, 0x8a, 0xae, 0xa3, 0x3c, 0xa, 0xc7, 0xdb, 0xcf, 0x74, 0xdb, 0x69, 0x93, 0xe0, 0xaa, 0xe1, 0x7c, 0xa7, 0x41, 0xc2, 0x17, 0x86, 0x20, 0x1c, 0xf, 0x9e, 0xc9, 0x9e, 0xe9, 0x64, 0xfd, 0x0, 0xe8, 0xa0, 0x57, 0x22, 0x74, 0x4f, 0xd4, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x7d, 0x91, 0x41, 0x4e, 0xc3, 0x30, 0x14, 0x44, 0x9f, 0xed, 0x8f, 0x6d, 0x35, 0x8b, 0x9a, 0x6d, 0xb9, 0x6, 0xfb, 0xde, 0x81, 0xd3, 0xe4, 0x8, 0xf4, 0x32, 0xbd, 0x1, 0xb, 0x6e, 0xc0, 0x25, 0x60, 0x83, 0xa8, 0x2, 0x6a, 0xa4, 0xc6, 0x49, 0xfc, 0xbb, 0x88, 0x54, 0x11, 0x94, 0x30, 0xb3, 0xf9, 0xd2, 0x9f, 0x19, 0x8d, 0x34, 0x6, 0xc1, 0x13, 0x88, 0x78, 0x1c, 0x96, 0x9, 0x85, 0x91, 0xcc, 0x85, 0x8e, 0x2c, 0x78, 0x2a, 0x12, 0x5b, 0x2a, 0x2, 0x6, 0x3, 0x28, 0x4a, 0x47, 0xcb, 0x37, 0xd, 0x8, 0x81, 0xb4, 0x7f, 0x7a, 0xa8, 0x87, 0xc4, 0xc, 0xd2, 0xbc, 0x3f, 0xbf, 0x1e, 0x19, 0x84, 0xc8, 0x76, 0x57, 0x9f, 0xd2, 0x80, 0xfe, 0x7a, 0x1b, 0x24, 0xed, 0x6a, 0x5e, 0x38, 0xb, 0x9e, 0xaa, 0x4f, 0xfd, 0xdc, 0x8e, 0xd2, 0xd3, 0x27, 0x2a, 0xbc, 0xe0, 0x8, 0x65, 0xe6, 0xe6, 0xd6, 0x94, 0x80, 0x13, 0x2c, 0x46, 0x29, 0xb, 0x2, 0x5, 0x83, 0x15, 0xc0, 0xac, 0x26, 0x18, 0x90, 0xe9, 0x5c, 0x11, 0x30, 0x9, 0x54, 0x17, 0x5, 0xa, 0xa, 0x42, 0x41, 0xcb, 0x62, 0x87, 0x2, 0x4a, 0x11, 0x46, 0xba, 0xd5, 0x84, 0x8e, 0xd1, 0x92, 0x69, 0x6d, 0xe3, 0xd0, 0x3f, 0x74, 0xd8, 0x86, 0x96, 0xec, 0xb8, 0xc3, 0xa5, 0xaf, 0xfb, 0x47, 0x1f, 0x3d, 0xe1, 0xc6, 0x48, 0x3c, 0x7d, 0x1e, 0x3e, 0xde, 0xf8, 0x31, 0x6c, 0xfe, 0x1d, 0xab, 0x15, 0x32, 0x30, 0x70, 0x5e, 0x9b, 0xfb, 0xa, 0xbb, 0x7c, 0x61, 0xa2, 0x50, 0x44, 0x45, 0xca, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_focus_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x3f, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x4, 0x42, 0x26, 0xa1, 0xa1, 0xce, 0x8a, 0x40, 0x46, 0x7a, 0xe7, 0xcc, 0x99, 0x33, 0xca, 0x80, 0x8c, 0xd5, 0x20, 0xe1, 0x5d, 0x40, 0x1c, 0x3, 0x62, 0x1c, 0x5, 0xe2, 0x48, 0x10, 0x63, 0x2a, 0x7e, 0x6, 0x5c, 0x31, 0x58, 0xbb, 0x14, 0x10, 0xe7, 0xee, 0x9c, 0x39, 0x73, 0x1e, 0xc8, 0x40, 0x31, 0x98, 0x15, 0xe8, 0x0, 0x0, 0xec, 0xe0, 0x11, 0x6d, 0x2c, 0x6f, 0x45, 0x2b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
-static const unsigned char button_group_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x60, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0x97, 0xcd, 0x6e, 0x82, 0x40, 0x14, 0x46, 0x8f, 0xad, 0xa0, 0x51, 0x1a, 0xd1, 0xa5, 0xab, 0x76, 0xd1, 0xf7, 0x7f, 0xa1, 0xb6, 0xa6, 0x9b, 0x6e, 0x8b, 0x9, 0x5a, 0xa3, 0x18, 0xbb, 0xb8, 0x40, 0xc6, 0xf1, 0x32, 0x19, 0x90, 0x61, 0xd3, 0x9e, 0x25, 0x19, 0xf3, 0x1d, 0xe6, 0xc7, 0xf9, 0x80, 0xbf, 0xce, 0xa8, 0xe5, 0xf8, 0x19, 0xb0, 0x0, 0x12, 0x20, 0x2, 0xe2, 0xf2, 0xf9, 0x11, 0x38, 0x1, 0x39, 0xb0, 0x5, 0xf6, 0x7d, 0xb, 0x2c, 0x81, 0x35, 0x30, 0xf1, 0x1c, 0x7f, 0x0, 0xbe, 0x80, 0xec, 0x5e, 0x81, 0x9, 0xf0, 0xc, 0xcc, 0x3d, 0x83, 0x6d, 0x76, 0xc0, 0x6, 0x99, 0x21, 0x95, 0x47, 0xc7, 0x8f, 0x13, 0xe0, 0x15, 0x98, 0x76, 0xc, 0x7, 0x59, 0xa2, 0x15, 0xb2, 0x24, 0xaa, 0x44, 0x93, 0xc0, 0x53, 0x19, 0xee, 0x12, 0xf4, 0xe5, 0xa1, 0x94, 0xc8, 0x35, 0x9, 0x2d, 0x20, 0xee, 0x31, 0xbc, 0x62, 0x84, 0x6c, 0xde, 0xc, 0x38, 0xdb, 0x76, 0x36, 0x2f, 0xc0, 0xb8, 0xc7, 0xf0, 0x8a, 0x31, 0xb2, 0x9f, 0xae, 0xb0, 0x5, 0x96, 0x74, 0xdf, 0x70, 0x3e, 0xcc, 0x81, 0xd4, 0x25, 0xb0, 0xe, 0x18, 0xae, 0x66, 0x98, 0x2, 0x33, 0xfc, 0xcf, 0xf9, 0x3d, 0x4c, 0xcb, 0xac, 0x1b, 0x81, 0xf4, 0x76, 0x6c, 0x30, 0x16, 0x9a, 0x40, 0xc8, 0xb5, 0xb7, 0x49, 0x34, 0x81, 0x58, 0x19, 0x18, 0x8a, 0x48, 0x13, 0x88, 0x94, 0x81, 0xa1, 0xa8, 0x5f, 0xd6, 0x14, 0xb8, 0xc, 0x28, 0x50, 0x67, 0x99, 0x2, 0xc5, 0x80, 0x2, 0x27, 0x4d, 0xa0, 0xf1, 0xc6, 0x1a, 0x4a, 0x20, 0x1f, 0x50, 0xa0, 0xce, 0x32, 0x5, 0xb6, 0x3, 0xa, 0xd4, 0x45, 0xc5, 0x14, 0xd8, 0x23, 0x4d, 0x26, 0x34, 0x7, 0xe0, 0x47, 0x13, 0x0, 0xa9, 0x51, 0xa1, 0xb9, 0xca, 0xb0, 0x5, 0x32, 0xa4, 0x46, 0x85, 0x22, 0xc7, 0xea, 0x89, 0x5a, 0x1f, 0xd8, 0x10, 0xe6, 0x48, 0x16, 0xc0, 0xa7, 0xfd, 0x50, 0x6b, 0x3d, 0x67, 0x64, 0x16, 0x56, 0xb4, 0xaf, 0xed, 0x4d, 0x5c, 0x80, 0x77, 0x8c, 0xb5, 0x77, 0x9, 0x80, 0xfc, 0x27, 0xe4, 0xc8, 0xad, 0xa5, 0xcd, 0x52, 0x1b, 0xa, 0xe0, 0x83, 0x86, 0x63, 0xee, 0xea, 0x7d, 0x47, 0xe0, 0x1b, 0xb9, 0x25, 0xbb, 0x5e, 0x54, 0x39, 0xf0, 0x86, 0xf2, 0xe6, 0x15, 0xbe, 0x53, 0x9c, 0x22, 0x4d, 0xc6, 0xb7, 0xa2, 0xf7, 0xf6, 0x61, 0x62, 0xe3, 0xf3, 0x69, 0x96, 0xe1, 0x78, 0xe3, 0x7f, 0x6c, 0x7e, 0x1, 0x6e, 0x8e, 0x40, 0x43, 0xe2, 0x3d, 0x6f, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
-};
-
static const unsigned char button_hover_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xea, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xd3, 0x2d, 0x52, 0x82, 0x61, 0x14, 0xc5, 0xf1, 0xdf, 0x65, 0x58, 0x80, 0x45, 0x67, 0x94, 0x60, 0xa2, 0xab, 0x7b, 0xa0, 0xf9, 0xc1, 0xb8, 0x0, 0xb5, 0x13, 0xc4, 0x1d, 0xb0, 0x3, 0x8, 0x68, 0x56, 0x56, 0x20, 0x43, 0x64, 0xf, 0x6c, 0x80, 0x64, 0x80, 0xa0, 0x5, 0x36, 0xe0, 0x35, 0xf8, 0xf2, 0x26, 0xf9, 0x98, 0xa1, 0x7a, 0xd2, 0xd, 0xf7, 0x7f, 0xee, 0x99, 0x67, 0xce, 0xc3, 0x9e, 0x8a, 0x72, 0xca, 0x8c, 0xa7, 0xa1, 0x87, 0xc, 0xd, 0x1c, 0xae, 0xd9, 0xff, 0x8a, 0x34, 0xee, 0xde, 0x78, 0x15, 0x91, 0xa5, 0x41, 0xa7, 0x93, 0x95, 0xe5, 0xb9, 0x61, 0x72, 0x89, 0x29, 0x3e, 0xd6, 0x18, 0x9c, 0xa2, 0x2e, 0x8c, 0xe, 0x26, 0x9a, 0x9d, 0x4e, 0x7c, 0x57, 0x61, 0x79, 0xe6, 0x3e, 0xb9, 0x8c, 0xd0, 0xea, 0x5e, 0xc7, 0xcb, 0xa6, 0xc8, 0xed, 0xf7, 0x6c, 0xa1, 0xbf, 0xb8, 0x70, 0x87, 0xd7, 0xa, 0x14, 0xb1, 0xa7, 0xdb, 0x60, 0xe8, 0x35, 0xe3, 0x19, 0xd3, 0xa4, 0x1, 0xd5, 0xe2, 0x25, 0x8e, 0x31, 0xdb, 0x6, 0x97, 0xa, 0xb3, 0xe0, 0x4, 0x2a, 0x3b, 0x43, 0x6b, 0xf4, 0x6f, 0x50, 0x18, 0x24, 0x73, 0xa9, 0xb6, 0x33, 0x95, 0x6a, 0xc9, 0xbc, 0x34, 0x8, 0xc6, 0xa8, 0x17, 0x25, 0xd9, 0xa8, 0x62, 0xa7, 0x5e, 0x30, 0xbf, 0x3d, 0x38, 0x98, 0x18, 0x2c, 0x2e, 0xdc, 0xa2, 0xdf, 0x1e, 0xe6, 0xa3, 0xdd, 0xaa, 0x3c, 0x28, 0x8e, 0xaf, 0x62, 0x65, 0xb4, 0x47, 0xee, 0x93, 0x46, 0xa4, 0xa3, 0x3f, 0x93, 0x87, 0xcf, 0x60, 0xdc, 0xbb, 0xf2, 0xb6, 0xfa, 0x4c, 0x7b, 0xeb, 0x7, 0xd1, 0xc3, 0x49, 0x77, 0x7a, 0x49, 0x64, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x5f, 0x5a, 0x6b, 0x56, 0x53, 0x64, 0x57, 0x53, 0x64, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x57, 0x53, 0x63, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5b, 0x57, 0x66, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x43, 0x40, 0x4c, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0xff, 0xff, 0xff, 0x99, 0x8b, 0x2e, 0x55, 0x0, 0x0, 0x0, 0x16, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0x6b, 0x28, 0x52, 0x7a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2e, 0x54, 0xd3, 0x10, 0x87, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x97, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x49, 0x12, 0x82, 0x30, 0x10, 0x5, 0xd0, 0xce, 0x48, 0x46, 0x40, 0x51, 0x4, 0x41, 0x45, 0xc4, 0x20, 0x88, 0xf7, 0xbf, 0x9e, 0x21, 0x45, 0x65, 0xa1, 0x6f, 0xd7, 0xbf, 0xaa, 0x27, 0x0, 0x84, 0x9, 0x65, 0xdc, 0x63, 0x94, 0x60, 0x4, 0x80, 0x12, 0x21, 0x95, 0x36, 0xd6, 0x1a, 0xad, 0xa4, 0x48, 0x10, 0x60, 0x91, 0x66, 0xe5, 0x29, 0x28, 0xb3, 0x54, 0x60, 0x20, 0x32, 0xaf, 0xea, 0x73, 0x50, 0x57, 0xb9, 0x24, 0x40, 0x55, 0xb3, 0xd5, 0x3e, 0x69, 0x14, 0x5, 0xa6, 0xdb, 0x4b, 0xd4, 0x6a, 0x6, 0xdc, 0x5c, 0x6f, 0xd1, 0xd5, 0x70, 0xe0, 0xb6, 0xbb, 0x47, 0x9d, 0x5d, 0x83, 0xfe, 0x11, 0xf5, 0x6b, 0x60, 0x86, 0x67, 0x34, 0xf8, 0x16, 0xa6, 0xdd, 0x18, 0x39, 0x3f, 0x94, 0x2a, 0x37, 0xbe, 0x36, 0xa3, 0xf3, 0x6b, 0x89, 0xdc, 0x4d, 0xf3, 0x3b, 0x98, 0xa7, 0xbd, 0x3f, 0xc, 0x8b, 0xe2, 0xb0, 0x7c, 0x82, 0xe5, 0x58, 0xf8, 0xd3, 0xff, 0x9e, 0xfb, 0x7d, 0xff, 0xb, 0x74, 0xeb, 0x15, 0x11, 0xe1, 0xa7, 0x60, 0xfc, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_normal_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x2, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0xa1, 0x4e, 0xc3, 0x0, 0x10, 0x86, 0xbf, 0xbf, 0x99, 0x98, 0x60, 0x38, 0x48, 0x60, 0x82, 0x64, 0x4b, 0x1f, 0xa5, 0x6e, 0x82, 0xa0, 0xc7, 0x86, 0xaf, 0x20, 0xc, 0xd1, 0xe1, 0xea, 0x18, 0xa2, 0xc3, 0xc, 0xf4, 0xe8, 0x78, 0x1, 0x82, 0xec, 0xa3, 0x2c, 0x2c, 0x41, 0xc, 0x1, 0x12, 0x44, 0x67, 0x76, 0x88, 0x95, 0x41, 0x48, 0x43, 0x21, 0xb5, 0xfc, 0xea, 0xc4, 0x7d, 0x5f, 0x2e, 0x97, 0x3b, 0x28, 0x19, 0xad, 0x2b, 0x33, 0x9d, 0x5d, 0xde, 0x1e, 0x99, 0xe1, 0x61, 0xda, 0xca, 0xef, 0xb6, 0x17, 0x89, 0xe4, 0xfc, 0xa4, 0x3d, 0x46, 0xb2, 0xb5, 0x20, 0xc, 0x43, 0x27, 0xad, 0x35, 0xee, 0x40, 0x2d, 0xc4, 0x94, 0xa5, 0x1e, 0x73, 0x5, 0x8e, 0xed, 0x61, 0xb8, 0x18, 0xf7, 0xd5, 0xb7, 0x87, 0xfd, 0x30, 0xc, 0x97, 0x15, 0x80, 0xc5, 0x66, 0xb3, 0x8b, 0xd1, 0x42, 0xf2, 0x7, 0xbd, 0xf6, 0xf5, 0x4f, 0x23, 0x7, 0x51, 0xec, 0x4b, 0x1a, 0xa5, 0xb5, 0x46, 0x7, 0x18, 0x3b, 0xab, 0xe9, 0xf1, 0x10, 0xd3, 0x22, 0x18, 0xe0, 0xe2, 0xb4, 0x73, 0x85, 0x98, 0xa, 0x3c, 0x0, 0x27, 0xdb, 0xc4, 0xe, 0x30, 0x2f, 0x82, 0xbf, 0x64, 0x6e, 0xd2, 0xee, 0xa7, 0xa0, 0x44, 0xfe, 0x5, 0x99, 0x40, 0x66, 0x4f, 0x40, 0xfd, 0xf, 0x5c, 0x3d, 0x63, 0x56, 0x2, 0x83, 0x4, 0xc3, 0xd, 0xa2, 0xd8, 0x2f, 0x22, 0x83, 0x28, 0xf6, 0x31, 0x5c, 0x83, 0x4, 0xa0, 0x2, 0x50, 0x7d, 0x9d, 0xc5, 0xe9, 0x46, 0xf3, 0x40, 0xd2, 0xa8, 0x3f, 0x9c, 0x1c, 0xff, 0xee, 0x94, 0x67, 0x31, 0x7c, 0x7b, 0xa6, 0xfe, 0x70, 0xd2, 0x15, 0x78, 0x66, 0xce, 0x76, 0x1e, 0x2f, 0x2d, 0x9f, 0xd, 0x92, 0x41, 0xef, 0xf0, 0xe6, 0xe3, 0x99, 0x4a, 0xe7, 0x1d, 0xad, 0xe8, 0x5d, 0x6, 0x36, 0xf7, 0x1f, 0x56, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0xff, 0xff, 0xff, 0xe5, 0x37, 0x10, 0x78, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2d, 0xcd, 0xda, 0x41, 0x3d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x47, 0x12, 0x82, 0x40, 0x10, 0x5, 0xd0, 0x9e, 0xc8, 0x44, 0x92, 0x22, 0x41, 0x54, 0x44, 0x40, 0x14, 0xef, 0x7f, 0x3e, 0x7, 0x8a, 0xea, 0x85, 0xbe, 0xe5, 0xaf, 0xea, 0xf0, 0x1, 0x8, 0x65, 0x5c, 0xc8, 0x40, 0x70, 0x46, 0x9, 0x0, 0x89, 0x94, 0x36, 0xd6, 0x79, 0xef, 0xac, 0xd1, 0x2a, 0x22, 0x40, 0x55, 0x9c, 0x14, 0xa7, 0x4d, 0x91, 0xc4, 0x8a, 0x2, 0xd3, 0x69, 0x59, 0xd5, 0x9b, 0xaa, 0x4c, 0x35, 0x3, 0x6e, 0x9a, 0xfa, 0xbc, 0xab, 0x1b, 0xc3, 0x41, 0xd8, 0xf6, 0x82, 0x5a, 0x2b, 0x40, 0xba, 0xeb, 0xd, 0x5d, 0x9d, 0x4, 0xe9, 0xbb, 0x3b, 0xea, 0xfc, 0x1a, 0xf4, 0xf, 0xd4, 0xaf, 0x81, 0x1b, 0x46, 0x34, 0x84, 0x11, 0x61, 0xa7, 0x27, 0x9a, 0xc2, 0x52, 0x6e, 0xe6, 0x17, 0x9a, 0xc3, 0x59, 0xa6, 0xb3, 0xf1, 0xbd, 0x1b, 0xb3, 0xf0, 0x18, 0x55, 0xf9, 0x61, 0xf9, 0x6c, 0x96, 0x63, 0x1e, 0x5e, 0xff, 0x2b, 0xf7, 0x5b, 0xff, 0xb, 0x69, 0x5a, 0x14, 0xfa, 0x84, 0xf6, 0xc2, 0x8, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char button_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xe8, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xd3, 0x21, 0x4f, 0x42, 0x51, 0x18, 0xc6, 0xf1, 0xdf, 0xb9, 0x50, 0xa4, 0xeb, 0xa6, 0x4, 0x13, 0x1f, 0xe5, 0x36, 0x82, 0xf3, 0x3, 0x88, 0x9d, 0x60, 0x12, 0x93, 0x8c, 0x41, 0xc3, 0x8a, 0x66, 0xe4, 0x1b, 0x38, 0x23, 0x1f, 0x85, 0x64, 0x80, 0xa0, 0x9d, 0xc6, 0x7d, 0xd, 0x5e, 0x68, 0x17, 0xd8, 0xa8, 0xfe, 0xd3, 0xd9, 0xd9, 0xfb, 0xfc, 0x77, 0xde, 0xed, 0x39, 0x9c, 0x48, 0xda, 0x9d, 0x22, 0x52, 0xdf, 0xf8, 0x9e, 0x94, 0x7, 0xe7, 0x15, 0xc3, 0x3f, 0xc4, 0x7c, 0xa8, 0x37, 0x95, 0x52, 0xec, 0x4, 0x83, 0x18, 0x64, 0x1b, 0x8d, 0x8f, 0x44, 0x1b, 0x8b, 0xe0, 0xab, 0x42, 0x70, 0x8d, 0x16, 0x3e, 0x33, 0xeb, 0x9b, 0x41, 0x1a, 0x14, 0x75, 0x28, 0x9c, 0x75, 0x12, 0xed, 0x10, 0xdd, 0x51, 0x7a, 0x7a, 0xdb, 0xf7, 0xe4, 0x7e, 0x8c, 0xbb, 0x98, 0x6c, 0x34, 0xee, 0x30, 0xcd, 0x4a, 0x77, 0x8e, 0xc5, 0xa1, 0x30, 0xc, 0x53, 0xef, 0x15, 0x8b, 0x8c, 0x1c, 0xea, 0x10, 0x5c, 0x62, 0x79, 0x28, 0xbc, 0x25, 0x58, 0x6, 0x57, 0x90, 0x1d, 0x1b, 0xaa, 0xe2, 0x5f, 0x50, 0xa, 0x32, 0x56, 0x89, 0xe6, 0xb1, 0xa1, 0x44, 0x33, 0x63, 0xb5, 0x13, 0x14, 0xcc, 0xd1, 0x2a, 0x4b, 0xb2, 0x97, 0x72, 0xa6, 0x55, 0x66, 0xfe, 0x7a, 0x50, 0xb3, 0x9e, 0x15, 0x1a, 0xb7, 0x98, 0xf4, 0x63, 0xfc, 0x70, 0x4c, 0x95, 0x6b, 0xd6, 0xb3, 0xf2, 0xae, 0x24, 0x22, 0x3d, 0x7b, 0xe9, 0x64, 0xe4, 0x5, 0x17, 0x15, 0xfb, 0x7e, 0x17, 0xcc, 0x47, 0x1e, 0xdf, 0xb7, 0x9f, 0xe9, 0x64, 0x7e, 0x1, 0x43, 0xf2, 0x49, 0x4e, 0xb4, 0x2a, 0xa5, 0x9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x7, 0x1c, 0xc, 0x14, 0x2b, 0xf9, 0x77, 0x52, 0x64, 0x0, 0x0, 0x1, 0x92, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x8d, 0x93, 0x4d, 0x4e, 0x1b, 0x41, 0x10, 0x85, 0xbf, 0xea, 0xaa, 0x1e, 0x20, 0x83, 0xf9, 0x9, 0x36, 0xb2, 0x85, 0x72, 0x84, 0x8, 0x65, 0x11, 0xe5, 0xc, 0x9c, 0x80, 0x73, 0x10, 0xee, 0xc1, 0x41, 0x38, 0x1, 0xab, 0xec, 0xa3, 0x2c, 0x2, 0x8a, 0xe0, 0x2, 0x51, 0xc2, 0x48, 0x46, 0x42, 0x64, 0xc6, 0x91, 0x21, 0xf4, 0x74, 0x16, 0x2e, 0xb0, 0x71, 0x2, 0xf2, 0x93, 0x9e, 0xba, 0x16, 0xdd, 0xaf, 0x5e, 0xa9, 0x5f, 0x9, 0x60, 0x40, 0x1, 0x2c, 0x1, 0xcb, 0x5e, 0x2b, 0x10, 0x78, 0x8a, 0x16, 0x48, 0xc0, 0x1d, 0x30, 0x6, 0x6e, 0x81, 0x3b, 0xf3, 0x87, 0x25, 0xb0, 0x9, 0xac, 0x7b, 0xbd, 0xc, 0x88, 0x13, 0x20, 0x3b, 0xc7, 0xc0, 0x8, 0xb8, 0x1, 0xae, 0x81, 0x91, 0xf9, 0xe5, 0xad, 0x77, 0xbb, 0x1f, 0xf6, 0x7b, 0xdd, 0xfe, 0x41, 0x4a, 0x69, 0x2d, 0x93, 0xf9, 0x1f, 0x4, 0x41, 0x55, 0x7f, 0xd, 0xaf, 0xaa, 0xa3, 0xaf, 0x67, 0x9f, 0x8f, 0x81, 0x64, 0xde, 0xb1, 0xbb, 0xdd, 0x1b, 0x7c, 0xac, 0x9b, 0x9b, 0xce, 0xd9, 0xb7, 0x2f, 0xfc, 0xf3, 0x5e, 0xa6, 0xe5, 0xee, 0xdb, 0xf7, 0x6b, 0xdb, 0xbd, 0xc1, 0x21, 0xf0, 0x9, 0x18, 0x5, 0x60, 0x5, 0xd8, 0x48, 0x6d, 0xdb, 0x39, 0xbf, 0x38, 0xc5, 0x34, 0x62, 0x36, 0x47, 0x9d, 0xf2, 0xfc, 0xe2, 0x94, 0xd4, 0xb6, 0x1d, 0x60, 0x3, 0x58, 0x31, 0x20, 0x2, 0x65, 0x40, 0x88, 0x31, 0x92, 0xbd, 0xbb, 0x8, 0xe4, 0x3c, 0x39, 0x67, 0x91, 0x33, 0x84, 0x89, 0xa5, 0x12, 0x88, 0xf, 0x3f, 0x10, 0x45, 0x5, 0xb3, 0xc8, 0x73, 0x10, 0x11, 0xb2, 0xab, 0x8b, 0xa, 0xde, 0xb8, 0x30, 0x9f, 0xb0, 0x8, 0xa2, 0xc4, 0x58, 0xb0, 0x8, 0x82, 0x28, 0xde, 0x58, 0xcc, 0xff, 0x5c, 0x45, 0x64, 0x61, 0x1, 0x99, 0xcc, 0xa5, 0x80, 0x4e, 0x5, 0xc2, 0xcb, 0x2, 0xe2, 0x41, 0x10, 0x40, 0xc2, 0x53, 0x81, 0xc, 0xa8, 0x8a, 0x52, 0x2c, 0xe8, 0x40, 0x27, 0x23, 0x28, 0x90, 0xcd, 0xe3, 0x79, 0x1b, 0x34, 0x50, 0x14, 0x4b, 0xf0, 0x4c, 0x88, 0x66, 0xbd, 0x4, 0xd, 0x78, 0x94, 0x93, 0x79, 0x3c, 0x9b, 0x18, 0x63, 0x7a, 0xbd, 0xb9, 0xa5, 0xcd, 0xa8, 0x7e, 0xb4, 0x3a, 0x2f, 0x15, 0x10, 0xca, 0x72, 0x95, 0x18, 0x8b, 0x4, 0x34, 0xc0, 0xd8, 0x80, 0x1a, 0x18, 0x56, 0xd5, 0xcf, 0x93, 0x41, 0x7f, 0x67, 0xaf, 0xb3, 0xba, 0x1e, 0x5e, 0x8a, 0xb2, 0x99, 0xb5, 0x97, 0xd5, 0x8f, 0x13, 0x60, 0x8, 0xd4, 0x2, 0x74, 0x9d, 0x6f, 0x80, 0xbe, 0x2f, 0x55, 0xe9, 0x26, 0xc2, 0xcc, 0x26, 0x66, 0x5f, 0xa4, 0x6b, 0xa0, 0x2, 0xbe, 0x3, 0x57, 0xe6, 0x56, 0x1e, 0x66, 0x1a, 0x2, 0xaf, 0x3c, 0x24, 0x36, 0x67, 0xe0, 0x1e, 0xf8, 0x3, 0xfc, 0xf6, 0x6d, 0xac, 0x81, 0xe6, 0x2f, 0x7c, 0x22, 0x6d, 0x74, 0x25, 0xb, 0xb3, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char checked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0xa, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xc5, 0x92, 0x3d, 0x6a, 0xc3, 0x40, 0x10, 0x46, 0xbf, 0x4f, 0x3f, 0xbd, 0x4d, 0x88, 0xd3, 0xed, 0xa, 0xcc, 0x9e, 0x22, 0x4d, 0x20, 0xc7, 0x91, 0xfb, 0xf8, 0x6, 0x82, 0xa4, 0xb, 0x4e, 0xf0, 0x25, 0xe4, 0x6b, 0xe4, 0x10, 0x8b, 0xa, 0x6d, 0xb1, 0x10, 0x37, 0x72, 0xbd, 0xa, 0x4c, 0x1a, 0x9, 0x14, 0xdb, 0x92, 0x52, 0x25, 0x53, 0xcd, 0x30, 0xfb, 0xde, 0xce, 0xc0, 0x0, 0xff, 0x1d, 0xec, 0x93, 0xba, 0xae, 0xef, 0x45, 0x64, 0xb, 0xe0, 0x76, 0x12, 0x20, 0x8f, 0x22, 0x52, 0x64, 0x59, 0xf6, 0x1, 0x0, 0xd1, 0xa0, 0xf7, 0x34, 0x7, 0x3, 0x80, 0x88, 0xac, 0x48, 0x6e, 0xfb, 0x3a, 0x1a, 0x36, 0x66, 0xd8, 0x86, 0xe4, 0xa1, 0x7b, 0x7b, 0x77, 0x21, 0x98, 0x83, 0xdb, 0xb6, 0xdd, 0x68, 0xad, 0x9f, 0x1, 0x94, 0xc3, 0xc6, 0xac, 0x80, 0xe4, 0x29, 0x8a, 0xa2, 0x8d, 0x31, 0xa6, 0xf2, 0xde, 0x6b, 0x0, 0xf, 0xbf, 0x16, 0x90, 0x3c, 0x91, 0xcc, 0x95, 0x52, 0x95, 0xf7, 0x5e, 0x87, 0x10, 0xde, 0x1, 0xdc, 0x4c, 0xa, 0xba, 0x3d, 0x1b, 0x0, 0x4d, 0x8, 0x21, 0x57, 0x4a, 0x55, 0xd6, 0xda, 0x75, 0x8, 0x61, 0x7f, 0xe, 0x3, 0x40, 0x72, 0x56, 0x97, 0x5a, 0xeb, 0x17, 0x6b, 0x6d, 0x9, 0x0, 0xc6, 0x98, 0xca, 0x5a, 0xbb, 0x4e, 0xd3, 0x74, 0x7, 0x60, 0x79, 0x6d, 0xca, 0x1f, 0x2, 0x92, 0x8f, 0xce, 0xb9, 0x83, 0x52, 0xaa, 0x2, 0x80, 0x6e, 0xec, 0xd7, 0x31, 0xf8, 0x42, 0x20, 0x22, 0xb, 0x0, 0x6f, 0xce, 0xb9, 0x3c, 0x49, 0x92, 0xaf, 0x6b, 0x3b, 0x8f, 0xa, 0xba, 0xb, 0x5b, 0x89, 0xc8, 0x42, 0x44, 0x76, 0x21, 0x4, 0x8c, 0xfd, 0x4c, 0xf2, 0xb3, 0xcf, 0x87, 0x87, 0x54, 0x90, 0x3c, 0x76, 0xe5, 0x72, 0xa, 0x8e, 0xe3, 0xb8, 0x98, 0x9a, 0xea, 0x6f, 0xe3, 0x1b, 0x38, 0xbf, 0x6e, 0xb3, 0x2e, 0xdd, 0xd5, 0x21, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x58, 0x56, 0x63, 0xb0, 0xaf, 0xb5, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0xb6, 0xb6, 0xb9, 0x57, 0x57, 0x5a, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x8b, 0x8b, 0x8d, 0xff, 0xff, 0xff, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x42, 0x42, 0x47, 0xf8, 0xf8, 0xf8, 0xfe, 0xfe, 0xfe, 0x25, 0x25, 0x2a, 0x4e, 0x4e, 0x52, 0x26, 0x26, 0x2b, 0xc5, 0xc5, 0xc7, 0xaa, 0xaa, 0xab, 0xb8, 0xb8, 0xba, 0x5f, 0x5f, 0x63, 0x74, 0x74, 0x77, 0xed, 0xed, 0xed, 0x33, 0x33, 0x38, 0x8d, 0x8d, 0x8f, 0xb8, 0xb8, 0xb9, 0x35, 0x35, 0x39, 0x3a, 0x3a, 0x3e, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xb2, 0xb2, 0xb4, 0x45, 0x45, 0x49, 0x61, 0x61, 0x65, 0x8f, 0x8f, 0x92, 0x63, 0x63, 0x66, 0x2a, 0x2a, 0x2f, 0x40, 0x82, 0xb, 0xf6, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0x6a, 0x81, 0xb4, 0xfa, 0xdd, 0xfb, 0xfb, 0xb4, 0xfa, 0xb8, 0xf0, 0x7f, 0x59, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x12, 0x7b, 0xbc, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x8e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x5b, 0x12, 0x82, 0x30, 0xc, 0x40, 0x51, 0x48, 0x5b, 0x15, 0x5, 0x5b, 0x42, 0x2b, 0x4, 0x50, 0x40, 0xc5, 0xb7, 0xee, 0x7f, 0x79, 0x96, 0x8a, 0x88, 0x7a, 0x3f, 0xcf, 0x4c, 0x26, 0x89, 0xe7, 0xfd, 0xe5, 0x3, 0xe3, 0xc2, 0x35, 0x99, 0x82, 0x6f, 0x1, 0x66, 0x81, 0x54, 0xae, 0x18, 0xe7, 0x60, 0x81, 0x5, 0x89, 0x36, 0x5d, 0xab, 0x34, 0x5b, 0x30, 0xb, 0x5c, 0x6a, 0xa2, 0xbc, 0x20, 0x2a, 0x71, 0x2d, 0xb9, 0x5, 0xa1, 0xc, 0x6d, 0xb0, 0xa2, 0x1a, 0x9b, 0xad, 0x12, 0x3d, 0xec, 0x70, 0xdf, 0x36, 0x58, 0x9b, 0x1, 0xe, 0xc7, 0xd3, 0x19, 0x4b, 0xfa, 0x80, 0x9d, 0xc9, 0xd2, 0xcb, 0x18, 0xae, 0x88, 0x37, 0x1a, 0x43, 0x91, 0xdf, 0x1f, 0x6f, 0x70, 0x6b, 0x5f, 0x69, 0xb7, 0x76, 0x38, 0xcc, 0xe8, 0x24, 0xec, 0xe, 0x83, 0x28, 0xec, 0x4f, 0x97, 0xcb, 0x8, 0xbe, 0x9e, 0xe3, 0xcc, 0x3d, 0xf7, 0xd3, 0x13, 0x10, 0x58, 0xd, 0x44, 0xd4, 0xa5, 0x38, 0x3e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char checker_bg_png[] = {
@@ -51,11 +47,11 @@ static const unsigned char checker_bg_png[] = {
};
static const unsigned char close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xbe, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xd5, 0x90, 0x3b, 0xe, 0xc2, 0x40, 0xc, 0x44, 0x9f, 0x9, 0x45, 0xf8, 0x14, 0x80, 0xb8, 0xf, 0x15, 0x8a, 0x8, 0x48, 0xdc, 0x94, 0x8a, 0x4, 0x85, 0x9a, 0xe3, 0x20, 0x48, 0xc3, 0xa7, 0x20, 0x32, 0x8d, 0x41, 0x8b, 0xc9, 0x4a, 0xb4, 0xb8, 0xda, 0x1d, 0x7b, 0x9e, 0x35, 0x86, 0xbf, 0x2f, 0x9, 0x3f, 0xaa, 0xba, 0x2, 0xba, 0x40, 0x25, 0x22, 0x37, 0xd7, 0xeb, 0x1, 0x19, 0xf0, 0x10, 0x91, 0xed, 0x4b, 0xef, 0x38, 0x60, 0x2, 0x4c, 0x81, 0xdc, 0xc, 0xa1, 0x39, 0xb7, 0x5e, 0x12, 0x1a, 0x3c, 0xa0, 0x2, 0x4e, 0xc0, 0x18, 0x58, 0xaa, 0x6a, 0x5f, 0x55, 0x53, 0x60, 0x61, 0x5a, 0xd, 0xec, 0xa3, 0x11, 0x6c, 0x5b, 0x6a, 0xdb, 0x26, 0xc0, 0xc5, 0xe4, 0x81, 0x99, 0xb, 0x1f, 0xed, 0xb, 0x10, 0x40, 0xd6, 0xc0, 0xcc, 0x66, 0xe, 0xc0, 0xc6, 0x9b, 0xdb, 0x22, 0xc4, 0x4a, 0x63, 0xcb, 0x7e, 0x89, 0xa0, 0xc0, 0xd0, 0x22, 0x94, 0x22, 0x72, 0x8d, 0x2, 0x9c, 0xb9, 0x6, 0xa, 0x3, 0x84, 0xda, 0x7, 0xc4, 0x47, 0xc8, 0x6c, 0xf0, 0x8c, 0x1d, 0x4c, 0x44, 0xee, 0xc0, 0xce, 0xb4, 0x11, 0x30, 0xf, 0xd, 0x1e, 0xd0, 0x0, 0x47, 0xdb, 0xf2, 0x3e, 0x98, 0xbd, 0x4b, 0xeb, 0x35, 0x6d, 0xb7, 0xf8, 0xe3, 0x7a, 0x2, 0x49, 0x7e, 0x47, 0x10, 0xc3, 0xf7, 0xae, 0x75, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char close_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xbe, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xd5, 0x90, 0x3b, 0xe, 0xc2, 0x40, 0xc, 0x44, 0x9f, 0x9, 0x45, 0xf8, 0x14, 0x80, 0xb8, 0xf, 0x15, 0x8a, 0x8, 0x48, 0xdc, 0x94, 0x8a, 0x4, 0x85, 0x9a, 0xe3, 0x20, 0x48, 0xc3, 0xa7, 0x20, 0x32, 0x8d, 0x41, 0x8b, 0xc9, 0x4a, 0xb4, 0xb8, 0xda, 0x1d, 0x7b, 0x9e, 0x35, 0x86, 0xbf, 0x2f, 0x9, 0x3f, 0xaa, 0xba, 0x2, 0xba, 0x40, 0x25, 0x22, 0x37, 0xd7, 0xeb, 0x1, 0x19, 0xf0, 0x10, 0x91, 0xed, 0x4b, 0xef, 0x38, 0x60, 0x2, 0x4c, 0x81, 0xdc, 0xc, 0xa1, 0x39, 0xb7, 0x5e, 0x12, 0x1a, 0x3c, 0xa0, 0x2, 0x4e, 0xc0, 0x18, 0x58, 0xaa, 0x6a, 0x5f, 0x55, 0x53, 0x60, 0x61, 0x5a, 0xd, 0xec, 0xa3, 0x11, 0x6c, 0x5b, 0x6a, 0xdb, 0x26, 0xc0, 0xc5, 0xe4, 0x81, 0x99, 0xb, 0x1f, 0xed, 0xb, 0x10, 0x40, 0xd6, 0xc0, 0xcc, 0x66, 0xe, 0xc0, 0xc6, 0x9b, 0xdb, 0x22, 0xc4, 0x4a, 0x63, 0xcb, 0x7e, 0x89, 0xa0, 0xc0, 0xd0, 0x22, 0x94, 0x22, 0x72, 0x8d, 0x2, 0x9c, 0xb9, 0x6, 0xa, 0x3, 0x84, 0xda, 0x7, 0xc4, 0x47, 0xc8, 0x6c, 0xf0, 0x8c, 0x1d, 0x4c, 0x44, 0xee, 0xc0, 0xce, 0xb4, 0x11, 0x30, 0xf, 0xd, 0x1e, 0xd0, 0x0, 0x47, 0xdb, 0xf2, 0x3e, 0x98, 0xbd, 0x4b, 0xeb, 0x35, 0x6d, 0xb7, 0xf8, 0xe3, 0x7a, 0x2, 0x49, 0x7e, 0x47, 0x10, 0xc3, 0xf7, 0xae, 0x75, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char color_picker_hue_png[] = {
@@ -71,7 +67,7 @@ static const unsigned char dosfont_png[] = {
};
static const unsigned char dropdown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x68, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0xa5, 0x8e, 0x21, 0xe, 0xc3, 0x60, 0x14, 0x82, 0x3f, 0xfe, 0xa4, 0x99, 0xee, 0x9, 0x9e, 0xa8, 0xe9, 0xe1, 0x66, 0x76, 0x92, 0x99, 0x9a, 0x1d, 0x6e, 0x82, 0x13, 0x54, 0xcf, 0xfc, 0x4c, 0xbd, 0xa4, 0x6e, 0x62, 0x28, 0x2, 0x4, 0x80, 0x7f, 0x21, 0xdb, 0x2f, 0xe0, 0x6, 0x3c, 0xaa, 0xea, 0x4, 0xb0, 0xbd, 0x2, 0x4f, 0xe0, 0x33, 0x92, 0x2c, 0x49, 0x76, 0x49, 0x87, 0xed, 0xd5, 0xf6, 0x2a, 0xe9, 0x48, 0xb2, 0x27, 0x59, 0xd4, 0xc2, 0x9c, 0x73, 0x1b, 0x63, 0xbc, 0x1, 0x9a, 0x27, 0xb9, 0xab, 0x2b, 0x3b, 0x4, 0xd0, 0x66, 0x55, 0x9d, 0xea, 0x33, 0x97, 0x5d, 0xae, 0x7f, 0x7e, 0xe2, 0xb, 0xf3, 0x6d, 0x3b, 0xdb, 0xfc, 0x5b, 0x1f, 0x84, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x60, 0xf8, 0xc0, 0xcc, 0x0, 0x5, 0x1f, 0x98, 0x19, 0x18, 0x18, 0x3f, 0x30, 0xff, 0xd3, 0x83, 0x70, 0xff, 0x33, 0x33, 0x30, 0x8, 0x9f, 0x61, 0xf9, 0x6b, 0xff, 0x65, 0x2f, 0x3, 0x1c, 0xbc, 0xea, 0x66, 0x62, 0xbc, 0xcf, 0xc0, 0xc0, 0xf0, 0x7, 0x26, 0xc0, 0x74, 0x89, 0x89, 0xe9, 0x29, 0x9f, 0x14, 0x3, 0xb, 0xc3, 0x5f, 0x6, 0x6, 0x6, 0x6, 0xee, 0x38, 0x91, 0x25, 0xc, 0xc, 0xc, 0x1f, 0xd8, 0xde, 0x4b, 0x3e, 0xfc, 0xff, 0xf0, 0xff, 0x9b, 0x58, 0xb8, 0xce, 0xf, 0x6c, 0xef, 0xe4, 0xde, 0xa4, 0x32, 0x20, 0x83, 0xf, 0x4c, 0x30, 0x16, 0x0, 0x75, 0xad, 0x1b, 0x7f, 0x65, 0xec, 0x78, 0x4c, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char error_icon_png[] = {
@@ -79,19 +75,19 @@ static const unsigned char error_icon_png[] = {
};
static const unsigned char focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x3a, 0x0, 0x0, 0x2, 0x4c, 0x0, 0x1, 0x4e, 0x94, 0x8c, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xb9, 0xa2, 0x9b, 0xc9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char frame_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x3a, 0x0, 0x0, 0x2, 0x4c, 0x0, 0x1, 0x4e, 0x94, 0x8c, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x4, 0x3, 0x0, 0x0, 0x0, 0xa4, 0x5b, 0x41, 0xd4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0xff, 0xff, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0x47, 0x8c, 0xbf, 0xff, 0xff, 0xff, 0xcc, 0x40, 0x27, 0xb9, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xe, 0x39, 0x68, 0x7a, 0x7b, 0x3a, 0x74, 0x10, 0x8, 0x69, 0xf, 0x6, 0x75, 0x11, 0xb8, 0x16, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x88, 0x5, 0x1d, 0x48, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x10, 0x32, 0x9, 0xd, 0x75, 0x56, 0x64, 0x48, 0xef, 0x9c, 0x39, 0x73, 0x46, 0x19, 0xc3, 0x6a, 0x6, 0x20, 0xd8, 0xc5, 0x10, 0x3, 0xa2, 0x8e, 0x32, 0x44, 0x82, 0xa8, 0xa9, 0xd8, 0x29, 0xa8, 0x12, 0xb0, 0x6, 0x29, 0x86, 0xdc, 0x9d, 0x33, 0x67, 0xce, 0x2b, 0x63, 0x10, 0x3, 0x1b, 0x6, 0x0, 0xdf, 0xc6, 0x11, 0x6d, 0xb8, 0xf4, 0x9c, 0xac, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char full_panel_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x1, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0x4a, 0x3, 0x61, 0x10, 0x85, 0xdf, 0x9b, 0xfd, 0x97, 0x9c, 0xc0, 0x80, 0x62, 0x6d, 0xb7, 0x75, 0xec, 0x84, 0x40, 0x1a, 0x5, 0xaf, 0x60, 0xe, 0xe1, 0x1, 0x72, 0x14, 0xbd, 0x82, 0x62, 0xb5, 0x10, 0xb0, 0x33, 0x9d, 0x90, 0x3, 0xa8, 0x20, 0x29, 0x62, 0x1f, 0xdd, 0xcd, 0xbf, 0xf3, 0x2c, 0x76, 0x9, 0x11, 0x56, 0x12, 0xd9, 0xd6, 0x7, 0x3f, 0xfc, 0xc5, 0xcc, 0x37, 0x6f, 0xe0, 0xd, 0xd0, 0x51, 0xdc, 0xfe, 0x67, 0x83, 0xe1, 0x98, 0xc0, 0x8, 0xd4, 0x41, 0x6b, 0xb5, 0xf8, 0x21, 0x20, 0x9f, 0xcf, 0xa6, 0x37, 0x0, 0xb4, 0x5, 0x98, 0x58, 0x36, 0x78, 0xbc, 0x27, 0x79, 0x2e, 0x79, 0xf4, 0xaa, 0xa, 0xad, 0xd3, 0x92, 0x24, 0x1a, 0x2d, 0x48, 0x7a, 0x98, 0xcf, 0xce, 0x2e, 0x81, 0x89, 0x27, 0x0, 0x90, 0xd, 0x6c, 0x4c, 0xf2, 0xba, 0xf8, 0x5a, 0xa1, 0xf8, 0x5c, 0x59, 0x5c, 0xaf, 0xd1, 0xfa, 0xca, 0xc2, 0xe4, 0x42, 0x48, 0xd3, 0x93, 0xfe, 0xf1, 0xdb, 0xeb, 0xf2, 0xfd, 0xe5, 0xd9, 0x1a, 0x1b, 0x23, 0xc9, 0x63, 0x2c, 0xcb, 0x9d, 0x3b, 0xc7, 0x75, 0x1, 0xc9, 0x2b, 0x2, 0x23, 0x0, 0xb0, 0x7a, 0x35, 0x1d, 0xba, 0x7b, 0xab, 0xed, 0x36, 0xb9, 0x7b, 0x22, 0xe8, 0x68, 0x3, 0xe8, 0xa2, 0x7f, 0x40, 0x3, 0x20, 0xb8, 0xa0, 0x59, 0xdc, 0xb7, 0x89, 0x66, 0x91, 0xe0, 0x62, 0x3, 0x10, 0x90, 0x1b, 0x2d, 0x84, 0xb4, 0xb7, 0xb3, 0x39, 0xa4, 0x3d, 0x18, 0x2d, 0x8, 0xc8, 0xeb, 0xe1, 0x0, 0x9a, 0x28, 0xdf, 0x91, 0xbc, 0x70, 0x79, 0xd4, 0x1f, 0xa2, 0xfc, 0xf3, 0x98, 0x4e, 0x87, 0x57, 0x75, 0xc2, 0xd4, 0xff, 0xc5, 0xfc, 0x52, 0x40, 0x3e, 0x7f, 0x9a, 0xde, 0xa2, 0x39, 0xa6, 0xce, 0xfa, 0x6, 0xb9, 0xde, 0x7b, 0x63, 0x8a, 0x21, 0x2a, 0x35, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x44, 0xa4, 0x8a, 0xc6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0x26, 0x26, 0x28, 0x25, 0x25, 0x27, 0x24, 0x24, 0x26, 0x23, 0x23, 0x25, 0x22, 0x22, 0x24, 0x21, 0x21, 0x23, 0x1e, 0x1e, 0x20, 0x1d, 0x1d, 0x1f, 0x1c, 0x1c, 0x1e, 0x31, 0x30, 0x32, 0x50, 0x4e, 0x54, 0x4e, 0x4c, 0x50, 0x4c, 0x4a, 0x4e, 0x3d, 0x3b, 0x3f, 0x38, 0x36, 0x3a, 0xff, 0xff, 0xff, 0x4, 0xb3, 0x69, 0x9b, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x63, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0xed, 0x93, 0x29, 0x12, 0xc0, 0x30, 0xc, 0xc4, 0x7c, 0x3b, 0x67, 0xf3, 0xff, 0xdf, 0xb6, 0xe1, 0xce, 0x98, 0x15, 0x45, 0x58, 0xb3, 0x68, 0x5, 0x0, 0x80, 0x48, 0x21, 0x88, 0xb0, 0x41, 0x62, 0x51, 0xb, 0x50, 0x61, 0xda, 0xa, 0xb1, 0x79, 0xa9, 0x1, 0xc5, 0x8d, 0xe9, 0x1b, 0x60, 0x6b, 0x7d, 0xcc, 0x80, 0xd1, 0x9b, 0x31, 0x2, 0x8a, 0xf7, 0x67, 0x85, 0x3c, 0xdd, 0x5, 0x81, 0xb4, 0x8c, 0x75, 0x60, 0x14, 0x25, 0x20, 0xab, 0xf3, 0x24, 0xcc, 0x6a, 0x57, 0xb8, 0xc2, 0xff, 0x42, 0x76, 0xda, 0xf4, 0xf6, 0x69, 0x38, 0x69, 0x7a, 0x79, 0xbc, 0x49, 0xfe, 0x2f, 0x65, 0xd3, 0x2d, 0x45, 0xb, 0x5e, 0xbc, 0x3b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x46, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc5, 0x24, 0x14, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xca, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0xce, 0xa1, 0xe, 0x41, 0x71, 0x14, 0xc7, 0xf1, 0xef, 0xf9, 0xef, 0x6a, 0x82, 0xd, 0xe9, 0xa, 0x66, 0xf3, 0x2, 0x9e, 0x41, 0xc0, 0x33, 0x90, 0x5, 0xe3, 0x61, 0x68, 0x34, 0xaa, 0xa0, 0x29, 0x1e, 0xe1, 0x4e, 0x37, 0xc5, 0x26, 0xd9, 0x2e, 0x81, 0x8d, 0x76, 0x8f, 0x80, 0xa0, 0x5d, 0x7f, 0xb4, 0xf3, 0x4b, 0xa7, 0xfc, 0x3e, 0xbf, 0x3, 0x5f, 0x46, 0xa2, 0x48, 0x33, 0xfb, 0xdd, 0xb9, 0x2b, 0x4a, 0x43, 0xa1, 0x90, 0xaa, 0x4, 0x31, 0xe2, 0x96, 0x87, 0xe3, 0x66, 0x1c, 0xec, 0x77, 0xe7, 0x2e, 0x4a, 0x5b, 0x3f, 0x58, 0x55, 0x28, 0xa0, 0x49, 0xa7, 0x98, 0xab, 0xe2, 0x48, 0x68, 0x7a, 0x7e, 0x8f, 0x8, 0x2d, 0x87, 0x90, 0xf7, 0x5, 0x10, 0xf2, 0xce, 0xbb, 0xfc, 0x8c, 0x1, 0x6, 0x18, 0x60, 0xc0, 0xcf, 0x80, 0xe0, 0x75, 0xc, 0xfa, 0xf5, 0xf5, 0x27, 0xc5, 0xe1, 0x68, 0x55, 0xfb, 0xc9, 0x7, 0x6, 0x18, 0x60, 0x80, 0x1, 0x6, 0x18, 0x60, 0x80, 0x1, 0x6, 0x18, 0xf0, 0x1f, 0x40, 0x20, 0x6, 0x8, 0xc3, 0xca, 0x35, 0x6d, 0x29, 0x2c, 0x55, 0x6e, 0x0, 0xaa, 0xc4, 0xb2, 0x98, 0x5f, 0x7a, 0xaa, 0x49, 0xc7, 0x67, 0x5d, 0x60, 0xea, 0x4a, 0xe5, 0xec, 0x58, 0xc4, 0xcd, 0x54, 0x1f, 0x9f, 0xa4, 0x89, 0x2a, 0xb1, 0x26, 0xcc, 0xe, 0xa7, 0xed, 0xc4, 0x67, 0xf8, 0x2d, 0x77, 0x97, 0xcc, 0x36, 0xeb, 0x4d, 0x52, 0xcd, 0xa3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x17, 0xd, 0x5, 0x12, 0xa1, 0x38, 0x83, 0x9b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x2, 0x74, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0x3d, 0x6f, 0xd3, 0x60, 0x10, 0xc7, 0x7f, 0x17, 0x9b, 0x26, 0x25, 0x22, 0xad, 0xa, 0x8, 0xf1, 0x52, 0x75, 0x0, 0x16, 0x24, 0x90, 0x2a, 0x96, 0x7c, 0x1, 0x6, 0xc4, 0xce, 0xc4, 0x17, 0x0, 0x31, 0xb0, 0x30, 0x0, 0x23, 0x82, 0x85, 0x5, 0x9, 0x4, 0x5f, 0x80, 0x89, 0x1d, 0x31, 0xf0, 0x5, 0x58, 0x50, 0x25, 0x50, 0x59, 0x80, 0xa1, 0xe2, 0xad, 0x28, 0x34, 0x4a, 0x3, 0x25, 0x76, 0xea, 0xe7, 0x39, 0x6, 0x3f, 0x76, 0x6d, 0xc7, 0x49, 0x5f, 0xd8, 0x90, 0x6f, 0xb1, 0xf5, 0xe4, 0xb9, 0xdf, 0xdd, 0xfd, 0xef, 0x22, 0xf9, 0x84, 0x2d, 0x13, 0xa0, 0x6, 0x78, 0xee, 0x29, 0xe4, 0x4d, 0x1, 0xb, 0x18, 0xf7, 0x54, 0x32, 0x97, 0x6a, 0xc0, 0x7e, 0x60, 0xe, 0x38, 0xc, 0xb4, 0x80, 0x7d, 0x5, 0xc0, 0x26, 0xd0, 0x7, 0x3a, 0x40, 0x17, 0xf8, 0x3, 0xd8, 0x24, 0x6a, 0x13, 0x38, 0x35, 0x73, 0x60, 0xf6, 0x6a, 0xa3, 0xde, 0xb8, 0x38, 0x35, 0x55, 0x3f, 0x41, 0x89, 0xd, 0x87, 0xe1, 0x97, 0x20, 0xc, 0x5e, 0xae, 0xff, 0xea, 0x3d, 0x5, 0x3e, 0x2, 0x1b, 0xe2, 0x22, 0x2d, 0xcc, 0xcd, 0x1e, 0x7c, 0x78, 0x72, 0xe1, 0xf4, 0xa5, 0x7b, 0xb7, 0x1f, 0x7c, 0x9e, 0x6e, 0x35, 0xca, 0xfc, 0x19, 0xf4, 0x3, 0xee, 0xdc, 0xbf, 0x39, 0xff, 0x69, 0xe5, 0xc3, 0x8b, 0x6e, 0x6f, 0xed, 0x6, 0xb0, 0x22, 0x40, 0x3, 0x58, 0x3c, 0x7a, 0xe4, 0xf8, 0xab, 0x67, 0x4f, 0x9e, 0x77, 0xa3, 0xc8, 0x12, 0xd, 0xa3, 0x52, 0x80, 0x3f, 0xe5, 0xe3, 0xfb, 0x35, 0xae, 0x5c, 0xbb, 0x3c, 0xf7, 0xfd, 0xc7, 0xd7, 0xb, 0xc0, 0x92, 0xef, 0x74, 0x68, 0xfa, 0x9e, 0xdf, 0x1c, 0xfc, 0xe, 0xbb, 0x88, 0xc6, 0x47, 0xa, 0x2a, 0x59, 0x85, 0x95, 0x61, 0xb8, 0xc9, 0x30, 0x4, 0xdf, 0xf3, 0x9b, 0xae, 0x6c, 0x49, 0x0, 0x1e, 0x80, 0x51, 0x1b, 0xfb, 0xc7, 0x2, 0xc7, 0x5a, 0x3b, 0x88, 0x66, 0xcf, 0x63, 0xf3, 0x12, 0x80, 0x26, 0xbf, 0xa8, 0xb5, 0xa8, 0xa, 0x88, 0x22, 0x8, 0x8a, 0x22, 0x2a, 0x19, 0x37, 0x1d, 0xe9, 0xad, 0x9f, 0x6b, 0xb4, 0x55, 0x14, 0x5, 0x55, 0x44, 0xe2, 0x32, 0x6c, 0xe2, 0x24, 0x71, 0x18, 0x9d, 0x4, 0xb0, 0x6a, 0xd3, 0x1b, 0x2a, 0xe9, 0x4b, 0xfc, 0xae, 0xe4, 0x45, 0x19, 0x9f, 0x81, 0x2b, 0xdb, 0x15, 0xa6, 0xa2, 0x19, 0x2d, 0xec, 0x8, 0x24, 0x7, 0x30, 0xd6, 0x16, 0xf8, 0x82, 0xa8, 0xc6, 0x45, 0x68, 0x52, 0xbf, 0x4e, 0xce, 0x60, 0xeb, 0x42, 0x5c, 0xb4, 0x66, 0x9c, 0x6c, 0xc9, 0x1f, 0xa4, 0x0, 0xb0, 0x39, 0xc5, 0xc9, 0xa1, 0x28, 0x89, 0x5f, 0x14, 0xd1, 0x5a, 0x37, 0x32, 0x89, 0xf2, 0x82, 0xc6, 0x3, 0xe0, 0xda, 0xa, 0x22, 0x3a, 0xa9, 0xb, 0x9a, 0x26, 0xaa, 0xf1, 0x41, 0x9a, 0x42, 0x2, 0xb2, 0xb2, 0x6d, 0x6, 0x5b, 0xa3, 0xab, 0x23, 0xd5, 0x48, 0x32, 0x92, 0xe3, 0x33, 0x10, 0x37, 0xb7, 0x2a, 0xea, 0xee, 0x4a, 0x2a, 0x42, 0xe, 0x5a, 0x2a, 0xa2, 0x51, 0x37, 0x40, 0x85, 0x48, 0x96, 0xb4, 0x23, 0xdb, 0x88, 0x68, 0x5c, 0xc4, 0xcc, 0x3c, 0x14, 0xa7, 0x6f, 0xa2, 0x6, 0xaa, 0xb1, 0x7c, 0xd9, 0x30, 0xaa, 0x79, 0xc7, 0x49, 0x93, 0x78, 0xf7, 0xd1, 0xad, 0x79, 0x76, 0x69, 0x29, 0x20, 0xda, 0x34, 0x2c, 0x9e, 0x3d, 0xff, 0x7a, 0x27, 0x4e, 0x4b, 0xef, 0xde, 0xb4, 0x4b, 0x33, 0x58, 0xef, 0xf7, 0x76, 0x9b, 0x0, 0x35, 0xfe, 0xd1, 0x2a, 0x40, 0x5, 0xa8, 0x0, 0x15, 0xa0, 0x2, 0x54, 0x80, 0xa, 0xf0, 0x5f, 0x2, 0xa4, 0xe4, 0x13, 0x78, 0xd7, 0x19, 0xd8, 0x3d, 0xf8, 0xda, 0x4, 0x60, 0x81, 0xc0, 0x18, 0x13, 0xda, 0x68, 0x7, 0x5e, 0x11, 0x18, 0x63, 0x42, 0x20, 0x0, 0x6c, 0xcd, 0xad, 0xb2, 0x6b, 0x41, 0x38, 0x58, 0xee, 0x74, 0x57, 0xdb, 0x93, 0x20, 0x36, 0x82, 0x4e, 0x77, 0xb5, 0x1d, 0x84, 0x83, 0x65, 0x60, 0xd, 0x30, 0xc9, 0xe6, 0x3a, 0x3, 0x9c, 0x6b, 0x35, 0x67, 0x1f, 0x37, 0xea, 0xd3, 0x67, 0x3c, 0xcf, 0x2b, 0x15, 0xd7, 0x18, 0x63, 0x83, 0x70, 0xf0, 0xbe, 0xbf, 0xd1, 0xbb, 0xe, 0xbc, 0x5, 0xd6, 0x25, 0xb3, 0xc2, 0xb5, 0x80, 0x63, 0xc0, 0x21, 0xa0, 0x3e, 0x66, 0xf9, 0xe, 0x81, 0x9f, 0xc0, 0x37, 0xb7, 0x47, 0x1b, 0x29, 0x8, 0xea, 0x27, 0xfb, 0xe0, 0x98, 0x2a, 0xd4, 0x95, 0x1c, 0xed, 0x51, 0xf8, 0x51, 0xfb, 0xb, 0x1, 0xbe, 0x20, 0x9f, 0x90, 0x81, 0x17, 0xaa, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_breakpoint_png[] = {
@@ -103,11 +99,11 @@ static const unsigned char graph_node_close_png[] = {
};
static const unsigned char graph_node_comment_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x46, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc5, 0x24, 0x14, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x8b, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0xd8, 0xb1, 0xd, 0xc2, 0x40, 0xc, 0x5, 0xd0, 0x97, 0x28, 0x75, 0x90, 0x18, 0x6, 0x58, 0x80, 0x92, 0x82, 0x1d, 0x18, 0x8b, 0x2d, 0x22, 0xa, 0xd8, 0x0, 0xb6, 0xc9, 0x4, 0x47, 0x13, 0x4, 0x25, 0xc9, 0x41, 0xf7, 0x5d, 0xf9, 0x24, 0xff, 0x77, 0xae, 0x4d, 0x65, 0x35, 0xa5, 0x94, 0xe, 0x7, 0x6c, 0xb0, 0xfa, 0x32, 0x37, 0xe2, 0x81, 0xa1, 0x29, 0xa5, 0x1c, 0xb1, 0x5f, 0xb8, 0xc0, 0xad, 0xc5, 0x76, 0x61, 0x18, 0x76, 0x2d, 0xfa, 0xa, 0xa0, 0x6f, 0x2b, 0xc2, 0x20, 0x40, 0x80, 0x0, 0x1, 0x7e, 0x6, 0x74, 0x1f, 0xfd, 0x79, 0x66, 0xf6, 0xf4, 0x93, 0xd, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80, 0x0, 0x1, 0x2, 0x4, 0xf8, 0x1b, 0x30, 0x4e, 0xfd, 0x7a, 0x46, 0xee, 0x35, 0x3b, 0xd6, 0x1e, 0x20, 0xae, 0x1d, 0x86, 0xe9, 0x31, 0xf7, 0x4, 0x72, 0xc7, 0x65, 0xe1, 0xc7, 0xef, 0x7a, 0x2, 0x67, 0x50, 0x16, 0x1c, 0x57, 0x97, 0xfe, 0x1f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x19, 0x11, 0x2a, 0x1d, 0xd6, 0x78, 0x8b, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x1, 0x74, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0xbf, 0x4e, 0xc2, 0x50, 0x14, 0xc6, 0x7f, 0x6d, 0x91, 0x56, 0x1b, 0x90, 0x80, 0x2c, 0x44, 0xc2, 0xa0, 0x2e, 0xe, 0x3e, 0x3, 0x89, 0x93, 0xf1, 0x1d, 0x4c, 0x18, 0x4d, 0x1c, 0x7c, 0xb, 0x57, 0x7, 0x13, 0x47, 0x13, 0x77, 0x46, 0xe3, 0xc4, 0x4b, 0x98, 0x60, 0x4c, 0xd4, 0x81, 0x60, 0x58, 0x94, 0xff, 0x22, 0x2d, 0xd0, 0xd6, 0xe5, 0xde, 0x88, 0x8, 0x2, 0x35, 0x6e, 0xf7, 0x5b, 0x6e, 0x9a, 0x9c, 0xef, 0x77, 0xee, 0x39, 0x37, 0x1d, 0x3e, 0x8d, 0x2f, 0x69, 0x80, 0xe, 0x18, 0xe2, 0xd4, 0xf8, 0xae, 0x0, 0xf0, 0x1, 0x4f, 0x9c, 0x1, 0x63, 0x45, 0x3a, 0xb0, 0x6, 0x24, 0x81, 0x34, 0x10, 0x7, 0x56, 0x26, 0x0, 0x43, 0xa0, 0x3, 0xbc, 0x2, 0xd, 0xe0, 0x3, 0xf0, 0x65, 0x57, 0x1b, 0xd8, 0x5e, 0x8f, 0x25, 0x8e, 0x2d, 0xd3, 0x3a, 0x88, 0x46, 0xcd, 0x4d, 0xa6, 0x68, 0x30, 0x70, 0x5f, 0x1c, 0xd7, 0xb9, 0x6d, 0x77, 0x5b, 0x97, 0xc0, 0x13, 0xd0, 0xd3, 0x44, 0xa7, 0x5c, 0x32, 0x91, 0x3a, 0xdf, 0xca, 0xed, 0x1c, 0x16, 0x52, 0xdd, 0x2a, 0xbf, 0xe8, 0xaa, 0x1e, 0xcb, 0x3e, 0x57, 0x1e, 0x6f, 0x1a, 0xad, 0xfa, 0x29, 0x50, 0x91, 0x33, 0xa7, 0x4d, 0xd3, 0xca, 0xcf, 0x33, 0x3, 0x14, 0x52, 0xdd, 0xaa, 0x69, 0x5a, 0x79, 0x31, 0xaa, 0x21, 0x97, 0x65, 0x47, 0x8c, 0x88, 0xcd, 0x82, 0x12, 0xb5, 0x36, 0xa0, 0x49, 0x80, 0xc1, 0xf2, 0x32, 0x24, 0x20, 0x90, 0x4f, 0x12, 0x46, 0x3a, 0x7f, 0x94, 0x2, 0x28, 0x80, 0x2, 0x88, 0x5f, 0x7b, 0xfc, 0xe3, 0xec, 0xe1, 0x3d, 0x1b, 0x1a, 0x30, 0x1a, 0x7a, 0x1c, 0x65, 0xd8, 0x5f, 0xc4, 0x74, 0x5d, 0xa3, 0xa4, 0x5e, 0x41, 0x1, 0x14, 0x40, 0x1, 0x14, 0x40, 0x1, 0x14, 0x40, 0x1, 0xfe, 0x15, 0xa0, 0x4d, 0xc9, 0x88, 0x4b, 0xdf, 0xc0, 0xf, 0xe1, 0xf5, 0x25, 0xc0, 0x7, 0x1c, 0xcf, 0xf3, 0xdc, 0x45, 0x9d, 0xa2, 0xd6, 0x1, 0x7c, 0x5d, 0x44, 0xd9, 0xba, 0xe3, 0xf6, 0xcb, 0xc5, 0xa6, 0x5d, 0x9a, 0x67, 0x2e, 0x36, 0xed, 0x92, 0xe3, 0xf6, 0xcb, 0x40, 0x1d, 0xf0, 0x64, 0x72, 0x5d, 0x7, 0xf6, 0xe2, 0x76, 0xe2, 0xc2, 0x32, 0x57, 0x77, 0xd, 0xc3, 0xd0, 0x67, 0x74, 0xf6, 0x1d, 0xb7, 0x7f, 0xdf, 0xe9, 0xb5, 0x4e, 0x80, 0x3b, 0xa0, 0xad, 0x8d, 0x45, 0xb8, 0x38, 0x90, 0x1, 0x36, 0x0, 0x73, 0x46, 0xf8, 0x76, 0x81, 0x37, 0xa0, 0x26, 0x72, 0xb4, 0xa7, 0x4d, 0x2c, 0x34, 0x22, 0xf3, 0xe0, 0x8c, 0x9, 0x2, 0x31, 0xf2, 0x28, 0xe4, 0xe2, 0x7f, 0xea, 0x13, 0x64, 0x47, 0x6c, 0x83, 0x36, 0x6d, 0xd2, 0x40, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_comment_focus_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x46, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc5, 0x24, 0x14, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x97, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0xd8, 0xb1, 0x11, 0xc2, 0x30, 0x10, 0x44, 0xd1, 0x7f, 0x8c, 0x87, 0xe, 0x80, 0xd4, 0x94, 0xa4, 0x2a, 0xa0, 0x0, 0x12, 0x5c, 0x3, 0x10, 0x9a, 0x2e, 0xa0, 0x11, 0x9a, 0x20, 0xb4, 0x29, 0x62, 0x9, 0xd0, 0xc, 0x84, 0xb6, 0x6c, 0xb2, 0xbd, 0x44, 0xa7, 0x60, 0x9f, 0x36, 0x16, 0x4c, 0x9c, 0x90, 0xb4, 0x4, 0xe, 0x40, 0x2, 0xd6, 0x3, 0x73, 0x3d, 0x70, 0x3, 0x4e, 0x21, 0xa9, 0x1, 0x76, 0x85, 0x5, 0xae, 0x21, 0xe9, 0x1, 0xac, 0xa, 0x81, 0x57, 0x48, 0x7a, 0x16, 0x86, 0x1, 0x58, 0x4c, 0x9, 0x1b, 0x30, 0x60, 0xc0, 0xc0, 0xac, 0x40, 0xf5, 0xb3, 0xa7, 0x91, 0xd9, 0xfb, 0x2c, 0xd, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x1, 0x3, 0x6, 0xc, 0x18, 0xf8, 0x1b, 0xd0, 0xe7, 0xbd, 0x1e, 0x91, 0xdb, 0xe6, 0xb3, 0xb, 0x49, 0x47, 0x60, 0x5f, 0x58, 0xa0, 0xad, 0x80, 0x73, 0xbe, 0x24, 0x60, 0x33, 0x30, 0xd8, 0xf1, 0xf9, 0x2, 0xb9, 0x14, 0x3e, 0xfc, 0x9d, 0x37, 0xf9, 0xbd, 0x1e, 0x48, 0x36, 0x1d, 0x7d, 0x70, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xf9, 0x43, 0xbb, 0x7f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x9, 0x2, 0xe, 0x16, 0x22, 0xbe, 0xef, 0xc2, 0xe1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x1, 0x4a, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0xd7, 0xbf, 0x4b, 0xdb, 0x41, 0x1c, 0xc6, 0xf1, 0xd7, 0x37, 0x51, 0x4, 0x3, 0xa, 0xa2, 0x20, 0xd2, 0xe2, 0xe2, 0x64, 0x41, 0xdc, 0xdc, 0xac, 0xe0, 0x54, 0xdc, 0xb2, 0xe6, 0x2f, 0x10, 0x1a, 0xf0, 0x4f, 0x11, 0x22, 0xf8, 0x17, 0x64, 0xcd, 0x26, 0x9d, 0x1c, 0x74, 0x73, 0x13, 0x21, 0x4e, 0x2e, 0xa5, 0xa5, 0x14, 0xac, 0x82, 0x82, 0x62, 0xd0, 0x7c, 0xd3, 0xa1, 0x77, 0x18, 0x35, 0xfe, 0x48, 0xa4, 0xdb, 0x3d, 0x70, 0xdc, 0xf2, 0x79, 0xde, 0x77, 0xf7, 0x39, 0x38, 0xee, 0xc9, 0xdc, 0x2b, 0x43, 0x1, 0xc5, 0x30, 0x67, 0x1e, 0xaa, 0x83, 0x1c, 0xed, 0x30, 0x77, 0x74, 0x15, 0x15, 0x30, 0x8a, 0x9, 0x4c, 0x61, 0xc, 0xc3, 0x8f, 0x0, 0xb7, 0xb8, 0xc4, 0x29, 0xce, 0x71, 0x8d, 0x3c, 0xae, 0x5a, 0xc2, 0x5c, 0xa3, 0x5a, 0x59, 0xc7, 0x17, 0x7c, 0xd0, 0x5b, 0x3f, 0xf1, 0xad, 0x5c, 0xab, 0x6f, 0xe3, 0x4, 0x57, 0x59, 0x58, 0x69, 0xb6, 0x51, 0xad, 0x6c, 0x62, 0xed, 0x77, 0xf3, 0xf0, 0x87, 0x17, 0x34, 0xfd, 0x69, 0xf1, 0x23, 0x76, 0xca, 0xb5, 0xfa, 0x6, 0xbe, 0xc7, 0x33, 0x4f, 0x61, 0xe5, 0x35, 0x33, 0x84, 0x9a, 0x95, 0xe0, 0x29, 0xc6, 0x66, 0x95, 0xc2, 0x78, 0xab, 0x62, 0x7d, 0x16, 0x1, 0x45, 0xfd, 0xab, 0x18, 0x1, 0x9d, 0x78, 0x25, 0x83, 0xa8, 0xe0, 0x9d, 0x4a, 0x80, 0x4, 0x48, 0x80, 0x7f, 0x1a, 0xea, 0xf1, 0xda, 0xc, 0xe, 0x38, 0xd8, 0xdf, 0x5b, 0x7d, 0x8b, 0x69, 0x69, 0xf9, 0xf3, 0x6e, 0xba, 0x85, 0x4, 0x48, 0x80, 0x4, 0x48, 0x80, 0x4, 0x48, 0x80, 0x4, 0xf8, 0xaf, 0x80, 0xac, 0x47, 0x46, 0xec, 0x7b, 0x7, 0xf9, 0x0, 0xde, 0x3c, 0x2, 0x72, 0xdc, 0xa0, 0xd5, 0x87, 0xb9, 0x15, 0x3c, 0x79, 0x21, 0x44, 0xd9, 0x33, 0x34, 0xbb, 0x3f, 0x4f, 0xaf, 0x7c, 0xb0, 0x9a, 0xc1, 0xd3, 0x8e, 0xc9, 0x75, 0x1c, 0xb, 0x8d, 0x6a, 0x65, 0xb, 0xf3, 0x2f, 0x34, 0x37, 0xc7, 0x71, 0xb9, 0x56, 0xff, 0x8a, 0x23, 0x5c, 0x64, 0x5d, 0x11, 0x6e, 0xc, 0x33, 0x98, 0xc4, 0xc8, 0x33, 0xe1, 0xbb, 0x85, 0x3f, 0xf8, 0x15, 0x72, 0x74, 0x3b, 0x7b, 0xd4, 0xd0, 0xa1, 0x98, 0x7, 0x9f, 0xd9, 0x41, 0x27, 0x1c, 0xf9, 0x6e, 0xc0, 0xc6, 0x3f, 0xd5, 0x5f, 0x9d, 0x54, 0x4e, 0x15, 0xfd, 0xeb, 0xb4, 0x4f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_default_png[] = {
@@ -119,11 +115,11 @@ static const unsigned char graph_node_default_focus_png[] = {
};
static const unsigned char graph_node_position_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x46, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc5, 0x24, 0x14, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xb1, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0xd7, 0xb1, 0x11, 0x82, 0x50, 0x10, 0x84, 0xe1, 0xff, 0x80, 0x19, 0x33, 0x72, 0x68, 0x5, 0x4b, 0xc1, 0x32, 0x24, 0x60, 0x50, 0x3, 0xdf, 0x30, 0x9a, 0xd2, 0x2, 0xad, 0xa8, 0xa5, 0x40, 0xc, 0x31, 0xf0, 0xc, 0xc4, 0x31, 0x30, 0xf0, 0x81, 0xe9, 0x6d, 0xbe, 0xdf, 0x5e, 0x7a, 0xf0, 0x67, 0xc4, 0x56, 0xd5, 0x86, 0xae, 0x3b, 0x23, 0x92, 0x2, 0x91, 0x63, 0xaf, 0x5, 0x6a, 0x86, 0xe1, 0x10, 0xcc, 0xe5, 0xfd, 0xc2, 0xe1, 0x8, 0xc8, 0xf0, 0x7d, 0x1b, 0xcc, 0xcb, 0x0, 0x89, 0x14, 0xc5, 0xc3, 0xa5, 0x6d, 0xcb, 0x32, 0x61, 0x9a, 0x6e, 0x78, 0xde, 0xce, 0x7b, 0x9f, 0xed, 0x5a, 0x6, 0x90, 0x3c, 0xbf, 0xbf, 0x24, 0x1b, 0x7b, 0xcb, 0x2e, 0xff, 0x8e, 0x2, 0xa, 0x28, 0xa0, 0x80, 0x2, 0xa, 0x28, 0xa0, 0x80, 0x2, 0xa, 0x28, 0xa0, 0x80, 0x2, 0xa, 0x28, 0xf0, 0x1b, 0x68, 0x61, 0x7e, 0xe9, 0x1d, 0x63, 0x8d, 0xd9, 0x2, 0x20, 0xd2, 0x88, 0x35, 0xe6, 0xa, 0x64, 0x2b, 0xf, 0xb8, 0x4, 0x84, 0xe1, 0x91, 0xbe, 0x7, 0x91, 0x14, 0x6b, 0x63, 0xa7, 0x9a, 0x48, 0xc3, 0x34, 0xd5, 0x8c, 0xe3, 0x69, 0xe5, 0xf0, 0x27, 0x4f, 0xdd, 0xc, 0x30, 0x45, 0xe4, 0x56, 0x1f, 0x3c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x6, 0xf, 0x3b, 0x3b, 0x49, 0x6e, 0xe4, 0x1e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x90, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0xd7, 0xbd, 0x9, 0xc0, 0x20, 0x10, 0x5, 0xe0, 0x53, 0x2c, 0xdd, 0x40, 0x47, 0x70, 0x7, 0x67, 0x77, 0x7, 0x47, 0x88, 0x1b, 0xd8, 0x9b, 0xe6, 0x84, 0x53, 0x48, 0x10, 0x14, 0x52, 0xe4, 0x5d, 0x25, 0xfe, 0x7c, 0x9e, 0x58, 0x3d, 0xa2, 0xcd, 0x52, 0x7d, 0x50, 0x63, 0xb8, 0x88, 0xc8, 0x2d, 0x9e, 0x2b, 0x36, 0x65, 0x4f, 0xf2, 0x30, 0x3, 0x4b, 0x25, 0xf7, 0x1b, 0x9e, 0x73, 0x36, 0x65, 0xb5, 0xd0, 0x49, 0xb1, 0x29, 0x7b, 0x9b, 0xb2, 0xaf, 0x31, 0x34, 0x9, 0xc8, 0x67, 0x50, 0xc7, 0x9e, 0x6e, 0x96, 0xed, 0xeb, 0x69, 0x8f, 0x1b, 0xde, 0x36, 0x15, 0xaf, 0xd, 0xdd, 0xe9, 0xdd, 0x5f, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x80, 0x1f, 0x1, 0xe5, 0x2d, 0x3f, 0xf2, 0x5a, 0x91, 0x73, 0x66, 0x4e, 0x65, 0x1c, 0xed, 0xda, 0x52, 0x62, 0x3d, 0x91, 0x5c, 0xcf, 0x64, 0xe7, 0x4f, 0xeb, 0x6, 0x80, 0xff, 0x44, 0x93, 0xd4, 0xd9, 0xea, 0x7e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_node_selected_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x46, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc5, 0x24, 0x14, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xc4, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85, 0xed, 0xce, 0xb1, 0xd, 0x82, 0x40, 0x14, 0xc6, 0xf1, 0xef, 0x9d, 0x17, 0x43, 0x62, 0x2c, 0xc1, 0x1, 0xc0, 0x38, 0x86, 0x3, 0x58, 0x18, 0xd4, 0x1d, 0x64, 0x0, 0x1b, 0x77, 0x50, 0x4b, 0xb7, 0x80, 0xc4, 0xc2, 0x1, 0xec, 0x8c, 0x3d, 0x43, 0x40, 0x2b, 0x2a, 0x31, 0xc6, 0x67, 0xe3, 0x99, 0xd8, 0xc1, 0x89, 0xdd, 0xfb, 0xaa, 0x2b, 0xf8, 0xff, 0x1e, 0xc0, 0x8f, 0xa3, 0x34, 0xe5, 0x76, 0x51, 0x5c, 0x17, 0x4, 0xa, 0x1, 0x78, 0x15, 0xbb, 0x1c, 0x4c, 0x89, 0xd2, 0xce, 0x4a, 0xbf, 0xe3, 0x79, 0xcd, 0xc3, 0x1e, 0x88, 0xa3, 0xe7, 0xa3, 0x64, 0x5, 0xa6, 0x49, 0xcd, 0xf8, 0x33, 0x6, 0xcf, 0x14, 0x11, 0x5c, 0x5b, 0x80, 0x8, 0xae, 0xb2, 0x8d, 0xcd, 0x4, 0x10, 0x40, 0x0, 0x1, 0x1a, 0x3, 0xb4, 0x79, 0x4c, 0xc7, 0xc3, 0x7d, 0x9d, 0x30, 0xde, 0x1d, 0x46, 0x8d, 0xfc, 0x81, 0x0, 0x2, 0x8, 0x20, 0x80, 0x0, 0x2, 0x8, 0x20, 0x80, 0x0, 0x2, 0xfc, 0xd, 0xc8, 0x1, 0xc0, 0xf, 0xfa, 0xf7, 0xaa, 0x91, 0x1f, 0xc, 0xcc, 0xb7, 0x19, 0x9d, 0x8e, 0xb7, 0x25, 0x88, 0x23, 0x9b, 0xeb, 0xc, 0x6c, 0x75, 0xa7, 0xeb, 0xac, 0x2f, 0xe7, 0x12, 0x20, 0xe, 0x1, 0xf4, 0x2a, 0xb6, 0x19, 0x98, 0x92, 0x96, 0x76, 0x36, 0x36, 0x87, 0xbf, 0xf6, 0x2, 0x6c, 0x6e, 0x2d, 0xee, 0x58, 0x4d, 0xc1, 0x68, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x13, 0x7d, 0xf7, 0x96, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x17, 0xd, 0x4, 0x3b, 0xfa, 0x91, 0x2a, 0xb6, 0x0, 0x0, 0x3, 0x44, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xed, 0x97, 0x3f, 0x68, 0xdc, 0x76, 0x14, 0xc7, 0xbf, 0xef, 0xa7, 0x9f, 0x7e, 0x3a, 0xdd, 0x39, 0xf6, 0xdd, 0x95, 0xb3, 0x3, 0xc1, 0x75, 0x1b, 0x70, 0xa, 0xe9, 0x98, 0x25, 0x93, 0x87, 0x52, 0x3a, 0x4, 0x2, 0xce, 0xe0, 0xd2, 0x34, 0x35, 0x94, 0x8e, 0x1d, 0xbc, 0xd5, 0x4b, 0xc7, 0x2e, 0x25, 0x63, 0x2, 0x5d, 0xa, 0xa5, 0xb1, 0x1b, 0x2, 0xf5, 0xd0, 0x40, 0xa0, 0x90, 0x10, 0x3a, 0x64, 0xca, 0x92, 0x31, 0x81, 0x24, 0xd0, 0xd2, 0x9a, 0x40, 0x2f, 0x17, 0xdf, 0x1f, 0xfb, 0x74, 0xf2, 0xe9, 0x27, 0xfd, 0x5e, 0x7, 0x49, 0xb6, 0x4e, 0xe7, 0xea, 0x86, 0x6e, 0xe5, 0x1e, 0xdc, 0x49, 0x42, 0xef, 0x7d, 0xde, 0xf7, 0x7d, 0xf5, 0x13, 0xe8, 0x47, 0xcc, 0x4c, 0x0, 0xc4, 0xbd, 0x7b, 0x4f, 0x9c, 0xb0, 0xdd, 0x71, 0xdb, 0xfb, 0x2d, 0xc7, 0xb0, 0x11, 0x5a, 0x7, 0x84, 0x4c, 0xd8, 0xb6, 0x62, 0x41, 0xc2, 0xd4, 0x67, 0x1b, 0x43, 0x59, 0xaf, 0xf9, 0x97, 0x2f, 0x5f, 0x18, 0x2, 0x30, 0xc4, 0xcc, 0xd6, 0xdd, 0x1f, 0xef, 0x9e, 0xea, 0x79, 0x83, 0x33, 0xed, 0x6e, 0xf7, 0x6c, 0xaf, 0xd7, 0x59, 0xe8, 0x7b, 0xfd, 0x72, 0x10, 0x4, 0x32, 0xb, 0x50, 0x4a, 0x85, 0x33, 0x95, 0x99, 0xc1, 0xdc, 0x5c, 0xad, 0x59, 0xaf, 0x56, 0x7f, 0x9f, 0xab, 0x94, 0x5f, 0xad, 0x7e, 0xbe, 0x7a, 0x40, 0x5b, 0x5b, 0xf7, 0x2b, 0x41, 0xbb, 0xf9, 0x6e, 0xa7, 0xd7, 0x5e, 0xb9, 0x72, 0x75, 0xe5, 0x86, 0x72, 0xa4, 0x85, 0x82, 0x8, 0x86, 0x61, 0xf4, 0xcb, 0x9d, 0x47, 0x1b, 0xb5, 0xb9, 0xfa, 0x23, 0x55, 0x5f, 0xf8, 0x43, 0xea, 0x4e, 0xb7, 0xdc, 0x7c, 0xf3, 0xfa, 0xdc, 0xc7, 0xeb, 0x1f, 0xdc, 0x64, 0x66, 0x71, 0xb8, 0x37, 0xbb, 0x2b, 0x1d, 0xb, 0x44, 0x23, 0x13, 0x80, 0x99, 0x11, 0xe, 0x23, 0x50, 0x65, 0x6f, 0x71, 0xf5, 0x93, 0x95, 0x9b, 0x3f, 0x6f, 0xff, 0xb6, 0x76, 0x9a, 0x9c, 0xa6, 0x8, 0x42, 0x5f, 0x79, 0xfd, 0x83, 0x79, 0xa7, 0x24, 0x5, 0xfc, 0xfa, 0x2e, 0x9, 0x42, 0xa8, 0xd, 0xc2, 0x20, 0x1a, 0xfd, 0x69, 0x3, 0x12, 0x4, 0xf8, 0xf5, 0x5d, 0xa7, 0x24, 0x85, 0xd7, 0x3f, 0x98, 0xf, 0x42, 0x5f, 0x9, 0xc3, 0x46, 0xc, 0xfc, 0x81, 0xb, 0x0, 0x91, 0x66, 0x30, 0x1b, 0x10, 0x0, 0x98, 0x6c, 0x7b, 0x80, 0xc0, 0x60, 0x66, 0x44, 0x21, 0x3, 0x0, 0x6, 0xfe, 0xc0, 0x35, 0x6c, 0x84, 0xd0, 0x5a, 0x53, 0x84, 0x88, 0x0, 0x80, 0x13, 0xd9, 0xcc, 0xc, 0x88, 0xb8, 0x10, 0x0, 0x40, 0x0, 0x1b, 0x0, 0xcc, 0x0, 0xc7, 0x39, 0x11, 0x22, 0xd2, 0x5a, 0x93, 0xb4, 0x6d, 0x9b, 0x11, 0x25, 0x89, 0x86, 0xc1, 0x20, 0x80, 0x18, 0xa0, 0xe3, 0xee, 0x47, 0xd0, 0xcc, 0x31, 0xad, 0x91, 0x79, 0xa3, 0x40, 0x4, 0x80, 0x91, 0xe6, 0xe5, 0x83, 0x73, 0x37, 0x64, 0xee, 0x2e, 0xd8, 0x24, 0x9, 0xc4, 0xc7, 0xa, 0xb2, 0x6a, 0x8a, 0x0, 0x1c, 0xf7, 0xce, 0x5e, 0xc4, 0xc5, 0xe6, 0x18, 0x92, 0x57, 0x36, 0x2, 0x30, 0x26, 0x33, 0x7b, 0xe2, 0x1e, 0x71, 0xe2, 0xb, 0x33, 0x68, 0xf2, 0x8, 0xd9, 0x16, 0x94, 0xd1, 0x13, 0xff, 0x9b, 0x49, 0xa, 0xc0, 0x6, 0x6c, 0x72, 0xf6, 0x8f, 0xbb, 0x58, 0xe0, 0x41, 0x32, 0x77, 0x22, 0x1a, 0xc9, 0xf2, 0x49, 0x87, 0x89, 0xcf, 0x8a, 0x14, 0xc4, 0x0, 0x93, 0x14, 0x66, 0xba, 0xd1, 0xf1, 0xec, 0xa6, 0x18, 0x60, 0xe2, 0xfa, 0x91, 0xde, 0xd9, 0xae, 0x34, 0xf9, 0x31, 0x52, 0xba, 0x1e, 0x28, 0x5d, 0x4c, 0x94, 0xfa, 0x99, 0xbc, 0xf, 0x45, 0xa, 0x4c, 0x5c, 0x38, 0xd6, 0xc9, 0xe0, 0xe8, 0x89, 0xe4, 0xad, 0x1d, 0x5f, 0xca, 0x9c, 0x7f, 0x15, 0x8b, 0x63, 0xdc, 0xc4, 0x7c, 0x8f, 0x8c, 0x91, 0xb9, 0x93, 0x71, 0xc0, 0xd7, 0xdf, 0x7c, 0xf5, 0xea, 0xd9, 0x8b, 0xa7, 0x85, 0x1d, 0xcf, 0x9f, 0x7b, 0x1f, 0xdf, 0xdf, 0xfa, 0x76, 0xf1, 0x44, 0xc0, 0xd9, 0xa5, 0x65, 0x58, 0xc2, 0x2e, 0x4, 0x2c, 0x2d, 0xbe, 0xf3, 0xef, 0xa, 0x3c, 0xaf, 0x8f, 0xde, 0x7e, 0xb7, 0x10, 0xe0, 0x79, 0xfd, 0x91, 0x6b, 0x81, 0xff, 0x18, 0x53, 0xc0, 0x14, 0x30, 0x5, 0x4c, 0x1, 0x53, 0xc0, 0x14, 0x30, 0x5, 0xfc, 0xff, 0x0, 0x5a, 0x6b, 0x82, 0x75, 0xe2, 0xe7, 0xcf, 0xc9, 0x91, 0xe6, 0x58, 0x19, 0x5, 0x16, 0x2c, 0x6, 0x0, 0x5b, 0xca, 0x89, 0xf5, 0x69, 0x4e, 0x5a, 0x23, 0x1c, 0xe5, 0x44, 0x8e, 0x52, 0x1, 0x0, 0x94, 0xdd, 0x99, 0x89, 0x80, 0x34, 0xc7, 0x51, 0x2a, 0x70, 0x94, 0x13, 0x49, 0x25, 0xdd, 0xa0, 0xe4, 0x96, 0x5b, 0xc3, 0x43, 0xcd, 0x1b, 0x9b, 0x9f, 0x5e, 0xbc, 0x71, 0x9d, 0x1e, 0xf, 0xfc, 0x3, 0xe8, 0x30, 0x1c, 0xd9, 0x74, 0xd9, 0x52, 0xa2, 0xec, 0x9e, 0xc2, 0xc6, 0xe6, 0xd5, 0x8b, 0xc3, 0x43, 0xcd, 0x25, 0xb7, 0xdc, 0x52, 0xd2, 0xd, 0x68, 0x6b, 0xeb, 0x7e, 0x65, 0xef, 0xaf, 0x97, 0xcb, 0xdd, 0xfd, 0xce, 0x87, 0x9f, 0x7d, 0x71, 0xe9, 0xba, 0xe3, 0xda, 0x85, 0x4e, 0xc, 0x7d, 0xcd, 0x3f, 0xfd, 0xf0, 0xeb, 0x66, 0x75, 0xb6, 0xf6, 0xf0, 0xad, 0xb7, 0x97, 0x5f, 0x12, 0x33, 0x5b, 0xb7, 0xbf, 0xbb, 0x3d, 0xdb, 0xea, 0x74, 0x97, 0x3a, 0xdd, 0xee, 0x7b, 0x3, 0xdf, 0x9b, 0xd7, 0x5a, 0xdb, 0xc6, 0x8c, 0x7e, 0xad, 0xa, 0x21, 0x60, 0xdb, 0xb6, 0x2e, 0xbb, 0x95, 0xd7, 0xb5, 0x6a, 0xf5, 0x79, 0xa3, 0x56, 0xfd, 0xf3, 0xda, 0x97, 0xd7, 0xf6, 0x29, 0xdd, 0xbd, 0x6f, 0x6f, 0x3f, 0x28, 0xf5, 0xff, 0x6e, 0x56, 0xb4, 0x19, 0x2a, 0x66, 0x73, 0xe2, 0xe3, 0x25, 0x12, 0xc6, 0x16, 0x4e, 0x30, 0x73, 0x7a, 0xc1, 0x5b, 0x5f, 0xff, 0xe8, 0x10, 0xc0, 0xd1, 0xf6, 0x4, 0xcc, 0x4c, 0x3b, 0x3b, 0x3b, 0xa2, 0xd1, 0x68, 0x14, 0x8e, 0xd0, 0x6a, 0xb5, 0x78, 0x6d, 0x6d, 0xcd, 0x10, 0xc5, 0xdb, 0xba, 0x7f, 0x0, 0xb2, 0x1f, 0xaf, 0x82, 0x62, 0x7a, 0x69, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char graph_port_png[] = {
@@ -131,19 +127,19 @@ static const unsigned char graph_port_png[] = {
};
static const unsigned char hseparator_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x63, 0x60, 0x18, 0x5, 0xc, 0xc, 0xc, 0xc, 0x0, 0x1, 0x8, 0x0, 0x1, 0x7d, 0x41, 0xa5, 0xce, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xff, 0xff, 0xff, 0x64, 0x6c, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3, 0x11, 0xc, 0x4c, 0xf2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x10, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x64, 0x60, 0x60, 0xc2, 0x40, 0x8c, 0xc, 0x0, 0x0, 0xc7, 0x0, 0xf, 0xf5, 0x92, 0x2f, 0xa7, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x66, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xd0, 0xab, 0xe, 0x83, 0x50, 0x10, 0x84, 0xe1, 0xf, 0x4e, 0x48, 0x4d, 0xd5, 0x31, 0x4d, 0xe0, 0xfd, 0x5f, 0xd, 0xc, 0xc5, 0x50, 0x87, 0x0, 0x73, 0xb8, 0x8, 0x1a, 0x8, 0x58, 0x7e, 0xb3, 0xc9, 0x24, 0x33, 0xbb, 0xb3, 0x3c, 0xdc, 0x26, 0xdb, 0xcc, 0x12, 0x11, 0xc5, 0x81, 0x67, 0x40, 0x87, 0x1a, 0x63, 0x48, 0x62, 0x85, 0xf, 0xc2, 0x3f, 0xd7, 0x86, 0x80, 0x37, 0x72, 0xf4, 0x79, 0x12, 0xe3, 0xf9, 0xa3, 0x17, 0xa2, 0x94, 0x72, 0x8b, 0x39, 0xa0, 0xbb, 0xe0, 0xfd, 0xb2, 0x76, 0xfe, 0xa5, 0xb0, 0x97, 0xe3, 0x3f, 0xc, 0x68, 0xd1, 0x5c, 0x58, 0xfa, 0xb0, 0xc7, 0x4, 0xc6, 0x95, 0xb, 0x14, 0x1e, 0x95, 0x6c, 0x6f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x4e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0x5f, 0xd6, 0x94, 0x4d, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x68, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x1a, 0x96, 0x95, 0x6b, 0xe2, 0xd5, 0x49, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x19, 0xec, 0x6e, 0xb5, 0x88, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x65, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xce, 0xdd, 0xe, 0x80, 0x20, 0x8, 0x5, 0x60, 0x54, 0xb4, 0x22, 0xb5, 0x34, 0x7f, 0x7a, 0xff, 0x27, 0x8d, 0xad, 0xd6, 0x6a, 0x5c, 0xf8, 0xdd, 0xc1, 0x6, 0xe7, 0x0, 0x8c, 0xa9, 0x1f, 0x9e, 0xb5, 0x41, 0xeb, 0x26, 0xe6, 0x2c, 0x1a, 0xad, 0x40, 0xcf, 0xb, 0xad, 0xf9, 0x60, 0x79, 0xa5, 0x65, 0xd6, 0x60, 0x7c, 0x28, 0xb5, 0x75, 0xd6, 0x6a, 0x9, 0xde, 0x0, 0x52, 0xe9, 0xe7, 0xa3, 0x17, 0x42, 0xb0, 0xb1, 0x9e, 0xaf, 0x1a, 0xad, 0x5c, 0x88, 0x93, 0x6d, 0xff, 0x3e, 0xdd, 0x37, 0x8e, 0x4d, 0x14, 0xef, 0xd8, 0x48, 0x89, 0x63, 0x45, 0x31, 0x51, 0x7d, 0xe8, 0x2, 0xf5, 0xf, 0x9, 0x67, 0xd9, 0x88, 0x8f, 0x5b, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xfd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x92, 0x31, 0x4e, 0xc3, 0x30, 0x18, 0x46, 0x9f, 0x7f, 0xc9, 0xde, 0x60, 0x83, 0xb, 0x50, 0xc8, 0x10, 0x45, 0x96, 0x72, 0x8d, 0x76, 0x84, 0x1e, 0x20, 0x7b, 0xb9, 0x4c, 0x66, 0xe, 0x80, 0x54, 0xb1, 0xb4, 0x5c, 0x23, 0x52, 0x32, 0x56, 0xf4, 0x2, 0x85, 0x85, 0x76, 0x8c, 0x94, 0x9f, 0x25, 0x89, 0xa2, 0x94, 0x56, 0xb5, 0xe0, 0x1b, 0x3f, 0xe9, 0xbd, 0xcf, 0xb6, 0xc, 0x7f, 0x8c, 0x19, 0x17, 0x65, 0x59, 0xde, 0x8a, 0xc8, 0x33, 0x30, 0x5, 0xee, 0x1, 0x54, 0x75, 0x3, 0xbc, 0xab, 0x6a, 0xee, 0xbd, 0xdf, 0x9d, 0x14, 0x54, 0x55, 0xf5, 0x64, 0x8c, 0x79, 0x1, 0xae, 0x4e, 0xc, 0x1e, 0x44, 0x24, 0x8b, 0xe3, 0x78, 0x79, 0x24, 0x68, 0xe1, 0xd7, 0xdf, 0x4e, 0x35, 0x8a, 0x8a, 0xc8, 0xbc, 0x93, 0x98, 0xc1, 0xb1, 0x3f, 0xce, 0x2c, 0x8f, 0xb3, 0xaf, 0xeb, 0x7a, 0x92, 0xa6, 0xe9, 0xa7, 0x0, 0xb4, 0x77, 0xbe, 0x14, 0x6, 0xb8, 0x76, 0xce, 0x2d, 0x0, 0xa4, 0x2d, 0x66, 0x1, 0x30, 0x0, 0x4d, 0xd3, 0xcc, 0x86, 0x82, 0xbb, 0x50, 0x81, 0x31, 0x66, 0x32, 0x14, 0x68, 0xa8, 0xa0, 0x63, 0x3a, 0xc1, 0x36, 0x98, 0x56, 0xdd, 0xf6, 0x2, 0x55, 0x5d, 0x87, 0xa, 0x44, 0x64, 0x35, 0x14, 0xe4, 0xc0, 0x21, 0x80, 0xff, 0xb6, 0xd6, 0xe6, 0xbd, 0xc0, 0x7b, 0xbf, 0x13, 0x91, 0x8c, 0xcb, 0xde, 0x42, 0x81, 0x2c, 0x8a, 0xa2, 0xaf, 0x5e, 0x0, 0x10, 0xc7, 0xf1, 0x52, 0x44, 0xe6, 0xc0, 0xfe, 0xdc, 0x32, 0xf0, 0x98, 0x24, 0xc9, 0x5b, 0x57, 0x1c, 0x7d, 0xdb, 0xa2, 0x28, 0x6e, 0x9c, 0x73, 0xb, 0x55, 0x9d, 0x2, 0xf, 0x6d, 0xbd, 0x31, 0xc6, 0xac, 0xad, 0xb5, 0x79, 0xb7, 0xfc, 0x6f, 0xf9, 0x1, 0x3c, 0x90, 0x4c, 0xcc, 0x74, 0x25, 0x3a, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x85, 0xd1, 0x3f, 0x4b, 0xc3, 0x40, 0x18, 0xc7, 0xf1, 0xef, 0x25, 0xad, 0x89, 0xa9, 0x70, 0x83, 0x43, 0x5d, 0xc4, 0x21, 0x6e, 0x4a, 0x7, 0x47, 0xdf, 0x83, 0x53, 0x16, 0x17, 0xd7, 0x4e, 0xbe, 0x2, 0x5f, 0x85, 0x83, 0xa0, 0xb8, 0x38, 0xb8, 0x88, 0xd0, 0x51, 0x5d, 0x1c, 0x1c, 0x1c, 0x1c, 0x2a, 0xa2, 0xe8, 0x22, 0x2d, 0x82, 0x2d, 0x88, 0x54, 0xed, 0x3f, 0x1b, 0x9a, 0x78, 0x49, 0x1c, 0x9a, 0x54, 0x4f, 0x5, 0x6f, 0x3a, 0xee, 0xf9, 0xf0, 0x3c, 0x3f, 0x9e, 0x83, 0x7f, 0x8e, 0x18, 0xdf, 0x4c, 0x1c, 0x24, 0x5, 0x60, 0x40, 0x17, 0x9f, 0x48, 0x7, 0x26, 0xd3, 0xe5, 0x55, 0xd7, 0x93, 0x25, 0xe8, 0xde, 0xd4, 0x2b, 0xbb, 0x7, 0xbc, 0x8e, 0x88, 0x99, 0x82, 0xa9, 0xf2, 0xda, 0xe2, 0x86, 0x58, 0x78, 0xb7, 0x87, 0xf6, 0xc4, 0xdc, 0xcc, 0xd2, 0x6c, 0xfb, 0xf2, 0x8e, 0x10, 0xc0, 0x48, 0x81, 0x74, 0x3d, 0x55, 0xf4, 0x51, 0x28, 0x7c, 0x54, 0xd1, 0xf5, 0x90, 0xa3, 0x42, 0x6, 0xa, 0xb2, 0x14, 0x90, 0x0, 0x90, 0x10, 0x20, 0x4b, 0x14, 0x74, 0x20, 0x62, 0xf1, 0x3d, 0x7b, 0x24, 0xb2, 0x74, 0x19, 0x8, 0x83, 0x96, 0x39, 0x2e, 0xb, 0x82, 0x37, 0x94, 0xe, 0x6, 0xbd, 0xdb, 0xfc, 0x18, 0xe4, 0x49, 0x9e, 0xf0, 0x75, 0xd0, 0xbf, 0x3e, 0xb6, 0x22, 0x23, 0x7d, 0x9a, 0x4c, 0xce, 0xf6, 0xe8, 0xe9, 0x20, 0xb8, 0xaa, 0x6, 0xcd, 0x1c, 0x0, 0x39, 0x3e, 0x1e, 0x4f, 0xce, 0x7f, 0x76, 0x88, 0x1f, 0x1a, 0xcf, 0xa7, 0xe, 0x6, 0x6, 0xe, 0x8d, 0x23, 0xd5, 0x22, 0xd6, 0x41, 0x42, 0x77, 0x6b, 0x33, 0xaa, 0x59, 0x58, 0xc4, 0xf5, 0x9d, 0xed, 0x6c, 0xc0, 0xd7, 0x26, 0x21, 0xe, 0x7, 0x9d, 0xda, 0xf2, 0x8a, 0x1d, 0x1f, 0xae, 0xdf, 0x57, 0x19, 0xfe, 0x6, 0xa0, 0x9a, 0x2f, 0xf3, 0xed, 0xfe, 0xc5, 0x7e, 0x85, 0xce, 0x5f, 0xbf, 0x39, 0xca, 0x67, 0x21, 0x18, 0x66, 0x3b, 0x0, 0xf8, 0x4, 0x7e, 0x5c, 0x62, 0x33, 0x51, 0xf0, 0xbb, 0xff, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf1, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x92, 0x31, 0x4e, 0x2, 0x61, 0x10, 0x85, 0xbf, 0x37, 0xc6, 0x52, 0x3b, 0xbd, 0x0, 0xe8, 0x65, 0xa0, 0x54, 0xe, 0x40, 0xaf, 0x15, 0x64, 0xa3, 0x85, 0xf9, 0x2b, 0x4d, 0xa4, 0xdc, 0xda, 0x3, 0x98, 0x10, 0x1b, 0xf1, 0x32, 0x44, 0x2e, 0x0, 0x34, 0x42, 0xa9, 0x61, 0x2c, 0xfe, 0xdd, 0x65, 0xb3, 0xa, 0xba, 0xe8, 0xeb, 0x66, 0x92, 0xf7, 0xbd, 0x37, 0xc9, 0xc0, 0x1f, 0xa5, 0xea, 0x22, 0xf8, 0xe0, 0x78, 0xc5, 0xea, 0x12, 0xd4, 0x2, 0x4e, 0xe2, 0xd6, 0xc7, 0x42, 0x2f, 0x42, 0x69, 0x50, 0x7f, 0xba, 0x11, 0x70, 0xe3, 0xf7, 0xe7, 0xc0, 0x3, 0x70, 0xb0, 0x21, 0x70, 0x69, 0x78, 0x37, 0x28, 0x19, 0x7e, 0x1, 0x64, 0xe6, 0xc7, 0xef, 0x5a, 0x55, 0xe4, 0x86, 0x77, 0x72, 0x88, 0xd6, 0xb5, 0xfd, 0x75, 0x4b, 0x72, 0x55, 0x8b, 0x77, 0x3e, 0x9a, 0x77, 0xba, 0x9e, 0x19, 0x40, 0xbc, 0xf9, 0xd7, 0x66, 0x80, 0xc3, 0x7d, 0xf6, 0x2e, 0x0, 0x2c, 0xce, 0xd6, 0xae, 0x61, 0xce, 0xd5, 0x2e, 0x1, 0x68, 0xd4, 0xf7, 0xab, 0x59, 0x2, 0xb8, 0xef, 0xd0, 0xc0, 0xcb, 0xd, 0x26, 0x3b, 0xf8, 0x27, 0x5, 0x40, 0x30, 0xaa, 0x6b, 0x17, 0x7a, 0x2e, 0x1, 0x94, 0x2, 0xcb, 0x1a, 0xfe, 0x37, 0x61, 0x69, 0x1, 0x8, 0xea, 0x4f, 0xd, 0xef, 0x92, 0xdd, 0xf5, 0x83, 0x3c, 0x7e, 0x63, 0x6f, 0x5e, 0x0, 0x22, 0x24, 0x19, 0x1a, 0xde, 0x1, 0x16, 0xdb, 0x92, 0xd, 0x3f, 0xb, 0x4a, 0x9e, 0xd6, 0xa7, 0x54, 0x74, 0xe5, 0xb7, 0x47, 0xf1, 0x49, 0xd4, 0x2, 0x9d, 0x66, 0xa1, 0x63, 0xc1, 0x48, 0x58, 0x9a, 0x27, 0xff, 0x9b, 0x3e, 0x1, 0x5e, 0x62, 0x48, 0x81, 0x2e, 0xbf, 0x88, 0xea, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc6, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x48, 0x83, 0x83, 0x60, 0xaf, 0xb1, 0x65, 0xbb, 0xca, 0x61, 0xb3, 0xc2, 0x0, 0x0, 0x0, 0x63, 0xb7, 0xc8, 0x63, 0xb7, 0xc7, 0x0, 0x0, 0x0, 0x61, 0xb3, 0xbc, 0x60, 0xb1, 0xbc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x5b, 0xa6, 0xa5, 0x63, 0xb4, 0xb6, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3a, 0x69, 0x69, 0x5e, 0xb1, 0xcd, 0x5e, 0xb0, 0xcd, 0x36, 0x63, 0x63, 0x0, 0x0, 0x0, 0x17, 0x2a, 0x29, 0x60, 0xb2, 0xbd, 0x62, 0xb3, 0xbf, 0x3, 0x5, 0x5, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0x9b, 0x9a, 0x52, 0x96, 0x95, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf, 0xf, 0x62, 0xb4, 0xbd, 0x63, 0xb7, 0xbf, 0x0, 0x0, 0x0, 0x27, 0x48, 0x47, 0x68, 0xc0, 0xcf, 0x68, 0xc1, 0xcf, 0x2d, 0x52, 0x52, 0x51, 0x93, 0x92, 0x56, 0x9d, 0x9c, 0x0, 0x0, 0x0, 0x54, 0xa2, 0xc8, 0x4c, 0x94, 0xc2, 0x48, 0x8e, 0xc0, 0x47, 0x8c, 0xbf, 0x4b, 0x93, 0xc2, 0x4b, 0x92, 0xc2, 0x4f, 0x98, 0xc4, 0x4d, 0x96, 0xc3, 0x55, 0xa3, 0xc8, 0x53, 0x9f, 0xc7, 0x49, 0x8f, 0xc0, 0x4e, 0x97, 0xc4, 0x5a, 0xab, 0xcb, 0x5a, 0xac, 0xcc, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0xff, 0xff, 0xff, 0x6b, 0x1e, 0xb5, 0x61, 0x0, 0x0, 0x0, 0x31, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x3, 0xd, 0x1c, 0x27, 0x16, 0x6e, 0xc1, 0xef, 0xe8, 0x28, 0xf0, 0xf0, 0x22, 0xdb, 0xde, 0x24, 0x17, 0xaf, 0xc5, 0x1a, 0xa, 0x65, 0xfc, 0xfe, 0x64, 0xc, 0x31, 0xe0, 0xe0, 0x28, 0x2, 0x1, 0x14, 0x9c, 0x95, 0x13, 0x5, 0x2c, 0xdb, 0xdc, 0xb, 0x4f, 0xf4, 0xf7, 0x55, 0x73, 0x7d, 0x4, 0x28, 0xf1, 0xfd, 0xa1, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x41, 0x89, 0xde, 0x6c, 0x4e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0xcf, 0xd7, 0x12, 0x82, 0x30, 0x10, 0x5, 0x50, 0x48, 0x42, 0x12, 0xb0, 0x77, 0x8d, 0xd, 0xb, 0x28, 0x56, 0x12, 0x62, 0xd, 0x96, 0xff, 0xff, 0x2a, 0x61, 0xc, 0xe0, 0x83, 0xfb, 0xb4, 0xf7, 0xcc, 0xec, 0xcc, 0x5d, 0xc3, 0xf8, 0x37, 0x26, 0x80, 0x8, 0x41, 0x60, 0xe6, 0xd9, 0xc2, 0x84, 0x52, 0x82, 0xad, 0x4c, 0x0, 0xb6, 0xb9, 0x10, 0xdc, 0xc6, 0x40, 0x3, 0x24, 0x3c, 0x92, 0x32, 0xe2, 0x4, 0x6a, 0x40, 0x54, 0xc8, 0x64, 0x4, 0x45, 0x1a, 0x9c, 0xd2, 0x29, 0x85, 0x73, 0xd9, 0xd1, 0x50, 0xa9, 0x5e, 0x52, 0xb8, 0xd6, 0xea, 0x1a, 0x1a, 0xcd, 0x5b, 0xa, 0xf7, 0x56, 0x5b, 0x43, 0xa7, 0xdb, 0x53, 0x52, 0xaa, 0xfe, 0x80, 0x65, 0x3d, 0x86, 0xa3, 0x58, 0xca, 0x78, 0x3c, 0x99, 0x6a, 0x70, 0x67, 0xf3, 0x87, 0x52, 0xcf, 0xc5, 0x32, 0xaf, 0xee, 0xf9, 0xab, 0xd7, 0x7b, 0xed, 0x7b, 0xc5, 0x33, 0xc1, 0x66, 0xbb, 0xdb, 0xb3, 0x22, 0x27, 0x47, 0x87, 0xa3, 0xe5, 0xfe, 0xfe, 0x1b, 0x6, 0x2c, 0xfc, 0x6e, 0x1f, 0x93, 0x2a, 0x10, 0x62, 0x3, 0x21, 0x32, 0x75, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hslider_tick_png[] = {
@@ -151,11 +147,11 @@ static const unsigned char hslider_tick_png[] = {
};
static const unsigned char hsplit_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x15, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x63, 0x64, 0x60, 0x60, 0x30, 0x62, 0xc0, 0x3, 0x98, 0xf0, 0x49, 0xe, 0x1f, 0x5, 0x0, 0x3c, 0x10, 0x0, 0x42, 0xb5, 0xb3, 0xc, 0x3f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char hsplitter_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x40, 0x8, 0x6, 0x0, 0x0, 0x0, 0x27, 0x4, 0x36, 0x8a, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x39, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0x63, 0x60, 0x20, 0x5, 0xfc, 0xff, 0xff, 0xdf, 0xe7, 0xff, 0xff, 0xff, 0x3e, 0xc8, 0x62, 0x2c, 0x68, 0x6a, 0x24, 0xd0, 0x35, 0x31, 0x11, 0x32, 0x75, 0x54, 0xc1, 0xa8, 0x82, 0x51, 0x5, 0xa3, 0xa, 0x46, 0x15, 0x8c, 0x2a, 0x18, 0x55, 0x40, 0x4f, 0x5, 0xe8, 0x75, 0xf7, 0xb, 0x42, 0x1a, 0x30, 0x0, 0x0, 0xf0, 0x37, 0x8, 0x11, 0x77, 0x42, 0x12, 0x8a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x40, 0x8, 0x0, 0x0, 0x0, 0x0, 0x2, 0x6f, 0x69, 0x56, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x27, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x80, 0x2, 0x66, 0x86, 0x5, 0xa2, 0xe7, 0x18, 0x16, 0x88, 0x9e, 0x63, 0x66, 0x10, 0xbd, 0xf6, 0x98, 0x41, 0xf4, 0xda, 0x63, 0x6, 0xc, 0x30, 0xaa, 0x66, 0x54, 0xd, 0x9a, 0x1a, 0x0, 0x5c, 0x29, 0x6a, 0x81, 0x90, 0x8f, 0x52, 0x12, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_add_png[] = {
@@ -163,7 +159,7 @@ static const unsigned char icon_add_png[] = {
};
static const unsigned char icon_close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xbe, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xd5, 0x90, 0x3b, 0xe, 0xc2, 0x40, 0xc, 0x44, 0x9f, 0x9, 0x45, 0xf8, 0x14, 0x80, 0xb8, 0xf, 0x15, 0x8a, 0x8, 0x48, 0xdc, 0x94, 0x8a, 0x4, 0x85, 0x9a, 0xe3, 0x20, 0x48, 0xc3, 0xa7, 0x20, 0x32, 0x8d, 0x41, 0x8b, 0xc9, 0x4a, 0xb4, 0xb8, 0xda, 0x1d, 0x7b, 0x9e, 0x35, 0x86, 0xbf, 0x2f, 0x9, 0x3f, 0xaa, 0xba, 0x2, 0xba, 0x40, 0x25, 0x22, 0x37, 0xd7, 0xeb, 0x1, 0x19, 0xf0, 0x10, 0x91, 0xed, 0x4b, 0xef, 0x38, 0x60, 0x2, 0x4c, 0x81, 0xdc, 0xc, 0xa1, 0x39, 0xb7, 0x5e, 0x12, 0x1a, 0x3c, 0xa0, 0x2, 0x4e, 0xc0, 0x18, 0x58, 0xaa, 0x6a, 0x5f, 0x55, 0x53, 0x60, 0x61, 0x5a, 0xd, 0xec, 0xa3, 0x11, 0x6c, 0x5b, 0x6a, 0xdb, 0x26, 0xc0, 0xc5, 0xe4, 0x81, 0x99, 0xb, 0x1f, 0xed, 0xb, 0x10, 0x40, 0xd6, 0xc0, 0xcc, 0x66, 0xe, 0xc0, 0xc6, 0x9b, 0xdb, 0x22, 0xc4, 0x4a, 0x63, 0xcb, 0x7e, 0x89, 0xa0, 0xc0, 0xd0, 0x22, 0x94, 0x22, 0x72, 0x8d, 0x2, 0x9c, 0xb9, 0x6, 0xa, 0x3, 0x84, 0xda, 0x7, 0xc4, 0x47, 0xc8, 0x6c, 0xf0, 0x8c, 0x1d, 0x4c, 0x44, 0xee, 0xc0, 0xce, 0xb4, 0x11, 0x30, 0xf, 0xd, 0x1e, 0xd0, 0x0, 0x47, 0xdb, 0xf2, 0x3e, 0x98, 0xbd, 0x4b, 0xeb, 0x35, 0x6d, 0xb7, 0xf8, 0xe3, 0x7a, 0x2, 0x49, 0x7e, 0x47, 0x10, 0xc3, 0xf7, 0xae, 0x75, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0xe, 0xc2, 0x30, 0x10, 0x4, 0x17, 0xaa, 0x3d, 0x67, 0xdb, 0x58, 0xd0, 0xd3, 0xf0, 0xa3, 0x7c, 0x36, 0x3c, 0x82, 0x48, 0x44, 0x22, 0x6f, 0xb1, 0x4d, 0x85, 0x14, 0x81, 0xf, 0x2c, 0x28, 0xe0, 0xda, 0xd5, 0x8c, 0x4e, 0x77, 0xb, 0xfc, 0xd5, 0x98, 0xd9, 0x20, 0x29, 0x7a, 0xb9, 0xa4, 0x68, 0x66, 0x83, 0xb, 0x93, 0xcc, 0x24, 0xa7, 0x9a, 0x44, 0x52, 0x24, 0x39, 0x91, 0xcc, 0x55, 0x89, 0xa4, 0xde, 0xcc, 0xce, 0x24, 0xb, 0xc9, 0x39, 0x84, 0xb0, 0xf7, 0xb2, 0xae, 0xeb, 0x76, 0xde, 0x8a, 0x4f, 0x92, 0x66, 0xd8, 0x91, 0x5c, 0x49, 0x5e, 0x9a, 0xe1, 0xb5, 0x64, 0x5, 0x16, 0x92, 0x8b, 0x7, 0x6f, 0x9b, 0x8c, 0x0, 0x4a, 0x29, 0x9b, 0x26, 0x81, 0xa4, 0x3e, 0xa5, 0x34, 0x2, 0x38, 0x2, 0x58, 0x0, 0xcc, 0x0, 0xe, 0x39, 0xe7, 0xd3, 0xfa, 0xb0, 0xee, 0xea, 0x8f, 0x7, 0x7b, 0xf5, 0x9d, 0xb7, 0xb0, 0x97, 0x55, 0x25, 0x5f, 0x17, 0xe9, 0x2e, 0xf9, 0xb8, 0xca, 0x3f, 0x9b, 0x1b, 0x1a, 0xe3, 0x40, 0x47, 0xa0, 0xda, 0xda, 0x61, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char icon_color_pick_png[] = {
@@ -203,19 +199,15 @@ static const unsigned char icon_zoom_reset_png[] = {
};
static const unsigned char line_edit_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x4d, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x8f, 0xcd, 0x4a, 0x2, 0x61, 0x14, 0x86, 0xdf, 0x73, 0xbe, 0x51, 0x90, 0x71, 0x12, 0x4, 0x2b, 0x15, 0x61, 0xc, 0x9b, 0xd0, 0x74, 0xe1, 0x26, 0x97, 0xd6, 0xc2, 0x4d, 0x44, 0xd7, 0xe0, 0x2e, 0xda, 0x77, 0x1f, 0x5d, 0x42, 0xde, 0x40, 0xab, 0x68, 0x55, 0x11, 0xd2, 0xaa, 0x56, 0x81, 0xb6, 0x69, 0x35, 0xd0, 0x1f, 0x2a, 0xb8, 0x49, 0x1d, 0xc1, 0x71, 0x4e, 0xb, 0x43, 0x24, 0xa6, 0x14, 0xdc, 0xf5, 0xc2, 0x81, 0x6f, 0x71, 0xde, 0xe7, 0x7b, 0xe, 0xb0, 0x64, 0x68, 0xf6, 0x5d, 0x28, 0x95, 0xab, 0x10, 0xae, 0x8, 0x49, 0xcc, 0x77, 0x59, 0xa8, 0x3, 0xf2, 0xae, 0x1a, 0xf7, 0xf5, 0x1a, 0x0, 0x99, 0x5, 0x70, 0x7e, 0x67, 0xef, 0x2, 0x90, 0x7d, 0x22, 0x72, 0x41, 0xa4, 0xf9, 0x7e, 0x27, 0xe2, 0x8a, 0x88, 0x6, 0xd0, 0x65, 0xf3, 0xe1, 0xf6, 0x10, 0x80, 0xa7, 0x0, 0xa0, 0x50, 0x2a, 0x57, 0x1, 0x9c, 0x30, 0x6b, 0x50, 0x9a, 0xc6, 0xcc, 0xc, 0xff, 0x51, 0xc, 0x22, 0x88, 0x78, 0xd6, 0x5a, 0xc2, 0xb4, 0xdb, 0xef, 0xf6, 0x23, 0x4f, 0xc8, 0x5c, 0x21, 0x22, 0x97, 0x15, 0xcf, 0xbd, 0x99, 0x99, 0x41, 0x44, 0x63, 0x8f, 0xa4, 0x2, 0x0, 0x3c, 0x31, 0x93, 0x38, 0xf0, 0x8b, 0xb6, 0x6f, 0x48, 0x91, 0x50, 0x62, 0xa, 0x58, 0x26, 0xff, 0x5, 0x60, 0xe5, 0x8b, 0x49, 0x33, 0x93, 0x5b, 0xb8, 0x64, 0x66, 0x72, 0xb0, 0xf2, 0xc5, 0x24, 0x0, 0x68, 0x0, 0x10, 0x8d, 0xad, 0x7, 0x43, 0xba, 0x21, 0x2f, 0xf6, 0x33, 0xfd, 0x5d, 0xfd, 0x6, 0x6c, 0x65, 0x65, 0xd8, 0xfb, 0xc, 0x4c, 0xd, 0x9c, 0xfe, 0xe0, 0x46, 0xf, 0x1b, 0x94, 0x4a, 0x5b, 0x73, 0xcb, 0xa9, 0xf4, 0x26, 0x74, 0x7d, 0x85, 0x1c, 0xa7, 0x7f, 0x3d, 0x35, 0x78, 0x7b, 0xaa, 0x1f, 0xe9, 0x86, 0x71, 0xb0, 0x5d, 0x2c, 0xad, 0x9a, 0x56, 0x56, 0x9c, 0x5e, 0xdf, 0xd7, 0x24, 0x14, 0xe, 0x8b, 0xae, 0x1b, 0xd4, 0xed, 0xb4, 0x5b, 0xaf, 0x8d, 0xbb, 0x63, 0x0, 0x50, 0x0, 0x60, 0xdb, 0xb6, 0xb7, 0x11, 0x8f, 0x9c, 0x3a, 0x23, 0x4e, 0x42, 0x24, 0xaa, 0x5, 0x82, 0x1e, 0x2b, 0xe5, 0xfc, 0x9c, 0xd1, 0x70, 0xd0, 0xee, 0xb6, 0x3e, 0xce, 0xcf, 0x22, 0xee, 0xae, 0x5d, 0xab, 0x8d, 0x17, 0x39, 0x77, 0x6e, 0xbe, 0x0, 0xac, 0x8, 0x6b, 0x3c, 0x2d, 0x57, 0x1a, 0xdf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
-};
-
-static const unsigned char line_edit_active_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x50, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x93, 0x4d, 0x4b, 0x2, 0x51, 0x14, 0x86, 0xdf, 0x73, 0x66, 0xc, 0x1d, 0x87, 0xa0, 0xa8, 0x4c, 0x27, 0x19, 0x49, 0xc, 0x84, 0x24, 0xda, 0xe4, 0x52, 0x22, 0xdc, 0x44, 0x44, 0x2d, 0x86, 0x5a, 0xba, 0xb1, 0x68, 0xef, 0xf, 0xf0, 0x6f, 0xb4, 0xab, 0x6d, 0x9b, 0x16, 0xe1, 0xaa, 0x24, 0x5a, 0x16, 0xf4, 0x69, 0x3f, 0xc0, 0x82, 0xd2, 0x8a, 0x8, 0x2, 0x47, 0xa1, 0x69, 0x4e, 0xb, 0x41, 0x5c, 0x4c, 0x29, 0xb8, 0xeb, 0x81, 0xb, 0x77, 0x71, 0xde, 0xe7, 0xbe, 0x67, 0x71, 0x81, 0x1, 0xa1, 0xee, 0x7b, 0x2a, 0x9d, 0xc9, 0x41, 0x38, 0x2b, 0x24, 0xe3, 0x9e, 0xc3, 0x42, 0x6f, 0x20, 0xf7, 0xb8, 0x72, 0x7e, 0xb6, 0x7, 0x40, 0xba, 0x5, 0x3c, 0xbb, 0xb0, 0x78, 0x4, 0xc8, 0x32, 0x11, 0x39, 0x20, 0x52, 0x3d, 0x9f, 0x13, 0x71, 0x44, 0x44, 0x5, 0xa8, 0x74, 0x7f, 0x71, 0xba, 0xa, 0xc0, 0x55, 0x0, 0x20, 0x95, 0xce, 0xe4, 0x0, 0x14, 0x98, 0x55, 0x28, 0xaa, 0xca, 0xcc, 0xc, 0xef, 0xa3, 0x30, 0x88, 0x20, 0xe2, 0xce, 0x84, 0x22, 0xb1, 0xea, 0xeb, 0x73, 0xf5, 0x86, 0xdb, 0x66, 0xce, 0x12, 0x91, 0xc3, 0xa, 0xf7, 0xdc, 0x99, 0x99, 0x41, 0x44, 0xdf, 0x2e, 0x49, 0x16, 0x0, 0xb8, 0xdd, 0x4c, 0xc2, 0xc0, 0x2f, 0xb5, 0x3d, 0x21, 0x85, 0x84, 0x22, 0x1d, 0xc1, 0x20, 0xfc, 0x17, 0x41, 0x32, 0x9f, 0x30, 0xe2, 0x96, 0xd9, 0x77, 0x28, 0x6e, 0x99, 0x48, 0xe6, 0x13, 0x6, 0x0, 0xa8, 0x0, 0x30, 0x36, 0x3f, 0x32, 0x14, 0x8, 0x69, 0x52, 0x3d, 0x7c, 0xa2, 0xbf, 0xa3, 0x6d, 0xa6, 0x37, 0x4c, 0x69, 0xd6, 0x6c, 0x5f, 0xa7, 0x41, 0xa3, 0xde, 0x2a, 0xeb, 0x51, 0x8d, 0xcc, 0x35, 0xa3, 0x67, 0x38, 0xb6, 0x6e, 0x40, 0x9f, 0xd2, 0xc8, 0xae, 0x37, 0x4f, 0x3a, 0xd, 0x1e, 0x2f, 0xef, 0xb6, 0xf5, 0x68, 0x70, 0x65, 0xae, 0x90, 0x9c, 0x88, 0x6f, 0x9a, 0x62, 0xd7, 0x9a, 0x9e, 0x4d, 0xb4, 0x88, 0x26, 0xba, 0x11, 0xa0, 0xf7, 0xdb, 0x8f, 0x97, 0x87, 0xab, 0xca, 0xe, 0xd0, 0xf5, 0x99, 0xac, 0x3, 0x4b, 0x9, 0xfa, 0xc3, 0xbb, 0x81, 0x49, 0xff, 0x92, 0x1a, 0xf4, 0xd, 0x7b, 0x9, 0x9c, 0xc6, 0xd7, 0xa7, 0x5d, 0x6b, 0x95, 0xf7, 0xaf, 0x47, 0xb7, 0x50, 0x2c, 0xba, 0xfd, 0xac, 0xdb, 0x93, 0x1f, 0xc, 0x91, 0x5f, 0xe7, 0xb9, 0x80, 0x59, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char line_edit_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x3a, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x93, 0x31, 0x4b, 0x3, 0x41, 0x10, 0x85, 0xdf, 0xcc, 0xec, 0x6d, 0x8c, 0x26, 0x7a, 0x20, 0x51, 0x4c, 0x1a, 0x2b, 0x2b, 0xd3, 0x9a, 0x32, 0x88, 0xa4, 0x11, 0xb1, 0xbb, 0x3e, 0x95, 0x62, 0xef, 0x9f, 0xb1, 0xb3, 0xb4, 0x17, 0x41, 0xd0, 0x20, 0x16, 0x16, 0x5a, 0x9, 0xfa, 0x3, 0x52, 0x25, 0xa8, 0x9d, 0xa6, 0xb8, 0xdc, 0xed, 0xed, 0x58, 0x44, 0x42, 0x8a, 0xd3, 0x4, 0xd2, 0xf9, 0xc1, 0xc0, 0x14, 0xfb, 0xde, 0xbc, 0x57, 0x2c, 0x30, 0x27, 0x34, 0xb9, 0xd7, 0x1b, 0xcd, 0x36, 0x94, 0x5b, 0x4a, 0x5a, 0xc9, 0x7d, 0xac, 0xf4, 0x1, 0xf2, 0x37, 0x2f, 0x8f, 0xf7, 0xe7, 0x0, 0x74, 0xd2, 0x80, 0xb7, 0x77, 0x76, 0x2f, 0x1, 0xdd, 0x27, 0x22, 0x7, 0x22, 0x93, 0x7b, 0x4e, 0xd5, 0xa9, 0xaa, 0x1, 0xe8, 0xea, 0xf5, 0xe9, 0xee, 0x10, 0x80, 0x17, 0x0, 0xa8, 0x37, 0x9a, 0x6d, 0x0, 0xa7, 0xcc, 0x6, 0x62, 0xc, 0x33, 0x33, 0xf2, 0x47, 0x18, 0x44, 0x50, 0xf5, 0x5b, 0xeb, 0xd5, 0xcd, 0xee, 0x7b, 0xaf, 0xfb, 0xcc, 0x23, 0x67, 0x6e, 0x11, 0x91, 0x63, 0xe1, 0xa9, 0x9d, 0x99, 0x19, 0x44, 0x94, 0x79, 0xd2, 0x16, 0x0, 0xf0, 0x28, 0x99, 0x6e, 0x0, 0xbf, 0xc4, 0xce, 0x85, 0x84, 0x94, 0xaa, 0x63, 0x83, 0x79, 0xf8, 0x7, 0x6, 0x6, 0x0, 0x96, 0xc2, 0xd5, 0x9a, 0x7a, 0x45, 0x12, 0xf, 0x66, 0x12, 0x15, 0x4b, 0x21, 0x88, 0xa9, 0x36, 0x36, 0x8, 0xa, 0x8b, 0x56, 0x24, 0xd0, 0x24, 0x1e, 0xd0, 0xdf, 0xd2, 0x11, 0xb, 0xe5, 0x50, 0x35, 0x4d, 0x3, 0xe0, 0xa7, 0x42, 0x96, 0xba, 0x8e, 0x4, 0x96, 0x6c, 0xb1, 0x3c, 0x55, 0x5c, 0x28, 0x96, 0x61, 0x8c, 0x25, 0x9f, 0xb9, 0xdb, 0x71, 0x82, 0xc2, 0xb0, 0x7f, 0x9c, 0x58, 0x7b, 0x50, 0xa, 0x2b, 0x6b, 0xae, 0xb4, 0xa2, 0x3e, 0x73, 0xb9, 0x49, 0x44, 0x8c, 0x8a, 0xb1, 0x94, 0xc, 0xe3, 0xb7, 0x20, 0xee, 0x9f, 0x0, 0x13, 0x9f, 0x29, 0x8a, 0x22, 0xe9, 0x7d, 0x5, 0x67, 0x2c, 0xb2, 0x7, 0x23, 0xcb, 0xb9, 0xe7, 0x5d, 0xf6, 0xe9, 0xb3, 0xb4, 0xf3, 0x70, 0x7d, 0x71, 0x4, 0xc0, 0xcf, 0x52, 0x77, 0x2a, 0xdf, 0x87, 0x72, 0x62, 0x0, 0x51, 0xb5, 0x8, 0xdb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x8, 0x4, 0x0, 0x0, 0x0, 0x27, 0x3b, 0x7, 0x36, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x95, 0xce, 0x31, 0x12, 0x2, 0x21, 0x10, 0x44, 0xd1, 0x3f, 0x40, 0xa1, 0x44, 0xa6, 0x46, 0xde, 0x63, 0x4f, 0xe5, 0x15, 0x38, 0xb2, 0xd6, 0x6, 0xb0, 0xc8, 0x30, 0x6, 0x96, 0xac, 0x56, 0x99, 0xf8, 0xb3, 0x7e, 0x51, 0xcb, 0xf9, 0x1a, 0xb3, 0x3f, 0xa, 0xaf, 0xc, 0xad, 0x2d, 0xcb, 0xe5, 0x76, 0x38, 0x5, 0x76, 0xec, 0x6c, 0xf7, 0xe0, 0x53, 0xe0, 0x13, 0xa1, 0x27, 0x27, 0x43, 0x26, 0x81, 0x20, 0xc8, 0x70, 0xfc, 0xe8, 0xf, 0x34, 0x67, 0xd8, 0x9c, 0x86, 0x61, 0x2e, 0x68, 0xe9, 0x91, 0xaf, 0x4b, 0x5a, 0x7d, 0x2a, 0x2c, 0x3, 0xed, 0xef, 0x1e, 0x6b, 0xcb, 0x4f, 0xa6, 0x66, 0x2b, 0x25, 0x6, 0x1, 0x37, 0x40, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
-static const unsigned char line_edit_selected_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x50, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xdd, 0x93, 0x4d, 0x4b, 0x2, 0x51, 0x14, 0x86, 0xdf, 0x73, 0x66, 0xc, 0x1d, 0x87, 0xa0, 0xa8, 0x4c, 0x27, 0x19, 0x49, 0xc, 0x84, 0x24, 0xda, 0xe4, 0x52, 0x22, 0xdc, 0x44, 0x44, 0x2d, 0x86, 0x5a, 0xba, 0xb1, 0x68, 0xef, 0xf, 0xf0, 0x6f, 0xb4, 0xab, 0x6d, 0x9b, 0x16, 0xe1, 0xaa, 0x24, 0x5a, 0x16, 0xf4, 0x69, 0x3f, 0xc0, 0x82, 0xd2, 0x8a, 0x8, 0x2, 0x47, 0xa1, 0x69, 0x4e, 0xb, 0x41, 0x5c, 0x4c, 0x29, 0xb8, 0xeb, 0x81, 0xb, 0x77, 0x71, 0xde, 0xe7, 0xbe, 0x67, 0x71, 0x81, 0x1, 0xa1, 0xee, 0x7b, 0x2a, 0x9d, 0xc9, 0x41, 0x38, 0x2b, 0x24, 0xe3, 0x9e, 0xc3, 0x42, 0x6f, 0x20, 0xf7, 0xb8, 0x72, 0x7e, 0xb6, 0x7, 0x40, 0xba, 0x5, 0x3c, 0xbb, 0xb0, 0x78, 0x4, 0xc8, 0x32, 0x11, 0x39, 0x20, 0x52, 0x3d, 0x9f, 0x13, 0x71, 0x44, 0x44, 0x5, 0xa8, 0x74, 0x7f, 0x71, 0xba, 0xa, 0xc0, 0x55, 0x0, 0x20, 0x95, 0xce, 0xe4, 0x0, 0x14, 0x98, 0x55, 0x28, 0xaa, 0xca, 0xcc, 0xc, 0xef, 0xa3, 0x30, 0x88, 0x20, 0xe2, 0xce, 0x84, 0x22, 0xb1, 0xea, 0xeb, 0x73, 0xf5, 0x86, 0xdb, 0x66, 0xce, 0x12, 0x91, 0xc3, 0xa, 0xf7, 0xdc, 0x99, 0x99, 0x41, 0x44, 0xdf, 0x2e, 0x49, 0x16, 0x0, 0xb8, 0xdd, 0x4c, 0xc2, 0xc0, 0x2f, 0xb5, 0x3d, 0x21, 0x85, 0x84, 0x22, 0x1d, 0xc1, 0x20, 0xfc, 0x17, 0x41, 0x32, 0x9f, 0x30, 0xe2, 0x96, 0xd9, 0x77, 0x28, 0x6e, 0x99, 0x48, 0xe6, 0x13, 0x6, 0x0, 0xa8, 0x0, 0x30, 0x36, 0x3f, 0x32, 0x14, 0x8, 0x69, 0x52, 0x3d, 0x7c, 0xa2, 0xbf, 0xa3, 0x6d, 0xa6, 0x37, 0x4c, 0x69, 0xd6, 0x6c, 0x5f, 0xa7, 0x41, 0xa3, 0xde, 0x2a, 0xeb, 0x51, 0x8d, 0xcc, 0x35, 0xa3, 0x67, 0x38, 0xb6, 0x6e, 0x40, 0x9f, 0xd2, 0xc8, 0xae, 0x37, 0x4f, 0x3a, 0xd, 0x1e, 0x2f, 0xef, 0xb6, 0xf5, 0x68, 0x70, 0x65, 0xae, 0x90, 0x9c, 0x88, 0x6f, 0x9a, 0x62, 0xd7, 0x9a, 0x9e, 0x4d, 0xb4, 0x88, 0x26, 0xba, 0x11, 0xa0, 0xf7, 0xdb, 0x8f, 0x97, 0x87, 0xab, 0xca, 0xe, 0xd0, 0xf5, 0x99, 0xac, 0x3, 0x4b, 0x9, 0xfa, 0xc3, 0xbb, 0x81, 0x49, 0xff, 0x92, 0x1a, 0xf4, 0xd, 0x7b, 0x9, 0x9c, 0xc6, 0xd7, 0xa7, 0x5d, 0x6b, 0x95, 0xf7, 0xaf, 0x47, 0xb7, 0x50, 0x2c, 0xba, 0xfd, 0xac, 0xdb, 0x93, 0x1f, 0xc, 0x91, 0x5f, 0xe7, 0xb9, 0x80, 0x59, 0xbb, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+static const unsigned char line_edit_focus_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xab, 0x50, 0x4c, 0x54, 0x45, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0x1b, 0x17, 0x18, 0xc8, 0x68, 0x12, 0xef, 0xed, 0xe7, 0xef, 0xed, 0xe8, 0xf0, 0xed, 0xe8, 0xf0, 0xee, 0xe8, 0xf0, 0xed, 0xe7, 0xed, 0xeb, 0xe5, 0xee, 0xeb, 0xe5, 0xee, 0xeb, 0xe6, 0xec, 0xe9, 0xe3, 0xeb, 0xe9, 0xe3, 0xeb, 0xe9, 0xe2, 0xec, 0xe9, 0xe2, 0xe9, 0xe6, 0xe0, 0xea, 0xe7, 0xe0, 0xea, 0xe7, 0xe1, 0xe8, 0xe4, 0xdd, 0xe8, 0xe5, 0xde, 0xe8, 0xe5, 0xdd, 0xe8, 0xe4, 0xde, 0xe6, 0xe2, 0xdb, 0xe6, 0xe3, 0xdb, 0xe6, 0xe3, 0xdc, 0xe7, 0xe2, 0xdb, 0xe7, 0xe3, 0xdb, 0xe4, 0xe0, 0xd8, 0xe5, 0xe0, 0xd8, 0xe5, 0xe1, 0xd9, 0xe5, 0xe0, 0xd9, 0xe4, 0xe1, 0xd9, 0xe5, 0xe1, 0xd8, 0xe4, 0xe0, 0xd9, 0xe2, 0xdf, 0xd6, 0xe3, 0xdf, 0xd6, 0xe3, 0xde, 0xd6, 0xe2, 0xde, 0xd6, 0xe1, 0xdc, 0xd4, 0xe1, 0xdc, 0xd3, 0xe0, 0xdc, 0xd3, 0xe1, 0xdd, 0xd3, 0xe1, 0xdd, 0xd4, 0xdf, 0xda, 0xd0, 0xdf, 0xda, 0xd1, 0xdf, 0xdb, 0xd1, 0xe0, 0xda, 0xd1, 0xdd, 0xd8, 0xcf, 0xdd, 0xd8, 0xce, 0xde, 0xd9, 0xce, 0xde, 0xd8, 0xce, 0xdd, 0xd9, 0xce, 0xdc, 0xd6, 0xcc, 0xdb, 0xd6, 0xcc, 0xdc, 0xd6, 0xcb, 0xff, 0xff, 0xff, 0x73, 0x72, 0x65, 0x6f, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x36, 0x61, 0xc5, 0x3a, 0xd, 0x83, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x38, 0xa0, 0x7, 0xa5, 0xd6, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x9e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xcf, 0xdb, 0x16, 0x82, 0x20, 0x10, 0x85, 0x61, 0xb4, 0xb4, 0x13, 0x1d, 0x28, 0x14, 0xcb, 0x4a, 0x33, 0xf, 0x59, 0x52, 0x98, 0x62, 0xef, 0xff, 0x66, 0xd1, 0xf6, 0xca, 0xfe, 0x19, 0xd6, 0x62, 0x7d, 0x77, 0x43, 0x88, 0x3d, 0x88, 0x10, 0x7b, 0x34, 0xc8, 0x36, 0x30, 0x76, 0x1c, 0x77, 0xe2, 0x3a, 0xee, 0xd4, 0x7c, 0x0, 0xb3, 0x79, 0x3f, 0xa6, 0x5, 0x80, 0xa2, 0x25, 0xa5, 0xab, 0x35, 0x5, 0x6c, 0x18, 0x63, 0x5b, 0xd6, 0x7, 0xd8, 0x71, 0xcf, 0xe3, 0x9c, 0xfb, 0x9c, 0x7b, 0x3e, 0x40, 0x4, 0xfb, 0xe0, 0x10, 0x84, 0xa1, 0x8, 0x85, 0x0, 0x1c, 0x4f, 0xe7, 0x28, 0xbe, 0x44, 0x71, 0x9c, 0x24, 0x67, 0xc0, 0x35, 0x4d, 0xb3, 0x2c, 0xcb, 0xcd, 0x4b, 0x73, 0x40, 0x71, 0x33, 0x15, 0xe5, 0xfd, 0x51, 0x16, 0x25, 0xa0, 0x92, 0xf2, 0xf9, 0x92, 0xbf, 0x2a, 0x9, 0x50, 0xaa, 0x56, 0xef, 0x46, 0xb5, 0x4d, 0x5b, 0x37, 0x0, 0xdd, 0x7d, 0xb4, 0x36, 0xdb, 0x69, 0xad, 0x1, 0x7f, 0xc7, 0x59, 0xc3, 0xf3, 0xad, 0x2f, 0x30, 0x4f, 0x11, 0x50, 0x3e, 0x12, 0x48, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char logo_png[] = {
@@ -223,31 +215,35 @@ static const unsigned char logo_png[] = {
};
static const unsigned char option_arrow_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x82, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xcd, 0x90, 0x31, 0xa, 0xc2, 0x50, 0x10, 0x44, 0xdf, 0x4f, 0x95, 0x46, 0xc8, 0xc7, 0xdc, 0x40, 0x1b, 0xbd, 0x9a, 0xc7, 0x89, 0xb1, 0xb0, 0x48, 0x44, 0xb0, 0xf0, 0x26, 0x5e, 0x42, 0xd0, 0x5e, 0xcf, 0xf0, 0x6c, 0xb6, 0xf8, 0x1, 0xd1, 0x36, 0x53, 0xce, 0xbe, 0x59, 0x86, 0x81, 0x79, 0x4a, 0x3d, 0xa8, 0xa3, 0xda, 0x7c, 0xb9, 0x35, 0xea, 0xa0, 0x1e, 0x1, 0xaa, 0xf0, 0x6b, 0x60, 0x3, 0xf4, 0x6a, 0x2e, 0x61, 0xa0, 0x3, 0xb6, 0xc1, 0x4c, 0xbe, 0x5c, 0xd4, 0x9b, 0x7a, 0x55, 0x5b, 0x75, 0xa1, 0x9e, 0x4a, 0xf, 0x20, 0x15, 0xa1, 0xc, 0xec, 0x81, 0x15, 0x70, 0x7, 0x4, 0xd6, 0xc0, 0x3, 0xd8, 0xa5, 0x94, 0xde, 0x93, 0x40, 0x51, 0xa1, 0x8f, 0x10, 0xc0, 0x33, 0xe0, 0xd7, 0xaf, 0x1, 0x72, 0x54, 0x39, 0xab, 0xcb, 0x7f, 0x83, 0xcd, 0x40, 0x1f, 0xb6, 0x77, 0x59, 0xce, 0xb2, 0xbd, 0x7f, 0xb8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x98, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xbd, 0x91, 0xb1, 0xd, 0xc2, 0x30, 0x10, 0x45, 0xdf, 0xd1, 0xb8, 0xf0, 0x2, 0xee, 0xdc, 0x87, 0x1, 0xd8, 0x24, 0xb5, 0xe9, 0x19, 0x87, 0x1e, 0xea, 0x6c, 0xc2, 0x0, 0xa4, 0xb5, 0xdc, 0x79, 0x1, 0x17, 0xae, 0x8e, 0x26, 0x48, 0x76, 0x14, 0x40, 0x48, 0x88, 0xdf, 0xfd, 0xf7, 0xef, 0x4b, 0x77, 0x3a, 0xf8, 0x85, 0x62, 0x8c, 0x21, 0xc6, 0x18, 0xb6, 0x32, 0x59, 0x83, 0x94, 0xd2, 0x5e, 0x55, 0x6f, 0x0, 0x22, 0x72, 0xf0, 0xde, 0xdf, 0xdb, 0x7c, 0xd7, 0x9a, 0x9c, 0xb3, 0x55, 0xd5, 0x9, 0xb0, 0x80, 0x55, 0xd5, 0x29, 0xe7, 0x6c, 0x5f, 0x16, 0x6a, 0xad, 0x67, 0x60, 0x68, 0xd0, 0xb0, 0xb0, 0x3f, 0xaa, 0x3b, 0x3a, 0xa5, 0x74, 0x51, 0xd5, 0xd0, 0xd, 0x88, 0x5c, 0xbd, 0xf7, 0xc7, 0xa7, 0xef, 0x6e, 0x30, 0xc6, 0x9c, 0x80, 0xb9, 0x41, 0xf3, 0xc2, 0xd8, 0x2c, 0x38, 0xe7, 0x8a, 0x88, 0x8c, 0x40, 0x1, 0x8a, 0x88, 0x8c, 0xce, 0xb9, 0xf2, 0x71, 0xcf, 0x77, 0x8f, 0xfb, 0x5a, 0xf, 0x28, 0x4a, 0x37, 0xff, 0x58, 0x46, 0x7b, 0x50, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_disabled_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x77, 0x0, 0x7d, 0x59, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0xf, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xd5, 0x31, 0x4a, 0x3, 0x41, 0x18, 0x86, 0xe1, 0xf7, 0x9f, 0xd9, 0x94, 0xda, 0x27, 0x17, 0x30, 0x27, 0xb0, 0x15, 0xa2, 0x57, 0xd0, 0x4d, 0x20, 0xeb, 0x5, 0x9c, 0x68, 0x50, 0xc4, 0x80, 0x8, 0x8b, 0x6b, 0xa2, 0x85, 0x85, 0xa2, 0x37, 0x70, 0x5, 0x41, 0x4, 0x4b, 0x2d, 0x52, 0xe4, 0x18, 0xf6, 0x41, 0x6b, 0x4d, 0x17, 0x76, 0x66, 0x2c, 0x24, 0x51, 0x82, 0x8d, 0xc5, 0xae, 0x4d, 0xbe, 0xea, 0x9f, 0xea, 0x7d, 0xba, 0x81, 0x7f, 0x9e, 0x4c, 0x8e, 0x86, 0xe9, 0x55, 0x9d, 0x64, 0x67, 0x38, 0xa9, 0x21, 0x2c, 0xe4, 0x52, 0xf3, 0x8c, 0x10, 0xfa, 0x4e, 0xd3, 0xb9, 0xbf, 0x3c, 0x7a, 0x99, 0x2, 0x1a, 0xa6, 0x57, 0xb5, 0xd8, 0x81, 0x8, 0xe7, 0x25, 0xad, 0xd2, 0xf4, 0xe2, 0xf0, 0x2d, 0x8f, 0x7e, 0xb3, 0xdd, 0x2d, 0x8f, 0x33, 0x1f, 0x9, 0x7e, 0xd7, 0x69, 0x56, 0x26, 0x8, 0xc2, 0xd6, 0xf1, 0x63, 0xd8, 0x4a, 0xf6, 0xf3, 0x88, 0xfe, 0xb6, 0xfa, 0x56, 0x72, 0x10, 0x9a, 0xe4, 0x1, 0x40, 0x1, 0xe0, 0xa4, 0x56, 0xd2, 0x2a, 0x2d, 0xa, 0x80, 0xd8, 0x1b, 0x60, 0x6d, 0xfa, 0xe, 0x4d, 0xe2, 0xb, 0x8b, 0xcf, 0x34, 0x55, 0xd1, 0xe1, 0xd9, 0xcd, 0x1, 0x73, 0xc0, 0x17, 0xc0, 0x33, 0x6a, 0xb6, 0xbb, 0xe5, 0xa2, 0xa2, 0x75, 0x13, 0x57, 0x80, 0xf7, 0x6f, 0x80, 0xd0, 0x1f, 0x67, 0x3e, 0x2a, 0xa, 0xe0, 0x9, 0x36, 0x45, 0x78, 0x6, 0x8, 0x0, 0x9c, 0xa6, 0xa3, 0xac, 0x1f, 0x6c, 0x98, 0x13, 0x14, 0x59, 0x7a, 0x77, 0x1d, 0xbf, 0xe6, 0x11, 0xae, 0x9b, 0xb8, 0x82, 0xd7, 0x91, 0xc3, 0x6f, 0x7, 0xd8, 0x65, 0xf8, 0xf1, 0x19, 0xad, 0xef, 0x24, 0x4b, 0x62, 0xfd, 0xa9, 0x20, 0xab, 0xc0, 0x62, 0x1e, 0x0, 0xe0, 0x43, 0x84, 0x27, 0x8d, 0xdd, 0xbb, 0xbd, 0x8a, 0x87, 0x39, 0x35, 0xfe, 0xb6, 0x4f, 0xcf, 0xae, 0x53, 0xd0, 0x62, 0x78, 0xc7, 0x3a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x32, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3f, 0x3f, 0x5a, 0x5a, 0x5a, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x59, 0x59, 0x59, 0x2a, 0x2a, 0x30, 0x4b, 0x4b, 0x4b, 0x22, 0x22, 0x27, 0x35, 0x35, 0x35, 0x4a, 0x4a, 0x4a, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x56, 0x56, 0x56, 0x62, 0x62, 0x62, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x48, 0x48, 0x48, 0x44, 0x44, 0x44, 0x43, 0x43, 0x43, 0x54, 0x54, 0x54, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x52, 0x52, 0x52, 0x42, 0x42, 0x42, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x51, 0x51, 0x51, 0x40, 0x40, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4f, 0x4f, 0x4f, 0x3f, 0x3f, 0x3f, 0x4d, 0x4d, 0x4d, 0x3e, 0x3e, 0x3e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4c, 0x4c, 0x4c, 0x3d, 0x3d, 0x3d, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4a, 0x4a, 0x4a, 0x3b, 0x3b, 0x3b, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x49, 0x49, 0x49, 0x3a, 0x3a, 0x3a, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x39, 0x39, 0x39, 0x47, 0x47, 0x47, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x46, 0x46, 0x46, 0xff, 0xff, 0xff, 0xbd, 0x3f, 0x83, 0xbb, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x65, 0xb5, 0xdd, 0x88, 0x9f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xb, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd9, 0x56, 0xc2, 0x30, 0x10, 0x80, 0x61, 0xd6, 0xa2, 0xa8, 0x6c, 0x75, 0xdf, 0x10, 0x54, 0xa8, 0x82, 0x74, 0xd2, 0x4a, 0x49, 0x5b, 0xa4, 0xb5, 0x5a, 0x44, 0x10, 0x5c, 0xd0, 0xaa, 0x80, 0x8a, 0xcb, 0xfb, 0x3f, 0x83, 0x21, 0x24, 0x1c, 0x8e, 0x5e, 0xe8, 0x77, 0xfd, 0x9f, 0x93, 0x99, 0x89, 0xcf, 0x1f, 0x8, 0x86, 0xc2, 0x42, 0x84, 0x10, 0x66, 0x66, 0xa3, 0x73, 0xf3, 0xbe, 0x9f, 0x2, 0xb, 0xb1, 0x78, 0x22, 0x99, 0x12, 0x45, 0x71, 0x71, 0x69, 0x79, 0x25, 0xea, 0xff, 0x15, 0x4, 0x63, 0xab, 0x6b, 0x7b, 0xcc, 0x7e, 0x2e, 0x2f, 0x1d, 0x30, 0x87, 0x52, 0x21, 0xbf, 0xbe, 0x41, 0x82, 0x50, 0x7c, 0xb3, 0x78, 0x54, 0x1a, 0x93, 0x1, 0x29, 0x2a, 0x73, 0xac, 0x94, 0x35, 0x6d, 0x8b, 0x4, 0xe1, 0x84, 0x5c, 0xe2, 0xe4, 0xa, 0xd6, 0xb, 0x8c, 0xa1, 0x2b, 0xd8, 0x54, 0x48, 0x20, 0x24, 0xab, 0x27, 0x5c, 0xb5, 0x2, 0x39, 0x89, 0xa9, 0x19, 0x2a, 0x58, 0xa3, 0x20, 0x92, 0xb2, 0x4f, 0x39, 0xdb, 0x1, 0xe3, 0x8c, 0xa9, 0x9d, 0xbb, 0x60, 0x3a, 0xa3, 0x40, 0xac, 0x5f, 0x70, 0xf5, 0xe9, 0xc0, 0x20, 0x1, 0xd0, 0xa0, 0x71, 0xc9, 0x35, 0xca, 0x4d, 0x75, 0x6a, 0x86, 0xd6, 0x15, 0xa6, 0x4f, 0xb4, 0x3b, 0x5c, 0x1b, 0xa1, 0xeb, 0x1b, 0x46, 0xbf, 0x5, 0xed, 0xe, 0xd1, 0x21, 0xbb, 0xf7, 0x5c, 0xf7, 0xc1, 0xf2, 0x26, 0x6b, 0x7a, 0x4d, 0xeb, 0xd1, 0xa2, 0x6b, 0x3e, 0x3d, 0x73, 0xc5, 0x5e, 0x1f, 0x7b, 0xc, 0xe0, 0xc1, 0xcb, 0xab, 0x49, 0xf, 0xb5, 0xdd, 0x79, 0x63, 0x86, 0xbd, 0x77, 0xd, 0x33, 0xad, 0x41, 0xff, 0xe3, 0x33, 0x4d, 0x4f, 0xbd, 0x93, 0x19, 0x7e, 0x8d, 0xd9, 0x0, 0xee, 0x64, 0x6, 0xd7, 0x41, 0xd9, 0xdd, 0xff, 0x7c, 0xd6, 0x5f, 0xdf, 0xfd, 0xd, 0xbf, 0xaa, 0x55, 0xdf, 0x7c, 0xb2, 0x44, 0x90, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+static const unsigned char option_button_focus_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xb4, 0x50, 0x4c, 0x54, 0x45, 0x95, 0xa9, 0xb0, 0x92, 0xa7, 0xae, 0x8e, 0xa2, 0xa9, 0x8a, 0x9d, 0xa4, 0x85, 0x98, 0x9f, 0x80, 0x93, 0x9b, 0x7b, 0x8f, 0x96, 0x77, 0x8a, 0x92, 0x72, 0x86, 0x8c, 0x6e, 0x80, 0x88, 0x69, 0x7c, 0x84, 0x64, 0x77, 0x7f, 0x60, 0x72, 0x7a, 0x5b, 0x6e, 0x75, 0x56, 0x69, 0x71, 0xc8, 0xe3, 0xe7, 0xc8, 0xe2, 0xe7, 0xca, 0xe3, 0xe7, 0xce, 0xe6, 0xe9, 0xce, 0xe6, 0xea, 0xd0, 0xe6, 0xe9, 0xce, 0xe5, 0xea, 0xd0, 0xe6, 0xea, 0xce, 0xe5, 0xe9, 0xd0, 0xe5, 0xe9, 0xd3, 0xe7, 0xeb, 0xd4, 0xe7, 0xeb, 0xd9, 0xea, 0xed, 0xd7, 0xe9, 0xed, 0xd7, 0xea, 0xed, 0xdc, 0xec, 0xef, 0xdc, 0xeb, 0xef, 0xe0, 0xed, 0xf1, 0xdf, 0xee, 0xf1, 0xdf, 0xed, 0xf1, 0xe0, 0xee, 0xf1, 0xe3, 0xf0, 0xf2, 0xe2, 0xef, 0xf2, 0xe3, 0xef, 0xf2, 0xe6, 0xf1, 0xf3, 0xe8, 0xf2, 0xf5, 0xe8, 0xf3, 0xf4, 0xe8, 0xf2, 0xf4, 0xe8, 0xf3, 0xf5, 0xd6, 0x5a, 0x5b, 0xd4, 0x57, 0x58, 0xe5, 0x89, 0x89, 0xd5, 0x57, 0x59, 0xd5, 0x58, 0x59, 0xd5, 0x59, 0x5a, 0xd6, 0x59, 0x5a, 0xd6, 0x5a, 0x5c, 0xd7, 0x5b, 0x5c, 0xd7, 0x5b, 0x5d, 0xd8, 0x5c, 0x5d, 0xd8, 0x5c, 0x5e, 0xd8, 0x5d, 0x5f, 0xd9, 0x5d, 0x5f, 0xe8, 0x6c, 0x6e, 0xff, 0xff, 0xff, 0xa1, 0xe, 0x37, 0x8c, 0x0, 0x0, 0x0, 0x2c, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0xac, 0x80, 0x68, 0x47, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3b, 0x39, 0xe, 0xf4, 0x6c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xa3, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x5d, 0xce, 0xdb, 0x16, 0x42, 0x60, 0x18, 0x84, 0xe1, 0x4f, 0x8, 0x65, 0x57, 0x2a, 0x45, 0xd9, 0x15, 0xf9, 0xa3, 0x89, 0x28, 0xea, 0xfe, 0x2f, 0x2c, 0x4e, 0x2c, 0x79, 0xd6, 0xbc, 0xe7, 0x43, 0x34, 0xc5, 0xe5, 0x7f, 0x38, 0x9a, 0xdd, 0x31, 0x72, 0x9f, 0x11, 0xff, 0x80, 0x61, 0x18, 0xa6, 0x69, 0xac, 0xba, 0x50, 0xf0, 0x24, 0x14, 0x58, 0x5b, 0x9b, 0xed, 0xce, 0xb6, 0x6d, 0x6b, 0x8f, 0x42, 0x20, 0xb1, 0xc4, 0xc1, 0x71, 0xe, 0x7d, 0x8e, 0x83, 0x52, 0xa4, 0xf9, 0x13, 0xae, 0x7b, 0x74, 0x7b, 0xa7, 0x13, 0x9e, 0x73, 0x92, 0x72, 0x78, 0xbe, 0xef, 0x75, 0x7c, 0xcf, 0x47, 0x2e, 0x91, 0x5c, 0x21, 0x8, 0xc2, 0x20, 0x8c, 0x82, 0x73, 0x18, 0xa1, 0x92, 0x49, 0xa9, 0x71, 0x89, 0xe3, 0x38, 0x49, 0xba, 0x25, 0xa8, 0x15, 0x5a, 0xbc, 0x70, 0x1d, 0xe0, 0xb5, 0xa0, 0xe5, 0x1b, 0x69, 0xca, 0xd8, 0x8d, 0x31, 0x96, 0x65, 0x68, 0x96, 0xa4, 0x36, 0x60, 0x3, 0x34, 0x2a, 0x69, 0xed, 0xf8, 0x7a, 0xab, 0x91, 0xfe, 0xf9, 0x8e, 0x7c, 0x74, 0xd2, 0x27, 0x7e, 0x7e, 0x46, 0x20, 0x17, 0xe, 0x2d, 0x4e, 0x9, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_hover_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x77, 0x0, 0x7d, 0x59, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf5, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xd5, 0x31, 0x4e, 0xc3, 0x40, 0x10, 0x46, 0xe1, 0x37, 0xbb, 0xdb, 0x42, 0x9f, 0xf4, 0x8, 0x8b, 0x3, 0x50, 0x82, 0x30, 0x88, 0x5b, 0x98, 0x23, 0x50, 0x80, 0x10, 0xb9, 0x1, 0x14, 0xb9, 0x5, 0x6e, 0x91, 0x28, 0x21, 0x8a, 0x13, 0x25, 0x87, 0x88, 0xec, 0x84, 0x12, 0x41, 0xd, 0xe9, 0xa2, 0xac, 0x87, 0xca, 0xc8, 0x8a, 0x68, 0x28, 0x76, 0x69, 0xf2, 0x57, 0xd3, 0xbd, 0xaf, 0x1b, 0xf8, 0xe7, 0x49, 0x73, 0x8c, 0x2b, 0x4d, 0xbc, 0xe1, 0x5e, 0x20, 0x5, 0x76, 0x2, 0xf5, 0x96, 0x40, 0x21, 0x9e, 0x5e, 0x9a, 0x48, 0xf5, 0x3, 0x18, 0x57, 0x9a, 0xd4, 0x86, 0x89, 0x28, 0x7d, 0xb7, 0x26, 0x3f, 0x3a, 0x90, 0x8f, 0x10, 0xf5, 0xe9, 0x4c, 0x3b, 0x2b, 0x47, 0x26, 0xc2, 0x95, 0x78, 0x8e, 0x1b, 0x4, 0xc3, 0x85, 0x3e, 0x8d, 0xe6, 0x7a, 0x13, 0x22, 0xfa, 0xdb, 0x8a, 0x85, 0xde, 0x16, 0xaf, 0xfa, 0x8, 0x60, 0x0, 0x4, 0x52, 0xb7, 0x26, 0x8f, 0x5, 0xf0, 0x9e, 0x7, 0x94, 0xb3, 0xb6, 0x48, 0x63, 0xc5, 0x37, 0x9b, 0x26, 0x76, 0x78, 0x73, 0x5b, 0xc0, 0x16, 0xd0, 0x0, 0x96, 0xd3, 0x99, 0x76, 0x62, 0x45, 0x7, 0xa5, 0x76, 0x81, 0xcf, 0x36, 0xa0, 0x58, 0x39, 0xb2, 0x58, 0x0, 0x6b, 0xb9, 0x0, 0x5e, 0x0, 0x1c, 0x80, 0x78, 0x7a, 0x58, 0x26, 0xc3, 0xb9, 0x52, 0xd7, 0xe4, 0xe7, 0x89, 0xbc, 0x87, 0x8, 0xf, 0x4a, 0xed, 0x5a, 0x4b, 0xa6, 0xc2, 0xa5, 0x55, 0xe, 0xa1, 0xf5, 0x8c, 0x46, 0xa5, 0xee, 0xab, 0xe1, 0xe, 0xe1, 0x14, 0xd8, 0xd, 0x1, 0x0, 0xbe, 0x80, 0x67, 0x3, 0xd7, 0x27, 0x7b, 0xf2, 0x16, 0xa8, 0xf1, 0xb7, 0x7d, 0x3, 0x6a, 0x72, 0x53, 0x9c, 0x5f, 0x1a, 0xab, 0xcf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x44, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x42, 0x40, 0x4b, 0x5f, 0x5a, 0x6c, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x5f, 0x5a, 0x6b, 0x2a, 0x2a, 0x30, 0x56, 0x53, 0x64, 0x22, 0x22, 0x27, 0x3e, 0x3b, 0x46, 0x57, 0x53, 0x63, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x5b, 0x57, 0x68, 0x5a, 0x56, 0x67, 0x67, 0x63, 0x76, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x4d, 0x4a, 0x57, 0x49, 0x46, 0x52, 0x48, 0x45, 0x51, 0x5a, 0x56, 0x65, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x5b, 0x57, 0x66, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x59, 0x55, 0x64, 0x47, 0x44, 0x50, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x58, 0x54, 0x64, 0x46, 0x43, 0x50, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x56, 0x53, 0x63, 0x45, 0x42, 0x4f, 0x56, 0x53, 0x62, 0x45, 0x42, 0x4e, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x55, 0x51, 0x62, 0x44, 0x41, 0x4e, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x55, 0x51, 0x60, 0x44, 0x41, 0x4d, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x43, 0x40, 0x4c, 0x54, 0x50, 0x5f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x47, 0x43, 0x51, 0x43, 0x3f, 0x4d, 0x42, 0x3f, 0x4c, 0x53, 0x4f, 0x5f, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x53, 0x50, 0x5f, 0x53, 0x4f, 0x5e, 0x5f, 0x5a, 0x6c, 0xff, 0xff, 0xff, 0xd1, 0x85, 0xc5, 0x5, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0x10, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd9, 0x52, 0xc2, 0x30, 0x14, 0x80, 0x61, 0xd6, 0xa2, 0xa8, 0x6c, 0x75, 0xdf, 0x77, 0xa8, 0xa2, 0x70, 0xd2, 0x4a, 0x25, 0x6d, 0x81, 0x62, 0xa1, 0x88, 0x20, 0x6e, 0xc5, 0xaa, 0x80, 0xfb, 0xfa, 0xfe, 0xf, 0x60, 0x49, 0x13, 0x86, 0xd1, 0xb, 0xfd, 0x6e, 0xf3, 0xcf, 0xe4, 0x24, 0xc7, 0xe3, 0xf5, 0xf9, 0x3, 0x41, 0x2e, 0xe4, 0xe0, 0x46, 0x46, 0xc3, 0x63, 0xe3, 0x9e, 0x9f, 0x7c, 0x13, 0x91, 0x68, 0x2c, 0x9e, 0xe0, 0x79, 0x7e, 0x72, 0x6a, 0x7a, 0x26, 0xec, 0xfd, 0x15, 0xf8, 0x23, 0xb3, 0x73, 0x9b, 0x5b, 0xae, 0xed, 0x64, 0x4a, 0xd8, 0xa1, 0x76, 0x85, 0x74, 0x6a, 0x7e, 0xc1, 0x9, 0x2, 0xd1, 0xc5, 0xbd, 0xfd, 0x8c, 0x2b, 0xb, 0x48, 0x94, 0xa8, 0x3, 0x31, 0x27, 0xcb, 0x4b, 0x4e, 0x10, 0x8c, 0x1d, 0xb2, 0xf3, 0x4c, 0x36, 0x8f, 0x95, 0x34, 0xa5, 0x2a, 0x22, 0xd6, 0x44, 0x27, 0xe0, 0xe2, 0x85, 0x22, 0x53, 0xc8, 0x43, 0x52, 0xa0, 0x4a, 0xaa, 0x4, 0x7a, 0x3f, 0x8, 0x25, 0xca, 0x47, 0x4c, 0xd9, 0x0, 0xb5, 0x42, 0x95, 0xaa, 0x26, 0x68, 0x46, 0x3f, 0xe0, 0x6b, 0xc7, 0x4c, 0x6d, 0x38, 0x50, 0x9d, 0x0, 0x48, 0x50, 0x3f, 0x61, 0xea, 0xb9, 0x86, 0x34, 0x34, 0x43, 0xf3, 0x14, 0x93, 0x2b, 0x5a, 0x67, 0x4c, 0xb, 0xa1, 0xf3, 0xb, 0x4a, 0xb9, 0x4, 0xf9, 0xa, 0x91, 0x21, 0xad, 0x36, 0x63, 0x5d, 0xeb, 0xf6, 0xe0, 0x99, 0x76, 0x43, 0xbf, 0xd1, 0xc9, 0x33, 0xad, 0xf6, 0x2d, 0x75, 0xd7, 0xe9, 0x62, 0x9b, 0x2, 0xdc, 0xbb, 0x7f, 0xd0, 0xc8, 0x47, 0x2d, 0x3f, 0x3e, 0x3d, 0xbb, 0x5e, 0x3a, 0xaf, 0x32, 0xa6, 0x9a, 0xbd, 0xee, 0xdb, 0xfb, 0xa, 0xf9, 0xea, 0xd5, 0xb5, 0x8f, 0x4f, 0xd7, 0x17, 0x80, 0x39, 0x98, 0xc1, 0x34, 0xd0, 0xfa, 0xc6, 0x7f, 0x96, 0xf5, 0xd7, 0xba, 0xbf, 0x1, 0xfe, 0x22, 0x58, 0x7c, 0xf4, 0xd2, 0xd1, 0x68, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_normal_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x1c, 0x8, 0x6, 0x0, 0x0, 0x0, 0x0, 0xc2, 0xbd, 0x22, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x19, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xc1, 0x1, 0x1, 0x0, 0x0, 0x0, 0x82, 0x20, 0xff, 0xaf, 0x6e, 0x48, 0x40, 0x1, 0x0, 0x0, 0xf0, 0x6e, 0xe, 0x1c, 0x0, 0x1, 0xe8, 0x20, 0x47, 0xc2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x44, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x56, 0x52, 0x60, 0x2a, 0x2a, 0x30, 0x47, 0x44, 0x52, 0x22, 0x22, 0x27, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x5d, 0x5a, 0x6a, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x46, 0x42, 0x4f, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0x4e, 0x4b, 0x58, 0xff, 0xff, 0xff, 0xd7, 0xc8, 0xfe, 0x88, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x1, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0xd7, 0x56, 0xc2, 0x40, 0x10, 0x80, 0x61, 0x6a, 0x50, 0x54, 0x5a, 0xec, 0xbd, 0x43, 0x14, 0x85, 0xdd, 0x44, 0xa2, 0x6c, 0x12, 0x20, 0x18, 0xd, 0x22, 0x8, 0x16, 0x34, 0x16, 0xc0, 0x5e, 0xde, 0xff, 0x1, 0x5c, 0x36, 0xb3, 0x1c, 0x8e, 0x5e, 0xe8, 0x77, 0xfd, 0x9f, 0xb3, 0x33, 0xb3, 0x1e, 0xaf, 0xcf, 0x1f, 0x8, 0xa, 0x21, 0x4a, 0x18, 0x1a, 0xe, 0x8f, 0x8c, 0x7a, 0x7e, 0xf2, 0x8d, 0x45, 0xa2, 0xb1, 0x78, 0x42, 0x14, 0xc5, 0xf1, 0x89, 0xc9, 0xa9, 0xb0, 0xf7, 0x57, 0xe0, 0x8f, 0x4c, 0xcf, 0xac, 0x6f, 0xb8, 0x36, 0x93, 0x29, 0x69, 0xb, 0x6c, 0x4b, 0xe9, 0xd4, 0xec, 0x1c, 0xd, 0x2, 0xd1, 0xf9, 0x9d, 0xdd, 0x8c, 0x2b, 0x8b, 0xb0, 0xac, 0x80, 0x3d, 0x39, 0xa7, 0xaa, 0xb, 0x34, 0x8, 0xc6, 0xb2, 0x99, 0x7d, 0x70, 0x90, 0x27, 0x5a, 0x1a, 0xe8, 0x9a, 0x4c, 0xc, 0x99, 0x6, 0x42, 0xbc, 0x50, 0xe4, 0xa, 0x79, 0x94, 0x94, 0x40, 0x49, 0x57, 0x90, 0xd9, 0xb, 0x42, 0x89, 0xf2, 0x21, 0x57, 0xb6, 0x90, 0x7e, 0x4, 0x4a, 0xc7, 0x36, 0x32, 0xac, 0x5e, 0x20, 0x56, 0x4e, 0xb8, 0xca, 0x60, 0xa0, 0xd3, 0x0, 0xb1, 0xa0, 0x7a, 0xca, 0x55, 0x73, 0x35, 0x65, 0x60, 0x86, 0xfa, 0x19, 0x61, 0x4f, 0x34, 0x9a, 0x5c, 0x3, 0xe3, 0xf3, 0xb, 0xa0, 0x5d, 0x22, 0xf5, 0xa, 0xb3, 0x21, 0x5b, 0xd7, 0x5c, 0xeb, 0xc6, 0x74, 0xfa, 0x6b, 0x3a, 0x35, 0xf3, 0xd6, 0x64, 0x6b, 0xde, 0xdd, 0x73, 0xf, 0xed, 0xe, 0x71, 0x0, 0x22, 0xdd, 0xc7, 0x27, 0x83, 0x1d, 0x6a, 0xb1, 0xf9, 0xc, 0x5e, 0xda, 0xaf, 0x2a, 0x1, 0xf5, 0x6e, 0xe7, 0xed, 0x7d, 0x89, 0x9d, 0x7a, 0x79, 0xe5, 0xe3, 0xd3, 0xf5, 0x85, 0x90, 0xdd, 0x9f, 0xc1, 0xb6, 0xf0, 0xea, 0xda, 0x7f, 0x3e, 0xeb, 0xaf, 0xef, 0xfe, 0x6, 0x1a, 0x96, 0x59, 0x89, 0x91, 0xf7, 0xf1, 0x7b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char option_button_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x77, 0x0, 0x7d, 0x59, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf3, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xd5, 0x31, 0x4a, 0x3, 0x41, 0x18, 0x86, 0xe1, 0xf7, 0x9f, 0x95, 0x74, 0xda, 0x27, 0x17, 0xd0, 0x13, 0xd8, 0xa, 0xd1, 0x6b, 0xac, 0x47, 0x10, 0x54, 0x64, 0x43, 0x30, 0xcb, 0x14, 0xa2, 0xce, 0x1a, 0xc8, 0x21, 0xdc, 0x56, 0xb0, 0xd4, 0x22, 0x45, 0x8e, 0x61, 0x2f, 0x5a, 0x6b, 0xca, 0xc4, 0xfd, 0x2c, 0xcc, 0x86, 0x20, 0x82, 0x58, 0xcc, 0xda, 0xe4, 0xab, 0x86, 0x61, 0xe0, 0x7d, 0xba, 0x81, 0x7f, 0x9e, 0xd5, 0x7, 0xaf, 0xe1, 0x4e, 0x45, 0x75, 0xd, 0x74, 0x81, 0xcd, 0x48, 0xbd, 0xa9, 0x60, 0x2c, 0xd4, 0xbb, 0xb0, 0xec, 0x69, 0x9, 0x58, 0xc4, 0x27, 0xa0, 0xe1, 0x9c, 0x56, 0x79, 0x69, 0xc7, 0xaf, 0x31, 0xea, 0x7d, 0x8d, 0xda, 0x9, 0xb3, 0xd4, 0xe0, 0xa4, 0x42, 0x7b, 0x35, 0x82, 0x5c, 0xc5, 0x7d, 0xae, 0x70, 0x16, 0x23, 0xfa, 0xd3, 0x72, 0x85, 0x6c, 0xa0, 0x9b, 0x3b, 0x0, 0xb7, 0xb8, 0xeb, 0xce, 0x69, 0x95, 0x4d, 0x1, 0x1c, 0xdc, 0x1a, 0x3a, 0x58, 0x11, 0x15, 0x6a, 0x2a, 0xfe, 0xbd, 0xe9, 0x7e, 0x7b, 0x18, 0x7b, 0x6b, 0xc0, 0x1a, 0x50, 0x3, 0xa6, 0x7d, 0x8d, 0xda, 0x4d, 0x45, 0xbd, 0x42, 0x7, 0x78, 0x5b, 0x2, 0x4, 0xe3, 0x84, 0x59, 0xda, 0x14, 0xe0, 0x3, 0x3b, 0x34, 0xf4, 0x8, 0xb0, 0xf1, 0x5, 0x50, 0xcf, 0x61, 0x93, 0x81, 0xa, 0x12, 0x54, 0x7a, 0xcb, 0x5e, 0x62, 0x84, 0xbd, 0x42, 0xa7, 0x82, 0x14, 0x74, 0x64, 0xb0, 0xb, 0x2b, 0x9f, 0xd1, 0xb9, 0xc2, 0xb6, 0xc3, 0xae, 0x80, 0x7d, 0x60, 0x2b, 0x6, 0x0, 0x78, 0x37, 0xf4, 0x60, 0x70, 0xea, 0x2d, 0x7b, 0x8e, 0xd4, 0xf8, 0xdb, 0x3e, 0x1, 0x97, 0xcd, 0x54, 0x90, 0xa4, 0x27, 0x1c, 0xb4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x40, 0xde, 0x8d, 0x6b, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x4d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x31, 0x2f, 0x37, 0x46, 0x43, 0x4f, 0x2b, 0x2b, 0x31, 0x2e, 0x2e, 0x34, 0x47, 0x44, 0x50, 0x2a, 0x2a, 0x30, 0x55, 0x52, 0x5f, 0x22, 0x22, 0x27, 0x3d, 0x3a, 0x45, 0x56, 0x52, 0x60, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x43, 0x40, 0x4c, 0x42, 0x40, 0x4b, 0x4c, 0x49, 0x56, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x2d, 0x2d, 0x34, 0x2f, 0x2f, 0x36, 0x2e, 0x2e, 0x35, 0x2c, 0x2c, 0x32, 0x3a, 0x38, 0x41, 0x36, 0x34, 0x3d, 0x44, 0x41, 0x4c, 0x26, 0x26, 0x2b, 0x24, 0x24, 0x28, 0x27, 0x27, 0x2d, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x25, 0x25, 0x2b, 0x23, 0x23, 0x28, 0x44, 0x42, 0x4e, 0x36, 0x34, 0x3e, 0x44, 0x41, 0x4e, 0x26, 0x26, 0x2c, 0x25, 0x25, 0x2a, 0x2a, 0x2a, 0x2f, 0x2b, 0x2b, 0x31, 0x22, 0x22, 0x26, 0x46, 0x42, 0x4f, 0x38, 0x35, 0x3f, 0x2d, 0x2d, 0x33, 0x22, 0x22, 0x27, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x27, 0x27, 0x2b, 0x2e, 0x2e, 0x34, 0x2c, 0x2c, 0x31, 0x29, 0x29, 0x2e, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x24, 0x24, 0x2a, 0x24, 0x24, 0x29, 0x20, 0x20, 0x25, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x28, 0x28, 0x2d, 0x2b, 0x2b, 0x30, 0x29, 0x29, 0x2d, 0x20, 0x20, 0x23, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x22, 0x22, 0x28, 0x27, 0x27, 0x2c, 0x1e, 0x1e, 0x22, 0x50, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x3f, 0x3d, 0x47, 0x4f, 0x4c, 0x59, 0x21, 0x21, 0x26, 0x21, 0x21, 0x25, 0x23, 0x23, 0x27, 0x20, 0x20, 0x24, 0x1d, 0x1d, 0x21, 0x45, 0x42, 0x4d, 0x41, 0x3e, 0x49, 0x40, 0x3e, 0x48, 0x50, 0x4e, 0x5a, 0x1f, 0x1f, 0x24, 0x1f, 0x1f, 0x23, 0x1e, 0x1e, 0x21, 0x52, 0x4e, 0x5c, 0x51, 0x4e, 0x5b, 0x5d, 0x59, 0x69, 0xff, 0xff, 0xff, 0x2, 0x4e, 0xff, 0xf1, 0x0, 0x0, 0x0, 0x24, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x1d, 0x16, 0xd, 0x7, 0x2, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x43, 0x3a, 0x2d, 0x1b, 0x77, 0xef, 0xe6, 0x49, 0xef, 0xe6, 0xef, 0xe7, 0x77, 0xef, 0xe4, 0x4a, 0xba, 0xea, 0xc1, 0xeb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6e, 0x22, 0xf, 0x51, 0x17, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xe, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x8d, 0xd1, 0x57, 0x53, 0xc2, 0x40, 0x10, 0xc0, 0x71, 0x6a, 0x50, 0x54, 0x5a, 0xec, 0xbd, 0x43, 0x14, 0xf5, 0x2e, 0x91, 0xa8, 0x5c, 0x12, 0x20, 0x18, 0xd, 0x22, 0x88, 0xd, 0x8d, 0xd, 0xb0, 0xd7, 0xef, 0xff, 0xea, 0x71, 0xd9, 0x63, 0x18, 0x7d, 0xd0, 0xdf, 0xf3, 0x7f, 0xe6, 0x76, 0xf7, 0x3c, 0x5e, 0x9f, 0x3f, 0x10, 0x14, 0x42, 0x94, 0xd0, 0xd3, 0x1b, 0xee, 0xeb, 0xf7, 0xfc, 0xe4, 0x1b, 0x88, 0x44, 0x63, 0xf1, 0x84, 0x28, 0x8a, 0x83, 0x43, 0xc3, 0x23, 0x61, 0xef, 0xaf, 0xc0, 0x1f, 0x19, 0x1d, 0x5b, 0x5c, 0x72, 0x2d, 0x27, 0x53, 0xd2, 0xa, 0x58, 0x95, 0xd2, 0xa9, 0xf1, 0x9, 0x1a, 0x4, 0xa2, 0x93, 0x6b, 0xeb, 0x60, 0x3, 0x61, 0x59, 0x1, 0x9b, 0x72, 0x46, 0x55, 0xa7, 0x68, 0x10, 0x8c, 0x6d, 0x6d, 0x73, 0x3b, 0x59, 0xa2, 0xa5, 0x81, 0xae, 0xc9, 0xc4, 0x90, 0x69, 0x20, 0xc4, 0x73, 0x79, 0x2e, 0x97, 0x45, 0x49, 0x9, 0x14, 0x74, 0x5, 0x99, 0xed, 0x20, 0x94, 0x28, 0xee, 0x72, 0x45, 0xb, 0xe9, 0x7b, 0xa0, 0xb0, 0x6f, 0x23, 0xc3, 0x6a, 0x7, 0x62, 0xe9, 0x80, 0x2b, 0x75, 0x7, 0x3a, 0xd, 0x10, 0xb, 0xca, 0x87, 0x5c, 0x39, 0x53, 0x51, 0xba, 0x66, 0xa8, 0x1e, 0x11, 0xf6, 0x44, 0xed, 0x98, 0xab, 0x61, 0x7c, 0x72, 0xa, 0xb4, 0x33, 0xa4, 0x9e, 0x63, 0x36, 0x64, 0xfd, 0x82, 0xab, 0x5f, 0x9a, 0x4e, 0x67, 0x4d, 0xa7, 0x62, 0x5e, 0x99, 0x6c, 0xcd, 0xeb, 0x9b, 0x5b, 0x70, 0xd7, 0x68, 0x12, 0x7, 0x20, 0xd2, 0xba, 0x7f, 0x30, 0xd8, 0xa1, 0xa6, 0x1f, 0x9f, 0x9e, 0x5d, 0x2f, 0x8d, 0x57, 0x95, 0x80, 0x6a, 0xab, 0xf9, 0xf6, 0x3e, 0xc3, 0x4e, 0x3d, 0x3b, 0xf7, 0xf1, 0xe9, 0xfa, 0x42, 0xc8, 0xee, 0xcc, 0x60, 0x5b, 0x78, 0x7e, 0xe1, 0x3f, 0x9f, 0xf5, 0xd7, 0x77, 0x7f, 0x3, 0x1c, 0x7f, 0x59, 0xc2, 0x5e, 0xdd, 0xbf, 0x43, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char panel_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x2, 0x0, 0x0, 0x0, 0x4b, 0x6d, 0x29, 0xdc, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x14, 0x49, 0x44, 0x41, 0x54, 0x8, 0x99, 0x63, 0x54, 0xd6, 0x32, 0x62, 0xc0, 0x6, 0x98, 0xb0, 0x8a, 0xe, 0x5a, 0x9, 0x0, 0x69, 0x33, 0x0, 0x8f, 0xd7, 0xa0, 0x34, 0xa8, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x25, 0x2a, 0x35, 0x32, 0x3b, 0x4a, 0x73, 0x58, 0x4a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x5e, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0x4b, 0x1c, 0x51, 0x14, 0x85, 0xbf, 0x77, 0x67, 0xde, 0x9b, 0x85, 0x71, 0x58, 0xc, 0x51, 0xc2, 0x16, 0x6, 0x2c, 0x42, 0x48, 0x29, 0x81, 0x5d, 0x42, 0x8, 0xb6, 0x8a, 0x42, 0xba, 0x74, 0xfe, 0x87, 0xfc, 0x92, 0x14, 0xf9, 0x15, 0x69, 0x55, 0x4c, 0x17, 0xb6, 0x58, 0xc2, 0x6, 0xf6, 0x17, 0xb8, 0xcd, 0x36, 0x2e, 0xc2, 0x80, 0xb2, 0x98, 0x31, 0x99, 0x37, 0x33, 0xf7, 0xa5, 0x30, 0x85, 0xc8, 0xae, 0x2e, 0xd6, 0x1e, 0x38, 0xe5, 0x77, 0xb8, 0xf7, 0xc0, 0x31, 0xdc, 0x48, 0x80, 0x17, 0xc0, 0x33, 0xc0, 0x71, 0xbf, 0x3c, 0x70, 0x1, 0x9c, 0x3, 0x6a, 0xfe, 0xc3, 0xaf, 0x80, 0xf4, 0xed, 0xf6, 0xde, 0x7e, 0x9a, 0x65, 0x5d, 0x91, 0x78, 0x75, 0x1e, 0xa9, 0x5a, 0x5f, 0x16, 0x57, 0x57, 0xbf, 0x46, 0xfd, 0xe3, 0x23, 0xa0, 0x0, 0x4e, 0xd, 0xd0, 0xb1, 0xd6, 0x76, 0xde, 0xed, 0x7c, 0xfa, 0xe2, 0x5c, 0xf2, 0x5e, 0x55, 0x9b, 0x10, 0x34, 0x9a, 0x17, 0x60, 0x8c, 0x34, 0x22, 0x12, 0x79, 0x5f, 0xe, 0x7e, 0x7e, 0xff, 0xf6, 0xb9, 0xaa, 0xaa, 0x69, 0x4, 0xbc, 0xdc, 0xfa, 0xb0, 0xfb, 0x71, 0x25, 0x6b, 0x1f, 0x94, 0x7f, 0xaf, 0x29, 0xff, 0x5c, 0x4b, 0x5d, 0x79, 0xe6, 0xb9, 0xf2, 0xa5, 0x84, 0x10, 0x48, 0x92, 0xd6, 0x46, 0xfb, 0xf9, 0xfa, 0x74, 0x3a, 0x19, 0x4f, 0x4, 0xb0, 0x69, 0x96, 0x75, 0x55, 0xb5, 0xa9, 0xbc, 0x7f, 0xe0, 0x7d, 0xa8, 0x7c, 0x49, 0x50, 0x6d, 0xd2, 0xb4, 0xdd, 0x3, 0xac, 0x0, 0x46, 0x24, 0x5e, 0x5b, 0x74, 0xf6, 0xdc, 0x2e, 0x82, 0x46, 0x12, 0xc7, 0x6b, 0x80, 0x91, 0x65, 0xa1, 0x45, 0x7a, 0xa, 0xb8, 0x9, 0x8, 0x5a, 0xd7, 0xb9, 0x31, 0xd2, 0x2c, 0xb, 0x19, 0x23, 0x8d, 0xd6, 0x75, 0xe, 0x4, 0x1, 0xaa, 0xa2, 0x98, 0xd, 0x45, 0x24, 0xb2, 0x2e, 0x79, 0x10, 0xb6, 0x2e, 0x41, 0x44, 0xa2, 0xa2, 0x98, 0xd, 0x1, 0x1f, 0x1, 0x71, 0x7e, 0x36, 0x39, 0xef, 0x6c, 0xbe, 0x7e, 0x93, 0x24, 0xad, 0x8d, 0xd8, 0xba, 0x26, 0xb6, 0x56, 0xac, 0x73, 0xdc, 0xb5, 0x4b, 0x5a, 0x8d, 0xb5, 0x4e, 0xbc, 0x2f, 0x7, 0xa3, 0x1f, 0x87, 0x5f, 0x55, 0x35, 0xbf, 0x33, 0xa6, 0xdd, 0xbd, 0x34, 0x6d, 0xf7, 0x24, 0x5e, 0x30, 0xa6, 0xba, 0xbe, 0x2c, 0x8a, 0xd9, 0x70, 0xd4, 0x3f, 0x39, 0x6, 0x7e, 0x3, 0x63, 0x73, 0xab, 0x8b, 0x47, 0xcd, 0xf9, 0x1f, 0x55, 0x2d, 0x97, 0x76, 0x54, 0xe2, 0xdb, 0x90, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xa5, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3b, 0x3b, 0x43, 0x42, 0x42, 0x4b, 0x3e, 0x3e, 0x47, 0x3e, 0x3e, 0x46, 0x41, 0x41, 0x4a, 0x0, 0x0, 0x0, 0x3d, 0x3d, 0x45, 0x3b, 0x3b, 0x43, 0x3a, 0x3a, 0x42, 0x38, 0x38, 0x41, 0x37, 0x37, 0x3e, 0x36, 0x36, 0x3d, 0x35, 0x35, 0x3c, 0x0, 0x0, 0x0, 0x38, 0x38, 0x40, 0x38, 0x38, 0x40, 0x31, 0x31, 0x38, 0x34, 0x34, 0x3b, 0x34, 0x34, 0x3b, 0x39, 0x39, 0x3f, 0x31, 0x31, 0x38, 0x2f, 0x2f, 0x36, 0x2d, 0x2d, 0x33, 0x2c, 0x2c, 0x32, 0x2b, 0x2b, 0x31, 0x2a, 0x2a, 0x31, 0x2a, 0x2a, 0x30, 0x29, 0x29, 0x30, 0x29, 0x29, 0x2f, 0x28, 0x28, 0x2e, 0x28, 0x28, 0x2d, 0x27, 0x27, 0x2d, 0x27, 0x27, 0x2c, 0x29, 0x29, 0x2e, 0x26, 0x26, 0x2c, 0x35, 0x32, 0x3b, 0xf, 0xeb, 0x7f, 0x60, 0x0, 0x0, 0x0, 0x28, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0x4, 0x13, 0x19, 0x1f, 0x22, 0x23, 0x16, 0x27, 0x35, 0x3f, 0x45, 0x46, 0x94, 0xf5, 0xfa, 0xfb, 0xf5, 0x40, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0x1a, 0xf5, 0xf6, 0x95, 0xfa, 0xfb, 0xf4, 0x94, 0x71, 0xda, 0xac, 0x92, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x36, 0x47, 0xbf, 0x88, 0xd1, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xaf, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0xc9, 0x12, 0x82, 0x30, 0x10, 0x4, 0xd0, 0x1, 0x12, 0xb6, 0x0, 0x21, 0x2c, 0xb2, 0xaa, 0xa0, 0xa8, 0x80, 0x88, 0x8, 0xf8, 0xff, 0xbf, 0x66, 0x98, 0x93, 0xa5, 0xef, 0xd8, 0x55, 0xd3, 0xd5, 0x3, 0xa0, 0xa8, 0x1a, 0xa1, 0xba, 0x44, 0x89, 0xa6, 0x2a, 0x0, 0x8a, 0x41, 0x4d, 0xcb, 0x66, 0x8e, 0xc3, 0x6c, 0xcb, 0xa4, 0x86, 0x2, 0x2a, 0x75, 0x3d, 0xee, 0x8b, 0x20, 0x10, 0x3e, 0xf7, 0x5c, 0xaa, 0x82, 0x66, 0x7a, 0x61, 0x14, 0xef, 0xa4, 0x38, 0xa, 0x3d, 0x53, 0x3, 0x62, 0xf1, 0xa4, 0xed, 0x50, 0x9b, 0x70, 0x8b, 0x0, 0xb5, 0xd3, 0xac, 0xeb, 0x51, 0x97, 0xa5, 0x36, 0x5, 0x9d, 0x89, 0xbc, 0xbf, 0xa3, 0x3e, 0x17, 0x4c, 0x7, 0xdd, 0x9, 0x8a, 0xe1, 0x81, 0x86, 0x22, 0x70, 0x30, 0x28, 0xc7, 0x27, 0x1a, 0x4b, 0xc, 0x98, 0xd8, 0x4f, 0x2f, 0x34, 0xed, 0xb7, 0x13, 0x59, 0x7a, 0x98, 0x17, 0x34, 0x1f, 0xb7, 0x52, 0x52, 0xf1, 0x7a, 0x5d, 0xde, 0xd2, 0xb2, 0x9e, 0x78, 0x45, 0xb6, 0x61, 0xe7, 0xba, 0xb9, 0x48, 0xcd, 0xf5, 0xb6, 0xd, 0xc3, 0xe9, 0xe9, 0xd7, 0xf4, 0xbf, 0xe7, 0x7e, 0xdf, 0xff, 0x0, 0xda, 0x19, 0x15, 0x34, 0xd5, 0xa4, 0x90, 0x50, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char popup_bg_disabled_png[] = {
@@ -258,24 +254,32 @@ static const unsigned char popup_checked_png[] = {
0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa3, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x85, 0xcd, 0xa1, 0xa, 0xc2, 0x50, 0x0, 0x85, 0xe1, 0xff, 0xdc, 0x5d, 0xd8, 0x14, 0x4, 0xab, 0x69, 0x37, 0xac, 0x98, 0xd5, 0x27, 0xb0, 0x89, 0x16, 0x8b, 0xd5, 0xf7, 0xd0, 0xec, 0x73, 0xf8, 0x4, 0x16, 0x61, 0x4d, 0x10, 0xc, 0x16, 0xa3, 0x61, 0x71, 0xab, 0x16, 0xeb, 0x84, 0x3b, 0xae, 0x45, 0x8b, 0xa, 0x9e, 0x78, 0xce, 0x7, 0x7, 0xfe, 0x44, 0xbf, 0xca, 0xa2, 0x28, 0x3a, 0x71, 0x1c, 0x1f, 0x24, 0x3d, 0xcc, 0xe7, 0x18, 0x42, 0x50, 0x92, 0x24, 0x5b, 0x49, 0x23, 0xa0, 0xfd, 0x5, 0xaa, 0xaa, 0x5a, 0x1, 0x73, 0xe0, 0x1e, 0x45, 0xd1, 0x42, 0x65, 0x59, 0x9e, 0x80, 0x96, 0xf7, 0x7e, 0x62, 0xad, 0x1d, 0x2, 0xfb, 0x97, 0x9d, 0x39, 0xe7, 0x72, 0x1b, 0x42, 0x88, 0x25, 0xd, 0xac, 0xb5, 0x47, 0xa0, 0x7, 0x18, 0x60, 0xed, 0x9c, 0xcb, 0x1, 0x4c, 0xd3, 0x34, 0x53, 0xe0, 0xa, 0xf4, 0x81, 0x2e, 0xb0, 0x4b, 0xd3, 0x74, 0xf3, 0xbe, 0x34, 0x59, 0x96, 0xdd, 0xbc, 0xf7, 0x63, 0xe0, 0x2, 0x9c, 0xeb, 0xba, 0x5e, 0x4a, 0xa, 0x6f, 0xf0, 0x4, 0x57, 0x3d, 0x2c, 0x27, 0x2b, 0xe9, 0x62, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
+static const unsigned char popup_hover_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0x20, 0x2e, 0x31, 0x83, 0xae, 0xb7, 0xb3, 0xd8, 0xe1, 0xaf, 0xd5, 0xde, 0xac, 0xd2, 0xdb, 0xa9, 0xcf, 0xd8, 0xa5, 0xcc, 0xd5, 0xa2, 0xc9, 0xd2, 0x9e, 0xc6, 0xcf, 0x9b, 0xc3, 0xcc, 0x97, 0xc0, 0xc9, 0x94, 0xbd, 0xc6, 0x91, 0xba, 0xc3, 0x8d, 0xb7, 0xc0, 0xff, 0xff, 0xff, 0x73, 0xd4, 0x4e, 0xcb, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x14, 0x4, 0x3, 0x1, 0x6, 0x21, 0x25, 0x30, 0x50, 0x64, 0x10, 0x32, 0x6, 0x3, 0x20, 0xc3, 0x5, 0xc, 0x80, 0x8c, 0x50, 0x30, 0x0, 0x32, 0xd2, 0xc0, 0x0, 0xc8, 0x28, 0x7, 0x3, 0x20, 0xa3, 0x3, 0xc, 0x80, 0x8c, 0x99, 0x60, 0x0, 0x64, 0xac, 0x2, 0x3, 0x20, 0x63, 0x37, 0x18, 0x0, 0x19, 0x67, 0xc0, 0x0, 0xc8, 0xb8, 0xb, 0x6, 0x40, 0xc6, 0x3b, 0x30, 0x50, 0x44, 0x58, 0xa, 0x73, 0x6, 0x0, 0xe9, 0xb4, 0x2d, 0xf5, 0x51, 0xd4, 0xb8, 0xa1, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+static const unsigned char popup_unchecked_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0xff, 0x0, 0xff, 0xff, 0xff, 0xff, 0x9f, 0x18, 0x32, 0xe0, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
static const unsigned char popup_window_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x14, 0x0, 0x0, 0x0, 0x24, 0x8, 0x6, 0x0, 0x0, 0x0, 0x89, 0xf3, 0x1a, 0xa0, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0xb7, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0x96, 0x31, 0x6f, 0xd3, 0x40, 0x18, 0x86, 0x9f, 0xfb, 0x62, 0x27, 0x71, 0x2, 0x49, 0x93, 0x3a, 0x48, 0x91, 0x80, 0x2e, 0x1d, 0x2a, 0x48, 0xa5, 0x22, 0x41, 0xc5, 0x42, 0x18, 0x18, 0x18, 0x18, 0xf9, 0x2b, 0xfc, 0xd, 0xfe, 0x9, 0x7f, 0x80, 0x91, 0x46, 0x95, 0x10, 0xa8, 0x62, 0x48, 0x51, 0x18, 0x58, 0x0, 0x75, 0xa9, 0x4b, 0x1a, 0x2c, 0x48, 0x1a, 0x9f, 0x73, 0xc7, 0x10, 0x87, 0x18, 0xe4, 0x88, 0x56, 0xca, 0xe8, 0x57, 0xba, 0xe1, 0x24, 0xbf, 0xcf, 0xdd, 0x77, 0x5e, 0x1e, 0x58, 0x73, 0x54, 0xc6, 0xbe, 0x5, 0x34, 0x0, 0xf, 0x90, 0x15, 0x3d, 0x3, 0x4c, 0x80, 0x21, 0x70, 0x6, 0xd8, 0x2c, 0xa0, 0xb, 0x6c, 0x27, 0xc0, 0x4d, 0xa0, 0x9c, 0x71, 0xe0, 0x22, 0x36, 0x5, 0xc, 0x80, 0xcf, 0x80, 0x6, 0x70, 0x52, 0xe0, 0x6d, 0x60, 0xb, 0xd8, 0xbc, 0xfb, 0xe0, 0x71, 0xb7, 0xde, 0xf4, 0x3b, 0x8e, 0xe3, 0xd6, 0xb2, 0x68, 0x71, 0xac, 0xc3, 0x1f, 0xc3, 0xb3, 0xe3, 0x8f, 0xef, 0xdf, 0x1c, 0x24, 0x93, 0x0, 0x7c, 0x2, 0xec, 0xe2, 0x6, 0x37, 0x80, 0x9d, 0x42, 0xa1, 0x70, 0xeb, 0xe1, 0xd3, 0xe7, 0x2f, 0x2a, 0x95, 0xeb, 0x7b, 0xc6, 0x18, 0x63, 0xad, 0xc9, 0x1c, 0x59, 0x29, 0x31, 0x22, 0x22, 0xe3, 0xf1, 0xcf, 0xf, 0x6f, 0x5f, 0xbf, 0x7a, 0x39, 0x9b, 0xcd, 0xbe, 0x1, 0x3, 0x20, 0x28, 0x24, 0xdf, 0xdc, 0x4, 0xb6, 0xee, 0xdc, 0xef, 0x3e, 0x69, 0xb6, 0xda, 0xcf, 0xa6, 0x17, 0x63, 0xa6, 0x93, 0xb1, 0x8a, 0x75, 0x44, 0xd6, 0xd2, 0xd1, 0x54, 0x59, 0x6b, 0xf1, 0xbc, 0x6a, 0xbb, 0x5c, 0xad, 0x6, 0xa7, 0x27, 0x5f, 0x4e, 0x80, 0x5f, 0xc0, 0xf7, 0xc5, 0xd, 0x3c, 0xa0, 0x5c, 0x6f, 0xfa, 0x1d, 0x63, 0x8c, 0xd1, 0x51, 0xb4, 0xe2, 0xe9, 0x96, 0xd1, 0xd1, 0x14, 0x6b, 0x8c, 0xa9, 0x6d, 0xb4, 0x76, 0x99, 0xbf, 0xb7, 0x7, 0xcb, 0xbf, 0x28, 0x80, 0x72, 0x1c, 0xb7, 0xb1, 0x6a, 0xcc, 0xac, 0x18, 0x6b, 0xc4, 0x71, 0xdd, 0x46, 0xd2, 0x97, 0x34, 0x70, 0x6d, 0xc9, 0x81, 0x39, 0x30, 0x7, 0xe6, 0xc0, 0x1c, 0x98, 0x3, 0xd7, 0xd, 0x34, 0x80, 0x8d, 0xb5, 0x3e, 0x57, 0x4a, 0xcc, 0x65, 0xcb, 0x4a, 0x89, 0x89, 0xb5, 0x3e, 0x4f, 0xfa, 0xb3, 0x34, 0x70, 0x2, 0x4c, 0xc2, 0x51, 0xd0, 0x17, 0x11, 0x71, 0x8b, 0xa5, 0xff, 0xc2, 0xdc, 0x62, 0x9, 0x11, 0x91, 0x70, 0x14, 0xf4, 0x81, 0x8b, 0x64, 0xfd, 0x71, 0x9b, 0x21, 0x30, 0x1c, 0x1c, 0x1d, 0xf6, 0xea, 0x7e, 0x7b, 0xbf, 0x52, 0xb9, 0x76, 0xcf, 0x2d, 0x96, 0x2e, 0xa5, 0x22, 0x83, 0xa3, 0xc3, 0xde, 0xa2, 0xf, 0x4b, 0xbb, 0x52, 0xc0, 0xe, 0x70, 0x1b, 0xf0, 0x3b, 0xfb, 0xdd, 0x47, 0xb5, 0x8d, 0xd6, 0xae, 0xe3, 0xae, 0x90, 0x25, 0xad, 0xc3, 0x70, 0x14, 0xf4, 0x8f, 0xdf, 0x1d, 0xf4, 0x98, 0xeb, 0xdc, 0x57, 0xfe, 0x91, 0x25, 0xf8, 0x5b, 0xe7, 0x9a, 0xcc, 0xd5, 0xe2, 0xca, 0x3a, 0x97, 0x25, 0x9c, 0x7e, 0xa, 0x78, 0x65, 0xe1, 0x5c, 0x7b, 0x7e, 0x3, 0x2f, 0x8a, 0xb1, 0xd0, 0xbc, 0xa4, 0x7e, 0x33, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x2a, 0x0, 0x0, 0x0, 0x46, 0x8, 0x3, 0x0, 0x0, 0x0, 0x8d, 0x2b, 0xf6, 0x48, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x6e, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0xe8, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x22, 0x0, 0x0, 0x0, 0x1a, 0x19, 0x1c, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x1d, 0x21, 0x17, 0x16, 0x19, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1b, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x1e, 0x1c, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x20, 0x1e, 0x23, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x21, 0x1f, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x22, 0x20, 0x25, 0x0, 0x0, 0x0, 0x20, 0x20, 0x25, 0x20, 0x1d, 0x25, 0x20, 0x1d, 0x22, 0x1d, 0x1d, 0x22, 0x1d, 0x1d, 0x20, 0x1d, 0x1a, 0x20, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x32, 0x30, 0x38, 0xe8, 0xe5, 0xf1, 0xe5, 0xe2, 0xeb, 0xe3, 0xe1, 0xe8, 0xe1, 0xdf, 0xe7, 0xe0, 0xde, 0xe6, 0xdf, 0xdd, 0xe5, 0xde, 0xdc, 0xe4, 0xdd, 0xdb, 0xe3, 0xdc, 0xda, 0xe2, 0xda, 0xd8, 0xe0, 0xd9, 0xd7, 0xdf, 0xd7, 0xd6, 0xdf, 0xd6, 0xd4, 0xdd, 0xd5, 0xd3, 0xdc, 0xd4, 0xd1, 0xdb, 0xd3, 0xd0, 0xda, 0xd1, 0xce, 0xd8, 0xd0, 0xcd, 0xd7, 0xcf, 0xcd, 0xd7, 0xe2, 0xdf, 0xeb, 0x48, 0x46, 0x51, 0x42, 0x40, 0x4b, 0x40, 0x3e, 0x48, 0x40, 0x3d, 0x48, 0x48, 0x45, 0x50, 0x42, 0x3f, 0x4a, 0x3f, 0x3d, 0x48, 0x47, 0x44, 0x50, 0x41, 0x3f, 0x4a, 0x3f, 0x3d, 0x47, 0x41, 0x3e, 0x49, 0x3f, 0x3c, 0x47, 0x46, 0x43, 0x4f, 0x3e, 0x3c, 0x46, 0x40, 0x3e, 0x49, 0x3d, 0x3b, 0x46, 0x45, 0x43, 0x4e, 0x3d, 0x3b, 0x45, 0x44, 0x42, 0x4d, 0x3d, 0x3a, 0x45, 0x3e, 0x3c, 0x47, 0x3c, 0x3a, 0x44, 0x43, 0x42, 0x4c, 0x43, 0x40, 0x4c, 0x3e, 0x3b, 0x46, 0x3b, 0x39, 0x43, 0x43, 0x3f, 0x4c, 0x43, 0x3f, 0x4b, 0x3a, 0x38, 0x42, 0x42, 0x3e, 0x4b, 0x42, 0x3e, 0x49, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3f, 0x3e, 0x48, 0x39, 0x37, 0x40, 0x38, 0x36, 0x40, 0x3e, 0x3d, 0x48, 0x38, 0x36, 0x3f, 0x3e, 0x3d, 0x47, 0x3a, 0x38, 0x41, 0x38, 0x35, 0x3f, 0x37, 0x35, 0x3e, 0x39, 0x36, 0x40, 0x37, 0x34, 0x3e, 0x3d, 0x3a, 0x46, 0x36, 0x34, 0x3d, 0x3d, 0x3a, 0x44, 0x37, 0x35, 0x3f, 0x35, 0x33, 0x3c, 0x46, 0x44, 0x4f, 0xff, 0xff, 0xff, 0x7e, 0xde, 0x1d, 0x81, 0x0, 0x0, 0x0, 0x33, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xa2, 0x3, 0x9, 0x17, 0xc, 0x20, 0xf, 0x2a, 0x5e, 0x12, 0x30, 0x68, 0x46, 0x20, 0x4e, 0xa2, 0x7d, 0x3a, 0x4f, 0xa4, 0x7d, 0x3f, 0x25, 0x60, 0xc0, 0xb8, 0x57, 0x1d, 0xba, 0x59, 0xbd, 0x5b, 0x22, 0xbf, 0x5e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xa1, 0x9f, 0x9e, 0x52, 0x92, 0x15, 0x44, 0x7e, 0xd8, 0x5, 0xc7, 0xf4, 0xac, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x79, 0xa1, 0xdc, 0xd4, 0xd0, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x1, 0xe8, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0xd6, 0xd9, 0x53, 0xd3, 0x60, 0x14, 0xc6, 0xe1, 0x92, 0x5a, 0xa3, 0x44, 0xa3, 0xd6, 0x85, 0xa0, 0xb1, 0x5a, 0xcb, 0xda, 0xbd, 0x7c, 0xb8, 0xef, 0x2b, 0x69, 0x21, 0xd0, 0xda, 0x22, 0x25, 0xd, 0x69, 0x20, 0x60, 0x69, 0x11, 0x2a, 0x22, 0xcb, 0x9f, 0xef, 0x78, 0x97, 0x7e, 0xe7, 0x3d, 0x33, 0x1d, 0xbd, 0x70, 0xfc, 0x5d, 0x3f, 0x77, 0xe7, 0xe2, 0x3d, 0x91, 0xc8, 0x7f, 0xd8, 0x88, 0x60, 0x1a, 0x21, 0x54, 0xcc, 0x3f, 0x84, 0xcd, 0xb, 0x4a, 0x1f, 0x31, 0xfd, 0x1d, 0x7d, 0xcc, 0x4, 0xe8, 0x13, 0x26, 0x40, 0x9f, 0x32, 0x1, 0xfa, 0x8c, 0x9, 0xd0, 0xe7, 0x4c, 0x80, 0xbe, 0x60, 0x2, 0xf4, 0x25, 0x13, 0xa0, 0xaf, 0x98, 0x0, 0x7d, 0xcd, 0x44, 0xa8, 0x22, 0xde, 0x30, 0x49, 0x54, 0x89, 0x9e, 0x13, 0x6f, 0x99, 0x64, 0x1a, 0x3b, 0x2f, 0xde, 0x31, 0x49, 0x54, 0xbd, 0x70, 0x51, 0xbc, 0x67, 0x92, 0xe8, 0xa8, 0x76, 0x49, 0x7c, 0x60, 0x12, 0x97, 0xf5, 0x68, 0x88, 0xea, 0x57, 0xae, 0x8a, 0x8f, 0x4c, 0xe2, 0x5a, 0x7c, 0x34, 0x4c, 0xaf, 0xdf, 0x10, 0x9f, 0x98, 0xc4, 0xcd, 0x5b, 0x21, 0xaa, 0x8c, 0x19, 0xe3, 0xb, 0x56, 0x19, 0x66, 0x2d, 0xdc, 0xbe, 0x63, 0x2a, 0x43, 0xd2, 0xbb, 0x9, 0x7d, 0x58, 0x7a, 0xef, 0x7e, 0x72, 0x58, 0xfa, 0x20, 0x35, 0x36, 0x2c, 0x1d, 0x37, 0x8, 0xad, 0xc0, 0x0, 0x5d, 0x5c, 0xb2, 0x61, 0x4b, 0x8b, 0x32, 0x9d, 0x58, 0x5e, 0xa9, 0xc2, 0x56, 0x96, 0x27, 0x8, 0xad, 0x7d, 0x86, 0xd5, 0x28, 0xad, 0xd7, 0x1a, 0xb0, 0x5a, 0x9d, 0xd2, 0x55, 0x4c, 0x57, 0x1, 0xad, 0x7c, 0x81, 0x55, 0x8, 0x9d, 0x5c, 0xb3, 0x9b, 0x30, 0x7b, 0x6d, 0x52, 0xa2, 0x53, 0xeb, 0x55, 0x7, 0x56, 0x5d, 0x9f, 0x22, 0xb4, 0xe5, 0xc2, 0x5a, 0x94, 0x6e, 0x34, 0x30, 0x6d, 0x6c, 0x10, 0xea, 0xb5, 0x7d, 0x58, 0xdb, 0x93, 0xe9, 0xf4, 0x66, 0x13, 0xd3, 0xe6, 0xe6, 0xb4, 0x4c, 0xb7, 0x9c, 0x0, 0xe6, 0x6c, 0x11, 0xba, 0xed, 0x62, 0xea, 0x6e, 0x13, 0xba, 0xe3, 0x7e, 0x85, 0xb9, 0x3b, 0x84, 0x96, 0xfd, 0xe, 0xcc, 0x2f, 0x13, 0xba, 0xeb, 0x77, 0x61, 0xfe, 0x2e, 0xa1, 0x76, 0xd0, 0x83, 0x5, 0x36, 0xa1, 0x7b, 0xc1, 0x37, 0x58, 0xb0, 0x27, 0xd3, 0x99, 0xfd, 0x83, 0x3e, 0xec, 0x60, 0x7f, 0x46, 0xa2, 0xb3, 0xad, 0xce, 0x77, 0x58, 0xa7, 0x35, 0x2b, 0xd3, 0xf6, 0x21, 0xa6, 0x87, 0x6d, 0x40, 0x7f, 0xc0, 0x0, 0x3d, 0xea, 0xfd, 0x84, 0xf5, 0x8e, 0x8, 0x75, 0xfa, 0x98, 0xf6, 0x1d, 0x42, 0x8f, 0x39, 0x7a, 0x4c, 0xe9, 0xc9, 0x29, 0xec, 0x64, 0x90, 0x46, 0x92, 0xa9, 0xb4, 0x75, 0xca, 0x64, 0xa5, 0x53, 0xc9, 0xc8, 0x1f, 0xd2, 0xc, 0x4f, 0x33, 0x3, 0x54, 0x4f, 0x64, 0x79, 0x9a, 0x4d, 0xe8, 0x21, 0x6a, 0xe6, 0xf2, 0x1e, 0x47, 0xbd, 0x7c, 0xce, 0xc, 0xd1, 0x42, 0xb1, 0x54, 0xef, 0x62, 0xd9, 0x3d, 0x2b, 0x15, 0xb, 0x21, 0xaa, 0x6a, 0xc6, 0xdc, 0x99, 0x67, 0x81, 0xbc, 0xfa, 0x9c, 0xa1, 0xa9, 0x21, 0x1a, 0x35, 0xe3, 0x46, 0x29, 0x9f, 0xcd, 0xa4, 0xa5, 0x32, 0xd9, 0x7c, 0xc9, 0x88, 0x9b, 0xe1, 0xe1, 0x54, 0x62, 0xa6, 0x56, 0xcc, 0x25, 0x52, 0xa4, 0x44, 0xae, 0xa8, 0x99, 0xb1, 0xd0, 0x5, 0x7e, 0x3f, 0x4, 0x6a, 0xc1, 0xd4, 0x93, 0x24, 0xdd, 0x2c, 0xa8, 0xd1, 0x1, 0xf9, 0xf, 0xfb, 0x5, 0x66, 0x6f, 0x2a, 0x9a, 0xa8, 0x51, 0x81, 0xce, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char progress_bar_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x12, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x60, 0x14, 0x8c, 0x2, 0x8, 0x0, 0x0, 0x4, 0x10, 0x0, 0x1, 0x7f, 0x4d, 0x78, 0x8e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0x27, 0x27, 0x27, 0xe1, 0x1d, 0x66, 0x4d, 0x0, 0x0, 0x0, 0xc, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xb7, 0x4a, 0xbe, 0x33, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x44, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xc5, 0xcf, 0x31, 0x16, 0x0, 0x10, 0xc, 0x44, 0xc1, 0x4d, 0x84, 0x4, 0xc1, 0xfd, 0x6f, 0xab, 0xc9, 0x53, 0x70, 0x0, 0x53, 0x6e, 0xb5, 0x1f, 0x20, 0x4e, 0x12, 0x12, 0x13, 0x40, 0xb9, 0xa8, 0x5, 0x2d, 0x99, 0xc0, 0xb5, 0x75, 0xf, 0xbd, 0x55, 0x86, 0xe8, 0x98, 0x2b, 0xcc, 0xa1, 0x2, 0x31, 0x5f, 0x87, 0xdb, 0xbf, 0xe1, 0x3e, 0xf6, 0x5c, 0x7f, 0xe2, 0xee, 0xfc, 0xd, 0x60, 0x3b, 0xa, 0x1d, 0x9e, 0x6a, 0x29, 0x33, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char progress_fill_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xea, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x31, 0x6e, 0xc2, 0x40, 0x10, 0x45, 0xdf, 0xd8, 0x96, 0x70, 0xe9, 0xd4, 0xb9, 0x41, 0x14, 0x29, 0x74, 0xe4, 0x10, 0x3e, 0x1, 0xd4, 0x88, 0xca, 0x14, 0x6e, 0xd3, 0xd0, 0xd0, 0x52, 0xe0, 0xce, 0x35, 0x1c, 0x21, 0x67, 0x0, 0x3a, 0x17, 0x28, 0x37, 0xa0, 0x76, 0x83, 0x40, 0x1b, 0xc9, 0x99, 0x14, 0xb1, 0x2d, 0x2b, 0xc6, 0xc9, 0x52, 0xc1, 0x97, 0xb6, 0xd8, 0xaf, 0xff, 0xdf, 0x8c, 0x56, 0xb, 0xb7, 0x96, 0xfc, 0x36, 0x22, 0x5d, 0xf6, 0x2, 0xcc, 0x44, 0xd0, 0x21, 0xf0, 0x5c, 0xda, 0x7b, 0x60, 0x9d, 0xe3, 0xa7, 0x89, 0x4c, 0x4d, 0x27, 0xe0, 0x4d, 0x17, 0x8f, 0x2e, 0xc5, 0x3b, 0xe8, 0x4b, 0xc7, 0xc0, 0xac, 0xc0, 0xb, 0xe7, 0x12, 0x1f, 0x5a, 0x80, 0x48, 0x97, 0xbd, 0x7, 0xcc, 0xee, 0x8f, 0x72, 0xd, 0xc9, 0xf1, 0x5f, 0xab, 0x4d, 0x9c, 0xca, 0xd, 0x30, 0x13, 0x8b, 0x32, 0x40, 0x3f, 0xe0, 0x3c, 0xae, 0x2e, 0x35, 0x40, 0xd0, 0x91, 0x45, 0xb9, 0xcc, 0x4a, 0x9d, 0x75, 0x1a, 0xf6, 0x93, 0x2d, 0x0, 0xa4, 0x7a, 0xdc, 0x26, 0xe0, 0x1a, 0xe9, 0xd7, 0x5, 0x80, 0x7e, 0x5c, 0x41, 0xa8, 0xb3, 0xcd, 0xd, 0x56, 0xd6, 0xf3, 0xd1, 0x75, 0xb, 0x90, 0xe3, 0xa7, 0x40, 0x66, 0xd1, 0xcf, 0x5c, 0xce, 0x69, 0xb, 0x90, 0xc8, 0xd4, 0x14, 0x78, 0xe1, 0x3f, 0x90, 0xac, 0xc0, 0xb, 0x67, 0x32, 0xfb, 0x6c, 0x1, 0x0, 0xe6, 0x12, 0x1f, 0x1c, 0x4e, 0x3, 0x45, 0x23, 0x60, 0xb, 0x72, 0xfc, 0x39, 0x6c, 0x14, 0x8d, 0x1c, 0x4e, 0x83, 0xe6, 0x2f, 0xbc, 0xf, 0x7d, 0x3, 0xd2, 0x20, 0x45, 0xab, 0xcc, 0x7a, 0x21, 0xba, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x26, 0x78, 0x80, 0xa6, 0xcf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x60, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0x18, 0x78, 0xc0, 0x8, 0x63, 0x38, 0x58, 0x7c, 0xde, 0xf8, 0x45, 0xc, 0xc2, 0xe6, 0x79, 0xc5, 0xeb, 0x7f, 0xe0, 0x4, 0x9a, 0x2, 0xe3, 0x97, 0x1f, 0xb9, 0xff, 0x70, 0x43, 0xd8, 0x2c, 0x5f, 0xf9, 0xbf, 0x9e, 0x15, 0x87, 0xb2, 0x61, 0xa, 0xbe, 0x88, 0xfd, 0x81, 0x1b, 0xfb, 0x87, 0xfb, 0xb, 0x37, 0x8c, 0xcd, 0x44, 0xc8, 0xd, 0x54, 0x54, 0xc0, 0xf3, 0x8a, 0xe5, 0x2b, 0x8c, 0xcd, 0xf2, 0x95, 0xe7, 0x15, 0x86, 0x2, 0x5e, 0x7f, 0xfe, 0xaf, 0xec, 0xc, 0x10, 0xc8, 0xff, 0x95, 0xd7, 0x9f, 0xe6, 0x1, 0x4c, 0x2, 0x0, 0x0, 0x68, 0x3f, 0x16, 0xd7, 0xea, 0x7c, 0xdd, 0x1a, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char radio_checked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xc5, 0x52, 0xb1, 0x4e, 0x1b, 0x41, 0x14, 0x9c, 0x59, 0xe1, 0xf5, 0x5a, 0x72, 0x89, 0x23, 0xb9, 0x31, 0x82, 0x8, 0x17, 0x88, 0xd2, 0x88, 0x9e, 0x6, 0x92, 0x8a, 0x54, 0x40, 0x41, 0x93, 0xce, 0xb4, 0x14, 0x28, 0x1f, 0x41, 0x84, 0xf8, 0x0, 0xe8, 0x5d, 0xb9, 0x33, 0xe4, 0xb, 0x12, 0xc9, 0x1f, 0x80, 0xac, 0x88, 0x28, 0xd7, 0x58, 0xd6, 0xc9, 0xad, 0xa5, 0xdb, 0xd3, 0xdd, 0xd0, 0xec, 0x21, 0xc3, 0x1d, 0xb5, 0x5f, 0xb3, 0xa3, 0xd1, 0x7b, 0xf3, 0x66, 0xdf, 0x7b, 0xc0, 0xaa, 0x83, 0xef, 0x9, 0x49, 0xb5, 0x28, 0x8a, 0xbe, 0x49, 0x3a, 0x4, 0xb0, 0x15, 0xe8, 0x67, 0x92, 0xf, 0x9d, 0x4e, 0x67, 0x48, 0x32, 0xfd, 0x50, 0x60, 0x3a, 0x9d, 0xb6, 0xbc, 0xf7, 0x3f, 0x25, 0x6d, 0x57, 0x76, 0x23, 0x27, 0xd6, 0xda, 0xcb, 0x76, 0xbb, 0x1d, 0x17, 0x9c, 0x59, 0xee, 0x5c, 0x14, 0x93, 0x9c, 0x1, 0xf8, 0x61, 0xad, 0x3d, 0xb0, 0xd6, 0x1e, 0x48, 0xba, 0x22, 0xf9, 0x5f, 0x52, 0xd7, 0x7b, 0x7f, 0x2d, 0xa9, 0x56, 0x12, 0x8, 0xb6, 0xb7, 0x49, 0xce, 0x16, 0x8b, 0xc5, 0x77, 0x63, 0xcc, 0x4e, 0x9a, 0xa6, 0x3, 0xef, 0xfd, 0x80, 0xe4, 0xae, 0x31, 0xa6, 0x4f, 0x72, 0x26, 0xa9, 0x1b, 0x45, 0xd1, 0x71, 0x95, 0x83, 0xa3, 0xf0, 0xde, 0x34, 0x1a, 0x8d, 0xd3, 0x3c, 0xcf, 0xcf, 0x25, 0xad, 0x3, 0x58, 0x7, 0x70, 0x9e, 0x65, 0xd9, 0x19, 0x80, 0xdb, 0x90, 0x73, 0x58, 0x12, 0x0, 0xb0, 0x9, 0x0, 0xd6, 0xda, 0x3f, 0x24, 0xbf, 0x54, 0x8c, 0xe0, 0x6b, 0xbd, 0x5e, 0xff, 0x1d, 0x70, 0x31, 0xdc, 0x37, 0x2, 0xaf, 0x21, 0xa9, 0x8a, 0xce, 0xe7, 0xf3, 0x79, 0x69, 0x6b, 0xcb, 0x2, 0xff, 0x0, 0x20, 0x49, 0x92, 0x3d, 0x0, 0xa3, 0xa, 0x81, 0x51, 0xb3, 0xd9, 0xdc, 0xf, 0xf8, 0xb9, 0x20, 0xd7, 0xa, 0x40, 0x72, 0x24, 0x69, 0xc7, 0x18, 0x73, 0x61, 0x8c, 0xe9, 0x67, 0x59, 0x6, 0x0, 0xc5, 0x57, 0x46, 0x49, 0x92, 0xc, 0x9c, 0x73, 0x77, 0x21, 0xf7, 0xb1, 0xe4, 0x20, 0x1c, 0xc9, 0x44, 0xd2, 0x46, 0x9e, 0xe7, 0xf7, 0x24, 0x9f, 0x9c, 0x73, 0x27, 0xce, 0xb9, 0x93, 0x80, 0xef, 0x24, 0x7d, 0x22, 0x39, 0x89, 0xe3, 0x78, 0xf8, 0xda, 0x78, 0xd9, 0x63, 0x38, 0xa4, 0x6b, 0x49, 0xdd, 0xaa, 0x21, 0x54, 0x1d, 0x52, 0x69, 0x28, 0xe3, 0xf1, 0xb8, 0xd6, 0x6a, 0xb5, 0x8e, 0xc3, 0xaa, 0x3e, 0x87, 0xc2, 0xbf, 0x0, 0x7e, 0xc5, 0x71, 0x3c, 0xec, 0xf5, 0x7a, 0xe9, 0xfb, 0x9a, 0xd5, 0xc6, 0xb, 0x17, 0xe, 0xab, 0x4e, 0xf1, 0x77, 0xc8, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x45, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd8, 0xd8, 0xd8, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xd3, 0xd3, 0xd3, 0xa2, 0xa2, 0xa2, 0x79, 0x79, 0x79, 0x73, 0x73, 0x73, 0x1c, 0x1c, 0x1c, 0x3, 0x3, 0x3, 0x0, 0x0, 0x0, 0xff, 0xff, 0xff, 0xa, 0x69, 0x4, 0xd4, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x16, 0x7c, 0xd1, 0xa8, 0x19, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x69, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x6d, 0x8f, 0xdb, 0xe, 0xc0, 0x20, 0x8, 0x43, 0xdd, 0xc5, 0x3b, 0x9d, 0xa8, 0xec, 0xff, 0x7f, 0x75, 0x6a, 0x96, 0x2c, 0x8b, 0xf6, 0xad, 0x27, 0x14, 0x8a, 0x52, 0x2b, 0x69, 0x63, 0x9d, 0xb3, 0x46, 0xbf, 0x76, 0xf3, 0x21, 0x12, 0x40, 0x31, 0xf8, 0x7d, 0x0, 0x7f, 0x35, 0xdb, 0x45, 0x97, 0x1f, 0xf3, 0x81, 0x90, 0x38, 0x67, 0x4e, 0xa0, 0xd0, 0x53, 0x26, 0x22, 0x95, 0x2a, 0x52, 0x4b, 0x42, 0x34, 0xd, 0x58, 0x2, 0xd7, 0xbb, 0xa9, 0x32, 0xc8, 0x36, 0xe0, 0x80, 0x2c, 0x1d, 0x48, 0x6, 0xdc, 0xa, 0x4c, 0x91, 0x69, 0xe9, 0x74, 0x76, 0x2a, 0xa6, 0x8e, 0xaf, 0xfa, 0xb9, 0x7e, 0xee, 0xaf, 0x7, 0xb9, 0xfb, 0x8, 0xe7, 0x90, 0x1c, 0x65, 0x49, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char radio_unchecked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x4b, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x52, 0x3d, 0x4b, 0x3, 0x41, 0x10, 0x7d, 0x73, 0x98, 0x4d, 0x73, 0x62, 0xb5, 0x42, 0x9a, 0x80, 0xca, 0xdd, 0x2f, 0x88, 0x68, 0x9d, 0x26, 0x96, 0xf1, 0x7, 0x58, 0xd9, 0xd9, 0xa4, 0xb0, 0x10, 0x7f, 0x44, 0x44, 0xd2, 0xdb, 0xd9, 0xd9, 0xa4, 0xf3, 0xa3, 0xb3, 0x53, 0x8, 0xfe, 0x80, 0x60, 0x22, 0x5e, 0x13, 0xc2, 0x92, 0x46, 0x21, 0x70, 0x9b, 0xe2, 0xd9, 0xec, 0x86, 0xcb, 0xdd, 0x5, 0x4b, 0x9d, 0x66, 0x87, 0x61, 0xdf, 0x7b, 0xf3, 0x66, 0x6, 0xf8, 0xeb, 0x90, 0x7c, 0x81, 0x64, 0x25, 0x49, 0x92, 0x63, 0x92, 0x2d, 0x0, 0xbb, 0xae, 0x3c, 0x16, 0x91, 0x87, 0x7a, 0xbd, 0xde, 0x17, 0x91, 0xc5, 0x5a, 0x82, 0xc9, 0x64, 0xa2, 0xad, 0xb5, 0x57, 0x24, 0xa3, 0x52, 0x35, 0x91, 0xa1, 0x52, 0xea, 0xbc, 0x56, 0xab, 0x19, 0x5f, 0xb, 0xb2, 0xca, 0x1e, 0x2c, 0x22, 0x53, 0x0, 0x97, 0x4a, 0xa9, 0xa6, 0x52, 0xaa, 0x49, 0xf2, 0x42, 0x44, 0x3e, 0x49, 0xc6, 0xd6, 0xda, 0x2e, 0xc9, 0x8a, 0xc7, 0x6d, 0xf8, 0xc4, 0xb5, 0x1d, 0x89, 0xc8, 0xd4, 0x5a, 0x7b, 0x12, 0x45, 0xd1, 0x57, 0x46, 0xfc, 0xd9, 0x18, 0xf3, 0x36, 0x9f, 0xcf, 0x6f, 0x49, 0xc6, 0x49, 0x92, 0xb4, 0x1, 0xdc, 0xe5, 0x3b, 0x38, 0x72, 0xef, 0x75, 0xe, 0xc, 0x0, 0xd0, 0x5a, 0x7f, 0x3, 0xe8, 0xb9, 0x3f, 0xad, 0x82, 0x5, 0x0, 0x3b, 0x0, 0xa0, 0x94, 0x7a, 0x2d, 0xf3, 0xf, 0x0, 0xd5, 0x6a, 0xf5, 0xc5, 0xa5, 0x7e, 0xb8, 0x2b, 0x4, 0xbf, 0xc6, 0x6c, 0x36, 0x2b, 0x6c, 0x2d, 0x4b, 0xf0, 0x1, 0x0, 0x69, 0x9a, 0xee, 0xaf, 0x23, 0x8, 0xc3, 0xf0, 0xc0, 0xa5, 0xe3, 0x2, 0x81, 0x88, 0xdc, 0x3, 0x40, 0x10, 0x4, 0x67, 0xc6, 0x98, 0xcd, 0x3c, 0x78, 0x34, 0x1a, 0x6d, 0x1, 0xe8, 0xb8, 0xbf, 0x8f, 0x4b, 0x9c, 0x4f, 0xdc, 0x1, 0xdd, 0x90, 0x8c, 0xdd, 0x1a, 0x7b, 0xde, 0x73, 0x9a, 0xa6, 0x87, 0x0, 0x3a, 0x24, 0xb7, 0x45, 0x64, 0x68, 0x8c, 0x39, 0x6d, 0x34, 0x1a, 0x8b, 0x15, 0x2, 0x60, 0x79, 0x48, 0x5d, 0x92, 0x71, 0x99, 0x85, 0xb2, 0x43, 0x2a, 0xc, 0x65, 0x30, 0x18, 0x54, 0xb4, 0xd6, 0x6d, 0xb7, 0xaa, 0x3d, 0x7, 0x7c, 0x7, 0xf0, 0x64, 0x8c, 0xe9, 0x7b, 0xe5, 0xff, 0x13, 0x3f, 0xc5, 0x34, 0x9d, 0x5, 0x4, 0x6a, 0x0, 0xfe, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4, 0x3, 0x4, 0x9, 0x9, 0x9, 0x6, 0x6, 0x6, 0xa, 0xa, 0xb, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x7f, 0x7f, 0x82, 0xd9, 0xd9, 0xd9, 0x47, 0x47, 0x48, 0xff, 0xff, 0xff, 0xbd, 0x7d, 0x89, 0x66, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x88, 0xd1, 0xf7, 0x64, 0xf6, 0x2, 0xb3, 0xed, 0xd7, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xe, 0x6f, 0xbd, 0x30, 0x4f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4a, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x80, 0xb0, 0x8a, 0xf6, 0x54, 0x10, 0x2d, 0xb9, 0xfa, 0xcc, 0x99, 0x5d, 0x93, 0x80, 0x8c, 0xb9, 0x67, 0x80, 0xe0, 0x26, 0x3, 0x3, 0xeb, 0x1a, 0x10, 0xe3, 0x54, 0x0, 0x3, 0xdb, 0x1e, 0x10, 0xe3, 0x74, 0x2, 0x3, 0xfb, 0x19, 0x30, 0x28, 0x60, 0xe0, 0x80, 0x30, 0x1a, 0x10, 0xc, 0xb8, 0x14, 0x5c, 0x31, 0x5c, 0x3b, 0xdc, 0x40, 0x6, 0x4b, 0x90, 0x15, 0x53, 0x90, 0x2d, 0x85, 0x2, 0x0, 0x37, 0xca, 0x3d, 0x81, 0xc4, 0xfc, 0x38, 0x7b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char reference_border_png[] = {
@@ -283,111 +287,115 @@ static const unsigned char reference_border_png[] = {
};
static const unsigned char scroll_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x3a, 0x0, 0x0, 0x2, 0x4c, 0x0, 0x1, 0x4e, 0x94, 0x8c, 0x4d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x48, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x40, 0x3e, 0x4a, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x20, 0x20, 0x24, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1e, 0x1e, 0x23, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0x34, 0x3f, 0xa6, 0x65, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x4, 0x19, 0x40, 0x5d, 0x66, 0x28, 0x93, 0xf0, 0xfc, 0x94, 0xfc, 0xfd, 0x67, 0x1a, 0x96, 0x95, 0x1c, 0xf0, 0x43, 0x52, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x17, 0xb, 0xd6, 0x98, 0x8f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x5c, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x55, 0x8e, 0x49, 0xe, 0xc0, 0x20, 0xc, 0x3, 0x3, 0x61, 0x9, 0x3b, 0x61, 0xfb, 0xff, 0x53, 0x4b, 0x5b, 0x55, 0x15, 0x73, 0x1b, 0xc9, 0xb2, 0xd, 0x20, 0x24, 0x2a, 0xad, 0x15, 0x4a, 0x1, 0x20, 0x8c, 0x25, 0xc7, 0xec, 0xc8, 0x1a, 0x1, 0xd2, 0x87, 0xd6, 0xc7, 0xe8, 0x2d, 0x78, 0x9, 0x48, 0x6d, 0xae, 0xcd, 0x6c, 0x84, 0xa0, 0x62, 0x5f, 0xf, 0x3d, 0x2a, 0x48, 0x3c, 0x5e, 0x19, 0x9c, 0x4e, 0x39, 0x62, 0x47, 0x41, 0x2e, 0x5f, 0x75, 0xc9, 0x7b, 0xb4, 0x52, 0x64, 0x8e, 0x54, 0xcd, 0x7d, 0xe1, 0xbf, 0x73, 0x1, 0x30, 0x2f, 0x7, 0x53, 0x16, 0x34, 0xbd, 0xfa, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_down_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x70, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xd5, 0xcf, 0x31, 0xe, 0xc2, 0x50, 0xc, 0x3, 0xd0, 0xe7, 0x76, 0x5, 0xe, 0xd0, 0x1b, 0x20, 0xb1, 0xf7, 0xfe, 0x33, 0x23, 0x48, 0x48, 0x1d, 0x19, 0x38, 0x1, 0x6b, 0x9, 0x4b, 0x2b, 0x7d, 0x2a, 0xb1, 0x83, 0x97, 0x28, 0x89, 0x63, 0xc7, 0xfc, 0x3f, 0x2, 0x55, 0x35, 0xa2, 0xc3, 0x25, 0xc9, 0xb3, 0x25, 0x54, 0xd5, 0xe, 0x27, 0xcc, 0x49, 0xce, 0x5d, 0xb3, 0xdb, 0x63, 0xac, 0xaa, 0xa1, 0x21, 0xf, 0x18, 0x71, 0x58, 0xc5, 0x57, 0x87, 0x1e, 0x47, 0xac, 0xe4, 0xc7, 0x52, 0xdb, 0xfe, 0x96, 0x64, 0xce, 0xc6, 0x7e, 0x58, 0xe, 0xfb, 0x65, 0xf4, 0xc2, 0x94, 0xe4, 0xfe, 0x91, 0xe1, 0xcb, 0xcf, 0x70, 0xdd, 0x66, 0xfa, 0x41, 0xbc, 0x1, 0xb0, 0x67, 0x22, 0xbf, 0x25, 0xb5, 0x86, 0x91, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_down_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xd5, 0x8f, 0x3d, 0xe, 0x1, 0x51, 0x18, 0x45, 0xcf, 0x7d, 0x44, 0xc1, 0x52, 0x14, 0xa, 0xb, 0x20, 0xb6, 0x21, 0xf1, 0xa6, 0xd7, 0x33, 0xcd, 0x4c, 0x31, 0x1a, 0x19, 0x95, 0xc2, 0xb4, 0x7e, 0x96, 0xf3, 0x7a, 0x4b, 0x31, 0xd1, 0xf0, 0x69, 0x5e, 0x18, 0x62, 0x1, 0xdc, 0xf2, 0xe6, 0xe6, 0xe4, 0x5c, 0xf8, 0xff, 0x8, 0x20, 0xb7, 0x32, 0x80, 0x3a, 0xc6, 0x6d, 0xba, 0x52, 0x7a, 0x6e, 0xe, 0x32, 0x5b, 0xf7, 0x85, 0x3b, 0x82, 0x5d, 0xa, 0x2d, 0x47, 0x2e, 0xf6, 0x6, 0x36, 0x10, 0x2e, 0x64, 0x56, 0x26, 0xaf, 0x71, 0x99, 0x8, 0x17, 0x80, 0x21, 0xa8, 0x5, 0xd0, 0x6, 0xa8, 0xd1, 0xa4, 0xb, 0x3b, 0x30, 0x2f, 0xd8, 0xe7, 0xb6, 0x19, 0x47, 0x8e, 0x8f, 0x1a, 0x7, 0x51, 0xcf, 0x9f, 0x4a, 0xd, 0xe2, 0x4c, 0x50, 0x1, 0xbd, 0x58, 0x5d, 0x81, 0xb4, 0xd0, 0x62, 0xfb, 0xf6, 0xe1, 0x8b, 0xf3, 0x9, 0x30, 0xe3, 0xee, 0x3f, 0x3f, 0xfd, 0x60, 0x1e, 0x29, 0x1e, 0x2d, 0x53, 0x18, 0xb0, 0x91, 0xaf, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x33, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xf1, 0x33, 0x66, 0x2, 0x1, 0x2a, 0xa3, 0x73, 0xe6, 0xcc, 0x19, 0x10, 0x35, 0x40, 0x1, 0x8, 0xa3, 0x73, 0x6, 0x1, 0x73, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0x5a, 0xfa, 0x3d, 0xf9, 0xfa, 0xe2, 0x64, 0xe2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_left_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x84, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x95, 0x8f, 0x31, 0x12, 0x41, 0x41, 0x10, 0x44, 0x5f, 0xfb, 0x32, 0x94, 0x7c, 0x5d, 0x0, 0x45, 0xe6, 0xfe, 0x7, 0x90, 0x7e, 0x85, 0xb, 0xd8, 0xb, 0x90, 0xd2, 0x92, 0xd, 0xd4, 0xfa, 0xf3, 0x97, 0xce, 0x7a, 0x5e, 0xf5, 0x4c, 0xf, 0xfc, 0x29, 0xd, 0xd, 0x6d, 0x77, 0xc0, 0x1, 0xb0, 0xa4, 0xe3, 0x27, 0x9b, 0x4, 0x8b, 0x36, 0xc0, 0x12, 0xe8, 0x6a, 0xf0, 0x15, 0xb0, 0xbd, 0x2, 0x12, 0xf0, 0x2, 0x4e, 0xa3, 0x1, 0xdb, 0x73, 0x60, 0x5d, 0xec, 0x59, 0xd2, 0xbd, 0x75, 0x61, 0x5f, 0x6a, 0x64, 0x49, 0x79, 0xa8, 0x6b, 0xf4, 0x43, 0xa8, 0x3a, 0xd0, 0x3, 0x4f, 0x20, 0xd9, 0x4e, 0xcd, 0x80, 0xa4, 0x7, 0x70, 0x2d, 0x76, 0x6b, 0x7b, 0xd1, 0xac, 0x24, 0xe9, 0x6, 0xe4, 0xc2, 0x76, 0x35, 0x9f, 0x6, 0x55, 0x2f, 0xc0, 0xc, 0x70, 0xc0, 0x7f, 0xd7, 0x1b, 0x9c, 0x80, 0x1f, 0x32, 0x93, 0x39, 0x2b, 0x5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x3e, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x19, 0x33, 0xa1, 0x8c, 0xae, 0x55, 0x50, 0xc6, 0x2e, 0x28, 0xa3, 0x7b, 0xf7, 0x6e, 0x8, 0xa3, 0xe7, 0xcc, 0x19, 0xa8, 0x14, 0x9c, 0xd1, 0x7b, 0x17, 0xa6, 0xfd, 0x1d, 0x86, 0x81, 0x60, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0xcc, 0x4e, 0x3f, 0xd1, 0x4, 0x90, 0xbf, 0x60, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_left_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa9, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x95, 0x8f, 0x3d, 0xe, 0x82, 0x60, 0x10, 0x44, 0xdf, 0x82, 0x85, 0xf9, 0x8c, 0xf7, 0x30, 0xb1, 0xb0, 0xb4, 0xf2, 0x24, 0x16, 0x48, 0xad, 0xa5, 0x7f, 0xd, 0x16, 0xd0, 0x20, 0xd6, 0xc6, 0x52, 0x29, 0x3c, 0x86, 0x17, 0xb0, 0xf7, 0x2a, 0xc4, 0x84, 0x90, 0xb5, 0xa0, 0x51, 0xfc, 0x0, 0x9d, 0x72, 0x67, 0x27, 0xf3, 0x6, 0xfe, 0x94, 0xd8, 0x8e, 0x4b, 0x3d, 0xf4, 0xc, 0x7a, 0x3, 0xc9, 0x43, 0x59, 0x4d, 0xde, 0x3d, 0xc7, 0x16, 0x30, 0x70, 0x4, 0xc6, 0x40, 0xbf, 0xea, 0x7d, 0x5, 0x76, 0xba, 0xf7, 0x41, 0x3d, 0xe0, 0xa9, 0x14, 0x5e, 0x23, 0x52, 0xa0, 0xf1, 0x50, 0x70, 0xee, 0x80, 0x51, 0xf0, 0x23, 0x59, 0x5f, 0x1a, 0x1b, 0x4, 0xf7, 0x5a, 0x12, 0x49, 0x6a, 0x7b, 0xae, 0xdd, 0xd0, 0xa4, 0x8f, 0x80, 0x52, 0x4c, 0x81, 0xc, 0xd4, 0xb, 0x34, 0x99, 0xb5, 0x6, 0x22, 0xd9, 0x3e, 0x40, 0x17, 0x25, 0x1e, 0xa7, 0x40, 0xe3, 0x51, 0x2b, 0x52, 0x28, 0x9b, 0x33, 0x48, 0xa, 0x74, 0x5, 0x37, 0xad, 0xfa, 0x1d, 0x5b, 0x6d, 0x6, 0x73, 0x3, 0x3, 0x20, 0xaf, 0x5f, 0xf3, 0xa3, 0x5e, 0xf4, 0x92, 0x29, 0x8d, 0x1, 0xf8, 0x4f, 0x56, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0x2a, 0x13, 0xff, 0x12, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x10, 0x95, 0xb2, 0xd, 0x2c, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xcf, 0xcb, 0xe, 0x80, 0x20, 0xc, 0x44, 0xd1, 0xa2, 0x96, 0x47, 0x7, 0xe4, 0xff, 0xff, 0x16, 0xdc, 0x90, 0xe, 0xc6, 0x78, 0x97, 0x27, 0x69, 0xd3, 0x8a, 0x4, 0x75, 0x85, 0x43, 0x62, 0xca, 0xae, 0x14, 0x45, 0x33, 0xa5, 0xdf, 0x50, 0xa, 0x83, 0x99, 0x11, 0xa0, 0xa2, 0x7a, 0x0, 0xd0, 0xe0, 0xa1, 0x3d, 0xd1, 0xc8, 0x3d, 0xe3, 0xa5, 0xbd, 0x6f, 0x30, 0xe5, 0xef, 0xb0, 0x5, 0xaf, 0xe7, 0x4e, 0x7e, 0xff, 0x1a, 0xb, 0x26, 0x7, 0xac, 0xd9, 0xa3, 0x51, 0xe3, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_right_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x82, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x95, 0x90, 0x3b, 0xe, 0xc2, 0x40, 0x10, 0x43, 0x9f, 0x49, 0xb, 0xa2, 0xdf, 0x5c, 0x80, 0x8f, 0x68, 0xb9, 0xff, 0x1, 0xe8, 0x50, 0x2, 0x17, 0x60, 0x7b, 0x4, 0xed, 0x62, 0xa, 0xb6, 0x8a, 0x46, 0x59, 0xe2, 0x6e, 0x3c, 0x7a, 0x63, 0x6b, 0x60, 0xa1, 0x34, 0x35, 0x6c, 0x9f, 0xab, 0x7f, 0x91, 0x54, 0xa6, 0xfb, 0x55, 0x70, 0xa4, 0x3, 0xb6, 0xc0, 0x3e, 0x4a, 0x88, 0x80, 0x2b, 0x50, 0x80, 0x64, 0x3b, 0x35, 0x1, 0x49, 0x6f, 0xe0, 0x5e, 0xc7, 0x83, 0xed, 0x4d, 0x2b, 0x1, 0x49, 0xf, 0x20, 0xd7, 0xfd, 0xb1, 0x9, 0xcc, 0x29, 0x4, 0x6c, 0xf7, 0x40, 0x2, 0x3e, 0xc0, 0x30, 0xb, 0xd8, 0x5e, 0x3, 0xbb, 0x3a, 0x8e, 0x92, 0x5e, 0xad, 0x84, 0x13, 0xbf, 0xd7, 0x66, 0x49, 0xf9, 0x9f, 0x4a, 0x5, 0x78, 0x2, 0xb7, 0xa8, 0xee, 0x62, 0x7d, 0x1, 0x99, 0xba, 0x20, 0x14, 0x78, 0xfe, 0x46, 0x82, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0x59, 0x59, 0x59, 0x8e, 0x47, 0x76, 0xf1, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x40, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0x51, 0x18, 0x33, 0x61, 0x8c, 0x59, 0x2b, 0xa0, 0x8c, 0x5d, 0xab, 0xa0, 0x8c, 0xdd, 0xbb, 0x77, 0x40, 0x18, 0x67, 0xce, 0x9c, 0x80, 0x31, 0xa0, 0x52, 0x77, 0x6f, 0x40, 0x19, 0xef, 0x30, 0xc, 0x84, 0x30, 0xe0, 0x96, 0x1a, 0x42, 0x9c, 0x21, 0x2, 0x0, 0xfd, 0x36, 0x40, 0x93, 0xf1, 0x83, 0x5f, 0xf2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_right_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa8, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0x95, 0x90, 0x2b, 0xe, 0xc2, 0x50, 0x10, 0x45, 0xcf, 0x3c, 0x4, 0xa4, 0x61, 0x27, 0x8, 0x14, 0xb, 0x60, 0x1f, 0x24, 0xb4, 0x41, 0x82, 0xe5, 0x63, 0x5e, 0x5, 0x35, 0xe5, 0x63, 0x9, 0x8a, 0x50, 0x4, 0x2b, 0x41, 0x81, 0x67, 0x29, 0x7d, 0x41, 0x75, 0x30, 0x8, 0xd2, 0x6f, 0x7a, 0xe5, 0xdc, 0x39, 0x33, 0x77, 0x6, 0x5a, 0x4a, 0xf2, 0x85, 0x50, 0xf, 0xf, 0xd0, 0xae, 0x43, 0xc6, 0x47, 0x59, 0xa6, 0x79, 0xdf, 0x14, 0x67, 0x68, 0x1f, 0x18, 0x79, 0x70, 0x2a, 0xdb, 0x50, 0x0, 0x94, 0x6c, 0x2, 0x38, 0xd0, 0xa9, 0xd5, 0xbd, 0xdf, 0x8, 0x44, 0xb2, 0x79, 0x83, 0x2e, 0x7e, 0x79, 0xcf, 0x56, 0xe3, 0x61, 0x43, 0x24, 0xd8, 0xca, 0xfa, 0x2a, 0x90, 0x0, 0x3d, 0xc1, 0x5c, 0x1a, 0x81, 0x3a, 0x95, 0x2, 0xa1, 0xee, 0x2, 0x5, 0x1f, 0xf8, 0x28, 0xd9, 0xec, 0xdf, 0x2b, 0xbc, 0xd5, 0x6a, 0x3c, 0x10, 0xcc, 0xb, 0xf0, 0x14, 0x82, 0x48, 0x56, 0x49, 0xed, 0x6, 0xa1, 0x73, 0x7, 0x3c, 0x90, 0x5b, 0xbe, 0xb9, 0x2a, 0x52, 0xa, 0x3c, 0x1d, 0xcc, 0xab, 0x2f, 0x69, 0xa1, 0x2f, 0x8b, 0xc4, 0x2c, 0x1a, 0xc7, 0x92, 0x74, 0xf5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc6, 0xc6, 0xc6, 0xc7, 0xc7, 0xc7, 0xc5, 0xc5, 0xc5, 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0x59, 0x59, 0x59, 0x56, 0xec, 0x9e, 0xdc, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x11, 0xe2, 0xb5, 0x3d, 0xba, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x0, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x85, 0xcf, 0xcb, 0xe, 0x80, 0x30, 0x8, 0x44, 0x51, 0xaa, 0xd2, 0x7, 0xb4, 0xd2, 0xff, 0xff, 0xda, 0xea, 0x6e, 0x46, 0x63, 0xbc, 0xcb, 0x93, 0x40, 0x40, 0x24, 0x29, 0x94, 0x36, 0xc9, 0xa5, 0x42, 0x25, 0x8b, 0x56, 0x4a, 0xbf, 0xa0, 0xb5, 0x7, 0x98, 0x19, 0x83, 0x77, 0xef, 0xc, 0x3e, 0xdc, 0x11, 0xc6, 0x1d, 0xc2, 0x79, 0x45, 0x23, 0x11, 0xc1, 0x4b, 0xe7, 0xfc, 0x3b, 0xc, 0xe0, 0xf5, 0xdc, 0xce, 0xef, 0x1f, 0xb, 0xc, 0x30, 0x7, 0xaf, 0x1f, 0x5b, 0x76, 0x12, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_up_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x73, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xd5, 0x90, 0xb1, 0xa, 0xc3, 0x40, 0xc, 0x43, 0x9f, 0xb8, 0x8c, 0x81, 0xee, 0xf7, 0x7, 0x81, 0xec, 0xfd, 0xff, 0x35, 0x6b, 0xb, 0x81, 0x8e, 0x1d, 0x6e, 0xe, 0x49, 0xd7, 0x44, 0x59, 0x5c, 0xb8, 0x96, 0x36, 0x73, 0xab, 0xc5, 0x48, 0xb6, 0xb0, 0x6c, 0xf8, 0x39, 0xe8, 0x5d, 0xb0, 0xdd, 0x2, 0x7d, 0xd0, 0xab, 0xa4, 0xc7, 0x57, 0x83, 0xed, 0xc, 0x74, 0x40, 0xa, 0x69, 0x3, 0x6e, 0x92, 0xee, 0x2f, 0x6, 0xdb, 0x29, 0x6, 0x73, 0xe8, 0x25, 0x6a, 0xcd, 0x47, 0x49, 0xeb, 0xd3, 0x70, 0x6, 0x4e, 0xc0, 0x1a, 0x8d, 0xf2, 0x61, 0xe3, 0x24, 0x69, 0x68, 0xaa, 0x44, 0xb, 0x70, 0xa9, 0x33, 0x4b, 0x2a, 0xb6, 0xe7, 0xb8, 0xc9, 0x47, 0xcf, 0xf8, 0x27, 0xec, 0x8c, 0xe8, 0x25, 0xc9, 0x7b, 0x5, 0xa, 0xd0, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x2d, 0x2c, 0x2f, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0x38, 0x36, 0x3a, 0xc3, 0xc3, 0xc3, 0x59, 0x59, 0x59, 0xb3, 0x52, 0xf2, 0x5, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x8, 0xfe, 0x9, 0xd, 0x19, 0x4a, 0xb6, 0xc1, 0xe6, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_button_up_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9d, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xcd, 0x90, 0x2b, 0xe, 0xc2, 0x50, 0x14, 0x44, 0xcf, 0xbc, 0xa0, 0xca, 0x3a, 0x50, 0x38, 0x48, 0xaa, 0x58, 0xb, 0xc5, 0x57, 0x60, 0xa0, 0xc1, 0x40, 0x9a, 0x3c, 0x43, 0x8a, 0xae, 0x7f, 0xb0, 0x10, 0x82, 0x25, 0x1, 0x81, 0x60, 0x2b, 0x55, 0xa4, 0x17, 0xd1, 0x12, 0x7e, 0xa, 0xc7, 0x98, 0xc9, 0x9d, 0xb9, 0xc9, 0x49, 0x6, 0xfe, 0x4e, 0xfa, 0xc, 0x96, 0xb6, 0xee, 0xb, 0xb7, 0x3, 0xcc, 0xa8, 0x13, 0xaf, 0xc5, 0xf5, 0xb5, 0x77, 0xef, 0xcf, 0xc5, 0x58, 0xb8, 0x23, 0x30, 0x0, 0x86, 0xc2, 0x9d, 0x56, 0x56, 0x4c, 0xbf, 0x8, 0x33, 0xdb, 0x74, 0x23, 0x28, 0xc1, 0x92, 0x36, 0xde, 0x36, 0xde, 0xdc, 0x82, 0x20, 0xaa, 0x34, 0x57, 0x5e, 0x75, 0x0, 0x22, 0x6c, 0xf, 0xc4, 0x40, 0x65, 0x90, 0x7a, 0xcd, 0x43, 0x4b, 0x3c, 0x8, 0x4a, 0x83, 0x89, 0x11, 0xf5, 0x80, 0x91, 0x7b, 0x92, 0x74, 0x31, 0xea, 0xd8, 0x2b, 0xb, 0xf, 0xbc, 0x57, 0x16, 0x8c, 0x3a, 0x6, 0xce, 0xc0, 0xed, 0xe7, 0x85, 0xfe, 0x54, 0x77, 0x8c, 0xb2, 0x2f, 0x36, 0xd, 0xf7, 0x95, 0x26, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x21, 0x50, 0x4c, 0x54, 0x45, 0x3d, 0x3b, 0x3f, 0x60, 0x5d, 0x62, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x3d, 0x3b, 0x3f, 0x65, 0x62, 0x67, 0x60, 0x5d, 0x62, 0x56, 0x53, 0x58, 0x4b, 0x49, 0x4e, 0xce, 0xce, 0xce, 0x59, 0x59, 0x59, 0xb8, 0xf5, 0x6d, 0x48, 0x0, 0x0, 0x0, 0x5, 0x74, 0x52, 0x4e, 0x53, 0x7, 0xfe, 0xc, 0x9, 0x1c, 0xda, 0x2b, 0xa5, 0x57, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa, 0x68, 0xd0, 0xf4, 0x56, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x36, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc, 0x5, 0x3, 0x21, 0x86, 0xf4, 0xe, 0x30, 0x28, 0x63, 0x88, 0x80, 0x30, 0x5a, 0xb1, 0x33, 0x3a, 0x67, 0x40, 0x19, 0x33, 0x67, 0x42, 0x18, 0x9d, 0x33, 0x67, 0xce, 0x0, 0x33, 0x66, 0x2, 0x1, 0x2a, 0x3, 0x9f, 0x39, 0x10, 0x6, 0xdc, 0x52, 0x43, 0x88, 0x33, 0x44, 0x0, 0x59, 0xc8, 0x3d, 0xf9, 0xf, 0x68, 0xc5, 0xa9, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x48, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xd5, 0xcc, 0xb1, 0xd, 0x80, 0x40, 0x10, 0x3, 0xc1, 0x39, 0x12, 0x68, 0x80, 0x22, 0xa0, 0xff, 0x5a, 0xbe, 0xa, 0xa, 0x20, 0x3b, 0x92, 0xf, 0x0, 0x9d, 0x90, 0x8, 0x7f, 0x25, 0x27, 0xb6, 0xd6, 0x8c, 0x4f, 0xbc, 0x8b, 0xcc, 0x5c, 0xb1, 0x23, 0xd1, 0x22, 0xe2, 0xb8, 0xef, 0x53, 0x71, 0xb2, 0x61, 0xc6, 0xd2, 0xc5, 0x7, 0x95, 0xf0, 0x49, 0x25, 0x34, 0x9c, 0x3d, 0xed, 0xef, 0xe1, 0x8, 0x5c, 0x37, 0x9a, 0xa, 0x6, 0x38, 0xcd, 0xba, 0x62, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x60, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x5b, 0x59, 0x61, 0x5b, 0x59, 0x61, 0x5a, 0x58, 0x60, 0x59, 0x57, 0x5f, 0x5a, 0x58, 0x60, 0x5a, 0x58, 0x60, 0x57, 0x56, 0x5e, 0x58, 0x56, 0x5e, 0x56, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x57, 0x55, 0x5d, 0x55, 0x53, 0x5b, 0x55, 0x53, 0x5b, 0x54, 0x53, 0x5b, 0x55, 0x54, 0x5c, 0x54, 0x52, 0x5a, 0x55, 0x53, 0x5b, 0x5a, 0x58, 0x60, 0x56, 0x54, 0x5c, 0x54, 0x53, 0x5a, 0x55, 0x53, 0x5b, 0x53, 0x51, 0x59, 0x52, 0x51, 0x59, 0x52, 0x50, 0x58, 0x51, 0x50, 0x58, 0x51, 0x4f, 0x57, 0x50, 0x4e, 0x56, 0x4f, 0x4d, 0x55, 0x50, 0x4f, 0x57, 0x54, 0x52, 0x5a, 0xff, 0xff, 0xff, 0xc7, 0x51, 0xc2, 0xf2, 0x0, 0x0, 0x0, 0x12, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x2c, 0xb8, 0xf4, 0x2e, 0xf2, 0xb8, 0xf4, 0xf5, 0xf4, 0xf5, 0xb8, 0x2f, 0xf2, 0x2e, 0xb8, 0xf4, 0xb8, 0x66, 0xf6, 0xf7, 0x12, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1f, 0x5, 0xd, 0x10, 0xbd, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x50, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x7, 0x18, 0x99, 0x98, 0x85, 0x98, 0x18, 0x21, 0x6c, 0x16, 0x56, 0x61, 0x11, 0x11, 0x61, 0x56, 0x16, 0x30, 0x87, 0x4d, 0x54, 0xc, 0x8, 0x44, 0xd9, 0xc0, 0x1c, 0x76, 0x71, 0x9, 0x20, 0x10, 0xe7, 0x0, 0x73, 0x38, 0x25, 0xa5, 0x80, 0x40, 0x92, 0xb, 0xcc, 0xe1, 0x96, 0x90, 0x6, 0x2, 0x9, 0x6e, 0x30, 0x87, 0x87, 0x57, 0x4a, 0x46, 0x46, 0x96, 0x97, 0x7, 0x62, 0x1c, 0x1f, 0xbf, 0x80, 0x9c, 0x20, 0x1f, 0x5e, 0xdb, 0x1, 0x23, 0xfd, 0x4, 0x11, 0x2d, 0x48, 0xcb, 0xd2, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char scroll_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x6, 0x0, 0x0, 0x0, 0x56, 0x75, 0x5c, 0xe7, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x71, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xcd, 0x8f, 0x3b, 0xe, 0x83, 0x30, 0x10, 0x44, 0xdf, 0x5a, 0x88, 0x2, 0xce, 0x8, 0xdc, 0x82, 0x50, 0x11, 0xb, 0x8e, 0xc2, 0x19, 0xdd, 0x20, 0xe1, 0xa1, 0x88, 0xac, 0xd8, 0x4, 0xa5, 0x66, 0xba, 0x59, 0xcd, 0x6f, 0xe1, 0x71, 0xb0, 0x9c, 0x78, 0xf9, 0x5a, 0x34, 0xab, 0x50, 0x7, 0x26, 0xb0, 0xcd, 0x11, 0x66, 0x6f, 0x7e, 0x4f, 0x9a, 0x2a, 0x37, 0x44, 0xda, 0x5, 0x34, 0x7e, 0x73, 0xf4, 0x8a, 0xb4, 0x0, 0x53, 0xd2, 0xb8, 0xb2, 0x30, 0xf6, 0xbf, 0x23, 0x34, 0xe4, 0xec, 0x62, 0x30, 0xdd, 0xcc, 0x3e, 0xfe, 0x19, 0xb6, 0xab, 0xda, 0xa0, 0xb8, 0x15, 0x3f, 0x38, 0xc2, 0xfc, 0xd9, 0xac, 0x2e, 0x5, 0x18, 0xe1, 0x7d, 0xd3, 0xfa, 0x24, 0x9c, 0x8, 0xa7, 0x1c, 0xfa, 0x20, 0xb5, 0xcd, 0xac, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xc, 0x0, 0x0, 0x0, 0xc, 0x8, 0x3, 0x0, 0x0, 0x0, 0x61, 0xab, 0xac, 0xd5, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x97, 0xd0, 0xdf, 0x92, 0xcb, 0xdc, 0x84, 0xbb, 0xd4, 0x92, 0xca, 0xdc, 0x95, 0xd0, 0xdd, 0x83, 0xbb, 0xd3, 0x8b, 0xc8, 0xd7, 0x79, 0xb5, 0xcb, 0x78, 0xb4, 0xca, 0x73, 0xb0, 0xc7, 0x73, 0xb0, 0xc7, 0x7b, 0xc0, 0xcf, 0x79, 0xc5, 0xd1, 0x6b, 0xae, 0xc1, 0x75, 0xc6, 0xcf, 0x70, 0xbc, 0xca, 0x64, 0xa6, 0xbc, 0x71, 0xbc, 0xc9, 0x82, 0xba, 0xd4, 0x6a, 0xa2, 0xc6, 0x62, 0x9a, 0xc2, 0x61, 0x9a, 0xc1, 0x68, 0x9f, 0xc2, 0x5d, 0x92, 0xbb, 0x5c, 0x92, 0xb8, 0x58, 0x8d, 0xb6, 0x59, 0x8e, 0xb3, 0x56, 0x89, 0xb0, 0x5c, 0x91, 0xb2, 0x53, 0x84, 0xa9, 0x58, 0x8f, 0xae, 0x54, 0x83, 0xa4, 0x57, 0x8e, 0xad, 0x64, 0xa5, 0xba, 0xff, 0xff, 0xff, 0xbb, 0x65, 0x65, 0x27, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x25, 0xad, 0xf1, 0xad, 0x27, 0xef, 0xad, 0xf1, 0xf3, 0xf1, 0xf3, 0xad, 0x28, 0xef, 0x27, 0xad, 0xf2, 0xad, 0xcd, 0x8a, 0x27, 0xfe, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x23, 0x2a, 0x62, 0x6c, 0x3a, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x50, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x7, 0x18, 0x99, 0x98, 0x85, 0x59, 0x18, 0x21, 0x6c, 0x56, 0x36, 0x11, 0x51, 0x31, 0x11, 0x36, 0x56, 0x30, 0x87, 0x5d, 0x5c, 0x2, 0x8, 0xc4, 0xd9, 0xc1, 0x1c, 0xe, 0x49, 0x29, 0x20, 0x90, 0xe4, 0x4, 0x73, 0xb8, 0xa4, 0x65, 0x80, 0x40, 0x9a, 0x1b, 0xcc, 0xe1, 0x91, 0x95, 0x3, 0x2, 0x59, 0x1e, 0x30, 0x87, 0x97, 0x4f, 0x5e, 0x41, 0x41, 0x91, 0x8f, 0x17, 0x62, 0x1c, 0xbf, 0x80, 0xa0, 0x92, 0x10, 0x3f, 0x5e, 0xdb, 0x1, 0x41, 0x87, 0x4, 0x7d, 0x15, 0xc4, 0xfd, 0x6a, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char selection_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xba, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xc5, 0xd2, 0xc1, 0x4a, 0x43, 0x31, 0x10, 0x85, 0xe1, 0x6f, 0x42, 0xdd, 0x15, 0xb, 0x15, 0x14, 0xe9, 0x23, 0xb4, 0xd7, 0xf7, 0x7f, 0x8e, 0x56, 0x17, 0xdd, 0x8b, 0x16, 0xc1, 0x82, 0xc5, 0xdd, 0x15, 0xc6, 0x45, 0x73, 0xe5, 0x6e, 0xaa, 0x91, 0x22, 0x9e, 0xcd, 0x64, 0x92, 0xfc, 0x73, 0x48, 0x38, 0xfc, 0xb7, 0x62, 0x58, 0x64, 0xe6, 0xd, 0x56, 0xb8, 0xc2, 0xe4, 0xc4, 0xfd, 0xf, 0xbc, 0x62, 0x1b, 0x11, 0x8f, 0x5f, 0x3, 0x32, 0x73, 0x85, 0x6e, 0x3c, 0xb0, 0x41, 0xf7, 0x11, 0xb1, 0x9e, 0x54, 0xe7, 0xae, 0x6e, 0x3e, 0xe1, 0xf0, 0x3, 0x38, 0xc5, 0x2, 0xcb, 0xcc, 0xdc, 0x95, 0x91, 0xf3, 0x73, 0x3, 0xc, 0xef, 0xd8, 0x55, 0xa6, 0x2b, 0x98, 0xd7, 0x83, 0x16, 0x78, 0xd0, 0x5b, 0xad, 0xf3, 0xe2, 0xf4, 0x87, 0xb5, 0xe8, 0xa2, 0x9c, 0x1, 0x83, 0x82, 0xfe, 0xc, 0xbe, 0x2f, 0xd8, 0xd7, 0x66, 0xfa, 0xb, 0xf0, 0xb2, 0xd6, 0x7d, 0xc1, 0xb6, 0x36, 0xb, 0xcc, 0x1a, 0xe0, 0x19, 0x6e, 0x91, 0xd8, 0xc, 0x41, 0xba, 0xc3, 0x52, 0x7b, 0x90, 0x12, 0xeb, 0x88, 0x78, 0x18, 0x47, 0xf9, 0xda, 0x31, 0x13, 0xdf, 0x45, 0xb9, 0x77, 0x7c, 0xf2, 0x26, 0x22, 0x5e, 0x1a, 0xcd, 0xfe, 0x58, 0x9f, 0x3f, 0x85, 0x2f, 0x71, 0xd3, 0xd7, 0x3f, 0x66, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2d, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xfd, 0xfb, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfd, 0xf6, 0xff, 0xf6, 0xf4, 0xff, 0x15, 0x15, 0x17, 0xff, 0x70, 0xc0, 0x21, 0x0, 0x0, 0x0, 0xe, 0x74, 0x52, 0x4e, 0x53, 0x6, 0xf, 0x16, 0x18, 0x2a, 0x3b, 0x40, 0x3c, 0x6, 0x3d, 0x44, 0x3e, 0x31, 0x25, 0x8, 0x3d, 0x16, 0xb4, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xe, 0x6f, 0xbd, 0x30, 0x4f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x37, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x6, 0x2, 0x23, 0x1, 0x6, 0x91, 0xb0, 0x34, 0x20, 0x48, 0x75, 0x64, 0x50, 0xef, 0x5c, 0x5, 0x4, 0x33, 0x8a, 0x18, 0xcc, 0xf6, 0xdc, 0x5, 0x82, 0xd3, 0xc9, 0xc, 0x66, 0x6b, 0x41, 0x8c, 0x5b, 0x94, 0x33, 0x60, 0x6, 0xc2, 0xad, 0x80, 0x5b, 0xa, 0x73, 0x6, 0x0, 0x45, 0x34, 0x48, 0x41, 0xa3, 0xc5, 0x91, 0x23, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char selection_oof_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xb6, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xd3, 0xbd, 0x4a, 0x43, 0x41, 0x10, 0xc5, 0xf1, 0xdf, 0x2c, 0xb1, 0xb, 0x6, 0x22, 0x28, 0x92, 0x47, 0x48, 0xae, 0xef, 0xff, 0x1c, 0x89, 0x16, 0xe9, 0x45, 0x83, 0x60, 0xc0, 0x60, 0x77, 0x85, 0xb1, 0xb8, 0x7b, 0x43, 0xa, 0x3f, 0x56, 0xd2, 0x7a, 0x9a, 0xe1, 0xec, 0xf0, 0x9f, 0x61, 0x7, 0x4e, 0xa8, 0xca, 0xcc, 0x1b, 0xac, 0x70, 0x85, 0x89, 0xaf, 0xf5, 0x81, 0x57, 0x6c, 0x23, 0xe2, 0x11, 0xa2, 0xc2, 0x2b, 0x74, 0xa3, 0x6f, 0xd4, 0x7d, 0x44, 0xac, 0x27, 0x75, 0x73, 0x57, 0x1f, 0x9f, 0x70, 0xf8, 0x5, 0x9c, 0x62, 0x81, 0x65, 0x66, 0xee, 0xca, 0xc9, 0xe6, 0xe7, 0x6, 0x18, 0xde, 0xb1, 0xab, 0x4c, 0x57, 0x30, 0xaf, 0x8d, 0x16, 0x78, 0xd4, 0x5b, 0xad, 0xf3, 0xe2, 0xfb, 0x83, 0xb5, 0xe8, 0xa2, 0x9c, 0x1, 0x83, 0xff, 0x1, 0xc3, 0x80, 0xfe, 0xc, 0xbe, 0x2f, 0xd8, 0x57, 0x33, 0xfd, 0x3, 0x78, 0x59, 0xeb, 0xbe, 0x60, 0x5b, 0xcd, 0x2, 0xb3, 0x6, 0x78, 0x86, 0x5b, 0x24, 0x36, 0x63, 0x98, 0xee, 0xb0, 0xd4, 0x1e, 0xa6, 0xc4, 0x3a, 0x22, 0x1e, 0x8e, 0x40, 0x66, 0x5e, 0x1b, 0x72, 0xf1, 0x53, 0x9c, 0x7b, 0xc3, 0x97, 0x37, 0x11, 0xf1, 0x2, 0x9f, 0x25, 0x19, 0x2f, 0x79, 0x66, 0x8a, 0x69, 0x6e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x4, 0x3, 0x0, 0x0, 0x0, 0xed, 0xdd, 0xe2, 0x52, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x30, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2c, 0x2, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0xfd, 0xfb, 0xff, 0x15, 0x15, 0x17, 0xe9, 0x54, 0x1, 0x21, 0x0, 0x0, 0x0, 0xf, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0x3, 0x20, 0x25, 0x16, 0xc, 0x1f, 0x74, 0xbf, 0x74, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xf, 0x18, 0xba, 0x0, 0xd9, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x38, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x76, 0x1, 0x2, 0x23, 0x1, 0x6, 0xd1, 0xf4, 0xe, 0x20, 0x28, 0xb, 0x64, 0xd0, 0x5c, 0x7d, 0x6, 0x8, 0x76, 0x4d, 0x62, 0x70, 0xdf, 0xfb, 0xe, 0x8, 0x6e, 0x97, 0x30, 0x78, 0x9c, 0x3, 0x31, 0xde, 0xb4, 0x50, 0xca, 0x80, 0x1b, 0x8, 0xb7, 0x2, 0x6e, 0x29, 0xcc, 0x19, 0x0, 0x1a, 0x23, 0x52, 0x59, 0xa4, 0x2f, 0x3d, 0xa7, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char spinbox_updown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0xe, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xc5, 0x53, 0xc1, 0x4a, 0xc3, 0x40, 0x14, 0x9c, 0x79, 0x90, 0xd4, 0xa3, 0x1, 0x8f, 0x81, 0xa5, 0xe4, 0x50, 0xff, 0x4c, 0xb1, 0x45, 0xd0, 0xbf, 0xd0, 0x83, 0x7a, 0x88, 0xd0, 0x4f, 0x6b, 0xf, 0xa1, 0xbc, 0xbb, 0xa5, 0x1e, 0xa5, 0x98, 0x37, 0x5e, 0xc, 0xc4, 0xd0, 0x68, 0xa1, 0x7, 0xe7, 0xb4, 0xfb, 0x96, 0x9d, 0x19, 0x66, 0x67, 0x81, 0x13, 0xc1, 0xb1, 0x3, 0x77, 0x2f, 0x24, 0x3d, 0x90, 0xcc, 0x0, 0xdc, 0xa7, 0x94, 0x76, 0x47, 0x13, 0x6c, 0x36, 0x9b, 0x73, 0x92, 0xaf, 0x0, 0x2a, 0x0, 0x90, 0xe4, 0xfb, 0xfd, 0x7e, 0x3e, 0x9b, 0xcd, 0xde, 0xfe, 0x24, 0x70, 0xf7, 0x82, 0x64, 0x1d, 0x11, 0x95, 0x99, 0x35, 0x0, 0xd0, 0xad, 0x25, 0x2d, 0x86, 0x4e, 0x6c, 0xa8, 0x2c, 0xa9, 0x8e, 0x88, 0x4a, 0x92, 0x9b, 0xd9, 0x6d, 0xdb, 0xb6, 0x73, 0x0, 0x4d, 0x44, 0x54, 0x11, 0xb1, 0x5c, 0xaf, 0xd7, 0x17, 0xa3, 0x4, 0x66, 0xf6, 0xc, 0xa0, 0x32, 0xb3, 0xc6, 0xcc, 0xae, 0xcb, 0xb2, 0xdc, 0x4e, 0xa7, 0xd3, 0x77, 0x92, 0xb, 0x33, 0x6b, 0x48, 0xa6, 0xc9, 0x64, 0xf2, 0x38, 0x4a, 0x20, 0xa9, 0x25, 0xb9, 0x1a, 0x5a, 0x4d, 0x29, 0xed, 0x24, 0x2d, 0x48, 0xae, 0x0, 0xc4, 0xa1, 0xdc, 0xfe, 0xf, 0x3f, 0x5e, 0xc1, 0xdd, 0x97, 0x0, 0xce, 0x0, 0xdc, 0xd, 0xd3, 0x76, 0xf7, 0x22, 0x22, 0x5e, 0xcc, 0xec, 0x23, 0xa5, 0x74, 0xd5, 0xcd, 0x87, 0x19, 0xe4, 0x92, 0x2e, 0x49, 0xd6, 0xee, 0x5e, 0xf4, 0x2f, 0x93, 0xac, 0x49, 0xce, 0x24, 0x65, 0xa3, 0xe, 0xfa, 0x5, 0xea, 0xca, 0x93, 0xe7, 0xf9, 0x67, 0x7f, 0x96, 0x65, 0xd9, 0x4d, 0x59, 0x96, 0xdb, 0x83, 0x4, 0x7d, 0xb5, 0x63, 0x8b, 0x74, 0x74, 0x95, 0x87, 0xca, 0xbf, 0x12, 0x74, 0x4e, 0x0, 0x3c, 0x7d, 0x6f, 0x47, 0x3f, 0xd3, 0xc9, 0xf8, 0x2, 0x8c, 0x16, 0xa2, 0xfd, 0x26, 0x18, 0xca, 0xf6, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xcd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xe5, 0x53, 0x31, 0xe, 0x82, 0x40, 0x10, 0x9c, 0x5d, 0x22, 0x3e, 0x80, 0x86, 0xc4, 0x0, 0xe1, 0xf, 0x16, 0x5a, 0x58, 0xf9, 0x5, 0xe3, 0x13, 0xd0, 0xc2, 0xc4, 0xcf, 0xd8, 0xf0, 0x5, 0xe3, 0x1f, 0x2c, 0x2c, 0x6c, 0xf8, 0x1, 0xc5, 0x72, 0x85, 0x9, 0xd, 0xf, 0x10, 0x43, 0xce, 0x86, 0x82, 0xe0, 0xe9, 0x19, 0x8d, 0x95, 0x53, 0xce, 0xce, 0x6e, 0x26, 0x99, 0x59, 0xe0, 0x97, 0x10, 0x91, 0x95, 0x52, 0x2a, 0x79, 0xa5, 0xa1, 0x67, 0x83, 0xa2, 0x28, 0xa6, 0x0, 0x8e, 0x0, 0x98, 0x99, 0xe7, 0x61, 0x18, 0x9e, 0xde, 0x3e, 0x20, 0x22, 0x3e, 0x11, 0x65, 0x0, 0x46, 0x2d, 0x55, 0x3a, 0x8e, 0x33, 0xe, 0x82, 0xe0, 0xd2, 0xd7, 0x72, 0x9f, 0xc8, 0xb2, 0x6c, 0x0, 0x60, 0xdf, 0x59, 0x6, 0x0, 0xbf, 0x69, 0x9a, 0x43, 0x9e, 0xe7, 0x43, 0xeb, 0x1, 0xcf, 0xf3, 0x76, 0x44, 0x34, 0x33, 0x18, 0x9b, 0xb8, 0xae, 0x9b, 0x9a, 0x1c, 0xff, 0x3b, 0x1e, 0x62, 0x14, 0x91, 0x94, 0x88, 0x8c, 0xe5, 0x21, 0xa2, 0x34, 0x8a, 0xa2, 0x75, 0x97, 0x7b, 0x48, 0xa1, 0xaa, 0xaa, 0x8d, 0xd6, 0xda, 0x54, 0x9a, 0x73, 0x5d, 0xd7, 0x5b, 0xab, 0x83, 0xd6, 0xc5, 0xe7, 0x45, 0x2, 0x80, 0x38, 0x8e, 0x4b, 0xad, 0xf5, 0x2, 0xc0, 0x15, 0xc0, 0x8d, 0x99, 0x97, 0xa6, 0x65, 0x2b, 0x94, 0x52, 0x89, 0xed, 0x99, 0xbe, 0xc6, 0x1d, 0x31, 0x1f, 0x40, 0xdc, 0x74, 0x8a, 0x5b, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char submenu_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x8e, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x75, 0xcf, 0x31, 0xa, 0xc2, 0x50, 0x10, 0x4, 0xd0, 0x99, 0x8d, 0x62, 0x4a, 0x5, 0xcb, 0xc0, 0x27, 0xa4, 0xf1, 0x70, 0xbf, 0x51, 0xbc, 0x85, 0x60, 0x95, 0x42, 0x6f, 0x66, 0x8a, 0x10, 0xf6, 0x4, 0x49, 0x2f, 0xec, 0xd8, 0x18, 0x31, 0xa0, 0x53, 0x2d, 0xc3, 0x63, 0x61, 0x88, 0x77, 0xdc, 0xfd, 0xe, 0x60, 0x3, 0xe0, 0x98, 0x52, 0x1a, 0xe7, 0xde, 0xe6, 0x43, 0xd2, 0x5a, 0xd2, 0x81, 0x64, 0xeb, 0xee, 0xbb, 0x5f, 0xe0, 0x4, 0xa0, 0x8f, 0x88, 0x26, 0x22, 0x6e, 0x5d, 0xd7, 0xed, 0x17, 0xa0, 0xae, 0xeb, 0x89, 0x64, 0x36, 0xb3, 0x9e, 0x64, 0x2a, 0xcb, 0xf2, 0xb2, 0x0, 0xff, 0xf2, 0x1, 0xc3, 0x30, 0x6c, 0x25, 0xb5, 0x11, 0xd1, 0x48, 0xf2, 0xa2, 0x28, 0xce, 0x0, 0xb0, 0x9a, 0x1, 0xc9, 0x2b, 0x80, 0xc6, 0xcc, 0x7a, 0x49, 0xb9, 0xaa, 0xaa, 0x71, 0xf1, 0x81, 0xe4, 0x93, 0xe4, 0x43, 0x52, 0xfe, 0x9e, 0xf9, 0x2, 0x35, 0xca, 0x3a, 0xf, 0x29, 0x4, 0xd0, 0xe4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x7d, 0xca, 0x21, 0x12, 0x80, 0x20, 0x14, 0x45, 0xd1, 0xf7, 0x2d, 0x4, 0x36, 0x40, 0x63, 0xa8, 0xba, 0x1f, 0xbb, 0x9d, 0xe5, 0xb8, 0x0, 0xb3, 0xfb, 0xd1, 0xc, 0x8d, 0xd, 0x10, 0x48, 0xcf, 0x22, 0x6, 0xc7, 0xef, 0x6d, 0x77, 0xe6, 0x8, 0x0, 0xa4, 0x94, 0x88, 0x3b, 0x92, 0x4b, 0x8, 0x61, 0xeb, 0x3f, 0xe0, 0x95, 0x88, 0xac, 0x39, 0xe7, 0x49, 0x5, 0x0, 0x2c, 0xc9, 0xbd, 0x94, 0x62, 0x35, 0x0, 0x0, 0x63, 0x6b, 0x6d, 0xfd, 0x3, 0x4f, 0x1a, 0x38, 0x8d, 0x31, 0x51, 0x3, 0x55, 0x44, 0x66, 0xe7, 0x5c, 0xfd, 0x4, 0x24, 0xa3, 0xf7, 0xfe, 0xe8, 0x7f, 0x1, 0xe, 0xc2, 0x1e, 0x10, 0xa, 0xf0, 0x33, 0x4c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x53, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x75, 0x8f, 0x31, 0xe, 0x80, 0x30, 0xc, 0x3, 0xcf, 0xa5, 0x73, 0xbb, 0xf0, 0xff, 0x3f, 0xc2, 0xa, 0xd4, 0x2c, 0x54, 0xa, 0x11, 0xdc, 0xe8, 0x58, 0x3e, 0x45, 0x4, 0x6c, 0x77, 0x40, 0xc0, 0x2e, 0x69, 0x0, 0x14, 0xde, 0x8, 0xa8, 0x40, 0xb7, 0x5d, 0x66, 0x10, 0x17, 0xa, 0xd0, 0x9e, 0xd2, 0x5, 0x6c, 0xb2, 0xbd, 0xf2, 0xcf, 0x91, 0x15, 0x19, 0x7d, 0x29, 0x3a, 0xb0, 0x4c, 0x45, 0x5e, 0x68, 0xf1, 0x28, 0x69, 0xd4, 0x54, 0x30, 0x70, 0x12, 0xde, 0xbc, 0x1, 0x5f, 0x4b, 0x1d, 0x1b, 0xbf, 0xb6, 0xb, 0xf9, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x4, 0x0, 0x0, 0x0, 0x6e, 0x6, 0x76, 0x0, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x0, 0xaa, 0x8d, 0x23, 0x32, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0xc0, 0x4, 0xff, 0x23, 0xff, 0x8b, 0xfc, 0x17, 0xf9, 0x1f, 0x49, 0xac, 0x10, 0x13, 0x3, 0x3, 0x61, 0x53, 0xb0, 0x98, 0x80, 0xc, 0x0, 0xa8, 0x3e, 0x18, 0x31, 0xbe, 0x78, 0xfc, 0x7a, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_behind_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x12, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x60, 0x14, 0x8c, 0x2, 0x8, 0x0, 0x0, 0x4, 0x10, 0x0, 0x1, 0x7f, 0x4d, 0x78, 0x8e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x5a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x2e, 0x36, 0x43, 0x40, 0x4d, 0x0, 0x0, 0x0, 0x43, 0x40, 0x4c, 0x3e, 0x3c, 0x47, 0x3e, 0x3b, 0x46, 0x31, 0x2f, 0x38, 0x2d, 0x2b, 0x33, 0x3f, 0x3c, 0x47, 0x35, 0x32, 0x3b, 0x5b, 0xb0, 0x1, 0xb7, 0x0, 0x0, 0x0, 0x18, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x3, 0x5, 0x8, 0xa, 0xb, 0xc, 0x4, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x77, 0xf3, 0x7, 0xef, 0xd3, 0x51, 0x5e, 0xca, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1d, 0xeb, 0x3, 0x71, 0x91, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x6e, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xb5, 0xcc, 0x49, 0xe, 0x80, 0x20, 0x10, 0x44, 0xd1, 0x2, 0x6c, 0x90, 0x49, 0x26, 0x27, 0xd4, 0xfb, 0x9f, 0x53, 0x63, 0x34, 0x2e, 0x58, 0xfb, 0x97, 0x2f, 0xa9, 0x2, 0x18, 0x17, 0x1d, 0x49, 0xa5, 0x24, 0x75, 0x82, 0x33, 0x80, 0xf5, 0xa4, 0x8d, 0x75, 0xde, 0x3b, 0x6b, 0x34, 0xf5, 0xc, 0x9c, 0x86, 0x10, 0x53, 0x2e, 0x25, 0xa7, 0x18, 0x6, 0xe2, 0x10, 0x3a, 0x8c, 0xd3, 0x5a, 0xaf, 0xd6, 0x69, 0xc, 0x5a, 0x60, 0x36, 0x71, 0xd9, 0xf6, 0xbb, 0x6d, 0x89, 0x66, 0x6, 0xd9, 0x74, 0xec, 0x4f, 0x47, 0xb2, 0x4, 0xe9, 0x72, 0x7d, 0xa1, 0x66, 0x27, 0xa1, 0x7c, 0xf9, 0xa0, 0x78, 0xd5, 0x42, 0x33, 0x69, 0x4e, 0xff, 0x80, 0x13, 0xce, 0x8, 0x12, 0xa9, 0x90, 0xd8, 0x47, 0x93, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_close_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xbe, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xd5, 0x90, 0x3b, 0xe, 0xc2, 0x40, 0xc, 0x44, 0x9f, 0x9, 0x45, 0xf8, 0x14, 0x80, 0xb8, 0xf, 0x15, 0x8a, 0x8, 0x48, 0xdc, 0x94, 0x8a, 0x4, 0x85, 0x9a, 0xe3, 0x20, 0x48, 0xc3, 0xa7, 0x20, 0x32, 0x8d, 0x41, 0x8b, 0xc9, 0x4a, 0xb4, 0xb8, 0xda, 0x1d, 0x7b, 0x9e, 0x35, 0x86, 0xbf, 0x2f, 0x9, 0x3f, 0xaa, 0xba, 0x2, 0xba, 0x40, 0x25, 0x22, 0x37, 0xd7, 0xeb, 0x1, 0x19, 0xf0, 0x10, 0x91, 0xed, 0x4b, 0xef, 0x38, 0x60, 0x2, 0x4c, 0x81, 0xdc, 0xc, 0xa1, 0x39, 0xb7, 0x5e, 0x12, 0x1a, 0x3c, 0xa0, 0x2, 0x4e, 0xc0, 0x18, 0x58, 0xaa, 0x6a, 0x5f, 0x55, 0x53, 0x60, 0x61, 0x5a, 0xd, 0xec, 0xa3, 0x11, 0x6c, 0x5b, 0x6a, 0xdb, 0x26, 0xc0, 0xc5, 0xe4, 0x81, 0x99, 0xb, 0x1f, 0xed, 0xb, 0x10, 0x40, 0xd6, 0xc0, 0xcc, 0x66, 0xe, 0xc0, 0xc6, 0x9b, 0xdb, 0x22, 0xc4, 0x4a, 0x63, 0xcb, 0x7e, 0x89, 0xa0, 0xc0, 0xd0, 0x22, 0x94, 0x22, 0x72, 0x8d, 0x2, 0x9c, 0xb9, 0x6, 0xa, 0x3, 0x84, 0xda, 0x7, 0xc4, 0x47, 0xc8, 0x6c, 0xf0, 0x8c, 0x1d, 0x4c, 0x44, 0xee, 0xc0, 0xce, 0xb4, 0x11, 0x30, 0xf, 0xd, 0x1e, 0xd0, 0x0, 0x47, 0xdb, 0xf2, 0x3e, 0x98, 0xbd, 0x4b, 0xeb, 0x35, 0x6d, 0xb7, 0xf8, 0xe3, 0x7a, 0x2, 0x49, 0x7e, 0x47, 0x10, 0xc3, 0xf7, 0xae, 0x75, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
-};
-
-static const unsigned char tab_container_backup_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x88, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x92, 0xb1, 0xd, 0xc2, 0x40, 0xc, 0x45, 0x9f, 0xcf, 0x91, 0x4e, 0x99, 0x21, 0x7, 0xb, 0x65, 0x5, 0x3a, 0xa4, 0x5b, 0x3, 0xb1, 0x5, 0x81, 0x9a, 0x19, 0x18, 0x28, 0xd9, 0x1, 0xa5, 0x48, 0x4c, 0xc3, 0x45, 0x54, 0x58, 0x14, 0x28, 0x14, 0xfc, 0xca, 0x67, 0xfb, 0x3d, 0xb9, 0x38, 0x58, 0x3b, 0x52, 0x8a, 0xdd, 0xfe, 0xd8, 0x9a, 0x58, 0x7, 0x34, 0xe, 0x33, 0x20, 0x92, 0xaf, 0x97, 0xc3, 0xd, 0xa0, 0x2a, 0x5d, 0x13, 0x3b, 0x8d, 0xe3, 0xbd, 0x99, 0xa7, 0xe9, 0x2d, 0x1d, 0x54, 0x53, 0x8c, 0x75, 0x7, 0x6c, 0x1, 0xc2, 0xcb, 0x2c, 0x79, 0x30, 0xc0, 0x73, 0x67, 0xb3, 0x8, 0x5d, 0xc2, 0xc9, 0x5f, 0xf0, 0x6b, 0x82, 0x21, 0xa8, 0xfa, 0x40, 0x50, 0x80, 0xbe, 0xbc, 0x97, 0x9f, 0x88, 0x48, 0x8e, 0xb1, 0x3e, 0x3, 0xc9, 0x71, 0xf4, 0x62, 0xe4, 0x8f, 0xce, 0xfc, 0x6a, 0x1e, 0x1b, 0xcd, 0x1d, 0x1e, 0xc0, 0x10, 0x6, 0x8e, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xfa, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xcd, 0x92, 0x5f, 0x4a, 0xc4, 0x30, 0x10, 0x87, 0xbf, 0xb1, 0xb9, 0xc2, 0x16, 0x7c, 0x6b, 0xc1, 0xa2, 0x85, 0x7a, 0x4, 0x2d, 0xfe, 0x39, 0xc4, 0x9e, 0x70, 0x4f, 0x61, 0xc5, 0x3d, 0x83, 0x5, 0x95, 0x4, 0xd2, 0x37, 0x5, 0x8f, 0x90, 0x94, 0xf1, 0xc5, 0x4a, 0x76, 0xcd, 0x22, 0xf8, 0xa2, 0xf3, 0x38, 0xc3, 0xef, 0x9b, 0xe4, 0x4b, 0xe0, 0x5f, 0x95, 0xf7, 0x7e, 0xed, 0x9c, 0x2b, 0xf, 0xcd, 0x9d, 0x73, 0xa5, 0xf7, 0x7e, 0x9d, 0xf6, 0x8e, 0xd2, 0xb0, 0x88, 0x6c, 0x8c, 0x31, 0x43, 0xe, 0xe2, 0x9c, 0x2b, 0x8d, 0x31, 0x83, 0x88, 0x6c, 0x52, 0xc8, 0x17, 0x20, 0xc6, 0x38, 0xa8, 0xea, 0x8, 0x74, 0xc6, 0x98, 0xed, 0x34, 0x4d, 0xc7, 0xcb, 0xcc, 0x5a, 0xbb, 0x2a, 0x8a, 0xe2, 0xe, 0xe8, 0x80, 0x17, 0xe0, 0x61, 0x99, 0x49, 0xba, 0xc5, 0x5a, 0xbb, 0xfa, 0xdc, 0x72, 0xe, 0x3c, 0x3, 0xd7, 0x21, 0x84, 0x98, 0xf6, 0x54, 0xf5, 0xaa, 0xae, 0xeb, 0xb7, 0x2c, 0x60, 0x1f, 0x22, 0x22, 0x56, 0x55, 0x23, 0xd0, 0xe6, 0xc2, 0x59, 0x40, 0x2, 0xd9, 0x8a, 0x48, 0xbb, 0x28, 0x50, 0xd5, 0x8b, 0xfd, 0xf0, 0x8e, 0x83, 0x9f, 0x4a, 0x44, 0xb2, 0xcb, 0xbe, 0x1, 0x92, 0x2b, 0xb4, 0xaa, 0x6a, 0x81, 0x27, 0xe0, 0x4, 0xb8, 0x4f, 0xc5, 0x66, 0x1, 0x19, 0x89, 0x97, 0x21, 0x84, 0x5e, 0x55, 0x1f, 0x81, 0xb3, 0x1c, 0x44, 0xe, 0x85, 0x53, 0x61, 0xb9, 0xd7, 0xa9, 0xaa, 0xea, 0x75, 0xe7, 0x4, 0xc6, 0x98, 0x1b, 0x11, 0xe9, 0x80, 0x31, 0xc6, 0xd8, 0xa7, 0xc2, 0x9a, 0xa6, 0x79, 0x9f, 0xe7, 0xf9, 0x16, 0x18, 0x81, 0x53, 0x55, 0xed, 0xb3, 0xa2, 0x7e, 0xf3, 0x95, 0xff, 0xbe, 0x3e, 0x0, 0xbd, 0x2c, 0x93, 0xec, 0xb, 0xe5, 0x4f, 0xb1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_container_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x1, 0x0, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0x4a, 0x43, 0x51, 0x10, 0x45, 0xcf, 0x7d, 0xef, 0x83, 0x2b, 0x50, 0x88, 0x8d, 0x9d, 0xbd, 0xa9, 0x52, 0x44, 0xbb, 0x8f, 0x62, 0xe1, 0x16, 0xcc, 0x22, 0x5c, 0x40, 0x96, 0xa2, 0xd9, 0x82, 0x4, 0x94, 0xdf, 0x19, 0x1b, 0x9b, 0x8f, 0xb, 0xb0, 0x10, 0x91, 0x8, 0xba, 0x84, 0xbc, 0xf7, 0xae, 0x8d, 0x86, 0x20, 0x3f, 0x28, 0xa4, 0xf5, 0xc2, 0xc0, 0x14, 0x33, 0x67, 0xee, 0xc, 0xc, 0x6c, 0x28, 0xad, 0xe6, 0xfd, 0xe1, 0xf1, 0x48, 0x52, 0x6d, 0xd8, 0x5e, 0x53, 0xfc, 0x61, 0xbb, 0x69, 0xef, 0x6f, 0x2f, 0x1, 0xaf, 0x0, 0xc6, 0xe1, 0xe0, 0xe8, 0xe1, 0x5a, 0xf6, 0xa9, 0xa4, 0x84, 0x54, 0x75, 0x8e, 0xb3, 0x93, 0xed, 0xa, 0x31, 0x6d, 0xef, 0x6, 0x67, 0x30, 0x2e, 0x11, 0xa0, 0x3f, 0xdc, 0x1a, 0x9, 0x2e, 0x62, 0xac, 0x8, 0xb1, 0xa, 0x21, 0x4, 0xba, 0x23, 0x6, 0x4, 0x2e, 0xde, 0xef, 0xed, 0xbd, 0x3e, 0xbf, 0xbd, 0x3c, 0x3d, 0x6, 0x0, 0x49, 0xb5, 0xa4, 0xa4, 0x10, 0x7e, 0xdd, 0x39, 0x84, 0x88, 0xa4, 0x6c, 0xab, 0x6, 0x8, 0x0, 0x5, 0x7a, 0x6b, 0x6d, 0x77, 0x1e, 0x43, 0x11, 0x79, 0x77, 0x9, 0xd8, 0x44, 0xff, 0x80, 0x6f, 0x80, 0x35, 0xc7, 0x4e, 0x7f, 0xee, 0xb2, 0x13, 0xd6, 0x7c, 0x9, 0x90, 0xdc, 0xd8, 0xae, 0x4a, 0xc9, 0xbf, 0xf6, 0x96, 0x92, 0xb1, 0x5d, 0x49, 0x6e, 0x96, 0x80, 0x76, 0x36, 0x98, 0x20, 0xa6, 0x25, 0x67, 0x72, 0x5a, 0xa4, 0x9c, 0x13, 0x9d, 0x91, 0x16, 0xa9, 0xe4, 0xc, 0x62, 0xda, 0xce, 0x6, 0x13, 0xf8, 0xf9, 0x4c, 0x87, 0x27, 0xe7, 0xb6, 0x6a, 0xc9, 0x3b, 0xdd, 0xce, 0xf5, 0x2e, 0xb9, 0x69, 0x67, 0x37, 0x57, 0x7c, 0x3d, 0xd3, 0xc6, 0xfa, 0x4, 0xa9, 0xb7, 0x78, 0x10, 0x23, 0xd5, 0x4b, 0x13, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x8a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3c, 0x3a, 0x44, 0x56, 0x53, 0x61, 0x56, 0x52, 0x60, 0x47, 0x44, 0x52, 0x33, 0x31, 0x39, 0x47, 0x44, 0x50, 0x47, 0x44, 0x51, 0x52, 0x50, 0x5d, 0x51, 0x4f, 0x5d, 0x46, 0x42, 0x4e, 0x42, 0x3e, 0x4a, 0x41, 0x3e, 0x49, 0x51, 0x4e, 0x5b, 0x40, 0x3e, 0x48, 0x4f, 0x4c, 0x59, 0x3f, 0x3d, 0x47, 0x4e, 0x4a, 0x58, 0x3e, 0x3b, 0x46, 0x4b, 0x49, 0x55, 0x3c, 0x3a, 0x44, 0x4a, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x49, 0x46, 0x53, 0x3a, 0x38, 0x42, 0x47, 0x45, 0x50, 0x39, 0x37, 0x40, 0x47, 0x43, 0x50, 0x38, 0x35, 0x3f, 0x36, 0x34, 0x3e, 0x44, 0x42, 0x4d, 0x44, 0x41, 0x4c, 0xff, 0xff, 0xff, 0xe5, 0x37, 0x10, 0x78, 0x0, 0x0, 0x0, 0x15, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xef, 0x77, 0xef, 0xed, 0xe8, 0xff, 0x76, 0xed, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x2d, 0xcd, 0xda, 0x41, 0x3d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x93, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x65, 0xcf, 0x47, 0x12, 0x82, 0x40, 0x10, 0x5, 0xd0, 0x9e, 0xc8, 0x44, 0x92, 0x22, 0x41, 0x54, 0x44, 0x40, 0x14, 0xef, 0x7f, 0x3e, 0x7, 0x8a, 0xea, 0x85, 0xbe, 0xe5, 0xaf, 0xea, 0xf0, 0x1, 0x8, 0x65, 0x5c, 0xc8, 0x40, 0x70, 0x46, 0x9, 0x0, 0x89, 0x94, 0x36, 0xd6, 0x79, 0xef, 0xac, 0xd1, 0x2a, 0x22, 0x40, 0x55, 0x9c, 0x14, 0xa7, 0x4d, 0x91, 0xc4, 0x8a, 0x2, 0xd3, 0x69, 0x59, 0xd5, 0x9b, 0xaa, 0x4c, 0x35, 0x3, 0x6e, 0x9a, 0xfa, 0xbc, 0xab, 0x1b, 0xc3, 0x41, 0xd8, 0xf6, 0x82, 0x5a, 0x2b, 0x40, 0xba, 0xeb, 0xd, 0x5d, 0x9d, 0x4, 0xe9, 0xbb, 0x3b, 0xea, 0xfc, 0x1a, 0xf4, 0xf, 0xd4, 0xaf, 0x81, 0x1b, 0x46, 0x34, 0x84, 0x11, 0x61, 0xa7, 0x27, 0x9a, 0xc2, 0x52, 0x6e, 0xe6, 0x17, 0x9a, 0xc3, 0x59, 0xa6, 0xb3, 0xf1, 0xbd, 0x1b, 0xb3, 0xf0, 0x18, 0x55, 0xf9, 0x61, 0xf9, 0x6c, 0x96, 0x63, 0x1e, 0x5e, 0xff, 0x2b, 0xf7, 0x5b, 0xff, 0xb, 0x69, 0x5a, 0x14, 0xfa, 0x84, 0xf6, 0xc2, 0x8, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_current_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xb5, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xcf, 0x21, 0x6e, 0x2, 0x61, 0x10, 0xc5, 0xf1, 0xff, 0x7b, 0x1f, 0x88, 0x1e, 0x0, 0x1, 0xa2, 0x8e, 0x3, 0xac, 0x22, 0x4d, 0x36, 0xa8, 0x35, 0x88, 0xde, 0x81, 0x9e, 0x81, 0xb, 0xec, 0x55, 0xb8, 0x3, 0xc1, 0xd4, 0x11, 0xc, 0x6, 0xb8, 0x0, 0x82, 0x56, 0x20, 0x7a, 0x85, 0xe5, 0x1b, 0x5c, 0xa9, 0x58, 0x52, 0x1, 0x92, 0x97, 0x4c, 0x32, 0x62, 0xf2, 0x9b, 0x19, 0xb8, 0x33, 0xba, 0xb6, 0xb5, 0x8b, 0x72, 0x33, 0xb5, 0xa2, 0xa, 0xe8, 0xdd, 0x18, 0xfe, 0x89, 0x88, 0xcf, 0xed, 0xfa, 0x6d, 0xe, 0x75, 0xfe, 0x3, 0xd4, 0x2e, 0xc6, 0x9b, 0x85, 0x22, 0x26, 0x12, 0xd, 0x72, 0xa7, 0x75, 0x5d, 0xe4, 0x26, 0x82, 0x4e, 0x48, 0xcb, 0xdd, 0x6a, 0xf4, 0xe, 0x75, 0x4e, 0x0, 0x45, 0xf9, 0xf2, 0x21, 0x62, 0xe6, 0x94, 0x48, 0xa9, 0x6b, 0xdb, 0xb4, 0x57, 0xb2, 0x24, 0x22, 0xe7, 0x61, 0xff, 0xf5, 0xfb, 0x78, 0xfa, 0x3a, 0xec, 0xd, 0x60, 0x45, 0x25, 0xa9, 0xb1, 0xd3, 0xff, 0x3f, 0xdb, 0x48, 0x3a, 0x7, 0xae, 0x0, 0xc, 0x90, 0xa1, 0x8f, 0xd4, 0x7e, 0x76, 0xab, 0xa2, 0x84, 0x62, 0xf0, 0xb, 0xdc, 0x93, 0x27, 0xf0, 0x4, 0x1e, 0x2, 0x5c, 0x0, 0x20, 0x84, 0x2f, 0x10, 0x74, 0xfb, 0x66, 0x2f, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x9c, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0x3d, 0x48, 0x5b, 0x58, 0x66, 0x5b, 0x57, 0x65, 0x57, 0x54, 0x62, 0x55, 0x53, 0x62, 0x4a, 0x46, 0x52, 0x46, 0x41, 0x4e, 0x45, 0x41, 0x4d, 0x55, 0x52, 0x60, 0x44, 0x41, 0x4c, 0x53, 0x50, 0x5e, 0x43, 0x40, 0x4b, 0x52, 0x4e, 0x5d, 0x41, 0x3e, 0x4a, 0x4f, 0x4d, 0x5a, 0x3f, 0x3d, 0x48, 0x4e, 0x4b, 0x59, 0x3e, 0x3c, 0x47, 0x4d, 0x4a, 0x58, 0x3d, 0x3b, 0x46, 0x4b, 0x49, 0x54, 0x3c, 0x3a, 0x44, 0x4b, 0x47, 0x54, 0x3b, 0x39, 0x43, 0x3b, 0x39, 0x42, 0x3b, 0x38, 0x43, 0x3b, 0x38, 0x42, 0x3a, 0x37, 0x41, 0x39, 0x37, 0x41, 0x3a, 0x38, 0x41, 0x39, 0x36, 0x3f, 0x38, 0x36, 0x3f, 0x39, 0x36, 0x40, 0x38, 0x36, 0x40, 0x37, 0x35, 0x3e, 0x37, 0x34, 0x3e, 0x36, 0x35, 0x3d, 0x35, 0x32, 0x3b, 0x59, 0xdd, 0xd3, 0xff, 0x0, 0x0, 0x0, 0x11, 0x74, 0x52, 0x4e, 0x53, 0x4, 0xa, 0x11, 0x19, 0x1f, 0x22, 0x24, 0x15, 0x25, 0x34, 0x3f, 0x46, 0x47, 0x48, 0x77, 0xef, 0xef, 0xa3, 0x31, 0x6b, 0xc2, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x33, 0x37, 0xd5, 0x7c, 0x5e, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xa2, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x45, 0xcd, 0xd9, 0x12, 0x82, 0x30, 0xc, 0x40, 0xd1, 0x0, 0x2d, 0x4b, 0x5b, 0x36, 0x59, 0x44, 0x44, 0x44, 0xa4, 0x68, 0x59, 0x54, 0xfc, 0xff, 0x8f, 0x33, 0x30, 0x4c, 0x3d, 0x93, 0xa7, 0x3b, 0x93, 0x4, 0xc0, 0x30, 0x2d, 0x42, 0x6d, 0x44, 0x89, 0x65, 0x1a, 0x0, 0x86, 0xe3, 0x7a, 0x8c, 0xb, 0xdf, 0x17, 0x9c, 0x79, 0xae, 0x63, 0x80, 0xe9, 0x6, 0x61, 0x7c, 0xd8, 0xc4, 0x61, 0xe0, 0x9a, 0x60, 0x79, 0x51, 0x92, 0x66, 0x9b, 0x34, 0x89, 0x3c, 0xb, 0x8, 0xcb, 0xb3, 0xe3, 0x2e, 0xcb, 0x19, 0x1, 0xca, 0x8b, 0x93, 0x56, 0x70, 0xa, 0xb6, 0x28, 0xcf, 0x5a, 0x29, 0x6c, 0xb0, 0xfd, 0xea, 0xa2, 0x55, 0xfe, 0x1a, 0xea, 0xab, 0x56, 0xaf, 0x41, 0x34, 0x37, 0xad, 0xc1, 0x15, 0xca, 0xdb, 0xbb, 0xd6, 0xe2, 0x51, 0xc2, 0xba, 0x7f, 0xe8, 0xf0, 0x2d, 0x6, 0x29, 0xfb, 0x5e, 0xca, 0xc7, 0x53, 0xca, 0x3d, 0xa8, 0x61, 0x50, 0xc3, 0xa8, 0xc6, 0x41, 0xed, 0x61, 0x9a, 0xa6, 0x19, 0xbd, 0xe6, 0xf7, 0x1e, 0x3e, 0xcb, 0x82, 0x83, 0xbe, 0x18, 0x7e, 0xa1, 0xe5, 0x17, 0x1f, 0xcf, 0x5d, 0x82, 0x6b, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_menu_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x47, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x64, 0xc0, 0x1, 0xfe, 0xff, 0xff, 0x2f, 0xcb, 0xc0, 0xc0, 0x60, 0x3, 0xe5, 0x1e, 0x61, 0x64, 0x64, 0x7c, 0x8c, 0x4d, 0x1d, 0x13, 0x2e, 0x3, 0xa0, 0x9a, 0xb9, 0xa1, 0xd8, 0x6, 0x97, 0x22, 0x7c, 0x6, 0x10, 0x5, 0xf0, 0x19, 0x70, 0x84, 0x81, 0x81, 0xe1, 0x2b, 0x14, 0x1f, 0xa6, 0xd4, 0x22, 0xda, 0x1, 0x46, 0x5c, 0x12, 0xa3, 0xb1, 0x40, 0x47, 0x30, 0x1a, 0xb, 0xc, 0xc, 0x0, 0xfd, 0x7d, 0x1b, 0x13, 0xc4, 0xa1, 0x25, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x81, 0x81, 0x11, 0x5d, 0xe0, 0xc1, 0x83, 0x7, 0xff, 0xf1, 0x69, 0x50, 0x50, 0x50, 0x40, 0xd1, 0xc3, 0x44, 0xa9, 0xb, 0xa8, 0x6f, 0x0, 0x23, 0x23, 0x63, 0x3c, 0x3, 0x3, 0xc3, 0x57, 0x2c, 0x6a, 0xbf, 0x33, 0x32, 0x32, 0xa6, 0x63, 0xa8, 0xc7, 0x66, 0xea, 0xfd, 0xfb, 0xf7, 0x35, 0x18, 0x18, 0x18, 0x56, 0x31, 0x32, 0x32, 0xea, 0x42, 0x85, 0x6e, 0x30, 0x33, 0x33, 0x87, 0xc9, 0xca, 0xca, 0x5e, 0x26, 0xca, 0x0, 0x6, 0x6, 0x6, 0x86, 0x17, 0x2f, 0x5e, 0x70, 0xff, 0xfc, 0xf9, 0x73, 0xa, 0x3, 0x3, 0x3, 0x3, 0x3b, 0x3b, 0x7b, 0x8e, 0x84, 0x84, 0x4, 0x36, 0x57, 0xd, 0x2, 0x0, 0x0, 0x67, 0xf2, 0x14, 0xc2, 0xc2, 0xbe, 0xf5, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tab_menu_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x47, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x64, 0xc0, 0x1, 0xfe, 0xff, 0xff, 0x2f, 0xcb, 0xc0, 0xc0, 0x60, 0x3, 0xe5, 0x1e, 0x61, 0x64, 0x64, 0x7c, 0x8c, 0x4d, 0x1d, 0x13, 0x2e, 0x3, 0xa0, 0x9a, 0xb9, 0xa1, 0xd8, 0x6, 0x97, 0x22, 0x7c, 0x6, 0x10, 0x5, 0xf0, 0x19, 0x70, 0x84, 0x81, 0x81, 0xe1, 0x2b, 0x14, 0x1f, 0xa6, 0xd4, 0x22, 0xda, 0x1, 0x46, 0x5c, 0x12, 0xa3, 0xb1, 0x40, 0x47, 0x30, 0x1a, 0xb, 0xc, 0xc, 0x0, 0xfd, 0x7d, 0x1b, 0x13, 0xc4, 0xa1, 0x25, 0x31, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x6f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x5, 0xa3, 0x80, 0x81, 0x81, 0x11, 0x5d, 0xe0, 0xc1, 0x83, 0x7, 0xff, 0xf1, 0x69, 0x50, 0x50, 0x50, 0x40, 0xd1, 0xc3, 0x44, 0xa9, 0xb, 0xa8, 0x6f, 0x0, 0x23, 0x23, 0x63, 0x3c, 0x3, 0x3, 0xc3, 0x57, 0x2c, 0x6a, 0xbf, 0x33, 0x32, 0x32, 0xa6, 0x63, 0xa8, 0xc7, 0x66, 0xea, 0xfd, 0xfb, 0xf7, 0x35, 0x18, 0x18, 0x18, 0x56, 0x31, 0x32, 0x32, 0xea, 0x42, 0x85, 0x6e, 0x30, 0x33, 0x33, 0x87, 0xc9, 0xca, 0xca, 0x5e, 0x26, 0xca, 0x0, 0x6, 0x6, 0x6, 0x86, 0x17, 0x2f, 0x5e, 0x70, 0xff, 0xfc, 0xf9, 0x73, 0xa, 0x3, 0x3, 0x3, 0x3, 0x3b, 0x3b, 0x7b, 0x8e, 0x84, 0x84, 0x4, 0x36, 0x57, 0xd, 0x2, 0x0, 0x0, 0x67, 0xf2, 0x14, 0xc2, 0xc2, 0xbe, 0xf5, 0xb5, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char toggle_off_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0xa2, 0x9d, 0x7e, 0x84, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x2, 0x73, 0x49, 0x44, 0x41, 0x54, 0x68, 0x81, 0xed, 0x98, 0x4d, 0x4b, 0x1b, 0x51, 0x14, 0x86, 0x1f, 0x33, 0x38, 0xa9, 0x2d, 0xc6, 0x14, 0x46, 0xd2, 0x66, 0xba, 0x2a, 0xae, 0xba, 0xae, 0xa5, 0x3b, 0xd7, 0x11, 0xa4, 0x24, 0x6b, 0x21, 0xbf, 0xa0, 0x83, 0xc5, 0x75, 0x77, 0x5d, 0xdb, 0x45, 0x83, 0x4b, 0x5, 0x51, 0x68, 0x83, 0x20, 0x45, 0xa6, 0x4b, 0x77, 0xa5, 0x98, 0xfe, 0x6, 0x5d, 0x94, 0x99, 0x90, 0x81, 0x91, 0xaa, 0x83, 0xa6, 0xc9, 0x94, 0x4c, 0x17, 0x93, 0x94, 0x50, 0x6d, 0x31, 0xf7, 0x8c, 0x6d, 0xc1, 0x79, 0xe0, 0x2e, 0xcf, 0x79, 0xcf, 0x7d, 0xef, 0x7, 0xe7, 0x5e, 0x48, 0x49, 0x49, 0x49, 0x49, 0xb9, 0xb9, 0x8c, 0x5d, 0x43, 0xbe, 0x7c, 0x7f, 0x4c, 0x0, 0x3a, 0x90, 0x11, 0xe6, 0xec, 0x1, 0x5d, 0xa0, 0xd, 0x1c, 0xf7, 0x47, 0x24, 0xcc, 0xf9, 0x93, 0x24, 0xd, 0xc8, 0x3, 0x26, 0x90, 0x4d, 0x30, 0xe7, 0x65, 0x74, 0x0, 0x97, 0xd8, 0x8, 0x31, 0x49, 0x18, 0x30, 0x6, 0x14, 0x81, 0x2, 0x80, 0x65, 0x59, 0x33, 0xa5, 0x52, 0xa9, 0x6c, 0x18, 0xc6, 0xac, 0xae, 0xeb, 0x45, 0x80, 0x6e, 0xb7, 0xdb, 0xf4, 0x7d, 0xbf, 0x61, 0xdb, 0xf6, 0x4e, 0xad, 0x56, 0x3b, 0x48, 0x40, 0x13, 0xc0, 0x23, 0x36, 0x42, 0x44, 0x12, 0x6, 0x98, 0x40, 0xc1, 0x34, 0x4d, 0x7d, 0x6d, 0x6d, 0x6d, 0xb9, 0x58, 0x2c, 0x56, 0xf8, 0xfd, 0xb6, 0xef, 0xb9, 0xae, 0xbb, 0x5d, 0xad, 0x56, 0x57, 0x3c, 0xcf, 0xb, 0x13, 0xd0, 0x16, 0x9b, 0x20, 0x35, 0x20, 0xf, 0x3c, 0x34, 0x4d, 0x53, 0xaf, 0xd7, 0xeb, 0x6f, 0x72, 0xb9, 0xdc, 0xe3, 0xab, 0x4, 0x9d, 0x9e, 0x9e, 0x7e, 0xae, 0x54, 0x2a, 0xcf, 0x13, 0x32, 0xe1, 0x10, 0xc1, 0x71, 0x90, 0x5c, 0x50, 0x63, 0xc4, 0xab, 0xcf, 0xfa, 0xfa, 0xfa, 0xf2, 0x55, 0x27, 0xf, 0x90, 0xcb, 0xe5, 0x66, 0x37, 0x36, 0x36, 0x5e, 0x8, 0xb4, 0x87, 0x79, 0x80, 0x60, 0x21, 0x35, 0x81, 0xf0, 0x5d, 0xc0, 0xb0, 0x2c, 0x6b, 0x66, 0x6e, 0x6e, 0xee, 0xe5, 0xa8, 0x45, 0x4c, 0x4e, 0x4e, 0x3e, 0xd2, 0x34, 0x6d, 0xaf, 0xd1, 0x68, 0x7c, 0x15, 0xd4, 0x0, 0xf1, 0x1c, 0xbe, 0xf5, 0xc7, 0xc8, 0x48, 0x76, 0x40, 0x1e, 0xa0, 0x54, 0x2a, 0x95, 0x15, 0xf3, 0x64, 0xe6, 0xe7, 0xe7, 0x9f, 0x9, 0xf4, 0x87, 0x99, 0x52, 0xd, 0x94, 0x18, 0x70, 0x1b, 0xc0, 0x30, 0x8c, 0x27, 0xaa, 0x9, 0xa6, 0xa7, 0xa7, 0x9f, 0xa, 0xf4, 0x2f, 0xd4, 0xa2, 0x82, 0xc4, 0x80, 0x71, 0x0, 0x5d, 0xd7, 0xef, 0x29, 0x27, 0x18, 0x1f, 0xbf, 0x2f, 0xd0, 0x1f, 0x46, 0x57, 0xd, 0x94, 0x76, 0x69, 0x44, 0x91, 0xa8, 0x29, 0x4b, 0xaa, 0xa3, 0x53, 0xce, 0x23, 0x31, 0x20, 0x4, 0x8, 0xc3, 0xb0, 0xa5, 0x9c, 0x40, 0x10, 0x7b, 0x59, 0x2d, 0x2a, 0x48, 0xc, 0x38, 0x7, 0xf0, 0x7d, 0x7f, 0x5f, 0x35, 0x81, 0xef, 0xfb, 0x9f, 0x4, 0xfa, 0x17, 0x6a, 0x51, 0x41, 0x62, 0xc0, 0x31, 0x80, 0x6d, 0xdb, 0x3b, 0xc4, 0xf, 0x96, 0x51, 0xe9, 0xed, 0xee, 0xee, 0xbe, 0x17, 0xe8, 0x5f, 0xa8, 0x45, 0x5, 0xa9, 0x1, 0x9d, 0x5a, 0xad, 0x76, 0xe0, 0xba, 0xee, 0xf6, 0xa8, 0xc1, 0x8e, 0xe3, 0xd4, 0x57, 0x57, 0x57, 0xf, 0x5, 0xfa, 0x3, 0x3a, 0xc0, 0x89, 0x6a, 0xb0, 0xc4, 0x80, 0x88, 0x7e, 0x1f, 0x5e, 0xad, 0x56, 0x57, 0x82, 0x20, 0x68, 0x5c, 0x35, 0x30, 0x8, 0x82, 0xfd, 0xc5, 0xc5, 0xc5, 0xd7, 0x2, 0xed, 0x61, 0x1c, 0xfe, 0xd1, 0x25, 0x8, 0xf1, 0x2e, 0xf0, 0x3c, 0xcf, 0xb, 0xcb, 0xe5, 0xb2, 0xd5, 0x6c, 0x36, 0xdf, 0xf1, 0xe7, 0xe3, 0xd0, 0x73, 0x1c, 0xe7, 0xed, 0xc2, 0xc2, 0x82, 0x75, 0x74, 0x74, 0xf4, 0x5d, 0xa8, 0xd, 0xf1, 0x63, 0x48, 0x79, 0xf5, 0x41, 0xd6, 0xa, 0xf, 0x8, 0x80, 0xcc, 0xd9, 0xd9, 0xd9, 0xc4, 0xe6, 0xe6, 0xe6, 0x47, 0x4d, 0xd3, 0xf6, 0xa, 0x85, 0x42, 0x37, 0x9b, 0xcd, 0xde, 0xc9, 0x64, 0x32, 0xb7, 0xa2, 0x28, 0xa, 0x3b, 0x9d, 0xce, 0x97, 0x56, 0xab, 0xf5, 0x61, 0x6b, 0x6b, 0xeb, 0xd5, 0xd2, 0xd2, 0x92, 0xdd, 0x6e, 0xb7, 0x55, 0xee, 0x8c, 0x5f, 0xf9, 0x6f, 0x9e, 0xc3, 0x3, 0xfe, 0xe6, 0x87, 0x88, 0x83, 0x70, 0xe5, 0x7, 0x5c, 0xd7, 0x97, 0xd8, 0x14, 0x71, 0x7b, 0x9a, 0xe4, 0x97, 0xd8, 0x39, 0xf1, 0x91, 0x3b, 0x21, 0xc1, 0x2f, 0xb1, 0x94, 0x94, 0x94, 0x94, 0x94, 0x9b, 0xcc, 0xf, 0x49, 0x2b, 0xc7, 0x9a, 0xce, 0xd2, 0xbd, 0x5d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x7a, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x14, 0x14, 0x17, 0x20, 0x20, 0x25, 0x24, 0x24, 0x28, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x10, 0x10, 0x13, 0x22, 0x22, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x19, 0x19, 0x1c, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x12, 0x12, 0x14, 0x23, 0x23, 0x27, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x15, 0x15, 0x18, 0x20, 0x20, 0x25, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x24, 0x24, 0x28, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x27, 0x15, 0x15, 0x18, 0x23, 0x23, 0x28, 0x12, 0x12, 0x14, 0x0, 0x0, 0x0, 0x1a, 0x1a, 0x1e, 0x0, 0x0, 0x0, 0x11, 0x11, 0x13, 0x22, 0x22, 0x26, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x24, 0x24, 0x29, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x28, 0x25, 0x25, 0x28, 0x25, 0x25, 0x29, 0x25, 0x25, 0x27, 0x2d, 0x26, 0x2c, 0x4d, 0x2b, 0x37, 0x63, 0x2f, 0x3f, 0x6e, 0x31, 0x43, 0x71, 0x32, 0x44, 0x6c, 0x31, 0x42, 0x51, 0x2c, 0x39, 0x47, 0x2a, 0x35, 0x66, 0x30, 0x40, 0x4d, 0x2b, 0x38, 0x32, 0x26, 0x2e, 0x26, 0x25, 0x2a, 0x2e, 0x25, 0x2c, 0x3c, 0x28, 0x31, 0x52, 0x2c, 0x39, 0x68, 0x30, 0x40, 0x27, 0x25, 0x2a, 0x50, 0x2c, 0x38, 0x5f, 0x2e, 0x3d, 0x35, 0x27, 0x2f, 0x38, 0x27, 0x30, 0x5e, 0x2e, 0x3d, 0x43, 0x2a, 0x34, 0x5f, 0x2f, 0x3e, 0x2f, 0x25, 0x2c, 0x44, 0x2a, 0x34, 0x2b, 0x26, 0x2c, 0x64, 0x2f, 0x3f, 0x36, 0x27, 0x30, 0x37, 0x27, 0x30, 0x66, 0x2f, 0x40, 0x2c, 0x26, 0x2c, 0x46, 0x2a, 0x35, 0x53, 0x2c, 0x39, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x32, 0x32, 0x37, 0x5d, 0x2e, 0x3d, 0x3e, 0x29, 0x32, 0xc9, 0xc9, 0xca, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x69, 0x30, 0x41, 0x2f, 0x26, 0x2d, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0x4e, 0x4e, 0x52, 0x48, 0x2b, 0x36, 0x2c, 0x26, 0x2b, 0x97, 0xb0, 0x86, 0xb4, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x98, 0xe5, 0xfa, 0xfe, 0x8, 0x17, 0x35, 0x86, 0xf3, 0x7, 0x3a, 0xb4, 0xb9, 0xb, 0x28, 0x8a, 0x8b, 0xf6, 0x45, 0x5, 0x9b, 0xe6, 0xe6, 0x37, 0xf, 0xfb, 0x4c, 0xfe, 0x4e, 0x4f, 0x50, 0xfb, 0x9c, 0xf6, 0x8c, 0x3b, 0xbb, 0x3c, 0x87, 0xf3, 0x53, 0x14, 0xe5, 0x7c, 0xf3, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x6b, 0x52, 0x65, 0xa5, 0x98, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x2, 0x47, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0x55, 0xfb, 0x5b, 0x93, 0x50, 0x18, 0x96, 0x3, 0xc, 0x48, 0x60, 0xde, 0x70, 0x9b, 0x43, 0x37, 0x75, 0xa6, 0x9b, 0xb5, 0xad, 0x56, 0x59, 0x99, 0xe9, 0xc6, 0x39, 0xb3, 0x56, 0x59, 0xcd, 0x4c, 0xbb, 0xd9, 0x3d, 0xdb, 0xd, 0x74, 0xa6, 0xa3, 0xdb, 0xff, 0x1e, 0x70, 0x68, 0x6e, 0xc0, 0xe0, 0xe9, 0xe9, 0x97, 0x7a, 0x79, 0x9e, 0x3, 0xf, 0x7c, 0xdf, 0xcb, 0x7b, 0xbe, 0xf3, 0x5d, 0x86, 0x86, 0xfe, 0x21, 0x10, 0x80, 0x24, 0xa9, 0x40, 0x90, 0x24, 0x20, 0x3c, 0xdd, 0x1, 0x45, 0x87, 0x18, 0x96, 0x3b, 0x17, 0x0, 0x8e, 0x65, 0x42, 0x34, 0x5, 0xdc, 0x7f, 0xa7, 0x86, 0x59, 0x5e, 0x10, 0xc3, 0x23, 0xa3, 0x63, 0xbe, 0x18, 0x1d, 0x9, 0x8b, 0x2, 0xcf, 0xe, 0x53, 0xe, 0x15, 0x60, 0x7c, 0x42, 0x9a, 0x8c, 0x44, 0x63, 0x53, 0xc5, 0x52, 0x0, 0x8a, 0x53, 0xb1, 0x68, 0x64, 0x52, 0x9a, 0x18, 0xef, 0x13, 0x1, 0xe2, 0xf2, 0xf4, 0x4c, 0x42, 0x81, 0x10, 0x21, 0x84, 0xed, 0x90, 0x9, 0x88, 0xca, 0xc8, 0x93, 0x24, 0x31, 0x33, 0x2d, 0xc7, 0x7b, 0x18, 0x88, 0x24, 0x37, 0x3b, 0xa7, 0xc0, 0xcd, 0x3b, 0x77, 0x2b, 0xf7, 0x30, 0xee, 0x3f, 0xd8, 0xb4, 0x58, 0xca, 0x70, 0x80, 0x8e, 0xb9, 0x59, 0x2e, 0x49, 0x9c, 0xed, 0x9f, 0x11, 0xe6, 0x15, 0xb4, 0xf5, 0xf0, 0xd1, 0xe3, 0xaa, 0xf5, 0xb9, 0xba, 0xfd, 0x64, 0xe7, 0xe9, 0xd6, 0xae, 0xa5, 0x64, 0xd0, 0x4e, 0xe6, 0x5, 0xa6, 0x1b, 0x7, 0x90, 0x5a, 0x38, 0xaf, 0xa0, 0xbd, 0x67, 0xcf, 0x7b, 0x2d, 0x5e, 0xbc, 0xdc, 0xdb, 0xf5, 0x8d, 0xc5, 0xe2, 0x42, 0xea, 0xf7, 0x26, 0x28, 0x59, 0x5c, 0x82, 0xaf, 0xf6, 0xb7, 0xfb, 0x2d, 0x5e, 0xef, 0xbf, 0xa9, 0xfa, 0x31, 0x2c, 0xa5, 0xe5, 0xc, 0x96, 0x40, 0xd0, 0xfc, 0x32, 0x7c, 0xfb, 0xee, 0xbd, 0xd3, 0xe2, 0xc3, 0xc7, 0x4f, 0xbe, 0xe7, 0xb1, 0xcc, 0xd3, 0x98, 0x0, 0x84, 0x84, 0xb, 0xf0, 0x60, 0xc7, 0x6d, 0xf1, 0xf9, 0xc0, 0x7e, 0xa8, 0xd5, 0x1b, 0xcd, 0x56, 0x49, 0x6d, 0x18, 0xb0, 0x16, 0xcd, 0x7a, 0x7b, 0x31, 0x9b, 0xc3, 0x7b, 0x20, 0x19, 0x31, 0x86, 0xe, 0x8f, 0xdc, 0x4, 0x47, 0x87, 0xf6, 0x43, 0xfb, 0xb8, 0xf6, 0xa5, 0x51, 0x53, 0x4d, 0x47, 0xd5, 0xf6, 0x36, 0x90, 0x4f, 0x33, 0x24, 0x26, 0x60, 0x2f, 0x5d, 0x46, 0x27, 0xa7, 0x6e, 0x82, 0xd3, 0x13, 0x5b, 0x80, 0xe9, 0x74, 0xdc, 0x51, 0x75, 0x93, 0x40, 0xef, 0x12, 0x14, 0xb, 0x2c, 0x85, 0x9, 0xe4, 0x2b, 0xa, 0xaa, 0x78, 0x4, 0xac, 0x5a, 0xc1, 0x77, 0x55, 0x37, 0x96, 0xaf, 0x75, 0xb5, 0xdd, 0x6e, 0x6b, 0xd6, 0x62, 0x7f, 0xbf, 0x2a, 0xdb, 0x4, 0x6c, 0x58, 0xf1, 0x55, 0xa0, 0x99, 0xa, 0xea, 0xdf, 0x54, 0xd3, 0x53, 0x6d, 0x7b, 0x28, 0x60, 0xc4, 0x6b, 0xd0, 0x37, 0x6, 0x7a, 0xa7, 0xa4, 0x35, 0x5b, 0x4e, 0x82, 0x6e, 0xc, 0x40, 0x28, 0x1b, 0x70, 0xa, 0x6a, 0x53, 0x6f, 0xd6, 0x4b, 0x4e, 0x82, 0xee, 0x29, 0x18, 0x79, 0xb0, 0x12, 0x90, 0x7, 0x5a, 0xe7, 0xbb, 0x11, 0xcb, 0x96, 0x66, 0x2f, 0x18, 0x2b, 0x92, 0x9d, 0x7, 0x66, 0x26, 0x5e, 0x47, 0x7f, 0x91, 0x89, 0x66, 0x2d, 0x2c, 0xfe, 0x79, 0x2d, 0xdc, 0x38, 0xab, 0x5, 0xef, 0x6a, 0xfc, 0xe1, 0xef, 0xdf, 0x5b, 0x8d, 0x66, 0x3f, 0xb8, 0xb9, 0xaa, 0xc0, 0x9f, 0xce, 0x7e, 0xe0, 0xe3, 0xbf, 0x7a, 0xab, 0xa7, 0x1f, 0x98, 0x1d, 0x89, 0x13, 0xd6, 0x6e, 0xc3, 0x32, 0xc4, 0xd, 0x9, 0xd9, 0x80, 0xc6, 0xe5, 0xe9, 0x9f, 0x58, 0x13, 0xb8, 0x78, 0x7f, 0x4f, 0x4b, 0x32, 0x92, 0x18, 0x89, 0xe6, 0x3, 0x5b, 0xa2, 0xf1, 0xf3, 0x7c, 0x34, 0x22, 0x4a, 0x4c, 0xd2, 0xd1, 0x98, 0x9, 0x2a, 0xc5, 0xf2, 0xd9, 0x74, 0x61, 0x7d, 0x2c, 0x0, 0xeb, 0x85, 0x74, 0x96, 0x67, 0x53, 0x94, 0x6b, 0x36, 0x10, 0x20, 0x43, 0xe7, 0x36, 0xe4, 0xe0, 0xb9, 0x20, 0x6f, 0xe4, 0xe8, 0x8c, 0xf7, 0x6c, 0x31, 0x26, 0x53, 0xf0, 0x60, 0x32, 0x46, 0xd3, 0x80, 0xc9, 0xf4, 0xff, 0xe2, 0x17, 0x82, 0xde, 0x40, 0xde, 0x2d, 0xc3, 0x2a, 0xca, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char toggle_on_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0xa2, 0x9d, 0x7e, 0x84, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x2, 0x97, 0x49, 0x44, 0x41, 0x54, 0x68, 0x81, 0xed, 0x98, 0x4f, 0x48, 0x14, 0x51, 0x1c, 0xc7, 0x3f, 0xb3, 0xbb, 0xed, 0x9f, 0xdc, 0x76, 0x47, 0x9, 0xf2, 0x4f, 0x91, 0x44, 0x4, 0x2d, 0x6c, 0x8, 0x66, 0x4, 0xe1, 0xa1, 0x53, 0x97, 0x20, 0xf4, 0xe4, 0xa1, 0x43, 0x75, 0x49, 0x88, 0x88, 0xf0, 0x6a, 0xd4, 0xa1, 0x8e, 0x19, 0x25, 0x52, 0xd1, 0x45, 0x8a, 0x10, 0x43, 0x90, 0xe, 0x85, 0x78, 0x58, 0x8c, 0xfe, 0xa1, 0x41, 0x4a, 0xe1, 0x51, 0xc5, 0xb2, 0x34, 0x2, 0x1b, 0x77, 0xcd, 0x71, 0xdc, 0x75, 0xa6, 0xc3, 0x8c, 0x5b, 0x7, 0x3, 0x77, 0x7e, 0x63, 0x4, 0xce, 0x7, 0x1e, 0xec, 0x83, 0xf7, 0xfd, 0xbd, 0xdf, 0xfb, 0xce, 0xbe, 0xc7, 0xef, 0x3d, 0xf0, 0xf1, 0xf1, 0xf1, 0xf1, 0xd9, 0xba, 0x28, 0x9b, 0x10, 0x4f, 0x75, 0x5a, 0xc, 0x8, 0x3, 0x1, 0x61, 0x4c, 0x13, 0x58, 0x1, 0x74, 0x40, 0x73, 0x9a, 0x25, 0x8c, 0x59, 0xc4, 0x4b, 0x3, 0x54, 0xa0, 0x6, 0x88, 0x78, 0x18, 0x73, 0x3d, 0xc, 0xe0, 0xb, 0xb6, 0x11, 0x62, 0xbc, 0x30, 0x40, 0x1, 0xaa, 0x81, 0x5d, 0x1e, 0xc4, 0xe2, 0xf8, 0x8d, 0x13, 0xfb, 0xd3, 0x2d, 0x75, 0x4d, 0xf1, 0xaa, 0x44, 0x43, 0x30, 0x12, 0xaa, 0x6, 0x58, 0x35, 0xa, 0x5f, 0x73, 0xb3, 0xb9, 0x91, 0xf1, 0x9e, 0xb1, 0xfe, 0x4c, 0xfb, 0xc0, 0x84, 0x33, 0xf4, 0x1b, 0xb6, 0x11, 0x22, 0xbc, 0x30, 0xa0, 0x6, 0xf, 0x16, 0x9f, 0xa8, 0xad, 0x8, 0x9f, 0x19, 0x3a, 0xdf, 0xa6, 0xee, 0x2d, 0x6f, 0xe6, 0x6f, 0xdb, 0xc6, 0xb2, 0x4c, 0x6d, 0x5a, 0xeb, 0xeb, 0x6e, 0xec, 0xea, 0xc8, 0xce, 0x64, 0xf3, 0x78, 0x60, 0x82, 0xd4, 0x0, 0x15, 0xd8, 0x27, 0x8c, 0x41, 0xa2, 0xb6, 0x22, 0xdc, 0x3a, 0x7a, 0xa9, 0x33, 0xaa, 0xc6, 0xe, 0x6f, 0x64, 0xbc, 0xae, 0xe9, 0xef, 0xee, 0xa7, 0x6f, 0x5e, 0x74, 0x4c, 0x98, 0x44, 0xb0, 0x1d, 0x24, 0x7, 0x94, 0x82, 0xfd, 0xf5, 0xc5, 0x9c, 0x7b, 0xd1, 0xda, 0xb6, 0xd1, 0xc5, 0x3, 0xc4, 0xd4, 0x58, 0xc3, 0xd9, 0x97, 0x17, 0x2e, 0x3b, 0xdd, 0xdd, 0x8, 0x3e, 0x64, 0xd0, 0xad, 0x10, 0x28, 0x7, 0x76, 0xa, 0xf4, 0x80, 0xbd, 0xe7, 0xf, 0x9c, 0x4c, 0x5d, 0xa1, 0xc4, 0x45, 0x44, 0x93, 0xd1, 0x14, 0x1, 0x25, 0x33, 0x3d, 0x34, 0x99, 0x5, 0x96, 0x9d, 0x56, 0x32, 0x92, 0x7f, 0x80, 0x2a, 0xd0, 0x16, 0x49, 0xb7, 0xd4, 0x35, 0xb9, 0xca, 0x43, 0x51, 0x2, 0x87, 0x4e, 0xd7, 0x9f, 0x72, 0x7a, 0x49, 0xb7, 0xf3, 0x4b, 0xc, 0xd8, 0x2e, 0xd0, 0x16, 0x29, 0xab, 0x4a, 0x1c, 0x71, 0xab, 0x8d, 0x57, 0xc6, 0x8f, 0x4a, 0x73, 0x91, 0x18, 0xb0, 0x4d, 0xa0, 0x2d, 0x12, 0x8a, 0x84, 0x2a, 0x5, 0xda, 0x2a, 0xe7, 0x67, 0xd8, 0x6d, 0xc, 0x69, 0x95, 0x26, 0xc7, 0x72, 0x5f, 0xd4, 0x59, 0xbf, 0x2b, 0x42, 0xd7, 0x41, 0x24, 0x6, 0xe4, 0x5, 0xda, 0x22, 0x85, 0x95, 0xd5, 0x39, 0xb7, 0xda, 0x55, 0xa3, 0xb0, 0xa6, 0x75, 0x9d, 0x8b, 0xc4, 0x80, 0x25, 0x81, 0xb6, 0xc8, 0xe2, 0x6c, 0x6e, 0xd8, 0xad, 0xf6, 0xe7, 0x5c, 0xee, 0xad, 0x34, 0x17, 0x89, 0x1, 0x9e, 0xd4, 0xe2, 0xe3, 0x3d, 0x63, 0xfd, 0x58, 0x96, 0x59, 0xb2, 0xd0, 0xb2, 0xcc, 0xf, 0x8f, 0x46, 0x9f, 0x4a, 0x73, 0x91, 0x1a, 0x60, 0x8, 0xf4, 0x0, 0x64, 0xda, 0x7, 0x26, 0xb4, 0x69, 0xad, 0xaf, 0xe4, 0xc9, 0xa7, 0xe6, 0x9f, 0xc, 0x5d, 0x1b, 0x9c, 0x74, 0x72, 0x58, 0x70, 0x3b, 0xbf, 0xc4, 0x0, 0xb, 0xf, 0x2e, 0x23, 0x0, 0xdd, 0x8d, 0x5d, 0x1d, 0xcb, 0x9a, 0x3e, 0xb2, 0xd1, 0xf1, 0xfa, 0xf, 0x7d, 0xf8, 0xc1, 0xb1, 0xbb, 0xb7, 0x9c, 0xee, 0xc, 0x82, 0x43, 0x50, 0x52, 0x9, 0x82, 0x5d, 0x7d, 0x5, 0x80, 0xb8, 0x24, 0x88, 0x91, 0x35, 0xcc, 0x8f, 0x8f, 0xdf, 0xf, 0x1e, 0x6c, 0x4e, 0xef, 0x88, 0x26, 0xa3, 0x29, 0x14, 0x65, 0xfd, 0xaa, 0xd0, 0xb2, 0x4c, 0x6d, 0x6a, 0xbe, 0xf7, 0x5e, 0xfd, 0x9d, 0xab, 0xfa, 0x5c, 0xb6, 0x80, 0x7d, 0x19, 0xfa, 0x2e, 0x99, 0x5b, 0x6a, 0x0, 0x40, 0xe, 0x8f, 0x4c, 0x18, 0xbe, 0xfd, 0xea, 0x35, 0x1, 0x25, 0x93, 0xdc, 0x53, 0xbe, 0x12, 0x8a, 0x4, 0xcb, 0x2, 0xc1, 0x40, 0x14, 0x8b, 0x7c, 0x41, 0xcf, 0x7f, 0xca, 0x7d, 0xd6, 0x9e, 0x8f, 0x74, 0xbe, 0xb9, 0xde, 0xdb, 0xfc, 0xf0, 0x59, 0x61, 0xd1, 0x30, 0xf9, 0x8f, 0xae, 0xc3, 0x6b, 0xfc, 0xcb, 0x7, 0x91, 0x19, 0x4, 0xfb, 0xfe, 0x4f, 0x36, 0xeb, 0x49, 0x2c, 0x89, 0x5d, 0x9e, 0x7a, 0xf9, 0x24, 0xb6, 0x84, 0x7d, 0xf0, 0x2e, 0xe0, 0xe1, 0x93, 0x98, 0x8f, 0x8f, 0x8f, 0x8f, 0xcf, 0x56, 0xe6, 0x17, 0xc3, 0x92, 0xcd, 0xe2, 0x0, 0xde, 0xae, 0x9b, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x20, 0x8, 0x3, 0x0, 0x0, 0x0, 0x95, 0x43, 0x8e, 0xb6, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x1, 0x74, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xd, 0xf, 0x1a, 0x1a, 0x1e, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x24, 0x24, 0x29, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xa, 0xa, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x11, 0x14, 0x23, 0x23, 0x28, 0x12, 0x12, 0x15, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xb, 0xb, 0xd, 0x23, 0x23, 0x28, 0xb, 0xb, 0xd, 0x1e, 0x1e, 0x22, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0x1a, 0x1a, 0x1e, 0x1a, 0x1a, 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x20, 0x20, 0x24, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xe, 0x10, 0xb, 0xb, 0xd, 0x0, 0x0, 0x0, 0x13, 0x13, 0x15, 0x0, 0x0, 0x0, 0xb, 0xb, 0xc, 0x1d, 0x1d, 0x21, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x25, 0x25, 0x2a, 0x24, 0x24, 0x29, 0x25, 0x2c, 0x36, 0x27, 0x49, 0x65, 0x29, 0x5d, 0x85, 0x2a, 0x66, 0x95, 0x2a, 0x68, 0x99, 0x29, 0x64, 0x92, 0x28, 0x4c, 0x6b, 0x25, 0x27, 0x2d, 0x27, 0x43, 0x5c, 0x29, 0x5f, 0x89, 0x27, 0x49, 0x66, 0x25, 0x30, 0x3e, 0x25, 0x26, 0x2d, 0x25, 0x25, 0x2b, 0x25, 0x26, 0x2c, 0x25, 0x2d, 0x38, 0x25, 0x3a, 0x4c, 0x27, 0x4d, 0x6b, 0x29, 0x60, 0x8c, 0x27, 0x44, 0x5c, 0x27, 0x4b, 0x69, 0x28, 0x59, 0x7f, 0x25, 0x34, 0x43, 0x25, 0x35, 0x45, 0x28, 0x58, 0x7f, 0x25, 0x26, 0x2b, 0x27, 0x40, 0x57, 0x27, 0x41, 0x57, 0x25, 0x2a, 0x33, 0x29, 0x5d, 0x87, 0x25, 0x34, 0x44, 0x25, 0x2b, 0x34, 0x40, 0x40, 0x44, 0xad, 0xad, 0xaf, 0xff, 0xff, 0xff, 0xf2, 0xf2, 0xf2, 0x77, 0x77, 0x7a, 0x5b, 0x5b, 0x5f, 0x4e, 0x4e, 0x52, 0xc9, 0xc9, 0xca, 0x27, 0x43, 0x5b, 0x27, 0x4d, 0x6c, 0x27, 0x4e, 0x6d, 0xbb, 0xbb, 0xbd, 0x69, 0x69, 0x6c, 0x28, 0x56, 0x7b, 0x26, 0x3b, 0x4e, 0x26, 0x3a, 0x4e, 0x32, 0x32, 0x37, 0x84, 0x84, 0x87, 0xd6, 0xd6, 0xd7, 0x29, 0x61, 0x8d, 0x25, 0x2e, 0x39, 0x92, 0x92, 0x94, 0xa0, 0xa0, 0xa2, 0xe4, 0xe4, 0xe5, 0x27, 0x44, 0x5d, 0xdd, 0xc9, 0xf2, 0x7e, 0x0, 0x0, 0x0, 0x41, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x1, 0x2, 0x3, 0x4, 0x9, 0xe, 0x13, 0x16, 0x18, 0x19, 0xa, 0x26, 0x36, 0x44, 0x4d, 0x52, 0x54, 0x55, 0x6, 0x12, 0x27, 0x43, 0x80, 0xc5, 0xe7, 0xf5, 0xfe, 0x8, 0x17, 0x35, 0x73, 0xd9, 0x7, 0x3a, 0x96, 0xf9, 0x9a, 0xb, 0x28, 0x76, 0xfb, 0x77, 0xde, 0x45, 0x5, 0x82, 0xc6, 0xc6, 0x37, 0xf, 0xe9, 0x4c, 0x4e, 0x4f, 0x50, 0x83, 0x78, 0x3b, 0x9c, 0x3c, 0x74, 0xda, 0x53, 0x14, 0x37, 0x21, 0x5a, 0x6c, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x65, 0xb5, 0xdd, 0x88, 0x9f, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x4, 0x4e, 0x1d, 0x2, 0xaf, 0x0, 0x0, 0x2, 0x28, 0x49, 0x44, 0x41, 0x54, 0x48, 0xc7, 0xd5, 0x55, 0x69, 0x57, 0xd3, 0x40, 0x14, 0x25, 0x93, 0xa4, 0x49, 0x24, 0x49, 0xd9, 0x42, 0xd7, 0x0, 0x85, 0x50, 0x2c, 0xb4, 0x68, 0x5b, 0xab, 0x28, 0xb2, 0xc, 0x4b, 0x95, 0x82, 0x56, 0xab, 0x42, 0x45, 0x5c, 0x9b, 0xad, 0x45, 0x11, 0x6d, 0x3, 0xa8, 0x7f, 0xde, 0xc4, 0x94, 0x26, 0x69, 0x30, 0x89, 0xc7, 0x2f, 0x7a, 0x3f, 0xe4, 0x9c, 0xcc, 0x3b, 0xef, 0xce, 0x7d, 0x6f, 0xde, 0x32, 0x30, 0xf0, 0xf, 0x1, 0x1, 0x28, 0x8a, 0xf9, 0x2, 0x45, 0x1, 0x72, 0xa5, 0x3b, 0xc0, 0xf0, 0x10, 0x41, 0x52, 0xd7, 0x7c, 0x40, 0x91, 0x44, 0x8, 0xc7, 0x80, 0xfb, 0x76, 0x6c, 0x90, 0xa4, 0x19, 0x36, 0x3c, 0x34, 0x3c, 0xe2, 0x89, 0xe1, 0xa1, 0x30, 0xcb, 0xd0, 0xe4, 0x20, 0xd6, 0xa7, 0x2, 0x8c, 0x8e, 0x71, 0xe3, 0x91, 0x68, 0x2c, 0x9e, 0x80, 0x3e, 0x48, 0xc4, 0x63, 0xd1, 0xc8, 0x38, 0x37, 0x36, 0xea, 0x10, 0x1, 0x92, 0xfc, 0xc4, 0xe4, 0xd4, 0x86, 0x9f, 0xf3, 0x25, 0x36, 0xa6, 0x26, 0x27, 0xf8, 0xa4, 0x8d, 0x1, 0x49, 0x51, 0xd3, 0x33, 0x82, 0xa7, 0xcf, 0xe6, 0xd6, 0x76, 0xf9, 0x81, 0x89, 0x87, 0x3b, 0x9b, 0x50, 0x98, 0x99, 0xa6, 0x52, 0x88, 0x15, 0x3f, 0xc1, 0xcc, 0x7a, 0x6a, 0xaf, 0xec, 0xee, 0x3d, 0x7a, 0x5c, 0x7d, 0x62, 0xe0, 0x69, 0xed, 0xd9, 0xf3, 0x17, 0xfb, 0x95, 0xc4, 0x2c, 0x43, 0xf4, 0xf2, 0x0, 0xd2, 0x73, 0xd7, 0x33, 0x9e, 0xfe, 0x7, 0xf5, 0x97, 0xf6, 0xff, 0xc3, 0x57, 0x7, 0x95, 0xcc, 0xfc, 0x5c, 0xfa, 0x32, 0x8, 0x8c, 0x67, 0x17, 0xbc, 0xfc, 0x8f, 0x5e, 0xd7, 0x6b, 0xce, 0x93, 0x5a, 0xfd, 0xcd, 0xd1, 0x42, 0x96, 0xcf, 0x99, 0x12, 0x10, 0x9c, 0x5e, 0xf4, 0x8c, 0xff, 0xed, 0xbb, 0xf7, 0xfd, 0x47, 0x87, 0x7b, 0x1f, 0xe0, 0x22, 0x8d, 0x9b, 0x4, 0x20, 0xc4, 0xdc, 0xb0, 0x4c, 0xd, 0x51, 0x92, 0x15, 0xa8, 0x4a, 0x4d, 0xa8, 0xb6, 0xba, 0x47, 0xc7, 0x1f, 0xdd, 0xa4, 0x9f, 0x8e, 0xe1, 0xcd, 0x7c, 0xc1, 0x8c, 0x1, 0x25, 0xd8, 0x98, 0x65, 0x69, 0x9d, 0x34, 0x3e, 0x4b, 0xd, 0x55, 0x6a, 0x59, 0x4, 0xa7, 0x5f, 0xdc, 0x4, 0x5f, 0x4f, 0x61, 0x31, 0x4b, 0xa0, 0x26, 0x1, 0x79, 0x2b, 0x6e, 0x9, 0x90, 0xda, 0x10, 0x9e, 0x74, 0x54, 0x4d, 0x56, 0x7b, 0x4, 0x67, 0xe7, 0x6e, 0x82, 0xf3, 0x33, 0x28, 0x94, 0x48, 0xcc, 0x24, 0xe0, 0x6f, 0x5b, 0x6f, 0xa8, 0x6a, 0xfa, 0xe7, 0x42, 0x54, 0x5b, 0x17, 0x5a, 0x8f, 0xa0, 0x5c, 0x75, 0x13, 0x54, 0xcb, 0x10, 0xde, 0xe1, 0xbb, 0x4, 0x64, 0xd8, 0x2a, 0xa2, 0xb6, 0xa1, 0x40, 0xfc, 0xa6, 0x3b, 0x7f, 0x17, 0x3, 0x2b, 0x20, 0xd8, 0xa2, 0x65, 0xd1, 0x3a, 0xb0, 0x2d, 0x2b, 0x3a, 0x81, 0x22, 0x5, 0xcd, 0x1, 0x8, 0xe5, 0x6d, 0xaf, 0xa0, 0xca, 0x9a, 0x2c, 0xfe, 0x4a, 0xa0, 0x16, 0xf4, 0x15, 0xf4, 0x3a, 0x58, 0xb2, 0x99, 0xda, 0x9d, 0xa6, 0x9e, 0x4b, 0x5, 0xc2, 0xa6, 0xe2, 0x5d, 0x7, 0x4b, 0x5c, 0xb7, 0xe, 0xfe, 0xba, 0x12, 0x8d, 0x5e, 0x98, 0xff, 0xf3, 0x5e, 0xb8, 0x6b, 0xf5, 0x42, 0x80, 0x6e, 0xdc, 0x77, 0x76, 0xe3, 0xf, 0x67, 0x37, 0x1a, 0xf3, 0xe0, 0xde, 0xb2, 0xa7, 0x86, 0xfe, 0x79, 0x90, 0x59, 0xbe, 0x6f, 0x9b, 0x7, 0xc6, 0x44, 0xa2, 0x98, 0x95, 0x55, 0x18, 0x18, 0xab, 0x2b, 0xc, 0x95, 0x74, 0xce, 0xb4, 0x14, 0xc1, 0xb1, 0x91, 0x68, 0x51, 0xf0, 0x77, 0x16, 0x8a, 0xd1, 0x8, 0xcb, 0x11, 0xa9, 0xbe, 0xc1, 0x8c, 0x60, 0x69, 0x92, 0xce, 0x67, 0x4b, 0x6b, 0x23, 0x3e, 0x58, 0x2b, 0x65, 0xf3, 0x34, 0x99, 0xc6, 0x5c, 0xbb, 0x1, 0x1, 0x39, 0xbc, 0xb0, 0xce, 0xfb, 0xef, 0x5, 0x7e, 0xbd, 0x80, 0xe7, 0xae, 0xde, 0x2d, 0xfa, 0x66, 0xf2, 0x5f, 0x4c, 0xfa, 0x6a, 0xfa, 0xcd, 0x66, 0xfa, 0x7f, 0xf1, 0x13, 0xb7, 0x71, 0x36, 0xc6, 0x87, 0x41, 0xd4, 0x5, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+static const unsigned char tool_button_pressed_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x2, 0x1, 0x50, 0x4c, 0x54, 0x45, 0x29, 0x3a, 0x40, 0x2d, 0x3e, 0x44, 0x26, 0x34, 0x3b, 0x24, 0x34, 0x39, 0x23, 0x31, 0x38, 0x22, 0x31, 0x37, 0x22, 0x31, 0x37, 0x22, 0x30, 0x36, 0x22, 0x31, 0x36, 0x26, 0x34, 0x3c, 0x32, 0x44, 0x4c, 0x26, 0x34, 0x39, 0x23, 0x31, 0x36, 0x21, 0x2e, 0x34, 0x1f, 0x2c, 0x30, 0x1f, 0x2b, 0x2f, 0x1f, 0x2a, 0x2e, 0x1e, 0x2b, 0x2f, 0x1f, 0x2b, 0x2e, 0x36, 0x4b, 0x52, 0x25, 0x33, 0x38, 0x20, 0x2f, 0x32, 0x1c, 0x29, 0x2e, 0x1b, 0x26, 0x2a, 0x1a, 0x23, 0x26, 0x18, 0x22, 0x26, 0x19, 0x22, 0x26, 0x19, 0x23, 0x26, 0x19, 0x26, 0x29, 0x20, 0x2d, 0x32, 0x25, 0x31, 0x38, 0x3c, 0x51, 0x59, 0x23, 0x31, 0x37, 0x1f, 0x2b, 0x31, 0x1a, 0x25, 0x2b, 0x17, 0x20, 0x24, 0x15, 0x1c, 0x21, 0x14, 0x1b, 0x21, 0x14, 0x1c, 0x21, 0x13, 0x1b, 0x21, 0x15, 0x1d, 0x21, 0x1a, 0x25, 0x2a, 0x40, 0x57, 0x60, 0x23, 0x31, 0x36, 0x1f, 0x2b, 0x31, 0x1b, 0x25, 0x29, 0x16, 0x1e, 0x23, 0x14, 0x1b, 0x1d, 0x12, 0x19, 0x1d, 0x12, 0x1b, 0x1d, 0x14, 0x1a, 0x1d, 0x45, 0x5e, 0x67, 0x22, 0x32, 0x37, 0x20, 0x2d, 0x31, 0x1a, 0x26, 0x2a, 0x15, 0x1f, 0x25, 0x14, 0x1c, 0x1f, 0x12, 0x1b, 0x1f, 0x12, 0x1b, 0x20, 0x14, 0x1b, 0x1f, 0x15, 0x1e, 0x24, 0x1a, 0x25, 0x29, 0x4b, 0x64, 0x6d, 0x23, 0x32, 0x38, 0x20, 0x2e, 0x32, 0x1b, 0x27, 0x2b, 0x17, 0x22, 0x27, 0x16, 0x1e, 0x23, 0x14, 0x1e, 0x23, 0x16, 0x20, 0x24, 0x14, 0x1e, 0x22, 0x15, 0x1e, 0x22, 0x17, 0x21, 0x27, 0x1c, 0x27, 0x2c, 0x4f, 0x6a, 0x75, 0x21, 0x2f, 0x33, 0x1d, 0x29, 0x2d, 0x19, 0x23, 0x2a, 0x18, 0x22, 0x27, 0x16, 0x21, 0x27, 0x18, 0x23, 0x29, 0x17, 0x21, 0x26, 0x19, 0x23, 0x29, 0x1c, 0x28, 0x2d, 0x21, 0x2e, 0x33, 0x54, 0x70, 0x7c, 0x23, 0x33, 0x38, 0x22, 0x30, 0x34, 0x1e, 0x2a, 0x2f, 0x1a, 0x26, 0x2d, 0x1a, 0x25, 0x2b, 0x19, 0x25, 0x2b, 0x1a, 0x26, 0x2d, 0x1a, 0x26, 0x2c, 0x18, 0x25, 0x2a, 0x1a, 0x24, 0x2a, 0x1a, 0x25, 0x2c, 0x1d, 0x2a, 0x2f, 0x22, 0x2f, 0x34, 0x59, 0x77, 0x82, 0x23, 0x33, 0x39, 0x22, 0x30, 0x35, 0x1f, 0x2c, 0x31, 0x1c, 0x28, 0x30, 0x1c, 0x28, 0x2e, 0x1b, 0x29, 0x2f, 0x1c, 0x2a, 0x31, 0x1b, 0x28, 0x2f, 0x1c, 0x28, 0x2d, 0x1b, 0x27, 0x2f, 0x1f, 0x2b, 0x31, 0x5e, 0x7d, 0x8a, 0x24, 0x34, 0x39, 0x21, 0x2f, 0x37, 0x20, 0x2d, 0x34, 0x1d, 0x2b, 0x33, 0x1d, 0x2b, 0x32, 0x1d, 0x2d, 0x35, 0x1e, 0x2e, 0x36, 0x1f, 0x2e, 0x36, 0x1d, 0x2b, 0x34, 0x1d, 0x2b, 0x31, 0x1d, 0x2b, 0x32, 0x20, 0x2d, 0x32, 0x21, 0x2f, 0x36, 0x63, 0x83, 0x90, 0x25, 0x34, 0x39, 0x21, 0x31, 0x36, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x34, 0x1f, 0x2e, 0x36, 0x20, 0x31, 0x39, 0x21, 0x33, 0x3b, 0x21, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1e, 0x2d, 0x33, 0x1f, 0x2d, 0x33, 0x21, 0x30, 0x36, 0x67, 0x8a, 0x97, 0x24, 0x33, 0x39, 0x20, 0x30, 0x36, 0x1f, 0x2f, 0x35, 0x21, 0x30, 0x37, 0x22, 0x32, 0x39, 0x21, 0x35, 0x3e, 0x24, 0x37, 0x41, 0x24, 0x36, 0x41, 0x21, 0x33, 0x3c, 0x21, 0x31, 0x38, 0x1e, 0x2f, 0x35, 0x1e, 0x2e, 0x35, 0x20, 0x2e, 0x35, 0x24, 0x31, 0x39, 0x6c, 0x90, 0x9e, 0x22, 0x30, 0x36, 0x1f, 0x2e, 0x36, 0x20, 0x30, 0x36, 0x20, 0x31, 0x39, 0x23, 0x34, 0x3d, 0x23, 0x37, 0x41, 0x26, 0x3c, 0x47, 0x26, 0x3b, 0x46, 0x22, 0x35, 0x3f, 0x22, 0x32, 0x3b, 0x1f, 0x30, 0x37, 0x1f, 0x2e, 0x35, 0x1f, 0x2d, 0x35, 0x21, 0x30, 0x36, 0x72, 0x96, 0xa5, 0x72, 0x96, 0xa5, 0xe8, 0x14, 0xaa, 0x3f, 0x0, 0x0, 0x0, 0xaa, 0x74, 0x52, 0x4e, 0x53, 0xc3, 0xc3, 0xe6, 0xd7, 0xcb, 0xc3, 0xbf, 0xbe, 0xbd, 0xe5, 0xc3, 0xd7, 0xc0, 0xac, 0xa0, 0x9a, 0x98, 0x98, 0x98, 0xc3, 0xcb, 0xac, 0x92, 0x82, 0x7b, 0x78, 0x78, 0x7b, 0x82, 0xac, 0xcb, 0xc3, 0xc3, 0xa0, 0x82, 0x6f, 0x67, 0x64, 0x63, 0x64, 0x67, 0x82, 0xc3, 0xbf, 0x9a, 0x7a, 0x67, 0x5e, 0x5b, 0x5a, 0x5e, 0xc3, 0xbd, 0x98, 0x78, 0x64, 0x5b, 0x57, 0x57, 0x5b, 0x64, 0x78, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x78, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x77, 0x98, 0xc3, 0xbd, 0x98, 0x77, 0x63, 0x5a, 0x57, 0x56, 0x57, 0x5a, 0x63, 0x77, 0xc3, 0xbb, 0x96, 0x76, 0x63, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x5a, 0x63, 0x76, 0x96, 0xc3, 0xb5, 0x92, 0x75, 0x62, 0x5a, 0x57, 0x56, 0x56, 0x57, 0x59, 0x62, 0x74, 0x92, 0xc3, 0xa9, 0x8b, 0x71, 0x61, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x61, 0x71, 0x8b, 0xa9, 0xc3, 0x95, 0x7e, 0x6b, 0x5e, 0x59, 0x57, 0x56, 0x56, 0x57, 0x59, 0x5e, 0x6b, 0x7e, 0x95, 0xc3, 0x4f, 0x78, 0x99, 0x30, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xa9, 0x27, 0xf, 0x6, 0x4, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xff, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0x40, 0x7, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x1c, 0x1c, 0x6c, 0xac, 0x2c, 0xcc, 0x9c, 0x8c, 0xc, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x2, 0x82, 0x82, 0x42, 0xfc, 0x7c, 0xbc, 0x3c, 0xdc, 0x5c, 0xc, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0x52, 0x92, 0xd2, 0x32, 0x62, 0xb2, 0x72, 0xc2, 0xc, 0xf2, 0xa, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0x6a, 0xea, 0x1a, 0xca, 0x9a, 0x8a, 0xa, 0xf2, 0xc, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x6, 0x86, 0x86, 0x6, 0x46, 0x7a, 0xba, 0x3a, 0xda, 0x5a, 0xc, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0x56, 0x96, 0xd6, 0x36, 0xb6, 0xa6, 0x26, 0xc6, 0xc, 0x76, 0xf6, 0xe, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0xae, 0x6e, 0xee, 0x1e, 0x9e, 0xe, 0x26, 0x76, 0xc, 0x5e, 0xf6, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x1, 0x1, 0xfe, 0x81, 0x41, 0xc1, 0x21, 0xf6, 0x5e, 0xc, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, 0x9, 0x89, 0x49, 0x61, 0xa1, 0xc, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xa9, 0x29, 0xc9, 0xc, 0xf9, 0x5, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0x5, 0xf9, 0xc, 0xb5, 0x75, 0xf5, 0xd, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0x75, 0xb5, 0xc, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x13, 0x26, 0x4e, 0x9a, 0x3c, 0x65, 0xea, 0xb4, 0xe9, 0x33, 0x66, 0x76, 0x33, 0xcc, 0x9a, 0x3d, 0x67, 0xee, 0xbc, 0xf9, 0xb, 0x16, 0x2e, 0x5a, 0xbc, 0x64, 0xe9, 0xb2, 0xe5, 0x2b, 0x66, 0x31, 0xac, 0x44, 0x3, 0x0, 0xa4, 0xd7, 0x4d, 0x73, 0x12, 0x21, 0x19, 0xde, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tooltip_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x77, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0xc1, 0xd, 0x40, 0x40, 0x14, 0x44, 0xdf, 0xa, 0x15, 0x50, 0x86, 0x42, 0xe8, 0x81, 0xb3, 0x3, 0x15, 0x71, 0xa3, 0x5, 0x89, 0x46, 0x94, 0xb1, 0x6a, 0x18, 0x97, 0xdd, 0x10, 0x71, 0xd8, 0x75, 0x36, 0xa7, 0xff, 0x93, 0x79, 0xf3, 0xe7, 0xf2, 0x8d, 0xa4, 0xc, 0xe8, 0x80, 0xa, 0x28, 0x8, 0x93, 0x5, 0x36, 0x60, 0x34, 0x92, 0x6, 0xa0, 0x9, 0x4, 0x9f, 0x5a, 0x8c, 0xa4, 0xd5, 0x5d, 0xde, 0x81, 0x3c, 0x10, 0x3c, 0x80, 0x12, 0xb0, 0x9, 0x57, 0xed, 0x50, 0xf8, 0xee, 0x2d, 0x92, 0x8, 0xe8, 0x55, 0x7f, 0xc0, 0x1f, 0xe0, 0x3, 0xac, 0x9b, 0x8f, 0x8, 0xce, 0x33, 0xd6, 0x48, 0xea, 0x81, 0xf6, 0x63, 0x81, 0x39, 0x5, 0x46, 0xb7, 0xd4, 0xc4, 0xbf, 0xf3, 0x74, 0x2, 0x7e, 0x1c, 0x1c, 0xd5, 0x3c, 0x27, 0x88, 0xb3, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x33, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2d, 0x2c, 0x2f, 0x48, 0x46, 0x4a, 0xdd, 0xdd, 0xdd, 0x4c, 0x4a, 0x4e, 0x48, 0x46, 0x4a, 0x40, 0x3e, 0x42, 0xdd, 0xdd, 0xdd, 0xfe, 0x3f, 0x83, 0xa9, 0x0, 0x0, 0x0, 0xd, 0x74, 0x52, 0x4e, 0x53, 0xa, 0x1a, 0x26, 0x29, 0x2a, 0x48, 0x65, 0x6d, 0x6e, 0x66, 0xf5, 0xfe, 0xcc, 0xff, 0xb7, 0x4a, 0xbe, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xc, 0x81, 0xb3, 0x51, 0x63, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x44, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xc5, 0xcf, 0xbb, 0x15, 0x0, 0x20, 0x8, 0x43, 0xd1, 0x80, 0x28, 0xf8, 0x41, 0xf7, 0xdf, 0xd6, 0x86, 0x63, 0xa1, 0x3, 0x78, 0xcb, 0x54, 0x79, 0x0, 0x71, 0x92, 0x90, 0x98, 0x0, 0xca, 0x45, 0x2d, 0x68, 0xc9, 0x4, 0xae, 0xad, 0x7b, 0xe8, 0xad, 0x32, 0x44, 0xe7, 0x1a, 0x61, 0x4d, 0x15, 0x88, 0xf9, 0x38, 0xdc, 0xfe, 0xd, 0xf7, 0xb1, 0xe7, 0xfa, 0x13, 0x77, 0xe7, 0x6f, 0xdc, 0x6c, 0x9, 0x25, 0x82, 0x67, 0x68, 0x78, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xe5, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x93, 0x31, 0x4a, 0x43, 0x41, 0x18, 0x84, 0xbf, 0xd9, 0x7f, 0xdf, 0x9, 0x24, 0x1, 0x5, 0xcb, 0xd8, 0xa5, 0x35, 0x5e, 0x20, 0x8d, 0x82, 0x57, 0xd0, 0x43, 0x78, 0x20, 0xbd, 0x82, 0x62, 0xf5, 0x2e, 0xa0, 0x56, 0x81, 0x94, 0x69, 0x2c, 0xc4, 0x22, 0x82, 0x27, 0xd8, 0xb7, 0xbf, 0xc5, 0x3e, 0x49, 0x94, 0x95, 0x28, 0xaf, 0xf5, 0x87, 0x85, 0x2d, 0x76, 0x66, 0xfe, 0x61, 0x67, 0x60, 0xe0, 0x68, 0xfb, 0x3e, 0x99, 0xce, 0x2e, 0x11, 0x73, 0x60, 0xf4, 0xc3, 0xfb, 0x37, 0x9c, 0x76, 0xb5, 0x7c, 0xbc, 0x6, 0x7c, 0x9b, 0x20, 0x4c, 0xa6, 0xb3, 0x3b, 0xc4, 0x69, 0x90, 0x92, 0x4b, 0xb1, 0xaa, 0xe6, 0x9e, 0xb2, 0x7b, 0xc4, 0xfd, 0x7e, 0xb5, 0x7c, 0x3a, 0x7, 0xb2, 0x1, 0xf4, 0xca, 0x57, 0x16, 0x1b, 0x62, 0xd3, 0x4, 0x33, 0xa3, 0x76, 0x82, 0xc5, 0x20, 0x89, 0xec, 0xf9, 0x68, 0x6f, 0x7c, 0xf8, 0xfc, 0xbe, 0x7e, 0x59, 0x84, 0xde, 0xc8, 0x3c, 0x48, 0xc9, 0xcc, 0x76, 0x7a, 0xe, 0x66, 0x48, 0xea, 0x7a, 0xab, 0x14, 0x2, 0x67, 0x1f, 0xea, 0x6b, 0x57, 0xad, 0x20, 0xc3, 0xfd, 0x60, 0x43, 0x30, 0x60, 0xfe, 0x9, 0x3e, 0x9, 0xa4, 0x57, 0xf0, 0xf4, 0x7b, 0x98, 0xa7, 0x82, 0xd9, 0x7c, 0x63, 0x9b, 0xdd, 0x63, 0xee, 0xba, 0x9d, 0xd0, 0xdc, 0x75, 0x94, 0x34, 0xd2, 0xc2, 0x97, 0x28, 0x1f, 0xdf, 0x22, 0x9d, 0xfd, 0x35, 0xca, 0xdf, 0xca, 0x74, 0x72, 0x51, 0x12, 0xe6, 0xe3, 0xba, 0xbe, 0xd6, 0xa5, 0x4c, 0xf, 0x37, 0xf4, 0x65, 0x1a, 0x3c, 0x1f, 0xbb, 0xac, 0x55, 0xac, 0xed, 0xfe, 0xe5, 0xf1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0xa, 0x0, 0x0, 0x0, 0xa, 0x4, 0x3, 0x0, 0x0, 0x0, 0x7f, 0x1c, 0xd2, 0x8e, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2a, 0x50, 0x4c, 0x54, 0x45, 0x17, 0x16, 0x1a, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x21, 0x1f, 0x25, 0x1d, 0x1c, 0x21, 0x20, 0x1e, 0x24, 0x1d, 0x1c, 0x21, 0x1d, 0x1c, 0x21, 0x24, 0x22, 0x29, 0x28, 0x26, 0x2d, 0x28, 0x26, 0x2e, 0x2b, 0x2a, 0x31, 0x2c, 0x2a, 0x32, 0xff, 0xff, 0xff, 0xb9, 0x11, 0x56, 0x3e, 0x0, 0x0, 0x0, 0x8, 0x74, 0x52, 0x4e, 0x53, 0x6f, 0xef, 0xf7, 0xf7, 0xf0, 0xf9, 0xf1, 0xee, 0xcf, 0x21, 0xd2, 0xdf, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0xd, 0xf6, 0xb4, 0x61, 0xf5, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x2d, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x54, 0x36, 0x36, 0x12, 0x60, 0xf0, 0x98, 0xb5, 0x6a, 0x65, 0xb, 0x43, 0xe4, 0x9e, 0x33, 0xa7, 0xa7, 0x32, 0x58, 0x9d, 0x39, 0x73, 0x66, 0x31, 0x16, 0x12, 0x22, 0xb, 0x52, 0xd9, 0xc6, 0xc0, 0x2, 0xd4, 0x55, 0x0, 0x0, 0xc, 0x14, 0x1a, 0x90, 0x55, 0x1a, 0xec, 0xdb, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+};
+
+static const unsigned char tree_bg_focus_png[] = {
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x20, 0x0, 0x0, 0x0, 0x20, 0x8, 0x6, 0x0, 0x0, 0x0, 0x73, 0x7a, 0x7a, 0xf4, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xdb, 0xb, 0x4, 0x12, 0x2d, 0x3a, 0xb5, 0x1b, 0x14, 0x49, 0x0, 0x0, 0x2, 0xd9, 0x49, 0x44, 0x41, 0x54, 0x58, 0xc3, 0xc5, 0x57, 0x31, 0x8e, 0x14, 0x31, 0x10, 0xac, 0xea, 0x3d, 0x11, 0x91, 0xdf, 0x49, 0xf7, 0xf, 0x78, 0x1, 0xf, 0x40, 0x84, 0x44, 0x10, 0xf2, 0x20, 0x42, 0x62, 0x12, 0xc4, 0x3, 0x78, 0x1, 0xff, 0x21, 0x42, 0xb8, 0x8a, 0xc0, 0x1e, 0x4f, 0xdb, 0xe3, 0xb9, 0xbb, 0x45, 0x20, 0x7c, 0x1a, 0xdd, 0x8c, 0xec, 0xed, 0xae, 0xae, 0xea, 0xee, 0xe9, 0xe1, 0xfd, 0xed, 0xdd, 0xb, 0x0, 0xdf, 0xf1, 0x7f, 0xd6, 0x4b, 0xde, 0xdf, 0xde, 0xf9, 0xcb, 0xeb, 0x9f, 0xff, 0xc5, 0xfb, 0x9b, 0xaf, 0xcf, 0x70, 0xb3, 0x3d, 0x3c, 0xff, 0xf0, 0xd, 0x24, 0x11, 0x71, 0x1, 0x49, 0x90, 0x4, 0x0, 0x4, 0xd3, 0x2f, 0xb6, 0x7b, 0xf, 0xff, 0x86, 0x2d, 0x8c, 0x47, 0x60, 0x1b, 0x0, 0x61, 0x1b, 0xb6, 0x21, 0x15, 0xd8, 0xc6, 0x8f, 0x8f, 0xaf, 0x0, 0x60, 0x7, 0x0, 0xa2, 0x2, 0x20, 0x11, 0x41, 0x30, 0xa2, 0x2, 0xc1, 0xb5, 0x0, 0x8c, 0x79, 0xd9, 0x80, 0x24, 0x48, 0x0, 0x48, 0x28, 0x9d, 0xb9, 0xd9, 0xd, 0xb0, 0x31, 0x40, 0x5c, 0x2e, 0x1, 0x46, 0x0, 0xd, 0xd0, 0xb6, 0xef, 0x35, 0x8e, 0x13, 0x6, 0xbc, 0x33, 0x60, 0xa3, 0x9a, 0x11, 0x6c, 0x82, 0xe6, 0xa, 0x0, 0x86, 0xe8, 0x2f, 0x71, 0xa9, 0xf7, 0x9c, 0x4d, 0x1f, 0x69, 0x5e, 0x1, 0xd8, 0xa3, 0x37, 0xa4, 0xa, 0x27, 0x1a, 0x13, 0x79, 0x25, 0x9, 0xaa, 0xe3, 0xd8, 0x9c, 0x5f, 0xea, 0x7d, 0x67, 0x80, 0xd7, 0x31, 0x20, 0xab, 0x3, 0x20, 0x5, 0x20, 0x2a, 0x13, 0x41, 0x40, 0x2b, 0x0, 0x76, 0x22, 0xb9, 0xb1, 0xd1, 0x92, 0x91, 0x5d, 0x86, 0xf3, 0x35, 0xef, 0x5, 0xa3, 0x25, 0x60, 0xd, 0x6e, 0x66, 0xe5, 0x0, 0xc0, 0xa8, 0x54, 0x1, 0x6, 0xe9, 0x16, 0x9f, 0x4f, 0xdc, 0x1c, 0x13, 0xed, 0xb1, 0x55, 0x31, 0x78, 0x70, 0x8e, 0xca, 0xcb, 0x8e, 0x6a, 0xbe, 0x56, 0x88, 0x67, 0x38, 0xdb, 0x75, 0x58, 0x76, 0xdf, 0x1b, 0x6c, 0x7a, 0xc, 0x6c, 0x90, 0x0, 0xfd, 0xe0, 0xe8, 0x98, 0xe4, 0x4, 0xe2, 0x69, 0xc, 0xe4, 0x40, 0xaa, 0xf9, 0x63, 0x70, 0xbb, 0x4, 0x16, 0x9c, 0x12, 0xa7, 0x3e, 0xe7, 0x38, 0xb3, 0x4, 0x2b, 0x6f, 0xc7, 0x23, 0xbb, 0xc3, 0x66, 0xdb, 0x38, 0x7, 0x0, 0xcf, 0x32, 0x34, 0xb6, 0x52, 0xb4, 0x3c, 0xf7, 0x35, 0x10, 0xd9, 0xf7, 0x6, 0x56, 0x93, 0x4, 0x4b, 0x0, 0x43, 0x28, 0xf9, 0x4a, 0x3d, 0x6e, 0xb0, 0x3e, 0x9, 0x31, 0xa9, 0x62, 0xd6, 0xc4, 0x36, 0x9c, 0xf2, 0xd9, 0xbd, 0x41, 0x2d, 0x24, 0x68, 0xc7, 0x1f, 0x62, 0x60, 0x6a, 0xc1, 0x7f, 0x95, 0x81, 0xaa, 0x13, 0x61, 0x9, 0xa6, 0xf6, 0x1c, 0x30, 0x17, 0x11, 0x6f, 0x48, 0x12, 0x3b, 0xf3, 0x7b, 0xc2, 0xeb, 0xca, 0x92, 0xb7, 0x72, 0x5f, 0x31, 0x90, 0x11, 0x4e, 0x48, 0xb3, 0x13, 0xa6, 0xcc, 0x3e, 0x51, 0x60, 0x91, 0x53, 0x55, 0x87, 0xf3, 0x2a, 0x98, 0xff, 0x7c, 0x6c, 0x1a, 0xf9, 0xec, 0xda, 0xeb, 0x94, 0x13, 0x43, 0xdd, 0x3f, 0x2a, 0x41, 0xd2, 0xb, 0x27, 0x65, 0xe8, 0x13, 0x20, 0x29, 0x3f, 0xc6, 0x7c, 0x48, 0x65, 0x8, 0x41, 0xda, 0xa4, 0xd5, 0x11, 0xc0, 0x2a, 0x61, 0xce, 0x18, 0x58, 0xd2, 0xbe, 0x98, 0x48, 0x96, 0xdd, 0xf5, 0xbc, 0x11, 0x65, 0xb6, 0x12, 0x55, 0xcb, 0xde, 0xb3, 0x78, 0x27, 0x78, 0xdc, 0xcb, 0x72, 0xe6, 0xd7, 0x8a, 0x27, 0xe6, 0x52, 0x1f, 0x10, 0xe0, 0xb8, 0x92, 0x81, 0xb4, 0x3f, 0x1, 0x1d, 0xed, 0x6c, 0xd4, 0xef, 0x12, 0x2f, 0x73, 0xa0, 0xe, 0xf, 0x42, 0x24, 0x20, 0xf, 0x91, 0xbf, 0x6e, 0x44, 0xfb, 0xde, 0xa1, 0x4, 0xa5, 0x7, 0xaa, 0xa0, 0x23, 0xad, 0xd4, 0x4b, 0xaa, 0x73, 0x0, 0xb7, 0xa1, 0x82, 0x87, 0x46, 0x74, 0x9a, 0xf, 0x48, 0x5d, 0xb3, 0xd, 0xa2, 0xb0, 0x96, 0xe5, 0x7d, 0xc8, 0x81, 0x19, 0xf1, 0x36, 0x2b, 0xba, 0xbd, 0x5e, 0xb3, 0xb7, 0x55, 0x12, 0x76, 0x90, 0xc4, 0x3a, 0x1, 0xa7, 0x66, 0xbc, 0x3, 0x90, 0xe0, 0x8, 0xc8, 0x42, 0x29, 0xa5, 0x7b, 0xa2, 0x63, 0x9f, 0x88, 0x26, 0xa, 0x9c, 0x85, 0x6f, 0x7b, 0x2b, 0x0, 0x92, 0x51, 0x4a, 0x81, 0x5c, 0x2a, 0xcb, 0x2a, 0x47, 0x0, 0xb0, 0x2b, 0x8, 0x11, 0x62, 0x20, 0x58, 0x20, 0x47, 0x77, 0x5a, 0xe5, 0x98, 0x43, 0x3f, 0x2, 0xd8, 0xc1, 0xa5, 0x39, 0x40, 0x82, 0xb5, 0xd9, 0xd7, 0x5a, 0x2, 0x59, 0x80, 0x9, 0x8a, 0x0, 0x7f, 0x1, 0x8, 0x44, 0x8, 0x64, 0xe0, 0xe8, 0x6e, 0x4b, 0xb4, 0x87, 0xa6, 0xc4, 0x3d, 0x17, 0x24, 0xa3, 0xa8, 0xc0, 0x32, 0x8a, 0xea, 0x33, 0x67, 0x0, 0x6e, 0xc, 0x94, 0x5e, 0xe2, 0x46, 0x11, 0x3a, 0x0, 0x82, 0x57, 0x1, 0x98, 0xbf, 0xb, 0xa4, 0xf6, 0x55, 0xd4, 0x2a, 0xe1, 0x0, 0x40, 0xf5, 0xf3, 0xa5, 0xd3, 0x16, 0x6a, 0xb4, 0xa7, 0x19, 0xfa, 0x4f, 0x18, 0xe8, 0x2c, 0x34, 0xfb, 0x92, 0x20, 0xbb, 0xf, 0xa3, 0x1d, 0xc0, 0xcd, 0xe7, 0xb7, 0x83, 0xf9, 0xf2, 0x24, 0xd3, 0xd7, 0xaf, 0x40, 0x9a, 0x84, 0x1, 0xf0, 0xfe, 0xf6, 0xee, 0x1d, 0x80, 0x4f, 0xff, 0xc8, 0xdf, 0x63, 0xeb, 0xfd, 0x6f, 0x3, 0x74, 0x35, 0xa7, 0x2a, 0xf0, 0x17, 0xed, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_cursor_png[] = {
@@ -399,35 +407,35 @@ static const unsigned char tree_cursor_unfocus_png[] = {
};
static const unsigned char tree_title_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x64, 0x60, 0x60, 0x30, 0x62, 0xa0, 0x0, 0x30, 0x51, 0xa2, 0x79, 0xd4, 0x80, 0x51, 0x3, 0x46, 0xd, 0x18, 0x4c, 0x6, 0x0, 0x0, 0xf, 0x77, 0x0, 0x52, 0xbd, 0x9b, 0x8a, 0x28, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x25, 0x23, 0x25, 0x4c, 0x4a, 0x4e, 0x1, 0xf9, 0x98, 0x2e, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xc, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x20, 0xd, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0xc7, 0xaa, 0x85, 0x8e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char tree_title_pressed_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x1d, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x64, 0x60, 0x60, 0x70, 0x63, 0xa0, 0x0, 0x30, 0x51, 0xa2, 0x79, 0xd4, 0x80, 0x51, 0x3, 0x46, 0xd, 0x18, 0x4c, 0x6, 0x0, 0x0, 0x60, 0x67, 0x0, 0x66, 0xf1, 0xae, 0x47, 0x48, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x1, 0x3, 0x0, 0x0, 0x0, 0x25, 0x3d, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x36, 0x34, 0x36, 0x4c, 0x4a, 0x4e, 0x14, 0xd7, 0x5b, 0xf8, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xc, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x20, 0xd, 0x0, 0x0, 0x0, 0x30, 0x0, 0x1, 0xc7, 0xaa, 0x85, 0x8e, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char unchecked_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x9c, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0x52, 0xbb, 0xd, 0xc2, 0x30, 0x10, 0x7d, 0x2f, 0xc7, 0xa, 0x84, 0xd6, 0x52, 0xa4, 0x2c, 0xc1, 0x2e, 0xac, 0x41, 0x36, 0xf0, 0x1e, 0x59, 0x86, 0x1d, 0x90, 0x2c, 0x25, 0x65, 0xb2, 0x83, 0xf5, 0x68, 0x30, 0x8a, 0x48, 0x1c, 0x8b, 0x6, 0x1a, 0x5e, 0x75, 0x77, 0xef, 0x73, 0x57, 0x1c, 0xf0, 0x6b, 0x30, 0x15, 0xe3, 0x38, 0x9e, 0x25, 0x75, 0x0, 0x8e, 0xbb, 0x6, 0x72, 0x96, 0xe4, 0x9d, 0x73, 0x37, 0x0, 0xa8, 0x16, 0xdc, 0xb5, 0x64, 0x6, 0x0, 0x49, 0x35, 0xc9, 0x2e, 0xf5, 0x87, 0x25, 0x1, 0x0, 0x31, 0xc6, 0x4b, 0xd3, 0x34, 0xf7, 0x2d, 0x73, 0x8, 0xa1, 0x35, 0xb3, 0x5e, 0xd2, 0x29, 0xcd, 0xaa, 0x77, 0x51, 0xce, 0x9c, 0xe3, 0x56, 0x1, 0x9f, 0xe2, 0x1f, 0xb0, 0x11, 0x10, 0x42, 0x68, 0x73, 0xe2, 0x2d, 0xee, 0xf5, 0x7, 0xcf, 0xf, 0xab, 0xcd, 0xac, 0x1f, 0x86, 0x61, 0x77, 0x2b, 0xc9, 0x69, 0x75, 0x81, 0x24, 0x4f, 0x72, 0x2e, 0x9d, 0x4c, 0x72, 0x32, 0x33, 0x5f, 0xd2, 0x7d, 0xf, 0xf, 0x38, 0xc7, 0x34, 0x81, 0x1c, 0x84, 0x6d, 0x22, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x36, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x38, 0x37, 0x40, 0x20, 0x20, 0x24, 0x20, 0x20, 0x24, 0x38, 0x36, 0x40, 0x20, 0x20, 0x25, 0x1e, 0x1e, 0x22, 0x1f, 0x1f, 0x23, 0x20, 0x20, 0x24, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0xff, 0xff, 0xff, 0xf7, 0x93, 0x46, 0x7a, 0x0, 0x0, 0x0, 0xb, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x7, 0x27, 0x50, 0x66, 0x68, 0xb4, 0xfa, 0xfb, 0xb4, 0xfa, 0xa4, 0x7f, 0xe1, 0x5a, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x11, 0xe2, 0xb5, 0x3d, 0xba, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x53, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0xb5, 0xcf, 0xc1, 0x12, 0x80, 0x20, 0x8, 0x45, 0x51, 0x5, 0x14, 0xd, 0x5, 0xff, 0xff, 0x6b, 0x23, 0x27, 0x67, 0x9a, 0x6c, 0xdb, 0x5d, 0x9e, 0xd, 0x8f, 0x10, 0xb6, 0x22, 0x20, 0xa5, 0x19, 0x21, 0x44, 0x7, 0xc8, 0x2c, 0x6d, 0x26, 0x9c, 0xc1, 0x1, 0xb9, 0xab, 0xcd, 0xb4, 0x33, 0x3a, 0x90, 0xe8, 0xb8, 0x53, 0x21, 0x87, 0xd4, 0x6c, 0x81, 0xb5, 0xf4, 0x17, 0x6c, 0x67, 0x9f, 0xc3, 0xca, 0x35, 0xc, 0x6a, 0x59, 0xd3, 0x8f, 0xa, 0x5f, 0xcf, 0xbd, 0x3a, 0x1, 0x93, 0xe2, 0x8, 0xa4, 0xb1, 0xeb, 0xd3, 0x56, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char updown_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x2b, 0x8a, 0x3e, 0x7d, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x8b, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xad, 0x90, 0x31, 0xe, 0xc2, 0x50, 0xc, 0x43, 0x5f, 0x2a, 0x55, 0xcc, 0xbd, 0x2, 0x2c, 0xed, 0xd9, 0x60, 0xe1, 0x24, 0x2c, 0xed, 0xc0, 0x54, 0x6e, 0xf5, 0x27, 0x7a, 0x85, 0xce, 0x9d, 0xcc, 0x80, 0xf3, 0x85, 0x58, 0x18, 0x8a, 0xa5, 0x2c, 0xb1, 0x63, 0xc5, 0x86, 0xbf, 0x41, 0x52, 0x27, 0x69, 0xf6, 0x74, 0xb9, 0x8f, 0x24, 0x81, 0x11, 0x38, 0x79, 0xff, 0x4, 0x2e, 0x11, 0xb1, 0x86, 0xc9, 0x9, 0x38, 0x9a, 0xc0, 0xc2, 0x5, 0x38, 0x87, 0xa4, 0x19, 0x18, 0xf2, 0xca, 0x82, 0x74, 0x2b, 0xd, 0xb0, 0x1, 0xa5, 0x5a, 0x46, 0xac, 0x16, 0x16, 0x73, 0x3b, 0x11, 0x92, 0xee, 0xc0, 0x1, 0xb8, 0xda, 0x3e, 0x53, 0xdd, 0x80, 0xad, 0x1, 0x5a, 0xa0, 0x7, 0x46, 0x77, 0x91, 0x91, 0x7b, 0xa0, 0x8d, 0xaf, 0xe, 0x3e, 0x63, 0xbe, 0xbb, 0xf8, 0x55, 0x54, 0x7d, 0xc6, 0xf6, 0xf, 0x4f, 0xad, 0x7a, 0x3f, 0x5e, 0x1d, 0x33, 0x50, 0xfd, 0xb1, 0xf2, 0xd7, 0xa2, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x2b, 0x8a, 0x3e, 0x7d, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xa6, 0x49, 0x44, 0x41, 0x54, 0x28, 0x91, 0xa5, 0x90, 0x21, 0xe, 0xc2, 0x50, 0x10, 0x44, 0xdf, 0x27, 0x9b, 0x10, 0x2e, 0xc0, 0x9, 0xd6, 0x81, 0xe3, 0x6, 0xe0, 0xa0, 0xd7, 0x2d, 0xae, 0x18, 0x24, 0x95, 0xc5, 0x7d, 0x51, 0xdd, 0xb, 0x60, 0xf6, 0x67, 0x31, 0xfb, 0x49, 0xc1, 0x20, 0x3a, 0x6a, 0x93, 0x99, 0x9d, 0xcc, 0xc, 0x2c, 0x45, 0xaa, 0x47, 0xce, 0x79, 0x2b, 0x22, 0x2d, 0x80, 0x99, 0x5d, 0x54, 0x75, 0xfa, 0x8, 0x82, 0xec, 0x80, 0x7d, 0xe8, 0x7, 0x33, 0x3b, 0xa9, 0xea, 0x94, 0x82, 0xbc, 0x1, 0x3b, 0x60, 0x8, 0xc1, 0x1e, 0x78, 0x9a, 0xd9, 0x51, 0xc2, 0x76, 0x57, 0xbf, 0x0, 0xaa, 0x9b, 0x88, 0xb4, 0x2b, 0x77, 0x7f, 0x1, 0x7d, 0xb5, 0x54, 0xd5, 0x29, 0x84, 0x7d, 0x70, 0x4b, 0x6b, 0x8e, 0xe3, 0x78, 0x7, 0x36, 0x66, 0x76, 0xae, 0xd5, 0x22, 0xf8, 0x15, 0x78, 0x89, 0xbb, 0xaf, 0x53, 0x4a, 0x7, 0x11, 0xe9, 0x72, 0xce, 0x5f, 0x21, 0xdd, 0xfd, 0x21, 0xa5, 0x94, 0x66, 0x96, 0xba, 0x9b, 0xd5, 0x1c, 0x4a, 0x29, 0xcd, 0xff, 0xa1, 0x7e, 0xa6, 0xbe, 0xc6, 0xd4, 0x9f, 0x3c, 0xcb, 0xf1, 0x6, 0x8e, 0x4e, 0x65, 0x44, 0x6f, 0x74, 0x5c, 0xa1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vseparator_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x63, 0x60, 0x18, 0x5, 0xc, 0xc, 0xc, 0xc, 0x0, 0x1, 0x8, 0x0, 0x1, 0x7d, 0x41, 0xa5, 0xce, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x2, 0x3, 0x0, 0x0, 0x0, 0xb9, 0x61, 0x56, 0x18, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0xc, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x73, 0x9b, 0xaa, 0xce, 0xdc, 0xe1, 0xff, 0xff, 0xff, 0x64, 0x6c, 0x1, 0xd2, 0x0, 0x0, 0x0, 0x3, 0x74, 0x52, 0x4e, 0x53, 0x0, 0xb3, 0xb3, 0x67, 0xf6, 0xdb, 0x93, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x3, 0x11, 0xc, 0x4c, 0xf2, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x10, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x80, 0x81, 0xac, 0x95, 0xc, 0x48, 0x0, 0x0, 0xe, 0x79, 0x1, 0x14, 0xa1, 0xc9, 0x59, 0x2, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x69, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xed, 0xd3, 0xa1, 0xe, 0x83, 0x40, 0x14, 0x5, 0xd1, 0x3, 0xa4, 0xc1, 0xa0, 0x30, 0x4d, 0xe8, 0xff, 0xff, 0x1a, 0x18, 0xc0, 0x80, 0x6b, 0xd2, 0x62, 0x56, 0x11, 0x1e, 0xd9, 0x4, 0x83, 0xe0, 0xba, 0x9d, 0x37, 0x19, 0xb7, 0x5c, 0x5c, 0x71, 0xc2, 0x3b, 0xb4, 0xe9, 0x3d, 0xa3, 0xc7, 0x7f, 0x2f, 0x56, 0x41, 0xe0, 0x83, 0x77, 0xba, 0x57, 0x68, 0x50, 0x62, 0xd9, 0x8b, 0x65, 0x10, 0x68, 0x33, 0x59, 0x18, 0x78, 0x65, 0xb2, 0x30, 0x90, 0xbd, 0x27, 0x70, 0xe7, 0xc0, 0x37, 0x93, 0x85, 0x81, 0xf9, 0x80, 0x4d, 0x47, 0x62, 0xf4, 0x17, 0xd6, 0x14, 0xaf, 0xf1, 0xc3, 0x88, 0x21, 0x70, 0xaf, 0x6d, 0x3, 0x2b, 0xaa, 0xc, 0x24, 0xe2, 0x1d, 0xb9, 0xf7, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x54, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x4d, 0x4b, 0x59, 0x34, 0x33, 0x3a, 0x2d, 0x2c, 0x32, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x4d, 0x4b, 0x59, 0x3f, 0x3e, 0x49, 0x2a, 0x29, 0x2f, 0x20, 0x20, 0x24, 0x3f, 0x3e, 0x49, 0x3f, 0x3e, 0x49, 0x1f, 0x1f, 0x24, 0x40, 0x3e, 0x4a, 0x20, 0x20, 0x24, 0x34, 0x33, 0x3a, 0x20, 0x20, 0x25, 0x22, 0x22, 0x27, 0x23, 0x23, 0x28, 0x25, 0x25, 0x2a, 0x1e, 0x1e, 0x23, 0x23, 0x23, 0x27, 0x2d, 0x2c, 0x32, 0x1f, 0x1f, 0x23, 0xff, 0xff, 0xff, 0x3, 0x35, 0xf1, 0x5f, 0x0, 0x0, 0x0, 0x13, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x0, 0x0, 0x4, 0x1a, 0x40, 0x5d, 0x19, 0x28, 0x96, 0xf0, 0xfd, 0x94, 0x95, 0xfc, 0x93, 0xfc, 0xc0, 0x0, 0xb4, 0xa, 0x5f, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1b, 0x2, 0x60, 0xd4, 0xa4, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x64, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x9d, 0xcf, 0x39, 0x2, 0x80, 0x20, 0x10, 0x3, 0xc0, 0xe5, 0x90, 0x43, 0x50, 0x94, 0x1b, 0xfe, 0xff, 0x50, 0x5, 0x69, 0x94, 0xce, 0x94, 0x53, 0xec, 0x26, 0x0, 0x0, 0x88, 0x2e, 0x8c, 0x73, 0x26, 0x28, 0x82, 0x1e, 0x44, 0xe5, 0xaa, 0xb4, 0x56, 0x9b, 0x1c, 0x82, 0xc4, 0x6e, 0x9c, 0xf7, 0xce, 0x1c, 0x62, 0x0, 0x53, 0x2e, 0xc4, 0x18, 0x9c, 0x62, 0x3, 0xb8, 0xf6, 0xf1, 0x8e, 0x3f, 0xf9, 0x3, 0xd8, 0xa6, 0xdc, 0x20, 0x27, 0x8b, 0x3b, 0x90, 0x52, 0x43, 0x83, 0x50, 0xb, 0xf9, 0xb, 0xd3, 0xd1, 0xe9, 0xed, 0x5c, 0x6c, 0xaa, 0xfe, 0x1d, 0xf7, 0x9e, 0x7f, 0x1, 0x89, 0x5c, 0xa, 0x6b, 0x1f, 0xe5, 0xca, 0x60, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_grabber_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xfd, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x92, 0x31, 0x4e, 0xc3, 0x30, 0x18, 0x46, 0x9f, 0x7f, 0xc9, 0xde, 0x60, 0x83, 0xb, 0x50, 0xc8, 0x10, 0x45, 0x96, 0x72, 0x8d, 0x76, 0x84, 0x1e, 0x20, 0x7b, 0xb9, 0x4c, 0x66, 0xe, 0x80, 0x54, 0xb1, 0xb4, 0x5c, 0x23, 0x52, 0x32, 0x56, 0xf4, 0x2, 0x85, 0x85, 0x76, 0x8c, 0x94, 0x9f, 0x25, 0x89, 0xa2, 0x94, 0x56, 0xb5, 0xe0, 0x1b, 0x3f, 0xe9, 0xbd, 0xcf, 0xb6, 0xc, 0x7f, 0x8c, 0x19, 0x17, 0x65, 0x59, 0xde, 0x8a, 0xc8, 0x33, 0x30, 0x5, 0xee, 0x1, 0x54, 0x75, 0x3, 0xbc, 0xab, 0x6a, 0xee, 0xbd, 0xdf, 0x9d, 0x14, 0x54, 0x55, 0xf5, 0x64, 0x8c, 0x79, 0x1, 0xae, 0x4e, 0xc, 0x1e, 0x44, 0x24, 0x8b, 0xe3, 0x78, 0x79, 0x24, 0x68, 0xe1, 0xd7, 0xdf, 0x4e, 0x35, 0x8a, 0x8a, 0xc8, 0xbc, 0x93, 0x98, 0xc1, 0xb1, 0x3f, 0xce, 0x2c, 0x8f, 0xb3, 0xaf, 0xeb, 0x7a, 0x92, 0xa6, 0xe9, 0xa7, 0x0, 0xb4, 0x77, 0xbe, 0x14, 0x6, 0xb8, 0x76, 0xce, 0x2d, 0x0, 0xa4, 0x2d, 0x66, 0x1, 0x30, 0x0, 0x4d, 0xd3, 0xcc, 0x86, 0x82, 0xbb, 0x50, 0x81, 0x31, 0x66, 0x32, 0x14, 0x68, 0xa8, 0xa0, 0x63, 0x3a, 0xc1, 0x36, 0x98, 0x56, 0xdd, 0xf6, 0x2, 0x55, 0x5d, 0x87, 0xa, 0x44, 0x64, 0x35, 0x14, 0xe4, 0xc0, 0x21, 0x80, 0xff, 0xb6, 0xd6, 0xe6, 0xbd, 0xc0, 0x7b, 0xbf, 0x13, 0x91, 0x8c, 0xcb, 0xde, 0x42, 0x81, 0x2c, 0x8a, 0xa2, 0xaf, 0x5e, 0x0, 0x10, 0xc7, 0xf1, 0x52, 0x44, 0xe6, 0xc0, 0xfe, 0xdc, 0x32, 0xf0, 0x98, 0x24, 0xc9, 0x5b, 0x57, 0x1c, 0x7d, 0xdb, 0xa2, 0x28, 0x6e, 0x9c, 0x73, 0xb, 0x55, 0x9d, 0x2, 0xf, 0x6d, 0xbd, 0x31, 0xc6, 0xac, 0xad, 0xb5, 0x79, 0xb7, 0xfc, 0x6f, 0xf9, 0x1, 0x3c, 0x90, 0x4c, 0xcc, 0x74, 0x25, 0x3a, 0xc1, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x4, 0x0, 0x0, 0x0, 0xb5, 0xfa, 0x37, 0xea, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xb7, 0xff, 0x88, 0x5, 0x1d, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x1, 0x12, 0x1, 0x36, 0x8, 0x50, 0xb9, 0xa7, 0x53, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0xf6, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0xbd, 0x90, 0xb1, 0x4a, 0x42, 0x51, 0x0, 0x86, 0xbf, 0x73, 0x8e, 0x71, 0xe5, 0x9a, 0x5c, 0x41, 0xd0, 0x66, 0x6b, 0x33, 0x1c, 0x7c, 0x80, 0xa0, 0xa5, 0x17, 0x8, 0xa2, 0x2d, 0x84, 0xf0, 0x1, 0xa2, 0x25, 0xf1, 0x9, 0x9a, 0x1c, 0xda, 0x5b, 0xb2, 0x47, 0xa8, 0xa5, 0xc1, 0xa0, 0x51, 0x88, 0xa2, 0x29, 0xa, 0xc1, 0x84, 0x8, 0x43, 0xf4, 0x96, 0x17, 0xcf, 0xed, 0xde, 0x73, 0x9c, 0xcc, 0x5c, 0xda, 0xea, 0x9f, 0x3f, 0xfe, 0x9f, 0xef, 0x87, 0x3f, 0x8f, 0x0, 0x40, 0xe1, 0xe2, 0x91, 0x42, 0x10, 0x32, 0xe6, 0x3, 0x8d, 0xc1, 0xce, 0x1, 0x45, 0xb6, 0xba, 0xbb, 0xba, 0xed, 0x95, 0x8c, 0xd0, 0x7d, 0xff, 0xe1, 0xee, 0xe2, 0xb6, 0xdd, 0x79, 0x61, 0xc4, 0xd7, 0xc, 0x48, 0x57, 0x2b, 0xeb, 0xb5, 0x28, 0xaf, 0x1, 0xc5, 0x12, 0x4e, 0xac, 0x7b, 0x6f, 0x57, 0x27, 0x8d, 0xcf, 0xe, 0x1, 0x56, 0x1, 0xb9, 0x9d, 0xba, 0x28, 0x6, 0x18, 0xc, 0x31, 0x21, 0x5a, 0xda, 0x4c, 0xb6, 0xbc, 0xb9, 0x35, 0x7c, 0xea, 0xbd, 0x13, 0x4a, 0x20, 0xe5, 0x95, 0xf4, 0x6c, 0x12, 0x30, 0x84, 0xf8, 0x44, 0x6b, 0xfb, 0xcd, 0x83, 0x3d, 0x1c, 0xf9, 0x8b, 0x80, 0x4a, 0xba, 0x88, 0x4, 0x30, 0x1e, 0xdd, 0x3b, 0x1b, 0xf1, 0x77, 0x87, 0x24, 0x81, 0x8b, 0x79, 0x3e, 0x3b, 0x6a, 0x5d, 0x33, 0x51, 0x80, 0x2d, 0x38, 0x2b, 0x65, 0xb5, 0x6c, 0x91, 0x28, 0x92, 0xa4, 0xad, 0xec, 0x76, 0xcf, 0x8f, 0xf, 0x1f, 0xdb, 0xc, 0x31, 0xb, 0x9a, 0xb1, 0xd0, 0x3, 0xfb, 0xda, 0x3a, 0xbd, 0xbc, 0x89, 0xfa, 0xf8, 0x73, 0xcd, 0x9f, 0x47, 0x45, 0x4, 0xf8, 0x4, 0x18, 0xfe, 0x2f, 0x53, 0x8, 0x62, 0x5c, 0xcf, 0x1f, 0x5f, 0xcb, 0x2c, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_grabber_hl_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0xf1, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0xad, 0x92, 0x31, 0x4e, 0x2, 0x61, 0x10, 0x85, 0xbf, 0x37, 0xc6, 0x52, 0x3b, 0xbd, 0x0, 0xe8, 0x65, 0xa0, 0x54, 0xe, 0x40, 0xaf, 0x15, 0x64, 0xa3, 0x85, 0xf9, 0x2b, 0x4d, 0xa4, 0xdc, 0xda, 0x3, 0x98, 0x10, 0x1b, 0xf1, 0x32, 0x44, 0x2e, 0x0, 0x34, 0x42, 0xa9, 0x61, 0x2c, 0xfe, 0xdd, 0x65, 0xb3, 0xa, 0xba, 0xe8, 0xeb, 0x66, 0x92, 0xf7, 0xbd, 0x37, 0xc9, 0xc0, 0x1f, 0xa5, 0xea, 0x22, 0xf8, 0xe0, 0x78, 0xc5, 0xea, 0x12, 0xd4, 0x2, 0x4e, 0xe2, 0xd6, 0xc7, 0x42, 0x2f, 0x42, 0x69, 0x50, 0x7f, 0xba, 0x11, 0x70, 0xe3, 0xf7, 0xe7, 0xc0, 0x3, 0x70, 0xb0, 0x21, 0x70, 0x69, 0x78, 0x37, 0x28, 0x19, 0x7e, 0x1, 0x64, 0xe6, 0xc7, 0xef, 0x5a, 0x55, 0xe4, 0x86, 0x77, 0x72, 0x88, 0xd6, 0xb5, 0xfd, 0x75, 0x4b, 0x72, 0x55, 0x8b, 0x77, 0x3e, 0x9a, 0x77, 0xba, 0x9e, 0x19, 0x40, 0xbc, 0xf9, 0xd7, 0x66, 0x80, 0xc3, 0x7d, 0xf6, 0x2e, 0x0, 0x2c, 0xce, 0xd6, 0xae, 0x61, 0xce, 0xd5, 0x2e, 0x1, 0x68, 0xd4, 0xf7, 0xab, 0x59, 0x2, 0xb8, 0xef, 0xd0, 0xc0, 0xcb, 0xd, 0x26, 0x3b, 0xf8, 0x27, 0x5, 0x40, 0x30, 0xaa, 0x6b, 0x17, 0x7a, 0x2e, 0x1, 0x94, 0x2, 0xcb, 0x1a, 0xfe, 0x37, 0x61, 0x69, 0x1, 0x8, 0xea, 0x4f, 0xd, 0xef, 0x92, 0xdd, 0xf5, 0x83, 0x3c, 0x7e, 0x63, 0x6f, 0x5e, 0x0, 0x22, 0x24, 0x19, 0x1a, 0xde, 0x1, 0x16, 0xdb, 0x92, 0xd, 0x3f, 0xb, 0x4a, 0x9e, 0xd6, 0xa7, 0x54, 0x74, 0xe5, 0xb7, 0x47, 0xf1, 0x49, 0xd4, 0x2, 0x9d, 0x66, 0xa1, 0x63, 0xc1, 0x48, 0x58, 0x9a, 0x27, 0xff, 0x9b, 0x3e, 0x1, 0x5e, 0x62, 0x48, 0x81, 0x2e, 0xbf, 0x88, 0xea, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x3, 0x0, 0x0, 0x0, 0x28, 0x2d, 0xf, 0x53, 0x0, 0x0, 0x0, 0xc3, 0x50, 0x4c, 0x54, 0x45, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x17, 0x2a, 0x29, 0x3a, 0x69, 0x69, 0x5b, 0xa6, 0xa5, 0x61, 0xb3, 0xbc, 0x63, 0xb7, 0xc8, 0x65, 0xbb, 0xca, 0x60, 0xaf, 0xb1, 0x48, 0x83, 0x83, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0xf, 0xf, 0x55, 0x9b, 0x9a, 0x60, 0xb2, 0xbd, 0x5e, 0xb1, 0xcd, 0x61, 0xb3, 0xc2, 0x0, 0x0, 0x0, 0x27, 0x48, 0x47, 0x62, 0xb4, 0xbd, 0x51, 0x93, 0x92, 0x68, 0xc0, 0xcf, 0x0, 0x0, 0x0, 0x56, 0x9d, 0x9c, 0x68, 0xc1, 0xcf, 0x2d, 0x52, 0x52, 0x63, 0xb7, 0xbf, 0x52, 0x96, 0x95, 0x62, 0xb3, 0xbf, 0x5e, 0xb0, 0xcd, 0x0, 0x0, 0x0, 0x3, 0x5, 0x5, 0x36, 0x63, 0x63, 0x63, 0xb4, 0xb6, 0x60, 0xb1, 0xbc, 0x63, 0xb7, 0xc7, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x55, 0xa3, 0xc8, 0x4f, 0x98, 0xc4, 0x4b, 0x93, 0xc2, 0x4c, 0x94, 0xc2, 0x54, 0xa2, 0xc8, 0x5a, 0xab, 0xcb, 0x4e, 0x97, 0xc4, 0x49, 0x8f, 0xc0, 0x47, 0x8c, 0xbf, 0x48, 0x8e, 0xc0, 0x52, 0x9e, 0xc6, 0x51, 0x9d, 0xc6, 0x5a, 0xac, 0xcc, 0x53, 0x9f, 0xc7, 0x4d, 0x96, 0xc3, 0x4b, 0x92, 0xc2, 0xff, 0xff, 0xff, 0x76, 0xbd, 0x27, 0x7a, 0x0, 0x0, 0x0, 0x1, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x40, 0xe6, 0xd8, 0x66, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x0, 0x88, 0x5, 0x1d, 0x48, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe1, 0x1, 0x12, 0x1, 0x36, 0x11, 0x34, 0xd2, 0xf, 0x93, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x48, 0x49, 0x44, 0x41, 0x54, 0x18, 0xd3, 0x63, 0x60, 0xa0, 0x12, 0x10, 0x14, 0xe0, 0xe7, 0xe3, 0x45, 0xe2, 0x4b, 0x9a, 0x18, 0x1b, 0x19, 0x1a, 0x48, 0x88, 0x8b, 0xc1, 0xe4, 0x4d, 0x2c, 0x2d, 0x80, 0xc0, 0xdc, 0xcc, 0x54, 0x6, 0x22, 0x20, 0x60, 0x6c, 0x1, 0x1, 0xe6, 0x56, 0x72, 0x68, 0x2, 0xd6, 0x8a, 0xa8, 0x5a, 0x6c, 0x94, 0x11, 0x86, 0xda, 0xdb, 0xd9, 0xaa, 0xa9, 0xaa, 0x20, 0x59, 0xab, 0xa3, 0xad, 0xc5, 0x40, 0x3d, 0x0, 0x0, 0xbf, 0x8e, 0xc, 0xed, 0xed, 0xc7, 0x67, 0x72, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vslider_tick_png[] = {
@@ -435,15 +443,15 @@ static const unsigned char vslider_tick_png[] = {
};
static const unsigned char vsplit_bg_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0xc4, 0xf, 0xbe, 0x8b, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x15, 0x49, 0x44, 0x41, 0x54, 0x18, 0x95, 0x63, 0x64, 0x60, 0x60, 0x90, 0x64, 0xc0, 0x3, 0x98, 0xf0, 0x49, 0xe, 0x1f, 0x5, 0x0, 0x22, 0xac, 0x0, 0x29, 0x2d, 0xd1, 0x16, 0xa4, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x8, 0x0, 0x0, 0x0, 0x8, 0x1, 0x3, 0x0, 0x0, 0x0, 0xfe, 0xc1, 0x2c, 0xc8, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x6, 0x50, 0x4c, 0x54, 0x45, 0x27, 0x27, 0x29, 0xff, 0xff, 0xff, 0x11, 0xab, 0xb9, 0xf3, 0x0, 0x0, 0x0, 0x1, 0x62, 0x4b, 0x47, 0x44, 0x1, 0xff, 0x2, 0x2d, 0xde, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0xb, 0x49, 0x44, 0x41, 0x54, 0x8, 0xd7, 0x63, 0x60, 0x40, 0x5, 0x0, 0x0, 0x10, 0x0, 0x1, 0xa1, 0xc5, 0x21, 0xc1, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char vsplitter_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x8, 0x8, 0x6, 0x0, 0x0, 0x0, 0x49, 0x62, 0xf9, 0xdf, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x48, 0x89, 0xed, 0xce, 0x41, 0x1, 0x0, 0x20, 0x0, 0x2, 0xb1, 0xc3, 0x14, 0x86, 0x32, 0xae, 0xa1, 0x6c, 0x81, 0x2d, 0xe4, 0x21, 0x4b, 0x30, 0xa8, 0xfa, 0x9a, 0x0, 0x6c, 0x2f, 0x60, 0x86, 0x2f, 0xaf, 0x1d, 0x49, 0x7b, 0xa4, 0x17, 0x55, 0x15, 0x75, 0x1, 0x7e, 0xa6, 0x5, 0x4, 0x90, 0x92, 0x89, 0x73, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x40, 0x0, 0x0, 0x0, 0x8, 0x8, 0x0, 0x0, 0x0, 0x0, 0x6c, 0x9, 0xa6, 0x3, 0x0, 0x0, 0x0, 0x4, 0x67, 0x41, 0x4d, 0x41, 0x0, 0x0, 0xb1, 0x8f, 0xb, 0xfc, 0x61, 0x5, 0x0, 0x0, 0x0, 0x20, 0x63, 0x48, 0x52, 0x4d, 0x0, 0x0, 0x7a, 0x26, 0x0, 0x0, 0x80, 0x84, 0x0, 0x0, 0xfa, 0x0, 0x0, 0x0, 0x80, 0xe8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0x17, 0x70, 0x9c, 0xba, 0x51, 0x3c, 0x0, 0x0, 0x0, 0x2, 0x74, 0x52, 0x4e, 0x53, 0x0, 0x0, 0x76, 0x93, 0xcd, 0x38, 0x0, 0x0, 0x0, 0x2, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x87, 0x8f, 0xcc, 0xbf, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x6, 0x16, 0x12, 0x2b, 0x5, 0x39, 0x1a, 0x32, 0x39, 0x0, 0x0, 0x0, 0x1f, 0x49, 0x44, 0x41, 0x54, 0x28, 0xcf, 0x63, 0x60, 0xa0, 0x10, 0x30, 0x33, 0x2c, 0x10, 0x3d, 0x47, 0x9, 0x66, 0x66, 0x10, 0xbd, 0xf6, 0x98, 0x22, 0x3c, 0xe0, 0x60, 0x18, 0x84, 0x1, 0x0, 0x59, 0x34, 0x6a, 0x2d, 0x64, 0xeb, 0x72, 0x24, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xc9, 0xad, 0xc8, 0x52, 0x0, 0x0, 0x0, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3a, 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x0, 0x32, 0x30, 0x31, 0x36, 0x2d, 0x30, 0x36, 0x2d, 0x32, 0x32, 0x54, 0x32, 0x30, 0x3a, 0x33, 0x39, 0x3a, 0x32, 0x36, 0x2b, 0x30, 0x32, 0x3a, 0x30, 0x30, 0xb8, 0xf0, 0x70, 0xee, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
static const unsigned char window_resizer_png[] = {
- 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x6, 0x62, 0x4b, 0x47, 0x44, 0x0, 0xff, 0x0, 0xff, 0x0, 0xff, 0xa0, 0xbd, 0xa7, 0x93, 0x0, 0x0, 0x0, 0x3f, 0x49, 0x44, 0x41, 0x54, 0x38, 0x8d, 0x63, 0x60, 0x18, 0x32, 0xe0, 0xff, 0xff, 0xff, 0x29, 0x14, 0x69, 0xfe, 0xff, 0xff, 0xff, 0x9, 0x6c, 0x72, 0x4c, 0x44, 0xda, 0x8c, 0xd3, 0x76, 0xbc, 0x6, 0x10, 0xd2, 0x8c, 0xd7, 0x0, 0x62, 0x34, 0xe3, 0x34, 0x80, 0x58, 0xcd, 0x58, 0xd, 0x20, 0x45, 0x33, 0x86, 0x1, 0xa4, 0x6a, 0x46, 0x31, 0x80, 0x1c, 0xcd, 0xa3, 0x80, 0x4a, 0x0, 0x0, 0x6, 0xc5, 0x24, 0xf9, 0xe8, 0x3d, 0x88, 0x7a, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
+ 0x89, 0x50, 0x4e, 0x47, 0xd, 0xa, 0x1a, 0xa, 0x0, 0x0, 0x0, 0xd, 0x49, 0x48, 0x44, 0x52, 0x0, 0x0, 0x0, 0x10, 0x0, 0x0, 0x0, 0x10, 0x8, 0x6, 0x0, 0x0, 0x0, 0x1f, 0xf3, 0xff, 0x61, 0x0, 0x0, 0x0, 0x9, 0x70, 0x48, 0x59, 0x73, 0x0, 0x0, 0xb, 0x13, 0x0, 0x0, 0xb, 0x13, 0x1, 0x0, 0x9a, 0x9c, 0x18, 0x0, 0x0, 0x0, 0x7, 0x74, 0x49, 0x4d, 0x45, 0x7, 0xe0, 0x8, 0x19, 0x11, 0x33, 0x13, 0xaa, 0xc0, 0xf, 0x5f, 0x0, 0x0, 0x0, 0x19, 0x74, 0x45, 0x58, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x6e, 0x74, 0x0, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x77, 0x69, 0x74, 0x68, 0x20, 0x47, 0x49, 0x4d, 0x50, 0x57, 0x81, 0xe, 0x17, 0x0, 0x0, 0x0, 0x2f, 0x49, 0x44, 0x41, 0x54, 0x38, 0xcb, 0x63, 0x60, 0x18, 0x5, 0x24, 0x81, 0x17, 0x2f, 0x5e, 0xf4, 0xa3, 0x8b, 0x31, 0x91, 0xa2, 0xb9, 0xb9, 0xb9, 0x99, 0x7c, 0x9b, 0xb3, 0xb3, 0xb3, 0xfb, 0x87, 0x81, 0x66, 0x6c, 0x81, 0x48, 0x92, 0x66, 0xa2, 0x5c, 0x43, 0x91, 0xe6, 0x11, 0xa, 0x0, 0x73, 0x5b, 0x34, 0x19, 0x10, 0xa0, 0xb6, 0x7d, 0x0, 0x0, 0x0, 0x0, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82
};
// shaders block
diff --git a/scene/resources/default_theme/toggle_off.png b/scene/resources/default_theme/toggle_off.png
index 5537d00a4a..71cd64b001 100644
--- a/scene/resources/default_theme/toggle_off.png
+++ b/scene/resources/default_theme/toggle_off.png
Binary files differ
diff --git a/scene/resources/default_theme/toggle_on.png b/scene/resources/default_theme/toggle_on.png
index 77e4601205..6ea1b589c7 100644
--- a/scene/resources/default_theme/toggle_on.png
+++ b/scene/resources/default_theme/toggle_on.png
Binary files differ
diff --git a/scene/resources/default_theme/tool_button_pressed.png b/scene/resources/default_theme/tool_button_pressed.png
new file mode 100644
index 0000000000..bcf70b486d
--- /dev/null
+++ b/scene/resources/default_theme/tool_button_pressed.png
Binary files differ
diff --git a/scene/resources/default_theme/tooltip_bg.png b/scene/resources/default_theme/tooltip_bg.png
index 7ca3567788..eca0675a98 100644
--- a/scene/resources/default_theme/tooltip_bg.png
+++ b/scene/resources/default_theme/tooltip_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/tree_bg.png b/scene/resources/default_theme/tree_bg.png
index 0be4f628a9..839a6a272a 100644
--- a/scene/resources/default_theme/tree_bg.png
+++ b/scene/resources/default_theme/tree_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/tree_bg_focus.png b/scene/resources/default_theme/tree_bg_focus.png
new file mode 100644
index 0000000000..692cf71926
--- /dev/null
+++ b/scene/resources/default_theme/tree_bg_focus.png
Binary files differ
diff --git a/scene/resources/default_theme/tree_title.png b/scene/resources/default_theme/tree_title.png
index 7f81acd89e..b0ddcffbbe 100644
--- a/scene/resources/default_theme/tree_title.png
+++ b/scene/resources/default_theme/tree_title.png
Binary files differ
diff --git a/scene/resources/default_theme/tree_title_pressed.png b/scene/resources/default_theme/tree_title_pressed.png
index b09604015b..746d10039e 100644
--- a/scene/resources/default_theme/tree_title_pressed.png
+++ b/scene/resources/default_theme/tree_title_pressed.png
Binary files differ
diff --git a/scene/resources/default_theme/unchecked.png b/scene/resources/default_theme/unchecked.png
index 8341cdc643..d6f790cbc2 100644
--- a/scene/resources/default_theme/unchecked.png
+++ b/scene/resources/default_theme/unchecked.png
Binary files differ
diff --git a/scene/resources/default_theme/updown.png b/scene/resources/default_theme/updown.png
index efcb04fde6..916284a3cf 100644
--- a/scene/resources/default_theme/updown.png
+++ b/scene/resources/default_theme/updown.png
Binary files differ
diff --git a/scene/resources/default_theme/vseparator.png b/scene/resources/default_theme/vseparator.png
index 88165ea6b2..498768c05b 100644
--- a/scene/resources/default_theme/vseparator.png
+++ b/scene/resources/default_theme/vseparator.png
Binary files differ
diff --git a/scene/resources/default_theme/vslider_bg.png b/scene/resources/default_theme/vslider_bg.png
index b88582ba36..8d9ead3c5a 100644
--- a/scene/resources/default_theme/vslider_bg.png
+++ b/scene/resources/default_theme/vslider_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/vslider_grabber.png b/scene/resources/default_theme/vslider_grabber.png
index c8be897e07..afc490be45 100644
--- a/scene/resources/default_theme/vslider_grabber.png
+++ b/scene/resources/default_theme/vslider_grabber.png
Binary files differ
diff --git a/scene/resources/default_theme/vslider_grabber_hl.png b/scene/resources/default_theme/vslider_grabber_hl.png
index 1639776a28..548972e115 100644
--- a/scene/resources/default_theme/vslider_grabber_hl.png
+++ b/scene/resources/default_theme/vslider_grabber_hl.png
Binary files differ
diff --git a/scene/resources/default_theme/vsplit_bg.png b/scene/resources/default_theme/vsplit_bg.png
index 0c29b1e35c..7dd1d48b29 100644
--- a/scene/resources/default_theme/vsplit_bg.png
+++ b/scene/resources/default_theme/vsplit_bg.png
Binary files differ
diff --git a/scene/resources/default_theme/vsplitter.png b/scene/resources/default_theme/vsplitter.png
index 56fb20bc3f..ec5542bf69 100644
--- a/scene/resources/default_theme/vsplitter.png
+++ b/scene/resources/default_theme/vsplitter.png
Binary files differ
diff --git a/scene/resources/default_theme/window_resizer.png b/scene/resources/default_theme/window_resizer.png
index baa3f30e5b..ed51968c4e 100644
--- a/scene/resources/default_theme/window_resizer.png
+++ b/scene/resources/default_theme/window_resizer.png
Binary files differ
diff --git a/scene/resources/dynamic_font.cpp b/scene/resources/dynamic_font.cpp
index 6a5c4b97fc..d2848076a0 100644
--- a/scene/resources/dynamic_font.cpp
+++ b/scene/resources/dynamic_font.cpp
@@ -569,7 +569,7 @@ void DynamicFontAtSize::_update_char(CharType p_char) {
//blit to image and texture
{
- Image img(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata);
+ Ref<Image> img = memnew(Image(tex.texture_size, tex.texture_size, 0, Image::FORMAT_LA8, tex.imgdata));
if (tex.texture.is_null()) {
tex.texture.instance();
diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp
index 96871cc944..a435ba06cc 100644
--- a/scene/resources/environment.cpp
+++ b/scene/resources/environment.cpp
@@ -44,21 +44,21 @@ void Environment::set_background(BGMode p_bg) {
_change_notify();
}
-void Environment::set_skybox(const Ref<SkyBox> &p_skybox) {
+void Environment::set_sky(const Ref<Sky> &p_sky) {
- bg_skybox = p_skybox;
+ bg_sky = p_sky;
RID sb_rid;
- if (bg_skybox.is_valid())
- sb_rid = bg_skybox->get_rid();
+ if (bg_sky.is_valid())
+ sb_rid = bg_sky->get_rid();
- VS::get_singleton()->environment_set_skybox(environment, sb_rid);
+ VS::get_singleton()->environment_set_sky(environment, sb_rid);
}
-void Environment::set_skybox_scale(float p_scale) {
+void Environment::set_sky_scale(float p_scale) {
- bg_skybox_scale = p_scale;
- VS::get_singleton()->environment_set_skybox_scale(environment, p_scale);
+ bg_sky_scale = p_scale;
+ VS::get_singleton()->environment_set_sky_scale(environment, p_scale);
}
void Environment::set_bg_color(const Color &p_color) {
@@ -79,31 +79,31 @@ void Environment::set_canvas_max_layer(int p_max_layer) {
void Environment::set_ambient_light_color(const Color &p_color) {
ambient_color = p_color;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_skybox_contribution);
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
}
void Environment::set_ambient_light_energy(float p_energy) {
ambient_energy = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_skybox_contribution);
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
}
-void Environment::set_ambient_light_skybox_contribution(float p_energy) {
+void Environment::set_ambient_light_sky_contribution(float p_energy) {
- ambient_skybox_contribution = p_energy;
- VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_skybox_contribution);
+ ambient_sky_contribution = p_energy;
+ VS::get_singleton()->environment_set_ambient_light(environment, ambient_color, ambient_energy, ambient_sky_contribution);
}
Environment::BGMode Environment::get_background() const {
return bg_mode;
}
-Ref<SkyBox> Environment::get_skybox() const {
+Ref<Sky> Environment::get_sky() const {
- return bg_skybox;
+ return bg_sky;
}
-float Environment::get_skybox_scale() const {
+float Environment::get_sky_scale() const {
- return bg_skybox_scale;
+ return bg_sky_scale;
}
Color Environment::get_bg_color() const {
@@ -126,9 +126,9 @@ float Environment::get_ambient_light_energy() const {
return ambient_energy;
}
-float Environment::get_ambient_light_skybox_contribution() const {
+float Environment::get_ambient_light_sky_contribution() const {
- return ambient_skybox_contribution;
+ return ambient_sky_contribution;
}
void Environment::set_tonemapper(ToneMapper p_tone_mapper) {
@@ -217,6 +217,7 @@ void Environment::set_adjustment_enable(bool p_enable) {
adjustment_enabled = p_enable;
VS::get_singleton()->environment_set_adjustment(environment, adjustment_enabled, adjustment_brightness, adjustment_contrast, adjustment_saturation, adjustment_color_correction.is_valid() ? adjustment_color_correction->get_rid() : RID());
+ _change_notify();
}
bool Environment::is_adjustment_enabled() const {
@@ -266,29 +267,56 @@ Ref<Texture> Environment::get_adjustment_color_correction() const {
void Environment::_validate_property(PropertyInfo &property) const {
- if (property.name == "background/skybox" || property.name == "background/skybox_scale" || property.name == "ambient_light/skybox_contribution") {
- if (bg_mode != BG_SKYBOX) {
+ if (property.name == "background_sky" || property.name == "background_sky_scale" || property.name == "ambient_light/sky_contribution") {
+ if (bg_mode != BG_SKY) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
- if (property.name == "background/color") {
+ if (property.name == "background_color") {
if (bg_mode != BG_COLOR) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
- if (property.name == "background/canvas_max_layer") {
+ if (property.name == "background_canvas_max_layer") {
if (bg_mode != BG_CANVAS) {
property.usage = PROPERTY_USAGE_NOEDITOR;
}
}
+
+ static const char *hide_prefixes[] = {
+ "fog_",
+ "auto_exposure_",
+ "ss_reflections_",
+ "ssao_",
+ "dof_blur_far_",
+ "dof_blur_near_",
+ "glow_",
+ "adjustment_",
+ NULL
+
+ };
+
+ const char **prefixes = hide_prefixes;
+ while (*prefixes) {
+ String prefix = String(*prefixes);
+
+ String enabled = prefix + "enabled";
+ if (property.name.begins_with(prefix) && property.name != enabled && !bool(get(enabled))) {
+ property.usage = PROPERTY_USAGE_NOEDITOR;
+ return;
+ }
+
+ prefixes++;
+ }
}
void Environment::set_ssr_enabled(bool p_enable) {
ssr_enabled = p_enable;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
+ _change_notify();
}
bool Environment::is_ssr_enabled() const {
@@ -299,57 +327,47 @@ bool Environment::is_ssr_enabled() const {
void Environment::set_ssr_max_steps(int p_steps) {
ssr_max_steps = p_steps;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
}
int Environment::get_ssr_max_steps() const {
return ssr_max_steps;
}
-void Environment::set_ssr_accel(float p_accel) {
+void Environment::set_ssr_fade_in(float p_fade_in) {
- ssr_accel = p_accel;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ ssr_fade_in = p_fade_in;
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
}
-float Environment::get_ssr_accel() const {
+float Environment::get_ssr_fade_in() const {
- return ssr_accel;
+ return ssr_fade_in;
}
-void Environment::set_ssr_fade(float p_fade) {
+void Environment::set_ssr_fade_out(float p_fade_out) {
- ssr_fade = p_fade;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ ssr_fade_out = p_fade_out;
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
}
-float Environment::get_ssr_fade() const {
+float Environment::get_ssr_fade_out() const {
- return ssr_fade;
+ return ssr_fade_out;
}
void Environment::set_ssr_depth_tolerance(float p_depth_tolerance) {
ssr_depth_tolerance = p_depth_tolerance;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
}
float Environment::get_ssr_depth_tolerance() const {
return ssr_depth_tolerance;
}
-void Environment::set_ssr_smooth(bool p_enable) {
-
- ssr_smooth = p_enable;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
-}
-bool Environment::is_ssr_smooth() const {
-
- return ssr_smooth;
-}
-
void Environment::set_ssr_rough(bool p_enable) {
ssr_roughness = p_enable;
- VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_accel, ssr_fade, ssr_depth_tolerance, ssr_smooth, ssr_roughness);
+ VS::get_singleton()->environment_set_ssr(environment, ssr_enabled, ssr_max_steps, ssr_fade_in, ssr_fade_out, ssr_depth_tolerance, ssr_roughness);
}
bool Environment::is_ssr_rough() const {
@@ -360,6 +378,7 @@ void Environment::set_ssao_enabled(bool p_enable) {
ssao_enabled = p_enable;
VS::get_singleton()->environment_set_ssao(environment, ssao_enabled, ssao_radius, ssao_intensity, ssao_radius2, ssao_intensity2, ssao_bias, ssao_direct_light_affect, ssao_color, ssao_blur);
+ _change_notify();
}
bool Environment::is_ssao_enabled() const {
@@ -453,6 +472,7 @@ void Environment::set_glow_enabled(bool p_enabled) {
glow_enabled = p_enabled;
VS::get_singleton()->environment_set_glow(environment, glow_enabled, glow_levels, glow_intensity, glow_strength, glow_bloom, VS::EnvironmentGlowBlendMode(glow_blend_mode), glow_hdr_bleed_treshold, glow_hdr_bleed_treshold, glow_bicubic_upscale);
+ _change_notify();
}
bool Environment::is_glow_enabled() const {
@@ -558,6 +578,7 @@ void Environment::set_dof_blur_far_enabled(bool p_enable) {
dof_blur_far_enabled = p_enable;
VS::get_singleton()->environment_set_dof_blur_far(environment, dof_blur_far_enabled, dof_blur_far_distance, dof_blur_far_transition, dof_blur_far_amount, VS::EnvironmentDOFBlurQuality(dof_blur_far_quality));
+ _change_notify();
}
bool Environment::is_dof_blur_far_enabled() const {
@@ -610,6 +631,7 @@ void Environment::set_dof_blur_near_enabled(bool p_enable) {
dof_blur_near_enabled = p_enable;
VS::get_singleton()->environment_set_dof_blur_near(environment, dof_blur_near_enabled, dof_blur_near_distance, dof_blur_near_transition, dof_blur_near_amount, VS::EnvironmentDOFBlurQuality(dof_blur_near_quality));
+ _change_notify();
}
bool Environment::is_dof_blur_near_enabled() const {
@@ -661,39 +683,260 @@ Environment::DOFBlurQuality Environment::get_dof_blur_near_quality() const {
return dof_blur_near_quality;
}
+void Environment::set_fog_enabled(bool p_enabled) {
+
+ fog_enabled = p_enabled;
+ VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+ _change_notify();
+}
+
+bool Environment::is_fog_enabled() const {
+
+ return fog_enabled;
+}
+
+void Environment::set_fog_color(const Color &p_color) {
+
+ fog_color = p_color;
+ VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+}
+Color Environment::get_fog_color() const {
+
+ return fog_color;
+}
+
+void Environment::set_fog_sun_color(const Color &p_color) {
+
+ fog_sun_color = p_color;
+ VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+}
+Color Environment::get_fog_sun_color() const {
+
+ return fog_sun_color;
+}
+
+void Environment::set_fog_sun_amount(float p_amount) {
+
+ fog_sun_amount = p_amount;
+ VS::get_singleton()->environment_set_fog(environment, fog_enabled, fog_color, fog_sun_color, fog_sun_amount);
+}
+float Environment::get_fog_sun_amount() const {
+
+ return fog_sun_amount;
+}
+
+void Environment::set_fog_depth_enabled(bool p_enabled) {
+
+ fog_depth_enabled = p_enabled;
+ VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+bool Environment::is_fog_depth_enabled() const {
+
+ return fog_depth_enabled;
+}
+
+void Environment::set_fog_depth_begin(float p_distance) {
+
+ fog_depth_begin = p_distance;
+ VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+float Environment::get_fog_depth_begin() const {
+
+ return fog_depth_begin;
+}
+
+void Environment::set_fog_depth_curve(float p_curve) {
+
+ fog_depth_curve = p_curve;
+ VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+float Environment::get_fog_depth_curve() const {
+
+ return fog_depth_curve;
+}
+
+void Environment::set_fog_transmit_enabled(bool p_enabled) {
+
+ fog_transmit_enabled = p_enabled;
+ VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+bool Environment::is_fog_transmit_enabled() const {
+
+ return fog_transmit_enabled;
+}
+
+void Environment::set_fog_transmit_curve(float p_curve) {
+
+ fog_transmit_curve = p_curve;
+ VS::get_singleton()->environment_set_fog_depth(environment, fog_depth_enabled, fog_depth_begin, fog_depth_curve, fog_transmit_enabled, fog_transmit_curve);
+}
+float Environment::get_fog_transmit_curve() const {
+
+ return fog_transmit_curve;
+}
+
+void Environment::set_fog_height_enabled(bool p_enabled) {
+
+ fog_height_enabled = p_enabled;
+ VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
+}
+bool Environment::is_fog_height_enabled() const {
+
+ return fog_height_enabled;
+}
+
+void Environment::set_fog_height_min(float p_distance) {
+
+ fog_height_min = p_distance;
+ VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
+}
+float Environment::get_fog_height_min() const {
+
+ return fog_height_min;
+}
+
+void Environment::set_fog_height_max(float p_distance) {
+
+ fog_height_max = p_distance;
+ VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
+}
+float Environment::get_fog_height_max() const {
+
+ return fog_height_max;
+}
+
+void Environment::set_fog_height_curve(float p_distance) {
+
+ fog_height_curve = p_distance;
+ VS::get_singleton()->environment_set_fog_height(environment, fog_height_enabled, fog_height_min, fog_height_max, fog_height_curve);
+}
+float Environment::get_fog_height_curve() const {
+
+ return fog_height_curve;
+}
+
void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_background", "mode"), &Environment::set_background);
- ClassDB::bind_method(D_METHOD("set_skybox", "skybox:CubeMap"), &Environment::set_skybox);
- ClassDB::bind_method(D_METHOD("set_skybox_scale", "scale"), &Environment::set_skybox_scale);
+ ClassDB::bind_method(D_METHOD("set_sky", "sky:CubeMap"), &Environment::set_sky);
+ ClassDB::bind_method(D_METHOD("set_sky_scale", "scale"), &Environment::set_sky_scale);
ClassDB::bind_method(D_METHOD("set_bg_color", "color"), &Environment::set_bg_color);
ClassDB::bind_method(D_METHOD("set_bg_energy", "energy"), &Environment::set_bg_energy);
ClassDB::bind_method(D_METHOD("set_canvas_max_layer", "layer"), &Environment::set_canvas_max_layer);
ClassDB::bind_method(D_METHOD("set_ambient_light_color", "color"), &Environment::set_ambient_light_color);
ClassDB::bind_method(D_METHOD("set_ambient_light_energy", "energy"), &Environment::set_ambient_light_energy);
- ClassDB::bind_method(D_METHOD("set_ambient_light_skybox_contribution", "energy"), &Environment::set_ambient_light_skybox_contribution);
+ ClassDB::bind_method(D_METHOD("set_ambient_light_sky_contribution", "energy"), &Environment::set_ambient_light_sky_contribution);
ClassDB::bind_method(D_METHOD("get_background"), &Environment::get_background);
- ClassDB::bind_method(D_METHOD("get_skybox:CubeMap"), &Environment::get_skybox);
- ClassDB::bind_method(D_METHOD("get_skybox_scale"), &Environment::get_skybox_scale);
+ ClassDB::bind_method(D_METHOD("get_sky:CubeMap"), &Environment::get_sky);
+ ClassDB::bind_method(D_METHOD("get_sky_scale"), &Environment::get_sky_scale);
ClassDB::bind_method(D_METHOD("get_bg_color"), &Environment::get_bg_color);
ClassDB::bind_method(D_METHOD("get_bg_energy"), &Environment::get_bg_energy);
ClassDB::bind_method(D_METHOD("get_canvas_max_layer"), &Environment::get_canvas_max_layer);
ClassDB::bind_method(D_METHOD("get_ambient_light_color"), &Environment::get_ambient_light_color);
ClassDB::bind_method(D_METHOD("get_ambient_light_energy"), &Environment::get_ambient_light_energy);
- ClassDB::bind_method(D_METHOD("get_ambient_light_skybox_contribution"), &Environment::get_ambient_light_skybox_contribution);
+ ClassDB::bind_method(D_METHOD("get_ambient_light_sky_contribution"), &Environment::get_ambient_light_sky_contribution);
ADD_GROUP("Background", "background_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Skybox,Canvas,Keep"), "set_background", "get_background");
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_skybox", PROPERTY_HINT_RESOURCE_TYPE, "SkyBox"), "set_skybox", "get_skybox");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_skybox_scale", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_skybox_scale", "get_skybox_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "background_mode", PROPERTY_HINT_ENUM, "Clear Color,Custom Color,Sky,Canvas,Keep"), "set_background", "get_background");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "background_sky", PROPERTY_HINT_RESOURCE_TYPE, "Sky"), "set_sky", "get_sky");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_sky_scale", PROPERTY_HINT_RANGE, "0,32,0.01"), "set_sky_scale", "get_sky_scale");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "background_color"), "set_bg_color", "get_bg_color");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "background_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_bg_energy", "get_bg_energy");
ADD_PROPERTY(PropertyInfo(Variant::INT, "background_canvas_max_layer", PROPERTY_HINT_RANGE, "-1000,1000,1"), "set_canvas_max_layer", "get_canvas_max_layer");
ADD_GROUP("Ambient Light", "ambient_light_");
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ambient_light_color"), "set_ambient_light_color", "get_ambient_light_color");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_energy", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_ambient_light_energy", "get_ambient_light_energy");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_skybox_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_skybox_contribution", "get_ambient_light_skybox_contribution");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ambient_light_sky_contribution", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_ambient_light_sky_contribution", "get_ambient_light_sky_contribution");
+
+ ClassDB::bind_method(D_METHOD("set_fog_enabled", "enabled"), &Environment::set_fog_enabled);
+ ClassDB::bind_method(D_METHOD("is_fog_enabled"), &Environment::is_fog_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_fog_color", "color"), &Environment::set_fog_color);
+ ClassDB::bind_method(D_METHOD("get_fog_color"), &Environment::get_fog_color);
+
+ ClassDB::bind_method(D_METHOD("set_fog_sun_color", "color"), &Environment::set_fog_sun_color);
+ ClassDB::bind_method(D_METHOD("get_fog_sun_color"), &Environment::get_fog_sun_color);
+
+ ClassDB::bind_method(D_METHOD("set_fog_sun_amount", "amount"), &Environment::set_fog_sun_amount);
+ ClassDB::bind_method(D_METHOD("get_fog_sun_amount"), &Environment::get_fog_sun_amount);
+
+ ClassDB::bind_method(D_METHOD("set_fog_depth_enabled", "enabled"), &Environment::set_fog_depth_enabled);
+ ClassDB::bind_method(D_METHOD("is_fog_depth_enabled"), &Environment::is_fog_depth_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_fog_depth_begin", "distance"), &Environment::set_fog_depth_begin);
+ ClassDB::bind_method(D_METHOD("get_fog_depth_begin"), &Environment::get_fog_depth_begin);
+
+ ClassDB::bind_method(D_METHOD("set_fog_depth_curve", "curve"), &Environment::set_fog_depth_curve);
+ ClassDB::bind_method(D_METHOD("get_fog_depth_curve"), &Environment::get_fog_depth_curve);
+
+ ClassDB::bind_method(D_METHOD("set_fog_transmit_enabled", "enabled"), &Environment::set_fog_transmit_enabled);
+ ClassDB::bind_method(D_METHOD("is_fog_transmit_enabled"), &Environment::is_fog_transmit_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_fog_transmit_curve", "curve"), &Environment::set_fog_transmit_curve);
+ ClassDB::bind_method(D_METHOD("get_fog_transmit_curve"), &Environment::get_fog_transmit_curve);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height_enabled", "enabled"), &Environment::set_fog_height_enabled);
+ ClassDB::bind_method(D_METHOD("is_fog_height_enabled"), &Environment::is_fog_height_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height_min", "height"), &Environment::set_fog_height_min);
+ ClassDB::bind_method(D_METHOD("get_fog_height_min"), &Environment::get_fog_height_min);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height_max", "height"), &Environment::set_fog_height_max);
+ ClassDB::bind_method(D_METHOD("get_fog_height_max"), &Environment::get_fog_height_max);
+
+ ClassDB::bind_method(D_METHOD("set_fog_height_curve", "curve"), &Environment::set_fog_height_curve);
+ ClassDB::bind_method(D_METHOD("get_fog_height_curve"), &Environment::get_fog_height_curve);
+
+ ADD_GROUP("Fog", "fog_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_enabled"), "set_fog_enabled", "is_fog_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_color"), "set_fog_color", "get_fog_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "fog_sun_color"), "set_fog_sun_color", "get_fog_sun_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_sun_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_fog_sun_amount", "get_fog_sun_amount");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_depth_enabled"), "set_fog_depth_enabled", "is_fog_depth_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_begin", PROPERTY_HINT_RANGE, "0,4000,0.1"), "set_fog_depth_begin", "get_fog_depth_begin");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_depth_curve", PROPERTY_HINT_EXP_EASING), "set_fog_depth_curve", "get_fog_depth_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_transmit_enabled"), "set_fog_transmit_enabled", "is_fog_transmit_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_transmit_curve", PROPERTY_HINT_EXP_EASING), "set_fog_transmit_curve", "get_fog_transmit_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "fog_height_enabled"), "set_fog_height_enabled", "is_fog_height_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_min", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_min", "get_fog_height_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_max", PROPERTY_HINT_RANGE, "-4000,4000,0.1"), "set_fog_height_max", "get_fog_height_max");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "fog_height_curve", PROPERTY_HINT_EXP_EASING), "set_fog_height_curve", "get_fog_height_curve");
+
+ ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
+ ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure);
+ ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white);
+ ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure);
+ ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max);
+ ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min);
+ ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed);
+ ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed);
+
+ ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey);
+ ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
+
+ ADD_GROUP("Tonemap", "tonemap_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
+ ADD_GROUP("Auto Exposure", "auto_exposure_");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_exposure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_exposure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
ClassDB::bind_method(D_METHOD("set_ssr_enabled", "enabled"), &Environment::set_ssr_enabled);
ClassDB::bind_method(D_METHOD("is_ssr_enabled"), &Environment::is_ssr_enabled);
@@ -701,18 +944,15 @@ void Environment::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_ssr_max_steps", "max_steps"), &Environment::set_ssr_max_steps);
ClassDB::bind_method(D_METHOD("get_ssr_max_steps"), &Environment::get_ssr_max_steps);
- ClassDB::bind_method(D_METHOD("set_ssr_accel", "accel"), &Environment::set_ssr_accel);
- ClassDB::bind_method(D_METHOD("get_ssr_accel"), &Environment::get_ssr_accel);
+ ClassDB::bind_method(D_METHOD("set_ssr_fade_in", "fade_in"), &Environment::set_ssr_fade_in);
+ ClassDB::bind_method(D_METHOD("get_ssr_fade_in"), &Environment::get_ssr_fade_in);
- ClassDB::bind_method(D_METHOD("set_ssr_fade", "fade"), &Environment::set_ssr_fade);
- ClassDB::bind_method(D_METHOD("get_ssr_fade"), &Environment::get_ssr_fade);
+ ClassDB::bind_method(D_METHOD("set_ssr_fade_out", "fade_out"), &Environment::set_ssr_fade_out);
+ ClassDB::bind_method(D_METHOD("get_ssr_fade_out"), &Environment::get_ssr_fade_out);
ClassDB::bind_method(D_METHOD("set_ssr_depth_tolerance", "depth_tolerance"), &Environment::set_ssr_depth_tolerance);
ClassDB::bind_method(D_METHOD("get_ssr_depth_tolerance"), &Environment::get_ssr_depth_tolerance);
- ClassDB::bind_method(D_METHOD("set_ssr_smooth", "smooth"), &Environment::set_ssr_smooth);
- ClassDB::bind_method(D_METHOD("is_ssr_smooth"), &Environment::is_ssr_smooth);
-
ClassDB::bind_method(D_METHOD("set_ssr_rough", "rough"), &Environment::set_ssr_rough);
ClassDB::bind_method(D_METHOD("is_ssr_rough"), &Environment::is_ssr_rough);
@@ -720,9 +960,9 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_enabled"), "set_ssr_enabled", "is_ssr_enabled");
ADD_PROPERTY(PropertyInfo(Variant::INT, "ss_reflections_max_steps", PROPERTY_HINT_RANGE, "1,512,1"), "set_ssr_max_steps", "get_ssr_max_steps");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_accel", PROPERTY_HINT_RANGE, "0,4,0.01"), "set_ssr_accel", "get_ssr_accel");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade", PROPERTY_HINT_EXP_EASING), "set_ssr_fade", "get_ssr_fade");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_in", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_in", "get_ssr_fade_in");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_fade_out", PROPERTY_HINT_EXP_EASING), "set_ssr_fade_out", "get_ssr_fade_out");
ADD_PROPERTY(PropertyInfo(Variant::REAL, "ss_reflections_depth_tolerance", PROPERTY_HINT_RANGE, "0.1,128,0.1"), "set_ssr_depth_tolerance", "get_ssr_depth_tolerance");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_accel_smooth"), "set_ssr_smooth", "is_ssr_smooth");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "ss_reflections_roughness"), "set_ssr_rough", "is_ssr_rough");
ClassDB::bind_method(D_METHOD("set_ssao_enabled", "enabled"), &Environment::set_ssao_enabled);
@@ -852,41 +1092,6 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "glow_hdr_scale", PROPERTY_HINT_RANGE, "0.0,4.0,0.01"), "set_glow_hdr_bleed_scale", "get_glow_hdr_bleed_scale");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "glow_bicubic_upscale"), "set_glow_bicubic_upscale", "is_glow_bicubic_upscale_enabled");
- ClassDB::bind_method(D_METHOD("set_tonemapper", "mode"), &Environment::set_tonemapper);
- ClassDB::bind_method(D_METHOD("get_tonemapper"), &Environment::get_tonemapper);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_exposure", "exposure"), &Environment::set_tonemap_exposure);
- ClassDB::bind_method(D_METHOD("get_tonemap_exposure"), &Environment::get_tonemap_exposure);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_white", "white"), &Environment::set_tonemap_white);
- ClassDB::bind_method(D_METHOD("get_tonemap_white"), &Environment::get_tonemap_white);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure", "auto_exposure"), &Environment::set_tonemap_auto_exposure);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure"), &Environment::get_tonemap_auto_exposure);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_max", "exposure_max"), &Environment::set_tonemap_auto_exposure_max);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_max"), &Environment::get_tonemap_auto_exposure_max);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_min", "exposure_min"), &Environment::set_tonemap_auto_exposure_min);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_min"), &Environment::get_tonemap_auto_exposure_min);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_speed", "exposure_speed"), &Environment::set_tonemap_auto_exposure_speed);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_speed"), &Environment::get_tonemap_auto_exposure_speed);
-
- ClassDB::bind_method(D_METHOD("set_tonemap_auto_exposure_grey", "exposure_grey"), &Environment::set_tonemap_auto_exposure_grey);
- ClassDB::bind_method(D_METHOD("get_tonemap_auto_exposure_grey"), &Environment::get_tonemap_auto_exposure_grey);
-
- ADD_GROUP("Tonemap", "tonemap_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "tonemap_mode", PROPERTY_HINT_ENUM, "Linear,Reindhart,Filmic,Aces"), "set_tonemapper", "get_tonemapper");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_exposure", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_exposure", "get_tonemap_exposure");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "tonemap_white", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_white", "get_tonemap_white");
- ADD_GROUP("Auto Exposure", "auto_exposure_");
- ADD_PROPERTY(PropertyInfo(Variant::BOOL, "auto_expoure_enabled"), "set_tonemap_auto_exposure", "get_tonemap_auto_exposure");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_scale", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_grey", "get_tonemap_auto_exposure_grey");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_min_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_min", "get_tonemap_auto_exposure_min");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_max_luma", PROPERTY_HINT_RANGE, "0,16,0.01"), "set_tonemap_auto_exposure_max", "get_tonemap_auto_exposure_max");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "auto_expoure_speed", PROPERTY_HINT_RANGE, "0.01,64,0.01"), "set_tonemap_auto_exposure_speed", "get_tonemap_auto_exposure_speed");
-
ClassDB::bind_method(D_METHOD("set_adjustment_enable", "enabled"), &Environment::set_adjustment_enable);
ClassDB::bind_method(D_METHOD("is_adjustment_enabled"), &Environment::is_adjustment_enabled);
@@ -909,12 +1114,12 @@ void Environment::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::REAL, "adjustment_saturation", PROPERTY_HINT_RANGE, "0.01,8,0.01"), "set_adjustment_saturation", "get_adjustment_saturation");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "adjustment_color_correction", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_adjustment_color_correction", "get_adjustment_color_correction");
- GLOBAL_DEF("rendering/skybox/irradiance_cube_resolution", 256);
+ GLOBAL_DEF("rendering/sky/irradiance_cube_resolution", 256);
BIND_CONSTANT(BG_KEEP);
BIND_CONSTANT(BG_CLEAR_COLOR);
BIND_CONSTANT(BG_COLOR);
- BIND_CONSTANT(BG_SKYBOX);
+ BIND_CONSTANT(BG_SKY);
BIND_CONSTANT(BG_CANVAS);
BIND_CONSTANT(BG_MAX);
BIND_CONSTANT(GLOW_BLEND_MODE_ADDITIVE);
@@ -933,11 +1138,11 @@ void Environment::_bind_methods() {
Environment::Environment() {
bg_mode = BG_CLEAR_COLOR;
- bg_skybox_scale = 1.0;
+ bg_sky_scale = 1.0;
bg_energy = 1.0;
bg_canvas_max_layer = 0;
ambient_energy = 1.0;
- ambient_skybox_contribution = 0;
+ ambient_sky_contribution = 0;
tone_mapper = TONE_MAPPER_LINEAR;
tonemap_exposure = 1.0;
@@ -961,10 +1166,9 @@ Environment::Environment() {
ssr_enabled = false;
ssr_max_steps = 64;
- ssr_accel = 0.04;
- ssr_fade = 2.0;
+ ssr_fade_in = 0.15;
+ ssr_fade_out = 2.0;
ssr_depth_tolerance = 0.2;
- ssr_smooth = true;
ssr_roughness = true;
ssao_enabled = false;
@@ -997,6 +1201,27 @@ Environment::Environment() {
dof_blur_near_transition = 1;
dof_blur_near_amount = 0.1;
dof_blur_near_quality = DOF_BLUR_QUALITY_MEDIUM;
+
+ fog_enabled = false;
+ fog_color = Color(0.5, 0.5, 0.5);
+ fog_sun_color = Color(0.8, 0.8, 0.0);
+ fog_sun_amount = 0;
+
+ fog_depth_enabled = true;
+
+ fog_depth_begin = 10;
+ fog_depth_curve = 1;
+
+ fog_transmit_enabled = false;
+ fog_transmit_curve = 1;
+
+ fog_height_enabled = false;
+ fog_height_min = 0;
+ fog_height_max = 100;
+ fog_height_curve = 1;
+
+ set_fog_color(Color(0.5, 0.6, 0.7));
+ set_fog_sun_color(Color(1.0, 0.9, 0.7));
}
Environment::~Environment() {
diff --git a/scene/resources/environment.h b/scene/resources/environment.h
index 9014a9f5c2..7eda8506b5 100644
--- a/scene/resources/environment.h
+++ b/scene/resources/environment.h
@@ -44,7 +44,7 @@ public:
BG_CLEAR_COLOR,
BG_COLOR,
- BG_SKYBOX,
+ BG_SKY,
BG_CANVAS,
BG_KEEP,
BG_MAX
@@ -74,14 +74,14 @@ private:
RID environment;
BGMode bg_mode;
- Ref<SkyBox> bg_skybox;
- float bg_skybox_scale;
+ Ref<Sky> bg_sky;
+ float bg_sky_scale;
Color bg_color;
float bg_energy;
int bg_canvas_max_layer;
Color ambient_color;
float ambient_energy;
- float ambient_skybox_contribution;
+ float ambient_sky_contribution;
ToneMapper tone_mapper;
float tonemap_exposure;
@@ -100,10 +100,9 @@ private:
bool ssr_enabled;
int ssr_max_steps;
- float ssr_accel;
- float ssr_fade;
+ float ssr_fade_in;
+ float ssr_fade_out;
float ssr_depth_tolerance;
- bool ssr_smooth;
bool ssr_roughness;
bool ssao_enabled;
@@ -138,30 +137,47 @@ private:
float dof_blur_near_amount;
DOFBlurQuality dof_blur_near_quality;
+ bool fog_enabled;
+ Color fog_color;
+ Color fog_sun_color;
+ float fog_sun_amount;
+
+ bool fog_depth_enabled;
+ float fog_depth_begin;
+ float fog_depth_curve;
+
+ bool fog_transmit_enabled;
+ float fog_transmit_curve;
+
+ bool fog_height_enabled;
+ float fog_height_min;
+ float fog_height_max;
+ float fog_height_curve;
+
protected:
static void _bind_methods();
virtual void _validate_property(PropertyInfo &property) const;
public:
void set_background(BGMode p_bg);
- void set_skybox(const Ref<SkyBox> &p_skybox);
- void set_skybox_scale(float p_scale);
+ void set_sky(const Ref<Sky> &p_sky);
+ void set_sky_scale(float p_scale);
void set_bg_color(const Color &p_color);
void set_bg_energy(float p_energy);
void set_canvas_max_layer(int p_max_layer);
void set_ambient_light_color(const Color &p_color);
void set_ambient_light_energy(float p_energy);
- void set_ambient_light_skybox_contribution(float p_energy);
+ void set_ambient_light_sky_contribution(float p_energy);
BGMode get_background() const;
- Ref<SkyBox> get_skybox() const;
- float get_skybox_scale() const;
+ Ref<Sky> get_sky() const;
+ float get_sky_scale() const;
Color get_bg_color() const;
float get_bg_energy() const;
int get_canvas_max_layer() const;
Color get_ambient_light_color() const;
float get_ambient_light_energy() const;
- float get_ambient_light_skybox_contribution() const;
+ float get_ambient_light_sky_contribution() const;
void set_tonemapper(ToneMapper p_tone_mapper);
ToneMapper get_tonemapper() const;
@@ -208,18 +224,15 @@ public:
void set_ssr_max_steps(int p_steps);
int get_ssr_max_steps() const;
- void set_ssr_accel(float p_accel);
- float get_ssr_accel() const;
+ void set_ssr_fade_in(float p_transition);
+ float get_ssr_fade_in() const;
- void set_ssr_fade(float p_transition);
- float get_ssr_fade() const;
+ void set_ssr_fade_out(float p_transition);
+ float get_ssr_fade_out() const;
void set_ssr_depth_tolerance(float p_depth_tolerance);
float get_ssr_depth_tolerance() const;
- void set_ssr_smooth(bool p_enable);
- bool is_ssr_smooth() const;
-
void set_ssr_rough(bool p_enable);
bool is_ssr_rough() const;
@@ -307,6 +320,45 @@ public:
void set_dof_blur_near_quality(DOFBlurQuality p_quality);
DOFBlurQuality get_dof_blur_near_quality() const;
+ void set_fog_enabled(bool p_enabled);
+ bool is_fog_enabled() const;
+
+ void set_fog_color(const Color &p_color);
+ Color get_fog_color() const;
+
+ void set_fog_sun_color(const Color &p_color);
+ Color get_fog_sun_color() const;
+
+ void set_fog_sun_amount(float p_amount);
+ float get_fog_sun_amount() const;
+
+ void set_fog_depth_enabled(bool p_enabled);
+ bool is_fog_depth_enabled() const;
+
+ void set_fog_depth_begin(float p_distance);
+ float get_fog_depth_begin() const;
+
+ void set_fog_depth_curve(float p_curve);
+ float get_fog_depth_curve() const;
+
+ void set_fog_transmit_enabled(bool p_enabled);
+ bool is_fog_transmit_enabled() const;
+
+ void set_fog_transmit_curve(float p_curve);
+ float get_fog_transmit_curve() const;
+
+ void set_fog_height_enabled(bool p_enabled);
+ bool is_fog_height_enabled() const;
+
+ void set_fog_height_min(float p_distance);
+ float get_fog_height_min() const;
+
+ void set_fog_height_max(float p_distance);
+ float get_fog_height_max() const;
+
+ void set_fog_height_curve(float p_distance);
+ float get_fog_height_curve() const;
+
virtual RID get_rid() const;
Environment();
diff --git a/scene/resources/font.cpp b/scene/resources/font.cpp
index 692dc47677..225a42f651 100644
--- a/scene/resources/font.cpp
+++ b/scene/resources/font.cpp
@@ -120,8 +120,8 @@ PoolVector<int> BitmapFont::_get_chars() const {
const Character *c = char_map.getptr(*key);
chars.push_back(*key);
chars.push_back(c->texture_idx);
- chars.push_back(c->rect.pos.x);
- chars.push_back(c->rect.pos.y);
+ chars.push_back(c->rect.position.x);
+ chars.push_back(c->rect.position.y);
chars.push_back(c->rect.size.x);
chars.push_back(c->rect.size.y);
@@ -272,9 +272,9 @@ Error BitmapFont::create_from_fnt(const String &p_string) {
Rect2 rect;
if (keys.has("x"))
- rect.pos.x = keys["x"].to_int();
+ rect.position.x = keys["x"].to_int();
if (keys.has("y"))
- rect.pos.y = keys["y"].to_int();
+ rect.position.y = keys["y"].to_int();
if (keys.has("width"))
rect.size.width = keys["width"].to_int();
if (keys.has("height"))
diff --git a/scene/resources/font.h b/scene/resources/font.h
index 20978acccd..a04ffbdd4b 100644
--- a/scene/resources/font.h
+++ b/scene/resources/font.h
@@ -66,7 +66,7 @@ public:
class BitmapFont : public Font {
GDCLASS(BitmapFont, Font);
- RES_BASE_EXTENSION("fnt");
+ RES_BASE_EXTENSION("font");
Vector<Ref<Texture> > textures;
diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp
index 48299d566c..ce88325539 100644
--- a/scene/resources/material.cpp
+++ b/scene/resources/material.cpp
@@ -181,7 +181,7 @@ void SpatialMaterial::init_shaders() {
shader_names->albedo = "albedo";
shader_names->specular = "specular";
shader_names->roughness = "roughness";
- shader_names->metalness = "metalness";
+ shader_names->metallic = "metallic";
shader_names->emission = "emission";
shader_names->emission_energy = "emission_energy";
shader_names->normal_scale = "normal_scale";
@@ -190,10 +190,9 @@ void SpatialMaterial::init_shaders() {
shader_names->clearcoat = "clearcoat";
shader_names->clearcoat_gloss = "clearcoat_gloss";
shader_names->anisotropy = "anisotropy_ratio";
- shader_names->height_scale = "height_scale";
+ shader_names->depth_scale = "depth_scale";
shader_names->subsurface_scattering_strength = "subsurface_scattering_strength";
shader_names->refraction = "refraction";
- shader_names->refraction_roughness = "refraction_roughness";
shader_names->point_size = "point_size";
shader_names->uv1_scale = "uv1_scale";
shader_names->uv1_offset = "uv1_offset";
@@ -203,19 +202,21 @@ void SpatialMaterial::init_shaders() {
shader_names->particle_h_frames = "particle_h_frames";
shader_names->particle_v_frames = "particle_v_frames";
shader_names->particles_anim_loop = "particles_anim_loop";
+ shader_names->depth_min_layers = "depth_min_layers";
+ shader_names->depth_max_layers = "depth_max_layers";
shader_names->texture_names[TEXTURE_ALBEDO] = "texture_albedo";
- shader_names->texture_names[TEXTURE_SPECULAR] = "texture_specular";
+ shader_names->texture_names[TEXTURE_METALLIC] = "texture_metallic";
+ shader_names->texture_names[TEXTURE_ROUGHNESS] = "texture_roughness";
shader_names->texture_names[TEXTURE_EMISSION] = "texture_emission";
shader_names->texture_names[TEXTURE_NORMAL] = "texture_normal";
shader_names->texture_names[TEXTURE_RIM] = "texture_rim";
shader_names->texture_names[TEXTURE_CLEARCOAT] = "texture_clearcoat";
shader_names->texture_names[TEXTURE_FLOWMAP] = "texture_flowmap";
shader_names->texture_names[TEXTURE_AMBIENT_OCCLUSION] = "texture_ambient_occlusion";
- shader_names->texture_names[TEXTURE_HEIGHT] = "texture_height";
+ shader_names->texture_names[TEXTURE_DEPTH] = "texture_depth";
shader_names->texture_names[TEXTURE_SUBSURFACE_SCATTERING] = "texture_subsurface_scattering";
shader_names->texture_names[TEXTURE_REFRACTION] = "texture_refraction";
- shader_names->texture_names[TEXTURE_REFRACTION_ROUGHNESS] = "texture_refraction_roughness";
shader_names->texture_names[TEXTURE_DETAIL_MASK] = "texture_detail_mask";
shader_names->texture_names[TEXTURE_DETAIL_ALBEDO] = "texture_detail_albedo";
shader_names->texture_names[TEXTURE_DETAIL_NORMAL] = "texture_detail_normal";
@@ -266,7 +267,12 @@ void SpatialMaterial::_update_shader() {
case BLEND_MODE_MUL: code += "blend_mul"; break;
}
- switch (depth_draw_mode) {
+ DepthDrawMode ddm = depth_draw_mode;
+ if (features[FEATURE_REFRACTION]) {
+ ddm = DEPTH_DRAW_ALWAYS;
+ }
+
+ switch (ddm) {
case DEPTH_DRAW_OPAQUE_ONLY: code += ",depth_draw_opaque"; break;
case DEPTH_DRAW_ALWAYS: code += ",depth_draw_always"; break;
case DEPTH_DRAW_DISABLED: code += ",depth_draw_never"; break;
@@ -278,6 +284,12 @@ void SpatialMaterial::_update_shader() {
case CULL_FRONT: code += ",cull_front"; break;
case CULL_DISABLED: code += ",cull_disabled"; break;
}
+ switch (diffuse_mode) {
+ case DIFFUSE_LAMBERT: code += ",diffuse_lambert"; break;
+ case DIFFUSE_HALF_LAMBERT: code += ",diffuse_half_lambert"; break;
+ case DIFFUSE_OREN_NAYAR: code += ",diffuse_oren_nayar"; break;
+ case DIFFUSE_BURLEY: code += ",diffuse_burley"; break;
+ }
if (flags[FLAG_UNSHADED]) {
code += ",unshaded";
@@ -290,15 +302,13 @@ void SpatialMaterial::_update_shader() {
code += "uniform vec4 albedo : hint_color;\n";
code += "uniform sampler2D texture_albedo : hint_albedo;\n";
- if (specular_mode == SPECULAR_MODE_SPECULAR) {
- code += "uniform vec4 specular : hint_color;\n";
- } else {
- code += "uniform float metalness;\n";
- }
+ code += "uniform float specular;\n";
+ code += "uniform float metallic;\n";
code += "uniform float roughness : hint_range(0,1);\n";
code += "uniform float point_size : hint_range(0,128);\n";
- code += "uniform sampler2D texture_specular : hint_white;\n";
+ code += "uniform sampler2D texture_metallic : hint_white;\n";
+ code += "uniform sampler2D texture_roughness : hint_white;\n";
code += "uniform vec2 uv1_scale;\n";
code += "uniform vec2 uv1_offset;\n";
code += "uniform vec2 uv2_scale;\n";
@@ -316,6 +326,11 @@ void SpatialMaterial::_update_shader() {
code += "uniform float emission_energy;\n";
}
+ if (features[FEATURE_REFRACTION]) {
+ code += "uniform sampler2D texture_refraction;\n";
+ code += "uniform float refraction : hint_range(-16,16);\n";
+ }
+
if (features[FEATURE_NORMAL_MAPPING]) {
code += "uniform sampler2D texture_normal : hint_normal;\n";
code += "uniform float normal_scale : hint_range(-16,16);\n";
@@ -350,6 +365,13 @@ void SpatialMaterial::_update_shader() {
code += "uniform sampler2D texture_subsurface_scattering : hint_white;\n";
}
+ if (features[FEATURE_DEPTH_MAPPING]) {
+ code += "uniform sampler2D texture_depth : hint_black;\n";
+ code += "uniform float depth_scale;\n";
+ code += "uniform int depth_min_layers;\n";
+ code += "uniform int depth_max_layers;\n";
+ }
+
code += "\n\n";
code += "void vertex() {\n";
@@ -423,10 +445,52 @@ void SpatialMaterial::_update_shader() {
code += "\n\n";
code += "void fragment() {\n";
+ code += "\tvec2 base_uv = UV;\n";
+ if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
+ code += "\tvec2 base_uv2 = UV2;\n";
+ }
+
+ if (features[FEATURE_DEPTH_MAPPING]) {
+ code += "\t{\n";
+ code += "\t\tvec3 view_dir = normalize(normalize(-VERTEX)*mat3(TANGENT,BINORMAL,NORMAL));\n";
+
+ if (deep_parallax) {
+ code += "\t\tfloat num_layers = mix(float(depth_max_layers),float(depth_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));\n";
+ code += "\t\tfloat layer_depth = 1.0 / num_layers;\n";
+ code += "\t\tfloat current_layer_depth = 0.0;\n";
+ code += "\t\tvec2 P = view_dir.xy * depth_scale;\n";
+ code += "\t\tvec2 delta = P / num_layers;\n";
+ code += "\t\tvec2 ofs = base_uv;\n";
+ code += "\t\tfloat depth = texture(texture_depth, ofs).r;\n";
+ code += "\t\tfloat current_depth = 0.0;\n";
+ code += "\t\twhile(current_depth < depth) {\n";
+ code += "\t\t\tofs -= delta;\n";
+ code += "\t\t\tdepth = texture(texture_depth, ofs).r;\n";
+ code += "\t\t\tcurrent_depth += layer_depth;\n";
+ code += "\t\t}\n";
+ code += "\t\tvec2 prev_ofs = ofs + delta;\n";
+ code += "\t\tfloat after_depth = depth - current_depth;\n";
+ code += "\t\tfloat before_depth = texture(texture_depth, prev_ofs).r - current_depth + layer_depth;\n";
+ code += "\t\tfloat weight = after_depth / (after_depth - before_depth);\n";
+ code += "\t\tofs = mix(ofs,prev_ofs,weight);\n";
+
+ } else {
+ code += "\t\tfloat depth = texture(texture_depth, base_uv).r;\n";
+ code += "\t\tvec2 ofs = base_uv - view_dir.xy / view_dir.z * (depth * depth_scale);\n";
+ }
+
+ code += "\t\tbase_uv=ofs;\n";
+ if (features[FEATURE_DETAIL] && detail_uv == DETAIL_UV_2) {
+ code += "\t\tbase_uv2-=ofs;\n";
+ }
+
+ code += "\t}\n";
+ }
+
if (flags[FLAG_USE_POINT_SIZE]) {
code += "\tvec4 albedo_tex = texture(texture_albedo,POINT_COORD);\n";
} else {
- code += "\tvec4 albedo_tex = texture(texture_albedo,UV);\n";
+ code += "\tvec4 albedo_tex = texture(texture_albedo,base_uv);\n";
}
if (flags[FLAG_ALBEDO_FROM_VERTEX_COLOR]) {
@@ -434,52 +498,72 @@ void SpatialMaterial::_update_shader() {
}
code += "\tALBEDO = albedo.rgb * albedo_tex.rgb;\n";
- if (features[FEATURE_TRANSPARENT]) {
- code += "\tALPHA = albedo.a * albedo_tex.a;\n";
+ code += "\tfloat metallic_tex = texture(texture_metallic,base_uv).r;\n";
+ code += "\tMETALLIC = metallic_tex * metallic;\n";
+ code += "\tfloat roughness_tex = texture(texture_roughness,base_uv).r;\n";
+ code += "\tROUGHNESS = roughness_tex * roughness;\n";
+ code += "\tSPECULAR = specular;\n";
+
+ if (features[FEATURE_NORMAL_MAPPING]) {
+ code += "\tNORMALMAP = texture(texture_normal,base_uv).rgb;\n";
+ code += "\tNORMALMAP_DEPTH = normal_scale;\n";
}
if (features[FEATURE_EMISSION]) {
- code += "\tEMISSION = (emission.rgb+texture(texture_emission,UV).rgb)*emission_energy;\n";
+ code += "\tEMISSION = (emission.rgb+texture(texture_emission,base_uv).rgb)*emission_energy;\n";
}
- if (features[FEATURE_NORMAL_MAPPING]) {
- code += "\tNORMALMAP = texture(texture_normal,UV).rgb;\n";
- code += "\tNORMALMAP_DEPTH = normal_scale;\n";
+ if (features[FEATURE_REFRACTION]) {
+
+ if (features[FEATURE_NORMAL_MAPPING]) {
+ code += "\tvec3 ref_normal = normalize( mix(NORMAL,TANGENT * NORMALMAP.x + BINORMAL * NORMALMAP.y + NORMAL * NORMALMAP.z,NORMALMAP_DEPTH) ) * SIDE;\n";
+ } else {
+ code += "\tvec3 ref_normal = NORMAL;\n";
+ }
+
+ code += "\tvec2 ref_ofs = SCREEN_UV - ref_normal.xy * texture(texture_refraction,base_uv).r * refraction;\n";
+ code += "\tfloat ref_amount = 1.0 - albedo.a * albedo_tex.a;\n";
+ code += "\tEMISSION += textureLod(SCREEN_TEXTURE,ref_ofs,ROUGHNESS * 8.0).rgb * ref_amount;\n";
+ code += "\tALBEDO *= 1.0 - ref_amount;\n";
+ code += "\tALPHA = 1.0;\n";
+
+ } else if (features[FEATURE_TRANSPARENT]) {
+ code += "\tALPHA = albedo.a * albedo_tex.a;\n";
}
if (features[FEATURE_RIM]) {
- code += "\tvec2 rim_tex = texture(texture_rim,UV).xw;\n";
+ code += "\tvec2 rim_tex = texture(texture_rim,base_uv).xw;\n";
code += "\tRIM = rim*rim_tex.x;";
code += "\tRIM_TINT = rim_tint*rim_tex.y;\n";
}
if (features[FEATURE_CLEARCOAT]) {
- code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,UV).xw;\n";
+ code += "\tvec2 clearcoat_tex = texture(texture_clearcoat,base_uv).xw;\n";
code += "\tCLEARCOAT = clearcoat*clearcoat_tex.x;";
code += "\tCLEARCOAT_GLOSS = clearcoat_gloss*clearcoat_tex.y;\n";
}
if (features[FEATURE_ANISOTROPY]) {
- code += "\tvec4 anisotropy_tex = texture(texture_flowmap,UV);\n";
+ code += "\tvec4 anisotropy_tex = texture(texture_flowmap,base_uv);\n";
code += "\tANISOTROPY = anisotropy_ratio*anisotropy_tex.a;\n";
code += "\tANISOTROPY_FLOW = anisotropy_tex.rg*2.0-1.0;\n";
}
if (features[FEATURE_AMBIENT_OCCLUSION]) {
- code += "\tAO = texture(texture_ambient_occlusion,UV).r;\n";
+ code += "\tAO = texture(texture_ambient_occlusion,base_uv).r;\n";
}
if (features[FEATURE_SUBSURACE_SCATTERING]) {
- code += "\tfloat sss_tex = texture(texture_subsurface_scattering,UV).r;\n";
+ code += "\tfloat sss_tex = texture(texture_subsurface_scattering,base_uv).r;\n";
code += "\tSSS_STRENGTH=subsurface_scattering_strength*sss_tex;\n";
}
if (features[FEATURE_DETAIL]) {
- String det_uv = detail_uv == DETAIL_UV_1 ? "UV" : "UV2";
+ String det_uv = detail_uv == DETAIL_UV_1 ? "base_uv" : "base_uv2";
code += "\tvec4 detail_tex = texture(texture_detail_albedo," + det_uv + ");\n";
code += "\tvec4 detail_norm_tex = texture(texture_detail_normal," + det_uv + ");\n";
- code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,UV);\n";
+ code += "\tvec4 detail_mask_tex = texture(texture_detail_mask,base_uv);\n";
switch (detail_blend_mode) {
case BLEND_MODE_MIX: {
@@ -502,17 +586,6 @@ void SpatialMaterial::_update_shader() {
code += "\tALBEDO.rgb = mix(ALBEDO.rgb,detail,detail_mask_tex.r);\n";
}
- if (specular_mode == SPECULAR_MODE_SPECULAR) {
-
- code += "\tvec4 specular_tex = texture(texture_specular,UV);\n";
- code += "\tSPECULAR = specular.rgb * specular_tex.rgb;\n";
- code += "\tROUGHNESS = specular_tex.a * roughness;\n";
- } else {
- code += "\tvec4 specular_tex = texture(texture_specular,UV);\n";
- code += "\tSPECULAR = vec3(ALBEDO.rgb * metalness * specular_tex.r);\n";
- code += "\tROUGHNESS = specular_tex.a * roughness;\n";
- }
-
code += "}\n";
ShaderData shader_data;
@@ -579,23 +652,13 @@ Color SpatialMaterial::get_albedo() const {
return albedo;
}
-void SpatialMaterial::set_specular_mode(SpecularMode p_mode) {
- specular_mode = p_mode;
- _change_notify();
- _queue_shader_change();
-}
-
-SpatialMaterial::SpecularMode SpatialMaterial::get_specular_mode() const {
-
- return specular_mode;
-}
-
-void SpatialMaterial::set_specular(const Color &p_specular) {
+void SpatialMaterial::set_specular(float p_specular) {
specular = p_specular;
VS::get_singleton()->material_set_param(_get_material(), shader_names->specular, p_specular);
}
-Color SpatialMaterial::get_specular() const {
+
+float SpatialMaterial::get_specular() const {
return specular;
}
@@ -611,15 +674,15 @@ float SpatialMaterial::get_roughness() const {
return roughness;
}
-void SpatialMaterial::set_metalness(float p_metalness) {
+void SpatialMaterial::set_metallic(float p_metallic) {
- metalness = p_metalness;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->metalness, p_metalness);
+ metallic = p_metallic;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->metallic, p_metallic);
}
-float SpatialMaterial::get_metalness() const {
+float SpatialMaterial::get_metallic() const {
- return metalness;
+ return metallic;
}
void SpatialMaterial::set_emission(const Color &p_emission) {
@@ -704,15 +767,15 @@ float SpatialMaterial::get_anisotropy() const {
return anisotropy;
}
-void SpatialMaterial::set_height_scale(float p_height_scale) {
+void SpatialMaterial::set_depth_scale(float p_depth_scale) {
- height_scale = p_height_scale;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->height_scale, p_height_scale);
+ depth_scale = p_depth_scale;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_scale, p_depth_scale);
}
-float SpatialMaterial::get_height_scale() const {
+float SpatialMaterial::get_depth_scale() const {
- return height_scale;
+ return depth_scale;
}
void SpatialMaterial::set_subsurface_scattering_strength(float p_subsurface_scattering_strength) {
@@ -737,16 +800,6 @@ float SpatialMaterial::get_refraction() const {
return refraction;
}
-void SpatialMaterial::set_refraction_roughness(float p_refraction_roughness) {
-
- refraction_roughness = p_refraction_roughness;
- VS::get_singleton()->material_set_param(_get_material(), shader_names->refraction_roughness, refraction_roughness);
-}
-float SpatialMaterial::get_refraction_roughness() const {
-
- return refraction_roughness;
-}
-
void SpatialMaterial::set_detail_uv(DetailUV p_detail_uv) {
if (detail_uv == p_detail_uv)
@@ -874,6 +927,9 @@ void SpatialMaterial::_validate_feature(const String &text, Feature feature, Pro
if (property.name.begins_with(text) && property.name != text + "_enabled" && !features[feature]) {
property.usage = 0;
}
+ if ((property.name == "depth_min_layers" || property.name == "depth_max_layers") && !deep_parallax) {
+ property.usage = 0;
+ }
}
void SpatialMaterial::_validate_property(PropertyInfo &property) const {
@@ -883,18 +939,11 @@ void SpatialMaterial::_validate_property(PropertyInfo &property) const {
_validate_feature("clearcoat", FEATURE_CLEARCOAT, property);
_validate_feature("anisotropy", FEATURE_ANISOTROPY, property);
_validate_feature("ao", FEATURE_AMBIENT_OCCLUSION, property);
- _validate_feature("height", FEATURE_HEIGHT_MAPPING, property);
+ _validate_feature("depth", FEATURE_DEPTH_MAPPING, property);
_validate_feature("subsurf_scatter", FEATURE_SUBSURACE_SCATTERING, property);
_validate_feature("refraction", FEATURE_REFRACTION, property);
_validate_feature("detail", FEATURE_DETAIL, property);
- if (property.name == "specular/color" && specular_mode == SPECULAR_MODE_METALLIC) {
- property.usage = 0;
- }
- if (property.name == "specular/metalness" && specular_mode == SPECULAR_MODE_SPECULAR) {
- property.usage = 0;
- }
-
if (property.name.begins_with("particles_anim_") && billboard_mode != BILLBOARD_PARTICLES) {
property.usage = 0;
}
@@ -1009,19 +1058,49 @@ int SpatialMaterial::get_particles_anim_loop() const {
return particles_anim_loop;
}
+void SpatialMaterial::set_depth_deep_parallax(bool p_enable) {
+
+ deep_parallax = p_enable;
+ _queue_shader_change();
+ _change_notify();
+ ;
+}
+
+bool SpatialMaterial::is_depth_deep_parallax_enabled() const {
+
+ return deep_parallax;
+}
+
+void SpatialMaterial::set_depth_deep_parallax_min_layers(int p_layer) {
+
+ deep_parallax_min_layers = p_layer;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_min_layers, p_layer);
+}
+int SpatialMaterial::get_depth_deep_parallax_min_layers() const {
+
+ return deep_parallax_min_layers;
+}
+
+void SpatialMaterial::set_depth_deep_parallax_max_layers(int p_layer) {
+
+ deep_parallax_max_layers = p_layer;
+ VS::get_singleton()->material_set_param(_get_material(), shader_names->depth_max_layers, p_layer);
+}
+int SpatialMaterial::get_depth_deep_parallax_max_layers() const {
+
+ return deep_parallax_max_layers;
+}
+
void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_albedo", "albedo"), &SpatialMaterial::set_albedo);
ClassDB::bind_method(D_METHOD("get_albedo"), &SpatialMaterial::get_albedo);
- ClassDB::bind_method(D_METHOD("set_specular_mode", "specular_mode"), &SpatialMaterial::set_specular_mode);
- ClassDB::bind_method(D_METHOD("get_specular_mode"), &SpatialMaterial::get_specular_mode);
-
ClassDB::bind_method(D_METHOD("set_specular", "specular"), &SpatialMaterial::set_specular);
ClassDB::bind_method(D_METHOD("get_specular"), &SpatialMaterial::get_specular);
- ClassDB::bind_method(D_METHOD("set_metalness", "metalness"), &SpatialMaterial::set_metalness);
- ClassDB::bind_method(D_METHOD("get_metalness"), &SpatialMaterial::get_metalness);
+ ClassDB::bind_method(D_METHOD("set_metallic", "metallic"), &SpatialMaterial::set_metallic);
+ ClassDB::bind_method(D_METHOD("get_metallic"), &SpatialMaterial::get_metallic);
ClassDB::bind_method(D_METHOD("set_roughness", "roughness"), &SpatialMaterial::set_roughness);
ClassDB::bind_method(D_METHOD("get_roughness"), &SpatialMaterial::get_roughness);
@@ -1050,8 +1129,8 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_anisotropy", "anisotropy"), &SpatialMaterial::set_anisotropy);
ClassDB::bind_method(D_METHOD("get_anisotropy"), &SpatialMaterial::get_anisotropy);
- ClassDB::bind_method(D_METHOD("set_height_scale", "height_scale"), &SpatialMaterial::set_height_scale);
- ClassDB::bind_method(D_METHOD("get_height_scale"), &SpatialMaterial::get_height_scale);
+ ClassDB::bind_method(D_METHOD("set_depth_scale", "depth_scale"), &SpatialMaterial::set_depth_scale);
+ ClassDB::bind_method(D_METHOD("get_depth_scale"), &SpatialMaterial::get_depth_scale);
ClassDB::bind_method(D_METHOD("set_subsurface_scattering_strength", "strength"), &SpatialMaterial::set_subsurface_scattering_strength);
ClassDB::bind_method(D_METHOD("get_subsurface_scattering_strength"), &SpatialMaterial::get_subsurface_scattering_strength);
@@ -1059,9 +1138,6 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_refraction", "refraction"), &SpatialMaterial::set_refraction);
ClassDB::bind_method(D_METHOD("get_refraction"), &SpatialMaterial::get_refraction);
- ClassDB::bind_method(D_METHOD("set_refraction_roughness", "refraction_roughness"), &SpatialMaterial::set_refraction_roughness);
- ClassDB::bind_method(D_METHOD("get_refraction_roughness"), &SpatialMaterial::get_refraction_roughness);
-
ClassDB::bind_method(D_METHOD("set_line_width", "line_width"), &SpatialMaterial::set_line_width);
ClassDB::bind_method(D_METHOD("get_line_width"), &SpatialMaterial::get_line_width);
@@ -1119,6 +1195,15 @@ void SpatialMaterial::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_particles_anim_loop", "frames"), &SpatialMaterial::set_particles_anim_loop);
ClassDB::bind_method(D_METHOD("get_particles_anim_loop"), &SpatialMaterial::get_particles_anim_loop);
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax", "enable"), &SpatialMaterial::set_depth_deep_parallax);
+ ClassDB::bind_method(D_METHOD("is_depth_deep_parallax_enabled"), &SpatialMaterial::is_depth_deep_parallax_enabled);
+
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_min_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_min_layers);
+ ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_min_layers"), &SpatialMaterial::get_depth_deep_parallax_min_layers);
+
+ ClassDB::bind_method(D_METHOD("set_depth_deep_parallax_max_layers", "layer"), &SpatialMaterial::set_depth_deep_parallax_max_layers);
+ ClassDB::bind_method(D_METHOD("get_depth_deep_parallax_max_layers"), &SpatialMaterial::get_depth_deep_parallax_max_layers);
+
ADD_GROUP("Flags", "flags_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_transparent"), "set_feature", "get_feature", FEATURE_TRANSPARENT);
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "flags_unshaded"), "set_flag", "get_flag", FLAG_UNSHADED);
@@ -1146,12 +1231,14 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "albedo_color"), "set_albedo", "get_albedo");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "albedo_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ALBEDO);
- ADD_GROUP("Specular", "specular_");
- ADD_PROPERTY(PropertyInfo(Variant::INT, "specular_mode", PROPERTY_HINT_ENUM, "Metallic,Specular"), "set_specular_mode", "get_specular_mode");
- ADD_PROPERTY(PropertyInfo(Variant::COLOR, "specular_color", PROPERTY_HINT_COLOR_NO_ALPHA), "set_specular", "get_specular");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "specular_metalness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metalness", "get_metalness");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "specular_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "specular_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_SPECULAR);
+ ADD_GROUP("Metallic", "metallic_");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_metallic", "get_metallic");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "metallic_specular", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_specular", "get_specular");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "metallic_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_METALLIC);
+
+ ADD_GROUP("Roughness", "roughness_");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "roughness_amount", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_roughness", "get_roughness");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "roughness_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_ROUGHNESS);
ADD_GROUP("Emission", "emission_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "emission_enabled"), "set_feature", "get_feature", FEATURE_EMISSION);
@@ -1185,10 +1272,13 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "ao_enabled"), "set_feature", "get_feature", FEATURE_AMBIENT_OCCLUSION);
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "ao_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_AMBIENT_OCCLUSION);
- ADD_GROUP("Height", "height_");
- ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "height_enabled"), "set_feature", "get_feature", FEATURE_HEIGHT_MAPPING);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "height_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_height_scale", "get_height_scale");
- ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "height_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_HEIGHT);
+ ADD_GROUP("Depth", "depth_");
+ ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "depth_enabled"), "set_feature", "get_feature", FEATURE_DEPTH_MAPPING);
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "depth_scale", PROPERTY_HINT_RANGE, "-16,16,0.01"), "set_depth_scale", "get_depth_scale");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "depth_deep_parallax"), "set_depth_deep_parallax", "is_depth_deep_parallax_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_min_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_min_layers", "get_depth_deep_parallax_min_layers");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "depth_max_layers", PROPERTY_HINT_RANGE, "1,32,1"), "set_depth_deep_parallax_max_layers", "get_depth_deep_parallax_max_layers");
+ ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "depth_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_DEPTH);
ADD_GROUP("Subsurf Scatter", "subsurf_scatter_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "subsurf_scatter_enabled"), "set_feature", "get_feature", FEATURE_SUBSURACE_SCATTERING);
@@ -1197,8 +1287,7 @@ void SpatialMaterial::_bind_methods() {
ADD_GROUP("Refraction", "refraction_");
ADD_PROPERTYI(PropertyInfo(Variant::BOOL, "refraction_enabled"), "set_feature", "get_feature", FEATURE_REFRACTION);
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_displacement", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
- ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_roughness", PROPERTY_HINT_RANGE, "0,1,0.01"), "set_refraction_roughness", "get_refraction_roughness");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "refraction_scale", PROPERTY_HINT_RANGE, "-1,1,0.01"), "set_refraction", "get_refraction");
ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "refraction_texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture", TEXTURE_REFRACTION);
ADD_GROUP("Detail", "detail_");
@@ -1218,17 +1307,17 @@ void SpatialMaterial::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "uv2_offset"), "set_uv2_offset", "get_uv2_offset");
BIND_CONSTANT(TEXTURE_ALBEDO);
- BIND_CONSTANT(TEXTURE_SPECULAR);
+ BIND_CONSTANT(TEXTURE_METALLIC);
+ BIND_CONSTANT(TEXTURE_ROUGHNESS);
BIND_CONSTANT(TEXTURE_EMISSION);
BIND_CONSTANT(TEXTURE_NORMAL);
BIND_CONSTANT(TEXTURE_RIM);
BIND_CONSTANT(TEXTURE_CLEARCOAT);
BIND_CONSTANT(TEXTURE_FLOWMAP);
BIND_CONSTANT(TEXTURE_AMBIENT_OCCLUSION);
- BIND_CONSTANT(TEXTURE_HEIGHT);
+ BIND_CONSTANT(TEXTURE_DEPTH);
BIND_CONSTANT(TEXTURE_SUBSURFACE_SCATTERING);
BIND_CONSTANT(TEXTURE_REFRACTION);
- BIND_CONSTANT(TEXTURE_REFRACTION_ROUGHNESS);
BIND_CONSTANT(TEXTURE_DETAIL_MASK);
BIND_CONSTANT(TEXTURE_DETAIL_ALBEDO);
BIND_CONSTANT(TEXTURE_DETAIL_NORMAL);
@@ -1244,7 +1333,7 @@ void SpatialMaterial::_bind_methods() {
BIND_CONSTANT(FEATURE_CLEARCOAT);
BIND_CONSTANT(FEATURE_ANISOTROPY);
BIND_CONSTANT(FEATURE_AMBIENT_OCCLUSION);
- BIND_CONSTANT(FEATURE_HEIGHT_MAPPING);
+ BIND_CONSTANT(FEATURE_DEPTH_MAPPING);
BIND_CONSTANT(FEATURE_SUBSURACE_SCATTERING);
BIND_CONSTANT(FEATURE_REFRACTION);
BIND_CONSTANT(FEATURE_DETAIL);
@@ -1273,13 +1362,10 @@ void SpatialMaterial::_bind_methods() {
BIND_CONSTANT(FLAG_MAX);
BIND_CONSTANT(DIFFUSE_LAMBERT);
- BIND_CONSTANT(DIFFUSE_LAMBERT_WRAP);
+ BIND_CONSTANT(DIFFUSE_HALF_LAMBERT);
BIND_CONSTANT(DIFFUSE_OREN_NAYAR);
BIND_CONSTANT(DIFFUSE_BURLEY);
- BIND_CONSTANT(SPECULAR_MODE_METALLIC);
- BIND_CONSTANT(SPECULAR_MODE_SPECULAR);
-
BIND_CONSTANT(BILLBOARD_DISABLED);
BIND_CONSTANT(BILLBOARD_ENABLED);
BIND_CONSTANT(BILLBOARD_FIXED_Y);
@@ -1290,11 +1376,10 @@ SpatialMaterial::SpatialMaterial()
: element(this) {
//initialize to right values
- specular_mode = SPECULAR_MODE_METALLIC;
set_albedo(Color(0.7, 0.7, 0.7, 1.0));
- set_specular(Color(0.1, 0.1, 0.1));
+ set_specular(0.5);
set_roughness(0.0);
- set_metalness(0.1);
+ set_metallic(0.1);
set_emission(Color(0, 0, 0));
set_emission_energy(1.0);
set_normal_scale(1);
@@ -1303,10 +1388,9 @@ SpatialMaterial::SpatialMaterial()
set_clearcoat(1);
set_clearcoat_gloss(0.5);
set_anisotropy(0);
- set_height_scale(1);
+ set_depth_scale(0.05);
set_subsurface_scattering_strength(0);
- set_refraction(0);
- set_refraction_roughness(0);
+ set_refraction(0.05);
set_line_width(1);
set_point_size(1);
set_uv1_offset(Vector2(0, 0));
@@ -1318,6 +1402,10 @@ SpatialMaterial::SpatialMaterial()
set_particles_anim_v_frames(1);
set_particles_anim_loop(false);
+ deep_parallax = false;
+ set_depth_deep_parallax_min_layers(8);
+ set_depth_deep_parallax_max_layers(32);
+
detail_uv = DETAIL_UV_1;
blend_mode = BLEND_MODE_MIX;
detail_blend_mode = BLEND_MODE_MIX;
diff --git a/scene/resources/material.h b/scene/resources/material.h
index 408815d756..c043236489 100644
--- a/scene/resources/material.h
+++ b/scene/resources/material.h
@@ -43,7 +43,7 @@
class Material : public Resource {
GDCLASS(Material, Resource);
- RES_BASE_EXTENSION("mtl");
+ RES_BASE_EXTENSION("material");
OBJ_SAVE_TYPE(Material);
RID material;
@@ -89,17 +89,17 @@ class SpatialMaterial : public Material {
public:
enum TextureParam {
TEXTURE_ALBEDO,
- TEXTURE_SPECULAR,
+ TEXTURE_METALLIC,
+ TEXTURE_ROUGHNESS,
TEXTURE_EMISSION,
TEXTURE_NORMAL,
TEXTURE_RIM,
TEXTURE_CLEARCOAT,
TEXTURE_FLOWMAP,
TEXTURE_AMBIENT_OCCLUSION,
- TEXTURE_HEIGHT,
+ TEXTURE_DEPTH,
TEXTURE_SUBSURFACE_SCATTERING,
TEXTURE_REFRACTION,
- TEXTURE_REFRACTION_ROUGHNESS,
TEXTURE_DETAIL_MASK,
TEXTURE_DETAIL_ALBEDO,
TEXTURE_DETAIL_NORMAL,
@@ -120,7 +120,7 @@ public:
FEATURE_CLEARCOAT,
FEATURE_ANISOTROPY,
FEATURE_AMBIENT_OCCLUSION,
- FEATURE_HEIGHT_MAPPING,
+ FEATURE_DEPTH_MAPPING,
FEATURE_SUBSURACE_SCATTERING,
FEATURE_REFRACTION,
FEATURE_DETAIL,
@@ -160,16 +160,11 @@ public:
enum DiffuseMode {
DIFFUSE_LAMBERT,
- DIFFUSE_LAMBERT_WRAP,
+ DIFFUSE_HALF_LAMBERT,
DIFFUSE_OREN_NAYAR,
DIFFUSE_BURLEY,
};
- enum SpecularMode {
- SPECULAR_MODE_METALLIC,
- SPECULAR_MODE_SPECULAR,
- };
-
enum BillboardMode {
BILLBOARD_DISABLED,
BILLBOARD_ENABLED,
@@ -190,7 +185,7 @@ private:
uint32_t detail_blend_mode : 2;
uint32_t diffuse_mode : 2;
uint32_t invalid_key : 1;
- uint32_t specular_mode : 1;
+ uint32_t deep_parallax : 1;
uint32_t billboard_mode : 2;
};
@@ -230,8 +225,9 @@ private:
}
mk.detail_blend_mode = detail_blend_mode;
mk.diffuse_mode = diffuse_mode;
- mk.specular_mode = specular_mode;
mk.billboard_mode = billboard_mode;
+ mk.deep_parallax = deep_parallax ? 1 : 0;
+ ;
return mk;
}
@@ -239,7 +235,7 @@ private:
struct ShaderNames {
StringName albedo;
StringName specular;
- StringName metalness;
+ StringName metallic;
StringName roughness;
StringName emission;
StringName emission_energy;
@@ -249,10 +245,9 @@ private:
StringName clearcoat;
StringName clearcoat_gloss;
StringName anisotropy;
- StringName height_scale;
+ StringName depth_scale;
StringName subsurface_scattering_strength;
StringName refraction;
- StringName refraction_roughness;
StringName point_size;
StringName uv1_scale;
StringName uv1_offset;
@@ -261,6 +256,9 @@ private:
StringName particle_h_frames;
StringName particle_v_frames;
StringName particles_anim_loop;
+ StringName depth_min_layers;
+ StringName depth_max_layers;
+
StringName texture_names[TEXTURE_MAX];
};
@@ -275,8 +273,8 @@ private:
_FORCE_INLINE_ bool _is_shader_dirty() const;
Color albedo;
- Color specular;
- float metalness;
+ float specular;
+ float metallic;
float roughness;
Color emission;
float emission_energy;
@@ -286,10 +284,9 @@ private:
float clearcoat;
float clearcoat_gloss;
float anisotropy;
- float height_scale;
+ float depth_scale;
float subsurface_scattering_strength;
float refraction;
- float refraction_roughness;
float line_width;
float point_size;
int particles_anim_h_frames;
@@ -304,13 +301,16 @@ private:
DetailUV detail_uv;
+ bool deep_parallax;
+ int deep_parallax_min_layers;
+ int deep_parallax_max_layers;
+
BlendMode blend_mode;
BlendMode detail_blend_mode;
DepthDrawMode depth_draw_mode;
CullMode cull_mode;
bool flags[FLAG_MAX];
DiffuseMode diffuse_mode;
- SpecularMode specular_mode;
BillboardMode billboard_mode;
bool features[FEATURE_MAX];
@@ -327,14 +327,11 @@ public:
void set_albedo(const Color &p_albedo);
Color get_albedo() const;
- void set_specular_mode(SpecularMode p_mode);
- SpecularMode get_specular_mode() const;
-
- void set_specular(const Color &p_specular);
- Color get_specular() const;
+ void set_specular(float p_specular);
+ float get_specular() const;
- void set_metalness(float p_metalness);
- float get_metalness() const;
+ void set_metallic(float p_metallic);
+ float get_metallic() const;
void set_roughness(float p_roughness);
float get_roughness() const;
@@ -363,8 +360,17 @@ public:
void set_anisotropy(float p_anisotropy);
float get_anisotropy() const;
- void set_height_scale(float p_height_scale);
- float get_height_scale() const;
+ void set_depth_scale(float p_depth_scale);
+ float get_depth_scale() const;
+
+ void set_depth_deep_parallax(bool p_enable);
+ bool is_depth_deep_parallax_enabled() const;
+
+ void set_depth_deep_parallax_min_layers(int p_layer);
+ int get_depth_deep_parallax_min_layers() const;
+
+ void set_depth_deep_parallax_max_layers(int p_layer);
+ int get_depth_deep_parallax_max_layers() const;
void set_subsurface_scattering_strength(float p_strength);
float get_subsurface_scattering_strength() const;
@@ -372,9 +378,6 @@ public:
void set_refraction(float p_refraction);
float get_refraction() const;
- void set_refraction_roughness(float p_refraction_roughness);
- float get_refraction_roughness() const;
-
void set_line_width(float p_line_width);
float get_line_width() const;
@@ -447,7 +450,6 @@ VARIANT_ENUM_CAST(SpatialMaterial::DepthDrawMode)
VARIANT_ENUM_CAST(SpatialMaterial::CullMode)
VARIANT_ENUM_CAST(SpatialMaterial::Flags)
VARIANT_ENUM_CAST(SpatialMaterial::DiffuseMode)
-VARIANT_ENUM_CAST(SpatialMaterial::SpecularMode)
VARIANT_ENUM_CAST(SpatialMaterial::BillboardMode)
//////////////////////
diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp
index ab3e143e60..a3180ee1df 100644
--- a/scene/resources/mesh.cpp
+++ b/scene/resources/mesh.cpp
@@ -32,6 +32,390 @@
#include "scene/resources/convex_polygon_shape.h"
#include "surface_tool.h"
+void Mesh::_clear_triangle_mesh() {
+
+ triangle_mesh.unref();
+ ;
+}
+
+Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
+
+ if (triangle_mesh.is_valid())
+ return triangle_mesh;
+
+ int facecount = 0;
+
+ for (int i = 0; i < get_surface_count(); i++) {
+
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ continue;
+
+ if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
+
+ facecount += surface_get_array_index_len(i);
+ } else {
+
+ facecount += surface_get_array_len(i);
+ }
+ }
+
+ if (facecount == 0 || (facecount % 3) != 0)
+ return triangle_mesh;
+
+ PoolVector<Vector3> faces;
+ faces.resize(facecount);
+ PoolVector<Vector3>::Write facesw = faces.write();
+
+ int widx = 0;
+
+ for (int i = 0; i < get_surface_count(); i++) {
+
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ continue;
+
+ Array a = surface_get_arrays(i);
+
+ int vc = surface_get_array_len(i);
+ PoolVector<Vector3> vertices = a[ARRAY_VERTEX];
+ PoolVector<Vector3>::Read vr = vertices.read();
+
+ if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
+
+ int ic = surface_get_array_index_len(i);
+ PoolVector<int> indices = a[ARRAY_INDEX];
+ PoolVector<int>::Read ir = indices.read();
+
+ for (int i = 0; i < ic; i++) {
+ int index = ir[i];
+ facesw[widx++] = vr[index];
+ }
+
+ } else {
+
+ for (int i = 0; i < vc; i++)
+ facesw[widx++] = vr[i];
+ }
+ }
+
+ facesw = PoolVector<Vector3>::Write();
+
+ triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
+ triangle_mesh->create(faces);
+
+ return triangle_mesh;
+}
+
+PoolVector<Face3> Mesh::get_faces() const {
+
+ Ref<TriangleMesh> tm = generate_triangle_mesh();
+ if (tm.is_valid())
+ return tm->get_faces();
+ return PoolVector<Face3>();
+ /*
+ for (int i=0;i<surfaces.size();i++) {
+
+ if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES )
+ continue;
+
+ PoolVector<int> indices;
+ PoolVector<Vector3> vertices;
+
+ vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX);
+
+ int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
+ bool has_indices;
+
+ if (len>0) {
+
+ indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX);
+ has_indices=true;
+
+ } else {
+
+ len=vertices.size();
+ has_indices=false;
+ }
+
+ if (len<=0)
+ continue;
+
+ PoolVector<int>::Read indicesr = indices.read();
+ const int *indicesptr = indicesr.ptr();
+
+ PoolVector<Vector3>::Read verticesr = vertices.read();
+ const Vector3 *verticesptr = verticesr.ptr();
+
+ int old_faces=faces.size();
+ int new_faces=old_faces+(len/3);
+
+ faces.resize(new_faces);
+
+ PoolVector<Face3>::Write facesw = faces.write();
+ Face3 *facesptr=facesw.ptr();
+
+
+ for (int i=0;i<len/3;i++) {
+
+ Face3 face;
+
+ for (int j=0;j<3;j++) {
+
+ int idx=i*3+j;
+ face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx];
+ }
+
+ facesptr[i+old_faces]=face;
+ }
+
+ }
+*/
+}
+
+Ref<Shape> Mesh::create_convex_shape() const {
+
+ PoolVector<Vector3> vertices;
+
+ for (int i = 0; i < get_surface_count(); i++) {
+
+ Array a = surface_get_arrays(i);
+ PoolVector<Vector3> v = a[ARRAY_VERTEX];
+ vertices.append_array(v);
+ }
+
+ Ref<ConvexPolygonShape> shape = memnew(ConvexPolygonShape);
+ shape->set_points(vertices);
+ return shape;
+}
+
+Ref<Shape> Mesh::create_trimesh_shape() const {
+
+ PoolVector<Face3> faces = get_faces();
+ if (faces.size() == 0)
+ return Ref<Shape>();
+
+ PoolVector<Vector3> face_points;
+ face_points.resize(faces.size() * 3);
+
+ for (int i = 0; i < face_points.size(); i++) {
+
+ Face3 f = faces.get(i / 3);
+ face_points.set(i, f.vertex[i % 3]);
+ }
+
+ Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape);
+ shape->set_faces(face_points);
+ return shape;
+}
+
+Ref<Mesh> Mesh::create_outline(float p_margin) const {
+
+ Array arrays;
+ int index_accum = 0;
+ for (int i = 0; i < get_surface_count(); i++) {
+
+ if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
+ continue;
+
+ Array a = surface_get_arrays(i);
+ int vcount = 0;
+
+ if (i == 0) {
+ arrays = a;
+ PoolVector<Vector3> v = a[ARRAY_VERTEX];
+ index_accum += v.size();
+ } else {
+
+ for (int j = 0; j < arrays.size(); j++) {
+
+ if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) {
+ //mismatch, do not use
+ arrays[j] = Variant();
+ continue;
+ }
+
+ switch (j) {
+
+ case ARRAY_VERTEX:
+ case ARRAY_NORMAL: {
+
+ PoolVector<Vector3> dst = arrays[j];
+ PoolVector<Vector3> src = a[j];
+ if (j == ARRAY_VERTEX)
+ vcount = src.size();
+ if (dst.size() == 0 || src.size() == 0) {
+ arrays[j] = Variant();
+ continue;
+ }
+ dst.append_array(src);
+ arrays[j] = dst;
+ } break;
+ case ARRAY_TANGENT:
+ case ARRAY_BONES:
+ case ARRAY_WEIGHTS: {
+
+ PoolVector<real_t> dst = arrays[j];
+ PoolVector<real_t> src = a[j];
+ if (dst.size() == 0 || src.size() == 0) {
+ arrays[j] = Variant();
+ continue;
+ }
+ dst.append_array(src);
+ arrays[j] = dst;
+
+ } break;
+ case ARRAY_COLOR: {
+ PoolVector<Color> dst = arrays[j];
+ PoolVector<Color> src = a[j];
+ if (dst.size() == 0 || src.size() == 0) {
+ arrays[j] = Variant();
+ continue;
+ }
+ dst.append_array(src);
+ arrays[j] = dst;
+
+ } break;
+ case ARRAY_TEX_UV:
+ case ARRAY_TEX_UV2: {
+ PoolVector<Vector2> dst = arrays[j];
+ PoolVector<Vector2> src = a[j];
+ if (dst.size() == 0 || src.size() == 0) {
+ arrays[j] = Variant();
+ continue;
+ }
+ dst.append_array(src);
+ arrays[j] = dst;
+
+ } break;
+ case ARRAY_INDEX: {
+ PoolVector<int> dst = arrays[j];
+ PoolVector<int> src = a[j];
+ if (dst.size() == 0 || src.size() == 0) {
+ arrays[j] = Variant();
+ continue;
+ }
+ {
+ int ss = src.size();
+ PoolVector<int>::Write w = src.write();
+ for (int k = 0; k < ss; k++) {
+ w[k] += index_accum;
+ }
+ }
+ dst.append_array(src);
+ arrays[j] = dst;
+ index_accum += vcount;
+
+ } break;
+ }
+ }
+ }
+ }
+
+ {
+ PoolVector<int>::Write ir;
+ PoolVector<int> indices = arrays[ARRAY_INDEX];
+ bool has_indices = false;
+ PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX];
+ int vc = vertices.size();
+ ERR_FAIL_COND_V(!vc, Ref<ArrayMesh>());
+ PoolVector<Vector3>::Write r = vertices.write();
+
+ if (indices.size()) {
+ vc = indices.size();
+ ir = indices.write();
+ has_indices = true;
+ }
+
+ Map<Vector3, Vector3> normal_accum;
+
+ //fill normals with triangle normals
+ for (int i = 0; i < vc; i += 3) {
+
+ Vector3 t[3];
+
+ if (has_indices) {
+ t[0] = r[ir[i + 0]];
+ t[1] = r[ir[i + 1]];
+ t[2] = r[ir[i + 2]];
+ } else {
+ t[0] = r[i + 0];
+ t[1] = r[i + 1];
+ t[2] = r[i + 2];
+ }
+
+ Vector3 n = Plane(t[0], t[1], t[2]).normal;
+
+ for (int j = 0; j < 3; j++) {
+
+ Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]);
+ if (!E) {
+ normal_accum[t[j]] = n;
+ } else {
+ float d = n.dot(E->get());
+ if (d < 1.0)
+ E->get() += n * (1.0 - d);
+ //E->get()+=n;
+ }
+ }
+ }
+
+ //normalize
+
+ for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) {
+ E->get().normalize();
+ }
+
+ //displace normals
+ int vc2 = vertices.size();
+
+ for (int i = 0; i < vc2; i++) {
+
+ Vector3 t = r[i];
+
+ Map<Vector3, Vector3>::Element *E = normal_accum.find(t);
+ ERR_CONTINUE(!E);
+
+ t += E->get() * p_margin;
+ r[i] = t;
+ }
+
+ r = PoolVector<Vector3>::Write();
+ arrays[ARRAY_VERTEX] = vertices;
+
+ if (!has_indices) {
+
+ PoolVector<int> new_indices;
+ new_indices.resize(vertices.size());
+ PoolVector<int>::Write iw = new_indices.write();
+
+ for (int j = 0; j < vc2; j += 3) {
+
+ iw[j] = j;
+ iw[j + 1] = j + 2;
+ iw[j + 2] = j + 1;
+ }
+
+ iw = PoolVector<int>::Write();
+ arrays[ARRAY_INDEX] = new_indices;
+
+ } else {
+
+ for (int j = 0; j < vc; j += 3) {
+
+ SWAP(ir[j + 1], ir[j + 2]);
+ }
+ ir = PoolVector<int>::Write();
+ arrays[ARRAY_INDEX] = indices;
+ }
+ }
+
+ Ref<ArrayMesh> newmesh = memnew(ArrayMesh);
+ newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays);
+ return newmesh;
+}
+
+Mesh::Mesh() {
+}
+
static const char *_array_name[] = {
"vertex_array",
"normal_array",
@@ -45,34 +429,34 @@ static const char *_array_name[] = {
NULL
};
-static const Mesh::ArrayType _array_types[] = {
-
- Mesh::ARRAY_VERTEX,
- Mesh::ARRAY_NORMAL,
- Mesh::ARRAY_TANGENT,
- Mesh::ARRAY_COLOR,
- Mesh::ARRAY_TEX_UV,
- Mesh::ARRAY_TEX_UV2,
- Mesh::ARRAY_BONES,
- Mesh::ARRAY_WEIGHTS,
- Mesh::ARRAY_INDEX
+static const ArrayMesh::ArrayType _array_types[] = {
+
+ ArrayMesh::ARRAY_VERTEX,
+ ArrayMesh::ARRAY_NORMAL,
+ ArrayMesh::ARRAY_TANGENT,
+ ArrayMesh::ARRAY_COLOR,
+ ArrayMesh::ARRAY_TEX_UV,
+ ArrayMesh::ARRAY_TEX_UV2,
+ ArrayMesh::ARRAY_BONES,
+ ArrayMesh::ARRAY_WEIGHTS,
+ ArrayMesh::ARRAY_INDEX
};
/* compatibility */
static const int _format_translate[] = {
- Mesh::ARRAY_FORMAT_VERTEX,
- Mesh::ARRAY_FORMAT_NORMAL,
- Mesh::ARRAY_FORMAT_TANGENT,
- Mesh::ARRAY_FORMAT_COLOR,
- Mesh::ARRAY_FORMAT_TEX_UV,
- Mesh::ARRAY_FORMAT_TEX_UV2,
- Mesh::ARRAY_FORMAT_BONES,
- Mesh::ARRAY_FORMAT_WEIGHTS,
- Mesh::ARRAY_FORMAT_INDEX,
+ ArrayMesh::ARRAY_FORMAT_VERTEX,
+ ArrayMesh::ARRAY_FORMAT_NORMAL,
+ ArrayMesh::ARRAY_FORMAT_TANGENT,
+ ArrayMesh::ARRAY_FORMAT_COLOR,
+ ArrayMesh::ARRAY_FORMAT_TEX_UV,
+ ArrayMesh::ARRAY_FORMAT_TEX_UV2,
+ ArrayMesh::ARRAY_FORMAT_BONES,
+ ArrayMesh::ARRAY_FORMAT_WEIGHTS,
+ ArrayMesh::ARRAY_FORMAT_INDEX,
};
-bool Mesh::_set(const StringName &p_name, const Variant &p_value) {
+bool ArrayMesh::_set(const StringName &p_name, const Variant &p_value) {
String sname = p_name;
@@ -191,7 +575,7 @@ bool Mesh::_set(const StringName &p_name, const Variant &p_value) {
return false;
}
-bool Mesh::_get(const StringName &p_name, Variant &r_ret) const {
+bool ArrayMesh::_get(const StringName &p_name, Variant &r_ret) const {
if (_is_generated())
return false;
@@ -270,7 +654,7 @@ bool Mesh::_get(const StringName &p_name, Variant &r_ret) const {
return true;
}
-void Mesh::_get_property_list(List<PropertyInfo> *p_list) const {
+void ArrayMesh::_get_property_list(List<PropertyInfo> *p_list) const {
if (_is_generated())
return;
@@ -290,7 +674,7 @@ void Mesh::_get_property_list(List<PropertyInfo> *p_list) const {
p_list->push_back(PropertyInfo(Variant::RECT3, "custom_aabb/custom_aabb"));
}
-void Mesh::_recompute_aabb() {
+void ArrayMesh::_recompute_aabb() {
// regenerate AABB
aabb = Rect3();
@@ -304,16 +688,17 @@ void Mesh::_recompute_aabb() {
}
}
-void Mesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) {
+void ArrayMesh::add_surface(uint32_t p_format, PrimitiveType p_primitive, const PoolVector<uint8_t> &p_array, int p_vertex_count, const PoolVector<uint8_t> &p_index_array, int p_index_count, const Rect3 &p_aabb, const Vector<PoolVector<uint8_t> > &p_blend_shapes, const Vector<Rect3> &p_bone_aabbs) {
Surface s;
s.aabb = p_aabb;
surfaces.push_back(s);
+ _recompute_aabb();
VisualServer::get_singleton()->mesh_add_surface(mesh, p_format, (VS::PrimitiveType)p_primitive, p_array, p_vertex_count, p_index_array, p_index_count, p_aabb, p_blend_shapes, p_bone_aabbs);
}
-void Mesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_flags) {
+void ArrayMesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_flags) {
ERR_FAIL_COND(p_arrays.size() != ARRAY_MAX);
@@ -335,7 +720,7 @@ void Mesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arr
for (int i = 0; i < len; i++) {
if (i == 0)
- aabb.pos = vtx[i];
+ aabb.position = vtx[i];
else
aabb.expand_to(vtx[i]);
}
@@ -345,28 +730,28 @@ void Mesh::add_surface_from_arrays(PrimitiveType p_primitive, const Array &p_arr
_recompute_aabb();
}
- triangle_mesh = Ref<TriangleMesh>();
+ _clear_triangle_mesh();
_change_notify();
emit_changed();
}
-Array Mesh::surface_get_arrays(int p_surface) const {
+Array ArrayMesh::surface_get_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, p_surface);
}
-Array Mesh::surface_get_blend_shape_arrays(int p_surface) const {
+Array ArrayMesh::surface_get_blend_shape_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, surfaces.size(), Array());
return Array();
}
-int Mesh::get_surface_count() const {
+int ArrayMesh::get_surface_count() const {
return surfaces.size();
}
-void Mesh::add_blend_shape(const StringName &p_name) {
+void ArrayMesh::add_blend_shape(const StringName &p_name) {
if (surfaces.size()) {
ERR_EXPLAIN("Can't add a shape key count if surfaces are already created.");
@@ -389,15 +774,15 @@ void Mesh::add_blend_shape(const StringName &p_name) {
VS::get_singleton()->mesh_set_blend_shape_count(mesh, blend_shapes.size());
}
-int Mesh::get_blend_shape_count() const {
+int ArrayMesh::get_blend_shape_count() const {
return blend_shapes.size();
}
-StringName Mesh::get_blend_shape_name(int p_index) const {
+StringName ArrayMesh::get_blend_shape_name(int p_index) const {
ERR_FAIL_INDEX_V(p_index, blend_shapes.size(), StringName());
return blend_shapes[p_index];
}
-void Mesh::clear_blend_shapes() {
+void ArrayMesh::clear_blend_shapes() {
if (surfaces.size()) {
ERR_EXPLAIN("Can't set shape key count if surfaces are already created.");
@@ -407,54 +792,54 @@ void Mesh::clear_blend_shapes() {
blend_shapes.clear();
}
-void Mesh::set_blend_shape_mode(BlendShapeMode p_mode) {
+void ArrayMesh::set_blend_shape_mode(BlendShapeMode p_mode) {
blend_shape_mode = p_mode;
VS::get_singleton()->mesh_set_blend_shape_mode(mesh, (VS::BlendShapeMode)p_mode);
}
-Mesh::BlendShapeMode Mesh::get_blend_shape_mode() const {
+ArrayMesh::BlendShapeMode ArrayMesh::get_blend_shape_mode() const {
return blend_shape_mode;
}
-void Mesh::surface_remove(int p_idx) {
+void ArrayMesh::surface_remove(int p_idx) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
VisualServer::get_singleton()->mesh_remove_surface(mesh, p_idx);
surfaces.remove(p_idx);
- triangle_mesh = Ref<TriangleMesh>();
+ _clear_triangle_mesh();
_recompute_aabb();
_change_notify();
emit_changed();
}
-int Mesh::surface_get_array_len(int p_idx) const {
+int ArrayMesh::surface_get_array_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, p_idx);
}
-int Mesh::surface_get_array_index_len(int p_idx) const {
+int ArrayMesh::surface_get_array_index_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), -1);
return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, p_idx);
}
-uint32_t Mesh::surface_get_format(int p_idx) const {
+uint32_t ArrayMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), 0);
return VisualServer::get_singleton()->mesh_surface_get_format(mesh, p_idx);
}
-Mesh::PrimitiveType Mesh::surface_get_primitive_type(int p_idx) const {
+ArrayMesh::PrimitiveType ArrayMesh::surface_get_primitive_type(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), PRIMITIVE_LINES);
return (PrimitiveType)VisualServer::get_singleton()->mesh_surface_get_primitive_type(mesh, p_idx);
}
-void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
+void ArrayMesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
if (surfaces[p_idx].material == p_material)
@@ -465,40 +850,40 @@ void Mesh::surface_set_material(int p_idx, const Ref<Material> &p_material) {
_change_notify("material");
}
-void Mesh::surface_set_name(int p_idx, const String &p_name) {
+void ArrayMesh::surface_set_name(int p_idx, const String &p_name) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces[p_idx].name = p_name;
}
-String Mesh::surface_get_name(int p_idx) const {
+String ArrayMesh::surface_get_name(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), String());
return surfaces[p_idx].name;
}
-void Mesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) {
+void ArrayMesh::surface_set_custom_aabb(int p_idx, const Rect3 &p_aabb) {
ERR_FAIL_INDEX(p_idx, surfaces.size());
surfaces[p_idx].aabb = p_aabb;
// set custom aabb too?
}
-Ref<Material> Mesh::surface_get_material(int p_idx) const {
+Ref<Material> ArrayMesh::surface_get_material(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, surfaces.size(), Ref<Material>());
return surfaces[p_idx].material;
}
-void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
+void ArrayMesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
VisualServer::get_singleton()->mesh_add_surface_from_mesh_data(mesh, p_mesh_data);
Rect3 aabb;
for (int i = 0; i < p_mesh_data.vertices.size(); i++) {
if (i == 0)
- aabb.pos = p_mesh_data.vertices[i];
+ aabb.position = p_mesh_data.vertices[i];
else
aabb.expand_to(p_mesh_data.vertices[i]);
}
@@ -510,7 +895,7 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
else
aabb.merge_with(s.aabb);
- triangle_mesh = Ref<TriangleMesh>();
+ _clear_triangle_mesh();
surfaces.push_back(s);
_change_notify();
@@ -518,129 +903,27 @@ void Mesh::add_surface_from_mesh_data(const Geometry::MeshData &p_mesh_data) {
emit_changed();
}
-RID Mesh::get_rid() const {
+RID ArrayMesh::get_rid() const {
return mesh;
}
-Rect3 Mesh::get_aabb() const {
+Rect3 ArrayMesh::get_aabb() const {
return aabb;
}
-void Mesh::set_custom_aabb(const Rect3 &p_custom) {
+void ArrayMesh::set_custom_aabb(const Rect3 &p_custom) {
custom_aabb = p_custom;
VS::get_singleton()->mesh_set_custom_aabb(mesh, custom_aabb);
}
-Rect3 Mesh::get_custom_aabb() const {
+Rect3 ArrayMesh::get_custom_aabb() const {
return custom_aabb;
}
-PoolVector<Face3> Mesh::get_faces() const {
-
- Ref<TriangleMesh> tm = generate_triangle_mesh();
- if (tm.is_valid())
- return tm->get_faces();
- return PoolVector<Face3>();
- /*
- for (int i=0;i<surfaces.size();i++) {
-
- if (VisualServer::get_singleton()->mesh_surface_get_primitive_type( mesh, i ) != VisualServer::PRIMITIVE_TRIANGLES )
- continue;
-
- PoolVector<int> indices;
- PoolVector<Vector3> vertices;
-
- vertices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_VERTEX);
-
- int len=VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, i);
- bool has_indices;
-
- if (len>0) {
-
- indices=VisualServer::get_singleton()->mesh_surface_get_array(mesh, i,VisualServer::ARRAY_INDEX);
- has_indices=true;
-
- } else {
-
- len=vertices.size();
- has_indices=false;
- }
-
- if (len<=0)
- continue;
-
- PoolVector<int>::Read indicesr = indices.read();
- const int *indicesptr = indicesr.ptr();
-
- PoolVector<Vector3>::Read verticesr = vertices.read();
- const Vector3 *verticesptr = verticesr.ptr();
-
- int old_faces=faces.size();
- int new_faces=old_faces+(len/3);
-
- faces.resize(new_faces);
-
- PoolVector<Face3>::Write facesw = faces.write();
- Face3 *facesptr=facesw.ptr();
-
-
- for (int i=0;i<len/3;i++) {
-
- Face3 face;
-
- for (int j=0;j<3;j++) {
-
- int idx=i*3+j;
- face.vertex[j] = has_indices ? verticesptr[ indicesptr[ idx ] ] : verticesptr[idx];
- }
-
- facesptr[i+old_faces]=face;
- }
-
- }
-*/
-}
-
-Ref<Shape> Mesh::create_convex_shape() const {
-
- PoolVector<Vector3> vertices;
-
- for (int i = 0; i < get_surface_count(); i++) {
-
- Array a = surface_get_arrays(i);
- PoolVector<Vector3> v = a[ARRAY_VERTEX];
- vertices.append_array(v);
- }
-
- Ref<ConvexPolygonShape> shape = memnew(ConvexPolygonShape);
- shape->set_points(vertices);
- return shape;
-}
-
-Ref<Shape> Mesh::create_trimesh_shape() const {
-
- PoolVector<Face3> faces = get_faces();
- if (faces.size() == 0)
- return Ref<Shape>();
-
- PoolVector<Vector3> face_points;
- face_points.resize(faces.size() * 3);
-
- for (int i = 0; i < face_points.size(); i++) {
-
- Face3 f = faces.get(i / 3);
- face_points.set(i, f.vertex[i % 3]);
- }
-
- Ref<ConcavePolygonShape> shape = memnew(ConcavePolygonShape);
- shape->set_faces(face_points);
- return shape;
-}
-
-void Mesh::center_geometry() {
+void ArrayMesh::center_geometry() {
/*
Vector3 ofs = aabb.pos+aabb.size*0.5;
@@ -668,13 +951,13 @@ void Mesh::center_geometry() {
*/
}
-void Mesh::regen_normalmaps() {
+void ArrayMesh::regen_normalmaps() {
Vector<Ref<SurfaceTool> > surfs;
for (int i = 0; i < get_surface_count(); i++) {
Ref<SurfaceTool> st = memnew(SurfaceTool);
- st->create_from(Ref<Mesh>(this), i);
+ st->create_from(Ref<ArrayMesh>(this), i);
surfs.push_back(st);
}
@@ -685,310 +968,42 @@ void Mesh::regen_normalmaps() {
for (int i = 0; i < surfs.size(); i++) {
surfs[i]->generate_tangents();
- surfs[i]->commit(Ref<Mesh>(this));
- }
-}
-
-Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
-
- if (triangle_mesh.is_valid())
- return triangle_mesh;
-
- int facecount = 0;
-
- for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
- continue;
-
- if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
- facecount += surface_get_array_index_len(i);
- } else {
-
- facecount += surface_get_array_len(i);
- }
- }
-
- if (facecount == 0 || (facecount % 3) != 0)
- return triangle_mesh;
-
- PoolVector<Vector3> faces;
- faces.resize(facecount);
- PoolVector<Vector3>::Write facesw = faces.write();
-
- int widx = 0;
-
- for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
- continue;
-
- Array a = surface_get_arrays(i);
-
- int vc = surface_get_array_len(i);
- PoolVector<Vector3> vertices = a[ARRAY_VERTEX];
- PoolVector<Vector3>::Read vr = vertices.read();
-
- if (surface_get_format(i) & ARRAY_FORMAT_INDEX) {
-
- int ic = surface_get_array_index_len(i);
- PoolVector<int> indices = a[ARRAY_INDEX];
- PoolVector<int>::Read ir = indices.read();
-
- for (int i = 0; i < ic; i++) {
- int index = ir[i];
- facesw[widx++] = vr[index];
- }
-
- } else {
-
- for (int i = 0; i < vc; i++)
- facesw[widx++] = vr[i];
- }
- }
-
- facesw = PoolVector<Vector3>::Write();
-
- triangle_mesh = Ref<TriangleMesh>(memnew(TriangleMesh));
- triangle_mesh->create(faces);
-
- return triangle_mesh;
-}
-
-Ref<Mesh> Mesh::create_outline(float p_margin) const {
-
- Array arrays;
- int index_accum = 0;
- for (int i = 0; i < get_surface_count(); i++) {
-
- if (surface_get_primitive_type(i) != PRIMITIVE_TRIANGLES)
- continue;
-
- Array a = surface_get_arrays(i);
- int vcount = 0;
-
- if (i == 0) {
- arrays = a;
- PoolVector<Vector3> v = a[ARRAY_VERTEX];
- index_accum += v.size();
- } else {
-
- for (int j = 0; j < arrays.size(); j++) {
-
- if (arrays[j].get_type() == Variant::NIL || a[j].get_type() == Variant::NIL) {
- //mismatch, do not use
- arrays[j] = Variant();
- continue;
- }
-
- switch (j) {
-
- case ARRAY_VERTEX:
- case ARRAY_NORMAL: {
-
- PoolVector<Vector3> dst = arrays[j];
- PoolVector<Vector3> src = a[j];
- if (j == ARRAY_VERTEX)
- vcount = src.size();
- if (dst.size() == 0 || src.size() == 0) {
- arrays[j] = Variant();
- continue;
- }
- dst.append_array(src);
- arrays[j] = dst;
- } break;
- case ARRAY_TANGENT:
- case ARRAY_BONES:
- case ARRAY_WEIGHTS: {
-
- PoolVector<real_t> dst = arrays[j];
- PoolVector<real_t> src = a[j];
- if (dst.size() == 0 || src.size() == 0) {
- arrays[j] = Variant();
- continue;
- }
- dst.append_array(src);
- arrays[j] = dst;
-
- } break;
- case ARRAY_COLOR: {
- PoolVector<Color> dst = arrays[j];
- PoolVector<Color> src = a[j];
- if (dst.size() == 0 || src.size() == 0) {
- arrays[j] = Variant();
- continue;
- }
- dst.append_array(src);
- arrays[j] = dst;
-
- } break;
- case ARRAY_TEX_UV:
- case ARRAY_TEX_UV2: {
- PoolVector<Vector2> dst = arrays[j];
- PoolVector<Vector2> src = a[j];
- if (dst.size() == 0 || src.size() == 0) {
- arrays[j] = Variant();
- continue;
- }
- dst.append_array(src);
- arrays[j] = dst;
-
- } break;
- case ARRAY_INDEX: {
- PoolVector<int> dst = arrays[j];
- PoolVector<int> src = a[j];
- if (dst.size() == 0 || src.size() == 0) {
- arrays[j] = Variant();
- continue;
- }
- {
- int ss = src.size();
- PoolVector<int>::Write w = src.write();
- for (int k = 0; k < ss; k++) {
- w[k] += index_accum;
- }
- }
- dst.append_array(src);
- arrays[j] = dst;
- index_accum += vcount;
-
- } break;
- }
- }
- }
+ surfs[i]->commit(Ref<ArrayMesh>(this));
}
-
- {
- PoolVector<int>::Write ir;
- PoolVector<int> indices = arrays[ARRAY_INDEX];
- bool has_indices = false;
- PoolVector<Vector3> vertices = arrays[ARRAY_VERTEX];
- int vc = vertices.size();
- ERR_FAIL_COND_V(!vc, Ref<Mesh>());
- PoolVector<Vector3>::Write r = vertices.write();
-
- if (indices.size()) {
- vc = indices.size();
- ir = indices.write();
- has_indices = true;
- }
-
- Map<Vector3, Vector3> normal_accum;
-
- //fill normals with triangle normals
- for (int i = 0; i < vc; i += 3) {
-
- Vector3 t[3];
-
- if (has_indices) {
- t[0] = r[ir[i + 0]];
- t[1] = r[ir[i + 1]];
- t[2] = r[ir[i + 2]];
- } else {
- t[0] = r[i + 0];
- t[1] = r[i + 1];
- t[2] = r[i + 2];
- }
-
- Vector3 n = Plane(t[0], t[1], t[2]).normal;
-
- for (int j = 0; j < 3; j++) {
-
- Map<Vector3, Vector3>::Element *E = normal_accum.find(t[j]);
- if (!E) {
- normal_accum[t[j]] = n;
- } else {
- float d = n.dot(E->get());
- if (d < 1.0)
- E->get() += n * (1.0 - d);
- //E->get()+=n;
- }
- }
- }
-
- //normalize
-
- for (Map<Vector3, Vector3>::Element *E = normal_accum.front(); E; E = E->next()) {
- E->get().normalize();
- }
-
- //displace normals
- int vc2 = vertices.size();
-
- for (int i = 0; i < vc2; i++) {
-
- Vector3 t = r[i];
-
- Map<Vector3, Vector3>::Element *E = normal_accum.find(t);
- ERR_CONTINUE(!E);
-
- t += E->get() * p_margin;
- r[i] = t;
- }
-
- r = PoolVector<Vector3>::Write();
- arrays[ARRAY_VERTEX] = vertices;
-
- if (!has_indices) {
-
- PoolVector<int> new_indices;
- new_indices.resize(vertices.size());
- PoolVector<int>::Write iw = new_indices.write();
-
- for (int j = 0; j < vc2; j += 3) {
-
- iw[j] = j;
- iw[j + 1] = j + 2;
- iw[j + 2] = j + 1;
- }
-
- iw = PoolVector<int>::Write();
- arrays[ARRAY_INDEX] = new_indices;
-
- } else {
-
- for (int j = 0; j < vc; j += 3) {
-
- SWAP(ir[j + 1], ir[j + 2]);
- }
- ir = PoolVector<int>::Write();
- arrays[ARRAY_INDEX] = indices;
- }
- }
-
- Ref<Mesh> newmesh = memnew(Mesh);
- newmesh->add_surface_from_arrays(PRIMITIVE_TRIANGLES, arrays);
- return newmesh;
}
-void Mesh::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &Mesh::add_blend_shape);
- ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &Mesh::get_blend_shape_count);
- ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &Mesh::get_blend_shape_name);
- ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &Mesh::clear_blend_shapes);
- ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &Mesh::set_blend_shape_mode);
- ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &Mesh::get_blend_shape_mode);
-
- ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &Mesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
- ClassDB::bind_method(D_METHOD("get_surface_count"), &Mesh::get_surface_count);
- ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &Mesh::surface_remove);
- ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &Mesh::surface_get_array_len);
- ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &Mesh::surface_get_array_index_len);
- ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &Mesh::surface_get_format);
- ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &Mesh::surface_get_primitive_type);
- ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material:Material"), &Mesh::surface_set_material);
- ClassDB::bind_method(D_METHOD("surface_get_material:Material", "surf_idx"), &Mesh::surface_get_material);
- ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &Mesh::surface_set_name);
- ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &Mesh::surface_get_name);
- ClassDB::bind_method(D_METHOD("center_geometry"), &Mesh::center_geometry);
+void ArrayMesh::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("add_blend_shape", "name"), &ArrayMesh::add_blend_shape);
+ ClassDB::bind_method(D_METHOD("get_blend_shape_count"), &ArrayMesh::get_blend_shape_count);
+ ClassDB::bind_method(D_METHOD("get_blend_shape_name", "index"), &ArrayMesh::get_blend_shape_name);
+ ClassDB::bind_method(D_METHOD("clear_blend_shapes"), &ArrayMesh::clear_blend_shapes);
+ ClassDB::bind_method(D_METHOD("set_blend_shape_mode", "mode"), &ArrayMesh::set_blend_shape_mode);
+ ClassDB::bind_method(D_METHOD("get_blend_shape_mode"), &ArrayMesh::get_blend_shape_mode);
+
+ ClassDB::bind_method(D_METHOD("add_surface_from_arrays", "primitive", "arrays", "blend_shapes", "compress_flags"), &ArrayMesh::add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("get_surface_count"), &ArrayMesh::get_surface_count);
+ ClassDB::bind_method(D_METHOD("surface_remove", "surf_idx"), &ArrayMesh::surface_remove);
+ ClassDB::bind_method(D_METHOD("surface_get_array_len", "surf_idx"), &ArrayMesh::surface_get_array_len);
+ ClassDB::bind_method(D_METHOD("surface_get_array_index_len", "surf_idx"), &ArrayMesh::surface_get_array_index_len);
+ ClassDB::bind_method(D_METHOD("surface_get_format", "surf_idx"), &ArrayMesh::surface_get_format);
+ ClassDB::bind_method(D_METHOD("surface_get_primitive_type", "surf_idx"), &ArrayMesh::surface_get_primitive_type);
+ ClassDB::bind_method(D_METHOD("surface_set_material", "surf_idx", "material:Material"), &ArrayMesh::surface_set_material);
+ ClassDB::bind_method(D_METHOD("surface_get_material:Material", "surf_idx"), &ArrayMesh::surface_get_material);
+ ClassDB::bind_method(D_METHOD("surface_set_name", "surf_idx", "name"), &ArrayMesh::surface_set_name);
+ ClassDB::bind_method(D_METHOD("surface_get_name", "surf_idx"), &ArrayMesh::surface_get_name);
+ ClassDB::bind_method(D_METHOD("create_trimesh_shape:Shape"), &ArrayMesh::create_trimesh_shape);
+ ClassDB::bind_method(D_METHOD("create_convex_shape:Shape"), &ArrayMesh::create_convex_shape);
+ ClassDB::bind_method(D_METHOD("create_outline:ArrayMesh", "margin"), &ArrayMesh::create_outline);
+ ClassDB::bind_method(D_METHOD("center_geometry"), &ArrayMesh::center_geometry);
ClassDB::set_method_flags(get_class_static(), _scs_create("center_geometry"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::bind_method(D_METHOD("regen_normalmaps"), &Mesh::regen_normalmaps);
+ ClassDB::bind_method(D_METHOD("regen_normalmaps"), &ArrayMesh::regen_normalmaps);
ClassDB::set_method_flags(get_class_static(), _scs_create("regen_normalmaps"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
+ ClassDB::bind_method(D_METHOD("get_faces"), &ArrayMesh::get_faces);
+ ClassDB::bind_method(D_METHOD("generate_triangle_mesh:TriangleMesh"), &ArrayMesh::generate_triangle_mesh);
- ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &Mesh::set_custom_aabb);
- ClassDB::bind_method(D_METHOD("get_custom_aabb"), &Mesh::get_custom_aabb);
+ ClassDB::bind_method(D_METHOD("set_custom_aabb", "aabb"), &ArrayMesh::set_custom_aabb);
+ ClassDB::bind_method(D_METHOD("get_custom_aabb"), &ArrayMesh::get_custom_aabb);
BIND_CONSTANT(NO_INDEX_ARRAY);
BIND_CONSTANT(ARRAY_WEIGHTS_SIZE);
@@ -1022,81 +1037,13 @@ void Mesh::_bind_methods() {
BIND_CONSTANT(PRIMITIVE_TRIANGLE_FAN);
}
-Mesh::Mesh() {
+ArrayMesh::ArrayMesh() {
mesh = VisualServer::get_singleton()->mesh_create();
blend_shape_mode = BLEND_SHAPE_MODE_RELATIVE;
}
-Mesh::~Mesh() {
+ArrayMesh::~ArrayMesh() {
VisualServer::get_singleton()->free(mesh);
}
-
-////////////////////////
-
-void QuadMesh::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &QuadMesh::set_material);
- ClassDB::bind_method(D_METHOD("get_material:Material"), &QuadMesh::get_material);
-
- ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
-}
-
-void QuadMesh::set_material(const Ref<Material> &p_material) {
-
- surface_set_material(0, p_material);
-}
-
-Ref<Material> QuadMesh::get_material() const {
-
- return surface_get_material(0);
-}
-
-QuadMesh::QuadMesh() {
-
- PoolVector<Vector3> faces;
- PoolVector<Vector3> normals;
- PoolVector<float> tangents;
- PoolVector<Vector2> uvs;
-
- faces.resize(4);
- normals.resize(4);
- tangents.resize(4 * 4);
- uvs.resize(4);
-
- for (int i = 0; i < 4; i++) {
-
- static const Vector3 quad_faces[4] = {
- Vector3(-1, -1, 0),
- Vector3(-1, 1, 0),
- Vector3(1, 1, 0),
- Vector3(1, -1, 0),
- };
-
- faces.set(i, quad_faces[i]);
- normals.set(i, Vector3(0, 0, 1));
- tangents.set(i * 4 + 0, 1.0);
- tangents.set(i * 4 + 1, 0.0);
- tangents.set(i * 4 + 2, 0.0);
- tangents.set(i * 4 + 3, 1.0);
-
- static const Vector2 quad_uv[4] = {
- Vector2(0, 1),
- Vector2(0, 0),
- Vector2(1, 0),
- Vector2(1, 1),
- };
-
- uvs.set(i, quad_uv[i]);
- }
-
- Array arr;
- arr.resize(ARRAY_MAX);
- arr[ARRAY_VERTEX] = faces;
- arr[ARRAY_NORMAL] = normals;
- arr[ARRAY_TANGENT] = tangents;
- arr[ARRAY_TEX_UV] = uvs;
-
- add_surface_from_arrays(PRIMITIVE_TRIANGLE_FAN, arr);
-}
diff --git a/scene/resources/mesh.h b/scene/resources/mesh.h
index e441b4924a..37fddf3aa6 100644
--- a/scene/resources/mesh.h
+++ b/scene/resources/mesh.h
@@ -38,10 +38,13 @@
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
-class Mesh : public Resource {
+class Mesh : public Resource {
GDCLASS(Mesh, Resource);
- RES_BASE_EXTENSION("msh");
+
+ mutable Ref<TriangleMesh> triangle_mesh; //cached
+protected:
+ void _clear_triangle_mesh();
public:
enum {
@@ -111,6 +114,34 @@ public:
BLEND_SHAPE_MODE_RELATIVE = VS::BLEND_SHAPE_MODE_RELATIVE,
};
+ virtual int get_surface_count() const = 0;
+ virtual int surface_get_array_len(int p_idx) const = 0;
+ virtual int surface_get_array_index_len(int p_idx) const = 0;
+ virtual Array surface_get_arrays(int p_surface) const = 0;
+ virtual uint32_t surface_get_format(int p_idx) const = 0;
+ virtual PrimitiveType surface_get_primitive_type(int p_idx) const = 0;
+ virtual Ref<Material> surface_get_material(int p_idx) const = 0;
+ virtual int get_blend_shape_count() const = 0;
+ virtual StringName get_blend_shape_name(int p_index) const = 0;
+
+ PoolVector<Face3> get_faces() const;
+ Ref<TriangleMesh> generate_triangle_mesh() const;
+
+ Ref<Shape> create_trimesh_shape() const;
+ Ref<Shape> create_convex_shape() const;
+
+ Ref<Mesh> create_outline(float p_margin) const;
+
+ virtual Rect3 get_aabb() const = 0;
+
+ Mesh();
+};
+
+class ArrayMesh : public Mesh {
+
+ GDCLASS(ArrayMesh, Mesh);
+ RES_BASE_EXTENSION("mesh");
+
private:
struct Surface {
String name;
@@ -124,8 +155,6 @@ private:
Vector<StringName> blend_shapes;
Rect3 custom_aabb;
- mutable Ref<TriangleMesh> triangle_mesh;
-
void _recompute_aabb();
protected:
@@ -177,33 +206,12 @@ public:
Rect3 get_aabb() const;
virtual RID get_rid() const;
- Ref<Shape> create_trimesh_shape() const;
- Ref<Shape> create_convex_shape() const;
-
- Ref<Mesh> create_outline(float p_margin) const;
-
void center_geometry();
void regen_normalmaps();
- PoolVector<Face3> get_faces() const;
- Ref<TriangleMesh> generate_triangle_mesh() const;
- Mesh();
-
- ~Mesh();
-};
-
-class QuadMesh : public Mesh {
-
- GDCLASS(QuadMesh, Mesh)
+ ArrayMesh();
-protected:
- virtual bool _is_generated() const { return true; }
- static void _bind_methods();
-
-public:
- void set_material(const Ref<Material> &p_material);
- Ref<Material> get_material() const;
- QuadMesh();
+ ~ArrayMesh();
};
VARIANT_ENUM_CAST(Mesh::ArrayType);
diff --git a/scene/resources/mesh_data_tool.cpp b/scene/resources/mesh_data_tool.cpp
index b6b47bf443..dc3713fb57 100644
--- a/scene/resources/mesh_data_tool.cpp
+++ b/scene/resources/mesh_data_tool.cpp
@@ -38,7 +38,7 @@ void MeshDataTool::clear() {
format = 0;
}
-Error MeshDataTool::create_from_surface(const Ref<Mesh> &p_mesh, int p_surface) {
+Error MeshDataTool::create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface) {
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
@@ -179,7 +179,7 @@ Error MeshDataTool::create_from_surface(const Ref<Mesh> &p_mesh, int p_surface)
return OK;
}
-Error MeshDataTool::commit_to_surface(const Ref<Mesh> &p_mesh) {
+Error MeshDataTool::commit_to_surface(const Ref<ArrayMesh> &p_mesh) {
ERR_FAIL_COND_V(p_mesh.is_null(), ERR_INVALID_PARAMETER);
Array arr;
@@ -309,7 +309,7 @@ Error MeshDataTool::commit_to_surface(const Ref<Mesh> &p_mesh) {
if (w.size())
arr[Mesh::ARRAY_WEIGHTS] = w;
- Ref<Mesh> ncmesh = p_mesh;
+ Ref<ArrayMesh> ncmesh = p_mesh;
int sc = ncmesh->get_surface_count();
ncmesh->add_surface_from_arrays(Mesh::PRIMITIVE_TRIANGLES, arr);
ncmesh->surface_set_material(sc, material);
diff --git a/scene/resources/mesh_data_tool.h b/scene/resources/mesh_data_tool.h
index f6797d3e5e..ad771edbd1 100644
--- a/scene/resources/mesh_data_tool.h
+++ b/scene/resources/mesh_data_tool.h
@@ -78,8 +78,8 @@ protected:
public:
void clear();
- Error create_from_surface(const Ref<Mesh> &p_mesh, int p_surface);
- Error commit_to_surface(const Ref<Mesh> &p_mesh);
+ Error create_from_surface(const Ref<ArrayMesh> &p_mesh, int p_surface);
+ Error commit_to_surface(const Ref<ArrayMesh> &p_mesh);
int get_format() const;
diff --git a/scene/resources/mesh_library.h b/scene/resources/mesh_library.h
index a381f54a19..cc39110a99 100644
--- a/scene/resources/mesh_library.h
+++ b/scene/resources/mesh_library.h
@@ -39,7 +39,7 @@
class MeshLibrary : public Resource {
GDCLASS(MeshLibrary, Resource);
- RES_BASE_EXTENSION("gt");
+ RES_BASE_EXTENSION("meshlib");
struct Item {
String name;
diff --git a/scene/resources/multimesh.h b/scene/resources/multimesh.h
index 4a00685b9f..7d6a0ce44f 100644
--- a/scene/resources/multimesh.h
+++ b/scene/resources/multimesh.h
@@ -36,7 +36,7 @@
class MultiMesh : public Resource {
GDCLASS(MultiMesh, Resource);
- RES_BASE_EXTENSION("mmsh");
+ RES_BASE_EXTENSION("multimesh");
public:
enum TransformFormat {
diff --git a/scene/resources/polygon_path_finder.cpp b/scene/resources/polygon_path_finder.cpp
index 472031366f..80b413630a 100644
--- a/scene/resources/polygon_path_finder.cpp
+++ b/scene/resources/polygon_path_finder.cpp
@@ -71,7 +71,7 @@ void PolygonPathFinder::setup(const Vector<Vector2> &p_points, const Vector<int>
outside_point.y = i == 0 ? p_points[0].y : (MAX(p_points[i].y, outside_point.y));
if (i == 0) {
- bounds.pos = points[i].pos;
+ bounds.position = points[i].pos;
} else {
bounds.expand_to(points[i].pos);
}
diff --git a/scene/resources/primitive_meshes.cpp b/scene/resources/primitive_meshes.cpp
new file mode 100644
index 0000000000..d4221dcb3f
--- /dev/null
+++ b/scene/resources/primitive_meshes.cpp
@@ -0,0 +1,1454 @@
+/*************************************************************************/
+/* primitive_meshes.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 "primitive_meshes.h"
+#include "servers/visual_server.h"
+
+/**
+ PrimitiveMesh
+*/
+void PrimitiveMesh::_update() {
+ if (!cache_is_dirty)
+ return;
+
+ Array arr;
+ arr.resize(VS::ARRAY_MAX);
+ _create_mesh_array(arr);
+
+ // in with the new
+ VisualServer::get_singleton()->mesh_clear(mesh);
+ VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr);
+ VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
+
+ cache_is_dirty = false;
+
+ _clear_triangle_mesh();
+ emit_changed();
+}
+
+void PrimitiveMesh::_queue_update() {
+ if (!cache_is_dirty) {
+ cache_is_dirty = true;
+ call_deferred("_update");
+ }
+}
+
+void PrimitiveMesh::set_aabb(Rect3 p_aabb) {
+ aabb = p_aabb;
+}
+
+int PrimitiveMesh::get_surface_count() const {
+ return 1;
+}
+
+int PrimitiveMesh::surface_get_array_len(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, 1, -1);
+ return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0);
+}
+
+int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, 1, -1);
+ return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0);
+}
+
+Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
+ ERR_FAIL_INDEX_V(p_surface, 1, Array());
+ return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0);
+}
+
+uint32_t PrimitiveMesh::surface_get_format(int p_idx) const {
+ ERR_FAIL_INDEX_V(p_idx, 1, 0);
+ return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0);
+}
+
+Mesh::PrimitiveType PrimitiveMesh::surface_get_primitive_type(int p_idx) const {
+ return primitive_type;
+}
+
+Ref<Material> PrimitiveMesh::surface_get_material(int p_idx) const {
+ return material;
+}
+
+int PrimitiveMesh::get_blend_shape_count() const {
+ return 0;
+}
+
+StringName PrimitiveMesh::get_blend_shape_name(int p_index) const {
+ return StringName();
+}
+
+Rect3 PrimitiveMesh::get_aabb() const {
+ return aabb;
+}
+
+RID PrimitiveMesh::get_rid() const {
+ return mesh;
+}
+
+void PrimitiveMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("_update"), &PrimitiveMesh::_update);
+
+ ClassDB::bind_method(D_METHOD("set_material", "material:Material"), &PrimitiveMesh::set_material);
+ ClassDB::bind_method(D_METHOD("get_material:Material"), &PrimitiveMesh::get_material);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material");
+}
+
+void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
+ material = p_material;
+ if (!cache_is_dirty) {
+ // just apply it, else it'll happen when _update is called.
+ VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
+
+ _change_notify();
+ emit_changed();
+ };
+}
+
+Ref<Material> PrimitiveMesh::get_material() const {
+ return material;
+}
+
+PrimitiveMesh::PrimitiveMesh() {
+ // defaults
+ mesh = VisualServer::get_singleton()->mesh_create();
+
+ // assume primitive triangles as the type, correct for all but one and it will change this :)
+ primitive_type = Mesh::PRIMITIVE_TRIANGLES;
+
+ // make sure we do an update after we've finished constructing our object
+ cache_is_dirty = false;
+ _queue_update();
+}
+
+PrimitiveMesh::~PrimitiveMesh() {
+ VisualServer::get_singleton()->free(mesh);
+}
+
+/**
+ CapsuleMesh
+*/
+
+void CapsuleMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, y, z, u, v, w;
+ float onethird = 1.0 / 3.0;
+ float twothirds = 2.0 / 3.0;
+
+ set_aabb(Rect3(Vector3(-radius, (mid_height * -0.5) - radius, -radius), Vector3(radius * 2.0, mid_height + (2.0 * radius), radius * 2.0)));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ /* top hemisphere */
+ thisrow = 0;
+ prevrow = 0;
+ for (j = 0; j <= (rings + 1); j++) {
+ v = j;
+ w;
+
+ v /= (rings + 1);
+ w = sin(0.5 * Math_PI * v);
+ y = radius * cos(0.5 * Math_PI * v);
+
+ for (i = 0; i <= radial_segments; i++) {
+ u = i;
+ u /= radial_segments;
+
+ x = sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
+
+ Vector3 p = Vector3(x * radius * w, y, z * radius * w);
+ points.push_back(p + Vector3(0.0, 0.5 * mid_height, 0.0));
+ normals.push_back(p.normalized());
+ ADD_TANGENT(-z, 0.0, x, -1.0)
+ uvs.push_back(Vector2(u, v * onethird));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+ };
+
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ /* cylinder */
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (rings + 1); j++) {
+ v = j;
+ v /= (rings + 1);
+
+ y = mid_height * v;
+ y = (mid_height * 0.5) - y;
+
+ for (i = 0; i <= radial_segments; i++) {
+ u = i;
+ u /= radial_segments;
+
+ x = sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
+
+ Vector3 p = Vector3(x * radius, y, z * radius);
+ points.push_back(p);
+ normals.push_back(Vector3(x, 0.0, z));
+ ADD_TANGENT(-z, 0.0, x, -1.0)
+ uvs.push_back(Vector2(u, onethird + (v * onethird)));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+ };
+
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ /* bottom hemisphere */
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (rings + 1); j++) {
+ v = j;
+ w;
+
+ v /= (rings + 1);
+ v += 1.0;
+ w = sin(0.5 * Math_PI * v);
+ y = radius * cos(0.5 * Math_PI * v);
+
+ for (i = 0; i <= radial_segments; i++) {
+ float u = i;
+ u /= radial_segments;
+
+ x = sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
+
+ Vector3 p = Vector3(x * radius * w, y, z * radius * w);
+ points.push_back(p + Vector3(0.0, -0.5 * mid_height, 0.0));
+ normals.push_back(p.normalized());
+ ADD_TANGENT(-z, 0.0, x, -1.0)
+ uvs.push_back(Vector2(u, twothirds + ((v - 1.0) * onethird)));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+ };
+
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void CapsuleMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleMesh::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleMesh::get_radius);
+ ClassDB::bind_method(D_METHOD("set_mid_height", "mid_height"), &CapsuleMesh::set_mid_height);
+ ClassDB::bind_method(D_METHOD("get_mid_height"), &CapsuleMesh::get_mid_height);
+
+ ClassDB::bind_method(D_METHOD("set_radial_segments", "segments"), &CapsuleMesh::set_radial_segments);
+ ClassDB::bind_method(D_METHOD("get_radial_segments"), &CapsuleMesh::get_radial_segments);
+ ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CapsuleMesh::set_rings);
+ ClassDB::bind_method(D_METHOD("get_rings"), &CapsuleMesh::get_rings);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "mid_height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_mid_height", "get_mid_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
+}
+
+void CapsuleMesh::set_radius(const float p_radius) {
+ radius = p_radius;
+ _queue_update();
+}
+
+float CapsuleMesh::get_radius() const {
+ return radius;
+}
+
+void CapsuleMesh::set_mid_height(const float p_mid_height) {
+ mid_height = p_mid_height;
+ _queue_update();
+}
+
+float CapsuleMesh::get_mid_height() const {
+ return mid_height;
+}
+
+void CapsuleMesh::set_radial_segments(const int p_segments) {
+ radial_segments = p_segments > 4 ? p_segments : 4;
+ _queue_update();
+}
+
+int CapsuleMesh::get_radial_segments() const {
+ return radial_segments;
+}
+
+void CapsuleMesh::set_rings(const int p_rings) {
+ rings = p_rings > 1 ? p_rings : 1;
+ _queue_update();
+}
+
+int CapsuleMesh::get_rings() const {
+ return rings;
+}
+
+CapsuleMesh::CapsuleMesh() {
+ // defaults
+ radius = 0.5;
+ mid_height = 0.5;
+ radial_segments = 64;
+ rings = 8;
+}
+
+/**
+ CubeMesh
+*/
+
+void CubeMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, y, z;
+ float onethird = 1.0 / 3.0;
+ float twothirds = 2.0 / 3.0;
+
+ Vector3 start_pos = size * -0.5;
+
+ // set our bounding box
+ set_aabb(Rect3(start_pos, size));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ // front + back
+ y = start_pos.y;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= subdivide_h + 1; j++) {
+ x = start_pos.x;
+ for (i = 0; i <= subdivide_w + 1; i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_w + 1.0));
+ v /= (2.0 * (subdivide_h + 1.0));
+
+ // front
+ points.push_back(Vector3(x, -y, -start_pos.z)); // double negative on the Z!
+ normals.push_back(Vector3(0.0, 0.0, 1.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(u, v));
+ point++;
+
+ // back
+ points.push_back(Vector3(-x, -y, start_pos.z));
+ normals.push_back(Vector3(0.0, 0.0, -1.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(twothirds + u, v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ int i2 = i * 2;
+
+ // front
+ indices.push_back(prevrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ // back
+ indices.push_back(prevrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ };
+
+ x += size.x / (subdivide_w + 1.0);
+ };
+
+ y += size.y / (subdivide_h + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ // left + right
+ y = start_pos.y;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_h + 1); j++) {
+ z = start_pos.z;
+ for (i = 0; i <= (subdivide_d + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_d + 1.0));
+ v /= (2.0 * (subdivide_h + 1.0));
+
+ // right
+ points.push_back(Vector3(-start_pos.x, -y, -z));
+ normals.push_back(Vector3(1.0, 0.0, 0.0));
+ ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
+ uvs.push_back(Vector2(onethird + u, v));
+ point++;
+
+ // left
+ points.push_back(Vector3(start_pos.x, -y, z));
+ normals.push_back(Vector3(-1.0, 0.0, 0.0));
+ ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
+ uvs.push_back(Vector2(u, 0.5 + v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ int i2 = i * 2;
+
+ // right
+ indices.push_back(prevrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ // left
+ indices.push_back(prevrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ };
+
+ z += size.z / (subdivide_d + 1.0);
+ };
+
+ y += size.y / (subdivide_h + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ // top + bottom
+ z = start_pos.z;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_d + 1); j++) {
+ x = start_pos.x;
+ for (i = 0; i <= (subdivide_w + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_w + 1.0));
+ v /= (2.0 * (subdivide_d + 1.0));
+
+ // top
+ points.push_back(Vector3(-x, -start_pos.y, -z));
+ normals.push_back(Vector3(0.0, 1.0, 0.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(onethird + u, 0.5 + v));
+ point++;
+
+ // bottom
+ points.push_back(Vector3(x, start_pos.y, -z));
+ normals.push_back(Vector3(0.0, -1.0, 0.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(twothirds + u, 0.5 + v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ int i2 = i * 2;
+
+ // top
+ indices.push_back(prevrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ // bottom
+ indices.push_back(prevrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ };
+
+ x += size.x / (subdivide_w + 1.0);
+ };
+
+ z += size.z / (subdivide_d + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void CubeMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &CubeMesh::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &CubeMesh::get_size);
+
+ ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &CubeMesh::set_subdivide_width);
+ ClassDB::bind_method(D_METHOD("get_subdivide_width"), &CubeMesh::get_subdivide_width);
+ ClassDB::bind_method(D_METHOD("set_subdivide_height", "divisions"), &CubeMesh::set_subdivide_height);
+ ClassDB::bind_method(D_METHOD("get_subdivide_height"), &CubeMesh::get_subdivide_height);
+ ClassDB::bind_method(D_METHOD("set_subdivide_depth", "divisions"), &CubeMesh::set_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &CubeMesh::get_subdivide_depth);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_height", "get_subdivide_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth");
+}
+
+void CubeMesh::set_size(const Vector3 &p_size) {
+ size = p_size;
+ _queue_update();
+}
+
+Vector3 CubeMesh::get_size() const {
+ return size;
+}
+
+void CubeMesh::set_subdivide_width(const int p_subdivide) {
+ subdivide_w = p_subdivide > 0 ? p_subdivide : 0;
+ _queue_update();
+}
+
+int CubeMesh::get_subdivide_width() const {
+ return subdivide_w;
+}
+
+void CubeMesh::set_subdivide_height(const int p_subdivide) {
+ subdivide_h = p_subdivide > 0 ? p_subdivide : 0;
+ _queue_update();
+}
+
+int CubeMesh::get_subdivide_height() const {
+ return subdivide_h;
+}
+
+void CubeMesh::set_subdivide_depth(const int p_subdivide) {
+ subdivide_d = p_subdivide > 0 ? p_subdivide : 0;
+ _queue_update();
+}
+
+int CubeMesh::get_subdivide_depth() const {
+ return subdivide_d;
+}
+
+CubeMesh::CubeMesh() {
+ // defaults
+ size = Vector3(1.0, 1.0, 1.0);
+ subdivide_w = 0;
+ subdivide_h = 0;
+ subdivide_d = 0;
+}
+
+/**
+ CylinderMesh
+*/
+
+void CylinderMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, y, z, u, v, radius;
+
+ radius = bottom_radius > top_radius ? bottom_radius : top_radius;
+
+ set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0)));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ thisrow = 0;
+ prevrow = 0;
+ for (j = 0; j <= (rings + 1); j++) {
+ v = j;
+ v /= (rings + 1);
+
+ radius = top_radius + ((bottom_radius - top_radius) * v);
+
+ y = height * v;
+ y = (height * 0.5) - y;
+
+ for (i = 0; i <= radial_segments; i++) {
+ u = i;
+ u /= radial_segments;
+
+ x = sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
+
+ Vector3 p = Vector3(x * radius, y, z * radius);
+ points.push_back(p);
+ normals.push_back(Vector3(x, 0.0, z));
+ ADD_TANGENT(-z, 0.0, x, -1.0)
+ uvs.push_back(Vector2(u, v * 0.5));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+ };
+
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ // add top
+ if (top_radius > 0.0) {
+ y = height * 0.5;
+
+ thisrow = point;
+ points.push_back(Vector3(0.0, y, 0.0));
+ normals.push_back(Vector3(0.0, 1.0, 0.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+ uvs.push_back(Vector2(0.25, 0.75));
+ point++;
+
+ for (i = 0; i <= radial_segments; i++) {
+ float r = i;
+ r /= radial_segments;
+
+ x = sin(r * (Math_PI * 2.0));
+ z = cos(r * (Math_PI * 2.0));
+
+ u = ((x + 1.0) * 0.25);
+ v = 0.5 + ((z + 1.0) * 0.25);
+
+ Vector3 p = Vector3(x * top_radius, y, z * top_radius);
+ points.push_back(p);
+ normals.push_back(Vector3(0.0, 1.0, 0.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, 1.0)
+ uvs.push_back(Vector2(u, v));
+ point++;
+
+ if (i > 0) {
+ indices.push_back(thisrow);
+ indices.push_back(point - 1);
+ indices.push_back(point - 2);
+ };
+ };
+ };
+
+ // add bottom
+ if (bottom_radius > 0.0) {
+ y = height * -0.5;
+
+ thisrow = point;
+ points.push_back(Vector3(0.0, y, 0.0));
+ normals.push_back(Vector3(0.0, -1.0, 0.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0)
+ uvs.push_back(Vector2(0.75, 0.75));
+ point++;
+
+ for (i = 0; i <= radial_segments; i++) {
+ float r = i;
+ r /= radial_segments;
+
+ x = sin(r * (Math_PI * 2.0));
+ z = cos(r * (Math_PI * 2.0));
+
+ u = 0.5 + ((x + 1.0) * 0.25);
+ v = 1.0 - ((z + 1.0) * 0.25);
+
+ Vector3 p = Vector3(x * bottom_radius, y, z * bottom_radius);
+ points.push_back(p);
+ normals.push_back(Vector3(0.0, -1.0, 0.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0)
+ uvs.push_back(Vector2(u, v));
+ point++;
+
+ if (i > 0) {
+ indices.push_back(thisrow);
+ indices.push_back(point - 2);
+ indices.push_back(point - 1);
+ };
+ };
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void CylinderMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_top_radius", "radius"), &CylinderMesh::set_top_radius);
+ ClassDB::bind_method(D_METHOD("get_top_radius"), &CylinderMesh::get_top_radius);
+ ClassDB::bind_method(D_METHOD("set_bottom_radius", "radius"), &CylinderMesh::set_bottom_radius);
+ ClassDB::bind_method(D_METHOD("get_bottom_radius"), &CylinderMesh::get_bottom_radius);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &CylinderMesh::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &CylinderMesh::get_height);
+
+ ClassDB::bind_method(D_METHOD("set_radial_segments", "segments"), &CylinderMesh::set_radial_segments);
+ ClassDB::bind_method(D_METHOD("get_radial_segments"), &CylinderMesh::get_radial_segments);
+ ClassDB::bind_method(D_METHOD("set_rings", "rings"), &CylinderMesh::set_rings);
+ ClassDB::bind_method(D_METHOD("get_rings"), &CylinderMesh::get_rings);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "top_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_top_radius", "get_top_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "bottom_radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_bottom_radius", "get_bottom_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
+}
+
+void CylinderMesh::set_top_radius(const float p_radius) {
+ top_radius = p_radius;
+ _queue_update();
+}
+
+float CylinderMesh::get_top_radius() const {
+ return top_radius;
+}
+
+void CylinderMesh::set_bottom_radius(const float p_radius) {
+ bottom_radius = p_radius;
+ _queue_update();
+}
+
+float CylinderMesh::get_bottom_radius() const {
+ return bottom_radius;
+}
+
+void CylinderMesh::set_height(const float p_height) {
+ height = p_height;
+ _queue_update();
+}
+
+float CylinderMesh::get_height() const {
+ return height;
+}
+
+void CylinderMesh::set_radial_segments(const int p_segments) {
+ radial_segments = p_segments > 4 ? p_segments : 4;
+ _queue_update();
+}
+
+int CylinderMesh::get_radial_segments() const {
+ return radial_segments;
+}
+
+void CylinderMesh::set_rings(const int p_rings) {
+ rings = p_rings > 0 ? p_rings : 0;
+ _queue_update();
+}
+
+int CylinderMesh::get_rings() const {
+ return rings;
+}
+
+CylinderMesh::CylinderMesh() {
+ // defaults
+ top_radius = 0.5;
+ bottom_radius = 0.5;
+ height = 1.0;
+ radial_segments = 64;
+ rings = 4;
+}
+
+/**
+ PlaneMesh
+*/
+
+void PlaneMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, z;
+
+ Size2 start_pos = size * -0.5;
+
+ set_aabb(Rect3(Vector3(start_pos.x, 0.0, start_pos.y), Vector3(size.x, 0.0, size.y)));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ /* top + bottom */
+ z = start_pos.y;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_d + 1); j++) {
+ x = start_pos.x;
+ for (i = 0; i <= (subdivide_w + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (subdivide_w + 1.0);
+ v /= (subdivide_d + 1.0);
+
+ points.push_back(Vector3(-x, 0.0, -z));
+ normals.push_back(Vector3(0.0, 1.0, 0.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(u, v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+
+ x += size.x / (subdivide_w + 1.0);
+ };
+
+ z += size.y / (subdivide_d + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void PlaneMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &PlaneMesh::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &PlaneMesh::get_size);
+
+ ClassDB::bind_method(D_METHOD("set_subdivide_width", "subdivide"), &PlaneMesh::set_subdivide_width);
+ ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PlaneMesh::get_subdivide_width);
+ ClassDB::bind_method(D_METHOD("set_subdivide_depth", "subdivide"), &PlaneMesh::set_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PlaneMesh::get_subdivide_depth);
+
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth");
+}
+
+void PlaneMesh::set_size(const Size2 &p_size) {
+ size = p_size;
+ _queue_update();
+}
+
+Size2 PlaneMesh::get_size() const {
+ return size;
+}
+
+void PlaneMesh::set_subdivide_width(const int p_subdivide) {
+ subdivide_w = p_subdivide > 0 ? p_subdivide : 0;
+ _queue_update();
+}
+
+int PlaneMesh::get_subdivide_width() const {
+ return subdivide_w;
+}
+
+void PlaneMesh::set_subdivide_depth(const int p_subdivide) {
+ subdivide_d = p_subdivide > 0 ? p_subdivide : 0;
+ _queue_update();
+}
+
+int PlaneMesh::get_subdivide_depth() const {
+ return subdivide_d;
+}
+
+PlaneMesh::PlaneMesh() {
+ // defaults
+ size = Size2(1.0, 1.0);
+ subdivide_w = 0;
+ subdivide_d = 0;
+}
+
+/**
+ PrismMesh
+*/
+
+void PrismMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, y, z;
+ float onethird = 1.0 / 3.0;
+ float twothirds = 2.0 / 3.0;
+
+ Vector3 start_pos = size * -0.5;
+
+ // set our bounding box
+ set_aabb(Rect3(start_pos, size));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ /* front + back */
+ y = start_pos.y;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_h + 1); j++) {
+ float scale = (y - start_pos.y) / size.y;
+ float scaled_size_x = size.x * scale;
+ float start_x = start_pos.x;
+ float offset_front = 0.0;
+ float offset_back = 0.0;
+
+ start_x += (1.0 - scale) * size.x * left_to_right;
+ offset_front += (1.0 - scale) * onethird * left_to_right;
+ offset_back = (1.0 - scale) * onethird * (1.0 - left_to_right);
+
+ x = 0.0;
+ for (i = 0; i <= (subdivide_w + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_w + 1.0));
+ v /= (2.0 * (subdivide_h + 1.0));
+
+ u *= scale;
+
+ /* front */
+ points.push_back(Vector3(start_x + x, -y, -start_pos.z)); // double negative on the Z!
+ normals.push_back(Vector3(0.0, 0.0, 1.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(offset_front + u, v));
+ point++;
+
+ /* back */
+ points.push_back(Vector3(start_x + scaled_size_x - x, -y, start_pos.z));
+ normals.push_back(Vector3(0.0, 0.0, -1.0));
+ ADD_TANGENT(1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(twothirds + offset_back + u, v));
+ point++;
+
+ if (i > 0 && j == 1) {
+ int i2 = i * 2;
+
+ /* front */
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ /* back */
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ } else if (i > 0 && j > 0) {
+ int i2 = i * 2;
+
+ /* front */
+ indices.push_back(prevrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ /* back */
+ indices.push_back(prevrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ };
+
+ x += scale * size.x / (subdivide_w + 1.0);
+ };
+
+ y += size.y / (subdivide_h + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ /* left + right */
+ Vector3 normal_left, normal_right;
+
+ normal_left = Vector3(-size.y, size.x * left_to_right, 0.0);
+ normal_right = Vector3(size.y, size.x * left_to_right, 0.0);
+ normal_left.normalize();
+ normal_right.normalize();
+
+ y = start_pos.y;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_h + 1); j++) {
+ float left, right;
+ float scale = (y - start_pos.y) / size.y;
+
+ left = start_pos.x + (size.x * (1.0 - scale) * left_to_right);
+ right = left + (size.x * scale);
+
+ z = start_pos.z;
+ for (i = 0; i <= (subdivide_d + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_d + 1.0));
+ v /= (2.0 * (subdivide_h + 1.0));
+
+ /* right */
+ points.push_back(Vector3(right, -y, -z));
+ normals.push_back(normal_right);
+ ADD_TANGENT(0.0, 0.0, 1.0, -1.0);
+ uvs.push_back(Vector2(onethird + u, v));
+ point++;
+
+ /* left */
+ points.push_back(Vector3(left, -y, z));
+ normals.push_back(normal_left);
+ ADD_TANGENT(0.0, 0.0, -1.0, -1.0);
+ uvs.push_back(Vector2(u, 0.5 + v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ int i2 = i * 2;
+
+ /* right */
+ indices.push_back(prevrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+ indices.push_back(prevrow + i2);
+ indices.push_back(thisrow + i2);
+ indices.push_back(thisrow + i2 - 2);
+
+ /* left */
+ indices.push_back(prevrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ indices.push_back(prevrow + i2 + 1);
+ indices.push_back(thisrow + i2 + 1);
+ indices.push_back(thisrow + i2 - 1);
+ };
+
+ z += size.z / (subdivide_d + 1.0);
+ };
+
+ y += size.y / (subdivide_h + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ /* bottom */
+ z = start_pos.z;
+ thisrow = point;
+ prevrow = 0;
+ for (j = 0; j <= (subdivide_d + 1); j++) {
+ x = start_pos.x;
+ for (i = 0; i <= (subdivide_w + 1); i++) {
+ float u = i;
+ float v = j;
+ u /= (3.0 * (subdivide_w + 1.0));
+ v /= (2.0 * (subdivide_d + 1.0));
+
+ /* bottom */
+ points.push_back(Vector3(x, start_pos.y, -z));
+ normals.push_back(Vector3(0.0, -1.0, 0.0));
+ ADD_TANGENT(-1.0, 0.0, 0.0, -1.0);
+ uvs.push_back(Vector2(twothirds + u, 0.5 + v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ /* bottom */
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+
+ x += size.x / (subdivide_w + 1.0);
+ };
+
+ z += size.z / (subdivide_d + 1.0);
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void PrismMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_left_to_right", "left_to_right"), &PrismMesh::set_left_to_right);
+ ClassDB::bind_method(D_METHOD("get_left_to_right"), &PrismMesh::get_left_to_right);
+
+ ClassDB::bind_method(D_METHOD("set_size", "size"), &PrismMesh::set_size);
+ ClassDB::bind_method(D_METHOD("get_size"), &PrismMesh::get_size);
+
+ ClassDB::bind_method(D_METHOD("set_subdivide_width", "segments"), &PrismMesh::set_subdivide_width);
+ ClassDB::bind_method(D_METHOD("get_subdivide_width"), &PrismMesh::get_subdivide_width);
+ ClassDB::bind_method(D_METHOD("set_subdivide_height", "segments"), &PrismMesh::set_subdivide_height);
+ ClassDB::bind_method(D_METHOD("get_subdivide_height"), &PrismMesh::get_subdivide_height);
+ ClassDB::bind_method(D_METHOD("set_subdivide_depth", "segments"), &PrismMesh::set_subdivide_depth);
+ ClassDB::bind_method(D_METHOD("get_subdivide_depth"), &PrismMesh::get_subdivide_depth);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "left_to_right", PROPERTY_HINT_RANGE, "-2.0,2.0,0.1"), "set_left_to_right", "get_left_to_right");
+ ADD_PROPERTY(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_size", "get_size");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_width", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_width", "get_subdivide_width");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_height", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_height", "get_subdivide_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "subdivide_depth", PROPERTY_HINT_RANGE, "0,100,1"), "set_subdivide_depth", "get_subdivide_depth");
+}
+
+void PrismMesh::set_left_to_right(const float p_left_to_right) {
+ left_to_right = p_left_to_right;
+ _queue_update();
+}
+
+float PrismMesh::get_left_to_right() const {
+ return left_to_right;
+}
+
+void PrismMesh::set_size(const Vector3 &p_size) {
+ size = p_size;
+ _queue_update();
+}
+
+Vector3 PrismMesh::get_size() const {
+ return size;
+}
+
+void PrismMesh::set_subdivide_width(const int p_divisions) {
+ subdivide_w = p_divisions > 0 ? p_divisions : 0;
+ _queue_update();
+}
+
+int PrismMesh::get_subdivide_width() const {
+ return subdivide_w;
+}
+
+void PrismMesh::set_subdivide_height(const int p_divisions) {
+ subdivide_h = p_divisions > 0 ? p_divisions : 0;
+ _queue_update();
+}
+
+int PrismMesh::get_subdivide_height() const {
+ return subdivide_h;
+}
+
+void PrismMesh::set_subdivide_depth(const int p_divisions) {
+ subdivide_d = p_divisions > 0 ? p_divisions : 0;
+ _queue_update();
+}
+
+int PrismMesh::get_subdivide_depth() const {
+ return subdivide_d;
+}
+
+PrismMesh::PrismMesh() {
+ // defaults
+ left_to_right = 0.5;
+ size = Vector3(1.0, 1.0, 1.0);
+ subdivide_w = 0;
+ subdivide_h = 0;
+ subdivide_d = 0;
+}
+
+/**
+ QuadMesh
+*/
+
+void QuadMesh::_create_mesh_array(Array &p_arr) {
+ PoolVector<Vector3> faces;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+
+ faces.resize(4);
+ normals.resize(4);
+ tangents.resize(4 * 4);
+ uvs.resize(4);
+
+ for (int i = 0; i < 4; i++) {
+
+ static const Vector3 quad_faces[4] = {
+ Vector3(-1, -1, 0),
+ Vector3(-1, 1, 0),
+ Vector3(1, 1, 0),
+ Vector3(1, -1, 0),
+ };
+
+ faces.set(i, quad_faces[i]);
+ normals.set(i, Vector3(0, 0, 1));
+ tangents.set(i * 4 + 0, 1.0);
+ tangents.set(i * 4 + 1, 0.0);
+ tangents.set(i * 4 + 2, 0.0);
+ tangents.set(i * 4 + 3, 1.0);
+
+ static const Vector2 quad_uv[4] = {
+ Vector2(0, 1),
+ Vector2(0, 0),
+ Vector2(1, 0),
+ Vector2(1, 1),
+ };
+
+ uvs.set(i, quad_uv[i]);
+ }
+
+ p_arr[ARRAY_VERTEX] = faces;
+ p_arr[ARRAY_NORMAL] = normals;
+ p_arr[ARRAY_TANGENT] = tangents;
+ p_arr[ARRAY_TEX_UV] = uvs;
+};
+
+void QuadMesh::_bind_methods() {
+ // nothing here yet...
+}
+
+QuadMesh::QuadMesh() {
+ primitive_type = PRIMITIVE_TRIANGLE_FAN;
+}
+
+/**
+ SphereMesh
+*/
+
+void SphereMesh::_create_mesh_array(Array &p_arr) {
+ int i, j, prevrow, thisrow, point;
+ float x, y, z;
+
+ // set our bounding box
+ set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0)));
+
+ PoolVector<Vector3> points;
+ PoolVector<Vector3> normals;
+ PoolVector<float> tangents;
+ PoolVector<Vector2> uvs;
+ PoolVector<int> indices;
+ point = 0;
+
+#define ADD_TANGENT(m_x, m_y, m_z, m_d) \
+ tangents.push_back(m_x); \
+ tangents.push_back(m_y); \
+ tangents.push_back(m_z); \
+ tangents.push_back(m_d);
+
+ thisrow = 0;
+ prevrow = 0;
+ for (j = 0; j <= (rings + 1); j++) {
+ float v = j;
+ float w;
+
+ v /= (rings + 1);
+ w = sin(Math_PI * v);
+ y = height * (is_hemisphere ? 1.0 : 0.5) * cos(Math_PI * v);
+
+ for (i = 0; i <= radial_segments; i++) {
+ float u = i;
+ u /= radial_segments;
+
+ x = sin(u * (Math_PI * 2.0));
+ z = cos(u * (Math_PI * 2.0));
+
+ if (is_hemisphere && y < 0.0) {
+ points.push_back(Vector3(x * radius * w, 0.0, z * radius * w));
+ normals.push_back(Vector3(0.0, -1.0, 0.0));
+ } else {
+ Vector3 p = Vector3(x * radius * w, y, z * radius * w);
+ points.push_back(p);
+ normals.push_back(p.normalized());
+ };
+ ADD_TANGENT(-z, 0.0, x, -1.0)
+ uvs.push_back(Vector2(u, v));
+ point++;
+
+ if (i > 0 && j > 0) {
+ indices.push_back(prevrow + i - 1);
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i - 1);
+
+ indices.push_back(prevrow + i);
+ indices.push_back(thisrow + i);
+ indices.push_back(thisrow + i - 1);
+ };
+ };
+
+ prevrow = thisrow;
+ thisrow = point;
+ };
+
+ p_arr[VS::ARRAY_VERTEX] = points;
+ p_arr[VS::ARRAY_NORMAL] = normals;
+ p_arr[VS::ARRAY_TANGENT] = tangents;
+ p_arr[VS::ARRAY_TEX_UV] = uvs;
+ p_arr[VS::ARRAY_INDEX] = indices;
+}
+
+void SphereMesh::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("set_radius", "radius"), &SphereMesh::set_radius);
+ ClassDB::bind_method(D_METHOD("get_radius"), &SphereMesh::get_radius);
+ ClassDB::bind_method(D_METHOD("set_height", "height"), &SphereMesh::set_height);
+ ClassDB::bind_method(D_METHOD("get_height"), &SphereMesh::get_height);
+
+ ClassDB::bind_method(D_METHOD("set_radial_segments", "radial_segments"), &SphereMesh::set_radial_segments);
+ ClassDB::bind_method(D_METHOD("get_radial_segments"), &SphereMesh::get_radial_segments);
+ ClassDB::bind_method(D_METHOD("set_rings", "rings"), &SphereMesh::set_rings);
+ ClassDB::bind_method(D_METHOD("get_rings"), &SphereMesh::get_rings);
+
+ ClassDB::bind_method(D_METHOD("set_is_hemisphere", "is_hemisphere"), &SphereMesh::set_is_hemisphere);
+ ClassDB::bind_method(D_METHOD("get_is_hemisphere"), &SphereMesh::get_is_hemisphere);
+
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_radius", "get_radius");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "height", PROPERTY_HINT_RANGE, "0.1,100.0,0.1"), "set_height", "get_height");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "radial_segments", PROPERTY_HINT_RANGE, "1,100,1"), "set_radial_segments", "get_radial_segments");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "rings", PROPERTY_HINT_RANGE, "1,100,1"), "set_rings", "get_rings");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_hemisphere"), "set_is_hemisphere", "get_is_hemisphere");
+}
+
+void SphereMesh::set_radius(const float p_radius) {
+ radius = p_radius;
+ _queue_update();
+}
+
+float SphereMesh::get_radius() const {
+ return radius;
+}
+
+void SphereMesh::set_height(const float p_height) {
+ height = p_height;
+ _queue_update();
+}
+
+float SphereMesh::get_height() const {
+ return height;
+}
+
+void SphereMesh::set_radial_segments(const int p_radial_segments) {
+ radial_segments = p_radial_segments > 4 ? p_radial_segments : 4;
+ _queue_update();
+}
+
+int SphereMesh::get_radial_segments() const {
+ return radial_segments;
+}
+
+void SphereMesh::set_rings(const int p_rings) {
+ rings = p_rings > 1 ? p_rings : 1;
+ _queue_update();
+}
+
+int SphereMesh::get_rings() const {
+ return rings;
+}
+
+void SphereMesh::set_is_hemisphere(const bool p_is_hemisphere) {
+ is_hemisphere = p_is_hemisphere;
+ _queue_update();
+}
+
+bool SphereMesh::get_is_hemisphere() const {
+ return is_hemisphere;
+}
+
+SphereMesh::SphereMesh() {
+ // defaults
+ radius = 0.5;
+ height = 1.0;
+ radial_segments = 64;
+ rings = 32;
+ is_hemisphere = false;
+}
diff --git a/scene/resources/primitive_meshes.h b/scene/resources/primitive_meshes.h
new file mode 100644
index 0000000000..91d1af2ee1
--- /dev/null
+++ b/scene/resources/primitive_meshes.h
@@ -0,0 +1,312 @@
+/*************************************************************************/
+/* primitive_meshes.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 PRIMITIVE_MESHES_H
+#define PRIMITIVE_MESHES_H
+
+#include "scene/resources/mesh.h"
+
+///@TODO probably should change a few integers to unsigned integers...
+
+/**
+ @author Bastiaan Olij <mux213@gmail.com>
+
+ Base class for all the classes in this file, handles a number of code functions that are shared among all meshes.
+ This class is set appart that it assumes a single surface is always generated for our mesh.
+*/
+class PrimitiveMesh : public Mesh {
+
+ GDCLASS(PrimitiveMesh, Mesh);
+
+private:
+ RID mesh;
+ Rect3 aabb;
+
+ Ref<Material> material;
+
+ bool cache_is_dirty;
+ void _update();
+
+protected:
+ Mesh::PrimitiveType primitive_type;
+
+ static void _bind_methods();
+
+ virtual void _create_mesh_array(Array &p_arr) = 0;
+ void _queue_update();
+
+ void set_aabb(Rect3 p_aabb);
+
+public:
+ virtual int get_surface_count() const;
+ virtual int surface_get_array_len(int p_idx) const;
+ virtual int surface_get_array_index_len(int p_idx) const;
+ virtual Array surface_get_arrays(int p_surface) const;
+ virtual uint32_t surface_get_format(int p_idx) const;
+ virtual Mesh::PrimitiveType surface_get_primitive_type(int p_idx) const;
+ virtual Ref<Material> surface_get_material(int p_idx) const;
+ virtual int get_blend_shape_count() const;
+ virtual StringName get_blend_shape_name(int p_index) const;
+ virtual Rect3 get_aabb() const;
+ virtual RID get_rid() const;
+
+ void set_material(const Ref<Material> &p_material);
+ Ref<Material> get_material() const;
+
+ PrimitiveMesh();
+ ~PrimitiveMesh();
+};
+
+/**
+ Mesh for a simple capsule
+*/
+class CapsuleMesh : public PrimitiveMesh {
+ GDCLASS(CapsuleMesh, PrimitiveMesh);
+
+private:
+ float radius;
+ float mid_height;
+ int radial_segments;
+ int rings;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_radius(const float p_radius);
+ float get_radius() const;
+
+ void set_mid_height(const float p_mid_height);
+ float get_mid_height() const;
+
+ void set_radial_segments(const int p_segments);
+ int get_radial_segments() const;
+
+ void set_rings(const int p_rings);
+ int get_rings() const;
+
+ CapsuleMesh();
+};
+
+/**
+ Similar to test cube but with subdivision support and different texture coordinates
+*/
+class CubeMesh : public PrimitiveMesh {
+
+ GDCLASS(CubeMesh, PrimitiveMesh);
+
+private:
+ Vector3 size;
+ int subdivide_w;
+ int subdivide_h;
+ int subdivide_d;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
+
+ void set_subdivide_width(const int p_divisions);
+ int get_subdivide_width() const;
+
+ void set_subdivide_height(const int p_divisions);
+ int get_subdivide_height() const;
+
+ void set_subdivide_depth(const int p_divisions);
+ int get_subdivide_depth() const;
+
+ CubeMesh();
+};
+
+/**
+ A cylinder
+*/
+
+class CylinderMesh : public PrimitiveMesh {
+
+ GDCLASS(CylinderMesh, PrimitiveMesh);
+
+private:
+ float top_radius;
+ float bottom_radius;
+ float height;
+ int radial_segments;
+ int rings;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_top_radius(const float p_radius);
+ float get_top_radius() const;
+
+ void set_bottom_radius(const float p_radius);
+ float get_bottom_radius() const;
+
+ void set_height(const float p_height);
+ float get_height() const;
+
+ void set_radial_segments(const int p_segments);
+ int get_radial_segments() const;
+
+ void set_rings(const int p_rings);
+ int get_rings() const;
+
+ CylinderMesh();
+};
+
+/**
+ Similar to quadmesh but with tesselation support
+*/
+class PlaneMesh : public PrimitiveMesh {
+
+ GDCLASS(PlaneMesh, PrimitiveMesh);
+
+private:
+ Size2 size;
+ int subdivide_w;
+ int subdivide_d;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_size(const Size2 &p_size);
+ Size2 get_size() const;
+
+ void set_subdivide_width(const int p_divisions);
+ int get_subdivide_width() const;
+
+ void set_subdivide_depth(const int p_divisions);
+ int get_subdivide_depth() const;
+
+ PlaneMesh();
+};
+
+/**
+ A prism shapen, handy for ramps, triangles, etc.
+*/
+class PrismMesh : public PrimitiveMesh {
+
+ GDCLASS(PrismMesh, PrimitiveMesh);
+
+private:
+ float left_to_right;
+ Vector3 size;
+ int subdivide_w;
+ int subdivide_h;
+ int subdivide_d;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_left_to_right(const float p_left_to_right);
+ float get_left_to_right() const;
+
+ void set_size(const Vector3 &p_size);
+ Vector3 get_size() const;
+
+ void set_subdivide_width(const int p_divisions);
+ int get_subdivide_width() const;
+
+ void set_subdivide_height(const int p_divisions);
+ int get_subdivide_height() const;
+
+ void set_subdivide_depth(const int p_divisions);
+ int get_subdivide_depth() const;
+
+ PrismMesh();
+};
+
+/**
+ Our original quadmesh...
+*/
+
+class QuadMesh : public PrimitiveMesh {
+
+ GDCLASS(QuadMesh, PrimitiveMesh)
+
+private:
+ // nothing? really? Maybe add size some day atleast... :)
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ QuadMesh();
+};
+
+/**
+ A sphere..
+*/
+class SphereMesh : public PrimitiveMesh {
+
+ GDCLASS(SphereMesh, PrimitiveMesh);
+
+private:
+ float radius;
+ float height;
+ int radial_segments;
+ int rings;
+ bool is_hemisphere;
+
+protected:
+ static void _bind_methods();
+ virtual void _create_mesh_array(Array &p_arr);
+
+public:
+ void set_radius(const float p_radius);
+ float get_radius() const;
+
+ void set_height(const float p_height);
+ float get_height() const;
+
+ void set_radial_segments(const int p_radial_segments);
+ int get_radial_segments() const;
+
+ void set_rings(const int p_rings);
+ int get_rings() const;
+
+ void set_is_hemisphere(const bool p_is_hemisphere);
+ bool get_is_hemisphere() const;
+
+ SphereMesh();
+};
+
+#endif
diff --git a/scene/resources/segment_shape_2d.cpp b/scene/resources/segment_shape_2d.cpp
index 145374ff05..99062d693b 100644
--- a/scene/resources/segment_shape_2d.cpp
+++ b/scene/resources/segment_shape_2d.cpp
@@ -35,7 +35,7 @@
void SegmentShape2D::_update_shape() {
Rect2 r;
- r.pos = a;
+ r.position = a;
r.size = b;
Physics2DServer::get_singleton()->shape_set_data(get_rid(), r);
emit_changed();
@@ -69,7 +69,7 @@ void SegmentShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Rect2 SegmentShape2D::get_rect() const {
Rect2 rect;
- rect.pos = a;
+ rect.position = a;
rect.expand_to(b);
return rect;
}
@@ -121,7 +121,7 @@ void RayShape2D::draw(const RID &p_to_rid, const Color &p_color) {
Rect2 RayShape2D::get_rect() const {
Rect2 rect;
- rect.pos = Vector2();
+ rect.position = Vector2();
rect.expand_to(Vector2(0, length));
rect = rect.grow(0.707 * 4);
return rect;
diff --git a/scene/resources/shader_graph.h b/scene/resources/shader_graph.h
index b9ec294eb8..36578ce1f7 100644
--- a/scene/resources/shader_graph.h
+++ b/scene/resources/shader_graph.h
@@ -37,7 +37,7 @@
class ShaderGraph : public Shader {
GDCLASS( ShaderGraph, Shader );
- RES_BASE_EXTENSION("sgp");
+ RES_BASE_EXTENSION("vshader");
public:
diff --git a/scene/resources/shape.cpp b/scene/resources/shape.cpp
index b449932b17..77f2096d9b 100644
--- a/scene/resources/shape.cpp
+++ b/scene/resources/shape.cpp
@@ -49,14 +49,14 @@ void Shape::add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p
}
}
-Ref<Mesh> Shape::get_debug_mesh() {
+Ref<ArrayMesh> Shape::get_debug_mesh() {
if (debug_mesh_cache.is_valid())
return debug_mesh_cache;
Vector<Vector3> lines = _gen_debug_mesh_lines();
- debug_mesh_cache = Ref<Mesh>(memnew(Mesh));
+ debug_mesh_cache = Ref<ArrayMesh>(memnew(ArrayMesh));
if (!lines.empty()) {
//make mesh
diff --git a/scene/resources/shape.h b/scene/resources/shape.h
index 01b8db650e..c15638aeed 100644
--- a/scene/resources/shape.h
+++ b/scene/resources/shape.h
@@ -31,16 +31,16 @@
#define SHAPE_H
#include "resource.h"
-class Mesh;
+class ArrayMesh;
class Shape : public Resource {
GDCLASS(Shape, Resource);
OBJ_SAVE_TYPE(Shape);
- RES_BASE_EXTENSION("shp");
+ RES_BASE_EXTENSION("shape");
RID shape;
- Ref<Mesh> debug_mesh_cache;
+ Ref<ArrayMesh> debug_mesh_cache;
protected:
_FORCE_INLINE_ RID get_shape() const { return shape; }
@@ -50,7 +50,7 @@ protected:
public:
virtual RID get_rid() const { return shape; }
- Ref<Mesh> get_debug_mesh();
+ Ref<ArrayMesh> get_debug_mesh();
void add_vertices_to_array(PoolVector<Vector3> &array, const Transform &p_xform);
diff --git a/scene/resources/shape_line_2d.cpp b/scene/resources/shape_line_2d.cpp
index 89c1cea252..c38ae04eff 100644
--- a/scene/resources/shape_line_2d.cpp
+++ b/scene/resources/shape_line_2d.cpp
@@ -76,7 +76,7 @@ Rect2 LineShape2D::get_rect() const {
Vector2 l1[2] = { point - get_normal().tangent() * 100, point + get_normal().tangent() * 100 };
Vector2 l2[2] = { point, point + get_normal() * 30 };
Rect2 rect;
- rect.pos = l1[0];
+ rect.position = l1[0];
rect.expand_to(l1[1]);
rect.expand_to(l2[0]);
rect.expand_to(l2[1]);
diff --git a/scene/resources/sky_box.cpp b/scene/resources/sky_box.cpp
index 241675569f..61aaaf8fb4 100644
--- a/scene/resources/sky_box.cpp
+++ b/scene/resources/sky_box.cpp
@@ -30,22 +30,22 @@
#include "sky_box.h"
#include "io/image_loader.h"
-void SkyBox::set_radiance_size(RadianceSize p_size) {
+void Sky::set_radiance_size(RadianceSize p_size) {
ERR_FAIL_INDEX(p_size, RADIANCE_SIZE_MAX);
radiance_size = p_size;
_radiance_changed();
}
-SkyBox::RadianceSize SkyBox::get_radiance_size() const {
+Sky::RadianceSize Sky::get_radiance_size() const {
return radiance_size;
}
-void SkyBox::_bind_methods() {
+void Sky::_bind_methods() {
- ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &SkyBox::set_radiance_size);
- ClassDB::bind_method(D_METHOD("get_radiance_size"), &SkyBox::get_radiance_size);
+ ClassDB::bind_method(D_METHOD("set_radiance_size", "size"), &Sky::set_radiance_size);
+ ClassDB::bind_method(D_METHOD("get_radiance_size"), &Sky::get_radiance_size);
ADD_PROPERTY(PropertyInfo(Variant::INT, "radiance_size", PROPERTY_HINT_ENUM, "256,512,1024,2048"), "set_radiance_size", "get_radiance_size");
@@ -56,123 +56,450 @@ void SkyBox::_bind_methods() {
BIND_CONSTANT(RADIANCE_SIZE_MAX);
}
-SkyBox::SkyBox() {
+Sky::Sky() {
radiance_size = RADIANCE_SIZE_512;
}
/////////////////////////////////////////
-void ImageSkyBox::_radiance_changed() {
+void PanoramaSky::_radiance_changed() {
- if (cube_map_valid) {
+ if (panorama.is_valid()) {
static const int size[RADIANCE_SIZE_MAX] = {
256, 512, 1024, 2048
};
- VS::get_singleton()->skybox_set_texture(sky_box, cube_map, size[get_radiance_size()]);
+ VS::get_singleton()->sky_set_texture(sky, panorama->get_rid(), size[get_radiance_size()]);
}
}
-void ImageSkyBox::set_image_path(ImagePath p_image, const String &p_path) {
+void PanoramaSky::set_panorama(const Ref<Texture> &p_panorama) {
- ERR_FAIL_INDEX(p_image, IMAGE_PATH_MAX);
- image_path[p_image] = p_path;
+ panorama = p_panorama;
- bool all_ok = true;
- for (int i = 0; i < IMAGE_PATH_MAX; i++) {
- if (image_path[i] == String()) {
- all_ok = false;
- }
+ if (panorama.is_valid()) {
+
+ _radiance_changed();
+
+ } else {
+ VS::get_singleton()->sky_set_texture(sky, RID(), 0);
}
+}
- cube_map_valid = false;
+Ref<Texture> PanoramaSky::get_panorama() const {
- if (all_ok) {
+ return panorama;
+}
- Image images[IMAGE_PATH_MAX];
- int w = 0, h = 0;
- Image::Format format;
+RID PanoramaSky::get_rid() const {
- for (int i = 0; i < IMAGE_PATH_MAX; i++) {
- Error err = ImageLoader::load_image(image_path[i], &images[i]);
- if (err) {
- ERR_PRINTS("Error loading image for skybox: " + image_path[i]);
- return;
- }
+ return sky;
+}
+
+void PanoramaSky::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("set_panorama", "texture:Texture"), &PanoramaSky::set_panorama);
+ ClassDB::bind_method(D_METHOD("get_panorama:Texture"), &PanoramaSky::get_panorama);
+
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "panorama", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_panorama", "get_panorama");
+}
+
+PanoramaSky::PanoramaSky() {
+
+ sky = VS::get_singleton()->sky_create();
+}
+
+PanoramaSky::~PanoramaSky() {
+
+ VS::get_singleton()->free(sky);
+}
+//////////////////////////////////
+
+void ProceduralSky::_radiance_changed() {
+
+ if (update_queued)
+ return; //do nothing yet
+
+ static const int size[RADIANCE_SIZE_MAX] = {
+ 256, 512, 1024, 2048
+ };
+ VS::get_singleton()->sky_set_texture(sky, texture, size[get_radiance_size()]);
+}
+
+void ProceduralSky::_update_sky() {
+
+ update_queued = false;
+
+ PoolVector<uint8_t> imgdata;
+
+ static const int size[TEXTURE_SIZE_MAX] = {
+ 1024, 2048, 4096
+ };
+
+ int w = size[texture_size];
+ int h = w / 2;
+
+ imgdata.resize(w * h * 4); //RGBE
+
+ {
+ PoolVector<uint8_t>::Write dataw = imgdata.write();
+
+ uint32_t *ptr = (uint32_t *)dataw.ptr();
+
+ Color sky_top_linear = sky_top_color.to_linear();
+ Color sky_horizon_linear = sky_horizon_color.to_linear();
+
+ Color ground_bottom_linear = ground_bottom_color.to_linear();
+ Color ground_horizon_linear = ground_horizon_color.to_linear();
+
+ //Color sun_linear = sun_color.to_linear();
+
+ Vector3 sun(0, 0, -1);
+
+ sun = Basis(Vector3(1, 0, 0), Math::deg2rad(sun_latitude)).xform(sun);
+ sun = Basis(Vector3(0, 1, 0), Math::deg2rad(sun_longitude)).xform(sun);
+
+ sun.normalize();
+
+ for (int i = 0; i < w; i++) {
+
+ float u = float(i) / (w - 1);
+ float phi = u * 2.0 * Math_PI;
+
+ for (int j = 0; j < h; j++) {
+
+ float v = float(j) / (h - 1);
+ float theta = v * Math_PI;
- if (i == 0) {
- w = images[0].get_width();
- h = images[0].get_height();
- format = images[0].get_format();
- } else {
- if (images[i].get_width() != w || images[i].get_height() != h || images[i].get_format() != format) {
- ERR_PRINTS("Image size mismatch (" + itos(images[i].get_width()) + "," + itos(images[i].get_height()) + ":" + Image::get_format_name(images[i].get_format()) + " when it should be " + itos(w) + "," + itos(h) + ":" + Image::get_format_name(format) + "): " + image_path[i]);
- return;
+ Vector3 normal(
+ Math::sin(phi) * Math::sin(theta) * -1.0,
+ Math::cos(theta),
+ Math::cos(phi) * Math::sin(theta) * -1.0);
+
+ normal.normalize();
+
+ float v_angle = Math::acos(normal.y);
+
+ Color color;
+
+ if (normal.y < 0) {
+ //ground
+
+ float c = (v_angle - (Math_PI * 0.5)) / (Math_PI * 0.5);
+ color = ground_horizon_linear.linear_interpolate(ground_bottom_linear, Math::ease(c, ground_curve));
+ } else {
+ float c = v_angle / (Math_PI * 0.5);
+ color = sky_horizon_linear.linear_interpolate(sky_top_linear, Math::ease(1.0 - c, sky_curve));
+
+ float sun_angle = Math::rad2deg(Math::acos(sun.dot(normal)));
+
+ if (sun_angle < sun_angle_min) {
+ color = color.blend(sun_color);
+ } else if (sun_angle < sun_angle_max) {
+
+ float c2 = (sun_angle - sun_angle_min) / (sun_angle_max - sun_angle_min);
+ c2 = Math::ease(c2, sun_curve);
+
+ color = color.blend(sun_color).linear_interpolate(color, c2);
+ }
}
+
+ ptr[j * w + i] = color.to_rgbe9995();
}
}
+ }
- VS::get_singleton()->texture_allocate(cube_map, w, h, format, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_CUBEMAP | VS::TEXTURE_FLAG_MIPMAPS);
- for (int i = 0; i < IMAGE_PATH_MAX; i++) {
- VS::get_singleton()->texture_set_data(cube_map, images[i], VS::CubeMapSide(i));
- }
+ Ref<Image> image;
+ image.instance();
+ image->create(w, h, false, Image::FORMAT_RGBE9995, imgdata);
- cube_map_valid = true;
- _radiance_changed();
- }
+ VS::get_singleton()->texture_allocate(texture, w, h, Image::FORMAT_RGBE9995, VS::TEXTURE_FLAG_FILTER | VS::TEXTURE_FLAG_REPEAT);
+ VS::get_singleton()->texture_set_data(texture, image);
+ _radiance_changed();
}
-String ImageSkyBox::get_image_path(ImagePath p_image) const {
+void ProceduralSky::set_sky_top_color(const Color &p_sky_top) {
- ERR_FAIL_INDEX_V(p_image, IMAGE_PATH_MAX, String());
- return image_path[p_image];
+ sky_top_color = p_sky_top;
+ _queue_update();
}
-RID ImageSkyBox::get_rid() const {
+Color ProceduralSky::get_sky_top_color() const {
- return sky_box;
+ return sky_top_color;
}
-void ImageSkyBox::_bind_methods() {
+void ProceduralSky::set_sky_horizon_color(const Color &p_sky_horizon) {
- ClassDB::bind_method(D_METHOD("set_image_path", "image", "path"), &ImageSkyBox::set_image_path);
- ClassDB::bind_method(D_METHOD("get_image_path", "image"), &ImageSkyBox::get_image_path);
+ sky_horizon_color = p_sky_horizon;
+ _queue_update();
+}
+Color ProceduralSky::get_sky_horizon_color() const {
- List<String> extensions;
- ImageLoader::get_recognized_extensions(&extensions);
- String hints;
- for (List<String>::Element *E = extensions.front(); E; E = E->next()) {
- if (hints != String()) {
- hints += ",";
- }
- hints += "*." + E->get();
- }
+ return sky_horizon_color;
+}
+
+void ProceduralSky::set_sky_curve(float p_curve) {
+
+ sky_curve = p_curve;
+ _queue_update();
+}
+float ProceduralSky::get_sky_curve() const {
+
+ return sky_curve;
+}
+
+void ProceduralSky::set_sky_energy(float p_energy) {
+
+ sky_energy = p_energy;
+ _queue_update();
+}
+float ProceduralSky::get_sky_energy() const {
+
+ return sky_energy;
+}
+
+void ProceduralSky::set_ground_bottom_color(const Color &p_ground_bottom) {
+
+ ground_bottom_color = p_ground_bottom;
+ _queue_update();
+}
+Color ProceduralSky::get_ground_bottom_color() const {
+
+ return ground_bottom_color;
+}
+
+void ProceduralSky::set_ground_horizon_color(const Color &p_ground_horizon) {
+
+ ground_horizon_color = p_ground_horizon;
+ _queue_update();
+}
+Color ProceduralSky::get_ground_horizon_color() const {
+
+ return ground_horizon_color;
+}
+
+void ProceduralSky::set_ground_curve(float p_curve) {
- ADD_GROUP("Image Path", "image_path_");
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_negative_x", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_NEGATIVE_X);
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_positive_x", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_POSITIVE_X);
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_negative_y", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_NEGATIVE_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_positive_y", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_POSITIVE_Y);
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_negative_z", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_NEGATIVE_Z);
- ADD_PROPERTYI(PropertyInfo(Variant::STRING, "image_path_positive_z", PROPERTY_HINT_FILE, hints), "set_image_path", "get_image_path", IMAGE_PATH_POSITIVE_Z);
+ ground_curve = p_curve;
+ _queue_update();
+}
+float ProceduralSky::get_ground_curve() const {
+
+ return ground_curve;
+}
+
+void ProceduralSky::set_ground_energy(float p_energy) {
+
+ ground_energy = p_energy;
+ _queue_update();
+}
+float ProceduralSky::get_ground_energy() const {
+
+ return ground_energy;
+}
+
+void ProceduralSky::set_sun_color(const Color &p_sun) {
+
+ sun_color = p_sun;
+ _queue_update();
+}
+Color ProceduralSky::get_sun_color() const {
+
+ return sun_color;
+}
+
+void ProceduralSky::set_sun_latitude(float p_angle) {
+
+ sun_latitude = p_angle;
+ _queue_update();
+}
+float ProceduralSky::get_sun_latitude() const {
+
+ return sun_latitude;
+}
+
+void ProceduralSky::set_sun_longitude(float p_angle) {
+
+ sun_longitude = p_angle;
+ _queue_update();
+}
+float ProceduralSky::get_sun_longitude() const {
+
+ return sun_longitude;
+}
+
+void ProceduralSky::set_sun_angle_min(float p_angle) {
+
+ sun_angle_min = p_angle;
+ _queue_update();
+}
+float ProceduralSky::get_sun_angle_min() const {
+
+ return sun_angle_min;
+}
+
+void ProceduralSky::set_sun_angle_max(float p_angle) {
+
+ sun_angle_max = p_angle;
+ _queue_update();
+}
+float ProceduralSky::get_sun_angle_max() const {
+
+ return sun_angle_max;
+}
+
+void ProceduralSky::set_sun_curve(float p_curve) {
+
+ sun_curve = p_curve;
+ _queue_update();
+}
+float ProceduralSky::get_sun_curve() const {
+
+ return sun_curve;
+}
+
+void ProceduralSky::set_sun_energy(float p_energy) {
+
+ sun_energy = p_energy;
+ _queue_update();
+}
+float ProceduralSky::get_sun_energy() const {
+
+ return sun_energy;
+}
+
+void ProceduralSky::set_texture_size(TextureSize p_size) {
+ ERR_FAIL_INDEX(p_size, TEXTURE_SIZE_MAX);
+
+ texture_size = p_size;
+ _queue_update();
+}
+ProceduralSky::TextureSize ProceduralSky::get_texture_size() const {
+ return texture_size;
+}
+
+RID ProceduralSky::get_rid() const {
+ return sky;
+}
+
+void ProceduralSky::_queue_update() {
+
+ if (update_queued)
+ return;
+
+ update_queued = true;
+ call_deferred("_update_sky");
+}
+
+void ProceduralSky::_bind_methods() {
+
+ ClassDB::bind_method(D_METHOD("_update_sky"), &ProceduralSky::_update_sky);
+
+ ClassDB::bind_method(D_METHOD("set_sky_top_color", "color"), &ProceduralSky::set_sky_top_color);
+ ClassDB::bind_method(D_METHOD("get_sky_top_color"), &ProceduralSky::get_sky_top_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_horizon_color", "color"), &ProceduralSky::set_sky_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_sky_horizon_color"), &ProceduralSky::get_sky_horizon_color);
+
+ ClassDB::bind_method(D_METHOD("set_sky_curve", "curve"), &ProceduralSky::set_sky_curve);
+ ClassDB::bind_method(D_METHOD("get_sky_curve"), &ProceduralSky::get_sky_curve);
+
+ ClassDB::bind_method(D_METHOD("set_sky_energy", "energy"), &ProceduralSky::set_sky_energy);
+ ClassDB::bind_method(D_METHOD("get_sky_energy"), &ProceduralSky::get_sky_energy);
+
+ ClassDB::bind_method(D_METHOD("set_ground_bottom_color", "color"), &ProceduralSky::set_ground_bottom_color);
+ ClassDB::bind_method(D_METHOD("get_ground_bottom_color"), &ProceduralSky::get_ground_bottom_color);
- BIND_CONSTANT(IMAGE_PATH_NEGATIVE_X);
- BIND_CONSTANT(IMAGE_PATH_POSITIVE_X);
- BIND_CONSTANT(IMAGE_PATH_NEGATIVE_Y);
- BIND_CONSTANT(IMAGE_PATH_POSITIVE_Y);
- BIND_CONSTANT(IMAGE_PATH_NEGATIVE_Z);
- BIND_CONSTANT(IMAGE_PATH_POSITIVE_Z);
- BIND_CONSTANT(IMAGE_PATH_MAX);
+ ClassDB::bind_method(D_METHOD("set_ground_horizon_color", "color"), &ProceduralSky::set_ground_horizon_color);
+ ClassDB::bind_method(D_METHOD("get_ground_horizon_color"), &ProceduralSky::get_ground_horizon_color);
+
+ ClassDB::bind_method(D_METHOD("set_ground_curve", "curve"), &ProceduralSky::set_ground_curve);
+ ClassDB::bind_method(D_METHOD("get_ground_curve"), &ProceduralSky::get_ground_curve);
+
+ ClassDB::bind_method(D_METHOD("set_ground_energy", "energy"), &ProceduralSky::set_ground_energy);
+ ClassDB::bind_method(D_METHOD("get_ground_energy"), &ProceduralSky::get_ground_energy);
+
+ ClassDB::bind_method(D_METHOD("set_sun_color", "color"), &ProceduralSky::set_sun_color);
+ ClassDB::bind_method(D_METHOD("get_sun_color"), &ProceduralSky::get_sun_color);
+
+ ClassDB::bind_method(D_METHOD("set_sun_latitude", "degrees"), &ProceduralSky::set_sun_latitude);
+ ClassDB::bind_method(D_METHOD("get_sun_latitude"), &ProceduralSky::get_sun_latitude);
+
+ ClassDB::bind_method(D_METHOD("set_sun_longitude", "degrees"), &ProceduralSky::set_sun_longitude);
+ ClassDB::bind_method(D_METHOD("get_sun_longitude"), &ProceduralSky::get_sun_longitude);
+
+ ClassDB::bind_method(D_METHOD("set_sun_angle_min", "degrees"), &ProceduralSky::set_sun_angle_min);
+ ClassDB::bind_method(D_METHOD("get_sun_angle_min"), &ProceduralSky::get_sun_angle_min);
+
+ ClassDB::bind_method(D_METHOD("set_sun_angle_max", "degrees"), &ProceduralSky::set_sun_angle_max);
+ ClassDB::bind_method(D_METHOD("get_sun_angle_max"), &ProceduralSky::get_sun_angle_max);
+
+ ClassDB::bind_method(D_METHOD("set_sun_curve", "curve"), &ProceduralSky::set_sun_curve);
+ ClassDB::bind_method(D_METHOD("get_sun_curve"), &ProceduralSky::get_sun_curve);
+
+ ClassDB::bind_method(D_METHOD("set_sun_energy", "energy"), &ProceduralSky::set_sun_energy);
+ ClassDB::bind_method(D_METHOD("get_sun_energy"), &ProceduralSky::get_sun_energy);
+
+ ClassDB::bind_method(D_METHOD("set_texture_size", "size"), &ProceduralSky::set_texture_size);
+ ClassDB::bind_method(D_METHOD("get_texture_size"), &ProceduralSky::get_texture_size);
+
+ ADD_GROUP("Sky", "sky_");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_top_color"), "set_sky_top_color", "get_sky_top_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sky_horizon_color"), "set_sky_horizon_color", "get_sky_horizon_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_curve", PROPERTY_HINT_EXP_EASING), "set_sky_curve", "get_sky_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sky_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sky_energy", "get_sky_energy");
+
+ ADD_GROUP("Ground", "ground_");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_bottom_color"), "set_ground_bottom_color", "get_ground_bottom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "ground_horizon_color"), "set_ground_horizon_color", "get_ground_horizon_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_curve", PROPERTY_HINT_EXP_EASING), "set_ground_curve", "get_ground_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "ground_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_ground_energy", "get_ground_energy");
+
+ ADD_GROUP("Sun", "sun_");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "sun_color"), "set_sun_color", "get_sun_color");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_latitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_latitude", "get_sun_latitude");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_longitude", PROPERTY_HINT_RANGE, "-180,180,0.01"), "set_sun_longitude", "get_sun_longitude");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_min", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_min", "get_sun_angle_min");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_angle_max", PROPERTY_HINT_RANGE, "0,360,0.01"), "set_sun_angle_max", "get_sun_angle_max");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_curve", PROPERTY_HINT_EXP_EASING), "set_sun_curve", "get_sun_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::REAL, "sun_energy", PROPERTY_HINT_RANGE, "0,64,0.01"), "set_sun_energy", "get_sun_energy");
+
+ ADD_GROUP("Texture", "texture_");
+ ADD_PROPERTY(PropertyInfo(Variant::INT, "texture_size", PROPERTY_HINT_ENUM, "1024,2048,4096"), "set_texture_size", "get_texture_size");
}
-ImageSkyBox::ImageSkyBox() {
+ProceduralSky::ProceduralSky() {
+
+ sky = VS::get_singleton()->sky_create();
+ texture = VS::get_singleton()->texture_create();
+
+ update_queued = false;
+
+ sky_top_color = Color::hex(0x4d67e8ff);
+ sky_horizon_color = Color::hex(0x8ed2e8ff);
+ sky_curve = 0.25;
+ sky_energy = 1;
+
+ ground_bottom_color = Color::hex(0x322719ff);
+ ground_horizon_color = Color::hex(0x543610ff);
+ ground_curve = 0.25;
+ ground_energy = 1;
+
+ sun_color = Color(1, 1, 1);
+ sun_latitude = 35;
+ sun_longitude = 0;
+ sun_angle_min = 1;
+ sun_angle_max = 100;
+ sun_curve = 0.05;
+ sun_energy = 16;
+
+ texture_size = TEXTURE_SIZE_1024;
- cube_map = VS::get_singleton()->texture_create();
- sky_box = VS::get_singleton()->skybox_create();
- cube_map_valid = false;
+ _queue_update();
}
-ImageSkyBox::~ImageSkyBox() {
+ProceduralSky::~ProceduralSky() {
- VS::get_singleton()->free(cube_map);
- VS::get_singleton()->free(sky_box);
+ VS::get_singleton()->free(sky);
+ VS::get_singleton()->free(texture);
}
diff --git a/scene/resources/sky_box.h b/scene/resources/sky_box.h
index f748ac1e2d..7b707af3a6 100644
--- a/scene/resources/sky_box.h
+++ b/scene/resources/sky_box.h
@@ -27,13 +27,13 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef SKYBOX_H
-#define SKYBOX_H
+#ifndef Sky_H
+#define Sky_H
#include "scene/resources/texture.h"
-class SkyBox : public Resource {
- GDCLASS(SkyBox, Resource);
+class Sky : public Resource {
+ GDCLASS(Sky, Resource);
public:
enum RadianceSize {
@@ -54,46 +54,131 @@ protected:
public:
void set_radiance_size(RadianceSize p_size);
RadianceSize get_radiance_size() const;
- SkyBox();
+ Sky();
};
-VARIANT_ENUM_CAST(SkyBox::RadianceSize)
+VARIANT_ENUM_CAST(Sky::RadianceSize)
-class ImageSkyBox : public SkyBox {
- GDCLASS(ImageSkyBox, SkyBox);
+class PanoramaSky : public Sky {
+ GDCLASS(PanoramaSky, Sky);
+
+private:
+ RID sky;
+ Ref<Texture> panorama;
+
+protected:
+ static void _bind_methods();
+ virtual void _radiance_changed();
public:
- enum ImagePath {
- IMAGE_PATH_NEGATIVE_X,
- IMAGE_PATH_POSITIVE_X,
- IMAGE_PATH_NEGATIVE_Y,
- IMAGE_PATH_POSITIVE_Y,
- IMAGE_PATH_NEGATIVE_Z,
- IMAGE_PATH_POSITIVE_Z,
- IMAGE_PATH_MAX
+ void set_panorama(const Ref<Texture> &p_panorama);
+ Ref<Texture> get_panorama() const;
+
+ virtual RID get_rid() const;
+
+ PanoramaSky();
+ ~PanoramaSky();
+};
+
+class ProceduralSky : public Sky {
+ GDCLASS(ProceduralSky, Sky);
+
+public:
+ enum TextureSize {
+ TEXTURE_SIZE_1024,
+ TEXTURE_SIZE_2048,
+ TEXTURE_SIZE_4096,
+ TEXTURE_SIZE_MAX
};
private:
- RID cube_map;
- RID sky_box;
- bool cube_map_valid;
+ Color sky_top_color;
+ Color sky_horizon_color;
+ float sky_curve;
+ float sky_energy;
+
+ Color ground_bottom_color;
+ Color ground_horizon_color;
+ float ground_curve;
+ float ground_energy;
+
+ Color sun_color;
+ float sun_latitude;
+ float sun_longitude;
+ float sun_angle_min;
+ float sun_angle_max;
+ float sun_curve;
+ float sun_energy;
+
+ TextureSize texture_size;
+
+ RID sky;
+ RID texture;
- String image_path[IMAGE_PATH_MAX];
+ bool update_queued;
protected:
static void _bind_methods();
virtual void _radiance_changed();
+ void _update_sky();
+ void _queue_update();
+
public:
- void set_image_path(ImagePath p_image, const String &p_path);
- String get_image_path(ImagePath p_image) const;
+ void set_sky_top_color(const Color &p_sky_top);
+ Color get_sky_top_color() const;
+
+ void set_sky_horizon_color(const Color &p_sky_horizon);
+ Color get_sky_horizon_color() const;
+
+ void set_sky_curve(float p_curve);
+ float get_sky_curve() const;
+
+ void set_sky_energy(float p_energy);
+ float get_sky_energy() const;
+
+ void set_ground_bottom_color(const Color &p_ground_bottom);
+ Color get_ground_bottom_color() const;
+
+ void set_ground_horizon_color(const Color &p_ground_horizon);
+ Color get_ground_horizon_color() const;
+
+ void set_ground_curve(float p_curve);
+ float get_ground_curve() const;
+
+ void set_ground_energy(float p_energy);
+ float get_ground_energy() const;
+
+ void set_sun_color(const Color &p_sun);
+ Color get_sun_color() const;
+
+ void set_sun_latitude(float p_angle);
+ float get_sun_latitude() const;
+
+ void set_sun_longitude(float p_angle);
+ float get_sun_longitude() const;
+
+ void set_sun_angle_min(float p_angle);
+ float get_sun_angle_min() const;
+
+ void set_sun_angle_max(float p_angle);
+ float get_sun_angle_max() const;
+
+ void set_sun_curve(float p_curve);
+ float get_sun_curve() const;
+
+ void set_sun_energy(float p_energy);
+ float get_sun_energy() const;
+
+ void set_texture_size(TextureSize p_size);
+ TextureSize get_texture_size() const;
virtual RID get_rid() const;
- ImageSkyBox();
- ~ImageSkyBox();
+ ProceduralSky();
+ ~ProceduralSky();
};
-VARIANT_ENUM_CAST(ImageSkyBox::ImagePath)
+VARIANT_ENUM_CAST(ProceduralSky::TextureSize)
-#endif // SKYBOX_H
+#endif // Sky_H
diff --git a/scene/resources/style_box.cpp b/scene/resources/style_box.cpp
index 13529c8572..2714ffec10 100644
--- a/scene/resources/style_box.cpp
+++ b/scene/resources/style_box.cpp
@@ -114,6 +114,19 @@ RES StyleBoxTexture::get_texture() const {
return texture;
}
+void StyleBoxTexture::set_normal_map(RES p_normal_map) {
+
+ if (normal_map == p_normal_map)
+ return;
+ normal_map = p_normal_map;
+ emit_changed();
+}
+
+RES StyleBoxTexture::get_normal_map() const {
+
+ return normal_map;
+}
+
void StyleBoxTexture::set_margin_size(Margin p_margin, float p_size) {
margin[p_margin] = p_size;
@@ -138,12 +151,16 @@ void StyleBoxTexture::draw(RID p_canvas_item, const Rect2 &p_rect) const {
texture->get_rect_region(rect, src_rect, rect, src_rect);
- rect.pos.x -= expand_margin[MARGIN_LEFT];
- rect.pos.y -= expand_margin[MARGIN_TOP];
+ rect.position.x -= expand_margin[MARGIN_LEFT];
+ rect.position.y -= expand_margin[MARGIN_TOP];
rect.size.x += expand_margin[MARGIN_LEFT] + expand_margin[MARGIN_RIGHT];
rect.size.y += expand_margin[MARGIN_TOP] + expand_margin[MARGIN_BOTTOM];
- VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate);
+ RID normal_rid;
+ if (normal_map.is_valid())
+ normal_rid = normal_map->get_rid();
+
+ VisualServer::get_singleton()->canvas_item_add_nine_patch(p_canvas_item, rect, src_rect, texture->get_rid(), Vector2(margin[MARGIN_LEFT], margin[MARGIN_TOP]), Vector2(margin[MARGIN_RIGHT], margin[MARGIN_BOTTOM]), VS::NINE_PATCH_STRETCH, VS::NINE_PATCH_STRETCH, draw_center, modulate, normal_rid);
}
void StyleBoxTexture::set_draw_center(bool p_draw) {
@@ -209,6 +226,9 @@ void StyleBoxTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_texture", "texture:Texture"), &StyleBoxTexture::set_texture);
ClassDB::bind_method(D_METHOD("get_texture:Texture"), &StyleBoxTexture::get_texture);
+ ClassDB::bind_method(D_METHOD("set_normal_map", "normal_map:Texture"), &StyleBoxTexture::set_normal_map);
+ ClassDB::bind_method(D_METHOD("get_normal_map:Texture"), &StyleBoxTexture::get_normal_map);
+
ClassDB::bind_method(D_METHOD("set_margin_size", "margin", "size"), &StyleBoxTexture::set_margin_size);
ClassDB::bind_method(D_METHOD("get_margin_size", "margin"), &StyleBoxTexture::get_margin_size);
@@ -227,6 +247,7 @@ void StyleBoxTexture::_bind_methods() {
ADD_SIGNAL(MethodInfo("texture_changed"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_texture", "get_texture");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "normal_map", PROPERTY_HINT_RESOURCE_TYPE, "Texture"), "set_normal_map", "get_normal_map");
ADD_PROPERTYNZ(PropertyInfo(Variant::RECT2, "region_rect"), "set_region_rect", "get_region_rect");
ADD_GROUP("Margin", "margin_");
ADD_PROPERTYI(PropertyInfo(Variant::REAL, "margin_left", PROPERTY_HINT_RANGE, "0,2048,1"), "set_margin_size", "get_margin_size", MARGIN_LEFT);
@@ -297,6 +318,15 @@ int StyleBoxFlat::get_border_size() const {
return border_size;
}
+void StyleBoxFlat::_set_additional_border_size(Margin p_margin, int p_size) {
+ additional_border_size[p_margin] = p_size;
+ emit_changed();
+}
+
+int StyleBoxFlat::_get_additional_border_size(Margin p_margin) const {
+ return additional_border_size[p_margin];
+}
+
void StyleBoxFlat::set_border_blend(bool p_blend) {
blend = p_blend;
@@ -343,20 +373,26 @@ void StyleBoxFlat::draw(RID p_canvas_item, const Rect2 &p_rect) const {
color_downright.b = (border_size - i) * color_downright.b / border_size + i * bg_color.b / border_size;
}
- vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.pos.x, r.pos.y + r.size.y - 1), Size2(r.size.x, 1)), color_downright);
- vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.pos.x + r.size.x - 1, r.pos.y), Size2(1, r.size.y)), color_downright);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.position.x, r.position.y + r.size.y - 1), Size2(r.size.x, 1)), color_downright);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r.position.x + r.size.x - 1, r.position.y), Size2(1, r.size.y)), color_downright);
- vs->canvas_item_add_rect(p_canvas_item, Rect2(r.pos, Size2(r.size.x, 1)), color_upleft);
- vs->canvas_item_add_rect(p_canvas_item, Rect2(r.pos, Size2(1, r.size.y)), color_upleft);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, Size2(r.size.x, 1)), color_upleft);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, Size2(1, r.size.y)), color_upleft);
- r.pos.x++;
- r.pos.y++;
+ r.position.x++;
+ r.position.y++;
r.size.x -= 2;
r.size.y -= 2;
}
if (draw_center)
- vs->canvas_item_add_rect(p_canvas_item, Rect2(r.pos, r.size), bg_color);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(r.position, r.size), bg_color);
+
+ Rect2i r_add = p_rect;
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y - additional_border_size[MARGIN_TOP]), Size2(r_add.size.width + additional_border_size[MARGIN_LEFT] + additional_border_size[MARGIN_RIGHT], additional_border_size[MARGIN_TOP])), light_color);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y), Size2(additional_border_size[MARGIN_LEFT], r_add.size.height)), light_color);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x + r_add.size.width, r_add.position.y), Size2(additional_border_size[MARGIN_RIGHT], r_add.size.height)), dark_color);
+ vs->canvas_item_add_rect(p_canvas_item, Rect2(Point2i(r_add.position.x - additional_border_size[MARGIN_LEFT], r_add.position.y + r_add.size.height), Size2(r_add.size.width + additional_border_size[MARGIN_LEFT] + additional_border_size[MARGIN_RIGHT], additional_border_size[MARGIN_BOTTOM])), dark_color);
}
float StyleBoxFlat::get_style_margin(Margin p_margin) const {
@@ -394,6 +430,10 @@ StyleBoxFlat::StyleBoxFlat() {
draw_center = true;
blend = true;
border_size = 0;
+ additional_border_size[0] = 0;
+ additional_border_size[1] = 0;
+ additional_border_size[2] = 0;
+ additional_border_size[3] = 0;
}
StyleBoxFlat::~StyleBoxFlat() {
}
diff --git a/scene/resources/style_box.h b/scene/resources/style_box.h
index e14a536879..7547c2ea81 100644
--- a/scene/resources/style_box.h
+++ b/scene/resources/style_box.h
@@ -39,7 +39,7 @@
class StyleBox : public Resource {
GDCLASS(StyleBox, Resource);
- RES_BASE_EXTENSION("sbx");
+ RES_BASE_EXTENSION("stylebox");
OBJ_SAVE_TYPE(StyleBox);
float margin[4];
@@ -81,6 +81,7 @@ class StyleBoxTexture : public StyleBox {
float margin[4];
Rect2 region_rect;
Ref<Texture> texture;
+ Ref<Texture> normal_map;
bool draw_center;
Color modulate;
@@ -101,6 +102,9 @@ public:
void set_texture(RES p_texture);
RES get_texture() const;
+ void set_normal_map(RES p_normal_map);
+ RES get_normal_map() const;
+
void set_draw_center(bool p_draw);
bool get_draw_center() const;
virtual Size2 get_center_size() const;
@@ -123,6 +127,7 @@ class StyleBoxFlat : public StyleBox {
Color dark_color;
int border_size;
+ int additional_border_size[4];
bool draw_center;
bool blend;
@@ -143,6 +148,9 @@ public:
void set_border_size(int p_size);
int get_border_size() const;
+ void _set_additional_border_size(Margin p_margin, int p_size);
+ int _get_additional_border_size(Margin p_margin) const;
+
void set_border_blend(bool p_blend);
bool get_border_blend() const;
diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp
index 4c36d79a7a..60fb97c792 100644
--- a/scene/resources/surface_tool.cpp
+++ b/scene/resources/surface_tool.cpp
@@ -224,13 +224,13 @@ void SurfaceTool::add_index(int p_index) {
index_array.push_back(p_index);
}
-Ref<Mesh> SurfaceTool::commit(const Ref<Mesh> &p_existing) {
+Ref<ArrayMesh> SurfaceTool::commit(const Ref<ArrayMesh> &p_existing) {
- Ref<Mesh> mesh;
+ Ref<ArrayMesh> mesh;
if (p_existing.is_valid())
mesh = p_existing;
else
- mesh = Ref<Mesh>(memnew(Mesh));
+ mesh.instance();
int varr_len = vertex_array.size();
diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h
index b143086e11..753c3626b8 100644
--- a/scene/resources/surface_tool.h
+++ b/scene/resources/surface_tool.h
@@ -125,7 +125,7 @@ public:
void create_from(const Ref<Mesh> &p_existing, int p_surface);
void append_from(const Ref<Mesh> &p_existing, int p_surface, const Transform &p_xform);
- Ref<Mesh> commit(const Ref<Mesh> &p_existing = Ref<Mesh>());
+ Ref<ArrayMesh> commit(const Ref<ArrayMesh> &p_existing = Ref<ArrayMesh>());
SurfaceTool();
};
diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp
index f0ac30a76e..2120b37497 100644
--- a/scene/resources/texture.cpp
+++ b/scene/resources/texture.cpp
@@ -28,25 +28,28 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "texture.h"
+#include "core/method_bind_ext.inc"
#include "core/os/os.h"
#include "io/image_loader.h"
-
Size2 Texture::get_size() const {
return Size2(get_width(), get_height());
}
-void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void Texture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, get_size()), get_rid(), false, p_modulate, p_transpose, normal_rid);
}
-void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void Texture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, get_rid(), p_tile, p_modulate, p_transpose, normal_rid);
}
-void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const {
+void Texture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, get_rid(), p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
}
bool Texture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
@@ -65,9 +68,9 @@ void Texture::_bind_methods() {
ClassDB::bind_method(D_METHOD("has_alpha"), &Texture::has_alpha);
ClassDB::bind_method(D_METHOD("set_flags", "flags"), &Texture::set_flags);
ClassDB::bind_method(D_METHOD("get_flags"), &Texture::get_flags);
- ClassDB::bind_method(D_METHOD("draw", "canvas_item", "pos", "modulate", "transpose"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
- ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false));
+ ClassDB::bind_method(D_METHOD("draw", "canvas_item", "pos", "modulate", "transpose", "normal_map:Texture"), &Texture::draw, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_rect", "canvas_item", "rect", "tile", "modulate", "transpose", "normal_map:Texture"), &Texture::draw_rect, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()));
+ ClassDB::bind_method(D_METHOD("draw_rect_region", "canvas_item", "rect", "src_rect", "modulate", "transpose", "normal_map:Texture", "clip_uv"), &Texture::draw_rect_region, DEFVAL(Color(1, 1, 1)), DEFVAL(false), DEFVAL(Variant()), DEFVAL(true));
BIND_CONSTANT(FLAG_MIPMAPS);
BIND_CONSTANT(FLAG_REPEAT);
@@ -91,9 +94,10 @@ void ImageTexture::reload_from_file() {
return;
uint32_t flags = get_flags();
- Image img;
+ Ref<Image> img;
+ img.instance();
- Error err = ImageLoader::load_image(path, &img);
+ Error err = ImageLoader::load_image(path, img);
ERR_FAIL_COND(err != OK);
create_from_image(img, flags);
@@ -101,7 +105,7 @@ void ImageTexture::reload_from_file() {
bool ImageTexture::_set(const StringName &p_name, const Variant &p_value) {
- if (p_name == "image" && p_value.get_type() == Variant::IMAGE)
+ if (p_name == "image")
create_from_image(p_value, flags);
else if (p_name == "flags")
if (w * h == 0)
@@ -155,7 +159,7 @@ void ImageTexture::_get_property_list(List<PropertyInfo> *p_list) const {
}
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter,Anisotropic,sRGB,Mirrored Repeat"));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "image", img_hint, String::num(lossy_storage_quality)));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "image", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
p_list->push_back(PropertyInfo(Variant::VECTOR2, "size", PROPERTY_HINT_NONE, ""));
p_list->push_back(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless"));
p_list->push_back(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
@@ -167,8 +171,9 @@ void ImageTexture::_reload_hook(const RID &p_hook) {
if (!path.is_resource_file())
return;
- Image img;
- Error err = ImageLoader::load_image(path, &img);
+ Ref<Image> img;
+ img.instance();
+ Error err = ImageLoader::load_image(path, img);
ERR_FAIL_COND(err != OK);
@@ -185,14 +190,14 @@ void ImageTexture::create(int p_width, int p_height, Image::Format p_format, uin
w = p_width;
h = p_height;
}
-void ImageTexture::create_from_image(const Image &p_image, uint32_t p_flags) {
+void ImageTexture::create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
flags = p_flags;
- w = p_image.get_width();
- h = p_image.get_height();
- format = p_image.get_format();
+ w = p_image->get_width();
+ h = p_image->get_height();
+ format = p_image->get_format();
- VisualServer::get_singleton()->texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), p_flags);
+ VisualServer::get_singleton()->texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), p_flags);
VisualServer::get_singleton()->texture_set_data(texture, p_image);
_change_notify();
}
@@ -220,12 +225,13 @@ Image::Format ImageTexture::get_format() const {
void ImageTexture::load(const String &p_path) {
- Image img;
- img.load(p_path);
+ Ref<Image> img;
+ img.instance();
+ img->load(p_path);
create_from_image(img);
}
-void ImageTexture::set_data(const Image &p_image) {
+void ImageTexture::set_data(const Ref<Image> &p_image) {
VisualServer::get_singleton()->texture_set_data(texture, p_image);
@@ -237,7 +243,7 @@ void ImageTexture::_resource_path_changed() {
String path = get_path();
}
-Image ImageTexture::get_data() const {
+Ref<Image> ImageTexture::get_data() const {
return VisualServer::get_singleton()->texture_get_data(texture);
}
@@ -257,64 +263,31 @@ RID ImageTexture::get_rid() const {
return texture;
}
-void ImageTexture::fix_alpha_edges() {
-
- if (format == Image::FORMAT_RGBA8 /*&& !(flags&FLAG_CUBEMAP)*/) {
-
- Image img = get_data();
- img.fix_alpha_edges();
- set_data(img);
- }
-}
-
-void ImageTexture::premultiply_alpha() {
-
- if (format == Image::FORMAT_RGBA8 /*&& !(flags&FLAG_CUBEMAP)*/) {
-
- Image img = get_data();
- img.premultiply_alpha();
- set_data(img);
- }
-}
-
-void ImageTexture::normal_to_xy() {
-
- Image img = get_data();
- img.normalmap_to_xy();
- create_from_image(img, flags);
-}
-
-void ImageTexture::shrink_x2_and_keep_size() {
-
- Size2 sizeov = get_size();
- Image img = get_data();
- img.resize(img.get_width() / 2, img.get_height() / 2, Image::INTERPOLATE_BILINEAR);
- create_from_image(img, flags);
- set_size_override(sizeov);
-}
-
bool ImageTexture::has_alpha() const {
return (format == Image::FORMAT_LA8 || format == Image::FORMAT_RGBA8);
}
-void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void ImageTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
}
-void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void ImageTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
}
-void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const {
+void ImageTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
}
void ImageTexture::set_size_override(const Size2 &p_size) {
@@ -358,7 +331,8 @@ float ImageTexture::get_lossy_storage_quality() const {
void ImageTexture::_set_data(Dictionary p_data) {
- Image img = p_data["image"];
+ Ref<Image> img = p_data["image"];
+ ERR_FAIL_COND(!img.is_valid());
uint32_t flags = p_data["flags"];
create_from_image(img, flags);
@@ -372,25 +346,17 @@ void ImageTexture::_set_data(Dictionary p_data) {
void ImageTexture::_bind_methods() {
ClassDB::bind_method(D_METHOD("create", "width", "height", "format", "flags"), &ImageTexture::create, DEFVAL(FLAGS_DEFAULT));
- ClassDB::bind_method(D_METHOD("create_from_image", "image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT));
+ ClassDB::bind_method(D_METHOD("create_from_image", "image:Image", "flags"), &ImageTexture::create_from_image, DEFVAL(FLAGS_DEFAULT));
ClassDB::bind_method(D_METHOD("get_format"), &ImageTexture::get_format);
ClassDB::bind_method(D_METHOD("load", "path"), &ImageTexture::load);
- ClassDB::bind_method(D_METHOD("set_data", "image"), &ImageTexture::set_data);
- ClassDB::bind_method(D_METHOD("get_data", "cube_side"), &ImageTexture::get_data);
+ ClassDB::bind_method(D_METHOD("set_data", "image:Image"), &ImageTexture::set_data);
+ ClassDB::bind_method(D_METHOD("get_data:Image", "cube_side"), &ImageTexture::get_data);
ClassDB::bind_method(D_METHOD("set_storage", "mode"), &ImageTexture::set_storage);
ClassDB::bind_method(D_METHOD("get_storage"), &ImageTexture::get_storage);
ClassDB::bind_method(D_METHOD("set_lossy_storage_quality", "quality"), &ImageTexture::set_lossy_storage_quality);
ClassDB::bind_method(D_METHOD("get_lossy_storage_quality"), &ImageTexture::get_lossy_storage_quality);
- ClassDB::bind_method(D_METHOD("fix_alpha_edges"), &ImageTexture::fix_alpha_edges);
- ClassDB::bind_method(D_METHOD("premultiply_alpha"), &ImageTexture::premultiply_alpha);
- ClassDB::bind_method(D_METHOD("normal_to_xy"), &ImageTexture::normal_to_xy);
- ClassDB::bind_method(D_METHOD("shrink_x2_and_keep_size"), &ImageTexture::shrink_x2_and_keep_size);
ClassDB::bind_method(D_METHOD("set_size_override", "size"), &ImageTexture::set_size_override);
- ClassDB::set_method_flags(get_class_static(), _scs_create("fix_alpha_edges"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::set_method_flags(get_class_static(), _scs_create("premultiply_alpha"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::set_method_flags(get_class_static(), _scs_create("normal_to_xy"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
- ClassDB::set_method_flags(get_class_static(), _scs_create("shrink_x2_and_keep_size"), METHOD_FLAGS_DEFAULT | METHOD_FLAG_EDITOR);
ClassDB::bind_method(D_METHOD("_reload_hook", "rid"), &ImageTexture::_reload_hook);
BIND_CONSTANT(STORAGE_RAW);
@@ -430,8 +396,17 @@ void StreamTexture::_requested_srgb(void *p_ud) {
request_srgb_callback(stex);
}
+void StreamTexture::_requested_normal(void *p_ud) {
+
+ StreamTexture *st = (StreamTexture *)p_ud;
+ Ref<StreamTexture> stex(st);
+ ERR_FAIL_COND(!request_normal_callback);
+ request_normal_callback(stex);
+}
+
StreamTexture::TextureFormatRequestCallback StreamTexture::request_3d_callback = NULL;
StreamTexture::TextureFormatRequestCallback StreamTexture::request_srgb_callback = NULL;
+StreamTexture::TextureFormatRequestCallback StreamTexture::request_normal_callback = NULL;
uint32_t StreamTexture::get_flags() const {
@@ -442,7 +417,9 @@ Image::Format StreamTexture::get_format() const {
return format;
}
-Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Image &image, int p_size_limit) {
+Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit) {
+
+ ERR_FAIL_COND_V(image.is_null(), ERR_INVALID_PARAMETER);
FileAccess *f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V(!f, ERR_CANT_OPEN);
@@ -459,12 +436,13 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
flags = f->get_32(); //texture flags!
uint32_t df = f->get_32(); //data format
- /*
+/*
print_line("width: " + itos(tw));
print_line("height: " + itos(th));
print_line("flags: " + itos(flags));
print_line("df: " + itos(df));
*/
+#ifdef TOOLS_ENABLED
if (request_3d_callback && df & FORMAT_BIT_DETECT_3D) {
//print_line("request detect 3D at " + p_path);
@@ -482,6 +460,14 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
VS::get_singleton()->texture_set_detect_srgb_callback(texture, NULL, NULL);
}
+ if (request_srgb_callback && df & FORMAT_BIT_DETECT_NORMAL) {
+ //print_line("request detect srgb at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, _requested_normal, this);
+ } else {
+ //print_line("not requesting detect normal at " + p_path);
+ VS::get_singleton()->texture_set_detect_normal_callback(texture, NULL, NULL);
+ }
+#endif
if (!(df & FORMAT_BIT_STREAM)) {
p_size_limit = 0;
}
@@ -509,7 +495,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
}
//mipmaps need to be read independently, they will be later combined
- Vector<Image> mipmap_images;
+ Vector<Ref<Image> > mipmap_images;
int total_size = 0;
for (int i = 0; i < mipmaps; i++) {
@@ -525,18 +511,19 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
f->get_buffer(w.ptr(), size);
}
- Image img;
+ Ref<Image> img;
if (df & FORMAT_BIT_LOSSLESS) {
img = Image::lossless_unpacker(pv);
} else {
img = Image::lossy_unpacker(pv);
}
- if (img.empty()) {
+ if (img.is_null() || img->empty()) {
memdelete(f);
- ERR_FAIL_COND_V(img.empty(), ERR_FILE_CORRUPT);
+ ERR_FAIL_COND_V(img.is_null() || img->empty(), ERR_FILE_CORRUPT);
}
- total_size += img.get_data().size();
+
+ total_size += img->get_data().size();
mipmap_images.push_back(img);
}
@@ -560,7 +547,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
int ofs = 0;
for (int i = 0; i < mipmap_images.size(); i++) {
- PoolVector<uint8_t> id = mipmap_images[i].get_data();
+ PoolVector<uint8_t> id = mipmap_images[i]->get_data();
int len = id.size();
PoolVector<uint8_t>::Read r = id.read();
copymem(&w[ofs], r.ptr(), len);
@@ -568,7 +555,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
}
}
- image = Image(sw, sh, true, mipmap_images[0].get_format(), img_data);
+ image->create(sw, sh, true, mipmap_images[0]->get_format(), img_data);
return OK;
}
@@ -591,7 +578,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
memdelete(f);
- image = Image(tw, th, false, format, img_data);
+ image->create(tw, th, false, format, img_data);
return OK;
} else {
@@ -637,7 +624,7 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
}
}
- image = Image(sw, sh, true, format, img_data);
+ image->create(sw, sh, true, format, img_data);
return OK;
}
@@ -649,19 +636,20 @@ Error StreamTexture::_load_data(const String &p_path, int &tw, int &th, int &fla
Error StreamTexture::load(const String &p_path) {
int lw, lh, lflags;
- Image image;
+ Ref<Image> image;
+ image.instance();
Error err = _load_data(p_path, lw, lh, lflags, image);
if (err)
return err;
- VS::get_singleton()->texture_allocate(texture, image.get_width(), image.get_height(), image.get_format(), lflags);
+ VS::get_singleton()->texture_allocate(texture, image->get_width(), image->get_height(), image->get_format(), lflags);
VS::get_singleton()->texture_set_data(texture, image);
w = lw;
h = lh;
flags = lflags;
path_to_file = p_path;
- format = image.get_format();
+ format = image->get_format();
return OK;
}
@@ -683,23 +671,26 @@ RID StreamTexture::get_rid() const {
return texture;
}
-void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void StreamTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, Rect2(p_pos, Size2(w, h)), texture, false, p_modulate, p_transpose, normal_rid);
}
-void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void StreamTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item, p_rect, texture, p_tile, p_modulate, p_transpose, normal_rid);
}
-void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const {
+void StreamTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
if ((w | h) == 0)
return;
- VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, p_rect, texture, p_src_rect, p_modulate, p_transpose, normal_rid, p_clip_uv);
}
bool StreamTexture::has_alpha() const {
@@ -707,7 +698,7 @@ bool StreamTexture::has_alpha() const {
return false;
}
-Image StreamTexture::get_data() const {
+Ref<Image> StreamTexture::get_data() const {
return VS::get_singleton()->texture_get_data(texture);
}
@@ -881,7 +872,7 @@ void AtlasTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::RECT2, "margin"), "set_margin", "get_margin");
}
-void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
Rect2 rc = region;
@@ -896,10 +887,11 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_m
rc.size.height = atlas->get_height();
}
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.pos, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, Rect2(p_pos + margin.position, rc.size), atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid);
}
-void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
Rect2 rc = region;
@@ -915,11 +907,12 @@ void AtlasTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
}
Vector2 scale = p_rect.size / (region.size + margin.size);
- Rect2 dr(p_rect.pos + margin.pos * scale, rc.size * scale);
+ Rect2 dr(p_rect.position + margin.position * scale, rc.size * scale);
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), rc, p_modulate, p_transpose, normal_rid);
}
-void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const {
+void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
//this might not necessarily work well if using a rect, needs to be fixed properly
Rect2 rc = region;
@@ -928,26 +921,27 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
return;
Rect2 src = p_src_rect;
- src.pos += (rc.pos - margin.pos);
+ src.position += (rc.position - margin.position);
Rect2 src_c = rc.clip(src);
if (src_c.size == Size2())
return;
- Vector2 ofs = (src_c.pos - src.pos);
+ Vector2 ofs = (src_c.position - src.position);
Vector2 scale = p_rect.size / p_src_rect.size;
if (scale.x < 0) {
- float mx = (margin.size.width - margin.pos.x);
- mx -= margin.pos.x;
+ float mx = (margin.size.width - margin.position.x);
+ mx -= margin.position.x;
ofs.x = -(ofs.x + mx);
}
if (scale.y < 0) {
- float my = margin.size.height - margin.pos.y;
- my -= margin.pos.y;
+ float my = margin.size.height - margin.position.y;
+ my -= margin.position.y;
ofs.y = -(ofs.y + my);
}
- Rect2 dr(p_rect.pos + ofs * scale, src_c.size * scale);
+ Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale);
- VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose);
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
+ VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item, dr, atlas->get_rid(), src_c, p_modulate, p_transpose, normal_rid, p_clip_uv);
}
bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const {
@@ -958,24 +952,24 @@ bool AtlasTexture::get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect,
return false;
Rect2 src = p_src_rect;
- src.pos += (rc.pos - margin.pos);
+ src.position += (rc.position - margin.position);
Rect2 src_c = rc.clip(src);
if (src_c.size == Size2())
return false;
- Vector2 ofs = (src_c.pos - src.pos);
+ Vector2 ofs = (src_c.position - src.position);
Vector2 scale = p_rect.size / p_src_rect.size;
if (scale.x < 0) {
- float mx = (margin.size.width - margin.pos.x);
- mx -= margin.pos.x;
+ float mx = (margin.size.width - margin.position.x);
+ mx -= margin.position.x;
ofs.x = -(ofs.x + mx);
}
if (scale.y < 0) {
- float my = margin.size.height - margin.pos.y;
- my -= margin.pos.y;
+ float my = margin.size.height - margin.position.y;
+ my -= margin.position.y;
ofs.y = -(ofs.y + my);
}
- Rect2 dr(p_rect.pos + ofs * scale, src_c.size * scale);
+ Rect2 dr(p_rect.position + ofs * scale, src_c.size * scale);
r_rect = dr;
r_src_rect = src_c;
@@ -1112,16 +1106,16 @@ void LargeTexture::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::ARRAY, "_data", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NOEDITOR), "_set_data", "_get_data");
}
-void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose) const {
+void LargeTexture::draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
for (int i = 0; i < pieces.size(); i++) {
// TODO
- pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose);
+ pieces[i].texture->draw(p_canvas_item, pieces[i].offset + p_pos, p_modulate, p_transpose, p_normal_map);
}
}
-void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose) const {
+void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map) const {
//tiling not supported for this
if (size.x == 0 || size.y == 0)
@@ -1129,13 +1123,14 @@ void LargeTexture::draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile
Size2 scale = p_rect.size / size;
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
for (int i = 0; i < pieces.size(); i++) {
// TODO
- pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.pos, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose);
+ pieces[i].texture->draw_rect(p_canvas_item, Rect2(pieces[i].offset * scale + p_rect.position, pieces[i].texture->get_size() * scale), false, p_modulate, p_transpose, p_normal_map);
}
}
-void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) const {
+void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, const Ref<Texture> &p_normal_map, bool p_clip_uv) const {
//tiling not supported for this
if (p_src_rect.size.x == 0 || p_src_rect.size.y == 0)
@@ -1143,6 +1138,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
Size2 scale = p_rect.size / p_src_rect.size;
+ RID normal_rid = p_normal_map.is_valid() ? p_normal_map->get_rid() : RID();
for (int i = 0; i < pieces.size(); i++) {
// TODO
@@ -1152,9 +1148,9 @@ void LargeTexture::draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, cons
Rect2 local = p_src_rect.clip(rect);
Rect2 target = local;
target.size *= scale;
- target.pos = p_rect.pos + (p_src_rect.pos + rect.pos) * scale;
- local.pos -= rect.pos;
- pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose);
+ target.position = p_rect.position + (p_src_rect.position + rect.position) * scale;
+ local.position -= rect.position;
+ pieces[i].texture->draw_rect_region(p_canvas_item, target, local, p_modulate, p_transpose, p_normal_map, false);
}
}
@@ -1175,25 +1171,25 @@ uint32_t CubeMap::get_flags() const {
return flags;
}
-void CubeMap::set_side(Side p_side, const Image &p_image) {
+void CubeMap::set_side(Side p_side, const Ref<Image> &p_image) {
- ERR_FAIL_COND(p_image.empty());
+ ERR_FAIL_COND(p_image->empty());
ERR_FAIL_INDEX(p_side, 6);
if (!_is_valid()) {
- format = p_image.get_format();
- w = p_image.get_width();
- h = p_image.get_height();
- VS::get_singleton()->texture_allocate(cubemap, w, h, p_image.get_format(), flags | VS::TEXTURE_FLAG_CUBEMAP);
+ format = p_image->get_format();
+ w = p_image->get_width();
+ h = p_image->get_height();
+ VS::get_singleton()->texture_allocate(cubemap, w, h, p_image->get_format(), flags | VS::TEXTURE_FLAG_CUBEMAP);
}
VS::get_singleton()->texture_set_data(cubemap, p_image, VS::CubeMapSide(p_side));
valid[p_side] = true;
}
-Image CubeMap::get_side(Side p_side) const {
+Ref<Image> CubeMap::get_side(Side p_side) const {
if (!valid[p_side])
- return Image();
+ return Ref<Image>();
return VS::get_singleton()->texture_get_data(cubemap, VS::CubeMapSide(p_side));
}
@@ -1306,14 +1302,12 @@ void CubeMap::_get_property_list(List<PropertyInfo> *p_list) const {
}
p_list->push_back(PropertyInfo(Variant::INT, "flags", PROPERTY_HINT_FLAGS, "Mipmaps,Repeat,Filter"));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/left", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/right", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/bottom", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/top", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/front", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::IMAGE, "side/back", img_hint, String::num(lossy_storage_quality)));
- p_list->push_back(PropertyInfo(Variant::INT, "storage", PROPERTY_HINT_ENUM, "Uncompressed,Compress Lossy,Compress Lossless", PROPERTY_USAGE_EDITOR));
- p_list->push_back(PropertyInfo(Variant::REAL, "lossy_quality", PROPERTY_HINT_RANGE, "0.0,1.0,0.01"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/left", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/right", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/bottom", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/top", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/front", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
+ p_list->push_back(PropertyInfo(Variant::OBJECT, "side/back", PROPERTY_HINT_RESOURCE_TYPE, "Image"));
}
void CubeMap::_bind_methods() {
@@ -1603,7 +1597,7 @@ void CurveTexture::set_points(const PoolVector<Vector2> &p_points) {
}
}
- Image image(width, 1, false, Image::FORMAT_RF, data);
+ Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RF, data));
VS::get_singleton()->texture_allocate(texture, width, 1, Image::FORMAT_RF, VS::TEXTURE_FLAG_FILTER);
VS::get_singleton()->texture_set_data(texture, image);
@@ -1715,7 +1709,7 @@ void GradientTexture::_update() {
}
}
- Image image(width, 1, false, Image::FORMAT_RGBA8, data);
+ Ref<Image> image = memnew(Image(width, 1, false, Image::FORMAT_RGBA8, data));
VS::get_singleton()->texture_allocate(texture, width, 1, Image::FORMAT_RGBA8, VS::TEXTURE_FLAG_FILTER);
VS::get_singleton()->texture_set_data(texture, image);
@@ -1819,6 +1813,10 @@ float GradientTexture::get_offset(int pos) const {
return 0; //TODO: Maybe throw some error instead?
}
+Ref<Image> GradientTexture::get_data() const {
+ return VisualServer::get_singleton()->texture_get_data(texture);
+}
+
void GradientTexture::set_color(int pos, const Color &color) {
if (points.size() <= pos) {
points.resize(pos + 1);
diff --git a/scene/resources/texture.h b/scene/resources/texture.h
index a6ea163813..2b82dbd21f 100644
--- a/scene/resources/texture.h
+++ b/scene/resources/texture.h
@@ -68,12 +68,12 @@ public:
virtual void set_flags(uint32_t p_flags) = 0;
virtual uint32_t get_flags() const = 0;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
- virtual Image get_data() const { return Image(); }
+ virtual Ref<Image> get_data() const { return Ref<Image>(); }
Texture();
};
@@ -116,14 +116,14 @@ protected:
public:
void create(int p_width, int p_height, Image::Format p_format, uint32_t p_flags = FLAGS_DEFAULT);
- void create_from_image(const Image &p_image, uint32_t p_flags = FLAGS_DEFAULT);
+ void create_from_image(const Ref<Image> &p_image, uint32_t p_flags = FLAGS_DEFAULT);
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
Image::Format get_format() const;
void load(const String &p_path);
- void set_data(const Image &p_image);
- Image get_data() const;
+ void set_data(const Ref<Image> &p_image);
+ Ref<Image> get_data() const;
int get_width() const;
int get_height() const;
@@ -131,20 +131,15 @@ public:
virtual RID get_rid() const;
bool has_alpha() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
void set_storage(Storage p_storage);
Storage get_storage() const;
void set_lossy_storage_quality(float p_lossy_storage_quality);
float get_lossy_storage_quality() const;
- void fix_alpha_edges();
- void premultiply_alpha();
- void normal_to_xy();
- void shrink_x2_and_keep_size();
-
void set_size_override(const Size2 &p_size);
virtual void set_path(const String &p_path, bool p_take_over = false);
@@ -172,10 +167,11 @@ public:
FORMAT_BIT_HAS_MIPMAPS = 1 << 23,
FORMAT_BIT_DETECT_3D = 1 << 24,
FORMAT_BIT_DETECT_SRGB = 1 << 25,
+ FORMAT_BIT_DETECT_NORMAL = 1 << 26,
};
private:
- Error _load_data(const String &p_path, int &tw, int &th, int &flags, Image &image, int p_size_limit = 0);
+ Error _load_data(const String &p_path, int &tw, int &th, int &flags, Ref<Image> &image, int p_size_limit = 0);
String path_to_file;
RID texture;
Image::Format format;
@@ -186,6 +182,7 @@ private:
static void _requested_3d(void *p_ud);
static void _requested_srgb(void *p_ud);
+ static void _requested_normal(void *p_ud);
protected:
static void _bind_methods();
@@ -195,6 +192,7 @@ public:
static TextureFormatRequestCallback request_3d_callback;
static TextureFormatRequestCallback request_srgb_callback;
+ static TextureFormatRequestCallback request_normal_callback;
uint32_t get_flags() const;
Image::Format get_format() const;
@@ -205,14 +203,14 @@ public:
int get_height() const;
virtual RID get_rid() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
virtual bool has_alpha() const;
virtual void set_flags(uint32_t p_flags);
- virtual Image get_data() const;
+ virtual Ref<Image> get_data() const;
StreamTexture();
~StreamTexture();
@@ -231,7 +229,7 @@ VARIANT_ENUM_CAST(ImageTexture::Storage);
class AtlasTexture : public Texture {
GDCLASS(AtlasTexture, Texture);
- RES_BASE_EXTENSION("atex");
+ RES_BASE_EXTENSION("atlastex");
protected:
Ref<Texture> atlas;
@@ -259,9 +257,9 @@ public:
void set_margin(const Rect2 &p_margin);
Rect2 get_margin() const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
virtual bool get_rect_region(const Rect2 &p_rect, const Rect2 &p_src_rect, Rect2 &r_rect, Rect2 &r_src_rect) const;
AtlasTexture();
@@ -270,7 +268,7 @@ public:
class LargeTexture : public Texture {
GDCLASS(LargeTexture, Texture);
- RES_BASE_EXTENSION("ltex");
+ RES_BASE_EXTENSION("largetex");
protected:
struct Piece {
@@ -307,9 +305,9 @@ public:
Vector2 get_piece_offset(int p_idx) const;
Ref<Texture> get_piece_texture(int p_idx) const;
- virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
- virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) const;
+ virtual void draw(RID p_canvas_item, const Point2 &p_pos, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect(RID p_canvas_item, const Rect2 &p_rect, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>()) const;
+ virtual void draw_rect_region(RID p_canvas_item, const Rect2 &p_rect, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, const Ref<Texture> &p_normal_map = Ref<Texture>(), bool p_clip_uv = true) const;
LargeTexture();
};
@@ -317,7 +315,7 @@ public:
class CubeMap : public Resource {
GDCLASS(CubeMap, Resource);
- RES_BASE_EXTENSION("cbm");
+ RES_BASE_EXTENSION("cubemap");
public:
enum Storage {
@@ -370,8 +368,8 @@ protected:
public:
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
- void set_side(Side p_side, const Image &p_image);
- Image get_side(Side p_side) const;
+ void set_side(Side p_side, const Ref<Image> &p_image);
+ Ref<Image> get_side(Side p_side) const;
Image::Format get_format() const;
int get_width() const;
@@ -398,7 +396,7 @@ VARIANT_ENUM_CAST(CubeMap::Storage);
class CurveTexture : public Texture {
GDCLASS(CurveTexture, Texture);
- RES_BASE_EXTENSION("cvtex");
+ RES_BASE_EXTENSION("curvetex");
private:
RID texture;
@@ -544,6 +542,8 @@ public:
return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset - pointFirst.offset) / (pointSecond.offset - pointFirst.offset));
}
+ virtual Ref<Image> get_data() const;
+
int get_points_count() const;
GradientTexture();
diff --git a/scene/resources/theme.h b/scene/resources/theme.h
index 1a5cfcf4b2..1dfea7f421 100644
--- a/scene/resources/theme.h
+++ b/scene/resources/theme.h
@@ -43,7 +43,7 @@
class Theme : public Resource {
GDCLASS(Theme, Resource);
- RES_BASE_EXTENSION("thm");
+ RES_BASE_EXTENSION("theme");
static Ref<Theme> default_theme;
diff --git a/scene/resources/world.cpp b/scene/resources/world.cpp
index eab7cf6098..24551e9135 100644
--- a/scene/resources/world.cpp
+++ b/scene/resources/world.cpp
@@ -280,6 +280,20 @@ Ref<Environment> World::get_environment() const {
return environment;
}
+void World::set_fallback_environment(const Ref<Environment> &p_environment) {
+
+ fallback_environment = p_environment;
+ if (fallback_environment.is_valid())
+ VS::get_singleton()->scenario_set_fallback_environment(scenario, p_environment->get_rid());
+ else
+ VS::get_singleton()->scenario_set_fallback_environment(scenario, RID());
+}
+
+Ref<Environment> World::get_fallback_environment() const {
+
+ return fallback_environment;
+}
+
PhysicsDirectSpaceState *World::get_direct_space_state() {
return PhysicsServer::get_singleton()->space_get_direct_state(space);
@@ -291,8 +305,11 @@ void World::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_scenario"), &World::get_scenario);
ClassDB::bind_method(D_METHOD("set_environment", "env:Environment"), &World::set_environment);
ClassDB::bind_method(D_METHOD("get_environment:Environment"), &World::get_environment);
+ ClassDB::bind_method(D_METHOD("set_fallback_environment", "env:Environment"), &World::set_fallback_environment);
+ ClassDB::bind_method(D_METHOD("get_fallback_environment:Environment"), &World::get_fallback_environment);
ClassDB::bind_method(D_METHOD("get_direct_space_state:PhysicsDirectSpaceState"), &World::get_direct_space_state);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_environment", "get_environment");
+ ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "fallback_environment", PROPERTY_HINT_RESOURCE_TYPE, "Environment"), "set_fallback_environment", "get_fallback_environment");
}
World::World() {
diff --git a/scene/resources/world.h b/scene/resources/world.h
index f2c85f31f6..5291b3974b 100644
--- a/scene/resources/world.h
+++ b/scene/resources/world.h
@@ -41,13 +41,14 @@ class VisibilityNotifier;
class World : public Resource {
GDCLASS(World, Resource);
- RES_BASE_EXTENSION("wrd");
+ RES_BASE_EXTENSION("world");
private:
RID space;
RID scenario;
SpatialIndexer *indexer;
Ref<Environment> environment;
+ Ref<Environment> fallback_environment;
protected:
static void _bind_methods();
@@ -68,9 +69,13 @@ protected:
public:
RID get_space() const;
RID get_scenario() const;
+
void set_environment(const Ref<Environment> &p_environment);
Ref<Environment> get_environment() const;
+ void set_fallback_environment(const Ref<Environment> &p_environment);
+ Ref<Environment> get_fallback_environment() const;
+
PhysicsDirectSpaceState *get_direct_space_state();
World();
diff --git a/scene/resources/world_2d.cpp b/scene/resources/world_2d.cpp
index db72ccd03c..36d2a38b3d 100644
--- a/scene/resources/world_2d.cpp
+++ b/scene/resources/world_2d.cpp
@@ -97,9 +97,9 @@ struct SpatialIndexer2D {
void _notifier_update_cells(VisibilityNotifier2D *p_notifier, const Rect2 &p_rect, bool p_add) {
- Point2i begin = p_rect.pos;
+ Point2i begin = p_rect.position;
begin /= cell_size;
- Point2i end = p_rect.pos + p_rect.size;
+ Point2i end = p_rect.position + p_rect.size;
end /= cell_size;
for (int i = begin.x; i <= end.x; i++) {
@@ -220,9 +220,9 @@ struct SpatialIndexer2D {
for (Map<Viewport *, ViewportData>::Element *E = viewports.front(); E; E = E->next()) {
- Point2i begin = E->get().rect.pos;
+ Point2i begin = E->get().rect.position;
begin /= cell_size;
- Point2i end = E->get().rect.pos + E->get().rect.size;
+ Point2i end = E->get().rect.position + E->get().rect.size;
end /= cell_size;
pass++;
List<VisibilityNotifier2D *> added;
@@ -360,16 +360,17 @@ RID World2D::get_space() {
return space;
}
-RID World2D::get_sound_space() {
+void World2D::get_viewport_list(List<Viewport *> *r_viewports) {
- return sound_space;
+ for (Map<Viewport *, SpatialIndexer2D::ViewportData>::Element *E = indexer->viewports.front(); E; E = E->next()) {
+ r_viewports->push_back(E->key());
+ }
}
void World2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_canvas"), &World2D::get_canvas);
ClassDB::bind_method(D_METHOD("get_space"), &World2D::get_space);
- ClassDB::bind_method(D_METHOD("get_sound_space"), &World2D::get_sound_space);
ClassDB::bind_method(D_METHOD("get_direct_space_state:Physics2DDirectSpaceState"), &World2D::get_direct_space_state);
}
diff --git a/scene/resources/world_2d.h b/scene/resources/world_2d.h
index 2b6e7e7383..35c8ce390f 100644
--- a/scene/resources/world_2d.h
+++ b/scene/resources/world_2d.h
@@ -44,7 +44,6 @@ class World2D : public Resource {
RID canvas;
RID space;
- RID sound_space;
SpatialIndexer2D *indexer;
@@ -66,10 +65,11 @@ protected:
public:
RID get_canvas();
RID get_space();
- RID get_sound_space();
Physics2DDirectSpaceState *get_direct_space_state();
+ void get_viewport_list(List<Viewport *> *r_viewports);
+
World2D();
~World2D();
};
diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp
index 5eb10a4d09..d673088304 100644
--- a/servers/physics/collision_object_sw.cpp
+++ b/servers/physics/collision_object_sw.cpp
@@ -164,7 +164,7 @@ void CollisionObjectSW::_update_shapes_with_motion(const Vector3 &p_motion) {
Rect3 shape_aabb = s.shape->get_aabb();
Transform xform = transform * s.xform;
shape_aabb = xform.xform(shape_aabb);
- shape_aabb = shape_aabb.merge(Rect3(shape_aabb.pos + p_motion, shape_aabb.size)); //use motion
+ shape_aabb = shape_aabb.merge(Rect3(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
s.aabb_cache = shape_aabb;
space->get_broadphase()->move(s.bpid, shape_aabb);
@@ -208,7 +208,7 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) {
type = p_type;
space = NULL;
instance_id = 0;
- layer_mask = 1;
+ collision_layer = 1;
collision_mask = 1;
ray_pickable = true;
}
diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h
index 0767f88ba1..15082a0551 100644
--- a/servers/physics/collision_object_sw.h
+++ b/servers/physics/collision_object_sw.h
@@ -53,7 +53,7 @@ private:
Type type;
RID self;
ObjectID instance_id;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t collision_mask;
struct Shape {
@@ -134,14 +134,14 @@ public:
_FORCE_INLINE_ void set_shape_as_trigger(int p_idx, bool p_enable) { shapes[p_idx].trigger = p_enable; }
_FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; }
- _FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask = p_mask; }
- _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+ _FORCE_INLINE_ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
+ _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
_FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
_FORCE_INLINE_ bool test_collision_mask(CollisionObjectSW *p_other) const {
- return layer_mask & p_other->collision_mask || p_other->layer_mask & collision_mask;
+ return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
void remove_shape(ShapeSW *p_shape);
diff --git a/servers/physics/collision_solver_sw.cpp b/servers/physics/collision_solver_sw.cpp
index 38ce31ec78..32a42bcaf4 100644
--- a/servers/physics/collision_solver_sw.cpp
+++ b/servers/physics/collision_solver_sw.cpp
@@ -166,7 +166,7 @@ bool CollisionSolverSW::solve_concave(const ShapeSW *p_shape_A, const Transform
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
@@ -332,7 +332,7 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
Rect3 cc_hint_aabb;
if (use_cc_hint) {
cc_hint_aabb = p_concave_hint;
- cc_hint_aabb.pos -= p_transform_B.origin;
+ cc_hint_aabb.position -= p_transform_B.origin;
}
Rect3 local_aabb;
@@ -353,7 +353,7 @@ bool CollisionSolverSW::solve_distance(const ShapeSW *p_shape_A, const Transform
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
diff --git a/servers/physics/gjk_epa.cpp b/servers/physics/gjk_epa.cpp
index 2819aa7ca0..ab2a9b507a 100644
--- a/servers/physics/gjk_epa.cpp
+++ b/servers/physics/gjk_epa.cpp
@@ -34,6 +34,31 @@
/*************** Bullet's GJK-EPA2 IMPLEMENTATION *******************/
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2008 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the
+use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it
+freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not
+claim that you wrote the original software. If you use this software in a
+product, an acknowledgment in the product documentation would be appreciated
+but is not required.
+2. Altered source versions must be plainly marked as such, and must not be
+misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+GJK-EPA collision solver by Nathanael Presson, 2008
+*/
+
// Config
/* GJK */
diff --git a/servers/physics/joints/cone_twist_joint_sw.cpp b/servers/physics/joints/cone_twist_joint_sw.cpp
index d94618fd9f..7e13909592 100644
--- a/servers/physics/joints/cone_twist_joint_sw.cpp
+++ b/servers/physics/joints/cone_twist_joint_sw.cpp
@@ -30,7 +30,23 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+ConeTwistJointSW is Copyright (c) 2007 Starbreeze Studios
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+
+Written by: Marcus Hennix
*/
#include "cone_twist_joint_sw.h"
diff --git a/servers/physics/joints/generic_6dof_joint_sw.cpp b/servers/physics/joints/generic_6dof_joint_sw.cpp
index a1d0360db6..e4349bda9a 100644
--- a/servers/physics/joints/generic_6dof_joint_sw.cpp
+++ b/servers/physics/joints/generic_6dof_joint_sw.cpp
@@ -30,7 +30,28 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+2007-09-09
+Generic6DOFJointSW Refactored by Francisco Le?n
+email: projectileman@yahoo.com
+http://gimpact.sf.net
*/
#include "generic_6dof_joint_sw.h"
diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp
index b63fcaecd1..3938427cea 100644
--- a/servers/physics/joints/hinge_joint_sw.cpp
+++ b/servers/physics/joints/hinge_joint_sw.cpp
@@ -30,7 +30,21 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
*/
#include "hinge_joint_sw.h"
diff --git a/servers/physics/joints/pin_joint_sw.cpp b/servers/physics/joints/pin_joint_sw.cpp
index 80a4bd7f44..0792ffeecd 100644
--- a/servers/physics/joints/pin_joint_sw.cpp
+++ b/servers/physics/joints/pin_joint_sw.cpp
@@ -30,7 +30,21 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
*/
#include "pin_joint_sw.h"
diff --git a/servers/physics/joints/slider_joint_sw.cpp b/servers/physics/joints/slider_joint_sw.cpp
index ecc4be3b5e..947f46e960 100644
--- a/servers/physics/joints/slider_joint_sw.cpp
+++ b/servers/physics/joints/slider_joint_sw.cpp
@@ -30,7 +30,27 @@
/*
Adapted to Godot from the Bullet library.
-See corresponding header file for licensing info.
+*/
+
+/*
+Bullet Continuous Collision Detection and Physics Library
+Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
+
+This software is provided 'as-is', without any express or implied warranty.
+In no event will the authors be held liable for any damages arising from the use of this software.
+Permission is granted to anyone to use this software for any purpose,
+including commercial applications, and to alter it and redistribute it freely,
+subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+3. This notice may not be removed or altered from any source distribution.
+*/
+
+/*
+Added by Roman Ponomarev (rponom@gmail.com)
+April 04, 2008
+
*/
#include "slider_joint_sw.h"
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index 727ff38718..455863da91 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -389,12 +389,12 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const {
return area->get_transform();
};
-void PhysicsServerSW::area_set_layer_mask(RID p_area, uint32_t p_mask) {
+void PhysicsServerSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
AreaSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_layer_mask(p_mask);
+ area->set_collision_layer(p_layer);
}
void PhysicsServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
@@ -609,21 +609,21 @@ bool PhysicsServerSW::body_is_continuous_collision_detection_enabled(RID p_body)
return body->is_continuous_collision_detection_enabled();
}
-void PhysicsServerSW::body_set_layer_mask(RID p_body, uint32_t p_mask) {
+void PhysicsServerSW::body_set_collision_layer(RID p_body, uint32_t p_layer) {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_layer_mask(p_mask);
+ body->set_collision_layer(p_layer);
body->wakeup();
}
-uint32_t PhysicsServerSW::body_get_layer_mask(RID p_body, uint32_t p_mask) const {
+uint32_t PhysicsServerSW::body_get_collision_layer(RID p_body) const {
const BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
- return body->get_layer_mask();
+ return body->get_collision_layer();
}
void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
@@ -635,7 +635,7 @@ void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) {
body->wakeup();
}
-uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body, uint32_t p_mask) const {
+uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body) const {
const BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
@@ -665,7 +665,7 @@ void PhysicsServerSW::body_set_user_flags(RID p_body, uint32_t p_flags) {
ERR_FAIL_COND(!body);
};
-uint32_t PhysicsServerSW::body_get_user_flags(RID p_body, uint32_t p_flags) const {
+uint32_t PhysicsServerSW::body_get_user_flags(RID p_body) const {
BodySW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h
index 44f9aff662..559e9aeb51 100644
--- a/servers/physics/physics_server_sw.h
+++ b/servers/physics/physics_server_sw.h
@@ -130,7 +130,7 @@ public:
virtual bool area_is_ray_pickable(RID p_area) const;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask);
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask);
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer);
virtual void area_set_monitorable(RID p_area, bool p_monitorable);
@@ -168,14 +168,14 @@ public:
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable);
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t body_get_collision_layer(RID p_body) const;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const;
+ virtual uint32_t body_get_collision_mask(RID p_body) const;
virtual void body_set_user_flags(RID p_body, uint32_t p_flags);
- virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const;
+ virtual uint32_t body_get_user_flags(RID p_body) const;
virtual void body_set_param(RID p_body, BodyParameter p_param, real_t p_value);
virtual real_t body_get_param(RID p_body, BodyParameter p_param) const;
diff --git a/servers/physics/shape_sw.cpp b/servers/physics/shape_sw.cpp
index ff7b442442..7b3df37a63 100644
--- a/servers/physics/shape_sw.cpp
+++ b/servers/physics/shape_sw.cpp
@@ -757,7 +757,7 @@ void ConvexPolygonShapeSW::_setup(const Vector<Vector3> &p_vertices) {
for (int i = 0; i < mesh.vertices.size(); i++) {
if (i == 0)
- _aabb.pos = mesh.vertices[i];
+ _aabb.position = mesh.vertices[i];
else
_aabb.expand_to(mesh.vertices[i]);
}
@@ -1388,7 +1388,7 @@ void ConcavePolygonShapeSW::_setup(PoolVector<Vector3> p_faces) {
Face3 face(facesr[i * 3 + 0], facesr[i * 3 + 1], facesr[i * 3 + 2]);
bvh_arrayw[i].aabb = face.get_aabb();
- bvh_arrayw[i].center = bvh_arrayw[i].aabb.pos + bvh_arrayw[i].aabb.size * 0.5;
+ bvh_arrayw[i].center = bvh_arrayw[i].aabb.position + bvh_arrayw[i].aabb.size * 0.5;
bvh_arrayw[i].face_index = i;
facesw[i].indices[0] = i * 3 + 0;
facesw[i].indices[1] = i * 3 + 1;
@@ -1504,7 +1504,7 @@ void HeightMapShapeSW::_setup(PoolVector<real_t> p_heights, int p_width, int p_d
Vector3 pos(j * cell_size, h, i * cell_size);
if (i == 0 || j == 0)
- aabb.pos = pos;
+ aabb.position = pos;
else
aabb.expand_to(pos);
}
diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp
index a4bf857bd8..67ac21e4f9 100644
--- a/servers/physics/space_sw.cpp
+++ b/servers/physics/space_sw.cpp
@@ -32,12 +32,12 @@
#include "global_config.h"
#include "physics_server_sw.h"
-_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
+_FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
if (p_object->get_type() == CollisionObjectSW::TYPE_AREA)
return p_type_mask & PhysicsDirectSpaceState::TYPE_MASK_AREA;
- if ((p_object->get_layer_mask() & p_layer_mask) == 0)
+ if ((p_object->get_collision_layer() & p_collision_layer) == 0)
return false;
BodySW *body = static_cast<BodySW *>(p_object);
@@ -45,7 +45,7 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObjectSW *p_object,
return (1 << body->get_mode()) & p_type_mask;
}
-bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, bool p_pick_ray) {
+bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, bool p_pick_ray) {
ERR_FAIL_COND_V(space->locked, false);
@@ -67,7 +67,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_pick_ray && !(static_cast<CollisionObjectSW *>(space->intersection_query_results[i])->is_ray_pickable()))
@@ -123,7 +123,7 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3 &p_from, const Vecto
return true;
}
-int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -144,7 +144,7 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
if (cc >= p_result_max)
break;
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
//area can't be picked by ray (default)
@@ -174,13 +174,13 @@ int PhysicsDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transfo
return cc;
}
-bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, ShapeRestInfo *r_info) {
+bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, ShapeRestInfo *r_info) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
Rect3 aabb = p_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect3(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect3(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
/*
@@ -204,7 +204,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -295,7 +295,7 @@ bool PhysicsDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform
return true;
}
-bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -325,7 +325,7 @@ bool PhysicsDirectSpaceStateSW::collide_shape(RID p_shape, const Transform &p_sh
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
@@ -374,7 +374,7 @@ static void _rest_cbk_result(const Vector3 &p_point_A, const Vector3 &p_point_B,
rd->best_object = rd->object;
rd->best_shape = rd->shape;
}
-bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
ShapeSW *shape = static_cast<PhysicsServerSW *>(PhysicsServer::get_singleton())->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
@@ -391,7 +391,7 @@ bool PhysicsDirectSpaceStateSW::rest_info(RID p_shape, const Transform &p_shape_
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObjectSW *col_obj = space->intersection_query_results[i];
diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h
index 20a2a06862..782bacbd65 100644
--- a/servers/physics/space_sw.h
+++ b/servers/physics/space_sw.h
@@ -47,11 +47,11 @@ class PhysicsDirectSpaceStateSW : public PhysicsDirectSpaceState {
public:
SpaceSW *space;
- virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false);
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL);
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, real_t p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
PhysicsDirectSpaceStateSW();
};
diff --git a/servers/physics_2d/broad_phase_2d_hash_grid.cpp b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
index e39a5b6df1..438cd416f6 100644
--- a/servers/physics_2d/broad_phase_2d_hash_grid.cpp
+++ b/servers/physics_2d/broad_phase_2d_hash_grid.cpp
@@ -116,8 +116,8 @@ void BroadPhase2DHashGrid::_enter_grid(Element *p_elem, const Rect2 &p_rect, boo
return;
}
- Point2i from = (p_rect.pos / cell_size).floor();
- Point2i to = ((p_rect.pos + p_rect.size) / cell_size).floor();
+ Point2i from = (p_rect.position / cell_size).floor();
+ Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
@@ -214,8 +214,8 @@ void BroadPhase2DHashGrid::_exit_grid(Element *p_elem, const Rect2 &p_rect, bool
return;
}
- Point2i from = (p_rect.pos / cell_size).floor();
- Point2i to = ((p_rect.pos + p_rect.size) / cell_size).floor();
+ Point2i from = (p_rect.position / cell_size).floor();
+ Point2i to = ((p_rect.position + p_rect.size) / cell_size).floor();
for (int i = from.x; i <= to.x; i++) {
@@ -574,8 +574,8 @@ int BroadPhase2DHashGrid::cull_aabb(const Rect2 &p_aabb, CollisionObject2DSW **p
pass++;
- Point2i from = (p_aabb.pos / cell_size).floor();
- Point2i to = ((p_aabb.pos + p_aabb.size) / cell_size).floor();
+ Point2i from = (p_aabb.position / cell_size).floor();
+ Point2i to = ((p_aabb.position + p_aabb.size) / cell_size).floor();
int cullcount = 0;
for (int i = from.x; i <= to.x; i++) {
diff --git a/servers/physics_2d/collision_object_2d_sw.cpp b/servers/physics_2d/collision_object_2d_sw.cpp
index 265b5bb836..0163a18850 100644
--- a/servers/physics_2d/collision_object_2d_sw.cpp
+++ b/servers/physics_2d/collision_object_2d_sw.cpp
@@ -169,7 +169,7 @@ void CollisionObject2DSW::_update_shapes_with_motion(const Vector2 &p_motion) {
Rect2 shape_aabb = s.shape->get_aabb();
Transform2D xform = transform * s.xform;
shape_aabb = xform.xform(shape_aabb);
- shape_aabb = shape_aabb.merge(Rect2(shape_aabb.pos + p_motion, shape_aabb.size)); //use motion
+ shape_aabb = shape_aabb.merge(Rect2(shape_aabb.position + p_motion, shape_aabb.size)); //use motion
s.aabb_cache = shape_aabb;
space->get_broadphase()->move(s.bpid, shape_aabb);
@@ -214,6 +214,6 @@ CollisionObject2DSW::CollisionObject2DSW(Type p_type) {
space = NULL;
instance_id = 0;
collision_mask = 1;
- layer_mask = 1;
+ collision_layer = 1;
pickable = true;
}
diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h
index 8ca6c92dbc..f2059e8618 100644
--- a/servers/physics_2d/collision_object_2d_sw.h
+++ b/servers/physics_2d/collision_object_2d_sw.h
@@ -67,7 +67,7 @@ private:
Transform2D transform;
Transform2D inv_transform;
uint32_t collision_mask;
- uint32_t layer_mask;
+ uint32_t collision_layer;
bool _static;
void _update_shapes();
@@ -122,8 +122,8 @@ public:
void set_collision_mask(uint32_t p_mask) { collision_mask = p_mask; }
_FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; }
- void set_layer_mask(uint32_t p_mask) { layer_mask = p_mask; }
- _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; }
+ void set_collision_layer(uint32_t p_layer) { collision_layer = p_layer; }
+ _FORCE_INLINE_ uint32_t get_collision_layer() const { return collision_layer; }
void remove_shape(Shape2DSW *p_shape);
void remove_shape(int p_index);
@@ -137,7 +137,7 @@ public:
_FORCE_INLINE_ bool test_collision_mask(CollisionObject2DSW *p_other) const {
- return layer_mask & p_other->collision_mask || p_other->layer_mask & collision_mask;
+ return collision_layer & p_other->collision_mask || p_other->collision_layer & collision_mask;
}
virtual ~CollisionObject2DSW() {}
diff --git a/servers/physics_2d/collision_solver_2d_sw.cpp b/servers/physics_2d/collision_solver_2d_sw.cpp
index e57d1b7044..b482f826c2 100644
--- a/servers/physics_2d/collision_solver_2d_sw.cpp
+++ b/servers/physics_2d/collision_solver_2d_sw.cpp
@@ -203,7 +203,7 @@ bool CollisionSolver2DSW::solve_concave(const Shape2DSW *p_shape_A, const Transf
smin *= axis_scale;
smax *= axis_scale;
- local_aabb.pos[i] = smin;
+ local_aabb.position[i] = smin;
local_aabb.size[i] = smax - smin;
}
diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp
index 03e0f8a7fd..9a31fa49b0 100644
--- a/servers/physics_2d/physics_2d_server_sw.cpp
+++ b/servers/physics_2d/physics_2d_server_sw.cpp
@@ -476,12 +476,12 @@ void Physics2DServerSW::area_set_collision_mask(RID p_area, uint32_t p_mask) {
area->set_collision_mask(p_mask);
}
-void Physics2DServerSW::area_set_layer_mask(RID p_area, uint32_t p_mask) {
+void Physics2DServerSW::area_set_collision_layer(RID p_area, uint32_t p_layer) {
Area2DSW *area = area_owner.get(p_area);
ERR_FAIL_COND(!area);
- area->set_layer_mask(p_mask);
+ area->set_collision_layer(p_layer);
}
void Physics2DServerSW::area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) {
@@ -691,19 +691,19 @@ uint32_t Physics2DServerSW::body_get_object_instance_ID(RID p_body) const {
return body->get_instance_id();
};
-void Physics2DServerSW::body_set_layer_mask(RID p_body, uint32_t p_flags) {
+void Physics2DServerSW::body_set_collision_layer(RID p_body, uint32_t p_flags) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
- body->set_layer_mask(p_flags);
+ body->set_collision_layer(p_flags);
};
-uint32_t Physics2DServerSW::body_get_layer_mask(RID p_body) const {
+uint32_t Physics2DServerSW::body_get_collision_layer(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body, 0);
- return body->get_layer_mask();
+ return body->get_collision_layer();
};
void Physics2DServerSW::body_set_collision_mask(RID p_body, uint32_t p_flags) {
diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h
index a8d85932ff..be67e3157d 100644
--- a/servers/physics_2d/physics_2d_server_sw.h
+++ b/servers/physics_2d/physics_2d_server_sw.h
@@ -136,7 +136,7 @@ public:
virtual Transform2D area_get_transform(RID p_area) const;
virtual void area_set_monitorable(RID p_area, bool p_monitorable);
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask);
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask);
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer);
virtual void area_set_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
virtual void area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method);
@@ -176,8 +176,8 @@ public:
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode);
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask);
- virtual uint32_t body_get_layer_mask(RID p_body) const;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer);
+ virtual uint32_t body_get_collision_layer(RID p_body) const;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask);
virtual uint32_t body_get_collision_mask(RID p_) const;
diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h
index ddcf31182a..1026d84fd9 100644
--- a/servers/physics_2d/physics_2d_server_wrap_mt.h
+++ b/servers/physics_2d/physics_2d_server_wrap_mt.h
@@ -162,7 +162,7 @@ public:
FUNC1RC(Transform2D, area_get_transform, RID);
FUNC2(area_set_collision_mask, RID, uint32_t);
- FUNC2(area_set_layer_mask, RID, uint32_t);
+ FUNC2(area_set_collision_layer, RID, uint32_t);
FUNC2(area_set_monitorable, RID, bool);
FUNC2(area_set_pickable, RID, bool);
@@ -203,8 +203,8 @@ public:
FUNC2(body_set_continuous_collision_detection_mode, RID, CCDMode);
FUNC1RC(CCDMode, body_get_continuous_collision_detection_mode, RID);
- FUNC2(body_set_layer_mask, RID, uint32_t);
- FUNC1RC(uint32_t, body_get_layer_mask, RID);
+ FUNC2(body_set_collision_layer, RID, uint32_t);
+ FUNC1RC(uint32_t, body_get_collision_layer, RID);
FUNC2(body_set_collision_mask, RID, uint32_t);
FUNC1RC(uint32_t, body_get_collision_mask, RID);
diff --git a/servers/physics_2d/shape_2d_sw.cpp b/servers/physics_2d/shape_2d_sw.cpp
index 203a1052b2..245b4e15bc 100644
--- a/servers/physics_2d/shape_2d_sw.cpp
+++ b/servers/physics_2d/shape_2d_sw.cpp
@@ -246,12 +246,12 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
ERR_FAIL_COND(p_data.get_type() != Variant::RECT2);
Rect2 r = p_data;
- a = r.pos;
+ a = r.position;
b = r.size;
n = (b - a).tangent();
Rect2 aabb;
- aabb.pos = a;
+ aabb.position = a;
aabb.expand_to(b);
if (aabb.size.x == 0)
aabb.size.x = 0.001;
@@ -263,7 +263,7 @@ void SegmentShape2DSW::set_data(const Variant &p_data) {
Variant SegmentShape2DSW::get_data() const {
Rect2 r;
- r.pos = a;
+ r.position = a;
r.size = b;
return r;
}
@@ -621,13 +621,13 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2 &p_begin, const Vec
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(real_t p_mass, const Size2 &p_scale) const {
Rect2 aabb;
- aabb.pos = points[0].pos * p_scale;
+ aabb.position = points[0].pos * p_scale;
for (int i = 0; i < point_count; i++) {
aabb.expand_to(points[i].pos * p_scale);
}
- return p_mass * aabb.size.dot(aabb.size) / 12.0 + p_mass * (aabb.pos + aabb.size * 0.5).length_squared();
+ return p_mass * aabb.size.dot(aabb.size) / 12.0 + p_mass * (aabb.position + aabb.size * 0.5).length_squared();
}
void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
@@ -677,7 +677,7 @@ void ConvexPolygonShape2DSW::set_data(const Variant &p_data) {
ERR_FAIL_COND(point_count == 0);
Rect2 aabb;
- aabb.pos = points[0].pos;
+ aabb.position = points[0].pos;
for (int i = 1; i < point_count; i++)
aabb.expand_to(points[i].pos);
@@ -942,7 +942,7 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
}
points.resize(pointmap.size());
- aabb.pos = pointmap.front()->key();
+ aabb.position = pointmap.front()->key();
for (Map<Point2, int>::Element *E = pointmap.front(); E; E = E->next()) {
aabb.expand_to(E->key());
@@ -953,7 +953,7 @@ void ConcavePolygonShape2DSW::set_data(const Variant &p_data) {
main_vbh.resize(segments.size());
for (int i = 0; i < main_vbh.size(); i++) {
- main_vbh[i].aabb.pos = points[segments[i].points[0]];
+ main_vbh[i].aabb.position = points[segments[i].points[0]];
main_vbh[i].aabb.expand_to(points[segments[i].points[1]]);
main_vbh[i].left = -1;
main_vbh[i].right = i;
diff --git a/servers/physics_2d/shape_2d_sw.h b/servers/physics_2d/shape_2d_sw.h
index 547ecdcd11..4cc98b7f1e 100644
--- a/servers/physics_2d/shape_2d_sw.h
+++ b/servers/physics_2d/shape_2d_sw.h
@@ -513,7 +513,7 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
- return (a.aabb.pos.x + a.aabb.size.x * 0.5) < (b.aabb.pos.x + b.aabb.size.x * 0.5);
+ return (a.aabb.position.x + a.aabb.size.x * 0.5) < (b.aabb.position.x + b.aabb.size.x * 0.5);
}
};
@@ -521,7 +521,7 @@ class ConcavePolygonShape2DSW : public ConcaveShape2DSW {
_FORCE_INLINE_ bool operator()(const BVH &a, const BVH &b) const {
- return (a.aabb.pos.y + a.aabb.size.y * 0.5) < (b.aabb.pos.y + b.aabb.size.y * 0.5);
+ return (a.aabb.position.y + a.aabb.size.y * 0.5) < (b.aabb.position.y + b.aabb.size.y * 0.5);
}
};
diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp
index ac479aab7a..fd94fc01cd 100644
--- a/servers/physics_2d/space_2d_sw.cpp
+++ b/servers/physics_2d/space_2d_sw.cpp
@@ -31,9 +31,9 @@
#include "collision_solver_2d_sw.h"
#include "physics_2d_server_sw.h"
-_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_layer_mask, uint32_t p_type_mask) {
+_FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_object, uint32_t p_collision_layer, uint32_t p_type_mask) {
- if ((p_object->get_layer_mask() & p_layer_mask) == 0)
+ if ((p_object->get_collision_layer() & p_collision_layer) == 0)
return false;
if (p_object->get_type() == CollisionObject2DSW::TYPE_AREA)
@@ -44,13 +44,13 @@ _FORCE_INLINE_ static bool _match_object_type_query(CollisionObject2DSW *p_objec
return (1 << body->get_mode()) & p_type_mask;
}
-int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask, bool p_pick_point) {
+int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask, bool p_pick_point) {
if (p_result_max <= 0)
return 0;
Rect2 aabb;
- aabb.pos = p_point - Vector2(0.00001, 0.00001);
+ aabb.position = p_point - Vector2(0.00001, 0.00001);
aabb.size = Vector2(0.00002, 0.00002);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -59,7 +59,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -95,7 +95,7 @@ int Physics2DDirectSpaceStateSW::intersect_point(const Vector2 &p_point, ShapeRe
return cc;
}
-bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
ERR_FAIL_COND_V(space->locked, false);
@@ -117,7 +117,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -175,7 +175,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2 &p_from, const Vec
return true;
}
-int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -192,7 +192,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -217,13 +217,13 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID &p_shape, const Trans
return cc;
}
-bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, false);
Rect2 aabb = p_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
/*
@@ -238,7 +238,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
if (p_exclude.has(space->intersection_query_results[i]->get_self()))
@@ -330,7 +330,7 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID &p_shape, const Transfor
return true;
}
-bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
if (p_result_max <= 0)
return 0;
@@ -339,7 +339,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -361,7 +361,7 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Transform2D &
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -428,13 +428,13 @@ static void _rest_cbk_result(const Vector2 &p_point_A, const Vector2 &p_point_B,
rd->best_shape = rd->shape;
}
-bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_layer_mask, uint32_t p_object_type_mask) {
+bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude, uint32_t p_collision_layer, uint32_t p_object_type_mask) {
Shape2DSW *shape = Physics2DServerSW::singletonsw->shape_owner.get(p_shape);
ERR_FAIL_COND_V(!shape, 0);
Rect2 aabb = p_shape_xform.xform(shape->get_aabb());
- aabb = aabb.merge(Rect2(aabb.pos + p_motion, aabb.size)); //motion
+ aabb = aabb.merge(Rect2(aabb.position + p_motion, aabb.size)); //motion
aabb = aabb.grow(p_margin);
int amount = space->broadphase->cull_aabb(aabb, space->intersection_query_results, Space2DSW::INTERSECTION_QUERY_MAX, space->intersection_query_subindex_results);
@@ -446,7 +446,7 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Transform2D &p_sh
for (int i = 0; i < amount; i++) {
- if (!_match_object_type_query(space->intersection_query_results[i], p_layer_mask, p_object_type_mask))
+ if (!_match_object_type_query(space->intersection_query_results[i], p_collision_layer, p_object_type_mask))
continue;
const CollisionObject2DSW *col_obj = space->intersection_query_results[i];
@@ -656,7 +656,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
}
body_transform.elements[2] += recover_motion;
- body_aabb.pos += recover_motion;
+ body_aabb.position += recover_motion;
recover_attempts--;
@@ -671,7 +671,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
// STEP 2 ATTEMPT MOTION
Rect2 motion_aabb = body_aabb;
- motion_aabb.pos += p_motion;
+ motion_aabb.position += p_motion;
motion_aabb = motion_aabb.merge(body_aabb);
int amount = _cull_aabb_for_body(p_body, motion_aabb);
@@ -807,7 +807,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body, const Transform2D &p_from, co
Transform2D body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
Shape2DSW *body_shape = p_body->get_shape(best_shape);
- body_aabb.pos += p_motion * unsafe;
+ body_aabb.position += p_motion * unsafe;
int amount = _cull_aabb_for_body(p_body, body_aabb);
diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h
index 46435b1c66..64841c4328 100644
--- a/servers/physics_2d/space_2d_sw.h
+++ b/servers/physics_2d/space_2d_sw.h
@@ -47,12 +47,12 @@ class Physics2DDirectSpaceStateSW : public Physics2DDirectSpaceState {
public:
Space2DSW *space;
- virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false);
- virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
- virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false);
+ virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, real_t p_margin, real_t &p_closest_safe, real_t &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
+ virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, real_t p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION);
Physics2DDirectSpaceStateSW();
};
diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp
index 43295073aa..8ffa82214c 100644
--- a/servers/physics_2d_server.cpp
+++ b/servers/physics_2d_server.cpp
@@ -154,13 +154,13 @@ float Physics2DShapeQueryParameters::get_margin() const {
return margin;
}
-void Physics2DShapeQueryParameters::set_layer_mask(int p_layer_mask) {
+void Physics2DShapeQueryParameters::set_collision_layer(int p_collision_layer) {
- layer_mask = p_layer_mask;
+ collision_layer = p_collision_layer;
}
-int Physics2DShapeQueryParameters::get_layer_mask() const {
+int Physics2DShapeQueryParameters::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void Physics2DShapeQueryParameters::set_object_type_mask(int p_object_type_mask) {
@@ -204,8 +204,8 @@ void Physics2DShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &Physics2DShapeQueryParameters::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &Physics2DShapeQueryParameters::get_margin);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &Physics2DShapeQueryParameters::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &Physics2DShapeQueryParameters::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &Physics2DShapeQueryParameters::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &Physics2DShapeQueryParameters::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_object_type_mask", "object_type_mask"), &Physics2DShapeQueryParameters::set_object_type_mask);
ClassDB::bind_method(D_METHOD("get_object_type_mask"), &Physics2DShapeQueryParameters::get_object_type_mask);
@@ -217,7 +217,7 @@ void Physics2DShapeQueryParameters::_bind_methods() {
Physics2DShapeQueryParameters::Physics2DShapeQueryParameters() {
margin = 0;
- layer_mask = 0x7FFFFFFF;
+ collision_layer = 0x7FFFFFFF;
object_type_mask = Physics2DDirectSpaceState::TYPE_MASK_COLLISION;
}
@@ -249,7 +249,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(psq->shape, psq->transform, psq->motion, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->layer_mask, psq->object_type_mask);
+ int rc = intersect_shape(psq->shape, psq->transform, psq->motion, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->collision_layer, psq->object_type_mask);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -269,7 +269,7 @@ Array Physics2DDirectSpaceState::_intersect_shape(const Ref<Physics2DShapeQueryP
Array Physics2DDirectSpaceState::_cast_motion(const Ref<Physics2DShapeQueryParameters> &psq) {
float closest_safe, closest_unsafe;
- bool res = cast_motion(psq->shape, psq->transform, psq->motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = cast_motion(psq->shape, psq->transform, psq->motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->collision_layer, psq->object_type_mask);
if (!res)
return Array();
Array ret;
@@ -312,7 +312,7 @@ Array Physics2DDirectSpaceState::_collide_shape(const Ref<Physics2DShapeQueryPar
Vector<Vector2> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(psq->shape, psq->transform, psq->motion, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = collide_shape(psq->shape, psq->transform, psq->motion, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->collision_layer, psq->object_type_mask);
if (!res)
return Array();
Array r;
@@ -325,7 +325,7 @@ Dictionary Physics2DDirectSpaceState::_get_rest_info(const Ref<Physics2DShapeQue
ShapeRestInfo sri;
- bool res = rest_info(psq->shape, psq->transform, psq->motion, psq->margin, &sri, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = rest_info(psq->shape, psq->transform, psq->motion, psq->margin, &sri, psq->exclude, psq->collision_layer, psq->object_type_mask);
Dictionary r;
if (!res)
return r;
@@ -346,8 +346,8 @@ Physics2DDirectSpaceState::Physics2DDirectSpaceState() {
void Physics2DDirectSpaceState::_bind_methods() {
- ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "layer_mask", "type_mask"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
- ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "layer_mask", "type_mask"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_point", "point", "max_results", "exclude", "collision_layer", "type_mask"), &Physics2DDirectSpaceState::_intersect_point, DEFVAL(32), DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "collision_layer", "type_mask"), &Physics2DDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
ClassDB::bind_method(D_METHOD("intersect_shape", "shape:Physics2DShapeQueryParameters", "max_results"), &Physics2DDirectSpaceState::_intersect_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("cast_motion", "shape:Physics2DShapeQueryParameters"), &Physics2DDirectSpaceState::_cast_motion);
ClassDB::bind_method(D_METHOD("collide_shape", "shape:Physics2DShapeQueryParameters", "max_results"), &Physics2DDirectSpaceState::_collide_shape, DEFVAL(32));
@@ -504,7 +504,7 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_remove_shape", "area", "shape_idx"), &Physics2DServer::area_remove_shape);
ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &Physics2DServer::area_clear_shapes);
- ClassDB::bind_method(D_METHOD("area_set_layer_mask", "area", "mask"), &Physics2DServer::area_set_layer_mask);
+ ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &Physics2DServer::area_set_collision_layer);
ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &Physics2DServer::area_set_collision_mask);
ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &Physics2DServer::area_set_param);
@@ -548,8 +548,8 @@ void Physics2DServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_continuous_collision_detection_mode", "body", "mode"), &Physics2DServer::body_set_continuous_collision_detection_mode);
ClassDB::bind_method(D_METHOD("body_get_continuous_collision_detection_mode", "body"), &Physics2DServer::body_get_continuous_collision_detection_mode);
- ClassDB::bind_method(D_METHOD("body_set_layer_mask", "body", "mask"), &Physics2DServer::body_set_layer_mask);
- ClassDB::bind_method(D_METHOD("body_get_layer_mask", "body"), &Physics2DServer::body_get_layer_mask);
+ ClassDB::bind_method(D_METHOD("body_set_collision_layer", "body", "layer"), &Physics2DServer::body_set_collision_layer);
+ ClassDB::bind_method(D_METHOD("body_get_collision_layer", "body"), &Physics2DServer::body_get_collision_layer);
ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &Physics2DServer::body_set_collision_mask);
ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &Physics2DServer::body_get_collision_mask);
diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h
index 4ea037e1b4..80113dd7d6 100644
--- a/servers/physics_2d_server.h
+++ b/servers/physics_2d_server.h
@@ -97,7 +97,7 @@ class Physics2DShapeQueryParameters : public Reference {
Vector2 motion;
float margin;
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t object_type_mask;
protected:
@@ -117,8 +117,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_layer_mask(int p_layer_mask);
- int get_layer_mask() const;
+ void set_collision_layer(int p_collision_layer);
+ int get_collision_layer() const;
void set_object_type_mask(int p_object_type_mask);
int get_object_type_mask() const;
@@ -166,7 +166,7 @@ public:
Variant metadata;
};
- virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool intersect_ray(const Vector2 &p_from, const Vector2 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeResult {
@@ -177,13 +177,13 @@ public:
Variant metadata;
};
- virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false) = 0;
+ virtual int intersect_point(const Vector2 &p_point, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_point = false) = 0;
- virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual int intersect_shape(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform2D &p_xform, const Vector2 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool collide_shape(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, Vector2 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeRestInfo {
@@ -196,7 +196,7 @@ public:
Variant metadata;
};
- virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool rest_info(RID p_shape, const Transform2D &p_shape_xform, const Vector2 &p_motion, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
Physics2DDirectSpaceState();
};
@@ -342,7 +342,7 @@ public:
virtual Transform2D area_get_transform(RID p_area) const = 0;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0;
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask) = 0;
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0;
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
virtual void area_set_pickable(RID p_area, bool p_pickable) = 0;
@@ -398,8 +398,8 @@ public:
virtual void body_set_continuous_collision_detection_mode(RID p_body, CCDMode p_mode) = 0;
virtual CCDMode body_get_continuous_collision_detection_mode(RID p_body) const = 0;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_layer_mask(RID p_body) const = 0;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) = 0;
+ virtual uint32_t body_get_collision_layer(RID p_body) const = 0;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) = 0;
virtual uint32_t body_get_collision_mask(RID p_body) const = 0;
diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp
index b19dfc1c68..6b6db1ff8c 100644
--- a/servers/physics_server.cpp
+++ b/servers/physics_server.cpp
@@ -151,13 +151,13 @@ float PhysicsShapeQueryParameters::get_margin() const {
return margin;
}
-void PhysicsShapeQueryParameters::set_layer_mask(int p_layer_mask) {
+void PhysicsShapeQueryParameters::set_collision_layer(int p_collision_layer) {
- layer_mask = p_layer_mask;
+ collision_layer = p_collision_layer;
}
-int PhysicsShapeQueryParameters::get_layer_mask() const {
+int PhysicsShapeQueryParameters::get_collision_layer() const {
- return layer_mask;
+ return collision_layer;
}
void PhysicsShapeQueryParameters::set_object_type_mask(int p_object_type_mask) {
@@ -198,8 +198,8 @@ void PhysicsShapeQueryParameters::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_margin", "margin"), &PhysicsShapeQueryParameters::set_margin);
ClassDB::bind_method(D_METHOD("get_margin"), &PhysicsShapeQueryParameters::get_margin);
- ClassDB::bind_method(D_METHOD("set_layer_mask", "layer_mask"), &PhysicsShapeQueryParameters::set_layer_mask);
- ClassDB::bind_method(D_METHOD("get_layer_mask"), &PhysicsShapeQueryParameters::get_layer_mask);
+ ClassDB::bind_method(D_METHOD("set_collision_layer", "collision_layer"), &PhysicsShapeQueryParameters::set_collision_layer);
+ ClassDB::bind_method(D_METHOD("get_collision_layer"), &PhysicsShapeQueryParameters::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_object_type_mask", "object_type_mask"), &PhysicsShapeQueryParameters::set_object_type_mask);
ClassDB::bind_method(D_METHOD("get_object_type_mask"), &PhysicsShapeQueryParameters::get_object_type_mask);
@@ -211,7 +211,7 @@ void PhysicsShapeQueryParameters::_bind_methods() {
PhysicsShapeQueryParameters::PhysicsShapeQueryParameters() {
margin = 0;
- layer_mask = 0x7FFFFFFF;
+ collision_layer = 0x7FFFFFFF;
object_type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
}
@@ -274,7 +274,7 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
Vector<ShapeResult> sr;
sr.resize(p_max_results);
- int rc = intersect_shape(psq->shape, psq->transform, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->layer_mask, psq->object_type_mask);
+ int rc = intersect_shape(psq->shape, psq->transform, psq->margin, sr.ptr(), sr.size(), psq->exclude, psq->collision_layer, psq->object_type_mask);
Array ret;
ret.resize(rc);
for (int i = 0; i < rc; i++) {
@@ -293,7 +293,7 @@ Array PhysicsDirectSpaceState::_intersect_shape(const Ref<PhysicsShapeQueryParam
Array PhysicsDirectSpaceState::_cast_motion(const Ref<PhysicsShapeQueryParameters> &psq, const Vector3 &p_motion) {
float closest_safe, closest_unsafe;
- bool res = cast_motion(psq->shape, psq->transform, p_motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = cast_motion(psq->shape, psq->transform, p_motion, psq->margin, closest_safe, closest_unsafe, psq->exclude, psq->collision_layer, psq->object_type_mask);
if (!res)
return Array();
Array ret;
@@ -307,7 +307,7 @@ Array PhysicsDirectSpaceState::_collide_shape(const Ref<PhysicsShapeQueryParamet
Vector<Vector3> ret;
ret.resize(p_max_results * 2);
int rc = 0;
- bool res = collide_shape(psq->shape, psq->transform, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = collide_shape(psq->shape, psq->transform, psq->margin, ret.ptr(), p_max_results, rc, psq->exclude, psq->collision_layer, psq->object_type_mask);
if (!res)
return Array();
Array r;
@@ -320,7 +320,7 @@ Dictionary PhysicsDirectSpaceState::_get_rest_info(const Ref<PhysicsShapeQueryPa
ShapeRestInfo sri;
- bool res = rest_info(psq->shape, psq->transform, psq->margin, &sri, psq->exclude, psq->layer_mask, psq->object_type_mask);
+ bool res = rest_info(psq->shape, psq->transform, psq->margin, &sri, psq->exclude, psq->collision_layer, psq->object_type_mask);
Dictionary r;
if (!res)
return r;
@@ -343,7 +343,7 @@ void PhysicsDirectSpaceState::_bind_methods() {
//ClassDB::bind_method(D_METHOD("intersect_ray","from","to","exclude","umask"),&PhysicsDirectSpaceState::_intersect_ray,DEFVAL(Array()),DEFVAL(0));
//ClassDB::bind_method(D_METHOD("intersect_shape:PhysicsShapeQueryResult","shape","xform","result_max","exclude","umask"),&PhysicsDirectSpaceState::_intersect_shape,DEFVAL(Array()),DEFVAL(0));
- ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "layer_mask", "type_mask"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
+ ClassDB::bind_method(D_METHOD("intersect_ray:Dictionary", "from", "to", "exclude", "collision_layer", "type_mask"), &PhysicsDirectSpaceState::_intersect_ray, DEFVAL(Array()), DEFVAL(0x7FFFFFFF), DEFVAL(TYPE_MASK_COLLISION));
ClassDB::bind_method(D_METHOD("intersect_shape", "shape:PhysicsShapeQueryParameters", "max_results"), &PhysicsDirectSpaceState::_intersect_shape, DEFVAL(32));
ClassDB::bind_method(D_METHOD("cast_motion", "shape:PhysicsShapeQueryParameters", "motion"), &PhysicsDirectSpaceState::_cast_motion);
ClassDB::bind_method(D_METHOD("collide_shape", "shape:PhysicsShapeQueryParameters", "max_results"), &PhysicsDirectSpaceState::_collide_shape, DEFVAL(32));
@@ -425,7 +425,7 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("area_remove_shape", "area", "shape_idx"), &PhysicsServer::area_remove_shape);
ClassDB::bind_method(D_METHOD("area_clear_shapes", "area"), &PhysicsServer::area_clear_shapes);
- ClassDB::bind_method(D_METHOD("area_set_layer_mask", "area", "mask"), &PhysicsServer::area_set_layer_mask);
+ ClassDB::bind_method(D_METHOD("area_set_collision_layer", "area", "layer"), &PhysicsServer::area_set_collision_layer);
ClassDB::bind_method(D_METHOD("area_set_collision_mask", "area", "mask"), &PhysicsServer::area_set_collision_mask);
ClassDB::bind_method(D_METHOD("area_set_param", "area", "param", "value"), &PhysicsServer::area_set_param);
@@ -450,8 +450,8 @@ void PhysicsServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("body_set_mode", "body", "mode"), &PhysicsServer::body_set_mode);
ClassDB::bind_method(D_METHOD("body_get_mode", "body"), &PhysicsServer::body_get_mode);
- ClassDB::bind_method(D_METHOD("body_set_layer_mask", "body", "mask"), &PhysicsServer::body_set_layer_mask);
- ClassDB::bind_method(D_METHOD("body_get_layer_mask", "body"), &PhysicsServer::body_get_layer_mask);
+ ClassDB::bind_method(D_METHOD("body_set_collision_layer", "body", "layer"), &PhysicsServer::body_set_collision_layer);
+ ClassDB::bind_method(D_METHOD("body_get_collision_layer", "body"), &PhysicsServer::body_get_collision_layer);
ClassDB::bind_method(D_METHOD("body_set_collision_mask", "body", "mask"), &PhysicsServer::body_set_collision_mask);
ClassDB::bind_method(D_METHOD("body_get_collision_mask", "body"), &PhysicsServer::body_get_collision_mask);
diff --git a/servers/physics_server.h b/servers/physics_server.h
index 95f725b774..3d1a2aec7a 100644
--- a/servers/physics_server.h
+++ b/servers/physics_server.h
@@ -100,7 +100,7 @@ class PhysicsShapeQueryParameters : public Reference {
Transform transform;
float margin;
Set<RID> exclude;
- uint32_t layer_mask;
+ uint32_t collision_layer;
uint32_t object_type_mask;
protected:
@@ -117,8 +117,8 @@ public:
void set_margin(float p_margin);
float get_margin() const;
- void set_layer_mask(int p_layer_mask);
- int get_layer_mask() const;
+ void set_collision_layer(int p_collision_layer);
+ int get_collision_layer() const;
void set_object_type_mask(int p_object_type_mask);
int get_object_type_mask() const;
@@ -166,7 +166,7 @@ public:
int shape;
};
- virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
+ virtual bool intersect_ray(const Vector3 &p_from, const Vector3 &p_to, RayResult &r_result, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, bool p_pick_ray = false) = 0;
struct ShapeResult {
@@ -176,7 +176,7 @@ public:
int shape;
};
- virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual int intersect_shape(const RID &p_shape, const Transform &p_xform, float p_margin, ShapeResult *r_results, int p_result_max, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
struct ShapeRestInfo {
@@ -188,11 +188,11 @@ public:
Vector3 linear_velocity; //velocity at contact point
};
- virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL) = 0;
+ virtual bool cast_motion(const RID &p_shape, const Transform &p_xform, const Vector3 &p_motion, float p_margin, float &p_closest_safe, float &p_closest_unsafe, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION, ShapeRestInfo *r_info = NULL) = 0;
- virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool collide_shape(RID p_shape, const Transform &p_shape_xform, float p_margin, Vector3 *r_results, int p_result_max, int &r_result_count, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
- virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_layer_mask = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
+ virtual bool rest_info(RID p_shape, const Transform &p_shape_xform, float p_margin, ShapeRestInfo *r_info, const Set<RID> &p_exclude = Set<RID>(), uint32_t p_collision_layer = 0xFFFFFFFF, uint32_t p_object_type_mask = TYPE_MASK_COLLISION) = 0;
PhysicsDirectSpaceState();
};
@@ -332,7 +332,7 @@ public:
virtual Transform area_get_transform(RID p_area) const = 0;
virtual void area_set_collision_mask(RID p_area, uint32_t p_mask) = 0;
- virtual void area_set_layer_mask(RID p_area, uint32_t p_mask) = 0;
+ virtual void area_set_collision_layer(RID p_area, uint32_t p_layer) = 0;
virtual void area_set_monitorable(RID p_area, bool p_monitorable) = 0;
@@ -382,14 +382,14 @@ public:
virtual void body_set_enable_continuous_collision_detection(RID p_body, bool p_enable) = 0;
virtual bool body_is_continuous_collision_detection_enabled(RID p_body) const = 0;
- virtual void body_set_layer_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const = 0;
+ virtual void body_set_collision_layer(RID p_body, uint32_t p_layer) = 0;
+ virtual uint32_t body_get_collision_layer(RID p_body) const = 0;
virtual void body_set_collision_mask(RID p_body, uint32_t p_mask) = 0;
- virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const = 0;
+ virtual uint32_t body_get_collision_mask(RID p_body) const = 0;
virtual void body_set_user_flags(RID p_body, uint32_t p_flags) = 0;
- virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const = 0;
+ virtual uint32_t body_get_user_flags(RID p_body) const = 0;
// common body variables
enum BodyParameter {
diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h
index f6b78e8f40..e285483e2b 100644
--- a/servers/server_wrap_mt_common.h
+++ b/servers/server_wrap_mt_common.h
@@ -41,8 +41,9 @@
}
#define FUNCRID(m_type) \
+ List<RID> m_type##_id_pool; \
int m_type##allocn() { \
- for (int i = 0; i < m_type##_pool_max_size; i++) { \
+ for (int i = 0; i < pool_max_size; i++) { \
m_type##_id_pool.push_back(server_name->m_type##_create()); \
} \
return 0; \
@@ -747,3 +748,30 @@
server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8); \
} \
}
+
+#define FUNC9(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9) { \
+ if (Thread::get_caller_ID() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9); \
+ } \
+ }
+
+#define FUNC10(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10) { \
+ if (Thread::get_caller_ID() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10); \
+ } \
+ }
+
+#define FUNC11(m_type, m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8, m_arg9, m_arg10, m_arg11) \
+ virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8, m_arg9 p9, m_arg10 p10, m_arg11 p11) { \
+ if (Thread::get_caller_ID() != server_thread) { \
+ command_queue.push(server_name, &ServerName::m_type, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } else { \
+ server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11); \
+ } \
+ }
diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp
index b565ee8f9d..f7ea158646 100644
--- a/servers/visual/rasterizer.cpp
+++ b/servers/visual/rasterizer.cpp
@@ -38,11 +38,11 @@ Rasterizer *Rasterizer::create() {
return _create_func();
}
-RasterizerStorage *RasterizerStorage::base_signleton = NULL;
+RasterizerStorage *RasterizerStorage::base_singleton = NULL;
RasterizerStorage::RasterizerStorage() {
- base_signleton = this;
+ base_singleton = this;
}
#if 0
diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h
index ff679bc15f..07d6542b62 100644
--- a/servers/visual/rasterizer.h
+++ b/servers/visual/rasterizer.h
@@ -52,25 +52,29 @@ public:
virtual RID environment_create() = 0;
virtual void environment_set_background(RID p_env, VS::EnvironmentBG p_bg) = 0;
- virtual void environment_set_skybox(RID p_env, RID p_skybox) = 0;
- virtual void environment_set_skybox_scale(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_scale(RID p_env, float p_scale) = 0;
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_skybox_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
virtual void environment_set_dof_blur_near(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
virtual void environment_set_dof_blur_far(RID p_env, bool p_enable, float p_distance, float p_transition, float p_far_amount, VS::EnvironmentDOFBlurQuality p_quality) = 0;
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, VS::EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
- virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) = 0;
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_int, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0;
virtual void environment_set_tonemap(RID p_env, VS::EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_scale) = 0;
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
struct InstanceBase : RID_Data {
VS::InstanceType base_type;
@@ -127,7 +131,7 @@ public:
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
- virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass) = 0;
+ virtual void light_instance_set_shadow_transform(RID p_light_instance, const CameraMatrix &p_projection, const Transform &p_transform, float p_far, float p_split, int p_pass, float p_bias_scale = 1.0) = 0;
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
virtual RID reflection_atlas_create() = 0;
@@ -151,6 +155,7 @@ public:
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, InstanceBase **p_cull_result, int p_cull_count) = 0;
virtual void set_scene_pass(uint64_t p_pass) = 0;
+ virtual void set_debug_draw_mode(VS::ViewportDebugDraw p_debug_draw) = 0;
virtual bool free(RID p_rid) = 0;
@@ -163,11 +168,12 @@ public:
virtual RID texture_create() = 0;
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT) = 0;
- virtual void texture_set_data(RID p_texture, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
- virtual Image texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) = 0;
+ virtual Ref<Image> texture_get_data(RID p_texture, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
virtual Image::Format texture_get_format(RID p_texture) const = 0;
+ virtual uint32_t texture_get_texid(RID p_texture) const = 0;
virtual uint32_t texture_get_width(RID p_texture) const = 0;
virtual uint32_t texture_get_height(RID p_texture) const = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -183,13 +189,14 @@ public:
virtual void texture_set_detect_3d_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void texture_set_detect_srgb_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_normal_callback(RID p_texture, VisualServer::TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void textures_keep_original(bool p_enable) = 0;
- /* SKYBOX API */
+ /* SKY API */
- virtual RID skybox_create() = 0;
- virtual void skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size) = 0;
+ virtual RID sky_create() = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
@@ -458,11 +465,15 @@ public:
virtual void particles_set_emission_transform(RID p_particles, const Transform &p_transform) = 0;
+ virtual int particles_get_draw_passes(RID p_particles) const = 0;
+ virtual RID particles_get_draw_pass_mesh(RID p_particles, int p_pass) const = 0;
+
/* RENDER TARGET */
enum RenderTargetFlags {
RENDER_TARGET_VFLIP,
RENDER_TARGET_TRANSPARENT,
+ RENDER_TARGET_NO_3D_EFFECTS,
RENDER_TARGET_NO_3D,
RENDER_TARGET_NO_SAMPLING,
RENDER_TARGET_HDR,
@@ -473,7 +484,8 @@ public:
virtual void render_target_set_size(RID p_render_target, int p_width, int p_height) = 0;
virtual RID render_target_get_texture(RID p_render_target) const = 0;
virtual void render_target_set_flag(RID p_render_target, RenderTargetFlags p_flag, bool p_value) = 0;
- virtual bool render_target_renedered_in_frame(RID p_render_target) = 0;
+ virtual bool render_target_was_used(RID p_render_target) = 0;
+ virtual void render_target_clear_used(RID p_render_target) = 0;
virtual void render_target_set_msaa(RID p_render_target, VS::ViewportMSAA p_msaa) = 0;
/* CANVAS SHADOW */
@@ -492,7 +504,15 @@ public:
virtual void update_dirty_resources() = 0;
- static RasterizerStorage *base_signleton;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
+ virtual void render_info_begin_capture() = 0;
+ virtual void render_info_end_capture() = 0;
+ virtual int get_captured_render_info(VS::RenderInfo p_info) = 0;
+
+ virtual int get_render_info(VS::RenderInfo p_info) = 0;
+
+ static RasterizerStorage *base_singleton;
RasterizerStorage();
virtual ~RasterizerStorage() {}
};
@@ -505,7 +525,8 @@ public:
CANVAS_RECT_TILE = 2,
CANVAS_RECT_FLIP_H = 4,
CANVAS_RECT_FLIP_V = 8,
- CANVAS_RECT_TRANSPOSE = 16
+ CANVAS_RECT_TRANSPOSE = 16,
+ CANVAS_RECT_CLIP_UV = 32
};
struct Light : public RID_Data {
@@ -531,6 +552,7 @@ public:
float shadow_gradient_length;
VS::CanvasLightShadowFilter shadow_filter;
Color shadow_color;
+ float shadow_smooth;
void *texture_cache; // implementation dependent
Rect2 rect_cache;
@@ -569,6 +591,7 @@ public:
shadow_buffer_size = 256;
shadow_gradient_length = 0;
shadow_filter = VS::CANVAS_LIGHT_FILTER_NONE;
+ shadow_smooth = 0.0;
}
};
@@ -611,6 +634,7 @@ public:
Rect2 rect;
RID texture;
+ RID normal_map;
Color modulate;
Rect2 source;
uint8_t flags;
@@ -626,6 +650,7 @@ public:
Rect2 rect;
Rect2 source;
RID texture;
+ RID normal_map;
float margin[4];
bool draw_center;
Color color;
@@ -643,6 +668,7 @@ public:
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
+ RID normal_map;
float width;
CommandPrimitive() {
@@ -658,6 +684,7 @@ public:
Vector<Point2> uvs;
Vector<Color> colors;
RID texture;
+ RID normal_map;
int count;
CommandPolygon() {
@@ -768,7 +795,7 @@ public:
case Item::Command::TYPE_LINE: {
const Item::CommandLine *line = static_cast<const Item::CommandLine *>(c);
- r.pos = line->from;
+ r.position = line->from;
r.expand_to(line->to);
} break;
case Item::Command::TYPE_RECT: {
@@ -785,7 +812,7 @@ public:
case Item::Command::TYPE_PRIMITIVE: {
const Item::CommandPrimitive *primitive = static_cast<const Item::CommandPrimitive *>(c);
- r.pos = primitive->points[0];
+ r.position = primitive->points[0];
for (int i = 1; i < primitive->points.size(); i++) {
r.expand_to(primitive->points[i]);
@@ -796,7 +823,7 @@ public:
const Item::CommandPolygon *polygon = static_cast<const Item::CommandPolygon *>(c);
int l = polygon->points.size();
const Point2 *pp = &polygon->points[0];
- r.pos = pp[0];
+ r.position = pp[0];
for (int i = 1; i < l; i++) {
r.expand_to(pp[i]);
@@ -805,23 +832,23 @@ public:
case Item::Command::TYPE_MESH: {
const Item::CommandMesh *mesh = static_cast<const Item::CommandMesh *>(c);
- Rect3 aabb = RasterizerStorage::base_signleton->mesh_get_aabb(mesh->mesh, mesh->skeleton);
+ Rect3 aabb = RasterizerStorage::base_singleton->mesh_get_aabb(mesh->mesh, mesh->skeleton);
- r = Rect2(aabb.pos.x, aabb.pos.y, aabb.size.x, aabb.size.y);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
} break;
case Item::Command::TYPE_MULTIMESH: {
const Item::CommandMultiMesh *multimesh = static_cast<const Item::CommandMultiMesh *>(c);
- Rect3 aabb = RasterizerStorage::base_signleton->multimesh_get_aabb(multimesh->multimesh);
+ Rect3 aabb = RasterizerStorage::base_singleton->multimesh_get_aabb(multimesh->multimesh);
- r = Rect2(aabb.pos.x, aabb.pos.y, aabb.size.x, aabb.size.y);
+ r = Rect2(aabb.position.x, aabb.position.y, aabb.size.x, aabb.size.y);
} break;
case Item::Command::TYPE_CIRCLE: {
const Item::CommandCircle *circle = static_cast<const Item::CommandCircle *>(c);
- r.pos = Point2(-circle->radius, -circle->radius) + circle->pos;
+ r.position = Point2(-circle->radius, -circle->radius) + circle->pos;
r.size = Point2(circle->radius * 2.0, circle->radius * 2.0);
} break;
case Item::Command::TYPE_TRANSFORM: {
@@ -931,7 +958,7 @@ public:
virtual RasterizerCanvas *get_canvas() = 0;
virtual RasterizerScene *get_scene() = 0;
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) = 0;
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) = 0;
virtual void initialize() = 0;
virtual void begin_frame() = 0;
diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp
index 9fe92f0fec..96d56dfc56 100644
--- a/servers/visual/shader_language.cpp
+++ b/servers/visual/shader_language.cpp
@@ -2549,12 +2549,14 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
} break;
- default: {}
+ default: {
+ ok = false;
+ }
}
if (!ok) {
- _set_error("Invalid member for expression: ." + ident);
+ _set_error("Invalid member for " + get_datatype_name(dt) + " expression: ." + ident);
return NULL;
}
@@ -3185,7 +3187,7 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
tk = _get_token();
if (tk.type != TK_PARENTHESIS_CLOSE) {
- _set_error("Expected '(' after expression");
+ _set_error("Expected ')' after expression");
return ERR_PARSE_ERROR;
}
@@ -3196,6 +3198,8 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
p_block->statements.push_back(cf);
Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
pos = _get_tkpos();
tk = _get_token();
@@ -3209,6 +3213,35 @@ Error ShaderLanguage::_parse_block(BlockNode *p_block, const Map<StringName, Dat
} else {
_set_tkpos(pos); //rollback
}
+ } else if (tk.type == TK_CF_WHILE) {
+ //if () {}
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_OPEN) {
+ _set_error("Expected '(' after if");
+ return ERR_PARSE_ERROR;
+ }
+
+ ControlFlowNode *cf = alloc_node<ControlFlowNode>();
+ cf->flow_op = FLOW_OP_WHILE;
+ Node *n = _parse_and_reduce_expression(p_block, p_builtin_types);
+ if (!n)
+ return ERR_PARSE_ERROR;
+
+ tk = _get_token();
+ if (tk.type != TK_PARENTHESIS_CLOSE) {
+ _set_error("Expected ')' after expression");
+ return ERR_PARSE_ERROR;
+ }
+
+ BlockNode *block = alloc_node<BlockNode>();
+ block->parent_block = p_block;
+ cf->expressions.push_back(n);
+ cf->blocks.push_back(block);
+ p_block->statements.push_back(cf);
+
+ Error err = _parse_block(block, p_builtin_types, true, p_can_break, p_can_continue);
+ if (err)
+ return err;
} else if (tk.type == TK_CF_RETURN) {
diff --git a/servers/visual/shader_types.cpp b/servers/visual/shader_types.cpp
index 8d72ee3f34..81139ecc1c 100644
--- a/servers/visual/shader_types.cpp
+++ b/servers/visual/shader_types.cpp
@@ -52,7 +52,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_VERTEX"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_NORMAL"] = ShaderLanguage::TYPE_VEC3;
- shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_TANGENT"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_BONES"] = ShaderLanguage::TYPE_IVEC4;
shader_modes[VS::SHADER_SPATIAL].functions["vertex"]["SRC_WEIGHTS"] = ShaderLanguage::TYPE_VEC4;
@@ -91,7 +90,8 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALBEDO"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ALPHA"] = ShaderLanguage::TYPE_FLOAT;
- shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_VEC3;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["METALLIC"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECULAR"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["ROUGHNESS"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["RIM_TINT"] = ShaderLanguage::TYPE_FLOAT;
@@ -104,8 +104,11 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["EMISSION"] = ShaderLanguage::TYPE_VEC3;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SPECIAL"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DISCARD"] = ShaderLanguage::TYPE_BOOL;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["DEPTH_TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
+ shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["SIDE"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["WORLD_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_SPATIAL].functions["fragment"]["INV_CAMERA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
@@ -130,6 +133,11 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_SPATIAL].modes.insert("unshaded");
shader_modes[VS::SHADER_SPATIAL].modes.insert("ontop");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_half_lambert");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_oren_nayar");
+ shader_modes[VS::SHADER_SPATIAL].modes.insert("diffuse_burley");
+
shader_modes[VS::SHADER_SPATIAL].modes.insert("skip_default_transform");
/************ CANVAS ITEM **************************/
@@ -145,6 +153,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["EXTRA_MATRIX"] = ShaderLanguage::TYPE_MAT4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["PARTICLE_CUSTOM"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["vertex"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SRC_COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
@@ -158,6 +167,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["POINT_COORD"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
+ shader_modes[VS::SHADER_CANVAS_ITEM].functions["fragment"]["AT_LIGHT_PASS"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["POSITION"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["NORMAL"] = ShaderLanguage::TYPE_VEC3;
@@ -165,8 +175,6 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["COLOR"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE"] = ShaderLanguage::TYPE_SAMPLER2D;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["TEXTURE_PIXEL_SIZE"] = ShaderLanguage::TYPE_VEC2;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR1"] = ShaderLanguage::TYPE_VEC4;
- shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["VAR2"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["SCREEN_UV"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_VEC"] = ShaderLanguage::TYPE_VEC2;
shader_modes[VS::SHADER_CANVAS_ITEM].functions["light"]["LIGHT_HEIGHT"] = ShaderLanguage::TYPE_FLOAT;
@@ -198,7 +206,7 @@ ShaderTypes::ShaderTypes() {
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["RESTART"] = ShaderLanguage::TYPE_BOOL;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["CUSTOM"] = ShaderLanguage::TYPE_VEC4;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TRANSFORM"] = ShaderLanguage::TYPE_MAT4;
- shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_VEC4;
+ shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["TIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["LIFETIME"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["DELTA"] = ShaderLanguage::TYPE_FLOAT;
shader_modes[VS::SHADER_PARTICLES].functions["vertex"]["NUMBER"] = ShaderLanguage::TYPE_UINT;
diff --git a/servers/visual/visual_server_canvas.cpp b/servers/visual/visual_server_canvas.cpp
index 3a83ba887d..2ef1fd417b 100644
--- a/servers/visual/visual_server_canvas.cpp
+++ b/servers/visual/visual_server_canvas.cpp
@@ -61,7 +61,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
Rect2 rect = ci->get_rect();
Transform2D xform = p_transform * ci->xform;
Rect2 global_rect = xform.xform(rect);
- global_rect.pos += p_clip_rect.pos;
+ global_rect.position += p_clip_rect.position;
if (ci->use_parent_material && p_material_owner)
ci->material_owner = p_material_owner;
@@ -119,7 +119,7 @@ void VisualServerCanvas::_render_canvas_item(Item *p_canvas_item, const Transfor
ci->final_transform = xform;
ci->final_modulate = Color(modulate.r * ci->self_modulate.r, modulate.g * ci->self_modulate.g, modulate.b * ci->self_modulate.b, modulate.a * ci->self_modulate.a);
ci->global_rect_cache = global_rect;
- ci->global_rect_cache.pos -= p_clip_rect.pos;
+ ci->global_rect_cache.position -= p_clip_rect.position;
ci->light_masked = false;
int zidx = p_z - VS::CANVAS_ITEM_Z_MIN;
@@ -233,7 +233,6 @@ void VisualServerCanvas::render_canvas(Canvas *p_canvas, const Transform2D &p_tr
}
VSG::canvas_render->canvas_end();
-
}
RID VisualServerCanvas::canvas_create() {
@@ -426,7 +425,7 @@ void VisualServerCanvas::canvas_item_add_circle(RID p_item, const Point2 &p_pos,
canvas_item->commands.push_back(circle);
}
-void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose) {
+void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile, const Color &p_modulate, bool p_transpose, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -457,11 +456,12 @@ void VisualServerCanvas::canvas_item_add_texture_rect(RID p_item, const Rect2 &p
SWAP(rect->rect.size.x, rect->rect.size.y);
}
rect->texture = p_texture;
+ rect->normal_map = p_normal_map;
canvas_item->rect_dirty = true;
canvas_item->commands.push_back(rect);
}
-void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose) {
+void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate, bool p_transpose, RID p_normal_map, bool p_clip_uv) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -471,6 +471,7 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
rect->modulate = p_modulate;
rect->rect = p_rect;
rect->texture = p_texture;
+ rect->normal_map = p_normal_map;
rect->source = p_src_rect;
rect->flags = RasterizerCanvas::CANVAS_RECT_REGION;
@@ -489,12 +490,16 @@ void VisualServerCanvas::canvas_item_add_texture_rect_region(RID p_item, const R
SWAP(rect->rect.size.x, rect->rect.size.y);
}
+ if (p_clip_uv) {
+ rect->flags |= RasterizerCanvas::CANVAS_RECT_CLIP_UV;
+ }
+
canvas_item->rect_dirty = true;
canvas_item->commands.push_back(rect);
}
-void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate) {
+void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode, VS::NinePatchAxisMode p_y_axis_mode, bool p_draw_center, const Color &p_modulate, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -502,6 +507,7 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
Item::CommandNinePatch *style = memnew(Item::CommandNinePatch);
ERR_FAIL_COND(!style);
style->texture = p_texture;
+ style->normal_map = p_normal_map;
style->rect = p_rect;
style->source = p_source;
style->draw_center = p_draw_center;
@@ -516,7 +522,7 @@ void VisualServerCanvas::canvas_item_add_nine_patch(RID p_item, const Rect2 &p_r
canvas_item->commands.push_back(style);
}
-void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width) {
+void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -524,6 +530,7 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
Item::CommandPrimitive *prim = memnew(Item::CommandPrimitive);
ERR_FAIL_COND(!prim);
prim->texture = p_texture;
+ prim->normal_map = p_normal_map;
prim->points = p_points;
prim->uvs = p_uvs;
prim->colors = p_colors;
@@ -533,7 +540,7 @@ void VisualServerCanvas::canvas_item_add_primitive(RID p_item, const Vector<Poin
canvas_item->commands.push_back(prim);
}
-void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
+void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -556,6 +563,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
ERR_FAIL_COND(!polygon);
polygon->texture = p_texture;
+ polygon->normal_map = p_normal_map;
polygon->points = p_points;
polygon->uvs = p_uvs;
polygon->colors = p_colors;
@@ -566,7 +574,7 @@ void VisualServerCanvas::canvas_item_add_polygon(RID p_item, const Vector<Point2
canvas_item->commands.push_back(polygon);
}
-void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, int p_count) {
+void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, int p_count, RID p_normal_map) {
Item *canvas_item = canvas_item_owner.getornull(p_item);
ERR_FAIL_COND(!canvas_item);
@@ -594,6 +602,7 @@ void VisualServerCanvas::canvas_item_add_triangle_array(RID p_item, const Vector
Item::CommandPolygon *polygon = memnew(Item::CommandPolygon);
ERR_FAIL_COND(!polygon);
polygon->texture = p_texture;
+ polygon->normal_map = p_normal_map;
polygon->points = p_points;
polygon->uvs = p_uvs;
polygon->colors = p_colors;
@@ -917,6 +926,13 @@ void VisualServerCanvas::canvas_light_set_shadow_color(RID p_light, const Color
clight->shadow_color = p_color;
}
+void VisualServerCanvas::canvas_light_set_shadow_smooth(RID p_light, float p_smooth) {
+
+ RasterizerCanvas::Light *clight = canvas_light_owner.get(p_light);
+ ERR_FAIL_COND(!clight);
+ clight->shadow_smooth = p_smooth;
+}
+
RID VisualServerCanvas::canvas_light_occluder_create() {
RasterizerCanvas::LightOccluderInstance *occluder = memnew(RasterizerCanvas::LightOccluderInstance);
@@ -1041,7 +1057,7 @@ void VisualServerCanvas::canvas_occluder_polygon_set_shape_as_lines(RID p_occlud
PoolVector<Vector2>::Read r = p_shape.read();
for (int i = 0; i < lc; i++) {
if (i == 0)
- occluder_poly->aabb.pos = r[i];
+ occluder_poly->aabb.position = r[i];
else
occluder_poly->aabb.expand_to(r[i]);
}
diff --git a/servers/visual/visual_server_canvas.h b/servers/visual/visual_server_canvas.h
index 47b057f96a..2c86b14c70 100644
--- a/servers/visual/visual_server_canvas.h
+++ b/servers/visual/visual_server_canvas.h
@@ -165,12 +165,12 @@ public:
void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false);
void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color);
void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color);
- void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
- void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false);
- void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1));
- void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0);
- void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID());
- void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1);
+ void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID());
+ void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true);
+ void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, VS::NinePatchAxisMode p_x_axis_mode = VS::NINE_PATCH_STRETCH, VS::NinePatchAxisMode p_y_axis_mode = VS::NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID());
+ void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID());
+ void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID());
+ void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID());
void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID());
void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID());
void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform);
@@ -209,6 +209,7 @@ public:
void canvas_light_set_shadow_gradient_length(RID p_light, float p_length);
void canvas_light_set_shadow_filter(RID p_light, VS::CanvasLightShadowFilter p_filter);
void canvas_light_set_shadow_color(RID p_light, const Color &p_color);
+ void canvas_light_set_shadow_smooth(RID p_light, float p_smooth);
RID canvas_light_occluder_create();
void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas);
diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp
index 5ba975d193..8d332b3e6c 100644
--- a/servers/visual/visual_server_raster.cpp
+++ b/servers/visual/visual_server_raster.cpp
@@ -74,6 +74,19 @@ void VisualServerRaster::free(RID p_rid) {
/* EVENT QUEUING */
+void VisualServerRaster::request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) {
+
+ ERR_FAIL_NULL(p_where);
+ FrameDrawnCallbacks fdc;
+ fdc.object = p_where->get_instance_ID();
+ fdc.method = p_method;
+ fdc.param = p_userdata;
+
+ frame_drawn_callbacks.push_back(fdc);
+
+ print_line("added callback to draw");
+}
+
void VisualServerRaster::draw() {
/*
@@ -92,6 +105,22 @@ void VisualServerRaster::draw() {
//_draw_cursors_and_margins();
VSG::rasterizer->end_frame();
//draw_extra_frame=VS:rasterizer->needs_to_draw_next_frame();
+
+ while (frame_drawn_callbacks.front()) {
+
+ Object *obj = ObjectDB::get_instance(frame_drawn_callbacks.front()->get().object);
+ if (obj) {
+ Variant::CallError ce;
+ const Variant *v = &frame_drawn_callbacks.front()->get().param;
+ obj->call(frame_drawn_callbacks.front()->get().method, &v, 1, ce);
+ if (ce.error != Variant::CallError::CALL_OK) {
+ String err = Variant::get_call_error_text(obj, frame_drawn_callbacks.front()->get().method, &v, 1, ce);
+ ERR_PRINTS("Error calling frame drawn function: " + err);
+ }
+ }
+
+ frame_drawn_callbacks.pop_front();
+ }
}
void VisualServerRaster::sync() {
}
@@ -116,12 +145,12 @@ void VisualServerRaster::finish() {
int VisualServerRaster::get_render_info(RenderInfo p_info) {
- return 0;
+ return VSG::storage->get_render_info(p_info);
}
/* TESTING */
-void VisualServerRaster::set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) {
+void VisualServerRaster::set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) {
redraw_request();
VSG::rasterizer->set_boot_image(p_image, p_color, p_scale);
@@ -146,6 +175,11 @@ bool VisualServerRaster::has_os_feature(const String &p_feature) const {
return VSG::storage->has_os_feature(p_feature);
}
+void VisualServerRaster::set_debug_generate_wireframes(bool p_generate) {
+
+ VSG::storage->set_debug_generate_wireframes(p_generate);
+}
+
VisualServerRaster::VisualServerRaster() {
VSG::canvas = memnew(VisualServerCanvas);
diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h
index 7de497d529..c48bee7fa4 100644
--- a/servers/visual/visual_server_raster.h
+++ b/servers/visual/visual_server_raster.h
@@ -61,6 +61,15 @@ class VisualServerRaster : public VisualServer {
bool draw_extra_frame;
RID test_cube;
+ struct FrameDrawnCallbacks {
+
+ ObjectID object;
+ StringName method;
+ Variant param;
+ };
+
+ List<FrameDrawnCallbacks> frame_drawn_callbacks;
+
#if 0
struct Room {
@@ -586,6 +595,8 @@ public:
m_r m_name(m_type1 arg1) { return BINDBASE->m_name(arg1); }
#define BIND1RC(m_r, m_name, m_type1) \
m_r m_name(m_type1 arg1) const { return BINDBASE->m_name(arg1); }
+#define BIND2R(m_r, m_name, m_type1, m_type2) \
+ m_r m_name(m_type1 arg1, m_type2 arg2) { return BINDBASE->m_name(arg1, arg2); }
#define BIND2RC(m_r, m_name, m_type1, m_type2) \
m_r m_name(m_type1 arg1, m_type2 arg2) const { return BINDBASE->m_name(arg1, arg2); }
#define BIND3RC(m_r, m_name, m_type1, m_type2, m_type3) \
@@ -615,6 +626,8 @@ public:
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9); }
#define BIND10(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10) \
void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10); }
+#define BIND11(m_name, m_type1, m_type2, m_type3, m_type4, m_type5, m_type6, m_type7, m_type8, m_type9, m_type10, m_type11) \
+ void m_name(m_type1 arg1, m_type2 arg2, m_type3 arg3, m_type4 arg4, m_type5 arg5, m_type6 arg6, m_type7 arg7, m_type8 arg8, m_type9 arg9, m_type10 arg10, m_type11 arg11) { DISPLAY_CHANGED BINDBASE->m_name(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11); }
//from now on, calls forwarded to this singleton
#define BINDBASE VSG::storage
@@ -623,18 +636,19 @@ public:
BIND0R(RID, texture_create)
BIND5(texture_allocate, RID, int, int, Image::Format, uint32_t)
- BIND3(texture_set_data, RID, const Image &, CubeMapSide)
- BIND2RC(Image, texture_get_data, RID, CubeMapSide)
+ BIND3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ BIND2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
BIND2(texture_set_flags, RID, uint32_t)
BIND1RC(uint32_t, texture_get_flags, RID)
BIND1RC(Image::Format, texture_get_format, RID)
+ BIND1RC(uint32_t, texture_get_texid, RID)
BIND1RC(uint32_t, texture_get_width, RID)
BIND1RC(uint32_t, texture_get_height, RID)
BIND3(texture_set_size_override, RID, int, int)
- BIND2RC(RID, texture_create_radiance_cubemap, RID, int)
BIND3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
BIND3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
+ BIND3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
BIND2(texture_set_path, RID, const String &)
BIND1RC(String, texture_get_path, RID)
@@ -643,10 +657,10 @@ public:
BIND1(textures_keep_original, bool)
- /* SKYBOX API */
+ /* SKY API */
- BIND0R(RID, skybox_create)
- BIND3(skybox_set_texture, RID, RID, int)
+ BIND0R(RID, sky_create)
+ BIND3(sky_set_texture, RID, RID, int)
/* SHADER API */
@@ -921,6 +935,10 @@ public:
BIND3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
BIND2(viewport_set_msaa, RID, ViewportMSAA)
BIND2(viewport_set_hdr, RID, bool)
+ BIND2(viewport_set_usage, RID, ViewportUsage)
+
+ BIND2R(int, viewport_get_render_info, RID, ViewportRenderInfo)
+ BIND2(viewport_set_debug_draw, RID, ViewportDebugDraw)
/* ENVIRONMENT API */
@@ -931,24 +949,27 @@ public:
BIND0R(RID, environment_create)
BIND2(environment_set_background, RID, EnvironmentBG)
- BIND2(environment_set_skybox, RID, RID)
- BIND2(environment_set_skybox_scale, RID, float)
+ BIND2(environment_set_sky, RID, RID)
+ BIND2(environment_set_sky_scale, RID, float)
BIND2(environment_set_bg_color, RID, const Color &)
BIND2(environment_set_bg_energy, RID, float)
BIND2(environment_set_canvas_max_layer, RID, int)
BIND4(environment_set_ambient_light, RID, const Color &, float, float)
- BIND8(environment_set_ssr, RID, bool, int, float, float, float, bool, bool)
+ BIND7(environment_set_ssr, RID, bool, int, float, float, float, bool)
BIND10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool)
BIND6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
BIND10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
- BIND5(environment_set_fog, RID, bool, float, float, RID)
BIND9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
BIND6(environment_set_adjustment, RID, bool, float, float, float, RID)
+ BIND5(environment_set_fog, RID, bool, const Color &, const Color &, float)
+ BIND6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ BIND5(environment_set_fog_height, RID, bool, float, float, float)
+
/* SCENARIO API */
#undef BINDBASE
@@ -1020,12 +1041,12 @@ public:
BIND6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
BIND3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
BIND4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
- BIND6(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool)
- BIND6(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool)
- BIND10(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &)
- BIND6(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float)
- BIND5(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID)
- BIND7(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int)
+ BIND7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID)
+ BIND8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool)
+ BIND11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
+ BIND7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
+ BIND6(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID)
+ BIND8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
BIND3(canvas_item_add_mesh, RID, const RID &, RID)
BIND3(canvas_item_add_multimesh, RID, RID, RID)
BIND2(canvas_item_add_set_transform, RID, const Transform2D &)
@@ -1064,6 +1085,7 @@ public:
BIND2(canvas_light_set_shadow_gradient_length, RID, float)
BIND2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
BIND2(canvas_light_set_shadow_color, RID, const Color &)
+ BIND2(canvas_light_set_shadow_smooth, RID, float)
BIND0R(RID, canvas_light_occluder_create)
BIND2(canvas_light_occluder_attach_to_canvas, RID, RID)
@@ -1095,6 +1117,8 @@ public:
/* EVENT QUEUING */
+ virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata);
+
virtual void draw();
virtual void sync();
virtual bool has_changed() const;
@@ -1109,12 +1133,13 @@ public:
/* TESTING */
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale);
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale);
virtual void set_default_clear_color(const Color &p_color);
virtual bool has_feature(Features p_feature) const;
virtual bool has_os_feature(const String &p_feature) const;
+ virtual void set_debug_generate_wireframes(bool p_generate);
VisualServerRaster();
~VisualServerRaster();
diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp
index b905b230dc..6d1f698a5c 100644
--- a/servers/visual/visual_server_scene.cpp
+++ b/servers/visual/visual_server_scene.cpp
@@ -1347,6 +1347,8 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
bool overlap = VSG::storage->light_directional_get_blend_splits(p_instance->base);
+ float first_radius = 0.0;
+
for (int i = 0; i < splits; i++) {
// setup a camera matrix for that range!
@@ -1373,9 +1375,11 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
// obtain the light frustm ranges (given endpoints)
- Vector3 x_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_X).normalized();
- Vector3 y_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Y).normalized();
- Vector3 z_vec = p_instance->transform.basis.get_axis(Vector3::AXIS_Z).normalized();
+ Transform transform = p_instance->transform.orthonormalized(); //discard scale and stabilize light
+
+ Vector3 x_vec = transform.basis.get_axis(Vector3::AXIS_X).normalized();
+ Vector3 y_vec = transform.basis.get_axis(Vector3::AXIS_Y).normalized();
+ Vector3 z_vec = transform.basis.get_axis(Vector3::AXIS_Z).normalized();
//z_vec points agsint the camera, like in default opengl
float x_min, x_max;
@@ -1386,7 +1390,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
float y_min_cam, y_max_cam;
float z_min_cam, z_max_cam;
+ float bias_scale = 1.0;
+
//used for culling
+
for (int j = 0; j < 8; j++) {
float d_x = x_vec.dot(endpoints[j]);
@@ -1435,6 +1442,12 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
radius *= texture_size / (texture_size - 2.0); //add a texel by each side, so stepified texture will always fit
+ if (i == 0) {
+ first_radius = radius;
+ } else {
+ bias_scale = radius / first_radius;
+ }
+
x_max_cam = x_vec.dot(center) + radius;
x_min_cam = x_vec.dot(center) - radius;
y_max_cam = y_vec.dot(center) + radius;
@@ -1493,10 +1506,10 @@ void VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons
ortho_camera.set_orthogonal(-half_x, half_x, -half_y, half_y, 0, (z_max - z_min_cam));
Transform ortho_transform;
- ortho_transform.basis = p_instance->transform.basis;
+ ortho_transform.basis = transform.basis;
ortho_transform.origin = x_vec * (x_min_cam + half_x) + y_vec * (y_min_cam + half_y) + z_vec * z_max;
- VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i);
+ VSG::scene_render->light_instance_set_shadow_transform(light->instance, ortho_camera, ortho_transform, 0, distances[i + 1], i, bias_scale);
}
VSG::scene_render->render_shadow(light->instance, p_shadow_atlas, i, (RasterizerScene::InstanceBase **)instance_shadow_cull_result, cull_count);
@@ -3310,6 +3323,36 @@ void VisualServerScene::_update_dirty_instance(Instance *p_instance) {
} else {
can_cast_shadows = false;
}
+ } else if (p_instance->base_type == VS::INSTANCE_PARTICLES) {
+
+ bool cast_shadows = false;
+
+ int dp = VSG::storage->particles_get_draw_passes(p_instance->base);
+
+ for (int i = 0; i < dp; i++) {
+
+ RID mesh = VSG::storage->particles_get_draw_pass_mesh(p_instance->base, i);
+
+ int sc = VSG::storage->mesh_get_surface_count(mesh);
+ for (int j = 0; j < sc; j++) {
+
+ RID mat = VSG::storage->mesh_surface_get_material(mesh, j);
+
+ if (!mat.is_valid()) {
+ cast_shadows = true;
+ break;
+ }
+
+ if (VSG::storage->material_casts_shadows(mat)) {
+ cast_shadows = true;
+ break;
+ }
+ }
+ }
+
+ if (!cast_shadows) {
+ can_cast_shadows = false;
+ }
}
}
diff --git a/servers/visual/visual_server_scene.h b/servers/visual/visual_server_scene.h
index 1aab624654..92c6421987 100644
--- a/servers/visual/visual_server_scene.h
+++ b/servers/visual/visual_server_scene.h
@@ -118,7 +118,7 @@ public:
Camera() {
visible_layers = 0xFFFFFFFF;
- fov = 60;
+ fov = 65;
type = PERSPECTIVE;
znear = 0.1;
zfar = 100;
diff --git a/servers/visual/visual_server_viewport.cpp b/servers/visual/visual_server_viewport.cpp
index 63ed0ac7c4..2fbbcd225f 100644
--- a/servers/visual/visual_server_viewport.cpp
+++ b/servers/visual/visual_server_viewport.cpp
@@ -88,7 +88,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
}
}
- if (!p_viewport->disable_3d && p_viewport->camera.is_valid()) {
+ if (!p_viewport->disable_3d && !p_viewport->disable_3d_by_usage && p_viewport->camera.is_valid()) {
VSG::scene->render_camera(p_viewport->camera, p_viewport->scenario, p_viewport->size, p_viewport->shadow_atlas);
}
@@ -133,7 +133,7 @@ void VisualServerViewport::_draw_viewport(Viewport *p_viewport) {
cl->texture_cache = NULL;
Transform2D scale;
scale.scale(cl->rect_cache.size);
- scale.elements[2] = cl->rect_cache.pos;
+ scale.elements[2] = cl->rect_cache.position;
cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse();
cl->light_shader_pos = cl->xform_cache[2];
if (cl->shadow_buffer.is_valid()) {
@@ -266,14 +266,28 @@ void VisualServerViewport::draw_viewports() {
ERR_CONTINUE(!vp->render_target.is_valid());
- bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE;
+ bool visible = vp->viewport_to_screen_rect != Rect2() || vp->update_mode == VS::VIEWPORT_UPDATE_ALWAYS || vp->update_mode == VS::VIEWPORT_UPDATE_ONCE || (vp->update_mode == VS::VIEWPORT_UPDATE_WHEN_VISIBLE && VSG::storage->render_target_was_used(vp->render_target));
if (!visible)
continue;
+ VSG::storage->render_target_clear_used(vp->render_target);
+
VSG::rasterizer->set_current_render_target(vp->render_target);
+
+ VSG::scene_render->set_debug_draw_mode(vp->debug_draw);
+ VSG::storage->render_info_begin_capture();
+
_draw_viewport(vp);
+ VSG::storage->render_info_end_capture();
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_OBJECTS_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_VERTICES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_MATERIAL_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SHADER_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_SURFACE_CHANGES_IN_FRAME);
+ vp->render_info[VS::VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME] = VSG::storage->get_captured_render_info(VS::INFO_DRAW_CALLS_IN_FRAME);
+
if (vp->viewport_to_screen_rect != Rect2()) {
//copy to screen if set as such
VSG::rasterizer->set_current_render_target(RID());
@@ -283,6 +297,7 @@ void VisualServerViewport::draw_viewports() {
if (vp->update_mode == VS::VIEWPORT_UPDATE_ONCE) {
vp->update_mode = VS::VIEWPORT_UPDATE_DISABLED;
}
+ VSG::scene_render->set_debug_draw_mode(VS::VIEWPORT_DEBUG_DRAW_DISABLED);
}
}
@@ -409,7 +424,8 @@ void VisualServerViewport::viewport_set_disable_3d(RID p_viewport, bool p_disabl
ERR_FAIL_COND(!viewport);
viewport->disable_3d = p_disable;
- VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable);
+ //VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, p_disable);
+ //this should be just for disabling rendering of 3D, to actually disable it, set usage
}
void VisualServerViewport::viewport_attach_camera(RID p_viewport, RID p_camera) {
@@ -518,6 +534,63 @@ void VisualServerViewport::viewport_set_hdr(RID p_viewport, bool p_enabled) {
VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_HDR, p_enabled);
}
+void VisualServerViewport::viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ switch (p_usage) {
+ case VS::VIEWPORT_USAGE_2D: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+
+ viewport->disable_3d_by_usage = true;
+ } break;
+ case VS::VIEWPORT_USAGE_2D_NO_SAMPLING: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, true);
+ viewport->disable_3d_by_usage = true;
+ } break;
+ case VS::VIEWPORT_USAGE_3D: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+ viewport->disable_3d_by_usage = false;
+ } break;
+ case VS::VIEWPORT_USAGE_3D_NO_EFFECTS: {
+
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D, false);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_3D_EFFECTS, true);
+ VSG::storage->render_target_set_flag(viewport->render_target, RasterizerStorage::RENDER_TARGET_NO_SAMPLING, false);
+ viewport->disable_3d_by_usage = false;
+ } break;
+ }
+}
+
+int VisualServerViewport::viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info) {
+
+ ERR_FAIL_INDEX_V(p_info, VS::VIEWPORT_RENDER_INFO_MAX, -1);
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ if (!viewport)
+ return 0; //there should be a lock here..
+
+ return viewport->render_info[p_info];
+}
+
+void VisualServerViewport::viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw) {
+
+ Viewport *viewport = viewport_owner.getornull(p_viewport);
+ ERR_FAIL_COND(!viewport);
+
+ viewport->debug_draw = p_draw;
+}
+
bool VisualServerViewport::free(RID p_rid) {
if (viewport_owner.owns(p_rid)) {
diff --git a/servers/visual/visual_server_viewport.h b/servers/visual/visual_server_viewport.h
index 118d11a111..f963ce4aa3 100644
--- a/servers/visual/visual_server_viewport.h
+++ b/servers/visual/visual_server_viewport.h
@@ -59,13 +59,15 @@ public:
bool hide_canvas;
bool disable_environment;
bool disable_3d;
+ bool disable_3d_by_usage;
RID shadow_atlas;
int shadow_atlas_size;
- VS::ViewportClearMode clear_mode;
+ int render_info[VS::VIEWPORT_RENDER_INFO_MAX];
+ VS::ViewportDebugDraw debug_draw;
- bool rendered_in_prev_frame;
+ VS::ViewportClearMode clear_mode;
struct CanvasKey {
@@ -96,11 +98,15 @@ public:
Viewport() {
update_mode = VS::VIEWPORT_UPDATE_WHEN_VISIBLE;
clear_mode = VS::VIEWPORT_CLEAR_ALWAYS;
- rendered_in_prev_frame = false;
disable_environment = false;
viewport_to_screen = 0;
shadow_atlas_size = 0;
disable_3d = false;
+ disable_3d_by_usage = false;
+ debug_draw = VS::VIEWPORT_DEBUG_DRAW_DISABLED;
+ for (int i = 0; i < VS::VIEWPORT_RENDER_INFO_MAX; i++) {
+ render_info[i] = 0;
+ }
}
};
@@ -164,6 +170,10 @@ public:
void viewport_set_msaa(RID p_viewport, VS::ViewportMSAA p_msaa);
void viewport_set_hdr(RID p_viewport, bool p_enabled);
+ void viewport_set_usage(RID p_viewport, VS::ViewportUsage p_usage);
+
+ virtual int viewport_get_render_info(RID p_viewport, VS::ViewportRenderInfo p_info);
+ virtual void viewport_set_debug_draw(RID p_viewport, VS::ViewportDebugDraw p_draw);
void draw_viewports();
diff --git a/servers/visual/visual_server_wrap_mt.cpp b/servers/visual/visual_server_wrap_mt.cpp
new file mode 100644
index 0000000000..fd15633244
--- /dev/null
+++ b/servers/visual/visual_server_wrap_mt.cpp
@@ -0,0 +1,193 @@
+/*************************************************************************/
+/* visual_server_wrap_mt.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#include "visual_server_wrap_mt.h"
+#include "global_config.h"
+#include "os/os.h"
+
+void VisualServerWrapMT::thread_exit() {
+
+ exit = true;
+}
+
+void VisualServerWrapMT::thread_draw() {
+
+ draw_mutex->lock();
+
+ draw_pending--;
+ bool draw = (draw_pending == 0); // only draw when no more flushes are pending
+
+ draw_mutex->unlock();
+
+ if (draw) {
+
+ visual_server->draw();
+ }
+}
+
+void VisualServerWrapMT::thread_flush() {
+
+ draw_mutex->lock();
+
+ draw_pending--;
+
+ draw_mutex->unlock();
+}
+
+void VisualServerWrapMT::_thread_callback(void *_instance) {
+
+ VisualServerWrapMT *vsmt = reinterpret_cast<VisualServerWrapMT *>(_instance);
+
+ vsmt->thread_loop();
+}
+
+void VisualServerWrapMT::thread_loop() {
+
+ server_thread = Thread::get_caller_ID();
+
+ OS::get_singleton()->make_rendering_thread();
+
+ visual_server->init();
+
+ exit = false;
+ draw_thread_up = true;
+ while (!exit) {
+ // flush commands one by one, until exit is requested
+ command_queue.wait_and_flush_one();
+ }
+
+ command_queue.flush_all(); // flush all
+
+ visual_server->finish();
+}
+
+/* EVENT QUEUING */
+
+void VisualServerWrapMT::sync() {
+
+ if (create_thread) {
+
+ /* TODO: sync with the thread */
+
+ /*
+ ERR_FAIL_COND(!draw_mutex);
+ draw_mutex->lock();
+ draw_pending++; //cambiar por un saferefcount
+ draw_mutex->unlock();
+ */
+ //command_queue.push( this, &VisualServerWrapMT::thread_flush);
+ } else {
+
+ command_queue.flush_all(); //flush all pending from other threads
+ }
+}
+
+void VisualServerWrapMT::draw() {
+
+ if (create_thread) {
+
+ /* TODO: Make it draw
+ ERR_FAIL_COND(!draw_mutex);
+ draw_mutex->lock();
+ draw_pending++; //cambiar por un saferefcount
+ draw_mutex->unlock();
+
+ command_queue.push( this, &VisualServerWrapMT::thread_draw);
+ */
+ } else {
+
+ visual_server->draw();
+ }
+}
+
+void VisualServerWrapMT::init() {
+
+ if (create_thread) {
+
+ draw_mutex = Mutex::create();
+ print_line("CREATING RENDER THREAD");
+ OS::get_singleton()->release_rendering_thread();
+ if (create_thread) {
+ thread = Thread::create(_thread_callback, this);
+ print_line("STARTING RENDER THREAD");
+ }
+ while (!draw_thread_up) {
+ OS::get_singleton()->delay_usec(1000);
+ }
+ print_line("DONE RENDER THREAD");
+ } else {
+
+ visual_server->init();
+ }
+}
+
+void VisualServerWrapMT::finish() {
+
+ if (thread) {
+
+ command_queue.push(this, &VisualServerWrapMT::thread_exit);
+ Thread::wait_to_finish(thread);
+ memdelete(thread);
+
+ texture_free_cached_ids();
+ //mesh_free_cached_ids();
+
+ thread = NULL;
+ } else {
+ visual_server->finish();
+ }
+
+ if (draw_mutex)
+ memdelete(draw_mutex);
+}
+
+VisualServerWrapMT::VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread)
+ : command_queue(p_create_thread) {
+
+ visual_server = p_contained;
+ create_thread = p_create_thread;
+ thread = NULL;
+ draw_mutex = NULL;
+ draw_pending = 0;
+ draw_thread_up = false;
+ alloc_mutex = Mutex::create();
+ pool_max_size = GLOBAL_DEF("memory/servers/thread_rid_prealloc_amount", 20);
+
+ if (!p_create_thread) {
+ server_thread = Thread::get_caller_ID();
+ } else {
+ server_thread = 0;
+ }
+}
+
+VisualServerWrapMT::~VisualServerWrapMT() {
+
+ memdelete(visual_server);
+ memdelete(alloc_mutex);
+ //finish();
+}
diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h
new file mode 100644
index 0000000000..94cbfc815e
--- /dev/null
+++ b/servers/visual/visual_server_wrap_mt.h
@@ -0,0 +1,585 @@
+/*************************************************************************/
+/* visual_server_wrap_mt.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+#ifndef VISUAL_SERVER_WRAP_MT_H
+#define VISUAL_SERVER_WRAP_MT_H
+
+#include "command_queue_mt.h"
+#include "os/thread.h"
+#include "servers/visual_server.h"
+
+/**
+ @author Juan Linietsky <reduzio@gmail.com>
+*/
+class VisualServerWrapMT : public VisualServer {
+
+ // the real visual server
+ mutable VisualServer *visual_server;
+
+ mutable CommandQueueMT command_queue;
+
+ static void _thread_callback(void *_instance);
+ void thread_loop();
+
+ Thread::ID server_thread;
+ volatile bool exit;
+ Thread *thread;
+ volatile bool draw_thread_up;
+ bool create_thread;
+
+ Mutex *draw_mutex;
+ int draw_pending;
+ void thread_draw();
+ void thread_flush();
+
+ void thread_exit();
+
+ Mutex *alloc_mutex;
+
+ int pool_max_size;
+
+//#define DEBUG_SYNC
+
+#ifdef DEBUG_SYNC
+#define SYNC_DEBUG print_line("sync on: " + String(__FUNCTION__));
+#else
+#define SYNC_DEBUG
+#endif
+
+public:
+#define ServerName VisualServer
+#define ServerNameWrapMT VisualServerWrapMT
+#define server_name visual_server
+#include "servers/server_wrap_mt_common.h"
+
+ /* EVENT QUEUING */
+ FUNCRID(texture)
+ FUNC5(texture_allocate, RID, int, int, Image::Format, uint32_t)
+ FUNC3(texture_set_data, RID, const Ref<Image> &, CubeMapSide)
+ FUNC2RC(Ref<Image>, texture_get_data, RID, CubeMapSide)
+ FUNC2(texture_set_flags, RID, uint32_t)
+ FUNC1RC(uint32_t, texture_get_flags, RID)
+ FUNC1RC(Image::Format, texture_get_format, RID)
+ FUNC1RC(uint32_t, texture_get_texid, RID)
+ FUNC1RC(uint32_t, texture_get_width, RID)
+ FUNC1RC(uint32_t, texture_get_height, RID)
+ FUNC3(texture_set_size_override, RID, int, int)
+
+ FUNC3(texture_set_detect_3d_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_srgb_callback, RID, TextureDetectCallback, void *)
+ FUNC3(texture_set_detect_normal_callback, RID, TextureDetectCallback, void *)
+
+ FUNC2(texture_set_path, RID, const String &)
+ FUNC1RC(String, texture_get_path, RID)
+ FUNC1(texture_set_shrink_all_x2_on_set_data, bool)
+ FUNC1(texture_debug_usage, List<TextureInfo> *)
+
+ FUNC1(textures_keep_original, bool)
+
+ /* SKY API */
+
+ FUNC0R(RID, sky_create)
+ FUNC3(sky_set_texture, RID, RID, int)
+
+ /* SHADER API */
+
+ FUNC0R(RID, shader_create)
+
+ FUNC2(shader_set_code, RID, const String &)
+ FUNC1RC(String, shader_get_code, RID)
+
+ FUNC2SC(shader_get_param_list, RID, List<PropertyInfo> *)
+
+ FUNC3(shader_set_default_texture_param, RID, const StringName &, RID)
+ FUNC2RC(RID, shader_get_default_texture_param, RID, const StringName &)
+
+ /* COMMON MATERIAL API */
+
+ FUNC0R(RID, material_create)
+
+ FUNC2(material_set_shader, RID, RID)
+ FUNC1RC(RID, material_get_shader, RID)
+
+ FUNC3(material_set_param, RID, const StringName &, const Variant &)
+ FUNC2RC(Variant, material_get_param, RID, const StringName &)
+
+ FUNC2(material_set_line_width, RID, float)
+
+ /* MESH API */
+
+ FUNC0R(RID, mesh_create)
+
+ FUNC10(mesh_add_surface, RID, uint32_t, PrimitiveType, const PoolVector<uint8_t> &, int, const PoolVector<uint8_t> &, int, const Rect3 &, const Vector<PoolVector<uint8_t> > &, const Vector<Rect3> &)
+
+ FUNC2(mesh_set_blend_shape_count, RID, int)
+ FUNC1RC(int, mesh_get_blend_shape_count, RID)
+
+ FUNC2(mesh_set_blend_shape_mode, RID, BlendShapeMode)
+ FUNC1RC(BlendShapeMode, mesh_get_blend_shape_mode, RID)
+
+ FUNC3(mesh_surface_set_material, RID, int, RID)
+ FUNC2RC(RID, mesh_surface_get_material, RID, int)
+
+ FUNC2RC(int, mesh_surface_get_array_len, RID, int)
+ FUNC2RC(int, mesh_surface_get_array_index_len, RID, int)
+
+ FUNC2RC(PoolVector<uint8_t>, mesh_surface_get_array, RID, int)
+ FUNC2RC(PoolVector<uint8_t>, mesh_surface_get_index_array, RID, int)
+
+ FUNC2RC(uint32_t, mesh_surface_get_format, RID, int)
+ FUNC2RC(PrimitiveType, mesh_surface_get_primitive_type, RID, int)
+
+ FUNC2RC(Rect3, mesh_surface_get_aabb, RID, int)
+ FUNC2RC(Vector<PoolVector<uint8_t> >, mesh_surface_get_blend_shapes, RID, int)
+ FUNC2RC(Vector<Rect3>, mesh_surface_get_skeleton_aabb, RID, int)
+
+ FUNC2(mesh_remove_surface, RID, int)
+ FUNC1RC(int, mesh_get_surface_count, RID)
+
+ FUNC2(mesh_set_custom_aabb, RID, const Rect3 &)
+ FUNC1RC(Rect3, mesh_get_custom_aabb, RID)
+
+ FUNC1(mesh_clear, RID)
+
+ /* MULTIMESH API */
+
+ FUNC0R(RID, multimesh_create)
+
+ FUNC4(multimesh_allocate, RID, int, MultimeshTransformFormat, MultimeshColorFormat)
+ FUNC1RC(int, multimesh_get_instance_count, RID)
+
+ FUNC2(multimesh_set_mesh, RID, RID)
+ FUNC3(multimesh_instance_set_transform, RID, int, const Transform &)
+ FUNC3(multimesh_instance_set_transform_2d, RID, int, const Transform2D &)
+ FUNC3(multimesh_instance_set_color, RID, int, const Color &)
+
+ FUNC1RC(RID, multimesh_get_mesh, RID)
+ FUNC1RC(Rect3, multimesh_get_aabb, RID)
+
+ FUNC2RC(Transform, multimesh_instance_get_transform, RID, int)
+ FUNC2RC(Transform2D, multimesh_instance_get_transform_2d, RID, int)
+ FUNC2RC(Color, multimesh_instance_get_color, RID, int)
+
+ FUNC2(multimesh_set_visible_instances, RID, int)
+ FUNC1RC(int, multimesh_get_visible_instances, RID)
+
+ /* IMMEDIATE API */
+
+ FUNC0R(RID, immediate_create)
+ FUNC3(immediate_begin, RID, PrimitiveType, RID)
+ FUNC2(immediate_vertex, RID, const Vector3 &)
+ FUNC2(immediate_normal, RID, const Vector3 &)
+ FUNC2(immediate_tangent, RID, const Plane &)
+ FUNC2(immediate_color, RID, const Color &)
+ FUNC2(immediate_uv, RID, const Vector2 &)
+ FUNC2(immediate_uv2, RID, const Vector2 &)
+ FUNC1(immediate_end, RID)
+ FUNC1(immediate_clear, RID)
+ FUNC2(immediate_set_material, RID, RID)
+ FUNC1RC(RID, immediate_get_material, RID)
+
+ /* SKELETON API */
+
+ FUNC0R(RID, skeleton_create)
+ FUNC3(skeleton_allocate, RID, int, bool)
+ FUNC1RC(int, skeleton_get_bone_count, RID)
+ FUNC3(skeleton_bone_set_transform, RID, int, const Transform &)
+ FUNC2RC(Transform, skeleton_bone_get_transform, RID, int)
+ FUNC3(skeleton_bone_set_transform_2d, RID, int, const Transform2D &)
+ FUNC2RC(Transform2D, skeleton_bone_get_transform_2d, RID, int)
+
+ /* Light API */
+
+ FUNC1R(RID, light_create, LightType)
+
+ FUNC2(light_set_color, RID, const Color &)
+ FUNC3(light_set_param, RID, LightParam, float)
+ FUNC2(light_set_shadow, RID, bool)
+ FUNC2(light_set_shadow_color, RID, const Color &)
+ FUNC2(light_set_projector, RID, RID)
+ FUNC2(light_set_negative, RID, bool)
+ FUNC2(light_set_cull_mask, RID, uint32_t)
+
+ FUNC2(light_omni_set_shadow_mode, RID, LightOmniShadowMode)
+ FUNC2(light_omni_set_shadow_detail, RID, LightOmniShadowDetail)
+
+ FUNC2(light_directional_set_shadow_mode, RID, LightDirectionalShadowMode)
+ FUNC2(light_directional_set_blend_splits, RID, bool)
+
+ /* PROBE API */
+
+ FUNC0R(RID, reflection_probe_create)
+
+ FUNC2(reflection_probe_set_update_mode, RID, ReflectionProbeUpdateMode)
+ FUNC2(reflection_probe_set_intensity, RID, float)
+ FUNC2(reflection_probe_set_interior_ambient, RID, const Color &)
+ FUNC2(reflection_probe_set_interior_ambient_energy, RID, float)
+ FUNC2(reflection_probe_set_interior_ambient_probe_contribution, RID, float)
+ FUNC2(reflection_probe_set_max_distance, RID, float)
+ FUNC2(reflection_probe_set_extents, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_origin_offset, RID, const Vector3 &)
+ FUNC2(reflection_probe_set_as_interior, RID, bool)
+ FUNC2(reflection_probe_set_enable_box_projection, RID, bool)
+ FUNC2(reflection_probe_set_enable_shadows, RID, bool)
+ FUNC2(reflection_probe_set_cull_mask, RID, uint32_t)
+
+ /* ROOM API */
+
+ FUNC0R(RID, room_create)
+ FUNC4(room_add_bounds, RID, const PoolVector<Vector2> &, float, const Transform &)
+ FUNC1(room_clear_bounds, RID)
+
+ /* PORTAL API */
+
+ // portals are only (x/y) points, forming a convex shape, which its clockwise
+ // order points outside. (z is 0);
+
+ FUNC0R(RID, portal_create)
+ FUNC2(portal_set_shape, RID, const Vector<Point2> &)
+ FUNC2(portal_set_enabled, RID, bool)
+ FUNC2(portal_set_disable_distance, RID, float)
+ FUNC2(portal_set_disabled_color, RID, const Color &)
+
+ /* BAKED LIGHT API */
+
+ FUNC0R(RID, gi_probe_create)
+
+ FUNC2(gi_probe_set_bounds, RID, const Rect3 &)
+ FUNC1RC(Rect3, gi_probe_get_bounds, RID)
+
+ FUNC2(gi_probe_set_cell_size, RID, float)
+ FUNC1RC(float, gi_probe_get_cell_size, RID)
+
+ FUNC2(gi_probe_set_to_cell_xform, RID, const Transform &)
+ FUNC1RC(Transform, gi_probe_get_to_cell_xform, RID)
+
+ FUNC2(gi_probe_set_dynamic_range, RID, int)
+ FUNC1RC(int, gi_probe_get_dynamic_range, RID)
+
+ FUNC2(gi_probe_set_energy, RID, float)
+ FUNC1RC(float, gi_probe_get_energy, RID)
+
+ FUNC2(gi_probe_set_bias, RID, float)
+ FUNC1RC(float, gi_probe_get_bias, RID)
+
+ FUNC2(gi_probe_set_propagation, RID, float)
+ FUNC1RC(float, gi_probe_get_propagation, RID)
+
+ FUNC2(gi_probe_set_interior, RID, bool)
+ FUNC1RC(bool, gi_probe_is_interior, RID)
+
+ FUNC2(gi_probe_set_compress, RID, bool)
+ FUNC1RC(bool, gi_probe_is_compressed, RID)
+
+ FUNC2(gi_probe_set_dynamic_data, RID, const PoolVector<int> &)
+ FUNC1RC(PoolVector<int>, gi_probe_get_dynamic_data, RID)
+
+ /* PARTICLES */
+
+ FUNC0R(RID, particles_create)
+
+ FUNC2(particles_set_emitting, RID, bool)
+ FUNC2(particles_set_amount, RID, int)
+ FUNC2(particles_set_lifetime, RID, float)
+ FUNC2(particles_set_pre_process_time, RID, float)
+ FUNC2(particles_set_explosiveness_ratio, RID, float)
+ FUNC2(particles_set_randomness_ratio, RID, float)
+ FUNC2(particles_set_custom_aabb, RID, const Rect3 &)
+ FUNC2(particles_set_speed_scale, RID, float)
+ FUNC2(particles_set_use_local_coordinates, RID, bool)
+ FUNC2(particles_set_process_material, RID, RID)
+ FUNC2(particles_set_fixed_fps, RID, int)
+ FUNC2(particles_set_fractional_delta, RID, bool)
+
+ FUNC2(particles_set_draw_order, RID, VS::ParticlesDrawOrder)
+
+ FUNC2(particles_set_draw_passes, RID, int)
+ FUNC3(particles_set_draw_pass_mesh, RID, int, RID)
+
+ FUNC1R(Rect3, particles_get_current_aabb, RID)
+
+ /* CAMERA API */
+
+ FUNC0R(RID, camera_create)
+ FUNC4(camera_set_perspective, RID, float, float, float)
+ FUNC4(camera_set_orthogonal, RID, float, float, float)
+ FUNC2(camera_set_transform, RID, const Transform &)
+ FUNC2(camera_set_cull_mask, RID, uint32_t)
+ FUNC2(camera_set_environment, RID, RID)
+ FUNC2(camera_set_use_vertical_aspect, RID, bool)
+
+ /* VIEWPORT TARGET API */
+
+ FUNC0R(RID, viewport_create)
+
+ FUNC3(viewport_set_size, RID, int, int)
+
+ FUNC2(viewport_set_active, RID, bool)
+ FUNC2(viewport_set_parent_viewport, RID, RID)
+
+ FUNC2(viewport_set_clear_mode, RID, ViewportClearMode)
+
+ FUNC3(viewport_attach_to_screen, RID, const Rect2 &, int)
+ FUNC1(viewport_detach, RID)
+
+ FUNC2(viewport_set_update_mode, RID, ViewportUpdateMode)
+ FUNC2(viewport_set_vflip, RID, bool)
+
+ FUNC1RC(RID, viewport_get_texture, RID)
+
+ FUNC2(viewport_set_hide_scenario, RID, bool)
+ FUNC2(viewport_set_hide_canvas, RID, bool)
+ FUNC2(viewport_set_disable_environment, RID, bool)
+ FUNC2(viewport_set_disable_3d, RID, bool)
+
+ FUNC2(viewport_attach_camera, RID, RID)
+ FUNC2(viewport_set_scenario, RID, RID)
+ FUNC2(viewport_attach_canvas, RID, RID)
+
+ FUNC2(viewport_remove_canvas, RID, RID)
+ FUNC3(viewport_set_canvas_transform, RID, RID, const Transform2D &)
+ FUNC2(viewport_set_transparent_background, RID, bool)
+
+ FUNC2(viewport_set_global_canvas_transform, RID, const Transform2D &)
+ FUNC3(viewport_set_canvas_layer, RID, RID, int)
+ FUNC2(viewport_set_shadow_atlas_size, RID, int)
+ FUNC3(viewport_set_shadow_atlas_quadrant_subdivision, RID, int, int)
+ FUNC2(viewport_set_msaa, RID, ViewportMSAA)
+ FUNC2(viewport_set_hdr, RID, bool)
+ FUNC2(viewport_set_usage, RID, ViewportUsage)
+
+ //this passes directly to avoid stalling, but it's pretty dangerous, so dont call after freeing a viewport
+ virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) {
+ return visual_server->viewport_get_render_info(p_viewport, p_info);
+ }
+
+ FUNC2(viewport_set_debug_draw, RID, ViewportDebugDraw)
+
+ /* ENVIRONMENT API */
+
+ FUNC0R(RID, environment_create)
+
+ FUNC2(environment_set_background, RID, EnvironmentBG)
+ FUNC2(environment_set_sky, RID, RID)
+ FUNC2(environment_set_sky_scale, RID, float)
+ FUNC2(environment_set_bg_color, RID, const Color &)
+ FUNC2(environment_set_bg_energy, RID, float)
+ FUNC2(environment_set_canvas_max_layer, RID, int)
+ FUNC4(environment_set_ambient_light, RID, const Color &, float, float)
+ FUNC7(environment_set_ssr, RID, bool, int, float, float, float, bool)
+ FUNC10(environment_set_ssao, RID, bool, float, float, float, float, float, float, const Color &, bool)
+
+ FUNC6(environment_set_dof_blur_near, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
+ FUNC6(environment_set_dof_blur_far, RID, bool, float, float, float, EnvironmentDOFBlurQuality)
+ FUNC10(environment_set_glow, RID, bool, int, float, float, float, EnvironmentGlowBlendMode, float, float, bool)
+
+ FUNC9(environment_set_tonemap, RID, EnvironmentToneMapper, float, float, bool, float, float, float, float)
+
+ FUNC6(environment_set_adjustment, RID, bool, float, float, float, RID)
+
+ FUNC5(environment_set_fog, RID, bool, const Color &, const Color &, float)
+ FUNC6(environment_set_fog_depth, RID, bool, float, float, bool, float)
+ FUNC5(environment_set_fog_height, RID, bool, float, float, float)
+
+ FUNC0R(RID, scenario_create)
+
+ FUNC2(scenario_set_debug, RID, ScenarioDebugMode)
+ FUNC2(scenario_set_environment, RID, RID)
+ FUNC3(scenario_set_reflection_atlas_size, RID, int, int)
+ FUNC2(scenario_set_fallback_environment, RID, RID)
+
+ /* INSTANCING API */
+ // from can be mesh, light, area and portal so far.
+ FUNC0R(RID, instance_create)
+
+ FUNC2(instance_set_base, RID, RID) // from can be mesh, light, poly, area and portal so far.
+ FUNC2(instance_set_scenario, RID, RID) // from can be mesh, light, poly, area and portal so far.
+ FUNC2(instance_set_layer_mask, RID, uint32_t)
+ FUNC2(instance_set_transform, RID, const Transform &)
+ FUNC2(instance_attach_object_instance_ID, RID, ObjectID)
+ FUNC3(instance_set_blend_shape_weight, RID, int, float)
+ FUNC3(instance_set_surface_material, RID, int, RID)
+ FUNC2(instance_set_visible, RID, bool)
+
+ FUNC2(instance_attach_skeleton, RID, RID)
+ FUNC2(instance_set_exterior, RID, bool)
+ FUNC2(instance_set_room, RID, RID)
+
+ FUNC2(instance_set_extra_visibility_margin, RID, real_t)
+
+ // don't use these in a game!
+ FUNC2RC(Vector<ObjectID>, instances_cull_aabb, const Rect3 &, RID)
+ FUNC3RC(Vector<ObjectID>, instances_cull_ray, const Vector3 &, const Vector3 &, RID)
+ FUNC2RC(Vector<ObjectID>, instances_cull_convex, const Vector<Plane> &, RID)
+
+ FUNC3(instance_geometry_set_flag, RID, InstanceFlags, bool)
+ FUNC2(instance_geometry_set_cast_shadows_setting, RID, ShadowCastingSetting)
+ FUNC2(instance_geometry_set_material_override, RID, RID)
+
+ FUNC5(instance_geometry_set_draw_range, RID, float, float, float, float)
+ FUNC2(instance_geometry_set_as_instance_lod, RID, RID)
+
+ /* CANVAS (2D) */
+
+ FUNC0R(RID, canvas_create)
+ FUNC3(canvas_set_item_mirroring, RID, RID, const Point2 &)
+ FUNC2(canvas_set_modulate, RID, const Color &)
+
+ FUNC0R(RID, canvas_item_create)
+ FUNC2(canvas_item_set_parent, RID, RID)
+
+ FUNC2(canvas_item_set_visible, RID, bool)
+ FUNC2(canvas_item_set_light_mask, RID, int)
+
+ FUNC2(canvas_item_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_set_clip, RID, bool)
+ FUNC2(canvas_item_set_distance_field_mode, RID, bool)
+ FUNC3(canvas_item_set_custom_rect, RID, bool, const Rect2 &)
+ FUNC2(canvas_item_set_modulate, RID, const Color &)
+ FUNC2(canvas_item_set_self_modulate, RID, const Color &)
+
+ FUNC2(canvas_item_set_draw_behind_parent, RID, bool)
+
+ FUNC6(canvas_item_add_line, RID, const Point2 &, const Point2 &, const Color &, float, bool)
+ FUNC3(canvas_item_add_rect, RID, const Rect2 &, const Color &)
+ FUNC4(canvas_item_add_circle, RID, const Point2 &, float, const Color &)
+ FUNC7(canvas_item_add_texture_rect, RID, const Rect2 &, RID, bool, const Color &, bool, RID)
+ FUNC8(canvas_item_add_texture_rect_region, RID, const Rect2 &, RID, const Rect2 &, const Color &, bool, RID, bool)
+ FUNC11(canvas_item_add_nine_patch, RID, const Rect2 &, const Rect2 &, RID, const Vector2 &, const Vector2 &, NinePatchAxisMode, NinePatchAxisMode, bool, const Color &, RID)
+ FUNC7(canvas_item_add_primitive, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, float, RID)
+ FUNC6(canvas_item_add_polygon, RID, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, RID)
+ FUNC8(canvas_item_add_triangle_array, RID, const Vector<int> &, const Vector<Point2> &, const Vector<Color> &, const Vector<Point2> &, RID, int, RID)
+ FUNC3(canvas_item_add_mesh, RID, const RID &, RID)
+ FUNC3(canvas_item_add_multimesh, RID, RID, RID)
+ FUNC2(canvas_item_add_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_item_add_clip_ignore, RID, bool)
+ FUNC2(canvas_item_set_sort_children_by_y, RID, bool)
+ FUNC2(canvas_item_set_z, RID, int)
+ FUNC2(canvas_item_set_z_as_relative_to_parent, RID, bool)
+ FUNC3(canvas_item_set_copy_to_backbuffer, RID, bool, const Rect2 &)
+
+ FUNC1(canvas_item_clear, RID)
+ FUNC2(canvas_item_set_draw_index, RID, int)
+
+ FUNC2(canvas_item_set_material, RID, RID)
+
+ FUNC2(canvas_item_set_use_parent_material, RID, bool)
+
+ FUNC0R(RID, canvas_light_create)
+ FUNC2(canvas_light_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_set_enabled, RID, bool)
+ FUNC2(canvas_light_set_scale, RID, float)
+ FUNC2(canvas_light_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_set_texture, RID, RID)
+ FUNC2(canvas_light_set_texture_offset, RID, const Vector2 &)
+ FUNC2(canvas_light_set_color, RID, const Color &)
+ FUNC2(canvas_light_set_height, RID, float)
+ FUNC2(canvas_light_set_energy, RID, float)
+ FUNC3(canvas_light_set_z_range, RID, int, int)
+ FUNC3(canvas_light_set_layer_range, RID, int, int)
+ FUNC2(canvas_light_set_item_cull_mask, RID, int)
+ FUNC2(canvas_light_set_item_shadow_cull_mask, RID, int)
+
+ FUNC2(canvas_light_set_mode, RID, CanvasLightMode)
+
+ FUNC2(canvas_light_set_shadow_enabled, RID, bool)
+ FUNC2(canvas_light_set_shadow_buffer_size, RID, int)
+ FUNC2(canvas_light_set_shadow_gradient_length, RID, float)
+ FUNC2(canvas_light_set_shadow_filter, RID, CanvasLightShadowFilter)
+ FUNC2(canvas_light_set_shadow_color, RID, const Color &)
+ FUNC2(canvas_light_set_shadow_smooth, RID, float)
+
+ FUNC0R(RID, canvas_light_occluder_create)
+ FUNC2(canvas_light_occluder_attach_to_canvas, RID, RID)
+ FUNC2(canvas_light_occluder_set_enabled, RID, bool)
+ FUNC2(canvas_light_occluder_set_polygon, RID, RID)
+ FUNC2(canvas_light_occluder_set_transform, RID, const Transform2D &)
+ FUNC2(canvas_light_occluder_set_light_mask, RID, int)
+
+ FUNC0R(RID, canvas_occluder_polygon_create)
+ FUNC3(canvas_occluder_polygon_set_shape, RID, const PoolVector<Vector2> &, bool)
+ FUNC2(canvas_occluder_polygon_set_shape_as_lines, RID, const PoolVector<Vector2> &)
+
+ FUNC2(canvas_occluder_polygon_set_cull_mode, RID, CanvasOccluderPolygonCullMode)
+
+ /* CURSOR */
+ FUNC2(cursor_set_rotation, float, int) // radians
+ FUNC4(cursor_set_texture, RID, const Point2 &, int, const Rect2 &)
+ FUNC2(cursor_set_visible, bool, int)
+ FUNC2(cursor_set_pos, const Point2 &, int)
+
+ /* BLACK BARS */
+
+ FUNC4(black_bars_set_margins, int, int, int, int)
+ FUNC4(black_bars_set_images, RID, RID, RID, RID)
+
+ /* FREE */
+
+ FUNC1(free, RID)
+
+ /* EVENT QUEUING */
+
+ FUNC3(request_frame_drawn_callback, Object *, const StringName &, const Variant &)
+
+ virtual void init();
+ virtual void finish();
+ virtual void draw();
+ virtual void sync();
+ FUNC0RC(bool, has_changed)
+
+ /* RENDER INFO */
+
+ //this passes directly to avoid stalling
+ virtual int get_render_info(RenderInfo p_info) {
+ return visual_server->get_render_info(p_info);
+ }
+
+ FUNC3(set_boot_image, const Ref<Image> &, const Color &, bool)
+ FUNC1(set_default_clear_color, const Color &)
+
+ FUNC0R(RID, get_test_cube)
+
+ FUNC1(set_debug_generate_wireframes, bool)
+
+ virtual bool has_feature(Features p_feature) const { return visual_server->has_feature(p_feature); }
+ virtual bool has_os_feature(const String &p_feature) const { return visual_server->has_os_feature(p_feature); }
+
+ VisualServerWrapMT(VisualServer *p_contained, bool p_create_thread);
+ ~VisualServerWrapMT();
+
+#undef ServerName
+#undef ServerNameWrapMT
+#undef server_name
+};
+
+#ifdef DEBUG_SYNC
+#undef DEBUG_SYNC
+#endif
+#undef SYNC_DEBUG
+
+#endif
diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp
index 20906d0239..c3ae58cf4f 100644
--- a/servers/visual_server.cpp
+++ b/servers/visual_server.cpp
@@ -68,10 +68,11 @@ VisualServer *VisualServer::create() {
return NULL;
}
-RID VisualServer::texture_create_from_image(const Image &p_image, uint32_t p_flags) {
+RID VisualServer::texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags) {
+ ERR_FAIL_COND_V(!p_image.is_valid(), RID());
RID texture = texture_create();
- texture_allocate(texture, p_image.get_width(), p_image.get_height(), p_image.get_format(), p_flags); //if it has mipmaps, use, else generate
+ texture_allocate(texture, p_image->get_width(), p_image->get_height(), p_image->get_format(), p_flags); //if it has mipmaps, use, else generate
ERR_FAIL_COND_V(!texture.is_valid(), texture);
texture_set_data(texture, p_image);
@@ -120,12 +121,12 @@ RID VisualServer::get_test_texture() {
}
}
- Image data(TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, false, Image::FORMAT_RGB8, test_data);
+ Ref<Image> data = memnew(Image(TEST_TEXTURE_SIZE, TEST_TEXTURE_SIZE, false, Image::FORMAT_RGB8, test_data));
test_texture = texture_create_from_image(data);
return test_texture;
-};
+}
void VisualServer::_free_internal_rids() {
@@ -326,7 +327,7 @@ RID VisualServer::get_white_texture() {
for (int i = 0; i < 16 * 3; i++)
w[i] = 255;
}
- Image white(4, 4, 0, Image::FORMAT_RGB8, wt);
+ Ref<Image> white = memnew(Image(4, 4, 0, Image::FORMAT_RGB8, wt));
white_texture = texture_create();
texture_allocate(white_texture, 4, 4, Image::FORMAT_RGB8);
texture_set_data(white_texture, white);
@@ -339,8 +340,6 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
PoolVector<uint8_t>::Write iw;
if (r_index_array.size()) {
- print_line("elements: " + itos(r_index_array.size()));
-
iw = r_index_array.write();
}
@@ -400,7 +399,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
}
}
- r_aabb = Rect3(Vector3(aabb.pos.x, aabb.pos.y, 0), Vector3(aabb.size.x, aabb.size.y, 0));
+ r_aabb = Rect3(Vector3(aabb.position.x, aabb.position.y, 0), Vector3(aabb.size.x, aabb.size.y, 0));
} else {
PoolVector<Vector3> array = p_arrays[ai];
@@ -466,7 +465,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
for (int i = 0; i < p_vertex_array_len; i++) {
- uint8_t vector[4] = {
+ int8_t vector[4] = {
CLAMP(src[i].x * 127, -128, 127),
CLAMP(src[i].y * 127, -128, 127),
CLAMP(src[i].z * 127, -128, 127),
@@ -771,7 +770,7 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
if (bptr->size.x < 0) {
//first
bptr[idx] = Rect3();
- bptr[idx].pos = v;
+ bptr[idx].position = v;
any_valid = true;
} else {
bptr[idx].expand_to(v);
@@ -1234,11 +1233,12 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
if (p_format & ARRAY_COMPRESS_NORMAL) {
PoolVector<Vector3>::Write w = arr.write();
+ const float multiplier = 1.f / 127.f;
for (int j = 0; j < p_vertex_len; j++) {
- const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
- w[j] = Vector3(float(v[0] / 255.0) * 2.0 - 1.0, float(v[1] / 255.0) * 2.0 - 1.0, float(v[2] / 255.0) * 2.0 - 1.0);
+ const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
+ w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier);
}
} else {
PoolVector<Vector3>::Write w = arr.write();
@@ -1294,7 +1294,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
for (int j = 0; j < p_vertex_len; j++) {
const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
- w[j] = Color(float(v[0] / 255.0) * 2.0 - 1.0, float(v[1] / 255.0) * 2.0 - 1.0, float(v[2] / 255.0) * 2.0 - 1.0, float(v[3] / 255.0) * 2.0 - 1.0);
+ w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0));
}
} else {
PoolVector<Color>::Write w = arr.write();
@@ -1567,6 +1567,10 @@ VisualServer::VisualServer() {
//ERR_FAIL_COND(singleton);
singleton = this;
+ GLOBAL_DEF("rendering/vram_formats/use_s3tc", true);
+ GLOBAL_DEF("rendering/vram_formats/use_etc", false);
+ GLOBAL_DEF("rendering/vram_formats/use_etc2", true);
+ GLOBAL_DEF("rendering/vram_formats/use_pvrtc", false);
}
VisualServer::~VisualServer() {
diff --git a/servers/visual_server.h b/servers/visual_server.h
index f21271122d..589fa80084 100644
--- a/servers/visual_server.h
+++ b/servers/visual_server.h
@@ -32,6 +32,7 @@
#include "bsp_tree.h"
#include "geometry.h"
+#include "image.h"
#include "math_2d.h"
#include "object.h"
#include "rid.h"
@@ -106,13 +107,14 @@ public:
};
virtual RID texture_create() = 0;
- RID texture_create_from_image(const Image &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
+ RID texture_create_from_image(const Ref<Image> &p_image, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT); // helper
virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = TEXTURE_FLAGS_DEFAULT) = 0;
- virtual void texture_set_data(RID p_texture, const Image &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
- virtual Image texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
+ virtual void texture_set_data(RID p_texture, const Ref<Image> &p_image, CubeMapSide p_cube_side = CUBEMAP_LEFT) = 0;
+ virtual Ref<Image> texture_get_data(RID p_texture, CubeMapSide p_cube_side = CUBEMAP_LEFT) const = 0;
virtual void texture_set_flags(RID p_texture, uint32_t p_flags) = 0;
virtual uint32_t texture_get_flags(RID p_texture) const = 0;
virtual Image::Format texture_get_format(RID p_texture) const = 0;
+ virtual uint32_t texture_get_texid(RID p_texture) const = 0;
virtual uint32_t texture_get_width(RID p_texture) const = 0;
virtual uint32_t texture_get_height(RID p_texture) const = 0;
virtual void texture_set_size_override(RID p_texture, int p_width, int p_height) = 0;
@@ -126,6 +128,7 @@ public:
virtual void texture_set_detect_3d_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
virtual void texture_set_detect_srgb_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
+ virtual void texture_set_detect_normal_callback(RID p_texture, TextureDetectCallback p_callback, void *p_userdata) = 0;
struct TextureInfo {
RID texture;
@@ -139,10 +142,10 @@ public:
virtual void textures_keep_original(bool p_enable) = 0;
- /* SKYBOX API */
+ /* SKY API */
- virtual RID skybox_create() = 0;
- virtual void skybox_set_texture(RID p_skybox, RID p_cube_map, int p_radiance_size) = 0;
+ virtual RID sky_create() = 0;
+ virtual void sky_set_texture(RID p_sky, RID p_cube_map, int p_radiance_size) = 0;
/* SHADER API */
@@ -356,7 +359,6 @@ public:
LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET,
LIGHT_PARAM_SHADOW_NORMAL_BIAS,
LIGHT_PARAM_SHADOW_BIAS,
- LIGHT_PARAM_SHADOW_BIAS_SPLIT_SCALE,
LIGHT_PARAM_MAX
};
@@ -577,7 +579,38 @@ public:
};
virtual void viewport_set_msaa(RID p_viewport, ViewportMSAA p_msaa) = 0;
+
+ enum ViewportUsage {
+ VIEWPORT_USAGE_2D,
+ VIEWPORT_USAGE_2D_NO_SAMPLING,
+ VIEWPORT_USAGE_3D,
+ VIEWPORT_USAGE_3D_NO_EFFECTS,
+ };
+
virtual void viewport_set_hdr(RID p_viewport, bool p_enabled) = 0;
+ virtual void viewport_set_usage(RID p_viewport, ViewportUsage p_usage) = 0;
+
+ enum ViewportRenderInfo {
+
+ VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_VERTICES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MATERIAL_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SHADER_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_SURFACE_CHANGES_IN_FRAME,
+ VIEWPORT_RENDER_INFO_DRAW_CALLS_IN_FRAME,
+ VIEWPORT_RENDER_INFO_MAX
+ };
+
+ virtual int viewport_get_render_info(RID p_viewport, ViewportRenderInfo p_info) = 0;
+
+ enum ViewportDebugDraw {
+ VIEWPORT_DEBUG_DRAW_DISABLED,
+ VIEWPORT_DEBUG_DRAW_UNSHADED,
+ VIEWPORT_DEBUG_DRAW_OVERDRAW,
+ VIEWPORT_DEBUG_DRAW_WIREFRAME,
+ };
+
+ virtual void viewport_set_debug_draw(RID p_viewport, ViewportDebugDraw p_draw) = 0;
/* ENVIRONMENT API */
@@ -587,19 +620,19 @@ public:
ENV_BG_CLEAR_COLOR,
ENV_BG_COLOR,
- ENV_BG_SKYBOX,
+ ENV_BG_SKY,
ENV_BG_CANVAS,
ENV_BG_KEEP,
ENV_BG_MAX
};
virtual void environment_set_background(RID p_env, EnvironmentBG p_bg) = 0;
- virtual void environment_set_skybox(RID p_env, RID p_skybox) = 0;
- virtual void environment_set_skybox_scale(RID p_env, float p_scale) = 0;
+ virtual void environment_set_sky(RID p_env, RID p_sky) = 0;
+ virtual void environment_set_sky_scale(RID p_env, float p_scale) = 0;
virtual void environment_set_bg_color(RID p_env, const Color &p_color) = 0;
virtual void environment_set_bg_energy(RID p_env, float p_energy) = 0;
virtual void environment_set_canvas_max_layer(RID p_env, int p_max_layer) = 0;
- virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_skybox_contribution = 0.0) = 0;
+ virtual void environment_set_ambient_light(RID p_env, const Color &p_color, float p_energy = 1.0, float p_sky_contribution = 0.0) = 0;
//set default SSAO options
//set default SSR options
@@ -621,7 +654,6 @@ public:
GLOW_BLEND_MODE_REPLACE,
};
virtual void environment_set_glow(RID p_env, bool p_enable, int p_level_flags, float p_intensity, float p_strength, float p_bloom_treshold, EnvironmentGlowBlendMode p_blend_mode, float p_hdr_bleed_treshold, float p_hdr_bleed_scale, bool p_bicubic_upscale) = 0;
- virtual void environment_set_fog(RID p_env, bool p_enable, float p_begin, float p_end, RID p_gradient_texture) = 0;
enum EnvironmentToneMapper {
ENV_TONE_MAPPER_LINEAR,
@@ -633,9 +665,13 @@ public:
virtual void environment_set_tonemap(RID p_env, EnvironmentToneMapper p_tone_mapper, float p_exposure, float p_white, bool p_auto_exposure, float p_min_luminance, float p_max_luminance, float p_auto_exp_speed, float p_auto_exp_grey) = 0;
virtual void environment_set_adjustment(RID p_env, bool p_enable, float p_brightness, float p_contrast, float p_saturation, RID p_ramp) = 0;
- virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_accel, float p_fade, float p_depth_tolerance, bool p_smooth, bool p_roughness) = 0;
+ virtual void environment_set_ssr(RID p_env, bool p_enable, int p_max_steps, float p_fade_in, float p_fade_out, float p_depth_tolerance, bool p_roughness) = 0;
virtual void environment_set_ssao(RID p_env, bool p_enable, float p_radius, float p_intensity, float p_radius2, float p_intensity2, float p_bias, float p_light_affect, const Color &p_color, bool p_blur) = 0;
+ virtual void environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) = 0;
+ virtual void environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) = 0;
+ virtual void environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) = 0;
+
/* SCENARIO API */
virtual RID scenario_create() = 0;
@@ -749,12 +785,12 @@ public:
virtual void canvas_item_add_line(RID p_item, const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width = 1.0, bool p_antialiased = false) = 0;
virtual void canvas_item_add_rect(RID p_item, const Rect2 &p_rect, const Color &p_color) = 0;
virtual void canvas_item_add_circle(RID p_item, const Point2 &p_pos, float p_radius, const Color &p_color) = 0;
- virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0;
- virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false) = 0;
- virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1)) = 0;
- virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0) = 0;
- virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID()) = 0;
- virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1) = 0;
+ virtual void canvas_item_add_texture_rect(RID p_item, const Rect2 &p_rect, RID p_texture, bool p_tile = false, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2 &p_rect, RID p_texture, const Rect2 &p_src_rect, const Color &p_modulate = Color(1, 1, 1), bool p_transpose = false, RID p_normal_map = RID(), bool p_clip_uv = true) = 0;
+ virtual void canvas_item_add_nine_patch(RID p_item, const Rect2 &p_rect, const Rect2 &p_source, RID p_texture, const Vector2 &p_topleft, const Vector2 &p_bottomright, NinePatchAxisMode p_x_axis_mode = NINE_PATCH_STRETCH, NinePatchAxisMode p_y_axis_mode = NINE_PATCH_STRETCH, bool p_draw_center = true, const Color &p_modulate = Color(1, 1, 1), RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture, float p_width = 1.0, RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), RID p_normal_map = RID()) = 0;
+ virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int> &p_indices, const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs = Vector<Point2>(), RID p_texture = RID(), int p_count = -1, RID p_normal_map = RID()) = 0;
virtual void canvas_item_add_mesh(RID p_item, const RID &p_mesh, RID p_skeleton = RID()) = 0;
virtual void canvas_item_add_multimesh(RID p_item, RID p_mesh, RID p_skeleton = RID()) = 0;
virtual void canvas_item_add_set_transform(RID p_item, const Transform2D &p_transform) = 0;
@@ -808,6 +844,7 @@ public:
virtual void canvas_light_set_shadow_gradient_length(RID p_light, float p_length) = 0;
virtual void canvas_light_set_shadow_filter(RID p_light, CanvasLightShadowFilter p_filter) = 0;
virtual void canvas_light_set_shadow_color(RID p_light, const Color &p_color) = 0;
+ virtual void canvas_light_set_shadow_smooth(RID p_light, float p_smooth) = 0;
virtual RID canvas_light_occluder_create() = 0;
virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder, RID p_canvas) = 0;
@@ -842,6 +879,8 @@ public:
virtual void free(RID p_rid) = 0; ///< free RIDs associated with the visual server
+ virtual void request_frame_drawn_callback(Object *p_where, const StringName &p_method, const Variant &p_userdata) = 0;
+
/* EVENT QUEUING */
virtual void draw() = 0;
@@ -884,7 +923,7 @@ public:
virtual void mesh_add_surface_from_mesh_data(RID p_mesh, const Geometry::MeshData &p_mesh_data);
virtual void mesh_add_surface_from_planes(RID p_mesh, const PoolVector<Plane> &p_planes);
- virtual void set_boot_image(const Image &p_image, const Color &p_color, bool p_scale) = 0;
+ virtual void set_boot_image(const Ref<Image> &p_image, const Color &p_color, bool p_scale) = 0;
virtual void set_default_clear_color(const Color &p_color) = 0;
enum Features {
@@ -896,6 +935,8 @@ public:
virtual bool has_os_feature(const String &p_feature) const = 0;
+ virtual void set_debug_generate_wireframes(bool p_generate) = 0;
+
VisualServer();
virtual ~VisualServer();
};
diff --git a/signal_renames.txt b/signal_renames.txt
deleted file mode 100644
index 859985cb11..0000000000
--- a/signal_renames.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-area_enter = area_entered
-area_exit = area_exited
-
-area_enter_shape = area_shape_entered
-area_exit_shape = area_shape_exited
-
-body_enter = body_entered
-body_exit = body_exited
-
-body_enter_shape = body_shape_entered
-body_exit_shape = body_shape_exited
-
-mouse_enter = mouse_entered
-mouse_exit = mouse_exited
-focus_enter = focus_entered
-focus_exit = focus_exited
-
-modal_close = modal_closed
-
-enter_tree = tree_entered
-exit_tree = tree_exited \ No newline at end of file
diff --git a/thirdparty/README.md b/thirdparty/README.md
index 1c4bad4836..c846094a6a 100644
--- a/thirdparty/README.md
+++ b/thirdparty/README.md
@@ -37,6 +37,18 @@ Check the diff of enet.h, protocol.c, and host.c with the 1.3.13
tarball before the next update.
+## etc2comp
+
+- Upstream: https://github.com/google/etc2comp
+- Version: 9cd0f9c (git)
+- License: Apache
+
+Files extracted from upstream source:
+
+- all .cpp and .h files in EtcLib/
+- README.md, LICENSE, AUTHORS
+
+
## fonts
- Upstream: ?
@@ -60,7 +72,7 @@ Files extracted from upstream source:
## glad
- Upstream: https://github.com/Dav1dde/glad
-- Version: 0.1.13a0
+- Version: 0.1.14a0
- License: MIT
The files we package are automatically generated.
@@ -112,6 +124,10 @@ Files extracted from upstream source:
- Version: 05cfdc2 (git)
- License: MIT, BSD-3-Clause
+Files extracted from upstream source:
+
+TODO.
+
## libvorbis
@@ -132,6 +148,10 @@ Files extracted from upstream source:
- Version: 1.6.0
- License: BSD-3-Clause
+Files extracted from upstream source:
+
+TODO.
+
## libwebp
@@ -242,13 +262,29 @@ Collection of single-file libraries used in Godot components.
Files extracted from the upstream source:
-TODO.
+- Our `openssl/`: contains the headers installed in /usr/include/openssl;
+ gather them in the source tarball with `make links` and
+ `cp -f include/openssl/*.h ../openssl/openssl/`
+- Our `crypto/`: copy of upstream `crypto/`, with some cleanup (see below).
+- Our `ssl/`: copy of upstream `ssl/`, with some cleanup (see below).
+- Cleanup:
+ ```
+ find \( -name "Makefile" -o -name "*.S" -o -name "*.bat" -o -name "*.bc" \
+ -o -name "*.com" -o -name "*.cnf" -o -name "*.ec" -o -name "*.fre" \
+ -o -name "*.gcc" -o -name "*.in" -o -name "*.lnx" -o -name "*.m4" \
+ -o -name "*.pl" -o -name "*.pod" -o -name "*.s" -o -name "*.sh" \
+ -o -name "*.sol" -o -name "*test*" \) -delete
+ cd openssl; for file in *.h; do find ../{crypto,ssl} -name "$file" -delete; done
+ ```
+ For the rest check the `git status` and decide.
+- e_os.h
+- Apply the Godot-specific patches in the `patches/` folder.
## opus
- Upstream: https://opus-codec.org
-- Version: 1.1.4 (opus) and 0.8 (opusfile)
+- Version: 1.1.5 (opus) and 0.8 (opusfile)
- License: BSD-3-Clause
Files extracted from upstream source:
@@ -272,17 +308,6 @@ Files extracted from upstream source:
- LICENSE.TXT
-## rg-etc1
-
-- Upstream: https://github.com/richgel999/rg-etc1
-- Version: 1.04
-- License: zlib
-
-Files extracted from upstream source:
-
-- `rg_etc1.{cpp,h}`
-
-
## rtaudio
- Upstream: http://www.music.mcgill.ca/~gary/rtaudio/
@@ -318,6 +343,21 @@ Files extracted from upstream source:
- COPYING and LICENSE
+## tinyexr
+
+- Upstream: https://github.com/syoyo/tinyexr
+- Version: 0.9.5+ (git a145d69)
+- License: BSD-3-Clause
+
+Files extracted from upstream source:
+
+- `tinyexr.{cc,h}`
+
+Important: Some changes were made to get TinyEXR to build on the ancient
+MinGW-w64 toolchain of Travis CI.
+https://github.com/godotengine/godot/commit/37f5e1dcd94611dd5b670f013abf0323e8b47def
+
+
## zlib
- Upstream: http://www.zlib.net/
@@ -327,3 +367,14 @@ Files extracted from upstream source:
Files extracted from upstream source:
- all .c and .h files
+
+## zstd
+
+- Upstream: https://github.com/facebook/zstd
+- Version: 1.2.0
+- License: BSD-3-Clause
+
+Files extracted from upstream source:
+
+- all .c and .h under lib/
+- README.md, LICENSE, PATENTS
diff --git a/thirdparty/etc2comp/AUTHORS b/thirdparty/etc2comp/AUTHORS
new file mode 100644
index 0000000000..32daca27fe
--- /dev/null
+++ b/thirdparty/etc2comp/AUTHORS
@@ -0,0 +1,7 @@
+# This is the list of Etc2Comp authors for copyright purposes.
+#
+# This does not necessarily list everyone who has contributed code, since in
+# some cases, their employer may be the copyright holder. To see the full list
+# of contributors, see the revision history in source control.
+Google Inc.
+Blue Shift Inc.
diff --git a/thirdparty/etc2comp/Etc.cpp b/thirdparty/etc2comp/Etc.cpp
new file mode 100644
index 0000000000..a5ee706048
--- /dev/null
+++ b/thirdparty/etc2comp/Etc.cpp
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EtcConfig.h"
+#include "Etc.h"
+#include "EtcFilter.h"
+
+#include <string.h>
+
+namespace Etc
+{
+ // ----------------------------------------------------------------------------------------------------
+ // C-style inteface to the encoder
+ //
+ void Encode(float *a_pafSourceRGBA,
+ unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ Image::Format a_format,
+ ErrorMetric a_eErrMetric,
+ float a_fEffort,
+ unsigned int a_uiJobs,
+ unsigned int a_uiMaxJobs,
+ unsigned char **a_ppaucEncodingBits,
+ unsigned int *a_puiEncodingBitsBytes,
+ unsigned int *a_puiExtendedWidth,
+ unsigned int *a_puiExtendedHeight,
+ int *a_piEncodingTime_ms, bool a_bVerboseOutput)
+ {
+
+ Image image(a_pafSourceRGBA, a_uiSourceWidth,
+ a_uiSourceHeight,
+ a_eErrMetric);
+ image.m_bVerboseOutput = a_bVerboseOutput;
+ image.Encode(a_format, a_eErrMetric, a_fEffort, a_uiJobs, a_uiMaxJobs);
+
+ *a_ppaucEncodingBits = image.GetEncodingBits();
+ *a_puiEncodingBitsBytes = image.GetEncodingBitsBytes();
+ *a_puiExtendedWidth = image.GetExtendedWidth();
+ *a_puiExtendedHeight = image.GetExtendedHeight();
+ *a_piEncodingTime_ms = image.GetEncodingTimeMs();
+ }
+
+ void EncodeMipmaps(float *a_pafSourceRGBA,
+ unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ Image::Format a_format,
+ ErrorMetric a_eErrMetric,
+ float a_fEffort,
+ unsigned int a_uiJobs,
+ unsigned int a_uiMaxJobs,
+ unsigned int a_uiMaxMipmaps,
+ unsigned int a_uiMipFilterFlags,
+ RawImage* a_pMipmapImages,
+ int *a_piEncodingTime_ms,
+ bool a_bVerboseOutput)
+ {
+ auto mipWidth = a_uiSourceWidth;
+ auto mipHeight = a_uiSourceHeight;
+ int totalEncodingTime = 0;
+ for(unsigned int mip = 0; mip < a_uiMaxMipmaps && mipWidth >= 1 && mipHeight >= 1; mip++)
+ {
+ float* pImageData = nullptr;
+ float* pMipImage = nullptr;
+
+ if(mip == 0)
+ {
+ pImageData = a_pafSourceRGBA;
+ }
+ else
+ {
+ pMipImage = new float[mipWidth*mipHeight*4];
+ if(FilterTwoPass(a_pafSourceRGBA, a_uiSourceWidth, a_uiSourceHeight, pMipImage, mipWidth, mipHeight, a_uiMipFilterFlags, Etc::FilterLanczos3) )
+ {
+ pImageData = pMipImage;
+ }
+ }
+
+ if ( pImageData )
+ {
+
+ Image image(pImageData, mipWidth, mipHeight, a_eErrMetric);
+
+ image.m_bVerboseOutput = a_bVerboseOutput;
+ image.Encode(a_format, a_eErrMetric, a_fEffort, a_uiJobs, a_uiMaxJobs);
+
+ a_pMipmapImages[mip].paucEncodingBits = std::shared_ptr<unsigned char>(image.GetEncodingBits(), [](unsigned char *p) { delete[] p; });
+ a_pMipmapImages[mip].uiEncodingBitsBytes = image.GetEncodingBitsBytes();
+ a_pMipmapImages[mip].uiExtendedWidth = image.GetExtendedWidth();
+ a_pMipmapImages[mip].uiExtendedHeight = image.GetExtendedHeight();
+
+ totalEncodingTime += image.GetEncodingTimeMs();
+ }
+
+ if(pMipImage)
+ {
+ delete[] pMipImage;
+ }
+
+ if (!pImageData)
+ {
+ break;
+ }
+
+ mipWidth >>= 1;
+ mipHeight >>= 1;
+ }
+
+ *a_piEncodingTime_ms = totalEncodingTime;
+ }
+
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+}
diff --git a/thirdparty/etc2comp/Etc.h b/thirdparty/etc2comp/Etc.h
new file mode 100644
index 0000000000..439388d649
--- /dev/null
+++ b/thirdparty/etc2comp/Etc.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcConfig.h"
+#include "EtcImage.h"
+#include "EtcColor.h"
+#include "EtcErrorMetric.h"
+#include <memory>
+
+#define ETCCOMP_MIN_EFFORT_LEVEL (0.0f)
+#define ETCCOMP_DEFAULT_EFFORT_LEVEL (40.0f)
+#define ETCCOMP_MAX_EFFORT_LEVEL (100.0f)
+
+namespace Etc
+{
+ class Block4x4EncodingBits;
+
+ struct RawImage
+ {
+ int uiExtendedWidth;
+ int uiExtendedHeight;
+ unsigned int uiEncodingBitsBytes;
+ std::shared_ptr<unsigned char> paucEncodingBits;
+ };
+
+
+
+ // C-style inteface to the encoder
+ void Encode(float *a_pafSourceRGBA,
+ unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ Image::Format a_format,
+ ErrorMetric a_eErrMetric,
+ float a_fEffort,
+ unsigned int a_uiJobs,
+ unsigned int a_uimaxJobs,
+ unsigned char **a_ppaucEncodingBits,
+ unsigned int *a_puiEncodingBitsBytes,
+ unsigned int *a_puiExtendedWidth,
+ unsigned int *a_puiExtendedHeight,
+ int *a_piEncodingTime_ms, bool a_bVerboseOutput = false);
+
+ void EncodeMipmaps(float *a_pafSourceRGBA,
+ unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ Image::Format a_format,
+ ErrorMetric a_eErrMetric,
+ float a_fEffort,
+ unsigned int a_uiJobs,
+ unsigned int a_uiMaxJobs,
+ unsigned int a_uiMaxMipmaps,
+ unsigned int a_uiMipFilterFlags,
+ RawImage* a_pMipmaps,
+ int *a_piEncodingTime_ms, bool a_bVerboseOutput = false);
+
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4.cpp b/thirdparty/etc2comp/EtcBlock4x4.cpp
new file mode 100644
index 0000000000..3082fe60db
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4.cpp
@@ -0,0 +1,425 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4.cpp
+
+Implements the state associated with each 4x4 block of pixels in an image
+
+Source images that are not a multiple of 4x4 are extended to fill the Block4x4 using pixels with an
+alpha of NAN
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcColor.h"
+#include "EtcImage.h"
+#include "EtcColorFloatRGBA.h"
+#include "EtcBlock4x4Encoding_RGB8.h"
+#include "EtcBlock4x4Encoding_RGBA8.h"
+#include "EtcBlock4x4Encoding_RGB8A1.h"
+#include "EtcBlock4x4Encoding_R11.h"
+#include "EtcBlock4x4Encoding_RG11.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace Etc
+{
+ // ETC pixels are scanned vertically.
+ // this mapping is for when someone wants to scan the ETC pixels horizontally
+ const unsigned int Block4x4::s_auiPixelOrderHScan[PIXELS] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4::Block4x4(void)
+ {
+ m_pimageSource = nullptr;
+ m_uiSourceH = 0;
+ m_uiSourceV = 0;
+
+ m_sourcealphamix = SourceAlphaMix::UNKNOWN;
+ m_boolBorderPixels = false;
+ m_boolPunchThroughPixels = false;
+
+ m_pencoding = nullptr;
+
+ m_errormetric = ErrorMetric::NUMERIC;
+
+ }
+ Block4x4::~Block4x4()
+ {
+ m_pimageSource = nullptr;
+ if (m_pencoding)
+ {
+ delete m_pencoding;
+ m_pencoding = nullptr;
+ }
+ }
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding from a source image
+ // [a_uiSourceH,a_uiSourceV] is the location of the block in a_pimageSource
+ // a_paucEncodingBits is the place to store the final encoding
+ // a_errormetric is used for finding the best encoding
+ //
+ void Block4x4::InitFromSource(Image *a_pimageSource,
+ unsigned int a_uiSourceH, unsigned int a_uiSourceV,
+ unsigned char *a_paucEncodingBits,
+ ErrorMetric a_errormetric)
+ {
+
+ Block4x4();
+
+ m_pimageSource = a_pimageSource;
+ m_uiSourceH = a_uiSourceH;
+ m_uiSourceV = a_uiSourceV;
+ m_errormetric = a_errormetric;
+
+ SetSourcePixels();
+
+ // set block encoder function
+ switch (m_pimageSource->GetFormat())
+ {
+ case Image::Format::ETC1:
+ m_pencoding = new Block4x4Encoding_ETC1;
+ break;
+
+ case Image::Format::RGB8:
+ case Image::Format::SRGB8:
+ m_pencoding = new Block4x4Encoding_RGB8;
+ break;
+
+ case Image::Format::RGBA8:
+ case Image::Format::SRGBA8:
+ if (a_errormetric == RGBX)
+ {
+ m_pencoding = new Block4x4Encoding_RGBA8;
+ }
+ else
+ {
+ switch (m_sourcealphamix)
+ {
+ case SourceAlphaMix::OPAQUE:
+ m_pencoding = new Block4x4Encoding_RGBA8_Opaque;
+ break;
+
+ case SourceAlphaMix::TRANSPARENT:
+ m_pencoding = new Block4x4Encoding_RGBA8_Transparent;
+ break;
+
+ case SourceAlphaMix::TRANSLUCENT:
+ m_pencoding = new Block4x4Encoding_RGBA8;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ break;
+ }
+ break;
+
+ case Image::Format::RGB8A1:
+ case Image::Format::SRGB8A1:
+ switch (m_sourcealphamix)
+ {
+ case SourceAlphaMix::OPAQUE:
+ m_pencoding = new Block4x4Encoding_RGB8A1_Opaque;
+ break;
+
+ case SourceAlphaMix::TRANSPARENT:
+ m_pencoding = new Block4x4Encoding_RGB8A1_Transparent;
+ break;
+
+ case SourceAlphaMix::TRANSLUCENT:
+ if (m_boolPunchThroughPixels)
+ {
+ m_pencoding = new Block4x4Encoding_RGB8A1;
+ }
+ else
+ {
+ m_pencoding = new Block4x4Encoding_RGB8A1_Opaque;
+ }
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ break;
+
+ case Image::Format::R11:
+ case Image::Format::SIGNED_R11:
+ m_pencoding = new Block4x4Encoding_R11;
+ break;
+ case Image::Format::RG11:
+ case Image::Format::SIGNED_RG11:
+ m_pencoding = new Block4x4Encoding_RG11;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ m_pencoding->InitFromSource(this, m_afrgbaSource,
+ a_paucEncodingBits, a_errormetric);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization of encoding state from a prior encoding using encoding bits
+ // [a_uiSourceH,a_uiSourceV] is the location of the block in a_pimageSource
+ // a_paucEncodingBits is the place to read the prior encoding
+ // a_imageformat is used to determine how to interpret a_paucEncodingBits
+ // a_errormetric was used for the prior encoding
+ //
+ void Block4x4::InitFromEtcEncodingBits(Image::Format a_imageformat,
+ unsigned int a_uiSourceH, unsigned int a_uiSourceV,
+ unsigned char *a_paucEncodingBits,
+ Image *a_pimageSource,
+ ErrorMetric a_errormetric)
+ {
+ Block4x4();
+
+ m_pimageSource = a_pimageSource;
+ m_uiSourceH = a_uiSourceH;
+ m_uiSourceV = a_uiSourceV;
+ m_errormetric = a_errormetric;
+
+ SetSourcePixels();
+
+ // set block encoder function
+ switch (a_imageformat)
+ {
+ case Image::Format::ETC1:
+ m_pencoding = new Block4x4Encoding_ETC1;
+ break;
+
+ case Image::Format::RGB8:
+ case Image::Format::SRGB8:
+ m_pencoding = new Block4x4Encoding_RGB8;
+ break;
+
+ case Image::Format::RGBA8:
+ case Image::Format::SRGBA8:
+ m_pencoding = new Block4x4Encoding_RGBA8;
+ break;
+
+ case Image::Format::RGB8A1:
+ case Image::Format::SRGB8A1:
+ m_pencoding = new Block4x4Encoding_RGB8A1;
+ break;
+
+ case Image::Format::R11:
+ case Image::Format::SIGNED_R11:
+ m_pencoding = new Block4x4Encoding_R11;
+ break;
+ case Image::Format::RG11:
+ case Image::Format::SIGNED_RG11:
+ m_pencoding = new Block4x4Encoding_RG11;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ m_pencoding->InitFromEncodingBits(this, a_paucEncodingBits, m_afrgbaSource,
+ m_pimageSource->GetErrorMetric());
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set source pixels from m_pimageSource
+ // set m_alphamix
+ //
+ void Block4x4::SetSourcePixels(void)
+ {
+
+ Image::Format imageformat = m_pimageSource->GetFormat();
+
+ // alpha census
+ unsigned int uiTransparentSourcePixels = 0;
+ unsigned int uiOpaqueSourcePixels = 0;
+
+ // copy source to consecutive memory locations
+ // convert from image horizontal scan to block vertical scan
+ unsigned int uiPixel = 0;
+ for (unsigned int uiBlockPixelH = 0; uiBlockPixelH < Block4x4::COLUMNS; uiBlockPixelH++)
+ {
+ unsigned int uiSourcePixelH = m_uiSourceH + uiBlockPixelH;
+
+ for (unsigned int uiBlockPixelV = 0; uiBlockPixelV < Block4x4::ROWS; uiBlockPixelV++)
+ {
+ unsigned int uiSourcePixelV = m_uiSourceV + uiBlockPixelV;
+
+ ColorFloatRGBA *pfrgbaSource = m_pimageSource->GetSourcePixel(uiSourcePixelH, uiSourcePixelV);
+
+ // if pixel extends beyond source image because of block padding
+ if (pfrgbaSource == nullptr)
+ {
+ m_afrgbaSource[uiPixel] = ColorFloatRGBA(0.0f, 0.0f, 0.0f, NAN); // denotes border pixel
+ m_boolBorderPixels = true;
+ uiTransparentSourcePixels++;
+ }
+ else
+ {
+ //get teh current pixel data, and store some of the attributes
+ //before capping values to fit the encoder type
+
+ m_afrgbaSource[uiPixel] = (*pfrgbaSource).ClampRGBA();
+
+ if (m_afrgbaSource[uiPixel].fA == 1.0f || m_errormetric == RGBX)
+ {
+ m_pimageSource->m_iNumOpaquePixels++;
+ }
+ else if (m_afrgbaSource[uiPixel].fA == 0.0f)
+ {
+ m_pimageSource->m_iNumTransparentPixels++;
+ }
+ else if(m_afrgbaSource[uiPixel].fA > 0.0f && m_afrgbaSource[uiPixel].fA < 1.0f)
+ {
+ m_pimageSource->m_iNumTranslucentPixels++;
+ }
+ else
+ {
+ m_pimageSource->m_numOutOfRangeValues.fA++;
+ }
+
+ if (m_afrgbaSource[uiPixel].fR != 0.0f)
+ {
+ m_pimageSource->m_numColorValues.fR++;
+ //make sure we are getting a float between 0-1
+ if (m_afrgbaSource[uiPixel].fR - 1.0f > 0.0f)
+ {
+ m_pimageSource->m_numOutOfRangeValues.fR++;
+ }
+ }
+
+ if (m_afrgbaSource[uiPixel].fG != 0.0f)
+ {
+ m_pimageSource->m_numColorValues.fG++;
+ if (m_afrgbaSource[uiPixel].fG - 1.0f > 0.0f)
+ {
+ m_pimageSource->m_numOutOfRangeValues.fG++;
+ }
+ }
+ if (m_afrgbaSource[uiPixel].fB != 0.0f)
+ {
+ m_pimageSource->m_numColorValues.fB++;
+ if (m_afrgbaSource[uiPixel].fB - 1.0f > 0.0f)
+ {
+ m_pimageSource->m_numOutOfRangeValues.fB++;
+ }
+ }
+ // for formats with no alpha, set source alpha to 1
+ if (imageformat == Image::Format::ETC1 ||
+ imageformat == Image::Format::RGB8 ||
+ imageformat == Image::Format::SRGB8)
+ {
+ m_afrgbaSource[uiPixel].fA = 1.0f;
+ }
+
+ if (imageformat == Image::Format::R11 ||
+ imageformat == Image::Format::SIGNED_R11)
+ {
+ m_afrgbaSource[uiPixel].fA = 1.0f;
+ m_afrgbaSource[uiPixel].fG = 0.0f;
+ m_afrgbaSource[uiPixel].fB = 0.0f;
+ }
+
+ if (imageformat == Image::Format::RG11 ||
+ imageformat == Image::Format::SIGNED_RG11)
+ {
+ m_afrgbaSource[uiPixel].fA = 1.0f;
+ m_afrgbaSource[uiPixel].fB = 0.0f;
+ }
+
+
+ // for RGB8A1, set source alpha to 0.0 or 1.0
+ // set punch through flag
+ if (imageformat == Image::Format::RGB8A1 ||
+ imageformat == Image::Format::SRGB8A1)
+ {
+ if (m_afrgbaSource[uiPixel].fA >= 0.5f)
+ {
+ m_afrgbaSource[uiPixel].fA = 1.0f;
+ }
+ else
+ {
+ m_afrgbaSource[uiPixel].fA = 0.0f;
+ m_boolPunchThroughPixels = true;
+ }
+ }
+
+ if (m_afrgbaSource[uiPixel].fA == 1.0f || m_errormetric == RGBX)
+ {
+ uiOpaqueSourcePixels++;
+ }
+ else if (m_afrgbaSource[uiPixel].fA == 0.0f)
+ {
+ uiTransparentSourcePixels++;
+ }
+
+ }
+
+ uiPixel += 1;
+ }
+ }
+
+ if (uiOpaqueSourcePixels == PIXELS)
+ {
+ m_sourcealphamix = SourceAlphaMix::OPAQUE;
+ }
+ else if (uiTransparentSourcePixels == PIXELS)
+ {
+ m_sourcealphamix = SourceAlphaMix::TRANSPARENT;
+ }
+ else
+ {
+ m_sourcealphamix = SourceAlphaMix::TRANSLUCENT;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // return a name for the encoding mode
+ //
+ const char * Block4x4::GetEncodingModeName(void)
+ {
+
+ switch (m_pencoding->GetMode())
+ {
+ case Block4x4Encoding::MODE_ETC1:
+ return "ETC1";
+ case Block4x4Encoding::MODE_T:
+ return "T";
+ case Block4x4Encoding::MODE_H:
+ return "H";
+ case Block4x4Encoding::MODE_PLANAR:
+ return "PLANAR";
+ default:
+ return "???";
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4.h b/thirdparty/etc2comp/EtcBlock4x4.h
new file mode 100644
index 0000000000..0fd30c598d
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4.h
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcColor.h"
+#include "EtcColorFloatRGBA.h"
+#include "EtcErrorMetric.h"
+#include "EtcImage.h"
+#include "EtcBlock4x4Encoding.h"
+
+namespace Etc
+{
+ class Block4x4EncodingBits;
+
+ class Block4x4
+ {
+ public:
+
+ static const unsigned int ROWS = 4;
+ static const unsigned int COLUMNS = 4;
+ static const unsigned int PIXELS = ROWS * COLUMNS;
+
+ // the alpha mix for a 4x4 block of pixels
+ enum class SourceAlphaMix
+ {
+ UNKNOWN,
+ //
+ OPAQUE, // all 1.0
+ TRANSPARENT, // all 0.0 or NAN
+ TRANSLUCENT // not all opaque or transparent
+ };
+
+ typedef void (Block4x4::*EncoderFunctionPtr)(void);
+
+ Block4x4(void);
+ ~Block4x4();
+ void InitFromSource(Image *a_pimageSource,
+ unsigned int a_uiSourceH,
+ unsigned int a_uiSourceV,
+ unsigned char *a_paucEncodingBits,
+ ErrorMetric a_errormetric);
+
+ void InitFromEtcEncodingBits(Image::Format a_imageformat,
+ unsigned int a_uiSourceH,
+ unsigned int a_uiSourceV,
+ unsigned char *a_paucEncodingBits,
+ Image *a_pimageSource,
+ ErrorMetric a_errormetric);
+
+ // return true if final iteration was performed
+ inline void PerformEncodingIteration(float a_fEffort)
+ {
+ m_pencoding->PerformIteration(a_fEffort);
+ }
+
+ inline void SetEncodingBitsFromEncoding(void)
+ {
+ m_pencoding->SetEncodingBits();
+ }
+
+ inline unsigned int GetSourceH(void)
+ {
+ return m_uiSourceH;
+ }
+
+ inline unsigned int GetSourceV(void)
+ {
+ return m_uiSourceV;
+ }
+
+ inline float GetError(void)
+ {
+ return m_pencoding->GetError();
+ }
+
+ static const unsigned int s_auiPixelOrderHScan[PIXELS];
+
+ inline ColorFloatRGBA * GetDecodedColors(void)
+ {
+ return m_pencoding->GetDecodedColors();
+ }
+
+ inline float * GetDecodedAlphas(void)
+ {
+ return m_pencoding->GetDecodedAlphas();
+ }
+
+ inline Block4x4Encoding::Mode GetEncodingMode(void)
+ {
+ return m_pencoding->GetMode();
+ }
+
+ inline bool GetFlip(void)
+ {
+ return m_pencoding->GetFlip();
+ }
+
+ inline bool IsDifferential(void)
+ {
+ return m_pencoding->IsDifferential();
+ }
+
+ inline ColorFloatRGBA * GetSource()
+ {
+ return m_afrgbaSource;
+ }
+
+ inline ErrorMetric GetErrorMetric()
+ {
+ return m_errormetric;
+ }
+
+ const char * GetEncodingModeName(void);
+
+ inline Block4x4Encoding * GetEncoding(void)
+ {
+ return m_pencoding;
+ }
+
+ inline SourceAlphaMix GetSourceAlphaMix(void)
+ {
+ return m_sourcealphamix;
+ }
+
+ inline Image * GetImageSource(void)
+ {
+ return m_pimageSource;
+ }
+
+ inline bool HasBorderPixels(void)
+ {
+ return m_boolBorderPixels;
+ }
+
+ inline bool HasPunchThroughPixels(void)
+ {
+ return m_boolPunchThroughPixels;
+ }
+
+ private:
+
+ void SetSourcePixels(void);
+
+ Image *m_pimageSource;
+ unsigned int m_uiSourceH;
+ unsigned int m_uiSourceV;
+ ErrorMetric m_errormetric;
+ ColorFloatRGBA m_afrgbaSource[PIXELS]; // vertical scan
+
+ SourceAlphaMix m_sourcealphamix;
+ bool m_boolBorderPixels; // marked as rgba(NAN, NAN, NAN, NAN)
+ bool m_boolPunchThroughPixels; // RGB8A1 or SRGB8A1 with any pixels with alpha < 0.5
+
+ Block4x4Encoding *m_pencoding;
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding.cpp
new file mode 100644
index 0000000000..7a9e68c4cf
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding.cpp
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding.cpp
+
+Block4x4Encoding is the abstract base class for the different encoders. Each encoder targets a
+particular file format (e.g. ETC1, RGB8, RGBA8, R11)
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace Etc
+{
+ // ----------------------------------------------------------------------------------------------------
+ //
+ const float Block4x4Encoding::LUMA_WEIGHT = 3.0f;
+ const float Block4x4Encoding::CHROMA_BLUE_WEIGHT = 0.5f;
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding::Block4x4Encoding(void)
+ {
+
+ m_pblockParent = nullptr;
+
+ m_pafrgbaSource = nullptr;
+
+ m_boolBorderPixels = false;
+
+ m_fError = -1.0f;
+
+ m_mode = MODE_UNKNOWN;
+
+ m_uiEncodingIterations = 0;
+ m_boolDone = false;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(-1.0f, -1.0f, -1.0f, -1.0f);
+ m_afDecodedAlphas[uiPixel] = -1.0f;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialize the generic encoding for a 4x4 block
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // init the decoded pixels to -1 to mark them as undefined
+ // init the error to -1 to mark it as undefined
+ //
+ void Block4x4Encoding::Init(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ m_pblockParent = a_pblockParent;
+
+ m_pafrgbaSource = a_pafrgbaSource;
+
+ m_boolBorderPixels = m_pblockParent->HasBorderPixels();
+
+ m_fError = -1.0f;
+
+ m_uiEncodingIterations = 0;
+
+ m_errormetric = a_errormetric;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(-1.0f, -1.0f, -1.0f, -1.0f);
+ m_afDecodedAlphas[uiPixel] = -1.0f;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // calculate the error for the block by summing the pixel errors
+ //
+ void Block4x4Encoding::CalcBlockError(void)
+ {
+ m_fError = 0.0f;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_fError += CalcPixelError(m_afrgbaDecodedColors[uiPixel], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // calculate the error between the source pixel and the decoded pixel
+ // the error amount is base on the error metric
+ //
+ float Block4x4Encoding::CalcPixelError(ColorFloatRGBA a_frgbaDecodedColor, float a_fDecodedAlpha,
+ ColorFloatRGBA a_frgbaSourcePixel)
+ {
+
+ // if a border pixel
+ if (isnan(a_frgbaSourcePixel.fA))
+ {
+ return 0.0f;
+ }
+
+ if (m_errormetric == ErrorMetric::RGBA)
+ {
+ assert(a_fDecodedAlpha >= 0.0f);
+
+ float fDRed = (a_fDecodedAlpha * a_frgbaDecodedColor.fR) -
+ (a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fR);
+ float fDGreen = (a_fDecodedAlpha * a_frgbaDecodedColor.fG) -
+ (a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fG);
+ float fDBlue = (a_fDecodedAlpha * a_frgbaDecodedColor.fB) -
+ (a_frgbaSourcePixel.fA * a_frgbaSourcePixel.fB);
+
+ float fDAlpha = a_fDecodedAlpha - a_frgbaSourcePixel.fA;
+
+ return fDRed*fDRed + fDGreen*fDGreen + fDBlue*fDBlue + fDAlpha*fDAlpha;
+ }
+ else if (m_errormetric == ErrorMetric::RGBX)
+ {
+ assert(a_fDecodedAlpha >= 0.0f);
+
+ float fDRed = a_frgbaDecodedColor.fR - a_frgbaSourcePixel.fR;
+ float fDGreen = a_frgbaDecodedColor.fG - a_frgbaSourcePixel.fG;
+ float fDBlue = a_frgbaDecodedColor.fB - a_frgbaSourcePixel.fB;
+ float fDAlpha = a_fDecodedAlpha - a_frgbaSourcePixel.fA;
+
+ return fDRed*fDRed + fDGreen*fDGreen + fDBlue*fDBlue + fDAlpha*fDAlpha;
+ }
+ else if (m_errormetric == ErrorMetric::REC709)
+ {
+ assert(a_fDecodedAlpha >= 0.0f);
+
+ float fLuma1 = a_frgbaSourcePixel.fR*0.2126f + a_frgbaSourcePixel.fG*0.7152f + a_frgbaSourcePixel.fB*0.0722f;
+ float fChromaR1 = 0.5f * ((a_frgbaSourcePixel.fR - fLuma1) * (1.0f / (1.0f - 0.2126f)));
+ float fChromaB1 = 0.5f * ((a_frgbaSourcePixel.fB - fLuma1) * (1.0f / (1.0f - 0.0722f)));
+
+ float fLuma2 = a_frgbaDecodedColor.fR*0.2126f +
+ a_frgbaDecodedColor.fG*0.7152f +
+ a_frgbaDecodedColor.fB*0.0722f;
+ float fChromaR2 = 0.5f * ((a_frgbaDecodedColor.fR - fLuma2) * (1.0f / (1.0f - 0.2126f)));
+ float fChromaB2 = 0.5f * ((a_frgbaDecodedColor.fB - fLuma2) * (1.0f / (1.0f - 0.0722f)));
+
+ float fDeltaL = a_frgbaSourcePixel.fA * fLuma1 - a_fDecodedAlpha * fLuma2;
+ float fDeltaCr = a_frgbaSourcePixel.fA * fChromaR1 - a_fDecodedAlpha * fChromaR2;
+ float fDeltaCb = a_frgbaSourcePixel.fA * fChromaB1 - a_fDecodedAlpha * fChromaB2;
+
+ float fDAlpha = a_fDecodedAlpha - a_frgbaSourcePixel.fA;
+
+ // Favor Luma accuracy over Chroma, and Red over Blue
+ return LUMA_WEIGHT*fDeltaL*fDeltaL +
+ fDeltaCr*fDeltaCr +
+ CHROMA_BLUE_WEIGHT*fDeltaCb*fDeltaCb +
+ fDAlpha*fDAlpha;
+ #if 0
+ float fDRed = a_frgbaDecodedPixel.fR - a_frgbaSourcePixel.fR;
+ float fDGreen = a_frgbaDecodedPixel.fG - a_frgbaSourcePixel.fG;
+ float fDBlue = a_frgbaDecodedPixel.fB - a_frgbaSourcePixel.fB;
+ return 2.0f * 3.0f * fDeltaL * fDeltaL + fDRed*fDRed + fDGreen*fDGreen + fDBlue*fDBlue;
+#endif
+ }
+ else if (m_errormetric == ErrorMetric::NORMALXYZ)
+ {
+ float fDecodedX = 2.0f * a_frgbaDecodedColor.fR - 1.0f;
+ float fDecodedY = 2.0f * a_frgbaDecodedColor.fG - 1.0f;
+ float fDecodedZ = 2.0f * a_frgbaDecodedColor.fB - 1.0f;
+
+ float fDecodedLength = sqrtf(fDecodedX*fDecodedX + fDecodedY*fDecodedY + fDecodedZ*fDecodedZ);
+
+ if (fDecodedLength < 0.5f)
+ {
+ return 1.0f;
+ }
+ else if (fDecodedLength == 0.0f)
+ {
+ fDecodedX = 1.0f;
+ fDecodedY = 0.0f;
+ fDecodedZ = 0.0f;
+ }
+ else
+ {
+ fDecodedX /= fDecodedLength;
+ fDecodedY /= fDecodedLength;
+ fDecodedZ /= fDecodedLength;
+ }
+
+ float fSourceX = 2.0f * a_frgbaSourcePixel.fR - 1.0f;
+ float fSourceY = 2.0f * a_frgbaSourcePixel.fG - 1.0f;
+ float fSourceZ = 2.0f * a_frgbaSourcePixel.fB - 1.0f;
+
+ float fSourceLength = sqrtf(fSourceX*fSourceX + fSourceY*fSourceY + fSourceZ*fSourceZ);
+
+ if (fSourceLength == 0.0f)
+ {
+ fSourceX = 1.0f;
+ fSourceY = 0.0f;
+ fSourceZ = 0.0f;
+ }
+ else
+ {
+ fSourceX /= fSourceLength;
+ fSourceY /= fSourceLength;
+ fSourceZ /= fSourceLength;
+ }
+
+ float fDotProduct = fSourceX*fDecodedX + fSourceY*fDecodedY + fSourceZ*fDecodedZ;
+ float fNormalizedDotProduct = 1.0f - 0.5f * (fDotProduct + 1.0f);
+ float fDotProductError = fNormalizedDotProduct * fNormalizedDotProduct;
+
+ float fLength2 = fDecodedX*fDecodedX + fDecodedY*fDecodedY + fDecodedZ*fDecodedZ;
+ float fLength2Error = fabsf(1.0f - fLength2);
+
+ float fDeltaW = a_frgbaDecodedColor.fA - a_frgbaSourcePixel.fA;
+ float fErrorW = fDeltaW * fDeltaW;
+
+ return fDotProductError + fLength2Error + fErrorW;
+ }
+ else // ErrorMetric::NUMERIC
+ {
+ assert(a_fDecodedAlpha >= 0.0f);
+
+ float fDX = a_frgbaDecodedColor.fR - a_frgbaSourcePixel.fR;
+ float fDY = a_frgbaDecodedColor.fG - a_frgbaSourcePixel.fG;
+ float fDZ = a_frgbaDecodedColor.fB - a_frgbaSourcePixel.fB;
+ float fDW = a_frgbaDecodedColor.fA - a_frgbaSourcePixel.fA;
+
+ return fDX*fDX + fDY*fDY + fDZ*fDZ + fDW*fDW;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
+
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding.h b/thirdparty/etc2comp/EtcBlock4x4Encoding.h
new file mode 100644
index 0000000000..c14c3b8616
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcColorFloatRGBA.h"
+
+#include "EtcErrorMetric.h"
+
+#include <assert.h>
+#include <float.h>
+
+namespace Etc
+{
+ class Block4x4;
+
+ // abstract base class for specific encodings
+ class Block4x4Encoding
+ {
+ public:
+
+ static const unsigned int ROWS = 4;
+ static const unsigned int COLUMNS = 4;
+ static const unsigned int PIXELS = ROWS * COLUMNS;
+ static const float LUMA_WEIGHT;
+ static const float CHROMA_BLUE_WEIGHT;
+
+ typedef enum
+ {
+ MODE_UNKNOWN,
+ //
+ MODE_ETC1,
+ MODE_T,
+ MODE_H,
+ MODE_PLANAR,
+ MODE_R11,
+ MODE_RG11,
+ //
+ MODES
+ } Mode;
+
+ Block4x4Encoding(void);
+ //virtual ~Block4x4Encoding(void) =0;
+ virtual ~Block4x4Encoding(void) {}
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric) = 0;
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ ErrorMetric a_errormetric) = 0;
+
+ // perform an iteration of the encoding
+ // the first iteration must generate a complete, valid (if poor) encoding
+ virtual void PerformIteration(float a_fEffort) = 0;
+
+ void CalcBlockError(void);
+
+ inline float GetError(void)
+ {
+ assert(m_fError >= 0.0f);
+
+ return m_fError;
+ }
+
+ inline ColorFloatRGBA * GetDecodedColors(void)
+ {
+ return m_afrgbaDecodedColors;
+ }
+
+ inline float * GetDecodedAlphas(void)
+ {
+ return m_afDecodedAlphas;
+ }
+
+ virtual void SetEncodingBits(void) = 0;
+
+ virtual bool GetFlip(void) = 0;
+
+ virtual bool IsDifferential(void) = 0;
+
+ virtual bool HasSeverelyBentDifferentialColors(void) const = 0;
+
+ inline Mode GetMode(void)
+ {
+ return m_mode;
+ }
+
+ inline bool IsDone(void)
+ {
+ return m_boolDone;
+ }
+
+ inline void SetDoneIfPerfect()
+ {
+ if (GetError() == 0.0f)
+ {
+ m_boolDone = true;
+ }
+ }
+
+ float CalcPixelError(ColorFloatRGBA a_frgbaDecodedColor, float a_fDecodedAlpha,
+ ColorFloatRGBA a_frgbaSourcePixel);
+
+ protected:
+
+ void Init(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ ErrorMetric a_errormetric);
+
+ Block4x4 *m_pblockParent;
+ ColorFloatRGBA *m_pafrgbaSource;
+
+ bool m_boolBorderPixels; // if block has any border pixels
+
+ ColorFloatRGBA m_afrgbaDecodedColors[PIXELS]; // decoded RGB components, ignore Alpha
+ float m_afDecodedAlphas[PIXELS]; // decoded alpha component
+ float m_fError; // error for RGBA relative to m_pafrgbaSource
+
+ // intermediate encoding
+ Mode m_mode;
+
+ unsigned int m_uiEncodingIterations;
+ bool m_boolDone; // all iterations have been done
+ ErrorMetric m_errormetric;
+
+ private:
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4EncodingBits.h b/thirdparty/etc2comp/EtcBlock4x4EncodingBits.h
new file mode 100644
index 0000000000..4065700379
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4EncodingBits.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ################################################################################
+ // Block4x4EncodingBits
+ // Base class for Block4x4EncodingBits_XXXX
+ // ################################################################################
+
+ class Block4x4EncodingBits
+ {
+ public:
+
+ enum class Format
+ {
+ UNKNOWN,
+ //
+ RGB8,
+ RGBA8,
+ R11,
+ RG11,
+ RGB8A1,
+ //
+ FORMATS
+ };
+
+ static unsigned int GetBytesPerBlock(Format a_format)
+ {
+ switch (a_format)
+ {
+ case Format::RGB8:
+ case Format::R11:
+ case Format::RGB8A1:
+ return 8;
+ break;
+
+ case Format::RGBA8:
+ case Format::RG11:
+ return 16;
+ break;
+
+ default:
+ return 0;
+ break;
+ }
+
+ }
+
+ };
+
+ // ################################################################################
+ // Block4x4EncodingBits_RGB8
+ // Encoding bits for the RGB portion of ETC1, RGB8, RGB8A1 and RGBA8
+ // ################################################################################
+
+ class Block4x4EncodingBits_RGB8
+ {
+ public:
+
+ static const unsigned int BYTES_PER_BLOCK = 8;
+
+ inline Block4x4EncodingBits_RGB8(void)
+ {
+ assert(sizeof(Block4x4EncodingBits_RGB8) == BYTES_PER_BLOCK);
+
+ for (unsigned int uiByte = 0; uiByte < BYTES_PER_BLOCK; uiByte++)
+ {
+ auc[uiByte] = 0;
+ }
+
+ }
+
+ typedef struct
+ {
+ unsigned red2 : 4;
+ unsigned red1 : 4;
+ //
+ unsigned green2 : 4;
+ unsigned green1 : 4;
+ //
+ unsigned blue2 : 4;
+ unsigned blue1 : 4;
+ //
+ unsigned flip : 1;
+ unsigned diff : 1;
+ unsigned cw2 : 3;
+ unsigned cw1 : 3;
+ //
+ unsigned int selectors;
+ } Individual;
+
+ typedef struct
+ {
+ signed dred2 : 3;
+ unsigned red1 : 5;
+ //
+ signed dgreen2 : 3;
+ unsigned green1 : 5;
+ //
+ signed dblue2 : 3;
+ unsigned blue1 : 5;
+ //
+ unsigned flip : 1;
+ unsigned diff : 1;
+ unsigned cw2 : 3;
+ unsigned cw1 : 3;
+ //
+ unsigned int selectors;
+ } Differential;
+
+ typedef struct
+ {
+ unsigned red1b : 2;
+ unsigned detect2 : 1;
+ unsigned red1a : 2;
+ unsigned detect1 : 3;
+ //
+ unsigned blue1 : 4;
+ unsigned green1 : 4;
+ //
+ unsigned green2 : 4;
+ unsigned red2 : 4;
+ //
+ unsigned db : 1;
+ unsigned diff : 1;
+ unsigned da : 2;
+ unsigned blue2 : 4;
+ //
+ unsigned int selectors;
+ } T;
+
+ typedef struct
+ {
+ unsigned green1a : 3;
+ unsigned red1 : 4;
+ unsigned detect1 : 1;
+ //
+ unsigned blue1b : 2;
+ unsigned detect3 : 1;
+ unsigned blue1a : 1;
+ unsigned green1b : 1;
+ unsigned detect2 : 3;
+ //
+ unsigned green2a : 3;
+ unsigned red2 : 4;
+ unsigned blue1c : 1;
+ //
+ unsigned db : 1;
+ unsigned diff : 1;
+ unsigned da : 1;
+ unsigned blue2 : 4;
+ unsigned green2b : 1;
+ //
+ unsigned int selectors;
+ } H;
+
+ typedef struct
+ {
+ unsigned originGreen1 : 1;
+ unsigned originRed : 6;
+ unsigned detect1 : 1;
+ //
+ unsigned originBlue1 : 1;
+ unsigned originGreen2 : 6;
+ unsigned detect2 : 1;
+ //
+ unsigned originBlue3 : 2;
+ unsigned detect4 : 1;
+ unsigned originBlue2 : 2;
+ unsigned detect3 : 3;
+ //
+ unsigned horizRed2 : 1;
+ unsigned diff : 1;
+ unsigned horizRed1 : 5;
+ unsigned originBlue4 : 1;
+ //
+ unsigned horizBlue1: 1;
+ unsigned horizGreen : 7;
+ //
+ unsigned vertRed1 : 3;
+ unsigned horizBlue2 : 5;
+ //
+ unsigned vertGreen1 : 5;
+ unsigned vertRed2 : 3;
+ //
+ unsigned vertBlue : 6;
+ unsigned vertGreen2 : 2;
+ } Planar;
+
+ union
+ {
+ unsigned char auc[BYTES_PER_BLOCK];
+ unsigned long int ul;
+ Individual individual;
+ Differential differential;
+ T t;
+ H h;
+ Planar planar;
+ };
+
+ };
+
+ // ################################################################################
+ // Block4x4EncodingBits_A8
+ // Encoding bits for the A portion of RGBA8
+ // ################################################################################
+
+ class Block4x4EncodingBits_A8
+ {
+ public:
+
+ static const unsigned int BYTES_PER_BLOCK = 8;
+ static const unsigned int SELECTOR_BYTES = 6;
+
+ typedef struct
+ {
+ unsigned base : 8;
+ unsigned table : 4;
+ unsigned multiplier : 4;
+ unsigned selectors0 : 8;
+ unsigned selectors1 : 8;
+ unsigned selectors2 : 8;
+ unsigned selectors3 : 8;
+ unsigned selectors4 : 8;
+ unsigned selectors5 : 8;
+ } Data;
+
+ Data data;
+
+ };
+
+ // ################################################################################
+ // Block4x4EncodingBits_R11
+ // Encoding bits for the R portion of R11
+ // ################################################################################
+
+ class Block4x4EncodingBits_R11
+ {
+ public:
+
+ static const unsigned int BYTES_PER_BLOCK = 8;
+ static const unsigned int SELECTOR_BYTES = 6;
+
+ typedef struct
+ {
+ unsigned base : 8;
+ unsigned table : 4;
+ unsigned multiplier : 4;
+ unsigned selectors0 : 8;
+ unsigned selectors1 : 8;
+ unsigned selectors2 : 8;
+ unsigned selectors3 : 8;
+ unsigned selectors4 : 8;
+ unsigned selectors5 : 8;
+ } Data;
+
+ Data data;
+
+ };
+
+ class Block4x4EncodingBits_RG11
+ {
+ public:
+
+ static const unsigned int BYTES_PER_BLOCK = 16;
+ static const unsigned int SELECTOR_BYTES = 12;
+
+ typedef struct
+ {
+ //Red portion
+ unsigned baseR : 8;
+ unsigned tableIndexR : 4;
+ unsigned multiplierR : 4;
+ unsigned selectorsR0 : 8;
+ unsigned selectorsR1 : 8;
+ unsigned selectorsR2 : 8;
+ unsigned selectorsR3 : 8;
+ unsigned selectorsR4 : 8;
+ unsigned selectorsR5 : 8;
+ //Green portion
+ unsigned baseG : 8;
+ unsigned tableIndexG : 4;
+ unsigned multiplierG : 4;
+ unsigned selectorsG0 : 8;
+ unsigned selectorsG1 : 8;
+ unsigned selectorsG2 : 8;
+ unsigned selectorsG3 : 8;
+ unsigned selectorsG4 : 8;
+ unsigned selectorsG5 : 8;
+ } Data;
+
+ Data data;
+
+ };
+
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.cpp
new file mode 100644
index 0000000000..a27f74c0d5
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.cpp
@@ -0,0 +1,1281 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_ETC1.cpp
+
+Block4x4Encoding_ETC1 is the encoder to use when targetting file format ETC1. This encoder is also
+used for the ETC1 subset of file format RGB8, RGBA8 and RGB8A1
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_ETC1.h"
+
+#include "EtcBlock4x4.h"
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcDifferentialTrys.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <limits>
+
+namespace Etc
+{
+
+ // pixel processing order if the flip bit = 0 (horizontal split)
+ const unsigned int Block4x4Encoding_ETC1::s_auiPixelOrderFlip0[PIXELS] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
+
+ // pixel processing order if the flip bit = 1 (vertical split)
+ const unsigned int Block4x4Encoding_ETC1::s_auiPixelOrderFlip1[PIXELS] = { 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15 };
+
+ // pixel processing order for horizontal scan (ETC normally does a vertical scan)
+ const unsigned int Block4x4Encoding_ETC1::s_auiPixelOrderHScan[PIXELS] = { 0, 4, 8, 12, 1, 5, 9, 13, 2, 6, 10, 14, 3, 7, 11, 15 };
+
+ // pixel indices for different block halves
+ const unsigned int Block4x4Encoding_ETC1::s_auiLeftPixelMapping[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
+ const unsigned int Block4x4Encoding_ETC1::s_auiRightPixelMapping[8] = { 8, 9, 10, 11, 12, 13, 14, 15 };
+ const unsigned int Block4x4Encoding_ETC1::s_auiTopPixelMapping[8] = { 0, 1, 4, 5, 8, 9, 12, 13 };
+ const unsigned int Block4x4Encoding_ETC1::s_auiBottomPixelMapping[8] = { 2, 3, 6, 7, 10, 11, 14, 15 };
+
+ // CW ranges that the ETC1 decoders use
+ // CW is basically a contrast for the different selector bits, since these values are offsets to the base color
+ // the first axis in the array is indexed by the CW in the encoding bits
+ // the second axis in the array is indexed by the selector bits
+ float Block4x4Encoding_ETC1::s_aafCwTable[CW_RANGES][SELECTORS] =
+ {
+ { 2.0f / 255.0f, 8.0f / 255.0f, -2.0f / 255.0f, -8.0f / 255.0f },
+ { 5.0f / 255.0f, 17.0f / 255.0f, -5.0f / 255.0f, -17.0f / 255.0f },
+ { 9.0f / 255.0f, 29.0f / 255.0f, -9.0f / 255.0f, -29.0f / 255.0f },
+ { 13.0f / 255.0f, 42.0f / 255.0f, -13.0f / 255.0f, -42.0f / 255.0f },
+ { 18.0f / 255.0f, 60.0f / 255.0f, -18.0f / 255.0f, -60.0f / 255.0f },
+ { 24.0f / 255.0f, 80.0f / 255.0f, -24.0f / 255.0f, -80.0f / 255.0f },
+ { 33.0f / 255.0f, 106.0f / 255.0f, -33.0f / 255.0f, -106.0f / 255.0f },
+ { 47.0f / 255.0f, 183.0f / 255.0f, -47.0f / 255.0f, -183.0f / 255.0f }
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_ETC1::Block4x4Encoding_ETC1(void)
+ {
+ m_mode = MODE_ETC1;
+ m_boolDiff = false;
+ m_boolFlip = false;
+ m_frgbaColor1 = ColorFloatRGBA();
+ m_frgbaColor2 = ColorFloatRGBA();
+ m_uiCW1 = 0;
+ m_uiCW2 = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = 0;
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+
+ m_boolMostLikelyFlip = false;
+
+ m_fError = -1.0f;
+
+ m_fError1 = -1.0f;
+ m_fError2 = -1.0f;
+ m_boolSeverelyBentDifferentialColors = false;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+
+ }
+
+ Block4x4Encoding_ETC1::~Block4x4Encoding_ETC1(void) {}
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits
+ //
+ void Block4x4Encoding_ETC1::InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
+ {
+
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+
+ m_fError = -1.0f;
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)(a_paucEncodingBits);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_ETC1::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
+ m_fError = -1.0f;
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
+
+ m_mode = MODE_ETC1;
+ m_boolDiff = m_pencodingbitsRGB8->individual.diff;
+ m_boolFlip = m_pencodingbitsRGB8->individual.flip;
+ if (m_boolDiff)
+ {
+ int iR2 = (int)(m_pencodingbitsRGB8->differential.red1 + m_pencodingbitsRGB8->differential.dred2);
+ if (iR2 < 0)
+ {
+ iR2 = 0;
+ }
+ else if (iR2 > 31)
+ {
+ iR2 = 31;
+ }
+
+ int iG2 = (int)(m_pencodingbitsRGB8->differential.green1 + m_pencodingbitsRGB8->differential.dgreen2);
+ if (iG2 < 0)
+ {
+ iG2 = 0;
+ }
+ else if (iG2 > 31)
+ {
+ iG2 = 31;
+ }
+
+ int iB2 = (int)(m_pencodingbitsRGB8->differential.blue1 + m_pencodingbitsRGB8->differential.dblue2);
+ if (iB2 < 0)
+ {
+ iB2 = 0;
+ }
+ else if (iB2 > 31)
+ {
+ iB2 = 31;
+ }
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5(m_pencodingbitsRGB8->differential.red1, m_pencodingbitsRGB8->differential.green1, m_pencodingbitsRGB8->differential.blue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iR2, (unsigned char)iG2, (unsigned char)iB2);
+
+ }
+ else
+ {
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(m_pencodingbitsRGB8->individual.red1, m_pencodingbitsRGB8->individual.green1, m_pencodingbitsRGB8->individual.blue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(m_pencodingbitsRGB8->individual.red2, m_pencodingbitsRGB8->individual.green2, m_pencodingbitsRGB8->individual.blue2);
+ }
+
+ m_uiCW1 = m_pencodingbitsRGB8->individual.cw1;
+ m_uiCW2 = m_pencodingbitsRGB8->individual.cw2;
+
+ InitFromEncodingBits_Selectors();
+
+ Decode();
+
+ CalcBlockError();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // init the selectors from a prior encoding
+ //
+ void Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors(void)
+ {
+
+ unsigned char *paucSelectors = (unsigned char *)&m_pencodingbitsRGB8->individual.selectors;
+
+ for (unsigned int iPixel = 0; iPixel < PIXELS; iPixel++)
+ {
+ unsigned int uiByteMSB = (unsigned int)(1 - (iPixel / 8));
+ unsigned int uiByteLSB = (unsigned int)(3 - (iPixel / 8));
+ unsigned int uiShift = (unsigned int)(iPixel & 7);
+
+ unsigned int uiSelectorMSB = (unsigned int)((paucSelectors[uiByteMSB] >> uiShift) & 1);
+ unsigned int uiSelectorLSB = (unsigned int)((paucSelectors[uiByteLSB] >> uiShift) & 1);
+
+ m_auiSelectors[iPixel] = (uiSelectorMSB << 1) + uiSelectorLSB;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_ETC1::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ PerformFirstIteration();
+ break;
+
+ case 1:
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 2:
+ TryIndividual(m_boolMostLikelyFlip, 1);
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 3:
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
+ if (a_fEffort <= 59.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 4:
+ TryIndividual(!m_boolMostLikelyFlip, 1);
+ if (a_fEffort <= 69.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 5:
+ TryDegenerates1();
+ if (a_fEffort <= 79.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 6:
+ TryDegenerates2();
+ if (a_fEffort <= 89.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 7:
+ TryDegenerates3();
+ if (a_fEffort <= 99.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 8:
+ TryDegenerates4();
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+ SetDoneIfPerfect();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best initial encoding to ensure block has a valid encoding
+ //
+ void Block4x4Encoding_ETC1::PerformFirstIteration(void)
+ {
+ CalculateMostLikelyFlip();
+
+ m_fError = FLT_MAX;
+
+ TryDifferential(m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+
+ TryIndividual(m_boolMostLikelyFlip, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ TryDifferential(!m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ TryIndividual(!m_boolMostLikelyFlip, 0);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // algorithm:
+ // create a source average color for the Left, Right, Top and Bottom halves using the 8 pixels in each half
+ // note: the "gray line" is the line of equal delta RGB that goes thru the average color
+ // for each half:
+ // see how close each of the 8 pixels are to the "gray line" that goes thru the source average color
+ // create an error value that is the sum of the distances from the gray line
+ // h_error is the sum of Left and Right errors
+ // v_error is the sum of Top and Bottom errors
+ //
+ void Block4x4Encoding_ETC1::CalculateMostLikelyFlip(void)
+ {
+ static const bool DEBUG_PRINT = false;
+
+ CalculateSourceAverages();
+
+ float fLeftGrayErrorSum = 0.0f;
+ float fRightGrayErrorSum = 0.0f;
+ float fTopGrayErrorSum = 0.0f;
+ float fBottomGrayErrorSum = 0.0f;
+
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ColorFloatRGBA *pfrgbaLeft = &m_pafrgbaSource[uiPixel];
+ ColorFloatRGBA *pfrgbaRight = &m_pafrgbaSource[uiPixel + 8];
+ ColorFloatRGBA *pfrgbaTop = &m_pafrgbaSource[s_auiTopPixelMapping[uiPixel]];
+ ColorFloatRGBA *pfrgbaBottom = &m_pafrgbaSource[s_auiBottomPixelMapping[uiPixel]];
+
+ float fLeftGrayError = CalcGrayDistance2(*pfrgbaLeft, m_frgbaSourceAverageLeft);
+ float fRightGrayError = CalcGrayDistance2(*pfrgbaRight, m_frgbaSourceAverageRight);
+ float fTopGrayError = CalcGrayDistance2(*pfrgbaTop, m_frgbaSourceAverageTop);
+ float fBottomGrayError = CalcGrayDistance2(*pfrgbaBottom, m_frgbaSourceAverageBottom);
+
+ fLeftGrayErrorSum += fLeftGrayError;
+ fRightGrayErrorSum += fRightGrayError;
+ fTopGrayErrorSum += fTopGrayError;
+ fBottomGrayErrorSum += fBottomGrayError;
+ }
+
+ if (DEBUG_PRINT)
+ {
+ printf("\n%.2f %.2f\n", fLeftGrayErrorSum + fRightGrayErrorSum, fTopGrayErrorSum + fBottomGrayErrorSum);
+ }
+
+ m_boolMostLikelyFlip = (fTopGrayErrorSum + fBottomGrayErrorSum) < (fLeftGrayErrorSum + fRightGrayErrorSum);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // calculate source pixel averages for each 2x2 quadrant in a 4x4 block
+ // these are used to determine the averages for each of the 4 different halves (left, right, top, bottom)
+ // ignore pixels that have alpha == NAN (these are border pixels outside of the source image)
+ // weight the averages based on a pixel's alpha
+ //
+ void Block4x4Encoding_ETC1::CalculateSourceAverages(void)
+ {
+ static const bool DEBUG_PRINT = false;
+
+ bool boolRGBX = m_pblockParent->GetImageSource()->GetErrorMetric() == ErrorMetric::RGBX;
+
+ if (m_pblockParent->GetSourceAlphaMix() == Block4x4::SourceAlphaMix::OPAQUE || boolRGBX)
+ {
+ ColorFloatRGBA frgbaSumUL = m_pafrgbaSource[0] + m_pafrgbaSource[1] + m_pafrgbaSource[4] + m_pafrgbaSource[5];
+ ColorFloatRGBA frgbaSumLL = m_pafrgbaSource[2] + m_pafrgbaSource[3] + m_pafrgbaSource[6] + m_pafrgbaSource[7];
+ ColorFloatRGBA frgbaSumUR = m_pafrgbaSource[8] + m_pafrgbaSource[9] + m_pafrgbaSource[12] + m_pafrgbaSource[13];
+ ColorFloatRGBA frgbaSumLR = m_pafrgbaSource[10] + m_pafrgbaSource[11] + m_pafrgbaSource[14] + m_pafrgbaSource[15];
+
+ m_frgbaSourceAverageLeft = (frgbaSumUL + frgbaSumLL) * 0.125f;
+ m_frgbaSourceAverageRight = (frgbaSumUR + frgbaSumLR) * 0.125f;
+ m_frgbaSourceAverageTop = (frgbaSumUL + frgbaSumUR) * 0.125f;
+ m_frgbaSourceAverageBottom = (frgbaSumLL + frgbaSumLR) * 0.125f;
+ }
+ else
+ {
+ float afSourceAlpha[PIXELS];
+
+ // treat alpha NAN as 0.0f
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ afSourceAlpha[uiPixel] = isnan(m_pafrgbaSource[uiPixel].fA) ?
+ 0.0f :
+ m_pafrgbaSource[uiPixel].fA;
+ }
+
+ ColorFloatRGBA afrgbaAlphaWeightedSource[PIXELS];
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ afrgbaAlphaWeightedSource[uiPixel] = m_pafrgbaSource[uiPixel] * afSourceAlpha[uiPixel];
+ }
+
+ ColorFloatRGBA frgbaSumUL = afrgbaAlphaWeightedSource[0] +
+ afrgbaAlphaWeightedSource[1] +
+ afrgbaAlphaWeightedSource[4] +
+ afrgbaAlphaWeightedSource[5];
+
+ ColorFloatRGBA frgbaSumLL = afrgbaAlphaWeightedSource[2] +
+ afrgbaAlphaWeightedSource[3] +
+ afrgbaAlphaWeightedSource[6] +
+ afrgbaAlphaWeightedSource[7];
+
+ ColorFloatRGBA frgbaSumUR = afrgbaAlphaWeightedSource[8] +
+ afrgbaAlphaWeightedSource[9] +
+ afrgbaAlphaWeightedSource[12] +
+ afrgbaAlphaWeightedSource[13];
+
+ ColorFloatRGBA frgbaSumLR = afrgbaAlphaWeightedSource[10] +
+ afrgbaAlphaWeightedSource[11] +
+ afrgbaAlphaWeightedSource[14] +
+ afrgbaAlphaWeightedSource[15];
+
+ float fWeightSumUL = afSourceAlpha[0] +
+ afSourceAlpha[1] +
+ afSourceAlpha[4] +
+ afSourceAlpha[5];
+
+ float fWeightSumLL = afSourceAlpha[2] +
+ afSourceAlpha[3] +
+ afSourceAlpha[6] +
+ afSourceAlpha[7];
+
+ float fWeightSumUR = afSourceAlpha[8] +
+ afSourceAlpha[9] +
+ afSourceAlpha[12] +
+ afSourceAlpha[13];
+
+ float fWeightSumLR = afSourceAlpha[10] +
+ afSourceAlpha[11] +
+ afSourceAlpha[14] +
+ afSourceAlpha[15];
+
+ ColorFloatRGBA frgbaSumLeft = frgbaSumUL + frgbaSumLL;
+ ColorFloatRGBA frgbaSumRight = frgbaSumUR + frgbaSumLR;
+ ColorFloatRGBA frgbaSumTop = frgbaSumUL + frgbaSumUR;
+ ColorFloatRGBA frgbaSumBottom = frgbaSumLL + frgbaSumLR;
+
+ float fWeightSumLeft = fWeightSumUL + fWeightSumLL;
+ float fWeightSumRight = fWeightSumUR + fWeightSumLR;
+ float fWeightSumTop = fWeightSumUL + fWeightSumUR;
+ float fWeightSumBottom = fWeightSumLL + fWeightSumLR;
+
+ // check to see if there is at least 1 pixel with non-zero alpha
+ // completely transparent block should not make it to this code
+ assert((fWeightSumLeft + fWeightSumRight) > 0.0f);
+ assert((fWeightSumTop + fWeightSumBottom) > 0.0f);
+
+ if (fWeightSumLeft > 0.0f)
+ {
+ m_frgbaSourceAverageLeft = frgbaSumLeft * (1.0f/fWeightSumLeft);
+ }
+ if (fWeightSumRight > 0.0f)
+ {
+ m_frgbaSourceAverageRight = frgbaSumRight * (1.0f/fWeightSumRight);
+ }
+ if (fWeightSumTop > 0.0f)
+ {
+ m_frgbaSourceAverageTop = frgbaSumTop * (1.0f/fWeightSumTop);
+ }
+ if (fWeightSumBottom > 0.0f)
+ {
+ m_frgbaSourceAverageBottom = frgbaSumBottom * (1.0f/fWeightSumBottom);
+ }
+
+ if (fWeightSumLeft == 0.0f)
+ {
+ assert(fWeightSumRight > 0.0f);
+ m_frgbaSourceAverageLeft = m_frgbaSourceAverageRight;
+ }
+ if (fWeightSumRight == 0.0f)
+ {
+ assert(fWeightSumLeft > 0.0f);
+ m_frgbaSourceAverageRight = m_frgbaSourceAverageLeft;
+ }
+ if (fWeightSumTop == 0.0f)
+ {
+ assert(fWeightSumBottom > 0.0f);
+ m_frgbaSourceAverageTop = m_frgbaSourceAverageBottom;
+ }
+ if (fWeightSumBottom == 0.0f)
+ {
+ assert(fWeightSumTop > 0.0f);
+ m_frgbaSourceAverageBottom = m_frgbaSourceAverageTop;
+ }
+ }
+
+
+
+ if (DEBUG_PRINT)
+ {
+ printf("\ntarget: [%.2f,%.2f,%.2f] [%.2f,%.2f,%.2f] [%.2f,%.2f,%.2f] [%.2f,%.2f,%.2f]\n",
+ m_frgbaSourceAverageLeft.fR, m_frgbaSourceAverageLeft.fG, m_frgbaSourceAverageLeft.fB,
+ m_frgbaSourceAverageRight.fR, m_frgbaSourceAverageRight.fG, m_frgbaSourceAverageRight.fB,
+ m_frgbaSourceAverageTop.fR, m_frgbaSourceAverageTop.fG, m_frgbaSourceAverageTop.fB,
+ m_frgbaSourceAverageBottom.fR, m_frgbaSourceAverageBottom.fG, m_frgbaSourceAverageBottom.fB);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try an ETC1 differential mode encoding
+ // use a_boolFlip to set the encoding F bit
+ // use a_uiRadius to alter basecolor components in the range[-a_uiRadius:a_uiRadius]
+ // use a_iGrayOffset1 and a_iGrayOffset2 to offset the basecolor to search for degenerate encodings
+ // replace the encoding if the encoding error is less than previous encoding
+ //
+ void Block4x4Encoding_ETC1::TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2)
+ {
+
+ ColorFloatRGBA frgbaColor1;
+ ColorFloatRGBA frgbaColor2;
+
+ const unsigned int *pauiPixelMapping1;
+ const unsigned int *pauiPixelMapping2;
+
+ if (a_boolFlip)
+ {
+ frgbaColor1 = m_frgbaSourceAverageTop;
+ frgbaColor2 = m_frgbaSourceAverageBottom;
+
+ pauiPixelMapping1 = s_auiTopPixelMapping;
+ pauiPixelMapping2 = s_auiBottomPixelMapping;
+ }
+ else
+ {
+ frgbaColor1 = m_frgbaSourceAverageLeft;
+ frgbaColor2 = m_frgbaSourceAverageRight;
+
+ pauiPixelMapping1 = s_auiLeftPixelMapping;
+ pauiPixelMapping2 = s_auiRightPixelMapping;
+ }
+
+ DifferentialTrys trys(frgbaColor1, frgbaColor2, pauiPixelMapping1, pauiPixelMapping2,
+ a_uiRadius, a_iGrayOffset1, a_iGrayOffset2);
+
+ Block4x4Encoding_ETC1 encodingTry = *this;
+ encodingTry.m_boolFlip = a_boolFlip;
+
+ encodingTry.TryDifferentialHalf(&trys.m_half1);
+ encodingTry.TryDifferentialHalf(&trys.m_half2);
+
+ // find best halves that are within differential range
+ DifferentialTrys::Try *ptryBest1 = nullptr;
+ DifferentialTrys::Try *ptryBest2 = nullptr;
+ encodingTry.m_fError = FLT_MAX;
+
+ // see if the best of each half are in differential range
+ int iDRed = trys.m_half2.m_ptryBest->m_iRed - trys.m_half1.m_ptryBest->m_iRed;
+ int iDGreen = trys.m_half2.m_ptryBest->m_iGreen - trys.m_half1.m_ptryBest->m_iGreen;
+ int iDBlue = trys.m_half2.m_ptryBest->m_iBlue - trys.m_half1.m_ptryBest->m_iBlue;
+ if (iDRed >= -4 && iDRed <= 3 && iDGreen >= -4 && iDGreen <= 3 && iDBlue >= -4 && iDBlue <= 3)
+ {
+ ptryBest1 = trys.m_half1.m_ptryBest;
+ ptryBest2 = trys.m_half2.m_ptryBest;
+ encodingTry.m_fError = trys.m_half1.m_ptryBest->m_fError + trys.m_half2.m_ptryBest->m_fError;
+ }
+ else
+ {
+ // else, find the next best halves that are in differential range
+ for (DifferentialTrys::Try *ptry1 = &trys.m_half1.m_atry[0];
+ ptry1 < &trys.m_half1.m_atry[trys.m_half1.m_uiTrys];
+ ptry1++)
+ {
+ for (DifferentialTrys::Try *ptry2 = &trys.m_half2.m_atry[0];
+ ptry2 < &trys.m_half2.m_atry[trys.m_half2.m_uiTrys];
+ ptry2++)
+ {
+ iDRed = ptry2->m_iRed - ptry1->m_iRed;
+ bool boolValidRedDelta = iDRed <= 3 && iDRed >= -4;
+ iDGreen = ptry2->m_iGreen - ptry1->m_iGreen;
+ bool boolValidGreenDelta = iDGreen <= 3 && iDGreen >= -4;
+ iDBlue = ptry2->m_iBlue - ptry1->m_iBlue;
+ bool boolValidBlueDelta = iDBlue <= 3 && iDBlue >= -4;
+
+ if (boolValidRedDelta && boolValidGreenDelta && boolValidBlueDelta)
+ {
+ float fError = ptry1->m_fError + ptry2->m_fError;
+
+ if (fError < encodingTry.m_fError)
+ {
+ encodingTry.m_fError = fError;
+
+ ptryBest1 = ptry1;
+ ptryBest2 = ptry2;
+ }
+ }
+
+ }
+ }
+ assert(encodingTry.m_fError < FLT_MAX);
+ assert(ptryBest1 != nullptr);
+ assert(ptryBest2 != nullptr);
+ }
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_ETC1;
+ m_boolDiff = true;
+ m_boolFlip = encodingTry.m_boolFlip;
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest1->m_iRed, (unsigned char)ptryBest1->m_iGreen, (unsigned char)ptryBest1->m_iBlue);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest2->m_iRed, (unsigned char)ptryBest2->m_iGreen, (unsigned char)ptryBest2->m_iBlue);
+ m_uiCW1 = ptryBest1->m_uiCW;
+ m_uiCW2 = ptryBest2->m_uiCW;
+
+ for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS / 2; uiPixelOrder++)
+ {
+ unsigned int uiPixel1 = pauiPixelMapping1[uiPixelOrder];
+ unsigned int uiPixel2 = pauiPixelMapping2[uiPixelOrder];
+
+ unsigned int uiSelector1 = ptryBest1->m_auiSelectors[uiPixelOrder];
+ unsigned int uiSelector2 = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ m_auiSelectors[uiPixel1] = uiSelector1;
+ m_auiSelectors[uiPixel2] = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ float fDeltaRGB1 = s_aafCwTable[m_uiCW1][uiSelector1];
+ float fDeltaRGB2 = s_aafCwTable[m_uiCW2][uiSelector2];
+
+ m_afrgbaDecodedColors[uiPixel1] = (m_frgbaColor1 + fDeltaRGB1).ClampRGB();
+ m_afrgbaDecodedColors[uiPixel2] = (m_frgbaColor2 + fDeltaRGB2).ClampRGB();
+ }
+
+ m_fError1 = ptryBest1->m_fError;
+ m_fError2 = ptryBest2->m_fError;
+ m_boolSeverelyBentDifferentialColors = trys.m_boolSeverelyBentColors;
+ m_fError = m_fError1 + m_fError2;
+
+ // sanity check
+ {
+ int iRed1 = m_frgbaColor1.IntRed(31.0f);
+ int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
+ int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
+
+ int iRed2 = m_frgbaColor2.IntRed(31.0f);
+ int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
+ int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
+
+ iDRed = iRed2 - iRed1;
+ iDGreen = iGreen2 - iGreen1;
+ iDBlue = iBlue2 - iBlue1;
+
+ assert(iDRed >= -4 && iDRed < 4);
+ assert(iDGreen >= -4 && iDGreen < 4);
+ assert(iDBlue >= -4 && iDBlue < 4);
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try an ETC1 differential mode encoding for a half of a 4x4 block
+ // vary the basecolor components using a radius
+ //
+ void Block4x4Encoding_ETC1::TryDifferentialHalf(DifferentialTrys::Half *a_phalf)
+ {
+
+ a_phalf->m_ptryBest = nullptr;
+ float fBestTryError = FLT_MAX;
+
+ a_phalf->m_uiTrys = 0;
+ for (int iRed = a_phalf->m_iRed - (int)a_phalf->m_uiRadius;
+ iRed <= a_phalf->m_iRed + (int)a_phalf->m_uiRadius;
+ iRed++)
+ {
+ assert(iRed >= 0 && iRed <= 31);
+
+ for (int iGreen = a_phalf->m_iGreen - (int)a_phalf->m_uiRadius;
+ iGreen <= a_phalf->m_iGreen + (int)a_phalf->m_uiRadius;
+ iGreen++)
+ {
+ assert(iGreen >= 0 && iGreen <= 31);
+
+ for (int iBlue = a_phalf->m_iBlue - (int)a_phalf->m_uiRadius;
+ iBlue <= a_phalf->m_iBlue + (int)a_phalf->m_uiRadius;
+ iBlue++)
+ {
+ assert(iBlue >= 0 && iBlue <= 31);
+
+ DifferentialTrys::Try *ptry = &a_phalf->m_atry[a_phalf->m_uiTrys];
+ assert(ptry < &a_phalf->m_atry[DifferentialTrys::Half::MAX_TRYS]);
+
+ ptry->m_iRed = iRed;
+ ptry->m_iGreen = iGreen;
+ ptry->m_iBlue = iBlue;
+ ptry->m_fError = FLT_MAX;
+ ColorFloatRGBA frgbaColor = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iRed, (unsigned char)iGreen, (unsigned char)iBlue);
+
+ // try each CW
+ for (unsigned int uiCW = 0; uiCW < CW_RANGES; uiCW++)
+ {
+ unsigned int auiPixelSelectors[PIXELS / 2];
+ ColorFloatRGBA afrgbaDecodedPixels[PIXELS / 2];
+ float afPixelErrors[PIXELS / 2] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+
+ // pre-compute decoded pixels for each selector
+ ColorFloatRGBA afrgbaSelectors[SELECTORS];
+ assert(SELECTORS == 4);
+ afrgbaSelectors[0] = (frgbaColor + s_aafCwTable[uiCW][0]).ClampRGB();
+ afrgbaSelectors[1] = (frgbaColor + s_aafCwTable[uiCW][1]).ClampRGB();
+ afrgbaSelectors[2] = (frgbaColor + s_aafCwTable[uiCW][2]).ClampRGB();
+ afrgbaSelectors[3] = (frgbaColor + s_aafCwTable[uiCW][3]).ClampRGB();
+
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ColorFloatRGBA *pfrgbaSourcePixel = &m_pafrgbaSource[a_phalf->m_pauiPixelMapping[uiPixel]];
+ ColorFloatRGBA frgbaDecodedPixel;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ frgbaDecodedPixel = afrgbaSelectors[uiSelector];
+
+ float fPixelError;
+
+ fPixelError = CalcPixelError(frgbaDecodedPixel, m_afDecodedAlphas[a_phalf->m_pauiPixelMapping[uiPixel]],
+ *pfrgbaSourcePixel);
+
+ if (fPixelError < afPixelErrors[uiPixel])
+ {
+ auiPixelSelectors[uiPixel] = uiSelector;
+ afrgbaDecodedPixels[uiPixel] = frgbaDecodedPixel;
+ afPixelErrors[uiPixel] = fPixelError;
+ }
+
+ }
+ }
+
+ // add up all pixel errors
+ float fCWError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ fCWError += afPixelErrors[uiPixel];
+ }
+
+ // if best CW so far
+ if (fCWError < ptry->m_fError)
+ {
+ ptry->m_uiCW = uiCW;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ptry->m_auiSelectors[uiPixel] = auiPixelSelectors[uiPixel];
+ }
+ ptry->m_fError = fCWError;
+ }
+
+ }
+
+ if (ptry->m_fError < fBestTryError)
+ {
+ a_phalf->m_ptryBest = ptry;
+ fBestTryError = ptry->m_fError;
+ }
+
+ assert(ptry->m_fError < FLT_MAX);
+
+ a_phalf->m_uiTrys++;
+ }
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try an ETC1 individual mode encoding
+ // use a_boolFlip to set the encoding F bit
+ // use a_uiRadius to alter basecolor components in the range[-a_uiRadius:a_uiRadius]
+ // replace the encoding if the encoding error is less than previous encoding
+ //
+ void Block4x4Encoding_ETC1::TryIndividual(bool a_boolFlip, unsigned int a_uiRadius)
+ {
+
+ ColorFloatRGBA frgbaColor1;
+ ColorFloatRGBA frgbaColor2;
+
+ const unsigned int *pauiPixelMapping1;
+ const unsigned int *pauiPixelMapping2;
+
+ if (a_boolFlip)
+ {
+ frgbaColor1 = m_frgbaSourceAverageTop;
+ frgbaColor2 = m_frgbaSourceAverageBottom;
+
+ pauiPixelMapping1 = s_auiTopPixelMapping;
+ pauiPixelMapping2 = s_auiBottomPixelMapping;
+ }
+ else
+ {
+ frgbaColor1 = m_frgbaSourceAverageLeft;
+ frgbaColor2 = m_frgbaSourceAverageRight;
+
+ pauiPixelMapping1 = s_auiLeftPixelMapping;
+ pauiPixelMapping2 = s_auiRightPixelMapping;
+ }
+
+ IndividualTrys trys(frgbaColor1, frgbaColor2, pauiPixelMapping1, pauiPixelMapping2, a_uiRadius);
+
+ Block4x4Encoding_ETC1 encodingTry = *this;
+ encodingTry.m_boolFlip = a_boolFlip;
+
+ encodingTry.TryIndividualHalf(&trys.m_half1);
+ encodingTry.TryIndividualHalf(&trys.m_half2);
+
+ // use the best of each half
+ IndividualTrys::Try *ptryBest1 = trys.m_half1.m_ptryBest;
+ IndividualTrys::Try *ptryBest2 = trys.m_half2.m_ptryBest;
+ encodingTry.m_fError = trys.m_half1.m_ptryBest->m_fError + trys.m_half2.m_ptryBest->m_fError;
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_ETC1;
+ m_boolDiff = false;
+ m_boolFlip = encodingTry.m_boolFlip;
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)ptryBest1->m_iRed, (unsigned char)ptryBest1->m_iGreen, (unsigned char)ptryBest1->m_iBlue);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)ptryBest2->m_iRed, (unsigned char)ptryBest2->m_iGreen, (unsigned char)ptryBest2->m_iBlue);
+ m_uiCW1 = ptryBest1->m_uiCW;
+ m_uiCW2 = ptryBest2->m_uiCW;
+
+ for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS / 2; uiPixelOrder++)
+ {
+ unsigned int uiPixel1 = pauiPixelMapping1[uiPixelOrder];
+ unsigned int uiPixel2 = pauiPixelMapping2[uiPixelOrder];
+
+ unsigned int uiSelector1 = ptryBest1->m_auiSelectors[uiPixelOrder];
+ unsigned int uiSelector2 = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ m_auiSelectors[uiPixel1] = uiSelector1;
+ m_auiSelectors[uiPixel2] = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ float fDeltaRGB1 = s_aafCwTable[m_uiCW1][uiSelector1];
+ float fDeltaRGB2 = s_aafCwTable[m_uiCW2][uiSelector2];
+
+ m_afrgbaDecodedColors[uiPixel1] = (m_frgbaColor1 + fDeltaRGB1).ClampRGB();
+ m_afrgbaDecodedColors[uiPixel2] = (m_frgbaColor2 + fDeltaRGB2).ClampRGB();
+ }
+
+ m_fError1 = ptryBest1->m_fError;
+ m_fError2 = ptryBest2->m_fError;
+ m_fError = m_fError1 + m_fError2;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try an ETC1 differential mode encoding for a half of a 4x4 block
+ // vary the basecolor components using a radius
+ //
+ void Block4x4Encoding_ETC1::TryIndividualHalf(IndividualTrys::Half *a_phalf)
+ {
+
+ a_phalf->m_ptryBest = nullptr;
+ float fBestTryError = FLT_MAX;
+
+ a_phalf->m_uiTrys = 0;
+ for (int iRed = a_phalf->m_iRed - (int)a_phalf->m_uiRadius;
+ iRed <= a_phalf->m_iRed + (int)a_phalf->m_uiRadius;
+ iRed++)
+ {
+ assert(iRed >= 0 && iRed <= 15);
+
+ for (int iGreen = a_phalf->m_iGreen - (int)a_phalf->m_uiRadius;
+ iGreen <= a_phalf->m_iGreen + (int)a_phalf->m_uiRadius;
+ iGreen++)
+ {
+ assert(iGreen >= 0 && iGreen <= 15);
+
+ for (int iBlue = a_phalf->m_iBlue - (int)a_phalf->m_uiRadius;
+ iBlue <= a_phalf->m_iBlue + (int)a_phalf->m_uiRadius;
+ iBlue++)
+ {
+ assert(iBlue >= 0 && iBlue <= 15);
+
+ IndividualTrys::Try *ptry = &a_phalf->m_atry[a_phalf->m_uiTrys];
+ assert(ptry < &a_phalf->m_atry[IndividualTrys::Half::MAX_TRYS]);
+
+ ptry->m_iRed = iRed;
+ ptry->m_iGreen = iGreen;
+ ptry->m_iBlue = iBlue;
+ ptry->m_fError = FLT_MAX;
+ ColorFloatRGBA frgbaColor = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed, (unsigned char)iGreen, (unsigned char)iBlue);
+
+ // try each CW
+ for (unsigned int uiCW = 0; uiCW < CW_RANGES; uiCW++)
+ {
+ unsigned int auiPixelSelectors[PIXELS / 2];
+ ColorFloatRGBA afrgbaDecodedPixels[PIXELS / 2];
+ float afPixelErrors[PIXELS / 2] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+
+ // pre-compute decoded pixels for each selector
+ ColorFloatRGBA afrgbaSelectors[SELECTORS];
+ assert(SELECTORS == 4);
+ afrgbaSelectors[0] = (frgbaColor + s_aafCwTable[uiCW][0]).ClampRGB();
+ afrgbaSelectors[1] = (frgbaColor + s_aafCwTable[uiCW][1]).ClampRGB();
+ afrgbaSelectors[2] = (frgbaColor + s_aafCwTable[uiCW][2]).ClampRGB();
+ afrgbaSelectors[3] = (frgbaColor + s_aafCwTable[uiCW][3]).ClampRGB();
+
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ColorFloatRGBA *pfrgbaSourcePixel = &m_pafrgbaSource[a_phalf->m_pauiPixelMapping[uiPixel]];
+ ColorFloatRGBA frgbaDecodedPixel;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ frgbaDecodedPixel = afrgbaSelectors[uiSelector];
+
+ float fPixelError;
+
+ fPixelError = CalcPixelError(frgbaDecodedPixel, m_afDecodedAlphas[a_phalf->m_pauiPixelMapping[uiPixel]],
+ *pfrgbaSourcePixel);
+
+ if (fPixelError < afPixelErrors[uiPixel])
+ {
+ auiPixelSelectors[uiPixel] = uiSelector;
+ afrgbaDecodedPixels[uiPixel] = frgbaDecodedPixel;
+ afPixelErrors[uiPixel] = fPixelError;
+ }
+
+ }
+ }
+
+ // add up all pixel errors
+ float fCWError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ fCWError += afPixelErrors[uiPixel];
+ }
+
+ // if best CW so far
+ if (fCWError < ptry->m_fError)
+ {
+ ptry->m_uiCW = uiCW;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ptry->m_auiSelectors[uiPixel] = auiPixelSelectors[uiPixel];
+ }
+ ptry->m_fError = fCWError;
+ }
+
+ }
+
+ if (ptry->m_fError < fBestTryError)
+ {
+ a_phalf->m_ptryBest = ptry;
+ fBestTryError = ptry->m_fError;
+ }
+
+ assert(ptry->m_fError < FLT_MAX);
+
+ a_phalf->m_uiTrys++;
+ }
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 1 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_ETC1::TryDegenerates1(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, -2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 2 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_ETC1::TryDegenerates2(void)
+ {
+
+ TryDifferential(!m_boolMostLikelyFlip, 1, -2, 0);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 2, 0);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, 2);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, -2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 3 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_ETC1::TryDegenerates3(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, -2);
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, 2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, -2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, 2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 4 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_ETC1::TryDegenerates4(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -4, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 4, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 4);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, -4);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find the best selector for each pixel based on a particular basecolor and CW that have been previously set
+ // calculate the selectors for each half of the block separately
+ // set the block error as the sum of each half's error
+ //
+ void Block4x4Encoding_ETC1::CalculateSelectors()
+ {
+ if (m_boolFlip)
+ {
+ CalculateHalfOfTheSelectors(0, s_auiTopPixelMapping);
+ CalculateHalfOfTheSelectors(1, s_auiBottomPixelMapping);
+ }
+ else
+ {
+ CalculateHalfOfTheSelectors(0, s_auiLeftPixelMapping);
+ CalculateHalfOfTheSelectors(1, s_auiRightPixelMapping);
+ }
+
+ m_fError = m_fError1 + m_fError2;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // choose best selectors for half of the block
+ // calculate the error for half of the block
+ //
+ void Block4x4Encoding_ETC1::CalculateHalfOfTheSelectors(unsigned int a_uiHalf,
+ const unsigned int *pauiPixelMapping)
+ {
+ static const bool DEBUG_PRINT = false;
+
+ ColorFloatRGBA *pfrgbaColor = a_uiHalf ? &m_frgbaColor2 : &m_frgbaColor1;
+ unsigned int *puiCW = a_uiHalf ? &m_uiCW2 : &m_uiCW1;
+
+ float *pfHalfError = a_uiHalf ? &m_fError2 : &m_fError1;
+ *pfHalfError = FLT_MAX;
+
+ // try each CW
+ for (unsigned int uiCW = 0; uiCW < CW_RANGES; uiCW++)
+ {
+ if (DEBUG_PRINT)
+ {
+ printf("\ncw=%u\n", uiCW);
+ }
+
+ unsigned int auiPixelSelectors[PIXELS / 2];
+ ColorFloatRGBA afrgbaDecodedPixels[PIXELS / 2];
+ float afPixelErrors[PIXELS / 2] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ if (DEBUG_PRINT)
+ {
+ printf("\tsource [%.2f,%.2f,%.2f]\n", m_pafrgbaSource[pauiPixelMapping[uiPixel]].fR,
+ m_pafrgbaSource[pauiPixelMapping[uiPixel]].fG, m_pafrgbaSource[pauiPixelMapping[uiPixel]].fB);
+ }
+
+ ColorFloatRGBA *pfrgbaSourcePixel = &m_pafrgbaSource[pauiPixelMapping[uiPixel]];
+ ColorFloatRGBA frgbaDecodedPixel;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ float fDeltaRGB = s_aafCwTable[uiCW][uiSelector];
+
+ frgbaDecodedPixel = (*pfrgbaColor + fDeltaRGB).ClampRGB();
+
+ float fPixelError;
+
+ fPixelError = CalcPixelError(frgbaDecodedPixel, m_afDecodedAlphas[pauiPixelMapping[uiPixel]],
+ *pfrgbaSourcePixel);
+
+ if (DEBUG_PRINT)
+ {
+ printf("\tpixel %u, index %u [%.2f,%.2f,%.2f], error %.2f", uiPixel, uiSelector,
+ frgbaDecodedPixel.fR,
+ frgbaDecodedPixel.fG,
+ frgbaDecodedPixel.fB,
+ fPixelError);
+ }
+
+ if (fPixelError < afPixelErrors[uiPixel])
+ {
+ if (DEBUG_PRINT)
+ {
+ printf(" *");
+ }
+
+ auiPixelSelectors[uiPixel] = uiSelector;
+ afrgbaDecodedPixels[uiPixel] = frgbaDecodedPixel;
+ afPixelErrors[uiPixel] = fPixelError;
+ }
+
+ if (DEBUG_PRINT)
+ {
+ printf("\n");
+ }
+ }
+ }
+
+ // add up all pixel errors
+ float fCWError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ fCWError += afPixelErrors[uiPixel];
+ }
+ if (DEBUG_PRINT)
+ {
+ printf("\terror %.2f\n", fCWError);
+ }
+
+ // if best CW so far
+ if (fCWError < *pfHalfError)
+ {
+ *pfHalfError = fCWError;
+ *puiCW = uiCW;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ m_auiSelectors[pauiPixelMapping[uiPixel]] = auiPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[pauiPixelMapping[uiPixel]] = afrgbaDecodedPixels[uiPixel];
+ }
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_ETC1::SetEncodingBits(void)
+ {
+ assert(m_mode == MODE_ETC1);
+
+ if (m_boolDiff)
+ {
+ int iRed1 = m_frgbaColor1.IntRed(31.0f);
+ int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
+ int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
+
+ int iRed2 = m_frgbaColor2.IntRed(31.0f);
+ int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
+ int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
+
+ int iDRed2 = iRed2 - iRed1;
+ int iDGreen2 = iGreen2 - iGreen1;
+ int iDBlue2 = iBlue2 - iBlue1;
+
+ assert(iDRed2 >= -4 && iDRed2 < 4);
+ assert(iDGreen2 >= -4 && iDGreen2 < 4);
+ assert(iDBlue2 >= -4 && iDBlue2 < 4);
+
+ m_pencodingbitsRGB8->differential.red1 = (unsigned int)iRed1;
+ m_pencodingbitsRGB8->differential.green1 = (unsigned int)iGreen1;
+ m_pencodingbitsRGB8->differential.blue1 = (unsigned int)iBlue1;
+
+ m_pencodingbitsRGB8->differential.dred2 = iDRed2;
+ m_pencodingbitsRGB8->differential.dgreen2 = iDGreen2;
+ m_pencodingbitsRGB8->differential.dblue2 = iDBlue2;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->individual.red1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ m_pencodingbitsRGB8->individual.green1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ m_pencodingbitsRGB8->individual.blue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+
+ m_pencodingbitsRGB8->individual.red2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ m_pencodingbitsRGB8->individual.green2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ m_pencodingbitsRGB8->individual.blue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+ }
+
+ m_pencodingbitsRGB8->individual.cw1 = m_uiCW1;
+ m_pencodingbitsRGB8->individual.cw2 = m_uiCW2;
+
+ SetEncodingBits_Selectors();
+
+ m_pencodingbitsRGB8->individual.diff = (unsigned int)m_boolDiff;
+ m_pencodingbitsRGB8->individual.flip = (unsigned int)m_boolFlip;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the selectors in the encoding bits
+ //
+ void Block4x4Encoding_ETC1::SetEncodingBits_Selectors(void)
+ {
+
+ m_pencodingbitsRGB8->individual.selectors = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiSelector = m_auiSelectors[uiPixel];
+
+ // set index msb
+ m_pencodingbitsRGB8->individual.selectors |= (uiSelector >> 1) << (uiPixel ^ 8);
+
+ // set index lsb
+ m_pencodingbitsRGB8->individual.selectors |= (uiSelector & 1) << ((16 + uiPixel) ^ 8);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state
+ //
+ void Block4x4Encoding_ETC1::Decode(void)
+ {
+
+ const unsigned int *pauiPixelOrder = m_boolFlip ? s_auiPixelOrderFlip1 : s_auiPixelOrderFlip0;
+
+ for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS; uiPixelOrder++)
+ {
+ ColorFloatRGBA *pfrgbaCenter = uiPixelOrder < 8 ? &m_frgbaColor1 : &m_frgbaColor2;
+ unsigned int uiCW = uiPixelOrder < 8 ? m_uiCW1 : m_uiCW2;
+
+ unsigned int uiPixel = pauiPixelOrder[uiPixelOrder];
+
+ float fDelta = s_aafCwTable[uiCW][m_auiSelectors[uiPixel]];
+ m_afrgbaDecodedColors[uiPixel] = (*pfrgbaCenter + fDelta).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.h
new file mode 100644
index 0000000000..c0dc84d5d5
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_ETC1.h
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding.h"
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcDifferentialTrys.h"
+#include "EtcIndividualTrys.h"
+
+namespace Etc
+{
+
+ // base class for Block4x4Encoding_RGB8
+ class Block4x4Encoding_ETC1 : public Block4x4Encoding
+ {
+ public:
+
+ Block4x4Encoding_ETC1(void);
+ virtual ~Block4x4Encoding_ETC1(void);
+
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ unsigned char *a_paucEncodingBits,
+ ErrorMetric a_errormetric);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ inline virtual bool GetFlip(void)
+ {
+ return m_boolFlip;
+ }
+
+ inline virtual bool IsDifferential(void)
+ {
+ return m_boolDiff;
+ }
+
+ virtual void SetEncodingBits(void);
+
+ void Decode(void);
+
+ inline ColorFloatRGBA GetColor1(void) const
+ {
+ return m_frgbaColor1;
+ }
+
+ inline ColorFloatRGBA GetColor2(void) const
+ {
+ return m_frgbaColor2;
+ }
+
+ inline const unsigned int * GetSelectors(void) const
+ {
+ return m_auiSelectors;
+ }
+
+ inline unsigned int GetCW1(void) const
+ {
+ return m_uiCW1;
+ }
+
+ inline unsigned int GetCW2(void) const
+ {
+ return m_uiCW2;
+ }
+
+ inline bool HasSeverelyBentDifferentialColors(void) const
+ {
+ return m_boolSeverelyBentDifferentialColors;
+ }
+
+ protected:
+
+ static const unsigned int s_auiPixelOrderFlip0[PIXELS];
+ static const unsigned int s_auiPixelOrderFlip1[PIXELS];
+ static const unsigned int s_auiPixelOrderHScan[PIXELS];
+
+ static const unsigned int s_auiLeftPixelMapping[8];
+ static const unsigned int s_auiRightPixelMapping[8];
+ static const unsigned int s_auiTopPixelMapping[8];
+ static const unsigned int s_auiBottomPixelMapping[8];
+
+ static const unsigned int SELECTOR_BITS = 2;
+ static const unsigned int SELECTORS = 1 << SELECTOR_BITS;
+
+ static const unsigned int CW_BITS = 3;
+ static const unsigned int CW_RANGES = 1 << CW_BITS;
+
+ static float s_aafCwTable[CW_RANGES][SELECTORS];
+ static unsigned char s_aucDifferentialCwRange[256];
+
+ static const int MAX_DIFFERENTIAL = 3;
+ static const int MIN_DIFFERENTIAL = -4;
+
+ void InitFromEncodingBits_Selectors(void);
+
+ void PerformFirstIteration(void);
+ void CalculateMostLikelyFlip(void);
+
+ void TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2);
+ void TryDifferentialHalf(DifferentialTrys::Half *a_phalf);
+
+ void TryIndividual(bool a_boolFlip, unsigned int a_uiRadius);
+ void TryIndividualHalf(IndividualTrys::Half *a_phalf);
+
+ void TryDegenerates1(void);
+ void TryDegenerates2(void);
+ void TryDegenerates3(void);
+ void TryDegenerates4(void);
+
+ void CalculateSelectors();
+ void CalculateHalfOfTheSelectors(unsigned int a_uiHalf,
+ const unsigned int *pauiPixelMapping);
+
+ // calculate the distance2 of r_frgbaPixel from r_frgbaTarget's gray line
+ inline float CalcGrayDistance2(ColorFloatRGBA &r_frgbaPixel,
+ ColorFloatRGBA &r_frgbaTarget)
+ {
+ float fDeltaGray = ((r_frgbaPixel.fR - r_frgbaTarget.fR) +
+ (r_frgbaPixel.fG - r_frgbaTarget.fG) +
+ (r_frgbaPixel.fB - r_frgbaTarget.fB)) / 3.0f;
+
+ ColorFloatRGBA frgbaPointOnGrayLine = (r_frgbaTarget + fDeltaGray).ClampRGB();
+
+ float fDR = r_frgbaPixel.fR - frgbaPointOnGrayLine.fR;
+ float fDG = r_frgbaPixel.fG - frgbaPointOnGrayLine.fG;
+ float fDB = r_frgbaPixel.fB - frgbaPointOnGrayLine.fB;
+
+ return (fDR*fDR) + (fDG*fDG) + (fDB*fDB);
+ }
+
+ void SetEncodingBits_Selectors(void);
+
+ // intermediate encoding
+ bool m_boolDiff;
+ bool m_boolFlip;
+ ColorFloatRGBA m_frgbaColor1;
+ ColorFloatRGBA m_frgbaColor2;
+ unsigned int m_uiCW1;
+ unsigned int m_uiCW2;
+ unsigned int m_auiSelectors[PIXELS];
+
+ // state shared between iterations
+ ColorFloatRGBA m_frgbaSourceAverageLeft;
+ ColorFloatRGBA m_frgbaSourceAverageRight;
+ ColorFloatRGBA m_frgbaSourceAverageTop;
+ ColorFloatRGBA m_frgbaSourceAverageBottom;
+ bool m_boolMostLikelyFlip;
+
+ // stats
+ float m_fError1; // error for Etc1 half 1
+ float m_fError2; // error for Etc1 half 2
+ bool m_boolSeverelyBentDifferentialColors; // only valid if m_boolDiff;
+
+ // final encoding
+ Block4x4EncodingBits_RGB8 *m_pencodingbitsRGB8; // or RGB8 portion of Block4x4EncodingBits_RGB8A8
+
+ private:
+
+ void CalculateSourceAverages(void);
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.cpp
new file mode 100644
index 0000000000..4c012fbbf1
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.cpp
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_R11.cpp
+
+Block4x4Encoding_R11 is the encoder to use when targetting file format R11 and SR11 (signed R11).
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_R11.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <limits>
+
+namespace Etc
+{
+
+ // modifier values to use for R11, SR11, RG11 and SRG11
+ float Block4x4Encoding_R11::s_aafModifierTable[MODIFIER_TABLE_ENTRYS][SELECTORS]
+ {
+ { -3.0f / 255.0f, -6.0f / 255.0f, -9.0f / 255.0f, -15.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 8.0f / 255.0f, 14.0f / 255.0f },
+ { -3.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, -13.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f, 12.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 12.0f / 255.0f },
+ { -2.0f / 255.0f, -4.0f / 255.0f, -6.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 12.0f / 255.0f },
+
+ { -3.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -12.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 11.0f / 255.0f },
+ { -3.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f, 10.0f / 255.0f },
+ { -4.0f / 255.0f, -7.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
+ { -3.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
+
+ { -2.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -4.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
+
+ { -3.0f / 255.0f, -4.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
+ { -1.0f / 255.0f, -2.0f / 255.0f, -3.0f / 255.0f, -10.0f / 255.0f, 0.0f / 255.0f, 1.0f / 255.0f, 2.0f / 255.0f, 9.0f / 255.0f },
+ { -4.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -9.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 8.0f / 255.0f },
+ { -3.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f }
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_R11::Block4x4Encoding_R11(void)
+ {
+
+ m_pencodingbitsR11 = nullptr;
+
+ }
+
+ Block4x4Encoding_R11::~Block4x4Encoding_R11(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits
+ //
+ void Block4x4Encoding_R11::InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
+ {
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
+
+ m_pencodingbitsR11 = (Block4x4EncodingBits_R11 *)a_paucEncodingBits;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_R11::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+ m_pencodingbitsR11 = (Block4x4EncodingBits_R11 *)a_paucEncodingBits;
+
+ // init RGB portion
+ Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
+ (unsigned char *)m_pencodingbitsR11,
+ a_pafrgbaSource,
+ a_errormetric);
+
+ // init R11 portion
+ {
+ m_mode = MODE_R11;
+ if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_fRedBase = (float)(signed char)m_pencodingbitsR11->data.base;
+ }
+ else
+ {
+ m_fRedBase = (float)(unsigned char)m_pencodingbitsR11->data.base;
+ }
+ m_fRedMultiplier = (float)m_pencodingbitsR11->data.multiplier;
+ m_uiRedModifierTableIndex = m_pencodingbitsR11->data.table;
+
+ unsigned long long int ulliSelectorBits = 0;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors0 << 40;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors1 << 32;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors2 << 24;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors3 << 16;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors4 << 8;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsR11->data.selectors5;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ m_auiRedSelectors[uiPixel] = (ulliSelectorBits >> uiShift) & (SELECTORS - 1);
+ }
+
+ // decode the red channel
+ // calc red error
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fDecodedPixelData = 0.0f;
+ if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ fDecodedPixelData = DecodePixelRed(m_fRedBase, m_fRedMultiplier,
+ m_uiRedModifierTableIndex,
+ m_auiRedSelectors[uiPixel]);
+ }
+ else if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ fDecodedPixelData = DecodePixelRed(m_fRedBase + 128, m_fRedMultiplier,
+ m_uiRedModifierTableIndex,
+ m_auiRedSelectors[uiPixel]);
+ }
+ else
+ {
+ assert(0);
+ }
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fDecodedPixelData, 0.0f, 0.0f, 1.0f);
+ }
+ CalcBlockError();
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_R11::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+ m_mode = MODE_R11;
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ m_fError = FLT_MAX;
+ m_fRedBlockError = FLT_MAX; // artificially high value
+ CalculateR11(8, 0.0f, 0.0f);
+ m_fError = m_fRedBlockError;
+ break;
+
+ case 1:
+ CalculateR11(8, 2.0f, 1.0f);
+ m_fError = m_fRedBlockError;
+ if (a_fEffort <= 24.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 2:
+ CalculateR11(8, 12.0f, 1.0f);
+ m_fError = m_fRedBlockError;
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 3:
+ CalculateR11(7, 6.0f, 1.0f);
+ m_fError = m_fRedBlockError;
+ break;
+
+ case 4:
+ CalculateR11(6, 3.0f, 1.0f);
+ m_fError = m_fRedBlockError;
+ break;
+
+ case 5:
+ CalculateR11(5, 1.0f, 0.0f);
+ m_fError = m_fRedBlockError;
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+ SetDoneIfPerfect();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find the best combination of base color, multiplier and selectors
+ //
+ // a_uiSelectorsUsed limits the number of selector combinations to try
+ // a_fBaseRadius limits the range of base colors to try
+ // a_fMultiplierRadius limits the range of multipliers to try
+ //
+ void Block4x4Encoding_R11::CalculateR11(unsigned int a_uiSelectorsUsed,
+ float a_fBaseRadius, float a_fMultiplierRadius)
+ {
+ // maps from virtual (monotonic) selector to ETC selector
+ static const unsigned int auiVirtualSelectorMap[8] = {3, 2, 1, 0, 4, 5, 6, 7};
+
+ // find min/max red
+ float fMinRed = 1.0f;
+ float fMaxRed = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // ignore border pixels
+ float fAlpha = m_pafrgbaSource[uiPixel].fA;
+ if (isnan(fAlpha))
+ {
+ continue;
+ }
+
+ float fRed = m_pafrgbaSource[uiPixel].fR;
+
+ if (fRed < fMinRed)
+ {
+ fMinRed = fRed;
+ }
+ if (fRed > fMaxRed)
+ {
+ fMaxRed = fRed;
+ }
+ }
+ assert(fMinRed <= fMaxRed);
+
+ float fRedRange = (fMaxRed - fMinRed);
+
+ // try each modifier table entry
+ for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
+ {
+ for (unsigned int uiMinVirtualSelector = 0;
+ uiMinVirtualSelector <= (8- a_uiSelectorsUsed);
+ uiMinVirtualSelector++)
+ {
+ unsigned int uiMaxVirtualSelector = uiMinVirtualSelector + a_uiSelectorsUsed - 1;
+
+ unsigned int uiMinSelector = auiVirtualSelectorMap[uiMinVirtualSelector];
+ unsigned int uiMaxSelector = auiVirtualSelectorMap[uiMaxVirtualSelector];
+
+ float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][uiMinSelector];
+
+ float fTableEntryRange = s_aafModifierTable[uiTableEntry][uiMaxSelector] -
+ s_aafModifierTable[uiTableEntry][uiMinSelector];
+
+ float fCenterRatio = fTableEntryCenter / fTableEntryRange;
+
+ float fCenter = fMinRed + fCenterRatio*fRedRange;
+ fCenter = roundf(255.0f * fCenter) / 255.0f;
+
+ float fMinBase = fCenter - (a_fBaseRadius / 255.0f);
+ if (fMinBase < 0.0f)
+ {
+ fMinBase = 0.0f;
+ }
+
+ float fMaxBase = fCenter + (a_fBaseRadius / 255.0f);
+ if (fMaxBase > 1.0f)
+ {
+ fMaxBase = 1.0f;
+ }
+
+ for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
+ {
+ float fRangeMultiplier = roundf(fRedRange / fTableEntryRange);
+
+ float fMinMultiplier = fRangeMultiplier - a_fMultiplierRadius;
+ if (fMinMultiplier < 1.0f)
+ {
+ fMinMultiplier = 0.0f;
+ }
+ else if (fMinMultiplier > 15.0f)
+ {
+ fMinMultiplier = 15.0f;
+ }
+
+ float fMaxMultiplier = fRangeMultiplier + a_fMultiplierRadius;
+ if (fMaxMultiplier < 1.0f)
+ {
+ fMaxMultiplier = 1.0f;
+ }
+ else if (fMaxMultiplier > 15.0f)
+ {
+ fMaxMultiplier = 15.0f;
+ }
+
+ for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
+ {
+ // find best selector for each pixel
+ unsigned int auiBestSelectors[PIXELS];
+ float afBestRedError[PIXELS];
+ float afBestPixelRed[PIXELS];
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fBestPixelRedError = FLT_MAX;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ float fPixelRed = DecodePixelRed(fBase * 255.0f, fMultiplier, uiTableEntry, uiSelector);
+
+ ColorFloatRGBA frgba(fPixelRed, m_pafrgbaSource[uiPixel].fG,0.0f,1.0f);
+
+ float fPixelRedError = CalcPixelError(frgba, 1.0f, m_pafrgbaSource[uiPixel]);
+
+ if (fPixelRedError < fBestPixelRedError)
+ {
+ fBestPixelRedError = fPixelRedError;
+ auiBestSelectors[uiPixel] = uiSelector;
+ afBestRedError[uiPixel] = fBestPixelRedError;
+ afBestPixelRed[uiPixel] = fPixelRed;
+ }
+ }
+ }
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestRedError[uiPixel];
+ }
+ if (fBlockError < m_fRedBlockError)
+ {
+ m_fRedBlockError = fBlockError;
+
+ if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ m_fRedBase = 255.0f * fBase;
+ }
+ else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_fRedBase = (fBase * 255) - 128;
+ }
+ else
+ {
+ assert(0);
+ }
+ m_fRedMultiplier = fMultiplier;
+ m_uiRedModifierTableIndex = uiTableEntry;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiRedSelectors[uiPixel] = auiBestSelectors[uiPixel];
+ float fBestPixelRed = afBestPixelRed[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fBestPixelRed, 0.0f, 0.0f, 1.0f);
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_R11::SetEncodingBits(void)
+ {
+ if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ m_pencodingbitsR11->data.base = (unsigned char)roundf(m_fRedBase);
+ }
+ else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_R11 || m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_pencodingbitsR11->data.base = (signed char)roundf(m_fRedBase);
+ }
+ else
+ {
+ assert(0);
+ }
+ m_pencodingbitsR11->data.table = m_uiRedModifierTableIndex;
+ m_pencodingbitsR11->data.multiplier = (unsigned char)roundf(m_fRedMultiplier);
+
+ unsigned long long int ulliSelectorBits = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ ulliSelectorBits |= ((unsigned long long int)m_auiRedSelectors[uiPixel]) << uiShift;
+ }
+
+ m_pencodingbitsR11->data.selectors0 = ulliSelectorBits >> 40;
+ m_pencodingbitsR11->data.selectors1 = ulliSelectorBits >> 32;
+ m_pencodingbitsR11->data.selectors2 = ulliSelectorBits >> 24;
+ m_pencodingbitsR11->data.selectors3 = ulliSelectorBits >> 16;
+ m_pencodingbitsR11->data.selectors4 = ulliSelectorBits >> 8;
+ m_pencodingbitsR11->data.selectors5 = ulliSelectorBits;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.h
new file mode 100644
index 0000000000..b40c1e0036
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_R11.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding_RGB8.h"
+
+namespace Etc
+{
+ class Block4x4EncodingBits_R11;
+
+ // ################################################################################
+ // Block4x4Encoding_R11
+ // ################################################################################
+
+ class Block4x4Encoding_R11 : public Block4x4Encoding_RGB8
+ {
+ public:
+
+ Block4x4Encoding_R11(void);
+ virtual ~Block4x4Encoding_R11(void);
+
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ inline float GetRedBase(void) const
+ {
+ return m_fRedBase;
+ }
+
+ inline float GetRedMultiplier(void) const
+ {
+ return m_fRedMultiplier;
+ }
+
+ inline int GetRedTableIndex(void) const
+ {
+ return m_uiRedModifierTableIndex;
+ }
+
+ inline const unsigned int * GetRedSelectors(void) const
+ {
+ return m_auiRedSelectors;
+ }
+
+ protected:
+
+ static const unsigned int MODIFIER_TABLE_ENTRYS = 16;
+ static const unsigned int SELECTOR_BITS = 3;
+ static const unsigned int SELECTORS = 1 << SELECTOR_BITS;
+
+ static float s_aafModifierTable[MODIFIER_TABLE_ENTRYS][SELECTORS];
+
+ void CalculateR11(unsigned int a_uiSelectorsUsed,
+ float a_fBaseRadius, float a_fMultiplierRadius);
+
+
+
+
+ inline float DecodePixelRed(float a_fBase, float a_fMultiplier,
+ unsigned int a_uiTableIndex, unsigned int a_uiSelector)
+ {
+ float fMultiplier = a_fMultiplier;
+ if (fMultiplier <= 0.0f)
+ {
+ fMultiplier = 1.0f / 8.0f;
+ }
+
+ float fPixelRed = a_fBase * 8 + 4 +
+ 8 * fMultiplier*s_aafModifierTable[a_uiTableIndex][a_uiSelector]*255;
+ fPixelRed /= 2047.0f;
+
+ if (fPixelRed < 0.0f)
+ {
+ fPixelRed = 0.0f;
+ }
+ else if (fPixelRed > 1.0f)
+ {
+ fPixelRed = 1.0f;
+ }
+
+ return fPixelRed;
+ }
+
+ Block4x4EncodingBits_R11 *m_pencodingbitsR11;
+
+ float m_fRedBase;
+ float m_fRedMultiplier;
+ float m_fRedBlockError;
+ unsigned int m_uiRedModifierTableIndex;
+ unsigned int m_auiRedSelectors[PIXELS];
+
+
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.cpp
new file mode 100644
index 0000000000..417835db51
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.cpp
@@ -0,0 +1,447 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_RG11.cpp
+
+Block4x4Encoding_RG11 is the encoder to use when targetting file format RG11 and SRG11 (signed RG11).
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_RG11.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <limits>
+
+namespace Etc
+{
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_RG11::Block4x4Encoding_RG11(void)
+ {
+ m_pencodingbitsRG11 = nullptr;
+ }
+
+ Block4x4Encoding_RG11::~Block4x4Encoding_RG11(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits
+ //
+ void Block4x4Encoding_RG11::InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
+ {
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
+
+ m_pencodingbitsRG11 = (Block4x4EncodingBits_RG11 *)a_paucEncodingBits;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_RG11::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ m_pencodingbitsRG11 = (Block4x4EncodingBits_RG11 *)a_paucEncodingBits;
+
+ // init RGB portion
+ Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
+ (unsigned char *)m_pencodingbitsRG11,
+ a_pafrgbaSource,
+ a_errormetric);
+ m_fError = 0.0f;
+
+ {
+ m_mode = MODE_RG11;
+ if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_fRedBase = (float)(signed char)m_pencodingbitsRG11->data.baseR;
+ m_fGrnBase = (float)(signed char)m_pencodingbitsRG11->data.baseG;
+ }
+ else
+ {
+ m_fRedBase = (float)(unsigned char)m_pencodingbitsRG11->data.baseR;
+ m_fGrnBase = (float)(unsigned char)m_pencodingbitsRG11->data.baseG;
+ }
+ m_fRedMultiplier = (float)m_pencodingbitsRG11->data.multiplierR;
+ m_fGrnMultiplier = (float)m_pencodingbitsRG11->data.multiplierG;
+ m_uiRedModifierTableIndex = m_pencodingbitsRG11->data.tableIndexR;
+ m_uiGrnModifierTableIndex = m_pencodingbitsRG11->data.tableIndexG;
+
+ unsigned long long int ulliSelectorBitsR = 0;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR0 << 40;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR1 << 32;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR2 << 24;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR3 << 16;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR4 << 8;
+ ulliSelectorBitsR |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsR5;
+
+ unsigned long long int ulliSelectorBitsG = 0;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG0 << 40;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG1 << 32;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG2 << 24;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG3 << 16;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG4 << 8;
+ ulliSelectorBitsG |= (unsigned long long int)m_pencodingbitsRG11->data.selectorsG5;
+
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ m_auiRedSelectors[uiPixel] = (ulliSelectorBitsR >> uiShift) & (SELECTORS - 1);
+ m_auiGrnSelectors[uiPixel] = (ulliSelectorBitsG >> uiShift) & (SELECTORS - 1);
+ }
+
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fRedDecodedData = 0.0f;
+ float fGrnDecodedData = 0.0f;
+ if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ fRedDecodedData = DecodePixelRed(m_fRedBase, m_fRedMultiplier, m_uiRedModifierTableIndex, m_auiRedSelectors[uiPixel]);
+ fGrnDecodedData = DecodePixelRed(m_fGrnBase, m_fGrnMultiplier, m_uiGrnModifierTableIndex, m_auiGrnSelectors[uiPixel]);
+ }
+ else if (a_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ fRedDecodedData = DecodePixelRed(m_fRedBase + 128, m_fRedMultiplier, m_uiRedModifierTableIndex, m_auiRedSelectors[uiPixel]);
+ fGrnDecodedData = DecodePixelRed(m_fGrnBase + 128, m_fGrnMultiplier, m_uiGrnModifierTableIndex, m_auiGrnSelectors[uiPixel]);
+ }
+ else
+ {
+ assert(0);
+ }
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA(fRedDecodedData, fGrnDecodedData, 0.0f, 1.0f);
+ }
+
+ }
+
+ CalcBlockError();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RG11::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ m_fError = FLT_MAX;
+ m_fGrnBlockError = FLT_MAX; // artificially high value
+ m_fRedBlockError = FLT_MAX;
+ CalculateR11(8, 0.0f, 0.0f);
+ CalculateG11(8, 0.0f, 0.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ break;
+
+ case 1:
+ CalculateR11(8, 2.0f, 1.0f);
+ CalculateG11(8, 2.0f, 1.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ if (a_fEffort <= 24.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 2:
+ CalculateR11(8, 12.0f, 1.0f);
+ CalculateG11(8, 12.0f, 1.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 3:
+ CalculateR11(7, 6.0f, 1.0f);
+ CalculateG11(7, 6.0f, 1.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ break;
+
+ case 4:
+ CalculateR11(6, 3.0f, 1.0f);
+ CalculateG11(6, 3.0f, 1.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ break;
+
+ case 5:
+ CalculateR11(5, 1.0f, 0.0f);
+ CalculateG11(5, 1.0f, 0.0f);
+ m_fError = (m_fGrnBlockError + m_fRedBlockError);
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+ SetDoneIfPerfect();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find the best combination of base color, multiplier and selectors
+ //
+ // a_uiSelectorsUsed limits the number of selector combinations to try
+ // a_fBaseRadius limits the range of base colors to try
+ // a_fMultiplierRadius limits the range of multipliers to try
+ //
+ void Block4x4Encoding_RG11::CalculateG11(unsigned int a_uiSelectorsUsed,
+ float a_fBaseRadius, float a_fMultiplierRadius)
+ {
+ // maps from virtual (monotonic) selector to etc selector
+ static const unsigned int auiVirtualSelectorMap[8] = { 3, 2, 1, 0, 4, 5, 6, 7 };
+
+ // find min/max Grn
+ float fMinGrn = 1.0f;
+ float fMaxGrn = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // ignore border pixels
+ float fAlpha = m_pafrgbaSource[uiPixel].fA;
+ if (isnan(fAlpha))
+ {
+ continue;
+ }
+
+ float fGrn = m_pafrgbaSource[uiPixel].fG;
+
+ if (fGrn < fMinGrn)
+ {
+ fMinGrn = fGrn;
+ }
+ if (fGrn > fMaxGrn)
+ {
+ fMaxGrn = fGrn;
+ }
+ }
+ assert(fMinGrn <= fMaxGrn);
+
+ float fGrnRange = (fMaxGrn - fMinGrn);
+
+ // try each modifier table entry
+ for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
+ {
+ for (unsigned int uiMinVirtualSelector = 0;
+ uiMinVirtualSelector <= (8 - a_uiSelectorsUsed);
+ uiMinVirtualSelector++)
+ {
+ unsigned int uiMaxVirtualSelector = uiMinVirtualSelector + a_uiSelectorsUsed - 1;
+
+ unsigned int uiMinSelector = auiVirtualSelectorMap[uiMinVirtualSelector];
+ unsigned int uiMaxSelector = auiVirtualSelectorMap[uiMaxVirtualSelector];
+
+ float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][uiMinSelector];
+
+ float fTableEntryRange = s_aafModifierTable[uiTableEntry][uiMaxSelector] -
+ s_aafModifierTable[uiTableEntry][uiMinSelector];
+
+ float fCenterRatio = fTableEntryCenter / fTableEntryRange;
+
+ float fCenter = fMinGrn + fCenterRatio*fGrnRange;
+ fCenter = roundf(255.0f * fCenter) / 255.0f;
+
+ float fMinBase = fCenter - (a_fBaseRadius / 255.0f);
+ if (fMinBase < 0.0f)
+ {
+ fMinBase = 0.0f;
+ }
+
+ float fMaxBase = fCenter + (a_fBaseRadius / 255.0f);
+ if (fMaxBase > 1.0f)
+ {
+ fMaxBase = 1.0f;
+ }
+
+ for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
+ {
+ float fRangeMultiplier = roundf(fGrnRange / fTableEntryRange);
+
+ float fMinMultiplier = fRangeMultiplier - a_fMultiplierRadius;
+ if (fMinMultiplier < 1.0f)
+ {
+ fMinMultiplier = 0.0f;
+ }
+ else if (fMinMultiplier > 15.0f)
+ {
+ fMinMultiplier = 15.0f;
+ }
+
+ float fMaxMultiplier = fRangeMultiplier + a_fMultiplierRadius;
+ if (fMaxMultiplier < 1.0f)
+ {
+ fMaxMultiplier = 1.0f;
+ }
+ else if (fMaxMultiplier > 15.0f)
+ {
+ fMaxMultiplier = 15.0f;
+ }
+
+ for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
+ {
+ // find best selector for each pixel
+ unsigned int auiBestSelectors[PIXELS];
+ float afBestGrnError[PIXELS];
+ float afBestPixelGrn[PIXELS];
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fBestPixelGrnError = FLT_MAX;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ //DecodePixelRed is not red channel specific
+ float fPixelGrn = DecodePixelRed(fBase * 255.0f, fMultiplier, uiTableEntry, uiSelector);
+
+ ColorFloatRGBA frgba(m_pafrgbaSource[uiPixel].fR, fPixelGrn, 0.0f, 1.0f);
+
+ float fPixelGrnError = CalcPixelError(frgba, 1.0f, m_pafrgbaSource[uiPixel]);
+
+ if (fPixelGrnError < fBestPixelGrnError)
+ {
+ fBestPixelGrnError = fPixelGrnError;
+ auiBestSelectors[uiPixel] = uiSelector;
+ afBestGrnError[uiPixel] = fBestPixelGrnError;
+ afBestPixelGrn[uiPixel] = fPixelGrn;
+ }
+ }
+ }
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestGrnError[uiPixel];
+ }
+
+ if (fBlockError < m_fGrnBlockError)
+ {
+ m_fGrnBlockError = fBlockError;
+
+ if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ m_fGrnBase = 255.0f * fBase;
+ }
+ else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_fGrnBase = (fBase * 255) - 128;
+ }
+ else
+ {
+ assert(0);
+ }
+ m_fGrnMultiplier = fMultiplier;
+ m_uiGrnModifierTableIndex = uiTableEntry;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiGrnSelectors[uiPixel] = auiBestSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel].fG = afBestPixelGrn[uiPixel];
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ }
+ }
+ }
+
+ }
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RG11::SetEncodingBits(void)
+ {
+ unsigned long long int ulliSelectorBitsR = 0;
+ unsigned long long int ulliSelectorBitsG = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ ulliSelectorBitsR |= ((unsigned long long int)m_auiRedSelectors[uiPixel]) << uiShift;
+ ulliSelectorBitsG |= ((unsigned long long int)m_auiGrnSelectors[uiPixel]) << uiShift;
+ }
+ if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ m_pencodingbitsRG11->data.baseR = (unsigned char)roundf(m_fRedBase);
+ }
+ else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_pencodingbitsRG11->data.baseR = (signed char)roundf(m_fRedBase);
+ }
+ else
+ {
+ assert(0);
+ }
+ m_pencodingbitsRG11->data.tableIndexR = m_uiRedModifierTableIndex;
+ m_pencodingbitsRG11->data.multiplierR = (unsigned char)roundf(m_fRedMultiplier);
+
+ m_pencodingbitsRG11->data.selectorsR0 = ulliSelectorBitsR >> 40;
+ m_pencodingbitsRG11->data.selectorsR1 = ulliSelectorBitsR >> 32;
+ m_pencodingbitsRG11->data.selectorsR2 = ulliSelectorBitsR >> 24;
+ m_pencodingbitsRG11->data.selectorsR3 = ulliSelectorBitsR >> 16;
+ m_pencodingbitsRG11->data.selectorsR4 = ulliSelectorBitsR >> 8;
+ m_pencodingbitsRG11->data.selectorsR5 = ulliSelectorBitsR;
+
+ if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::RG11)
+ {
+ m_pencodingbitsRG11->data.baseG = (unsigned char)roundf(m_fGrnBase);
+ }
+ else if (m_pblockParent->GetImageSource()->GetFormat() == Image::Format::SIGNED_RG11)
+ {
+ m_pencodingbitsRG11->data.baseG = (signed char)roundf(m_fGrnBase);
+ }
+ else
+ {
+ assert(0);
+ }
+ m_pencodingbitsRG11->data.tableIndexG = m_uiGrnModifierTableIndex;
+ m_pencodingbitsRG11->data.multiplierG = (unsigned char)roundf(m_fGrnMultiplier);
+
+ m_pencodingbitsRG11->data.selectorsG0 = ulliSelectorBitsG >> 40;
+ m_pencodingbitsRG11->data.selectorsG1 = ulliSelectorBitsG >> 32;
+ m_pencodingbitsRG11->data.selectorsG2 = ulliSelectorBitsG >> 24;
+ m_pencodingbitsRG11->data.selectorsG3 = ulliSelectorBitsG >> 16;
+ m_pencodingbitsRG11->data.selectorsG4 = ulliSelectorBitsG >> 8;
+ m_pencodingbitsRG11->data.selectorsG5 = ulliSelectorBitsG;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.h
new file mode 100644
index 0000000000..d4993b8c5f
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RG11.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding_RGB8.h"
+#include "EtcBlock4x4Encoding_R11.h"
+
+namespace Etc
+{
+ class Block4x4EncodingBits_RG11;
+
+ // ################################################################################
+ // Block4x4Encoding_RG11
+ // ################################################################################
+
+ class Block4x4Encoding_RG11 : public Block4x4Encoding_R11
+ {
+ float m_fGrnBase;
+ float m_fGrnMultiplier;
+ float m_fGrnBlockError;
+ unsigned int m_auiGrnSelectors[PIXELS];
+ unsigned int m_uiGrnModifierTableIndex;
+ public:
+
+ Block4x4Encoding_RG11(void);
+ virtual ~Block4x4Encoding_RG11(void);
+
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ Block4x4EncodingBits_RG11 *m_pencodingbitsRG11;
+
+ void CalculateG11(unsigned int a_uiSelectorsUsed, float a_fBaseRadius, float a_fMultiplierRadius);
+
+ inline float GetGrnBase(void) const
+ {
+ return m_fGrnBase;
+ }
+
+ inline float GetGrnMultiplier(void) const
+ {
+ return m_fGrnMultiplier;
+ }
+
+ inline int GetGrnTableIndex(void) const
+ {
+ return m_uiGrnModifierTableIndex;
+ }
+
+ inline const unsigned int * GetGrnSelectors(void) const
+ {
+ return m_auiGrnSelectors;
+ }
+
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp
new file mode 100644
index 0000000000..5656556db9
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.cpp
@@ -0,0 +1,1730 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_RGB8.cpp
+
+Block4x4Encoding_RGB8 is the encoder to use for the ETC2 extensions when targetting file format RGB8.
+This encoder is also used for the ETC2 subset of file format RGBA8.
+
+Block4x4Encoding_ETC1 encodes the ETC1 subset of RGB8.
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_RGB8.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
+#include "EtcMath.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <limits>
+
+namespace Etc
+{
+ float Block4x4Encoding_RGB8::s_afTHDistanceTable[TH_DISTANCES] =
+ {
+ 3.0f / 255.0f,
+ 6.0f / 255.0f,
+ 11.0f / 255.0f,
+ 16.0f / 255.0f,
+ 23.0f / 255.0f,
+ 32.0f / 255.0f,
+ 41.0f / 255.0f,
+ 64.0f / 255.0f
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_RGB8::Block4x4Encoding_RGB8(void)
+ {
+
+ m_pencodingbitsRGB8 = nullptr;
+
+ }
+
+ Block4x4Encoding_RGB8::~Block4x4Encoding_RGB8(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ // handle ETC1 modes
+ Block4x4Encoding_ETC1::InitFromEncodingBits(a_pblockParent,
+ a_paucEncodingBits, a_pafrgbaSource,a_errormetric);
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
+
+ // detect if there is a T, H or Planar mode present
+ if (m_pencodingbitsRGB8->differential.diff)
+ {
+ int iRed1 = (int)m_pencodingbitsRGB8->differential.red1;
+ int iDRed2 = m_pencodingbitsRGB8->differential.dred2;
+ int iRed2 = iRed1 + iDRed2;
+
+ int iGreen1 = (int)m_pencodingbitsRGB8->differential.green1;
+ int iDGreen2 = m_pencodingbitsRGB8->differential.dgreen2;
+ int iGreen2 = iGreen1 + iDGreen2;
+
+ int iBlue1 = (int)m_pencodingbitsRGB8->differential.blue1;
+ int iDBlue2 = m_pencodingbitsRGB8->differential.dblue2;
+ int iBlue2 = iBlue1 + iDBlue2;
+
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ InitFromEncodingBits_T();
+ }
+ else if (iGreen2 < 0 || iGreen2 > 31)
+ {
+ InitFromEncodingBits_H();
+ }
+ else if (iBlue2 < 0 || iBlue2 > 31)
+ {
+ InitFromEncodingBits_Planar();
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if T mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_T(void)
+ {
+
+ m_mode = MODE_T;
+
+ unsigned char ucRed1 = (unsigned char)((m_pencodingbitsRGB8->t.red1a << 2) +
+ m_pencodingbitsRGB8->t.red1b);
+ unsigned char ucGreen1 = m_pencodingbitsRGB8->t.green1;
+ unsigned char ucBlue1 = m_pencodingbitsRGB8->t.blue1;
+
+ unsigned char ucRed2 = m_pencodingbitsRGB8->t.red2;
+ unsigned char ucGreen2 = m_pencodingbitsRGB8->t.green2;
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->t.blue2;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+
+ m_uiCW1 = (m_pencodingbitsRGB8->t.da << 1) + m_pencodingbitsRGB8->t.db;
+
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+
+ DecodePixels_T();
+
+ CalcBlockError();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if H mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_H(void)
+ {
+
+ m_mode = MODE_H;
+
+ unsigned char ucRed1 = m_pencodingbitsRGB8->h.red1;
+ unsigned char ucGreen1 = (unsigned char)((m_pencodingbitsRGB8->h.green1a << 1) +
+ m_pencodingbitsRGB8->h.green1b);
+ unsigned char ucBlue1 = (unsigned char)((m_pencodingbitsRGB8->h.blue1a << 3) +
+ (m_pencodingbitsRGB8->h.blue1b << 1) +
+ m_pencodingbitsRGB8->h.blue1c);
+
+ unsigned char ucRed2 = m_pencodingbitsRGB8->h.red2;
+ unsigned char ucGreen2 = (unsigned char)((m_pencodingbitsRGB8->h.green2a << 1) +
+ m_pencodingbitsRGB8->h.green2b);
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->h.blue2;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+
+ // used to determine the LSB of the CW
+ unsigned int uiRGB1 = (unsigned int)(((int)ucRed1 << 16) + ((int)ucGreen1 << 8) + (int)ucBlue1);
+ unsigned int uiRGB2 = (unsigned int)(((int)ucRed2 << 16) + ((int)ucGreen2 << 8) + (int)ucBlue2);
+
+ m_uiCW1 = (m_pencodingbitsRGB8->h.da << 2) + (m_pencodingbitsRGB8->h.db << 1);
+ if (uiRGB1 >= uiRGB2)
+ {
+ m_uiCW1++;
+ }
+
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+
+ DecodePixels_H();
+
+ CalcBlockError();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if Planar mode is detected
+ //
+ void Block4x4Encoding_RGB8::InitFromEncodingBits_Planar(void)
+ {
+
+ m_mode = MODE_PLANAR;
+
+ unsigned char ucOriginRed = m_pencodingbitsRGB8->planar.originRed;
+ unsigned char ucOriginGreen = (unsigned char)((m_pencodingbitsRGB8->planar.originGreen1 << 6) +
+ m_pencodingbitsRGB8->planar.originGreen2);
+ unsigned char ucOriginBlue = (unsigned char)((m_pencodingbitsRGB8->planar.originBlue1 << 5) +
+ (m_pencodingbitsRGB8->planar.originBlue2 << 3) +
+ (m_pencodingbitsRGB8->planar.originBlue3 << 1) +
+ m_pencodingbitsRGB8->planar.originBlue4);
+
+ unsigned char ucHorizRed = (unsigned char)((m_pencodingbitsRGB8->planar.horizRed1 << 1) +
+ m_pencodingbitsRGB8->planar.horizRed2);
+ unsigned char ucHorizGreen = m_pencodingbitsRGB8->planar.horizGreen;
+ unsigned char ucHorizBlue = (unsigned char)((m_pencodingbitsRGB8->planar.horizBlue1 << 5) +
+ m_pencodingbitsRGB8->planar.horizBlue2);
+
+ unsigned char ucVertRed = (unsigned char)((m_pencodingbitsRGB8->planar.vertRed1 << 3) +
+ m_pencodingbitsRGB8->planar.vertRed2);
+ unsigned char ucVertGreen = (unsigned char)((m_pencodingbitsRGB8->planar.vertGreen1 << 2) +
+ m_pencodingbitsRGB8->planar.vertGreen2);
+ unsigned char ucVertBlue = m_pencodingbitsRGB8->planar.vertBlue;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromR6G7B6(ucOriginRed, ucOriginGreen, ucOriginBlue);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromR6G7B6(ucHorizRed, ucHorizGreen, ucHorizBlue);
+ m_frgbaColor3 = ColorFloatRGBA::ConvertFromR6G7B6(ucVertRed, ucVertGreen, ucVertBlue);
+
+ DecodePixels_Planar();
+
+ CalcBlockError();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGB8::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ Block4x4Encoding_ETC1::PerformFirstIteration();
+ if (m_boolDone)
+ {
+ break;
+ }
+ TryPlanar(0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ break;
+ }
+ TryTAndH(0);
+ break;
+
+ case 1:
+ Block4x4Encoding_ETC1::TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 2:
+ Block4x4Encoding_ETC1::TryIndividual(m_boolMostLikelyFlip, 1);
+ break;
+
+ case 3:
+ Block4x4Encoding_ETC1::TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 4:
+ Block4x4Encoding_ETC1::TryIndividual(!m_boolMostLikelyFlip, 1);
+ break;
+
+ case 5:
+ TryPlanar(1);
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 6:
+ TryTAndH(1);
+ if (a_fEffort <= 59.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 7:
+ Block4x4Encoding_ETC1::TryDegenerates1();
+ if (a_fEffort <= 69.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 8:
+ Block4x4Encoding_ETC1::TryDegenerates2();
+ if (a_fEffort <= 79.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 9:
+ Block4x4Encoding_ETC1::TryDegenerates3();
+ if (a_fEffort <= 89.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 10:
+ Block4x4Encoding_ETC1::TryDegenerates4();
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+
+ SetDoneIfPerfect();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in Planar mode
+ // save this encoding if it improves the error
+ //
+ void Block4x4Encoding_RGB8::TryPlanar(unsigned int a_uiRadius)
+ {
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ }
+
+ encodingTry.CalculatePlanarCornerColors();
+
+ encodingTry.DecodePixels_Planar();
+
+ encodingTry.CalcBlockError();
+
+ if (a_uiRadius > 0)
+ {
+ encodingTry.TwiddlePlanar();
+ }
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode or H mode
+ // save this encoding if it improves the error
+ //
+ void Block4x4Encoding_RGB8::TryTAndH(unsigned int a_uiRadius)
+ {
+
+ CalculateBaseColorsForTAndH();
+
+ TryT(a_uiRadius);
+
+ TryH(a_uiRadius);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // calculate original values for base colors
+ // store them in m_frgbaOriginalColor1 and m_frgbaOriginalColor2
+ //
+ void Block4x4Encoding_RGB8::CalculateBaseColorsForTAndH(void)
+ {
+
+ bool boolRGBX = m_pblockParent->GetImageSource()->GetErrorMetric() == ErrorMetric::RGBX;
+
+ ColorFloatRGBA frgbaBlockAverage = (m_frgbaSourceAverageLeft + m_frgbaSourceAverageRight) * 0.5f;
+
+ // find pixel farthest from average gray line
+ unsigned int uiFarthestPixel = 0;
+ float fFarthestGrayDistance2 = 0.0f;
+ unsigned int uiTransparentPixels = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // don't count transparent
+ if (m_pafrgbaSource[uiPixel].fA == 0.0f && !boolRGBX)
+ {
+ uiTransparentPixels++;
+ }
+ else
+ {
+ float fGrayDistance2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], frgbaBlockAverage);
+
+ if (fGrayDistance2 > fFarthestGrayDistance2)
+ {
+ uiFarthestPixel = uiPixel;
+ fFarthestGrayDistance2 = fGrayDistance2;
+ }
+ }
+ }
+ // a transparent block should not reach this method
+ assert(uiTransparentPixels < PIXELS);
+
+ // set the original base colors to:
+ // half way to the farthest pixel and
+ // the mirror color on the other side of the average
+ ColorFloatRGBA frgbaOffset = (m_pafrgbaSource[uiFarthestPixel] - frgbaBlockAverage) * 0.5f;
+ m_frgbaOriginalColor1_TAndH = (frgbaBlockAverage + frgbaOffset).QuantizeR4G4B4();
+ m_frgbaOriginalColor2_TAndH = (frgbaBlockAverage - frgbaOffset).ClampRGB().QuantizeR4G4B4(); // the "other side" might be out of range
+
+ // move base colors to find best fit
+ for (unsigned int uiIteration = 0; uiIteration < 10; uiIteration++)
+ {
+ // find the center of pixels closest to each color
+ float fPixelsCloserToColor1 = 0.0f;
+ ColorFloatRGBA frgbSumPixelsCloserToColor1;
+ float fPixelsCloserToColor2 = 0.0f;
+ ColorFloatRGBA frgbSumPixelsCloserToColor2;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ // don't count transparent pixels
+ if (m_pafrgbaSource[uiPixel].fA == 0.0f)
+ {
+ continue;
+ }
+
+ float fGrayDistance2ToColor1 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor1_TAndH);
+ float fGrayDistance2ToColor2 = CalcGrayDistance2(m_pafrgbaSource[uiPixel], m_frgbaOriginalColor2_TAndH);
+
+ ColorFloatRGBA frgbaAlphaWeightedSource = m_pafrgbaSource[uiPixel] * m_pafrgbaSource[uiPixel].fA;
+
+ if (fGrayDistance2ToColor1 <= fGrayDistance2ToColor2)
+ {
+ fPixelsCloserToColor1 += m_pafrgbaSource[uiPixel].fA;
+ frgbSumPixelsCloserToColor1 = frgbSumPixelsCloserToColor1 + frgbaAlphaWeightedSource;
+ }
+ else
+ {
+ fPixelsCloserToColor2 += m_pafrgbaSource[uiPixel].fA;
+ frgbSumPixelsCloserToColor2 = frgbSumPixelsCloserToColor2 + frgbaAlphaWeightedSource;
+ }
+ }
+ if (fPixelsCloserToColor1 == 0.0f || fPixelsCloserToColor2 == 0.0f)
+ {
+ break;
+ }
+
+ ColorFloatRGBA frgbAvgColor1Pixels = (frgbSumPixelsCloserToColor1 * (1.0f / fPixelsCloserToColor1)).QuantizeR4G4B4();
+ ColorFloatRGBA frgbAvgColor2Pixels = (frgbSumPixelsCloserToColor2 * (1.0f / fPixelsCloserToColor2)).QuantizeR4G4B4();
+
+ if (frgbAvgColor1Pixels.fR == m_frgbaOriginalColor1_TAndH.fR &&
+ frgbAvgColor1Pixels.fG == m_frgbaOriginalColor1_TAndH.fG &&
+ frgbAvgColor1Pixels.fB == m_frgbaOriginalColor1_TAndH.fB &&
+ frgbAvgColor2Pixels.fR == m_frgbaOriginalColor2_TAndH.fR &&
+ frgbAvgColor2Pixels.fG == m_frgbaOriginalColor2_TAndH.fG &&
+ frgbAvgColor2Pixels.fB == m_frgbaOriginalColor2_TAndH.fB)
+ {
+ break;
+ }
+
+ m_frgbaOriginalColor1_TAndH = frgbAvgColor1Pixels;
+ m_frgbaOriginalColor2_TAndH = frgbAvgColor2Pixels;
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode
+ // save this encoding if it improves the error
+ //
+ // since pixels that use base color1 don't use the distance table, color1 and color2 can be twiddled independently
+ // better encoding can be found if TWIDDLE_RADIUS is set to 2, but it will be much slower
+ //
+ void Block4x4Encoding_RGB8::TryT(unsigned int a_uiRadius)
+ {
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_T;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
+
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
+
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
+
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
+
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
+
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
+
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
+
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor2_TAndH
+ // twiddle color2 first, since it affects 3 selectors, while color1 only affects one selector
+ //
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor1_TAndH;
+ }
+
+ encodingTry.TryT_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+ }
+
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor2_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ }
+
+ encodingTry.TryT_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryT
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8::TryT_BestSelectorCombination(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = m_frgbaColor1;
+ afrgbaDecodedPixel[1] = (m_frgbaColor2 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = m_frgbaColor2;
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+ // try each selector
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
+ }
+ }
+
+
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
+
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode
+ // save this encoding if it improves the error
+ //
+ // since all pixels use the distance table, color1 and color2 can NOT be twiddled independently
+ // TWIDDLE_RADIUS of 2 is WAY too slow
+ //
+ void Block4x4Encoding_RGB8::TryH(unsigned int a_uiRadius)
+ {
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_H;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
+
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
+
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
+
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
+
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
+
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
+
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
+
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed1 == iColor2Red && iGreen1 == iColor2Green && iBlue1 == iColor2Blue)
+ {
+ continue;
+ }
+
+ encodingTry.TryH_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+
+ // twiddle m_frgbaOriginalColor2_TAndH
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed2 == iColor1Red && iGreen2 == iColor1Green && iBlue2 == iColor1Blue)
+ {
+ continue;
+ }
+
+ encodingTry.TryH_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryH
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8::TryH_BestSelectorCombination(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = (m_frgbaColor1 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[1] = (m_frgbaColor1 - fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = (m_frgbaColor2 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+ // try each selector
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
+ }
+ }
+
+
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
+
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // use linear regression to find the best fit for colors along the edges of the 4x4 block
+ //
+ void Block4x4Encoding_RGB8::CalculatePlanarCornerColors(void)
+ {
+ ColorFloatRGBA afrgbaRegression[MAX_PLANAR_REGRESSION_SIZE];
+ ColorFloatRGBA frgbaSlope;
+ ColorFloatRGBA frgbaOffset;
+
+ // top edge
+ afrgbaRegression[0] = m_pafrgbaSource[0];
+ afrgbaRegression[1] = m_pafrgbaSource[4];
+ afrgbaRegression[2] = m_pafrgbaSource[8];
+ afrgbaRegression[3] = m_pafrgbaSource[12];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor1 = frgbaOffset;
+ m_frgbaColor2 = (frgbaSlope * 4.0f) + frgbaOffset;
+
+ // left edge
+ afrgbaRegression[0] = m_pafrgbaSource[0];
+ afrgbaRegression[1] = m_pafrgbaSource[1];
+ afrgbaRegression[2] = m_pafrgbaSource[2];
+ afrgbaRegression[3] = m_pafrgbaSource[3];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor1 = (m_frgbaColor1 + frgbaOffset) * 0.5f; // average with top edge
+ m_frgbaColor3 = (frgbaSlope * 4.0f) + frgbaOffset;
+
+ // right edge
+ afrgbaRegression[0] = m_pafrgbaSource[12];
+ afrgbaRegression[1] = m_pafrgbaSource[13];
+ afrgbaRegression[2] = m_pafrgbaSource[14];
+ afrgbaRegression[3] = m_pafrgbaSource[15];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor2 = (m_frgbaColor2 + frgbaOffset) * 0.5f; // average with top edge
+
+ // bottom edge
+ afrgbaRegression[0] = m_pafrgbaSource[3];
+ afrgbaRegression[1] = m_pafrgbaSource[7];
+ afrgbaRegression[2] = m_pafrgbaSource[11];
+ afrgbaRegression[3] = m_pafrgbaSource[15];
+ ColorRegression(afrgbaRegression, 4, &frgbaSlope, &frgbaOffset);
+ m_frgbaColor3 = (m_frgbaColor3 + frgbaOffset) * 0.5f; // average with left edge
+
+ // quantize corner colors to 6/7/6
+ m_frgbaColor1 = m_frgbaColor1.QuantizeR6G7B6();
+ m_frgbaColor2 = m_frgbaColor2.QuantizeR6G7B6();
+ m_frgbaColor3 = m_frgbaColor3.QuantizeR6G7B6();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing R, G and B independently
+ //
+ // R, G and B decoding and errors are independent, so R, G and B twiddles can be independent
+ //
+ // return true if improvement
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanar(void)
+ {
+ bool boolImprovement = false;
+
+ while (TwiddlePlanarR())
+ {
+ boolImprovement = true;
+ }
+
+ while (TwiddlePlanarG())
+ {
+ boolImprovement = true;
+ }
+
+ while (TwiddlePlanarB())
+ {
+ boolImprovement = true;
+ }
+
+ return boolImprovement;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing R
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarR()
+ {
+ bool boolImprovement = false;
+
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ }
+
+ int iOriginRed = encodingTry.m_frgbaColor1.IntRed(63.0f);
+ int iHorizRed = encodingTry.m_frgbaColor2.IntRed(63.0f);
+ int iVertRed = encodingTry.m_frgbaColor3.IntRed(63.0f);
+
+ for (int iTryOriginRed = iOriginRed - 1; iTryOriginRed <= iOriginRed + 1; iTryOriginRed++)
+ {
+ // check for out of range
+ if (iTryOriginRed < 0 || iTryOriginRed > 63)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor1.fR = ((iTryOriginRed << 2) + (iTryOriginRed >> 4)) / 255.0f;
+
+ for (int iTryHorizRed = iHorizRed - 1; iTryHorizRed <= iHorizRed + 1; iTryHorizRed++)
+ {
+ // check for out of range
+ if (iTryHorizRed < 0 || iTryHorizRed > 63)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor2.fR = ((iTryHorizRed << 2) + (iTryHorizRed >> 4)) / 255.0f;
+
+ for (int iTryVertRed = iVertRed - 1; iTryVertRed <= iVertRed + 1; iTryVertRed++)
+ {
+ // check for out of range
+ if (iTryVertRed < 0 || iTryVertRed > 63)
+ {
+ continue;
+ }
+
+ // don't bother with null twiddle
+ if (iTryOriginRed == iOriginRed && iTryHorizRed == iHorizRed && iTryVertRed == iVertRed)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor3.fR = ((iTryVertRed << 2) + (iTryVertRed >> 4)) / 255.0f;
+
+ encodingTry.DecodePixels_Planar();
+
+ encodingTry.CalcBlockError();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+
+ boolImprovement = true;
+ }
+ }
+ }
+ }
+
+ return boolImprovement;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing G
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarG()
+ {
+ bool boolImprovement = false;
+
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ }
+
+ int iOriginGreen = encodingTry.m_frgbaColor1.IntGreen(127.0f);
+ int iHorizGreen = encodingTry.m_frgbaColor2.IntGreen(127.0f);
+ int iVertGreen = encodingTry.m_frgbaColor3.IntGreen(127.0f);
+
+ for (int iTryOriginGreen = iOriginGreen - 1; iTryOriginGreen <= iOriginGreen + 1; iTryOriginGreen++)
+ {
+ // check for out of range
+ if (iTryOriginGreen < 0 || iTryOriginGreen > 127)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor1.fG = ((iTryOriginGreen << 1) + (iTryOriginGreen >> 6)) / 255.0f;
+
+ for (int iTryHorizGreen = iHorizGreen - 1; iTryHorizGreen <= iHorizGreen + 1; iTryHorizGreen++)
+ {
+ // check for out of range
+ if (iTryHorizGreen < 0 || iTryHorizGreen > 127)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor2.fG = ((iTryHorizGreen << 1) + (iTryHorizGreen >> 6)) / 255.0f;
+
+ for (int iTryVertGreen = iVertGreen - 1; iTryVertGreen <= iVertGreen + 1; iTryVertGreen++)
+ {
+ // check for out of range
+ if (iTryVertGreen < 0 || iTryVertGreen > 127)
+ {
+ continue;
+ }
+
+ // don't bother with null twiddle
+ if (iTryOriginGreen == iOriginGreen &&
+ iTryHorizGreen == iHorizGreen &&
+ iTryVertGreen == iVertGreen)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor3.fG = ((iTryVertGreen << 1) + (iTryVertGreen >> 6)) / 255.0f;
+
+ encodingTry.DecodePixels_Planar();
+
+ encodingTry.CalcBlockError();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+
+ boolImprovement = true;
+ }
+ }
+ }
+ }
+
+ return boolImprovement;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try different corner colors by slightly changing B
+ //
+ bool Block4x4Encoding_RGB8::TwiddlePlanarB()
+ {
+ bool boolImprovement = false;
+
+ Block4x4Encoding_RGB8 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_PLANAR;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ }
+
+ int iOriginBlue = encodingTry.m_frgbaColor1.IntBlue(63.0f);
+ int iHorizBlue = encodingTry.m_frgbaColor2.IntBlue(63.0f);
+ int iVertBlue = encodingTry.m_frgbaColor3.IntBlue(63.0f);
+
+ for (int iTryOriginBlue = iOriginBlue - 1; iTryOriginBlue <= iOriginBlue + 1; iTryOriginBlue++)
+ {
+ // check for out of range
+ if (iTryOriginBlue < 0 || iTryOriginBlue > 63)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor1.fB = ((iTryOriginBlue << 2) + (iTryOriginBlue >> 4)) / 255.0f;
+
+ for (int iTryHorizBlue = iHorizBlue - 1; iTryHorizBlue <= iHorizBlue + 1; iTryHorizBlue++)
+ {
+ // check for out of range
+ if (iTryHorizBlue < 0 || iTryHorizBlue > 63)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor2.fB = ((iTryHorizBlue << 2) + (iTryHorizBlue >> 4)) / 255.0f;
+
+ for (int iTryVertBlue = iVertBlue - 1; iTryVertBlue <= iVertBlue + 1; iTryVertBlue++)
+ {
+ // check for out of range
+ if (iTryVertBlue < 0 || iTryVertBlue > 63)
+ {
+ continue;
+ }
+
+ // don't bother with null twiddle
+ if (iTryOriginBlue == iOriginBlue && iTryHorizBlue == iHorizBlue && iTryVertBlue == iVertBlue)
+ {
+ continue;
+ }
+
+ encodingTry.m_frgbaColor3.fB = ((iTryVertBlue << 2) + (iTryVertBlue >> 4)) / 255.0f;
+
+ encodingTry.DecodePixels_Planar();
+
+ encodingTry.CalcBlockError();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_PLANAR;
+ m_boolDiff = true;
+ m_boolFlip = false;
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_frgbaColor3 = encodingTry.m_frgbaColor3;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+
+ boolImprovement = true;
+ }
+ }
+ }
+ }
+
+ return boolImprovement;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits(void)
+ {
+
+ switch (m_mode)
+ {
+ case MODE_ETC1:
+ Block4x4Encoding_ETC1::SetEncodingBits();
+ break;
+
+ case MODE_T:
+ SetEncodingBits_T();
+ break;
+
+ case MODE_H:
+ SetEncodingBits_H();
+ break;
+
+ case MODE_PLANAR:
+ SetEncodingBits_Planar();
+ break;
+
+ default:
+ assert(false);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for T mode
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_T(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_T);
+ assert(m_boolDiff == true);
+
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+
+ m_pencodingbitsRGB8->t.red1a = uiRed1 >> 2;
+ m_pencodingbitsRGB8->t.red1b = uiRed1;
+ m_pencodingbitsRGB8->t.green1 = uiGreen1;
+ m_pencodingbitsRGB8->t.blue1 = uiBlue1;
+
+ m_pencodingbitsRGB8->t.red2 = uiRed2;
+ m_pencodingbitsRGB8->t.green2 = uiGreen2;
+ m_pencodingbitsRGB8->t.blue2 = uiBlue2;
+
+ m_pencodingbitsRGB8->t.da = m_uiCW1 >> 1;
+ m_pencodingbitsRGB8->t.db = m_uiCW1;
+
+ m_pencodingbitsRGB8->t.diff = 1;
+
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+
+ // create an invalid R differential to trigger T mode
+ m_pencodingbitsRGB8->t.detect1 = 0;
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ if (iRed2 >= 4)
+ {
+ m_pencodingbitsRGB8->t.detect1 = 7;
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->t.detect1 = 0;
+ m_pencodingbitsRGB8->t.detect2 = 1;
+ }
+
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+
+ // make sure red overflows
+ assert(iRed2 < 0 || iRed2 > 31);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for H mode
+ //
+ // colors and selectors may need to swap in order to generate lsb of distance index
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_H(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_H);
+ assert(m_boolDiff == true);
+
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+
+ unsigned int uiColor1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
+ unsigned int uiColor2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
+
+ bool boolOddDistance = m_uiCW1 & 1;
+ bool boolSwapColors = (uiColor1 < uiColor2) ^ !boolOddDistance;
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed2;
+ m_pencodingbitsRGB8->h.green1a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue2 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue2 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue2;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed1;
+ m_pencodingbitsRGB8->h.green2a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue1;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed1;
+ m_pencodingbitsRGB8->h.green1a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue1 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue1 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue1;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed2;
+ m_pencodingbitsRGB8->h.green2a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue2;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+
+ m_pencodingbitsRGB8->h.diff = 1;
+
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.selectors ^= 0x0000FFFF;
+ }
+
+ // create an invalid R differential to trigger T mode
+ m_pencodingbitsRGB8->h.detect1 = 0;
+ m_pencodingbitsRGB8->h.detect2 = 0;
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ m_pencodingbitsRGB8->h.detect1 = 1;
+ }
+ if (iGreen2 >= 4)
+ {
+ m_pencodingbitsRGB8->h.detect2 = 7;
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.detect2 = 0;
+ m_pencodingbitsRGB8->h.detect3 = 1;
+ }
+
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+
+ // make sure red doesn't overflow and green does
+ assert(iRed2 >= 0 && iRed2 <= 31);
+ assert(iGreen2 < 0 || iGreen2 > 31);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state for Planar mode
+ //
+ void Block4x4Encoding_RGB8::SetEncodingBits_Planar(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_PLANAR);
+ assert(m_boolDiff == true);
+
+ unsigned int uiOriginRed = (unsigned int)m_frgbaColor1.IntRed(63.0f);
+ unsigned int uiOriginGreen = (unsigned int)m_frgbaColor1.IntGreen(127.0f);
+ unsigned int uiOriginBlue = (unsigned int)m_frgbaColor1.IntBlue(63.0f);
+
+ unsigned int uiHorizRed = (unsigned int)m_frgbaColor2.IntRed(63.0f);
+ unsigned int uiHorizGreen = (unsigned int)m_frgbaColor2.IntGreen(127.0f);
+ unsigned int uiHorizBlue = (unsigned int)m_frgbaColor2.IntBlue(63.0f);
+
+ unsigned int uiVertRed = (unsigned int)m_frgbaColor3.IntRed(63.0f);
+ unsigned int uiVertGreen = (unsigned int)m_frgbaColor3.IntGreen(127.0f);
+ unsigned int uiVertBlue = (unsigned int)m_frgbaColor3.IntBlue(63.0f);
+
+ m_pencodingbitsRGB8->planar.originRed = uiOriginRed;
+ m_pencodingbitsRGB8->planar.originGreen1 = uiOriginGreen >> 6;
+ m_pencodingbitsRGB8->planar.originGreen2 = uiOriginGreen;
+ m_pencodingbitsRGB8->planar.originBlue1 = uiOriginBlue >> 5;
+ m_pencodingbitsRGB8->planar.originBlue2 = uiOriginBlue >> 3;
+ m_pencodingbitsRGB8->planar.originBlue3 = uiOriginBlue >> 1;
+ m_pencodingbitsRGB8->planar.originBlue4 = uiOriginBlue;
+
+ m_pencodingbitsRGB8->planar.horizRed1 = uiHorizRed >> 1;
+ m_pencodingbitsRGB8->planar.horizRed2 = uiHorizRed;
+ m_pencodingbitsRGB8->planar.horizGreen = uiHorizGreen;
+ m_pencodingbitsRGB8->planar.horizBlue1 = uiHorizBlue >> 5;
+ m_pencodingbitsRGB8->planar.horizBlue2 = uiHorizBlue;
+
+ m_pencodingbitsRGB8->planar.vertRed1 = uiVertRed >> 3;
+ m_pencodingbitsRGB8->planar.vertRed2 = uiVertRed;
+ m_pencodingbitsRGB8->planar.vertGreen1 = uiVertGreen >> 2;
+ m_pencodingbitsRGB8->planar.vertGreen2 = uiVertGreen;
+ m_pencodingbitsRGB8->planar.vertBlue = uiVertBlue;
+
+ m_pencodingbitsRGB8->planar.diff = 1;
+
+ // create valid RG differentials and an invalid B differential to trigger planar mode
+ m_pencodingbitsRGB8->planar.detect1 = 0;
+ m_pencodingbitsRGB8->planar.detect2 = 0;
+ m_pencodingbitsRGB8->planar.detect3 = 0;
+ m_pencodingbitsRGB8->planar.detect4 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ int iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ m_pencodingbitsRGB8->planar.detect1 = 1;
+ }
+ if (iGreen2 < 0 || iGreen2 > 31)
+ {
+ m_pencodingbitsRGB8->planar.detect2 = 1;
+ }
+ if (iBlue2 >= 4)
+ {
+ m_pencodingbitsRGB8->planar.detect3 = 7;
+ m_pencodingbitsRGB8->planar.detect4 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->planar.detect3 = 0;
+ m_pencodingbitsRGB8->planar.detect4 = 1;
+ }
+
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ iBlue2 = (int)m_pencodingbitsRGB8->differential.blue1 + (int)m_pencodingbitsRGB8->differential.dblue2;
+
+ // make sure red and green don't overflow and blue does
+ assert(iRed2 >= 0 && iRed2 <= 31);
+ assert(iGreen2 >= 0 && iGreen2 <= 31);
+ assert(iBlue2 < 0 || iBlue2 > 31);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for T mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_T(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
+ case 0:
+ m_afrgbaDecodedColors[uiPixel] = m_frgbaColor1;
+ break;
+
+ case 1:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
+ break;
+
+ case 2:
+ m_afrgbaDecodedColors[uiPixel] = m_frgbaColor2;
+ break;
+
+ case 3:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
+ break;
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for H mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_H(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
+ case 0:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 + frgbaDistance).ClampRGB();
+ break;
+
+ case 1:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 - frgbaDistance).ClampRGB();
+ break;
+
+ case 2:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
+ break;
+
+ case 3:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
+ break;
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the decoded colors and decoded alpha based on the encoding state for Planar mode
+ //
+ void Block4x4Encoding_RGB8::DecodePixels_Planar(void)
+ {
+
+ int iRO = (int)roundf(m_frgbaColor1.fR * 255.0f);
+ int iGO = (int)roundf(m_frgbaColor1.fG * 255.0f);
+ int iBO = (int)roundf(m_frgbaColor1.fB * 255.0f);
+
+ int iRH = (int)roundf(m_frgbaColor2.fR * 255.0f);
+ int iGH = (int)roundf(m_frgbaColor2.fG * 255.0f);
+ int iBH = (int)roundf(m_frgbaColor2.fB * 255.0f);
+
+ int iRV = (int)roundf(m_frgbaColor3.fR * 255.0f);
+ int iGV = (int)roundf(m_frgbaColor3.fG * 255.0f);
+ int iBV = (int)roundf(m_frgbaColor3.fB * 255.0f);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ int iX = (int)(uiPixel >> 2);
+ int iY = (int)(uiPixel & 3);
+
+ int iR = (iX*(iRH - iRO) + iY*(iRV - iRO) + 4*iRO + 2) >> 2;
+ int iG = (iX*(iGH - iGO) + iY*(iGV - iGO) + 4*iGO + 2) >> 2;
+ int iB = (iX*(iBH - iBO) + iY*(iBV - iBO) + 4*iBO + 2) >> 2;
+
+ ColorFloatRGBA frgba;
+ frgba.fR = (float)iR / 255.0f;
+ frgba.fG = (float)iG / 255.0f;
+ frgba.fB = (float)iB / 255.0f;
+ frgba.fA = 1.0f;
+
+ m_afrgbaDecodedColors[uiPixel] = frgba.ClampRGB();
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a linear regression for the a_uiPixels in a_pafrgbaPixels[]
+ //
+ // output the closest color line using a_pfrgbaSlope and a_pfrgbaOffset
+ //
+ void Block4x4Encoding_RGB8::ColorRegression(ColorFloatRGBA *a_pafrgbaPixels, unsigned int a_uiPixels,
+ ColorFloatRGBA *a_pfrgbaSlope, ColorFloatRGBA *a_pfrgbaOffset)
+ {
+ typedef struct
+ {
+ float f[4];
+ } Float4;
+
+ Float4 *paf4Pixels = (Float4 *)(a_pafrgbaPixels);
+ Float4 *pf4Slope = (Float4 *)(a_pfrgbaSlope);
+ Float4 *pf4Offset = (Float4 *)(a_pfrgbaOffset);
+
+ float afX[MAX_PLANAR_REGRESSION_SIZE];
+ float afY[MAX_PLANAR_REGRESSION_SIZE];
+
+ // handle r, g and b separately. don't bother with a
+ for (unsigned int uiComponent = 0; uiComponent < 3; uiComponent++)
+ {
+ for (unsigned int uiPixel = 0; uiPixel < a_uiPixels; uiPixel++)
+ {
+ afX[uiPixel] = (float)uiPixel;
+ afY[uiPixel] = paf4Pixels[uiPixel].f[uiComponent];
+
+ }
+ Etc::Regression(afX, afY, a_uiPixels,
+ &(pf4Slope->f[uiComponent]), &(pf4Offset->f[uiComponent]));
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.h
new file mode 100644
index 0000000000..03754d5e3b
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding_ETC1.h"
+
+namespace Etc
+{
+
+ class Block4x4Encoding_RGB8 : public Block4x4Encoding_ETC1
+ {
+ public:
+
+ Block4x4Encoding_RGB8(void);
+ virtual ~Block4x4Encoding_RGB8(void);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ inline ColorFloatRGBA GetColor3(void) const
+ {
+ return m_frgbaColor3;
+ }
+
+ protected:
+
+ static const unsigned int PLANAR_CORNER_COLORS = 3;
+ static const unsigned int MAX_PLANAR_REGRESSION_SIZE = 4;
+ static const unsigned int TH_DISTANCES = 8;
+
+ static float s_afTHDistanceTable[TH_DISTANCES];
+
+ void TryPlanar(unsigned int a_uiRadius);
+ void TryTAndH(unsigned int a_uiRadius);
+
+ void InitFromEncodingBits_Planar(void);
+
+ ColorFloatRGBA m_frgbaColor3; // used for planar
+
+ void SetEncodingBits_T(void);
+ void SetEncodingBits_H(void);
+ void SetEncodingBits_Planar(void);
+
+ // state shared between iterations
+ ColorFloatRGBA m_frgbaOriginalColor1_TAndH;
+ ColorFloatRGBA m_frgbaOriginalColor2_TAndH;
+
+ void CalculateBaseColorsForTAndH(void);
+ void TryT(unsigned int a_uiRadius);
+ void TryT_BestSelectorCombination(void);
+ void TryH(unsigned int a_uiRadius);
+ void TryH_BestSelectorCombination(void);
+
+ private:
+
+ void InitFromEncodingBits_T(void);
+ void InitFromEncodingBits_H(void);
+
+ void CalculatePlanarCornerColors(void);
+
+ void ColorRegression(ColorFloatRGBA *a_pafrgbaPixels, unsigned int a_uiPixels,
+ ColorFloatRGBA *a_pfrgbaSlope, ColorFloatRGBA *a_pfrgbaOffset);
+
+ bool TwiddlePlanar(void);
+ bool TwiddlePlanarR();
+ bool TwiddlePlanarG();
+ bool TwiddlePlanarB();
+
+ void DecodePixels_T(void);
+ void DecodePixels_H(void);
+ void DecodePixels_Planar(void);
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.cpp
new file mode 100644
index 0000000000..ba2b42fb05
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.cpp
@@ -0,0 +1,1819 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_RGB8A1.cpp contains:
+ Block4x4Encoding_RGB8A1
+ Block4x4Encoding_RGB8A1_Opaque
+ Block4x4Encoding_RGB8A1_Transparent
+
+These encoders are used when targetting file format RGB8A1.
+
+Block4x4Encoding_RGB8A1_Opaque is used when all pixels in the 4x4 block are opaque
+Block4x4Encoding_RGB8A1_Transparent is used when all pixels in the 4x4 block are transparent
+Block4x4Encoding_RGB8A1 is used when there is a mixture of alphas in the 4x4 block
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_RGB8A1.h"
+
+#include "EtcBlock4x4.h"
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4Encoding_RGB8.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGB8A1
+ // ####################################################################################################
+
+ float Block4x4Encoding_RGB8A1::s_aafCwOpaqueUnsetTable[CW_RANGES][SELECTORS] =
+ {
+ { 0.0f / 255.0f, 8.0f / 255.0f, 0.0f / 255.0f, -8.0f / 255.0f },
+ { 0.0f / 255.0f, 17.0f / 255.0f, 0.0f / 255.0f, -17.0f / 255.0f },
+ { 0.0f / 255.0f, 29.0f / 255.0f, 0.0f / 255.0f, -29.0f / 255.0f },
+ { 0.0f / 255.0f, 42.0f / 255.0f, 0.0f / 255.0f, -42.0f / 255.0f },
+ { 0.0f / 255.0f, 60.0f / 255.0f, 0.0f / 255.0f, -60.0f / 255.0f },
+ { 0.0f / 255.0f, 80.0f / 255.0f, 0.0f / 255.0f, -80.0f / 255.0f },
+ { 0.0f / 255.0f, 106.0f / 255.0f, 0.0f / 255.0f, -106.0f / 255.0f },
+ { 0.0f / 255.0f, 183.0f / 255.0f, 0.0f / 255.0f, -183.0f / 255.0f }
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_RGB8A1::Block4x4Encoding_RGB8A1(void)
+ {
+ m_pencodingbitsRGB8 = nullptr;
+ m_boolOpaque = false;
+ m_boolTransparent = false;
+ m_boolPunchThroughPixels = true;
+
+ }
+ Block4x4Encoding_RGB8A1::~Block4x4Encoding_RGB8A1(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits
+ //
+ void Block4x4Encoding_RGB8A1::InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits,
+ ErrorMetric a_errormetric)
+ {
+
+ Block4x4Encoding_RGB8::InitFromSource(a_pblockParent,
+ a_pafrgbaSource,
+ a_paucEncodingBits,
+ a_errormetric);
+
+ m_boolOpaque = a_pblockParent->GetSourceAlphaMix() == Block4x4::SourceAlphaMix::OPAQUE;
+ m_boolTransparent = a_pblockParent->GetSourceAlphaMix() == Block4x4::SourceAlphaMix::TRANSPARENT;
+ m_boolPunchThroughPixels = a_pblockParent->HasPunchThroughPixels();
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ if (m_pafrgbaSource[uiPixel].fA >= 0.5f)
+ {
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ else
+ {
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_RGB8A1::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+
+ InitFromEncodingBits_ETC1(a_pblockParent,
+ a_paucEncodingBits,
+ a_pafrgbaSource,
+ a_errormetric);
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
+
+ // detect if there is a T, H or Planar mode present
+ int iRed1 = m_pencodingbitsRGB8->differential.red1;
+ int iDRed2 = m_pencodingbitsRGB8->differential.dred2;
+ int iRed2 = iRed1 + iDRed2;
+
+ int iGreen1 = m_pencodingbitsRGB8->differential.green1;
+ int iDGreen2 = m_pencodingbitsRGB8->differential.dgreen2;
+ int iGreen2 = iGreen1 + iDGreen2;
+
+ int iBlue1 = m_pencodingbitsRGB8->differential.blue1;
+ int iDBlue2 = m_pencodingbitsRGB8->differential.dblue2;
+ int iBlue2 = iBlue1 + iDBlue2;
+
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ InitFromEncodingBits_T();
+ }
+ else if (iGreen2 < 0 || iGreen2 > 31)
+ {
+ InitFromEncodingBits_H();
+ }
+ else if (iBlue2 < 0 || iBlue2 > 31)
+ {
+ Block4x4Encoding_RGB8::InitFromEncodingBits_Planar();
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding assuming the encoding is an ETC1 mode.
+ // if it isn't an ETC1 mode, this will be overwritten later
+ //
+ void Block4x4Encoding_RGB8A1::InitFromEncodingBits_ETC1(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,
+ a_errormetric);
+
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)a_paucEncodingBits;
+
+ m_mode = MODE_ETC1;
+ m_boolDiff = true;
+ m_boolFlip = m_pencodingbitsRGB8->differential.flip;
+ m_boolOpaque = m_pencodingbitsRGB8->differential.diff;
+
+ int iR2 = m_pencodingbitsRGB8->differential.red1 + m_pencodingbitsRGB8->differential.dred2;
+ if (iR2 < 0)
+ {
+ iR2 = 0;
+ }
+ else if (iR2 > 31)
+ {
+ iR2 = 31;
+ }
+
+ int iG2 = m_pencodingbitsRGB8->differential.green1 + m_pencodingbitsRGB8->differential.dgreen2;
+ if (iG2 < 0)
+ {
+ iG2 = 0;
+ }
+ else if (iG2 > 31)
+ {
+ iG2 = 31;
+ }
+
+ int iB2 = m_pencodingbitsRGB8->differential.blue1 + m_pencodingbitsRGB8->differential.dblue2;
+ if (iB2 < 0)
+ {
+ iB2 = 0;
+ }
+ else if (iB2 > 31)
+ {
+ iB2 = 31;
+ }
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5(m_pencodingbitsRGB8->differential.red1, m_pencodingbitsRGB8->differential.green1, m_pencodingbitsRGB8->differential.blue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iR2, (unsigned char)iG2, (unsigned char)iB2);
+
+ m_uiCW1 = m_pencodingbitsRGB8->differential.cw1;
+ m_uiCW2 = m_pencodingbitsRGB8->differential.cw2;
+
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+
+ Decode_ETC1();
+
+ CalcBlockError();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if T mode is detected
+ //
+ void Block4x4Encoding_RGB8A1::InitFromEncodingBits_T(void)
+ {
+ m_mode = MODE_T;
+
+ unsigned char ucRed1 = (unsigned char)((m_pencodingbitsRGB8->t.red1a << 2) +
+ m_pencodingbitsRGB8->t.red1b);
+ unsigned char ucGreen1 = m_pencodingbitsRGB8->t.green1;
+ unsigned char ucBlue1 = m_pencodingbitsRGB8->t.blue1;
+
+ unsigned char ucRed2 = m_pencodingbitsRGB8->t.red2;
+ unsigned char ucGreen2 = m_pencodingbitsRGB8->t.green2;
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->t.blue2;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+
+ m_uiCW1 = (m_pencodingbitsRGB8->t.da << 1) + m_pencodingbitsRGB8->t.db;
+
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+
+ DecodePixels_T();
+
+ CalcBlockError();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding if H mode is detected
+ //
+ void Block4x4Encoding_RGB8A1::InitFromEncodingBits_H(void)
+ {
+ m_mode = MODE_H;
+
+ unsigned char ucRed1 = m_pencodingbitsRGB8->h.red1;
+ unsigned char ucGreen1 = (unsigned char)((m_pencodingbitsRGB8->h.green1a << 1) +
+ m_pencodingbitsRGB8->h.green1b);
+ unsigned char ucBlue1 = (unsigned char)((m_pencodingbitsRGB8->h.blue1a << 3) +
+ (m_pencodingbitsRGB8->h.blue1b << 1) +
+ m_pencodingbitsRGB8->h.blue1c);
+
+ unsigned char ucRed2 = m_pencodingbitsRGB8->h.red2;
+ unsigned char ucGreen2 = (unsigned char)((m_pencodingbitsRGB8->h.green2a << 1) +
+ m_pencodingbitsRGB8->h.green2b);
+ unsigned char ucBlue2 = m_pencodingbitsRGB8->h.blue2;
+
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4(ucRed1, ucGreen1, ucBlue1);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4(ucRed2, ucGreen2, ucBlue2);
+
+ // used to determine the LSB of the CW
+ unsigned int uiRGB1 = (unsigned int)(((int)ucRed1 << 16) + ((int)ucGreen1 << 8) + (int)ucBlue1);
+ unsigned int uiRGB2 = (unsigned int)(((int)ucRed2 << 16) + ((int)ucGreen2 << 8) + (int)ucBlue2);
+
+ m_uiCW1 = (m_pencodingbitsRGB8->h.da << 2) + (m_pencodingbitsRGB8->h.db << 1);
+ if (uiRGB1 >= uiRGB2)
+ {
+ m_uiCW1++;
+ }
+
+ Block4x4Encoding_ETC1::InitFromEncodingBits_Selectors();
+
+ DecodePixels_H();
+
+ CalcBlockError();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // for ETC1 modes, set the decoded colors and decoded alpha based on the encoding state
+ //
+ void Block4x4Encoding_RGB8A1::Decode_ETC1(void)
+ {
+
+ const unsigned int *pauiPixelOrder = m_boolFlip ? s_auiPixelOrderFlip1 : s_auiPixelOrderFlip0;
+
+ for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS; uiPixelOrder++)
+ {
+ ColorFloatRGBA *pfrgbaCenter = uiPixelOrder < 8 ? &m_frgbaColor1 : &m_frgbaColor2;
+ unsigned int uiCW = uiPixelOrder < 8 ? m_uiCW1 : m_uiCW2;
+
+ unsigned int uiPixel = pauiPixelOrder[uiPixelOrder];
+
+ float fDelta;
+ if (m_boolOpaque)
+ fDelta = Block4x4Encoding_ETC1::s_aafCwTable[uiCW][m_auiSelectors[uiPixel]];
+ else
+ fDelta = s_aafCwOpaqueUnsetTable[uiCW][m_auiSelectors[uiPixel]];
+
+ if (m_boolOpaque == false && m_auiSelectors[uiPixel] == TRANSPARENT_SELECTOR)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+ else
+ {
+ m_afrgbaDecodedColors[uiPixel] = (*pfrgbaCenter + fDelta).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // for T mode, set the decoded colors and decoded alpha based on the encoding state
+ //
+ void Block4x4Encoding_RGB8A1::DecodePixels_T(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
+ case 0:
+ m_afrgbaDecodedColors[uiPixel] = m_frgbaColor1;
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+
+ case 1:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+
+ case 2:
+ if (m_boolOpaque == false)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+ else
+ {
+ m_afrgbaDecodedColors[uiPixel] = m_frgbaColor2;
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ break;
+
+ case 3:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // for H mode, set the decoded colors and decoded alpha based on the encoding state
+ //
+ void Block4x4Encoding_RGB8A1::DecodePixels_H(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+ ColorFloatRGBA frgbaDistance(fDistance, fDistance, fDistance, 0.0f);
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ switch (m_auiSelectors[uiPixel])
+ {
+ case 0:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 + frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+
+ case 1:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor1 - frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+
+ case 2:
+ if (m_boolOpaque == false)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+ else
+ {
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 + frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ break;
+
+ case 3:
+ m_afrgbaDecodedColors[uiPixel] = (m_frgbaColor2 - frgbaDistance).ClampRGB();
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ break;
+ }
+
+ }
+
+ }
+
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ // RGB8A1 can't use individual mode
+ // RGB8A1 with transparent pixels can't use planar mode
+ //
+ void Block4x4Encoding_RGB8A1::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolOpaque);
+ assert(!m_boolTransparent);
+ assert(!m_boolDone);
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ PerformFirstIteration();
+ break;
+
+ case 1:
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 2:
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
+ if (a_fEffort <= 39.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 3:
+ Block4x4Encoding_RGB8::CalculateBaseColorsForTAndH();
+ TryT(1);
+ TryH(1);
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 4:
+ TryDegenerates1();
+ if (a_fEffort <= 59.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 5:
+ TryDegenerates2();
+ if (a_fEffort <= 69.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 6:
+ TryDegenerates3();
+ if (a_fEffort <= 79.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 7:
+ TryDegenerates4();
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+
+ SetDoneIfPerfect();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best initial encoding to ensure block has a valid encoding
+ //
+ void Block4x4Encoding_RGB8A1::PerformFirstIteration(void)
+ {
+ Block4x4Encoding_ETC1::CalculateMostLikelyFlip();
+
+ m_fError = FLT_MAX;
+
+ TryDifferential(m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ TryDifferential(!m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // mostly copied from ETC1
+ // differences:
+ // Block4x4Encoding_RGB8A1 encodingTry = *this;
+ //
+ void Block4x4Encoding_RGB8A1::TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2)
+ {
+
+ ColorFloatRGBA frgbaColor1;
+ ColorFloatRGBA frgbaColor2;
+
+ const unsigned int *pauiPixelMapping1;
+ const unsigned int *pauiPixelMapping2;
+
+ if (a_boolFlip)
+ {
+ frgbaColor1 = m_frgbaSourceAverageTop;
+ frgbaColor2 = m_frgbaSourceAverageBottom;
+
+ pauiPixelMapping1 = s_auiTopPixelMapping;
+ pauiPixelMapping2 = s_auiBottomPixelMapping;
+ }
+ else
+ {
+ frgbaColor1 = m_frgbaSourceAverageLeft;
+ frgbaColor2 = m_frgbaSourceAverageRight;
+
+ pauiPixelMapping1 = s_auiLeftPixelMapping;
+ pauiPixelMapping2 = s_auiRightPixelMapping;
+ }
+
+ DifferentialTrys trys(frgbaColor1, frgbaColor2, pauiPixelMapping1, pauiPixelMapping2,
+ a_uiRadius, a_iGrayOffset1, a_iGrayOffset2);
+
+ Block4x4Encoding_RGB8A1 encodingTry = *this;
+ encodingTry.m_boolFlip = a_boolFlip;
+
+ encodingTry.TryDifferentialHalf(&trys.m_half1);
+ encodingTry.TryDifferentialHalf(&trys.m_half2);
+
+ // find best halves that are within differential range
+ DifferentialTrys::Try *ptryBest1 = nullptr;
+ DifferentialTrys::Try *ptryBest2 = nullptr;
+ encodingTry.m_fError = FLT_MAX;
+
+ // see if the best of each half are in differential range
+ int iDRed = trys.m_half2.m_ptryBest->m_iRed - trys.m_half1.m_ptryBest->m_iRed;
+ int iDGreen = trys.m_half2.m_ptryBest->m_iGreen - trys.m_half1.m_ptryBest->m_iGreen;
+ int iDBlue = trys.m_half2.m_ptryBest->m_iBlue - trys.m_half1.m_ptryBest->m_iBlue;
+ if (iDRed >= -4 && iDRed <= 3 && iDGreen >= -4 && iDGreen <= 3 && iDBlue >= -4 && iDBlue <= 3)
+ {
+ ptryBest1 = trys.m_half1.m_ptryBest;
+ ptryBest2 = trys.m_half2.m_ptryBest;
+ encodingTry.m_fError = trys.m_half1.m_ptryBest->m_fError + trys.m_half2.m_ptryBest->m_fError;
+ }
+ else
+ {
+ // else, find the next best halves that are in differential range
+ for (DifferentialTrys::Try *ptry1 = &trys.m_half1.m_atry[0];
+ ptry1 < &trys.m_half1.m_atry[trys.m_half1.m_uiTrys];
+ ptry1++)
+ {
+ for (DifferentialTrys::Try *ptry2 = &trys.m_half2.m_atry[0];
+ ptry2 < &trys.m_half2.m_atry[trys.m_half2.m_uiTrys];
+ ptry2++)
+ {
+ iDRed = ptry2->m_iRed - ptry1->m_iRed;
+ bool boolValidRedDelta = iDRed <= 3 && iDRed >= -4;
+ iDGreen = ptry2->m_iGreen - ptry1->m_iGreen;
+ bool boolValidGreenDelta = iDGreen <= 3 && iDGreen >= -4;
+ iDBlue = ptry2->m_iBlue - ptry1->m_iBlue;
+ bool boolValidBlueDelta = iDBlue <= 3 && iDBlue >= -4;
+
+ if (boolValidRedDelta && boolValidGreenDelta && boolValidBlueDelta)
+ {
+ float fError = ptry1->m_fError + ptry2->m_fError;
+
+ if (fError < encodingTry.m_fError)
+ {
+ encodingTry.m_fError = fError;
+
+ ptryBest1 = ptry1;
+ ptryBest2 = ptry2;
+ }
+ }
+
+ }
+ }
+ assert(encodingTry.m_fError < FLT_MAX);
+ assert(ptryBest1 != nullptr);
+ assert(ptryBest2 != nullptr);
+ }
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = MODE_ETC1;
+ m_boolDiff = true;
+ m_boolFlip = encodingTry.m_boolFlip;
+ m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest1->m_iRed, (unsigned char)ptryBest1->m_iGreen, (unsigned char)ptryBest1->m_iBlue);
+ m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB5((unsigned char)ptryBest2->m_iRed, (unsigned char)ptryBest2->m_iGreen, (unsigned char)ptryBest2->m_iBlue);
+ m_uiCW1 = ptryBest1->m_uiCW;
+ m_uiCW2 = ptryBest2->m_uiCW;
+
+ m_fError = 0.0f;
+ for (unsigned int uiPixelOrder = 0; uiPixelOrder < PIXELS / 2; uiPixelOrder++)
+ {
+ unsigned int uiPixel1 = pauiPixelMapping1[uiPixelOrder];
+ unsigned int uiPixel2 = pauiPixelMapping2[uiPixelOrder];
+
+ unsigned int uiSelector1 = ptryBest1->m_auiSelectors[uiPixelOrder];
+ unsigned int uiSelector2 = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ m_auiSelectors[uiPixel1] = uiSelector1;
+ m_auiSelectors[uiPixel2] = ptryBest2->m_auiSelectors[uiPixelOrder];
+
+ if (uiSelector1 == TRANSPARENT_SELECTOR)
+ {
+ m_afrgbaDecodedColors[uiPixel1] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel1] = 0.0f;
+ }
+ else
+ {
+ float fDeltaRGB1 = s_aafCwOpaqueUnsetTable[m_uiCW1][uiSelector1];
+ m_afrgbaDecodedColors[uiPixel1] = (m_frgbaColor1 + fDeltaRGB1).ClampRGB();
+ m_afDecodedAlphas[uiPixel1] = 1.0f;
+ }
+
+ if (uiSelector2 == TRANSPARENT_SELECTOR)
+ {
+ m_afrgbaDecodedColors[uiPixel2] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel2] = 0.0f;
+ }
+ else
+ {
+ float fDeltaRGB2 = s_aafCwOpaqueUnsetTable[m_uiCW2][uiSelector2];
+ m_afrgbaDecodedColors[uiPixel2] = (m_frgbaColor2 + fDeltaRGB2).ClampRGB();
+ m_afDecodedAlphas[uiPixel2] = 1.0f;
+ }
+
+ float fDeltaA1 = m_afDecodedAlphas[uiPixel1] - m_pafrgbaSource[uiPixel1].fA;
+ m_fError += fDeltaA1 * fDeltaA1;
+ float fDeltaA2 = m_afDecodedAlphas[uiPixel2] - m_pafrgbaSource[uiPixel2].fA;
+ m_fError += fDeltaA2 * fDeltaA2;
+ }
+
+ m_fError1 = ptryBest1->m_fError;
+ m_fError2 = ptryBest2->m_fError;
+ m_boolSeverelyBentDifferentialColors = trys.m_boolSeverelyBentColors;
+ m_fError = m_fError1 + m_fError2;
+
+ // sanity check
+ {
+ int iRed1 = m_frgbaColor1.IntRed(31.0f);
+ int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
+ int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
+
+ int iRed2 = m_frgbaColor2.IntRed(31.0f);
+ int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
+ int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
+
+ iDRed = iRed2 - iRed1;
+ iDGreen = iGreen2 - iGreen1;
+ iDBlue = iBlue2 - iBlue1;
+
+ assert(iDRed >= -4 && iDRed < 4);
+ assert(iDGreen >= -4 && iDGreen < 4);
+ assert(iDBlue >= -4 && iDBlue < 4);
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // mostly copied from ETC1
+ // differences:
+ // uses s_aafCwOpaqueUnsetTable
+ // color for selector set to 0,0,0,0
+ //
+ void Block4x4Encoding_RGB8A1::TryDifferentialHalf(DifferentialTrys::Half *a_phalf)
+ {
+
+ a_phalf->m_ptryBest = nullptr;
+ float fBestTryError = FLT_MAX;
+
+ a_phalf->m_uiTrys = 0;
+ for (int iRed = a_phalf->m_iRed - (int)a_phalf->m_uiRadius;
+ iRed <= a_phalf->m_iRed + (int)a_phalf->m_uiRadius;
+ iRed++)
+ {
+ assert(iRed >= 0 && iRed <= 31);
+
+ for (int iGreen = a_phalf->m_iGreen - (int)a_phalf->m_uiRadius;
+ iGreen <= a_phalf->m_iGreen + (int)a_phalf->m_uiRadius;
+ iGreen++)
+ {
+ assert(iGreen >= 0 && iGreen <= 31);
+
+ for (int iBlue = a_phalf->m_iBlue - (int)a_phalf->m_uiRadius;
+ iBlue <= a_phalf->m_iBlue + (int)a_phalf->m_uiRadius;
+ iBlue++)
+ {
+ assert(iBlue >= 0 && iBlue <= 31);
+
+ DifferentialTrys::Try *ptry = &a_phalf->m_atry[a_phalf->m_uiTrys];
+ assert(ptry < &a_phalf->m_atry[DifferentialTrys::Half::MAX_TRYS]);
+
+ ptry->m_iRed = iRed;
+ ptry->m_iGreen = iGreen;
+ ptry->m_iBlue = iBlue;
+ ptry->m_fError = FLT_MAX;
+ ColorFloatRGBA frgbaColor = ColorFloatRGBA::ConvertFromRGB5((unsigned char)iRed, (unsigned char)iGreen, (unsigned char)iBlue);
+
+ // try each CW
+ for (unsigned int uiCW = 0; uiCW < CW_RANGES; uiCW++)
+ {
+ unsigned int auiPixelSelectors[PIXELS / 2];
+ ColorFloatRGBA afrgbaDecodedColors[PIXELS / 2];
+ float afPixelErrors[PIXELS / 2] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+
+ // pre-compute decoded pixels for each selector
+ ColorFloatRGBA afrgbaSelectors[SELECTORS];
+ assert(SELECTORS == 4);
+ afrgbaSelectors[0] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][0]).ClampRGB();
+ afrgbaSelectors[1] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][1]).ClampRGB();
+ afrgbaSelectors[2] = ColorFloatRGBA();
+ afrgbaSelectors[3] = (frgbaColor + s_aafCwOpaqueUnsetTable[uiCW][3]).ClampRGB();
+
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ColorFloatRGBA *pfrgbaSourcePixel = &m_pafrgbaSource[a_phalf->m_pauiPixelMapping[uiPixel]];
+ ColorFloatRGBA frgbaDecodedPixel;
+
+ for (unsigned int uiSelector = 0; uiSelector < SELECTORS; uiSelector++)
+ {
+ if (pfrgbaSourcePixel->fA < 0.5f)
+ {
+ uiSelector = TRANSPARENT_SELECTOR;
+ }
+ else if (uiSelector == TRANSPARENT_SELECTOR)
+ {
+ continue;
+ }
+
+ frgbaDecodedPixel = afrgbaSelectors[uiSelector];
+
+ float fPixelError;
+
+ fPixelError = CalcPixelError(frgbaDecodedPixel, m_afDecodedAlphas[a_phalf->m_pauiPixelMapping[uiPixel]],
+ *pfrgbaSourcePixel);
+
+ if (fPixelError < afPixelErrors[uiPixel])
+ {
+ auiPixelSelectors[uiPixel] = uiSelector;
+ afrgbaDecodedColors[uiPixel] = frgbaDecodedPixel;
+ afPixelErrors[uiPixel] = fPixelError;
+ }
+
+ if (uiSelector == TRANSPARENT_SELECTOR)
+ {
+ break;
+ }
+ }
+ }
+
+ // add up all pixel errors
+ float fCWError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ fCWError += afPixelErrors[uiPixel];
+ }
+
+ // if best CW so far
+ if (fCWError < ptry->m_fError)
+ {
+ ptry->m_uiCW = uiCW;
+ for (unsigned int uiPixel = 0; uiPixel < 8; uiPixel++)
+ {
+ ptry->m_auiSelectors[uiPixel] = auiPixelSelectors[uiPixel];
+ }
+ ptry->m_fError = fCWError;
+ }
+
+ }
+
+ if (ptry->m_fError < fBestTryError)
+ {
+ a_phalf->m_ptryBest = ptry;
+ fBestTryError = ptry->m_fError;
+ }
+
+ assert(ptry->m_fError < FLT_MAX);
+
+ a_phalf->m_uiTrys++;
+ }
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in T mode
+ // save this encoding if it improves the error
+ //
+ // since pixels that use base color1 don't use the distance table, color1 and color2 can be twiddled independently
+ // better encoding can be found if TWIDDLE_RADIUS is set to 2, but it will be much slower
+ //
+ void Block4x4Encoding_RGB8A1::TryT(unsigned int a_uiRadius)
+ {
+ Block4x4Encoding_RGB8A1 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_T;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
+
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
+
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
+
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
+
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
+
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
+
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
+
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor2_TAndH
+ // twiddle color2 first, since it affects 3 selectors, while color1 only affects one selector
+ //
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor1_TAndH;
+ }
+
+ encodingTry.TryT_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+ }
+
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ for (unsigned int uiBaseColorSwaps = 0; uiBaseColorSwaps < 2; uiBaseColorSwaps++)
+ {
+ if (uiBaseColorSwaps == 0)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+ }
+ else
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor2_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ }
+
+ encodingTry.TryT_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryT
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8A1::TryT_BestSelectorCombination(void)
+ {
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = m_frgbaColor1;
+ afrgbaDecodedPixel[1] = (m_frgbaColor2 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = ColorFloatRGBA();
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+ // try each selector
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiMinSelector = 0;
+ unsigned int uiMaxSelector = SELECTORS - 1;
+
+ if (m_pafrgbaSource[uiPixel].fA < 0.5f)
+ {
+ uiMinSelector = 2;
+ uiMaxSelector = 2;
+ }
+
+ for (unsigned int uiSelector = uiMinSelector; uiSelector <= uiMaxSelector; uiSelector++)
+ {
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
+ }
+ }
+
+
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
+
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try encoding in H mode
+ // save this encoding if it improves the error
+ //
+ // since all pixels use the distance table, color1 and color2 can NOT be twiddled independently
+ // TWIDDLE_RADIUS of 2 is WAY too slow
+ //
+ void Block4x4Encoding_RGB8A1::TryH(unsigned int a_uiRadius)
+ {
+ Block4x4Encoding_RGB8A1 encodingTry = *this;
+
+ // init "try"
+ {
+ encodingTry.m_mode = MODE_H;
+ encodingTry.m_boolDiff = true;
+ encodingTry.m_boolFlip = false;
+ encodingTry.m_fError = FLT_MAX;
+ }
+
+ int iColor1Red = m_frgbaOriginalColor1_TAndH.IntRed(15.0f);
+ int iColor1Green = m_frgbaOriginalColor1_TAndH.IntGreen(15.0f);
+ int iColor1Blue = m_frgbaOriginalColor1_TAndH.IntBlue(15.0f);
+
+ int iMinRed1 = iColor1Red - (int)a_uiRadius;
+ if (iMinRed1 < 0)
+ {
+ iMinRed1 = 0;
+ }
+ int iMaxRed1 = iColor1Red + (int)a_uiRadius;
+ if (iMaxRed1 > 15)
+ {
+ iMinRed1 = 15;
+ }
+
+ int iMinGreen1 = iColor1Green - (int)a_uiRadius;
+ if (iMinGreen1 < 0)
+ {
+ iMinGreen1 = 0;
+ }
+ int iMaxGreen1 = iColor1Green + (int)a_uiRadius;
+ if (iMaxGreen1 > 15)
+ {
+ iMinGreen1 = 15;
+ }
+
+ int iMinBlue1 = iColor1Blue - (int)a_uiRadius;
+ if (iMinBlue1 < 0)
+ {
+ iMinBlue1 = 0;
+ }
+ int iMaxBlue1 = iColor1Blue + (int)a_uiRadius;
+ if (iMaxBlue1 > 15)
+ {
+ iMinBlue1 = 15;
+ }
+
+ int iColor2Red = m_frgbaOriginalColor2_TAndH.IntRed(15.0f);
+ int iColor2Green = m_frgbaOriginalColor2_TAndH.IntGreen(15.0f);
+ int iColor2Blue = m_frgbaOriginalColor2_TAndH.IntBlue(15.0f);
+
+ int iMinRed2 = iColor2Red - (int)a_uiRadius;
+ if (iMinRed2 < 0)
+ {
+ iMinRed2 = 0;
+ }
+ int iMaxRed2 = iColor2Red + (int)a_uiRadius;
+ if (iMaxRed2 > 15)
+ {
+ iMinRed2 = 15;
+ }
+
+ int iMinGreen2 = iColor2Green - (int)a_uiRadius;
+ if (iMinGreen2 < 0)
+ {
+ iMinGreen2 = 0;
+ }
+ int iMaxGreen2 = iColor2Green + (int)a_uiRadius;
+ if (iMaxGreen2 > 15)
+ {
+ iMinGreen2 = 15;
+ }
+
+ int iMinBlue2 = iColor2Blue - (int)a_uiRadius;
+ if (iMinBlue2 < 0)
+ {
+ iMinBlue2 = 0;
+ }
+ int iMaxBlue2 = iColor2Blue + (int)a_uiRadius;
+ if (iMaxBlue2 > 15)
+ {
+ iMinBlue2 = 15;
+ }
+
+ for (unsigned int uiDistance = 0; uiDistance < TH_DISTANCES; uiDistance++)
+ {
+ encodingTry.m_uiCW1 = uiDistance;
+
+ // twiddle m_frgbaOriginalColor1_TAndH
+ for (int iRed1 = iMinRed1; iRed1 <= iMaxRed1; iRed1++)
+ {
+ for (int iGreen1 = iMinGreen1; iGreen1 <= iMaxGreen1; iGreen1++)
+ {
+ for (int iBlue1 = iMinBlue1; iBlue1 <= iMaxBlue1; iBlue1++)
+ {
+ encodingTry.m_frgbaColor1 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed1, (unsigned char)iGreen1, (unsigned char)iBlue1);
+ encodingTry.m_frgbaColor2 = m_frgbaOriginalColor2_TAndH;
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed1 == iColor2Red && iGreen1 == iColor2Green && iBlue1 == iColor2Blue)
+ {
+ continue;
+ }
+
+ encodingTry.TryH_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+
+ // twiddle m_frgbaOriginalColor2_TAndH
+ for (int iRed2 = iMinRed2; iRed2 <= iMaxRed2; iRed2++)
+ {
+ for (int iGreen2 = iMinGreen2; iGreen2 <= iMaxGreen2; iGreen2++)
+ {
+ for (int iBlue2 = iMinBlue2; iBlue2 <= iMaxBlue2; iBlue2++)
+ {
+ encodingTry.m_frgbaColor1 = m_frgbaOriginalColor1_TAndH;
+ encodingTry.m_frgbaColor2 = ColorFloatRGBA::ConvertFromRGB4((unsigned char)iRed2, (unsigned char)iGreen2, (unsigned char)iBlue2);
+
+ // if color1 == color2, H encoding issues can pop up, so abort
+ if (iRed2 == iColor1Red && iGreen2 == iColor1Green && iBlue2 == iColor1Blue)
+ {
+ continue;
+ }
+
+ encodingTry.TryH_BestSelectorCombination();
+
+ if (encodingTry.m_fError < m_fError)
+ {
+ m_mode = encodingTry.m_mode;
+ m_boolDiff = encodingTry.m_boolDiff;
+ m_boolFlip = encodingTry.m_boolFlip;
+
+ m_frgbaColor1 = encodingTry.m_frgbaColor1;
+ m_frgbaColor2 = encodingTry.m_frgbaColor2;
+ m_uiCW1 = encodingTry.m_uiCW1;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = encodingTry.m_auiSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = encodingTry.m_afrgbaDecodedColors[uiPixel];
+ }
+
+ m_fError = encodingTry.m_fError;
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best selector combination for TryH
+ // called on an encodingTry
+ //
+ void Block4x4Encoding_RGB8A1::TryH_BestSelectorCombination(void)
+ {
+
+ // abort if colors and CW will pose an encoding problem
+ {
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(255.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(255.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(255.0f);
+ unsigned int uiColorValue1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
+
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(255.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(255.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(255.0f);
+ unsigned int uiColorValue2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
+
+ unsigned int uiCWLsb = m_uiCW1 & 1;
+
+ if ((uiColorValue1 >= (uiColorValue2 & uiCWLsb)) == 0 ||
+ (uiColorValue1 < (uiColorValue2 & uiCWLsb)) == 1)
+ {
+ return;
+ }
+ }
+
+ float fDistance = s_afTHDistanceTable[m_uiCW1];
+
+ unsigned int auiBestPixelSelectors[PIXELS];
+ float afBestPixelErrors[PIXELS] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
+ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX };
+ ColorFloatRGBA afrgbaBestDecodedPixels[PIXELS];
+ ColorFloatRGBA afrgbaDecodedPixel[SELECTORS];
+
+ assert(SELECTORS == 4);
+ afrgbaDecodedPixel[0] = (m_frgbaColor1 + fDistance).ClampRGB();
+ afrgbaDecodedPixel[1] = (m_frgbaColor1 - fDistance).ClampRGB();
+ afrgbaDecodedPixel[2] = ColorFloatRGBA();;
+ afrgbaDecodedPixel[3] = (m_frgbaColor2 - fDistance).ClampRGB();
+
+
+ // try each selector
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiMinSelector = 0;
+ unsigned int uiMaxSelector = SELECTORS - 1;
+
+ if (m_pafrgbaSource[uiPixel].fA < 0.5f)
+ {
+ uiMinSelector = 2;
+ uiMaxSelector = 2;
+ }
+
+ for (unsigned int uiSelector = uiMinSelector; uiSelector <= uiMaxSelector; uiSelector++)
+ {
+ float fPixelError = CalcPixelError(afrgbaDecodedPixel[uiSelector], m_afDecodedAlphas[uiPixel],
+ m_pafrgbaSource[uiPixel]);
+
+ if (fPixelError < afBestPixelErrors[uiPixel])
+ {
+ afBestPixelErrors[uiPixel] = fPixelError;
+ auiBestPixelSelectors[uiPixel] = uiSelector;
+ afrgbaBestDecodedPixels[uiPixel] = afrgbaDecodedPixel[uiSelector];
+ }
+ }
+ }
+
+
+ // add up all of the pixel errors
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestPixelErrors[uiPixel];
+ }
+
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = auiBestPixelSelectors[uiPixel];
+ m_afrgbaDecodedColors[uiPixel] = afrgbaBestDecodedPixels[uiPixel];
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 1 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_RGB8A1::TryDegenerates1(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, -2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 2 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_RGB8A1::TryDegenerates2(void)
+ {
+
+ TryDifferential(!m_boolMostLikelyFlip, 1, -2, 0);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 2, 0);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, 2);
+ TryDifferential(!m_boolMostLikelyFlip, 1, 0, -2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 3 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_RGB8A1::TryDegenerates3(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, -2);
+ TryDifferential(m_boolMostLikelyFlip, 1, -2, 2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, -2);
+ TryDifferential(m_boolMostLikelyFlip, 1, 2, 2);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // try version 4 of the degenerate search
+ // degenerate encodings use basecolor movement and a subset of the selectors to find useful encodings
+ // each subsequent version of the degenerate search uses more basecolor movement and is less likely to
+ // be successfull
+ //
+ void Block4x4Encoding_RGB8A1::TryDegenerates4(void)
+ {
+
+ TryDifferential(m_boolMostLikelyFlip, 1, -4, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 4, 0);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, 4);
+ TryDifferential(m_boolMostLikelyFlip, 1, 0, -4);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGB8A1::SetEncodingBits(void)
+ {
+ switch (m_mode)
+ {
+ case MODE_ETC1:
+ SetEncodingBits_ETC1();
+ break;
+
+ case MODE_T:
+ SetEncodingBits_T();
+ break;
+
+ case MODE_H:
+ SetEncodingBits_H();
+ break;
+
+ case MODE_PLANAR:
+ Block4x4Encoding_RGB8::SetEncodingBits_Planar();
+ break;
+
+ default:
+ assert(false);
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state if ETC1 mode
+ //
+ void Block4x4Encoding_RGB8A1::SetEncodingBits_ETC1(void)
+ {
+
+ // there is no individual mode in RGB8A1
+ assert(m_boolDiff);
+
+ int iRed1 = m_frgbaColor1.IntRed(31.0f);
+ int iGreen1 = m_frgbaColor1.IntGreen(31.0f);
+ int iBlue1 = m_frgbaColor1.IntBlue(31.0f);
+
+ int iRed2 = m_frgbaColor2.IntRed(31.0f);
+ int iGreen2 = m_frgbaColor2.IntGreen(31.0f);
+ int iBlue2 = m_frgbaColor2.IntBlue(31.0f);
+
+ int iDRed2 = iRed2 - iRed1;
+ int iDGreen2 = iGreen2 - iGreen1;
+ int iDBlue2 = iBlue2 - iBlue1;
+
+ assert(iDRed2 >= -4 && iDRed2 < 4);
+ assert(iDGreen2 >= -4 && iDGreen2 < 4);
+ assert(iDBlue2 >= -4 && iDBlue2 < 4);
+
+ m_pencodingbitsRGB8->differential.red1 = iRed1;
+ m_pencodingbitsRGB8->differential.green1 = iGreen1;
+ m_pencodingbitsRGB8->differential.blue1 = iBlue1;
+
+ m_pencodingbitsRGB8->differential.dred2 = iDRed2;
+ m_pencodingbitsRGB8->differential.dgreen2 = iDGreen2;
+ m_pencodingbitsRGB8->differential.dblue2 = iDBlue2;
+
+ m_pencodingbitsRGB8->individual.cw1 = m_uiCW1;
+ m_pencodingbitsRGB8->individual.cw2 = m_uiCW2;
+
+ SetEncodingBits_Selectors();
+
+ // in RGB8A1 encoding bits, opaque replaces differential
+ m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
+
+ m_pencodingbitsRGB8->individual.flip = m_boolFlip;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state if T mode
+ //
+ void Block4x4Encoding_RGB8A1::SetEncodingBits_T(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_T);
+ assert(m_boolDiff == true);
+
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+
+ m_pencodingbitsRGB8->t.red1a = uiRed1 >> 2;
+ m_pencodingbitsRGB8->t.red1b = uiRed1;
+ m_pencodingbitsRGB8->t.green1 = uiGreen1;
+ m_pencodingbitsRGB8->t.blue1 = uiBlue1;
+
+ m_pencodingbitsRGB8->t.red2 = uiRed2;
+ m_pencodingbitsRGB8->t.green2 = uiGreen2;
+ m_pencodingbitsRGB8->t.blue2 = uiBlue2;
+
+ m_pencodingbitsRGB8->t.da = m_uiCW1 >> 1;
+ m_pencodingbitsRGB8->t.db = m_uiCW1;
+
+ // in RGB8A1 encoding bits, opaque replaces differential
+ m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
+
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+
+ // create an invalid R differential to trigger T mode
+ m_pencodingbitsRGB8->t.detect1 = 0;
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ if (iRed2 >= 4)
+ {
+ m_pencodingbitsRGB8->t.detect1 = 7;
+ m_pencodingbitsRGB8->t.detect2 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->t.detect1 = 0;
+ m_pencodingbitsRGB8->t.detect2 = 1;
+ }
+
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+
+ // make sure red overflows
+ assert(iRed2 < 0 || iRed2 > 31);
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state if H mode
+ //
+ // colors and selectors may need to swap in order to generate lsb of distance index
+ //
+ void Block4x4Encoding_RGB8A1::SetEncodingBits_H(void)
+ {
+ static const bool SANITY_CHECK = true;
+
+ assert(m_mode == MODE_H);
+ assert(m_boolDiff == true);
+
+ unsigned int uiRed1 = (unsigned int)m_frgbaColor1.IntRed(15.0f);
+ unsigned int uiGreen1 = (unsigned int)m_frgbaColor1.IntGreen(15.0f);
+ unsigned int uiBlue1 = (unsigned int)m_frgbaColor1.IntBlue(15.0f);
+
+ unsigned int uiRed2 = (unsigned int)m_frgbaColor2.IntRed(15.0f);
+ unsigned int uiGreen2 = (unsigned int)m_frgbaColor2.IntGreen(15.0f);
+ unsigned int uiBlue2 = (unsigned int)m_frgbaColor2.IntBlue(15.0f);
+
+ unsigned int uiColor1 = (uiRed1 << 16) + (uiGreen1 << 8) + uiBlue1;
+ unsigned int uiColor2 = (uiRed2 << 16) + (uiGreen2 << 8) + uiBlue2;
+
+ bool boolOddDistance = m_uiCW1 & 1;
+ bool boolSwapColors = (uiColor1 < uiColor2) ^ !boolOddDistance;
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed2;
+ m_pencodingbitsRGB8->h.green1a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue2 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue2 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue2;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed1;
+ m_pencodingbitsRGB8->h.green2a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue1;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.red1 = uiRed1;
+ m_pencodingbitsRGB8->h.green1a = uiGreen1 >> 1;
+ m_pencodingbitsRGB8->h.green1b = uiGreen1;
+ m_pencodingbitsRGB8->h.blue1a = uiBlue1 >> 3;
+ m_pencodingbitsRGB8->h.blue1b = uiBlue1 >> 1;
+ m_pencodingbitsRGB8->h.blue1c = uiBlue1;
+
+ m_pencodingbitsRGB8->h.red2 = uiRed2;
+ m_pencodingbitsRGB8->h.green2a = uiGreen2 >> 1;
+ m_pencodingbitsRGB8->h.green2b = uiGreen2;
+ m_pencodingbitsRGB8->h.blue2 = uiBlue2;
+
+ m_pencodingbitsRGB8->h.da = m_uiCW1 >> 2;
+ m_pencodingbitsRGB8->h.db = m_uiCW1 >> 1;
+ }
+
+ // in RGB8A1 encoding bits, opaque replaces differential
+ m_pencodingbitsRGB8->differential.diff = !m_boolPunchThroughPixels;
+
+ Block4x4Encoding_ETC1::SetEncodingBits_Selectors();
+
+ if (boolSwapColors)
+ {
+ m_pencodingbitsRGB8->h.selectors ^= 0x0000FFFF;
+ }
+
+ // create an invalid R differential to trigger T mode
+ m_pencodingbitsRGB8->h.detect1 = 0;
+ m_pencodingbitsRGB8->h.detect2 = 0;
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ int iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ int iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+ if (iRed2 < 0 || iRed2 > 31)
+ {
+ m_pencodingbitsRGB8->h.detect1 = 1;
+ }
+ if (iGreen2 >= 4)
+ {
+ m_pencodingbitsRGB8->h.detect2 = 7;
+ m_pencodingbitsRGB8->h.detect3 = 0;
+ }
+ else
+ {
+ m_pencodingbitsRGB8->h.detect2 = 0;
+ m_pencodingbitsRGB8->h.detect3 = 1;
+ }
+
+ if (SANITY_CHECK)
+ {
+ iRed2 = (int)m_pencodingbitsRGB8->differential.red1 + (int)m_pencodingbitsRGB8->differential.dred2;
+ iGreen2 = (int)m_pencodingbitsRGB8->differential.green1 + (int)m_pencodingbitsRGB8->differential.dgreen2;
+
+ // make sure red doesn't overflow and green does
+ assert(iRed2 >= 0 && iRed2 <= 31);
+ assert(iGreen2 < 0 || iGreen2 > 31);
+ }
+
+ }
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGB8A1_Opaque
+ // ####################################################################################################
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGB8A1_Opaque::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolPunchThroughPixels);
+ assert(!m_boolTransparent);
+ assert(!m_boolDone);
+
+ switch (m_uiEncodingIterations)
+ {
+ case 0:
+ PerformFirstIteration();
+ break;
+
+ case 1:
+ Block4x4Encoding_ETC1::TryDifferential(m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 2:
+ Block4x4Encoding_ETC1::TryDifferential(!m_boolMostLikelyFlip, 1, 0, 0);
+ break;
+
+ case 3:
+ Block4x4Encoding_RGB8::TryPlanar(1);
+ break;
+
+ case 4:
+ Block4x4Encoding_RGB8::TryTAndH(1);
+ if (a_fEffort <= 49.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 5:
+ Block4x4Encoding_ETC1::TryDegenerates1();
+ if (a_fEffort <= 59.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 6:
+ Block4x4Encoding_ETC1::TryDegenerates2();
+ if (a_fEffort <= 69.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 7:
+ Block4x4Encoding_ETC1::TryDegenerates3();
+ if (a_fEffort <= 79.5f)
+ {
+ m_boolDone = true;
+ }
+ break;
+
+ case 8:
+ Block4x4Encoding_ETC1::TryDegenerates4();
+ m_boolDone = true;
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ m_uiEncodingIterations++;
+ SetDoneIfPerfect();
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find best initial encoding to ensure block has a valid encoding
+ //
+ void Block4x4Encoding_RGB8A1_Opaque::PerformFirstIteration(void)
+ {
+
+ // set decoded alphas
+ // calculate alpha error
+ m_fError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+
+ float fDeltaA = 1.0f - m_pafrgbaSource[uiPixel].fA;
+ m_fError += fDeltaA * fDeltaA;
+ }
+
+ CalculateMostLikelyFlip();
+
+ m_fError = FLT_MAX;
+
+ Block4x4Encoding_ETC1::TryDifferential(m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ Block4x4Encoding_ETC1::TryDifferential(!m_boolMostLikelyFlip, 0, 0, 0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ Block4x4Encoding_RGB8::TryPlanar(0);
+ SetDoneIfPerfect();
+ if (m_boolDone)
+ {
+ return;
+ }
+ Block4x4Encoding_RGB8::TryTAndH(0);
+ SetDoneIfPerfect();
+ }
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGB8A1_Transparent
+ // ####################################################################################################
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGB8A1_Transparent::PerformIteration(float )
+ {
+ assert(!m_boolOpaque);
+ assert(m_boolTransparent);
+ assert(!m_boolDone);
+ assert(m_uiEncodingIterations == 0);
+
+ m_mode = MODE_ETC1;
+ m_boolDiff = true;
+ m_boolFlip = false;
+
+ m_uiCW1 = 0;
+ m_uiCW2 = 0;
+
+ m_frgbaColor1 = ColorFloatRGBA();
+ m_frgbaColor2 = ColorFloatRGBA();
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiSelectors[uiPixel] = TRANSPARENT_SELECTOR;
+
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+
+ CalcBlockError();
+
+ m_boolDone = true;
+ m_uiEncodingIterations++;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.h
new file mode 100644
index 0000000000..ff26e462f8
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGB8A1.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding_RGB8.h"
+#include "EtcErrorMetric.h"
+#include "EtcBlock4x4EncodingBits.h"
+
+namespace Etc
+{
+
+ // ################################################################################
+ // Block4x4Encoding_RGB8A1
+ // RGB8A1 if not completely opaque or transparent
+ // ################################################################################
+
+ class Block4x4Encoding_RGB8A1 : public Block4x4Encoding_RGB8
+ {
+ public:
+
+ static const unsigned int TRANSPARENT_SELECTOR = 2;
+
+ Block4x4Encoding_RGB8A1(void);
+ virtual ~Block4x4Encoding_RGB8A1(void);
+
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits,
+ ErrorMetric a_errormetric);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ void InitFromEncodingBits_ETC1(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric);
+
+ void InitFromEncodingBits_T(void);
+ void InitFromEncodingBits_H(void);
+
+ void PerformFirstIteration(void);
+
+ void Decode_ETC1(void);
+ void DecodePixels_T(void);
+ void DecodePixels_H(void);
+ void SetEncodingBits_ETC1(void);
+ void SetEncodingBits_T(void);
+ void SetEncodingBits_H(void);
+
+ protected:
+
+ bool m_boolOpaque; // all source pixels have alpha >= 0.5
+ bool m_boolTransparent; // all source pixels have alpha < 0.5
+ bool m_boolPunchThroughPixels; // some source pixels have alpha < 0.5
+
+ static float s_aafCwOpaqueUnsetTable[CW_RANGES][SELECTORS];
+
+ private:
+
+ void TryDifferential(bool a_boolFlip, unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2);
+ void TryDifferentialHalf(DifferentialTrys::Half *a_phalf);
+
+ void TryT(unsigned int a_uiRadius);
+ void TryT_BestSelectorCombination(void);
+ void TryH(unsigned int a_uiRadius);
+ void TryH_BestSelectorCombination(void);
+
+ void TryDegenerates1(void);
+ void TryDegenerates2(void);
+ void TryDegenerates3(void);
+ void TryDegenerates4(void);
+
+ };
+
+ // ################################################################################
+ // Block4x4Encoding_RGB8A1_Opaque
+ // RGB8A1 if all pixels have alpha==1
+ // ################################################################################
+
+ class Block4x4Encoding_RGB8A1_Opaque : public Block4x4Encoding_RGB8A1
+ {
+ public:
+
+ virtual void PerformIteration(float a_fEffort);
+
+ void PerformFirstIteration(void);
+
+ private:
+
+ };
+
+ // ################################################################################
+ // Block4x4Encoding_RGB8A1_Transparent
+ // RGB8A1 if all pixels have alpha==0
+ // ################################################################################
+
+ class Block4x4Encoding_RGB8A1_Transparent : public Block4x4Encoding_RGB8A1
+ {
+ public:
+
+ virtual void PerformIteration(float a_fEffort);
+
+ private:
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.cpp b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.cpp
new file mode 100644
index 0000000000..600c7ab405
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.cpp
@@ -0,0 +1,474 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcBlock4x4Encoding_RGBA8.cpp contains:
+ Block4x4Encoding_RGBA8
+ Block4x4Encoding_RGBA8_Opaque
+ Block4x4Encoding_RGBA8_Transparent
+
+These encoders are used when targetting file format RGBA8.
+
+Block4x4Encoding_RGBA8_Opaque is used when all pixels in the 4x4 block are opaque
+Block4x4Encoding_RGBA8_Transparent is used when all pixels in the 4x4 block are transparent
+Block4x4Encoding_RGBA8 is used when there is a mixture of alphas in the 4x4 block
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcBlock4x4Encoding_RGBA8.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcBlock4x4.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <float.h>
+#include <limits>
+
+namespace Etc
+{
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGBA8
+ // ####################################################################################################
+
+ float Block4x4Encoding_RGBA8::s_aafModifierTable[MODIFIER_TABLE_ENTRYS][ALPHA_SELECTORS]
+ {
+ { -3.0f / 255.0f, -6.0f / 255.0f, -9.0f / 255.0f, -15.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 8.0f / 255.0f, 14.0f / 255.0f },
+ { -3.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, -13.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f, 12.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 12.0f / 255.0f },
+ { -2.0f / 255.0f, -4.0f / 255.0f, -6.0f / 255.0f, -13.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 12.0f / 255.0f },
+
+ { -3.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -12.0f / 255.0f, 2.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 11.0f / 255.0f },
+ { -3.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f, 10.0f / 255.0f },
+ { -4.0f / 255.0f, -7.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
+ { -3.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -11.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 10.0f / 255.0f },
+
+ { -2.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -4.0f / 255.0f, -8.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 3.0f / 255.0f, 7.0f / 255.0f, 9.0f / 255.0f },
+ { -2.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 1.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
+
+ { -3.0f / 255.0f, -4.0f / 255.0f, -7.0f / 255.0f, -10.0f / 255.0f, 2.0f / 255.0f, 3.0f / 255.0f, 6.0f / 255.0f, 9.0f / 255.0f },
+ { -1.0f / 255.0f, -2.0f / 255.0f, -3.0f / 255.0f, -10.0f / 255.0f, 0.0f / 255.0f, 1.0f / 255.0f, 2.0f / 255.0f, 9.0f / 255.0f },
+ { -4.0f / 255.0f, -6.0f / 255.0f, -8.0f / 255.0f, -9.0f / 255.0f, 3.0f / 255.0f, 5.0f / 255.0f, 7.0f / 255.0f, 8.0f / 255.0f },
+ { -3.0f / 255.0f, -5.0f / 255.0f, -7.0f / 255.0f, -9.0f / 255.0f, 2.0f / 255.0f, 4.0f / 255.0f, 6.0f / 255.0f, 8.0f / 255.0f }
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Block4x4Encoding_RGBA8::Block4x4Encoding_RGBA8(void)
+ {
+
+ m_pencodingbitsA8 = nullptr;
+
+ }
+ Block4x4Encoding_RGBA8::~Block4x4Encoding_RGBA8(void) {}
+ // ----------------------------------------------------------------------------------------------------
+ // initialization prior to encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits
+ //
+ void Block4x4Encoding_RGBA8::InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric)
+ {
+ Block4x4Encoding::Init(a_pblockParent, a_pafrgbaSource,a_errormetric);
+
+ m_pencodingbitsA8 = (Block4x4EncodingBits_A8 *)a_paucEncodingBits;
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)(a_paucEncodingBits + sizeof(Block4x4EncodingBits_A8));
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // initialization from the encoding bits of a previous encoding
+ // a_pblockParent points to the block associated with this encoding
+ // a_errormetric is used to choose the best encoding
+ // a_pafrgbaSource points to a 4x4 block subset of the source image
+ // a_paucEncodingBits points to the final encoding bits of a previous encoding
+ //
+ void Block4x4Encoding_RGBA8::InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric)
+ {
+
+ m_pencodingbitsA8 = (Block4x4EncodingBits_A8 *)a_paucEncodingBits;
+ m_pencodingbitsRGB8 = (Block4x4EncodingBits_RGB8 *)(a_paucEncodingBits + sizeof(Block4x4EncodingBits_A8));
+
+ // init RGB portion
+ Block4x4Encoding_RGB8::InitFromEncodingBits(a_pblockParent,
+ (unsigned char *) m_pencodingbitsRGB8,
+ a_pafrgbaSource,
+ a_errormetric);
+
+ // init A8 portion
+ // has to be done after InitFromEncodingBits()
+ {
+ m_fBase = m_pencodingbitsA8->data.base / 255.0f;
+ m_fMultiplier = (float)m_pencodingbitsA8->data.multiplier;
+ m_uiModifierTableIndex = m_pencodingbitsA8->data.table;
+
+ unsigned long long int ulliSelectorBits = 0;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors0 << 40;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors1 << 32;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors2 << 24;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors3 << 16;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors4 << 8;
+ ulliSelectorBits |= (unsigned long long int)m_pencodingbitsA8->data.selectors5;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ m_auiAlphaSelectors[uiPixel] = (ulliSelectorBits >> uiShift) & (ALPHA_SELECTORS - 1);
+ }
+
+ // decode the alphas
+ // calc alpha error
+ m_fError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afDecodedAlphas[uiPixel] = DecodePixelAlpha(m_fBase, m_fMultiplier,
+ m_uiModifierTableIndex,
+ m_auiAlphaSelectors[uiPixel]);
+
+ float fDeltaAlpha = m_afDecodedAlphas[uiPixel] - m_pafrgbaSource[uiPixel].fA;
+ m_fError += fDeltaAlpha * fDeltaAlpha;
+ }
+ }
+
+ // redo error calc to include alpha
+ CalcBlockError();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ // similar to Block4x4Encoding_RGB8_Base::Encode_RGB8(), but with alpha added
+ //
+ void Block4x4Encoding_RGBA8::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+
+ if (m_uiEncodingIterations == 0)
+ {
+ if (a_fEffort < 24.9f)
+ {
+ CalculateA8(0.0f);
+ }
+ else if (a_fEffort < 49.9f)
+ {
+ CalculateA8(1.0f);
+ }
+ else
+ {
+ CalculateA8(2.0f);
+ }
+ }
+
+ Block4x4Encoding_RGB8::PerformIteration(a_fEffort);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // find the best combination of base alpga, multiplier and selectors
+ //
+ // a_fRadius limits the range of base alpha to try
+ //
+ void Block4x4Encoding_RGBA8::CalculateA8(float a_fRadius)
+ {
+
+ // find min/max alpha
+ float fMinAlpha = 1.0f;
+ float fMaxAlpha = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fAlpha = m_pafrgbaSource[uiPixel].fA;
+
+ // ignore border pixels
+ if (isnan(fAlpha))
+ {
+ continue;
+ }
+
+ if (fAlpha < fMinAlpha)
+ {
+ fMinAlpha = fAlpha;
+ }
+ if (fAlpha > fMaxAlpha)
+ {
+ fMaxAlpha = fAlpha;
+ }
+ }
+ assert(fMinAlpha <= fMaxAlpha);
+
+ float fAlphaRange = fMaxAlpha - fMinAlpha;
+
+ // try each modifier table entry
+ m_fError = FLT_MAX; // artificially high value
+ for (unsigned int uiTableEntry = 0; uiTableEntry < MODIFIER_TABLE_ENTRYS; uiTableEntry++)
+ {
+ static const unsigned int MIN_VALUE_SELECTOR = 3;
+ static const unsigned int MAX_VALUE_SELECTOR = 7;
+
+ float fTableEntryCenter = -s_aafModifierTable[uiTableEntry][MIN_VALUE_SELECTOR];
+
+ float fTableEntryRange = s_aafModifierTable[uiTableEntry][MAX_VALUE_SELECTOR] -
+ s_aafModifierTable[uiTableEntry][MIN_VALUE_SELECTOR];
+
+ float fCenterRatio = fTableEntryCenter / fTableEntryRange;
+
+ float fCenter = fMinAlpha + fCenterRatio*fAlphaRange;
+ fCenter = roundf(255.0f * fCenter) / 255.0f;
+
+ float fMinBase = fCenter - (a_fRadius / 255.0f);
+ if (fMinBase < 0.0f)
+ {
+ fMinBase = 0.0f;
+ }
+
+ float fMaxBase = fCenter + (a_fRadius / 255.0f);
+ if (fMaxBase > 1.0f)
+ {
+ fMaxBase = 1.0f;
+ }
+
+ for (float fBase = fMinBase; fBase <= fMaxBase; fBase += (0.999999f / 255.0f))
+ {
+
+ float fRangeMultiplier = roundf(fAlphaRange / fTableEntryRange);
+
+ float fMinMultiplier = fRangeMultiplier - a_fRadius;
+ if (fMinMultiplier < 1.0f)
+ {
+ fMinMultiplier = 1.0f;
+ }
+ else if (fMinMultiplier > 15.0f)
+ {
+ fMinMultiplier = 15.0f;
+ }
+
+ float fMaxMultiplier = fRangeMultiplier + a_fRadius;
+ if (fMaxMultiplier < 1.0f)
+ {
+ fMaxMultiplier = 1.0f;
+ }
+ else if (fMaxMultiplier > 15.0f)
+ {
+ fMaxMultiplier = 15.0f;
+ }
+
+ for (float fMultiplier = fMinMultiplier; fMultiplier <= fMaxMultiplier; fMultiplier += 1.0f)
+ {
+ // find best selector for each pixel
+ unsigned int auiBestSelectors[PIXELS];
+ float afBestAlphaError[PIXELS];
+ float afBestDecodedAlphas[PIXELS];
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ float fBestPixelAlphaError = FLT_MAX;
+ for (unsigned int uiSelector = 0; uiSelector < ALPHA_SELECTORS; uiSelector++)
+ {
+ float fDecodedAlpha = DecodePixelAlpha(fBase, fMultiplier, uiTableEntry, uiSelector);
+
+ // border pixels (NAN) should have zero error
+ float fPixelDeltaAlpha = isnan(m_pafrgbaSource[uiPixel].fA) ?
+ 0.0f :
+ fDecodedAlpha - m_pafrgbaSource[uiPixel].fA;
+
+ float fPixelAlphaError = fPixelDeltaAlpha * fPixelDeltaAlpha;
+
+ if (fPixelAlphaError < fBestPixelAlphaError)
+ {
+ fBestPixelAlphaError = fPixelAlphaError;
+ auiBestSelectors[uiPixel] = uiSelector;
+ afBestAlphaError[uiPixel] = fBestPixelAlphaError;
+ afBestDecodedAlphas[uiPixel] = fDecodedAlpha;
+ }
+ }
+ }
+
+ float fBlockError = 0.0f;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ fBlockError += afBestAlphaError[uiPixel];
+ }
+
+ if (fBlockError < m_fError)
+ {
+ m_fError = fBlockError;
+
+ m_fBase = fBase;
+ m_fMultiplier = fMultiplier;
+ m_uiModifierTableIndex = uiTableEntry;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_auiAlphaSelectors[uiPixel] = auiBestSelectors[uiPixel];
+ m_afDecodedAlphas[uiPixel] = afBestDecodedAlphas[uiPixel];
+ }
+ }
+ }
+ }
+
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGBA8::SetEncodingBits(void)
+ {
+
+ // set the RGB8 portion
+ Block4x4Encoding_RGB8::SetEncodingBits();
+
+ // set the A8 portion
+ {
+ m_pencodingbitsA8->data.base = (unsigned char)roundf(255.0f * m_fBase);
+ m_pencodingbitsA8->data.table = m_uiModifierTableIndex;
+ m_pencodingbitsA8->data.multiplier = (unsigned char)roundf(m_fMultiplier);
+
+ unsigned long long int ulliSelectorBits = 0;
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ unsigned int uiShift = 45 - (3 * uiPixel);
+ ulliSelectorBits |= ((unsigned long long int)m_auiAlphaSelectors[uiPixel]) << uiShift;
+ }
+
+ m_pencodingbitsA8->data.selectors0 = ulliSelectorBits >> 40;
+ m_pencodingbitsA8->data.selectors1 = ulliSelectorBits >> 32;
+ m_pencodingbitsA8->data.selectors2 = ulliSelectorBits >> 24;
+ m_pencodingbitsA8->data.selectors3 = ulliSelectorBits >> 16;
+ m_pencodingbitsA8->data.selectors4 = ulliSelectorBits >> 8;
+ m_pencodingbitsA8->data.selectors5 = ulliSelectorBits;
+ }
+
+ }
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGBA8_Opaque
+ // ####################################################################################################
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGBA8_Opaque::PerformIteration(float a_fEffort)
+ {
+ assert(!m_boolDone);
+
+ if (m_uiEncodingIterations == 0)
+ {
+ m_fError = 0.0f;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afDecodedAlphas[uiPixel] = 1.0f;
+ }
+ }
+
+ Block4x4Encoding_RGB8::PerformIteration(a_fEffort);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGBA8_Opaque::SetEncodingBits(void)
+ {
+
+ // set the RGB8 portion
+ Block4x4Encoding_RGB8::SetEncodingBits();
+
+ // set the A8 portion
+ m_pencodingbitsA8->data.base = 255;
+ m_pencodingbitsA8->data.table = 15;
+ m_pencodingbitsA8->data.multiplier = 15;
+ m_pencodingbitsA8->data.selectors0 = 0xFF;
+ m_pencodingbitsA8->data.selectors1 = 0xFF;
+ m_pencodingbitsA8->data.selectors2 = 0xFF;
+ m_pencodingbitsA8->data.selectors3 = 0xFF;
+ m_pencodingbitsA8->data.selectors4 = 0xFF;
+ m_pencodingbitsA8->data.selectors5 = 0xFF;
+
+ }
+
+ // ####################################################################################################
+ // Block4x4Encoding_RGBA8_Transparent
+ // ####################################################################################################
+
+ // ----------------------------------------------------------------------------------------------------
+ // perform a single encoding iteration
+ // replace the encoding if a better encoding was found
+ // subsequent iterations generally take longer for each iteration
+ // set m_boolDone if encoding is perfect or encoding is finished based on a_fEffort
+ //
+ void Block4x4Encoding_RGBA8_Transparent::PerformIteration(float )
+ {
+ assert(!m_boolDone);
+ assert(m_uiEncodingIterations == 0);
+
+ m_mode = MODE_ETC1;
+ m_boolDiff = true;
+ m_boolFlip = false;
+
+ for (unsigned int uiPixel = 0; uiPixel < PIXELS; uiPixel++)
+ {
+ m_afrgbaDecodedColors[uiPixel] = ColorFloatRGBA();
+ m_afDecodedAlphas[uiPixel] = 0.0f;
+ }
+
+ m_fError = 0.0f;
+
+ m_boolDone = true;
+ m_uiEncodingIterations++;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits based on encoding state
+ //
+ void Block4x4Encoding_RGBA8_Transparent::SetEncodingBits(void)
+ {
+
+ Block4x4Encoding_RGB8::SetEncodingBits();
+
+ // set the A8 portion
+ m_pencodingbitsA8->data.base = 0;
+ m_pencodingbitsA8->data.table = 0;
+ m_pencodingbitsA8->data.multiplier = 1;
+ m_pencodingbitsA8->data.selectors0 = 0;
+ m_pencodingbitsA8->data.selectors1 = 0;
+ m_pencodingbitsA8->data.selectors2 = 0;
+ m_pencodingbitsA8->data.selectors3 = 0;
+ m_pencodingbitsA8->data.selectors4 = 0;
+ m_pencodingbitsA8->data.selectors5 = 0;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+}
diff --git a/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.h b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.h
new file mode 100644
index 0000000000..5765d36b90
--- /dev/null
+++ b/thirdparty/etc2comp/EtcBlock4x4Encoding_RGBA8.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcBlock4x4Encoding_RGB8.h"
+
+namespace Etc
+{
+ class Block4x4EncodingBits_A8;
+
+ // ################################################################################
+ // Block4x4Encoding_RGBA8
+ // RGBA8 if not completely opaque or transparent
+ // ################################################################################
+
+ class Block4x4Encoding_RGBA8 : public Block4x4Encoding_RGB8
+ {
+ public:
+
+ Block4x4Encoding_RGBA8(void);
+ virtual ~Block4x4Encoding_RGBA8(void);
+
+ virtual void InitFromSource(Block4x4 *a_pblockParent,
+ ColorFloatRGBA *a_pafrgbaSource,
+ unsigned char *a_paucEncodingBits, ErrorMetric a_errormetric);
+
+ virtual void InitFromEncodingBits(Block4x4 *a_pblockParent,
+ unsigned char *a_paucEncodingBits,
+ ColorFloatRGBA *a_pafrgbaSource,
+ ErrorMetric a_errormetric);
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ protected:
+
+ static const unsigned int MODIFIER_TABLE_ENTRYS = 16;
+ static const unsigned int ALPHA_SELECTOR_BITS = 3;
+ static const unsigned int ALPHA_SELECTORS = 1 << ALPHA_SELECTOR_BITS;
+
+ static float s_aafModifierTable[MODIFIER_TABLE_ENTRYS][ALPHA_SELECTORS];
+
+ void CalculateA8(float a_fRadius);
+
+ Block4x4EncodingBits_A8 *m_pencodingbitsA8; // A8 portion of Block4x4EncodingBits_RGBA8
+
+ float m_fBase;
+ float m_fMultiplier;
+ unsigned int m_uiModifierTableIndex;
+ unsigned int m_auiAlphaSelectors[PIXELS];
+
+ private:
+
+ inline float DecodePixelAlpha(float a_fBase, float a_fMultiplier,
+ unsigned int a_uiTableIndex, unsigned int a_uiSelector)
+ {
+ float fPixelAlpha = a_fBase +
+ a_fMultiplier*s_aafModifierTable[a_uiTableIndex][a_uiSelector];
+ if (fPixelAlpha < 0.0f)
+ {
+ fPixelAlpha = 0.0f;
+ }
+ else if (fPixelAlpha > 1.0f)
+ {
+ fPixelAlpha = 1.0f;
+ }
+
+ return fPixelAlpha;
+ }
+
+ };
+
+ // ################################################################################
+ // Block4x4Encoding_RGBA8_Opaque
+ // RGBA8 if all pixels have alpha==1
+ // ################################################################################
+
+ class Block4x4Encoding_RGBA8_Opaque : public Block4x4Encoding_RGBA8
+ {
+ public:
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ };
+
+ // ################################################################################
+ // Block4x4Encoding_RGBA8_Transparent
+ // RGBA8 if all pixels have alpha==0
+ // ################################################################################
+
+ class Block4x4Encoding_RGBA8_Transparent : public Block4x4Encoding_RGBA8
+ {
+ public:
+
+ virtual void PerformIteration(float a_fEffort);
+
+ virtual void SetEncodingBits(void);
+
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcColor.h b/thirdparty/etc2comp/EtcColor.h
new file mode 100644
index 0000000000..7ceae05b65
--- /dev/null
+++ b/thirdparty/etc2comp/EtcColor.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <math.h>
+
+namespace Etc
+{
+
+ inline float LogToLinear(float a_fLog)
+ {
+ static const float ALPHA = 0.055f;
+ static const float ONE_PLUS_ALPHA = 1.0f + ALPHA;
+
+ if (a_fLog <= 0.04045f)
+ {
+ return a_fLog / 12.92f;
+ }
+ else
+ {
+ return powf((a_fLog + ALPHA) / ONE_PLUS_ALPHA, 2.4f);
+ }
+ }
+
+ inline float LinearToLog(float &a_fLinear)
+ {
+ static const float ALPHA = 0.055f;
+ static const float ONE_PLUS_ALPHA = 1.0f + ALPHA;
+
+ if (a_fLinear <= 0.0031308f)
+ {
+ return 12.92f * a_fLinear;
+ }
+ else
+ {
+ return ONE_PLUS_ALPHA * powf(a_fLinear, (1.0f/2.4f)) - ALPHA;
+ }
+ }
+
+ class ColorR8G8B8A8
+ {
+ public:
+
+ unsigned char ucR;
+ unsigned char ucG;
+ unsigned char ucB;
+ unsigned char ucA;
+
+ };
+}
diff --git a/thirdparty/etc2comp/EtcColorFloatRGBA.h b/thirdparty/etc2comp/EtcColorFloatRGBA.h
new file mode 100644
index 0000000000..f2ca2c1f71
--- /dev/null
+++ b/thirdparty/etc2comp/EtcColorFloatRGBA.h
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcConfig.h"
+#include "EtcColor.h"
+
+#include <math.h>
+
+namespace Etc
+{
+
+ class ColorFloatRGBA
+ {
+ public:
+
+ ColorFloatRGBA(void)
+ {
+ fR = fG = fB = fA = 0.0f;
+ }
+
+ ColorFloatRGBA(float a_fR, float a_fG, float a_fB, float a_fA)
+ {
+ fR = a_fR;
+ fG = a_fG;
+ fB = a_fB;
+ fA = a_fA;
+ }
+
+ inline ColorFloatRGBA operator+(ColorFloatRGBA& a_rfrgba)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = fR + a_rfrgba.fR;
+ frgba.fG = fG + a_rfrgba.fG;
+ frgba.fB = fB + a_rfrgba.fB;
+ frgba.fA = fA + a_rfrgba.fA;
+ return frgba;
+ }
+
+ inline ColorFloatRGBA operator+(float a_f)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = fR + a_f;
+ frgba.fG = fG + a_f;
+ frgba.fB = fB + a_f;
+ frgba.fA = fA;
+ return frgba;
+ }
+
+ inline ColorFloatRGBA operator-(float a_f)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = fR - a_f;
+ frgba.fG = fG - a_f;
+ frgba.fB = fB - a_f;
+ frgba.fA = fA;
+ return frgba;
+ }
+
+ inline ColorFloatRGBA operator-(ColorFloatRGBA& a_rfrgba)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = fR - a_rfrgba.fR;
+ frgba.fG = fG - a_rfrgba.fG;
+ frgba.fB = fB - a_rfrgba.fB;
+ frgba.fA = fA - a_rfrgba.fA;
+ return frgba;
+ }
+
+ inline ColorFloatRGBA operator*(float a_f)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = fR * a_f;
+ frgba.fG = fG * a_f;
+ frgba.fB = fB * a_f;
+ frgba.fA = fA;
+
+ return frgba;
+ }
+
+ inline ColorFloatRGBA ScaleRGB(float a_f)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = a_f * fR;
+ frgba.fG = a_f * fG;
+ frgba.fB = a_f * fB;
+ frgba.fA = fA;
+
+ return frgba;
+ }
+
+ inline ColorFloatRGBA RoundRGB(void)
+ {
+ ColorFloatRGBA frgba;
+ frgba.fR = roundf(fR);
+ frgba.fG = roundf(fG);
+ frgba.fB = roundf(fB);
+
+ return frgba;
+ }
+
+ inline ColorFloatRGBA ToLinear()
+ {
+ ColorFloatRGBA frgbaLinear;
+ frgbaLinear.fR = LogToLinear(fR);
+ frgbaLinear.fG = LogToLinear(fG);
+ frgbaLinear.fB = LogToLinear(fB);
+ frgbaLinear.fA = fA;
+
+ return frgbaLinear;
+ }
+
+ inline ColorFloatRGBA ToLog(void)
+ {
+ ColorFloatRGBA frgbaLog;
+ frgbaLog.fR = LinearToLog(fR);
+ frgbaLog.fG = LinearToLog(fG);
+ frgbaLog.fB = LinearToLog(fB);
+ frgbaLog.fA = fA;
+
+ return frgbaLog;
+ }
+
+ inline static ColorFloatRGBA ConvertFromRGBA8(unsigned char a_ucR,
+ unsigned char a_ucG, unsigned char a_ucB, unsigned char a_ucA)
+ {
+ ColorFloatRGBA frgba;
+
+ frgba.fR = (float)a_ucR / 255.0f;
+ frgba.fG = (float)a_ucG / 255.0f;
+ frgba.fB = (float)a_ucB / 255.0f;
+ frgba.fA = (float)a_ucA / 255.0f;
+
+ return frgba;
+ }
+
+ inline static ColorFloatRGBA ConvertFromRGB4(unsigned char a_ucR4,
+ unsigned char a_ucG4,
+ unsigned char a_ucB4)
+ {
+ ColorFloatRGBA frgba;
+
+ unsigned char ucR8 = (unsigned char)((a_ucR4 << 4) + a_ucR4);
+ unsigned char ucG8 = (unsigned char)((a_ucG4 << 4) + a_ucG4);
+ unsigned char ucB8 = (unsigned char)((a_ucB4 << 4) + a_ucB4);
+
+ frgba.fR = (float)ucR8 / 255.0f;
+ frgba.fG = (float)ucG8 / 255.0f;
+ frgba.fB = (float)ucB8 / 255.0f;
+ frgba.fA = 1.0f;
+
+ return frgba;
+ }
+
+ inline static ColorFloatRGBA ConvertFromRGB5(unsigned char a_ucR5,
+ unsigned char a_ucG5,
+ unsigned char a_ucB5)
+ {
+ ColorFloatRGBA frgba;
+
+ unsigned char ucR8 = (unsigned char)((a_ucR5 << 3) + (a_ucR5 >> 2));
+ unsigned char ucG8 = (unsigned char)((a_ucG5 << 3) + (a_ucG5 >> 2));
+ unsigned char ucB8 = (unsigned char)((a_ucB5 << 3) + (a_ucB5 >> 2));
+
+ frgba.fR = (float)ucR8 / 255.0f;
+ frgba.fG = (float)ucG8 / 255.0f;
+ frgba.fB = (float)ucB8 / 255.0f;
+ frgba.fA = 1.0f;
+
+ return frgba;
+ }
+
+ inline static ColorFloatRGBA ConvertFromR6G7B6(unsigned char a_ucR6,
+ unsigned char a_ucG7,
+ unsigned char a_ucB6)
+ {
+ ColorFloatRGBA frgba;
+
+ unsigned char ucR8 = (unsigned char)((a_ucR6 << 2) + (a_ucR6 >> 4));
+ unsigned char ucG8 = (unsigned char)((a_ucG7 << 1) + (a_ucG7 >> 6));
+ unsigned char ucB8 = (unsigned char)((a_ucB6 << 2) + (a_ucB6 >> 4));
+
+ frgba.fR = (float)ucR8 / 255.0f;
+ frgba.fG = (float)ucG8 / 255.0f;
+ frgba.fB = (float)ucB8 / 255.0f;
+ frgba.fA = 1.0f;
+
+ return frgba;
+ }
+
+ // quantize to 4 bits, expand to 8 bits
+ inline ColorFloatRGBA QuantizeR4G4B4(void) const
+ {
+ ColorFloatRGBA frgba = *this;
+
+ // quantize to 4 bits
+ frgba = frgba.ClampRGB().ScaleRGB(15.0f).RoundRGB();
+ unsigned int uiR4 = (unsigned int)frgba.fR;
+ unsigned int uiG4 = (unsigned int)frgba.fG;
+ unsigned int uiB4 = (unsigned int)frgba.fB;
+
+ // expand to 8 bits
+ frgba.fR = (float) ((uiR4 << 4) + uiR4);
+ frgba.fG = (float) ((uiG4 << 4) + uiG4);
+ frgba.fB = (float) ((uiB4 << 4) + uiB4);
+
+ frgba = frgba.ScaleRGB(1.0f/255.0f);
+
+ return frgba;
+ }
+
+ // quantize to 5 bits, expand to 8 bits
+ inline ColorFloatRGBA QuantizeR5G5B5(void) const
+ {
+ ColorFloatRGBA frgba = *this;
+
+ // quantize to 5 bits
+ frgba = frgba.ClampRGB().ScaleRGB(31.0f).RoundRGB();
+ unsigned int uiR5 = (unsigned int)frgba.fR;
+ unsigned int uiG5 = (unsigned int)frgba.fG;
+ unsigned int uiB5 = (unsigned int)frgba.fB;
+
+ // expand to 8 bits
+ frgba.fR = (float)((uiR5 << 3) + (uiR5 >> 2));
+ frgba.fG = (float)((uiG5 << 3) + (uiG5 >> 2));
+ frgba.fB = (float)((uiB5 << 3) + (uiB5 >> 2));
+
+ frgba = frgba.ScaleRGB(1.0f / 255.0f);
+
+ return frgba;
+ }
+
+ // quantize to 6/7/6 bits, expand to 8 bits
+ inline ColorFloatRGBA QuantizeR6G7B6(void) const
+ {
+ ColorFloatRGBA frgba = *this;
+
+ // quantize to 6/7/6 bits
+ ColorFloatRGBA frgba6 = frgba.ClampRGB().ScaleRGB(63.0f).RoundRGB();
+ ColorFloatRGBA frgba7 = frgba.ClampRGB().ScaleRGB(127.0f).RoundRGB();
+ unsigned int uiR6 = (unsigned int)frgba6.fR;
+ unsigned int uiG7 = (unsigned int)frgba7.fG;
+ unsigned int uiB6 = (unsigned int)frgba6.fB;
+
+ // expand to 8 bits
+ frgba.fR = (float)((uiR6 << 2) + (uiR6 >> 4));
+ frgba.fG = (float)((uiG7 << 1) + (uiG7 >> 6));
+ frgba.fB = (float)((uiB6 << 2) + (uiB6 >> 4));
+
+ frgba = frgba.ScaleRGB(1.0f / 255.0f);
+
+ return frgba;
+ }
+
+ inline ColorFloatRGBA ClampRGB(void)
+ {
+ ColorFloatRGBA frgba = *this;
+ if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
+ if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
+ if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
+ if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
+ if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
+ if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
+
+ return frgba;
+ }
+
+ inline ColorFloatRGBA ClampRGBA(void)
+ {
+ ColorFloatRGBA frgba = *this;
+ if (frgba.fR < 0.0f) { frgba.fR = 0.0f; }
+ if (frgba.fR > 1.0f) { frgba.fR = 1.0f; }
+ if (frgba.fG < 0.0f) { frgba.fG = 0.0f; }
+ if (frgba.fG > 1.0f) { frgba.fG = 1.0f; }
+ if (frgba.fB < 0.0f) { frgba.fB = 0.0f; }
+ if (frgba.fB > 1.0f) { frgba.fB = 1.0f; }
+ if (frgba.fA < 0.0f) { frgba.fA = 0.0f; }
+ if (frgba.fA > 1.0f) { frgba.fA = 1.0f; }
+
+ return frgba;
+ }
+
+ inline int IntRed(float a_fScale)
+ {
+ return (int)roundf(fR * a_fScale);
+ }
+
+ inline int IntGreen(float a_fScale)
+ {
+ return (int)roundf(fG * a_fScale);
+ }
+
+ inline int IntBlue(float a_fScale)
+ {
+ return (int)roundf(fB * a_fScale);
+ }
+
+ inline int IntAlpha(float a_fScale)
+ {
+ return (int)roundf(fA * a_fScale);
+ }
+
+ float fR, fG, fB, fA;
+ };
+
+}
+
diff --git a/thirdparty/etc2comp/EtcConfig.h b/thirdparty/etc2comp/EtcConfig.h
new file mode 100644
index 0000000000..3bfe1d99a8
--- /dev/null
+++ b/thirdparty/etc2comp/EtcConfig.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef _WIN32
+#define ETC_WINDOWS (1)
+#else
+#define ETC_WINDOWS (0)
+#endif
+
+#if __APPLE__
+#define ETC_OSX (1)
+#else
+#define ETC_OSX (0)
+#endif
+
+#if __unix__
+#define ETC_UNIX (1)
+#else
+#define ETC_UNIX (0)
+#endif
+
+
+// short names for common types
+#include <stdint.h>
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef float f32;
+typedef double f64;
+
+// Keep asserts enabled in release builds during development
+#undef NDEBUG
+
+// 0=disable. stb_image can be used if you need to compress
+//other image formats like jpg
+#define USE_STB_IMAGE_LOAD 0
+
+#if ETC_WINDOWS
+#include <sdkddkver.h>
+#define _CRT_SECURE_NO_WARNINGS (1)
+#include <tchar.h>
+#endif
+
+#include <stdio.h>
+
diff --git a/thirdparty/etc2comp/EtcDifferentialTrys.cpp b/thirdparty/etc2comp/EtcDifferentialTrys.cpp
new file mode 100644
index 0000000000..ef4cd103d9
--- /dev/null
+++ b/thirdparty/etc2comp/EtcDifferentialTrys.cpp
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcDifferentialTrys.cpp
+
+Gathers the results of the various encoding trys for both halves of a 4x4 block for Differential mode
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcDifferentialTrys.h"
+
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ // construct a list of trys (encoding attempts)
+ //
+ // a_frgbaColor1 is the basecolor for the first half
+ // a_frgbaColor2 is the basecolor for the second half
+ // a_pauiPixelMapping1 is the pixel order for the first half
+ // a_pauiPixelMapping2 is the pixel order for the second half
+ // a_uiRadius is the amount to vary the base colors
+ //
+ DifferentialTrys::DifferentialTrys(ColorFloatRGBA a_frgbaColor1, ColorFloatRGBA a_frgbaColor2,
+ const unsigned int *a_pauiPixelMapping1,
+ const unsigned int *a_pauiPixelMapping2,
+ unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2)
+ {
+ assert(a_uiRadius <= MAX_RADIUS);
+
+ m_boolSeverelyBentColors = false;
+
+ ColorFloatRGBA frgbaQuantizedColor1 = a_frgbaColor1.QuantizeR5G5B5();
+ ColorFloatRGBA frgbaQuantizedColor2 = a_frgbaColor2.QuantizeR5G5B5();
+
+ // quantize base colors
+ // ensure that trys with a_uiRadius don't overflow
+ int iRed1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntRed(31.0f)+a_iGrayOffset1, a_uiRadius);
+ int iGreen1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntGreen(31.0f) + a_iGrayOffset1, a_uiRadius);
+ int iBlue1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntBlue(31.0f) + a_iGrayOffset1, a_uiRadius);
+ int iRed2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntRed(31.0f) + a_iGrayOffset2, a_uiRadius);
+ int iGreen2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntGreen(31.0f) + a_iGrayOffset2, a_uiRadius);
+ int iBlue2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntBlue(31.0f) + a_iGrayOffset2, a_uiRadius);
+
+ int iDeltaRed = iRed2 - iRed1;
+ int iDeltaGreen = iGreen2 - iGreen1;
+ int iDeltaBlue = iBlue2 - iBlue1;
+
+ // make sure components are within range
+ {
+ if (iDeltaRed > 3)
+ {
+ if (iDeltaRed > 7)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iRed1 += (iDeltaRed - 3) / 2;
+ iRed2 = iRed1 + 3;
+ iDeltaRed = 3;
+ }
+ else if (iDeltaRed < -4)
+ {
+ if (iDeltaRed < -8)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iRed1 += (iDeltaRed + 4) / 2;
+ iRed2 = iRed1 - 4;
+ iDeltaRed = -4;
+ }
+ assert(iRed1 >= (signed)(0 + a_uiRadius) && iRed1 <= (signed)(31 - a_uiRadius));
+ assert(iRed2 >= (signed)(0 + a_uiRadius) && iRed2 <= (signed)(31 - a_uiRadius));
+ assert(iDeltaRed >= -4 && iDeltaRed <= 3);
+
+ if (iDeltaGreen > 3)
+ {
+ if (iDeltaGreen > 7)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iGreen1 += (iDeltaGreen - 3) / 2;
+ iGreen2 = iGreen1 + 3;
+ iDeltaGreen = 3;
+ }
+ else if (iDeltaGreen < -4)
+ {
+ if (iDeltaGreen < -8)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iGreen1 += (iDeltaGreen + 4) / 2;
+ iGreen2 = iGreen1 - 4;
+ iDeltaGreen = -4;
+ }
+ assert(iGreen1 >= (signed)(0 + a_uiRadius) && iGreen1 <= (signed)(31 - a_uiRadius));
+ assert(iGreen2 >= (signed)(0 + a_uiRadius) && iGreen2 <= (signed)(31 - a_uiRadius));
+ assert(iDeltaGreen >= -4 && iDeltaGreen <= 3);
+
+ if (iDeltaBlue > 3)
+ {
+ if (iDeltaBlue > 7)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iBlue1 += (iDeltaBlue - 3) / 2;
+ iBlue2 = iBlue1 + 3;
+ iDeltaBlue = 3;
+ }
+ else if (iDeltaBlue < -4)
+ {
+ if (iDeltaBlue < -8)
+ {
+ m_boolSeverelyBentColors = true;
+ }
+
+ iBlue1 += (iDeltaBlue + 4) / 2;
+ iBlue2 = iBlue1 - 4;
+ iDeltaBlue = -4;
+ }
+ assert(iBlue1 >= (signed)(0+a_uiRadius) && iBlue1 <= (signed)(31 - a_uiRadius));
+ assert(iBlue2 >= (signed)(0 + a_uiRadius) && iBlue2 <= (signed)(31 - a_uiRadius));
+ assert(iDeltaBlue >= -4 && iDeltaBlue <= 3);
+ }
+
+ m_half1.Init(iRed1, iGreen1, iBlue1, a_pauiPixelMapping1, a_uiRadius);
+ m_half2.Init(iRed2, iGreen2, iBlue2, a_pauiPixelMapping2, a_uiRadius);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ void DifferentialTrys::Half::Init(int a_iRed, int a_iGreen, int a_iBlue,
+ const unsigned int *a_pauiPixelMapping, unsigned int a_uiRadius)
+ {
+
+ m_iRed = a_iRed;
+ m_iGreen = a_iGreen;
+ m_iBlue = a_iBlue;
+
+ m_pauiPixelMapping = a_pauiPixelMapping;
+ m_uiRadius = a_uiRadius;
+
+ m_uiTrys = 0;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcDifferentialTrys.h b/thirdparty/etc2comp/EtcDifferentialTrys.h
new file mode 100644
index 0000000000..71860908ff
--- /dev/null
+++ b/thirdparty/etc2comp/EtcDifferentialTrys.h
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcColorFloatRGBA.h"
+
+namespace Etc
+{
+
+ class DifferentialTrys
+ {
+ public:
+
+ static const unsigned int MAX_RADIUS = 2;
+
+ DifferentialTrys(ColorFloatRGBA a_frgbaColor1,
+ ColorFloatRGBA a_frgbaColor2,
+ const unsigned int *a_pauiPixelMapping1,
+ const unsigned int *a_pauiPixelMapping2,
+ unsigned int a_uiRadius,
+ int a_iGrayOffset1, int a_iGrayOffset2);
+
+ inline static int MoveAwayFromEdge(int a_i, int a_iDistance)
+ {
+ if (a_i < (0+ a_iDistance))
+ {
+ return (0 + a_iDistance);
+ }
+ else if (a_i > (31- a_iDistance))
+ {
+ return (31 - a_iDistance);
+ }
+
+ return a_i;
+ }
+
+ class Try
+ {
+ public :
+ static const unsigned int SELECTORS = 8; // per half
+
+ int m_iRed;
+ int m_iGreen;
+ int m_iBlue;
+ unsigned int m_uiCW;
+ unsigned int m_auiSelectors[SELECTORS];
+ float m_fError;
+ };
+
+ class Half
+ {
+ public:
+
+ static const unsigned int MAX_TRYS = 125;
+
+ void Init(int a_iRed, int a_iGreen, int a_iBlue,
+ const unsigned int *a_pauiPixelMapping,
+ unsigned int a_uiRadius);
+
+ // center of trys
+ int m_iRed;
+ int m_iGreen;
+ int m_iBlue;
+
+ const unsigned int *m_pauiPixelMapping;
+ unsigned int m_uiRadius;
+
+ unsigned int m_uiTrys;
+ Try m_atry[MAX_TRYS];
+
+ Try *m_ptryBest;
+ };
+
+ Half m_half1;
+ Half m_half2;
+
+ bool m_boolSeverelyBentColors;
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcErrorMetric.h b/thirdparty/etc2comp/EtcErrorMetric.h
new file mode 100644
index 0000000000..df4dcab4fb
--- /dev/null
+++ b/thirdparty/etc2comp/EtcErrorMetric.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace Etc
+{
+
+ enum ErrorMetric
+ {
+ RGBA,
+ RGBX,
+ REC709,
+ NUMERIC,
+ NORMALXYZ,
+ //
+ ERROR_METRICS,
+ //
+ BT709 = REC709
+ };
+
+ inline const char *ErrorMetricToString(ErrorMetric errorMetric)
+ {
+ switch (errorMetric)
+ {
+ case RGBA:
+ return "RGBA";
+ case RGBX:
+ return "RGBX";
+ case REC709:
+ return "REC709";
+ case NUMERIC:
+ return "NUMERIC";
+ case NORMALXYZ:
+ return "NORMALXYZ";
+ case ERROR_METRICS:
+ default:
+ return "UNKNOWN";
+ }
+ }
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcFile.cpp b/thirdparty/etc2comp/EtcFile.cpp
new file mode 100644
index 0000000000..831a3aac45
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFile.cpp
@@ -0,0 +1,390 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifdef _WIN32
+#define _CRT_SECURE_NO_WARNINGS (1)
+#endif
+
+#include "EtcConfig.h"
+
+
+#include "EtcFile.h"
+
+#include "EtcFileHeader.h"
+#include "EtcColor.h"
+#include "Etc.h"
+#include "EtcBlock4x4EncodingBits.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <stdlib.h>
+
+using namespace Etc;
+
+// ----------------------------------------------------------------------------------------------------
+//
+File::File(const char *a_pstrFilename, Format a_fileformat, Image::Format a_imageformat,
+ unsigned char *a_paucEncodingBits, unsigned int a_uiEncodingBitsBytes,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
+ unsigned int a_uiExtendedWidth, unsigned int a_uiExtendedHeight)
+{
+ if (a_pstrFilename == nullptr)
+ {
+ m_pstrFilename = const_cast<char *>("");
+ }
+ else
+ {
+ m_pstrFilename = new char[strlen(a_pstrFilename) + 1];
+ strcpy(m_pstrFilename, a_pstrFilename);
+ }
+
+ m_fileformat = a_fileformat;
+ if (m_fileformat == Format::INFER_FROM_FILE_EXTENSION)
+ {
+ // ***** TODO: add this later *****
+ m_fileformat = Format::KTX;
+ }
+
+ m_imageformat = a_imageformat;
+
+ m_uiNumMipmaps = 1;
+ m_pMipmapImages = new RawImage[m_uiNumMipmaps];
+ m_pMipmapImages[0].paucEncodingBits = std::shared_ptr<unsigned char>(a_paucEncodingBits, [](unsigned char *p) { delete[] p; } );
+ m_pMipmapImages[0].uiEncodingBitsBytes = a_uiEncodingBitsBytes;
+ m_pMipmapImages[0].uiExtendedWidth = a_uiExtendedWidth;
+ m_pMipmapImages[0].uiExtendedHeight = a_uiExtendedHeight;
+
+ m_uiSourceWidth = a_uiSourceWidth;
+ m_uiSourceHeight = a_uiSourceHeight;
+
+ switch (m_fileformat)
+ {
+ case Format::PKM:
+ m_pheader = new FileHeader_Pkm(this);
+ break;
+
+ case Format::KTX:
+ m_pheader = new FileHeader_Ktx(this);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+}
+
+// ----------------------------------------------------------------------------------------------------
+//
+File::File(const char *a_pstrFilename, Format a_fileformat, Image::Format a_imageformat,
+ unsigned int a_uiNumMipmaps, RawImage *a_pMipmapImages,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight)
+{
+ if (a_pstrFilename == nullptr)
+ {
+ m_pstrFilename = const_cast<char *>("");
+ }
+ else
+ {
+ m_pstrFilename = new char[strlen(a_pstrFilename) + 1];
+ strcpy(m_pstrFilename, a_pstrFilename);
+ }
+
+ m_fileformat = a_fileformat;
+ if (m_fileformat == Format::INFER_FROM_FILE_EXTENSION)
+ {
+ // ***** TODO: add this later *****
+ m_fileformat = Format::KTX;
+ }
+
+ m_imageformat = a_imageformat;
+
+ m_uiNumMipmaps = a_uiNumMipmaps;
+ m_pMipmapImages = new RawImage[m_uiNumMipmaps];
+
+ for(unsigned int mip = 0; mip < m_uiNumMipmaps; mip++)
+ {
+ m_pMipmapImages[mip] = a_pMipmapImages[mip];
+ }
+
+ m_uiSourceWidth = a_uiSourceWidth;
+ m_uiSourceHeight = a_uiSourceHeight;
+
+ switch (m_fileformat)
+ {
+ case Format::PKM:
+ m_pheader = new FileHeader_Pkm(this);
+ break;
+
+ case Format::KTX:
+ m_pheader = new FileHeader_Ktx(this);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+}
+
+// ----------------------------------------------------------------------------------------------------
+//
+File::File(const char *a_pstrFilename, Format a_fileformat)
+{
+ if (a_pstrFilename == nullptr)
+ {
+ return;
+ }
+ else
+ {
+ m_pstrFilename = new char[strlen(a_pstrFilename) + 1];
+ strcpy(m_pstrFilename, a_pstrFilename);
+ }
+
+ m_fileformat = a_fileformat;
+ if (m_fileformat == Format::INFER_FROM_FILE_EXTENSION)
+ {
+ // ***** TODO: add this later *****
+ m_fileformat = Format::KTX;
+ }
+
+ FILE *pfile = fopen(m_pstrFilename, "rb");
+ if (pfile == nullptr)
+ {
+ printf("ERROR: Couldn't open %s", m_pstrFilename);
+ exit(1);
+ }
+ fseek(pfile, 0, SEEK_END);
+ unsigned int fileSize = ftell(pfile);
+ fseek(pfile, 0, SEEK_SET);
+ size_t szResult;
+
+ m_pheader = new FileHeader_Ktx(this);
+ szResult = fread( ((FileHeader_Ktx*)m_pheader)->GetData(), 1, sizeof(FileHeader_Ktx::Data), pfile);
+ assert(szResult > 0);
+
+ m_uiNumMipmaps = 1;
+ m_pMipmapImages = new RawImage[m_uiNumMipmaps];
+
+ if (((FileHeader_Ktx*)m_pheader)->GetData()->m_u32BytesOfKeyValueData > 0)
+ fseek(pfile, ((FileHeader_Ktx*)m_pheader)->GetData()->m_u32BytesOfKeyValueData, SEEK_CUR);
+ szResult = fread(&m_pMipmapImages->uiEncodingBitsBytes, 1, sizeof(unsigned int), pfile);
+ assert(szResult > 0);
+
+ m_pMipmapImages->paucEncodingBits = std::shared_ptr<unsigned char>(new unsigned char[m_pMipmapImages->uiEncodingBitsBytes], [](unsigned char *p) { delete[] p; } );
+ assert(ftell(pfile) + m_pMipmapImages->uiEncodingBitsBytes <= fileSize);
+ szResult = fread(m_pMipmapImages->paucEncodingBits.get(), 1, m_pMipmapImages->uiEncodingBitsBytes, pfile);
+ assert(szResult == m_pMipmapImages->uiEncodingBitsBytes);
+
+ uint32_t uiInternalFormat = ((FileHeader_Ktx*)m_pheader)->GetData()->m_u32GlInternalFormat;
+ uint32_t uiBaseInternalFormat = ((FileHeader_Ktx*)m_pheader)->GetData()->m_u32GlBaseInternalFormat;
+
+ if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC1_RGB8 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC1_RGB8)
+ {
+ m_imageformat = Image::Format::ETC1;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_RGB8 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_RGB8)
+ {
+ m_imageformat = Image::Format::RGB8;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_RGB8A1 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_RGB8A1)
+ {
+ m_imageformat = Image::Format::RGB8A1;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_RGBA8 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_RGBA8)
+ {
+ m_imageformat = Image::Format::RGBA8;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_R11 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_R11)
+ {
+ m_imageformat = Image::Format::R11;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_SIGNED_R11 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_R11)
+ {
+ m_imageformat = Image::Format::SIGNED_R11;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_RG11 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_RG11)
+ {
+ m_imageformat = Image::Format::RG11;
+ }
+ else if (uiInternalFormat == (uint32_t)FileHeader_Ktx::InternalFormat::ETC2_SIGNED_RG11 && uiBaseInternalFormat == (uint32_t)FileHeader_Ktx::BaseInternalFormat::ETC2_RG11)
+ {
+ m_imageformat = Image::Format::SIGNED_RG11;
+ }
+ else
+ {
+ m_imageformat = Image::Format::UNKNOWN;
+ }
+
+ m_uiSourceWidth = ((FileHeader_Ktx*)m_pheader)->GetData()->m_u32PixelWidth;
+ m_uiSourceHeight = ((FileHeader_Ktx*)m_pheader)->GetData()->m_u32PixelHeight;
+ m_pMipmapImages->uiExtendedWidth = Image::CalcExtendedDimension((unsigned short)m_uiSourceWidth);
+ m_pMipmapImages->uiExtendedHeight = Image::CalcExtendedDimension((unsigned short)m_uiSourceHeight);
+
+ unsigned int uiBlocks = m_pMipmapImages->uiExtendedWidth * m_pMipmapImages->uiExtendedHeight / 16;
+ Block4x4EncodingBits::Format encodingbitsformat = Image::DetermineEncodingBitsFormat(m_imageformat);
+ unsigned int expectedbytes = uiBlocks * Block4x4EncodingBits::GetBytesPerBlock(encodingbitsformat);
+ assert(expectedbytes == m_pMipmapImages->uiEncodingBitsBytes);
+
+ fclose(pfile);
+}
+
+File::~File()
+{
+ if (m_pMipmapImages != nullptr)
+ {
+ delete [] m_pMipmapImages;
+ }
+
+ if(m_pstrFilename != nullptr)
+ {
+ delete[] m_pstrFilename;
+ m_pstrFilename = nullptr;
+ }
+ if (m_pheader != nullptr)
+ {
+ delete m_pheader;
+ m_pheader = nullptr;
+ }
+}
+
+void File::UseSingleBlock(int a_iPixelX, int a_iPixelY)
+{
+ if (a_iPixelX <= -1 || a_iPixelY <= -1)
+ return;
+ if (a_iPixelX >(int) m_uiSourceWidth)
+ {
+ //if we are using a ktx thats the size of a single block or less
+ //then make sure we use the 4x4 image as the single block
+ if (m_uiSourceWidth <= 4)
+ {
+ a_iPixelX = 0;
+ }
+ else
+ {
+ printf("blockAtHV: H coordinate out of range, capped to image width\n");
+ a_iPixelX = m_uiSourceWidth - 1;
+ }
+ }
+ if (a_iPixelY >(int) m_uiSourceHeight)
+ {
+ //if we are using a ktx thats the size of a single block or less
+ //then make sure we use the 4x4 image as the single block
+ if (m_uiSourceHeight <= 4)
+ {
+ a_iPixelY= 0;
+ }
+ else
+ {
+ printf("blockAtHV: V coordinate out of range, capped to image height\n");
+ a_iPixelY = m_uiSourceHeight - 1;
+ }
+ }
+
+ unsigned int origWidth = m_uiSourceWidth;
+ unsigned int origHeight = m_uiSourceHeight;
+
+ m_uiSourceWidth = 4;
+ m_uiSourceHeight = 4;
+
+ Block4x4EncodingBits::Format encodingbitsformat = Image::DetermineEncodingBitsFormat(m_imageformat);
+ unsigned int uiEncodingBitsBytesPerBlock = Block4x4EncodingBits::GetBytesPerBlock(encodingbitsformat);
+
+ int numMipmaps = 1;
+ RawImage* pMipmapImages = new RawImage[numMipmaps];
+ pMipmapImages[0].uiExtendedWidth = Image::CalcExtendedDimension((unsigned short)m_uiSourceWidth);
+ pMipmapImages[0].uiExtendedHeight = Image::CalcExtendedDimension((unsigned short)m_uiSourceHeight);
+ pMipmapImages[0].uiEncodingBitsBytes = 0;
+ pMipmapImages[0].paucEncodingBits = std::shared_ptr<unsigned char>(new unsigned char[uiEncodingBitsBytesPerBlock], [](unsigned char *p) { delete[] p; });
+
+ //block position in pixels
+ // remove the bottom 2 bits to get the block coordinates
+ unsigned int iBlockPosX = (a_iPixelX & 0xFFFFFFFC);
+ unsigned int iBlockPosY = (a_iPixelY & 0xFFFFFFFC);
+
+ int numXBlocks = (origWidth / 4);
+ int numYBlocks = (origHeight / 4);
+
+
+ // block location
+ //int iBlockX = (a_iPixelX % 4) == 0 ? a_iPixelX / 4.0f : (a_iPixelX / 4) + 1;
+ //int iBlockY = (a_iPixelY % 4) == 0 ? a_iPixelY / 4.0f : (a_iPixelY / 4) + 1;
+ //m_paucEncodingBits += ((iBlockY * numXBlocks) + iBlockX) * uiEncodingBitsBytesPerBlock;
+
+
+ unsigned int num = numXBlocks*numYBlocks;
+ unsigned int uiH = 0, uiV = 0;
+ unsigned char* pEncodingBits = m_pMipmapImages[0].paucEncodingBits.get();
+ for (unsigned int uiBlock = 0; uiBlock < num; uiBlock++)
+ {
+ if (uiH == iBlockPosX && uiV == iBlockPosY)
+ {
+ memcpy(pMipmapImages[0].paucEncodingBits.get(),pEncodingBits, uiEncodingBitsBytesPerBlock);
+ break;
+ }
+ pEncodingBits += uiEncodingBitsBytesPerBlock;
+ uiH += 4;
+
+ if (uiH >= origWidth)
+ {
+ uiH = 0;
+ uiV += 4;
+ }
+ }
+
+ delete [] m_pMipmapImages;
+ m_pMipmapImages = pMipmapImages;
+}
+// ----------------------------------------------------------------------------------------------------
+//
+void File::Write()
+{
+
+ FILE *pfile = fopen(m_pstrFilename, "wb");
+ if (pfile == nullptr)
+ {
+ printf("Error: couldn't open Etc file (%s)\n", m_pstrFilename);
+ exit(1);
+ }
+
+ m_pheader->Write(pfile);
+
+ for(unsigned int mip = 0; mip < m_uiNumMipmaps; mip++)
+ {
+ if(m_fileformat == Format::KTX)
+ {
+ // Write u32 image size
+ uint32_t u32ImageSize = m_pMipmapImages[mip].uiEncodingBitsBytes;
+ uint32_t szBytesWritten = fwrite(&u32ImageSize, 1, sizeof(u32ImageSize), pfile);
+ assert(szBytesWritten == sizeof(u32ImageSize));
+ }
+
+ unsigned int iResult = (int)fwrite(m_pMipmapImages[mip].paucEncodingBits.get(), 1, m_pMipmapImages[mip].uiEncodingBitsBytes, pfile);
+ if (iResult != m_pMipmapImages[mip].uiEncodingBitsBytes)
+ {
+ printf("Error: couldn't write Etc file (%s)\n", m_pstrFilename);
+ exit(1);
+ }
+ }
+
+ fclose(pfile);
+
+}
+
+// ----------------------------------------------------------------------------------------------------
+//
+
diff --git a/thirdparty/etc2comp/EtcFile.h b/thirdparty/etc2comp/EtcFile.h
new file mode 100644
index 0000000000..69bf3b2d3a
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFile.h
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcColorFloatRGBA.h"
+#include "EtcImage.h"
+#include "Etc.h"
+
+namespace Etc
+{
+ class FileHeader;
+ class SourceImage;
+
+ class File
+ {
+ public:
+
+ enum class Format
+ {
+ INFER_FROM_FILE_EXTENSION,
+ PKM,
+ KTX,
+ };
+
+ File(const char *a_pstrFilename, Format a_fileformat, Image::Format a_imageformat,
+ unsigned char *a_paucEncodingBits, unsigned int a_uiEncodingBitsBytes,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
+ unsigned int a_uiExtendedWidth, unsigned int a_uiExtendedHeight);
+
+ File(const char *a_pstrFilename, Format a_fileformat, Image::Format a_imageformat,
+ unsigned int a_uiNumMipmaps, RawImage *pMipmapImages,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight );
+
+ File(const char *a_pstrFilename, Format a_fileformat);
+ ~File();
+ const char *GetFilename(void) { return m_pstrFilename; }
+
+ void Read(const char *a_pstrFilename);
+ void Write(void);
+
+ inline unsigned int GetSourceWidth(void)
+ {
+ return m_uiSourceWidth;
+ }
+
+ inline unsigned int GetSourceHeight(void)
+ {
+ return m_uiSourceHeight;
+ }
+
+ inline unsigned int GetExtendedWidth(unsigned int mipmapIndex = 0)
+ {
+ if (mipmapIndex < m_uiNumMipmaps)
+ {
+ return m_pMipmapImages[mipmapIndex].uiExtendedWidth;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ inline unsigned int GetExtendedHeight(unsigned int mipmapIndex = 0)
+ {
+ if (mipmapIndex < m_uiNumMipmaps)
+ {
+ return m_pMipmapImages[mipmapIndex].uiExtendedHeight;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ inline Image::Format GetImageFormat()
+ {
+ return m_imageformat;
+ }
+
+ inline unsigned int GetEncodingBitsBytes(unsigned int mipmapIndex = 0)
+ {
+ if (mipmapIndex < m_uiNumMipmaps)
+ {
+ return m_pMipmapImages[mipmapIndex].uiEncodingBitsBytes;
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ inline unsigned char* GetEncodingBits(unsigned int mipmapIndex = 0)
+ {
+ if( mipmapIndex < m_uiNumMipmaps)
+ {
+ return m_pMipmapImages[mipmapIndex].paucEncodingBits.get();
+ }
+ else
+ {
+ return nullptr;
+ }
+ }
+
+ inline unsigned int GetNumMipmaps()
+ {
+ return m_uiNumMipmaps;
+ }
+
+ void UseSingleBlock(int a_iPixelX = -1, int a_iPixelY = -1);
+ private:
+
+ char *m_pstrFilename; // includes directory path and file extension
+ Format m_fileformat;
+ Image::Format m_imageformat;
+ FileHeader *m_pheader;
+ unsigned int m_uiNumMipmaps;
+ RawImage* m_pMipmapImages;
+ unsigned int m_uiSourceWidth;
+ unsigned int m_uiSourceHeight;
+ };
+
+}
diff --git a/thirdparty/etc2comp/EtcFileHeader.cpp b/thirdparty/etc2comp/EtcFileHeader.cpp
new file mode 100644
index 0000000000..f02fcab011
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFileHeader.cpp
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EtcFileHeader.h"
+
+#include "EtcBlock4x4EncodingBits.h"
+
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ FileHeader_Pkm::FileHeader_Pkm(File *a_pfile)
+ {
+ m_pfile = a_pfile;
+
+ static const char s_acMagicNumberData[4] = { 'P', 'K', 'M', ' ' };
+ static const char s_acVersionData[2] = { '1', '0' };
+
+ for (unsigned int ui = 0; ui < sizeof(s_acMagicNumberData); ui++)
+ {
+ m_data.m_acMagicNumber[ui] = s_acMagicNumberData[ui];
+ }
+
+ for (unsigned int ui = 0; ui < sizeof(s_acVersionData); ui++)
+ {
+ m_data.m_acVersion[ui] = s_acVersionData[ui];
+ }
+
+ m_data.m_ucDataType_msb = 0; // ETC1_RGB_NO_MIPMAPS
+ m_data.m_ucDataType_lsb = 0;
+
+ m_data.m_ucOriginalWidth_msb = (unsigned char)(m_pfile->GetSourceWidth() >> 8);
+ m_data.m_ucOriginalWidth_lsb = m_pfile->GetSourceWidth() & 0xFF;
+ m_data.m_ucOriginalHeight_msb = (unsigned char)(m_pfile->GetSourceHeight() >> 8);
+ m_data.m_ucOriginalHeight_lsb = m_pfile->GetSourceHeight() & 0xFF;
+
+ m_data.m_ucExtendedWidth_msb = (unsigned char)(m_pfile->GetExtendedWidth() >> 8);
+ m_data.m_ucExtendedWidth_lsb = m_pfile->GetExtendedWidth() & 0xFF;
+ m_data.m_ucExtendedHeight_msb = (unsigned char)(m_pfile->GetExtendedHeight() >> 8);
+ m_data.m_ucExtendedHeight_lsb = m_pfile->GetExtendedHeight() & 0xFF;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ void FileHeader_Pkm::Write(FILE *a_pfile)
+ {
+
+ fwrite(&m_data, sizeof(Data), 1, a_pfile);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ FileHeader_Ktx::FileHeader_Ktx(File *a_pfile)
+ {
+ m_pfile = a_pfile;
+
+ static const uint8_t s_au8Itentfier[12] =
+ {
+ 0xAB, 0x4B, 0x54, 0x58, // first four bytes of Byte[12] identifier
+ 0x20, 0x31, 0x31, 0xBB, // next four bytes of Byte[12] identifier
+ 0x0D, 0x0A, 0x1A, 0x0A // final four bytes of Byte[12] identifier
+ };
+
+ for (unsigned int ui = 0; ui < sizeof(s_au8Itentfier); ui++)
+ {
+ m_data.m_au8Identifier[ui] = s_au8Itentfier[ui];
+ }
+
+ m_data.m_u32Endianness = 0x04030201;
+ m_data.m_u32GlType = 0;
+ m_data.m_u32GlTypeSize = 1;
+ m_data.m_u32GlFormat = 0;
+
+ switch (m_pfile->GetImageFormat())
+ {
+ case Image::Format::RGB8:
+ case Image::Format::SRGB8:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_RGB8;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_RGB8;
+ break;
+
+ case Image::Format::RGBA8:
+ case Image::Format::SRGBA8:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_RGBA8;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_RGBA8;
+ break;
+
+ case Image::Format::RGB8A1:
+ case Image::Format::SRGB8A1:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_RGB8A1;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_RGB8A1;
+ break;
+
+ case Image::Format::R11:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_R11;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_R11;
+ break;
+
+ case Image::Format::SIGNED_R11:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_SIGNED_R11;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_R11;
+ break;
+
+ case Image::Format::RG11:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_RG11;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_RG11;
+ break;
+
+ case Image::Format::SIGNED_RG11:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC2_SIGNED_RG11;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC2_RG11;
+ break;
+
+ default:
+ m_data.m_u32GlInternalFormat = (unsigned int)InternalFormat::ETC1_RGB8;
+ m_data.m_u32GlBaseInternalFormat = (unsigned int)BaseInternalFormat::ETC1_RGB8;
+ break;
+ }
+
+ m_data.m_u32PixelWidth = 0;
+ m_data.m_u32PixelHeight = 0;
+ m_data.m_u32PixelDepth = 0;
+ m_data.m_u32NumberOfArrayElements = 0;
+ m_data.m_u32NumberOfFaces = 0;
+ m_data.m_u32BytesOfKeyValueData = 0;
+
+ m_pkeyvaluepair = nullptr;
+
+ m_u32Images = 0;
+ m_u32KeyValuePairs = 0;
+
+ m_data.m_u32PixelWidth = m_pfile->GetSourceWidth();
+ m_data.m_u32PixelHeight = m_pfile->GetSourceHeight();
+ m_data.m_u32PixelDepth = 0;
+ m_data.m_u32NumberOfArrayElements = 0;
+ m_data.m_u32NumberOfFaces = 1;
+ m_data.m_u32NumberOfMipmapLevels = m_pfile->GetNumMipmaps();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ void FileHeader_Ktx::Write(FILE *a_pfile)
+ {
+ size_t szBytesWritten;
+
+ // Write header
+ szBytesWritten = fwrite(&m_data, 1, sizeof(Data), a_pfile);
+ assert(szBytesWritten == sizeof(Data));
+
+ // Write KeyAndValuePairs
+ if (m_u32KeyValuePairs)
+ {
+ fwrite(m_pkeyvaluepair, m_pkeyvaluepair->u32KeyAndValueByteSize, 1, a_pfile);
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ FileHeader_Ktx::Data *FileHeader_Ktx::GetData()
+ {
+ return &m_data;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcFileHeader.h b/thirdparty/etc2comp/EtcFileHeader.h
new file mode 100644
index 0000000000..55a9cb5d9d
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFileHeader.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcFile.h"
+#include <stdio.h>
+#include <inttypes.h>
+
+namespace Etc
+{
+
+ class Image;
+
+ class FileHeader
+ {
+ public:
+
+ virtual void Write(FILE *a_pfile) = 0;
+ File GetFile();
+ virtual ~FileHeader(void) {}
+ protected:
+
+ File *m_pfile;
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ class FileHeader_Pkm : public FileHeader
+ {
+ public:
+
+ FileHeader_Pkm(File *a_pfile);
+
+ virtual void Write(FILE *a_pfile);
+ virtual ~FileHeader_Pkm(void) {}
+ private:
+
+ typedef struct
+ {
+ char m_acMagicNumber[4];
+ char m_acVersion[2];
+ unsigned char m_ucDataType_msb; // e.g. ETC1_RGB_NO_MIPMAPS
+ unsigned char m_ucDataType_lsb;
+ unsigned char m_ucExtendedWidth_msb; // padded to 4x4 blocks
+ unsigned char m_ucExtendedWidth_lsb;
+ unsigned char m_ucExtendedHeight_msb; // padded to 4x4 blocks
+ unsigned char m_ucExtendedHeight_lsb;
+ unsigned char m_ucOriginalWidth_msb;
+ unsigned char m_ucOriginalWidth_lsb;
+ unsigned char m_ucOriginalHeight_msb;
+ unsigned char m_ucOriginalHeight_lsb;
+ } Data;
+
+ Data m_data;
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ class FileHeader_Ktx : public FileHeader
+ {
+ public:
+
+ typedef struct
+ {
+ uint32_t u32KeyAndValueByteSize;
+ } KeyValuePair;
+
+ typedef struct
+ {
+ uint8_t m_au8Identifier[12];
+ uint32_t m_u32Endianness;
+ uint32_t m_u32GlType;
+ uint32_t m_u32GlTypeSize;
+ uint32_t m_u32GlFormat;
+ uint32_t m_u32GlInternalFormat;
+ uint32_t m_u32GlBaseInternalFormat;
+ uint32_t m_u32PixelWidth;
+ uint32_t m_u32PixelHeight;
+ uint32_t m_u32PixelDepth;
+ uint32_t m_u32NumberOfArrayElements;
+ uint32_t m_u32NumberOfFaces;
+ uint32_t m_u32NumberOfMipmapLevels;
+ uint32_t m_u32BytesOfKeyValueData;
+ } Data;
+
+ enum class InternalFormat
+ {
+ ETC1_RGB8 = 0x8D64,
+ ETC1_ALPHA8 = ETC1_RGB8,
+ //
+ ETC2_R11 = 0x9270,
+ ETC2_SIGNED_R11 = 0x9271,
+ ETC2_RG11 = 0x9272,
+ ETC2_SIGNED_RG11 = 0x9273,
+ ETC2_RGB8 = 0x9274,
+ ETC2_SRGB8 = 0x9275,
+ ETC2_RGB8A1 = 0x9276,
+ ETC2_SRGB8_PUNCHTHROUGH_ALPHA1 = 0x9277,
+ ETC2_RGBA8 = 0x9278
+ };
+
+ enum class BaseInternalFormat
+ {
+ ETC2_R11 = 0x1903,
+ ETC2_RG11 = 0x8227,
+ ETC1_RGB8 = 0x1907,
+ ETC1_ALPHA8 = ETC1_RGB8,
+ //
+ ETC2_RGB8 = 0x1907,
+ ETC2_RGB8A1 = 0x1908,
+ ETC2_RGBA8 = 0x1908,
+ };
+
+ FileHeader_Ktx(File *a_pfile);
+
+ virtual void Write(FILE *a_pfile);
+ virtual ~FileHeader_Ktx(void) {}
+
+ void AddKeyAndValue(KeyValuePair *a_pkeyvaluepair);
+
+ Data* GetData();
+
+ private:
+
+ Data m_data;
+ KeyValuePair *m_pkeyvaluepair;
+
+ uint32_t m_u32Images;
+ uint32_t m_u32KeyValuePairs;
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcFilter.cpp b/thirdparty/etc2comp/EtcFilter.cpp
new file mode 100644
index 0000000000..bc899a533e
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFilter.cpp
@@ -0,0 +1,401 @@
+#include <stdlib.h>
+#include <math.h>
+#include "EtcFilter.h"
+
+
+namespace Etc
+{
+
+static const double PiConst = 3.14159265358979323846;
+
+inline double sinc(double x)
+{
+ if ( x == 0.0 )
+ {
+ return 1.0;
+ }
+
+ return sin(PiConst * x) / (PiConst * x);
+}
+
+//inline float sincf( float x )
+//{
+// x *= F_PI;
+// if (x < 0.01f && x > -0.01f)
+// {
+// return 1.0f + x*x*(-1.0f/6.0f + x*x*1.0f/120.0f);
+// }
+//
+// return sinf(x)/x;
+//}
+//
+//double bessel0(double x)
+//{
+// const double EPSILON_RATIO = 1E-16;
+// double xh, sum, pow, ds;
+// int k;
+//
+// xh = 0.5 * x;
+// sum = 1.0;
+// pow = 1.0;
+// k = 0;
+// ds = 1.0;
+// while (ds > sum * EPSILON_RATIO)
+// {
+// ++k;
+// pow = pow * (xh / k);
+// ds = pow * pow;
+// sum = sum + ds;
+// }
+//
+// return sum;
+//}
+
+//**--------------------------------------------------------------------------
+//** Name: kaiser(double alpha, double half_width, double x)
+//** Returns:
+//** Description: Alpha controls shape of filter. We are using 4.
+//**--------------------------------------------------------------------------
+//inline double kaiser(double alpha, double half_width, double x)
+//{
+// double ratio = (x / half_width);
+// return bessel0(alpha * sqrt(1 - ratio * ratio)) / bessel0(alpha);
+//}
+//
+//float Filter_Lanczos4Sinc(float x)
+//{
+// if (x <= -4.0f || x >= 4.0f) // half-width of 4
+// {
+// return 0.0;
+// }
+//
+// return sinc(0.875f * x) * sinc(0.25f * x);
+//}
+//
+//double Filter_Kaiser4( double t )
+//{
+// return kaiser( 4.0, 3.0, t);
+//}
+//
+//double Filter_KaiserOptimal( double t )
+//{
+// return kaiser( 8.93, 3.0f, t);
+//}
+
+double FilterLanczos3( double t )
+{
+ if ( t <= -3.0 || t >= 3.0 )
+ {
+ return 0.0;
+ }
+
+ return sinc( t ) * sinc( t / 3.0 );
+}
+
+double FilterBox( double t )
+{
+ return ( t > -0.5 && t < 0.5) ? 1.0 : 0.0;
+}
+
+double FilterLinear( double t )
+{
+ if (t < 0.0) t = -t;
+
+ return (t < 1.0) ? (1.0 - t) : 0.0;
+}
+
+
+//**--------------------------------------------------------------------------
+//** Name: CalcContributions( int srcSize,
+//** int destSize,
+//** double filterSize,
+//** bool wrap,
+//** double (*FilterProc)(double),
+//** FilterWeights contrib[] )
+//** Returns: void
+//** Description:
+//**--------------------------------------------------------------------------
+void CalcContributions( int srcSize, int destSize, double filterSize, bool wrap, double (*FilterProc)(double), FilterWeights contrib[] )
+{
+ double scale;
+ double filterScale;
+ double center;
+ double totalWeight;
+ double weight;
+ int iRight;
+ int iLeft;
+ int iDest;
+
+ scale = (double)destSize / srcSize;
+ if ( scale < 1.0 )
+ {
+ filterSize = filterSize / scale;
+ filterScale = scale;
+ }
+ else
+ {
+ filterScale = 1.0;
+ }
+
+ if ( filterSize > (double)MaxFilterSize )
+ {
+ filterSize = (double)MaxFilterSize;
+ }
+
+ for ( iDest = 0; iDest < destSize; ++iDest )
+ {
+ center = (double)iDest / scale;
+
+ iLeft = (int)ceil(center - filterSize);
+ iRight = (int)floor(center + filterSize);
+
+ if ( !wrap )
+ {
+ if ( iLeft < 0 )
+ {
+ iLeft = 0;
+ }
+
+ if ( iRight >= srcSize )
+ {
+ iRight = srcSize - 1;
+ }
+ }
+
+ int numWeights = iRight - iLeft + 1;
+
+ contrib[iDest].first = iLeft;
+ contrib[iDest].numWeights = numWeights;
+
+ totalWeight = 0;
+ double t = ((double)iLeft - center) * filterScale;
+ for (int i = 0; i < numWeights; i++)
+ {
+ weight = (*FilterProc)(t) * filterScale;
+ totalWeight += weight;
+ contrib[iDest].weight[i] = weight;
+ t += filterScale;
+ }
+
+ //**--------------------------------------------------------
+ //** Normalize weights by dividing by the sum of the weights
+ //**--------------------------------------------------------
+ if ( totalWeight > 0.0 )
+ {
+ for ( int i = 0; i < numWeights; i++)
+ {
+ contrib[iDest].weight[i] /= totalWeight;
+ }
+ }
+ }
+}
+
+//**-------------------------------------------------------------------------
+//** Name: Filter_TwoPass( RGBCOLOR *pSrcImage,
+//** int srcWidth, int srcHeight,
+//** RGBCOLOR *pDestImage,
+//** int destWidth, int destHeight,
+//** double (*FilterProc)(double) )
+//** Returns: 0 on failure and 1 on success
+//** Description: Filters a 2d image with a two pass filter by averaging the
+//** weighted contributions of the pixels within the filter region. The
+//** contributions are determined by a weighting function parameter.
+//**-------------------------------------------------------------------------
+int FilterTwoPass( RGBCOLOR *pSrcImage, int srcWidth, int srcHeight,
+ RGBCOLOR *pDestImage, int destWidth, int destHeight, unsigned int wrapFlags, double (*FilterProc)(double) )
+{
+ FilterWeights *contrib;
+ RGBCOLOR *pPixel;
+ RGBCOLOR *pSrcPixel;
+ RGBCOLOR *pTempImage;
+ int iRow;
+ int iCol;
+ int iSrcCol;
+ int iSrcRow;
+ int iWeight;
+ double dRed;
+ double dGreen;
+ double dBlue;
+ double dAlpha;
+ double filterSize = 3.0;
+
+ int maxDim = (srcWidth>srcHeight)?srcWidth:srcHeight;
+ contrib = (FilterWeights*)malloc(maxDim * sizeof(FilterWeights));
+
+ //**------------------------------------------------------------------------
+ //** Need to create a temporary image to stuff the horizontally scaled image
+ //**------------------------------------------------------------------------
+ pTempImage = (RGBCOLOR *)malloc( destWidth * srcHeight * sizeof(RGBCOLOR) );
+ if ( pTempImage == NULL )
+ {
+ return 0;
+ }
+
+ //**-------------------------------------------------------
+ //** Horizontally filter the image into the temporary image
+ //**-------------------------------------------------------
+ bool bWrapHorizontal = !!(wrapFlags&FILTER_WRAP_X);
+ CalcContributions( srcWidth, destWidth, filterSize, bWrapHorizontal, FilterProc, contrib );
+ for ( iRow = 0; iRow < srcHeight; iRow++ )
+ {
+ for ( iCol = 0; iCol < destWidth; iCol++ )
+ {
+ dRed = 0;
+ dGreen = 0;
+ dBlue = 0;
+ dAlpha = 0;
+
+ for ( iWeight = 0; iWeight < contrib[iCol].numWeights; iWeight++ )
+ {
+ iSrcCol = iWeight + contrib[iCol].first;
+ if (bWrapHorizontal)
+ {
+ iSrcCol = (iSrcCol < 0) ? (srcWidth + iSrcCol) : (iSrcCol >= srcWidth) ? (iSrcCol - srcWidth) : iSrcCol;
+ }
+ pSrcPixel = pSrcImage + (iRow * srcWidth) + iSrcCol;
+ dRed += contrib[iCol].weight[iWeight] * pSrcPixel->rgba[0];
+ dGreen += contrib[iCol].weight[iWeight] * pSrcPixel->rgba[1];
+ dBlue += contrib[iCol].weight[iWeight] * pSrcPixel->rgba[2];
+ dAlpha += contrib[iCol].weight[iWeight] * pSrcPixel->rgba[3];
+ }
+
+ pPixel = pTempImage + (iRow * destWidth) + iCol;
+ pPixel->rgba[0] = static_cast<unsigned char>(std::max(0.0, std::min(255.0, dRed)));
+ pPixel->rgba[1] = static_cast<unsigned char>(std::max(0.0, std::min(255.0, dGreen)));
+ pPixel->rgba[2] = static_cast<unsigned char>(std::max(0.0, std::min(255.0, dBlue)));
+ pPixel->rgba[3] = static_cast<unsigned char>(std::max(0.0, std::min(255.0, dAlpha)));
+ }
+ }
+
+ //**-------------------------------------------------------
+ //** Vertically filter the image into the destination image
+ //**-------------------------------------------------------
+ bool bWrapVertical = !!(wrapFlags&FILTER_WRAP_Y);
+ CalcContributions(srcHeight, destHeight, filterSize, bWrapVertical, FilterProc, contrib);
+ for ( iCol = 0; iCol < destWidth; iCol++ )
+ {
+ for ( iRow = 0; iRow < destHeight; iRow++ )
+ {
+ dRed = 0;
+ dGreen = 0;
+ dBlue = 0;
+ dAlpha = 0;
+
+ for ( iWeight = 0; iWeight < contrib[iRow].numWeights; iWeight++ )
+ {
+ iSrcRow = iWeight + contrib[iRow].first;
+ if (bWrapVertical)
+ {
+ iSrcRow = (iSrcRow < 0) ? (srcHeight + iSrcRow) : (iSrcRow >= srcHeight) ? (iSrcRow - srcHeight) : iSrcRow;
+ }
+ pSrcPixel = pTempImage + (iSrcRow * destWidth) + iCol;
+ dRed += contrib[iRow].weight[iWeight] * pSrcPixel->rgba[0];
+ dGreen += contrib[iRow].weight[iWeight] * pSrcPixel->rgba[1];
+ dBlue += contrib[iRow].weight[iWeight] * pSrcPixel->rgba[2];
+ dAlpha += contrib[iRow].weight[iWeight] * pSrcPixel->rgba[3];
+ }
+
+ pPixel = pDestImage + (iRow * destWidth) + iCol;
+ pPixel->rgba[0] = (unsigned char)(std::max( 0.0, std::min( 255.0, dRed)));
+ pPixel->rgba[1] = (unsigned char)(std::max( 0.0, std::min( 255.0, dGreen)));
+ pPixel->rgba[2] = (unsigned char)(std::max( 0.0, std::min( 255.0, dBlue)));
+ pPixel->rgba[3] = (unsigned char)(std::max( 0.0, std::min( 255.0, dAlpha)));
+ }
+ }
+
+ free( pTempImage );
+ free( contrib );
+
+ return 1;
+}
+
+//**-------------------------------------------------------------------------
+//** Name: FilterResample(RGBCOLOR *pSrcImage, int srcWidth, int srcHeight,
+//** RGBCOLOR *pDstImage, int dstWidth, int dstHeight)
+//** Returns: 1
+//** Description: This function runs a 2d box filter over the srouce image
+//** to produce the destination image.
+//**-------------------------------------------------------------------------
+void FilterResample( RGBCOLOR *pSrcImage, int srcWidth, int srcHeight,
+ RGBCOLOR *pDstImage, int dstWidth, int dstHeight )
+{
+ int iRow;
+ int iCol;
+ int iSampleRow;
+ int iSampleCol;
+ int iFirstSampleRow;
+ int iFirstSampleCol;
+ int iLastSampleRow;
+ int iLastSampleCol;
+ int red;
+ int green;
+ int blue;
+ int alpha;
+ int samples;
+ float xScale;
+ float yScale;
+
+ RGBCOLOR *pSrcPixel;
+ RGBCOLOR *pDstPixel;
+
+ xScale = (float)srcWidth / dstWidth;
+ yScale = (float)srcHeight / dstHeight;
+
+ for ( iRow = 0; iRow < dstHeight; iRow++ )
+ {
+ for ( iCol = 0; iCol < dstWidth; iCol++ )
+ {
+ iFirstSampleRow = (int)(iRow * yScale);
+ iLastSampleRow = (int)ceil(iFirstSampleRow + yScale - 1);
+ if ( iLastSampleRow >= srcHeight )
+ {
+ iLastSampleRow = srcHeight - 1;
+ }
+
+ iFirstSampleCol = (int)(iCol * xScale);
+ iLastSampleCol = (int)ceil(iFirstSampleCol + xScale - 1);
+ if ( iLastSampleCol >= srcWidth )
+ {
+ iLastSampleCol = srcWidth - 1;
+ }
+
+ samples = 0;
+ red = 0;
+ green = 0;
+ blue = 0;
+ alpha = 0;
+ for ( iSampleRow = iFirstSampleRow; iSampleRow <= iLastSampleRow; iSampleRow++ )
+ {
+ for ( iSampleCol = iFirstSampleCol; iSampleCol <= iLastSampleCol; iSampleCol++ )
+ {
+ pSrcPixel = pSrcImage + iSampleRow * srcWidth + iSampleCol;
+ red += pSrcPixel->rgba[0];
+ green += pSrcPixel->rgba[1];
+ blue += pSrcPixel->rgba[2];
+ alpha += pSrcPixel->rgba[3];
+
+ samples++;
+ }
+ }
+
+ pDstPixel = pDstImage + iRow * dstWidth + iCol;
+ if ( samples > 0 )
+ {
+ pDstPixel->rgba[0] = static_cast<uint8_t>(red / samples);
+ pDstPixel->rgba[1] = static_cast<uint8_t>(green / samples);
+ pDstPixel->rgba[2] = static_cast<uint8_t>(blue / samples);
+ pDstPixel->rgba[3] = static_cast<uint8_t>(alpha / samples);
+ }
+ else
+ {
+ pDstPixel->rgba[0] = static_cast<uint8_t>(red);
+ pDstPixel->rgba[1] = static_cast<uint8_t>(green);
+ pDstPixel->rgba[2] = static_cast<uint8_t>(blue);
+ pDstPixel->rgba[3] = static_cast<uint8_t>(alpha);
+ }
+ }
+ }
+}
+
+
+} \ No newline at end of file
diff --git a/thirdparty/etc2comp/EtcFilter.h b/thirdparty/etc2comp/EtcFilter.h
new file mode 100644
index 0000000000..fcf125c6df
--- /dev/null
+++ b/thirdparty/etc2comp/EtcFilter.h
@@ -0,0 +1,244 @@
+#pragma once
+#include <stdint.h>
+#include <algorithm>
+
+namespace Etc
+{
+
+enum FilterEnums
+{
+ MaxFilterSize = 32
+};
+
+enum WrapFlags
+{
+ FILTER_WRAP_NONE = 0,
+ FILTER_WRAP_X = 0x1,
+ FILTER_WRAP_Y = 0x2
+};
+
+typedef struct tagFilterWeights
+{
+ int first;
+ int numWeights;
+ double weight[MaxFilterSize * 2 + 1];
+} FilterWeights;
+
+typedef struct tagRGBCOLOR
+{
+ union
+ {
+ uint32_t ulColor;
+ uint8_t rgba[4];
+ };
+} RGBCOLOR;
+
+
+double FilterBox( double t );
+double FilterLinear( double t );
+double FilterLanczos3( double t );
+
+int FilterTwoPass( RGBCOLOR *pSrcImage, int srcWidth, int srcHeight,
+ RGBCOLOR *pDestImage, int destWidth, int destHeight, unsigned int wrapFlags, double (*FilterProc)(double) );
+void FilterResample( RGBCOLOR *pSrcImage, int srcWidth, int srcHeight,
+ RGBCOLOR *pDstImage, int dstWidth, int dstHeight );
+
+
+void CalcContributions(int srcSize, int destSize, double filterSize, bool wrap, double(*FilterProc)(double), FilterWeights contrib[]);
+
+template <typename T>
+void FilterResample(T *pSrcImage, int srcWidth, int srcHeight, T *pDstImage, int dstWidth, int dstHeight)
+{
+ float xScale;
+ float yScale;
+
+ T *pSrcPixel;
+ T *pDstPixel;
+
+ xScale = (float)srcWidth / dstWidth;
+ yScale = (float)srcHeight / dstHeight;
+
+ for (int iRow = 0; iRow < dstHeight; iRow++)
+ {
+ for (int iCol = 0; iCol < dstWidth; iCol++)
+ {
+ int samples;
+ int iFirstSampleRow;
+ int iFirstSampleCol;
+ int iLastSampleRow;
+ int iLastSampleCol;
+ float red;
+ float green;
+ float blue;
+ float alpha;
+
+ iFirstSampleRow = (int)(iRow * yScale);
+ iLastSampleRow = (int)ceil(iFirstSampleRow + yScale - 1);
+ if (iLastSampleRow >= srcHeight)
+ {
+ iLastSampleRow = srcHeight - 1;
+ }
+
+ iFirstSampleCol = (int)(iCol * xScale);
+ iLastSampleCol = (int)ceil(iFirstSampleCol + xScale - 1);
+ if (iLastSampleCol >= srcWidth)
+ {
+ iLastSampleCol = srcWidth - 1;
+ }
+
+ samples = 0;
+ red = 0.f;
+ green = 0.f;
+ blue = 0.f;
+ alpha = 0.f;
+ for (int iSampleRow = iFirstSampleRow; iSampleRow <= iLastSampleRow; iSampleRow++)
+ {
+ for (int iSampleCol = iFirstSampleCol; iSampleCol <= iLastSampleCol; iSampleCol++)
+ {
+ pSrcPixel = pSrcImage + (iSampleRow * srcWidth + iSampleCol) * 4;
+ red += static_cast<float>(pSrcPixel[0]);
+ green += static_cast<float>(pSrcPixel[1]);
+ blue += static_cast<float>(pSrcPixel[2]);
+ alpha += static_cast<float>(pSrcPixel[3]);
+
+ samples++;
+ }
+ }
+
+ pDstPixel = pDstImage + (iRow * dstWidth + iCol) * 4;
+ if (samples > 0)
+ {
+ pDstPixel[0] = static_cast<T>(red / samples);
+ pDstPixel[1] = static_cast<T>(green / samples);
+ pDstPixel[2] = static_cast<T>(blue / samples);
+ pDstPixel[3] = static_cast<T>(alpha / samples);
+ }
+ else
+ {
+ pDstPixel[0] = static_cast<T>(red);
+ pDstPixel[1] = static_cast<T>(green);
+ pDstPixel[2] = static_cast<T>(blue);
+ pDstPixel[3] = static_cast<T>(alpha);
+ }
+ }
+ }
+
+}
+
+//**-------------------------------------------------------------------------
+//** Name: Filter_TwoPass( RGBCOLOR *pSrcImage,
+//** int srcWidth, int srcHeight,
+//** RGBCOLOR *pDestImage,
+//** int destWidth, int destHeight,
+//** double (*FilterProc)(double) )
+//** Returns: 0 on failure and 1 on success
+//** Description: Filters a 2d image with a two pass filter by averaging the
+//** weighted contributions of the pixels within the filter region. The
+//** contributions are determined by a weighting function parameter.
+//**-------------------------------------------------------------------------
+template <typename T>
+int FilterTwoPass(T *pSrcImage, int srcWidth, int srcHeight,
+ T *pDestImage, int destWidth, int destHeight, unsigned int wrapFlags, double(*FilterProc)(double))
+{
+ const int numComponents = 4;
+ FilterWeights *contrib;
+ T *pPixel;
+ T *pTempImage;
+ double dRed;
+ double dGreen;
+ double dBlue;
+ double dAlpha;
+ double filterSize = 3.0;
+
+ int maxDim = (srcWidth>srcHeight) ? srcWidth : srcHeight;
+ contrib = new FilterWeights[maxDim];
+
+ //**------------------------------------------------------------------------
+ //** Need to create a temporary image to stuff the horizontally scaled image
+ //**------------------------------------------------------------------------
+ pTempImage = new T[destWidth * srcHeight * numComponents];
+ if (pTempImage == NULL)
+ {
+ return 0;
+ }
+
+ //**-------------------------------------------------------
+ //** Horizontally filter the image into the temporary image
+ //**-------------------------------------------------------
+ bool bWrapHorizontal = !!(wrapFlags&FILTER_WRAP_X);
+ CalcContributions(srcWidth, destWidth, filterSize, bWrapHorizontal, FilterProc, contrib);
+ for (int iRow = 0; iRow < srcHeight; iRow++)
+ {
+ for (int iCol = 0; iCol < destWidth; iCol++)
+ {
+ dRed = 0;
+ dGreen = 0;
+ dBlue = 0;
+ dAlpha = 0;
+
+ for (int iWeight = 0; iWeight < contrib[iCol].numWeights; iWeight++)
+ {
+ int iSrcCol = iWeight + contrib[iCol].first;
+ if(bWrapHorizontal)
+ {
+ iSrcCol = (iSrcCol < 0)?(srcWidth+iSrcCol):(iSrcCol >= srcWidth)?(iSrcCol-srcWidth):iSrcCol;
+ }
+ T* pSrcPixel = pSrcImage + ((iRow * srcWidth) + iSrcCol)*numComponents;
+ dRed += contrib[iCol].weight[iWeight] * pSrcPixel[0];
+ dGreen += contrib[iCol].weight[iWeight] * pSrcPixel[1];
+ dBlue += contrib[iCol].weight[iWeight] * pSrcPixel[2];
+ dAlpha += contrib[iCol].weight[iWeight] * pSrcPixel[3];
+ }
+
+ pPixel = pTempImage + ((iRow * destWidth) + iCol)*numComponents;
+ pPixel[0] = static_cast<T>(std::max(0.0, std::min(255.0, dRed)));
+ pPixel[1] = static_cast<T>(std::max(0.0, std::min(255.0, dGreen)));
+ pPixel[2] = static_cast<T>(std::max(0.0, std::min(255.0, dBlue)));
+ pPixel[3] = static_cast<T>(std::max(0.0, std::min(255.0, dAlpha)));
+ }
+ }
+
+ //**-------------------------------------------------------
+ //** Vertically filter the image into the destination image
+ //**-------------------------------------------------------
+ bool bWrapVertical = !!(wrapFlags&FILTER_WRAP_Y);
+ CalcContributions(srcHeight, destHeight, filterSize, bWrapVertical, FilterProc, contrib);
+ for (int iCol = 0; iCol < destWidth; iCol++)
+ {
+ for (int iRow = 0; iRow < destHeight; iRow++)
+ {
+ dRed = 0;
+ dGreen = 0;
+ dBlue = 0;
+ dAlpha = 0;
+
+ for (int iWeight = 0; iWeight < contrib[iRow].numWeights; iWeight++)
+ {
+ int iSrcRow = iWeight + contrib[iRow].first;
+ if (bWrapVertical)
+ {
+ iSrcRow = (iSrcRow < 0) ? (srcHeight + iSrcRow) : (iSrcRow >= srcHeight) ? (iSrcRow - srcHeight) : iSrcRow;
+ }
+ T* pSrcPixel = pTempImage + ((iSrcRow * destWidth) + iCol)*numComponents;
+ dRed += contrib[iRow].weight[iWeight] * pSrcPixel[0];
+ dGreen += contrib[iRow].weight[iWeight] * pSrcPixel[1];
+ dBlue += contrib[iRow].weight[iWeight] * pSrcPixel[2];
+ dAlpha += contrib[iRow].weight[iWeight] * pSrcPixel[3];
+ }
+
+ pPixel = pDestImage + ((iRow * destWidth) + iCol)*numComponents;
+ pPixel[0] = static_cast<T>(std::max(0.0, std::min(255.0, dRed)));
+ pPixel[1] = static_cast<T>(std::max(0.0, std::min(255.0, dGreen)));
+ pPixel[2] = static_cast<T>(std::max(0.0, std::min(255.0, dBlue)));
+ pPixel[3] = static_cast<T>(std::max(0.0, std::min(255.0, dAlpha)));
+ }
+ }
+
+ delete[] pTempImage;
+ delete[] contrib;
+
+ return 1;
+}
+
+
+} \ No newline at end of file
diff --git a/thirdparty/etc2comp/EtcImage.cpp b/thirdparty/etc2comp/EtcImage.cpp
new file mode 100644
index 0000000000..7a1058844d
--- /dev/null
+++ b/thirdparty/etc2comp/EtcImage.cpp
@@ -0,0 +1,685 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcImage.cpp
+
+Image is an array of 4x4 blocks that represent the encoding of the source image
+
+*/
+
+#include "EtcConfig.h"
+
+#include <stdlib.h>
+
+#include "EtcImage.h"
+
+#include "Etc.h"
+#include "EtcBlock4x4.h"
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcSortedBlockList.h"
+
+#if ETC_WINDOWS
+#include <windows.h>
+#endif
+#include <ctime>
+#include <chrono>
+#include <future>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+// fix conflict with Block4x4::AlphaMix
+#ifdef OPAQUE
+#undef OPAQUE
+#endif
+#ifdef TRANSPARENT
+#undef TRANSPARENT
+#endif
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Image::Image(void)
+ {
+ m_encodingStatus = EncodingStatus::SUCCESS;
+ m_warningsToCapture = EncodingStatus::SUCCESS;
+ m_pafrgbaSource = nullptr;
+
+ m_pablock = nullptr;
+
+ m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
+ m_uiEncodingBitsBytes = 0;
+ m_paucEncodingBits = nullptr;
+
+ m_format = Format::UNKNOWN;
+ m_iNumOpaquePixels = 0;
+ m_iNumTranslucentPixels = 0;
+ m_iNumTransparentPixels = 0;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // constructor using source image
+ // used to set state before Encode() is called
+ //
+ Image::Image(float *a_pafSourceRGBA, unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ ErrorMetric a_errormetric)
+ {
+ m_encodingStatus = EncodingStatus::SUCCESS;
+ m_warningsToCapture = EncodingStatus::SUCCESS;
+ m_pafrgbaSource = (ColorFloatRGBA *) a_pafSourceRGBA;
+ m_uiSourceWidth = a_uiSourceWidth;
+ m_uiSourceHeight = a_uiSourceHeight;
+
+ m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
+ m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
+
+ m_uiBlockColumns = m_uiExtendedWidth >> 2;
+ m_uiBlockRows = m_uiExtendedHeight >> 2;
+
+ m_pablock = new Block4x4[GetNumberOfBlocks()];
+ assert(m_pablock);
+
+ m_format = Format::UNKNOWN;
+
+ m_encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
+ m_uiEncodingBitsBytes = 0;
+ m_paucEncodingBits = nullptr;
+
+ m_errormetric = a_errormetric;
+ m_fEffort = 0.0f;
+
+ m_iEncodeTime_ms = -1;
+
+ m_iNumOpaquePixels = 0;
+ m_iNumTranslucentPixels = 0;
+ m_iNumTransparentPixels = 0;
+ m_bVerboseOutput = false;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // constructor using encoding bits
+ // recreates encoding state using a previously encoded image
+ //
+ Image::Image(Format a_format,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
+ unsigned char *a_paucEncidingBits, unsigned int a_uiEncodingBitsBytes,
+ Image *a_pimageSource, ErrorMetric a_errormetric)
+ {
+ m_encodingStatus = EncodingStatus::SUCCESS;
+ m_pafrgbaSource = nullptr;
+ m_uiSourceWidth = a_uiSourceWidth;
+ m_uiSourceHeight = a_uiSourceHeight;
+
+ m_uiExtendedWidth = CalcExtendedDimension((unsigned short)m_uiSourceWidth);
+ m_uiExtendedHeight = CalcExtendedDimension((unsigned short)m_uiSourceHeight);
+
+ m_uiBlockColumns = m_uiExtendedWidth >> 2;
+ m_uiBlockRows = m_uiExtendedHeight >> 2;
+
+ unsigned int uiBlocks = GetNumberOfBlocks();
+
+ m_pablock = new Block4x4[uiBlocks];
+ assert(m_pablock);
+
+ m_format = a_format;
+
+ m_iNumOpaquePixels = 0;
+ m_iNumTranslucentPixels = 0;
+ m_iNumTransparentPixels = 0;
+
+ m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
+ if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
+ {
+ AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
+ return;
+ }
+ m_uiEncodingBitsBytes = a_uiEncodingBitsBytes;
+ m_paucEncodingBits = a_paucEncidingBits;
+
+ m_errormetric = a_errormetric;
+ m_fEffort = 0.0f;
+ m_bVerboseOutput = false;
+ m_iEncodeTime_ms = -1;
+
+ unsigned char *paucEncodingBits = m_paucEncodingBits;
+ unsigned int uiEncodingBitsBytesPerBlock = Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
+
+ unsigned int uiH = 0;
+ unsigned int uiV = 0;
+ for (unsigned int uiBlock = 0; uiBlock < uiBlocks; uiBlock++)
+ {
+ m_pablock[uiBlock].InitFromEtcEncodingBits(a_format, uiH, uiV, paucEncodingBits,
+ a_pimageSource, a_errormetric);
+ paucEncodingBits += uiEncodingBitsBytesPerBlock;
+ uiH += 4;
+ if (uiH >= m_uiSourceWidth)
+ {
+ uiH = 0;
+ uiV += 4;
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ Image::~Image(void)
+ {
+ if (m_pablock != nullptr)
+ {
+ delete[] m_pablock;
+ m_pablock = nullptr;
+ }
+
+ /*if (m_paucEncodingBits != nullptr)
+ {
+ delete[] m_paucEncodingBits;
+ m_paucEncodingBits = nullptr;
+ }*/
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // encode an image
+ // create a set of encoding bits that conforms to a_format
+ // find best fit using a_errormetric
+ // explore a range of possible encodings based on a_fEffort (range = [0:100])
+ // speed up process using a_uiJobs as the number of process threads (a_uiJobs must not excede a_uiMaxJobs)
+ //
+ Image::EncodingStatus Image::Encode(Format a_format, ErrorMetric a_errormetric, float a_fEffort, unsigned int a_uiJobs, unsigned int a_uiMaxJobs)
+ {
+
+ auto start = std::chrono::steady_clock::now();
+
+ m_encodingStatus = EncodingStatus::SUCCESS;
+
+ m_format = a_format;
+ m_errormetric = a_errormetric;
+ m_fEffort = a_fEffort;
+
+ if (m_errormetric < 0 || m_errormetric > ERROR_METRICS)
+ {
+ AddToEncodingStatus(ERROR_UNKNOWN_ERROR_METRIC);
+ return m_encodingStatus;
+ }
+
+ if (m_fEffort < ETCCOMP_MIN_EFFORT_LEVEL)
+ {
+ AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
+ m_fEffort = ETCCOMP_MIN_EFFORT_LEVEL;
+ }
+ else if (m_fEffort > ETCCOMP_MAX_EFFORT_LEVEL)
+ {
+ AddToEncodingStatus(WARNING_EFFORT_OUT_OF_RANGE);
+ m_fEffort = ETCCOMP_MAX_EFFORT_LEVEL;
+ }
+ if (a_uiJobs < 1)
+ {
+ a_uiJobs = 1;
+ AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
+ }
+ else if (a_uiJobs > a_uiMaxJobs)
+ {
+ a_uiJobs = a_uiMaxJobs;
+ AddToEncodingStatus(WARNING_JOBS_OUT_OF_RANGE);
+ }
+
+ m_encodingbitsformat = DetermineEncodingBitsFormat(m_format);
+
+ if (m_encodingbitsformat == Block4x4EncodingBits::Format::UNKNOWN)
+ {
+ AddToEncodingStatus(ERROR_UNKNOWN_FORMAT);
+ return m_encodingStatus;
+ }
+
+ assert(m_paucEncodingBits == nullptr);
+ m_uiEncodingBitsBytes = GetNumberOfBlocks() * Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
+ m_paucEncodingBits = new unsigned char[m_uiEncodingBitsBytes];
+
+ InitBlocksAndBlockSorter();
+
+
+ std::future<void> *handle = new std::future<void>[a_uiMaxJobs];
+
+ unsigned int uiNumThreadsNeeded = 0;
+ unsigned int uiUnfinishedBlocks = GetNumberOfBlocks();
+
+ uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
+
+ for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
+ {
+ handle[i] = async(std::launch::async, &Image::RunFirstPass, this, i, uiNumThreadsNeeded);
+ }
+
+ RunFirstPass(uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
+
+ for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
+ {
+ handle[i].get();
+ }
+
+ // perform effort-based encoding
+ if (m_fEffort > ETCCOMP_MIN_EFFORT_LEVEL)
+ {
+ unsigned int uiFinishedBlocks = 0;
+ unsigned int uiTotalEffortBlocks = static_cast<unsigned int>(roundf(0.01f * m_fEffort * GetNumberOfBlocks()));
+
+ if (m_bVerboseOutput)
+ {
+ printf("effortblocks = %d\n", uiTotalEffortBlocks);
+ }
+ unsigned int uiPass = 0;
+ while (1)
+ {
+ if (m_bVerboseOutput)
+ {
+ uiPass++;
+ printf("pass %u\n", uiPass);
+ }
+ m_psortedblocklist->Sort();
+ uiUnfinishedBlocks = m_psortedblocklist->GetNumberOfSortedBlocks();
+ uiFinishedBlocks = GetNumberOfBlocks() - uiUnfinishedBlocks;
+ if (m_bVerboseOutput)
+ {
+ printf(" %u unfinished blocks\n", uiUnfinishedBlocks);
+ // m_psortedblocklist->Print();
+ }
+
+
+
+ //stop enocding when we did enough to satify the effort percentage
+ if (uiFinishedBlocks >= uiTotalEffortBlocks)
+ {
+ if (m_bVerboseOutput)
+ {
+ printf("Finished %d Blocks out of %d\n", uiFinishedBlocks, uiTotalEffortBlocks);
+ }
+ break;
+ }
+
+ unsigned int uiIteratedBlocks = 0;
+ unsigned int blocksToIterateThisPass = (uiTotalEffortBlocks - uiFinishedBlocks);
+ uiNumThreadsNeeded = (uiUnfinishedBlocks < a_uiJobs) ? uiUnfinishedBlocks : a_uiJobs;
+
+ if (uiNumThreadsNeeded <= 1)
+ {
+ //since we already how many blocks each thread will process
+ //cap the thread limit to do the proper amount of work, and not more
+ uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, 0, 1);
+ }
+ else
+ {
+ //we have a lot of work to do, so lets multi thread it
+ std::future<unsigned int> *handleToBlockEncoders = new std::future<unsigned int>[uiNumThreadsNeeded-1];
+
+ for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
+ {
+ handleToBlockEncoders[i] = async(std::launch::async, &Image::IterateThroughWorstBlocks, this, blocksToIterateThisPass, i, uiNumThreadsNeeded);
+ }
+ uiIteratedBlocks = IterateThroughWorstBlocks(blocksToIterateThisPass, uiNumThreadsNeeded - 1, uiNumThreadsNeeded);
+
+ for (int i = 0; i < (int)uiNumThreadsNeeded - 1; i++)
+ {
+ uiIteratedBlocks += handleToBlockEncoders[i].get();
+ }
+
+ delete[] handleToBlockEncoders;
+ }
+
+ if (m_bVerboseOutput)
+ {
+ printf(" %u iterated blocks\n", uiIteratedBlocks);
+ }
+ }
+ }
+
+ // generate Etc2-compatible bit-format 4x4 blocks
+ for (int i = 0; i < (int)a_uiJobs - 1; i++)
+ {
+ handle[i] = async(std::launch::async, &Image::SetEncodingBits, this, i, a_uiJobs);
+ }
+ SetEncodingBits(a_uiJobs - 1, a_uiJobs);
+
+ for (int i = 0; i < (int)a_uiJobs - 1; i++)
+ {
+ handle[i].get();
+ }
+
+ auto end = std::chrono::steady_clock::now();
+ std::chrono::milliseconds elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
+ m_iEncodeTime_ms = (int)elapsed.count();
+
+ delete[] handle;
+ delete m_psortedblocklist;
+ return m_encodingStatus;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // iterate the encoding thru the blocks with the worst error
+ // stop when a_uiMaxBlocks blocks have been iterated
+ // split the blocks between the process threads using a_uiMultithreadingOffset and a_uiMultithreadingStride
+ //
+ unsigned int Image::IterateThroughWorstBlocks(unsigned int a_uiMaxBlocks,
+ unsigned int a_uiMultithreadingOffset,
+ unsigned int a_uiMultithreadingStride)
+ {
+ assert(a_uiMultithreadingStride > 0);
+ unsigned int uiIteratedBlocks = a_uiMultithreadingOffset;
+
+ SortedBlockList::Link *plink = m_psortedblocklist->GetLinkToFirstBlock();
+ for (plink = plink->Advance(a_uiMultithreadingOffset);
+ plink != nullptr;
+ plink = plink->Advance(a_uiMultithreadingStride) )
+ {
+ if (uiIteratedBlocks >= a_uiMaxBlocks)
+ {
+ break;
+ }
+
+ plink->GetBlock()->PerformEncodingIteration(m_fEffort);
+
+ uiIteratedBlocks += a_uiMultithreadingStride;
+ }
+
+ return uiIteratedBlocks;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // determine which warnings to check for during Encode() based on encoding format
+ //
+ void Image::FindEncodingWarningTypesForCurFormat()
+ {
+ TrackEncodingWarning(WARNING_ALL_TRANSPARENT_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_RGBA_NOT_0_TO_1);
+ switch (m_format)
+ {
+ case Image::Format::ETC1:
+ case Image::Format::RGB8:
+ case Image::Format::SRGB8:
+ TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
+ break;
+
+ case Image::Format::RGB8A1:
+ case Image::Format::SRGB8A1:
+ TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
+ TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
+ break;
+ case Image::Format::RGBA8:
+ case Image::Format::SRGBA8:
+ TrackEncodingWarning(WARNING_ALL_OPAQUE_PIXELS);
+ break;
+
+ case Image::Format::R11:
+ case Image::Format::SIGNED_R11:
+ TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
+ TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
+ break;
+
+ case Image::Format::RG11:
+ case Image::Format::SIGNED_RG11:
+ TrackEncodingWarning(WARNING_SOME_NON_OPAQUE_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_TRANSLUCENT_PIXELS);
+ TrackEncodingWarning(WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
+ break;
+ case Image::Format::FORMATS:
+ case Image::Format::UNKNOWN:
+ default:
+ assert(0);
+ break;
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // examine source pixels to check for warnings
+ //
+ void Image::FindAndSetEncodingWarnings()
+ {
+ int numPixels = (m_uiBlockRows * 4) * (m_uiBlockColumns * 4);
+ if (m_iNumOpaquePixels == numPixels)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_OPAQUE_PIXELS);
+ }
+ if (m_iNumOpaquePixels < numPixels)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_NON_OPAQUE_PIXELS);
+ }
+ if (m_iNumTranslucentPixels > 0)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_TRANSLUCENT_PIXELS);
+ }
+ if (m_iNumTransparentPixels == numPixels)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_ALL_TRANSPARENT_PIXELS);
+ }
+ if (m_numColorValues.fB > 0.0f)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO);
+ }
+ if (m_numColorValues.fG > 0.0f)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO);
+ }
+
+ if (m_numOutOfRangeValues.fR > 0.0f || m_numOutOfRangeValues.fG > 0.0f)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
+ }
+ if (m_numOutOfRangeValues.fB > 0.0f || m_numOutOfRangeValues.fA > 0.0f)
+ {
+ AddToEncodingStatusIfSignfigant(Image::EncodingStatus::WARNING_SOME_RGBA_NOT_0_TO_1);
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // return a string name for a given image format
+ //
+ const char * Image::EncodingFormatToString(Image::Format a_format)
+ {
+ switch (a_format)
+ {
+ case Image::Format::ETC1:
+ return "ETC1";
+ case Image::Format::RGB8:
+ return "RGB8";
+ case Image::Format::SRGB8:
+ return "SRGB8";
+
+ case Image::Format::RGB8A1:
+ return "RGB8A1";
+ case Image::Format::SRGB8A1:
+ return "SRGB8A1";
+ case Image::Format::RGBA8:
+ return "RGBA8";
+ case Image::Format::SRGBA8:
+ return "SRGBA8";
+
+ case Image::Format::R11:
+ return "R11";
+ case Image::Format::SIGNED_R11:
+ return "SIGNED_R11";
+
+ case Image::Format::RG11:
+ return "RG11";
+ case Image::Format::SIGNED_RG11:
+ return "SIGNED_RG11";
+ case Image::Format::FORMATS:
+ case Image::Format::UNKNOWN:
+ default:
+ return "UNKNOWN";
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // return a string name for the image's format
+ //
+ const char * Image::EncodingFormatToString(void)
+ {
+ return EncodingFormatToString(m_format);
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // init image blocks prior to encoding
+ // init block sorter for subsequent sortings
+ // check for encoding warnings
+ //
+ void Image::InitBlocksAndBlockSorter(void)
+ {
+
+ FindEncodingWarningTypesForCurFormat();
+
+ // init each block
+ Block4x4 *pblock = m_pablock;
+ unsigned char *paucEncodingBits = m_paucEncodingBits;
+ for (unsigned int uiBlockRow = 0; uiBlockRow < m_uiBlockRows; uiBlockRow++)
+ {
+ unsigned int uiBlockV = uiBlockRow * 4;
+
+ for (unsigned int uiBlockColumn = 0; uiBlockColumn < m_uiBlockColumns; uiBlockColumn++)
+ {
+ unsigned int uiBlockH = uiBlockColumn * 4;
+
+ pblock->InitFromSource(this, uiBlockH, uiBlockV, paucEncodingBits, m_errormetric);
+
+ paucEncodingBits += Block4x4EncodingBits::GetBytesPerBlock(m_encodingbitsformat);
+
+ pblock++;
+ }
+ }
+
+ FindAndSetEncodingWarnings();
+
+ // init block sorter
+ {
+ m_psortedblocklist = new SortedBlockList(GetNumberOfBlocks(), 100);
+
+ for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
+ {
+ pblock = &m_pablock[uiBlock];
+ m_psortedblocklist->AddBlock(pblock);
+ }
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // run the first pass of the encoder
+ // the encoder generally finds a reasonable, fast encoding
+ // this is run on all blocks regardless of effort to ensure that all blocks have a valid encoding
+ //
+ void Image::RunFirstPass(unsigned int a_uiMultithreadingOffset, unsigned int a_uiMultithreadingStride)
+ {
+ assert(a_uiMultithreadingStride > 0);
+
+ for (unsigned int uiBlock = a_uiMultithreadingOffset;
+ uiBlock < GetNumberOfBlocks();
+ uiBlock += a_uiMultithreadingStride)
+ {
+ Block4x4 *pblock = &m_pablock[uiBlock];
+ pblock->PerformEncodingIteration(m_fEffort);
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // set the encoding bits (for the output file) based on the best encoding for each block
+ //
+ void Image::SetEncodingBits(unsigned int a_uiMultithreadingOffset,
+ unsigned int a_uiMultithreadingStride)
+ {
+ assert(a_uiMultithreadingStride > 0);
+
+ for (unsigned int uiBlock = a_uiMultithreadingOffset;
+ uiBlock < GetNumberOfBlocks();
+ uiBlock += a_uiMultithreadingStride)
+ {
+ Block4x4 *pblock = &m_pablock[uiBlock];
+ pblock->SetEncodingBitsFromEncoding();
+ }
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // return the image error
+ // image error is the sum of all block errors
+ //
+ float Image::GetError(void)
+ {
+ float fError = 0.0f;
+
+ for (unsigned int uiBlock = 0; uiBlock < GetNumberOfBlocks(); uiBlock++)
+ {
+ Block4x4 *pblock = &m_pablock[uiBlock];
+ fError += pblock->GetError();
+ }
+
+ return fError;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // determine the encoding bits format based on the encoding format
+ // the encoding bits format is a family of bit encodings that are shared across various encoding formats
+ //
+ Block4x4EncodingBits::Format Image::DetermineEncodingBitsFormat(Format a_format)
+ {
+ Block4x4EncodingBits::Format encodingbitsformat;
+
+ // determine encoding bits format from image format
+ switch (a_format)
+ {
+ case Format::ETC1:
+ case Format::RGB8:
+ case Format::SRGB8:
+ encodingbitsformat = Block4x4EncodingBits::Format::RGB8;
+ break;
+
+ case Format::RGBA8:
+ case Format::SRGBA8:
+ encodingbitsformat = Block4x4EncodingBits::Format::RGBA8;
+ break;
+
+ case Format::R11:
+ case Format::SIGNED_R11:
+ encodingbitsformat = Block4x4EncodingBits::Format::R11;
+ break;
+
+ case Format::RG11:
+ case Format::SIGNED_RG11:
+ encodingbitsformat = Block4x4EncodingBits::Format::RG11;
+ break;
+
+ case Format::RGB8A1:
+ case Format::SRGB8A1:
+ encodingbitsformat = Block4x4EncodingBits::Format::RGB8A1;
+ break;
+
+ default:
+ encodingbitsformat = Block4x4EncodingBits::Format::UNKNOWN;
+ break;
+ }
+
+ return encodingbitsformat;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcImage.h b/thirdparty/etc2comp/EtcImage.h
new file mode 100644
index 0000000000..bd807ac32e
--- /dev/null
+++ b/thirdparty/etc2comp/EtcImage.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+//#include "Etc.h"
+#include "EtcColorFloatRGBA.h"
+#include "EtcBlock4x4EncodingBits.h"
+#include "EtcErrorMetric.h"
+
+
+namespace Etc
+{
+ class Block4x4;
+ class EncoderSpec;
+ class SortedBlockList;
+
+ class Image
+ {
+ public:
+
+ //the differnt warning and errors that can come up during encoding
+ enum EncodingStatus
+ {
+ SUCCESS = 0,
+ //
+ WARNING_THRESHOLD = 1 << 0,
+ //
+ WARNING_EFFORT_OUT_OF_RANGE = 1 << 1,
+ WARNING_JOBS_OUT_OF_RANGE = 1 << 2,
+ WARNING_SOME_NON_OPAQUE_PIXELS = 1 << 3,//just for opaque formats, etc1, rgb8, r11, rg11
+ WARNING_ALL_OPAQUE_PIXELS = 1 << 4,
+ WARNING_ALL_TRANSPARENT_PIXELS = 1 << 5,
+ WARNING_SOME_TRANSLUCENT_PIXELS = 1 << 6,//just for rgb8A1
+ WARNING_SOME_RGBA_NOT_0_TO_1 = 1 << 7,
+ WARNING_SOME_BLUE_VALUES_ARE_NOT_ZERO = 1 << 8,
+ WARNING_SOME_GREEN_VALUES_ARE_NOT_ZERO = 1 << 9,
+ //
+ ERROR_THRESHOLD = 1 << 16,
+ //
+ ERROR_UNKNOWN_FORMAT = 1 << 17,
+ ERROR_UNKNOWN_ERROR_METRIC = 1 << 18,
+ ERROR_ZERO_WIDTH_OR_HEIGHT = 1 << 19,
+ //
+ };
+
+ enum class Format
+ {
+ UNKNOWN,
+ //
+ ETC1,
+ //
+ // ETC2 formats
+ RGB8,
+ SRGB8,
+ RGBA8,
+ SRGBA8,
+ R11,
+ SIGNED_R11,
+ RG11,
+ SIGNED_RG11,
+ RGB8A1,
+ SRGB8A1,
+ //
+ FORMATS,
+ //
+ DEFAULT = SRGB8
+ };
+
+ // constructor using source image
+ Image(float *a_pafSourceRGBA, unsigned int a_uiSourceWidth,
+ unsigned int a_uiSourceHeight,
+ ErrorMetric a_errormetric);
+
+ // constructor using encoding bits
+ Image(Format a_format,
+ unsigned int a_uiSourceWidth, unsigned int a_uiSourceHeight,
+ unsigned char *a_paucEncidingBits, unsigned int a_uiEncodingBitsBytes,
+ Image *a_pimageSource,
+ ErrorMetric a_errormetric);
+
+ ~Image(void);
+
+ EncodingStatus Encode(Format a_format, ErrorMetric a_errormetric, float a_fEffort,
+ unsigned int a_uiJobs, unsigned int a_uiMaxJobs);
+
+ inline void AddToEncodingStatus(EncodingStatus a_encStatus)
+ {
+ m_encodingStatus = (EncodingStatus)((unsigned int)m_encodingStatus | (unsigned int)a_encStatus);
+ }
+
+ inline unsigned int GetSourceWidth(void)
+ {
+ return m_uiSourceWidth;
+ }
+
+ inline unsigned int GetSourceHeight(void)
+ {
+ return m_uiSourceHeight;
+ }
+
+ inline unsigned int GetExtendedWidth(void)
+ {
+ return m_uiExtendedWidth;
+ }
+
+ inline unsigned int GetExtendedHeight(void)
+ {
+ return m_uiExtendedHeight;
+ }
+
+ inline unsigned int GetNumberOfBlocks()
+ {
+ return m_uiBlockColumns * m_uiBlockRows;
+ }
+
+ inline Block4x4 * GetBlocks()
+ {
+ return m_pablock;
+ }
+
+ inline unsigned char * GetEncodingBits(void)
+ {
+ return m_paucEncodingBits;
+ }
+
+ inline unsigned int GetEncodingBitsBytes(void)
+ {
+ return m_uiEncodingBitsBytes;
+ }
+
+ inline int GetEncodingTimeMs(void)
+ {
+ return m_iEncodeTime_ms;
+ }
+
+ float GetError(void);
+
+ inline ColorFloatRGBA * GetSourcePixel(unsigned int a_uiH, unsigned int a_uiV)
+ {
+ if (a_uiH >= m_uiSourceWidth || a_uiV >= m_uiSourceHeight)
+ {
+ return nullptr;
+ }
+
+ return &m_pafrgbaSource[a_uiV*m_uiSourceWidth + a_uiH];
+ }
+
+ inline Format GetFormat(void)
+ {
+ return m_format;
+ }
+
+ static Block4x4EncodingBits::Format DetermineEncodingBitsFormat(Format a_format);
+
+ inline static unsigned short CalcExtendedDimension(unsigned short a_ushOriginalDimension)
+ {
+ return (unsigned short)((a_ushOriginalDimension + 3) & ~3);
+ }
+
+ inline ErrorMetric GetErrorMetric(void)
+ {
+ return m_errormetric;
+ }
+
+ static const char * EncodingFormatToString(Image::Format a_format);
+ const char * EncodingFormatToString(void);
+ //used to get basic information about the image data
+ int m_iNumOpaquePixels;
+ int m_iNumTranslucentPixels;
+ int m_iNumTransparentPixels;
+
+ ColorFloatRGBA m_numColorValues;
+ ColorFloatRGBA m_numOutOfRangeValues;
+
+ bool m_bVerboseOutput;
+ private:
+ //add a warning or error to check for while encoding
+ inline void TrackEncodingWarning(EncodingStatus a_encStatus)
+ {
+ m_warningsToCapture = (EncodingStatus)((unsigned int)m_warningsToCapture | (unsigned int)a_encStatus);
+ }
+
+ //report the warning if it is something we care about for this encoding
+ inline void AddToEncodingStatusIfSignfigant(EncodingStatus a_encStatus)
+ {
+ if ((EncodingStatus)((unsigned int)m_warningsToCapture & (unsigned int)a_encStatus) == a_encStatus)
+ {
+ AddToEncodingStatus(a_encStatus);
+ }
+ }
+
+ Image(void);
+ void FindEncodingWarningTypesForCurFormat();
+ void FindAndSetEncodingWarnings();
+
+ void InitBlocksAndBlockSorter(void);
+
+ void RunFirstPass(unsigned int a_uiMultithreadingOffset,
+ unsigned int a_uiMultithreadingStride);
+
+ void SetEncodingBits(unsigned int a_uiMultithreadingOffset,
+ unsigned int a_uiMultithreadingStride);
+
+ unsigned int IterateThroughWorstBlocks(unsigned int a_uiMaxBlocks,
+ unsigned int a_uiMultithreadingOffset,
+ unsigned int a_uiMultithreadingStride);
+
+ // inputs
+ ColorFloatRGBA *m_pafrgbaSource;
+ unsigned int m_uiSourceWidth;
+ unsigned int m_uiSourceHeight;
+ unsigned int m_uiExtendedWidth;
+ unsigned int m_uiExtendedHeight;
+ unsigned int m_uiBlockColumns;
+ unsigned int m_uiBlockRows;
+ // intermediate data
+ Block4x4 *m_pablock;
+ // encoding
+ Format m_format;
+ Block4x4EncodingBits::Format m_encodingbitsformat;
+ unsigned int m_uiEncodingBitsBytes; // for entire image
+ unsigned char *m_paucEncodingBits;
+ ErrorMetric m_errormetric;
+ float m_fEffort;
+ // stats
+ int m_iEncodeTime_ms;
+
+ SortedBlockList *m_psortedblocklist;
+ //this will hold any warning or errors that happen during encoding
+ EncodingStatus m_encodingStatus;
+ //these will be the warnings we are tracking
+ EncodingStatus m_warningsToCapture;
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcIndividualTrys.cpp b/thirdparty/etc2comp/EtcIndividualTrys.cpp
new file mode 100644
index 0000000000..56ff4c65ec
--- /dev/null
+++ b/thirdparty/etc2comp/EtcIndividualTrys.cpp
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcIndividualTrys.cpp
+
+Gathers the results of the various encoding trys for both halves of a 4x4 block for Individual mode
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcIndividualTrys.h"
+
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ // construct a list of trys (encoding attempts)
+ //
+ // a_frgbaColor1 is the basecolor for the first half
+ // a_frgbaColor2 is the basecolor for the second half
+ // a_pauiPixelMapping1 is the pixel order for the first half
+ // a_pauiPixelMapping2 is the pixel order for the second half
+ // a_uiRadius is the amount to vary the base colors
+ //
+ IndividualTrys::IndividualTrys(ColorFloatRGBA a_frgbaColor1, ColorFloatRGBA a_frgbaColor2,
+ const unsigned int *a_pauiPixelMapping1,
+ const unsigned int *a_pauiPixelMapping2,
+ unsigned int a_uiRadius)
+ {
+ assert(a_uiRadius <= MAX_RADIUS);
+
+ ColorFloatRGBA frgbaQuantizedColor1 = a_frgbaColor1.QuantizeR4G4B4();
+ ColorFloatRGBA frgbaQuantizedColor2 = a_frgbaColor2.QuantizeR4G4B4();
+
+ // quantize base colors
+ // ensure that trys with a_uiRadius don't overflow
+ int iRed1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntRed(15.0f), a_uiRadius);
+ int iGreen1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntGreen(15.0f), a_uiRadius);
+ int iBlue1 = MoveAwayFromEdge(frgbaQuantizedColor1.IntBlue(15.0f), a_uiRadius);
+ int iRed2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntRed(15.0f), a_uiRadius);
+ int iGreen2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntGreen(15.0f), a_uiRadius);
+ int iBlue2 = MoveAwayFromEdge(frgbaQuantizedColor2.IntBlue(15.0f), a_uiRadius);
+
+ m_half1.Init(iRed1, iGreen1, iBlue1, a_pauiPixelMapping1, a_uiRadius);
+ m_half2.Init(iRed2, iGreen2, iBlue2, a_pauiPixelMapping2, a_uiRadius);
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ void IndividualTrys::Half::Init(int a_iRed, int a_iGreen, int a_iBlue,
+ const unsigned int *a_pauiPixelMapping, unsigned int a_uiRadius)
+ {
+
+ m_iRed = a_iRed;
+ m_iGreen = a_iGreen;
+ m_iBlue = a_iBlue;
+
+ m_pauiPixelMapping = a_pauiPixelMapping;
+ m_uiRadius = a_uiRadius;
+
+ m_uiTrys = 0;
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcIndividualTrys.h b/thirdparty/etc2comp/EtcIndividualTrys.h
new file mode 100644
index 0000000000..5fb12fbcf4
--- /dev/null
+++ b/thirdparty/etc2comp/EtcIndividualTrys.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "EtcColorFloatRGBA.h"
+
+namespace Etc
+{
+
+ class IndividualTrys
+ {
+ public:
+
+ static const unsigned int MAX_RADIUS = 1;
+
+ IndividualTrys(ColorFloatRGBA a_frgbaColor1,
+ ColorFloatRGBA a_frgbaColor2,
+ const unsigned int *a_pauiPixelMapping1,
+ const unsigned int *a_pauiPixelMapping2,
+ unsigned int a_uiRadius);
+
+ inline static int MoveAwayFromEdge(int a_i, int a_iDistance)
+ {
+ if (a_i < (0+ a_iDistance))
+ {
+ return (0 + a_iDistance);
+ }
+ else if (a_i > (15- a_iDistance))
+ {
+ return (15 - a_iDistance);
+ }
+
+ return a_i;
+ }
+
+ class Try
+ {
+ public :
+ static const unsigned int SELECTORS = 8; // per half
+
+ int m_iRed;
+ int m_iGreen;
+ int m_iBlue;
+ unsigned int m_uiCW;
+ unsigned int m_auiSelectors[SELECTORS];
+ float m_fError;
+ };
+
+ class Half
+ {
+ public:
+
+ static const unsigned int MAX_TRYS = 27;
+
+ void Init(int a_iRed, int a_iGreen, int a_iBlue,
+ const unsigned int *a_pauiPixelMapping,
+ unsigned int a_uiRadius);
+
+ // center of trys
+ int m_iRed;
+ int m_iGreen;
+ int m_iBlue;
+
+ const unsigned int *m_pauiPixelMapping;
+ unsigned int m_uiRadius;
+
+ unsigned int m_uiTrys;
+ Try m_atry[MAX_TRYS];
+
+ Try *m_ptryBest;
+ };
+
+ Half m_half1;
+ Half m_half2;
+
+ };
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcMath.cpp b/thirdparty/etc2comp/EtcMath.cpp
new file mode 100644
index 0000000000..096d5f7ab9
--- /dev/null
+++ b/thirdparty/etc2comp/EtcMath.cpp
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "EtcConfig.h"
+#include "EtcMath.h"
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ // calculate the line that best fits the set of XY points contained in a_afX[] and a_afY[]
+ // use a_fSlope and a_fOffset to define that line
+ //
+ bool Regression(float a_afX[], float a_afY[], unsigned int a_Points,
+ float *a_fSlope, float *a_fOffset)
+ {
+ float fPoints = (float)a_Points;
+
+ float fSumX = 0.0f;
+ float fSumY = 0.0f;
+ float fSumXY = 0.0f;
+ float fSumX2 = 0.0f;
+
+ for (unsigned int uiPoint = 0; uiPoint < a_Points; uiPoint++)
+ {
+ fSumX += a_afX[uiPoint];
+ fSumY += a_afY[uiPoint];
+ fSumXY += a_afX[uiPoint] * a_afY[uiPoint];
+ fSumX2 += a_afX[uiPoint] * a_afX[uiPoint];
+ }
+
+ float fDivisor = fPoints*fSumX2 - fSumX*fSumX;
+
+ // if vertical line
+ if (fDivisor == 0.0f)
+ {
+ *a_fSlope = 0.0f;
+ *a_fOffset = 0.0f;
+ return true;
+ }
+
+ *a_fSlope = (fPoints*fSumXY - fSumX*fSumY) / fDivisor;
+ *a_fOffset = (fSumY - (*a_fSlope)*fSumX) / fPoints;
+
+ return false;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcMath.h b/thirdparty/etc2comp/EtcMath.h
new file mode 100644
index 0000000000..c58c9a91bc
--- /dev/null
+++ b/thirdparty/etc2comp/EtcMath.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <math.h>
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ // return true if vertical line
+ bool Regression(float a_afX[], float a_afY[], unsigned int a_Points,
+ float *a_fSlope, float *a_fOffset);
+
+ inline float ConvertMSEToPSNR(float a_fMSE)
+ {
+ if (a_fMSE == 0.0f)
+ {
+ return INFINITY;
+ }
+
+ return 10.0f * log10f(1.0f / a_fMSE);
+ }
+
+
+}
diff --git a/thirdparty/etc2comp/EtcSortedBlockList.cpp b/thirdparty/etc2comp/EtcSortedBlockList.cpp
new file mode 100644
index 0000000000..bfa6b7b3fa
--- /dev/null
+++ b/thirdparty/etc2comp/EtcSortedBlockList.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+EtcSortedBlockList.cpp
+
+SortedBlockList is a list of 4x4 blocks that can be used by the "effort" system to prioritize
+the encoding of the 4x4 blocks.
+
+The sorting is done with buckets, where each bucket is an indication of how much error each 4x4 block has
+
+*/
+
+#include "EtcConfig.h"
+#include "EtcSortedBlockList.h"
+
+#include "EtcBlock4x4.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+namespace Etc
+{
+
+ // ----------------------------------------------------------------------------------------------------
+ // construct an empty list
+ //
+ // allocate enough memory to add all of the image's 4x4 blocks later
+ // allocate enough buckets to sort the blocks
+ //
+ SortedBlockList::SortedBlockList(unsigned int a_uiImageBlocks, unsigned int a_uiBuckets)
+ {
+ m_uiImageBlocks = a_uiImageBlocks;
+ m_iBuckets = (int)a_uiBuckets;
+
+ m_uiAddedBlocks = 0;
+ m_uiSortedBlocks = 0;
+ m_palinkPool = new Link[m_uiImageBlocks];
+ m_pabucket = new Bucket[m_iBuckets];
+ m_fMaxError = 0.0f;
+
+ InitBuckets();
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+ SortedBlockList::~SortedBlockList(void)
+ {
+ delete[] m_palinkPool;
+ delete[] m_pabucket;
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // add a 4x4 block to the list
+ // the 4x4 block will be sorted later
+ //
+ void SortedBlockList::AddBlock(Block4x4 *a_pblock)
+ {
+ assert(m_uiAddedBlocks < m_uiImageBlocks);
+ Link *plink = &m_palinkPool[m_uiAddedBlocks++];
+ plink->Init(a_pblock);
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // sort all of the 4x4 blocks that have been added to the list
+ //
+ // first, determine the maximum error, then assign an error range to each bucket
+ // next, determine which bucket each 4x4 block belongs to based on the 4x4 block's error
+ // add the 4x4 block to the appropriate bucket
+ // lastly, walk thru the buckets and add each bucket to a sorted linked list
+ //
+ // the resultant sorting is an approximate sorting from most to least error
+ //
+ void SortedBlockList::Sort(void)
+ {
+ assert(m_uiAddedBlocks == m_uiImageBlocks);
+ InitBuckets();
+
+ // find max block error
+ m_fMaxError = -1.0f;
+
+ for (unsigned int uiLink = 0; uiLink < m_uiAddedBlocks; uiLink++)
+ {
+ Link *plinkBlock = &m_palinkPool[uiLink];
+
+ float fBlockError = plinkBlock->GetBlock()->GetError();
+ if (fBlockError > m_fMaxError)
+ {
+ m_fMaxError = fBlockError;
+ }
+ }
+ // prevent divide by zero or divide by negative
+ if (m_fMaxError <= 0.0f)
+ {
+ m_fMaxError = 1.0f;
+ }
+ //used for debugging
+ //int numDone = 0;
+ // put all of the blocks with unfinished encodings into the appropriate bucket
+ m_uiSortedBlocks = 0;
+ for (unsigned int uiLink = 0; uiLink < m_uiAddedBlocks; uiLink++)
+ {
+ Link *plinkBlock = &m_palinkPool[uiLink];
+
+ // if the encoding is done, don't add it to the list
+ if (plinkBlock->GetBlock()->GetEncoding()->IsDone())
+ {
+ //numDone++;
+ continue;
+ }
+
+ // calculate the appropriate sort bucket
+ float fBlockError = plinkBlock->GetBlock()->GetError();
+ int iBucket = (int) floorf(m_iBuckets * fBlockError / m_fMaxError);
+ // clamp to bucket index
+ iBucket = iBucket < 0 ? 0 : iBucket >= m_iBuckets ? m_iBuckets - 1 : iBucket;
+
+ // add block to bucket
+ {
+ Bucket *pbucket = &m_pabucket[iBucket];
+ if (pbucket->plinkLast)
+ {
+ pbucket->plinkLast->SetNext(plinkBlock);
+ pbucket->plinkLast = plinkBlock;
+ }
+ else
+ {
+ pbucket->plinkFirst = pbucket->plinkLast = plinkBlock;
+ }
+ plinkBlock->SetNext(nullptr);
+ }
+
+ m_uiSortedBlocks++;
+
+ if (0)
+ {
+ printf("%u: e=%.3f\n", uiLink, fBlockError);
+ Print();
+ printf("\n\n\n");
+ }
+ }
+ //printf("num blocks already done: %d\n",numDone);
+ //link the blocks together across buckets
+ m_plinkFirst = nullptr;
+ m_plinkLast = nullptr;
+ for (int iBucket = m_iBuckets - 1; iBucket >= 0; iBucket--)
+ {
+ Bucket *pbucket = &m_pabucket[iBucket];
+
+ if (pbucket->plinkFirst)
+ {
+ if (m_plinkFirst == nullptr)
+ {
+ m_plinkFirst = pbucket->plinkFirst;
+ }
+ else
+ {
+ assert(pbucket->plinkLast->GetNext() == nullptr);
+ m_plinkLast->SetNext(pbucket->plinkFirst);
+ }
+
+ m_plinkLast = pbucket->plinkLast;
+ }
+ }
+
+
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // clear all of the buckets. normally done in preparation for a sort
+ //
+ void SortedBlockList::InitBuckets(void)
+ {
+ for (int iBucket = 0; iBucket < m_iBuckets; iBucket++)
+ {
+ Bucket *pbucket = &m_pabucket[iBucket];
+
+ pbucket->plinkFirst = 0;
+ pbucket->plinkLast = 0;
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ // print out the list of sorted 4x4 blocks
+ // normally used for debugging
+ //
+ void SortedBlockList::Print(void)
+ {
+ for (int iBucket = m_iBuckets-1; iBucket >= 0; iBucket--)
+ {
+ Bucket *pbucket = &m_pabucket[iBucket];
+
+ unsigned int uiBlocks = 0;
+ for (Link *plink = pbucket->plinkFirst; plink != nullptr; plink = plink->GetNext() )
+ {
+ uiBlocks++;
+
+ if (plink == pbucket->plinkLast)
+ {
+ break;
+ }
+ }
+
+ float fBucketError = m_fMaxError * iBucket / m_iBuckets;
+ float fBucketRMS = sqrtf(fBucketError / (4.0f*16.0f) );
+ printf("%3d: e=%.3f rms=%.6f %u\n", iBucket, fBucketError, fBucketRMS, uiBlocks);
+ }
+ }
+
+ // ----------------------------------------------------------------------------------------------------
+ //
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/EtcSortedBlockList.h b/thirdparty/etc2comp/EtcSortedBlockList.h
new file mode 100644
index 0000000000..960e8adc34
--- /dev/null
+++ b/thirdparty/etc2comp/EtcSortedBlockList.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2015 The Etc2Comp Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace Etc
+{
+ class Block4x4;
+
+ class SortedBlockList
+ {
+ public:
+
+ class Link
+ {
+ public:
+
+ inline void Init(Block4x4 *a_pblock)
+ {
+ m_pblock = a_pblock;
+ m_plinkNext = nullptr;
+ }
+
+ inline Block4x4 * GetBlock(void)
+ {
+ return m_pblock;
+ }
+
+ inline void SetNext(Link *a_plinkNext)
+ {
+ m_plinkNext = a_plinkNext;
+ }
+
+ inline Link * GetNext(void)
+ {
+ return m_plinkNext;
+ }
+
+ inline Link * Advance(unsigned int a_uiSteps = 1)
+ {
+ Link *plink = this;
+
+ for (unsigned int uiStep = 0; uiStep < a_uiSteps; uiStep++)
+ {
+ if (plink == nullptr)
+ {
+ break;
+ }
+
+ plink = plink->m_plinkNext;
+ }
+
+ return plink;
+ }
+
+ private:
+
+ Block4x4 *m_pblock;
+ Link *m_plinkNext;
+ };
+
+ SortedBlockList(unsigned int a_uiImageBlocks, unsigned int a_uiBuckets);
+ ~SortedBlockList(void);
+
+ void AddBlock(Block4x4 *a_pblock);
+
+ void Sort(void);
+
+ inline Link * GetLinkToFirstBlock(void)
+ {
+ return m_plinkFirst;
+ }
+
+ inline unsigned int GetNumberOfAddedBlocks(void)
+ {
+ return m_uiAddedBlocks;
+ }
+
+ inline unsigned int GetNumberOfSortedBlocks(void)
+ {
+ return m_uiSortedBlocks;
+ }
+
+ void Print(void);
+
+ private:
+
+ void InitBuckets(void);
+
+ class Bucket
+ {
+ public:
+ Link *plinkFirst;
+ Link *plinkLast;
+ };
+
+ unsigned int m_uiImageBlocks;
+ int m_iBuckets;
+
+ unsigned int m_uiAddedBlocks;
+ unsigned int m_uiSortedBlocks;
+ Link *m_palinkPool;
+ Bucket *m_pabucket;
+ float m_fMaxError;
+
+ Link *m_plinkFirst;
+ Link *m_plinkLast;
+
+ };
+
+} // namespace Etc
diff --git a/thirdparty/etc2comp/LICENSE b/thirdparty/etc2comp/LICENSE
new file mode 100644
index 0000000000..75b52484ea
--- /dev/null
+++ b/thirdparty/etc2comp/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/thirdparty/etc2comp/README.md b/thirdparty/etc2comp/README.md
new file mode 100644
index 0000000000..1c70ae9f4e
--- /dev/null
+++ b/thirdparty/etc2comp/README.md
@@ -0,0 +1,197 @@
+# Etc2Comp - Texture to ETC2 compressor
+
+Etc2Comp is a command line tool that converts textures (e.g. bitmaps)
+into the [ETC2](https://en.wikipedia.org/wiki/Ericsson_Texture_Compression)
+format. The tool is built with a focus on encoding performance
+to reduce the amount of time required to compile asset heavy applications as
+well as reduce overall application size.
+
+This repo provides source code that can be compiled into a binary. The
+binary can then be used to convert textures to the ETC2 format.
+
+Important: This is not an official Google product. It is an experimental
+library published as-is. Please see the CONTRIBUTORS.md file for information
+about questions or issues.
+
+## Setup
+This project uses [CMake](https://cmake.org/) to generate platform-specific
+build files:
+ - Linux: make files
+ - OS X: Xcode workspace files
+ - Microsoft Windows: Visual Studio solution files
+ - Note: CMake supports other formats, but this doc only provides steps for
+ one of each platform for brevity.
+
+Refer to each platform's setup section to setup your environment and build
+an Etc2Comp binary. Then skip to the usage section of this page for examples
+of how to use the library.
+
+### Setup for OS X
+ build tested on this config:
+ OS X 10.9.5 i7 16GB RAM
+ Xcode 5.1.1
+ cmake 3.2.3
+
+Start by downloading and installing the following components if they are not
+already installed on your development machine.
+ - *Xcode* version 5.1.1, or greater
+ - [CMake](https://cmake.org/download/) version 3.2.3, or greater
+
+To build the Etc2Comp binary:
+ 1. Open a *Terminal* window and navigate to the project directory.
+ 1. Run `mkdir build_xcode`
+ 1. Run `cd build_xcode`
+ 1. Run `cmake -G Xcode ../`
+ 1. Open *Xcode* and import the `build_xcode/EtcTest.xcodeproj` file.
+ 1. Open the Product menu and choose Build For -> Running.
+ 1. Once the build succeeds the binary located at `build_xcode/EtcTool/Debug/EtcTool`
+can be executed.
+
+Optional
+Xcode EtcTool ‘Run’ preferences
+note: if the build_xcode/EtcTest.xcodeproj is manually deleted then some Xcode preferences
+will need to be set by hand after cmake is run (these prefs are retained across
+cmake updates if the .xcodeproj is not deleted/removed)
+
+1. Set the active scheme to ‘EtcTool’
+1. Edit the scheme
+1. Select option ‘Run EtcTool’, then tab ‘Arguments’.
+Add this launch argument: ‘-argfile ../../EtcTool/args.txt’
+1. Select tab ‘Options’ and set a custom working directory to: ‘$(SRCROOT)/Build_Xcode/EtcTool’
+
+### SetUp for Windows
+
+1. Open a *Terminal* window and navigate to the project directory.
+1. Run `mkdir build_vs`
+1. Run `cd build_vs`
+1. Run CMAKE, noting what build version you need, and pointing to the parent directory as the source root;
+ For VS 2013 : `cmake -G "Visual Studio 12 2013 Win64" ../`
+ For VS 2015 : `cmake -G "Visual Studio 14 2015 Win64" ../`
+ NOTE: To see what supported Visual Studio outputs there are, run `cmake -G`
+1. open the 'EtcTest' solution
+1. make the 'EtcTool' project the start up project
+1. (optional) in the project properties, under 'Debugging ->command arguments'
+add the argfile textfile thats included in the EtcTool directory.
+example: -argfile C:\etc2\EtcTool\Args.txt
+
+### Setup For Linux
+The Linux build was tested on this config:
+ Ubuntu desktop 14.04
+ gcc/g++ 4.8
+ cmake 2.8.12.2
+
+1. Verify linux has cmake and C++-11 capable g++ installed
+1. Open shell
+1. Run `mkdir build_linux`
+1. Run `cd build_linux`
+1. Run `cmake ../`
+1. Run `make`
+1. navigate to the newly created EtcTool directory `cd EtcTool`
+1. run the executable: `./EtcTool -argfile ../../EtcTool/args.txt`
+
+Skip to the <a href="#usage">Usage</a> section for more information about using the
+tool.
+
+## Usage
+
+### Command Line Usage
+EtcTool can be run from the command line with the following usage:
+ etctool.exe source_image [options ...] -output encoded_image
+
+The encoder will use an array of RGBA floats read from the source_image to create
+an ETC1 or ETC2 encoded image in encoded_image. The RGBA floats should be in the
+range [0:1].
+
+Options:
+
+ -analyze <analysis_folder>
+ -argfile <arg_file> additional command line arguments read from a file
+ -blockAtHV <H V> encodes a single block that contains the
+ pixel specified by the H V coordinates
+ -compare <comparison_image> compares source_image to comparison_image
+ -effort <amount> number between 0 and 100 to specify the encoding quality
+ (100 is the highest quality)
+ -errormetric <error_metric> specify the error metric, the options are
+ rgba, rgbx, rec709, numeric and normalxyz
+ -format <etc_format> ETC1, RGB8, SRGB8, RGBA8, SRGB8, RGB8A1,
+ SRGB8A1 or R11
+ -help prints this message
+ -jobs or -j <thread_count> specifies the number of threads (default=1)
+ -normalizexyz normalize RGB to have a length of 1
+ -verbose or -v shows status information during the encoding
+ process
+ -mipmaps or -m <mip_count> sets the maximum number of mipaps to generate (default=1)
+ -mipwrap or -w <x|y|xy> sets the mipmap filter wrap mode (default=clamp)
+
+* -analyze will run an analysis of the encoding and place it in folder
+"analysis_folder" (e.g. ../analysis/kodim05). within the analysis_folder, a folder
+will be created with a name of the current date/time (e.g. 20151204_153306). this
+date/time folder is used to compare encodings of the same texture over time.
+within the date/time folder is a text file with several encoding stats and a 2x png
+image showing the encoding mode for each 4x4 block.
+
+* -argfile allows additional command line arguments to be placed in a text file
+
+* -blockAtHV selects the 4x4 pixel subset of the source image at position (H,V).
+This is mainly used for debugging
+
+* -compare compares the source image to the created encoded image. The encoding
+will dictate what error analysis is used in the comparison.
+
+* -effort uses an "amount" between 0 and 100 to determine how much additional effort
+to apply during the encoding.
+
+* -errormetric selects the fitting algorithm used by the encoder. "rgba" calculates
+RMS error using RGB components that are weighted by A. "rgbx" calculates RMS error
+using RGBA components, where A is treated as an additional data channel, instead of
+as alpha. "rec709" is similar to "rgba", except the RGB components are also weighted
+according to Rec709. "numeric" calculates RMS error using unweighted RGBA components.
+"normalize" calculates error based on dot product and vector length for RGB and RMS
+error for A.
+
+* -help prints out the usage message
+
+* -jobs enables multi-threading to speed up image encoding
+
+* -normalizexyz normalizes the source RGB to have a length of 1.
+
+* -verbose shows information on the current encoding process. It will then display the
+PSNR and time time it took to encode the image.
+
+* -mipmaps takes an argument that specifies how many mipmaps to generate from the
+source image. The mipmaps are generated with a lanczos3 filter using edge clamping.
+If the mipmaps option is not specified no mipmaps are created.
+
+* -mipwrap takes an argument that specifies the mipmap filter wrap mode. The options
+are "x", "y" and "xy" which specify wrapping in x only, y only or x and y respectively.
+The default options are clamping in both x and y.
+
+Note: Path names can use slashes or backslashes. The tool will convert the
+slashes to the appropriate polarity for the current platform.
+
+
+## API
+
+The library supports two different APIs - a C-like API that is not heavily
+class-based and a class-based API.
+
+main() in EtcTool.cpp contains an example of both APIs.
+
+The Encode() method now returns an EncodingStatus that contains bit flags for
+reporting various warnings and flags encountered when encoding.
+
+
+## Copyright
+Copyright 2015 Etc2Comp Authors.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/thirdparty/glad/glad.c b/thirdparty/glad/glad.c
index 70a93f8d25..2d756ec3f6 100644
--- a/thirdparty/glad/glad.c
+++ b/thirdparty/glad/glad.c
@@ -1,6 +1,6 @@
/*
- OpenGL loader generated by glad 0.1.13a0 on Fri Jan 6 19:27:07 2017.
+ OpenGL loader generated by glad 0.1.14a0 on Wed Jun 14 20:12:45 2017.
Language/Generator: C/C++
Specification: gl
@@ -30,7 +30,7 @@ static void* get_proc(const char *namez);
static HMODULE libGL;
typedef void* (APIENTRYP PFNWGLGETPROCADDRESSPROC_PRIVATE)(const char*);
-PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
+static PFNWGLGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
static
int open_gl(void) {
@@ -57,7 +57,7 @@ static void* libGL;
#ifndef __APPLE__
typedef void* (APIENTRYP PFNGLXGETPROCADDRESSPROC_PRIVATE)(const char*);
-PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
+static PFNGLXGETPROCADDRESSPROC_PRIVATE gladGetProcAddressPtr;
#endif
static
@@ -152,19 +152,19 @@ static int get_exts(void) {
exts = (const char *)glGetString(GL_EXTENSIONS);
#ifdef _GLAD_IS_SOME_NEW_VERSION
} else {
- int index;
+ unsigned int index;
num_exts_i = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &num_exts_i);
if (num_exts_i > 0) {
- exts_i = (const char **)realloc((void *)exts_i, num_exts_i * sizeof *exts_i);
+ exts_i = (const char **)realloc((void *)exts_i, (size_t)num_exts_i * (sizeof *exts_i));
}
if (exts_i == NULL) {
return 0;
}
- for(index = 0; index < num_exts_i; index++) {
+ for(index = 0; index < (unsigned)num_exts_i; index++) {
exts_i[index] = (const char*)glGetStringi(GL_EXTENSIONS, index);
}
}
@@ -174,7 +174,7 @@ static int get_exts(void) {
static void free_exts(void) {
if (exts_i != NULL) {
- free((char **)exts_i);
+ free((void *)exts_i);
exts_i = NULL;
}
}
diff --git a/thirdparty/glad/glad/glad.h b/thirdparty/glad/glad/glad.h
index e5eb22e297..cb78df071e 100644
--- a/thirdparty/glad/glad/glad.h
+++ b/thirdparty/glad/glad/glad.h
@@ -1,6 +1,6 @@
/*
- OpenGL loader generated by glad 0.1.13a0 on Fri Jan 6 19:27:07 2017.
+ OpenGL loader generated by glad 0.1.14a0 on Wed Jun 14 20:12:45 2017.
Language/Generator: C/C++
Specification: gl
@@ -54,7 +54,7 @@ typedef void* (* GLADloadproc)(const char *name);
#ifndef GLAPI
# if defined(GLAD_GLAPI_EXPORT)
-# if defined(WIN32) || defined(__CYGWIN__)
+# if defined(_WIN32) || defined(__CYGWIN__)
# if defined(GLAD_GLAPI_EXPORT_BUILD)
# if defined(__GNUC__)
# define GLAPI __attribute__ ((dllexport)) extern
@@ -183,6 +183,7 @@ typedef void (APIENTRY *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLen
typedef void (APIENTRY *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam);
typedef unsigned short GLhalfNV;
typedef GLintptr GLvdpauSurfaceNV;
+typedef void (APIENTRY *GLVULKANPROCNV)(void);
#define GL_DEPTH_BUFFER_BIT 0x00000100
#define GL_STENCIL_BUFFER_BIT 0x00000400
#define GL_COLOR_BUFFER_BIT 0x00004000
@@ -264,7 +265,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_BLEND_SRC 0x0BE1
#define GL_BLEND 0x0BE2
#define GL_LOGIC_OP_MODE 0x0BF0
-#define GL_COLOR_LOGIC_OP 0x0BF2
#define GL_DRAW_BUFFER 0x0C01
#define GL_READ_BUFFER 0x0C02
#define GL_SCISSOR_BOX 0x0C10
@@ -292,21 +292,9 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_SUBPIXEL_BITS 0x0D50
#define GL_TEXTURE_1D 0x0DE0
#define GL_TEXTURE_2D 0x0DE1
-#define GL_POLYGON_OFFSET_UNITS 0x2A00
-#define GL_POLYGON_OFFSET_POINT 0x2A01
-#define GL_POLYGON_OFFSET_LINE 0x2A02
-#define GL_POLYGON_OFFSET_FILL 0x8037
-#define GL_POLYGON_OFFSET_FACTOR 0x8038
-#define GL_TEXTURE_BINDING_1D 0x8068
-#define GL_TEXTURE_BINDING_2D 0x8069
#define GL_TEXTURE_WIDTH 0x1000
#define GL_TEXTURE_HEIGHT 0x1001
-#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
#define GL_TEXTURE_BORDER_COLOR 0x1004
-#define GL_TEXTURE_RED_SIZE 0x805C
-#define GL_TEXTURE_GREEN_SIZE 0x805D
-#define GL_TEXTURE_BLUE_SIZE 0x805E
-#define GL_TEXTURE_ALPHA_SIZE 0x805F
#define GL_DONT_CARE 0x1100
#define GL_FASTEST 0x1101
#define GL_NICEST 0x1102
@@ -317,7 +305,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_INT 0x1404
#define GL_UNSIGNED_INT 0x1405
#define GL_FLOAT 0x1406
-#define GL_DOUBLE 0x140A
#define GL_STACK_OVERFLOW 0x0503
#define GL_STACK_UNDERFLOW 0x0504
#define GL_CLEAR 0x1500
@@ -369,23 +356,7 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_TEXTURE_MIN_FILTER 0x2801
#define GL_TEXTURE_WRAP_S 0x2802
#define GL_TEXTURE_WRAP_T 0x2803
-#define GL_PROXY_TEXTURE_1D 0x8063
-#define GL_PROXY_TEXTURE_2D 0x8064
#define GL_REPEAT 0x2901
-#define GL_R3_G3_B2 0x2A10
-#define GL_RGB4 0x804F
-#define GL_RGB5 0x8050
-#define GL_RGB8 0x8051
-#define GL_RGB10 0x8052
-#define GL_RGB12 0x8053
-#define GL_RGB16 0x8054
-#define GL_RGBA2 0x8055
-#define GL_RGBA4 0x8056
-#define GL_RGB5_A1 0x8057
-#define GL_RGBA8 0x8058
-#define GL_RGB10_A2 0x8059
-#define GL_RGBA12 0x805A
-#define GL_RGBA16 0x805B
#define GL_CURRENT_BIT 0x00000001
#define GL_POINT_BIT 0x00000002
#define GL_LINE_BIT 0x00000004
@@ -404,9 +375,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_TEXTURE_BIT 0x00040000
#define GL_SCISSOR_BIT 0x00080000
#define GL_ALL_ATTRIB_BITS 0xFFFFFFFF
-#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
-#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
-#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
#define GL_QUAD_STRIP 0x0008
#define GL_POLYGON 0x0009
#define GL_ACCUM 0x0100
@@ -446,14 +414,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_PIXEL_MAP_G_TO_G 0x0C77
#define GL_PIXEL_MAP_B_TO_B 0x0C78
#define GL_PIXEL_MAP_A_TO_A 0x0C79
-#define GL_VERTEX_ARRAY_POINTER 0x808E
-#define GL_NORMAL_ARRAY_POINTER 0x808F
-#define GL_COLOR_ARRAY_POINTER 0x8090
-#define GL_INDEX_ARRAY_POINTER 0x8091
-#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
-#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
-#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
-#define GL_SELECTION_BUFFER_POINTER 0x0DF3
#define GL_CURRENT_COLOR 0x0B00
#define GL_CURRENT_INDEX 0x0B01
#define GL_CURRENT_NORMAL 0x0B02
@@ -499,11 +459,9 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_PROJECTION_MATRIX 0x0BA7
#define GL_TEXTURE_MATRIX 0x0BA8
#define GL_ATTRIB_STACK_DEPTH 0x0BB0
-#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
#define GL_ALPHA_TEST 0x0BC0
#define GL_ALPHA_TEST_FUNC 0x0BC1
#define GL_ALPHA_TEST_REF 0x0BC2
-#define GL_INDEX_LOGIC_OP 0x0BF1
#define GL_LOGIC_OP 0x0BF1
#define GL_AUX_BUFFERS 0x0C00
#define GL_INDEX_CLEAR_VALUE 0x0C20
@@ -553,7 +511,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_MAX_NAME_STACK_DEPTH 0x0D37
#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38
#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39
-#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
#define GL_INDEX_BITS 0x0D51
#define GL_RED_BITS 0x0D52
#define GL_GREEN_BITS 0x0D53
@@ -589,35 +546,8 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_MAP1_GRID_SEGMENTS 0x0DD1
#define GL_MAP2_GRID_DOMAIN 0x0DD2
#define GL_MAP2_GRID_SEGMENTS 0x0DD3
-#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
-#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
-#define GL_SELECTION_BUFFER_SIZE 0x0DF4
-#define GL_VERTEX_ARRAY 0x8074
-#define GL_NORMAL_ARRAY 0x8075
-#define GL_COLOR_ARRAY 0x8076
-#define GL_INDEX_ARRAY 0x8077
-#define GL_TEXTURE_COORD_ARRAY 0x8078
-#define GL_EDGE_FLAG_ARRAY 0x8079
-#define GL_VERTEX_ARRAY_SIZE 0x807A
-#define GL_VERTEX_ARRAY_TYPE 0x807B
-#define GL_VERTEX_ARRAY_STRIDE 0x807C
-#define GL_NORMAL_ARRAY_TYPE 0x807E
-#define GL_NORMAL_ARRAY_STRIDE 0x807F
-#define GL_COLOR_ARRAY_SIZE 0x8081
-#define GL_COLOR_ARRAY_TYPE 0x8082
-#define GL_COLOR_ARRAY_STRIDE 0x8083
-#define GL_INDEX_ARRAY_TYPE 0x8085
-#define GL_INDEX_ARRAY_STRIDE 0x8086
-#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
-#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
-#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
-#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
#define GL_TEXTURE_COMPONENTS 0x1003
#define GL_TEXTURE_BORDER 0x1005
-#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
-#define GL_TEXTURE_INTENSITY_SIZE 0x8061
-#define GL_TEXTURE_PRIORITY 0x8066
-#define GL_TEXTURE_RESIDENT 0x8067
#define GL_AMBIENT 0x1200
#define GL_DIFFUSE 0x1201
#define GL_SPECULAR 0x1202
@@ -664,6 +594,91 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_OBJECT_PLANE 0x2501
#define GL_EYE_PLANE 0x2502
#define GL_CLAMP 0x2900
+#define GL_CLIP_PLANE0 0x3000
+#define GL_CLIP_PLANE1 0x3001
+#define GL_CLIP_PLANE2 0x3002
+#define GL_CLIP_PLANE3 0x3003
+#define GL_CLIP_PLANE4 0x3004
+#define GL_CLIP_PLANE5 0x3005
+#define GL_LIGHT0 0x4000
+#define GL_LIGHT1 0x4001
+#define GL_LIGHT2 0x4002
+#define GL_LIGHT3 0x4003
+#define GL_LIGHT4 0x4004
+#define GL_LIGHT5 0x4005
+#define GL_LIGHT6 0x4006
+#define GL_LIGHT7 0x4007
+#define GL_COLOR_LOGIC_OP 0x0BF2
+#define GL_POLYGON_OFFSET_UNITS 0x2A00
+#define GL_POLYGON_OFFSET_POINT 0x2A01
+#define GL_POLYGON_OFFSET_LINE 0x2A02
+#define GL_POLYGON_OFFSET_FILL 0x8037
+#define GL_POLYGON_OFFSET_FACTOR 0x8038
+#define GL_TEXTURE_BINDING_1D 0x8068
+#define GL_TEXTURE_BINDING_2D 0x8069
+#define GL_TEXTURE_INTERNAL_FORMAT 0x1003
+#define GL_TEXTURE_RED_SIZE 0x805C
+#define GL_TEXTURE_GREEN_SIZE 0x805D
+#define GL_TEXTURE_BLUE_SIZE 0x805E
+#define GL_TEXTURE_ALPHA_SIZE 0x805F
+#define GL_DOUBLE 0x140A
+#define GL_PROXY_TEXTURE_1D 0x8063
+#define GL_PROXY_TEXTURE_2D 0x8064
+#define GL_R3_G3_B2 0x2A10
+#define GL_RGB4 0x804F
+#define GL_RGB5 0x8050
+#define GL_RGB8 0x8051
+#define GL_RGB10 0x8052
+#define GL_RGB12 0x8053
+#define GL_RGB16 0x8054
+#define GL_RGBA2 0x8055
+#define GL_RGBA4 0x8056
+#define GL_RGB5_A1 0x8057
+#define GL_RGBA8 0x8058
+#define GL_RGB10_A2 0x8059
+#define GL_RGBA12 0x805A
+#define GL_RGBA16 0x805B
+#define GL_CLIENT_PIXEL_STORE_BIT 0x00000001
+#define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002
+#define GL_CLIENT_ALL_ATTRIB_BITS 0xFFFFFFFF
+#define GL_VERTEX_ARRAY_POINTER 0x808E
+#define GL_NORMAL_ARRAY_POINTER 0x808F
+#define GL_COLOR_ARRAY_POINTER 0x8090
+#define GL_INDEX_ARRAY_POINTER 0x8091
+#define GL_TEXTURE_COORD_ARRAY_POINTER 0x8092
+#define GL_EDGE_FLAG_ARRAY_POINTER 0x8093
+#define GL_FEEDBACK_BUFFER_POINTER 0x0DF0
+#define GL_SELECTION_BUFFER_POINTER 0x0DF3
+#define GL_CLIENT_ATTRIB_STACK_DEPTH 0x0BB1
+#define GL_INDEX_LOGIC_OP 0x0BF1
+#define GL_MAX_CLIENT_ATTRIB_STACK_DEPTH 0x0D3B
+#define GL_FEEDBACK_BUFFER_SIZE 0x0DF1
+#define GL_FEEDBACK_BUFFER_TYPE 0x0DF2
+#define GL_SELECTION_BUFFER_SIZE 0x0DF4
+#define GL_VERTEX_ARRAY 0x8074
+#define GL_NORMAL_ARRAY 0x8075
+#define GL_COLOR_ARRAY 0x8076
+#define GL_INDEX_ARRAY 0x8077
+#define GL_TEXTURE_COORD_ARRAY 0x8078
+#define GL_EDGE_FLAG_ARRAY 0x8079
+#define GL_VERTEX_ARRAY_SIZE 0x807A
+#define GL_VERTEX_ARRAY_TYPE 0x807B
+#define GL_VERTEX_ARRAY_STRIDE 0x807C
+#define GL_NORMAL_ARRAY_TYPE 0x807E
+#define GL_NORMAL_ARRAY_STRIDE 0x807F
+#define GL_COLOR_ARRAY_SIZE 0x8081
+#define GL_COLOR_ARRAY_TYPE 0x8082
+#define GL_COLOR_ARRAY_STRIDE 0x8083
+#define GL_INDEX_ARRAY_TYPE 0x8085
+#define GL_INDEX_ARRAY_STRIDE 0x8086
+#define GL_TEXTURE_COORD_ARRAY_SIZE 0x8088
+#define GL_TEXTURE_COORD_ARRAY_TYPE 0x8089
+#define GL_TEXTURE_COORD_ARRAY_STRIDE 0x808A
+#define GL_EDGE_FLAG_ARRAY_STRIDE 0x808C
+#define GL_TEXTURE_LUMINANCE_SIZE 0x8060
+#define GL_TEXTURE_INTENSITY_SIZE 0x8061
+#define GL_TEXTURE_PRIORITY 0x8066
+#define GL_TEXTURE_RESIDENT 0x8067
#define GL_ALPHA4 0x803B
#define GL_ALPHA8 0x803C
#define GL_ALPHA12 0x803D
@@ -697,20 +712,6 @@ typedef GLintptr GLvdpauSurfaceNV;
#define GL_T2F_N3F_V3F 0x2A2B
#define GL_T2F_C4F_N3F_V3F 0x2A2C
#define GL_T4F_C4F_N3F_V4F 0x2A2D
-#define GL_CLIP_PLANE0 0x3000
-#define GL_CLIP_PLANE1 0x3001
-#define GL_CLIP_PLANE2 0x3002
-#define GL_CLIP_PLANE3 0x3003
-#define GL_CLIP_PLANE4 0x3004
-#define GL_CLIP_PLANE5 0x3005
-#define GL_LIGHT0 0x4000
-#define GL_LIGHT1 0x4001
-#define GL_LIGHT2 0x4002
-#define GL_LIGHT3 0x4003
-#define GL_LIGHT4 0x4004
-#define GL_LIGHT5 0x4005
-#define GL_LIGHT6 0x4006
-#define GL_LIGHT7 0x4007
#define GL_UNSIGNED_BYTE_3_3_2 0x8032
#define GL_UNSIGNED_SHORT_4_4_4_4 0x8033
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
diff --git a/thirdparty/misc/yuv2rgb.h b/thirdparty/misc/yuv2rgb.h
index a9bef76da8..d0c2813a75 100644
--- a/thirdparty/misc/yuv2rgb.h
+++ b/thirdparty/misc/yuv2rgb.h
@@ -1,5 +1,28 @@
/* Thirdparty code presumably from http://wss.co.uk/pinknoise/yuv2rgb/ */
-/* FIXME: Move to thirdparty dir */
+
+/*
+This YUV2RGB code is Copyright (C) 2008-11 Robin Watts
+<theorarm@wss.co.uk>.
+
+The software is released under the BSD license.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION
+OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+In particular, I warrant absolutely nothing about how patent free
+this method is. It is your responsibility to ensure that this code
+does not infringe any patents that apply in your area before you
+ship it.
+*/
#ifndef YUV2RGB_H
#define YUV2RGB_H
diff --git a/thirdparty/openssl/crypto/LPdir_nyi.c b/thirdparty/openssl/crypto/LPdir_nyi.c
index 283d5b0636..b16e84957b 100644
--- a/thirdparty/openssl/crypto/LPdir_nyi.c
+++ b/thirdparty/openssl/crypto/LPdir_nyi.c
@@ -1,7 +1,4 @@
/*
- * $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
diff --git a/thirdparty/openssl/crypto/LPdir_unix.c b/thirdparty/openssl/crypto/LPdir_unix.c
index bead6abd71..c97e260492 100644
--- a/thirdparty/openssl/crypto/LPdir_unix.c
+++ b/thirdparty/openssl/crypto/LPdir_unix.c
@@ -1,8 +1,4 @@
/*
- * $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp
- * $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
diff --git a/thirdparty/openssl/crypto/LPdir_win32.c b/thirdparty/openssl/crypto/LPdir_win32.c
index b1c983d87f..84f61117b8 100644
--- a/thirdparty/openssl/crypto/LPdir_win32.c
+++ b/thirdparty/openssl/crypto/LPdir_win32.c
@@ -1,8 +1,4 @@
/*
- * $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
- * $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
diff --git a/thirdparty/openssl/crypto/LPdir_wince.c b/thirdparty/openssl/crypto/LPdir_wince.c
index ae8a56f4be..a8377f30f4 100644
--- a/thirdparty/openssl/crypto/LPdir_wince.c
+++ b/thirdparty/openssl/crypto/LPdir_wince.c
@@ -1,8 +1,4 @@
/*
- * $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
- * $
- */
-/*
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
* All rights reserved.
*
diff --git a/thirdparty/openssl/crypto/asn1/a_bitstr.c b/thirdparty/openssl/crypto/asn1/a_bitstr.c
index f906188b11..c429342e03 100644
--- a/thirdparty/openssl/crypto/asn1/a_bitstr.c
+++ b/thirdparty/openssl/crypto/asn1/a_bitstr.c
@@ -114,10 +114,11 @@ int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
*(p++) = (unsigned char)bits;
d = a->data;
- memcpy(p, d, len);
- p += len;
- if (len > 0)
+ if (len > 0) {
+ memcpy(p, d, len);
+ p += len;
p[-1] &= (0xff << bits);
+ }
*pp = p;
return (ret);
}
diff --git a/thirdparty/openssl/crypto/asn1/a_bytes.c b/thirdparty/openssl/crypto/asn1/a_bytes.c
index 385b53986a..65e5394664 100644
--- a/thirdparty/openssl/crypto/asn1/a_bytes.c
+++ b/thirdparty/openssl/crypto/asn1/a_bytes.c
@@ -60,7 +60,12 @@
#include "cryptlib.h"
#include <openssl/asn1.h>
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
+ int depth);
+static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
+ const unsigned char **pp, long length,
+ int Ptag, int Pclass, int depth,
+ int *perr);
/*
* type is a 'bitmap' of acceptable string types.
*/
@@ -99,7 +104,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
ret = (*a);
if (len != 0) {
- s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ s = OPENSSL_malloc((int)len + 1);
if (s == NULL) {
i = ERR_R_MALLOC_FAILURE;
goto err;
@@ -154,15 +159,38 @@ int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
return (r);
}
+/*
+ * Maximum recursion depth of d2i_ASN1_bytes(): much more than should be
+ * encountered in pratice.
+ */
+
+#define ASN1_BYTES_MAXDEPTH 20
+
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
long length, int Ptag, int Pclass)
{
+ int err = 0;
+ ASN1_STRING *s = int_d2i_ASN1_bytes(a, pp, length, Ptag, Pclass, 0, &err);
+ if (err != 0)
+ ASN1err(ASN1_F_D2I_ASN1_BYTES, err);
+ return s;
+}
+
+static ASN1_STRING *int_d2i_ASN1_bytes(ASN1_STRING **a,
+ const unsigned char **pp, long length,
+ int Ptag, int Pclass,
+ int depth, int *perr)
+{
ASN1_STRING *ret = NULL;
const unsigned char *p;
unsigned char *s;
long len;
int inf, tag, xclass;
- int i = 0;
+
+ if (depth > ASN1_BYTES_MAXDEPTH) {
+ *perr = ASN1_R_NESTED_ASN1_STRING;
+ return NULL;
+ }
if ((a == NULL) || ((*a) == NULL)) {
if ((ret = ASN1_STRING_new()) == NULL)
@@ -173,18 +201,19 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
p = *pp;
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
if (inf & 0x80) {
- i = ASN1_R_BAD_OBJECT_HEADER;
+ *perr = ASN1_R_BAD_OBJECT_HEADER;
goto err;
}
if (tag != Ptag) {
- i = ASN1_R_WRONG_TAG;
+ *perr = ASN1_R_WRONG_TAG;
goto err;
}
if (inf & V_ASN1_CONSTRUCTED) {
ASN1_const_CTX c;
+ c.error = 0;
c.pp = pp;
c.p = p;
c.inf = inf;
@@ -192,17 +221,18 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
c.tag = Ptag;
c.xclass = Pclass;
c.max = (length == 0) ? 0 : (p + length);
- if (!asn1_collate_primitive(ret, &c))
+ if (!asn1_collate_primitive(ret, &c, depth)) {
+ *perr = c.error;
goto err;
- else {
+ } else {
p = c.p;
}
} else {
if (len != 0) {
if ((ret->length < len) || (ret->data == NULL)) {
- s = (unsigned char *)OPENSSL_malloc((int)len + 1);
+ s = OPENSSL_malloc((int)len + 1);
if (s == NULL) {
- i = ERR_R_MALLOC_FAILURE;
+ *perr = ERR_R_MALLOC_FAILURE;
goto err;
}
if (ret->data != NULL)
@@ -230,7 +260,6 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
- ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
return (NULL);
}
@@ -242,7 +271,8 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
* There have been a few bug fixes for this function from Paul Keogh
* <paul.keogh@sse.ie>, many thanks to him
*/
-static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
+static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c,
+ int depth)
{
ASN1_STRING *os = NULL;
BUF_MEM b;
@@ -270,9 +300,8 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
}
c->q = c->p;
- if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
- == NULL) {
- c->error = ERR_R_ASN1_LIB;
+ if (int_d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass,
+ depth + 1, &c->error) == NULL) {
goto err;
}
@@ -297,7 +326,6 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
ASN1_STRING_free(os);
return (1);
err:
- ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
if (os != NULL)
ASN1_STRING_free(os);
if (b.data != NULL)
diff --git a/thirdparty/openssl/crypto/asn1/a_digest.c b/thirdparty/openssl/crypto/asn1/a_digest.c
index 7cbc4751cd..57a04f768c 100644
--- a/thirdparty/openssl/crypto/asn1/a_digest.c
+++ b/thirdparty/openssl/crypto/asn1/a_digest.c
@@ -86,8 +86,10 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
p = str;
i2d(data, &p);
- if (!EVP_Digest(str, i, md, len, type, NULL))
+ if (!EVP_Digest(str, i, md, len, type, NULL)) {
+ OPENSSL_free(str);
return 0;
+ }
OPENSSL_free(str);
return (1);
}
@@ -104,8 +106,10 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
if (!str)
return (0);
- if (!EVP_Digest(str, i, md, len, type, NULL))
+ if (!EVP_Digest(str, i, md, len, type, NULL)) {
+ OPENSSL_free(str);
return 0;
+ }
OPENSSL_free(str);
return (1);
}
diff --git a/thirdparty/openssl/crypto/asn1/a_gentm.c b/thirdparty/openssl/crypto/asn1/a_gentm.c
index fa76dcac91..8511813785 100644
--- a/thirdparty/openssl/crypto/asn1/a_gentm.c
+++ b/thirdparty/openssl/crypto/asn1/a_gentm.c
@@ -202,7 +202,7 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d)
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
- int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ int offsign = a[o] == '-' ? 1 : -1, offset = 0;
o++;
if (o + 4 > l)
goto err;
diff --git a/thirdparty/openssl/crypto/asn1/a_object.c b/thirdparty/openssl/crypto/asn1/a_object.c
index 27f9c16914..229a40ffa3 100644
--- a/thirdparty/openssl/crypto/asn1/a_object.c
+++ b/thirdparty/openssl/crypto/asn1/a_object.c
@@ -73,7 +73,7 @@ int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
return (0);
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
- if (pp == NULL)
+ if (pp == NULL || objsize == -1)
return objsize;
p = *pp;
@@ -174,8 +174,12 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
if (!tmp)
goto err;
}
- while (blsize--)
- tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
+ while (blsize--) {
+ BN_ULONG t = BN_div_word(bl, 0x80L);
+ if (t == (BN_ULONG)-1)
+ goto err;
+ tmp[i++] = (unsigned char)t;
+ }
} else {
for (;;) {
diff --git a/thirdparty/openssl/crypto/asn1/a_set.c b/thirdparty/openssl/crypto/asn1/a_set.c
index bf3f971889..5fb5865575 100644
--- a/thirdparty/openssl/crypto/asn1/a_set.c
+++ b/thirdparty/openssl/crypto/asn1/a_set.c
@@ -57,6 +57,7 @@
*/
#include <stdio.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/asn1_mac.h>
@@ -98,10 +99,14 @@ int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
if (a == NULL)
return (0);
- for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
+ for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) {
+ int tmplen = i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
+ if (tmplen > INT_MAX - ret)
+ return -1;
ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
+ }
r = ASN1_object_size(1, ret, ex_tag);
- if (pp == NULL)
+ if (pp == NULL || r == -1)
return (r);
p = *pp;
diff --git a/thirdparty/openssl/crypto/asn1/a_strex.c b/thirdparty/openssl/crypto/asn1/a_strex.c
index 35fd44cd22..2d562f9345 100644
--- a/thirdparty/openssl/crypto/asn1/a_strex.c
+++ b/thirdparty/openssl/crypto/asn1/a_strex.c
@@ -337,7 +337,7 @@ static const signed char tag2nbyte[] = {
-1, -1, -1, -1, -1, /* 5-9 */
-1, -1, 0, -1, /* 10-13 */
-1, -1, -1, -1, /* 15-17 */
- -1, 1, 1, /* 18-20 */
+ 1, 1, 1, /* 18-20 */
-1, 1, 1, 1, /* 21-24 */
-1, 1, -1, /* 25-27 */
4, -1, 2 /* 28-30 */
diff --git a/thirdparty/openssl/crypto/asn1/a_strnid.c b/thirdparty/openssl/crypto/asn1/a_strnid.c
index 5224345368..99ffe73787 100644
--- a/thirdparty/openssl/crypto/asn1/a_strnid.c
+++ b/thirdparty/openssl/crypto/asn1/a_strnid.c
@@ -192,7 +192,8 @@ static const ASN1_STRING_TABLE tbl_standard[] = {
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
- {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
+ {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
+ {NID_jurisdictionCountryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}
};
static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
@@ -250,6 +251,7 @@ int ASN1_STRING_TABLE_add(int nid,
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
tmp->nid = nid;
+ tmp->minsize = tmp->maxsize = -1;
new_nid = 1;
} else
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
diff --git a/thirdparty/openssl/crypto/asn1/a_time.c b/thirdparty/openssl/crypto/asn1/a_time.c
index fcb2d565cd..0eeb79cd42 100644
--- a/thirdparty/openssl/crypto/asn1/a_time.c
+++ b/thirdparty/openssl/crypto/asn1/a_time.c
@@ -137,7 +137,7 @@ int ASN1_TIME_check(ASN1_TIME *t)
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
ASN1_GENERALIZEDTIME **out)
{
- ASN1_GENERALIZEDTIME *ret;
+ ASN1_GENERALIZEDTIME *ret = NULL;
char *str;
int newlen;
@@ -146,22 +146,21 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
if (!out || !*out) {
if (!(ret = ASN1_GENERALIZEDTIME_new()))
- return NULL;
- if (out)
- *out = ret;
- } else
+ goto err;
+ } else {
ret = *out;
+ }
/* If already GeneralizedTime just copy across */
if (t->type == V_ASN1_GENERALIZEDTIME) {
if (!ASN1_STRING_set(ret, t->data, t->length))
- return NULL;
- return ret;
+ goto err;
+ goto done;
}
/* grow the string */
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
- return NULL;
+ goto err;
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
newlen = t->length + 2 + 1;
str = (char *)ret->data;
@@ -173,9 +172,18 @@ ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
BUF_strlcat(str, (char *)t->data, newlen);
- return ret;
+ done:
+ if (out != NULL && *out == NULL)
+ *out = ret;
+ return ret;
+
+ err:
+ if (out == NULL || *out != ret)
+ ASN1_GENERALIZEDTIME_free(ret);
+ return NULL;
}
+
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
{
ASN1_TIME t;
diff --git a/thirdparty/openssl/crypto/asn1/a_utctm.c b/thirdparty/openssl/crypto/asn1/a_utctm.c
index 724a10be4e..0344482cc2 100644
--- a/thirdparty/openssl/crypto/asn1/a_utctm.c
+++ b/thirdparty/openssl/crypto/asn1/a_utctm.c
@@ -172,7 +172,7 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d)
if (a[o] == 'Z')
o++;
else if ((a[o] == '+') || (a[o] == '-')) {
- int offsign = a[o] == '-' ? -1 : 1, offset = 0;
+ int offsign = a[o] == '-' ? 1 : -1, offset = 0;
o++;
if (o + 4 > l)
goto err;
diff --git a/thirdparty/openssl/crypto/asn1/ameth_lib.c b/thirdparty/openssl/crypto/asn1/ameth_lib.c
index 5389c04347..43ddebba33 100644
--- a/thirdparty/openssl/crypto/asn1/ameth_lib.c
+++ b/thirdparty/openssl/crypto/asn1/ameth_lib.c
@@ -93,7 +93,9 @@ static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
&eckey_asn1_meth,
#endif
&hmac_asn1_meth,
+#ifndef OPENSSL_NO_CMAC
&cmac_asn1_meth,
+#endif
#ifndef OPENSSL_NO_DH
&dhx_asn1_meth
#endif
diff --git a/thirdparty/openssl/crypto/asn1/asn1_lib.c b/thirdparty/openssl/crypto/asn1/asn1_lib.c
index 874b1af8b0..e63e82a8b4 100644
--- a/thirdparty/openssl/crypto/asn1/asn1_lib.c
+++ b/thirdparty/openssl/crypto/asn1/asn1_lib.c
@@ -256,26 +256,30 @@ static void asn1_put_length(unsigned char **pp, int length)
int ASN1_object_size(int constructed, int length, int tag)
{
- int ret;
-
- ret = length;
- ret++;
+ int ret = 1;
+ if (length < 0)
+ return -1;
if (tag >= 31) {
while (tag > 0) {
tag >>= 7;
ret++;
}
}
- if (constructed == 2)
- return ret + 3;
- ret++;
- if (length > 127) {
- while (length > 0) {
- length >>= 8;
- ret++;
+ if (constructed == 2) {
+ ret += 3;
+ } else {
+ ret++;
+ if (length > 127) {
+ int tmplen = length;
+ while (tmplen > 0) {
+ tmplen >>= 8;
+ ret++;
+ }
}
}
- return (ret);
+ if (ret >= INT_MAX - length)
+ return -1;
+ return ret + length;
}
static int _asn1_Finish(ASN1_const_CTX *c)
@@ -324,7 +328,7 @@ int asn1_GetSequence(ASN1_const_CTX *c, long *length)
return (0);
}
if (c->inf == (1 | V_ASN1_CONSTRUCTED))
- c->slen = *length + *(c->pp) - c->p;
+ c->slen = *length;
c->eos = 0;
return (1);
}
@@ -366,7 +370,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
else
len = strlen(data);
}
- if ((str->length < len) || (str->data == NULL)) {
+ if ((str->length <= len) || (str->data == NULL)) {
c = str->data;
if (c == NULL)
str->data = OPENSSL_malloc(len + 1);
diff --git a/thirdparty/openssl/crypto/asn1/asn_mime.c b/thirdparty/openssl/crypto/asn1/asn_mime.c
index 96110c540f..5170906c62 100644
--- a/thirdparty/openssl/crypto/asn1/asn_mime.c
+++ b/thirdparty/openssl/crypto/asn1/asn_mime.c
@@ -289,7 +289,7 @@ int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags,
if ((flags & SMIME_DETACHED) && data) {
/* We want multipart/signed */
/* Generate a random boundary */
- if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0)
+ if (RAND_bytes((unsigned char *)bound, 32) <= 0)
return 0;
for (i = 0; i < 32; i++) {
c = bound[i] & 0xf;
@@ -623,6 +623,8 @@ static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret)
if (bpart)
sk_BIO_push(parts, bpart);
bpart = BIO_new(BIO_s_mem());
+ if (bpart == NULL)
+ return 1;
BIO_set_mem_eof_return(bpart, 0);
} else if (eol)
BIO_write(bpart, "\r\n", 2);
diff --git a/thirdparty/openssl/crypto/asn1/bio_asn1.c b/thirdparty/openssl/crypto/asn1/bio_asn1.c
index 60189b3b2c..c3afff69dc 100644
--- a/thirdparty/openssl/crypto/asn1/bio_asn1.c
+++ b/thirdparty/openssl/crypto/asn1/bio_asn1.c
@@ -170,10 +170,12 @@ static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
ctx->copylen = 0;
ctx->asn1_class = V_ASN1_UNIVERSAL;
ctx->asn1_tag = V_ASN1_OCTET_STRING;
- ctx->ex_buf = 0;
- ctx->ex_pos = 0;
+ ctx->ex_buf = NULL;
ctx->ex_len = 0;
+ ctx->ex_pos = 0;
ctx->state = ASN1_STATE_START;
+ ctx->prefix = ctx->prefix_free = ctx->suffix = ctx->suffix_free = NULL;
+ ctx->ex_arg = NULL;
return 1;
}
diff --git a/thirdparty/openssl/crypto/asn1/bio_ndef.c b/thirdparty/openssl/crypto/asn1/bio_ndef.c
index 31949b8794..8d7046633c 100644
--- a/thirdparty/openssl/crypto/asn1/bio_ndef.c
+++ b/thirdparty/openssl/crypto/asn1/bio_ndef.c
@@ -136,6 +136,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
ndef_aux->ndef_bio = sarg.ndef_bio;
ndef_aux->boundary = sarg.boundary;
ndef_aux->out = out;
+ ndef_aux->derbuf = NULL;
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
diff --git a/thirdparty/openssl/crypto/asn1/d2i_pr.c b/thirdparty/openssl/crypto/asn1/d2i_pr.c
index d21829af19..86dcf5fba9 100644
--- a/thirdparty/openssl/crypto/asn1/d2i_pr.c
+++ b/thirdparty/openssl/crypto/asn1/d2i_pr.c
@@ -97,15 +97,17 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
if (!ret->ameth->old_priv_decode ||
!ret->ameth->old_priv_decode(ret, &p, length)) {
if (ret->ameth->priv_decode) {
+ EVP_PKEY *tmp;
PKCS8_PRIV_KEY_INFO *p8 = NULL;
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
if (!p8)
goto err;
- EVP_PKEY_free(ret);
- ret = EVP_PKCS82PKEY(p8);
+ tmp = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
- if (ret == NULL)
+ if (tmp == NULL)
goto err;
+ EVP_PKEY_free(ret);
+ ret = tmp;
} else {
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
goto err;
diff --git a/thirdparty/openssl/crypto/asn1/f_enum.c b/thirdparty/openssl/crypto/asn1/f_enum.c
index 591c3b5781..527f1d8f87 100644
--- a/thirdparty/openssl/crypto/asn1/f_enum.c
+++ b/thirdparty/openssl/crypto/asn1/f_enum.c
@@ -138,7 +138,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
bufp = (unsigned char *)buf;
if (first) {
first = 0;
- if ((bufp[0] == '0') && (buf[1] == '0')) {
+ if ((bufp[0] == '0') && (bufp[1] == '0')) {
bufp += 2;
i -= 2;
}
@@ -160,8 +160,6 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
i * 2);
if (sp == NULL) {
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
- if (s != NULL)
- OPENSSL_free(s);
goto err;
}
s = sp;
@@ -199,5 +197,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
err_sl:
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
diff --git a/thirdparty/openssl/crypto/asn1/f_int.c b/thirdparty/openssl/crypto/asn1/f_int.c
index 4a81f81c88..e6ed7f1e77 100644
--- a/thirdparty/openssl/crypto/asn1/f_int.c
+++ b/thirdparty/openssl/crypto/asn1/f_int.c
@@ -152,7 +152,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
bufp = (unsigned char *)buf;
if (first) {
first = 0;
- if ((bufp[0] == '0') && (buf[1] == '0')) {
+ if ((bufp[0] == '0') && (bufp[1] == '0')) {
bufp += 2;
i -= 2;
}
@@ -172,8 +172,6 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
if (sp == NULL) {
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
- if (s != NULL)
- OPENSSL_free(s);
goto err;
}
s = sp;
@@ -211,5 +209,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
err_sl:
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
diff --git a/thirdparty/openssl/crypto/asn1/f_string.c b/thirdparty/openssl/crypto/asn1/f_string.c
index 6a6cf34714..0f7b9cfb11 100644
--- a/thirdparty/openssl/crypto/asn1/f_string.c
+++ b/thirdparty/openssl/crypto/asn1/f_string.c
@@ -166,8 +166,6 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
i * 2);
if (sp == NULL) {
ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
- if (s != NULL)
- OPENSSL_free(s);
goto err;
}
s = sp;
@@ -205,5 +203,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
err_sl:
ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
}
+ if (ret != 1)
+ OPENSSL_free(s);
return (ret);
}
diff --git a/thirdparty/openssl/crypto/asn1/i2d_pr.c b/thirdparty/openssl/crypto/asn1/i2d_pr.c
index 4d338ac55a..12966ec536 100644
--- a/thirdparty/openssl/crypto/asn1/i2d_pr.c
+++ b/thirdparty/openssl/crypto/asn1/i2d_pr.c
@@ -69,10 +69,13 @@ int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
}
if (a->ameth && a->ameth->priv_encode) {
PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
- int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
- PKCS8_PRIV_KEY_INFO_free(p8);
+ int ret = 0;
+ if (p8 != NULL) {
+ ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ }
return ret;
}
ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
- return (-1);
+ return -1;
}
diff --git a/thirdparty/openssl/crypto/asn1/p5_pbe.c b/thirdparty/openssl/crypto/asn1/p5_pbe.c
index bdbfdcd67c..e2a1def53f 100644
--- a/thirdparty/openssl/crypto/asn1/p5_pbe.c
+++ b/thirdparty/openssl/crypto/asn1/p5_pbe.c
@@ -101,7 +101,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
sstr = ASN1_STRING_data(pbe->salt);
if (salt)
memcpy(sstr, salt, saltlen);
- else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
+ else if (RAND_bytes(sstr, saltlen) <= 0)
goto err;
if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
diff --git a/thirdparty/openssl/crypto/asn1/p5_pbev2.c b/thirdparty/openssl/crypto/asn1/p5_pbev2.c
index 73ba4a3d67..4c037d3d2c 100644
--- a/thirdparty/openssl/crypto/asn1/p5_pbev2.c
+++ b/thirdparty/openssl/crypto/asn1/p5_pbev2.c
@@ -91,12 +91,11 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
unsigned char *salt, int saltlen,
unsigned char *aiv, int prf_nid)
{
- X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
+ X509_ALGOR *scheme = NULL, *ret = NULL;
int alg_nid, keylen;
EVP_CIPHER_CTX ctx;
unsigned char iv[EVP_MAX_IV_LENGTH];
PBE2PARAM *pbe2 = NULL;
- ASN1_OBJECT *obj;
alg_nid = EVP_CIPHER_type(cipher);
if (alg_nid == NID_undef) {
@@ -104,7 +103,6 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
- obj = OBJ_nid2obj(alg_nid);
if (!(pbe2 = PBE2PARAM_new()))
goto merr;
@@ -112,7 +110,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
/* Setup the AlgorithmIdentifier for the encryption scheme */
scheme = pbe2->encryption;
- scheme->algorithm = obj;
+ scheme->algorithm = OBJ_nid2obj(alg_nid);
if (!(scheme->parameter = ASN1_TYPE_new()))
goto merr;
@@ -120,7 +118,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
if (EVP_CIPHER_iv_length(cipher)) {
if (aiv)
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
- else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
+ else if (RAND_bytes(iv, EVP_CIPHER_iv_length(cipher)) <= 0)
goto err;
}
@@ -188,11 +186,9 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
err:
PBE2PARAM_free(pbe2);
/* Note 'scheme' is freed as part of pbe2 */
- X509_ALGOR_free(kalg);
X509_ALGOR_free(ret);
return NULL;
-
}
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
@@ -225,7 +221,7 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
if (salt)
memcpy(osalt->data, salt, saltlen);
- else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
+ else if (RAND_bytes(osalt->data, saltlen) <= 0)
goto merr;
if (iter <= 0)
diff --git a/thirdparty/openssl/crypto/asn1/t_req.c b/thirdparty/openssl/crypto/asn1/t_req.c
index 024553ab19..70aba4cc3b 100644
--- a/thirdparty/openssl/crypto/asn1/t_req.c
+++ b/thirdparty/openssl/crypto/asn1/t_req.c
@@ -196,6 +196,7 @@ int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
if (BIO_puts(bp, ":") <= 0)
goto err;
if ((type == V_ASN1_PRINTABLESTRING) ||
+ (type == V_ASN1_UTF8STRING) ||
(type == V_ASN1_T61STRING) ||
(type == V_ASN1_IA5STRING)) {
if (BIO_write(bp, (char *)bs->data, bs->length)
diff --git a/thirdparty/openssl/crypto/asn1/tasn_dec.c b/thirdparty/openssl/crypto/asn1/tasn_dec.c
index 6bdcd5c542..d49a5d5792 100644
--- a/thirdparty/openssl/crypto/asn1/tasn_dec.c
+++ b/thirdparty/openssl/crypto/asn1/tasn_dec.c
@@ -400,7 +400,9 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
if (tt->flags & ASN1_TFLG_ADB_MASK) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
- seqtt = asn1_do_adb(pval, tt, 1);
+ seqtt = asn1_do_adb(pval, tt, 0);
+ if (seqtt == NULL)
+ continue;
pseqval = asn1_get_field_ptr(pval, seqtt);
ASN1_template_free(pseqval, seqtt);
}
@@ -411,7 +413,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
+ if (seqtt == NULL)
goto err;
pseqval = asn1_get_field_ptr(pval, seqtt);
/* Have we ran out of data? */
@@ -476,7 +478,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
for (; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
seqtt = asn1_do_adb(pval, tt, 1);
- if (!seqtt)
+ if (seqtt == NULL)
goto err;
if (seqtt->flags & ASN1_TFLG_OPTIONAL) {
ASN1_VALUE **pseqval;
@@ -671,6 +673,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
+ ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/thirdparty/openssl/crypto/asn1/tasn_enc.c b/thirdparty/openssl/crypto/asn1/tasn_enc.c
index f7f83e56a9..081a9d534f 100644
--- a/thirdparty/openssl/crypto/asn1/tasn_enc.c
+++ b/thirdparty/openssl/crypto/asn1/tasn_enc.c
@@ -59,6 +59,7 @@
#include <stddef.h>
#include <string.h>
+#include <limits.h>
#include "cryptlib.h"
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
@@ -216,17 +217,19 @@ int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
const ASN1_TEMPLATE *seqtt;
ASN1_VALUE **pseqval;
+ int tmplen;
seqtt = asn1_do_adb(pval, tt, 1);
if (!seqtt)
return 0;
pseqval = asn1_get_field_ptr(pval, seqtt);
- /* FIXME: check for errors in enhanced version */
- seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt,
- -1, aclass);
+ tmplen = asn1_template_ex_i2d(pseqval, NULL, seqtt, -1, aclass);
+ if (tmplen == -1 || (tmplen > INT_MAX - seqcontlen))
+ return -1;
+ seqcontlen += tmplen;
}
seqlen = ASN1_object_size(ndef, seqcontlen, tag);
- if (!out)
+ if (!out || seqlen == -1)
return seqlen;
/* Output SEQUENCE header */
ASN1_put_object(out, ndef, seqcontlen, tag, aclass);
@@ -339,19 +342,24 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
/* Determine total length of items */
skcontlen = 0;
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
+ int tmplen;
skitem = sk_ASN1_VALUE_value(sk, i);
- skcontlen += ASN1_item_ex_i2d(&skitem, NULL,
- ASN1_ITEM_ptr(tt->item),
- -1, iclass);
+ tmplen = ASN1_item_ex_i2d(&skitem, NULL, ASN1_ITEM_ptr(tt->item),
+ -1, iclass);
+ if (tmplen == -1 || (skcontlen > INT_MAX - tmplen))
+ return -1;
+ skcontlen += tmplen;
}
sklen = ASN1_object_size(ndef, skcontlen, sktag);
+ if (sklen == -1)
+ return -1;
/* If EXPLICIT need length of surrounding tag */
if (flags & ASN1_TFLG_EXPTAG)
ret = ASN1_object_size(ndef, sklen, ttag);
else
ret = sklen;
- if (!out)
+ if (!out || ret == -1)
return ret;
/* Now encode this lot... */
@@ -380,7 +388,7 @@ static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out,
return 0;
/* Find length of EXPLICIT tag */
ret = ASN1_object_size(ndef, i, ttag);
- if (out) {
+ if (out && ret != -1) {
/* Output tag and item */
ASN1_put_object(out, ndef, i, ttag, tclass);
ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass);
diff --git a/thirdparty/openssl/crypto/asn1/tasn_new.c b/thirdparty/openssl/crypto/asn1/tasn_new.c
index b0c73beeb5..54f459d1ed 100644
--- a/thirdparty/openssl/crypto/asn1/tasn_new.c
+++ b/thirdparty/openssl/crypto/asn1/tasn_new.c
@@ -158,7 +158,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
}
asn1_set_choice_selector(pval, -1, it);
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
- goto auxerr;
+ goto auxerr2;
break;
case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -186,10 +186,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
pseqval = asn1_get_field_ptr(pval, tt);
if (!ASN1_template_new(pseqval, tt))
- goto memerr;
+ goto memerr2;
}
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
- goto auxerr;
+ goto auxerr2;
break;
}
#ifdef CRYPTO_MDEBUG
@@ -198,6 +198,8 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
return 1;
+ memerr2:
+ ASN1_item_ex_free(pval, it);
memerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
@@ -206,9 +208,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
return 0;
+ auxerr2:
+ ASN1_item_ex_free(pval, it);
auxerr:
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
- ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname)
CRYPTO_pop_info();
diff --git a/thirdparty/openssl/crypto/asn1/tasn_prn.c b/thirdparty/openssl/crypto/asn1/tasn_prn.c
index 5e7d53e985..f628caddbd 100644
--- a/thirdparty/openssl/crypto/asn1/tasn_prn.c
+++ b/thirdparty/openssl/crypto/asn1/tasn_prn.c
@@ -204,7 +204,8 @@ static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent,
} else
asn1_cb = 0;
- if (*fld == NULL) {
+ if (((it->itype != ASN1_ITYPE_PRIMITIVE)
+ || (it->utype != V_ASN1_BOOLEAN)) && *fld == NULL) {
if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) {
if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx))
return 0;
@@ -446,6 +447,8 @@ static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str,
char *s;
int ret = 1;
s = i2s_ASN1_INTEGER(NULL, str);
+ if (s == NULL)
+ return 0;
if (BIO_puts(out, s) <= 0)
ret = 0;
OPENSSL_free(s);
@@ -496,11 +499,16 @@ static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld,
return 0;
if (pf && pf->prim_print)
return pf->prim_print(out, fld, it, indent, pctx);
- str = (ASN1_STRING *)*fld;
- if (it->itype == ASN1_ITYPE_MSTRING)
+ if (it->itype == ASN1_ITYPE_MSTRING) {
+ str = (ASN1_STRING *)*fld;
utype = str->type & ~V_ASN1_NEG;
- else
+ } else {
utype = it->utype;
+ if (utype == V_ASN1_BOOLEAN)
+ str = NULL;
+ else
+ str = (ASN1_STRING *)*fld;
+ }
if (utype == V_ASN1_ANY) {
ASN1_TYPE *atype = (ASN1_TYPE *)*fld;
utype = atype->type;
diff --git a/thirdparty/openssl/crypto/asn1/tasn_utl.c b/thirdparty/openssl/crypto/asn1/tasn_utl.c
index 41726d8feb..e14889feb1 100644
--- a/thirdparty/openssl/crypto/asn1/tasn_utl.c
+++ b/thirdparty/openssl/crypto/asn1/tasn_utl.c
@@ -234,7 +234,7 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
sfld = offset2ptr(*pval, adb->offset);
/* Check if NULL */
- if (!sfld) {
+ if (*sfld == NULL) {
if (!adb->null_tt)
goto err;
return adb->null_tt;
diff --git a/thirdparty/openssl/crypto/asn1/x_bignum.c b/thirdparty/openssl/crypto/asn1/x_bignum.c
index eaf046639d..c644199c9f 100644
--- a/thirdparty/openssl/crypto/asn1/x_bignum.c
+++ b/thirdparty/openssl/crypto/asn1/x_bignum.c
@@ -78,6 +78,8 @@ static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
const ASN1_ITEM *it);
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it);
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int indent, const ASN1_PCTX *pctx);
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
NULL, 0,
@@ -85,7 +87,8 @@ static ASN1_PRIMITIVE_FUNCS bignum_pf = {
bn_free,
0,
bn_c2i,
- bn_i2c
+ bn_i2c,
+ bn_print
};
ASN1_ITEM_start(BIGNUM)
@@ -151,3 +154,13 @@ static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
}
return 1;
}
+
+static int bn_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
+ int indent, const ASN1_PCTX *pctx)
+{
+ if (!BN_print(out, *(BIGNUM **)pval))
+ return 0;
+ if (BIO_puts(out, "\n") <= 0)
+ return 0;
+ return 1;
+}
diff --git a/thirdparty/openssl/crypto/asn1/x_crl.c b/thirdparty/openssl/crypto/asn1/x_crl.c
index 027950330d..c78ded89ef 100644
--- a/thirdparty/openssl/crypto/asn1/x_crl.c
+++ b/thirdparty/openssl/crypto/asn1/x_crl.c
@@ -254,6 +254,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
int nid;
+
ext = sk_X509_EXTENSION_value(exts, idx);
nid = OBJ_obj2nid(ext->object);
if (nid == NID_freshest_crl)
@@ -263,7 +264,7 @@ static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
if ((nid == NID_issuing_distribution_point)
|| (nid == NID_authority_key_identifier)
|| (nid == NID_delta_crl))
- break;;
+ continue;
crl->flags |= EXFLAG_CRITICAL;
break;
}
diff --git a/thirdparty/openssl/crypto/asn1/x_long.c b/thirdparty/openssl/crypto/asn1/x_long.c
index 3aed44a3dd..aecb95069d 100644
--- a/thirdparty/openssl/crypto/asn1/x_long.c
+++ b/thirdparty/openssl/crypto/asn1/x_long.c
@@ -126,7 +126,7 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
* set.
*/
if (ltmp < 0)
- utmp = -ltmp - 1;
+ utmp = 0 - (unsigned long)ltmp - 1;
else
utmp = ltmp;
clen = BN_num_bits_word(utmp);
@@ -155,19 +155,41 @@ static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
int utype, char *free_cont, const ASN1_ITEM *it)
{
- int neg, i;
+ int neg = -1, i;
long ltmp;
unsigned long utmp = 0;
char *cp = (char *)pval;
+
+ if (len) {
+ /*
+ * Check possible pad byte. Worst case, we're skipping past actual
+ * content, but since that's only with 0x00 and 0xff and we set neg
+ * accordingly, the result will be correct in the end anyway.
+ */
+ switch (cont[0]) {
+ case 0xff:
+ cont++;
+ len--;
+ neg = 1;
+ break;
+ case 0:
+ cont++;
+ len--;
+ neg = 0;
+ break;
+ }
+ }
if (len > (int)sizeof(long)) {
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
- /* Is it negative? */
- if (len && (cont[0] & 0x80))
- neg = 1;
- else
- neg = 0;
+ if (neg == -1) {
+ /* Is it negative? */
+ if (len && (cont[0] & 0x80))
+ neg = 1;
+ else
+ neg = 0;
+ }
utmp = 0;
for (i = 0; i < len; i++) {
utmp <<= 8;
@@ -178,8 +200,8 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
}
ltmp = (long)utmp;
if (neg) {
- ltmp++;
ltmp = -ltmp;
+ ltmp--;
}
if (ltmp == it->size) {
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
diff --git a/thirdparty/openssl/crypto/asn1/x_name.c b/thirdparty/openssl/crypto/asn1/x_name.c
index a858c2993b..1fb7ad1cbf 100644
--- a/thirdparty/openssl/crypto/asn1/x_name.c
+++ b/thirdparty/openssl/crypto/asn1/x_name.c
@@ -178,6 +178,16 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
*pval = NULL;
}
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_free(ne);
+}
+
+static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
+{
+ sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
+}
+
static int x509_name_ex_d2i(ASN1_VALUE **val,
const unsigned char **in, long len,
const ASN1_ITEM *it, int tag, int aclass,
@@ -199,10 +209,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
int i, j, ret;
STACK_OF(X509_NAME_ENTRY) *entries;
X509_NAME_ENTRY *entry;
- if (len > X509_NAME_MAX) {
- ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG);
- return 0;
- }
+ if (len > X509_NAME_MAX)
+ len = X509_NAME_MAX;
q = p;
/* Get internal representation of Name */
@@ -230,13 +238,14 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
entry->set = i;
if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
goto err;
+ sk_X509_NAME_ENTRY_set(entries, j, NULL);
}
- sk_X509_NAME_ENTRY_free(entries);
}
- sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
ret = x509_name_canon(nm.x);
if (!ret)
goto err;
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_free);
nm.x->modified = 0;
*val = nm.a;
*in = p;
@@ -244,6 +253,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
+ sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
+ local_sk_X509_NAME_ENTRY_pop_free);
ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
return 0;
}
@@ -269,16 +280,6 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
return ret;
}
-static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
-{
- sk_X509_NAME_ENTRY_free(ne);
-}
-
-static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
-{
- sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
-}
-
static int x509_name_encode(X509_NAME *a)
{
union {
@@ -301,8 +302,10 @@ static int x509_name_encode(X509_NAME *a)
entries = sk_X509_NAME_ENTRY_new_null();
if (!entries)
goto memerr;
- if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
+ sk_X509_NAME_ENTRY_free(entries);
goto memerr;
+ }
set = entry->set;
}
if (!sk_X509_NAME_ENTRY_push(entries, entry))
@@ -372,8 +375,10 @@ static int x509_name_canon(X509_NAME *a)
entries = sk_X509_NAME_ENTRY_new_null();
if (!entries)
goto err;
- if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
+ if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
+ sk_X509_NAME_ENTRY_free(entries);
goto err;
+ }
set = entry->set;
}
tmpentry = X509_NAME_ENTRY_new();
diff --git a/thirdparty/openssl/crypto/asn1/x_x509.c b/thirdparty/openssl/crypto/asn1/x_x509.c
index e31e1e750d..aada4a8413 100644
--- a/thirdparty/openssl/crypto/asn1/x_x509.c
+++ b/thirdparty/openssl/crypto/asn1/x_x509.c
@@ -199,12 +199,26 @@ X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length)
return NULL;
}
-int i2d_X509_AUX(X509 *a, unsigned char **pp)
+/*
+ * Serialize trusted certificate to *pp or just return the required buffer
+ * length if pp == NULL. We ultimately want to avoid modifying *pp in the
+ * error path, but that depends on similar hygiene in lower-level functions.
+ * Here we avoid compounding the problem.
+ */
+static int i2d_x509_aux_internal(X509 *a, unsigned char **pp)
{
int length, tmplen;
unsigned char *start = pp != NULL ? *pp : NULL;
+
+ OPENSSL_assert(pp == NULL || *pp != NULL);
+
+ /*
+ * This might perturb *pp on error, but fixing that belongs in i2d_X509()
+ * not here. It should be that if a == NULL length is zero, but we check
+ * both just in case.
+ */
length = i2d_X509(a, pp);
- if (length < 0 || a == NULL)
+ if (length <= 0 || a == NULL)
return length;
tmplen = i2d_X509_CERT_AUX(a->aux, pp);
@@ -218,6 +232,42 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp)
return length;
}
+/*
+ * Serialize trusted certificate to *pp, or just return the required buffer
+ * length if pp == NULL.
+ *
+ * When pp is not NULL, but *pp == NULL, we allocate the buffer, but since
+ * we're writing two ASN.1 objects back to back, we can't have i2d_X509() do
+ * the allocation, nor can we allow i2d_X509_CERT_AUX() to increment the
+ * allocated buffer.
+ */
+int i2d_X509_AUX(X509 *a, unsigned char **pp)
+{
+ int length;
+ unsigned char *tmp;
+
+ /* Buffer provided by caller */
+ if (pp == NULL || *pp != NULL)
+ return i2d_x509_aux_internal(a, pp);
+
+ /* Obtain the combined length */
+ if ((length = i2d_x509_aux_internal(a, NULL)) <= 0)
+ return length;
+
+ /* Allocate requisite combined storage */
+ *pp = tmp = OPENSSL_malloc(length);
+ if (tmp == NULL)
+ return -1; /* Push error onto error stack? */
+
+ /* Encode, but keep *pp at the originally malloced pointer */
+ length = i2d_x509_aux_internal(a, &tmp);
+ if (length <= 0) {
+ OPENSSL_free(*pp);
+ *pp = NULL;
+ }
+ return length;
+}
+
int i2d_re_X509_tbs(X509 *x, unsigned char **pp)
{
x->cert_info->enc.modified = 1;
diff --git a/thirdparty/openssl/crypto/bio/b_print.c b/thirdparty/openssl/crypto/bio/b_print.c
index 90248fa2aa..eb3ab75934 100644
--- a/thirdparty/openssl/crypto/bio/b_print.c
+++ b/thirdparty/openssl/crypto/bio/b_print.c
@@ -423,9 +423,15 @@ _dopr(char **sbuffer,
break;
}
}
- *truncated = (currlen > *maxlen - 1);
- if (*truncated)
- currlen = *maxlen - 1;
+ /*
+ * We have to truncate if there is no dynamic buffer and we have filled the
+ * static buffer.
+ */
+ if (buffer == NULL) {
+ *truncated = (currlen > *maxlen - 1);
+ if (*truncated)
+ currlen = *maxlen - 1;
+ }
if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'))
return 0;
*retlen = currlen - 1;
@@ -496,7 +502,7 @@ fmtint(char **sbuffer,
if (!(flags & DP_F_UNSIGNED)) {
if (value < 0) {
signvalue = '-';
- uvalue = -value;
+ uvalue = -(unsigned LLONG)value;
} else if (flags & DP_F_PLUS)
signvalue = '+';
else if (flags & DP_F_SPACE)
diff --git a/thirdparty/openssl/crypto/bio/bf_nbio.c b/thirdparty/openssl/crypto/bio/bf_nbio.c
index a04f32a008..4842bb4c82 100644
--- a/thirdparty/openssl/crypto/bio/bf_nbio.c
+++ b/thirdparty/openssl/crypto/bio/bf_nbio.c
@@ -139,7 +139,7 @@ static int nbiof_read(BIO *b, char *out, int outl)
BIO_clear_retry_flags(b);
#if 1
- if (RAND_pseudo_bytes(&n, 1) < 0)
+ if (RAND_bytes(&n, 1) <= 0)
return -1;
num = (n & 0x07);
@@ -179,7 +179,7 @@ static int nbiof_write(BIO *b, const char *in, int inl)
num = nt->lwn;
nt->lwn = 0;
} else {
- if (RAND_pseudo_bytes(&n, 1) < 0)
+ if (RAND_bytes(&n, 1) <= 0)
return -1;
num = (n & 7);
}
diff --git a/thirdparty/openssl/crypto/bio/bio_cb.c b/thirdparty/openssl/crypto/bio/bio_cb.c
index d3e860686c..f96294bb43 100644
--- a/thirdparty/openssl/crypto/bio/bio_cb.c
+++ b/thirdparty/openssl/crypto/bio/bio_cb.c
@@ -78,6 +78,9 @@ long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp,
len = BIO_snprintf(buf,sizeof buf,"BIO[%p]: ",(void *)bio);
+ /* Ignore errors and continue printing the other information. */
+ if (len < 0)
+ len = 0;
p = buf + len;
p_maxlen = sizeof(buf) - len;
diff --git a/thirdparty/openssl/crypto/bio/bss_bio.c b/thirdparty/openssl/crypto/bio/bss_bio.c
index 4d8727f8f8..3dd8187729 100644
--- a/thirdparty/openssl/crypto/bio/bss_bio.c
+++ b/thirdparty/openssl/crypto/bio/bss_bio.c
@@ -149,9 +149,13 @@ static int bio_new(BIO *bio)
return 0;
b->peer = NULL;
+ b->closed = 0;
+ b->len = 0;
+ b->offset = 0;
/* enough for one TLS record (just a default) */
b->size = 17 * 1024;
b->buf = NULL;
+ b->request = 0;
bio->ptr = b;
return 1;
@@ -655,16 +659,15 @@ static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr)
break;
case BIO_CTRL_EOF:
- {
- BIO *other_bio = ptr;
-
- if (other_bio) {
- struct bio_bio_st *other_b = other_bio->ptr;
+ if (b->peer != NULL) {
+ struct bio_bio_st *peer_b = b->peer->ptr;
- assert(other_b != NULL);
- ret = other_b->len == 0 && other_b->closed;
- } else
+ if (peer_b->len == 0 && peer_b->closed)
ret = 1;
+ else
+ ret = 0;
+ } else {
+ ret = 1;
}
break;
diff --git a/thirdparty/openssl/crypto/bio/bss_file.c b/thirdparty/openssl/crypto/bio/bss_file.c
index bfba93e62b..0cf67e5b77 100644
--- a/thirdparty/openssl/crypto/bio/bss_file.c
+++ b/thirdparty/openssl/crypto/bio/bss_file.c
@@ -174,7 +174,11 @@ BIO *BIO_new_file(const char *filename, const char *mode)
if (file == NULL) {
SYSerr(SYS_F_FOPEN, get_last_sys_error());
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
- if (errno == ENOENT)
+ if (errno == ENOENT
+# ifdef ENXIO
+ || errno == ENXIO
+# endif
+ )
BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
else
BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
@@ -247,7 +251,7 @@ static int MS_CALLBACK file_read(BIO *b, char *out, int outl)
ret = fread(out, 1, (int)outl, (FILE *)b->ptr);
if (ret == 0
&& (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) :
- ferror((FILE *)b->ptr)) {
+ ferror((FILE *)b->ptr)) {
SYSerr(SYS_F_FREAD, get_last_sys_error());
BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB);
ret = -1;
@@ -283,6 +287,7 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
FILE *fp = (FILE *)b->ptr;
FILE **fpp;
char p[4];
+ int st;
switch (cmd) {
case BIO_C_FILE_SEEK:
@@ -314,8 +319,11 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
# define _IOB_ENTRIES 20
# endif
-# if defined(_IOB_ENTRIES)
/* Safety net to catch purely internal BIO_set_fp calls */
+# if defined(_MSC_VER) && _MSC_VER>=1900
+ if (ptr == stdin || ptr == stdout || ptr == stderr)
+ BIO_clear_flags(b, BIO_FLAGS_UPLINK);
+# elif defined(_IOB_ENTRIES)
if ((size_t)ptr >= (size_t)stdin &&
(size_t)ptr < (size_t)(stdin + _IOB_ENTRIES))
BIO_clear_flags(b, BIO_FLAGS_UPLINK);
@@ -420,10 +428,14 @@ static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
b->shutdown = (int)num;
break;
case BIO_CTRL_FLUSH:
- if (b->flags & BIO_FLAGS_UPLINK)
- UP_fflush(b->ptr);
- else
- fflush((FILE *)b->ptr);
+ st = b->flags & BIO_FLAGS_UPLINK
+ ? UP_fflush(b->ptr) : fflush((FILE *)b->ptr);
+ if (st == EOF) {
+ SYSerr(SYS_F_FFLUSH, get_last_sys_error());
+ ERR_add_error_data(1, "fflush()");
+ BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
+ ret = 0;
+ }
break;
case BIO_CTRL_DUP:
ret = 1;
diff --git a/thirdparty/openssl/crypto/bio/bss_rtcp.c b/thirdparty/openssl/crypto/bio/bss_rtcp.c
index 09f14f48dc..5c98a8234d 100644
--- a/thirdparty/openssl/crypto/bio/bss_rtcp.c
+++ b/thirdparty/openssl/crypto/bio/bss_rtcp.c
@@ -170,6 +170,8 @@ static int rtcp_new(BIO *bi)
bi->num = 0;
bi->flags = 0;
bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx));
+ if (bi->ptr == NULL)
+ return (0);
ctx = (struct rpc_ctx *)bi->ptr;
ctx->filled = 0;
ctx->pos = 0;
diff --git a/thirdparty/openssl/crypto/bn/asm/x86_64-gcc.c b/thirdparty/openssl/crypto/bn/asm/x86_64-gcc.c
index d77dc433d4..1729b479d4 100644
--- a/thirdparty/openssl/crypto/bn/asm/x86_64-gcc.c
+++ b/thirdparty/openssl/crypto/bn/asm/x86_64-gcc.c
@@ -194,7 +194,7 @@ BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d)
BN_ULONG ret, waste;
asm("divq %4":"=a"(ret), "=d"(waste)
- : "a"(l), "d"(h), "g"(d)
+ : "a"(l), "d"(h), "r"(d)
: "cc");
return ret;
diff --git a/thirdparty/openssl/crypto/bn/bn_div.c b/thirdparty/openssl/crypto/bn/bn_div.c
index 72e6ce3f74..bc37671cf1 100644
--- a/thirdparty/openssl/crypto/bn/bn_div.c
+++ b/thirdparty/openssl/crypto/bn/bn_div.c
@@ -155,7 +155,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
({ asm volatile ( \
"divl %4" \
: "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
+ : "a"(n1), "d"(n0), "r"(d0) \
: "cc"); \
q; \
})
@@ -170,7 +170,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d,
({ asm volatile ( \
"divq %4" \
: "=a"(q), "=d"(rem) \
- : "a"(n1), "d"(n0), "g"(d0) \
+ : "a"(n1), "d"(n0), "r"(d0) \
: "cc"); \
q; \
})
diff --git a/thirdparty/openssl/crypto/bn/bn_exp.c b/thirdparty/openssl/crypto/bn/bn_exp.c
index 1670f01d1d..195a7867a4 100644
--- a/thirdparty/openssl/crypto/bn/bn_exp.c
+++ b/thirdparty/openssl/crypto/bn/bn_exp.c
@@ -180,8 +180,9 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
goto err;
}
}
- if (r != rr)
- BN_copy(r, rr);
+ if (r != rr && BN_copy(r, rr) == NULL)
+ goto err;
+
ret = 1;
err:
BN_CTX_end(ctx);
diff --git a/thirdparty/openssl/crypto/bn/bn_lib.c b/thirdparty/openssl/crypto/bn/bn_lib.c
index 80105fff41..10b78f5126 100644
--- a/thirdparty/openssl/crypto/bn/bn_lib.c
+++ b/thirdparty/openssl/crypto/bn/bn_lib.c
@@ -569,7 +569,7 @@ void BN_clear(BIGNUM *a)
{
bn_check_top(a);
if (a->d != NULL)
- memset(a->d, 0, a->dmax * sizeof(a->d[0]));
+ OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0]));
a->top = 0;
a->neg = 0;
}
diff --git a/thirdparty/openssl/crypto/bn/bn_mul.c b/thirdparty/openssl/crypto/bn/bn_mul.c
index b174850b6b..3c618dc307 100644
--- a/thirdparty/openssl/crypto/bn/bn_mul.c
+++ b/thirdparty/openssl/crypto/bn/bn_mul.c
@@ -1083,8 +1083,9 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx)
end:
#endif
bn_correct_top(rr);
- if (r != rr)
- BN_copy(r, rr);
+ if (r != rr && BN_copy(r, rr) == NULL)
+ goto err;
+
ret = 1;
err:
bn_check_top(r);
diff --git a/thirdparty/openssl/crypto/bn/bn_prime.c b/thirdparty/openssl/crypto/bn/bn_prime.c
index 1d256874c9..e911e15785 100644
--- a/thirdparty/openssl/crypto/bn/bn_prime.c
+++ b/thirdparty/openssl/crypto/bn/bn_prime.c
@@ -252,7 +252,6 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
BN_CTX *ctx = NULL;
BIGNUM *A1, *A1_odd, *check; /* taken from ctx */
BN_MONT_CTX *mont = NULL;
- const BIGNUM *A = NULL;
if (BN_cmp(a, BN_value_one()) <= 0)
return 0;
@@ -278,24 +277,14 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
goto err;
BN_CTX_start(ctx);
- /* A := abs(a) */
- if (a->neg) {
- BIGNUM *t;
- if ((t = BN_CTX_get(ctx)) == NULL)
- goto err;
- BN_copy(t, a);
- t->neg = 0;
- A = t;
- } else
- A = a;
A1 = BN_CTX_get(ctx);
A1_odd = BN_CTX_get(ctx);
check = BN_CTX_get(ctx);
if (check == NULL)
goto err;
- /* compute A1 := A - 1 */
- if (!BN_copy(A1, A))
+ /* compute A1 := a - 1 */
+ if (!BN_copy(A1, a))
goto err;
if (!BN_sub_word(A1, 1))
goto err;
@@ -311,11 +300,11 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
if (!BN_rshift(A1_odd, A1, k))
goto err;
- /* Montgomery setup for computations mod A */
+ /* Montgomery setup for computations mod a */
mont = BN_MONT_CTX_new();
if (mont == NULL)
goto err;
- if (!BN_MONT_CTX_set(mont, A, ctx))
+ if (!BN_MONT_CTX_set(mont, a, ctx))
goto err;
for (i = 0; i < checks; i++) {
@@ -323,9 +312,9 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
goto err;
if (!BN_add_word(check, 1))
goto err;
- /* now 1 <= check < A */
+ /* now 1 <= check < a */
- j = witness(check, A, A1, A1_odd, k, ctx, mont);
+ j = witness(check, a, A1, A1_odd, k, ctx, mont);
if (j == -1)
goto err;
if (j) {
diff --git a/thirdparty/openssl/crypto/bn/bn_prime.h b/thirdparty/openssl/crypto/bn/bn_prime.h
index 5cf0de169e..489af8b424 100644
--- a/thirdparty/openssl/crypto/bn/bn_prime.h
+++ b/thirdparty/openssl/crypto/bn/bn_prime.h
@@ -64,263 +64,263 @@ typedef unsigned short prime_t;
typedef unsigned char prime_t;
#endif
static const prime_t primes[NUMPRIMES] = {
- 2, 3, 5, 7, 11, 13, 17, 19,
- 23, 29, 31, 37, 41, 43, 47, 53,
- 59, 61, 67, 71, 73, 79, 83, 89,
- 97, 101, 103, 107, 109, 113, 127, 131,
- 137, 139, 149, 151, 157, 163, 167, 173,
- 179, 181, 191, 193, 197, 199, 211, 223,
- 227, 229, 233, 239, 241, 251,
+ 2, 3, 5, 7, 11, 13, 17, 19,
+ 23, 29, 31, 37, 41, 43, 47, 53,
+ 59, 61, 67, 71, 73, 79, 83, 89,
+ 97, 101, 103, 107, 109, 113, 127, 131,
+ 137, 139, 149, 151, 157, 163, 167, 173,
+ 179, 181, 191, 193, 197, 199, 211, 223,
+ 227, 229, 233, 239, 241, 251,
#ifndef EIGHT_BIT
- 257, 263,
- 269, 271, 277, 281, 283, 293, 307, 311,
- 313, 317, 331, 337, 347, 349, 353, 359,
- 367, 373, 379, 383, 389, 397, 401, 409,
- 419, 421, 431, 433, 439, 443, 449, 457,
- 461, 463, 467, 479, 487, 491, 499, 503,
- 509, 521, 523, 541, 547, 557, 563, 569,
- 571, 577, 587, 593, 599, 601, 607, 613,
- 617, 619, 631, 641, 643, 647, 653, 659,
- 661, 673, 677, 683, 691, 701, 709, 719,
- 727, 733, 739, 743, 751, 757, 761, 769,
- 773, 787, 797, 809, 811, 821, 823, 827,
- 829, 839, 853, 857, 859, 863, 877, 881,
- 883, 887, 907, 911, 919, 929, 937, 941,
- 947, 953, 967, 971, 977, 983, 991, 997,
- 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
- 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
- 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
- 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
- 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
- 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
- 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
- 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
- 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
- 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
- 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
- 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
- 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
- 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
- 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
- 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
- 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
- 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
- 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
- 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
- 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
- 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
- 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
- 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
- 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
- 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
- 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
- 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
- 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
- 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
- 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
- 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
- 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
- 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
- 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
- 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
- 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
- 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
- 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
- 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
- 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
- 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
- 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
- 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
- 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
- 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
- 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
- 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
- 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
- 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
- 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
- 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
- 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
- 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
- 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
- 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
- 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
- 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
- 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
- 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
- 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
- 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
- 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
- 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
- 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
- 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
- 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
- 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
- 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
- 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
- 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
- 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
- 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
- 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
- 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
- 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
- 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
- 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
- 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
- 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
- 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
- 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
- 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
- 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
- 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
- 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
- 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
- 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
- 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
- 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
- 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
- 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
- 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
- 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
- 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
- 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
- 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
- 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
- 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
- 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
- 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
- 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
- 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
- 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
- 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
- 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
- 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
- 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
- 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
- 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
- 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
- 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
- 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
- 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
- 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
- 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
- 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
- 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
- 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
- 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
- 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
- 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
- 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
- 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
- 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
- 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
- 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
- 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
- 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
- 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
- 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
- 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
- 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
- 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
- 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
- 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
- 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
- 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
- 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
- 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
- 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
- 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
- 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
- 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
- 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
- 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
- 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
- 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
- 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
- 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
- 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
- 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
- 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
- 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
- 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
- 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
- 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
- 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
- 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
- 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
- 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
- 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
- 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
- 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
- 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
- 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
- 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
- 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
- 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
- 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
- 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
- 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
- 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
- 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
- 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
- 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
- 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
- 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
- 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
- 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
- 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
- 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
- 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
- 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
- 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
- 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
- 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
- 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
- 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
- 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
- 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
- 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
- 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
- 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
- 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
- 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
- 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
- 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
- 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
- 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
- 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
- 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
- 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
- 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
- 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
- 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
- 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
- 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
- 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
- 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
- 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
- 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
- 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
- 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
- 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
- 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
- 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
- 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
- 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
- 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
- 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
- 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
- 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
- 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
- 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
- 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
- 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
- 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
- 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
- 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
- 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
- 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
- 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
- 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
- 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
+ 257, 263,
+ 269, 271, 277, 281, 283, 293, 307, 311,
+ 313, 317, 331, 337, 347, 349, 353, 359,
+ 367, 373, 379, 383, 389, 397, 401, 409,
+ 419, 421, 431, 433, 439, 443, 449, 457,
+ 461, 463, 467, 479, 487, 491, 499, 503,
+ 509, 521, 523, 541, 547, 557, 563, 569,
+ 571, 577, 587, 593, 599, 601, 607, 613,
+ 617, 619, 631, 641, 643, 647, 653, 659,
+ 661, 673, 677, 683, 691, 701, 709, 719,
+ 727, 733, 739, 743, 751, 757, 761, 769,
+ 773, 787, 797, 809, 811, 821, 823, 827,
+ 829, 839, 853, 857, 859, 863, 877, 881,
+ 883, 887, 907, 911, 919, 929, 937, 941,
+ 947, 953, 967, 971, 977, 983, 991, 997,
+ 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049,
+ 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
+ 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163,
+ 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223,
+ 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
+ 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321,
+ 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423,
+ 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
+ 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511,
+ 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571,
+ 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
+ 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693,
+ 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747,
+ 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
+ 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877,
+ 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949,
+ 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
+ 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069,
+ 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129,
+ 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
+ 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267,
+ 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311,
+ 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
+ 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423,
+ 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503,
+ 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
+ 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657,
+ 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693,
+ 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
+ 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801,
+ 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861,
+ 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
+ 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011,
+ 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079,
+ 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
+ 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221,
+ 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301,
+ 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
+ 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413,
+ 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491,
+ 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
+ 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607,
+ 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671,
+ 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
+ 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797,
+ 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863,
+ 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
+ 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003,
+ 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057,
+ 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
+ 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211,
+ 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259,
+ 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
+ 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409,
+ 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481,
+ 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
+ 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621,
+ 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673,
+ 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
+ 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813,
+ 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909,
+ 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
+ 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011,
+ 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087,
+ 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
+ 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233,
+ 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309,
+ 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
+ 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443,
+ 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507,
+ 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
+ 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653,
+ 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711,
+ 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
+ 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849,
+ 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897,
+ 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
+ 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073,
+ 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133,
+ 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
+ 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271,
+ 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329,
+ 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
+ 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473,
+ 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563,
+ 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
+ 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701,
+ 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779,
+ 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
+ 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907,
+ 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971,
+ 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
+ 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121,
+ 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207,
+ 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
+ 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349,
+ 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457,
+ 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
+ 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561,
+ 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621,
+ 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
+ 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757,
+ 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853,
+ 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
+ 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009,
+ 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087,
+ 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
+ 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231,
+ 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291,
+ 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
+ 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443,
+ 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537,
+ 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
+ 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677,
+ 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731,
+ 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
+ 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861,
+ 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941,
+ 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
+ 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091,
+ 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161,
+ 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
+ 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311,
+ 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377,
+ 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
+ 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491,
+ 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587,
+ 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
+ 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733,
+ 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791,
+ 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
+ 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929,
+ 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037,
+ 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099,
+ 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
+ 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247,
+ 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303,
+ 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369,
+ 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459,
+ 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
+ 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627,
+ 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691,
+ 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771,
+ 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859,
+ 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
+ 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003,
+ 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087,
+ 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161,
+ 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251,
+ 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
+ 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399,
+ 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483,
+ 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551,
+ 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657,
+ 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
+ 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813,
+ 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887,
+ 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941,
+ 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011,
+ 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
+ 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161,
+ 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251,
+ 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323,
+ 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401,
+ 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
+ 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527,
+ 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589,
+ 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653,
+ 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739,
+ 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
+ 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907,
+ 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967,
+ 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033,
+ 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109,
+ 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
+ 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259,
+ 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337,
+ 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421,
+ 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499,
+ 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
+ 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681,
+ 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723,
+ 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799,
+ 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879,
+ 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
+ 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033,
+ 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143,
+ 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221,
+ 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323,
+ 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
+ 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461,
+ 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549,
+ 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627,
+ 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699,
+ 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
+ 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821,
+ 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887,
+ 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957,
+ 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073,
+ 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
+ 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217,
+ 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277,
+ 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331,
+ 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401,
+ 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
+ 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569,
+ 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643,
+ 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727,
+ 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773,
+ 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
+ 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919,
+ 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007,
+ 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087,
+ 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183,
+ 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
+ 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349,
+ 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427,
+ 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493,
+ 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603,
+ 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
+ 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747,
+ 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843,
+ 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927,
+ 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993,
+ 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
+ 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159,
+ 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231,
+ 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327,
+ 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389,
+ 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
+ 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519,
+ 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599,
+ 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683,
+ 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783,
+ 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
#endif
};
diff --git a/thirdparty/openssl/crypto/bn/bn_print.c b/thirdparty/openssl/crypto/bn/bn_print.c
index bfa31efc56..f85a6550a5 100644
--- a/thirdparty/openssl/crypto/bn/bn_print.c
+++ b/thirdparty/openssl/crypto/bn/bn_print.c
@@ -72,12 +72,9 @@ char *BN_bn2hex(const BIGNUM *a)
char *buf;
char *p;
- if (a->neg && BN_is_zero(a)) {
- /* "-0" == 3 bytes including NULL terminator */
- buf = OPENSSL_malloc(3);
- } else {
- buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
- }
+ if (BN_is_zero(a))
+ return OPENSSL_strdup("0");
+ buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE);
goto err;
@@ -85,8 +82,6 @@ char *BN_bn2hex(const BIGNUM *a)
p = buf;
if (a->neg)
*(p++) = '-';
- if (BN_is_zero(a))
- *(p++) = '0';
for (i = a->top - 1; i >= 0; i--) {
for (j = BN_BITS2 - 8; j >= 0; j -= 8) {
/* strip leading zeros */
@@ -111,6 +106,7 @@ char *BN_bn2dec(const BIGNUM *a)
char *p;
BIGNUM *t = NULL;
BN_ULONG *bn_data = NULL, *lp;
+ int bn_data_num;
/*-
* get an upper bound for the length of the decimal integer
@@ -120,9 +116,9 @@ char *BN_bn2dec(const BIGNUM *a)
*/
i = BN_num_bits(a) * 3;
num = (i / 10 + i / 1000 + 1) + 1;
- bn_data =
- (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
- buf = (char *)OPENSSL_malloc(num + 3);
+ bn_data_num = num / BN_DEC_NUM + 1;
+ bn_data = OPENSSL_malloc(bn_data_num * sizeof(BN_ULONG));
+ buf = OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE);
goto err;
@@ -140,9 +136,12 @@ char *BN_bn2dec(const BIGNUM *a)
if (BN_is_negative(t))
*p++ = '-';
- i = 0;
while (!BN_is_zero(t)) {
+ if (lp - bn_data >= bn_data_num)
+ goto err;
*lp = BN_div_word(t, BN_DEC_CONV);
+ if (*lp == (BN_ULONG)-1)
+ goto err;
lp++;
}
lp--;
@@ -240,10 +239,12 @@ int BN_hex2bn(BIGNUM **bn, const char *a)
}
ret->top = h;
bn_correct_top(ret);
- ret->neg = neg;
*bn = ret;
bn_check_top(ret);
+ /* Don't set the negative flag if it's zero. */
+ if (ret->top != 0)
+ ret->neg = neg;
return (num);
err:
if (*bn == NULL)
@@ -295,7 +296,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
if (j == BN_DEC_NUM)
j = 0;
l = 0;
- while (*a) {
+ while (--i >= 0) {
l *= 10;
l += *a - '0';
a++;
@@ -306,11 +307,13 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
j = 0;
}
}
- ret->neg = neg;
bn_correct_top(ret);
*bn = ret;
bn_check_top(ret);
+ /* Don't set the negative flag if it's zero. */
+ if (ret->top != 0)
+ ret->neg = neg;
return (num);
err:
if (*bn == NULL)
@@ -321,6 +324,7 @@ int BN_dec2bn(BIGNUM **bn, const char *a)
int BN_asc2bn(BIGNUM **bn, const char *a)
{
const char *p = a;
+
if (*p == '-')
p++;
@@ -331,7 +335,8 @@ int BN_asc2bn(BIGNUM **bn, const char *a)
if (!BN_dec2bn(bn, p))
return 0;
}
- if (*a == '-')
+ /* Don't set the negative flag if it's zero. */
+ if (*a == '-' && (*bn)->top != 0)
(*bn)->neg = 1;
return 1;
}
diff --git a/thirdparty/openssl/crypto/bn/bn_rand.c b/thirdparty/openssl/crypto/bn/bn_rand.c
index f9fb2e9e45..60d3f2260b 100644
--- a/thirdparty/openssl/crypto/bn/bn_rand.c
+++ b/thirdparty/openssl/crypto/bn/bn_rand.c
@@ -121,15 +121,14 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
int ret = 0, bit, bytes, mask;
time_t tim;
- if (bits < 0 || (bits == 1 && top > 0)) {
- BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
- return 0;
- }
-
if (bits == 0) {
+ if (top != -1 || bottom != 0)
+ goto toosmall;
BN_zero(rnd);
return 1;
}
+ if (bits < 0 || (bits == 1 && top > 0))
+ goto toosmall;
bytes = (bits + 7) / 8;
bit = (bits - 1) % 8;
@@ -145,13 +144,9 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
time(&tim);
RAND_add(&tim, sizeof(tim), 0.0);
- if (pseudorand) {
- if (RAND_pseudo_bytes(buf, bytes) == -1)
- goto err;
- } else {
- if (RAND_bytes(buf, bytes) <= 0)
- goto err;
- }
+ /* We ignore the value of pseudorand and always call RAND_bytes */
+ if (RAND_bytes(buf, bytes) <= 0)
+ goto err;
#if 1
if (pseudorand == 2) {
@@ -199,6 +194,10 @@ static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom)
}
bn_check_top(rnd);
return (ret);
+
+toosmall:
+ BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL);
+ return 0;
}
int BN_rand(BIGNUM *rnd, int bits, int top, int bottom)
diff --git a/thirdparty/openssl/crypto/bn/bn_sqr.c b/thirdparty/openssl/crypto/bn/bn_sqr.c
index 3ca69879ee..256d26e8db 100644
--- a/thirdparty/openssl/crypto/bn/bn_sqr.c
+++ b/thirdparty/openssl/crypto/bn/bn_sqr.c
@@ -143,8 +143,9 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx)
rr->top = max - 1;
else
rr->top = max;
- if (rr != r)
- BN_copy(r, rr);
+ if (r != rr && BN_copy(r, rr) == NULL)
+ goto err;
+
ret = 1;
err:
bn_check_top(rr);
diff --git a/thirdparty/openssl/crypto/bn/bn_word.c b/thirdparty/openssl/crypto/bn/bn_word.c
index b031a60b5b..9b5f9cb98c 100644
--- a/thirdparty/openssl/crypto/bn/bn_word.c
+++ b/thirdparty/openssl/crypto/bn/bn_word.c
@@ -72,10 +72,32 @@ BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w)
if (w == 0)
return (BN_ULONG)-1;
+#ifndef BN_LLONG
+ /*
+ * If |w| is too long and we don't have BN_ULLONG then we need to fall
+ * back to using BN_div_word
+ */
+ if (w > ((BN_ULONG)1 << BN_BITS4)) {
+ BIGNUM *tmp = BN_dup(a);
+ if (tmp == NULL)
+ return (BN_ULONG)-1;
+
+ ret = BN_div_word(tmp, w);
+ BN_free(tmp);
+
+ return ret;
+ }
+#endif
+
bn_check_top(a);
w &= BN_MASK2;
for (i = a->top - 1; i >= 0; i--) {
#ifndef BN_LLONG
+ /*
+ * We can assume here that | w <= ((BN_ULONG)1 << BN_BITS4) | and so
+ * | ret < ((BN_ULONG)1 << BN_BITS4) | and therefore the shifts here are
+ * safe and will not overflow
+ */
ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w;
ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w;
#else
diff --git a/thirdparty/openssl/crypto/cms/cms_enc.c b/thirdparty/openssl/crypto/cms/cms_enc.c
index b14b4b68b5..90b1fcc750 100644
--- a/thirdparty/openssl/crypto/cms/cms_enc.c
+++ b/thirdparty/openssl/crypto/cms/cms_enc.c
@@ -119,7 +119,7 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
/* Generate a random IV if we need one */
ivlen = EVP_CIPHER_CTX_iv_length(ctx);
if (ivlen > 0) {
- if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+ if (RAND_bytes(iv, ivlen) <= 0)
goto err;
piv = iv;
}
@@ -179,10 +179,9 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
CMS_R_CIPHER_INITIALISATION_ERROR);
goto err;
}
-
- if (piv) {
+ if (enc) {
calg->parameter = ASN1_TYPE_new();
- if (!calg->parameter) {
+ if (calg->parameter == NULL) {
CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -191,6 +190,11 @@ BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec)
CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR);
goto err;
}
+ /* If parameter type not set omit parameter */
+ if (calg->parameter->type == V_ASN1_UNDEF) {
+ ASN1_TYPE_free(calg->parameter);
+ calg->parameter = NULL;
+ }
}
ok = 1;
diff --git a/thirdparty/openssl/crypto/cms/cms_ess.c b/thirdparty/openssl/crypto/cms/cms_ess.c
index 8631a2eb2b..8212560628 100644
--- a/thirdparty/openssl/crypto/cms/cms_ess.c
+++ b/thirdparty/openssl/crypto/cms/cms_ess.c
@@ -107,8 +107,7 @@ CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen,
else {
if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32))
goto merr;
- if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32)
- <= 0)
+ if (RAND_bytes(rr->signedContentIdentifier->data, 32) <= 0)
goto err;
}
diff --git a/thirdparty/openssl/crypto/cms/cms_kari.c b/thirdparty/openssl/crypto/cms/cms_kari.c
index 2cfcdb29cd..ee283172d3 100644
--- a/thirdparty/openssl/crypto/cms/cms_kari.c
+++ b/thirdparty/openssl/crypto/cms/cms_kari.c
@@ -401,9 +401,12 @@ static int cms_wrap_init(CMS_KeyAgreeRecipientInfo *kari,
* Pick a cipher based on content encryption cipher. If it is DES3 use
* DES3 wrap otherwise use AES wrap similar to key size.
*/
+#ifndef OPENSSL_NO_DES
if (EVP_CIPHER_type(cipher) == NID_des_ede3_cbc)
kekcipher = EVP_des_ede3_wrap();
- else if (keylen <= 16)
+ else
+#endif
+ if (keylen <= 16)
kekcipher = EVP_aes_128_wrap();
else if (keylen <= 24)
kekcipher = EVP_aes_192_wrap();
diff --git a/thirdparty/openssl/crypto/cms/cms_lib.c b/thirdparty/openssl/crypto/cms/cms_lib.c
index d6cb60d02d..6d27c4969b 100644
--- a/thirdparty/openssl/crypto/cms/cms_lib.c
+++ b/thirdparty/openssl/crypto/cms/cms_lib.c
@@ -413,6 +413,8 @@ static STACK_OF(CMS_CertificateChoices)
return &cms->d.signedData->certificates;
case NID_pkcs7_enveloped:
+ if (cms->d.envelopedData->originatorInfo == NULL)
+ return NULL;
return &cms->d.envelopedData->originatorInfo->certificates;
default:
@@ -488,6 +490,8 @@ static STACK_OF(CMS_RevocationInfoChoice)
return &cms->d.signedData->crls;
case NID_pkcs7_enveloped:
+ if (cms->d.envelopedData->originatorInfo == NULL)
+ return NULL;
return &cms->d.envelopedData->originatorInfo->crls;
default:
diff --git a/thirdparty/openssl/crypto/cms/cms_pwri.c b/thirdparty/openssl/crypto/cms/cms_pwri.c
index b91c01691f..5c817caf2f 100644
--- a/thirdparty/openssl/crypto/cms/cms_pwri.c
+++ b/thirdparty/openssl/crypto/cms/cms_pwri.c
@@ -134,7 +134,7 @@ CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms,
ivlen = EVP_CIPHER_CTX_iv_length(&ctx);
if (ivlen > 0) {
- if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+ if (RAND_bytes(iv, ivlen) <= 0)
goto err;
if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) {
CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB);
@@ -301,7 +301,7 @@ static int kek_wrap_key(unsigned char *out, size_t *outlen,
memcpy(out + 4, in, inlen);
/* Add random padding to end */
if (olen > inlen + 4
- && RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen) < 0)
+ && RAND_bytes(out + 4 + inlen, olen - 4 - inlen) <= 0)
return 0;
/* Encrypt twice */
EVP_EncryptUpdate(ctx, out, &dummy, out, olen);
diff --git a/thirdparty/openssl/crypto/comp/c_rle.c b/thirdparty/openssl/crypto/comp/c_rle.c
index e9aabbd166..41919613ee 100644
--- a/thirdparty/openssl/crypto/comp/c_rle.c
+++ b/thirdparty/openssl/crypto/comp/c_rle.c
@@ -31,12 +31,11 @@ static int rle_compress_block(COMP_CTX *ctx, unsigned char *out,
unsigned int olen, unsigned char *in,
unsigned int ilen)
{
- /* int i; */
+ if (ilen == 0)
+ return 0;
- if (ilen == 0 || olen < (ilen - 1)) {
- /* ZZZZZZZZZZZZZZZZZZZZZZ */
- return (-1);
- }
+ if (olen <= ilen)
+ return -1;
*(out++) = 0;
memcpy(out, in, ilen);
@@ -49,14 +48,16 @@ static int rle_expand_block(COMP_CTX *ctx, unsigned char *out,
{
int i;
- if (olen < (ilen - 1)) {
- /* ZZZZZZZZZZZZZZZZZZZZZZ */
- return (-1);
- }
+ if (ilen == 0)
+ return 0;
+
+ if (olen < (ilen - 1))
+ return -1;
i = *(in++);
- if (i == 0) {
- memcpy(out, in, ilen - 1);
- }
+ if (i != 0)
+ return -1;
+
+ memcpy(out, in, ilen - 1);
return (ilen - 1);
}
diff --git a/thirdparty/openssl/crypto/conf/conf_def.c b/thirdparty/openssl/crypto/conf/conf_def.c
index 68c77cec7d..75e309aaca 100644
--- a/thirdparty/openssl/crypto/conf/conf_def.c
+++ b/thirdparty/openssl/crypto/conf/conf_def.c
@@ -69,6 +69,12 @@
#include <openssl/buffer.h>
#include <openssl/err.h>
+/*
+ * The maximum length we can grow a value to after variable expansion. 64k
+ * should be more than enough for all reasonable uses.
+ */
+#define MAX_CONF_VALUE_LENGTH 65536
+
static char *eat_ws(CONF *conf, char *p);
static char *eat_alpha_numeric(CONF *conf, char *p);
static void clear_comments(CONF *conf, char *p);
@@ -530,6 +536,8 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from)
} else if (IS_EOF(conf, *from))
break;
else if (*from == '$') {
+ size_t newsize;
+
/* try to expand it */
rrp = NULL;
s = &(from[1]);
@@ -584,8 +592,12 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from)
CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE);
goto err;
}
- if (!BUF_MEM_grow_clean(buf,
- (strlen(p) + buf->length - (e - from)))) {
+ newsize = strlen(p) + buf->length - (e - from);
+ if (newsize > MAX_CONF_VALUE_LENGTH) {
+ CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_EXPANSION_TOO_LONG);
+ goto err;
+ }
+ if (!BUF_MEM_grow_clean(buf, newsize)) {
CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/thirdparty/openssl/crypto/conf/conf_def.h b/thirdparty/openssl/crypto/conf/conf_def.h
index 7d897b89f1..48b3442181 100644
--- a/thirdparty/openssl/crypto/conf/conf_def.h
+++ b/thirdparty/openssl/crypto/conf/conf_def.h
@@ -81,34 +81,34 @@
#define KEYTYPES(c) ((unsigned short *)((c)->meth_data))
#ifndef CHARSET_EBCDIC
-# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
-# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
-# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
-# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
-# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
-# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS)
-# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
+# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT)
+# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF)
+# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC)
+# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER)
+# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC)
# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
(KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
-# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
-# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
-# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
+# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE)
+# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT)
-#else /* CHARSET_EBCDIC */
+#else /*CHARSET_EBCDIC*/
-# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
-# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
-# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
-# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
-# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
-# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
-# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
+# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT)
+# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT)
+# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF)
+# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC)
+# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER)
+# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS)
+# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC)
# define IS_ALPHA_NUMERIC_PUNCT(c,a) \
(KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT)
-# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
-# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
-# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
-#endif /* CHARSET_EBCDIC */
+# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE)
+# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE)
+# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT)
+#endif /*CHARSET_EBCDIC*/
static unsigned short CONF_type_default[256] = {
0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
diff --git a/thirdparty/openssl/crypto/conf/conf_err.c b/thirdparty/openssl/crypto/conf/conf_err.c
index bb5e2fe252..b0b6896f83 100644
--- a/thirdparty/openssl/crypto/conf/conf_err.c
+++ b/thirdparty/openssl/crypto/conf/conf_err.c
@@ -115,6 +115,8 @@ static ERR_STRING_DATA CONF_str_reasons[] = {
{ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION),
"unable to create new section"},
{ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"},
+ {ERR_REASON(CONF_R_VARIABLE_EXPANSION_TOO_LONG),
+ "variable expansion too long"},
{ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"},
{0, NULL}
};
diff --git a/thirdparty/openssl/crypto/conf/conf_mod.c b/thirdparty/openssl/crypto/conf/conf_mod.c
index 9acfca4f71..e0c9a67ff6 100644
--- a/thirdparty/openssl/crypto/conf/conf_mod.c
+++ b/thirdparty/openssl/crypto/conf/conf_mod.c
@@ -288,6 +288,10 @@ static CONF_MODULE *module_add(DSO *dso, const char *name,
tmod->dso = dso;
tmod->name = BUF_strdup(name);
+ if (tmod->name == NULL) {
+ OPENSSL_free(tmod);
+ return NULL;
+ }
tmod->init = ifunc;
tmod->finish = ffunc;
tmod->links = 0;
diff --git a/thirdparty/openssl/crypto/conf/ssleay.cnf b/thirdparty/openssl/crypto/conf/ssleay.cnf
deleted file mode 100644
index ed33af601e..0000000000
--- a/thirdparty/openssl/crypto/conf/ssleay.cnf
+++ /dev/null
@@ -1,78 +0,0 @@
-#
-# This is a test configuration file for use in SSLeay etc...
-#
-
-init = 5
-in\#it1 =10
-init2='10'
-init3='10\''
-init4="10'"
-init5='='10\'' again'
-
-SSLeay::version = 0.5.0
-
-[genrsa]
-default_bits = 512
-SSLEAY::version = 0.5.0
-
-[gendh]
-default_bits = 512
-def_generator = 2
-
-[s_client]
-cipher1 = DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5\
-cipher2 = 'DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5'
-cipher3 = "DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5"
-cipher4 = DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5
-
-[ default ]
-cert_dir = $ENV::HOME/.ca_certs
-
-HOME = /tmp/eay
-
-tmp_cert_dir = $HOME/.ca_certs
-tmp2_cert_dir = thisis$(HOME)stuff
-
-LOGNAME = Eric Young (home=$HOME)
-
-[ special ]
-
-H=$HOME
-H=$default::HOME
-H=$ENV::HOME
-#
-# SSLeay example configuration file.
-# This is mostly being used for generation of certificate requests.
-#
-
-RANDFILE = $HOME/.rand
-
-[ req ]
-default_bits = 512
-default_keyfile = privkey.pem
-
-Attribute_type_1 = countryName
-Attribute_text_1 = Country Name (2 letter code)
-Attribute_default_1 = AU
-
-Attribute_type_2 = stateOrProvinceName
-Attribute_text_2 = State or Province Name (full name)
-Attribute_default_2 = Queensland
-
-Attribute_type_3 = localityName
-Attribute_text_3 = Locality Name (eg, city)
-
-Attribute_type_4 = organizationName
-Attribute_text_4 = Organization Name (eg, company)
-Attribute_default_4 = Mincom Pty Ltd
-
-Attribute_type_5 = organizationalUnitName
-Attribute_text_5 = Organizational Unit Name (eg, section)
-Attribute_default_5 = TR
-
-Attribute_type_6 = commonName
-Attribute_text_6 = Common Name (eg, YOUR name)
-
-Attribute_type_7 = emailAddress
-Attribute_text_7 = Email Address
-
diff --git a/thirdparty/openssl/crypto/crypto-lib.com b/thirdparty/openssl/crypto/crypto-lib.com
deleted file mode 100644
index 1423cac288..0000000000
--- a/thirdparty/openssl/crypto/crypto-lib.com
+++ /dev/null
@@ -1,1537 +0,0 @@
-$!
-$! CRYPTO-LIB.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$! Zoltan Arpadffy <arpadffy@polarhome.com>
-$!
-$! This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB"
-$! library for OpenSSL. The "xxx" denotes the machine architecture, ALPHA,
-$! IA64 or VAX.
-$!
-$! It was re-written so it would try to determine what "C" compiler to use
-$! or you can specify which "C" compiler to use.
-$!
-$! Specify the following as P1 to build just that part or ALL to just
-$! build everything.
-$!
-$! LIBRARY To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library.
-$! APPS To just compile the [.xxx.EXE.CRYPTO]*.EXE
-$! ALL To do both LIBRARY and APPS
-$!
-$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P3 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P4, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX For UCX
-$! TCPIP For TCPIP (post UCX)
-$! SOCKETSHR For SOCKETSHR+NETLIB
-$!
-$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! P6, if defined, sets a choice of crypto methods to compile.
-$! WARNING: this should only be done to recompile some part of an already
-$! fully compiled library.
-$!
-$! P7, if defined, specifies the C pointer size. Ignored on VAX.
-$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
-$! Supported values are:
-$!
-$! "" Compile with default (/NOPOINTER_SIZE)
-$! 32 Compile with /POINTER_SIZE=32 (SHORT)
-$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]).
-$! (Automatically select ARGV if compiler supports it.)
-$! 64= Compile with /POINTER_SIZE=64 (LONG).
-$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
-$!
-$! P8, if defined, specifies a directory where ZLIB files (zlib.h,
-$! libz.olb) may be found. Optionally, a non-default object library
-$! name may be included ("dev:[dir]libz_64.olb", for example).
-$!
-$!
-$! Announce/identify.
-$!
-$ proc = f$environment( "procedure")
-$ write sys$output "@@@ "+ -
- f$parse( proc, , , "name")+ f$parse( proc, , , "type")
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That Is, If We Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$ ZLIB_LIB = ""
-$!
-$! Check Which Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$ ARCHD = ARCH
-$ LIB32 = "32"
-$ OPT_FILE = ""
-$ POINTER_SIZE = ""
-$!
-$! Define The Different Encryption Types.
-$! NOTE: Some might think this list ugly. However, it's made this way to
-$! reflect the SDIRS variable in [-]Makefile.org as closely as possible,
-$! thereby making it fairly easy to verify that the lists are the same.
-$!
-$ ET_WHIRLPOOL = "WHRLPOOL"
-$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = ""
-$ ENCRYPT_TYPES = "Basic,"+ -
- "OBJECTS,"+ -
- "MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ -
- "DES,AES,RC2,RC4,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ -
- "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ -
- "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ -
- "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ -
- "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ -
- "CMS,PQUEUE,TS,JPAKE,SRP,STORE,CMAC"
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Define The OBJ and EXE Directories.
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.CRYPTO]
-$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]
-$!
-$! Specify the destination directory in any /MAP option.
-$!
-$ if (LINKMAP .eqs. "MAP")
-$ then
-$ LINKMAP = LINKMAP+ "=''EXE_DIR'"
-$ endif
-$!
-$! Add the location prefix to the linker options file name.
-$!
-$ if (OPT_FILE .nes. "")
-$ then
-$ OPT_FILE = EXE_DIR+ OPT_FILE
-$ endif
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
-$!
-$!
-$! Check To See If The Architecture Specific OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'OBJ_DIR'
-$!
-$! End The Architecture Specific OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The Architecture Specific Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIRECTORY 'EXE_DIR'
-$!
-$! End The Architecture Specific Directory Check.
-$!
-$ ENDIF
-$!
-$! Define The Library Name.
-$!
-$ LIB_NAME := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
-$!
-$! Define The CRYPTO-LIB We Are To Use.
-$!
-$ CRYPTO_LIB := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB
-$!
-$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library...
-$!
-$ IF (F$SEARCH(LIB_NAME).EQS."")
-$ THEN
-$!
-$! Guess Not, Create The Library.
-$!
-$ LIBRARY/CREATE/OBJECT 'LIB_NAME'
-$!
-$! End The Library Check.
-$!
-$ ENDIF
-$!
-$! Build our options file for the application
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Define The Different Encryption "library" Strings.
-$!
-$!!! Test apps disabled, as they aren't supported at all,
-$!!! not even in the unix build
-$!!! APPS_DES = "DES/DES,CBC3_ENC"
-$!!! APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE"
-$
-$! These variables are ordered as the SDIRS variable from the top Makefile.org
-$! The contents of these variables are copied from the LIBOBJ variable in the
-$! corresponding Makefile from each corresponding subdirectory, with .o stripped
-$! and spaces replaced with commas.
-$ LIB_ = "cryptlib,mem,mem_dbg,cversion,ex_data,cpt_err,ebcdic,"+ -
- "uid,o_time,o_str,o_dir,o_fips,o_init,fips_ers,mem_clr"
-$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref"
-$ LIB_MD2 = "md2_dgst,md2_one"
-$ LIB_MD4 = "md4_dgst,md4_one"
-$ LIB_MD5 = "md5_dgst,md5_one"
-$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512"
-$ LIB_MDC2 = "mdc2dgst,mdc2_one"
-$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth"
-$ LIB_RIPEMD = "rmd_dgst,rmd_one"
-$ LIB_WHRLPOOL = "wp_dgst,wp_block"
-$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
- "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
- "enc_read,enc_writ,ofb64enc,"+ -
- "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
- "des_enc,fcrypt_b,"+ -
- "fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ -
- "ede_cbcm_enc,des_old,des_old2,read2pwd"
-$ LIB_AES = "aes_misc,aes_ecb,aes_cfb,aes_ofb,aes_ctr,aes_ige,aes_wrap,"+ -
- "aes_core,aes_cbc"
-$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64"
-$ LIB_RC4 = "rc4_enc,rc4_skey,rc4_utl"
-$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64"
-$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey"
-$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64"
-$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64"
-$ LIB_CAMELLIA = "cmll_ecb,cmll_ofb,cmll_cfb,cmll_ctr,"+ -
- "cmll_utl,camellia,cmll_misc,cmll_cbc"
-$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb"
-$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128,gcm128,"+ -
- "ccm128,xts128,wrap128"
-$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper"
-$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN -
- LIB_BN_ASM = "bn_asm"
-$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ -
- "bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ -
- "bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ -
- "bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ -
- "bn_depr,bn_const,bn_x931p"
-$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ -
- "ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ -
- "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn,"+ -
- "ecp_nistp224,ecp_nistp256,ecp_nistp521,ecp_nistputil,"+ -
- "ecp_oct,ec2_oct,ec_oct"
-$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ -
- "rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ -
- "rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ -
- "rsa_pmeth,rsa_crpt"
-$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ -
- "dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn"
-$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err"
-$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ -
- "dh_ameth,dh_pmeth,dh_prn,dh_rfc5114,dh_kdf"
-$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err,ech_kdf"
-$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ -
- "dso_openssl,dso_win32,dso_vms,dso_beos"
-$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ -
- "eng_table,eng_pkey,eng_fat,eng_all,"+ -
- "tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ -
- "tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ -
- "eng_openssl,eng_cnf,eng_dyn,eng_cryptodev,"+ -
- "eng_rdrand"
-$ LIB_BUFFER = "buffer,buf_str,buf_err"
-$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ -
- "bss_mem,bss_null,bss_fd,"+ -
- "bss_file,bss_sock,bss_conn,"+ -
- "bf_null,bf_buff,b_print,b_dump,"+ -
- "b_sock,bss_acpt,bf_nbio,bss_log,bss_bio,"+ -
- "bss_dgram,"+ -
- "bf_lbuf,bss_rtcp" ! The last two are VMS specific
-$ LIB_STACK = "stack"
-$ LIB_LHASH = "lhash,lh_stats"
-$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ -
- "rand_vms" ! The last one is VMS specific
-$ LIB_ERR = "err,err_all,err_prn"
-$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,evp_cnf,"+ -
- "e_des,e_bf,e_idea,e_des3,e_camellia,"+ -
- "e_rc4,e_aes,names,e_seed,"+ -
- "e_xcbc_d,e_rc2,e_cast,e_rc5"
-$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + -
- "m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ -
- "p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ -
- "bio_md,bio_b64,bio_enc,evp_err,e_null,"+ -
- "c_all,c_allc,c_alld,evp_lib,bio_ok,"+-
- "evp_pkey,evp_pbe,p5_crpt,p5_crpt2"
-$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver,"+ -
- "e_aes_cbc_hmac_sha1,e_aes_cbc_hmac_sha256,e_rc4_hmac_md5"
-$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ -
- "a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ -
- "a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ -
- "x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ -
- "x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ -
- "x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr"
-$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ -
- "tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ -
- "tasn_prn,ameth_lib,"+ -
- "f_int,f_string,n_pkey,"+ -
- "f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ -
- "asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ -
- "evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid"
-$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ -
- "pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt"
-$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ -
- "x509_obj,x509_req,x509spki,x509_vfy,"+ -
- "x509_set,x509cset,x509rset,x509_err,"+ -
- "x509name,x509_v3,x509_ext,x509_att,"+ -
- "x509type,x509_lu,x_all,x509_txt,"+ -
- "x509_trs,by_file,by_dir,x509_vpm"
-$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ -
- "v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ -
- "v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ -
- "v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ -
- "pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ -
- "v3_asid,v3_addr,v3_scts"
-$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap"
-$ LIB_TXT_DB = "txt_db"
-$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ -
- "pk7_mime,bio_pk7"
-$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ -
- "p12_init,p12_key,p12_kiss,p12_mutl,"+ -
- "p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e"
-$ LIB_COMP = "comp_lib,comp_err,"+ -
- "c_rle,c_zlib"
-$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ -
- "ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err"
-$ LIB_UI_COMPAT = ",ui_compat"
-$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT
-$ LIB_KRB5 = "krb5_asn"
-$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ -
- "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess,"+ -
- "cms_pwri,cms_kari"
-$ LIB_PQUEUE = "pqueue"
-$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ -
- "ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ -
- "ts_asn1"
-$ LIB_JPAKE = "jpake,jpake_err"
-$ LIB_SRP = "srp_lib,srp_vfy"
-$ LIB_STORE = "str_err,str_lib,str_meth,str_mem"
-$ LIB_CMAC = "cmac,cm_ameth,cm_pmeth"
-$!
-$! Setup exceptional compilations
-$!
-$ CC3_SHOWN = 0
-$ CC4_SHOWN = 0
-$ CC5_SHOWN = 0
-$ CC6_SHOWN = 0
-$!
-$! The following lists must have leading and trailing commas, and no
-$! embedded spaces. (They are scanned for ",name,".)
-$!
-$ ! Add definitions for no threads on OpenVMS 7.1 and higher.
-$ COMPILEWITH_CC3 = ",bss_rtcp,"
-$ ! Disable the DOLLARID warning. Not needed with /STANDARD=RELAXED.
-$ COMPILEWITH_CC4 = "" !!! ",a_utctm,bss_log,o_time,o_dir,"
-$ ! Disable disjoint optimization on VAX with DECC.
-$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + -
- "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc,"
-$ ! Disable the MIXLINKAGE warning.
-$ COMPILEWITH_CC6 = "" !!! ",enc_read,set_key,"
-$!
-$! Figure Out What Other Modules We Are To Build.
-$!
-$ BUILD_SET:
-$!
-$! Define A Module Counter.
-$!
-$ MODULE_COUNTER = 0
-$!
-$! Top Of The Loop.
-$!
-$ MODULE_NEXT:
-$!
-$! Extract The Module Name From The Encryption List.
-$!
-$ MODULE_NAME = F$EDIT(F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES),"COLLAPSE")
-$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = ""
-$ MODULE_NAME1 = MODULE_NAME
-$!
-$! Check To See If We Are At The End Of The Module List.
-$!
-$ IF (MODULE_NAME.EQS.",")
-$ THEN
-$!
-$! We Are At The End Of The Module List, Go To MODULE_DONE.
-$!
-$ GOTO MODULE_DONE
-$!
-$! End The Module List Check.
-$!
-$ ENDIF
-$!
-$! Increment The Moudle Counter.
-$!
-$ MODULE_COUNTER = MODULE_COUNTER + 1
-$!
-$! Create The Library and Apps Module Names.
-$!
-$ LIB_MODULE = "LIB_" + MODULE_NAME
-$ APPS_MODULE = "APPS_" + MODULE_NAME
-$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_")
-$ THEN
-$ MODULE_NAME = "ASN1"
-$ ENDIF
-$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_")
-$ THEN
-$ MODULE_NAME = "EVP"
-$ ENDIF
-$!
-$! Set state (can be LIB and APPS)
-$!
-$ STATE = "LIB"
-$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS"
-$!
-$! Check if the library module name actually is defined
-$!
-$ IF F$TYPE('LIB_MODULE') .EQS. ""
-$ THEN
-$ WRITE SYS$ERROR ""
-$ WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist. Continuing..."
-$ WRITE SYS$ERROR ""
-$ GOTO MODULE_NEXT
-$ ENDIF
-$!
-$! Top Of The Module Loop.
-$!
-$ MODULE_AGAIN:
-$!
-$! Tell The User What Module We Are Building.
-$!
-$ IF (MODULE_NAME1.NES."")
-$ THEN
-$ IF STATE .EQS. "LIB"
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")"
-$ ELSE IF F$TYPE('APPS_MODULE') .NES. ""
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")"
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Define A File Counter And Set It To "0".
-$!
-$ FILE_COUNTER = 0
-$ APPLICATION = ""
-$ APPLICATION_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! Look in the LIB_MODULE is we're in state LIB
-$!
-$ IF STATE .EQS. "LIB"
-$ THEN
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE'),"COLLAPSE")
-$!
-$! else
-$!
-$ ELSE
-$ FILE_NAME = ","
-$!
-$ IF F$TYPE('APPS_MODULE') .NES. ""
-$ THEN
-$!
-$! Extract The File Name From The File List.
-$! This part is a bit more complicated.
-$!
-$ IF APPLICATION .EQS. ""
-$ THEN
-$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
-$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
-$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
-$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
-$ FILE_COUNTER = 0
-$ ENDIF
-$
-$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
-$! SHOW SYMBOL APPLICATION*
-$!
-$ IF APPLICATION .NES. ";"
-$ THEN
-$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS),"COLLAPSE")
-$ IF FILE_NAME .EQS. ","
-$ THEN
-$ APPLICATION = ""
-$ GOTO NEXT_FILE
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",")
-$ THEN
-$!
-$! We Are At The End Of The File List, Change State Or Goto FILE_DONE.
-$!
-$ IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY"
-$ THEN
-$ STATE = "APPS"
-$ GOTO MODULE_AGAIN
-$ ELSE
-$ GOTO FILE_DONE
-$ ENDIF
-$!
-$! End The File List Check.
-$!
-$ ENDIF
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME)
-$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME
-$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN -
- FILE_NAME = FILE_NAME + ".c"
-$ IF (MODULE_NAME.NES."")
-$ THEN
-$ SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME
-$ ELSE
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME
-$ ENDIF
-$ SOURCE_FILE = SOURCE_FILE - "]["
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Doesn't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ GOTO EXIT
-$!
-$! End The File Exist Check.
-$!
-$ ENDIF
-$!
-$! Tell The User We Are Compiling The File.
-$!
-$ IF (MODULE_NAME.EQS."")
-$ THEN
-$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File. (",BUILDALL,",",STATE,")"
-$ ENDIF
-$ IF (MODULE_NAME.NES."")
-$ THEN
-$ WRITE SYS$OUTPUT " ",FILE_NAME,""
-$ ENDIF
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
-$ IF FILE_NAME - ".mar" .NES. FILE_NAME
-$ THEN
-$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3
-$ THEN
-$ write sys$output " \Using special rule (3)"
-$ if (.not. CC3_SHOWN)
-$ then
-$ CC3_SHOWN = 1
-$ x = " "+ CC3
-$ write /symbol sys$output x
-$ endif
-$ CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4
-$ THEN
-$ write /symbol sys$output " \Using special rule (4)"
-$ if (.not. CC4_SHOWN)
-$ then
-$ CC4_SHOWN = 1
-$ x = " "+ CC4
-$ write /symbol sys$output x
-$ endif
-$ CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF CC5_DIFFERENT .AND. -
- (COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5)
-$ THEN
-$ write sys$output " \Using special rule (5)"
-$ if (.not. CC5_SHOWN)
-$ then
-$ CC5_SHOWN = 1
-$ x = " "+ CC5
-$ write /symbol sys$output x
-$ endif
-$ CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6
-$ THEN
-$ write sys$output " \Using special rule (6)"
-$ if (.not. CC6_SHOWN)
-$ then
-$ CC6_SHOWN = 1
-$ x = " "+ CC6
-$ write /symbol sys$output x
-$ endif
-$ CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ELSE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$ IF STATE .EQS. "LIB"
-$ THEN
-$!
-$! Add It To The Library.
-$!
-$ LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE'
-$!
-$! Time To Clean Up The Object File.
-$!
-$ DELETE 'OBJECT_FILE';*
-$ ENDIF
-$!
-$! Go Back And Do It Again.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library Part.
-$!
-$ FILE_DONE:
-$!
-$! Time To Build Some Applications
-$!
-$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY"
-$ THEN
-$ APPLICATION_COUNTER = 0
-$ NEXT_APPLICATION:
-$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE')
-$ IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE
-$
-$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1
-$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION)
-$ APPLICATION = F$ELEMENT(0,"/",APPLICATION)
-$
-$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*"
-$! SHOW SYMBOL APPLICATION*
-$!
-$! Tell the user what happens
-$!
-$ WRITE SYS$OUTPUT " ",APPLICATION,".exe"
-$!
-$! Link The Program.
-$!
-$ ON ERROR THEN GOTO NEXT_APPLICATION
-$!
-$! Link With A TCP/IP Library.
-$!
-$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' -
- /EXE='EXE_DIR''APPLICATION'.EXE -
- 'OBJ_DIR''APPLICATION_OBJECTS', -
- 'CRYPTO_LIB'/LIBRARY -
- 'TCPIP_LIB' -
- 'ZLIB_LIB' -
- ,'OPT_FILE' /OPTIONS
-$!
-$ GOTO NEXT_APPLICATION
-$ APPLICATION_DONE:
-$ ENDIF
-$!
-$! Go Back And Get The Next Module.
-$!
-$ GOTO MODULE_NEXT
-$!
-$! All Done With This Module.
-$!
-$ MODULE_DONE:
-$!
-$! Tell The User That We Are All Done.
-$!
-$ WRITE SYS$OUTPUT "All Done..."
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF ARCH .EQS. "VAX"
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Against
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is Blank, So Build Everything.
-$!
-$ BUILDALL = "TRUE"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library."
-$ WRITE SYS$OUTPUT " APPS : To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA[64]: Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64[64] : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."NODEBUG")
-$ THEN
-$!
-$! P2 Is NODEBUG, So Compile Without The Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ LINKMAP = "NOMAP"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ MACRO_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P2.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ LINKMAP = "MAP"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ MACRO_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! They Entered An Invalid Option.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P5.
-$!
-$ IF (P5.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P5 Check.
-$!
-$ ENDIF
-$!
-$! Check P7 (POINTER_SIZE).
-$!
-$ IF (P7 .NES. "") .AND. (ARCH .NES. "VAX")
-$ THEN
-$!
-$ IF (P7 .EQS. "32")
-$ THEN
-$ POINTER_SIZE = " /POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = F$EDIT( P7, "COLLAPSE, UPCASE")
-$ IF ((POINTER_SIZE .EQS. "64") .OR. -
- (POINTER_SIZE .EQS. "64=") .OR. -
- (POINTER_SIZE .EQS. "64=ARGV"))
-$ THEN
-$ ARCHD = ARCH+ "_64"
-$ LIB32 = ""
-$ POINTER_SIZE = " /POINTER_SIZE=64"
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", P7, -
- " Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT -
- " """" : Compile with default (short) pointers."
-$ WRITE SYS$OUTPUT -
- " 32 : Compile with 32-bit (short) pointers."
-$ WRITE SYS$OUTPUT -
- " 64 : Compile with 64-bit (long) pointers (auto ARGV)."
-$ WRITE SYS$OUTPUT -
- " 64= : Compile with 64-bit (long) pointers (no ARGV)."
-$ WRITE SYS$OUTPUT -
- " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$ ENDIF
-$!
-$ ENDIF
-$!
-$! End The P7 (POINTER_SIZE) Check.
-$!
-$ ENDIF
-$!
-$! Set basic C compiler /INCLUDE directories.
-$!
-$ CC_INCLUDES = "SYS$DISK:[.''ARCHD'],SYS$DISK:[],SYS$DISK:[-],"+ -
- "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.MODES],SYS$DISK:[.ASN1],SYS$DISK:[.EVP]"
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P3 = "GNUC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P3 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P3 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P4 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P4 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. ""
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + ","
-$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS
-$ ENDIF
-$!
-$! Check To See If We Have A ZLIB Option.
-$!
-$ ZLIB = P8
-$ IF (ZLIB .NES. "")
-$ THEN
-$!
-$! Check for expected ZLIB files.
-$!
-$ err = 0
-$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
-$ if (f$search( file1) .eqs. "")
-$ then
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
-$ WRITE SYS$OUTPUT " Can't find header: ''file1'"
-$ err = 1
-$ endif
-$ file1 = f$parse( "A.;", ZLIB)- "A.;"
-$!
-$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
-$ if (f$search( file2) .eqs. "")
-$ then
-$ if (err .eq. 0)
-$ then
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
-$ endif
-$ WRITE SYS$OUTPUT " Can't find library: ''file2'"
-$ WRITE SYS$OUTPUT ""
-$ err = err+ 2
-$ endif
-$ if (err .eq. 1)
-$ then
-$ WRITE SYS$OUTPUT ""
-$ endif
-$!
-$ if (err .ne. 0)
-$ then
-$ EXIT
-$ endif
-$!
-$ CCDEFS = """ZLIB=1"", "+ CCDEFS
-$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1
-$ ZLIB_LIB = ", ''file2' /library"
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2
-$!
-$! End The ZLIB Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The User Entered A Valid Parameter.
-$!
-$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P3.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
- "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
- " /INCLUDE=(''CC_INCLUDES')"+ -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P3.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(''CC_INCLUDES')"+ -
- CCEXTRAFLAGS
-$ CCDEFS = """VAXC""," + CCDEFS
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P3.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(''CC_INCLUDES')"+ -
- CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$! Not all compiler versions support MAYLOSEDATA3.
-$ OPT_TEST = "MAYLOSEDATA3"
-$ DEFINE /USER_MODE SYS$ERROR NL:
-$ DEFINE /USER_MODE SYS$OUTPUT NL:
-$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT -
- /WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL:
-$ IF ($SEVERITY)
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS+ ","
-$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST
-$ ENDIF
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ CC6DISABLEWARNINGS = "MIXLINKAGE"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE"
-$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ CC6DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ CC6DISABLEWARNINGS = ""
-$ ENDIF
-$ CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
-$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$ IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG"
-$ THEN
-$ CC5 = CC + " /OPTIMIZE=NODISJOINT"
-$ CC5_DIFFERENT = 1
-$ ELSE
-$ CC5 = CC
-$ CC5_DIFFERENT = 0
-$ ENDIF
-$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! Build a MACRO command for the architecture at hand
-$!
-$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'"
-$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'"
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
- .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P4.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P4.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P4 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P4.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P4.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P4.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Check if the user wanted to compile just a subset of all the encryption
-$! methods.
-$!
-$ IF P6 .NES. ""
-$ THEN
-$ ENCRYPT_TYPES = P6
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "CRYPTO]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
diff --git a/thirdparty/openssl/crypto/des/asm/des_enc.m4 b/thirdparty/openssl/crypto/des/asm/des_enc.m4
deleted file mode 100644
index dda08e126d..0000000000
--- a/thirdparty/openssl/crypto/des/asm/des_enc.m4
+++ /dev/null
@@ -1,2101 +0,0 @@
-! des_enc.m4
-! des_enc.S (generated from des_enc.m4)
-!
-! UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file.
-!
-! Version 1.0. 32-bit version.
-!
-! June 8, 2000.
-!
-! Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation
-! by Andy Polyakov.
-!
-! January 1, 2003.
-!
-! Assembler version: Copyright Svend Olaf Mikkelsen.
-!
-! Original C code: Copyright Eric A. Young.
-!
-! This code can be freely used by LibDES/SSLeay/OpenSSL users.
-!
-! The LibDES/SSLeay/OpenSSL copyright notices must be respected.
-!
-! This version can be redistributed.
-!
-! To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S
-!
-! Global registers 1 to 5 are used. This is the same as done by the
-! cc compiler. The UltraSPARC load/store little endian feature is used.
-!
-! Instruction grouping often refers to one CPU cycle.
-!
-! Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S
-!
-! Assemble through cc: cc -c -xarch=v8plusa -o des_enc.o des_enc.S
-!
-! Performance improvement according to './apps/openssl speed des'
-!
-! 32-bit build:
-! 23% faster than cc-5.2 -xarch=v8plus -xO5
-! 115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5
-! 64-bit build:
-! 50% faster than cc-5.2 -xarch=v9 -xO5
-! 100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5
-!
-
-.ident "des_enc.m4 2.1"
-.file "des_enc-sparc.S"
-
-#include <openssl/opensslconf.h>
-
-#if defined(__SUNPRO_C) && defined(__sparcv9)
-# define ABI64 /* They've said -xarch=v9 at command line */
-#elif defined(__GNUC__) && defined(__arch64__)
-# define ABI64 /* They've said -m64 at command line */
-#endif
-
-#ifdef ABI64
- .register %g2,#scratch
- .register %g3,#scratch
-# define FRAME -192
-# define BIAS 2047
-# define LDPTR ldx
-# define STPTR stx
-# define ARG0 128
-# define ARGSZ 8
-# ifndef OPENSSL_SYSNAME_ULTRASPARC
-# define OPENSSL_SYSNAME_ULTRASPARC
-# endif
-#else
-# define FRAME -96
-# define BIAS 0
-# define LDPTR ld
-# define STPTR st
-# define ARG0 68
-# define ARGSZ 4
-#endif
-
-#define LOOPS 7
-
-#define global0 %g0
-#define global1 %g1
-#define global2 %g2
-#define global3 %g3
-#define global4 %g4
-#define global5 %g5
-
-#define local0 %l0
-#define local1 %l1
-#define local2 %l2
-#define local3 %l3
-#define local4 %l4
-#define local5 %l5
-#define local7 %l6
-#define local6 %l7
-
-#define in0 %i0
-#define in1 %i1
-#define in2 %i2
-#define in3 %i3
-#define in4 %i4
-#define in5 %i5
-#define in6 %i6
-#define in7 %i7
-
-#define out0 %o0
-#define out1 %o1
-#define out2 %o2
-#define out3 %o3
-#define out4 %o4
-#define out5 %o5
-#define out6 %o6
-#define out7 %o7
-
-#define stub stb
-
-changequote({,})
-
-
-! Macro definitions:
-
-
-! {ip_macro}
-!
-! The logic used in initial and final permutations is the same as in
-! the C code. The permutations are done with a clever shift, xor, and
-! technique.
-!
-! The macro also loads address sbox 1 to 5 to global 1 to 5, address
-! sbox 6 to local6, and addres sbox 8 to out3.
-!
-! Rotates the halfs 3 left to bring the sbox bits in convenient positions.
-!
-! Loads key first round from address in parameter 5 to out0, out1.
-!
-! After the the original LibDES initial permutation, the resulting left
-! is in the variable initially used for right and vice versa. The macro
-! implements the possibility to keep the halfs in the original registers.
-!
-! parameter 1 left
-! parameter 2 right
-! parameter 3 result left (modify in first round)
-! parameter 4 result right (use in first round)
-! parameter 5 key address
-! parameter 6 1/2 for include encryption/decryption
-! parameter 7 1 for move in1 to in3
-! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
-! parameter 9 1 for load ks3 and ks2 to in4 and in3
-
-define(ip_macro, {
-
-! {ip_macro}
-! $1 $2 $4 $3 $5 $6 $7 $8 $9
-
- ld [out2+256], local1
- srl $2, 4, local4
-
- xor local4, $1, local4
- ifelse($7,1,{mov in1, in3},{nop})
-
- ld [out2+260], local2
- and local4, local1, local4
- ifelse($8,1,{mov in3, in4},{})
- ifelse($8,2,{mov in4, in3},{})
-
- ld [out2+280], out4 ! loop counter
- sll local4, 4, local1
- xor $1, local4, $1
-
- ld [out2+264], local3
- srl $1, 16, local4
- xor $2, local1, $2
-
- ifelse($9,1,{LDPTR KS3, in4},{})
- xor local4, $2, local4
- nop !sethi %hi(DES_SPtrans), global1 ! sbox addr
-
- ifelse($9,1,{LDPTR KS2, in3},{})
- and local4, local2, local4
- nop !or global1, %lo(DES_SPtrans), global1 ! sbox addr
-
- sll local4, 16, local1
- xor $2, local4, $2
-
- srl $2, 2, local4
- xor $1, local1, $1
-
- sethi %hi(16711680), local5
- xor local4, $1, local4
-
- and local4, local3, local4
- or local5, 255, local5
-
- sll local4, 2, local2
- xor $1, local4, $1
-
- srl $1, 8, local4
- xor $2, local2, $2
-
- xor local4, $2, local4
- add global1, 768, global4
-
- and local4, local5, local4
- add global1, 1024, global5
-
- ld [out2+272], local7
- sll local4, 8, local1
- xor $2, local4, $2
-
- srl $2, 1, local4
- xor $1, local1, $1
-
- ld [$5], out0 ! key 7531
- xor local4, $1, local4
- add global1, 256, global2
-
- ld [$5+4], out1 ! key 8642
- and local4, local7, local4
- add global1, 512, global3
-
- sll local4, 1, local1
- xor $1, local4, $1
-
- sll $1, 3, local3
- xor $2, local1, $2
-
- sll $2, 3, local2
- add global1, 1280, local6 ! address sbox 8
-
- srl $1, 29, local4
- add global1, 1792, out3 ! address sbox 8
-
- srl $2, 29, local1
- or local4, local3, $4
-
- or local2, local1, $3
-
- ifelse($6, 1, {
-
- ld [out2+284], local5 ! 0x0000FC00 used in the rounds
- or local2, local1, $3
- xor $4, out0, local1
-
- call .des_enc.1
- and local1, 252, local1
-
- },{})
-
- ifelse($6, 2, {
-
- ld [out2+284], local5 ! 0x0000FC00 used in the rounds
- or local2, local1, $3
- xor $4, out0, local1
-
- call .des_dec.1
- and local1, 252, local1
-
- },{})
-})
-
-
-! {rounds_macro}
-!
-! The logic used in the DES rounds is the same as in the C code,
-! except that calculations for sbox 1 and sbox 5 begin before
-! the previous round is finished.
-!
-! In each round one half (work) is modified based on key and the
-! other half (use).
-!
-! In this version we do two rounds in a loop repeated 7 times
-! and two rounds seperately.
-!
-! One half has the bits for the sboxes in the following positions:
-!
-! 777777xx555555xx333333xx111111xx
-!
-! 88xx666666xx444444xx222222xx8888
-!
-! The bits for each sbox are xor-ed with the key bits for that box.
-! The above xx bits are cleared, and the result used for lookup in
-! the sbox table. Each sbox entry contains the 4 output bits permuted
-! into 32 bits according to the P permutation.
-!
-! In the description of DES, left and right are switched after
-! each round, except after last round. In this code the original
-! left and right are kept in the same register in all rounds, meaning
-! that after the 16 rounds the result for right is in the register
-! originally used for left.
-!
-! parameter 1 first work (left in first round)
-! parameter 2 first use (right in first round)
-! parameter 3 enc/dec 1/-1
-! parameter 4 loop label
-! parameter 5 key address register
-! parameter 6 optional address for key next encryption/decryption
-! parameter 7 not empty for include retl
-!
-! also compares in2 to 8
-
-define(rounds_macro, {
-
-! {rounds_macro}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- xor $2, out0, local1
-
- ld [out2+284], local5 ! 0x0000FC00
- ba $4
- and local1, 252, local1
-
- .align 32
-
-$4:
- ! local6 is address sbox 6
- ! out3 is address sbox 8
- ! out4 is loop counter
-
- ld [global1+local1], local1
- xor $2, out1, out1 ! 8642
- xor $2, out0, out0 ! 7531
- ! fmovs %f0, %f0 ! fxor used for alignment
-
- srl out1, 4, local0 ! rotate 4 right
- and out0, local5, local3 ! 3
- ! fmovs %f0, %f0
-
- ld [$5+$3*8], local7 ! key 7531 next round
- srl local3, 8, local3 ! 3
- and local0, 252, local2 ! 2
- ! fmovs %f0, %f0
-
- ld [global3+local3],local3 ! 3
- sll out1, 28, out1 ! rotate
- xor $1, local1, $1 ! 1 finished, local1 now sbox 7
-
- ld [global2+local2], local2 ! 2
- srl out0, 24, local1 ! 7
- or out1, local0, out1 ! rotate
-
- ldub [out2+local1], local1 ! 7 (and 0xFC)
- srl out1, 24, local0 ! 8
- and out1, local5, local4 ! 4
-
- ldub [out2+local0], local0 ! 8 (and 0xFC)
- srl local4, 8, local4 ! 4
- xor $1, local2, $1 ! 2 finished local2 now sbox 6
-
- ld [global4+local4],local4 ! 4
- srl out1, 16, local2 ! 6
- xor $1, local3, $1 ! 3 finished local3 now sbox 5
-
- ld [out3+local0],local0 ! 8
- and local2, 252, local2 ! 6
- add global1, 1536, local5 ! address sbox 7
-
- ld [local6+local2], local2 ! 6
- srl out0, 16, local3 ! 5
- xor $1, local4, $1 ! 4 finished
-
- ld [local5+local1],local1 ! 7
- and local3, 252, local3 ! 5
- xor $1, local0, $1 ! 8 finished
-
- ld [global5+local3],local3 ! 5
- xor $1, local2, $1 ! 6 finished
- subcc out4, 1, out4
-
- ld [$5+$3*8+4], out0 ! key 8642 next round
- xor $1, local7, local2 ! sbox 5 next round
- xor $1, local1, $1 ! 7 finished
-
- srl local2, 16, local2 ! sbox 5 next round
- xor $1, local3, $1 ! 5 finished
-
- ld [$5+$3*16+4], out1 ! key 8642 next round again
- and local2, 252, local2 ! sbox5 next round
-! next round
- xor $1, local7, local7 ! 7531
-
- ld [global5+local2], local2 ! 5
- srl local7, 24, local3 ! 7
- xor $1, out0, out0 ! 8642
-
- ldub [out2+local3], local3 ! 7 (and 0xFC)
- srl out0, 4, local0 ! rotate 4 right
- and local7, 252, local1 ! 1
-
- sll out0, 28, out0 ! rotate
- xor $2, local2, $2 ! 5 finished local2 used
-
- srl local0, 8, local4 ! 4
- and local0, 252, local2 ! 2
- ld [local5+local3], local3 ! 7
-
- srl local0, 16, local5 ! 6
- or out0, local0, out0 ! rotate
- ld [global2+local2], local2 ! 2
-
- srl out0, 24, local0
- ld [$5+$3*16], out0 ! key 7531 next round
- and local4, 252, local4 ! 4
-
- and local5, 252, local5 ! 6
- ld [global4+local4], local4 ! 4
- xor $2, local3, $2 ! 7 finished local3 used
-
- and local0, 252, local0 ! 8
- ld [local6+local5], local5 ! 6
- xor $2, local2, $2 ! 2 finished local2 now sbox 3
-
- srl local7, 8, local2 ! 3 start
- ld [out3+local0], local0 ! 8
- xor $2, local4, $2 ! 4 finished
-
- and local2, 252, local2 ! 3
- ld [global1+local1], local1 ! 1
- xor $2, local5, $2 ! 6 finished local5 used
-
- ld [global3+local2], local2 ! 3
- xor $2, local0, $2 ! 8 finished
- add $5, $3*16, $5 ! enc add 8, dec add -8 to key pointer
-
- ld [out2+284], local5 ! 0x0000FC00
- xor $2, out0, local4 ! sbox 1 next round
- xor $2, local1, $2 ! 1 finished
-
- xor $2, local2, $2 ! 3 finished
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bne,pt %icc, $4
-#else
- bne $4
-#endif
- and local4, 252, local1 ! sbox 1 next round
-
-! two rounds more:
-
- ld [global1+local1], local1
- xor $2, out1, out1
- xor $2, out0, out0
-
- srl out1, 4, local0 ! rotate
- and out0, local5, local3
-
- ld [$5+$3*8], local7 ! key 7531
- srl local3, 8, local3
- and local0, 252, local2
-
- ld [global3+local3],local3
- sll out1, 28, out1 ! rotate
- xor $1, local1, $1 ! 1 finished, local1 now sbox 7
-
- ld [global2+local2], local2
- srl out0, 24, local1
- or out1, local0, out1 ! rotate
-
- ldub [out2+local1], local1
- srl out1, 24, local0
- and out1, local5, local4
-
- ldub [out2+local0], local0
- srl local4, 8, local4
- xor $1, local2, $1 ! 2 finished local2 now sbox 6
-
- ld [global4+local4],local4
- srl out1, 16, local2
- xor $1, local3, $1 ! 3 finished local3 now sbox 5
-
- ld [out3+local0],local0
- and local2, 252, local2
- add global1, 1536, local5 ! address sbox 7
-
- ld [local6+local2], local2
- srl out0, 16, local3
- xor $1, local4, $1 ! 4 finished
-
- ld [local5+local1],local1
- and local3, 252, local3
- xor $1, local0, $1
-
- ld [global5+local3],local3
- xor $1, local2, $1 ! 6 finished
- cmp in2, 8
-
- ifelse($6,{}, {}, {ld [out2+280], out4}) ! loop counter
- xor $1, local7, local2 ! sbox 5 next round
- xor $1, local1, $1 ! 7 finished
-
- ld [$5+$3*8+4], out0
- srl local2, 16, local2 ! sbox 5 next round
- xor $1, local3, $1 ! 5 finished
-
- and local2, 252, local2
-! next round (two rounds more)
- xor $1, local7, local7 ! 7531
-
- ld [global5+local2], local2
- srl local7, 24, local3
- xor $1, out0, out0 ! 8642
-
- ldub [out2+local3], local3
- srl out0, 4, local0 ! rotate
- and local7, 252, local1
-
- sll out0, 28, out0 ! rotate
- xor $2, local2, $2 ! 5 finished local2 used
-
- srl local0, 8, local4
- and local0, 252, local2
- ld [local5+local3], local3
-
- srl local0, 16, local5
- or out0, local0, out0 ! rotate
- ld [global2+local2], local2
-
- srl out0, 24, local0
- ifelse($6,{}, {}, {ld [$6], out0}) ! key next encryption/decryption
- and local4, 252, local4
-
- and local5, 252, local5
- ld [global4+local4], local4
- xor $2, local3, $2 ! 7 finished local3 used
-
- and local0, 252, local0
- ld [local6+local5], local5
- xor $2, local2, $2 ! 2 finished local2 now sbox 3
-
- srl local7, 8, local2 ! 3 start
- ld [out3+local0], local0
- xor $2, local4, $2
-
- and local2, 252, local2
- ld [global1+local1], local1
- xor $2, local5, $2 ! 6 finished local5 used
-
- ld [global3+local2], local2
- srl $1, 3, local3
- xor $2, local0, $2
-
- ifelse($6,{}, {}, {ld [$6+4], out1}) ! key next encryption/decryption
- sll $1, 29, local4
- xor $2, local1, $2
-
- ifelse($7,{}, {}, {retl})
- xor $2, local2, $2
-})
-
-
-! {fp_macro}
-!
-! parameter 1 right (original left)
-! parameter 2 left (original right)
-! parameter 3 1 for optional store to [in0]
-! parameter 4 1 for load input/output address to local5/7
-!
-! The final permutation logic switches the halfes, meaning that
-! left and right ends up the the registers originally used.
-
-define(fp_macro, {
-
-! {fp_macro}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- ! initially undo the rotate 3 left done after initial permutation
- ! original left is received shifted 3 right and 29 left in local3/4
-
- sll $2, 29, local1
- or local3, local4, $1
-
- srl $2, 3, $2
- sethi %hi(0x55555555), local2
-
- or $2, local1, $2
- or local2, %lo(0x55555555), local2
-
- srl $2, 1, local3
- sethi %hi(0x00ff00ff), local1
- xor local3, $1, local3
- or local1, %lo(0x00ff00ff), local1
- and local3, local2, local3
- sethi %hi(0x33333333), local4
- sll local3, 1, local2
-
- xor $1, local3, $1
-
- srl $1, 8, local3
- xor $2, local2, $2
- xor local3, $2, local3
- or local4, %lo(0x33333333), local4
- and local3, local1, local3
- sethi %hi(0x0000ffff), local1
- sll local3, 8, local2
-
- xor $2, local3, $2
-
- srl $2, 2, local3
- xor $1, local2, $1
- xor local3, $1, local3
- or local1, %lo(0x0000ffff), local1
- and local3, local4, local3
- sethi %hi(0x0f0f0f0f), local4
- sll local3, 2, local2
-
- ifelse($4,1, {LDPTR INPUT, local5})
- xor $1, local3, $1
-
- ifelse($4,1, {LDPTR OUTPUT, local7})
- srl $1, 16, local3
- xor $2, local2, $2
- xor local3, $2, local3
- or local4, %lo(0x0f0f0f0f), local4
- and local3, local1, local3
- sll local3, 16, local2
-
- xor $2, local3, local1
-
- srl local1, 4, local3
- xor $1, local2, $1
- xor local3, $1, local3
- and local3, local4, local3
- sll local3, 4, local2
-
- xor $1, local3, $1
-
- ! optional store:
-
- ifelse($3,1, {st $1, [in0]})
-
- xor local1, local2, $2
-
- ifelse($3,1, {st $2, [in0+4]})
-
-})
-
-
-! {fp_ip_macro}
-!
-! Does initial permutation for next block mixed with
-! final permutation for current block.
-!
-! parameter 1 original left
-! parameter 2 original right
-! parameter 3 left ip
-! parameter 4 right ip
-! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
-! 2: mov in4 to in3
-!
-! also adds -8 to length in2 and loads loop counter to out4
-
-define(fp_ip_macro, {
-
-! {fp_ip_macro}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- define({temp1},{out4})
- define({temp2},{local3})
-
- define({ip1},{local1})
- define({ip2},{local2})
- define({ip4},{local4})
- define({ip5},{local5})
-
- ! $1 in local3, local4
-
- ld [out2+256], ip1
- sll out5, 29, temp1
- or local3, local4, $1
-
- srl out5, 3, $2
- ifelse($5,2,{mov in4, in3})
-
- ld [out2+272], ip5
- srl $4, 4, local0
- or $2, temp1, $2
-
- srl $2, 1, temp1
- xor temp1, $1, temp1
-
- and temp1, ip5, temp1
- xor local0, $3, local0
-
- sll temp1, 1, temp2
- xor $1, temp1, $1
-
- and local0, ip1, local0
- add in2, -8, in2
-
- sll local0, 4, local7
- xor $3, local0, $3
-
- ld [out2+268], ip4
- srl $1, 8, temp1
- xor $2, temp2, $2
- ld [out2+260], ip2
- srl $3, 16, local0
- xor $4, local7, $4
- xor temp1, $2, temp1
- xor local0, $4, local0
- and temp1, ip4, temp1
- and local0, ip2, local0
- sll temp1, 8, temp2
- xor $2, temp1, $2
- sll local0, 16, local7
- xor $4, local0, $4
-
- srl $2, 2, temp1
- xor $1, temp2, $1
-
- ld [out2+264], temp2 ! ip3
- srl $4, 2, local0
- xor $3, local7, $3
- xor temp1, $1, temp1
- xor local0, $3, local0
- and temp1, temp2, temp1
- and local0, temp2, local0
- sll temp1, 2, temp2
- xor $1, temp1, $1
- sll local0, 2, local7
- xor $3, local0, $3
-
- srl $1, 16, temp1
- xor $2, temp2, $2
- srl $3, 8, local0
- xor $4, local7, $4
- xor temp1, $2, temp1
- xor local0, $4, local0
- and temp1, ip2, temp1
- and local0, ip4, local0
- sll temp1, 16, temp2
- xor $2, temp1, local4
- sll local0, 8, local7
- xor $4, local0, $4
-
- srl $4, 1, local0
- xor $3, local7, $3
-
- srl local4, 4, temp1
- xor local0, $3, local0
-
- xor $1, temp2, $1
- and local0, ip5, local0
-
- sll local0, 1, local7
- xor temp1, $1, temp1
-
- xor $3, local0, $3
- xor $4, local7, $4
-
- sll $3, 3, local5
- and temp1, ip1, temp1
-
- sll temp1, 4, temp2
- xor $1, temp1, $1
-
- ifelse($5,1,{LDPTR KS2, in4})
- sll $4, 3, local2
- xor local4, temp2, $2
-
- ! reload since used as temporar:
-
- ld [out2+280], out4 ! loop counter
-
- srl $3, 29, local0
- ifelse($5,1,{add in4, 120, in4})
-
- ifelse($5,1,{LDPTR KS1, in3})
- srl $4, 29, local7
-
- or local0, local5, $4
- or local2, local7, $3
-
-})
-
-
-
-! {load_little_endian}
-!
-! parameter 1 address
-! parameter 2 destination left
-! parameter 3 destination right
-! parameter 4 temporar
-! parameter 5 label
-
-define(load_little_endian, {
-
-! {load_little_endian}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- ! first in memory to rightmost in register
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- andcc $1, 3, global0
- bne,pn %icc, $5
- nop
-
- lda [$1] 0x88, $2
- add $1, 4, $4
-
- ba,pt %icc, $5a
- lda [$4] 0x88, $3
-#endif
-
-$5:
- ldub [$1+3], $2
-
- ldub [$1+2], $4
- sll $2, 8, $2
- or $2, $4, $2
-
- ldub [$1+1], $4
- sll $2, 8, $2
- or $2, $4, $2
-
- ldub [$1+0], $4
- sll $2, 8, $2
- or $2, $4, $2
-
-
- ldub [$1+3+4], $3
-
- ldub [$1+2+4], $4
- sll $3, 8, $3
- or $3, $4, $3
-
- ldub [$1+1+4], $4
- sll $3, 8, $3
- or $3, $4, $3
-
- ldub [$1+0+4], $4
- sll $3, 8, $3
- or $3, $4, $3
-$5a:
-
-})
-
-
-! {load_little_endian_inc}
-!
-! parameter 1 address
-! parameter 2 destination left
-! parameter 3 destination right
-! parameter 4 temporar
-! parameter 4 label
-!
-! adds 8 to address
-
-define(load_little_endian_inc, {
-
-! {load_little_endian_inc}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- ! first in memory to rightmost in register
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- andcc $1, 3, global0
- bne,pn %icc, $5
- nop
-
- lda [$1] 0x88, $2
- add $1, 4, $1
-
- lda [$1] 0x88, $3
- ba,pt %icc, $5a
- add $1, 4, $1
-#endif
-
-$5:
- ldub [$1+3], $2
-
- ldub [$1+2], $4
- sll $2, 8, $2
- or $2, $4, $2
-
- ldub [$1+1], $4
- sll $2, 8, $2
- or $2, $4, $2
-
- ldub [$1+0], $4
- sll $2, 8, $2
- or $2, $4, $2
-
- ldub [$1+3+4], $3
- add $1, 8, $1
-
- ldub [$1+2+4-8], $4
- sll $3, 8, $3
- or $3, $4, $3
-
- ldub [$1+1+4-8], $4
- sll $3, 8, $3
- or $3, $4, $3
-
- ldub [$1+0+4-8], $4
- sll $3, 8, $3
- or $3, $4, $3
-$5a:
-
-})
-
-
-! {load_n_bytes}
-!
-! Loads 1 to 7 bytes little endian
-! Remaining bytes are zeroed.
-!
-! parameter 1 address
-! parameter 2 length
-! parameter 3 destination register left
-! parameter 4 destination register right
-! parameter 5 temp
-! parameter 6 temp2
-! parameter 7 label
-! parameter 8 return label
-
-define(load_n_bytes, {
-
-! {load_n_bytes}
-! $1 $2 $5 $6 $7 $8 $7 $8 $9
-
-$7.0: call .+8
- sll $2, 2, $6
-
- add %o7,$7.jmp.table-$7.0,$5
-
- add $5, $6, $5
- mov 0, $4
-
- ld [$5], $5
-
- jmp %o7+$5
- mov 0, $3
-
-$7.7:
- ldub [$1+6], $5
- sll $5, 16, $5
- or $3, $5, $3
-$7.6:
- ldub [$1+5], $5
- sll $5, 8, $5
- or $3, $5, $3
-$7.5:
- ldub [$1+4], $5
- or $3, $5, $3
-$7.4:
- ldub [$1+3], $5
- sll $5, 24, $5
- or $4, $5, $4
-$7.3:
- ldub [$1+2], $5
- sll $5, 16, $5
- or $4, $5, $4
-$7.2:
- ldub [$1+1], $5
- sll $5, 8, $5
- or $4, $5, $4
-$7.1:
- ldub [$1+0], $5
- ba $8
- or $4, $5, $4
-
- .align 4
-
-$7.jmp.table:
- .word 0
- .word $7.1-$7.0
- .word $7.2-$7.0
- .word $7.3-$7.0
- .word $7.4-$7.0
- .word $7.5-$7.0
- .word $7.6-$7.0
- .word $7.7-$7.0
-})
-
-
-! {store_little_endian}
-!
-! parameter 1 address
-! parameter 2 source left
-! parameter 3 source right
-! parameter 4 temporar
-
-define(store_little_endian, {
-
-! {store_little_endian}
-! $1 $2 $3 $4 $5 $6 $7 $8 $9
-
- ! rightmost in register to first in memory
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- andcc $1, 3, global0
- bne,pn %icc, $5
- nop
-
- sta $2, [$1] 0x88
- add $1, 4, $4
-
- ba,pt %icc, $5a
- sta $3, [$4] 0x88
-#endif
-
-$5:
- and $2, 255, $4
- stub $4, [$1+0]
-
- srl $2, 8, $4
- and $4, 255, $4
- stub $4, [$1+1]
-
- srl $2, 16, $4
- and $4, 255, $4
- stub $4, [$1+2]
-
- srl $2, 24, $4
- stub $4, [$1+3]
-
-
- and $3, 255, $4
- stub $4, [$1+0+4]
-
- srl $3, 8, $4
- and $4, 255, $4
- stub $4, [$1+1+4]
-
- srl $3, 16, $4
- and $4, 255, $4
- stub $4, [$1+2+4]
-
- srl $3, 24, $4
- stub $4, [$1+3+4]
-
-$5a:
-
-})
-
-
-! {store_n_bytes}
-!
-! Stores 1 to 7 bytes little endian
-!
-! parameter 1 address
-! parameter 2 length
-! parameter 3 source register left
-! parameter 4 source register right
-! parameter 5 temp
-! parameter 6 temp2
-! parameter 7 label
-! parameter 8 return label
-
-define(store_n_bytes, {
-
-! {store_n_bytes}
-! $1 $2 $5 $6 $7 $8 $7 $8 $9
-
-$7.0: call .+8
- sll $2, 2, $6
-
- add %o7,$7.jmp.table-$7.0,$5
-
- add $5, $6, $5
-
- ld [$5], $5
-
- jmp %o7+$5
- nop
-
-$7.7:
- srl $3, 16, $5
- and $5, 0xff, $5
- stub $5, [$1+6]
-$7.6:
- srl $3, 8, $5
- and $5, 0xff, $5
- stub $5, [$1+5]
-$7.5:
- and $3, 0xff, $5
- stub $5, [$1+4]
-$7.4:
- srl $4, 24, $5
- stub $5, [$1+3]
-$7.3:
- srl $4, 16, $5
- and $5, 0xff, $5
- stub $5, [$1+2]
-$7.2:
- srl $4, 8, $5
- and $5, 0xff, $5
- stub $5, [$1+1]
-$7.1:
- and $4, 0xff, $5
-
-
- ba $8
- stub $5, [$1]
-
- .align 4
-
-$7.jmp.table:
-
- .word 0
- .word $7.1-$7.0
- .word $7.2-$7.0
- .word $7.3-$7.0
- .word $7.4-$7.0
- .word $7.5-$7.0
- .word $7.6-$7.0
- .word $7.7-$7.0
-})
-
-
-define(testvalue,{1})
-
-define(register_init, {
-
-! For test purposes:
-
- sethi %hi(testvalue), local0
- or local0, %lo(testvalue), local0
-
- ifelse($1,{},{}, {mov local0, $1})
- ifelse($2,{},{}, {mov local0, $2})
- ifelse($3,{},{}, {mov local0, $3})
- ifelse($4,{},{}, {mov local0, $4})
- ifelse($5,{},{}, {mov local0, $5})
- ifelse($6,{},{}, {mov local0, $6})
- ifelse($7,{},{}, {mov local0, $7})
- ifelse($8,{},{}, {mov local0, $8})
-
- mov local0, local1
- mov local0, local2
- mov local0, local3
- mov local0, local4
- mov local0, local5
- mov local0, local7
- mov local0, local6
- mov local0, out0
- mov local0, out1
- mov local0, out2
- mov local0, out3
- mov local0, out4
- mov local0, out5
- mov local0, global1
- mov local0, global2
- mov local0, global3
- mov local0, global4
- mov local0, global5
-
-})
-
-.section ".text"
-
- .align 32
-
-.des_enc:
-
- ! key address in3
- ! loads key next encryption/decryption first round from [in4]
-
- rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl)
-
-
- .align 32
-
-.des_dec:
-
- ! implemented with out5 as first parameter to avoid
- ! register exchange in ede modes
-
- ! key address in4
- ! loads key next encryption/decryption first round from [in3]
-
- rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl)
-
-
-
-! void DES_encrypt1(data, ks, enc)
-! *******************************
-
- .align 32
- .global DES_encrypt1
- .type DES_encrypt1,#function
-
-DES_encrypt1:
-
- save %sp, FRAME, %sp
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- ld [in0], in5 ! left
- cmp in2, 0 ! enc
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- be,pn %icc, .encrypt.dec ! enc/dec
-#else
- be .encrypt.dec
-#endif
- ld [in0+4], out5 ! right
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for move in1 to in3
- ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
-
- ip_macro(in5, out5, in5, out5, in3, 0, 1, 1)
-
- rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used
-
- fp_macro(in5, out5, 1) ! 1 for store to [in0]
-
- ret
- restore
-
-.encrypt.dec:
-
- add in1, 120, in3 ! use last subkey for first round
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for move in1 to in3
- ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
-
- ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec, ks in4
-
- fp_macro(out5, in5, 1) ! 1 for store to [in0]
-
- ret
- restore
-
-.DES_encrypt1.end:
- .size DES_encrypt1,.DES_encrypt1.end-DES_encrypt1
-
-
-! void DES_encrypt2(data, ks, enc)
-!*********************************
-
- ! encrypts/decrypts without initial/final permutation
-
- .align 32
- .global DES_encrypt2
- .type DES_encrypt2,#function
-
-DES_encrypt2:
-
- save %sp, FRAME, %sp
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- ! Set sbox address 1 to 6 and rotate halfs 3 left
- ! Errors caught by destest? Yes. Still? *NO*
-
- !sethi %hi(DES_SPtrans), global1 ! address sbox 1
-
- !or global1, %lo(DES_SPtrans), global1 ! sbox 1
-
- add global1, 256, global2 ! sbox 2
- add global1, 512, global3 ! sbox 3
-
- ld [in0], out5 ! right
- add global1, 768, global4 ! sbox 4
- add global1, 1024, global5 ! sbox 5
-
- ld [in0+4], in5 ! left
- add global1, 1280, local6 ! sbox 6
- add global1, 1792, out3 ! sbox 8
-
- ! rotate
-
- sll in5, 3, local5
- mov in1, in3 ! key address to in3
-
- sll out5, 3, local7
- srl in5, 29, in5
-
- srl out5, 29, out5
- add in5, local5, in5
-
- add out5, local7, out5
- cmp in2, 0
-
- ! we use our own stackframe
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- be,pn %icc, .encrypt2.dec ! decryption
-#else
- be .encrypt2.dec
-#endif
- STPTR in0, [%sp+BIAS+ARG0+0*ARGSZ]
-
- ld [in3], out0 ! key 7531 first round
- mov LOOPS, out4 ! loop counter
-
- ld [in3+4], out1 ! key 8642 first round
- sethi %hi(0x0000FC00), local5
-
- call .des_enc
- mov in3, in4
-
- ! rotate
- sll in5, 29, in0
- srl in5, 3, in5
- sll out5, 29, in1
- add in5, in0, in5
- srl out5, 3, out5
- LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0
- add out5, in1, out5
- st in5, [in0]
- st out5, [in0+4]
-
- ret
- restore
-
-
-.encrypt2.dec:
-
- add in3, 120, in4
-
- ld [in4], out0 ! key 7531 first round
- mov LOOPS, out4 ! loop counter
-
- ld [in4+4], out1 ! key 8642 first round
- sethi %hi(0x0000FC00), local5
-
- mov in5, local1 ! left expected in out5
- mov out5, in5
-
- call .des_dec
- mov local1, out5
-
-.encrypt2.finish:
-
- ! rotate
- sll in5, 29, in0
- srl in5, 3, in5
- sll out5, 29, in1
- add in5, in0, in5
- srl out5, 3, out5
- LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0
- add out5, in1, out5
- st out5, [in0]
- st in5, [in0+4]
-
- ret
- restore
-
-.DES_encrypt2.end:
- .size DES_encrypt2, .DES_encrypt2.end-DES_encrypt2
-
-
-! void DES_encrypt3(data, ks1, ks2, ks3)
-! **************************************
-
- .align 32
- .global DES_encrypt3
- .type DES_encrypt3,#function
-
-DES_encrypt3:
-
- save %sp, FRAME, %sp
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- ld [in0], in5 ! left
- add in2, 120, in4 ! ks2
-
- ld [in0+4], out5 ! right
- mov in3, in2 ! save ks3
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for mov in1 to in3
- ! parameter 8 1 for mov in3 to in4
- ! parameter 9 1 for load ks3 and ks2 to in4 and in3
-
- ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0)
-
- call .des_dec
- mov in2, in3 ! preload ks3
-
- call .des_enc
- nop
-
- fp_macro(in5, out5, 1)
-
- ret
- restore
-
-.DES_encrypt3.end:
- .size DES_encrypt3,.DES_encrypt3.end-DES_encrypt3
-
-
-! void DES_decrypt3(data, ks1, ks2, ks3)
-! **************************************
-
- .align 32
- .global DES_decrypt3
- .type DES_decrypt3,#function
-
-DES_decrypt3:
-
- save %sp, FRAME, %sp
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- ld [in0], in5 ! left
- add in3, 120, in4 ! ks3
-
- ld [in0+4], out5 ! right
- mov in2, in3 ! ks2
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for mov in1 to in3
- ! parameter 8 1 for mov in3 to in4
- ! parameter 9 1 for load ks3 and ks2 to in4 and in3
-
- ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0)
-
- call .des_enc
- add in1, 120, in4 ! preload ks1
-
- call .des_dec
- nop
-
- fp_macro(out5, in5, 1)
-
- ret
- restore
-
-.DES_decrypt3.end:
- .size DES_decrypt3,.DES_decrypt3.end-DES_decrypt3
-
-! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc)
-! *****************************************************************
-
-
- .align 32
- .global DES_ncbc_encrypt
- .type DES_ncbc_encrypt,#function
-
-DES_ncbc_encrypt:
-
- save %sp, FRAME, %sp
-
- define({INPUT}, { [%sp+BIAS+ARG0+0*ARGSZ] })
- define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] })
- define({IVEC}, { [%sp+BIAS+ARG0+4*ARGSZ] })
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- cmp in5, 0 ! enc
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- be,pn %icc, .ncbc.dec
-#else
- be .ncbc.dec
-#endif
- STPTR in4, IVEC
-
- ! addr left right temp label
- load_little_endian(in4, in5, out5, local3, .LLE1) ! iv
-
- addcc in2, -8, in2 ! bytes missing when first block done
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ncbc.enc.seven.or.less
-#else
- bl .ncbc.enc.seven.or.less
-#endif
- mov in3, in4 ! schedule
-
-.ncbc.enc.next.block:
-
- load_little_endian(in0, out4, global4, local3, .LLE2) ! block
-
-.ncbc.enc.next.block_1:
-
- xor in5, out4, in5 ! iv xor
- xor out5, global4, out5 ! iv xor
-
- ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3
- ip_macro(in5, out5, in5, out5, in3, 0, 0, 2)
-
-.ncbc.enc.next.block_2:
-
-!// call .des_enc ! compares in2 to 8
-! rounds inlined for alignment purposes
-
- add global1, 768, global4 ! address sbox 4 since register used below
-
- rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption ks in3
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ncbc.enc.next.block_fp
-#else
- bl .ncbc.enc.next.block_fp
-#endif
- add in0, 8, in0 ! input address
-
- ! If 8 or more bytes are to be encrypted after this block,
- ! we combine final permutation for this block with initial
- ! permutation for next block. Load next block:
-
- load_little_endian(in0, global3, global4, local5, .LLE12)
-
- ! parameter 1 original left
- ! parameter 2 original right
- ! parameter 3 left ip
- ! parameter 4 right ip
- ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
- ! 2: mov in4 to in3
- !
- ! also adds -8 to length in2 and loads loop counter to out4
-
- fp_ip_macro(out0, out1, global3, global4, 2)
-
- store_little_endian(in1, out0, out1, local3, .SLE10) ! block
-
- ld [in3], out0 ! key 7531 first round next block
- mov in5, local1
- xor global3, out5, in5 ! iv xor next block
-
- ld [in3+4], out1 ! key 8642
- add global1, 512, global3 ! address sbox 3 since register used
- xor global4, local1, out5 ! iv xor next block
-
- ba .ncbc.enc.next.block_2
- add in1, 8, in1 ! output adress
-
-.ncbc.enc.next.block_fp:
-
- fp_macro(in5, out5)
-
- store_little_endian(in1, in5, out5, local3, .SLE1) ! block
-
- addcc in2, -8, in2 ! bytes missing when next block done
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bpos,pt %icc, .ncbc.enc.next.block ! also jumps if 0
-#else
- bpos .ncbc.enc.next.block
-#endif
- add in1, 8, in1
-
-.ncbc.enc.seven.or.less:
-
- cmp in2, -8
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- ble,pt %icc, .ncbc.enc.finish
-#else
- ble .ncbc.enc.finish
-#endif
- nop
-
- add in2, 8, local1 ! bytes to load
-
- ! addr, length, dest left, dest right, temp, temp2, label, ret label
- load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1)
-
- ! Loads 1 to 7 bytes little endian to global4, out4
-
-
-.ncbc.enc.finish:
-
- LDPTR IVEC, local4
- store_little_endian(local4, in5, out5, local5, .SLE2) ! ivec
-
- ret
- restore
-
-
-.ncbc.dec:
-
- STPTR in0, INPUT
- cmp in2, 0 ! length
- add in3, 120, in3
-
- LDPTR IVEC, local7 ! ivec
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- ble,pn %icc, .ncbc.dec.finish
-#else
- ble .ncbc.dec.finish
-#endif
- mov in3, in4 ! schedule
-
- STPTR in1, OUTPUT
- mov in0, local5 ! input
-
- load_little_endian(local7, in0, in1, local3, .LLE3) ! ivec
-
-.ncbc.dec.next.block:
-
- load_little_endian(local5, in5, out5, local3, .LLE4) ! block
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for mov in1 to in3
- ! parameter 8 1 for mov in3 to in4
-
- ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion ks in4
-
- fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7
-
- ! in2 is bytes left to be stored
- ! in2 is compared to 8 in the rounds
-
- xor out5, in0, out4 ! iv xor
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ncbc.dec.seven.or.less
-#else
- bl .ncbc.dec.seven.or.less
-#endif
- xor in5, in1, global4 ! iv xor
-
- ! Load ivec next block now, since input and output address might be the same.
-
- load_little_endian_inc(local5, in0, in1, local3, .LLE5) ! iv
-
- store_little_endian(local7, out4, global4, local3, .SLE3)
-
- STPTR local5, INPUT
- add local7, 8, local7
- addcc in2, -8, in2
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bg,pt %icc, .ncbc.dec.next.block
-#else
- bg .ncbc.dec.next.block
-#endif
- STPTR local7, OUTPUT
-
-
-.ncbc.dec.store.iv:
-
- LDPTR IVEC, local4 ! ivec
- store_little_endian(local4, in0, in1, local5, .SLE4)
-
-.ncbc.dec.finish:
-
- ret
- restore
-
-.ncbc.dec.seven.or.less:
-
- load_little_endian_inc(local5, in0, in1, local3, .LLE13) ! ivec
-
- store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv)
-
-
-.DES_ncbc_encrypt.end:
- .size DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt
-
-
-! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc)
-! **************************************************************************
-
-
- .align 32
- .global DES_ede3_cbc_encrypt
- .type DES_ede3_cbc_encrypt,#function
-
-DES_ede3_cbc_encrypt:
-
- save %sp, FRAME, %sp
-
- define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] })
- define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] })
- define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] })
-
- sethi %hi(.PIC.DES_SPtrans-1f),global1
- or global1,%lo(.PIC.DES_SPtrans-1f),global1
-1: call .+8
- add %o7,global1,global1
- sub global1,.PIC.DES_SPtrans-.des_and,out2
-
- LDPTR [%fp+BIAS+ARG0+7*ARGSZ], local3 ! enc
- LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
- cmp local3, 0 ! enc
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- be,pn %icc, .ede3.dec
-#else
- be .ede3.dec
-#endif
- STPTR in4, KS2
-
- STPTR in5, KS3
-
- load_little_endian(local4, in5, out5, local3, .LLE6) ! ivec
-
- addcc in2, -8, in2 ! bytes missing after next block
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ede3.enc.seven.or.less
-#else
- bl .ede3.enc.seven.or.less
-#endif
- STPTR in3, KS1
-
-.ede3.enc.next.block:
-
- load_little_endian(in0, out4, global4, local3, .LLE7)
-
-.ede3.enc.next.block_1:
-
- LDPTR KS2, in4
- xor in5, out4, in5 ! iv xor
- xor out5, global4, out5 ! iv xor
-
- LDPTR KS1, in3
- add in4, 120, in4 ! for decryption we use last subkey first
- nop
-
- ip_macro(in5, out5, in5, out5, in3)
-
-.ede3.enc.next.block_2:
-
- call .des_enc ! ks1 in3
- nop
-
- call .des_dec ! ks2 in4
- LDPTR KS3, in3
-
- call .des_enc ! ks3 in3 compares in2 to 8
- nop
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ede3.enc.next.block_fp
-#else
- bl .ede3.enc.next.block_fp
-#endif
- add in0, 8, in0
-
- ! If 8 or more bytes are to be encrypted after this block,
- ! we combine final permutation for this block with initial
- ! permutation for next block. Load next block:
-
- load_little_endian(in0, global3, global4, local5, .LLE11)
-
- ! parameter 1 original left
- ! parameter 2 original right
- ! parameter 3 left ip
- ! parameter 4 right ip
- ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4
- ! 2: mov in4 to in3
- !
- ! also adds -8 to length in2 and loads loop counter to out4
-
- fp_ip_macro(out0, out1, global3, global4, 1)
-
- store_little_endian(in1, out0, out1, local3, .SLE9) ! block
-
- mov in5, local1
- xor global3, out5, in5 ! iv xor next block
-
- ld [in3], out0 ! key 7531
- add global1, 512, global3 ! address sbox 3
- xor global4, local1, out5 ! iv xor next block
-
- ld [in3+4], out1 ! key 8642
- add global1, 768, global4 ! address sbox 4
- ba .ede3.enc.next.block_2
- add in1, 8, in1
-
-.ede3.enc.next.block_fp:
-
- fp_macro(in5, out5)
-
- store_little_endian(in1, in5, out5, local3, .SLE5) ! block
-
- addcc in2, -8, in2 ! bytes missing when next block done
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bpos,pt %icc, .ede3.enc.next.block
-#else
- bpos .ede3.enc.next.block
-#endif
- add in1, 8, in1
-
-.ede3.enc.seven.or.less:
-
- cmp in2, -8
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- ble,pt %icc, .ede3.enc.finish
-#else
- ble .ede3.enc.finish
-#endif
- nop
-
- add in2, 8, local1 ! bytes to load
-
- ! addr, length, dest left, dest right, temp, temp2, label, ret label
- load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1)
-
-.ede3.enc.finish:
-
- LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
- store_little_endian(local4, in5, out5, local5, .SLE6) ! ivec
-
- ret
- restore
-
-.ede3.dec:
-
- STPTR in0, INPUT
- add in5, 120, in5
-
- STPTR in1, OUTPUT
- mov in0, local5
- add in3, 120, in3
-
- STPTR in3, KS1
- cmp in2, 0
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- ble %icc, .ede3.dec.finish
-#else
- ble .ede3.dec.finish
-#endif
- STPTR in5, KS3
-
- LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local7 ! iv
- load_little_endian(local7, in0, in1, local3, .LLE8)
-
-.ede3.dec.next.block:
-
- load_little_endian(local5, in5, out5, local3, .LLE9)
-
- ! parameter 6 1/2 for include encryption/decryption
- ! parameter 7 1 for mov in1 to in3
- ! parameter 8 1 for mov in3 to in4
- ! parameter 9 1 for load ks3 and ks2 to in4 and in3
-
- ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4
-
- call .des_enc ! ks2 in3
- LDPTR KS1, in4
-
- call .des_dec ! ks1 in4
- nop
-
- fp_macro(out5, in5, 0, 1) ! 1 for input and output address local5/7
-
- ! in2 is bytes left to be stored
- ! in2 is compared to 8 in the rounds
-
- xor out5, in0, out4
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bl,pn %icc, .ede3.dec.seven.or.less
-#else
- bl .ede3.dec.seven.or.less
-#endif
- xor in5, in1, global4
-
- load_little_endian_inc(local5, in0, in1, local3, .LLE10) ! iv next block
-
- store_little_endian(local7, out4, global4, local3, .SLE7) ! block
-
- STPTR local5, INPUT
- addcc in2, -8, in2
- add local7, 8, local7
-
-#ifdef OPENSSL_SYSNAME_ULTRASPARC
- bg,pt %icc, .ede3.dec.next.block
-#else
- bg .ede3.dec.next.block
-#endif
- STPTR local7, OUTPUT
-
-.ede3.dec.store.iv:
-
- LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec
- store_little_endian(local4, in0, in1, local5, .SLE8) ! ivec
-
-.ede3.dec.finish:
-
- ret
- restore
-
-.ede3.dec.seven.or.less:
-
- load_little_endian_inc(local5, in0, in1, local3, .LLE14) ! iv
-
- store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv)
-
-
-.DES_ede3_cbc_encrypt.end:
- .size DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt
-
- .align 256
- .type .des_and,#object
- .size .des_and,284
-
-.des_and:
-
-! This table is used for AND 0xFC when it is known that register
-! bits 8-31 are zero. Makes it possible to do three arithmetic
-! operations in one cycle.
-
- .byte 0, 0, 0, 0, 4, 4, 4, 4
- .byte 8, 8, 8, 8, 12, 12, 12, 12
- .byte 16, 16, 16, 16, 20, 20, 20, 20
- .byte 24, 24, 24, 24, 28, 28, 28, 28
- .byte 32, 32, 32, 32, 36, 36, 36, 36
- .byte 40, 40, 40, 40, 44, 44, 44, 44
- .byte 48, 48, 48, 48, 52, 52, 52, 52
- .byte 56, 56, 56, 56, 60, 60, 60, 60
- .byte 64, 64, 64, 64, 68, 68, 68, 68
- .byte 72, 72, 72, 72, 76, 76, 76, 76
- .byte 80, 80, 80, 80, 84, 84, 84, 84
- .byte 88, 88, 88, 88, 92, 92, 92, 92
- .byte 96, 96, 96, 96, 100, 100, 100, 100
- .byte 104, 104, 104, 104, 108, 108, 108, 108
- .byte 112, 112, 112, 112, 116, 116, 116, 116
- .byte 120, 120, 120, 120, 124, 124, 124, 124
- .byte 128, 128, 128, 128, 132, 132, 132, 132
- .byte 136, 136, 136, 136, 140, 140, 140, 140
- .byte 144, 144, 144, 144, 148, 148, 148, 148
- .byte 152, 152, 152, 152, 156, 156, 156, 156
- .byte 160, 160, 160, 160, 164, 164, 164, 164
- .byte 168, 168, 168, 168, 172, 172, 172, 172
- .byte 176, 176, 176, 176, 180, 180, 180, 180
- .byte 184, 184, 184, 184, 188, 188, 188, 188
- .byte 192, 192, 192, 192, 196, 196, 196, 196
- .byte 200, 200, 200, 200, 204, 204, 204, 204
- .byte 208, 208, 208, 208, 212, 212, 212, 212
- .byte 216, 216, 216, 216, 220, 220, 220, 220
- .byte 224, 224, 224, 224, 228, 228, 228, 228
- .byte 232, 232, 232, 232, 236, 236, 236, 236
- .byte 240, 240, 240, 240, 244, 244, 244, 244
- .byte 248, 248, 248, 248, 252, 252, 252, 252
-
- ! 5 numbers for initil/final permutation
-
- .word 0x0f0f0f0f ! offset 256
- .word 0x0000ffff ! 260
- .word 0x33333333 ! 264
- .word 0x00ff00ff ! 268
- .word 0x55555555 ! 272
-
- .word 0 ! 276
- .word LOOPS ! 280
- .word 0x0000FC00 ! 284
-
- .global DES_SPtrans
- .type DES_SPtrans,#object
- .size DES_SPtrans,2048
-.align 64
-DES_SPtrans:
-.PIC.DES_SPtrans:
- ! nibble 0
- .word 0x02080800, 0x00080000, 0x02000002, 0x02080802
- .word 0x02000000, 0x00080802, 0x00080002, 0x02000002
- .word 0x00080802, 0x02080800, 0x02080000, 0x00000802
- .word 0x02000802, 0x02000000, 0x00000000, 0x00080002
- .word 0x00080000, 0x00000002, 0x02000800, 0x00080800
- .word 0x02080802, 0x02080000, 0x00000802, 0x02000800
- .word 0x00000002, 0x00000800, 0x00080800, 0x02080002
- .word 0x00000800, 0x02000802, 0x02080002, 0x00000000
- .word 0x00000000, 0x02080802, 0x02000800, 0x00080002
- .word 0x02080800, 0x00080000, 0x00000802, 0x02000800
- .word 0x02080002, 0x00000800, 0x00080800, 0x02000002
- .word 0x00080802, 0x00000002, 0x02000002, 0x02080000
- .word 0x02080802, 0x00080800, 0x02080000, 0x02000802
- .word 0x02000000, 0x00000802, 0x00080002, 0x00000000
- .word 0x00080000, 0x02000000, 0x02000802, 0x02080800
- .word 0x00000002, 0x02080002, 0x00000800, 0x00080802
- ! nibble 1
- .word 0x40108010, 0x00000000, 0x00108000, 0x40100000
- .word 0x40000010, 0x00008010, 0x40008000, 0x00108000
- .word 0x00008000, 0x40100010, 0x00000010, 0x40008000
- .word 0x00100010, 0x40108000, 0x40100000, 0x00000010
- .word 0x00100000, 0x40008010, 0x40100010, 0x00008000
- .word 0x00108010, 0x40000000, 0x00000000, 0x00100010
- .word 0x40008010, 0x00108010, 0x40108000, 0x40000010
- .word 0x40000000, 0x00100000, 0x00008010, 0x40108010
- .word 0x00100010, 0x40108000, 0x40008000, 0x00108010
- .word 0x40108010, 0x00100010, 0x40000010, 0x00000000
- .word 0x40000000, 0x00008010, 0x00100000, 0x40100010
- .word 0x00008000, 0x40000000, 0x00108010, 0x40008010
- .word 0x40108000, 0x00008000, 0x00000000, 0x40000010
- .word 0x00000010, 0x40108010, 0x00108000, 0x40100000
- .word 0x40100010, 0x00100000, 0x00008010, 0x40008000
- .word 0x40008010, 0x00000010, 0x40100000, 0x00108000
- ! nibble 2
- .word 0x04000001, 0x04040100, 0x00000100, 0x04000101
- .word 0x00040001, 0x04000000, 0x04000101, 0x00040100
- .word 0x04000100, 0x00040000, 0x04040000, 0x00000001
- .word 0x04040101, 0x00000101, 0x00000001, 0x04040001
- .word 0x00000000, 0x00040001, 0x04040100, 0x00000100
- .word 0x00000101, 0x04040101, 0x00040000, 0x04000001
- .word 0x04040001, 0x04000100, 0x00040101, 0x04040000
- .word 0x00040100, 0x00000000, 0x04000000, 0x00040101
- .word 0x04040100, 0x00000100, 0x00000001, 0x00040000
- .word 0x00000101, 0x00040001, 0x04040000, 0x04000101
- .word 0x00000000, 0x04040100, 0x00040100, 0x04040001
- .word 0x00040001, 0x04000000, 0x04040101, 0x00000001
- .word 0x00040101, 0x04000001, 0x04000000, 0x04040101
- .word 0x00040000, 0x04000100, 0x04000101, 0x00040100
- .word 0x04000100, 0x00000000, 0x04040001, 0x00000101
- .word 0x04000001, 0x00040101, 0x00000100, 0x04040000
- ! nibble 3
- .word 0x00401008, 0x10001000, 0x00000008, 0x10401008
- .word 0x00000000, 0x10400000, 0x10001008, 0x00400008
- .word 0x10401000, 0x10000008, 0x10000000, 0x00001008
- .word 0x10000008, 0x00401008, 0x00400000, 0x10000000
- .word 0x10400008, 0x00401000, 0x00001000, 0x00000008
- .word 0x00401000, 0x10001008, 0x10400000, 0x00001000
- .word 0x00001008, 0x00000000, 0x00400008, 0x10401000
- .word 0x10001000, 0x10400008, 0x10401008, 0x00400000
- .word 0x10400008, 0x00001008, 0x00400000, 0x10000008
- .word 0x00401000, 0x10001000, 0x00000008, 0x10400000
- .word 0x10001008, 0x00000000, 0x00001000, 0x00400008
- .word 0x00000000, 0x10400008, 0x10401000, 0x00001000
- .word 0x10000000, 0x10401008, 0x00401008, 0x00400000
- .word 0x10401008, 0x00000008, 0x10001000, 0x00401008
- .word 0x00400008, 0x00401000, 0x10400000, 0x10001008
- .word 0x00001008, 0x10000000, 0x10000008, 0x10401000
- ! nibble 4
- .word 0x08000000, 0x00010000, 0x00000400, 0x08010420
- .word 0x08010020, 0x08000400, 0x00010420, 0x08010000
- .word 0x00010000, 0x00000020, 0x08000020, 0x00010400
- .word 0x08000420, 0x08010020, 0x08010400, 0x00000000
- .word 0x00010400, 0x08000000, 0x00010020, 0x00000420
- .word 0x08000400, 0x00010420, 0x00000000, 0x08000020
- .word 0x00000020, 0x08000420, 0x08010420, 0x00010020
- .word 0x08010000, 0x00000400, 0x00000420, 0x08010400
- .word 0x08010400, 0x08000420, 0x00010020, 0x08010000
- .word 0x00010000, 0x00000020, 0x08000020, 0x08000400
- .word 0x08000000, 0x00010400, 0x08010420, 0x00000000
- .word 0x00010420, 0x08000000, 0x00000400, 0x00010020
- .word 0x08000420, 0x00000400, 0x00000000, 0x08010420
- .word 0x08010020, 0x08010400, 0x00000420, 0x00010000
- .word 0x00010400, 0x08010020, 0x08000400, 0x00000420
- .word 0x00000020, 0x00010420, 0x08010000, 0x08000020
- ! nibble 5
- .word 0x80000040, 0x00200040, 0x00000000, 0x80202000
- .word 0x00200040, 0x00002000, 0x80002040, 0x00200000
- .word 0x00002040, 0x80202040, 0x00202000, 0x80000000
- .word 0x80002000, 0x80000040, 0x80200000, 0x00202040
- .word 0x00200000, 0x80002040, 0x80200040, 0x00000000
- .word 0x00002000, 0x00000040, 0x80202000, 0x80200040
- .word 0x80202040, 0x80200000, 0x80000000, 0x00002040
- .word 0x00000040, 0x00202000, 0x00202040, 0x80002000
- .word 0x00002040, 0x80000000, 0x80002000, 0x00202040
- .word 0x80202000, 0x00200040, 0x00000000, 0x80002000
- .word 0x80000000, 0x00002000, 0x80200040, 0x00200000
- .word 0x00200040, 0x80202040, 0x00202000, 0x00000040
- .word 0x80202040, 0x00202000, 0x00200000, 0x80002040
- .word 0x80000040, 0x80200000, 0x00202040, 0x00000000
- .word 0x00002000, 0x80000040, 0x80002040, 0x80202000
- .word 0x80200000, 0x00002040, 0x00000040, 0x80200040
- ! nibble 6
- .word 0x00004000, 0x00000200, 0x01000200, 0x01000004
- .word 0x01004204, 0x00004004, 0x00004200, 0x00000000
- .word 0x01000000, 0x01000204, 0x00000204, 0x01004000
- .word 0x00000004, 0x01004200, 0x01004000, 0x00000204
- .word 0x01000204, 0x00004000, 0x00004004, 0x01004204
- .word 0x00000000, 0x01000200, 0x01000004, 0x00004200
- .word 0x01004004, 0x00004204, 0x01004200, 0x00000004
- .word 0x00004204, 0x01004004, 0x00000200, 0x01000000
- .word 0x00004204, 0x01004000, 0x01004004, 0x00000204
- .word 0x00004000, 0x00000200, 0x01000000, 0x01004004
- .word 0x01000204, 0x00004204, 0x00004200, 0x00000000
- .word 0x00000200, 0x01000004, 0x00000004, 0x01000200
- .word 0x00000000, 0x01000204, 0x01000200, 0x00004200
- .word 0x00000204, 0x00004000, 0x01004204, 0x01000000
- .word 0x01004200, 0x00000004, 0x00004004, 0x01004204
- .word 0x01000004, 0x01004200, 0x01004000, 0x00004004
- ! nibble 7
- .word 0x20800080, 0x20820000, 0x00020080, 0x00000000
- .word 0x20020000, 0x00800080, 0x20800000, 0x20820080
- .word 0x00000080, 0x20000000, 0x00820000, 0x00020080
- .word 0x00820080, 0x20020080, 0x20000080, 0x20800000
- .word 0x00020000, 0x00820080, 0x00800080, 0x20020000
- .word 0x20820080, 0x20000080, 0x00000000, 0x00820000
- .word 0x20000000, 0x00800000, 0x20020080, 0x20800080
- .word 0x00800000, 0x00020000, 0x20820000, 0x00000080
- .word 0x00800000, 0x00020000, 0x20000080, 0x20820080
- .word 0x00020080, 0x20000000, 0x00000000, 0x00820000
- .word 0x20800080, 0x20020080, 0x20020000, 0x00800080
- .word 0x20820000, 0x00000080, 0x00800080, 0x20020000
- .word 0x20820080, 0x00800000, 0x20800000, 0x20000080
- .word 0x00820000, 0x00020080, 0x20020080, 0x20800000
- .word 0x00000080, 0x20820000, 0x00820080, 0x00000000
- .word 0x20000000, 0x20800080, 0x00020000, 0x00820080
-
diff --git a/thirdparty/openssl/crypto/des/des-lib.com b/thirdparty/openssl/crypto/des/des-lib.com
deleted file mode 100644
index 348f1c0470..0000000000
--- a/thirdparty/openssl/crypto/des/des-lib.com
+++ /dev/null
@@ -1,1005 +0,0 @@
-$!
-$! DES-LIB.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$!
-$! This command files compiles and creates the
-$! "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" library. The "xxx" denotes the machine
-$! architecture of ALPHA, IA64 or VAX.
-$!
-$! It was re-written to try to determine which "C" compiler to try to use
-$! or the user can specify a compiler in P3.
-$!
-$! Specify one of the following to build just that part, specify "ALL" to
-$! just build everything.
-$!
-$! ALL To Just Build "Everything".
-$! LIBRARY To Just Build The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library.
-$! DESTEST To Just Build The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program.
-$! SPEED To Just Build The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program.
-$! RPW To Just Build The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program.
-$! DES To Just Build The [.xxx.EXE.CRYPTO.DES]DES.EXE Program.
-$! DES_OPTS To Just Build The [.xxx.EXE.CRYPTO.DES]DES_OPTS.EXE Program.
-$!
-$! Specify either DEBUG or NODEBUG as P2 to compile with or without
-$! debugging information.
-$!
-$! Specify which compiler at P3 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't speficy a compiler, it will try to determine which
-$! "C" compiler to try to use.
-$!
-$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$!
-$! Make sure we know what architecture we run on.
-$!
-$!
-$! Check Which Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX
-$!
-$ ARCH := VAX
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$! Define The OBJ Directory Name.
-$!
-$ OBJ_DIR := SYS$DISK:[--.'ARCH'.OBJ.CRYPTO.DES]
-$!
-$! Define The EXE Directory Name.
-$!
-$ EXE_DIR :== SYS$DISK:[--.'ARCH'.EXE.CRYPTO.DES]
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine."
-$!
-$! Check To See If The Architecture Specific OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'OBJ_DIR'
-$!
-$! End The Architecture Specific OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The Architecture Specific Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'EXE_DIR'
-$!
-$! End The Architecture Specific Directory Check.
-$!
-$ ENDIF
-$!
-$! Define The Library Name.
-$!
-$ LIB_NAME := 'EXE_DIR'LIBDES.OLB
-$!
-$! Check To See What We Are To Do.
-$!
-$ IF (BUILDALL.EQS."TRUE")
-$ THEN
-$!
-$! Since Nothing Special Was Specified, Do Everything.
-$!
-$ GOSUB LIBRARY
-$ GOSUB DESTEST
-$ GOSUB SPEED
-$ GOSUB RPW
-$ GOSUB DES
-$ GOSUB DES_OPTS
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Build Just What The User Wants Us To Build.
-$!
-$ GOSUB 'BUILDALL'
-$!
-$! End The BUILDALL Check.
-$!
-$ ENDIF
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$ LIBRARY:
-$!
-$! Tell The User That We Are Compiling.
-$!
-$ WRITE SYS$OUTPUT "Compiling The ",LIB_NAME," Files."
-$!
-$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" Library...
-$!
-$ IF (F$SEARCH(LIB_NAME).EQS."")
-$ THEN
-$!
-$! Guess Not, Create The Library.
-$!
-$ LIBRARY/CREATE/OBJECT 'LIB_NAME'
-$!
-$! End The Library Exist Check.
-$!
-$ ENDIF
-$!
-$! Define The DES Library Files.
-$!
-$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ -
- "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ -
- "enc_read,enc_writ,ofb64enc,"+ -
- "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ -
- "des_enc,fcrypt_b,read2pwd,"+ -
- "fcrypt,xcbc_enc,read_pwd,rpc_enc,cbc_cksm,supp"
-$!
-$! Define A File Counter And Set It To "0".
-$!
-$ FILE_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_DES)
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
-$!
-$! Tell The User We Are Compiling The Source File.
-$!
-$ WRITE SYS$OUTPUT " ",FILE_NAME,".C"
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + FILE_NAME + "." + ARCH + "OBJ"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The File Exists Check.
-$!
-$ ENDIF
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$!
-$! Add It To The Library.
-$!
-$ LIBRARY/REPLACE/OBJECT 'LIB_NAME' 'OBJECT_FILE'
-$!
-$! Time To Clean Up The Object File.
-$!
-$ DELETE 'OBJECT_FILE';*
-$!
-$! Go Back And Do It Again.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library Part.
-$!
-$ FILE_DONE:
-$!
-$! Tell The User That We Are All Done.
-$!
-$ WRITE SYS$OUTPUT "Library ",LIB_NAME," Built."
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$!
-$! Compile The DESTEST Program.
-$!
-$ DESTEST:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]DESTEST.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File DESTEST.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The DESTEST.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DESTEST.EXE"
-$!
-$! Compile The DESTEST Program.
-$!
-$ CC/OBJECT='OBJ_DIR'DESTEST.OBJ SYS$DISK:[]DESTEST.C
-$!
-$! Link The DESTEST Program.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DESTEST.EXE -
- 'OBJ_DIR'DESTEST.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$!
-$! Compile The SPEED Program.
-$!
-$ SPEED:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]SPEED.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File SPEED.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The SPEED.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"SPEED.EXE"
-$!
-$! Compile The SPEED Program.
-$!
-$ CC/OBJECT='OBJ_DIR'SPEED.OBJ SYS$DISK:[]SPEED.C
-$!
-$! Link The SPEED Program.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'SPEED.EXE -
- 'OBJ_DIR'SPEED.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$!
-$! Compile The RPW Program.
-$!
-$ RPW:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]RPW.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File RPW.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The RPW.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"RPW.EXE"
-$!
-$! Compile The RPW Program.
-$!
-$ CC/OBJECT='OBJ_DIR'RPW.OBJ SYS$DISK:[]RPW.C
-$!
-$! Link The RPW Program.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'RPW.EXE -
- 'OBJ_DIR'RPW.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$!
-$! Compile The DES Program.
-$!
-$ DES:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]DES.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File DES.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The DES.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES.EXE"
-$!
-$! Compile The DES Program.
-$!
-$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]DES.C
-$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]CBC3_ENC.C
-$!
-$! Link The DES Program.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES.EXE -
- 'OBJ_DIR'DES.OBJ,'OBJ_DIR'CBC3_ENC.OBJ,-
- 'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$!
-$! Compile The DES_OPTS Program.
-$!
-$ DES_OPTS:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Actually Exists.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]DES_OPTS.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File DES_OPTS.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The DES_OPTS.C File Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What We Are Building.
-$!
-$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES_OPTS.EXE"
-$!
-$! Compile The DES_OPTS Program.
-$!
-$ CC/OBJECT='OBJ_DIR'DES_OPTS.OBJ SYS$DISK:[]DES_OPTS.C
-$!
-$! Link The DES_OPTS Program.
-$!
-$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES_OPTS.EXE -
- 'OBJ_DIR'DES_OPTS.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION
-$!
-$! All Done, Time To Return.
-$!
-$ RETURN
-$ EXIT
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need An non-VAX Or A VAX Linker Option File.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Agianst
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Agianst
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$!
-$! Library Check.
-$!
-$ LIB_CHECK:
-$!
-$! Look For The Library LIBDES.OLB.
-$!
-$ IF (F$SEARCH(LIB_NAME).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The [.xxx.CRYPTO.DES]LIBDES.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",LIB_NAME,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If We Are To "Just Build Everything".
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is "ALL", So Build Everything.
-$!
-$ BUILDALL = "TRUE"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."DESTEST").OR.(P1.EQS."SPEED") -
- .OR.(P1.EQS."RPW").OR.(P1.EQS."DES").OR.(P1.EQS."DES_OPTS")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library."
-$ WRITE SYS$OUTPUT " DESTEST : To Compile Just The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program."
-$ WRITE SYS$OUTPUT " SPEED : To Compile Just The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program."
-$ WRITE SYS$OUTPUT " RPW : To Compile Just The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program."
-$ WRITE SYS$OUTPUT " DES : To Compile Just The [.xxx.EXE.CRYPTO.DES]DES.EXE Program."
-$ WRITE SYS$OUTPUT " DES_OPTS : To Compile Just The [.xxx.EXE.CRYTPO.DES]DES_OPTS.EXE Program."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For: "
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Compile Without Debugger Information.
-$!
-$ IF (P2.EQS."NODEBUG")
-$ THEN
-$!
-$! P2 Is Blank, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P2.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option..
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later.
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN := ""
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P4 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P3 = "GNUC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P3 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P3 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = ""
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = ""
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN -
- CCDISABLEWARNINGS = USER_CCDISABLEWARNINGS
-$!
-$! Check To See If The User Entered A Valid Paramter.
-$!
-$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P3.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + -
- "/NOLIST/PREFIX=ALL" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P3.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
-$ CCDEFS = """VAXC""," + CCDEFS
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P3.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ ENDIF
-$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$!
-$! Show user the result
-$!
-$ WRITE SYS$OUTPUT "Main Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The P3 Check.
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
diff --git a/thirdparty/openssl/crypto/des/des.c b/thirdparty/openssl/crypto/des/des.c
index 586aed7237..d7374382d8 100644
--- a/thirdparty/openssl/crypto/des/des.c
+++ b/thirdparty/openssl/crypto/des/des.c
@@ -456,7 +456,7 @@ void doencryption(void)
len = l - rem;
if (feof(DES_IN)) {
for (i = 7 - rem; i > 0; i--) {
- if (RAND_pseudo_bytes(buf + l++, 1) < 0)
+ if (RAND_bytes(buf + l++, 1) <= 0)
goto problems;
}
buf[l++] = rem;
diff --git a/thirdparty/openssl/crypto/des/enc_writ.c b/thirdparty/openssl/crypto/des/enc_writ.c
index bfaabde516..c2aaa8e98c 100644
--- a/thirdparty/openssl/crypto/des/enc_writ.c
+++ b/thirdparty/openssl/crypto/des/enc_writ.c
@@ -135,7 +135,7 @@ int DES_enc_write(int fd, const void *_buf, int len,
if (len < 8) {
cp = shortbuf;
memcpy(shortbuf, buf, len);
- if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) {
+ if (RAND_bytes(shortbuf + len, 8 - len) <= 0) {
return -1;
}
rnum = 8;
diff --git a/thirdparty/openssl/crypto/des/makefile.bc b/thirdparty/openssl/crypto/des/makefile.bc
deleted file mode 100644
index 1fe6d4915a..0000000000
--- a/thirdparty/openssl/crypto/des/makefile.bc
+++ /dev/null
@@ -1,50 +0,0 @@
-#
-# Origional BC Makefile from Teun <Teun.Nijssen@kub.nl>
-#
-#
-CC = bcc
-TLIB = tlib /0 /C
-# note: the -3 flag produces code for 386, 486, Pentium etc; omit it for 286s
-OPTIMIZE= -3 -O2
-#WINDOWS= -W
-CFLAGS = -c -ml -d $(OPTIMIZE) $(WINDOWS) -DMSDOS
-LFLAGS = -ml $(WINDOWS)
-
-.c.obj:
- $(CC) $(CFLAGS) $*.c
-
-.obj.exe:
- $(CC) $(LFLAGS) -e$*.exe $*.obj libdes.lib
-
-all: $(LIB) destest.exe rpw.exe des.exe speed.exe
-
-# "make clean": use a directory containing only libdes .exe and .obj files...
-clean:
- del *.exe
- del *.obj
- del libdes.lib
- del libdes.rsp
-
-OBJS= cbc_cksm.obj cbc_enc.obj ecb_enc.obj pcbc_enc.obj \
- qud_cksm.obj rand_key.obj set_key.obj str2key.obj \
- enc_read.obj enc_writ.obj fcrypt.obj cfb_enc.obj \
- ecb3_enc.obj ofb_enc.obj cbc3_enc.obj read_pwd.obj\
- cfb64enc.obj ofb64enc.obj ede_enc.obj cfb64ede.obj\
- ofb64ede.obj supp.obj
-
-LIB= libdes.lib
-
-$(LIB): $(OBJS)
- del $(LIB)
- makersp "+%s &\n" &&|
- $(OBJS)
-| >libdes.rsp
- $(TLIB) libdes.lib @libdes.rsp,nul
- del libdes.rsp
-
-destest.exe: destest.obj libdes.lib
-rpw.exe: rpw.obj libdes.lib
-speed.exe: speed.obj libdes.lib
-des.exe: des.obj libdes.lib
-
-
diff --git a/thirdparty/openssl/crypto/des/set_key.c b/thirdparty/openssl/crypto/des/set_key.c
index 8fd8fe14bb..d9c5e7fcb3 100644
--- a/thirdparty/openssl/crypto/des/set_key.c
+++ b/thirdparty/openssl/crypto/des/set_key.c
@@ -120,7 +120,7 @@ int DES_check_key_parity(const_DES_cblock *key)
}
/*-
- * Weak and semi week keys as take from
+ * Weak and semi weak keys as taken from
* %A D.W. Davies
* %A W.L. Price
* %T Security for Computer Networks
diff --git a/thirdparty/openssl/crypto/des/t/test b/thirdparty/openssl/crypto/des/t/test
deleted file mode 100644
index 97acd0552e..0000000000
--- a/thirdparty/openssl/crypto/des/t/test
+++ /dev/null
@@ -1,27 +0,0 @@
-#!./perl
-
-BEGIN { push(@INC, qw(../../../lib ../../lib ../lib lib)); }
-
-use DES;
-
-$key='00000000';
-$ks=DES::set_key($key);
-@a=split(//,$ks);
-foreach (@a) { printf "%02x-",ord($_); }
-print "\n";
-
-
-$key=DES::random_key();
-print "($_)\n";
-@a=split(//,$key);
-foreach (@a) { printf "%02x-",ord($_); }
-print "\n";
-$str="this is and again into the breach";
-($k1,$k2)=DES::string_to_2keys($str);
-@a=split(//,$k1);
-foreach (@a) { printf "%02x-",ord($_); }
-print "\n";
-@a=split(//,$k2);
-foreach (@a) { printf "%02x-",ord($_); }
-print "\n";
-
diff --git a/thirdparty/openssl/crypto/des/times/486-50.sol b/thirdparty/openssl/crypto/des/times/486-50.sol
deleted file mode 100644
index 0de62d6db3..0000000000
--- a/thirdparty/openssl/crypto/des/times/486-50.sol
+++ /dev/null
@@ -1,16 +0,0 @@
-Solaris 2.4, 486 50mhz, gcc 2.6.3
-options des ecb/s
-16 r2 i 43552.51 100.0%
-16 r1 i 43487.45 99.9%
-16 c p 43003.23 98.7%
-16 r2 p 42339.00 97.2%
-16 c i 41900.91 96.2%
-16 r1 p 41360.64 95.0%
- 4 c i 38728.48 88.9%
- 4 c p 38225.63 87.8%
- 4 r1 i 38085.79 87.4%
- 4 r2 i 37825.64 86.9%
- 4 r2 p 34611.00 79.5%
- 4 r1 p 31802.00 73.0%
--DDES_UNROLL -DDES_RISC2
-
diff --git a/thirdparty/openssl/crypto/des/times/586-100.lnx b/thirdparty/openssl/crypto/des/times/586-100.lnx
deleted file mode 100644
index 4323914a11..0000000000
--- a/thirdparty/openssl/crypto/des/times/586-100.lnx
+++ /dev/null
@@ -1,20 +0,0 @@
-Pentium 100
-Linux 2 kernel
-gcc 2.7.0 -O3 -fomit-frame-pointer
-No X server running, just a console, it makes the top speed jump from 151,000
-to 158,000 :-).
-options des ecb/s
-assember 281000.00 177.1%
-16 r1 p 158667.40 100.0%
-16 r1 i 148471.70 93.6%
-16 r2 p 143961.80 90.7%
-16 r2 i 141689.20 89.3%
- 4 r1 i 140100.00 88.3%
- 4 r2 i 134049.40 84.5%
-16 c i 124145.20 78.2%
-16 c p 121584.20 76.6%
- 4 c i 118116.00 74.4%
- 4 r2 p 117977.90 74.4%
- 4 c p 114971.40 72.5%
- 4 r1 p 114578.40 72.2%
--DDES_UNROLL -DDES_RISC1 -DDES_PTR
diff --git a/thirdparty/openssl/crypto/des/times/686-200.fre b/thirdparty/openssl/crypto/des/times/686-200.fre
deleted file mode 100644
index 7d83f6adee..0000000000
--- a/thirdparty/openssl/crypto/des/times/686-200.fre
+++ /dev/null
@@ -1,18 +0,0 @@
-Pentium 100
-Free BSD 2.1.5 kernel
-gcc 2.7.2.2 -O3 -fomit-frame-pointer
-options des ecb/s
-assember 578000.00 133.1%
-16 r2 i 434454.80 100.0%
-16 r1 i 433621.43 99.8%
-16 r2 p 431375.69 99.3%
- 4 r1 i 423722.30 97.5%
- 4 r2 i 422399.40 97.2%
-16 r1 p 421739.40 97.1%
-16 c i 399027.94 91.8%
-16 c p 372251.70 85.7%
- 4 c i 365118.35 84.0%
- 4 c p 352880.51 81.2%
- 4 r2 p 255104.90 58.7%
- 4 r1 p 251289.18 57.8%
--DDES_UNROLL -DDES_RISC2
diff --git a/thirdparty/openssl/crypto/des/times/sparc.gcc b/thirdparty/openssl/crypto/des/times/sparc.gcc
deleted file mode 100644
index 8eaa042104..0000000000
--- a/thirdparty/openssl/crypto/des/times/sparc.gcc
+++ /dev/null
@@ -1,17 +0,0 @@
-solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2
-
-options des ecb/s
-16 c i 124382.70 100.0%
- 4 c i 118884.68 95.6%
-16 c p 112261.20 90.3%
-16 r2 i 111777.10 89.9%
-16 r2 p 108896.30 87.5%
-16 r1 p 108791.59 87.5%
- 4 c p 107290.10 86.3%
- 4 r1 p 104583.80 84.1%
-16 r1 i 104206.20 83.8%
- 4 r2 p 103709.80 83.4%
- 4 r2 i 98306.43 79.0%
- 4 r1 i 91525.80 73.6%
--DDES_UNROLL
-
diff --git a/thirdparty/openssl/crypto/dh/dh_ameth.c b/thirdparty/openssl/crypto/dh/dh_ameth.c
index ac72468bd1..4558283576 100644
--- a/thirdparty/openssl/crypto/dh/dh_ameth.c
+++ b/thirdparty/openssl/crypto/dh/dh_ameth.c
@@ -519,7 +519,7 @@ static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
static int dh_missing_parameters(const EVP_PKEY *a)
{
- if (!a->pkey.dh->p || !a->pkey.dh->g)
+ if (a->pkey.dh == NULL || a->pkey.dh->p == NULL || a->pkey.dh->g == NULL)
return 1;
return 0;
}
diff --git a/thirdparty/openssl/crypto/dh/dh_key.c b/thirdparty/openssl/crypto/dh/dh_key.c
index 1d80fb2c5f..387558f146 100644
--- a/thirdparty/openssl/crypto/dh/dh_key.c
+++ b/thirdparty/openssl/crypto/dh/dh_key.c
@@ -223,6 +223,8 @@ static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
goto err;
BN_CTX_start(ctx);
tmp = BN_CTX_get(ctx);
+ if (tmp == NULL)
+ goto err;
if (dh->priv_key == NULL) {
DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE);
diff --git a/thirdparty/openssl/crypto/dsa/dsa_ameth.c b/thirdparty/openssl/crypto/dsa/dsa_ameth.c
index cc83d6e6ad..c4fa105747 100644
--- a/thirdparty/openssl/crypto/dsa/dsa_ameth.c
+++ b/thirdparty/openssl/crypto/dsa/dsa_ameth.c
@@ -350,7 +350,7 @@ static int dsa_missing_parameters(const EVP_PKEY *pkey)
{
DSA *dsa;
dsa = pkey->pkey.dsa;
- if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+ if (dsa == NULL || dsa->p == NULL || dsa->q == NULL || dsa->g == NULL)
return 1;
return 0;
}
diff --git a/thirdparty/openssl/crypto/dsa/dsa_gen.c b/thirdparty/openssl/crypto/dsa/dsa_gen.c
index 15f3bb4f3f..1fce0f81c2 100644
--- a/thirdparty/openssl/crypto/dsa/dsa_gen.c
+++ b/thirdparty/openssl/crypto/dsa/dsa_gen.c
@@ -185,6 +185,9 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
p = BN_CTX_get(ctx);
test = BN_CTX_get(ctx);
+ if (test == NULL)
+ goto err;
+
if (!BN_lshift(test, BN_value_one(), bits - 1))
goto err;
@@ -197,7 +200,7 @@ int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits,
goto err;
if (!seed_len || !seed_in) {
- if (RAND_pseudo_bytes(seed, qsize) < 0)
+ if (RAND_bytes(seed, qsize) <= 0)
goto err;
seed_is_random = 1;
} else {
@@ -491,7 +494,7 @@ int dsa_builtin_paramgen2(DSA *ret, size_t L, size_t N,
goto err;
if (!seed_in) {
- if (RAND_pseudo_bytes(seed, seed_len) < 0)
+ if (RAND_bytes(seed, seed_len) <= 0)
goto err;
}
/* step 2 */
diff --git a/thirdparty/openssl/crypto/dsa/dsa_ossl.c b/thirdparty/openssl/crypto/dsa/dsa_ossl.c
index efc4f1b6ae..58013a4a13 100644
--- a/thirdparty/openssl/crypto/dsa/dsa_ossl.c
+++ b/thirdparty/openssl/crypto/dsa/dsa_ossl.c
@@ -247,11 +247,13 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
do
if (!BN_rand_range(&k, dsa->q))
goto err;
- while (BN_is_zero(&k)) ;
+ while (BN_is_zero(&k));
+
if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) {
BN_set_flags(&k, BN_FLG_CONSTTIME);
}
+
if (dsa->flags & DSA_FLAG_CACHE_MONT_P) {
if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p,
CRYPTO_LOCK_DSA, dsa->p, ctx))
@@ -264,6 +266,8 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
if (!BN_copy(&kq, &k))
goto err;
+ BN_set_flags(&kq, BN_FLG_CONSTTIME);
+
/*
* We do not want timing information to leak the length of k, so we
* compute g^k using an equivalent exponent of fixed length. (This
@@ -282,6 +286,7 @@ static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
} else {
K = &k;
}
+
DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx,
dsa->method_mont_p);
if (!BN_mod(r, r, dsa->q, ctx))
diff --git a/thirdparty/openssl/crypto/dsa/dsa_pmeth.c b/thirdparty/openssl/crypto/dsa/dsa_pmeth.c
index 42b8bb0862..78724839b5 100644
--- a/thirdparty/openssl/crypto/dsa/dsa_pmeth.c
+++ b/thirdparty/openssl/crypto/dsa/dsa_pmeth.c
@@ -180,7 +180,7 @@ static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE);
return 0;
}
- dctx->md = p2;
+ dctx->pmd = p2;
return 1;
case EVP_PKEY_CTRL_MD:
diff --git a/thirdparty/openssl/crypto/ec/ec2_mult.c b/thirdparty/openssl/crypto/ec/ec2_mult.c
index 68cc8771d5..1f9cc00aea 100644
--- a/thirdparty/openssl/crypto/ec/ec2_mult.c
+++ b/thirdparty/openssl/crypto/ec/ec2_mult.c
@@ -267,7 +267,7 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
BN_CTX *ctx)
{
BIGNUM *x1, *x2, *z1, *z2;
- int ret = 0, i;
+ int ret = 0, i, group_top;
BN_ULONG mask, word;
if (r == point) {
@@ -297,10 +297,12 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
x2 = &r->X;
z2 = &r->Y;
- bn_wexpand(x1, group->field.top);
- bn_wexpand(z1, group->field.top);
- bn_wexpand(x2, group->field.top);
- bn_wexpand(z2, group->field.top);
+ group_top = group->field.top;
+ if (bn_wexpand(x1, group_top) == NULL
+ || bn_wexpand(z1, group_top) == NULL
+ || bn_wexpand(x2, group_top) == NULL
+ || bn_wexpand(z2, group_top) == NULL)
+ goto err;
if (!BN_GF2m_mod_arr(x1, &point->X, group->poly))
goto err; /* x1 = x */
@@ -329,14 +331,14 @@ static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group,
for (; i >= 0; i--) {
word = scalar->d[i];
while (mask) {
- BN_consttime_swap(word & mask, x1, x2, group->field.top);
- BN_consttime_swap(word & mask, z1, z2, group->field.top);
+ BN_consttime_swap(word & mask, x1, x2, group_top);
+ BN_consttime_swap(word & mask, z1, z2, group_top);
if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx))
goto err;
if (!gf2m_Mdouble(group, x1, z1, ctx))
goto err;
- BN_consttime_swap(word & mask, x1, x2, group->field.top);
- BN_consttime_swap(word & mask, z1, z2, group->field.top);
+ BN_consttime_swap(word & mask, x1, x2, group_top);
+ BN_consttime_swap(word & mask, z1, z2, group_top);
mask >>= 1;
}
mask = BN_TBIT;
diff --git a/thirdparty/openssl/crypto/ec/ec_ameth.c b/thirdparty/openssl/crypto/ec/ec_ameth.c
index 83e208cfe4..2c41c6e7a9 100644
--- a/thirdparty/openssl/crypto/ec/ec_ameth.c
+++ b/thirdparty/openssl/crypto/ec/ec_ameth.c
@@ -66,9 +66,12 @@
#endif
#include <openssl/asn1t.h>
#include "asn1_locl.h"
+#include "ec_lcl.h"
+#ifndef OPENSSL_NO_CMS
static int ecdh_cms_decrypt(CMS_RecipientInfo *ri);
static int ecdh_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key)
{
@@ -221,6 +224,8 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec);
const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec),
*pb = EC_KEY_get0_public_key(b->pkey.ec);
+ if (group == NULL || pa == NULL || pb == NULL)
+ return -2;
r = EC_POINT_cmp(group, pa, pb, NULL);
if (r == 0)
return 1;
@@ -299,15 +304,13 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
{
- EC_KEY *ec_key;
+ EC_KEY ec_key = *(pkey->pkey.ec);
unsigned char *ep, *p;
int eplen, ptype;
void *pval;
- unsigned int tmp_flags, old_flags;
+ unsigned int old_flags;
- ec_key = pkey->pkey.ec;
-
- if (!eckey_param2type(&ptype, &pval, ec_key)) {
+ if (!eckey_param2type(&ptype, &pval, &ec_key)) {
ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR);
return 0;
}
@@ -318,34 +321,31 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
* do not include the parameters in the SEC1 private key see PKCS#11
* 12.11
*/
- old_flags = EC_KEY_get_enc_flags(ec_key);
- tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS;
- EC_KEY_set_enc_flags(ec_key, tmp_flags);
- eplen = i2d_ECPrivateKey(ec_key, NULL);
+ old_flags = EC_KEY_get_enc_flags(&ec_key);
+ EC_KEY_set_enc_flags(&ec_key, old_flags | EC_PKEY_NO_PARAMETERS);
+
+ eplen = i2d_ECPrivateKey(&ec_key, NULL);
if (!eplen) {
- EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
return 0;
}
ep = (unsigned char *)OPENSSL_malloc(eplen);
if (!ep) {
- EC_KEY_set_enc_flags(ec_key, old_flags);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
- if (!i2d_ECPrivateKey(ec_key, &p)) {
- EC_KEY_set_enc_flags(ec_key, old_flags);
+ if (!i2d_ECPrivateKey(&ec_key, &p)) {
OPENSSL_free(ep);
ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB);
return 0;
}
- /* restore old encoding flags */
- EC_KEY_set_enc_flags(ec_key, old_flags);
if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0,
- ptype, pval, ep, eplen))
+ ptype, pval, ep, eplen)) {
+ OPENSSL_free(ep);
return 0;
+ }
return 1;
}
@@ -378,7 +378,7 @@ static int ec_bits(const EVP_PKEY *pkey)
static int ec_missing_parameters(const EVP_PKEY *pkey)
{
- if (EC_KEY_get0_group(pkey->pkey.ec) == NULL)
+ if (pkey->pkey.ec == NULL || EC_KEY_get0_group(pkey->pkey.ec) == NULL)
return 1;
return 0;
}
@@ -398,6 +398,8 @@ static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
{
const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec),
*group_b = EC_KEY_get0_group(b->pkey.ec);
+ if (group_a == NULL || group_b == NULL)
+ return -2;
if (EC_GROUP_cmp(group_a, group_b, NULL))
return 0;
else
diff --git a/thirdparty/openssl/crypto/ec/ec_asn1.c b/thirdparty/openssl/crypto/ec/ec_asn1.c
index 33abf61f44..b0cd3e1788 100644
--- a/thirdparty/openssl/crypto/ec/ec_asn1.c
+++ b/thirdparty/openssl/crypto/ec/ec_asn1.c
@@ -62,17 +62,22 @@
#include <openssl/asn1t.h>
#include <openssl/objects.h>
+#define OSSL_NELEM(x) (sizeof(x)/sizeof(x[0]))
+
int EC_GROUP_get_basis_type(const EC_GROUP *group)
{
- int i = 0;
+ int i;
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
NID_X9_62_characteristic_two_field)
/* everything else is currently not supported */
return 0;
- while (group->poly[i] != 0)
- i++;
+ /* Find the last non-zero element of group->poly[] */
+ for (i = 0;
+ i < (int)OSSL_NELEM(group->poly) && group->poly[i] != 0;
+ i++)
+ continue;
if (i == 4)
return NID_X9_62_ppBasis;
diff --git a/thirdparty/openssl/crypto/ec/ec_key.c b/thirdparty/openssl/crypto/ec/ec_key.c
index bc94ab5661..456080ecfe 100644
--- a/thirdparty/openssl/crypto/ec/ec_key.c
+++ b/thirdparty/openssl/crypto/ec/ec_key.c
@@ -377,9 +377,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
return 0;
}
ctx = BN_CTX_new();
- if (!ctx)
- goto err;
-
+ if (ctx == NULL)
+ return 0;
+ BN_CTX_start(ctx);
point = EC_POINT_new(key->group);
if (!point)
@@ -432,10 +432,9 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
ok = 1;
err:
- if (ctx)
- BN_CTX_free(ctx);
- if (point)
- EC_POINT_free(point);
+ BN_CTX_end(ctx);
+ BN_CTX_free(ctx);
+ EC_POINT_free(point);
return ok;
}
diff --git a/thirdparty/openssl/crypto/ec/ec_mult.c b/thirdparty/openssl/crypto/ec/ec_mult.c
index 23b8c3089b..24ca67a6ef 100644
--- a/thirdparty/openssl/crypto/ec/ec_mult.c
+++ b/thirdparty/openssl/crypto/ec/ec_mult.c
@@ -68,10 +68,14 @@
#include "ec_lcl.h"
/*
- * This file implements the wNAF-based interleaving multi-exponentation method
- * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp>);
- * for multiplication with precomputation, we use wNAF splitting
- * (<URL:http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp>).
+ * This file implements the wNAF-based interleaving multi-exponentiation method
+ * Formerly at:
+ * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#multiexp
+ * You might now find it here:
+ * http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
+ * http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
+ * For multiplication with precomputation, we use wNAF splitting, formerly at:
+ * http://www.informatik.tu-darmstadt.de/TI/Mitarbeiter/moeller.html#fastexp
*/
/* structure for precomputed multiples of the generator */
diff --git a/thirdparty/openssl/crypto/ec/eck_prn.c b/thirdparty/openssl/crypto/ec/eck_prn.c
index df9b37a750..176ec1f173 100644
--- a/thirdparty/openssl/crypto/ec/eck_prn.c
+++ b/thirdparty/openssl/crypto/ec/eck_prn.c
@@ -342,7 +342,7 @@ static int print_bin(BIO *fp, const char *name, const unsigned char *buf,
size_t len, int off)
{
size_t i;
- char str[128];
+ char str[128 + 1 + 4];
if (buf == NULL)
return 1;
diff --git a/thirdparty/openssl/crypto/ec/ecp_nistz256.c b/thirdparty/openssl/crypto/ec/ecp_nistz256.c
index ca44d0aaee..99b8d613c8 100644
--- a/thirdparty/openssl/crypto/ec/ecp_nistz256.c
+++ b/thirdparty/openssl/crypto/ec/ecp_nistz256.c
@@ -82,19 +82,36 @@ typedef struct ec_pre_comp_st {
} EC_PRE_COMP;
/* Functions implemented in assembly */
+/*
+ * Most of below mentioned functions *preserve* the property of inputs
+ * being fully reduced, i.e. being in [0, modulus) range. Simply put if
+ * inputs are fully reduced, then output is too. Note that reverse is
+ * not true, in sense that given partially reduced inputs output can be
+ * either, not unlikely reduced. And "most" in first sentence refers to
+ * the fact that given the calculations flow one can tolerate that
+ * addition, 1st function below, produces partially reduced result *if*
+ * multiplications by 2 and 3, which customarily use addition, fully
+ * reduce it. This effectively gives two options: a) addition produces
+ * fully reduced result [as long as inputs are, just like remaining
+ * functions]; b) addition is allowed to produce partially reduced
+ * result, but multiplications by 2 and 3 perform additional reduction
+ * step. Choice between the two can be platform-specific, but it was a)
+ * in all cases so far...
+ */
+/* Modular add: res = a+b mod P */
+void ecp_nistz256_add(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS],
+ const BN_ULONG b[P256_LIMBS]);
/* Modular mul by 2: res = 2*a mod P */
void ecp_nistz256_mul_by_2(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS]);
-/* Modular div by 2: res = a/2 mod P */
-void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
- const BN_ULONG a[P256_LIMBS]);
/* Modular mul by 3: res = 3*a mod P */
void ecp_nistz256_mul_by_3(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS]);
-/* Modular add: res = a+b mod P */
-void ecp_nistz256_add(BN_ULONG res[P256_LIMBS],
- const BN_ULONG a[P256_LIMBS],
- const BN_ULONG b[P256_LIMBS]);
+
+/* Modular div by 2: res = a/2 mod P */
+void ecp_nistz256_div_by_2(BN_ULONG res[P256_LIMBS],
+ const BN_ULONG a[P256_LIMBS]);
/* Modular sub: res = a-b mod P */
void ecp_nistz256_sub(BN_ULONG res[P256_LIMBS],
const BN_ULONG a[P256_LIMBS],
@@ -205,21 +222,29 @@ static BN_ULONG is_equal(const BN_ULONG a[P256_LIMBS],
return is_zero(res);
}
-static BN_ULONG is_one(const BN_ULONG a[P256_LIMBS])
+static BN_ULONG is_one(const BIGNUM *z)
{
- BN_ULONG res;
-
- res = a[0] ^ ONE[0];
- res |= a[1] ^ ONE[1];
- res |= a[2] ^ ONE[2];
- res |= a[3] ^ ONE[3];
- if (P256_LIMBS == 8) {
- res |= a[4] ^ ONE[4];
- res |= a[5] ^ ONE[5];
- res |= a[6] ^ ONE[6];
+ BN_ULONG res = 0;
+ BN_ULONG *a = z->d;
+
+ if (z->top == (P256_LIMBS - P256_LIMBS / 8)) {
+ res = a[0] ^ ONE[0];
+ res |= a[1] ^ ONE[1];
+ res |= a[2] ^ ONE[2];
+ res |= a[3] ^ ONE[3];
+ if (P256_LIMBS == 8) {
+ res |= a[4] ^ ONE[4];
+ res |= a[5] ^ ONE[5];
+ res |= a[6] ^ ONE[6];
+ /*
+ * no check for a[7] (being zero) on 32-bit platforms,
+ * because value of "one" takes only 7 limbs.
+ */
+ }
+ res = is_zero(res);
}
- return is_zero(res);
+ return res;
}
static int ecp_nistz256_set_words(BIGNUM *a, BN_ULONG words[P256_LIMBS])
@@ -315,19 +340,16 @@ static void ecp_nistz256_point_add(P256_POINT *r,
const BN_ULONG *in2_y = b->Y;
const BN_ULONG *in2_z = b->Z;
- /* We encode infinity as (0,0), which is not on the curve,
- * so it is OK. */
- in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] |
- in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]);
+ /*
+ * Infinity in encoded as (,,0)
+ */
+ in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]);
if (P256_LIMBS == 8)
- in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] |
- in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]);
+ in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]);
- in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] |
- in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]);
+ in2infty = (in2_z[0] | in2_z[1] | in2_z[2] | in2_z[3]);
if (P256_LIMBS == 8)
- in2infty |= (in2_x[4] | in2_x[5] | in2_x[6] | in2_x[7] |
- in2_y[4] | in2_y[5] | in2_y[6] | in2_y[7]);
+ in2infty |= (in2_z[4] | in2_z[5] | in2_z[6] | in2_z[7]);
in1infty = is_zero(in1infty);
in2infty = is_zero(in2infty);
@@ -416,15 +438,16 @@ static void ecp_nistz256_point_add_affine(P256_POINT *r,
const BN_ULONG *in2_y = b->Y;
/*
- * In affine representation we encode infty as (0,0), which is not on the
- * curve, so it is OK
+ * Infinity in encoded as (,,0)
*/
- in1infty = (in1_x[0] | in1_x[1] | in1_x[2] | in1_x[3] |
- in1_y[0] | in1_y[1] | in1_y[2] | in1_y[3]);
+ in1infty = (in1_z[0] | in1_z[1] | in1_z[2] | in1_z[3]);
if (P256_LIMBS == 8)
- in1infty |= (in1_x[4] | in1_x[5] | in1_x[6] | in1_x[7] |
- in1_y[4] | in1_y[5] | in1_y[6] | in1_y[7]);
+ in1infty |= (in1_z[4] | in1_z[5] | in1_z[6] | in1_z[7]);
+ /*
+ * In affine representation we encode infinity as (0,0), which is
+ * not on the curve, so it is OK
+ */
in2infty = (in2_x[0] | in2_x[1] | in2_x[2] | in2_x[3] |
in2_y[0] | in2_y[1] | in2_y[2] | in2_y[3]);
if (P256_LIMBS == 8)
@@ -741,9 +764,8 @@ static int ecp_nistz256_is_affine_G(const EC_POINT *generator)
{
return (generator->X.top == P256_LIMBS) &&
(generator->Y.top == P256_LIMBS) &&
- (generator->Z.top == (P256_LIMBS - P256_LIMBS / 8)) &&
is_equal(generator->X.d, def_xG) &&
- is_equal(generator->Y.d, def_yG) && is_one(generator->Z.d);
+ is_equal(generator->Y.d, def_yG) && is_one(&generator->Z);
}
static int ecp_nistz256_mult_precompute(EC_GROUP *group, BN_CTX *ctx)
@@ -1249,6 +1271,8 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group,
} else
#endif
{
+ BN_ULONG infty;
+
/* First window */
wvalue = (p_str[0] << 1) & mask;
index += window_size;
@@ -1260,7 +1284,30 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group,
ecp_nistz256_neg(p.p.Z, p.p.Y);
copy_conditional(p.p.Y, p.p.Z, wvalue & 1);
- memcpy(p.p.Z, ONE, sizeof(ONE));
+ /*
+ * Since affine infinity is encoded as (0,0) and
+ * Jacobian ias (,,0), we need to harmonize them
+ * by assigning "one" or zero to Z.
+ */
+ infty = (p.p.X[0] | p.p.X[1] | p.p.X[2] | p.p.X[3] |
+ p.p.Y[0] | p.p.Y[1] | p.p.Y[2] | p.p.Y[3]);
+ if (P256_LIMBS == 8)
+ infty |= (p.p.X[4] | p.p.X[5] | p.p.X[6] | p.p.X[7] |
+ p.p.Y[4] | p.p.Y[5] | p.p.Y[6] | p.p.Y[7]);
+
+ infty = 0 - is_zero(infty);
+ infty = ~infty;
+
+ p.p.Z[0] = ONE[0] & infty;
+ p.p.Z[1] = ONE[1] & infty;
+ p.p.Z[2] = ONE[2] & infty;
+ p.p.Z[3] = ONE[3] & infty;
+ if (P256_LIMBS == 8) {
+ p.p.Z[4] = ONE[4] & infty;
+ p.p.Z[5] = ONE[5] & infty;
+ p.p.Z[6] = ONE[6] & infty;
+ p.p.Z[7] = ONE[7] & infty;
+ }
for (i = 1; i < 37; i++) {
unsigned int off = (index - 1) / 8;
@@ -1331,7 +1378,7 @@ static int ecp_nistz256_points_mul(const EC_GROUP *group,
!ecp_nistz256_set_words(&r->Z, p.p.Z)) {
goto err;
}
- r->Z_is_one = is_one(p.p.Z) & 1;
+ r->Z_is_one = is_one(&r->Z) & 1;
ret = 1;
diff --git a/thirdparty/openssl/crypto/ecdh/ech_ossl.c b/thirdparty/openssl/crypto/ecdh/ech_ossl.c
index df115cc262..d3b05247fe 100644
--- a/thirdparty/openssl/crypto/ecdh/ech_ossl.c
+++ b/thirdparty/openssl/crypto/ecdh/ech_ossl.c
@@ -212,7 +212,9 @@ static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
BN_CTX_end(ctx);
if (ctx)
BN_CTX_free(ctx);
- if (buf)
+ if (buf) {
+ OPENSSL_cleanse(buf, buflen);
OPENSSL_free(buf);
+ }
return (ret);
}
diff --git a/thirdparty/openssl/crypto/engine/eng_cryptodev.c b/thirdparty/openssl/crypto/engine/eng_cryptodev.c
index 8fb9c3373d..af59471c47 100644
--- a/thirdparty/openssl/crypto/engine/eng_cryptodev.c
+++ b/thirdparty/openssl/crypto/engine/eng_cryptodev.c
@@ -26,6 +26,7 @@
*
*/
+#include <string.h>
#include <openssl/objects.h>
#include <openssl/engine.h>
#include <openssl/evp.h>
@@ -809,14 +810,15 @@ static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data,
if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) {
/* if application doesn't support one buffer */
- state->mac_data =
+ char *mac_data =
OPENSSL_realloc(state->mac_data, state->mac_len + count);
- if (!state->mac_data) {
+ if (mac_data == NULL) {
printf("cryptodev_digest_update: realloc failed\n");
return (0);
}
+ state->mac_data = mac_data;
memcpy(state->mac_data + state->mac_len, data, count);
state->mac_len += count;
@@ -934,11 +936,15 @@ static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
return (0);
}
+ dstate->mac_len = fstate->mac_len;
if (fstate->mac_len != 0) {
if (fstate->mac_data != NULL) {
dstate->mac_data = OPENSSL_malloc(fstate->mac_len);
+ if (dstate->mac_data == NULL) {
+ printf("cryptodev_digest_init: malloc failed\n");
+ return 0;
+ }
memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len);
- dstate->mac_len = fstate->mac_len;
}
}
@@ -1064,8 +1070,7 @@ static void zapparams(struct crypt_kop *kop)
int i;
for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) {
- if (kop->crk_param[i].crp_p)
- free(kop->crk_param[i].crp_p);
+ OPENSSL_free(kop->crk_param[i].crp_p);
kop->crk_param[i].crp_p = NULL;
kop->crk_param[i].crp_nbits = 0;
}
@@ -1078,16 +1083,25 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
int fd, ret = -1;
if ((fd = get_asym_dev_crypto()) < 0)
- return (ret);
+ return ret;
if (r) {
- kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char));
+ kop->crk_param[kop->crk_iparams].crp_p = OPENSSL_malloc(rlen);
+ if (kop->crk_param[kop->crk_iparams].crp_p == NULL)
+ return ret;
+ memset(kop->crk_param[kop->crk_iparams].crp_p, 0, (size_t)rlen);
kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8;
kop->crk_oparams++;
}
if (s) {
- kop->crk_param[kop->crk_iparams + 1].crp_p =
- calloc(slen, sizeof(char));
+ kop->crk_param[kop->crk_iparams + 1].crp_p = OPENSSL_malloc(slen);
+ /* No need to free the kop->crk_iparams parameter if it was allocated,
+ * callers of this routine have to free allocated parameters through
+ * zapparams both in case of success and failure
+ */
+ if (kop->crk_param[kop->crk_iparams+1].crp_p == NULL)
+ return ret;
+ memset(kop->crk_param[kop->crk_iparams + 1].crp_p, 0, (size_t)slen);
kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8;
kop->crk_oparams++;
}
@@ -1100,7 +1114,7 @@ cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen,
ret = 0;
}
- return (ret);
+ return ret;
}
static int
diff --git a/thirdparty/openssl/crypto/err/err.c b/thirdparty/openssl/crypto/err/err.c
index e77d963b6b..0b1fcfc1f1 100644
--- a/thirdparty/openssl/crypto/err/err.c
+++ b/thirdparty/openssl/crypto/err/err.c
@@ -172,6 +172,7 @@ static ERR_STRING_DATA ERR_str_functs[] = {
# endif
{ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"},
{ERR_PACK(0, SYS_F_FREAD, 0), "fread"},
+ {ERR_PACK(0, SYS_F_FFLUSH, 0), "fflush"},
{0, NULL},
};
@@ -868,6 +869,9 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len)
const char *ls, *fs, *rs;
unsigned long l, f, r;
+ if (len == 0)
+ return;
+
l = ERR_GET_LIB(e);
f = ERR_GET_FUNC(e);
r = ERR_GET_REASON(e);
diff --git a/thirdparty/openssl/crypto/err/openssl.ec b/thirdparty/openssl/crypto/err/openssl.ec
deleted file mode 100644
index 139afe3234..0000000000
--- a/thirdparty/openssl/crypto/err/openssl.ec
+++ /dev/null
@@ -1,98 +0,0 @@
-# crypto/err/openssl.ec
-
-# configuration file for util/mkerr.pl
-
-# files that may have to be rewritten by util/mkerr.pl
-L ERR NONE NONE
-L BN crypto/bn/bn.h crypto/bn/bn_err.c
-L RSA crypto/rsa/rsa.h crypto/rsa/rsa_err.c
-L DH crypto/dh/dh.h crypto/dh/dh_err.c
-L EVP crypto/evp/evp.h crypto/evp/evp_err.c
-L BUF crypto/buffer/buffer.h crypto/buffer/buf_err.c
-L OBJ crypto/objects/objects.h crypto/objects/obj_err.c
-L PEM crypto/pem/pem.h crypto/pem/pem_err.c
-L DSA crypto/dsa/dsa.h crypto/dsa/dsa_err.c
-L X509 crypto/x509/x509.h crypto/x509/x509_err.c
-L ASN1 crypto/asn1/asn1.h crypto/asn1/asn1_err.c
-L CONF crypto/conf/conf.h crypto/conf/conf_err.c
-L CRYPTO crypto/crypto.h crypto/cpt_err.c
-L EC crypto/ec/ec.h crypto/ec/ec_err.c
-L SSL ssl/ssl.h ssl/ssl_err.c
-L BIO crypto/bio/bio.h crypto/bio/bio_err.c
-L PKCS7 crypto/pkcs7/pkcs7.h crypto/pkcs7/pkcs7err.c
-L X509V3 crypto/x509v3/x509v3.h crypto/x509v3/v3err.c
-L PKCS12 crypto/pkcs12/pkcs12.h crypto/pkcs12/pk12err.c
-L RAND crypto/rand/rand.h crypto/rand/rand_err.c
-L DSO crypto/dso/dso.h crypto/dso/dso_err.c
-L ENGINE crypto/engine/engine.h crypto/engine/eng_err.c
-L OCSP crypto/ocsp/ocsp.h crypto/ocsp/ocsp_err.c
-L UI crypto/ui/ui.h crypto/ui/ui_err.c
-L COMP crypto/comp/comp.h crypto/comp/comp_err.c
-L ECDSA crypto/ecdsa/ecdsa.h crypto/ecdsa/ecs_err.c
-L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c
-L STORE crypto/store/store.h crypto/store/str_err.c
-L TS crypto/ts/ts.h crypto/ts/ts_err.c
-L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c
-L CMS crypto/cms/cms.h crypto/cms/cms_err.c
-L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c
-
-# additional header files to be scanned for function names
-L NONE crypto/x509/x509_vfy.h NONE
-L NONE crypto/ec/ec_lcl.h NONE
-L NONE crypto/asn1/asn_lcl.h NONE
-L NONE crypto/cms/cms_lcl.h NONE
-L NONE ssl/ssl_locl.h NONE
-
-
-F RSAREF_F_RSA_BN2BIN
-F RSAREF_F_RSA_PRIVATE_DECRYPT
-F RSAREF_F_RSA_PRIVATE_ENCRYPT
-F RSAREF_F_RSA_PUBLIC_DECRYPT
-F RSAREF_F_RSA_PUBLIC_ENCRYPT
-#F SSL_F_CLIENT_CERTIFICATE
-
-R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
-R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
-R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021
-R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022
-R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030
-R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040
-R SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041
-R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042
-R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043
-R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044
-R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045
-R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046
-R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047
-R SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048
-R SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049
-R SSL_R_TLSV1_ALERT_DECODE_ERROR 1050
-R SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051
-R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060
-R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070
-R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071
-R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080
-R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086
-R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090
-R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100
-R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110
-R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111
-R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112
-R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113
-R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114
-
-R RSAREF_R_CONTENT_ENCODING 0x0400
-R RSAREF_R_DATA 0x0401
-R RSAREF_R_DIGEST_ALGORITHM 0x0402
-R RSAREF_R_ENCODING 0x0403
-R RSAREF_R_KEY 0x0404
-R RSAREF_R_KEY_ENCODING 0x0405
-R RSAREF_R_LEN 0x0406
-R RSAREF_R_MODULUS_LEN 0x0407
-R RSAREF_R_NEED_RANDOM 0x0408
-R RSAREF_R_PRIVATE_KEY 0x0409
-R RSAREF_R_PUBLIC_KEY 0x040a
-R RSAREF_R_SIGNATURE 0x040b
-R RSAREF_R_SIGNATURE_ENCODING 0x040c
-R RSAREF_R_ENCRYPTION_ALGORITHM 0x040d
-
diff --git a/thirdparty/openssl/crypto/evp/bio_enc.c b/thirdparty/openssl/crypto/evp/bio_enc.c
index 363e0246ae..0806f233b6 100644
--- a/thirdparty/openssl/crypto/evp/bio_enc.c
+++ b/thirdparty/openssl/crypto/evp/bio_enc.c
@@ -201,9 +201,14 @@ static int enc_read(BIO *b, char *out, int outl)
break;
}
} else {
- EVP_CipherUpdate(&(ctx->cipher),
- (unsigned char *)ctx->buf, &ctx->buf_len,
- (unsigned char *)&(ctx->buf[BUF_OFFSET]), i);
+ if (!EVP_CipherUpdate(&ctx->cipher,
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)&(ctx->buf[BUF_OFFSET]),
+ i)) {
+ BIO_clear_retry_flags(b);
+ ctx->ok = 0;
+ return 0;
+ }
ctx->cont = 1;
/*
* Note: it is possible for EVP_CipherUpdate to decrypt zero
@@ -260,9 +265,13 @@ static int enc_write(BIO *b, const char *in, int inl)
ctx->buf_off = 0;
while (inl > 0) {
n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl;
- EVP_CipherUpdate(&(ctx->cipher),
- (unsigned char *)ctx->buf, &ctx->buf_len,
- (unsigned char *)in, n);
+ if (!EVP_CipherUpdate(&ctx->cipher,
+ (unsigned char *)ctx->buf, &ctx->buf_len,
+ (unsigned char *)in, n)) {
+ BIO_clear_retry_flags(b);
+ ctx->ok = 0;
+ return 0;
+ }
inl -= n;
in += n;
diff --git a/thirdparty/openssl/crypto/evp/bio_ok.c b/thirdparty/openssl/crypto/evp/bio_ok.c
index 5c32e35e17..16e151f110 100644
--- a/thirdparty/openssl/crypto/evp/bio_ok.c
+++ b/thirdparty/openssl/crypto/evp/bio_ok.c
@@ -491,7 +491,7 @@ static int sig_out(BIO *b)
* FIXME: there's absolutely no guarantee this makes any sense at all,
* particularly now EVP_MD_CTX has been restructured.
*/
- if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0)
+ if (RAND_bytes(md->md_data, md->digest->md_size) <= 0)
goto berr;
memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size);
longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size);
diff --git a/thirdparty/openssl/crypto/evp/c_all.c b/thirdparty/openssl/crypto/evp/c_all.c
index a3ed00d4c1..719e34d22f 100644
--- a/thirdparty/openssl/crypto/evp/c_all.c
+++ b/thirdparty/openssl/crypto/evp/c_all.c
@@ -82,9 +82,4 @@ void OPENSSL_add_all_algorithms_noconf(void)
OPENSSL_cpuid_setup();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
-#ifndef OPENSSL_NO_ENGINE
-# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)
- ENGINE_setup_bsd_cryptodev();
-# endif
-#endif
}
diff --git a/thirdparty/openssl/crypto/evp/digest.c b/thirdparty/openssl/crypto/evp/digest.c
index 5b642b23fc..4db179629d 100644
--- a/thirdparty/openssl/crypto/evp/digest.c
+++ b/thirdparty/openssl/crypto/evp/digest.c
@@ -253,10 +253,10 @@ int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl)
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count)
{
#ifdef OPENSSL_FIPS
- return FIPS_digestupdate(ctx, data, count);
-#else
- return ctx->update(ctx, data, count);
+ if (FIPS_mode())
+ return FIPS_digestupdate(ctx, data, count);
#endif
+ return ctx->update(ctx, data, count);
}
/* The caller can assume that this removes any secret data from the context */
@@ -271,10 +271,11 @@ int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
/* The caller can assume that this removes any secret data from the context */
int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
{
-#ifdef OPENSSL_FIPS
- return FIPS_digestfinal(ctx, md, size);
-#else
int ret;
+#ifdef OPENSSL_FIPS
+ if (FIPS_mode())
+ return FIPS_digestfinal(ctx, md, size);
+#endif
OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE);
ret = ctx->digest->final(ctx, md);
@@ -284,9 +285,8 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size)
ctx->digest->cleanup(ctx);
EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED);
}
- memset(ctx->md_data, 0, ctx->digest->ctx_size);
+ OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size);
return ret;
-#endif
}
int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in)
diff --git a/thirdparty/openssl/crypto/evp/e_aes.c b/thirdparty/openssl/crypto/evp/e_aes.c
index 1734a823c1..b45b364466 100644
--- a/thirdparty/openssl/crypto/evp/e_aes.c
+++ b/thirdparty/openssl/crypto/evp/e_aes.c
@@ -155,10 +155,10 @@ void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out,
const unsigned char ivec[AES_BLOCK_SIZE]);
# endif
# ifdef AES_XTS_ASM
-void AES_xts_encrypt(const char *inp, char *out, size_t len,
+void AES_xts_encrypt(const unsigned char *inp, unsigned char *out, size_t len,
const AES_KEY *key1, const AES_KEY *key2,
const unsigned char iv[16]);
-void AES_xts_decrypt(const char *inp, char *out, size_t len,
+void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
const AES_KEY *key1, const AES_KEY *key2,
const unsigned char iv[16]);
# endif
@@ -1120,6 +1120,8 @@ BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS)
static int aes_gcm_cleanup(EVP_CIPHER_CTX *c)
{
EVP_AES_GCM_CTX *gctx = c->cipher_data;
+ if (gctx == NULL)
+ return 0;
OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm));
if (gctx->iv != c->iv)
OPENSSL_free(gctx->iv);
@@ -1235,10 +1237,15 @@ static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr)
{
unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1];
/* Correct length for explicit IV */
+ if (len < EVP_GCM_TLS_EXPLICIT_IV_LEN)
+ return 0;
len -= EVP_GCM_TLS_EXPLICIT_IV_LEN;
/* If decrypting correct for tag too */
- if (!c->encrypt)
+ if (!c->encrypt) {
+ if (len < EVP_GCM_TLS_TAG_LEN)
+ return 0;
len -= EVP_GCM_TLS_TAG_LEN;
+ }
c->buf[arg - 2] = len >> 8;
c->buf[arg - 1] = len & 0xff;
}
diff --git a/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
index 6dfd590a4a..d114710e98 100644
--- a/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
+++ b/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c
@@ -859,6 +859,8 @@ static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
key->payload_length = len;
if ((key->aux.tls_ver =
p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ if (len < AES_BLOCK_SIZE)
+ return 0;
len -= AES_BLOCK_SIZE;
p[arg - 2] = len >> 8;
p[arg - 1] = len;
diff --git a/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c b/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c
index 46c9d03389..917ae0751d 100644
--- a/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c
+++ b/thirdparty/openssl/crypto/evp/e_aes_cbc_hmac_sha256.c
@@ -825,15 +825,19 @@ static int aesni_cbc_hmac_sha256_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
case EVP_CTRL_AEAD_TLS1_AAD:
{
unsigned char *p = ptr;
- unsigned int len = p[arg - 2] << 8 | p[arg - 1];
+ unsigned int len;
if (arg != EVP_AEAD_TLS1_AAD_LEN)
return -1;
+ len = p[arg - 2] << 8 | p[arg - 1];
+
if (ctx->encrypt) {
key->payload_length = len;
if ((key->aux.tls_ver =
p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) {
+ if (len < AES_BLOCK_SIZE)
+ return 0;
len -= AES_BLOCK_SIZE;
p[arg - 2] = len >> 8;
p[arg - 1] = len;
diff --git a/thirdparty/openssl/crypto/evp/e_des3.c b/thirdparty/openssl/crypto/evp/e_des3.c
index 0e910d6d80..ab8126e5c9 100644
--- a/thirdparty/openssl/crypto/evp/e_des3.c
+++ b/thirdparty/openssl/crypto/evp/e_des3.c
@@ -212,6 +212,8 @@ static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
size_t n;
unsigned char c[1], d[1];
+ if (!EVP_CIPHER_CTX_test_flags(ctx, EVP_CIPH_FLAG_LENGTH_BITS))
+ inl *= 8;
for (n = 0; n < inl; ++n) {
c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0;
DES_ede3_cfb_encrypt(c, d, 1, 1,
diff --git a/thirdparty/openssl/crypto/evp/e_rc4_hmac_md5.c b/thirdparty/openssl/crypto/evp/e_rc4_hmac_md5.c
index 2da1117829..93cfe3f107 100644
--- a/thirdparty/openssl/crypto/evp/e_rc4_hmac_md5.c
+++ b/thirdparty/openssl/crypto/evp/e_rc4_hmac_md5.c
@@ -99,7 +99,7 @@ static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx,
return 1;
}
-# if !defined(OPENSSL_NO_ASM) && ( \
+# if defined(RC4_ASM) && defined(MD5_ASM) && ( \
defined(__x86_64) || defined(__x86_64__) || \
defined(_M_AMD64) || defined(_M_X64) || \
defined(__INTEL__) ) && \
@@ -254,6 +254,8 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
MD5_Init(&key->tail);
MD5_Update(&key->tail, hmac_key, sizeof(hmac_key));
+ OPENSSL_cleanse(hmac_key, sizeof(hmac_key));
+
return 1;
}
case EVP_CTRL_AEAD_TLS1_AAD:
@@ -267,6 +269,8 @@ static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg,
len = p[arg - 2] << 8 | p[arg - 1];
if (!ctx->encrypt) {
+ if (len < MD5_DIGEST_LENGTH)
+ return -1;
len -= MD5_DIGEST_LENGTH;
p[arg - 2] = len >> 8;
p[arg - 1] = len;
diff --git a/thirdparty/openssl/crypto/evp/e_seed.c b/thirdparty/openssl/crypto/evp/e_seed.c
index 7249d1b1ee..3d01eacac0 100644
--- a/thirdparty/openssl/crypto/evp/e_seed.c
+++ b/thirdparty/openssl/crypto/evp/e_seed.c
@@ -70,7 +70,8 @@ typedef struct {
} EVP_SEED_KEY;
IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed,
- 16, 16, 16, 128, 0, seed_init_key, 0, 0, 0, 0)
+ 16, 16, 16, 128, EVP_CIPH_FLAG_DEFAULT_ASN1,
+ seed_init_key, 0, 0, 0, 0)
static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const unsigned char *iv, int enc)
diff --git a/thirdparty/openssl/crypto/evp/evp_enc.c b/thirdparty/openssl/crypto/evp/evp_enc.c
index 7d7be245b0..be577bac76 100644
--- a/thirdparty/openssl/crypto/evp/evp_enc.c
+++ b/thirdparty/openssl/crypto/evp/evp_enc.c
@@ -170,7 +170,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
#ifdef OPENSSL_FIPS
if (FIPS_mode()) {
- const EVP_CIPHER *fcipher;
+ const EVP_CIPHER *fcipher = NULL;
if (cipher)
fcipher = evp_get_fips_cipher(cipher);
if (fcipher)
@@ -182,6 +182,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (ctx->cipher->ctx_size) {
ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
if (!ctx->cipher_data) {
+ ctx->cipher = NULL;
EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -193,6 +194,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->flags &= EVP_CIPHER_CTX_FLAG_WRAP_ALLOW;
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
+ ctx->cipher = NULL;
EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR);
return 0;
}
@@ -654,6 +656,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (!out->cipher_data) {
+ out->cipher = NULL;
EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -661,6 +664,10 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in)
}
if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY)
- return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out);
+ if (!in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out)) {
+ out->cipher = NULL;
+ EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INITIALIZATION_ERROR);
+ return 0;
+ }
return 1;
}
diff --git a/thirdparty/openssl/crypto/evp/evp_err.c b/thirdparty/openssl/crypto/evp/evp_err.c
index 15cf5532b3..bcd841eb77 100644
--- a/thirdparty/openssl/crypto/evp/evp_err.c
+++ b/thirdparty/openssl/crypto/evp/evp_err.c
@@ -1,6 +1,6 @@
/* crypto/evp/evp_err.c */
/* ====================================================================
- * Copyright (c) 1999-2013 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -192,6 +192,7 @@ static ERR_STRING_DATA EVP_str_reasons[] = {
{ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"},
{ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"},
{ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"},
+ {ERR_REASON(EVP_R_INVALID_KEY), "invalid key"},
{ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"},
{ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"},
{ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"},
diff --git a/thirdparty/openssl/crypto/evp/evptests.txt b/thirdparty/openssl/crypto/evp/evptests.txt
deleted file mode 100644
index 4e9958b3b5..0000000000
--- a/thirdparty/openssl/crypto/evp/evptests.txt
+++ /dev/null
@@ -1,401 +0,0 @@
-#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt)
-#aadcipher:key:iv:plaintext:ciphertext:aad:tag:0/1(decrypt/encrypt)
-#digest:::input:output
-
-# SHA(1) tests (from shatest.c)
-SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d
-
-# MD5 tests (from md5test.c)
-MD5::::d41d8cd98f00b204e9800998ecf8427e
-MD5:::61:0cc175b9c0f1b6a831c399e269772661
-MD5:::616263:900150983cd24fb0d6963f7d28e17f72
-MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0
-MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b
-MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f
-MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a
-
-# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
-
-AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1
-
-# AES 192 ECB tests (from FIPS-197 test vectors, encrypt)
-
-AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1
-
-# AES 256 ECB tests (from FIPS-197 test vectors, encrypt)
-
-AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1
-
-# AES 128 ECB tests (from NIST test vectors, encrypt)
-
-#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1
-
-# AES 128 ECB tests (from NIST test vectors, decrypt)
-
-#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0
-
-# AES 192 ECB tests (from NIST test vectors, decrypt)
-
-#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0
-
-# AES 256 ECB tests (from NIST test vectors, decrypt)
-
-#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0
-
-# AES 128 CBC tests (from NIST test vectors, encrypt)
-
-#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1
-
-# AES 192 CBC tests (from NIST test vectors, encrypt)
-
-#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1
-
-# AES 256 CBC tests (from NIST test vectors, encrypt)
-
-#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1
-
-# AES 128 CBC tests (from NIST test vectors, decrypt)
-
-#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0
-
-# AES tests from NIST document SP800-38A
-# For all ECB encrypts and decrypts, the transformed sequence is
-# AES-bits-ECB:key::plaintext:ciphertext:encdec
-# ECB-AES128.Encrypt and ECB-AES128.Decrypt
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688
-AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4
-# ECB-AES192.Encrypt and ECB-AES192.Decrypt
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E
-AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E
-# ECB-AES256.Encrypt and ECB-AES256.Decrypt
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D
-AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7
-# For all CBC encrypts and decrypts, the transformed sequence is
-# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CBC-AES128.Encrypt and CBC-AES128.Decrypt
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516
-AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7
-# CBC-AES192.Encrypt and CBC-AES192.Decrypt
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0
-AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD
-# CBC-AES256.Encrypt and CBC-AES256.Decrypt
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461
-AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B
-# We don't support CFB{1,8}-AESxxx.{En,De}crypt
-# For all CFB128 encrypts and decrypts, the transformed sequence is
-# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CFB128-AES128.Encrypt
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1
-# CFB128-AES128.Decrypt
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0
-AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0
-# CFB128-AES192.Encrypt
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1
-# CFB128-AES192.Decrypt
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0
-AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0
-# CFB128-AES256.Encrypt
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1
-# CFB128-AES256.Decrypt
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0
-AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0
-# For all OFB encrypts and decrypts, the transformed sequence is
-# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec
-# OFB-AES128.Encrypt
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1
-# OFB-AES128.Decrypt
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0
-AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0
-# OFB-AES192.Encrypt
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1
-# OFB-AES192.Decrypt
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0
-AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0
-# OFB-AES256.Encrypt
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1
-# OFB-AES256.Decrypt
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0
-AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0
-
-# AES Counter test vectors from RFC3686
-aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1
-aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1
-aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1
-
-aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1
-aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1
-aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1
-
-aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1
-aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1
-aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1
-
-# DES ECB tests (from destest)
-
-DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7
-DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58
-DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B
-DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533
-DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D
-DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD
-DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4
-
-# DESX-CBC tests (from destest)
-DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4
-
-# DES EDE3 CBC tests (from destest)
-DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
-
-# RC4 tests (from rc4test)
-RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596
-RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879
-RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a
-RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858
-RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf
-RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61
-
-
-# Camellia tests from RFC3713
-# For all ECB encrypts and decrypts, the transformed sequence is
-# CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec
-CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43
-CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9
-CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509
-
-# ECB-CAMELLIA128.Encrypt
-CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1
-CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1
-CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1
-
-# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt
-CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96
-CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B
-CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636
-CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A
-
-# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt
-CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3
-CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A
-CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366
-CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26
-
-# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt
-CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA
-CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA
-CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28
-CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B
-
-# For all CBC encrypts and decrypts, the transformed sequence is
-# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt
-CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB
-CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887
-CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54
-CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980
-
-# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt
-CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93
-CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5
-CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449
-CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08
-
-# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt
-CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA
-CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50
-CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83
-CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F
-
-# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt
-# For all CFB128 encrypts and decrypts, the transformed sequence is
-# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec
-# CFB128-CAMELLIA128.Encrypt
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1
-
-# CFB128-CAMELLIA128.Decrypt
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0
-CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0
-
-# CFB128-CAMELLIA192.Encrypt
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1
-
-# CFB128-CAMELLIA192.Decrypt
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0
-CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0
-
-# CFB128-CAMELLIA256.Encrypt
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1
-
-# CFB128-CAMELLIA256.Decrypt
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0
-CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0
-
-# For all OFB encrypts and decrypts, the transformed sequence is
-# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec
-# OFB-CAMELLIA128.Encrypt
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1
-
-# OFB-CAMELLIA128.Decrypt
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0
-CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0
-
-# OFB-CAMELLIA192.Encrypt
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1
-
-# OFB-CAMELLIA192.Decrypt
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0
-CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0
-
-# OFB-CAMELLIA256.Encrypt
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1
-
-# OFB-CAMELLIA256.Decrypt
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0
-CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0
-
-# SEED test vectors from RFC4269
-SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0
-SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0
-SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0
-SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0
-SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1
-SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1
-SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1
-SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1
-
-# AES CCM 256 bit key
-aes-256-ccm:1bde3251d41a8b5ea013c195ae128b218b3e0306376357077ef1c1c78548b92e:5b8e40746f6b98e00f1d13ff41:53bd72a97089e312422bf72e242377b3c6ee3e2075389b999c4ef7f28bd2b80a:9a5fcccdb4cf04e7293d2775cc76a488f042382d949b43b7d6bb2b9864786726:c17a32514eb6103f3249e076d4c871dc97e04b286699e54491dc18f6d734d4c0:2024931d73bca480c24a24ece6b6c2bf
-
-# AES GCM test vectors from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000::::58e2fccefa7e3061367f1d57a4e7455a
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000:00000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78::ab6e47d42cec13bdf53a67b21257bddf
-aes-128-gcm:feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255:42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985::4d5c2af327cd64a62cf35abd2ba6fab4
-aes-128-gcm:feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091:feedfacedeadbeeffeedfacedeadbeefabaddad2:5bc94fbc3221a5db94fae95ae7121a47
-aes-128-gcm:feffe9928665731c6d6a8f9467308308:cafebabefacedbad:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:61353b4c2806934a777ff51fa22a4755699b2a714fcdc6f83766e5f97b6c742373806900e49f24b22b097544d4896b424989b5e1ebac0f07c23f4598:feedfacedeadbeeffeedfacedeadbeefabaddad2:3612d2e79e3b0785561be14aaca2fccb
-aes-128-gcm:feffe9928665731c6d6a8f9467308308:9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:8ce24998625615b603a033aca13fb894be9112a5c3a211a8ba262a3cca7e2ca701e4a9a4fba43c90ccdcb281d48c7c6fd62875d2aca417034c34aee5:feedfacedeadbeeffeedfacedeadbeefabaddad2:619cc5aefffe0bfa462af43c1699d050
-aes-192-gcm:000000000000000000000000000000000000000000000000:000000000000000000000000::::cd33b28ac773f74ba00ed1f312572435
-aes-192-gcm:000000000000000000000000000000000000000000000000:000000000000000000000000:00000000000000000000000000000000:98e7247c07f0fe411c267e4384b0f600::2ff58d80033927ab8ef4d4587514f0fb
-aes-192-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255:3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710acade256::9924a7c8587336bfb118024db8674a14
-aes-192-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:3980ca0b3c00e841eb06fac4872a2757859e1ceaa6efd984628593b40ca1e19c7d773d00c144c525ac619d18c84a3f4718e2448b2fe324d9ccda2710:feedfacedeadbeeffeedfacedeadbeefabaddad2:2519498e80f1478f37ba55bd6d27618c
-aes-192-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c:cafebabefacedbad:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:0f10f599ae14a154ed24b36e25324db8c566632ef2bbb34f8347280fc4507057fddc29df9a471f75c66541d4d4dad1c9e93a19a58e8b473fa0f062f7:feedfacedeadbeeffeedfacedeadbeefabaddad2:65dcc57fcf623a24094fcca40d3533f8
-aes-192-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c:9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:d27e88681ce3243c4830165a8fdcf9ff1de9a1d8e6b447ef6ef7b79828666e4581e79012af34ddd9e2f037589b292db3e67c036745fa22e7e9b7373b:feedfacedeadbeeffeedfacedeadbeefabaddad2:dcf566ff291c25bbb8568fc3d376a6d9
-aes-256-gcm:0000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000::::530f8afbc74536b9a963b4f1c4cb738b
-aes-256-gcm:0000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000:00000000000000000000000000000000:cea7403d4d606b6e074ec5d3baf39d18::d0d1c8a799996bf0265b98b5d48ab919
-aes-256-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255:522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad::b094dac5d93471bdec1a502270e3cc6c
-aes-256-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbaddecaf888:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662:feedfacedeadbeeffeedfacedeadbeefabaddad2:76fc6ece0f4e1768cddf8853bb2d551b
-aes-256-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:cafebabefacedbad:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:c3762df1ca787d32ae47c13bf19844cbaf1ae14d0b976afac52ff7d79bba9de0feb582d33934a4f0954cc2363bc73f7862ac430e64abe499f47c9b1f:feedfacedeadbeeffeedfacedeadbeefabaddad2:3a337dbf46a792c45e454913fe2ea8f2
-aes-256-gcm:feffe9928665731c6d6a8f9467308308feffe9928665731c6d6a8f9467308308:9313225df88406e555909c5aff5269aa6a7a9538534f7da1e4c303d2a318a728c3c0c95156809539fcf0e2429a6b525416aedbf5a0de6a57a637b39b:d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b39:5a8def2f0c9e53f1f75d7853659e2a20eeb2b22aafde6419a058ab4f6f746bf40fc0c3b780f244452da3ebf1c5d82cdea2418997200ef82e44ae7e3f:feedfacedeadbeeffeedfacedeadbeefabaddad2:a44a8266ee1c8eb0c8b5d4cf5ae9f19a
-# local add-ons, primarily streaming ghash tests
-# 128 bytes aad
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000:::d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255522dc1f099567d07f47f37a32a84427d643a8cdcbfe5c0c97598a2bd2555d1aa8cb08e48590dbb3da7b08b1056828838c5f61e6393ba7a0abcc9f662898015ad:5fea793a2d6f974d37e68e0cb8ff9492
-# 48 bytes plaintext
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0::9dd0a376b08e40eb00c35f29f9ea61a4
-# 80 bytes plaintext
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d5270291::98885a3a22bd4742fe7b72172193b163
-# 128 bytes plaintext
-aes-128-gcm:00000000000000000000000000000000:000000000000000000000000:0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:0388dace60b6a392f328c2b971b2fe78f795aaab494b5923f7fd89ff948bc1e0200211214e7394da2089b6acd093abe0c94da219118e297d7b7ebcbcc9c388f28ade7d85a8ee35616f7124a9d527029195b84d1b96c690ff2f2de30bf2ec89e00253786e126504f0dab90c48a30321de3345e6b0461e7c9e6c6b7afedde83f40::cac45f60e31efd3b5a43b98a22ce1aa1
-# 192 bytes plaintext, iv is chosen so that initial counter LSB is 0xFF
-aes-128-gcm:00000000000000000000000000000000:ffffffff000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000:56b3373ca9ef6e4a2b64fe1e9a17b61425f10d47a75a5fce13efc6bc784af24f4141bdd48cf7c770887afd573cca5418a9aeffcd7c5ceddfc6a78397b9a85b499da558257267caab2ad0b23ca476a53cb17fb41c4b8b475cb4f3f7165094c229c9e8c4dc0a2a5ff1903e501511221376a1cdb8364c5061a20cae74bc4acd76ceb0abc9fd3217ef9f8c90be402ddf6d8697f4f880dff15bfb7a6b28241ec8fe183c2d59e3f9dfff653c7126f0acb9e64211f42bae12af462b1070bef1ab5e3606::566f8ef683078bfdeeffa869d751a017
-# 80 bytes plaintext, submitted by Intel
-aes-128-gcm:843ffcf5d2b72694d19ed01d01249412:dbcca32ebf9b804617c3aa9e:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f:6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3dcee23ad2f1ab3a6c80eaf4b140eb05de3457f0fbc111a6b43d0763aa422a3013cf1dc37fe417d1fbfc449b75d4cc5:00000000000000000000000000000000101112131415161718191a1b1c1d1e1f:3b629ccfbc1119b7319e1dce2cd6fd6d
-
-# AES XTS test vectors from IEEE Std 1619-2007
-aes-128-xts:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:0000000000000000000000000000000000000000000000000000000000000000:917cf69ebd68b2ec9b9fe9a3eadda692cd43d2f59598ed858c02c2652fbf922e
-aes-128-xts:1111111111111111111111111111111122222222222222222222222222222222:33333333330000000000000000000000:4444444444444444444444444444444444444444444444444444444444444444:c454185e6a16936e39334038acef838bfb186fff7480adc4289382ecd6d394f0
-aes-128-xts:fffefdfcfbfaf9f8f7f6f5f4f3f2f1f022222222222222222222222222222222:33333333330000000000000000000000:4444444444444444444444444444444444444444444444444444444444444444:af85336b597afc1a900b2eb21ec949d292df4c047e0b21532186a5971a227a89
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:00000000000000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:01000000000000000000000000000000:27a7479befa1d476489f308cd4cfa6e2a96e4bbe3208ff25287dd3819616e89cc78cf7f5e543445f8333d8fa7f56000005279fa5d8b5e4ad40e736ddb4d35412328063fd2aab53e5ea1e0a9f332500a5df9487d07a5c92cc512c8866c7e860ce93fdf166a24912b422976146ae20ce846bb7dc9ba94a767aaef20c0d61ad02655ea92dc4c4e41a8952c651d33174be51a10c421110e6d81588ede82103a252d8a750e8768defffed9122810aaeb99f9172af82b604dc4b8e51bcb08235a6f4341332e4ca60482a4ba1a03b3e65008fc5da76b70bf1690db4eae29c5f1badd03c5ccf2a55d705ddcd86d449511ceb7ec30bf12b1fa35b913f9f747a8afd1b130e94bff94effd01a91735ca1726acd0b197c4e5b03393697e126826fb6bbde8ecc1e08298516e2c9ed03ff3c1b7860f6de76d4cecd94c8119855ef5297ca67e9f3e7ff72b1e99785ca0a7e7720c5b36dc6d72cac9574c8cbbc2f801e23e56fd344b07f22154beba0f08ce8891e643ed995c94d9a69c9f1b5f499027a78572aeebd74d20cc39881c213ee770b1010e4bea718846977ae119f7a023ab58cca0ad752afe656bb3c17256a9f6e9bf19fdd5a38fc82bbe872c5539edb609ef4f79c203ebb140f2e583cb2ad15b4aa5b655016a8449277dbd477ef2c8d6c017db738b18deb4a427d1923ce3ff262735779a418f20a282df920147beabe421ee5319d0568:264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:02000000000000000000000000000000:264d3ca8512194fec312c8c9891f279fefdd608d0c027b60483a3fa811d65ee59d52d9e40ec5672d81532b38b6b089ce951f0f9c35590b8b978d175213f329bb1c2fd30f2f7f30492a61a532a79f51d36f5e31a7c9a12c286082ff7d2394d18f783e1a8e72c722caaaa52d8f065657d2631fd25bfd8e5baad6e527d763517501c68c5edc3cdd55435c532d7125c8614deed9adaa3acade5888b87bef641c4c994c8091b5bcd387f3963fb5bc37aa922fbfe3df4e5b915e6eb514717bdd2a74079a5073f5c4bfd46adf7d282e7a393a52579d11a028da4d9cd9c77124f9648ee383b1ac763930e7162a8d37f350b2f74b8472cf09902063c6b32e8c2d9290cefbd7346d1c779a0df50edcde4531da07b099c638e83a755944df2aef1aa31752fd323dcb710fb4bfbb9d22b925bc3577e1b8949e729a90bbafeacf7f7879e7b1147e28ba0bae940db795a61b15ecf4df8db07b824bb062802cc98a9545bb2aaeed77cb3fc6db15dcd7d80d7d5bc406c4970a3478ada8899b329198eb61c193fb6275aa8ca340344a75a862aebe92eee1ce032fd950b47d7704a3876923b4ad62844bf4a09c4dbe8b4397184b7471360c9564880aedddb9baa4af2e75394b08cd32ff479c57a07d3eab5d54de5f9738b8d27f27a9f0ab11799d7b7ffefb2704c95c6ad12c39f1e867a4b7b1d7818a4b753dfd2a89ccb45e001a03a867b187f225dd:fa762a3680b76007928ed4a4f49a9456031b704782e65e16cecb54ed7d017b5e18abd67b338e81078f21edb7868d901ebe9c731a7c18b5e6dec1d6a72e078ac9a4262f860beefa14f4e821018272e411a951502b6e79066e84252c3346f3aa62344351a291d4bedc7a07618bdea2af63145cc7a4b8d4070691ae890cd65733e7946e9021a1dffc4c59f159425ee6d50ca9b135fa6162cea18a939838dc000fb386fad086acce5ac07cb2ece7fd580b00cfa5e98589631dc25e8e2a3daf2ffdec26531659912c9d8f7a15e5865ea8fb5816d6207052bd7128cd743c12c8118791a4736811935eb982a532349e31dd401e0b660a568cb1a4711f552f55ded59f1f15bf7196b3ca12a91e488ef59d64f3a02bf45239499ac6176ae321c4a211ec545365971c5d3f4f09d4eb139bfdf2073d33180b21002b65cc9865e76cb24cd92c874c24c18350399a936ab3637079295d76c417776b94efce3a0ef7206b15110519655c956cbd8b2489405ee2b09a6b6eebe0c53790a12a8998378b33a5b71159625f4ba49d2a2fdba59fbf0897bc7aabd8d707dc140a80f0f309f835d3da54ab584e501dfa0ee977fec543f74186a802b9a37adb3e8291eca04d66520d229e60401e7282bef486ae059aa70696e0e305d777140a7a883ecdcb69b9ff938e8a4231864c69ca2c2043bed007ff3e605e014bcf518138dc3a25c5e236171a2d01d6
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:fd000000000000000000000000000000:8e41b78c390b5af9d758bb214a67e9f6bf7727b09ac6124084c37611398fa45daad94868600ed391fb1acd4857a95b466e62ef9f4b377244d1c152e7b30d731aad30c716d214b707aed99eb5b5e580b3e887cf7497465651d4b60e6042051da3693c3b78c14489543be8b6ad0ba629565bba202313ba7b0d0c94a3252b676f46cc02ce0f8a7d34c0ed229129673c1f61aed579d08a9203a25aac3a77e9db60267996db38df637356d9dcd1632e369939f2a29d89345c66e05066f1a3677aef18dea4113faeb629e46721a66d0a7e785d3e29af2594eb67dfa982affe0aac058f6e15864269b135418261fc3afb089472cf68c45dd7f231c6249ba0255e1e033833fc4d00a3fe02132d7bc3873614b8aee34273581ea0325c81f0270affa13641d052d36f0757d484014354d02d6883ca15c24d8c3956b1bd027bcf41f151fd8023c5340e5606f37e90fdb87c86fb4fa634b3718a30bace06a66eaf8f63c4aa3b637826a87fe8cfa44282e92cb1615af3a28e53bc74c7cba1a0977be9065d0c1a5dec6c54ae38d37f37aa35283e048e5530a85c4e7a29d7b92ec0c3169cdf2a805c7604bce60049b9fb7b8eaac10f51ae23794ceba68bb58112e293b9b692ca721b37c662f8574ed4dba6f88e170881c82cddc1034a0ca7e284bf0962b6b26292d836fa9f73c1ac770eef0f2d3a1eaf61d3e03555fd424eedd67e18a18094f888:d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:fe000000000000000000000000000000:d55f684f81f4426e9fde92a5ff02df2ac896af63962888a97910c1379e20b0a3b1db613fb7fe2e07004329ea5c22bfd33e3dbe4cf58cc608c2c26c19a2e2fe22f98732c2b5cb844cc6c0702d91e1d50fc4382a7eba5635cd602432a2306ac4ce82f8d70c8d9bc15f918fe71e74c622d5cf71178bf6e0b9cc9f2b41dd8dbe441c41cd0c73a6dc47a348f6702f9d0e9b1b1431e948e299b9ec2272ab2c5f0c7be86affa5dec87a0bee81d3d50007edaa2bcfccb35605155ff36ed8edd4a40dcd4b243acd11b2b987bdbfaf91a7cac27e9c5aea525ee53de7b2d3332c8644402b823e94a7db26276d2d23aa07180f76b4fd29b9c0823099c9d62c519880aee7e9697617c1497d47bf3e571950311421b6b734d38b0db91eb85331b91ea9f61530f54512a5a52a4bad589eb69781d537f23297bb459bdad2948a29e1550bf4787e0be95bb173cf5fab17dab7a13a052a63453d97ccec1a321954886b7a1299faaeecae35c6eaaca753b041b5e5f093bf83397fd21dd6b3012066fcc058cc32c3b09d7562dee29509b5839392c9ff05f51f3166aaac4ac5f238038a3045e6f72e48ef0fe8bc675e82c318a268e43970271bf119b81bf6a982746554f84e72b9f00280a320a08142923c23c883423ff949827f29bbacdc1ccdb04938ce6098c95ba6b32528f4ef78eed778b2e122ddfd1cbdd11d1c0a6783e011fc536d63d053260637:72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a
-aes-128-xts:2718281828459045235360287471352631415926535897932384626433832795:ff000000000000000000000000000000:72efc1ebfe1ee25975a6eb3aa8589dda2b261f1c85bdab442a9e5b2dd1d7c3957a16fc08e526d4b1223f1b1232a11af274c3d70dac57f83e0983c498f1a6f1aecb021c3e70085a1e527f1ce41ee5911a82020161529cd82773762daf5459de94a0a82adae7e1703c808543c29ed6fb32d9e004327c1355180c995a07741493a09c21ba01a387882da4f62534b87bb15d60d197201c0fd3bf30c1500a3ecfecdd66d8721f90bcc4c17ee925c61b0a03727a9c0d5f5ca462fbfa0af1c2513a9d9d4b5345bd27a5f6e653f751693e6b6a2b8ead57d511e00e58c45b7b8d005af79288f5c7c22fd4f1bf7a898b03a5634c6a1ae3f9fae5de4f296a2896b23e7ed43ed14fa5a2803f4d28f0d3ffcf24757677aebdb47bb388378708948a8d4126ed1839e0da29a537a8c198b3c66ab00712dd261674bf45a73d67f76914f830ca014b65596f27e4cf62de66125a5566df9975155628b400fbfb3a29040ed50faffdbb18aece7c5c44693260aab386c0a37b11b114f1c415aebb653be468179428d43a4d8bc3ec38813eca30a13cf1bb18d524f1992d44d8b1a42ea30b22e6c95b199d8d182f8840b09d059585c31ad691fa0619ff038aca2c39a943421157361717c49d322028a74648113bd8c9d7ec77cf3c89c1ec8718ceff8516d96b34c3c614f10699c9abc4ed0411506223bea16af35c883accdbe1104eef0cfdb54e12fb230a:3260ae8dad1f4a32c5cafe3ab0eb95549d461a67ceb9e5aa2d3afb62dece0553193ba50c75be251e08d1d08f1088576c7efdfaaf3f459559571e12511753b07af073f35da06af0ce0bbf6b8f5ccc5cea500ec1b211bd51f63b606bf6528796ca12173ba39b8935ee44ccce646f90a45bf9ccc567f0ace13dc2d53ebeedc81f58b2e41179dddf0d5a5c42f5d8506c1a5d2f8f59f3ea873cbcd0eec19acbf325423bd3dcb8c2b1bf1d1eaed0eba7f0698e4314fbeb2f1566d1b9253008cbccf45a2b0d9c5c9c21474f4076e02be26050b99dee4fd68a4cf890e496e4fcae7b70f94ea5a9062da0daeba1993d2ccd1dd3c244b8428801495a58b216547e7e847c46d1d756377b6242d2e5fb83bf752b54e0df71e889f3a2bb0f4c10805bf3c590376e3c24e22ff57f7fa965577375325cea5d920db94b9c336b455f6e894c01866fe9fbb8c8d3f70a2957285f6dfb5dcd8cbf54782f8fe7766d4723819913ac773421e3a31095866bad22c86a6036b2518b2059b4229d18c8c2ccbdf906c6cc6e82464ee57bddb0bebcb1dc645325bfb3e665ef7251082c88ebb1cf203bd779fdd38675713c8daadd17e1cabee432b09787b6ddf3304e38b731b45df5df51b78fcfb3d32466028d0ba36555e7e11ab0ee0666061d1645d962444bc47a38188930a84b4d561395c73c087021927ca638b7afc8a8679ccb84c26555440ec7f10445cd
-
-aes-256-xts:27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592:ff000000000000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:1c3b3a102f770386e4836c99e370cf9bea00803f5e482357a4ae12d414a3e63b5d31e276f8fe4a8d66b317f9ac683f44680a86ac35adfc3345befecb4bb188fd5776926c49a3095eb108fd1098baec70aaa66999a72a82f27d848b21d4a741b0c5cd4d5fff9dac89aeba122961d03a757123e9870f8acf1000020887891429ca2a3e7a7d7df7b10355165c8b9a6d0a7de8b062c4500dc4cd120c0f7418dae3d0b5781c34803fa75421c790dfe1de1834f280d7667b327f6c8cd7557e12ac3a0f93ec05c52e0493ef31a12d3d9260f79a289d6a379bc70c50841473d1a8cc81ec583e9645e07b8d9670655ba5bbcfecc6dc3966380ad8fecb17b6ba02469a020a84e18e8f84252070c13e9f1f289be54fbc481457778f616015e1327a02b140f1505eb309326d68378f8374595c849d84f4c333ec4423885143cb47bd71c5edae9be69a2ffeceb1bec9de244fbe15992b11b77c040f12bd8f6a975a44a0f90c29a9abc3d4d893927284c58754cce294529f8614dcd2aba991925fedc4ae74ffac6e333b93eb4aff0479da9a410e4450e0dd7ae4c6e2910900575da401fc07059f645e8b7e9bfdef33943054ff84011493c27b3429eaedb4ed5376441a77ed43851ad77f16f541dfd269d50d6a5f14fb0aab1cbb4c1550be97f7ab4066193c4caa773dad38014bd2092fa755c824bb5e54c4f36ffda9fcea70b9c6e693e148c151
-aes-256-xts:27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592:ffff0000000000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:77a31251618a15e6b92d1d66dffe7b50b50bad552305ba0217a610688eff7e11e1d0225438e093242d6db274fde801d4cae06f2092c728b2478559df58e837c2469ee4a4fa794e4bbc7f39bc026e3cb72c33b0888f25b4acf56a2a9804f1ce6d3d6e1dc6ca181d4b546179d55544aa7760c40d06741539c7e3cd9d2f6650b2013fd0eeb8c2b8e3d8d240ccae2d4c98320a7442e1c8d75a42d6e6cfa4c2eca1798d158c7aecdf82490f24bb9b38e108bcda12c3faf9a21141c3613b58367f922aaa26cd22f23d708dae699ad7cb40a8ad0b6e2784973dcb605684c08b8d6998c69aac049921871ebb65301a4619ca80ecb485a31d744223ce8ddc2394828d6a80470c092f5ba413c3378fa6054255c6f9df4495862bbb3287681f931b687c888abf844dfc8fc28331e579928cd12bd2390ae123cf03818d14dedde5c0c24c8ab018bfca75ca096f2d531f3d1619e785f1ada437cab92e980558b3dce1474afb75bfedbf8ff54cb2618e0244c9ac0d3c66fb51598cd2db11f9be39791abe447c63094f7c453b7ff87cb5bb36b7c79efb0872d17058b83b15ab0866ad8a58656c5a7e20dbdf308b2461d97c0ec0024a2715055249cf3b478ddd4740de654f75ca686e0d7345c69ed50cdc2a8b332b1f8824108ac937eb050585608ee734097fc09054fbff89eeaeea791f4a7ab1f9868294a4f9e27b42af8100cb9d59cef9645803
-aes-256-xts:27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592:ffffff00000000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:e387aaa58ba483afa7e8eb469778317ecf4cf573aa9d4eac23f2cdf914e4e200a8b490e42ee646802dc6ee2b471b278195d60918ececb44bf79966f83faba0499298ebc699c0c8634715a320bb4f075d622e74c8c932004f25b41e361025b5a87815391f6108fc4afa6a05d9303c6ba68a128a55705d415985832fdeaae6c8e19110e84d1b1f199a2692119edc96132658f09da7c623efcec712537a3d94c0bf5d7e352ec94ae5797fdb377dc1551150721adf15bd26a8efc2fcaad56881fa9e62462c28f30ae1ceaca93c345cf243b73f542e2074a705bd2643bb9f7cc79bb6e7091ea6e232df0f9ad0d6cf502327876d82207abf2115cdacf6d5a48f6c1879a65b115f0f8b3cb3c59d15dd8c769bc014795a1837f3901b5845eb491adfefe097b1fa30a12fc1f65ba22905031539971a10f2f36c321bb51331cdefb39e3964c7ef079994f5b69b2edd83a71ef549971ee93f44eac3938fcdd61d01fa71799da3a8091c4c48aa9ed263ff0749df95d44fef6a0bb578ec69456aa5408ae32c7af08ad7ba8921287e3bbee31b767be06a0e705c864a769137df28292283ea81a2480241b44d9921cdbec1bc28dc1fda114bd8e5217ac9d8ebafa720e9da4f9ace231cc949e5b96fe76ffc21063fddc83a6b8679c00d35e09576a875305bed5f36ed242c8900dd1fa965bc950dfce09b132263a1eef52dd6888c309f5a7d712826
-aes-256-xts:27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592:ffffffff000000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:bf53d2dade78e822a4d949a9bc6766b01b06a8ef70d26748c6a7fc36d80ae4c5520f7c4ab0ac8544424fa405162fef5a6b7f229498063618d39f0003cb5fb8d1c86b643497da1ff945c8d3bedeca4f479702a7a735f043ddb1d6aaade3c4a0ac7ca7f3fa5279bef56f82cd7a2f38672e824814e10700300a055e1630b8f1cb0e919f5e942010a416e2bf48cb46993d3cb6a51c19bacf864785a00bc2ecff15d350875b246ed53e68be6f55bd7e05cfc2b2ed6432198a6444b6d8c247fab941f569768b5c429366f1d3f00f0345b96123d56204c01c63b22ce78baf116e525ed90fdea39fa469494d3866c31e05f295ff21fea8d4e6e13d67e47ce722e9698a1c1048d68ebcde76b86fcf976eab8aa9790268b7068e017a8b9b749409514f1053027fd16c3786ea1bac5f15cb79711ee2abe82f5cf8b13ae73030ef5b9e4457e75d1304f988d62dd6fc4b94ed38ba831da4b7634971b6cd8ec325d9c61c00f1df73627ed3745a5e8489f3a95c69639c32cd6e1d537a85f75cc844726e8a72fc0077ad22000f1d5078f6b866318c668f1ad03d5a5fced5219f2eabbd0aa5c0f460d183f04404a0d6f469558e81fab24a167905ab4c7878502ad3e38fdbe62a41556cec37325759533ce8f25f367c87bb5578d667ae93f9e2fd99bcbc5f2fbba88cf6516139420fcff3b7361d86322c4bd84c82f335abb152c4a93411373aaa8220
-aes-256-xts:27182818284590452353602874713526624977572470936999595749669676273141592653589793238462643383279502884197169399375105820974944592:ffffffffff0000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:64497e5a831e4a932c09be3e5393376daa599548b816031d224bbf50a818ed2350eae7e96087c8a0db51ad290bd00c1ac1620857635bf246c176ab463be30b808da548081ac847b158e1264be25bb0910bbc92647108089415d45fab1b3d2604e8a8eff1ae4020cfa39936b66827b23f371b92200be90251e6d73c5f86de5fd4a950781933d79a28272b782a2ec313efdfcc0628f43d744c2dc2ff3dcb66999b50c7ca895b0c64791eeaa5f29499fb1c026f84ce5b5c72ba1083cddb5ce45434631665c333b60b11593fb253c5179a2c8db813782a004856a1653011e93fb6d876c18366dd8683f53412c0c180f9c848592d593f8609ca736317d356e13e2bff3a9f59cd9aeb19cd482593d8c46128bb32423b37a9adfb482b99453fbe25a41bf6feb4aa0bef5ed24bf73c762978025482c13115e4015aac992e5613a3b5c2f685b84795cb6e9b2656d8c88157e52c42f978d8634c43d06fea928f2822e465aa6576e9bf419384506cc3ce3c54ac1a6f67dc66f3b30191e698380bc999b05abce19dc0c6dcc2dd001ec535ba18deb2df1a101023108318c75dc98611a09dc48a0acdec676fabdf222f07e026f059b672b56e5cbc8e1d21bbd867dd927212054681d70ea737134cdfce93b6f82ae22423274e58a0821cc5502e2d0ab4585e94de6975be5e0b4efce51cd3e70c25a1fbbbd609d273ad5b0d59631c531f6a0a57b9
-
-aes-128-xts:fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0:9a785634120000000000000000000000:000102030405060708090a0b0c0d0e0f10:6c1625db4671522d3d7599601de7ca09ed
-aes-128-xts:fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0:9a785634120000000000000000000000:000102030405060708090a0b0c0d0e0f1011:d069444b7a7e0cab09e24447d24deb1fedbf
-aes-128-xts:fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0:9a785634120000000000000000000000:000102030405060708090a0b0c0d0e0f101112:e5df1351c0544ba1350b3363cd8ef4beedbf9d
-aes-128-xts:fffefdfcfbfaf9f8f7f6f5f4f3f2f1f0bfbebdbcbbbab9b8b7b6b5b4b3b2b1b0:9a785634120000000000000000000000:000102030405060708090a0b0c0d0e0f10111213:9d84c813f719aa2c7be3f66171c7c5c2edbf9dac
-aes-128-xts:e0e1e2e3e4e5e6e7e8e9eaebecedeeefc0c1c2c3c4c5c6c7c8c9cacbcccdcecf:21436587a90000000000000000000000:000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f404142434445464748494a4b4c4d4e4f505152535455565758595a5b5c5d5e5f606162636465666768696a6b6c6d6e6f707172737475767778797a7b7c7d7e7f808182838485868788898a8b8c8d8e8f909192939495969798999a9b9c9d9e9fa0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebfc0c1c2c3c4c5c6c7c8c9cacbcccdcecfd0d1d2d3d4d5d6d7d8d9dadbdcdddedfe0e1e2e3e4e5e6e7e8e9eaebecedeeeff0f1f2f3f4f5f6f7f8f9fafbfcfdfeff:38b45812ef43a05bd957e545907e223b954ab4aaf088303ad910eadf14b42be68b2461149d8c8ba85f992be970bc621f1b06573f63e867bf5875acafa04e42ccbd7bd3c2a0fb1fff791ec5ec36c66ae4ac1e806d81fbf709dbe29e471fad38549c8e66f5345d7c1eb94f405d1ec785cc6f6a68f6254dd8339f9d84057e01a17741990482999516b5611a38f41bb6478e6f173f320805dd71b1932fc333cb9ee39936beea9ad96fa10fb4112b901734ddad40bc1878995f8e11aee7d141a2f5d48b7a4e1e7f0b2c04830e69a4fd1378411c2f287edf48c6c4e5c247a19680f7fe41cefbd49b582106e3616cbbe4dfb2344b2ae9519391f3e0fb4922254b1d6d2d19c6d4d537b3a26f3bcc51588b32f3eca0829b6a5ac72578fb814fb43cf80d64a233e3f997a3f02683342f2b33d25b492536b93becb2f5e1a8b82f5b883342729e8ae09d16938841a21a97fb543eea3bbff59f13c1a18449e398701c1ad51648346cbc04c27bb2da3b93a1372ccae548fb53bee476f9e9c91773b1bb19828394d55d3e1a20ed69113a860b6829ffa847224604435070221b257e8dff783615d2cae4803a93aa4334ab482a0afac9c0aeda70b45a481df5dec5df8cc0f423c77a5fd46cd312021d4b438862419a791be03bb4d97c0e59578542531ba466a83baf92cefc151b5cc1611a167893819b63fb8a6b18e86de60290fa72b797b0ce59f3
-# AES wrap tests from RFC3394
-id-aes128-wrap:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5
-id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D
-id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7
-id-aes192-wrap:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF0001020304050607:031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2
-id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF0001020304050607:A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1
-id-aes256-wrap:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F:28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21
diff --git a/thirdparty/openssl/crypto/evp/openbsd_hw.c b/thirdparty/openssl/crypto/evp/openbsd_hw.c
index 75d12e2330..07decf2674 100644
--- a/thirdparty/openssl/crypto/evp/openbsd_hw.c
+++ b/thirdparty/openssl/crypto/evp/openbsd_hw.c
@@ -133,6 +133,10 @@ static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher,
return 0;
CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY);
+ if (CDATA(ctx)->key == NULL {
+ err("CDATA(ctx)->key memory allocation failed");
+ return 0;
+ }
assert(ctx->cipher->iv_len <= MAX_HW_IV);
@@ -186,6 +190,11 @@ static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out,
if (((unsigned long)in & 3) || cinl != inl) {
cin = OPENSSL_malloc(cinl);
+ if (cin == NULL) {
+ err("cin - memory allocation failed");
+ abort();
+ return 0;
+ }
memcpy(cin, in, inl);
cryp.src = cin;
}
@@ -334,6 +343,11 @@ static int do_digest(int ses, unsigned char *md, const void *data, int len)
char *dcopy;
dcopy = OPENSSL_malloc(len);
+ if (dcopy == NULL) {
+ err("dcopy - memory allocation failed");
+ abort();
+ return 0;
+ }
memcpy(dcopy, data, len);
cryp.src = dcopy;
cryp.dst = cryp.src; // FIXME!!!
@@ -364,6 +378,10 @@ static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data,
return do_digest(md_data->sess.ses, md_data->md, data, len);
md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len);
+ if (md_data->data == NULL) {
+ err("DEV_CRYPTO_MD5_UPDATE: unable to allocate memory");
+ abort();
+ }
memcpy(md_data->data + md_data->len, data, len);
md_data->len += len;
@@ -397,6 +415,10 @@ static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from)
assert(from->digest->flags & EVP_MD_FLAG_ONESHOT);
to_md->data = OPENSSL_malloc(from_md->len);
+ if (to_md->data == NULL) {
+ err("DEV_CRYPTO_MD5_COPY: unable to allocate memory");
+ abort();
+ }
memcpy(to_md->data, from_md->data, from_md->len);
return 1;
diff --git a/thirdparty/openssl/crypto/evp/p_lib.c b/thirdparty/openssl/crypto/evp/p_lib.c
index c0171244d5..545d04fd77 100644
--- a/thirdparty/openssl/crypto/evp/p_lib.c
+++ b/thirdparty/openssl/crypto/evp/p_lib.c
@@ -130,6 +130,14 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS);
goto err;
}
+
+ if (!EVP_PKEY_missing_parameters(to)) {
+ if (EVP_PKEY_cmp_parameters(to, from) == 1)
+ return 1;
+ EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_PARAMETERS);
+ return 0;
+ }
+
if (from->ameth && from->ameth->param_copy)
return from->ameth->param_copy(to, from);
err:
diff --git a/thirdparty/openssl/crypto/evp/pmeth_fn.c b/thirdparty/openssl/crypto/evp/pmeth_fn.c
index a8b7f2f6d5..727869e3ee 100644
--- a/thirdparty/openssl/crypto/evp/pmeth_fn.c
+++ b/thirdparty/openssl/crypto/evp/pmeth_fn.c
@@ -65,20 +65,22 @@
#include "evp_locl.h"
#define M_check_autoarg(ctx, arg, arglen, err) \
- if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \
- { \
- size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
- if (!arg) \
- { \
- *arglen = pksize; \
- return 1; \
- } \
- else if (*arglen < pksize) \
- { \
- EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\
- return 0; \
- } \
- }
+ if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) { \
+ size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \
+ \
+ if (pksize == 0) { \
+ EVPerr(err, EVP_R_INVALID_KEY); /*ckerr_ignore*/ \
+ return 0; \
+ } \
+ if (!arg) { \
+ *arglen = pksize; \
+ return 1; \
+ } \
+ if (*arglen < pksize) { \
+ EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/ \
+ return 0; \
+ } \
+ }
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx)
{
diff --git a/thirdparty/openssl/crypto/evp/pmeth_gn.c b/thirdparty/openssl/crypto/evp/pmeth_gn.c
index 6435f1b632..6a4d3573ff 100644
--- a/thirdparty/openssl/crypto/evp/pmeth_gn.c
+++ b/thirdparty/openssl/crypto/evp/pmeth_gn.c
@@ -149,8 +149,10 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey)
if (!ppkey)
return -1;
- if (!*ppkey)
+ if (*ppkey == NULL)
*ppkey = EVP_PKEY_new();
+ if (*ppkey == NULL)
+ return -1;
ret = ctx->pmeth->keygen(ctx, *ppkey);
if (ret <= 0) {
diff --git a/thirdparty/openssl/crypto/evp/pmeth_lib.c b/thirdparty/openssl/crypto/evp/pmeth_lib.c
index 9f81d10021..b7b7bdcd02 100644
--- a/thirdparty/openssl/crypto/evp/pmeth_lib.c
+++ b/thirdparty/openssl/crypto/evp/pmeth_lib.c
@@ -91,7 +91,9 @@ static const EVP_PKEY_METHOD *standard_methods[] = {
&ec_pkey_meth,
#endif
&hmac_pkey_meth,
+#ifndef OPENSSL_NO_CMAC
&cmac_pkey_meth,
+#endif
#ifndef OPENSSL_NO_DH
&dhx_pkey_meth
#endif
@@ -186,6 +188,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
if (pmeth->init) {
if (pmeth->init(ret) <= 0) {
+ ret->pmeth = NULL;
EVP_PKEY_CTX_free(ret);
return NULL;
}
@@ -197,6 +200,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)
EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
{
EVP_PKEY_METHOD *pmeth;
+
pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD));
if (!pmeth)
return NULL;
@@ -205,33 +209,6 @@ EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags)
pmeth->pkey_id = id;
pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC;
-
- pmeth->init = 0;
- pmeth->copy = 0;
- pmeth->cleanup = 0;
- pmeth->paramgen_init = 0;
- pmeth->paramgen = 0;
- pmeth->keygen_init = 0;
- pmeth->keygen = 0;
- pmeth->sign_init = 0;
- pmeth->sign = 0;
- pmeth->verify_init = 0;
- pmeth->verify = 0;
- pmeth->verify_recover_init = 0;
- pmeth->verify_recover = 0;
- pmeth->signctx_init = 0;
- pmeth->signctx = 0;
- pmeth->verifyctx_init = 0;
- pmeth->verifyctx = 0;
- pmeth->encrypt_init = 0;
- pmeth->encrypt = 0;
- pmeth->decrypt_init = 0;
- pmeth->decrypt = 0;
- pmeth->derive_init = 0;
- pmeth->derive = 0;
- pmeth->ctrl = 0;
- pmeth->ctrl_str = 0;
-
return pmeth;
}
@@ -339,6 +316,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
if (pctx->pmeth->copy(rctx, pctx) > 0)
return rctx;
+ rctx->pmeth = NULL;
EVP_PKEY_CTX_free(rctx);
return NULL;
diff --git a/thirdparty/openssl/crypto/ex_data.c b/thirdparty/openssl/crypto/ex_data.c
index f96a51781a..108a1959ea 100644
--- a/thirdparty/openssl/crypto/ex_data.c
+++ b/thirdparty/openssl/crypto/ex_data.c
@@ -331,7 +331,11 @@ static EX_CLASS_ITEM *def_get_class(int class_index)
* from the insert will be NULL
*/
(void)lh_EX_CLASS_ITEM_insert(ex_data, gen);
- p = gen;
+ p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d);
+ if (p != gen) {
+ sk_CRYPTO_EX_DATA_FUNCS_free(gen->meth);
+ OPENSSL_free(gen);
+ }
}
}
}
@@ -455,7 +459,7 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
CRYPTO_EX_DATA *from)
{
int mx, j, i;
- char *ptr;
+ void *ptr;
CRYPTO_EX_DATA_FUNCS **storage = NULL;
EX_CLASS_ITEM *item;
if (!from->sk)
@@ -469,6 +473,8 @@ static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to,
if (j < mx)
mx = j;
if (mx > 0) {
+ if (!CRYPTO_set_ex_data(to, mx - 1, NULL))
+ goto skip;
storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *));
if (!storage)
goto skip;
@@ -499,11 +505,12 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
int mx, i;
EX_CLASS_ITEM *item;
void *ptr;
+ CRYPTO_EX_DATA_FUNCS *f;
CRYPTO_EX_DATA_FUNCS **storage = NULL;
if (ex_data == NULL)
- return;
+ goto err;
if ((item = def_get_class(class_index)) == NULL)
- return;
+ goto err;
CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth);
if (mx > 0) {
@@ -515,23 +522,23 @@ static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
}
skip:
CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
- if ((mx > 0) && !storage) {
- CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
- return;
- }
for (i = 0; i < mx; i++) {
- if (storage[i] && storage[i]->free_func) {
+ if (storage != NULL)
+ f = storage[i];
+ else {
+ CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA);
+ f = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i);
+ CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA);
+ }
+ if (f != NULL && f->free_func != NULL) {
ptr = CRYPTO_get_ex_data(ad, i);
- storage[i]->free_func(obj, ptr, ad, i,
- storage[i]->argl, storage[i]->argp);
+ f->free_func(obj, ptr, ad, i, f->argl, f->argp);
}
}
- if (storage)
- OPENSSL_free(storage);
- if (ad->sk) {
- sk_void_free(ad->sk);
- ad->sk = NULL;
- }
+ OPENSSL_free(storage);
+ err:
+ sk_void_free(ad->sk);
+ ad->sk = NULL;
}
/********************************************************************/
diff --git a/thirdparty/openssl/crypto/hmac/hm_pmeth.c b/thirdparty/openssl/crypto/hmac/hm_pmeth.c
index 0ffff79cc4..0a59a01cf0 100644
--- a/thirdparty/openssl/crypto/hmac/hm_pmeth.c
+++ b/thirdparty/openssl/crypto/hmac/hm_pmeth.c
@@ -99,15 +99,18 @@ static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src)
sctx = src->data;
dctx = dst->data;
dctx->md = sctx->md;
- HMAC_CTX_init(&dctx->ctx);
if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx))
- return 0;
- if (sctx->ktmp.data) {
+ goto err;
+ if (sctx->ktmp.data != NULL) {
if (!ASN1_OCTET_STRING_set(&dctx->ktmp,
sctx->ktmp.data, sctx->ktmp.length))
- return 0;
+ goto err;
}
return 1;
+ err:
+ HMAC_CTX_cleanup(&dctx->ctx);
+ OPENSSL_free(dctx);
+ return 0;
}
static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx)
diff --git a/thirdparty/openssl/crypto/hmac/hmac.c b/thirdparty/openssl/crypto/hmac/hmac.c
index 51a0a3efcd..213504e85f 100644
--- a/thirdparty/openssl/crypto/hmac/hmac.c
+++ b/thirdparty/openssl/crypto/hmac/hmac.c
@@ -234,7 +234,7 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx)
EVP_MD_CTX_cleanup(&ctx->i_ctx);
EVP_MD_CTX_cleanup(&ctx->o_ctx);
EVP_MD_CTX_cleanup(&ctx->md_ctx);
- memset(ctx, 0, sizeof *ctx);
+ OPENSSL_cleanse(ctx, sizeof *ctx);
}
unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len,
diff --git a/thirdparty/openssl/crypto/include/internal/bn_conf.h b/thirdparty/openssl/crypto/include/internal/bn_conf.h
new file mode 100644
index 0000000000..34bd8b78b4
--- /dev/null
+++ b/thirdparty/openssl/crypto/include/internal/bn_conf.h
@@ -0,0 +1,28 @@
+/* WARNING: do not edit! */
+/* Generated by Makefile from crypto/include/internal/bn_conf.h.in */
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_BN_CONF_H
+# define HEADER_BN_CONF_H
+
+/*
+ * The contents of this file are not used in the UEFI build, as
+ * both 32-bit and 64-bit builds are supported from a single run
+ * of the Configure script.
+ */
+
+/* Should we define BN_DIV2W here? */
+
+/* Only one for the following should be defined */
+#define SIXTY_FOUR_BIT_LONG
+#undef SIXTY_FOUR_BIT
+#undef THIRTY_TWO_BIT
+
+#endif
diff --git a/thirdparty/openssl/crypto/include/internal/dso_conf.h b/thirdparty/openssl/crypto/include/internal/dso_conf.h
new file mode 100644
index 0000000000..7a52dd1f1a
--- /dev/null
+++ b/thirdparty/openssl/crypto/include/internal/dso_conf.h
@@ -0,0 +1,16 @@
+/* WARNING: do not edit! */
+/* Generated by Makefile from crypto/include/internal/dso_conf.h.in */
+/*
+ * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#ifndef HEADER_DSO_CONF_H
+# define HEADER_DSO_CONF_H
+
+# define DSO_EXTENSION ".so"
+#endif
diff --git a/thirdparty/openssl/crypto/install-crypto.com b/thirdparty/openssl/crypto/install-crypto.com
deleted file mode 100755
index af1d75b526..0000000000
--- a/thirdparty/openssl/crypto/install-crypto.com
+++ /dev/null
@@ -1,196 +0,0 @@
-$! INSTALL.COM -- Installs the files in a given directory tree
-$!
-$! Author: Richard Levitte <richard@levitte.org>
-$! Time of creation: 22-MAY-1998 10:13
-$!
-$! Changes by Zoltan Arpadffy <zoli@polarhome.com>
-$!
-$! P1 root of the directory tree
-$! P2 "64" for 64-bit pointers.
-$!
-$!
-$! Announce/identify.
-$!
-$ proc = f$environment( "procedure")
-$ write sys$output "@@@ "+ -
- f$parse( proc, , , "name")+ f$parse( proc, , , "type")
-$!
-$ on error then goto tidy
-$ on control_c then goto tidy
-$!
-$ if (p1 .eqs. "")
-$ then
-$ write sys$output "First argument missing."
-$ write sys$output -
- "It should be the directory where you want things installed."
-$ exit
-$ endif
-$!
-$ if (f$getsyi( "cpu") .lt. 128)
-$ then
-$ arch = "VAX"
-$ else
-$ arch = f$edit( f$getsyi( "arch_name"), "upcase")
-$ if (arch .eqs. "") then arch = "UNK"
-$ endif
-$!
-$ archd = arch
-$ lib32 = "32"
-$ shr = "_SHR32"
-$!
-$ if (p2 .nes. "")
-$ then
-$ if (p2 .eqs. "64")
-$ then
-$ archd = arch+ "_64"
-$ lib32 = ""
-$ shr = "_SHR"
-$ else
-$ if (p2 .nes. "32")
-$ then
-$ write sys$output "Second argument invalid."
-$ write sys$output "It should be "32", "64", or nothing."
-$ exit
-$ endif
-$ endif
-$ endif
-$!
-$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
-$ root_dev = f$parse( root, , , "device", "syntax_only")
-$ root_dir = f$parse( root, , , "directory", "syntax_only") - -
- "[000000." - "][" - "[" - "]"
-$ root = root_dev + "[" + root_dir
-$!
-$ define /nolog wrk_sslroot 'root'.] /trans=conc
-$ define /nolog wrk_sslinclude wrk_sslroot:[include]
-$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
-$!
-$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
- create /directory /log wrk_sslroot:[000000]
-$ if f$parse("wrk_sslinclude:") .eqs. "" then -
- create /directory /log wrk_sslinclude:
-$ if f$parse("wrk_sslxlib:") .eqs. "" then -
- create /directory /log wrk_sslxlib:
-$!
-$ sdirs := , -
- 'archd', -
- objects, -
- md4, md5, sha, mdc2, hmac, ripemd, whrlpool, -
- des, aes, rc2, rc4, idea, bf, cast, camellia, seed, -
- bn, ec, rsa, dsa, ecdsa, dh, ecdh, dso, engine, -
- buffer, bio, stack, lhash, rand, err, -
- evp, asn1, pem, x509, x509v3, conf, txt_db, pkcs7, pkcs12, comp, ocsp, -
- ui, krb5, -
- store, cms, pqueue, ts, jpake
-$!
-$ exheader_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h
-$ exheader_'archd' := opensslconf.h
-$ exheader_objects := objects.h, obj_mac.h
-$ exheader_md2 := md2.h
-$ exheader_md4 := md4.h
-$ exheader_md5 := md5.h
-$ exheader_sha := sha.h
-$ exheader_mdc2 := mdc2.h
-$ exheader_hmac := hmac.h
-$ exheader_ripemd := ripemd.h
-$ exheader_whrlpool := whrlpool.h
-$ exheader_des := des.h, des_old.h
-$ exheader_aes := aes.h
-$ exheader_rc2 := rc2.h
-$ exheader_rc4 := rc4.h
-$ exheader_rc5 := rc5.h
-$ exheader_idea := idea.h
-$ exheader_bf := blowfish.h
-$ exheader_cast := cast.h
-$ exheader_camellia := camellia.h
-$ exheader_seed := seed.h
-$ exheader_modes := modes.h
-$ exheader_bn := bn.h
-$ exheader_ec := ec.h
-$ exheader_rsa := rsa.h
-$ exheader_dsa := dsa.h
-$ exheader_ecdsa := ecdsa.h
-$ exheader_dh := dh.h
-$ exheader_ecdh := ecdh.h
-$ exheader_dso := dso.h
-$ exheader_engine := engine.h
-$ exheader_buffer := buffer.h
-$ exheader_bio := bio.h
-$ exheader_stack := stack.h, safestack.h
-$ exheader_lhash := lhash.h
-$ exheader_rand := rand.h
-$ exheader_err := err.h
-$ exheader_evp := evp.h
-$ exheader_asn1 := asn1.h, asn1_mac.h, asn1t.h
-$ exheader_pem := pem.h, pem2.h
-$ exheader_x509 := x509.h, x509_vfy.h
-$ exheader_x509v3 := x509v3.h
-$ exheader_conf := conf.h, conf_api.h
-$ exheader_txt_db := txt_db.h
-$ exheader_pkcs7 := pkcs7.h
-$ exheader_pkcs12 := pkcs12.h
-$ exheader_comp := comp.h
-$ exheader_ocsp := ocsp.h
-$ exheader_ui := ui.h, ui_compat.h
-$ exheader_krb5 := krb5_asn.h
-$! exheader_store := store.h, str_compat.h
-$ exheader_store := store.h
-$ exheader_cms := cms.h
-$ exheader_pqueue := pqueue.h
-$ exheader_ts := ts.h
-$ exheader_jpake := jpake.h
-$ libs := ssl_libcrypto
-$!
-$ exe_dir := [-.'archd'.exe.crypto]
-$!
-$! Header files.
-$!
-$ i = 0
-$ loop_sdirs:
-$ d = f$edit( f$element( i, ",", sdirs), "trim")
-$ i = i + 1
-$ if d .eqs. "," then goto loop_sdirs_end
-$ tmp = exheader_'d'
-$ if (d .nes. "") then d = "."+ d
-$ copy /protection = w:re ['d']'tmp' wrk_sslinclude: /log
-$ goto loop_sdirs
-$ loop_sdirs_end:
-$!
-$! Object libraries, shareable images.
-$!
-$ i = 0
-$ loop_lib:
-$ e = f$edit( f$element( i, ",", libs), "trim")
-$ i = i + 1
-$ if e .eqs. "," then goto loop_lib_end
-$ set noon
-$ file = exe_dir+ e+ lib32+ ".olb"
-$ if f$search( file) .nes. ""
-$ then
-$ copy /protection = w:re 'file' wrk_sslxlib: /log
-$ endif
-$!
-$ file = exe_dir+ e+ shr+ ".exe"
-$ if f$search( file) .nes. ""
-$ then
-$ copy /protection = w:re 'file' wrk_sslxlib: /log
-$ endif
-$ set on
-$ goto loop_lib
-$ loop_lib_end:
-$!
-$ tidy:
-$!
-$ call deass wrk_sslroot
-$ call deass wrk_sslinclude
-$ call deass wrk_sslxlib
-$!
-$ exit
-$!
-$ deass: subroutine
-$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
-$ then
-$ deassign /process 'p1'
-$ endif
-$ endsubroutine
-$!
diff --git a/thirdparty/openssl/crypto/jpake/jpake.c b/thirdparty/openssl/crypto/jpake/jpake.c
index ebc0975575..2ba75f0172 100644
--- a/thirdparty/openssl/crypto/jpake/jpake.c
+++ b/thirdparty/openssl/crypto/jpake/jpake.c
@@ -116,6 +116,8 @@ JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name,
const BIGNUM *secret)
{
JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx);
+ if (ctx == NULL)
+ return NULL;
JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret);
@@ -151,6 +153,8 @@ static void hashbn(SHA_CTX *sha, const BIGNUM *bn)
size_t l = BN_num_bytes(bn);
unsigned char *bin = OPENSSL_malloc(l);
+ if (bin == NULL)
+ return;
hashlength(sha, l);
BN_bn2bin(bn, bin);
SHA1_Update(sha, bin, l);
diff --git a/thirdparty/openssl/crypto/lhash/lhash.c b/thirdparty/openssl/crypto/lhash/lhash.c
index 53c5c138bb..f20353aea3 100644
--- a/thirdparty/openssl/crypto/lhash/lhash.c
+++ b/thirdparty/openssl/crypto/lhash/lhash.c
@@ -335,8 +335,8 @@ static void expand(_LHASH *lh)
n = (LHASH_NODE **)OPENSSL_realloc(lh->b,
(int)(sizeof(LHASH_NODE *) * j));
if (n == NULL) {
-/* fputs("realloc error in lhash",stderr); */
lh->error++;
+ lh->num_nodes--;
lh->p = 0;
return;
}
diff --git a/thirdparty/openssl/crypto/md2/md2_dgst.c b/thirdparty/openssl/crypto/md2/md2_dgst.c
index 9cd79f8d70..7f5d9ba69b 100644
--- a/thirdparty/openssl/crypto/md2/md2_dgst.c
+++ b/thirdparty/openssl/crypto/md2/md2_dgst.c
@@ -219,6 +219,6 @@ int MD2_Final(unsigned char *md, MD2_CTX *c)
for (i = 0; i < 16; i++)
md[i] = (UCHAR) (p1[i] & 0xff);
- memset((char *)&c, 0, sizeof(c));
+ OPENSSL_cleanse(c, sizeof(*c));
return 1;
}
diff --git a/thirdparty/openssl/crypto/md32_common.h b/thirdparty/openssl/crypto/md32_common.h
index 96828d2693..b5a04bf133 100644
--- a/thirdparty/openssl/crypto/md32_common.h
+++ b/thirdparty/openssl/crypto/md32_common.h
@@ -109,6 +109,8 @@
* <appro@fy.chalmers.se>
*/
+#include <openssl/crypto.h>
+
#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN)
# error "DATA_ORDER must be defined!"
#endif
@@ -329,6 +331,12 @@ int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len)
data += n;
len -= n;
c->num = 0;
+ /*
+ * We use memset rather than OPENSSL_cleanse() here deliberately.
+ * Using OPENSSL_cleanse() here could be a performance issue. It
+ * will get properly cleansed on finalisation so this isn't a
+ * security problem.
+ */
memset(p, 0, HASH_CBLOCK); /* keep it zeroed */
} else {
memcpy(p + n, data, len);
@@ -384,7 +392,7 @@ int HASH_FINAL(unsigned char *md, HASH_CTX *c)
p -= HASH_CBLOCK;
HASH_BLOCK_DATA_ORDER(c, p, 1);
c->num = 0;
- memset(p, 0, HASH_CBLOCK);
+ OPENSSL_cleanse(p, HASH_CBLOCK);
#ifndef HASH_MAKE_STRING
# error "HASH_MAKE_STRING must be defined!"
diff --git a/thirdparty/openssl/crypto/mdc2/mdc2dgst.c b/thirdparty/openssl/crypto/mdc2/mdc2dgst.c
index 6615cf84d7..2dce493633 100644
--- a/thirdparty/openssl/crypto/mdc2/mdc2dgst.c
+++ b/thirdparty/openssl/crypto/mdc2/mdc2dgst.c
@@ -91,7 +91,7 @@ int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len)
i = c->num;
if (i != 0) {
- if (i + len < MDC2_BLOCK) {
+ if (len < MDC2_BLOCK - i) {
/* partial block */
memcpy(&(c->data[i]), in, len);
c->num += (int)len;
diff --git a/thirdparty/openssl/crypto/mem.c b/thirdparty/openssl/crypto/mem.c
index fdad49b76e..dd4c9ce9e0 100644
--- a/thirdparty/openssl/crypto/mem.c
+++ b/thirdparty/openssl/crypto/mem.c
@@ -82,6 +82,14 @@ static void *default_malloc_ex(size_t num, const char *file, int line)
static void *(*malloc_ex_func) (size_t, const char *file, int line)
= default_malloc_ex;
+#ifdef OPENSSL_SYS_VMS
+# if __INITIAL_POINTER_SIZE == 64
+# define realloc _realloc64
+# elif __INITIAL_POINTER_SIZE == 32
+# define realloc _realloc32
+# endif
+#endif
+
static void *(*realloc_func) (void *, size_t) = realloc;
static void *default_realloc_ex(void *str, size_t num,
const char *file, int line)
@@ -92,7 +100,11 @@ static void *default_realloc_ex(void *str, size_t num,
static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
= default_realloc_ex;
-static void (*free_func) (void *) = free;
+#ifdef OPENSSL_SYS_VMS
+ static void (*free_func) (__void_ptr64) = free;
+#else
+ static void (*free_func) (void *) = free;
+#endif
static void *(*malloc_locked_func) (size_t) = malloc;
static void *default_malloc_locked_ex(size_t num, const char *file, int line)
@@ -103,7 +115,11 @@ static void *default_malloc_locked_ex(size_t num, const char *file, int line)
static void *(*malloc_locked_ex_func) (size_t, const char *file, int line)
= default_malloc_locked_ex;
-static void (*free_locked_func) (void *) = free;
+#ifdef OPENSSL_SYS_VMS
+ static void (*free_locked_func) (__void_ptr64) = free;
+#else
+ static void (*free_locked_func) (void *) = free;
+#endif
/* may be changed as long as 'allow_customize_debug' is set */
/* XXX use correct function pointer types */
@@ -134,12 +150,12 @@ static long (*get_debug_options_func) (void) = NULL;
int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
void (*f) (void *))
{
- /* Dummy call just to ensure OPENSSL_init() gets linked in */
- OPENSSL_init();
if (!allow_customize)
return 0;
if ((m == 0) || (r == 0) || (f == 0))
return 0;
+ /* Dummy call just to ensure OPENSSL_init() gets linked in */
+ OPENSSL_init();
malloc_func = m;
malloc_ex_func = default_malloc_ex;
realloc_func = r;
@@ -298,18 +314,6 @@ void *CRYPTO_malloc_locked(int num, const char *file, int line)
if (malloc_debug_func != NULL)
malloc_debug_func(ret, num, file, line, 1);
-#ifndef OPENSSL_CPUID_OBJ
- /*
- * Create a dependency on the value of 'cleanse_ctr' so our memory
- * sanitisation function can't be optimised out. NB: We only do this for
- * >2Kb so the overhead doesn't bother us.
- */
- if (ret && (num > 2048)) {
- extern unsigned char cleanse_ctr;
- ((unsigned char *)ret)[0] = cleanse_ctr;
- }
-#endif
-
return ret;
}
@@ -346,18 +350,6 @@ void *CRYPTO_malloc(int num, const char *file, int line)
if (malloc_debug_func != NULL)
malloc_debug_func(ret, num, file, line, 1);
-#ifndef OPENSSL_CPUID_OBJ
- /*
- * Create a dependency on the value of 'cleanse_ctr' so our memory
- * sanitisation function can't be optimised out. NB: We only do this for
- * >2Kb so the overhead doesn't bother us.
- */
- if (ret && (num > 2048)) {
- extern unsigned char cleanse_ctr;
- ((unsigned char *)ret)[0] = cleanse_ctr;
- }
-#endif
-
return ret;
}
diff --git a/thirdparty/openssl/crypto/mem_clr.c b/thirdparty/openssl/crypto/mem_clr.c
index ab85344eef..579e9d1825 100644
--- a/thirdparty/openssl/crypto/mem_clr.c
+++ b/thirdparty/openssl/crypto/mem_clr.c
@@ -60,22 +60,16 @@
#include <string.h>
#include <openssl/crypto.h>
-unsigned char cleanse_ctr = 0;
+/*
+ * Pointer to memset is volatile so that compiler must de-reference
+ * the pointer and can't assume that it points to any function in
+ * particular (such as memset, which it then might further "optimize")
+ */
+typedef void *(*memset_t)(void *,int,size_t);
+
+static volatile memset_t memset_func = memset;
void OPENSSL_cleanse(void *ptr, size_t len)
{
- unsigned char *p = ptr;
- size_t loop = len, ctr = cleanse_ctr;
-
- if (ptr == NULL)
- return;
-
- while (loop--) {
- *(p++) = (unsigned char)ctr;
- ctr += (17 + ((size_t)p & 0xF));
- }
- p = memchr(ptr, (unsigned char)ctr, len);
- if (p)
- ctr += (63 + (size_t)p);
- cleanse_ctr = (unsigned char)ctr;
+ memset_func(ptr, 0, len);
}
diff --git a/thirdparty/openssl/crypto/modes/ctr128.c b/thirdparty/openssl/crypto/modes/ctr128.c
index bcafd6b6bf..d4b22728e6 100644
--- a/thirdparty/openssl/crypto/modes/ctr128.c
+++ b/thirdparty/openssl/crypto/modes/ctr128.c
@@ -100,7 +100,7 @@ static void ctr128_inc_aligned(unsigned char *counter)
--n;
d = data[n] += c;
/* did addition carry? */
- c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1);
+ c = ((d - c) & ~d) >> (sizeof(size_t) * 8 - 1);
} while (n);
}
#endif
diff --git a/thirdparty/openssl/crypto/o_dir.c b/thirdparty/openssl/crypto/o_dir.c
index f9dbed8711..fb3b2fd8e4 100644
--- a/thirdparty/openssl/crypto/o_dir.c
+++ b/thirdparty/openssl/crypto/o_dir.c
@@ -73,7 +73,8 @@
#include "o_dir.h"
#define LPDIR_H
-#if defined OPENSSL_SYS_UNIX || defined DJGPP
+#if defined OPENSSL_SYS_UNIX || defined DJGPP \
+ || (defined __VMS_VER && __VMS_VER >= 70000000)
# include "LPdir_unix.c"
#elif defined OPENSSL_SYS_VMS
# include "LPdir_vms.c"
diff --git a/thirdparty/openssl/crypto/o_init.c b/thirdparty/openssl/crypto/o_init.c
index 2088388128..185841ea04 100644
--- a/thirdparty/openssl/crypto/o_init.c
+++ b/thirdparty/openssl/crypto/o_init.c
@@ -73,6 +73,9 @@ void OPENSSL_init(void)
done = 1;
#ifdef OPENSSL_FIPS
FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock);
+# ifndef OPENSSL_NO_DEPRECATED
+ FIPS_crypto_set_id_callback(CRYPTO_thread_id);
+# endif
FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata);
FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free);
RAND_init_fips();
diff --git a/thirdparty/openssl/crypto/o_str.c b/thirdparty/openssl/crypto/o_str.c
index c10842300d..1854798e2c 100644
--- a/thirdparty/openssl/crypto/o_str.c
+++ b/thirdparty/openssl/crypto/o_str.c
@@ -59,16 +59,15 @@
#include <ctype.h>
#include <e_os.h>
+// -- GODOT start --
+#include <openssl/opensslconf.h>
+// -- GODOT end --
#include "o_str.h"
#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
!defined(OPENSSL_SYSNAME_WIN32) && !defined(OPENSSL_SYSNAME_WINCE) && \
!defined(NETWARE_CLIB)
-#ifdef _WIN32
-#include <string.h>
-#else
-#include <strings.h>
-#endif
+# include <strings.h>
#endif
int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n)
diff --git a/thirdparty/openssl/crypto/o_time.c b/thirdparty/openssl/crypto/o_time.c
index 635dae184d..04d805d9a9 100644..100755
--- a/thirdparty/openssl/crypto/o_time.c
+++ b/thirdparty/openssl/crypto/o_time.c
@@ -78,18 +78,36 @@
# include <descrip.h>
# include <stdlib.h>
# endif /* ndef VMS_GMTIME_OK */
-#endif
+
+
+/*
+ * Needed to pick up the correct definitions and declarations in some of the
+ * DEC C Header Files (*.H).
+ */
+# define __NEW_STARLET 1
+
+# if (defined(__alpha) || defined(__ia64))
+# include <iledef.h>
+# else
+
+/* VAX */
+typedef struct _ile3 { /* Copied from ILEDEF.H for Alpha */
+# pragma __nomember_alignment
+ unsigned short int ile3$w_length; /* Length of buffer in bytes */
+ unsigned short int ile3$w_code; /* Item code value */
+ void *ile3$ps_bufaddr; /* Buffer address */
+ unsigned short int *ile3$ps_retlen_addr; /* Address of word for returned length */
+} ILE3;
+# endif /* alpha || ia64 */
+#endif /* OPENSSL_SYS_VMS */
struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
{
struct tm *ts = NULL;
#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS)
- /*
- * should return &data, but doesn't on some systems, so we don't even
- * look at the return value
- */
- gmtime_r(timer, result);
+ if (gmtime_r(timer, result) == NULL)
+ return NULL;
ts = result;
#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK)
ts = gmtime(timer);
@@ -105,26 +123,42 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL");
char logvalue[256];
unsigned int reslen = 0;
- struct {
- short buflen;
- short code;
- void *bufaddr;
- unsigned int *reslen;
- } itemlist[] = {
- {
- 0, LNM$_STRING, 0, 0
- },
- {
- 0, 0, 0, 0
- },
- };
+# if __INITIAL_POINTER_SIZE == 64
+ ILEB_64 itemlist[2], *pitem;
+# else
+ ILE3 itemlist[2], *pitem;
+# endif
int status;
time_t t;
+
+ /*
+ * Setup an itemlist for the call to $TRNLNM - Translate Logical Name.
+ */
+ pitem = itemlist;
+
+# if __INITIAL_POINTER_SIZE == 64
+ pitem->ileb_64$w_mbo = 1;
+ pitem->ileb_64$w_code = LNM$_STRING;
+ pitem->ileb_64$l_mbmo = -1;
+ pitem->ileb_64$q_length = sizeof (logvalue);
+ pitem->ileb_64$pq_bufaddr = logvalue;
+ pitem->ileb_64$pq_retlen_addr = (unsigned __int64 *) &reslen;
+ pitem++;
+ /* Last item of the item list is null terminated */
+ pitem->ileb_64$q_length = pitem->ileb_64$w_code = 0;
+# else
+ pitem->ile3$w_length = sizeof (logvalue);
+ pitem->ile3$w_code = LNM$_STRING;
+ pitem->ile3$ps_bufaddr = logvalue;
+ pitem->ile3$ps_retlen_addr = (unsigned short int *) &reslen;
+ pitem++;
+ /* Last item of the item list is null terminated */
+ pitem->ile3$w_length = pitem->ile3$w_code = 0;
+# endif
+
+
/* Get the value for SYS$TIMEZONE_DIFFERENTIAL */
- itemlist[0].buflen = sizeof(logvalue);
- itemlist[0].bufaddr = logvalue;
- itemlist[0].reslen = &reslen;
status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist);
if (!(status & 1))
return NULL;
@@ -132,7 +166,7 @@ struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result)
t = *timer;
-/* The following is extracted from the DEC C header time.h */
+ /* The following is extracted from the DEC C header time.h */
/*
** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime
** have two implementations. One implementation is provided
diff --git a/thirdparty/openssl/crypto/objects/o_names.c b/thirdparty/openssl/crypto/objects/o_names.c
index 24859926ac..f106905ffa 100644
--- a/thirdparty/openssl/crypto/objects/o_names.c
+++ b/thirdparty/openssl/crypto/objects/o_names.c
@@ -191,7 +191,7 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME));
if (onp == NULL) {
/* ERROR */
- return (0);
+ return 0;
}
onp->name = name;
@@ -216,10 +216,11 @@ int OBJ_NAME_add(const char *name, int type, const char *data)
} else {
if (lh_OBJ_NAME_error(names_lh)) {
/* ERROR */
- return (0);
+ OPENSSL_free(onp);
+ return 0;
}
}
- return (1);
+ return 1;
}
int OBJ_NAME_remove(const char *name, int type)
diff --git a/thirdparty/openssl/crypto/ocsp/ocsp_cl.c b/thirdparty/openssl/crypto/ocsp/ocsp_cl.c
index b3612c8dfc..fca7db0b71 100644
--- a/thirdparty/openssl/crypto/ocsp/ocsp_cl.c
+++ b/thirdparty/openssl/crypto/ocsp/ocsp_cl.c
@@ -93,8 +93,10 @@ OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid)
if (one->reqCert)
OCSP_CERTID_free(one->reqCert);
one->reqCert = cid;
- if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one))
+ if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) {
+ one->reqCert = NULL; /* do not free on error */
goto err;
+ }
return one;
err:
OCSP_ONEREQ_free(one);
diff --git a/thirdparty/openssl/crypto/ocsp/ocsp_ext.c b/thirdparty/openssl/crypto/ocsp/ocsp_ext.c
index c19648c732..55af31b573 100644
--- a/thirdparty/openssl/crypto/ocsp/ocsp_ext.c
+++ b/thirdparty/openssl/crypto/ocsp/ocsp_ext.c
@@ -361,7 +361,7 @@ static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts,
ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL);
if (val)
memcpy(tmpval, val, len);
- else if (RAND_pseudo_bytes(tmpval, len) < 0)
+ else if (RAND_bytes(tmpval, len) <= 0)
goto err;
if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce,
&os, 0, X509V3_ADD_REPLACE))
diff --git a/thirdparty/openssl/crypto/ocsp/ocsp_lib.c b/thirdparty/openssl/crypto/ocsp/ocsp_lib.c
index cabf53933a..ff781e56e7 100644
--- a/thirdparty/openssl/crypto/ocsp/ocsp_lib.c
+++ b/thirdparty/openssl/crypto/ocsp/ocsp_lib.c
@@ -271,12 +271,18 @@ int OCSP_parse_url(const char *url, char **phost, char **pport, char **ppath,
err:
if (buf)
OPENSSL_free(buf);
- if (*ppath)
+ if (*ppath) {
OPENSSL_free(*ppath);
- if (*pport)
+ *ppath = NULL;
+ }
+ if (*pport) {
OPENSSL_free(*pport);
- if (*phost)
+ *pport = NULL;
+ }
+ if (*phost) {
OPENSSL_free(*phost);
+ *phost = NULL;
+ }
return 0;
}
diff --git a/thirdparty/openssl/crypto/opensslconf.h.in b/thirdparty/openssl/crypto/opensslconf.h.in
deleted file mode 100644
index 7a1c85d6ec..0000000000
--- a/thirdparty/openssl/crypto/opensslconf.h.in
+++ /dev/null
@@ -1,154 +0,0 @@
-/* crypto/opensslconf.h.in */
-
-/* Generate 80386 code? */
-#undef I386_ONLY
-
-#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */
-#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR)
-#define ENGINESDIR "/usr/local/lib/engines"
-#define OPENSSLDIR "/usr/local/ssl"
-#endif
-#endif
-
-#undef OPENSSL_UNISTD
-#define OPENSSL_UNISTD <unistd.h>
-
-#undef OPENSSL_EXPORT_VAR_AS_FUNCTION
-
-#if defined(HEADER_IDEA_H) && !defined(IDEA_INT)
-#define IDEA_INT unsigned int
-#endif
-
-#if defined(HEADER_MD2_H) && !defined(MD2_INT)
-#define MD2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC2_H) && !defined(RC2_INT)
-/* I need to put in a mod for the alpha - eay */
-#define RC2_INT unsigned int
-#endif
-
-#if defined(HEADER_RC4_H)
-#if !defined(RC4_INT)
-/* using int types make the structure larger but make the code faster
- * on most boxes I have tested - up to %20 faster. */
-/*
- * I don't know what does "most" mean, but declaring "int" is a must on:
- * - Intel P6 because partial register stalls are very expensive;
- * - elder Alpha because it lacks byte load/store instructions;
- */
-#define RC4_INT unsigned int
-#endif
-#if !defined(RC4_CHUNK)
-/*
- * This enables code handling data aligned at natural CPU word
- * boundary. See crypto/rc4/rc4_enc.c for further details.
- */
-#undef RC4_CHUNK
-#endif
-#endif
-
-#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG)
-/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
- * %20 speed up (longs are 8 bytes, int's are 4). */
-#ifndef DES_LONG
-#define DES_LONG unsigned long
-#endif
-#endif
-
-#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
-#define CONFIG_HEADER_BN_H
-#undef BN_LLONG
-
-/* Should we define BN_DIV2W here? */
-
-/* Only one for the following should be defined */
-#undef SIXTY_FOUR_BIT_LONG
-#undef SIXTY_FOUR_BIT
-#define THIRTY_TWO_BIT
-#endif
-
-#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
-#define CONFIG_HEADER_RC4_LOCL_H
-/* if this is defined data[i] is used instead of *data, this is a %20
- * speedup on x86 */
-#undef RC4_INDEX
-#endif
-
-#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H)
-#define CONFIG_HEADER_BF_LOCL_H
-#undef BF_PTR
-#endif /* HEADER_BF_LOCL_H */
-
-#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H)
-#define CONFIG_HEADER_DES_LOCL_H
-#ifndef DES_DEFAULT_OPTIONS
-/* the following is tweaked from a config script, that is why it is a
- * protected undef/define */
-#ifndef DES_PTR
-#undef DES_PTR
-#endif
-
-/* This helps C compiler generate the correct code for multiple functional
- * units. It reduces register dependancies at the expense of 2 more
- * registers */
-#ifndef DES_RISC1
-#undef DES_RISC1
-#endif
-
-#ifndef DES_RISC2
-#undef DES_RISC2
-#endif
-
-#if defined(DES_RISC1) && defined(DES_RISC2)
-#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!!
-#endif
-
-/* Unroll the inner loop, this sometimes helps, sometimes hinders.
- * Very mucy CPU dependant */
-#ifndef DES_UNROLL
-#undef DES_UNROLL
-#endif
-
-/* These default values were supplied by
- * Peter Gutman <pgut001@cs.auckland.ac.nz>
- * They are only used if nothing else has been defined */
-#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL)
-/* Special defines which change the way the code is built depending on the
- CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find
- even newer MIPS CPU's, but at the moment one size fits all for
- optimization options. Older Sparc's work better with only UNROLL, but
- there's no way to tell at compile time what it is you're running on */
-
-#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#elif defined( __ultrix ) /* Older MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined( __osf1__ ) /* Alpha */
-# define DES_PTR
-# define DES_RISC2
-#elif defined ( _AIX ) /* RS6000 */
- /* Unknown */
-#elif defined( __hpux ) /* HP-PA */
- /* Unknown */
-#elif defined( __aux ) /* 68K */
- /* Unknown */
-#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */
-# define DES_UNROLL
-#elif defined( __sgi ) /* Newer MIPS */
-# define DES_PTR
-# define DES_RISC2
-# define DES_UNROLL
-#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */
-# define DES_PTR
-# define DES_RISC1
-# define DES_UNROLL
-#endif /* Systems-specific speed defines */
-#endif
-
-#endif /* DES_DEFAULT_OPTIONS */
-#endif /* HEADER_DES_LOCL_H */
diff --git a/thirdparty/openssl/crypto/pem/pem_err.c b/thirdparty/openssl/crypto/pem/pem_err.c
index e1f4fdb432..4e5f8e936c 100644
--- a/thirdparty/openssl/crypto/pem/pem_err.c
+++ b/thirdparty/openssl/crypto/pem/pem_err.c
@@ -1,6 +1,6 @@
/* crypto/pem/pem_err.c */
/* ====================================================================
- * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -132,6 +132,7 @@ static ERR_STRING_DATA PEM_str_reasons[] = {
"expecting private key blob"},
{ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB),
"expecting public key blob"},
+ {ERR_REASON(PEM_R_HEADER_TOO_LONG), "header too long"},
{ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"},
{ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR),
"keyblob header parse error"},
diff --git a/thirdparty/openssl/crypto/pem/pem_lib.c b/thirdparty/openssl/crypto/pem/pem_lib.c
index fe881d6641..c82b3c0ae2 100644
--- a/thirdparty/openssl/crypto/pem/pem_lib.c
+++ b/thirdparty/openssl/crypto/pem/pem_lib.c
@@ -105,17 +105,23 @@ int PEM_def_callback(char *buf, int num, int w, void *key)
prompt = "Enter PEM pass phrase:";
for (;;) {
- i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w);
+ /*
+ * We assume that w == 0 means decryption,
+ * while w == 1 means encryption
+ */
+ int min_len = w ? MIN_LENGTH : 0;
+
+ i = EVP_read_pw_string_min(buf, min_len, num, prompt, w);
if (i != 0) {
PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD);
memset(buf, 0, (unsigned int)num);
return (-1);
}
j = strlen(buf);
- if (j < MIN_LENGTH) {
+ if (min_len && j < min_len) {
fprintf(stderr,
"phrase is too short, needs to be at least %d chars\n",
- MIN_LENGTH);
+ min_len);
} else
break;
}
@@ -387,7 +393,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
}
RAND_add(data, i, 0); /* put in the RSA key. */
OPENSSL_assert(enc->iv_len <= (int)sizeof(iv));
- if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) /* Generate a salt */
+ if (RAND_bytes(iv, enc->iv_len) <= 0) /* Generate a salt */
goto err;
/*
* The 'iv' is used as the iv and as a salt. It is NOT taken from
diff --git a/thirdparty/openssl/crypto/pem/pvkfmt.c b/thirdparty/openssl/crypto/pem/pvkfmt.c
index 61864468f6..1ce5a1e319 100644
--- a/thirdparty/openssl/crypto/pem/pvkfmt.c
+++ b/thirdparty/openssl/crypto/pem/pvkfmt.c
@@ -127,6 +127,9 @@ static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r)
# define MS_KEYTYPE_KEYX 0x1
# define MS_KEYTYPE_SIGN 0x2
+/* Maximum length of a blob after header */
+# define BLOB_MAX_LENGTH 102400
+
/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */
# define MS_PVKMAGIC 0xb0b5f11eL
/* Salt length for PVK files */
@@ -272,6 +275,10 @@ static EVP_PKEY *do_b2i_bio(BIO *in, int ispub)
return NULL;
length = blob_length(bitlen, isdss, ispub);
+ if (length > BLOB_MAX_LENGTH) {
+ PEMerr(PEM_F_DO_B2I_BIO, PEM_R_HEADER_TOO_LONG);
+ return NULL;
+ }
buf = OPENSSL_malloc(length);
if (!buf) {
PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE);
diff --git a/thirdparty/openssl/crypto/pkcs12/p12_mutl.c b/thirdparty/openssl/crypto/pkcs12/p12_mutl.c
index a9277827ff..b1f7381a6f 100644
--- a/thirdparty/openssl/crypto/pkcs12/p12_mutl.c
+++ b/thirdparty/openssl/crypto/pkcs12/p12_mutl.c
@@ -159,7 +159,10 @@ int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen,
int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
const EVP_MD *md_type)
{
- if (!(p12->mac = PKCS12_MAC_DATA_new()))
+ PKCS12_MAC_DATA_free(p12->mac);
+ p12->mac = NULL;
+
+ if ((p12->mac = PKCS12_MAC_DATA_new()) == NULL)
return PKCS12_ERROR;
if (iter > 1) {
if (!(p12->mac->iter = M_ASN1_INTEGER_new())) {
@@ -179,7 +182,7 @@ int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen,
}
p12->mac->salt->length = saltlen;
if (!salt) {
- if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0)
+ if (RAND_bytes(p12->mac->salt->data, saltlen) <= 0)
return 0;
} else
memcpy(p12->mac->salt->data, salt, saltlen);
diff --git a/thirdparty/openssl/crypto/pkcs12/p12_npas.c b/thirdparty/openssl/crypto/pkcs12/p12_npas.c
index a89b61abab..9e8ebb2a78 100644
--- a/thirdparty/openssl/crypto/pkcs12/p12_npas.c
+++ b/thirdparty/openssl/crypto/pkcs12/p12_npas.c
@@ -66,17 +66,18 @@
/* PKCS#12 password change routine */
-static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass);
-static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
- char *newpass);
-static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass);
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass);
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+ const char *newpass);
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+ const char *newpass);
static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen);
/*
* Change the password on a PKCS#12 structure.
*/
-int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass)
{
/* Check for NULL PKCS12 structure */
@@ -103,20 +104,21 @@ int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass)
/* Parse the outer PKCS#12 structure */
-static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
+static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
{
- STACK_OF(PKCS7) *asafes, *newsafes;
- STACK_OF(PKCS12_SAFEBAG) *bags;
+ STACK_OF(PKCS7) *asafes = NULL, *newsafes = NULL;
+ STACK_OF(PKCS12_SAFEBAG) *bags = NULL;
int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0;
PKCS7 *p7, *p7new;
- ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL;
+ ASN1_OCTET_STRING *p12_data_tmp = NULL;
unsigned char mac[EVP_MAX_MD_SIZE];
unsigned int maclen;
+ int rv = 0;
- if (!(asafes = PKCS12_unpack_authsafes(p12)))
- return 0;
- if (!(newsafes = sk_PKCS7_new_null()))
- return 0;
+ if ((asafes = PKCS12_unpack_authsafes(p12)) == NULL)
+ goto err;
+ if ((newsafes = sk_PKCS7_new_null()) == NULL)
+ goto err;
for (i = 0; i < sk_PKCS7_num(asafes); i++) {
p7 = sk_PKCS7_value(asafes, i);
bagnid = OBJ_obj2nid(p7->type);
@@ -125,67 +127,57 @@ static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass)
} else if (bagnid == NID_pkcs7_encrypted) {
bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
if (!alg_get(p7->d.encrypted->enc_data->algorithm,
- &pbe_nid, &pbe_iter, &pbe_saltlen)) {
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- bags = NULL;
- }
- } else
+ &pbe_nid, &pbe_iter, &pbe_saltlen))
+ goto err;
+ } else {
continue;
- if (!bags) {
- sk_PKCS7_pop_free(asafes, PKCS7_free);
- return 0;
- }
- if (!newpass_bags(bags, oldpass, newpass)) {
- sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- sk_PKCS7_pop_free(asafes, PKCS7_free);
- return 0;
}
+ if (bags == NULL)
+ goto err;
+ if (!newpass_bags(bags, oldpass, newpass))
+ goto err;
/* Repack bag in same form with new password */
if (bagnid == NID_pkcs7_data)
p7new = PKCS12_pack_p7data(bags);
else
p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL,
pbe_saltlen, pbe_iter, bags);
+ if (!p7new || !sk_PKCS7_push(newsafes, p7new))
+ goto err;
sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
- if (!p7new) {
- sk_PKCS7_pop_free(asafes, PKCS7_free);
- return 0;
- }
- sk_PKCS7_push(newsafes, p7new);
+ bags = NULL;
}
- sk_PKCS7_pop_free(asafes, PKCS7_free);
/* Repack safe: save old safe in case of error */
p12_data_tmp = p12->authsafes->d.data;
- if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new()))
- goto saferr;
+ if ((p12->authsafes->d.data = ASN1_OCTET_STRING_new()) == NULL)
+ goto err;
if (!PKCS12_pack_authsafes(p12, newsafes))
- goto saferr;
-
+ goto err;
if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen))
- goto saferr;
- if (!(macnew = ASN1_OCTET_STRING_new()))
- goto saferr;
- if (!ASN1_OCTET_STRING_set(macnew, mac, maclen))
- goto saferr;
- ASN1_OCTET_STRING_free(p12->mac->dinfo->digest);
- p12->mac->dinfo->digest = macnew;
- ASN1_OCTET_STRING_free(p12_data_tmp);
-
- return 1;
-
- saferr:
- /* Restore old safe */
- ASN1_OCTET_STRING_free(p12->authsafes->d.data);
- ASN1_OCTET_STRING_free(macnew);
- p12->authsafes->d.data = p12_data_tmp;
- return 0;
-
+ goto err;
+ if (!ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))
+ goto err;
+
+ rv = 1;
+
+err:
+ /* Restore old safe if necessary */
+ if (rv == 1) {
+ ASN1_OCTET_STRING_free(p12_data_tmp);
+ } else if (p12_data_tmp != NULL) {
+ ASN1_OCTET_STRING_free(p12->authsafes->d.data);
+ p12->authsafes->d.data = p12_data_tmp;
+ }
+ sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free);
+ sk_PKCS7_pop_free(asafes, PKCS7_free);
+ sk_PKCS7_pop_free(newsafes, PKCS7_free);
+ return rv;
}
-static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
- char *newpass)
+static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *oldpass,
+ const char *newpass)
{
int i;
for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) {
@@ -197,7 +189,8 @@ static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass,
/* Change password of safebag: only needs handle shrouded keybags */
-static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
+static int newpass_bag(PKCS12_SAFEBAG *bag, const char *oldpass,
+ const char *newpass)
{
PKCS8_PRIV_KEY_INFO *p8;
X509_SIG *p8new;
@@ -210,8 +203,10 @@ static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass)
return 0;
if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen))
return 0;
- if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
- p8_iter, p8)))
+ p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen,
+ p8_iter, p8);
+ PKCS8_PRIV_KEY_INFO_free(p8);
+ if (p8new == NULL)
return 0;
X509_SIG_free(bag->value.shkeybag);
bag->value.shkeybag = p8new;
diff --git a/thirdparty/openssl/crypto/pkcs12/p12_utl.c b/thirdparty/openssl/crypto/pkcs12/p12_utl.c
index a0b992eab6..e466f762ff 100644
--- a/thirdparty/openssl/crypto/pkcs12/p12_utl.c
+++ b/thirdparty/openssl/crypto/pkcs12/p12_utl.c
@@ -91,6 +91,10 @@ char *OPENSSL_uni2asc(unsigned char *uni, int unilen)
{
int asclen, i;
char *asctmp;
+
+ /* string must contain an even number of bytes */
+ if (unilen & 1)
+ return NULL;
asclen = unilen / 2;
/* If no terminating zero allow for one */
if (!unilen || uni[unilen - 1])
diff --git a/thirdparty/openssl/crypto/pkcs7/pk7_doit.c b/thirdparty/openssl/crypto/pkcs7/pk7_doit.c
index 946aaa6543..6cf8253bc2 100644
--- a/thirdparty/openssl/crypto/pkcs7/pk7_doit.c
+++ b/thirdparty/openssl/crypto/pkcs7/pk7_doit.c
@@ -340,7 +340,7 @@ BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio)
ivlen = EVP_CIPHER_iv_length(evp_cipher);
xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher));
if (ivlen > 0)
- if (RAND_pseudo_bytes(iv, ivlen) <= 0)
+ if (RAND_bytes(iv, ivlen) <= 0)
goto err;
if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0)
goto err;
@@ -642,6 +642,8 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert)
} else {
# if 0
bio = BIO_new(BIO_s_mem());
+ if (bio == NULL)
+ goto err;
/*
* We need to set this so that when we have read all the data, the
* encrypt BIO, if present, will read EOF and encode the last few
diff --git a/thirdparty/openssl/crypto/ppccap.c b/thirdparty/openssl/crypto/ppccap.c
index 74af4732b5..60566b1a5f 100644
--- a/thirdparty/openssl/crypto/ppccap.c
+++ b/thirdparty/openssl/crypto/ppccap.c
@@ -7,6 +7,10 @@
#if defined(__linux) || defined(_AIX)
# include <sys/utsname.h>
#endif
+#if defined(__APPLE__) && defined(__MACH__)
+# include <sys/types.h>
+# include <sys/sysctl.h>
+#endif
#include <openssl/crypto.h>
#include <openssl/bn.h>
@@ -123,6 +127,26 @@ void OPENSSL_cpuid_setup(void)
}
#endif
+#if defined(__APPLE__) && defined(__MACH__)
+ {
+ int val;
+ size_t len = sizeof(val);
+
+ if (sysctlbyname("hw.optional.64bitops", &val, &len, NULL, 0) == 0) {
+ if (val)
+ OPENSSL_ppccap_P |= PPC_FPU64;
+ }
+
+ len = sizeof(val);
+ if (sysctlbyname("hw.optional.altivec", &val, &len, NULL, 0) == 0) {
+ if (val)
+ OPENSSL_ppccap_P |= PPC_ALTIVEC;
+ }
+
+ return;
+ }
+#endif
+
memset(&ill_act, 0, sizeof(ill_act));
ill_act.sa_handler = ill_handler;
ill_act.sa_mask = all_masked;
diff --git a/thirdparty/openssl/crypto/rand/md_rand.c b/thirdparty/openssl/crypto/rand/md_rand.c
index 5c13d57765..29e465b075 100644
--- a/thirdparty/openssl/crypto/rand/md_rand.c
+++ b/thirdparty/openssl/crypto/rand/md_rand.c
@@ -136,7 +136,7 @@
/* #define PREDICT 1 */
#define STATE_SIZE 1023
-static int state_num = 0, state_index = 0;
+static size_t state_num = 0, state_index = 0;
static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
static unsigned char md[MD_DIGEST_LENGTH];
static long md_count[2] = { 0, 0 };
@@ -266,17 +266,21 @@ static void ssleay_rand_add(const void *buf, int num, double add)
j = (num - i);
j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
- MD_Init(&m);
- MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ if (!MD_Init(&m) ||
+ !MD_Update(&m, local_md, MD_DIGEST_LENGTH))
+ goto err;
k = (st_idx + j) - STATE_SIZE;
if (k > 0) {
- MD_Update(&m, &(state[st_idx]), j - k);
- MD_Update(&m, &(state[0]), k);
+ if (!MD_Update(&m, &(state[st_idx]), j - k) ||
+ !MD_Update(&m, &(state[0]), k))
+ goto err;
} else
- MD_Update(&m, &(state[st_idx]), j);
+ if (!MD_Update(&m, &(state[st_idx]), j))
+ goto err;
/* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
- MD_Update(&m, buf, j);
+ if (!MD_Update(&m, buf, j))
+ goto err;
/*
* We know that line may cause programs such as purify and valgrind
* to complain about use of uninitialized data. The problem is not,
@@ -285,8 +289,9 @@ static void ssleay_rand_add(const void *buf, int num, double add)
* insecure keys.
*/
- MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
- MD_Final(&m, local_md);
+ if (!MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) ||
+ !MD_Final(&m, local_md))
+ goto err;
md_c[1]++;
buf = (const char *)buf + j;
@@ -305,7 +310,6 @@ static void ssleay_rand_add(const void *buf, int num, double add)
st_idx = 0;
}
}
- EVP_MD_CTX_cleanup(&m);
if (!do_not_lock)
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
@@ -326,6 +330,9 @@ static void ssleay_rand_add(const void *buf, int num, double add)
#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
assert(md_c[1] == md_count[1]);
#endif
+
+ err:
+ EVP_MD_CTX_cleanup(&m);
}
static void ssleay_rand_seed(const void *buf, int num)
@@ -336,8 +343,8 @@ static void ssleay_rand_seed(const void *buf, int num)
int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
{
static volatile int stirred_pool = 0;
- int i, j, k, st_num, st_idx;
- int num_ceil;
+ int i, j, k;
+ size_t num_ceil, st_idx, st_num;
int ok;
long md_c[2];
unsigned char local_md[MD_DIGEST_LENGTH];
@@ -469,15 +476,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
/* num_ceil -= MD_DIGEST_LENGTH/2 */
j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
num -= j;
- MD_Init(&m);
+ if (!MD_Init(&m))
+ goto err;
#ifndef GETPID_IS_MEANINGLESS
if (curr_pid) { /* just in the first iteration to save time */
- MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid);
+ if (!MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid))
+ goto err;
curr_pid = 0;
}
#endif
- MD_Update(&m, local_md, MD_DIGEST_LENGTH);
- MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
+ if (!MD_Update(&m, local_md, MD_DIGEST_LENGTH) ||
+ !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
+ goto err;
#ifndef PURIFY /* purify complains */
/*
@@ -487,16 +497,21 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
* builds it is not used: the removal of such a small source of
* entropy has negligible impact on security.
*/
- MD_Update(&m, buf, j);
+ if (!MD_Update(&m, buf, j))
+ goto err;
#endif
k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
if (k > 0) {
- MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k);
- MD_Update(&m, &(state[0]), k);
- } else
- MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2);
- MD_Final(&m, local_md);
+ if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k) ||
+ !MD_Update(&m, &(state[0]), k))
+ goto err;
+ } else {
+ if (!MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
+ goto err;
+ }
+ if (!MD_Final(&m, local_md))
+ goto err;
for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
/* may compete with other threads */
@@ -508,13 +523,18 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
}
}
- MD_Init(&m);
- MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c));
- MD_Update(&m, local_md, MD_DIGEST_LENGTH);
+ if (!MD_Init(&m) ||
+ !MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)) ||
+ !MD_Update(&m, local_md, MD_DIGEST_LENGTH))
+ goto err;
if (lock)
CRYPTO_w_lock(CRYPTO_LOCK_RAND);
- MD_Update(&m, md, MD_DIGEST_LENGTH);
- MD_Final(&m, md);
+ if (!MD_Update(&m, md, MD_DIGEST_LENGTH) ||
+ !MD_Final(&m, md)) {
+ if (lock)
+ CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
+ goto err;
+ }
if (lock)
CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
@@ -529,6 +549,10 @@ int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock)
"http://www.openssl.org/support/faq.html");
return (0);
}
+
+ err:
+ EVP_MD_CTX_cleanup(&m);
+ return (0);
}
static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
diff --git a/thirdparty/openssl/crypto/rand/rand_unix.c b/thirdparty/openssl/crypto/rand/rand_unix.c
index 266111edda..6c5b65da00 100644
--- a/thirdparty/openssl/crypto/rand/rand_unix.c
+++ b/thirdparty/openssl/crypto/rand/rand_unix.c
@@ -235,7 +235,7 @@ int RAND_poll(void)
rnd >>= 8;
}
RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
- memset(buf, 0, sizeof(buf));
+ OPENSSL_cleanse(buf, sizeof(buf));
return 1;
}
diff --git a/thirdparty/openssl/crypto/rand/rand_vms.c b/thirdparty/openssl/crypto/rand/rand_vms.c
index 0e10c363e2..be4ff4cc87 100644..100755
--- a/thirdparty/openssl/crypto/rand/rand_vms.c
+++ b/thirdparty/openssl/crypto/rand/rand_vms.c
@@ -3,6 +3,11 @@
* Written by Richard Levitte <richard@levitte.org> for the OpenSSL project
* 2000.
*/
+/*
+ * Modified by VMS Software, Inc (2016)
+ * Eliminate looping through all processes (performance)
+ * Add additional randomizations using rand() function
+ */
/* ====================================================================
* Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
*
@@ -61,11 +66,11 @@
#include "rand_lcl.h"
#if defined(OPENSSL_SYS_VMS)
-
# include <descrip.h>
# include <jpidef.h>
# include <ssdef.h>
# include <starlet.h>
+# include <efndef>
# ifdef __DECC
# pragma message disable DOLLARID
# endif
@@ -83,77 +88,93 @@
# endif /* __INITIAL_POINTER_SIZE == 64 [else] */
static struct items_data_st {
- short length, code; /* length is amount of bytes */
+ short length, code; /* length is number of bytes */
} items_data[] = {
- {
- 4, JPI$_BUFIO
- },
- {
- 4, JPI$_CPUTIM
- },
- {
- 4, JPI$_DIRIO
- },
- {
- 8, JPI$_LOGINTIM
- },
- {
- 4, JPI$_PAGEFLTS
- },
- {
- 4, JPI$_PID
- },
- {
- 4, JPI$_WSSIZE
- },
- {
- 0, 0
- }
+ {4, JPI$_BUFIO},
+ {4, JPI$_CPUTIM},
+ {4, JPI$_DIRIO},
+ {4, JPI$_IMAGECOUNT},
+ {8, JPI$_LAST_LOGIN_I},
+ {8, JPI$_LOGINTIM},
+ {4, JPI$_PAGEFLTS},
+ {4, JPI$_PID},
+ {4, JPI$_PPGCNT},
+ {4, JPI$_WSPEAK},
+ {4, JPI$_FINALEXC},
+ {0, 0} /* zero terminated */
};
int RAND_poll(void)
{
- long pid, iosb[2];
- int status = 0;
+
+ /* determine the number of items in the JPI array */
+
+ struct items_data_st item_entry;
+ int item_entry_count = sizeof(items_data)/sizeof(item_entry);
+
+ /* Create the JPI itemlist array to hold item_data content */
+
struct {
short length, code;
- long *buffer;
+ int *buffer;
int *retlen;
- } item[32], *pitem;
- unsigned char data_buffer[256];
- short total_length = 0;
- struct items_data_st *pitems_data;
+ } item[item_entry_count], *pitem; /* number of entries in items_data */
+ struct items_data_st *pitems_data;
pitems_data = items_data;
pitem = item;
+ int data_buffer[(item_entry_count*2)+4]; /* 8 bytes per entry max */
+ int iosb[2];
+ int sys_time[2];
+ int *ptr;
+ int i, j ;
+ int tmp_length = 0;
+ int total_length = 0;
+
+ /* Setup itemlist for GETJPI */
- /* Setup */
- while (pitems_data->length && (total_length + pitems_data->length <= 256)) {
+ while (pitems_data->length) {
pitem->length = pitems_data->length;
- pitem->code = pitems_data->code;
- pitem->buffer = (long *)&data_buffer[total_length];
+ pitem->code = pitems_data->code;
+ pitem->buffer = &data_buffer[total_length];
pitem->retlen = 0;
- total_length += pitems_data->length;
+ /* total_length is in longwords */
+ total_length += pitems_data->length/4;
pitems_data++;
pitem ++;
}
pitem->length = pitem->code = 0;
- /*
- * Scan through all the processes in the system and add entropy with
- * results from the processes that were possible to look at.
- * However, view the information as only half trustable.
- */
- pid = -1; /* search context */
- while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
- != SS$_NOMOREPROC) {
- if (status == SS$_NORMAL) {
- RAND_add((PTR_T) data_buffer, total_length, total_length / 2);
+ /* Fill data_buffer with various info bits from this process */
+ /* and twist that data to seed the SSL random number init */
+
+ if (sys$getjpiw(EFN$C_ENF, NULL, NULL, item, &iosb, 0, 0) == SS$_NORMAL) {
+ for (i = 0; i < total_length; i++) {
+ sys$gettim((struct _generic_64 *)&sys_time[0]);
+ srand(sys_time[0] * data_buffer[0] * data_buffer[1] + i);
+
+ if (i == (total_length - 1)) { /* for JPI$_FINALEXC */
+ ptr = &data_buffer[i];
+ for (j = 0; j < 4; j++) {
+ data_buffer[i + j] = ptr[j];
+ /* OK to use rand() just to scramble the seed */
+ data_buffer[i + j] ^= (sys_time[0] ^ rand());
+ tmp_length++;
+ }
+ } else {
+ /* OK to use rand() just to scramble the seed */
+ data_buffer[i] ^= (sys_time[0] ^ rand());
+ }
}
+
+ total_length += (tmp_length - 1);
+
+ /* size of seed is total_length*4 bytes (64bytes) */
+ RAND_add((PTR_T) data_buffer, total_length*4, total_length * 2);
+ } else {
+ return 0;
}
- sys$gettim(iosb);
- RAND_add((PTR_T) iosb, sizeof(iosb), sizeof(iosb) / 2);
+
return 1;
}
-
#endif
diff --git a/thirdparty/openssl/crypto/rand/rand_win.c b/thirdparty/openssl/crypto/rand/rand_win.c
index da4c935a53..cb4093128d 100644
--- a/thirdparty/openssl/crypto/rand/rand_win.c
+++ b/thirdparty/openssl/crypto/rand/rand_win.c
@@ -118,10 +118,10 @@
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
# endif
-#ifndef UWP_ENABLED
+#ifndef UWP_ENABLED // -- GODOT --
# include <wincrypt.h>
# include <tlhelp32.h>
-#endif
+#endif // -- GODOT --
/*
* Limit the time spent walking through the heap, processes, threads and
@@ -163,7 +163,7 @@ typedef struct tagCURSORINFO {
# define CURSOR_SHOWING 0x00000001
# endif /* CURSOR_SHOWING */
-# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED)
+# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED) // -- GODOT --
typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR,
DWORD, DWORD);
typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *);
@@ -198,7 +198,7 @@ typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE);
# endif /* 1 */
# endif /* !OPENSSL_SYS_WINCE */
-#if !defined(UWP_ENABLED)
+#if !defined(UWP_ENABLED) // -- GODOT --
int RAND_poll(void)
{
MEMORYSTATUS m;
@@ -583,7 +583,7 @@ int RAND_poll(void)
return (1);
}
-#endif // UWP_ENABLED
+#endif // UWP_ENABLED // -- GODOT --
int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
{
@@ -687,7 +687,7 @@ static void readtimer(void)
static void readscreen(void)
{
-# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED)
+# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED) // -- GODOT --
HDC hScrDC; /* screen DC */
HBITMAP hBitmap; /* handle for our bitmap */
BITMAP bm; /* bitmap properties */
diff --git a/thirdparty/openssl/crypto/rand/randfile.c b/thirdparty/openssl/crypto/rand/randfile.c
index 9537c56a78..728fd0a721 100644
--- a/thirdparty/openssl/crypto/rand/randfile.c
+++ b/thirdparty/openssl/crypto/rand/randfile.c
@@ -56,11 +56,6 @@
* [including the GNU Public Licence.]
*/
-/* We need to define this to get macros like S_IFBLK and S_IFCHR */
-#if !defined(OPENSSL_SYS_VXWORKS)
-# define _XOPEN_SOURCE 500
-#endif
-
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
@@ -80,6 +75,29 @@
#ifndef OPENSSL_NO_POSIX_IO
# include <sys/stat.h>
# include <fcntl.h>
+/*
+ * Following should not be needed, and we could have been stricter
+ * and demand S_IS*. But some systems just don't comply... Formally
+ * below macros are "anatomically incorrect", because normally they
+ * would look like ((m) & MASK == TYPE), but since MASK availability
+ * is as questionable, we settle for this poor-man fallback...
+ */
+# if !defined(S_ISBLK)
+# if defined(_S_IFBLK)
+# define S_ISBLK(m) ((m) & _S_IFBLK)
+# elif defined(S_IFBLK)
+# define S_ISBLK(m) ((m) & S_IFBLK)
+# elif defined(_WIN32)
+# define S_ISBLK(m) 0 /* no concept of block devices on Windows */
+# endif
+# endif
+# if !defined(S_ISCHR)
+# if defined(_S_IFCHR)
+# define S_ISCHR(m) ((m) & _S_IFCHR)
+# elif defined(S_IFCHR)
+# define S_ISCHR(m) ((m) & S_IFCHR)
+# endif
+# endif
#endif
#ifdef _WIN32
@@ -93,7 +111,7 @@
#define BUFSIZE 1024
#define RAND_DATA 1024
-#ifdef OPENSSL_SYS_VMS
+#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64)))
/*
* This declaration is a nasty hack to get around vms' extension to fopen for
* passing in sharing options being disabled by our /STANDARD=ANSI89
@@ -122,7 +140,24 @@ int RAND_load_file(const char *file, long bytes)
struct stat sb;
#endif
int i, ret = 0, n;
+/*
+ * If setvbuf() is to be called, then the FILE pointer
+ * to it must be 32 bit.
+*/
+
+#if !defined OPENSSL_NO_SETVBUF_IONBF && defined(OPENSSL_SYS_VMS) && defined(__VMS_VER) && (__VMS_VER >= 70000000)
+ /* For 64-bit-->32 bit API Support*/
+#if __INITIAL_POINTER_SIZE == 64
+#pragma __required_pointer_size __save
+#pragma __required_pointer_size 32
+#endif
+ FILE *in; /* setvbuf() requires 32-bit pointers */
+#if __INITIAL_POINTER_SIZE == 64
+#pragma __required_pointer_size __restore
+#endif
+#else
FILE *in;
+#endif /* OPENSSL_SYS_VMS */
if (file == NULL)
return (0);
@@ -151,8 +186,8 @@ int RAND_load_file(const char *file, long bytes)
#endif
if (in == NULL)
goto err;
-#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
- if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
+#if defined(S_ISBLK) && defined(S_ISCHR) && !defined(OPENSSL_NO_POSIX_IO)
+ if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
/*
* this file is a device. we don't want read an infinite number of
* bytes from a random device, nor do we want to use buffered I/O
@@ -231,7 +266,7 @@ int RAND_write_file(const char *file)
}
#endif
-#ifdef OPENSSL_SYS_VMS
+#if (defined(OPENSSL_SYS_VMS) && (defined(__alpha) || defined(__ia64)))
/*
* VMS NOTE: Prior versions of this routine created a _new_ version of
* the rand file for each call into this routine, then deleted all
diff --git a/thirdparty/openssl/crypto/rsa/rsa_ameth.c b/thirdparty/openssl/crypto/rsa/rsa_ameth.c
index 4e0621827c..951e1d5ca3 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_ameth.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_ameth.c
@@ -68,10 +68,12 @@
#endif
#include "asn1_locl.h"
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_sign(CMS_SignerInfo *si);
static int rsa_cms_verify(CMS_SignerInfo *si);
static int rsa_cms_decrypt(CMS_RecipientInfo *ri);
static int rsa_cms_encrypt(CMS_RecipientInfo *ri);
+#endif
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
{
@@ -665,6 +667,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, EVP_PKEY_CTX *pkctx,
return rv;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_verify(CMS_SignerInfo *si)
{
int nid, nid2;
@@ -683,6 +686,7 @@ static int rsa_cms_verify(CMS_SignerInfo *si)
}
return 0;
}
+#endif
/*
* Customised RSA item verification routine. This is called when a signature
@@ -705,6 +709,7 @@ static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
return -1;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_sign(CMS_SignerInfo *si)
{
int pad_mode = RSA_PKCS1_PADDING;
@@ -729,6 +734,7 @@ static int rsa_cms_sign(CMS_SignerInfo *si)
X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os);
return 1;
}
+#endif
static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
X509_ALGOR *alg1, X509_ALGOR *alg2,
@@ -785,6 +791,7 @@ static RSA_OAEP_PARAMS *rsa_oaep_decode(const X509_ALGOR *alg,
return pss;
}
+#ifndef OPENSSL_NO_CMS
static int rsa_cms_decrypt(CMS_RecipientInfo *ri)
{
EVP_PKEY_CTX *pkctx;
@@ -920,6 +927,7 @@ static int rsa_cms_encrypt(CMS_RecipientInfo *ri)
ASN1_STRING_free(os);
return rv;
}
+#endif
const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = {
{
diff --git a/thirdparty/openssl/crypto/rsa/rsa_chk.c b/thirdparty/openssl/crypto/rsa/rsa_chk.c
index 607faa0017..475dfc5628 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_chk.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_chk.c
@@ -56,7 +56,6 @@ int RSA_check_key(const RSA *key)
{
BIGNUM *i, *j, *k, *l, *m;
BN_CTX *ctx;
- int r;
int ret = 1;
if (!key->p || !key->q || !key->n || !key->e || !key->d) {
@@ -70,75 +69,68 @@ int RSA_check_key(const RSA *key)
l = BN_new();
m = BN_new();
ctx = BN_CTX_new();
- if (i == NULL || j == NULL || k == NULL || l == NULL ||
- m == NULL || ctx == NULL) {
+ if (i == NULL || j == NULL || k == NULL || l == NULL
+ || m == NULL || ctx == NULL) {
ret = -1;
RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE);
goto err;
}
+ if (BN_is_one(key->e)) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE);
+ }
+ if (!BN_is_odd(key->e)) {
+ ret = 0;
+ RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_BAD_E_VALUE);
+ }
+
/* p prime? */
- r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL);
- if (r != 1) {
- ret = r;
- if (r != 0)
- goto err;
+ if (BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL) != 1) {
+ ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME);
}
/* q prime? */
- r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL);
- if (r != 1) {
- ret = r;
- if (r != 0)
- goto err;
+ if (BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL) != 1) {
+ ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME);
}
/* n = p*q? */
- r = BN_mul(i, key->p, key->q, ctx);
- if (!r) {
+ if (!BN_mul(i, key->p, key->q, ctx)) {
ret = -1;
goto err;
}
-
if (BN_cmp(i, key->n) != 0) {
ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q);
}
/* d*e = 1 mod lcm(p-1,q-1)? */
-
- r = BN_sub(i, key->p, BN_value_one());
- if (!r) {
+ if (!BN_sub(i, key->p, BN_value_one())) {
ret = -1;
goto err;
}
- r = BN_sub(j, key->q, BN_value_one());
- if (!r) {
+ if (!BN_sub(j, key->q, BN_value_one())) {
ret = -1;
goto err;
}
/* now compute k = lcm(i,j) */
- r = BN_mul(l, i, j, ctx);
- if (!r) {
+ if (!BN_mul(l, i, j, ctx)) {
ret = -1;
goto err;
}
- r = BN_gcd(m, i, j, ctx);
- if (!r) {
+ if (!BN_gcd(m, i, j, ctx)) {
ret = -1;
goto err;
}
- r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */
- if (!r) {
+ if (!BN_div(k, NULL, l, m, ctx)) { /* remainder is 0 */
ret = -1;
goto err;
}
-
- r = BN_mod_mul(i, key->d, key->e, k, ctx);
- if (!r) {
+ if (!BN_mod_mul(i, key->d, key->e, k, ctx)) {
ret = -1;
goto err;
}
@@ -150,36 +142,28 @@ int RSA_check_key(const RSA *key)
if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) {
/* dmp1 = d mod (p-1)? */
- r = BN_sub(i, key->p, BN_value_one());
- if (!r) {
+ if (!BN_sub(i, key->p, BN_value_one())) {
ret = -1;
goto err;
}
-
- r = BN_mod(j, key->d, i, ctx);
- if (!r) {
+ if (!BN_mod(j, key->d, i, ctx)) {
ret = -1;
goto err;
}
-
if (BN_cmp(j, key->dmp1) != 0) {
ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D);
}
/* dmq1 = d mod (q-1)? */
- r = BN_sub(i, key->q, BN_value_one());
- if (!r) {
+ if (!BN_sub(i, key->q, BN_value_one())) {
ret = -1;
goto err;
}
-
- r = BN_mod(j, key->d, i, ctx);
- if (!r) {
+ if (!BN_mod(j, key->d, i, ctx)) {
ret = -1;
goto err;
}
-
if (BN_cmp(j, key->dmq1) != 0) {
ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D);
@@ -190,7 +174,6 @@ int RSA_check_key(const RSA *key)
ret = -1;
goto err;
}
-
if (BN_cmp(i, key->iqmp) != 0) {
ret = 0;
RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q);
@@ -198,17 +181,11 @@ int RSA_check_key(const RSA *key)
}
err:
- if (i != NULL)
- BN_free(i);
- if (j != NULL)
- BN_free(j);
- if (k != NULL)
- BN_free(k);
- if (l != NULL)
- BN_free(l);
- if (m != NULL)
- BN_free(m);
- if (ctx != NULL)
- BN_CTX_free(ctx);
- return (ret);
+ BN_free(i);
+ BN_free(j);
+ BN_free(k);
+ BN_free(l);
+ BN_free(m);
+ BN_CTX_free(ctx);
+ return ret;
}
diff --git a/thirdparty/openssl/crypto/rsa/rsa_gen.c b/thirdparty/openssl/crypto/rsa/rsa_gen.c
index 7f7dca39fd..082c8da2ef 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_gen.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_gen.c
@@ -142,7 +142,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL))
goto err;
- BN_copy(rsa->e, e_value);
+ if (BN_copy(rsa->e, e_value) == NULL)
+ goto err;
/* generate p and q */
for (;;) {
diff --git a/thirdparty/openssl/crypto/rsa/rsa_lib.c b/thirdparty/openssl/crypto/rsa/rsa_lib.c
index a6805debc8..6ea6b40dc6 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_lib.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_lib.c
@@ -143,6 +143,7 @@ RSA *RSA_new_method(ENGINE *engine)
RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ memset(ret,0,sizeof(RSA));
ret->meth = RSA_get_default_method();
#ifndef OPENSSL_NO_ENGINE
diff --git a/thirdparty/openssl/crypto/rsa/rsa_oaep.c b/thirdparty/openssl/crypto/rsa/rsa_oaep.c
index 9c2a943cf7..19d28c6f0e 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_oaep.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_oaep.c
@@ -89,17 +89,21 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
}
if (PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md) < 0)
- return 0;
+ goto err;
for (i = 0; i < emlen - mdlen; i++)
db[i] ^= dbmask[i];
if (PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md) < 0)
- return 0;
+ goto err;
for (i = 0; i < mdlen; i++)
seed[i] ^= seedmask[i];
OPENSSL_free(dbmask);
return 1;
+
+ err:
+ OPENSSL_free(dbmask);
+ return 0;
}
int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen,
diff --git a/thirdparty/openssl/crypto/rsa/rsa_pmeth.c b/thirdparty/openssl/crypto/rsa/rsa_pmeth.c
index 203635595f..8896e2e977 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_pmeth.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_pmeth.c
@@ -373,6 +373,10 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx,
if (rctx->pad_mode == RSA_PKCS1_PADDING)
return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen,
sig, siglen, rsa);
+ if (tbslen != (size_t)EVP_MD_size(rctx->md)) {
+ RSAerr(RSA_F_PKEY_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH);
+ return -1;
+ }
if (rctx->pad_mode == RSA_X931_PADDING) {
if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0)
return 0;
@@ -442,19 +446,14 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx,
int ret;
RSA_PKEY_CTX *rctx = ctx->data;
if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) {
- int i;
if (!setup_tbuf(rctx, ctx))
return -1;
ret = RSA_private_decrypt(inlen, in, rctx->tbuf,
ctx->pkey->pkey.rsa, RSA_NO_PADDING);
if (ret <= 0)
return ret;
- for (i = 0; i < ret; i++) {
- if (rctx->tbuf[i])
- break;
- }
- ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf + i,
- ret - i, ret,
+ ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, ret, rctx->tbuf,
+ ret, ret,
rctx->oaep_label,
rctx->oaep_labellen,
rctx->md, rctx->mgf1md);
@@ -545,8 +544,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return 1;
case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP:
- if (!p2)
+ if (p2 == NULL || !BN_is_odd((BIGNUM *)p2) || BN_is_one((BIGNUM *)p2)) {
+ RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_BAD_E_VALUE);
return -2;
+ }
BN_free(rctx->pub_exp);
rctx->pub_exp = p2;
return 1;
diff --git a/thirdparty/openssl/crypto/rsa/rsa_pss.c b/thirdparty/openssl/crypto/rsa/rsa_pss.c
index 41bc0844e4..2c3fd73b09 100644
--- a/thirdparty/openssl/crypto/rsa/rsa_pss.c
+++ b/thirdparty/openssl/crypto/rsa/rsa_pss.c
@@ -122,7 +122,11 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash,
EM++;
emLen--;
}
- if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */
+ if (emLen < hLen + 2) {
+ RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
+ goto err;
+ }
+ if (sLen > emLen - hLen - 2) { /* sLen can be small negative */
RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE);
goto err;
}
@@ -222,9 +226,14 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
*EM++ = 0;
emLen--;
}
+ if (emLen < hLen + 2) {
+ RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
+ RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ goto err;
+ }
if (sLen == -2) {
sLen = emLen - hLen - 2;
- } else if (emLen < (hLen + sLen + 2)) {
+ } else if (sLen > emLen - hLen - 2) {
RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1,
RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
diff --git a/thirdparty/openssl/crypto/s390xcap.c b/thirdparty/openssl/crypto/s390xcap.c
index 47d6b6ff51..cf8c372c05 100644
--- a/thirdparty/openssl/crypto/s390xcap.c
+++ b/thirdparty/openssl/crypto/s390xcap.c
@@ -3,6 +3,7 @@
#include <string.h>
#include <setjmp.h>
#include <signal.h>
+#include "cryptlib.h"
extern unsigned long OPENSSL_s390xcap_P[];
diff --git a/thirdparty/openssl/crypto/srp/srp_lib.c b/thirdparty/openssl/crypto/srp/srp_lib.c
index e9a2e058f6..6df3b1cee7 100644
--- a/thirdparty/openssl/crypto/srp/srp_lib.c
+++ b/thirdparty/openssl/crypto/srp/srp_lib.c
@@ -159,8 +159,7 @@ BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL)
return NULL;
- if ((bn_ctx = BN_CTX_new()) == NULL ||
- (tmp = BN_new()) == NULL || (S = BN_new()) == NULL)
+ if ((bn_ctx = BN_CTX_new()) == NULL || (tmp = BN_new()) == NULL)
goto err;
/* S = (A*v**u) ** b */
@@ -169,8 +168,12 @@ BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b,
goto err;
if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx))
goto err;
- if (!BN_mod_exp(S, tmp, b, N, bn_ctx))
- goto err;
+
+ S = BN_new();
+ if (S != NULL && !BN_mod_exp(S, tmp, b, N, bn_ctx)) {
+ BN_free(S);
+ S = NULL;
+ }
err:
BN_CTX_free(bn_ctx);
BN_clear_free(tmp);
@@ -267,7 +270,7 @@ BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
if ((tmp = BN_new()) == NULL ||
(tmp2 = BN_new()) == NULL ||
- (tmp3 = BN_new()) == NULL || (K = BN_new()) == NULL)
+ (tmp3 = BN_new()) == NULL)
goto err;
if (!BN_mod_exp(tmp, g, x, N, bn_ctx))
@@ -279,12 +282,15 @@ BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x,
if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx))
goto err;
- if (!BN_mod_mul(tmp3, u, x, N, bn_ctx))
+ if (!BN_mul(tmp3, u, x, bn_ctx))
goto err;
- if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx))
- goto err;
- if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx))
+ if (!BN_add(tmp2, a, tmp3))
goto err;
+ K = BN_new();
+ if (K != NULL && !BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) {
+ BN_free(K);
+ K = NULL;
+ }
err:
BN_CTX_free(bn_ctx);
diff --git a/thirdparty/openssl/crypto/srp/srp_vfy.c b/thirdparty/openssl/crypto/srp/srp_vfy.c
index 26ad3e07b4..c8bc7a94b2 100644
--- a/thirdparty/openssl/crypto/srp/srp_vfy.c
+++ b/thirdparty/openssl/crypto/srp/srp_vfy.c
@@ -80,15 +80,21 @@ static char b64table[] =
/*
* Convert a base64 string into raw byte array representation.
*/
-static int t_fromb64(unsigned char *a, const char *src)
+static int t_fromb64(unsigned char *a, size_t alen, const char *src)
{
char *loc;
int i, j;
int size;
+ if (alen == 0 || alen > INT_MAX)
+ return -1;
+
while (*src && (*src == ' ' || *src == '\t' || *src == '\n'))
++src;
size = strlen(src);
+ if (size < 0 || size >= (int)alen)
+ return -1;
+
i = 0;
while (i < size) {
loc = strchr(b64table, src[i]);
@@ -124,7 +130,7 @@ static int t_fromb64(unsigned char *a, const char *src)
if (--i < 0)
break;
}
- while (a[j] == 0 && j <= size)
+ while (j <= size && a[j] == 0)
++j;
i = 0;
while (j <= size)
@@ -231,13 +237,25 @@ static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
unsigned char tmp[MAX_LEN];
int len;
- if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN)
+ vinfo->v = NULL;
+ vinfo->s = NULL;
+
+ len = t_fromb64(tmp, sizeof(tmp), v);
+ if (len < 0)
return 0;
- len = t_fromb64(tmp, v);
if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
return 0;
- len = t_fromb64(tmp, s);
- return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL);
+ len = t_fromb64(tmp, sizeof(tmp), s);
+ if (len < 0)
+ goto err;
+ vinfo->s = BN_bin2bn(tmp, len, NULL);
+ if (vinfo->s == NULL)
+ goto err;
+ return 1;
+ err:
+ BN_free(vinfo->v);
+ vinfo->v = NULL;
+ return 0;
}
static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
@@ -307,10 +325,13 @@ static SRP_gN_cache *SRP_gN_new_init(const char *ch)
if (newgN == NULL)
return NULL;
+ len = t_fromb64(tmp, sizeof(tmp), ch);
+ if (len < 0)
+ goto err;
+
if ((newgN->b64_bn = BUF_strdup(ch)) == NULL)
goto err;
- len = t_fromb64(tmp, ch);
if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
return newgN;
@@ -544,7 +565,7 @@ SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
if (!SRP_user_pwd_set_ids(user, username, NULL))
goto err;
- if (RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH) < 0)
+ if (RAND_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
goto err;
EVP_MD_CTX_init(&ctxt);
EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL);
@@ -580,10 +601,10 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
goto err;
if (N) {
- if (!(len = t_fromb64(tmp, N)))
+ if (!(len = t_fromb64(tmp, sizeof(tmp), N)))
goto err;
N_bn = BN_bin2bn(tmp, len, NULL);
- if (!(len = t_fromb64(tmp, g)))
+ if (!(len = t_fromb64(tmp, sizeof(tmp), g)))
goto err;
g_bn = BN_bin2bn(tmp, len, NULL);
defgNid = "*";
@@ -597,12 +618,12 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
}
if (*salt == NULL) {
- if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+ if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
goto err;
s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
} else {
- if (!(len = t_fromb64(tmp2, *salt)))
+ if (!(len = t_fromb64(tmp2, sizeof(tmp2), *salt)))
goto err;
s = BN_bin2bn(tmp2, len, NULL);
}
@@ -635,7 +656,8 @@ char *SRP_create_verifier(const char *user, const char *pass, char **salt,
BN_free(N_bn);
BN_free(g_bn);
}
- OPENSSL_cleanse(vf, vfsize);
+ if (vf != NULL)
+ OPENSSL_cleanse(vf, vfsize);
OPENSSL_free(vf);
BN_clear_free(s);
BN_clear_free(v);
@@ -670,7 +692,7 @@ int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
srp_bn_print(g);
if (*salt == NULL) {
- if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0)
+ if (RAND_bytes(tmp2, SRP_RANDOM_SALT_LEN) <= 0)
goto err;
salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
diff --git a/thirdparty/openssl/crypto/threads/netware.bat b/thirdparty/openssl/crypto/threads/netware.bat
deleted file mode 100644
index 0b3eca3caf..0000000000
--- a/thirdparty/openssl/crypto/threads/netware.bat
+++ /dev/null
@@ -1,79 +0,0 @@
-@echo off
-rem batch file to build multi-thread test ( mttest.nlm )
-
-rem command line arguments:
-rem debug => build using debug settings
-
-rem
-rem After building, copy mttest.nlm to the server and run it, you'll probably
-rem want to redirect stdout and stderr. An example command line would be
-rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err"
-rem
-
-del mttest.nlm
-
-set BLD_DEBUG=
-set CFLAGS=
-set LFLAGS=
-set LIBS=
-
-if "%1" == "DEBUG" set BLD_DEBUG=YES
-if "%1" == "debug" set BLD_DEBUG=YES
-
-if "%MWCIncludes%" == "" goto inc_error
-if "%PRELUDE%" == "" goto prelude_error
-if "%IMPORTS%" == "" goto imports_error
-
-set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20
-
-if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib
-if "%BLD_DEBUG%" == "" set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib
-
-set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal
-
-rem generate command file for metrowerks
-echo.
-echo Generating Metrowerks command file: mttest.def
-echo # dynamically generated command file for metrowerks build > mttest.def
-echo IMPORT @%IMPORTS%\clib.imp >> mttest.def
-echo IMPORT @%IMPORTS%\threads.imp >> mttest.def
-echo IMPORT @%IMPORTS%\ws2nlm.imp >> mttest.def
-echo IMPORT GetProcessSwitchCount >> mttest.def
-echo MODULE clib >> mttest.def
-
-rem compile
-echo.
-echo Compiling mttest.c
-mwccnlm.exe mttest.c %CFLAGS%
-if errorlevel 1 goto end
-
-rem link
-echo.
-echo Linking mttest.nlm
-mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm
-if errorlevel 1 goto end
-
-goto end
-
-:inc_error
-echo.
-echo Environment variable MWCIncludes is not set - see install.nw
-goto end
-
-:prelude_error
-echo.
-echo Environment variable PRELUDE is not set - see install.nw
-goto end
-
-:imports_error
-echo.
-echo Environment variable IMPORTS is not set - see install.nw
-goto end
-
-
-:end
-set BLD_DEBUG=
-set CFLAGS=
-set LFLAGS=
-set LIBS=
-
diff --git a/thirdparty/openssl/crypto/threads/profile.sh b/thirdparty/openssl/crypto/threads/profile.sh
deleted file mode 100644
index 6e3e342fc0..0000000000
--- a/thirdparty/openssl/crypto/threads/profile.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-/bin/rm -f mttest
-cc -p -DSOLARIS -I../../include -g mttest.c -o mttest -L/usr/lib/libc -ldl -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
-
diff --git a/thirdparty/openssl/crypto/threads/ptest.bat b/thirdparty/openssl/crypto/threads/ptest.bat
deleted file mode 100755
index 4071b5ffea..0000000000
--- a/thirdparty/openssl/crypto/threads/ptest.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-del mttest.exe
-
-purify cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssl32.lib ..\..\out\crypt32.lib
-
diff --git a/thirdparty/openssl/crypto/threads/pthread.sh b/thirdparty/openssl/crypto/threads/pthread.sh
deleted file mode 100644
index f1c49821d2..0000000000
--- a/thirdparty/openssl/crypto/threads/pthread.sh
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/sh
-#
-# build using pthreads
-#
-# http://www.mit.edu:8001/people/proven/pthreads.html
-#
-/bin/rm -f mttest
-pgcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto
-
diff --git a/thirdparty/openssl/crypto/threads/pthread2.sh b/thirdparty/openssl/crypto/threads/pthread2.sh
deleted file mode 100755
index ec945c451b..0000000000
--- a/thirdparty/openssl/crypto/threads/pthread2.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh
-#
-# build using pthreads where it's already built into the system
-#
-/bin/rm -f mttest
-gcc -DPTHREADS -I../../include -g mttest.c -o mttest -L../.. -lssl -lcrypto -lpthread -ldl
diff --git a/thirdparty/openssl/crypto/threads/pthreads-vms.com b/thirdparty/openssl/crypto/threads/pthreads-vms.com
deleted file mode 100644
index 1cf92bdf57..0000000000
--- a/thirdparty/openssl/crypto/threads/pthreads-vms.com
+++ /dev/null
@@ -1,14 +0,0 @@
-$! To compile mttest on VMS.
-$!
-$! WARNING: only tested with DEC C so far.
-$
-$ if (f$getsyi("cpu").lt.128)
-$ then
-$ arch := VAX
-$ else
-$ arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE")
-$ if (arch .eqs. "") then arch = "UNK"
-$ endif
-$ define/user openssl [--.include.openssl]
-$ cc/def=PTHREADS mttest.c
-$ link mttest,[--.'arch'.exe.ssl]libssl/lib,[--.'arch'.exe.crypto]libcrypto/lib
diff --git a/thirdparty/openssl/crypto/threads/purify.sh b/thirdparty/openssl/crypto/threads/purify.sh
deleted file mode 100644
index 6d44fe26b7..0000000000
--- a/thirdparty/openssl/crypto/threads/purify.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-/bin/rm -f mttest
-purify cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
-
diff --git a/thirdparty/openssl/crypto/threads/solaris.sh b/thirdparty/openssl/crypto/threads/solaris.sh
deleted file mode 100644
index bc93094a27..0000000000
--- a/thirdparty/openssl/crypto/threads/solaris.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-/bin/rm -f mttest
-cc -DSOLARIS -I../../include -g mttest.c -o mttest -L../.. -lthread -lssl -lcrypto -lnsl -lsocket
-
diff --git a/thirdparty/openssl/crypto/threads/win32.bat b/thirdparty/openssl/crypto/threads/win32.bat
deleted file mode 100755
index ee6da80a07..0000000000
--- a/thirdparty/openssl/crypto/threads/win32.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-del mttest.exe
-
-cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssleay32.lib ..\..\out\libeay32.lib
-
diff --git a/thirdparty/openssl/crypto/ts/ts_lib.c b/thirdparty/openssl/crypto/ts/ts_lib.c
index c51538a17f..e0f1063537 100644
--- a/thirdparty/openssl/crypto/ts/ts_lib.c
+++ b/thirdparty/openssl/crypto/ts/ts_lib.c
@@ -90,9 +90,8 @@ int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj)
{
char obj_txt[128];
- int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
- BIO_write(bio, obj_txt, len);
- BIO_write(bio, "\n", 1);
+ OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0);
+ BIO_printf(bio, "%s\n", obj_txt);
return 1;
}
diff --git a/thirdparty/openssl/crypto/ts/ts_rsp_verify.c b/thirdparty/openssl/crypto/ts/ts_rsp_verify.c
index 29aa5a497e..7918236287 100644
--- a/thirdparty/openssl/crypto/ts/ts_rsp_verify.c
+++ b/thirdparty/openssl/crypto/ts/ts_rsp_verify.c
@@ -434,51 +434,58 @@ static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx,
unsigned char *imprint = NULL;
unsigned imprint_len = 0;
int ret = 0;
+ int flags = ctx->flags;
+
+ /* Some options require us to also check the signature */
+ if (((flags & TS_VFY_SIGNER) && tsa_name != NULL)
+ || (flags & TS_VFY_TSA_NAME)) {
+ flags |= TS_VFY_SIGNATURE;
+ }
/* Verify the signature. */
- if ((ctx->flags & TS_VFY_SIGNATURE)
+ if ((flags & TS_VFY_SIGNATURE)
&& !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer))
goto err;
/* Check version number of response. */
- if ((ctx->flags & TS_VFY_VERSION)
+ if ((flags & TS_VFY_VERSION)
&& TS_TST_INFO_get_version(tst_info) != 1) {
TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION);
goto err;
}
/* Check policies. */
- if ((ctx->flags & TS_VFY_POLICY)
+ if ((flags & TS_VFY_POLICY)
&& !TS_check_policy(ctx->policy, tst_info))
goto err;
/* Check message imprints. */
- if ((ctx->flags & TS_VFY_IMPRINT)
+ if ((flags & TS_VFY_IMPRINT)
&& !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len,
tst_info))
goto err;
/* Compute and check message imprints. */
- if ((ctx->flags & TS_VFY_DATA)
+ if ((flags & TS_VFY_DATA)
&& (!TS_compute_imprint(ctx->data, tst_info,
&md_alg, &imprint, &imprint_len)
|| !TS_check_imprints(md_alg, imprint, imprint_len, tst_info)))
goto err;
/* Check nonces. */
- if ((ctx->flags & TS_VFY_NONCE)
+ if ((flags & TS_VFY_NONCE)
&& !TS_check_nonces(ctx->nonce, tst_info))
goto err;
/* Check whether TSA name and signer certificate match. */
- if ((ctx->flags & TS_VFY_SIGNER)
+ if ((flags & TS_VFY_SIGNER)
&& tsa_name && !TS_check_signer_name(tsa_name, signer)) {
TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH);
goto err;
}
/* Check whether the TSA is the expected one. */
- if ((ctx->flags & TS_VFY_TSA_NAME)
+ if ((flags & TS_VFY_TSA_NAME)
&& !TS_check_signer_name(ctx->tsa_name, signer)) {
TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED);
goto err;
@@ -548,13 +555,15 @@ static int TS_check_status_info(TS_RESP *response)
static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text)
{
int i;
- unsigned int length = 0;
+ int length = 0;
char *result = NULL;
char *p;
/* Determine length first. */
for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) {
ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i);
+ if (ASN1_STRING_length(current) > TS_MAX_STATUS_LENGTH - length - 1)
+ return NULL;
length += ASN1_STRING_length(current);
length += 1; /* separator character */
}
diff --git a/thirdparty/openssl/crypto/txt_db/txt_db.c b/thirdparty/openssl/crypto/txt_db/txt_db.c
index f9b42ac6e5..ed02efc261 100644
--- a/thirdparty/openssl/crypto/txt_db/txt_db.c
+++ b/thirdparty/openssl/crypto/txt_db/txt_db.c
@@ -162,6 +162,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num)
"wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n",
ln, num, n, f);
#endif
+ OPENSSL_free(pp);
er = 2;
goto err;
}
@@ -171,6 +172,7 @@ TXT_DB *TXT_DB_read(BIO *in, int num)
* fix :-( */
fprintf(stderr, "failure in sk_push\n");
#endif
+ OPENSSL_free(pp);
er = 2;
goto err;
}
@@ -222,7 +224,7 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp)
{
LHASH_OF(OPENSSL_STRING) *idx;
- OPENSSL_STRING *r;
+ OPENSSL_STRING *r, *k;
int i, n;
if (field >= db->num_fields) {
@@ -239,13 +241,18 @@ int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *),
r = sk_OPENSSL_PSTRING_value(db->data, i);
if ((qual != NULL) && (qual(r) == 0))
continue;
- if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
+ if ((k = lh_OPENSSL_STRING_insert(idx, r)) != NULL) {
db->error = DB_ERROR_INDEX_CLASH;
- db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r);
+ db->arg1 = sk_OPENSSL_PSTRING_find(db->data, k);
db->arg2 = i;
lh_OPENSSL_STRING_free(idx);
return (0);
}
+ if (lh_OPENSSL_STRING_retrieve(idx, r) == NULL) {
+ db->error = DB_ERROR_MALLOC;
+ lh_OPENSSL_STRING_free(idx);
+ return (0);
+ }
}
if (db->index[field] != NULL)
lh_OPENSSL_STRING_free(db->index[field]);
@@ -320,20 +327,29 @@ int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row)
}
}
}
- /* We have passed the index checks, now just append and insert */
- if (!sk_OPENSSL_PSTRING_push(db->data, row)) {
- db->error = DB_ERROR_MALLOC;
- goto err;
- }
for (i = 0; i < db->num_fields; i++) {
if (db->index[i] != NULL) {
if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
continue;
(void)lh_OPENSSL_STRING_insert(db->index[i], row);
+ if (lh_OPENSSL_STRING_retrieve(db->index[i], row) == NULL)
+ goto err1;
}
}
+ if (!sk_OPENSSL_PSTRING_push(db->data, row))
+ goto err1;
return (1);
+
+ err1:
+ db->error = DB_ERROR_MALLOC;
+ while (i-- > 0) {
+ if (db->index[i] != NULL) {
+ if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0))
+ continue;
+ (void)lh_OPENSSL_STRING_delete(db->index[i], row);
+ }
+ }
err:
return (0);
}
diff --git a/thirdparty/openssl/crypto/ui/ui_lib.c b/thirdparty/openssl/crypto/ui/ui_lib.c
index 2f580352ce..643ae59343 100644
--- a/thirdparty/openssl/crypto/ui/ui_lib.c
+++ b/thirdparty/openssl/crypto/ui/ui_lib.c
@@ -164,7 +164,7 @@ static int general_allocate_string(UI *ui, const char *prompt,
UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable,
type, input_flags, result_buf);
- if (s) {
+ if (s != NULL) {
if (allocate_string_stack(ui) >= 0) {
s->_.string_data.result_minsize = minsize;
s->_.string_data.result_maxsize = maxsize;
@@ -197,8 +197,8 @@ static int general_allocate_boolean(UI *ui,
} else if (cancel_chars == NULL) {
UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER);
} else {
- for (p = ok_chars; *p; p++) {
- if (strchr(cancel_chars, *p)) {
+ for (p = ok_chars; *p != '\0'; p++) {
+ if (strchr(cancel_chars, *p) != NULL) {
UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN,
UI_R_COMMON_OK_AND_CANCEL_CHARACTERS);
}
@@ -207,7 +207,7 @@ static int general_allocate_boolean(UI *ui,
s = general_allocate_prompt(ui, prompt, prompt_freeable,
type, input_flags, result_buf);
- if (s) {
+ if (s != NULL) {
if (allocate_string_stack(ui) >= 0) {
s->_.boolean_data.action_desc = action_desc;
s->_.boolean_data.ok_chars = ok_chars;
@@ -243,7 +243,7 @@ int UI_dup_input_string(UI *ui, const char *prompt, int flags,
{
char *prompt_copy = NULL;
- if (prompt) {
+ if (prompt != NULL) {
prompt_copy = BUF_strdup(prompt);
if (prompt_copy == NULL) {
UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE);
@@ -271,7 +271,7 @@ int UI_dup_verify_string(UI *ui, const char *prompt, int flags,
{
char *prompt_copy = NULL;
- if (prompt) {
+ if (prompt != NULL) {
prompt_copy = BUF_strdup(prompt);
if (prompt_copy == NULL) {
UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE);
@@ -302,7 +302,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
char *ok_chars_copy = NULL;
char *cancel_chars_copy = NULL;
- if (prompt) {
+ if (prompt != NULL) {
prompt_copy = BUF_strdup(prompt);
if (prompt_copy == NULL) {
UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -310,7 +310,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
}
}
- if (action_desc) {
+ if (action_desc != NULL) {
action_desc_copy = BUF_strdup(action_desc);
if (action_desc_copy == NULL) {
UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -318,7 +318,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
}
}
- if (ok_chars) {
+ if (ok_chars != NULL) {
ok_chars_copy = BUF_strdup(ok_chars);
if (ok_chars_copy == NULL) {
UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -326,7 +326,7 @@ int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc,
}
}
- if (cancel_chars) {
+ if (cancel_chars != NULL) {
cancel_chars_copy = BUF_strdup(cancel_chars);
if (cancel_chars_copy == NULL) {
UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE);
@@ -359,7 +359,7 @@ int UI_dup_info_string(UI *ui, const char *text)
{
char *text_copy = NULL;
- if (text) {
+ if (text != NULL) {
text_copy = BUF_strdup(text);
if (text_copy == NULL) {
UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE);
@@ -381,7 +381,7 @@ int UI_dup_error_string(UI *ui, const char *text)
{
char *text_copy = NULL;
- if (text) {
+ if (text != NULL) {
text_copy = BUF_strdup(text);
if (text_copy == NULL) {
UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE);
@@ -397,7 +397,7 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
{
char *prompt = NULL;
- if (ui->meth->ui_construct_prompt)
+ if (ui->meth->ui_construct_prompt != NULL)
prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name);
else {
char prompt1[] = "Enter ";
@@ -408,14 +408,16 @@ char *UI_construct_prompt(UI *ui, const char *object_desc,
if (object_desc == NULL)
return NULL;
len = sizeof(prompt1) - 1 + strlen(object_desc);
- if (object_name)
+ if (object_name != NULL)
len += sizeof(prompt2) - 1 + strlen(object_name);
len += sizeof(prompt3) - 1;
prompt = (char *)OPENSSL_malloc(len + 1);
+ if (prompt == NULL)
+ return NULL;
BUF_strlcpy(prompt, prompt1, len + 1);
BUF_strlcat(prompt, object_desc, len + 1);
- if (object_name) {
+ if (object_name != NULL) {
BUF_strlcat(prompt, prompt2, len + 1);
BUF_strlcat(prompt, object_name, len + 1);
}
@@ -457,7 +459,8 @@ static int print_error(const char *str, size_t len, UI *ui)
uis.type = UIT_ERROR;
uis.out_string = str;
- if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis))
+ if (ui->meth->ui_write_string != NULL
+ && ui->meth->ui_write_string(ui, &uis) <= 0)
return -1;
return 0;
}
@@ -466,24 +469,28 @@ int UI_process(UI *ui)
{
int i, ok = 0;
- if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui))
- return -1;
+ if (ui->meth->ui_open_session != NULL
+ && ui->meth->ui_open_session(ui) <= 0) {
+ ok = -1;
+ goto err;
+ }
if (ui->flags & UI_FLAG_PRINT_ERRORS)
ERR_print_errors_cb((int (*)(const char *, size_t, void *))
print_error, (void *)ui);
for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
- if (ui->meth->ui_write_string
- && !ui->meth->ui_write_string(ui,
- sk_UI_STRING_value(ui->strings, i)))
+ if (ui->meth->ui_write_string != NULL
+ && (ui->meth->ui_write_string(ui,
+ sk_UI_STRING_value(ui->strings, i))
+ <= 0))
{
ok = -1;
goto err;
}
}
- if (ui->meth->ui_flush)
+ if (ui->meth->ui_flush != NULL)
switch (ui->meth->ui_flush(ui)) {
case -1: /* Interrupt/Cancel/something... */
ok = -2;
@@ -497,7 +504,7 @@ int UI_process(UI *ui)
}
for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) {
- if (ui->meth->ui_read_string) {
+ if (ui->meth->ui_read_string != NULL) {
switch (ui->meth->ui_read_string(ui,
sk_UI_STRING_value(ui->strings,
i))) {
@@ -514,7 +521,8 @@ int UI_process(UI *ui)
}
}
err:
- if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui))
+ if (ui->meth->ui_close_session != NULL
+ && ui->meth->ui_close_session(ui) <= 0)
return -1;
return ok;
}
@@ -610,49 +618,49 @@ void UI_destroy_method(UI_METHOD *ui_method)
int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui))
{
- if (method) {
+ if (method != NULL) {
method->ui_open_session = opener;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
int UI_method_set_writer(UI_METHOD *method,
int (*writer) (UI *ui, UI_STRING *uis))
{
- if (method) {
+ if (method != NULL) {
method->ui_write_string = writer;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui))
{
- if (method) {
+ if (method != NULL) {
method->ui_flush = flusher;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
int UI_method_set_reader(UI_METHOD *method,
int (*reader) (UI *ui, UI_STRING *uis))
{
- if (method) {
+ if (method != NULL) {
method->ui_read_string = reader;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui))
{
- if (method) {
+ if (method != NULL) {
method->ui_close_session = closer;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
int UI_method_set_prompt_constructor(UI_METHOD *method,
@@ -662,55 +670,55 @@ int UI_method_set_prompt_constructor(UI_METHOD *method,
const char
*object_name))
{
- if (method) {
+ if (method != NULL) {
method->ui_construct_prompt = prompt_constructor;
return 0;
- } else
- return -1;
+ }
+ return -1;
}
-int (*UI_method_get_opener(UI_METHOD *method)) (UI *) {
- if (method)
+int (*UI_method_get_opener(UI_METHOD *method)) (UI *)
+{
+ if (method != NULL)
return method->ui_open_session;
- else
- return NULL;
+ return NULL;
}
-int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) {
- if (method)
+int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+ if (method != NULL)
return method->ui_write_string;
- else
- return NULL;
+ return NULL;
}
-int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) {
- if (method)
+int (*UI_method_get_flusher(UI_METHOD *method)) (UI *)
+{
+ if (method != NULL)
return method->ui_flush;
- else
- return NULL;
+ return NULL;
}
-int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) {
- if (method)
+int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *)
+{
+ if (method != NULL)
return method->ui_read_string;
- else
- return NULL;
+ return NULL;
}
-int (*UI_method_get_closer(UI_METHOD *method)) (UI *) {
- if (method)
+int (*UI_method_get_closer(UI_METHOD *method)) (UI *)
+{
+ if (method != NULL)
return method->ui_close_session;
- else
- return NULL;
+ return NULL;
}
char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *,
const char *,
- const char *) {
- if (method)
+ const char *)
+{
+ if (method != NULL)
return method->ui_construct_prompt;
- else
- return NULL;
+ return NULL;
}
enum UI_string_types UI_get_string_type(UI_STRING *uis)
@@ -739,7 +747,6 @@ const char *UI_get0_action_string(UI_STRING *uis)
if (!uis)
return NULL;
switch (uis->type) {
- case UIT_PROMPT:
case UIT_BOOLEAN:
return uis->_.boolean_data.action_desc;
default:
diff --git a/thirdparty/openssl/crypto/ui/ui_openssl.c b/thirdparty/openssl/crypto/ui/ui_openssl.c
index 9ab259b8f6..17d14f5842 100644
--- a/thirdparty/openssl/crypto/ui/ui_openssl.c
+++ b/thirdparty/openssl/crypto/ui/ui_openssl.c
@@ -440,7 +440,7 @@ static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl)
# else
p = fgets(result, maxsize, tty_in);
# endif
- if (!p)
+ if (p == NULL)
goto error;
if (feof(tty_in))
goto error;
@@ -509,18 +509,31 @@ static int open_console(UI *ui)
is_a_tty = 0;
else
# endif
+# ifdef ENODEV
+ /*
+ * MacOS X returns ENODEV (Operation not supported by device),
+ * which seems appropriate.
+ */
+ if (errno == ENODEV)
+ is_a_tty = 0;
+ else
+# endif
return 0;
}
#endif
#ifdef OPENSSL_SYS_VMS
status = sys$assign(&terminal, &channel, 0, 0);
+
+ /* if there isn't a TT device, something is very wrong */
if (status != SS$_NORMAL)
return 0;
- status =
- sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0,
- 0, 0);
+
+ status = sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12,
+ 0, 0, 0, 0);
+
+ /* If IO$_SENSEMODE doesn't work, this is not a terminal device */
if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
- return 0;
+ is_a_tty = 0;
#endif
return 1;
}
@@ -537,14 +550,15 @@ static int noecho_console(UI *ui)
return 0;
#endif
#ifdef OPENSSL_SYS_VMS
- tty_new[0] = tty_orig[0];
- tty_new[1] = tty_orig[1] | TT$M_NOECHO;
- tty_new[2] = tty_orig[2];
- status =
- sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
- 0);
- if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
- return 0;
+ if (is_a_tty) {
+ tty_new[0] = tty_orig[0];
+ tty_new[1] = tty_orig[1] | TT$M_NOECHO;
+ tty_new[2] = tty_orig[2];
+ status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+ 0, 0, 0, 0);
+ if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+ return 0;
+ }
#endif
return 1;
}
@@ -561,14 +575,15 @@ static int echo_console(UI *ui)
return 0;
#endif
#ifdef OPENSSL_SYS_VMS
- tty_new[0] = tty_orig[0];
- tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
- tty_new[2] = tty_orig[2];
- status =
- sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0,
- 0);
- if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
- return 0;
+ if (is_a_tty) {
+ tty_new[0] = tty_orig[0];
+ tty_new[1] = tty_orig[1] & ~TT$M_NOECHO;
+ tty_new[2] = tty_orig[2];
+ status = sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12,
+ 0, 0, 0, 0);
+ if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL))
+ return 0;
+ }
#endif
return 1;
}
@@ -581,6 +596,8 @@ static int close_console(UI *ui)
fclose(tty_out);
#ifdef OPENSSL_SYS_VMS
status = sys$dassgn(channel);
+ if (status != SS$_NORMAL)
+ return 0;
#endif
CRYPTO_w_unlock(CRYPTO_LOCK_UI);
diff --git a/thirdparty/openssl/crypto/whrlpool/wp_dgst.c b/thirdparty/openssl/crypto/whrlpool/wp_dgst.c
index e33bb4f833..807d1c49b2 100644
--- a/thirdparty/openssl/crypto/whrlpool/wp_dgst.c
+++ b/thirdparty/openssl/crypto/whrlpool/wp_dgst.c
@@ -51,6 +51,7 @@
* input. This is done for perfomance.
*/
+#include <openssl/crypto.h>
#include "wp_locl.h"
#include <openssl/crypto.h>
#include <string.h>
@@ -237,7 +238,7 @@ int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c)
if (md) {
memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH);
- memset(c, 0, sizeof(*c));
+ OPENSSL_cleanse(c, sizeof(*c));
return (1);
}
return (0);
diff --git a/thirdparty/openssl/crypto/x509/by_dir.c b/thirdparty/openssl/crypto/x509/by_dir.c
index 9ee8f8d859..bbc3189381 100644
--- a/thirdparty/openssl/crypto/x509/by_dir.c
+++ b/thirdparty/openssl/crypto/x509/by_dir.c
@@ -401,6 +401,10 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
}
if (!hent) {
hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
+ if (hent == NULL) {
+ X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE);
+ goto finish;
+ }
hent->hash = h;
hent->suffix = k;
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
diff --git a/thirdparty/openssl/crypto/x509/x509_att.c b/thirdparty/openssl/crypto/x509/x509_att.c
index bd59281f9d..2501075307 100644
--- a/thirdparty/openssl/crypto/x509/x509_att.c
+++ b/thirdparty/openssl/crypto/x509/x509_att.c
@@ -296,7 +296,7 @@ int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj)
int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
const void *data, int len)
{
- ASN1_TYPE *ttmp;
+ ASN1_TYPE *ttmp = NULL;
ASN1_STRING *stmp = NULL;
int atype = 0;
if (!attr)
@@ -324,20 +324,26 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype,
* least one value but some types use and zero length SET and require
* this.
*/
- if (attrtype == 0)
+ if (attrtype == 0) {
+ ASN1_STRING_free(stmp);
return 1;
+ }
if (!(ttmp = ASN1_TYPE_new()))
goto err;
if ((len == -1) && !(attrtype & MBSTRING_FLAG)) {
if (!ASN1_TYPE_set1(ttmp, attrtype, data))
goto err;
- } else
+ } else {
ASN1_TYPE_set(ttmp, atype, stmp);
+ stmp = NULL;
+ }
if (!sk_ASN1_TYPE_push(attr->value.set, ttmp))
goto err;
return 1;
err:
X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE);
+ ASN1_TYPE_free(ttmp);
+ ASN1_STRING_free(stmp);
return 0;
}
diff --git a/thirdparty/openssl/crypto/x509/x509_err.c b/thirdparty/openssl/crypto/x509/x509_err.c
index 1e779fefd9..a2a8e1b08b 100644
--- a/thirdparty/openssl/crypto/x509/x509_err.c
+++ b/thirdparty/openssl/crypto/x509/x509_err.c
@@ -1,6 +1,6 @@
/* crypto/x509/x509_err.c */
/* ====================================================================
- * Copyright (c) 1999-2012 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -72,6 +72,7 @@
static ERR_STRING_DATA X509_str_functs[] = {
{ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"},
{ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"},
+ {ERR_FUNC(X509_F_CHECK_NAME_CONSTRAINTS), "CHECK_NAME_CONSTRAINTS"},
{ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"},
{ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"},
{ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"},
diff --git a/thirdparty/openssl/crypto/x509/x509_lu.c b/thirdparty/openssl/crypto/x509/x509_lu.c
index 50120a4d70..b7424809fd 100644
--- a/thirdparty/openssl/crypto/x509/x509_lu.c
+++ b/thirdparty/openssl/crypto/x509/x509_lu.c
@@ -185,14 +185,16 @@ X509_STORE *X509_STORE_new(void)
if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL)
return NULL;
- ret->objs = sk_X509_OBJECT_new(x509_object_cmp);
+ if ((ret->objs = sk_X509_OBJECT_new(x509_object_cmp)) == NULL)
+ goto err0;
ret->cache = 1;
- ret->get_cert_methods = sk_X509_LOOKUP_new_null();
+ if ((ret->get_cert_methods = sk_X509_LOOKUP_new_null()) == NULL)
+ goto err1;
ret->verify = 0;
ret->verify_cb = 0;
if ((ret->param = X509_VERIFY_PARAM_new()) == NULL)
- return NULL;
+ goto err2;
ret->get_issuer = 0;
ret->check_issued = 0;
@@ -204,14 +206,21 @@ X509_STORE *X509_STORE_new(void)
ret->lookup_crls = 0;
ret->cleanup = 0;
- if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) {
- sk_X509_OBJECT_free(ret->objs);
- OPENSSL_free(ret);
- return NULL;
- }
+ if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data))
+ goto err3;
ret->references = 1;
return ret;
+
+ err3:
+ X509_VERIFY_PARAM_free(ret->param);
+ err2:
+ sk_X509_LOOKUP_free(ret->get_cert_methods);
+ err1:
+ sk_X509_OBJECT_free(ret->objs);
+ err0:
+ OPENSSL_free(ret);
+ return NULL;
}
static void cleanup(X509_OBJECT *a)
@@ -360,8 +369,12 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
X509err(X509_F_X509_STORE_ADD_CERT,
X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
- } else
- sk_X509_OBJECT_push(ctx->objs, obj);
+ } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ }
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
@@ -392,8 +405,12 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
OPENSSL_free(obj);
X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret = 0;
- } else
- sk_X509_OBJECT_push(ctx->objs, obj);
+ } else if (!sk_X509_OBJECT_push(ctx->objs, obj)) {
+ X509_OBJECT_free_contents(obj);
+ OPENSSL_free(obj);
+ X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE);
+ ret = 0;
+ }
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
diff --git a/thirdparty/openssl/crypto/x509/x509_obj.c b/thirdparty/openssl/crypto/x509/x509_obj.c
index 3de3ac7204..0a839f3e54 100644
--- a/thirdparty/openssl/crypto/x509/x509_obj.c
+++ b/thirdparty/openssl/crypto/x509/x509_obj.c
@@ -129,7 +129,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
type == V_ASN1_VISIBLESTRING ||
type == V_ASN1_PRINTABLESTRING ||
type == V_ASN1_TELETEXSTRING ||
- type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) {
+ type == V_ASN1_IA5STRING) {
if (num > (int)sizeof(ebcdic_buf))
num = sizeof(ebcdic_buf);
ascii2ebcdic(ebcdic_buf, q, num);
diff --git a/thirdparty/openssl/crypto/x509/x509_r2x.c b/thirdparty/openssl/crypto/x509/x509_r2x.c
index 0ff439c99f..2879569ead 100644
--- a/thirdparty/openssl/crypto/x509/x509_r2x.c
+++ b/thirdparty/openssl/crypto/x509/x509_r2x.c
@@ -70,10 +70,12 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
X509 *ret = NULL;
X509_CINF *xi = NULL;
X509_NAME *xn;
+ EVP_PKEY *pubkey = NULL;
+ int res;
if ((ret = X509_new()) == NULL) {
X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE);
- goto err;
+ return NULL;
}
/* duplicate the request */
@@ -89,9 +91,9 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
}
xn = X509_REQ_get_subject_name(r);
- if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0)
+ if (X509_set_subject_name(ret, xn) == 0)
goto err;
- if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0)
+ if (X509_set_issuer_name(ret, xn) == 0)
goto err;
if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL)
@@ -100,9 +102,11 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
NULL)
goto err;
- X509_set_pubkey(ret, X509_REQ_get_pubkey(r));
+ pubkey = X509_REQ_get_pubkey(r);
+ res = X509_set_pubkey(ret, pubkey);
+ EVP_PKEY_free(pubkey);
- if (!X509_sign(ret, pkey, EVP_md5()))
+ if (!res || !X509_sign(ret, pkey, EVP_md5()))
goto err;
if (0) {
err:
diff --git a/thirdparty/openssl/crypto/x509/x509_txt.c b/thirdparty/openssl/crypto/x509/x509_txt.c
index 3d46d3ff83..35db095591 100644
--- a/thirdparty/openssl/crypto/x509/x509_txt.c
+++ b/thirdparty/openssl/crypto/x509/x509_txt.c
@@ -204,6 +204,13 @@ const char *X509_verify_cert_error_string(long n)
case X509_V_ERR_IP_ADDRESS_MISMATCH:
return ("IP address mismatch");
+ case X509_V_ERR_INVALID_CALL:
+ return ("Invalid certificate verification context");
+ case X509_V_ERR_STORE_LOOKUP:
+ return ("Issuer certificate lookup error");
+ case X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION:
+ return ("proxy subject name violation");
+
default:
BIO_snprintf(buf, sizeof buf, "error number %ld", n);
return (buf);
diff --git a/thirdparty/openssl/crypto/x509/x509_vfy.c b/thirdparty/openssl/crypto/x509/x509_vfy.c
index 4d34dbac93..b1472018ba 100644
--- a/thirdparty/openssl/crypto/x509/x509_vfy.c
+++ b/thirdparty/openssl/crypto/x509/x509_vfy.c
@@ -199,6 +199,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (ctx->cert == NULL) {
X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+ ctx->error = X509_V_ERR_INVALID_CALL;
return -1;
}
if (ctx->chain != NULL) {
@@ -207,6 +208,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
* cannot do another one.
*/
X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ ctx->error = X509_V_ERR_INVALID_CALL;
return -1;
}
@@ -219,6 +221,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (((ctx->chain = sk_X509_new_null()) == NULL) ||
(!sk_X509_push(ctx->chain, ctx->cert))) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
ok = -1;
goto err;
}
@@ -229,6 +232,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (ctx->untrusted != NULL
&& (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
ok = -1;
goto err;
}
@@ -253,8 +257,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
*/
if (ctx->param->flags & X509_V_FLAG_TRUSTED_FIRST) {
ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0)
+ if (ok < 0) {
+ ctx->error = X509_V_ERR_STORE_LOOKUP;
goto err;
+ }
/*
* If successful for now free up cert so it will be picked up
* again later.
@@ -271,6 +277,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (xtmp != NULL) {
if (!sk_X509_push(ctx->chain, xtmp)) {
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
ok = -1;
goto err;
}
@@ -352,14 +359,17 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
break;
ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0)
+ if (ok < 0) {
+ ctx->error = X509_V_ERR_STORE_LOOKUP;
goto err;
+ }
if (ok == 0)
break;
x = xtmp;
if (!sk_X509_push(ctx->chain, x)) {
X509_free(xtmp);
X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
ok = -1;
goto err;
}
@@ -386,8 +396,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
while (j-- > 1) {
xtmp2 = sk_X509_value(ctx->chain, j - 1);
ok = ctx->get_issuer(&xtmp, ctx, xtmp2);
- if (ok < 0)
+ if (ok < 0) {
+ ctx->error = X509_V_ERR_STORE_LOOKUP;
goto err;
+ }
/* Check if we found an alternate chain */
if (ok > 0) {
/*
@@ -515,6 +527,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
sk_X509_free(sktmp);
if (chain_ss != NULL)
X509_free(chain_ss);
+
+ /* Safety net, error returns must set ctx->error */
+ if (ok <= 0 && ctx->error == X509_V_OK)
+ ctx->error = X509_V_ERR_UNSPECIFIED;
return ok;
}
@@ -697,13 +713,27 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
* the next certificate must be a CA certificate.
*/
if (x->ex_flags & EXFLAG_PROXY) {
- if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) {
- ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
- ctx->error_depth = i;
- ctx->current_cert = x;
- ok = cb(0, ctx);
- if (!ok)
- goto end;
+ /*
+ * RFC3820, 4.1.3 (b)(1) stipulates that if pCPathLengthConstraint
+ * is less than max_path_length, the former should be copied to
+ * the latter, and 4.1.4 (a) stipulates that max_path_length
+ * should be verified to be larger than zero and decrement it.
+ *
+ * Because we're checking the certs in the reverse order, we start
+ * with verifying that proxy_path_length isn't larger than pcPLC,
+ * and copy the latter to the former if it is, and finally,
+ * increment proxy_path_length.
+ */
+ if (x->ex_pcpathlen != -1) {
+ if (proxy_path_length > x->ex_pcpathlen) {
+ ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ ok = cb(0, ctx);
+ if (!ok)
+ goto end;
+ }
+ proxy_path_length = x->ex_pcpathlen;
}
proxy_path_length++;
must_be_ca = 0;
@@ -726,6 +756,81 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
/* Ignore self issued certs unless last in chain */
if (i && (x->ex_flags & EXFLAG_SI))
continue;
+
+ /*
+ * Proxy certificates policy has an extra constraint, where the
+ * certificate subject MUST be the issuer with a single CN entry
+ * added.
+ * (RFC 3820: 3.4, 4.1.3 (a)(4))
+ */
+ if (x->ex_flags & EXFLAG_PROXY) {
+ X509_NAME *tmpsubject = X509_get_subject_name(x);
+ X509_NAME *tmpissuer = X509_get_issuer_name(x);
+ X509_NAME_ENTRY *tmpentry = NULL;
+ int last_object_nid = 0;
+ int err = X509_V_OK;
+ int last_object_loc = X509_NAME_entry_count(tmpsubject) - 1;
+
+ /* Check that there are at least two RDNs */
+ if (last_object_loc < 1) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that there is exactly one more RDN in subject as
+ * there is in issuer.
+ */
+ if (X509_NAME_entry_count(tmpsubject)
+ != X509_NAME_entry_count(tmpissuer) + 1) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that the last subject component isn't part of a
+ * multivalued RDN
+ */
+ if (X509_NAME_get_entry(tmpsubject, last_object_loc)->set
+ == X509_NAME_get_entry(tmpsubject, last_object_loc - 1)->set) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ goto proxy_name_done;
+ }
+
+ /*
+ * Check that the last subject RDN is a commonName, and that
+ * all the previous RDNs match the issuer exactly
+ */
+ tmpsubject = X509_NAME_dup(tmpsubject);
+ if (tmpsubject == NULL) {
+ X509err(X509_F_CHECK_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
+ return 0;
+ }
+
+ tmpentry =
+ X509_NAME_delete_entry(tmpsubject, last_object_loc);
+ last_object_nid =
+ OBJ_obj2nid(X509_NAME_ENTRY_get_object(tmpentry));
+
+ if (last_object_nid != NID_commonName
+ || X509_NAME_cmp(tmpsubject, tmpissuer) != 0) {
+ err = X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION;
+ }
+
+ X509_NAME_ENTRY_free(tmpentry);
+ X509_NAME_free(tmpsubject);
+
+ proxy_name_done:
+ if (err != X509_V_OK) {
+ ctx->error = err;
+ ctx->error_depth = i;
+ ctx->current_cert = x;
+ if (!ctx->verify_cb(0, ctx))
+ return 0;
+ }
+ }
+
/*
* Check against constraints for all certificates higher in chain
* including trust anchor. Trust anchor not strictly speaking needed
@@ -736,12 +841,19 @@ static int check_name_constraints(X509_STORE_CTX *ctx)
NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc;
if (nc) {
rv = NAME_CONSTRAINTS_check(x, nc);
- if (rv != X509_V_OK) {
+ switch (rv) {
+ case X509_V_OK:
+ continue;
+ case X509_V_ERR_OUT_OF_MEM:
+ ctx->error = rv;
+ return 0;
+ default:
ctx->error = rv;
ctx->error_depth = i;
ctx->current_cert = x;
if (!ctx->verify_cb(0, ctx))
return 0;
+ break;
}
}
}
@@ -880,6 +992,8 @@ static int check_cert(X509_STORE_CTX *ctx)
ctx->current_issuer = NULL;
ctx->current_crl_score = 0;
ctx->current_reasons = 0;
+ if (x->ex_flags & EXFLAG_PROXY)
+ return 1;
while (ctx->current_reasons != CRLDP_ALL_REASONS) {
last_reasons = ctx->current_reasons;
/* Try to retrieve relevant CRL */
@@ -1010,13 +1124,25 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
crl = sk_X509_CRL_value(crls, i);
reasons = *preasons;
crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x);
-
- if (crl_score > best_score) {
- best_crl = crl;
- best_crl_issuer = crl_issuer;
- best_score = crl_score;
- best_reasons = reasons;
+ if (crl_score < best_score || crl_score == 0)
+ continue;
+ /* If current CRL is equivalent use it if it is newer */
+ if (crl_score == best_score && best_crl != NULL) {
+ int day, sec;
+ if (ASN1_TIME_diff(&day, &sec, X509_CRL_get_lastUpdate(best_crl),
+ X509_CRL_get_lastUpdate(crl)) == 0)
+ continue;
+ /*
+ * ASN1_TIME_diff never returns inconsistent signs for |day|
+ * and |sec|.
+ */
+ if (day <= 0 && sec <= 0)
+ continue;
}
+ best_crl = crl;
+ best_crl_issuer = crl_issuer;
+ best_score = crl_score;
+ best_reasons = reasons;
}
if (best_crl) {
@@ -1630,6 +1756,7 @@ static int check_policy(X509_STORE_CTX *ctx)
ctx->param->policies, ctx->param->flags);
if (ret == 0) {
X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
return 0;
}
/* Invalid or inconsistent extensions */
@@ -1658,7 +1785,12 @@ static int check_policy(X509_STORE_CTX *ctx)
if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) {
ctx->current_cert = NULL;
- ctx->error = X509_V_OK;
+ /*
+ * Verification errors need to be "sticky", a callback may have allowed
+ * an SSL handshake to continue despite an error, and we must then
+ * remain in an error state. Therefore, we MUST NOT clear earlier
+ * verification errors by setting the error to X509_V_OK.
+ */
if (!ctx->verify_cb(2, ctx))
return 0;
}
diff --git a/thirdparty/openssl/crypto/x509/x509spki.c b/thirdparty/openssl/crypto/x509/x509spki.c
index 2df84ead9e..5ae5d30a35 100644
--- a/thirdparty/openssl/crypto/x509/x509spki.c
+++ b/thirdparty/openssl/crypto/x509/x509spki.c
@@ -112,6 +112,8 @@ char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
der_spki = OPENSSL_malloc(der_len);
b64_str = OPENSSL_malloc(der_len * 2);
if (!der_spki || !b64_str) {
+ OPENSSL_free(der_spki);
+ OPENSSL_free(b64_str);
X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/thirdparty/openssl/crypto/x509v3/v3_addr.c b/thirdparty/openssl/crypto/x509v3/v3_addr.c
index 94cfed0509..1290dec9bb 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_addr.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_addr.c
@@ -1211,6 +1211,11 @@ int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b)
/*
* Core code for RFC 3779 2.3 path validation.
+ *
+ * Returns 1 for success, 0 on error.
+ *
+ * When returning 0, ctx->error MUST be set to an appropriate value other than
+ * X509_V_OK.
*/
static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
STACK_OF(X509) *chain,
@@ -1245,6 +1250,7 @@ static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx,
if ((child = sk_IPAddressFamily_dup(ext)) == NULL) {
X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL,
ERR_R_MALLOC_FAILURE);
+ ctx->error = X509_V_ERR_OUT_OF_MEM;
ret = 0;
goto done;
}
diff --git a/thirdparty/openssl/crypto/x509v3/v3_alt.c b/thirdparty/openssl/crypto/x509v3/v3_alt.c
index 22ec202846..a0351faf11 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_alt.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_alt.c
@@ -119,32 +119,39 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
int i;
switch (gen->type) {
case GEN_OTHERNAME:
- X509V3_add_value("othername", "<unsupported>", &ret);
+ if (!X509V3_add_value("othername", "<unsupported>", &ret))
+ return NULL;
break;
case GEN_X400:
- X509V3_add_value("X400Name", "<unsupported>", &ret);
+ if (!X509V3_add_value("X400Name", "<unsupported>", &ret))
+ return NULL;
break;
case GEN_EDIPARTY:
- X509V3_add_value("EdiPartyName", "<unsupported>", &ret);
+ if (!X509V3_add_value("EdiPartyName", "<unsupported>", &ret))
+ return NULL;
break;
case GEN_EMAIL:
- X509V3_add_value_uchar("email", gen->d.ia5->data, &ret);
+ if (!X509V3_add_value_uchar("email", gen->d.ia5->data, &ret))
+ return NULL;
break;
case GEN_DNS:
- X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret);
+ if (!X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret))
+ return NULL;
break;
case GEN_URI:
- X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret);
+ if (!X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret))
+ return NULL;
break;
case GEN_DIRNAME:
- X509_NAME_oneline(gen->d.dirn, oline, 256);
- X509V3_add_value("DirName", oline, &ret);
+ if (X509_NAME_oneline(gen->d.dirn, oline, 256) == NULL
+ || !X509V3_add_value("DirName", oline, &ret))
+ return NULL;
break;
case GEN_IPADD:
@@ -162,15 +169,18 @@ STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method,
strcat(oline, ":");
}
} else {
- X509V3_add_value("IP Address", "<invalid>", &ret);
+ if (!X509V3_add_value("IP Address", "<invalid>", &ret))
+ return NULL;
break;
}
- X509V3_add_value("IP Address", oline, &ret);
+ if (!X509V3_add_value("IP Address", oline, &ret))
+ return NULL;
break;
case GEN_RID:
i2t_ASN1_OBJECT(oline, 256, gen->d.rid);
- X509V3_add_value("Registered ID", oline, &ret);
+ if (!X509V3_add_value("Registered ID", oline, &ret))
+ return NULL;
break;
}
return ret;
@@ -573,6 +583,8 @@ static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
return 0;
objlen = p - value;
objtmp = OPENSSL_malloc(objlen + 1);
+ if (objtmp == NULL)
+ return 0;
strncpy(objtmp, value, objlen);
objtmp[objlen] = 0;
gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0);
diff --git a/thirdparty/openssl/crypto/x509v3/v3_conf.c b/thirdparty/openssl/crypto/x509v3/v3_conf.c
index eeff8bd185..c1b4c1a89f 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_conf.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_conf.c
@@ -135,11 +135,13 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
nval = NCONF_get_section(conf, value + 1);
else
nval = X509V3_parse_list(value);
- if (sk_CONF_VALUE_num(nval) <= 0) {
+ if (nval == NULL || sk_CONF_VALUE_num(nval) <= 0) {
X509V3err(X509V3_F_DO_EXT_NCONF,
X509V3_R_INVALID_EXTENSION_STRING);
ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=",
value);
+ if (*value != '@')
+ sk_CONF_VALUE_free(nval);
return NULL;
}
ext_struc = method->v2i(method, ctx, nval);
diff --git a/thirdparty/openssl/crypto/x509v3/v3_cpols.c b/thirdparty/openssl/crypto/x509v3/v3_cpols.c
index d97f6226b9..b99269e7f8 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_cpols.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_cpols.c
@@ -390,10 +390,10 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
return 1;
merr:
+ ASN1_INTEGER_free(aint);
X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE);
err:
- sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
return 0;
}
@@ -458,9 +458,15 @@ static void print_notice(BIO *out, USERNOTICE *notice, int indent)
num = sk_ASN1_INTEGER_value(ref->noticenos, i);
if (i)
BIO_puts(out, ", ");
- tmp = i2s_ASN1_INTEGER(NULL, num);
- BIO_puts(out, tmp);
- OPENSSL_free(tmp);
+ if (num == NULL)
+ BIO_puts(out, "(null)");
+ else {
+ tmp = i2s_ASN1_INTEGER(NULL, num);
+ if (tmp == NULL)
+ return;
+ BIO_puts(out, tmp);
+ OPENSSL_free(tmp);
+ }
}
BIO_puts(out, "\n");
}
diff --git a/thirdparty/openssl/crypto/x509v3/v3_info.c b/thirdparty/openssl/crypto/x509v3/v3_info.c
index e052a34b94..7064c725d9 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_info.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_info.c
@@ -107,29 +107,30 @@ ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS)
IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS)
-static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
- *method, AUTHORITY_INFO_ACCESS
- *ainfo, STACK_OF(CONF_VALUE)
- *ret)
+static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(
+ X509V3_EXT_METHOD *method, AUTHORITY_INFO_ACCESS *ainfo,
+ STACK_OF(CONF_VALUE) *ret)
{
ACCESS_DESCRIPTION *desc;
int i, nlen;
char objtmp[80], *ntmp;
CONF_VALUE *vtmp;
+ STACK_OF(CONF_VALUE) *tret = ret;
+
for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) {
+ STACK_OF(CONF_VALUE) *tmp;
+
desc = sk_ACCESS_DESCRIPTION_value(ainfo, i);
- ret = i2v_GENERAL_NAME(method, desc->location, ret);
- if (!ret)
- break;
- vtmp = sk_CONF_VALUE_value(ret, i);
+ tmp = i2v_GENERAL_NAME(method, desc->location, tret);
+ if (tmp == NULL)
+ goto err;
+ tret = tmp;
+ vtmp = sk_CONF_VALUE_value(tret, i);
i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method);
nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
ntmp = OPENSSL_malloc(nlen);
- if (!ntmp) {
- X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS,
- ERR_R_MALLOC_FAILURE);
- return NULL;
- }
+ if (ntmp == NULL)
+ goto err;
BUF_strlcpy(ntmp, objtmp, nlen);
BUF_strlcat(ntmp, " - ", nlen);
BUF_strlcat(ntmp, vtmp->name, nlen);
@@ -137,9 +138,15 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
vtmp->name = ntmp;
}
- if (!ret)
+ if (ret == NULL && tret == NULL)
return sk_CONF_VALUE_new_null();
- return ret;
+
+ return tret;
+ err:
+ X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ if (ret == NULL && tret != NULL)
+ sk_CONF_VALUE_pop_free(tret, X509V3_conf_free);
+ return NULL;
}
static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD
diff --git a/thirdparty/openssl/crypto/x509v3/v3_purp.c b/thirdparty/openssl/crypto/x509v3/v3_purp.c
index 845be673b7..96e629a930 100644
--- a/thirdparty/openssl/crypto/x509v3/v3_purp.c
+++ b/thirdparty/openssl/crypto/x509v3/v3_purp.c
@@ -321,6 +321,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
NID_subject_alt_name, /* 85 */
NID_basic_constraints, /* 87 */
NID_certificate_policies, /* 89 */
+ NID_crl_distribution_points, /* 103 */
NID_ext_key_usage, /* 126 */
#ifndef OPENSSL_NO_RFC3779
NID_sbgp_ipAddrBlock, /* 290 */
diff --git a/thirdparty/openssl/openssl/bio.h b/thirdparty/openssl/openssl/bio.h
index 6790aed28e..8f2438cdad 100644
--- a/thirdparty/openssl/openssl/bio.h
+++ b/thirdparty/openssl/openssl/bio.h
@@ -559,11 +559,11 @@ int BIO_read_filename(BIO *b, const char *name);
# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp)
# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL)
# define BIO_set_ssl_renegotiate_bytes(b,num) \
- BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL);
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL)
# define BIO_get_num_renegotiates(b) \
- BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL);
+ BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL)
# define BIO_set_ssl_renegotiate_timeout(b,seconds) \
- BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL);
+ BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL)
/* defined in evp.h */
/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */
diff --git a/thirdparty/openssl/openssl/bn.h b/thirdparty/openssl/openssl/bn.h
index 86264ae631..633d1b1f60 100644
--- a/thirdparty/openssl/openssl/bn.h
+++ b/thirdparty/openssl/openssl/bn.h
@@ -842,6 +842,8 @@ int RAND_pseudo_bytes(unsigned char *buf, int num);
if (*(ftl--)) break; \
(a)->top = tmp_top; \
} \
+ if ((a)->top == 0) \
+ (a)->neg = 0; \
bn_pollute(a); \
}
diff --git a/thirdparty/openssl/openssl/comp.h b/thirdparty/openssl/openssl/comp.h
index 60a073404e..df599ba331 100644
--- a/thirdparty/openssl/openssl/comp.h
+++ b/thirdparty/openssl/openssl/comp.h
@@ -14,7 +14,7 @@ extern "C" {
typedef struct comp_ctx_st COMP_CTX;
-typedef struct comp_method_st {
+struct comp_method_st {
int type; /* NID for compression library */
const char *name; /* A text string to identify the library */
int (*init) (COMP_CTX *ctx);
@@ -30,7 +30,7 @@ typedef struct comp_method_st {
*/
long (*ctrl) (void);
long (*callback_ctrl) (void);
-} COMP_METHOD;
+};
struct comp_ctx_st {
COMP_METHOD *meth;
diff --git a/thirdparty/openssl/openssl/conf.h b/thirdparty/openssl/openssl/conf.h
index 8d926d5d82..fe49113080 100644
--- a/thirdparty/openssl/openssl/conf.h
+++ b/thirdparty/openssl/openssl/conf.h
@@ -259,6 +259,7 @@ void ERR_load_CONF_strings(void);
# define CONF_R_NO_VALUE 108
# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103
# define CONF_R_UNKNOWN_MODULE_NAME 113
+# define CONF_R_VARIABLE_EXPANSION_TOO_LONG 116
# define CONF_R_VARIABLE_HAS_NO_VALUE 104
#ifdef __cplusplus
diff --git a/thirdparty/openssl/openssl/dh.h b/thirdparty/openssl/openssl/dh.h
index a5bd9016aa..a228c7a7a4 100644
--- a/thirdparty/openssl/openssl/dh.h
+++ b/thirdparty/openssl/openssl/dh.h
@@ -182,12 +182,29 @@ struct dh_st {
*/
# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME
-# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
- (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x))
-# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \
- (unsigned char *)(x))
-# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x)
-# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+# define d2i_DHparams_fp(fp,x) \
+ (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+ (char *(*)())d2i_DHparams, \
+ (fp), \
+ (unsigned char **)(x))
+# define i2d_DHparams_fp(fp,x) \
+ ASN1_i2d_fp(i2d_DHparams,(fp), (unsigned char *)(x))
+# define d2i_DHparams_bio(bp,x) \
+ ASN1_d2i_bio_of(DH, DH_new, d2i_DHparams, bp, x)
+# define i2d_DHparams_bio(bp,x) \
+ ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x)
+
+# define d2i_DHxparams_fp(fp,x) \
+ (DH *)ASN1_d2i_fp((char *(*)())DH_new, \
+ (char *(*)())d2i_DHxparams, \
+ (fp), \
+ (unsigned char **)(x))
+# define i2d_DHxparams_fp(fp,x) \
+ ASN1_i2d_fp(i2d_DHxparams,(fp), (unsigned char *)(x))
+# define d2i_DHxparams_bio(bp,x) \
+ ASN1_d2i_bio_of(DH, DH_new, d2i_DHxparams, bp, x)
+# define i2d_DHxparams_bio(bp,x) \
+ ASN1_i2d_bio_of_const(DH, i2d_DHxparams, bp, x)
DH *DHparams_dup(DH *);
diff --git a/thirdparty/openssl/openssl/dtls1.h b/thirdparty/openssl/openssl/dtls1.h
index cdd1e4d86e..81d28c29cd 100644
--- a/thirdparty/openssl/openssl/dtls1.h
+++ b/thirdparty/openssl/openssl/dtls1.h
@@ -69,9 +69,6 @@
# ifdef OPENSSL_SYS_WIN32
/* Needed for struct timeval */
# include <winsock.h>
-#ifdef X509_NAME
-#undef X509_NAME
-#endif
# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_)
# include <sys/timeval.h>
# else
@@ -81,9 +78,9 @@
# include <sys/time.h>
# endif
# endif
-#ifdef UWP_ENABLED
+#ifdef UWP_ENABLED // -- GODOT start --
#include <winsock2.h>
-#endif
+#endif // -- GODOT end --
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/openssl/openssl/err.h b/thirdparty/openssl/openssl/err.h
index 585aa8ba3d..f42365620d 100644
--- a/thirdparty/openssl/openssl/err.h
+++ b/thirdparty/openssl/openssl/err.h
@@ -258,6 +258,7 @@ typedef struct err_state_st {
# define SYS_F_WSASTARTUP 9/* Winsock stuff */
# define SYS_F_OPENDIR 10
# define SYS_F_FREAD 11
+# define SYS_F_FFLUSH 18
/* reasons */
# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */
diff --git a/thirdparty/openssl/openssl/evp.h b/thirdparty/openssl/openssl/evp.h
index 39ab7937d2..d258ef870a 100644
--- a/thirdparty/openssl/openssl/evp.h
+++ b/thirdparty/openssl/openssl/evp.h
@@ -1370,6 +1370,7 @@ void EVP_add_alg_module(void);
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
+
void ERR_load_EVP_strings(void);
/* Error codes for the EVP functions. */
@@ -1489,6 +1490,7 @@ void ERR_load_EVP_strings(void);
# define EVP_R_INPUT_NOT_INITIALIZED 111
# define EVP_R_INVALID_DIGEST 152
# define EVP_R_INVALID_FIPS_MODE 168
+# define EVP_R_INVALID_KEY 171
# define EVP_R_INVALID_KEY_LENGTH 130
# define EVP_R_INVALID_OPERATION 148
# define EVP_R_IV_TOO_LARGE 102
@@ -1528,7 +1530,7 @@ void ERR_load_EVP_strings(void);
# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109
# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
diff --git a/thirdparty/openssl/openssl/md5.h b/thirdparty/openssl/openssl/md5.h
index 300d3f3463..2659038abd 100644
--- a/thirdparty/openssl/openssl/md5.h
+++ b/thirdparty/openssl/openssl/md5.h
@@ -107,18 +107,11 @@ typedef struct MD5state_st {
# ifdef OPENSSL_FIPS
int private_MD5_Init(MD5_CTX *c);
# endif
-
-//#define MD5_Init _SSL_MD5_Init
-#define MD5_Final _SSL_MD5_Final
-#define MD5_Update _SSL_MD5_Update
-#define MD5_Transform _SSL_MD5_Transform
-#define MD5_Init private_MD5_Init
-
-int _SSL_MD5_Init(MD5_CTX *c);
-int _SSL_MD5_Update(MD5_CTX *c, const void *data, size_t len);
-int _SSL_MD5_Final(unsigned char *md, MD5_CTX *c);
+int MD5_Init(MD5_CTX *c);
+int MD5_Update(MD5_CTX *c, const void *data, size_t len);
+int MD5_Final(unsigned char *md, MD5_CTX *c);
unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md);
-void _SSL_MD5_Transform(MD5_CTX *c, const unsigned char *b);
+void MD5_Transform(MD5_CTX *c, const unsigned char *b);
#ifdef __cplusplus
}
#endif
diff --git a/thirdparty/openssl/openssl/opensslconf.h b/thirdparty/openssl/openssl/opensslconf.h
index c86bb60b94..19fad23423 100644
--- a/thirdparty/openssl/openssl/opensslconf.h
+++ b/thirdparty/openssl/openssl/opensslconf.h
@@ -1,37 +1,26 @@
/* opensslconf.h */
/* WARNING: Generated automatically from opensslconf.h.in by Configure. */
-//sorry godot needs a single file for multiple builds
-
#ifdef __cplusplus
extern "C" {
#endif
+/* OpenSSL was configured with the following options: */
+#ifndef OPENSSL_DOING_MAKEDEPEND
-// Check windows
-
-#ifdef USE_64BITS
-//weirder platforms that don't use GCC, LLVM or MSVC must define this
-# define OPENSSL_USE_64_BITS
-#elif _WIN32 || _WIN64
-# if _WIN64
-# define OPENSSL_USE_64_BITS
+// -- GODOT start --
+#if defined(OPENSSL_SYS_WINDOWS)
+# define WIN32_LEAN_AND_MEAN
+// Seems like we have troubles properly using the logic in e_os2.h
+# if defined(_WIN32)
+# define OPENSSL_SYS_WIN32
+# define OPENSSL_SYSNAME_WIN32
# endif
-// Check GCC
-#elif __GNUC__
-# if __x86_64__ || __ppc64__
-# define OPENSSL_USE_64_BITS
+# if defined(_WIN64)
+# define OPENSSL_SYS_WIN64
+# define OPENSSL_SYSNAME_WIN64
# endif
#endif
-
-#ifndef OPENSSL_USE_64_BITS
-//wqerw
-#endif
-
-
-
-/* OpenSSL was configured with the following options: */
-#ifndef OPENSSL_DOING_MAKEDEPEND
-
+// -- GODOT end --
#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
# define OPENSSL_NO_EC_NISTP_64_GCC_128
@@ -78,9 +67,6 @@ extern "C" {
#endif /* OPENSSL_DOING_MAKEDEPEND */
-#ifndef OPENSSL_THREADS
-# define OPENSSL_THREADS
-#endif
#ifndef OPENSSL_NO_DYNAMIC_ENGINE
# define OPENSSL_NO_DYNAMIC_ENGINE
#endif
@@ -134,8 +120,6 @@ extern "C" {
# endif
#endif
-//#define OPENSSL_CPUID_OBJ
-
/* crypto/opensslconf.h.in */
/* Generate 80386 code? */
@@ -175,19 +159,14 @@ extern "C" {
* - Intel P6 because partial register stalls are very expensive;
* - elder Alpha because it lacks byte load/store instructions;
*/
-#ifdef OPENSSL_USE_64_BITS
#define RC4_INT unsigned int
-#else
-#define RC4_INT unsigned char
-#endif
-
#endif
#if !defined(RC4_CHUNK)
/*
* This enables code handling data aligned at natural CPU word
* boundary. See crypto/rc4/rc4_enc.c for further details.
*/
-#define RC4_CHUNK unsigned long
+#undef RC4_CHUNK
#endif
#endif
@@ -195,42 +174,20 @@ extern "C" {
/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a
* %20 speed up (longs are 8 bytes, int's are 4). */
#ifndef DES_LONG
-#define DES_LONG unsigned int
+#define DES_LONG unsigned long
#endif
#endif
#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H)
#define CONFIG_HEADER_BN_H
-#ifdef OPENSSL_USE_64_BITS
#undef BN_LLONG
-#else
-#define BN_LLONG
-#endif
/* Should we define BN_DIV2W here? */
/* Only one for the following should be defined */
-
-#ifdef OPENSSL_USE_64_BITS
-
-# ifdef _WIN32
-# undef SIXTY_FOUR_BIT_LONG
-# define SIXTY_FOUR_BIT
-# else
-# define SIXTY_FOUR_BIT_LONG
-# undef SIXTY_FOUR_BIT
-# endif
-#undef THIRTY_TWO_BIT
-
-#else
-
#undef SIXTY_FOUR_BIT_LONG
#undef SIXTY_FOUR_BIT
#define THIRTY_TWO_BIT
-
-#endif
-
-
#endif
#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H)
@@ -272,7 +229,7 @@ extern "C" {
/* Unroll the inner loop, this sometimes helps, sometimes hinders.
* Very mucy CPU dependant */
#ifndef DES_UNROLL
-#define DES_UNROLL
+#undef DES_UNROLL
#endif
/* These default values were supplied by
diff --git a/thirdparty/openssl/openssl/opensslv.h b/thirdparty/openssl/openssl/opensslv.h
index 13fe440231..825a330abc 100644
--- a/thirdparty/openssl/openssl/opensslv.h
+++ b/thirdparty/openssl/openssl/opensslv.h
@@ -30,11 +30,11 @@ extern "C" {
* (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for
* major minor fix final patch/beta)
*/
-# define OPENSSL_VERSION_NUMBER 0x1000208fL
+# define OPENSSL_VERSION_NUMBER 0x100020cfL
# ifdef OPENSSL_FIPS
-# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h-fips 3 May 2016"
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l-fips 25 May 2017"
# else
-# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2h 3 May 2016"
+# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.2l 25 May 2017"
# endif
# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT
diff --git a/thirdparty/openssl/openssl/ossl_typ.h b/thirdparty/openssl/openssl/ossl_typ.h
index 9144ea2cf6..364d26238e 100644
--- a/thirdparty/openssl/openssl/ossl_typ.h
+++ b/thirdparty/openssl/openssl/ossl_typ.h
@@ -178,6 +178,8 @@ typedef struct engine_st ENGINE;
typedef struct ssl_st SSL;
typedef struct ssl_ctx_st SSL_CTX;
+typedef struct comp_method_st COMP_METHOD;
+
typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
diff --git a/thirdparty/openssl/openssl/pem.h b/thirdparty/openssl/openssl/pem.h
index d3b23fc997..aac72fb21e 100644
--- a/thirdparty/openssl/openssl/pem.h
+++ b/thirdparty/openssl/openssl/pem.h
@@ -531,6 +531,7 @@ int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel,
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
+
void ERR_load_PEM_strings(void);
/* Error codes for the PEM functions. */
@@ -592,6 +593,7 @@ void ERR_load_PEM_strings(void);
# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115
# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119
# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120
+# define PEM_R_HEADER_TOO_LONG 128
# define PEM_R_INCONSISTENT_HEADER 121
# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122
# define PEM_R_KEYBLOB_TOO_SHORT 123
@@ -609,7 +611,7 @@ void ERR_load_PEM_strings(void);
# define PEM_R_UNSUPPORTED_ENCRYPTION 114
# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
diff --git a/thirdparty/openssl/openssl/pkcs12.h b/thirdparty/openssl/openssl/pkcs12.h
index a39adf5eb5..21f1f62b36 100644
--- a/thirdparty/openssl/openssl/pkcs12.h
+++ b/thirdparty/openssl/openssl/pkcs12.h
@@ -270,7 +270,7 @@ int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12);
int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12);
PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12);
PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12);
-int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass);
+int PKCS12_newpass(PKCS12 *p12, const char *oldpass, const char *newpass);
/* BEGIN ERROR CODES */
/*
diff --git a/thirdparty/openssl/openssl/rand.h b/thirdparty/openssl/openssl/rand.h
index 66068834eb..2553afda20 100644
--- a/thirdparty/openssl/openssl/rand.h
+++ b/thirdparty/openssl/openssl/rand.h
@@ -64,23 +64,7 @@
# include <openssl/e_os2.h>
# if defined(OPENSSL_SYS_WINDOWS)
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#ifdef OCSP_RESPONSE
-#undef OCSP_RESPONSE
-#endif
-#ifdef OCSP_REQUEST
-#undef OCSP_REQUEST
-#endif
-#ifdef X509_NAME
-#undef X509_NAME
-#undef X509_NAME
-#undef X509_EXTENSIONS
-#undef X509_CERT_PAIR
-#undef PKCS7_ISSUER_AND_SERIAL
-#endif
-
-
+# include <windows.h>
# endif
#ifdef __cplusplus
diff --git a/thirdparty/openssl/openssl/ssl.h b/thirdparty/openssl/openssl/ssl.h
index 5ef56faa50..90aeb0ce4e 100644
--- a/thirdparty/openssl/openssl/ssl.h
+++ b/thirdparty/openssl/openssl/ssl.h
@@ -2532,7 +2532,6 @@ void SSL_set_tmp_ecdh_callback(SSL *ssl,
int keylength));
# endif
-# ifndef OPENSSL_NO_COMP
const COMP_METHOD *SSL_get_current_compression(SSL *s);
const COMP_METHOD *SSL_get_current_expansion(SSL *s);
const char *SSL_COMP_get_name(const COMP_METHOD *comp);
@@ -2541,13 +2540,6 @@ STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
*meths);
void SSL_COMP_free_compression_methods(void);
int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
-# else
-const void *SSL_get_current_compression(SSL *s);
-const void *SSL_get_current_expansion(SSL *s);
-const char *SSL_COMP_get_name(const void *comp);
-void *SSL_COMP_get_compression_methods(void);
-int SSL_COMP_add_compression_method(int id, void *cm);
-# endif
const SSL_CIPHER *SSL_CIPHER_find(SSL *ssl, const unsigned char *ptr);
@@ -2623,6 +2615,7 @@ void ERR_load_SSL_strings(void);
# define SSL_F_DTLS1_HEARTBEAT 305
# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255
# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288
+# define SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS 424
# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256
# define SSL_F_DTLS1_PROCESS_RECORD 257
# define SSL_F_DTLS1_READ_BYTES 258
@@ -3114,6 +3107,7 @@ void ERR_load_SSL_strings(void);
# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157
# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233
# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234
+# define SSL_R_TOO_MANY_WARN_ALERTS 409
# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235
# define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236
# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313
diff --git a/thirdparty/openssl/openssl/ts.h b/thirdparty/openssl/openssl/ts.h
index 16eccbb38d..2daa1b2fb5 100644
--- a/thirdparty/openssl/openssl/ts.h
+++ b/thirdparty/openssl/openssl/ts.h
@@ -565,6 +565,9 @@ int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx,
/* At most we accept usec precision. */
# define TS_MAX_CLOCK_PRECISION_DIGITS 6
+/* Maximum status message length */
+# define TS_MAX_STATUS_LENGTH (1024 * 1024)
+
/* No flags are set by default. */
void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags);
diff --git a/thirdparty/openssl/openssl/x509.h b/thirdparty/openssl/openssl/x509.h
index fc613ce635..6fa28ebada 100644
--- a/thirdparty/openssl/openssl/x509.h
+++ b/thirdparty/openssl/openssl/x509.h
@@ -1234,6 +1234,7 @@ int X509_TRUST_get_trust(X509_TRUST *xp);
* The following lines are auto generated by the script mkerr.pl. Any changes
* made after this point may be overwritten when the script is next run.
*/
+
void ERR_load_X509_strings(void);
/* Error codes for the X509 functions. */
@@ -1241,6 +1242,7 @@ void ERR_load_X509_strings(void);
/* Function codes. */
# define X509_F_ADD_CERT_DIR 100
# define X509_F_BY_FILE_CTRL 101
+# define X509_F_CHECK_NAME_CONSTRAINTS 106
# define X509_F_CHECK_POLICY 145
# define X509_F_DIR_CTRL 102
# define X509_F_GET_CERT_BY_SUBJECT 103
@@ -1322,7 +1324,7 @@ void ERR_load_X509_strings(void);
# define X509_R_WRONG_LOOKUP_TYPE 112
# define X509_R_WRONG_TYPE 122
-#ifdef __cplusplus
+# ifdef __cplusplus
}
-#endif
+# endif
#endif
diff --git a/thirdparty/openssl/openssl/x509_vfy.h b/thirdparty/openssl/openssl/x509_vfy.h
index 2663e1c0a3..50626826e0 100644
--- a/thirdparty/openssl/openssl/x509_vfy.h
+++ b/thirdparty/openssl/openssl/x509_vfy.h
@@ -368,6 +368,7 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
# define X509_V_ERR_PERMITTED_VIOLATION 47
# define X509_V_ERR_EXCLUDED_VIOLATION 48
# define X509_V_ERR_SUBTREE_MINMAX 49
+# define X509_V_ERR_APPLICATION_VERIFICATION 50
# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51
# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52
# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53
@@ -386,8 +387,12 @@ void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth);
# define X509_V_ERR_EMAIL_MISMATCH 63
# define X509_V_ERR_IP_ADDRESS_MISMATCH 64
-/* The application is not happy */
-# define X509_V_ERR_APPLICATION_VERIFICATION 50
+/* Caller error */
+# define X509_V_ERR_INVALID_CALL 65
+/* Issuer lookup error */
+# define X509_V_ERR_STORE_LOOKUP 66
+
+# define X509_V_ERR_PROXY_SUBJECT_NAME_VIOLATION 67
/* Certificate verify flags */
diff --git a/thirdparty/openssl/patches/config_windows.patch b/thirdparty/openssl/patches/config_windows.patch
new file mode 100644
index 0000000000..e69ff1356a
--- /dev/null
+++ b/thirdparty/openssl/patches/config_windows.patch
@@ -0,0 +1,49 @@
+commit 4c8ab8b4415d129d0283d7d0d9a5789163ec8d5e
+Author: Rémi Verschelde <rverschelde@gmail.com>
+Date: Sat May 27 16:38:46 2017 +0200
+
+ openssl: Define WIN32_LEAN_AND_MEAN on Windows
+
+ This avoids namespace collisions with things such as X509_NAME.
+ Also force include of necessary definitions in `crypto/o_str.c`
+ which seem missing on MSVC (but work on MinGW).
+
+diff --git a/thirdparty/openssl/crypto/o_str.c b/thirdparty/openssl/crypto/o_str.c
+index 7e61cde85..1854798e2 100644
+--- a/thirdparty/openssl/crypto/o_str.c
++++ b/thirdparty/openssl/crypto/o_str.c
+@@ -59,6 +59,9 @@
+
+ #include <ctype.h>
+ #include <e_os.h>
++// -- GODOT start --
++#include <openssl/opensslconf.h>
++// -- GODOT end --
+ #include "o_str.h"
+
+ #if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \
+diff --git a/thirdparty/openssl/openssl/opensslconf.h b/thirdparty/openssl/openssl/opensslconf.h
+index f533508b1..19fad2342 100644
+--- a/thirdparty/openssl/openssl/opensslconf.h
++++ b/thirdparty/openssl/openssl/opensslconf.h
+@@ -7,6 +7,20 @@ extern "C" {
+ /* OpenSSL was configured with the following options: */
+ #ifndef OPENSSL_DOING_MAKEDEPEND
+
++// -- GODOT start --
++#if defined(OPENSSL_SYS_WINDOWS)
++# define WIN32_LEAN_AND_MEAN
++// Seems like we have troubles properly using the logic in e_os2.h
++# if defined(_WIN32)
++# define OPENSSL_SYS_WIN32
++# define OPENSSL_SYSNAME_WIN32
++# endif
++# if defined(_WIN64)
++# define OPENSSL_SYS_WIN64
++# define OPENSSL_SYSNAME_WIN64
++# endif
++#endif
++// -- GODOT end --
+
+ #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+ # define OPENSSL_NO_EC_NISTP_64_GCC_128
diff --git a/thirdparty/openssl/uwp_fix.patch b/thirdparty/openssl/patches/uwp_fix.patch
index 00d8b64d00..54aeb1f80d 100644
--- a/thirdparty/openssl/uwp_fix.patch
+++ b/thirdparty/openssl/patches/uwp_fix.patch
@@ -1,15 +1,15 @@
-diff --git a/drivers/builtin_openssl2/crypto/rand/rand_win.c b/drivers/builtin_openssl2/crypto/rand/rand_win.c
-index 06670ae..70fd52a 100644
---- a/drivers/builtin_openssl2/crypto/rand/rand_win.c
-+++ b/drivers/builtin_openssl2/crypto/rand/rand_win.c
+diff --git a/thirdparty/openssl/crypto/rand/rand_win.c b/thirdparty/openssl/crypto/rand/rand_win.c
+index 06670ae01..cb4093128 100644
+--- a/thirdparty/openssl/crypto/rand/rand_win.c
++++ b/thirdparty/openssl/crypto/rand/rand_win.c
@@ -118,8 +118,10 @@
# ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
# endif
-+#ifndef UWP_ENABLED
++#ifndef UWP_ENABLED // -- GODOT --
# include <wincrypt.h>
# include <tlhelp32.h>
-+#endif
++#endif // -- GODOT --
/*
* Limit the time spent walking through the heap, processes, threads and
@@ -18,7 +18,7 @@ index 06670ae..70fd52a 100644
# endif /* CURSOR_SHOWING */
-# if !defined(OPENSSL_SYS_WINCE)
-+# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED)
++# if !defined(OPENSSL_SYS_WINCE) && !defined(UWP_ENABLED) // -- GODOT --
typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR,
DWORD, DWORD);
typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *);
@@ -26,7 +26,7 @@ index 06670ae..70fd52a 100644
# endif /* 1 */
# endif /* !OPENSSL_SYS_WINCE */
-+#if !defined(UWP_ENABLED)
++#if !defined(UWP_ENABLED) // -- GODOT --
int RAND_poll(void)
{
MEMORYSTATUS m;
@@ -34,7 +34,7 @@ index 06670ae..70fd52a 100644
return (1);
}
-+#endif // UWP_ENABLED
++#endif // UWP_ENABLED // -- GODOT --
+
int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
{
@@ -44,21 +44,21 @@ index 06670ae..70fd52a 100644
static void readscreen(void)
{
-# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
-+# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED)
++# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) && !defined(UWP_ENABLED) // -- GODOT --
HDC hScrDC; /* screen DC */
HBITMAP hBitmap; /* handle for our bitmap */
BITMAP bm; /* bitmap properties */
-diff --git a/drivers/builtin_openssl2/openssl/dtls1.h b/drivers/builtin_openssl2/openssl/dtls1.h
-index 64ad3c8..a58aca2 100644
---- a/drivers/builtin_openssl2/openssl/dtls1.h
-+++ b/drivers/builtin_openssl2/openssl/dtls1.h
-@@ -81,6 +81,9 @@
+diff --git a/thirdparty/openssl/openssl/dtls1.h b/thirdparty/openssl/openssl/dtls1.h
+index 30bbcf278..81d28c29c 100644
+--- a/thirdparty/openssl/openssl/dtls1.h
++++ b/thirdparty/openssl/openssl/dtls1.h
+@@ -78,6 +78,9 @@
# include <sys/time.h>
# endif
# endif
-+#ifdef UWP_ENABLED
++#ifdef UWP_ENABLED // -- GODOT start --
+#include <winsock2.h>
-+#endif
++#endif // -- GODOT end --
#ifdef __cplusplus
extern "C" {
diff --git a/thirdparty/openssl/ssl/d1_both.c b/thirdparty/openssl/ssl/d1_both.c
index 5d26c94926..e6bc761e8b 100644
--- a/thirdparty/openssl/ssl/d1_both.c
+++ b/thirdparty/openssl/ssl/d1_both.c
@@ -517,6 +517,17 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
return i;
}
+ /*
+ * Don't change the *message* read sequence number while listening. For
+ * the *record* write sequence we reflect the ClientHello sequence number
+ * when listening.
+ */
+ if (s->d1->listen)
+ memcpy(s->s3->write_sequence, s->s3->read_sequence,
+ sizeof(s->s3->write_sequence));
+ else
+ s->d1->handshake_read_seq++;
+
if (mt >= 0 && s->s3->tmp.message_type != mt) {
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE);
@@ -544,10 +555,6 @@ long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
memset(msg_hdr, 0x00, sizeof(struct hm_header_st));
- /* Don't change sequence numbers while listening */
- if (!s->d1->listen)
- s->d1->handshake_read_seq++;
-
s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH;
return s->init_num;
@@ -581,9 +588,12 @@ static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr,
/*
* msg_len is limited to 2^24, but is effectively checked against max
* above
+ *
+ * Make buffer slightly larger than message length as a precaution
+ * against small OOB reads e.g. CVE-2016-6306
*/
if (!BUF_MEM_grow_clean
- (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) {
+ (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH + 16)) {
SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB);
return SSL_AD_INTERNAL_ERROR;
}
@@ -618,11 +628,23 @@ static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
int al;
*ok = 0;
- item = pqueue_peek(s->d1->buffered_messages);
- if (item == NULL)
- return 0;
+ do {
+ item = pqueue_peek(s->d1->buffered_messages);
+ if (item == NULL)
+ return 0;
+
+ frag = (hm_fragment *)item->data;
+
+ if (frag->msg_header.seq < s->d1->handshake_read_seq) {
+ /* This is a stale message that has been buffered so clear it */
+ pqueue_pop(s->d1->buffered_messages);
+ dtls1_hm_fragment_free(frag);
+ pitem_free(item);
+ item = NULL;
+ frag = NULL;
+ }
+ } while (item == NULL);
- frag = (hm_fragment *)item->data;
/* Don't return if reassembly still in progress */
if (frag->reassembly != NULL)
@@ -1053,7 +1075,9 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
int dtls1_read_failed(SSL *s, int code)
{
if (code > 0) {
+#ifdef TLS_DEBUG
fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
+#endif
return 1;
}
@@ -1125,7 +1149,9 @@ int dtls1_retransmit_buffered_messages(SSL *s)
(frag->msg_header.seq,
frag->msg_header.is_ccs), 0,
&found) <= 0 && found) {
+#ifdef TLS_DEBUG
fprintf(stderr, "dtls1_retransmit_message() failed\n");
+#endif
return -1;
}
}
@@ -1211,7 +1237,7 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
unsigned long header_length;
unsigned char seq64be[8];
struct dtls1_retransmit_state saved_state;
- unsigned char save_write_sequence[8];
+ unsigned char save_write_sequence[8] = {0, 0, 0, 0, 0, 0, 0, 0};
/*-
OPENSSL_assert(s->init_num == 0);
@@ -1225,7 +1251,9 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
item = pqueue_find(s->d1->sent_messages, seq64be);
if (item == NULL) {
+#ifdef TLS_DEBUG
fprintf(stderr, "retransmit: message %d non-existant\n", seq);
+#endif
*found = 0;
return 0;
}
@@ -1296,18 +1324,6 @@ dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off,
return ret;
}
-/* call this function when the buffered messages are no longer needed */
-void dtls1_clear_record_buffer(SSL *s)
-{
- pitem *item;
-
- for (item = pqueue_pop(s->d1->sent_messages);
- item != NULL; item = pqueue_pop(s->d1->sent_messages)) {
- dtls1_hm_fragment_free((hm_fragment *)item->data);
- pitem_free(item);
- }
-}
-
unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p,
unsigned char mt, unsigned long len,
unsigned long frag_off,
@@ -1469,7 +1485,7 @@ int dtls1_process_heartbeat(SSL *s)
memcpy(bp, pl, payload);
bp += payload;
/* Random padding */
- if (RAND_pseudo_bytes(bp, padding) < 0) {
+ if (RAND_bytes(bp, padding) <= 0) {
OPENSSL_free(buffer);
return -1;
}
@@ -1546,6 +1562,8 @@ int dtls1_heartbeat(SSL *s)
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ if (buf == NULL)
+ goto err;
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
@@ -1554,11 +1572,11 @@ int dtls1_heartbeat(SSL *s)
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
- if (RAND_pseudo_bytes(p, 16) < 0)
+ if (RAND_bytes(p, 16) <= 0)
goto err;
p += 16;
/* Random padding */
- if (RAND_pseudo_bytes(p, padding) < 0)
+ if (RAND_bytes(p, padding) <= 0)
goto err;
ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding);
diff --git a/thirdparty/openssl/ssl/d1_clnt.c b/thirdparty/openssl/ssl/d1_clnt.c
index 3ddfa7bca4..76451a346d 100644
--- a/thirdparty/openssl/ssl/d1_clnt.c
+++ b/thirdparty/openssl/ssl/d1_clnt.c
@@ -320,8 +320,13 @@ int dtls1_connect(SSL *s)
s->shutdown = 0;
/* every DTLS ClientHello resets Finished MAC */
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
+ /* fall thru */
case SSL3_ST_CW_CLNT_HELLO_B:
dtls1_start_timer(s);
ret = ssl3_client_hello(s);
@@ -769,6 +774,7 @@ int dtls1_connect(SSL *s)
/* done with handshaking */
s->d1->handshake_read_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff --git a/thirdparty/openssl/ssl/d1_lib.c b/thirdparty/openssl/ssl/d1_lib.c
index ee78921ba8..debd4fd5dc 100644
--- a/thirdparty/openssl/ssl/d1_lib.c
+++ b/thirdparty/openssl/ssl/d1_lib.c
@@ -170,7 +170,6 @@ int dtls1_new(SSL *s)
static void dtls1_clear_queues(SSL *s)
{
pitem *item = NULL;
- hm_fragment *frag = NULL;
DTLS1_RECORD_DATA *rdata;
while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) {
@@ -191,28 +190,44 @@ static void dtls1_clear_queues(SSL *s)
pitem_free(item);
}
+ while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
+ rdata = (DTLS1_RECORD_DATA *)item->data;
+ if (rdata->rbuf.buf) {
+ OPENSSL_free(rdata->rbuf.buf);
+ }
+ OPENSSL_free(item->data);
+ pitem_free(item);
+ }
+
+ dtls1_clear_received_buffer(s);
+ dtls1_clear_sent_buffer(s);
+}
+
+void dtls1_clear_received_buffer(SSL *s)
+{
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
+
while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) {
frag = (hm_fragment *)item->data;
dtls1_hm_fragment_free(frag);
pitem_free(item);
}
+}
+
+void dtls1_clear_sent_buffer(SSL *s)
+{
+ pitem *item = NULL;
+ hm_fragment *frag = NULL;
while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) {
frag = (hm_fragment *)item->data;
dtls1_hm_fragment_free(frag);
pitem_free(item);
}
-
- while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) {
- rdata = (DTLS1_RECORD_DATA *)item->data;
- if (rdata->rbuf.buf) {
- OPENSSL_free(rdata->rbuf.buf);
- }
- OPENSSL_free(item->data);
- pitem_free(item);
- }
}
+
void dtls1_free(SSL *s)
{
ssl3_free(s);
@@ -456,7 +471,7 @@ void dtls1_stop_timer(SSL *s)
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
&(s->d1->next_timeout));
/* Clear retransmission buffer */
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
}
int dtls1_check_timeout_num(SSL *s)
diff --git a/thirdparty/openssl/ssl/d1_pkt.c b/thirdparty/openssl/ssl/d1_pkt.c
index fe30ec7d00..10586fee54 100644
--- a/thirdparty/openssl/ssl/d1_pkt.c
+++ b/thirdparty/openssl/ssl/d1_pkt.c
@@ -125,7 +125,7 @@
/* mod 128 saturating subtract of two 64-bit values in big-endian order */
static int satsub64be(const unsigned char *v1, const unsigned char *v2)
{
- int ret, sat, brw, i;
+ int ret, i;
if (sizeof(long) == 8)
do {
@@ -157,28 +157,51 @@ static int satsub64be(const unsigned char *v1, const unsigned char *v2)
return (int)l;
} while (0);
- ret = (int)v1[7] - (int)v2[7];
- sat = 0;
- brw = ret >> 8; /* brw is either 0 or -1 */
- if (ret & 0x80) {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= ~brw;
- brw >>= 8;
- }
- } else {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= brw;
- brw >>= 8;
+ ret = 0;
+ for (i=0; i<7; i++) {
+ if (v1[i] > v2[i]) {
+ /* v1 is larger... but by how much? */
+ if (v1[i] != v2[i] + 1)
+ return 128;
+ while (++i <= 6) {
+ if (v1[i] != 0x00 || v2[i] != 0xff)
+ return 128; /* too much */
+ }
+ /* We checked all the way to the penultimate byte,
+ * so despite higher bytes changing we actually
+ * know that it only changed from (e.g.)
+ * ... (xx) ff ff ff ??
+ * to ... (xx+1) 00 00 00 ??
+ * so we add a 'bias' of 256 for the carry that
+ * happened, and will eventually return
+ * 256 + v1[7] - v2[7]. */
+ ret = 256;
+ break;
+ } else if (v2[i] > v1[i]) {
+ /* v2 is larger... but by how much? */
+ if (v2[i] != v1[i] + 1)
+ return -128;
+ while (++i <= 6) {
+ if (v2[i] != 0x00 || v1[i] != 0xff)
+ return -128; /* too much */
+ }
+ /* Similar to the case above, we know it changed
+ * from ... (xx) 00 00 00 ??
+ * to ... (xx-1) ff ff ff ??
+ * so we add a 'bias' of -256 for the borrow,
+ * to return -256 + v1[7] - v2[7]. */
+ ret = -256;
}
}
- brw <<= 8; /* brw is either 0 or -256 */
- if (sat & 0xff)
- return brw | 0x80;
+ ret += (int)v1[7] - (int)v2[7];
+
+ if (ret > 128)
+ return 128;
+ else if (ret < -128)
+ return -128;
else
- return brw + (ret & 0xFF);
+ return ret;
}
static int have_handshake_fragment(SSL *s, int type, unsigned char *buf,
@@ -194,7 +217,7 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
#endif
static int dtls1_buffer_record(SSL *s, record_pqueue *q,
unsigned char *priority);
-static int dtls1_process_record(SSL *s);
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap);
/* copy buffered record into SSL structure */
static int dtls1_copy_record(SSL *s, pitem *item)
@@ -319,21 +342,70 @@ static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue)
static int dtls1_process_buffered_records(SSL *s)
{
pitem *item;
+ SSL3_BUFFER *rb;
+ SSL3_RECORD *rr;
+ DTLS1_BITMAP *bitmap;
+ unsigned int is_next_epoch;
+ int replayok = 1;
item = pqueue_peek(s->d1->unprocessed_rcds.q);
if (item) {
/* Check if epoch is current. */
if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch)
- return (1); /* Nothing to do. */
+ return 1; /* Nothing to do. */
+
+ rr = &s->s3->rrec;
+ rb = &s->s3->rbuf;
+
+ if (rb->left > 0) {
+ /*
+ * We've still got data from the current packet to read. There could
+ * be a record from the new epoch in it - so don't overwrite it
+ * with the unprocessed records yet (we'll do it when we've
+ * finished reading the current packet).
+ */
+ return 1;
+ }
+
/* Process all the records. */
while (pqueue_peek(s->d1->unprocessed_rcds.q)) {
dtls1_get_unprocessed_record(s);
- if (!dtls1_process_record(s))
- return (0);
+ bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch);
+ if (bitmap == NULL) {
+ /*
+ * Should not happen. This will only ever be NULL when the
+ * current record is from a different epoch. But that cannot
+ * be the case because we already checked the epoch above
+ */
+ SSLerr(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS,
+ ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+#ifndef OPENSSL_NO_SCTP
+ /* Only do replay check if no SCTP bio */
+ if (!BIO_dgram_is_sctp(SSL_get_rbio(s)))
+#endif
+ {
+ /*
+ * Check whether this is a repeat, or aged record. We did this
+ * check once already when we first received the record - but
+ * we might have updated the window since then due to
+ * records we subsequently processed.
+ */
+ replayok = dtls1_record_replay_check(s, bitmap);
+ }
+
+ if (!replayok || !dtls1_process_record(s, bitmap)) {
+ /* dump this record */
+ rr->length = 0;
+ s->packet_length = 0;
+ continue;
+ }
+
if (dtls1_buffer_record(s, &(s->d1->processed_rcds),
s->s3->rrec.seq_num) < 0)
- return -1;
+ return 0;
}
}
@@ -344,7 +416,7 @@ static int dtls1_process_buffered_records(SSL *s)
s->d1->processed_rcds.epoch = s->d1->r_epoch;
s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1;
- return (1);
+ return 1;
}
#if 0
@@ -391,7 +463,7 @@ static int dtls1_get_buffered_record(SSL *s)
#endif
-static int dtls1_process_record(SSL *s)
+static int dtls1_process_record(SSL *s, DTLS1_BITMAP *bitmap)
{
int i, al;
int enc_err;
@@ -551,6 +623,10 @@ static int dtls1_process_record(SSL *s)
/* we have pulled in a full packet so zero things */
s->packet_length = 0;
+
+ /* Mark receipt of record. */
+ dtls1_record_bitmap_update(s, bitmap);
+
return (1);
f_err:
@@ -581,11 +657,12 @@ int dtls1_get_record(SSL *s)
rr = &(s->s3->rrec);
+ again:
/*
* The epoch may have changed. If so, process all the pending records.
* This is a non-blocking operation.
*/
- if (dtls1_process_buffered_records(s) < 0)
+ if (!dtls1_process_buffered_records(s))
return -1;
/* if we're renegotiating, then there may be buffered records */
@@ -593,7 +670,6 @@ int dtls1_get_record(SSL *s)
return 1;
/* get something from the wire */
- again:
/* check if we have the header */
if ((s->rstate != SSL_ST_READ_BODY) ||
(s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
@@ -721,20 +797,17 @@ int dtls1_get_record(SSL *s)
if (dtls1_buffer_record
(s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0)
return -1;
- /* Mark receipt of record. */
- dtls1_record_bitmap_update(s, bitmap);
}
rr->length = 0;
s->packet_length = 0;
goto again;
}
- if (!dtls1_process_record(s)) {
+ if (!dtls1_process_record(s, bitmap)) {
rr->length = 0;
s->packet_length = 0; /* dump this record */
goto again; /* get another record */
}
- dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */
return (1);
@@ -878,6 +951,13 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
goto start;
}
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+ s->cert->alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1144,6 +1224,14 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (alert_level == SSL3_AL_WARNING) {
s->s3->warn_alert = alert_descr;
+
+ s->cert->alert_count++;
+ if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
#ifndef OPENSSL_NO_SCTP
/*
@@ -1201,7 +1289,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
return (0);
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -1235,9 +1323,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
/* XDTLS: check that epoch is consistent */
if ((rr->length != ccs_hdr_len) ||
(rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) {
- i = SSL_AD_ILLEGAL_PARAMETER;
+ al = SSL_AD_ILLEGAL_PARAMETER;
SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC);
- goto err;
+ goto f_err;
}
rr->length = 0;
@@ -1830,8 +1918,13 @@ static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr,
if (rr->epoch == s->d1->r_epoch)
return &s->d1->bitmap;
- /* Only HM and ALERT messages can be from the next epoch */
+ /*
+ * Only HM and ALERT messages can be from the next epoch and only if we
+ * have already processed all of the unprocessed records from the last
+ * epoch
+ */
else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) &&
+ s->d1->unprocessed_rcds.epoch != s->d1->r_epoch &&
(rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) {
*is_next_epoch = 1;
return &s->d1->next_bitmap;
@@ -1910,6 +2003,12 @@ void dtls1_reset_seq_numbers(SSL *s, int rw)
s->d1->r_epoch++;
memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP));
memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP));
+
+ /*
+ * We must not use any buffered messages received from the previous
+ * epoch
+ */
+ dtls1_clear_received_buffer(s);
} else {
seq = s->s3->write_sequence;
memcpy(s->d1->last_write_sequence, seq,
diff --git a/thirdparty/openssl/ssl/d1_srvr.c b/thirdparty/openssl/ssl/d1_srvr.c
index e677d880f0..8502b242e5 100644
--- a/thirdparty/openssl/ssl/d1_srvr.c
+++ b/thirdparty/openssl/ssl/d1_srvr.c
@@ -282,7 +282,12 @@ int dtls1_accept(SSL *s)
goto end;
}
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
+
s->state = SSL3_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
} else if (!s->s3->send_connection_binding &&
@@ -313,7 +318,7 @@ int dtls1_accept(SSL *s)
case SSL3_ST_SW_HELLO_REQ_B:
s->shutdown = 0;
- dtls1_clear_record_buffer(s);
+ dtls1_clear_sent_buffer(s);
dtls1_start_timer(s);
ret = ssl3_send_hello_request(s);
if (ret <= 0)
@@ -322,7 +327,11 @@ int dtls1_accept(SSL *s)
s->state = SSL3_ST_SW_FLUSH;
s->init_num = 0;
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
break;
case SSL3_ST_SW_HELLO_REQ_C:
@@ -346,15 +355,6 @@ int dtls1_accept(SSL *s)
s->init_num = 0;
- /*
- * Reflect ClientHello sequence to remain stateless while
- * listening
- */
- if (listen) {
- memcpy(s->s3->write_sequence, s->s3->read_sequence,
- sizeof(s->s3->write_sequence));
- }
-
/* If we're just listening, stop here */
if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) {
ret = 2;
@@ -381,7 +381,11 @@ int dtls1_accept(SSL *s)
/* HelloVerifyRequest resets Finished MAC */
if (s->version != DTLS1_BAD_VER)
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
break;
#ifndef OPENSSL_NO_SCTP
@@ -894,6 +898,7 @@ int dtls1_accept(SSL *s)
/* next message is server hello */
s->d1->handshake_write_seq = 0;
s->d1->next_handshake_write_seq = 0;
+ dtls1_clear_received_buffer(s);
goto end;
/* break; */
diff --git a/thirdparty/openssl/ssl/install-ssl.com b/thirdparty/openssl/ssl/install-ssl.com
deleted file mode 100755
index afe6967f85..0000000000
--- a/thirdparty/openssl/ssl/install-ssl.com
+++ /dev/null
@@ -1,136 +0,0 @@
-$! INSTALL-SSL.COM -- Installs the files in a given directory tree
-$!
-$! Author: Richard Levitte <richard@levitte.org>
-$! Time of creation: 22-MAY-1998 10:13
-$!
-$! P1 root of the directory tree
-$! P2 "64" for 64-bit pointers.
-$!
-$!
-$! Announce/identify.
-$!
-$ proc = f$environment( "procedure")
-$ write sys$output "@@@ "+ -
- f$parse( proc, , , "name")+ f$parse( proc, , , "type")
-$!
-$ on error then goto tidy
-$ on control_c then goto tidy
-$!
-$ if p1 .eqs. ""
-$ then
-$ write sys$output "First argument missing."
-$ write sys$output -
- "It should be the directory where you want things installed."
-$ exit
-$ endif
-$!
-$ if (f$getsyi( "cpu") .lt. 128)
-$ then
-$ arch = "VAX"
-$ else
-$ arch = f$edit( f$getsyi( "arch_name"), "upcase")
-$ if (arch .eqs. "") then arch = "UNK"
-$ endif
-$!
-$ archd = arch
-$ lib32 = "32"
-$ shr = "_SHR32"
-$!
-$ if (p2 .nes. "")
-$ then
-$ if (p2 .eqs. "64")
-$ then
-$ archd = arch+ "_64"
-$ lib32 = ""
-$ shr = "_SHR"
-$ else
-$ if (p2 .nes. "32")
-$ then
-$ write sys$output "Second argument invalid."
-$ write sys$output "It should be "32", "64", or nothing."
-$ exit
-$ endif
-$ endif
-$ endif
-$!
-$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0"
-$ root_dev = f$parse(root,,,"device","syntax_only")
-$ root_dir = f$parse(root,,,"directory","syntax_only") - -
- "[000000." - "][" - "[" - "]"
-$ root = root_dev + "[" + root_dir
-$!
-$ define /nolog wrk_sslroot 'root'.] /trans=conc
-$ define /nolog wrk_sslinclude wrk_sslroot:[include]
-$ define /nolog wrk_sslxexe wrk_sslroot:['archd'_exe]
-$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib]
-$!
-$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then -
- create /directory /log wrk_sslroot:[000000]
-$ if f$parse("wrk_sslinclude:") .eqs. "" then -
- create /directory /log wrk_sslinclude:
-$ if f$parse("wrk_sslxexe:") .eqs. "" then -
- create /directory /log wrk_sslxexe:
-$ if f$parse("wrk_sslxlib:") .eqs. "" then -
- create /directory /log wrk_sslxlib:
-$!
-$ exheader := ssl.h, ssl2.h, ssl3.h, ssl23.h, tls1.h, dtls1.h, kssl.h, srtp.h
-$ e_exe := ssl_task
-$ libs := ssl_libssl
-$!
-$ xexe_dir := [-.'archd'.exe.ssl]
-$!
-$ copy /protection = w:re 'exheader' wrk_sslinclude: /log
-$!
-$ i = 0
-$ loop_exe:
-$ e = f$edit( f$element( i, ",", e_exe), "trim")
-$ i = i + 1
-$ if e .eqs. "," then goto loop_exe_end
-$ set noon
-$ file = xexe_dir+ e+ ".exe"
-$ if f$search( file) .nes. ""
-$ then
-$ copy /protection = w:re 'file' wrk_sslxexe: /log
-$ endif
-$ set on
-$ goto loop_exe
-$ loop_exe_end:
-$!
-$ i = 0
-$ loop_lib:
-$ e = f$edit(f$element(i, ",", libs),"trim")
-$ i = i + 1
-$ if e .eqs. "," then goto loop_lib_end
-$ set noon
-$! Object library.
-$ file = xexe_dir+ e+ lib32+ ".olb"
-$ if f$search( file) .nes. ""
-$ then
-$ copy /protection = w:re 'file' wrk_sslxlib: /log
-$ endif
-$! Shareable image.
-$ file = xexe_dir+ e+ shr+ ".exe"
-$ if f$search( file) .nes. ""
-$ then
-$ copy /protection = w:re 'file' wrk_sslxlib: /log
-$ endif
-$ set on
-$ goto loop_lib
-$ loop_lib_end:
-$!
-$ tidy:
-$!
-$ call deass wrk_sslroot
-$ call deass wrk_sslinclude
-$ call deass wrk_sslxexe
-$ call deass wrk_sslxlib
-$!
-$ exit
-$!
-$ deass: subroutine
-$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "")
-$ then
-$ deassign /process 'p1'
-$ endif
-$ endsubroutine
-$!
diff --git a/thirdparty/openssl/ssl/s23_clnt.c b/thirdparty/openssl/ssl/s23_clnt.c
index f782010c47..b80d1fd8ce 100644
--- a/thirdparty/openssl/ssl/s23_clnt.c
+++ b/thirdparty/openssl/ssl/s23_clnt.c
@@ -204,7 +204,10 @@ int ssl23_connect(SSL *s)
goto end;
}
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ goto end;
+ }
s->state = SSL23_ST_CW_CLNT_HELLO_A;
s->ctx->stats.sess_connect++;
@@ -289,9 +292,9 @@ int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len)
unsigned long Time = (unsigned long)time(NULL);
unsigned char *p = result;
l2n(Time, p);
- return RAND_pseudo_bytes(p, len - 4);
+ return RAND_bytes(p, len - 4);
} else
- return RAND_pseudo_bytes(result, len);
+ return RAND_bytes(result, len);
}
static int ssl23_client_hello(SSL *s)
@@ -466,8 +469,8 @@ static int ssl23_client_hello(SSL *s)
i = ch_len;
s2n(i, d);
memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE);
- if (RAND_pseudo_bytes
- (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0)
+ if (RAND_bytes (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i)
+ <= 0)
return -1;
memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i);
diff --git a/thirdparty/openssl/ssl/s23_pkt.c b/thirdparty/openssl/ssl/s23_pkt.c
index efc8647841..6544180efe 100644
--- a/thirdparty/openssl/ssl/s23_pkt.c
+++ b/thirdparty/openssl/ssl/s23_pkt.c
@@ -63,6 +63,9 @@
#include <openssl/evp.h>
#include <openssl/buffer.h>
+/*
+ * Return values are as per SSL_write()
+ */
int ssl23_write_bytes(SSL *s)
{
int i, num, tot;
@@ -77,7 +80,7 @@ int ssl23_write_bytes(SSL *s)
if (i <= 0) {
s->init_off = tot;
s->init_num = num;
- return (i);
+ return i;
}
s->rwstate = SSL_NOTHING;
if (i == num)
@@ -88,7 +91,10 @@ int ssl23_write_bytes(SSL *s)
}
}
-/* return regularly only when we have read (at least) 'n' bytes */
+/* return regularly only when we have read (at least) 'n' bytes
+ *
+ * Return values are as per SSL_read()
+ */
int ssl23_read_bytes(SSL *s, int n)
{
unsigned char *p;
@@ -102,7 +108,7 @@ int ssl23_read_bytes(SSL *s, int n)
j = BIO_read(s->rbio, (char *)&(p[s->packet_length]),
n - s->packet_length);
if (j <= 0)
- return (j);
+ return j;
s->rwstate = SSL_NOTHING;
s->packet_length += j;
if (s->packet_length >= (unsigned int)n)
diff --git a/thirdparty/openssl/ssl/s23_srvr.c b/thirdparty/openssl/ssl/s23_srvr.c
index 470bd3d94f..d3f6db15cc 100644
--- a/thirdparty/openssl/ssl/s23_srvr.c
+++ b/thirdparty/openssl/ssl/s23_srvr.c
@@ -195,7 +195,10 @@ int ssl23_accept(SSL *s)
s->init_buf = buf;
}
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ goto end;
+ }
s->state = SSL23_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
diff --git a/thirdparty/openssl/ssl/s2_clnt.c b/thirdparty/openssl/ssl/s2_clnt.c
index 69da6b1421..20de1a8217 100644
--- a/thirdparty/openssl/ssl/s2_clnt.c
+++ b/thirdparty/openssl/ssl/s2_clnt.c
@@ -581,7 +581,7 @@ static int client_hello(SSL *s)
/*
* challenge id data
*/
- if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0)
+ if (RAND_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0)
return -1;
memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH);
d += SSL2_CHALLENGE_LENGTH;
@@ -629,7 +629,7 @@ static int client_master_key(SSL *s)
return -1;
}
if (i > 0)
- if (RAND_pseudo_bytes(sess->key_arg, i) <= 0)
+ if (RAND_bytes(sess->key_arg, i) <= 0)
return -1;
/* make a master key */
diff --git a/thirdparty/openssl/ssl/s2_lib.c b/thirdparty/openssl/ssl/s2_lib.c
index 88e67f083a..cc1360307b 100644
--- a/thirdparty/openssl/ssl/s2_lib.c
+++ b/thirdparty/openssl/ssl/s2_lib.c
@@ -254,7 +254,7 @@ OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = {
SSL_3DES,
SSL_MD5,
SSL_SSLV2,
- SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM,
0,
112,
168,
diff --git a/thirdparty/openssl/ssl/s2_pkt.c b/thirdparty/openssl/ssl/s2_pkt.c
index 7a61888134..e44bc0335a 100644
--- a/thirdparty/openssl/ssl/s2_pkt.c
+++ b/thirdparty/openssl/ssl/s2_pkt.c
@@ -307,6 +307,9 @@ int ssl2_peek(SSL *s, void *buf, int len)
return ssl2_read_internal(s, buf, len, 1);
}
+/*
+ * Return values are as per SSL_read()
+ */
static int read_n(SSL *s, unsigned int n, unsigned int max,
unsigned int extend)
{
@@ -374,7 +377,7 @@ static int read_n(SSL *s, unsigned int n, unsigned int max,
# endif
if (i <= 0) {
s->s2->rbuf_left += newb;
- return (i);
+ return i;
}
newb += i;
}
@@ -441,6 +444,9 @@ int ssl2_write(SSL *s, const void *_buf, int len)
}
}
+/*
+ * Return values are as per SSL_write()
+ */
static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
{
int i;
@@ -477,7 +483,7 @@ static int write_pending(SSL *s, const unsigned char *buf, unsigned int len)
s->rwstate = SSL_NOTHING;
return (s->s2->wpend_ret);
} else if (i <= 0)
- return (i);
+ return i;
s->s2->wpend_off += i;
s->s2->wpend_len -= i;
}
diff --git a/thirdparty/openssl/ssl/s2_srvr.c b/thirdparty/openssl/ssl/s2_srvr.c
index 07e9df8282..d3b243c27e 100644
--- a/thirdparty/openssl/ssl/s2_srvr.c
+++ b/thirdparty/openssl/ssl/s2_srvr.c
@@ -526,11 +526,8 @@ static int get_client_master_key(SSL *s)
* fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
*/
- /*
- * should be RAND_bytes, but we cannot work around a failure.
- */
- if (RAND_pseudo_bytes(rand_premaster_secret,
- (int)num_encrypted_key_bytes) <= 0)
+ if (RAND_bytes(rand_premaster_secret,
+ (int)num_encrypted_key_bytes) <= 0)
return 0;
i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc,
@@ -822,8 +819,7 @@ static int server_hello(SSL *s)
/* make and send conn_id */
s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */
s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH;
- if (RAND_pseudo_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <=
- 0)
+ if (RAND_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= 0)
return -1;
memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH);
d += SSL2_CONNECTION_ID_LENGTH;
@@ -962,7 +958,7 @@ static int request_certificate(SSL *s)
p = (unsigned char *)s->init_buf->data;
*(p++) = SSL2_MT_REQUEST_CERTIFICATE;
*(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION;
- if (RAND_pseudo_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
+ if (RAND_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0)
return -1;
memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH);
diff --git a/thirdparty/openssl/ssl/s3_both.c b/thirdparty/openssl/ssl/s3_both.c
index 09d0661e81..054ded1c99 100644
--- a/thirdparty/openssl/ssl/s3_both.c
+++ b/thirdparty/openssl/ssl/s3_both.c
@@ -356,21 +356,22 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
}
*ok = 1;
s->state = stn;
- s->init_msg = s->init_buf->data + 4;
+ s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
s->init_num = (int)s->s3->tmp.message_size;
return s->init_num;
}
p = (unsigned char *)s->init_buf->data;
- if (s->state == st1) { /* s->init_num < 4 */
+ if (s->state == st1) { /* s->init_num < SSL3_HM_HEADER_LENGTH */
int skip_message;
do {
- while (s->init_num < 4) {
+ while (s->init_num < SSL3_HM_HEADER_LENGTH) {
i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE,
&p[s->init_num],
- 4 - s->init_num, 0);
+ SSL3_HM_HEADER_LENGTH -
+ s->init_num, 0);
if (i <= 0) {
s->rwstate = SSL_READING;
*ok = 0;
@@ -394,12 +395,13 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE,
- p, 4, s, s->msg_callback_arg);
+ p, SSL3_HM_HEADER_LENGTH, s,
+ s->msg_callback_arg);
}
}
while (skip_message);
- /* s->init_num == 4 */
+ /* s->init_num == SSL3_HM_HEADER_LENGTH */
if ((mt >= 0) && (*p != mt)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
@@ -415,19 +417,20 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto f_err;
}
- if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */
- al = SSL_AD_ILLEGAL_PARAMETER;
- SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE);
- goto f_err;
- }
- if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) {
+ /*
+ * Make buffer slightly larger than message length as a precaution
+ * against small OOB reads e.g. CVE-2016-6306
+ */
+ if (l
+ && !BUF_MEM_grow_clean(s->init_buf,
+ (int)l + SSL3_HM_HEADER_LENGTH + 16)) {
SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB);
goto err;
}
s->s3->tmp.message_size = l;
s->state = stn;
- s->init_msg = s->init_buf->data + 4;
+ s->init_msg = s->init_buf->data + SSL3_HM_HEADER_LENGTH;
s->init_num = 0;
}
@@ -456,10 +459,12 @@ long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok)
#endif
/* Feed this message into MAC computation. */
- ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4);
+ ssl3_finish_mac(s, (unsigned char *)s->init_buf->data,
+ s->init_num + SSL3_HM_HEADER_LENGTH);
if (s->msg_callback)
s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data,
- (size_t)s->init_num + 4, s, s->msg_callback_arg);
+ (size_t)s->init_num + SSL3_HM_HEADER_LENGTH, s,
+ s->msg_callback_arg);
*ok = 1;
return s->init_num;
f_err:
@@ -535,6 +540,9 @@ int ssl_verify_alarm_type(long type)
case X509_V_ERR_CRL_NOT_YET_VALID:
case X509_V_ERR_CERT_UNTRUSTED:
case X509_V_ERR_CERT_REJECTED:
+ case X509_V_ERR_HOSTNAME_MISMATCH:
+ case X509_V_ERR_EMAIL_MISMATCH:
+ case X509_V_ERR_IP_ADDRESS_MISMATCH:
al = SSL_AD_BAD_CERTIFICATE;
break;
case X509_V_ERR_CERT_SIGNATURE_FAILURE:
@@ -548,7 +556,10 @@ int ssl_verify_alarm_type(long type)
case X509_V_ERR_CERT_REVOKED:
al = SSL_AD_CERTIFICATE_REVOKED;
break;
+ case X509_V_ERR_UNSPECIFIED:
case X509_V_ERR_OUT_OF_MEM:
+ case X509_V_ERR_INVALID_CALL:
+ case X509_V_ERR_STORE_LOOKUP:
al = SSL_AD_INTERNAL_ERROR;
break;
case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT:
diff --git a/thirdparty/openssl/ssl/s3_clnt.c b/thirdparty/openssl/ssl/s3_clnt.c
index 19dc8648b9..5b8b2da59f 100644
--- a/thirdparty/openssl/ssl/s3_clnt.c
+++ b/thirdparty/openssl/ssl/s3_clnt.c
@@ -263,6 +263,7 @@ int ssl3_connect(SSL *s)
if (!ssl3_setup_buffers(s)) {
ret = -1;
+ s->state = SSL_ST_ERR;
goto end;
}
@@ -275,7 +276,11 @@ int ssl3_connect(SSL *s)
/* don't push the buffering BIO quite yet */
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
s->state = SSL3_ST_CW_CLNT_HELLO_A;
s->ctx->stats.sess_connect++;
@@ -1216,6 +1221,12 @@ int ssl3_get_server_certificate(SSL *s)
goto f_err;
}
for (nc = 0; nc < llen;) {
+ if (nc + 3 > llen) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE,
+ SSL_R_CERT_LENGTH_MISMATCH);
+ goto f_err;
+ }
n2l3(p, l);
if ((l + nc + 3) > llen) {
al = SSL_AD_DECODE_ERROR;
@@ -1704,12 +1715,6 @@ int ssl3_get_key_exchange(SSL *s)
}
p += i;
- if (BN_is_zero(dh->p)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
- goto f_err;
- }
-
-
if (2 > n - param_len) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1730,11 +1735,6 @@ int ssl3_get_key_exchange(SSL *s)
}
p += i;
- if (BN_is_zero(dh->g)) {
- SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
- goto f_err;
- }
-
if (2 > n - param_len) {
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1761,6 +1761,39 @@ int ssl3_get_key_exchange(SSL *s)
goto f_err;
}
+ /*-
+ * Check that p and g are suitable enough
+ *
+ * p is odd
+ * 1 < g < p - 1
+ */
+ {
+ BIGNUM *tmp = NULL;
+
+ if (!BN_is_odd(dh->p)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE);
+ goto f_err;
+ }
+ if (BN_is_negative(dh->g) || BN_is_zero(dh->g)
+ || BN_is_one(dh->g)) {
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+ goto f_err;
+ }
+ if ((tmp = BN_new()) == NULL
+ || BN_copy(tmp, dh->p) == NULL
+ || !BN_sub_word(tmp, 1)) {
+ BN_free(tmp);
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB);
+ goto err;
+ }
+ if (BN_cmp(dh->g, tmp) >= 0) {
+ BN_free(tmp);
+ SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE);
+ goto f_err;
+ }
+ BN_free(tmp);
+ }
+
# ifndef OPENSSL_NO_RSA
if (alg_a & SSL_aRSA)
pkey =
@@ -1836,6 +1869,7 @@ int ssl3_get_key_exchange(SSL *s)
goto err;
}
if (EC_KEY_set_group(ecdh, ngroup) == 0) {
+ EC_GROUP_free(ngroup);
SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB);
goto err;
}
@@ -2111,6 +2145,10 @@ int ssl3_get_certificate_request(SSL *s)
if (ctype_num > SSL3_CT_NUMBER) {
/* If we exceed static buffer copy all to cert structure */
s->cert->ctypes = OPENSSL_malloc(ctype_num);
+ if (s->cert->ctypes == NULL) {
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
memcpy(s->cert->ctypes, p, ctype_num);
s->cert->ctype_num = (size_t)ctype_num;
ctype_num = SSL3_CT_NUMBER;
@@ -2167,6 +2205,11 @@ int ssl3_get_certificate_request(SSL *s)
}
for (nc = 0; nc < llen;) {
+ if (nc + 2 > llen) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
+ SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG);
+ goto err;
+ }
n2s(p, l);
if ((l + nc + 2) > llen) {
if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG))
@@ -2999,19 +3042,6 @@ int ssl3_send_client_key_exchange(SSL *s)
goto err;
}
/*
- * If we have client certificate, use its secret as peer key
- */
- if (s->s3->tmp.cert_req && s->cert->key->privatekey) {
- if (EVP_PKEY_derive_set_peer
- (pkey_ctx, s->cert->key->privatekey) <= 0) {
- /*
- * If there was an error - just ignore it. Ephemeral key
- * * would be used
- */
- ERR_clear_error();
- }
- }
- /*
* Compute shared IV and store it in algorithm-specific context
* data
*/
@@ -3057,12 +3087,6 @@ int ssl3_send_client_key_exchange(SSL *s)
n = msglen + 2;
}
memcpy(p, tmp, msglen);
- /* Check if pubkey from client certificate was used */
- if (EVP_PKEY_CTX_ctrl
- (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) {
- /* Set flag "skip certificate verify" */
- s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY;
- }
EVP_PKEY_CTX_free(pkey_ctx);
s->session->master_key_length =
s->method->ssl3_enc->generate_master_secret(s,
diff --git a/thirdparty/openssl/ssl/s3_enc.c b/thirdparty/openssl/ssl/s3_enc.c
index 47a0ec9fe0..1eee9d9b21 100644
--- a/thirdparty/openssl/ssl/s3_enc.c
+++ b/thirdparty/openssl/ssl/s3_enc.c
@@ -177,32 +177,34 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
EVP_MD_CTX_init(&s1);
for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) {
k++;
- if (k > sizeof buf) {
+ if (k > sizeof(buf))
/* bug: 'buf' is too small for this ciphersuite */
- SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
- return 0;
- }
+ goto err;
for (j = 0; j < k; j++)
buf[j] = c;
c++;
- EVP_DigestInit_ex(&s1, EVP_sha1(), NULL);
- EVP_DigestUpdate(&s1, buf, k);
- EVP_DigestUpdate(&s1, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(&s1, smd, NULL);
-
- EVP_DigestInit_ex(&m5, EVP_md5(), NULL);
- EVP_DigestUpdate(&m5, s->session->master_key,
- s->session->master_key_length);
- EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH);
+ if (!EVP_DigestInit_ex(&s1, EVP_sha1(), NULL) ||
+ !EVP_DigestUpdate(&s1, buf, k) ||
+ !EVP_DigestUpdate(&s1, s->session->master_key,
+ s->session->master_key_length) ||
+ !EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestFinal_ex(&s1, smd, NULL))
+ goto err2;
+
+ if (!EVP_DigestInit_ex(&m5, EVP_md5(), NULL) ||
+ !EVP_DigestUpdate(&m5, s->session->master_key,
+ s->session->master_key_length) ||
+ !EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH))
+ goto err2;
if ((int)(i + MD5_DIGEST_LENGTH) > num) {
- EVP_DigestFinal_ex(&m5, smd, NULL);
+ if (!EVP_DigestFinal_ex(&m5, smd, NULL))
+ goto err2;
memcpy(km, smd, (num - i));
} else
- EVP_DigestFinal_ex(&m5, km, NULL);
+ if (!EVP_DigestFinal_ex(&m5, km, NULL))
+ goto err2;
km += MD5_DIGEST_LENGTH;
}
@@ -210,6 +212,12 @@ static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num)
EVP_MD_CTX_cleanup(&m5);
EVP_MD_CTX_cleanup(&s1);
return 1;
+ err:
+ SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR);
+ err2:
+ EVP_MD_CTX_cleanup(&m5);
+ EVP_MD_CTX_cleanup(&s1);
+ return 0;
}
int ssl3_change_cipher_state(SSL *s, int which)
@@ -360,25 +368,33 @@ int ssl3_change_cipher_state(SSL *s, int which)
* In here I set both the read and write key/iv to the same value
* since only the correct one will be used :-).
*/
- EVP_DigestInit_ex(&md, EVP_md5(), NULL);
- EVP_DigestUpdate(&md, key, j);
- EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL);
+ if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) ||
+ !EVP_DigestUpdate(&md, key, j) ||
+ !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL)) {
+ EVP_MD_CTX_cleanup(&md);
+ goto err2;
+ }
key = &(exp_key[0]);
if (k > 0) {
- EVP_DigestInit_ex(&md, EVP_md5(), NULL);
- EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE);
- EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE);
- EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL);
+ if (!EVP_DigestInit_ex(&md, EVP_md5(), NULL) ||
+ !EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL)) {
+ EVP_MD_CTX_cleanup(&md);
+ goto err2;
+ }
iv = &(exp_iv[0]);
}
}
+ EVP_MD_CTX_cleanup(&md);
s->session->key_arg_length = 0;
- EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE));
+ if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)))
+ goto err2;
#ifdef OPENSSL_SSL_TRACE_CRYPTO
if (s->msg_callback) {
@@ -399,7 +415,6 @@ int ssl3_change_cipher_state(SSL *s, int which)
OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key));
OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv));
- EVP_MD_CTX_cleanup(&md);
return (1);
err:
SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE);
@@ -555,17 +570,20 @@ int ssl3_enc(SSL *s, int send)
if ((bs != 1) && !send)
return ssl3_cbc_remove_padding(s, rec, bs, mac_size);
}
- return (1);
+ return 1;
}
-void ssl3_init_finished_mac(SSL *s)
+int ssl3_init_finished_mac(SSL *s)
{
if (s->s3->handshake_buffer)
BIO_free(s->s3->handshake_buffer);
if (s->s3->handshake_dgst)
ssl3_free_digest_list(s);
s->s3->handshake_buffer = BIO_new(BIO_s_mem());
+ if (s->s3->handshake_buffer == NULL)
+ return 0;
(void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
+ return 1;
}
void ssl3_free_digest_list(SSL *s)
@@ -607,6 +625,10 @@ int ssl3_digest_cached_records(SSL *s)
ssl3_free_digest_list(s);
s->s3->handshake_dgst =
OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
+ if (s->s3->handshake_dgst == NULL) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata);
if (hdatalen <= 0) {
@@ -618,14 +640,22 @@ int ssl3_digest_cached_records(SSL *s)
for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) {
if ((mask & ssl_get_algorithm2(s)) && md) {
s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
+ if (s->s3->handshake_dgst[i] == NULL) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
#ifdef OPENSSL_FIPS
if (EVP_MD_nid(md) == NID_md5) {
EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i],
EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
}
#endif
- EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL);
- EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
+ if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL)
+ || !EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata,
+ hdatalen)) {
+ SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
} else {
s->s3->handshake_dgst[i] = NULL;
}
@@ -895,7 +925,7 @@ int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p,
s, s->msg_callback_arg);
}
#endif
- OPENSSL_cleanse(buf, sizeof buf);
+ OPENSSL_cleanse(buf, sizeof(buf));
return (ret);
}
diff --git a/thirdparty/openssl/ssl/s3_lib.c b/thirdparty/openssl/ssl/s3_lib.c
index 872e636af9..1014a3fce1 100644
--- a/thirdparty/openssl/ssl/s3_lib.c
+++ b/thirdparty/openssl/ssl/s3_lib.c
@@ -329,7 +329,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -382,7 +382,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -434,7 +434,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -487,7 +487,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -539,7 +539,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -625,7 +625,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -712,7 +712,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -778,7 +778,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_MD5,
SSL_SSLV3,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -1728,7 +1728,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2120,7 +2120,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2200,7 +2200,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2280,7 +2280,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2360,7 +2360,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2440,7 +2440,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS,
+ SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM | SSL_FIPS,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2490,7 +2490,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2506,7 +2506,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -2522,7 +2522,7 @@ OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = {
SSL_3DES,
SSL_SHA1,
SSL_TLSV1,
- SSL_NOT_EXP | SSL_HIGH,
+ SSL_NOT_EXP | SSL_MEDIUM,
SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF,
112,
168,
@@ -4237,7 +4237,7 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
return (int)s->cert->ctype_num;
}
/* get configured sigalgs */
- siglen = tls12_get_psigalgs(s, &sig);
+ siglen = tls12_get_psigalgs(s, 1, &sig);
if (s->cert->cert_flags & SSL_CERT_FLAGS_CHECK_TLS_STRICT)
nostrict = 0;
for (i = 0; i < siglen; i += 2, sig += 2) {
@@ -4528,7 +4528,10 @@ int ssl3_renegotiate_check(SSL *s)
*/
long ssl_get_algorithm2(SSL *s)
{
- long alg2 = s->s3->tmp.new_cipher->algorithm2;
+ long alg2;
+ if (s->s3 == NULL || s->s3->tmp.new_cipher == NULL)
+ return -1;
+ alg2 = s->s3->tmp.new_cipher->algorithm2;
if (s->method->ssl3_enc->enc_flags & SSL_ENC_FLAG_SHA256_PRF
&& alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF))
return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256;
diff --git a/thirdparty/openssl/ssl/s3_pkt.c b/thirdparty/openssl/ssl/s3_pkt.c
index 379890237e..0290c991d8 100644
--- a/thirdparty/openssl/ssl/s3_pkt.c
+++ b/thirdparty/openssl/ssl/s3_pkt.c
@@ -136,6 +136,9 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
unsigned int len, int create_empty_fragment);
static int ssl3_get_record(SSL *s);
+/*
+ * Return values are as per SSL_read()
+ */
int ssl3_read_n(SSL *s, int n, int max, int extend)
{
/*
@@ -667,7 +670,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
* promptly send beyond the end of the users buffer ... so we trap and
* report the error in a way the user will notice
*/
- if (len < tot) {
+ if ((len < tot) || ((wb->left != 0) && (len < (tot + s->s3->wpend_tot)))) {
SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH);
return (-1);
}
@@ -696,6 +699,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len)
len >= 4 * (int)(max_send_fragment = s->max_send_fragment) &&
s->compress == NULL && s->msg_callback == NULL &&
SSL_USE_EXPLICIT_IV(s) &&
+ s->enc_write_ctx != NULL &&
EVP_CIPHER_flags(s->enc_write_ctx->cipher) &
EVP_CIPH_FLAG_TLS1_1_MULTIBLOCK) {
unsigned char aad[13];
@@ -1082,7 +1086,10 @@ static int do_ssl3_write(SSL *s, int type, const unsigned char *buf,
return -1;
}
-/* if s->s3->wbuf.left != 0, we need to call this */
+/* if s->s3->wbuf.left != 0, we need to call this
+ *
+ * Return values are as per SSL_write(), i.e.
+ */
int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
unsigned int len)
{
@@ -1122,7 +1129,7 @@ int ssl3_write_pending(SSL *s, int type, const unsigned char *buf,
*/
wb->left = 0;
}
- return (i);
+ return i;
}
wb->offset += i;
wb->left -= i;
@@ -1229,6 +1236,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
return (ret);
}
+ /*
+ * Reset the count of consecutive warning alerts if we've got a non-empty
+ * record that isn't an alert.
+ */
+ if (rr->type != SSL3_RT_ALERT && rr->length != 0)
+ s->cert->alert_count = 0;
+
/* we now have a packet which can be read and processed */
if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec,
@@ -1443,6 +1457,14 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
if (alert_level == SSL3_AL_WARNING) {
s->s3->warn_alert = alert_descr;
+
+ s->cert->alert_count++;
+ if (s->cert->alert_count == MAX_WARN_ALERT_COUNT) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_TOO_MANY_WARN_ALERTS);
+ goto f_err;
+ }
+
if (alert_descr == SSL_AD_CLOSE_NOTIFY) {
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
return (0);
@@ -1473,7 +1495,7 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
return (0);
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
@@ -1578,16 +1600,13 @@ int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek)
switch (rr->type) {
default:
-#ifndef OPENSSL_NO_TLS
/*
- * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give
- * an unexpected message alert.
+ * TLS 1.0 and 1.1 say you SHOULD ignore unrecognised record types, but
+ * TLS 1.2 says you MUST send an unexpected message alert. We use the
+ * TLS 1.2 behaviour for all protocol versions to prevent issues where
+ * no progress is being made and the peer continually sends unrecognised
+ * record types, using up resources processing them.
*/
- if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) {
- rr->length = 0;
- goto start;
- }
-#endif
al = SSL_AD_UNEXPECTED_MESSAGE;
SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD);
goto f_err;
@@ -1698,7 +1717,7 @@ int ssl3_send_alert(SSL *s, int level, int desc)
return -1;
/* If a fatal one, remove from cache */
if ((level == 2) && (s->session != NULL))
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
s->s3->alert_dispatch = 1;
s->s3->send_alert[0] = level;
diff --git a/thirdparty/openssl/ssl/s3_srvr.c b/thirdparty/openssl/ssl/s3_srvr.c
index ab28702ee9..ba17f1b562 100644
--- a/thirdparty/openssl/ssl/s3_srvr.c
+++ b/thirdparty/openssl/ssl/s3_srvr.c
@@ -311,7 +311,12 @@ int ssl3_accept(SSL *s)
goto end;
}
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
+
s->state = SSL3_ST_SR_CLNT_HELLO_A;
s->ctx->stats.sess_accept++;
} else if (!s->s3->send_connection_binding &&
@@ -348,7 +353,11 @@ int ssl3_accept(SSL *s)
s->state = SSL3_ST_SW_FLUSH;
s->init_num = 0;
- ssl3_init_finished_mac(s);
+ if (!ssl3_init_finished_mac(s)) {
+ ret = -1;
+ s->state = SSL_ST_ERR;
+ goto end;
+ }
break;
case SSL3_ST_SW_HELLO_REQ_C:
@@ -506,7 +515,7 @@ int ssl3_accept(SSL *s)
* if SSL_VERIFY_CLIENT_ONCE is set, don't request cert
* during re-negotiation:
*/
- ((s->session->peer != NULL) &&
+ (s->s3->tmp.finish_md_len != 0 &&
(s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) ||
/*
* never request cert in anonymous ciphersuites (see
@@ -980,7 +989,8 @@ int ssl3_get_client_hello(SSL *s)
session_length = *(p + SSL3_RANDOM_SIZE);
- if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) {
+ if (SSL3_RANDOM_SIZE + session_length + 1
+ >= (unsigned int)((d + n) - p)) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -998,7 +1008,7 @@ int ssl3_get_client_hello(SSL *s)
/* get the session-id */
j = *(p++);
- if (p + j > d + n) {
+ if ((d + n) - p < j) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1054,14 +1064,14 @@ int ssl3_get_client_hello(SSL *s)
if (SSL_IS_DTLS(s)) {
/* cookie stuff */
- if (p + 1 > d + n) {
+ if ((d + n) - p < 1) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
}
cookie_len = *(p++);
- if (p + cookie_len > d + n) {
+ if ((unsigned int)((d + n ) - p) < cookie_len) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1131,7 +1141,7 @@ int ssl3_get_client_hello(SSL *s)
}
}
- if (p + 2 > d + n) {
+ if ((d + n ) - p < 2) {
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT);
goto f_err;
@@ -1145,7 +1155,7 @@ int ssl3_get_client_hello(SSL *s)
}
/* i bytes of cipher data + 1 byte for compression length later */
- if ((p + i + 1) > (d + n)) {
+ if ((d + n) - p < i + 1) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
@@ -1211,7 +1221,7 @@ int ssl3_get_client_hello(SSL *s)
/* compression */
i = *(p++);
- if ((p + i) > (d + n)) {
+ if ((d + n) - p < i) {
/* not enough data */
al = SSL_AD_DECODE_ERROR;
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH);
@@ -1464,9 +1474,9 @@ int ssl3_get_client_hello(SSL *s)
/* Handles TLS extensions that we couldn't check earlier */
if (s->version >= SSL3_VERSION) {
- if (ssl_check_clienthello_tlsext_late(s) <= 0) {
+ if (!ssl_check_clienthello_tlsext_late(s, &al)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT);
- goto err;
+ goto f_err;
}
}
@@ -1600,6 +1610,9 @@ int ssl3_send_server_key_exchange(SSL *s)
unsigned int u;
#endif
#ifndef OPENSSL_NO_DH
+# ifdef OPENSSL_NO_RSA
+ int j;
+# endif
DH *dh = NULL, *dhp;
#endif
#ifndef OPENSSL_NO_ECDH
@@ -1700,6 +1713,12 @@ int ssl3_send_server_key_exchange(SSL *s)
if (type & SSL_kEECDH) {
const EC_GROUP *group;
+ if (s->s3->tmp.ecdh != NULL) {
+ SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
+ ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+
ecdhp = cert->ecdh_tmp;
if (s->cert->ecdh_tmp_auto) {
/* Get NID of appropriate shared curve */
@@ -1720,17 +1739,7 @@ int ssl3_send_server_key_exchange(SSL *s)
goto f_err;
}
- if (s->s3->tmp.ecdh != NULL) {
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
/* Duplicate the ECDH structure. */
- if (ecdhp == NULL) {
- SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB);
- goto err;
- }
if (s->cert->ecdh_tmp_auto)
ecdh = ecdhp;
else if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) {
@@ -1861,6 +1870,16 @@ int ssl3_send_server_key_exchange(SSL *s)
n += 1 + nr[i];
else
#endif
+#ifndef OPENSSL_NO_DH
+ /*
+ * for interoperability with some versions of the Microsoft TLS
+ * stack, we need to zero pad the DHE pub key to the same length
+ * as the prime, so use the length of the prime here
+ */
+ if ((i == 2) && (type & (SSL_kEDH)))
+ n += 2 + nr[0];
+ else
+#endif
n += 2 + nr[i];
}
@@ -1872,6 +1891,11 @@ int ssl3_send_server_key_exchange(SSL *s)
goto f_err;
}
kn = EVP_PKEY_size(pkey);
+ /* Allow space for signature algorithm */
+ if (SSL_USE_SIGALGS(s))
+ kn += 2;
+ /* Allow space for signature length */
+ kn += 2;
} else {
pkey = NULL;
kn = 0;
@@ -1890,6 +1914,20 @@ int ssl3_send_server_key_exchange(SSL *s)
p++;
} else
#endif
+#ifndef OPENSSL_NO_DH
+ /*
+ * for interoperability with some versions of the Microsoft TLS
+ * stack, we need to zero pad the DHE pub key to the same length
+ * as the prime
+ */
+ if ((i == 2) && (type & (SSL_kEDH))) {
+ s2n(nr[0], p);
+ for (j = 0; j < (nr[0] - nr[2]); ++j) {
+ *p = 0;
+ ++p;
+ }
+ } else
+#endif
s2n(nr[i], p);
BN_bn2bin(r[i], p);
p += nr[i];
@@ -2051,7 +2089,7 @@ int ssl3_send_certificate_request(SSL *s)
if (SSL_USE_SIGALGS(s)) {
const unsigned char *psigs;
- nl = tls12_get_psigalgs(s, &psigs);
+ nl = tls12_get_psigalgs(s, 1, &psigs);
s2n(nl, p);
memcpy(p, psigs, nl);
p += nl;
@@ -2229,11 +2267,8 @@ int ssl3_get_client_key_exchange(SSL *s)
* fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1
*/
- /*
- * should be RAND_bytes, but we cannot work around a failure.
- */
- if (RAND_pseudo_bytes(rand_premaster_secret,
- sizeof(rand_premaster_secret)) <= 0)
+ if (RAND_bytes(rand_premaster_secret,
+ sizeof(rand_premaster_secret)) <= 0)
goto err;
decrypt_len =
RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING);
@@ -2323,7 +2358,8 @@ int ssl3_get_client_key_exchange(SSL *s)
if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE,
SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
- goto err;
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ goto f_err;
} else {
p -= 2;
i = (int)n;
@@ -2376,9 +2412,10 @@ int ssl3_get_client_key_exchange(SSL *s)
i = DH_compute_key(p, pub, dh_srvr);
if (i <= 0) {
+ al = SSL_AD_HANDSHAKE_FAILURE;
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB);
BN_clear_free(pub);
- goto err;
+ goto f_err;
}
DH_free(s->s3->tmp.dh);
@@ -2676,12 +2713,14 @@ int ssl3_get_client_key_exchange(SSL *s)
i = *p;
p += 1;
if (n != 1 + i) {
- SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH);
+ al = SSL_AD_DECODE_ERROR;
+ goto f_err;
}
if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) {
SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB);
- goto err;
+ al = SSL_AD_HANDSHAKE_FAILURE;
+ goto f_err;
}
/*
* p is pointing to somewhere in the buffer currently, so set it
@@ -2984,6 +3023,11 @@ int ssl3_get_cert_verify(SSL *s)
peer = s->session->peer;
pkey = X509_get_pubkey(peer);
+ if (pkey == NULL) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+
type = X509_certificate_type(peer, pkey);
if (!(type & EVP_PKT_SIGN)) {
@@ -3120,7 +3164,9 @@ int ssl3_get_cert_verify(SSL *s)
goto f_err;
}
if (i != 64) {
+#ifdef SSL_DEBUG
fprintf(stderr, "GOST signature length is %d", i);
+#endif
}
for (idx = 0; idx < 64; idx++) {
signature[63 - idx] = p[idx];
@@ -3213,6 +3259,12 @@ int ssl3_get_client_certificate(SSL *s)
goto f_err;
}
for (nc = 0; nc < llen;) {
+ if (nc + 3 > llen) {
+ al = SSL_AD_DECODE_ERROR;
+ SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE,
+ SSL_R_CERT_LENGTH_MISMATCH);
+ goto f_err;
+ }
n2l3(p, l);
if ((l + nc + 3) > llen) {
al = SSL_AD_DECODE_ERROR;
@@ -3423,8 +3475,22 @@ int ssl3_send_newsession_ticket(SSL *s)
* all the work otherwise use generated values from parent ctx.
*/
if (tctx->tlsext_ticket_key_cb) {
- if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
- &hctx, 1) < 0)
+ /* if 0 is returned, write en empty ticket */
+ int ret = tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx,
+ &hctx, 1);
+
+ if (ret == 0) {
+ l2n(0, p); /* timeout */
+ s2n(0, p); /* length */
+ ssl_set_handshake_header(s, SSL3_MT_NEWSESSION_TICKET,
+ p - ssl_handshake_start(s));
+ s->state = SSL3_ST_SW_SESSION_TICKET_B;
+ OPENSSL_free(senc);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ HMAC_CTX_cleanup(&hctx);
+ return ssl_do_write(s);
+ }
+ if (ret < 0)
goto err;
} else {
if (RAND_bytes(iv, 16) <= 0)
@@ -3497,37 +3563,34 @@ int ssl3_send_cert_status(SSL *s)
{
if (s->state == SSL3_ST_SW_CERT_STATUS_A) {
unsigned char *p;
+ size_t msglen;
+
/*-
* Grow buffer if need be: the length calculation is as
- * follows 1 (message type) + 3 (message length) +
+ * follows handshake_header_length +
* 1 (ocsp response type) + 3 (ocsp response length)
* + (ocsp response)
*/
- if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) {
+ msglen = 4 + s->tlsext_ocsp_resplen;
+ if (!BUF_MEM_grow(s->init_buf, SSL_HM_HEADER_LENGTH(s) + msglen)) {
s->state = SSL_ST_ERR;
return -1;
}
- p = (unsigned char *)s->init_buf->data;
+ p = ssl_handshake_start(s);
- /* do the header */
- *(p++) = SSL3_MT_CERTIFICATE_STATUS;
- /* message length */
- l2n3(s->tlsext_ocsp_resplen + 4, p);
/* status type */
*(p++) = s->tlsext_status_type;
/* length of OCSP response */
l2n3(s->tlsext_ocsp_resplen, p);
/* actual response */
memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen);
- /* number of bytes to write */
- s->init_num = 8 + s->tlsext_ocsp_resplen;
- s->state = SSL3_ST_SW_CERT_STATUS_B;
- s->init_off = 0;
+
+ ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_STATUS, msglen);
}
/* SSL3_ST_SW_CERT_STATUS_B */
- return (ssl3_do_write(s, SSL3_RT_HANDSHAKE));
+ return (ssl_do_write(s));
}
# ifndef OPENSSL_NO_NEXTPROTONEG
diff --git a/thirdparty/openssl/ssl/ssl-lib.com b/thirdparty/openssl/ssl/ssl-lib.com
deleted file mode 100644
index 43fea17541..0000000000
--- a/thirdparty/openssl/ssl/ssl-lib.com
+++ /dev/null
@@ -1,1229 +0,0 @@
-$!
-$! SSL-LIB.COM
-$! Written By: Robert Byer
-$! Vice-President
-$! A-Com Computing, Inc.
-$! byer@mail.all-net.net
-$!
-$! Changes by Richard Levitte <richard@levitte.org>
-$!
-$! This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB"
-$! library for OpenSSL. The "xxx" denotes the machine architecture of
-$! ALPHA, IA64 or VAX.
-$!
-$! It is written to detect what type of machine you are compiling on
-$! (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC
-$! or GNU C) or you can specify which compiler to use.
-$!
-$! Specify the following as P1 to build just that part or ALL to just
-$! build everything.
-$!
-$! LIBRARY To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library.
-$! SSL_TASK To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE
-$!
-$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger
-$! information.
-$!
-$! Specify which compiler at P3 to try to compile under.
-$!
-$! VAXC For VAX C.
-$! DECC For DEC C.
-$! GNUC For GNU C.
-$!
-$! If you don't specify a compiler, it will try to determine which
-$! "C" compiler to use.
-$!
-$! P4, if defined, sets a TCP/IP library to use, through one of the following
-$! keywords:
-$!
-$! UCX for UCX
-$! TCPIP for TCPIP (post UCX)
-$! SOCKETSHR for SOCKETSHR+NETLIB
-$!
-$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up)
-$!
-$! P6, if defined, specifies the C pointer size. Ignored on VAX.
-$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.)
-$! Supported values are:
-$!
-$! "" Compile with default (/NOPOINTER_SIZE)
-$! 32 Compile with /POINTER_SIZE=32 (SHORT)
-$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV])
-$! (Automatically select ARGV if compiler supports it.)
-$! 64= Compile with /POINTER_SIZE=64 (LONG).
-$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV).
-$!
-$! P7, if defined, specifies a directory where ZLIB files (zlib.h,
-$! libz.olb) may be found. Optionally, a non-default object library
-$! name may be included ("dev:[dir]libz_64.olb", for example).
-$!
-$!
-$! Announce/identify.
-$!
-$ proc = f$environment( "procedure")
-$ write sys$output "@@@ "+ -
- f$parse( proc, , , "name")+ f$parse( proc, , , "type")
-$!
-$! Define A TCP/IP Library That We Will Need To Link To.
-$! (That Is, If We Need To Link To One.)
-$!
-$ TCPIP_LIB = ""
-$ ZLIB_LIB = ""
-$!
-$! Check What Architecture We Are Using.
-$!
-$ IF (F$GETSYI("CPU").LT.128)
-$ THEN
-$!
-$! The Architecture Is VAX.
-$!
-$ ARCH = "VAX"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! The Architecture Is Alpha, IA64 or whatever comes in the future.
-$!
-$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE")
-$ IF (ARCH .EQS. "") THEN ARCH = "UNK"
-$!
-$! End The Architecture Check.
-$!
-$ ENDIF
-$!
-$ ARCHD = ARCH
-$ LIB32 = "32"
-$ OPT_FILE = ""
-$ POINTER_SIZE = ""
-$!
-$! Check To Make Sure We Have Valid Command Line Parameters.
-$!
-$ GOSUB CHECK_OPTIONS
-$!
-$! Define The OBJ and EXE Directories.
-$!
-$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.SSL]
-$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.SSL]
-$!
-$! Specify the destination directory in any /MAP option.
-$!
-$ if (LINKMAP .eqs. "MAP")
-$ then
-$ LINKMAP = LINKMAP+ "=''EXE_DIR'"
-$ endif
-$!
-$! Add the location prefix to the linker options file name.
-$!
-$ if (OPT_FILE .nes. "")
-$ then
-$ OPT_FILE = EXE_DIR+ OPT_FILE
-$ endif
-$!
-$! Initialise logical names and such
-$!
-$ GOSUB INITIALISE
-$!
-$! Tell The User What Kind of Machine We Run On.
-$!
-$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'"
-$!
-$! Check To See If The Architecture Specific OBJ Directory Exists.
-$!
-$ IF (F$PARSE(OBJ_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'OBJ_DIR'
-$!
-$! End The Architecture Specific OBJ Directory Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The Architecture Specific Directory Exists.
-$!
-$ IF (F$PARSE(EXE_DIR).EQS."")
-$ THEN
-$!
-$! It Dosen't Exist, So Create It.
-$!
-$ CREATE/DIR 'EXE_DIR'
-$!
-$! End The Architecture Specific Directory Check.
-$!
-$ ENDIF
-$!
-$! Define The Library Name.
-$!
-$ SSL_LIB := 'EXE_DIR'SSL_LIBSSL'LIB32'.OLB
-$!
-$! Define The CRYPTO-LIB We Are To Use.
-$!
-$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB
-$!
-$! Set up exceptional compilations.
-$!
-$ CC5_SHOWN = 0
-$!
-$! Check To See What We Are To Do.
-$!
-$ IF (BUILDALL.EQS."TRUE")
-$ THEN
-$!
-$! Since Nothing Special Was Specified, Do Everything.
-$!
-$ GOSUB LIBRARY
-$ GOSUB SSL_TASK
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Build Just What The User Wants Us To Build.
-$!
-$ GOSUB 'BUILDALL'
-$!
-$! End The BUILDALL Check.
-$!
-$ ENDIF
-$!
-$! Time To EXIT.
-$!
-$ EXIT:
-$ GOSUB CLEANUP
-$ EXIT
-$!
-$! Compile The Library.
-$!
-$ LIBRARY:
-$!
-$! Check To See If We Already Have A "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library...
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Guess Not, Create The Library.
-$!
-$ LIBRARY/CREATE/OBJECT 'SSL_LIB'
-$!
-$! End The Library Exist Check.
-$!
-$ ENDIF
-$!
-$! Define The Different SSL "library" Files.
-$!
-$ LIB_SSL = "s2_meth, s2_srvr, s2_clnt, s2_lib, s2_enc, s2_pkt,"+ -
- "s3_meth, s3_srvr, s3_clnt, s3_lib, s3_enc, s3_pkt, s3_both, s3_cbc,"+ -
- "s23_meth,s23_srvr,s23_clnt,s23_lib, s23_pkt,"+ -
- "t1_meth, t1_srvr, t1_clnt, t1_lib, t1_enc, t1_ext,"+ -
- "d1_meth, d1_srvr, d1_clnt, d1_lib, d1_pkt,"+ -
- "d1_both,d1_srtp,"+ -
- "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ -
- "ssl_ciph,ssl_stat,ssl_rsa,"+ -
- "ssl_asn1,ssl_txt,ssl_algs,ssl_conf,"+ -
- "bio_ssl,ssl_err,kssl,t1_reneg,tls_srp,t1_trce,ssl_utst"
-$!
-$ COMPILEWITH_CC5 = ""
-$!
-$! Tell The User That We Are Compiling The Library.
-$!
-$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library."
-$!
-$! Define A File Counter And Set It To "0"
-$!
-$ FILE_COUNTER = 0
-$!
-$! Top Of The File Loop.
-$!
-$ NEXT_FILE:
-$!
-$! O.K, Extract The File Name From The File List.
-$!
-$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",LIB_SSL),"COLLAPSE")
-$!
-$! Check To See If We Are At The End Of The File List.
-$!
-$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE
-$!
-$! Increment The Counter.
-$!
-$ FILE_COUNTER = FILE_COUNTER + 1
-$!
-$! Create The Source File Name.
-$!
-$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C"
-$!
-$! Create The Object File Name.
-$!
-$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ"
-$ ON WARNING THEN GOTO NEXT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH(SOURCE_FILE).EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The File Exists Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What File We Are Compiling.
-$!
-$ WRITE SYS$OUTPUT " ",FILE_NAME,".c"
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO NEXT_FILE
-$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE'
-$!
-$! Add It To The Library.
-$!
-$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE'
-$!
-$! Time To Clean Up The Object File.
-$!
-$ DELETE 'OBJECT_FILE';*
-$!
-$! Go Back And Get The Next File Name.
-$!
-$ GOTO NEXT_FILE
-$!
-$! All Done With This Library.
-$!
-$ FILE_DONE:
-$!
-$! Tell The User That We Are All Done.
-$!
-$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$ SSL_TASK:
-$!
-$! Check To See If We Have The Proper Libraries.
-$!
-$ GOSUB LIB_CHECK
-$!
-$! Check To See If We Have A Linker Option File.
-$!
-$ GOSUB CHECK_OPT_FILE
-$!
-$! Check To See If The File We Want To Compile Is Actually There.
-$!
-$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."")
-$ THEN
-$!
-$! Tell The User That The File Dosen't Exist.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Exit The Build.
-$!
-$ EXIT
-$!
-$! End The SSL_TASK.C File Check.
-$!
-$ ENDIF
-$!
-$ COMPILEWITH_CC5 = "" !!! ",ssl_task,"
-$!
-$! Tell The User We Are Creating The SSL_TASK.
-$!
-$! Tell The User We Are Creating The SSL_TASK.
-$!
-$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine."
-$!
-$! Tell The User What File We Are Compiling.
-$!
-$ FILE_NAME = "ssl_task"
-$ WRITE SYS$OUTPUT " ",FILE_NAME,".c"
-$!
-$! Compile The File.
-$!
-$ ON ERROR THEN GOTO SSL_TASK_END
-$!
-$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ ","
-$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5
-$ THEN
-$ if (.not. CC5_SHOWN)
-$ then
-$ CC5_SHOWN = 1
-$ write sys$output " \Using special rule (5)"
-$ x = " "+ CC5
-$ write /symbol sys$output x
-$ endif
-$ CC5 /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
-$ ELSE
-$ CC /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C
-$ ENDIF
-$!
-$! Link The Program.
-$!
-$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_DIR'SSL_TASK.EXE -
- 'OBJ_DIR'SSL_TASK.OBJ, -
- 'SSL_LIB'/LIBRARY, -
- 'CRYPTO_LIB'/LIBRARY -
- 'TCPIP_LIB' -
- 'ZLIB_LIB' -
- ,'OPT_FILE' /OPTIONS
-$!
-$! Time To Return.
-$!
-$SSL_TASK_END:
-$ RETURN
-$!
-$! Check For The Link Option FIle.
-$!
-$ CHECK_OPT_FILE:
-$!
-$! Check To See If We Need To Make A VAX C Option File.
-$!
-$ IF (COMPILER.EQS."VAXC")
-$ THEN
-$!
-$! Check To See If We Already Have A VAX C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A VAX C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable VAX C Runtime Library.
-!
-SYS$SHARE:VAXCRTL.EXE/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The VAXC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A GNU C Option File.
-$!
-$ IF (COMPILER.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If We Already Have A GNU C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! We Need A GNU C Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable C Runtime Library.
-!
-GNU_CC:[000000]GCCLIB/LIBRARY
-SYS$SHARE:VAXCRTL/SHARE
-$EOD
-$!
-$! End The Option File Check.
-$!
-$ ENDIF
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Need A DEC C Option File.
-$!
-$ IF (COMPILER.EQS."DECC")
-$ THEN
-$!
-$! Check To See If We Already Have A DEC C Linker Option File.
-$!
-$ IF (F$SEARCH(OPT_FILE).EQS."")
-$ THEN
-$!
-$! Figure Out If We Need A non-VAX Or A VAX Linker Option File.
-$!
-$ IF (ARCH.EQS."VAX")
-$ THEN
-$!
-$! We Need A DEC C Linker Option File For VAX.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File To Link Against
-! The Sharable DEC C Runtime Library.
-!
-SYS$SHARE:DECC$SHR.EXE/SHARE
-$EOD
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Create The non-VAX Linker Option File.
-$!
-$ CREATE 'OPT_FILE'
-$DECK
-!
-! Default System Options File For non-VAX To Link Against
-! The Sharable C Runtime Library.
-!
-SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE
-SYS$SHARE:CMA$OPEN_RTL/SHARE
-$EOD
-$!
-$! End The DEC C Option File Check.
-$!
-$ ENDIF
-$!
-$! End The Option File Search.
-$!
-$ ENDIF
-$!
-$! End The DEC C Check.
-$!
-$ ENDIF
-$!
-$! Tell The User What Linker Option File We Are Using.
-$!
-$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"."
-$!
-$! Time To RETURN.
-$!
-$ RETURN
-$ LIB_CHECK:
-$!
-$! Look For The VAX Library LIBSSL.OLB.
-$!
-$ IF (F$SEARCH(SSL_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBSSL.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The LIBSSL.OLB Library Check.
-$!
-$ ENDIF
-$!
-$! Look For The Library LIBCRYPTO.OLB.
-$!
-$ IF (F$SEARCH(CRYPTO_LIB).EQS."")
-$ THEN
-$!
-$! Tell The User We Can't Find The LIBCRYPTO.OLB Library.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"."
-$ WRITE SYS$OUTPUT "We Can't Link Without It."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Since We Can't Link Without It, Exit.
-$!
-$ EXIT
-$!
-$! End The LIBCRYPTO.OLB Library Check.
-$!
-$ ENDIF
-$!
-$! Time To Return.
-$!
-$ RETURN
-$!
-$! Check The User's Options.
-$!
-$ CHECK_OPTIONS:
-$!
-$! Check To See If P1 Is Blank.
-$!
-$ IF (P1.EQS."ALL")
-$ THEN
-$!
-$! P1 Is Blank, So Build Everything.
-$!
-$ BUILDALL = "TRUE"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Else, Check To See If P1 Has A Valid Argument.
-$!
-$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK")
-$ THEN
-$!
-$! A Valid Argument.
-$!
-$ BUILDALL = P1
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALL : Just Build Everything."
-$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library."
-$ WRITE SYS$OUTPUT " SSL_TASK : To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program."
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " ALPHA[64]: Alpha Architecture."
-$ WRITE SYS$OUTPUT " IA64[64] : IA64 Architecture."
-$ WRITE SYS$OUTPUT " VAX : VAX Architecture."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P1 Check.
-$!
-$ ENDIF
-$!
-$! Check To See If P2 Is Blank.
-$!
-$ IF (P2.EQS."NODEBUG")
-$ THEN
-$!
-$! P2 Is NODEBUG, So Compile Without Debugger Information.
-$!
-$ DEBUGGER = "NODEBUG"
-$ LINKMAP = "NOMAP"
-$ TRACEBACK = "NOTRACEBACK"
-$ GCC_OPTIMIZE = "OPTIMIZE"
-$ CC_OPTIMIZE = "OPTIMIZE"
-$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization."
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Check To See If We Are To Compile With Debugger Information.
-$!
-$ IF (P2.EQS."DEBUG")
-$ THEN
-$!
-$! Compile With Debugger Information.
-$!
-$ DEBUGGER = "DEBUG"
-$ LINKMAP = "MAP"
-$ TRACEBACK = "TRACEBACK"
-$ GCC_OPTIMIZE = "NOOPTIMIZE"
-$ CC_OPTIMIZE = "NOOPTIMIZE"
-$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile."
-$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization."
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information."
-$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! End The Valid Argument Check.
-$!
-$ ENDIF
-$!
-$! End The P2 Check.
-$!
-$ ENDIF
-$!
-$! Special Threads For OpenVMS v7.1 Or Later
-$!
-$! Written By: Richard Levitte
-$! richard@levitte.org
-$!
-$!
-$! Check To See If We Have A Option For P5.
-$!
-$ IF (P5.EQS."")
-$ THEN
-$!
-$! Get The Version Of VMS We Are Using.
-$!
-$ ISSEVEN :=
-$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION")))
-$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP))
-$!
-$! Check To See If The VMS Version Is v7.1 Or Later.
-$!
-$ IF (TMP.GE.71)
-$ THEN
-$!
-$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads.
-$!
-$ ISSEVEN := ,PTHREAD_USE_D4
-$!
-$! End The VMS Version Check.
-$!
-$ ENDIF
-$!
-$! End The P5 Check.
-$!
-$ ENDIF
-$!
-$! Check P6 (POINTER_SIZE).
-$!
-$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX")
-$ THEN
-$!
-$ IF (P6 .EQS. "32")
-$ THEN
-$ POINTER_SIZE = " /POINTER_SIZE=32"
-$ ELSE
-$ POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE")
-$ IF ((POINTER_SIZE .EQS. "64") .OR. -
- (POINTER_SIZE .EQS. "64=") .OR. -
- (POINTER_SIZE .EQS. "64=ARGV"))
-$ THEN
-$ ARCHD = ARCH+ "_64"
-$ LIB32 = ""
-$ POINTER_SIZE = " /POINTER_SIZE=64"
-$ ELSE
-$!
-$! Tell The User Entered An Invalid Option.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", P6, -
- " Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT -
- " """" : Compile with default (short) pointers."
-$ WRITE SYS$OUTPUT -
- " 32 : Compile with 32-bit (short) pointers."
-$ WRITE SYS$OUTPUT -
- " 64 : Compile with 64-bit (long) pointers (auto ARGV)."
-$ WRITE SYS$OUTPUT -
- " 64= : Compile with 64-bit (long) pointers (no ARGV)."
-$ WRITE SYS$OUTPUT -
- " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$ ENDIF
-$!
-$ ENDIF
-$!
-$! End The P6 (POINTER_SIZE) Check.
-$!
-$ ENDIF
-$!
-$! Set basic C compiler /INCLUDE directories.
-$!
-$ CC_INCLUDES = "SYS$DISK:[-.CRYPTO],SYS$DISK:[-]"
-$!
-$! Check To See If P3 Is Blank.
-$!
-$ IF (P3.EQS."")
-$ THEN
-$!
-$! O.K., The User Didn't Specify A Compiler, Let's Try To
-$! Find Out Which One To Use.
-$!
-$! Check To See If We Have GNU C.
-$!
-$ IF (F$TRNLNM("GNU_CC").NES."")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ P3 = "GNUC"
-$!
-$! End The GNU C Compiler Check.
-$!
-$ ELSE
-$!
-$! Check To See If We Have VAXC Or DECC.
-$!
-$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ P3 = "DECC"
-$!
-$! Else...
-$!
-$ ELSE
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ P3 = "VAXC"
-$!
-$! End The VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The DECC & VAXC Compiler Check.
-$!
-$ ENDIF
-$!
-$! End The Compiler Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Have A Option For P4.
-$!
-$ IF (P4.EQS."")
-$ THEN
-$!
-$! Find out what socket library we have available
-$!
-$ IF F$PARSE("SOCKETSHR:") .NES. ""
-$ THEN
-$!
-$! We have SOCKETSHR, and it is my opinion that it's the best to use.
-$!
-$ P4 = "SOCKETSHR"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP"
-$!
-$! Else, let's look for something else
-$!
-$ ELSE
-$!
-$! Like UCX (the reason to do this before Multinet is that the UCX
-$! emulation is easier to use...)
-$!
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" -
- .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" -
- .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. ""
-$ THEN
-$!
-$! Last resort: a UCX or UCX-compatible library
-$!
-$ P4 = "UCX"
-$!
-$! Tell the user
-$!
-$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP"
-$!
-$! That was all...
-$!
-$ ENDIF
-$ ENDIF
-$ ENDIF
-$!
-$! Set Up Initial CC Definitions, Possibly With User Ones
-$!
-$ CCDEFS = "TCPIP_TYPE_''P4'"
-$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS
-$ CCEXTRAFLAGS = ""
-$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS
-$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR"
-$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. ""
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + ","
-$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS
-$ ENDIF
-$!
-$! Check To See If We Have A ZLIB Option.
-$!
-$ ZLIB = P7
-$ IF (ZLIB .NES. "")
-$ THEN
-$!
-$! Check for expected ZLIB files.
-$!
-$ err = 0
-$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY")
-$ if (f$search( file1) .eqs. "")
-$ then
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
-$ WRITE SYS$OUTPUT " Can't find header: ''file1'"
-$ err = 1
-$ endif
-$ file1 = f$parse( "A.;", ZLIB)- "A.;"
-$!
-$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY")
-$ if (f$search( file2) .eqs. "")
-$ then
-$ if (err .eq. 0)
-$ then
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid."
-$ endif
-$ WRITE SYS$OUTPUT " Can't find library: ''file2'"
-$ WRITE SYS$OUTPUT ""
-$ err = err+ 2
-$ endif
-$ if (err .eq. 1)
-$ then
-$ WRITE SYS$OUTPUT ""
-$ endif
-$!
-$ if (err .ne. 0)
-$ then
-$ EXIT
-$ endif
-$!
-$ CCDEFS = """ZLIB=1"", "+ CCDEFS
-$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1
-$ ZLIB_LIB = ", ''file2' /library"
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2
-$!
-$! End The ZLIB Check.
-$!
-$ ENDIF
-$!
-$! Check To See If The User Entered A Valid Parameter.
-$!
-$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC")
-$ THEN
-$!
-$! Check To See If The User Wanted DECC.
-$!
-$ IF (P3.EQS."DECC")
-$ THEN
-$!
-$! Looks Like DECC, Set To Use DECC.
-$!
-$ COMPILER = "DECC"
-$!
-$! Tell The User We Are Using DECC.
-$!
-$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler."
-$!
-$! Use DECC...
-$!
-$ CC = "CC"
-$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" -
- THEN CC = "CC/DECC"
-$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ -
- "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + -
- " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_DECC_OPTIONS.OPT"
-$!
-$! End DECC Check.
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use VAXC.
-$!
-$ IF (P3.EQS."VAXC")
-$ THEN
-$!
-$! Looks Like VAXC, Set To Use VAXC.
-$!
-$ COMPILER = "VAXC"
-$!
-$! Tell The User We Are Using VAX C.
-$!
-$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler."
-$!
-$! Compile Using VAXC.
-$!
-$ CC = "CC"
-$ IF ARCH.NES."VAX"
-$ THEN
-$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!"
-$ EXIT
-$ ENDIF
-$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC"
-$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
-$ CCDEFS = CCDEFS + ",""VAXC"""
-$!
-$! Define <sys> As SYS$COMMON:[SYSLIB]
-$!
-$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB]
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT"
-$!
-$! End VAXC Check
-$!
-$ ENDIF
-$!
-$! Check To See If We Are To Use GNU C.
-$!
-$ IF (P3.EQS."GNUC")
-$ THEN
-$!
-$! Looks Like GNUC, Set To Use GNUC.
-$!
-$ COMPILER = "GNUC"
-$!
-$! Tell The User We Are Using GNUC.
-$!
-$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler."
-$!
-$! Use GNU C...
-$!
-$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC
-$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + -
- "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS
-$!
-$! Define The Linker Options File Name.
-$!
-$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT"
-$!
-$! End The GNU C Check.
-$!
-$ ENDIF
-$!
-$! Set up default defines
-$!
-$ CCDEFS = """FLAT_INC=1""," + CCDEFS
-$!
-$! Finish up the definition of CC.
-$!
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$! Not all compiler versions support MAYLOSEDATA3.
-$ OPT_TEST = "MAYLOSEDATA3"
-$ DEFINE /USER_MODE SYS$ERROR NL:
-$ DEFINE /USER_MODE SYS$OUTPUT NL:
-$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT -
- /WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL:
-$ IF ($SEVERITY)
-$ THEN
-$ IF CCDISABLEWARNINGS .NES. "" THEN -
- CCDISABLEWARNINGS = CCDISABLEWARNINGS+ ","
-$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST
-$ ENDIF
-$ IF CCDISABLEWARNINGS .EQS. ""
-$ THEN
-$ CC4DISABLEWARNINGS = "DOLLARID"
-$ ELSE
-$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID"
-$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))"
-$ ENDIF
-$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))"
-$ ELSE
-$ CCDISABLEWARNINGS = ""
-$ CC4DISABLEWARNINGS = ""
-$ ENDIF
-$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS
-$ CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS
-$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS
-$ IF COMPILER .EQS. "DECC"
-$ THEN
-$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS
-$ ELSE
-$ CC4 = CC
-$ CC5 = CC3
-$ ENDIF
-$!
-$! Show user the result
-$!
-$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C."
-$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C."
-$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$ ENDIF
-$!
-$! Time to check the contents, and to make sure we get the correct library.
-$!
-$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" -
- .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE"
-$ THEN
-$!
-$! Check to see if SOCKETSHR was chosen
-$!
-$ IF P4.EQS."SOCKETSHR"
-$ THEN
-$!
-$! Set the library to use SOCKETSHR
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS"
-$!
-$! Done with SOCKETSHR
-$!
-$ ENDIF
-$!
-$! Check to see if MULTINET was chosen
-$!
-$ IF P4.EQS."MULTINET"
-$ THEN
-$!
-$! Set the library to use UCX emulation.
-$!
-$ P4 = "UCX"
-$!
-$! Done with MULTINET
-$!
-$ ENDIF
-$!
-$! Check to see if UCX was chosen
-$!
-$ IF P4.EQS."UCX"
-$ THEN
-$!
-$! Set the library to use UCX.
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS"
-$ IF F$TRNLNM("UCX$IPC_SHR") .NES. ""
-$ THEN
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS"
-$ ELSE
-$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN -
- TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS"
-$ ENDIF
-$!
-$! Done with UCX
-$!
-$ ENDIF
-$!
-$! Check to see if TCPIP was chosen
-$!
-$ IF P4.EQS."TCPIP"
-$ THEN
-$!
-$! Set the library to use TCPIP (post UCX).
-$!
-$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS"
-$!
-$! Done with TCPIP
-$!
-$ ENDIF
-$!
-$! Check to see if NONE was chosen
-$!
-$ IF P4.EQS."NONE"
-$ THEN
-$!
-$! Do not use a TCPIP library.
-$!
-$ TCPIP_LIB = ""
-$!
-$! Done with NONE
-$!
-$ ENDIF
-$!
-$! Print info
-$!
-$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- ","
-$!
-$! Else The User Entered An Invalid Argument.
-$!
-$ ELSE
-$!
-$! Tell The User We Don't Know What They Want.
-$!
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:"
-$ WRITE SYS$OUTPUT ""
-$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library."
-$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library."
-$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library."
-$ WRITE SYS$OUTPUT ""
-$!
-$! Time To EXIT.
-$!
-$ EXIT
-$!
-$! Done with TCP/IP libraries
-$!
-$ ENDIF
-$!
-$! Time To RETURN...
-$!
-$ RETURN
-$!
-$ INITIALISE:
-$!
-$! Save old value of the logical name OPENSSL
-$!
-$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE")
-$!
-$! Save directory information
-$!
-$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;"
-$ __HERE = F$EDIT(__HERE,"UPCASE")
-$ __TOP = __HERE - "SSL]"
-$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]"
-$!
-$! Set up the logical name OPENSSL to point at the include directory
-$!
-$ DEFINE OPENSSL/NOLOG '__INCLUDE'
-$!
-$! Done
-$!
-$ RETURN
-$!
-$ CLEANUP:
-$!
-$! Restore the logical name OPENSSL if it had a value
-$!
-$ IF __SAVE_OPENSSL .EQS. ""
-$ THEN
-$ DEASSIGN OPENSSL
-$ ELSE
-$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL'
-$ ENDIF
-$!
-$! Done
-$!
-$ RETURN
diff --git a/thirdparty/openssl/ssl/ssl_asn1.c b/thirdparty/openssl/ssl/ssl_asn1.c
index 35cc27c5e9..499f0e85ad 100644
--- a/thirdparty/openssl/ssl/ssl_asn1.c
+++ b/thirdparty/openssl/ssl/ssl_asn1.c
@@ -527,6 +527,9 @@ SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp,
if (os.length > SSL_MAX_SID_CTX_LENGTH) {
c.error = SSL_R_BAD_LENGTH;
c.line = __LINE__;
+ OPENSSL_free(os.data);
+ os.data = NULL;
+ os.length = 0;
goto err;
} else {
ret->sid_ctx_length = os.length;
diff --git a/thirdparty/openssl/ssl/ssl_cert.c b/thirdparty/openssl/ssl/ssl_cert.c
index f48ebaecc0..155728d037 100644
--- a/thirdparty/openssl/ssl/ssl_cert.c
+++ b/thirdparty/openssl/ssl/ssl_cert.c
@@ -315,7 +315,7 @@ CERT *ssl_cert_dup(CERT *cert)
OPENSSL_malloc(cert->pkeys[i].serverinfo_length);
if (ret->pkeys[i].serverinfo == NULL) {
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
- return NULL;
+ goto err;
}
ret->pkeys[i].serverinfo_length =
cert->pkeys[i].serverinfo_length;
@@ -392,9 +392,7 @@ CERT *ssl_cert_dup(CERT *cert)
return (ret);
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH)
err:
-#endif
#ifndef OPENSSL_NO_RSA
if (ret->rsa_tmp != NULL)
RSA_free(ret->rsa_tmp);
@@ -414,6 +412,7 @@ CERT *ssl_cert_dup(CERT *cert)
#endif
ssl_cert_clear_certs(ret);
+ OPENSSL_free(ret);
return NULL;
}
diff --git a/thirdparty/openssl/ssl/ssl_ciph.c b/thirdparty/openssl/ssl/ssl_ciph.c
index 302464e643..40021329a9 100644
--- a/thirdparty/openssl/ssl/ssl_ciph.c
+++ b/thirdparty/openssl/ssl/ssl_ciph.c
@@ -1932,17 +1932,27 @@ SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n)
}
#ifdef OPENSSL_NO_COMP
-void *SSL_COMP_get_compression_methods(void)
+STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void)
+{
+ return NULL;
+}
+
+STACK_OF(SSL_COMP) *SSL_COMP_set0_compression_methods(STACK_OF(SSL_COMP)
+ *meths)
{
return NULL;
}
-int SSL_COMP_add_compression_method(int id, void *cm)
+void SSL_COMP_free_compression_methods(void)
+{
+}
+
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
{
return 1;
}
-const char *SSL_COMP_get_name(const void *comp)
+const char *SSL_COMP_get_name(const COMP_METHOD *comp)
{
return NULL;
}
@@ -1991,13 +2001,19 @@ int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm)
if (id < 193 || id > 255) {
SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD,
SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE);
- return 0;
+ return 1;
}
MemCheck_off();
comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP));
+ if (comp == NULL) {
+ MemCheck_on();
+ SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE);
+ return 1;
+ }
comp->id = id;
comp->method = cm;
+ comp->name = cm->name;
load_builtin_compressions();
if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) {
OPENSSL_free(comp);
diff --git a/thirdparty/openssl/ssl/ssl_err.c b/thirdparty/openssl/ssl/ssl_err.c
index 704088dc46..a4c17a6bf3 100644
--- a/thirdparty/openssl/ssl/ssl_err.c
+++ b/thirdparty/openssl/ssl/ssl_err.c
@@ -1,6 +1,6 @@
/* ssl/ssl_err.c */
/* ====================================================================
- * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved.
+ * Copyright (c) 1999-2016 The OpenSSL Project. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -93,6 +93,8 @@ static ERR_STRING_DATA SSL_str_functs[] = {
{ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "dtls1_heartbeat"},
{ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "dtls1_output_cert_chain"},
{ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"},
+ {ERR_FUNC(SSL_F_DTLS1_PROCESS_BUFFERED_RECORDS),
+ "DTLS1_PROCESS_BUFFERED_RECORDS"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE),
"DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"},
{ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"},
@@ -751,6 +753,7 @@ static ERR_STRING_DATA SSL_str_reasons[] = {
"tls illegal exporter label"},
{ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST),
"tls invalid ecpointformat list"},
+ {ERR_REASON(SSL_R_TOO_MANY_WARN_ALERTS), "too many warn alerts"},
{ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST),
"tls peer did not respond with certificate list"},
{ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG),
diff --git a/thirdparty/openssl/ssl/ssl_lib.c b/thirdparty/openssl/ssl/ssl_lib.c
index fd94325bb3..24be376c9f 100644
--- a/thirdparty/openssl/ssl/ssl_lib.c
+++ b/thirdparty/openssl/ssl/ssl_lib.c
@@ -1828,7 +1828,7 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
const unsigned char *p, size_t plen,
int use_context)
{
- if (s->version < TLS1_VERSION)
+ if (s->version < TLS1_VERSION && s->version != DTLS1_BAD_VER)
return -1;
return s->method->ssl3_enc->export_keying_material(s, out, olen, label,
@@ -1838,13 +1838,21 @@ int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen,
static unsigned long ssl_session_hash(const SSL_SESSION *a)
{
+ const unsigned char *session_id = a->session_id;
unsigned long l;
+ unsigned char tmp_storage[4];
+
+ if (a->session_id_length < sizeof(tmp_storage)) {
+ memset(tmp_storage, 0, sizeof(tmp_storage));
+ memcpy(tmp_storage, a->session_id, a->session_id_length);
+ session_id = tmp_storage;
+ }
l = (unsigned long)
- ((unsigned int)a->session_id[0]) |
- ((unsigned int)a->session_id[1] << 8L) |
- ((unsigned long)a->session_id[2] << 16L) |
- ((unsigned long)a->session_id[3] << 24L);
+ ((unsigned long)session_id[0]) |
+ ((unsigned long)session_id[1] << 8L) |
+ ((unsigned long)session_id[2] << 16L) |
+ ((unsigned long)session_id[3] << 24L);
return (l);
}
@@ -2000,7 +2008,7 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
ret->tlsext_servername_callback = 0;
ret->tlsext_servername_arg = NULL;
/* Setup RFC4507 ticket keys */
- if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0)
+ if ((RAND_bytes(ret->tlsext_tick_key_name, 16) <= 0)
|| (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0)
|| (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0))
ret->options |= SSL_OP_NO_TICKET;
@@ -2030,10 +2038,8 @@ SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth)
ret->rbuf_freelist->len = 0;
ret->rbuf_freelist->head = NULL;
ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST));
- if (!ret->wbuf_freelist) {
- OPENSSL_free(ret->rbuf_freelist);
+ if (!ret->wbuf_freelist)
goto err;
- }
ret->wbuf_freelist->chunklen = 0;
ret->wbuf_freelist->len = 0;
ret->wbuf_freelist->head = NULL;
@@ -3050,12 +3056,12 @@ const SSL_CIPHER *SSL_get_current_cipher(const SSL *s)
}
#ifdef OPENSSL_NO_COMP
-const void *SSL_get_current_compression(SSL *s)
+const COMP_METHOD *SSL_get_current_compression(SSL *s)
{
return NULL;
}
-const void *SSL_get_current_expansion(SSL *s)
+const COMP_METHOD *SSL_get_current_expansion(SSL *s)
{
return NULL;
}
@@ -3188,6 +3194,9 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
ssl->cert->alpn_proposed_len = ocert->alpn_proposed_len;
ocert->alpn_proposed = NULL;
ssl->cert->alpn_sent = ocert->alpn_sent;
+
+ if (!custom_exts_copy_flags(&ssl->cert->srv_ext, &ocert->srv_ext))
+ return NULL;
#endif
ssl_cert_free(ocert);
}
diff --git a/thirdparty/openssl/ssl/ssl_locl.h b/thirdparty/openssl/ssl/ssl_locl.h
index 747e718a52..aeffc00634 100644
--- a/thirdparty/openssl/ssl/ssl_locl.h
+++ b/thirdparty/openssl/ssl/ssl_locl.h
@@ -491,6 +491,12 @@
# define SSL_CLIENT_USE_TLS1_2_CIPHERS(s) \
((SSL_IS_DTLS(s) && s->client_version <= DTLS1_2_VERSION) || \
(!SSL_IS_DTLS(s) && s->client_version >= TLS1_2_VERSION))
+/*
+ * Determine if a client should send signature algorithms extension:
+ * as with TLS1.2 cipher we can't rely on method flags.
+ */
+# define SSL_CLIENT_USE_SIGALGS(s) \
+ SSL_CLIENT_USE_TLS1_2_CIPHERS(s)
/* Mostly for SSLv3 */
# define SSL_PKEY_RSA_ENC 0
@@ -585,6 +591,8 @@ typedef struct {
*/
# define SSL_EXT_FLAG_SENT 0x2
+# define MAX_WARN_ALERT_COUNT 5
+
typedef struct {
custom_ext_method *meths;
size_t meths_count;
@@ -692,6 +700,8 @@ typedef struct cert_st {
unsigned char *alpn_proposed; /* server */
unsigned int alpn_proposed_len;
int alpn_sent; /* client */
+ /* Count of the number of consecutive warning alerts received */
+ unsigned int alert_count;
} CERT;
typedef struct sess_cert_st {
@@ -1148,7 +1158,7 @@ long ssl2_default_timeout(void);
const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p);
int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p);
-void ssl3_init_finished_mac(SSL *s);
+int ssl3_init_finished_mac(SSL *s);
int ssl3_send_server_certificate(SSL *s);
int ssl3_send_newsession_ticket(SSL *s);
int ssl3_send_cert_status(SSL *s);
@@ -1242,7 +1252,8 @@ int dtls1_retransmit_message(SSL *s, unsigned short seq,
unsigned long frag_off, int *found);
int dtls1_get_queue_priority(unsigned short seq, int is_ccs);
int dtls1_retransmit_buffered_messages(SSL *s);
-void dtls1_clear_record_buffer(SSL *s);
+void dtls1_clear_received_buffer(SSL *s);
+void dtls1_clear_sent_buffer(SSL *s);
void dtls1_get_message_header(unsigned char *data,
struct hm_header_st *msg_hdr);
void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
@@ -1373,7 +1384,7 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data,
unsigned char *limit);
int tls1_set_server_sigalgs(SSL *s);
-int ssl_check_clienthello_tlsext_late(SSL *s);
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al);
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data,
unsigned char *d, int n);
int ssl_prepare_clienthello_tlsext(SSL *s);
@@ -1419,7 +1430,7 @@ int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len,
long ssl_get_algorithm2(SSL *s);
int tls1_save_sigalgs(SSL *s, const unsigned char *data, int dsize);
int tls1_process_sigalgs(SSL *s);
-size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs);
+size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs);
int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
const unsigned char *sig, EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
@@ -1471,6 +1482,8 @@ int custom_ext_add(SSL *s, int server,
unsigned char **pret, unsigned char *limit, int *al);
int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src);
+int custom_exts_copy_flags(custom_ext_methods *dst,
+ const custom_ext_methods *src);
void custom_exts_free(custom_ext_methods *exts);
# else
diff --git a/thirdparty/openssl/ssl/ssl_rsa.c b/thirdparty/openssl/ssl/ssl_rsa.c
index 82022470bf..af03d45c2e 100644
--- a/thirdparty/openssl/ssl/ssl_rsa.c
+++ b/thirdparty/openssl/ssl/ssl_rsa.c
@@ -912,6 +912,8 @@ static int serverinfo_process_buffer(const unsigned char *serverinfo,
int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
size_t serverinfo_length)
{
+ unsigned char *new_serverinfo;
+
if (ctx == NULL || serverinfo == NULL || serverinfo_length == 0) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_PASSED_NULL_PARAMETER);
return 0;
@@ -928,12 +930,13 @@ int SSL_CTX_use_serverinfo(SSL_CTX *ctx, const unsigned char *serverinfo,
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_INTERNAL_ERROR);
return 0;
}
- ctx->cert->key->serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
- serverinfo_length);
- if (ctx->cert->key->serverinfo == NULL) {
+ new_serverinfo = OPENSSL_realloc(ctx->cert->key->serverinfo,
+ serverinfo_length);
+ if (new_serverinfo == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO, ERR_R_MALLOC_FAILURE);
return 0;
}
+ ctx->cert->key->serverinfo = new_serverinfo;
memcpy(ctx->cert->key->serverinfo, serverinfo, serverinfo_length);
ctx->cert->key->serverinfo_length = serverinfo_length;
@@ -961,6 +964,7 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
int ret = 0;
BIO *bin = NULL;
size_t num_extensions = 0;
+ unsigned char *new_serverinfo;
if (ctx == NULL || file == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE,
@@ -1011,12 +1015,13 @@ int SSL_CTX_use_serverinfo_file(SSL_CTX *ctx, const char *file)
goto end;
}
/* Append the decoded extension to the serverinfo buffer */
- serverinfo =
+ new_serverinfo =
OPENSSL_realloc(serverinfo, serverinfo_length + extension_length);
- if (serverinfo == NULL) {
+ if (new_serverinfo == NULL) {
SSLerr(SSL_F_SSL_CTX_USE_SERVERINFO_FILE, ERR_R_MALLOC_FAILURE);
goto end;
}
+ serverinfo = new_serverinfo;
memcpy(serverinfo + serverinfo_length, extension, extension_length);
serverinfo_length += extension_length;
diff --git a/thirdparty/openssl/ssl/ssl_sess.c b/thirdparty/openssl/ssl/ssl_sess.c
index b182998343..f50f514212 100644
--- a/thirdparty/openssl/ssl/ssl_sess.c
+++ b/thirdparty/openssl/ssl/ssl_sess.c
@@ -382,7 +382,7 @@ static int def_generate_session_id(const SSL *ssl, unsigned char *id,
{
unsigned int retry = 0;
do
- if (RAND_pseudo_bytes(id, *id_len) <= 0)
+ if (RAND_bytes(id, *id_len) <= 0)
return 0;
while (SSL_has_matching_session_id(ssl, id, *id_len) &&
(++retry < MAX_SESS_ID_ATTEMPTS)) ;
@@ -573,7 +573,7 @@ int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len,
int r;
#endif
- if (session_id + len > limit) {
+ if (limit - session_id < len) {
fatal = 1;
goto err;
}
@@ -769,6 +769,15 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
* obtain the same session from an external cache)
*/
s = NULL;
+ } else if (s == NULL &&
+ lh_SSL_SESSION_retrieve(ctx->sessions, c) == NULL) {
+ /* s == NULL can also mean OOM error in lh_SSL_SESSION_insert ... */
+
+ /*
+ * ... so take back the extra reference and also don't add
+ * the session to the SSL_SESSION_list at this time
+ */
+ s = c;
}
/* Put at the head of the queue unless it is already in the cache */
@@ -919,6 +928,10 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
session->krb5_client_princ_len > 0) {
s->kssl_ctx->client_princ =
(char *)OPENSSL_malloc(session->krb5_client_princ_len + 1);
+ if (s->kssl_ctx->client_princ == NULL) {
+ SSLerr(SSL_F_SSL_SET_SESSION, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ,
session->krb5_client_princ_len);
s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0';
@@ -993,7 +1006,8 @@ int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx,
return 0;
}
s->sid_ctx_length = sid_ctx_len;
- memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
+ if (s->sid_ctx != sid_ctx)
+ memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
return 1;
}
@@ -1123,7 +1137,7 @@ int ssl_clear_bad_session(SSL *s)
if ((s->session != NULL) &&
!(s->shutdown & SSL_SENT_SHUTDOWN) &&
!(SSL_in_init(s) || SSL_in_before(s))) {
- SSL_CTX_remove_session(s->ctx, s->session);
+ SSL_CTX_remove_session(s->session_ctx, s->session);
return (1);
} else
return (0);
diff --git a/thirdparty/openssl/ssl/t1_enc.c b/thirdparty/openssl/ssl/t1_enc.c
index 514fcb3e4e..b6d1ee95a5 100644
--- a/thirdparty/openssl/ssl/t1_enc.c
+++ b/thirdparty/openssl/ssl/t1_enc.c
@@ -673,7 +673,6 @@ int tls1_setup_key_block(SSL *s)
if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) {
SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(p1);
goto err;
}
#ifdef TLS_DEBUG
diff --git a/thirdparty/openssl/ssl/t1_ext.c b/thirdparty/openssl/ssl/t1_ext.c
index 724ddf76ac..0f4aba0226 100644
--- a/thirdparty/openssl/ssl/t1_ext.c
+++ b/thirdparty/openssl/ssl/t1_ext.c
@@ -179,6 +179,25 @@ int custom_ext_add(SSL *s, int server,
return 1;
}
+/* Copy the flags from src to dst for any extensions that exist in both */
+int custom_exts_copy_flags(custom_ext_methods *dst,
+ const custom_ext_methods *src)
+{
+ size_t i;
+ custom_ext_method *methsrc = src->meths;
+
+ for (i = 0; i < src->meths_count; i++, methsrc++) {
+ custom_ext_method *methdst = custom_ext_find(dst, methsrc->ext_type);
+
+ if (methdst == NULL)
+ continue;
+
+ methdst->ext_flags = methsrc->ext_flags;
+ }
+
+ return 1;
+}
+
/* Copy table of custom extensions */
int custom_exts_copy(custom_ext_methods *dst, const custom_ext_methods *src)
{
@@ -223,16 +242,14 @@ static int custom_ext_meth_add(custom_ext_methods *exts,
/* Search for duplicate */
if (custom_ext_find(exts, ext_type))
return 0;
- exts->meths = OPENSSL_realloc(exts->meths,
- (exts->meths_count +
- 1) * sizeof(custom_ext_method));
-
- if (!exts->meths) {
- exts->meths_count = 0;
+ meth = OPENSSL_realloc(exts->meths,
+ (exts->meths_count + 1)
+ * sizeof(custom_ext_method));
+ if (meth == NULL)
return 0;
- }
- meth = exts->meths + exts->meths_count;
+ exts->meths = meth;
+ meth += exts->meths_count;
memset(meth, 0, sizeof(custom_ext_method));
meth->parse_cb = parse_cb;
meth->add_cb = add_cb;
@@ -275,7 +292,9 @@ int SSL_extension_supported(unsigned int ext_type)
case TLSEXT_TYPE_ec_point_formats:
case TLSEXT_TYPE_elliptic_curves:
case TLSEXT_TYPE_heartbeat:
+# ifndef OPENSSL_NO_NEXTPROTONEG
case TLSEXT_TYPE_next_proto_neg:
+# endif
case TLSEXT_TYPE_padding:
case TLSEXT_TYPE_renegotiate:
case TLSEXT_TYPE_server_name:
diff --git a/thirdparty/openssl/ssl/t1_lib.c b/thirdparty/openssl/ssl/t1_lib.c
index dd5bd0050d..6587e8bb68 100644
--- a/thirdparty/openssl/ssl/t1_lib.c
+++ b/thirdparty/openssl/ssl/t1_lib.c
@@ -132,6 +132,9 @@ static int ssl_check_clienthello_tlsext_early(SSL *s);
int ssl_check_serverhello_tlsext(SSL *s);
#endif
+#define CHECKLEN(curr, val, limit) \
+ (((curr) >= (limit)) || (size_t)((limit) - (curr)) < (size_t)(val))
+
SSL3_ENC_METHOD TLSv1_enc_data = {
tls1_enc,
tls1_mac,
@@ -1032,7 +1035,7 @@ static unsigned char suiteb_sigalgs[] = {
tlsext_sigalg_ecdsa(TLSEXT_hash_sha384)
};
# endif
-size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
+size_t tls12_get_psigalgs(SSL *s, int sent, const unsigned char **psigs)
{
/*
* If Suite B mode use Suite B sigalgs only, ignore any other
@@ -1054,7 +1057,7 @@ size_t tls12_get_psigalgs(SSL *s, const unsigned char **psigs)
}
# endif
/* If server use client authentication sigalgs if not NULL */
- if (s->server && s->cert->client_sigalgs) {
+ if (s->server == sent && s->cert->client_sigalgs) {
*psigs = s->cert->client_sigalgs;
return s->cert->client_sigalgslen;
} else if (s->cert->conf_sigalgs) {
@@ -1118,7 +1121,7 @@ int tls12_check_peer_sigalg(const EVP_MD **pmd, SSL *s,
# endif
/* Check signature matches a type we sent */
- sent_sigslen = tls12_get_psigalgs(s, &sent_sigs);
+ sent_sigslen = tls12_get_psigalgs(s, 1, &sent_sigs);
for (i = 0; i < sent_sigslen; i += 2, sent_sigs += 2) {
if (sig[0] == sent_sigs[0] && sig[1] == sent_sigs[1])
break;
@@ -1166,7 +1169,7 @@ void ssl_set_client_disabled(SSL *s)
* Now go through all signature algorithms seeing if we support any for
* RSA, DSA, ECDSA. Do this for all versions not just TLS 1.2.
*/
- sigalgslen = tls12_get_psigalgs(s, &sigalgs);
+ sigalgslen = tls12_get_psigalgs(s, 1, &sigalgs);
for (i = 0; i < sigalgslen; i += 2, sigalgs += 2) {
switch (sigalgs[1]) {
# ifndef OPENSSL_NO_RSA
@@ -1263,8 +1266,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
if (s->tlsext_hostname != NULL) {
/* Add TLS extension servername to the Client Hello message */
- unsigned long size_str;
- long lenmax;
+ size_t size_str;
/*-
* check for enough space.
@@ -1274,10 +1276,8 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
* 2 for hostname length
* + hostname length
*/
-
- if ((lenmax = limit - ret - 9) < 0
- || (size_str =
- strlen(s->tlsext_hostname)) > (unsigned long)lenmax)
+ size_str = strlen(s->tlsext_hostname);
+ if (CHECKLEN(ret, 9 + size_str, limit))
return NULL;
/* extension type and length */
@@ -1321,7 +1321,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the
* Client Hello message */
- int login_len = strlen(s->srp_ctx.login);
+ size_t login_len = strlen(s->srp_ctx.login);
if (login_len > 255 || login_len == 0) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
@@ -1333,7 +1333,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
* 1 for the srp user identity
* + srp user identity length
*/
- if ((limit - ret - 5 - login_len) < 0)
+ if (CHECKLEN(ret, 5 + login_len, limit))
return NULL;
/* fill in the extension */
@@ -1350,20 +1350,23 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
/*
* Add TLS extension ECPointFormats to the ClientHello message
*/
- long lenmax;
const unsigned char *pcurves, *pformats;
size_t num_curves, num_formats, curves_list_len;
tls1_get_formatlist(s, &pformats, &num_formats);
- if ((lenmax = limit - ret - 5) < 0)
- return NULL;
- if (num_formats > (size_t)lenmax)
- return NULL;
if (num_formats > 255) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
+ /*-
+ * check for enough space.
+ * 4 bytes for the ec point formats type and extension length
+ * 1 byte for the length of the formats
+ * + formats length
+ */
+ if (CHECKLEN(ret, 5 + num_formats, limit))
+ return NULL;
s2n(TLSEXT_TYPE_ec_point_formats, ret);
/* The point format list has 1-byte length. */
@@ -1379,15 +1382,20 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
if (!tls1_get_curvelist(s, 0, &pcurves, &num_curves))
return NULL;
- if ((lenmax = limit - ret - 6) < 0)
- return NULL;
- if (num_curves > (size_t)lenmax / 2)
- return NULL;
if (num_curves > 65532 / 2) {
SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
curves_list_len = 2 * num_curves;
+ /*-
+ * check for enough space.
+ * 4 bytes for the ec curves type and extension length
+ * 2 bytes for the curve list length
+ * + curve list length
+ */
+ if (CHECKLEN(ret, 6 + curves_list_len, limit))
+ return NULL;
+
s2n(TLSEXT_TYPE_elliptic_curves, ret);
s2n(curves_list_len + 2, ret);
s2n(curves_list_len, ret);
@@ -1397,7 +1405,7 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
# endif /* OPENSSL_NO_EC */
if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- int ticklen;
+ size_t ticklen;
if (!s->new_session && s->session && s->session->tlsext_tick)
ticklen = s->session->tlsext_ticklen;
else if (s->session && s->tlsext_session_ticket &&
@@ -1418,22 +1426,29 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
* Check for enough room 2 for extension type, 2 for len rest for
* ticket
*/
- if ((long)(limit - ret - 4 - ticklen) < 0)
+ if (CHECKLEN(ret, 4 + ticklen, limit))
return NULL;
s2n(TLSEXT_TYPE_session_ticket, ret);
s2n(ticklen, ret);
- if (ticklen) {
+ if (ticklen > 0) {
memcpy(ret, s->session->tlsext_tick, ticklen);
ret += ticklen;
}
}
skip_ext:
- if (SSL_USE_SIGALGS(s)) {
+ if (SSL_CLIENT_USE_SIGALGS(s)) {
size_t salglen;
const unsigned char *salg;
- salglen = tls12_get_psigalgs(s, &salg);
- if ((size_t)(limit - ret) < salglen + 6)
+ salglen = tls12_get_psigalgs(s, 1, &salg);
+
+ /*-
+ * check for enough space.
+ * 4 bytes for the sigalgs type and extension length
+ * 2 bytes for the sigalg list length
+ * + sigalg list length
+ */
+ if (CHECKLEN(ret, salglen + 6, limit))
return NULL;
s2n(TLSEXT_TYPE_signature_algorithms, ret);
s2n(salglen + 2, ret);
@@ -1460,30 +1475,42 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) {
int i;
- long extlen, idlen, itmp;
+ size_t extlen, idlen;
+ int lentmp;
OCSP_RESPID *id;
idlen = 0;
for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) {
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
- itmp = i2d_OCSP_RESPID(id, NULL);
- if (itmp <= 0)
+ lentmp = i2d_OCSP_RESPID(id, NULL);
+ if (lentmp <= 0)
return NULL;
- idlen += itmp + 2;
+ idlen += (size_t)lentmp + 2;
}
if (s->tlsext_ocsp_exts) {
- extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
- if (extlen < 0)
+ lentmp = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL);
+ if (lentmp < 0)
return NULL;
+ extlen = (size_t)lentmp;
} else
extlen = 0;
- if ((long)(limit - ret - 7 - extlen - idlen) < 0)
- return NULL;
- s2n(TLSEXT_TYPE_status_request, ret);
if (extlen + idlen > 0xFFF0)
return NULL;
+ /*
+ * 2 bytes for status request type
+ * 2 bytes for status request len
+ * 1 byte for OCSP request type
+ * 2 bytes for length of ids
+ * 2 bytes for length of extensions
+ * + length of ids
+ * + length of extensions
+ */
+ if (CHECKLEN(ret, 9 + idlen + extlen, limit))
+ return NULL;
+
+ s2n(TLSEXT_TYPE_status_request, ret);
s2n(extlen + idlen + 5, ret);
*(ret++) = TLSEXT_STATUSTYPE_ocsp;
s2n(idlen, ret);
@@ -1493,9 +1520,9 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i);
/* skip over id len */
ret += 2;
- itmp = i2d_OCSP_RESPID(id, &ret);
+ lentmp = i2d_OCSP_RESPID(id, &ret);
/* write id len */
- s2n(itmp, q);
+ s2n(lentmp, q);
}
s2n(extlen, ret);
if (extlen > 0)
@@ -1503,8 +1530,15 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
}
# ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension */
- if ((limit - ret - 4 - 1) < 0)
+
+ /*-
+ * check for enough space.
+ * 4 bytes for the heartbeat ext type and extension length
+ * 1 byte for the mode
+ */
+ if (CHECKLEN(ret, 5, limit))
return NULL;
+
s2n(TLSEXT_TYPE_heartbeat, ret);
s2n(1, ret);
/*-
@@ -1524,7 +1558,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
* The client advertises an emtpy extension to indicate its support
* for Next Protocol Negotiation
*/
- if (limit - ret - 4 < 0)
+
+ /*-
+ * check for enough space.
+ * 4 bytes for the NPN ext type and extension length
+ */
+ if (CHECKLEN(ret, 4, limit))
return NULL;
s2n(TLSEXT_TYPE_next_proto_neg, ret);
s2n(0, ret);
@@ -1532,7 +1571,13 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
# endif
if (s->alpn_client_proto_list && !s->s3->tmp.finish_md_len) {
- if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len)
+ /*-
+ * check for enough space.
+ * 4 bytes for the ALPN type and extension length
+ * 2 bytes for the ALPN protocol list length
+ * + ALPN protocol list length
+ */
+ if (CHECKLEN(ret, 6 + s->alpn_client_proto_list_len, limit))
return NULL;
s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
s2n(2 + s->alpn_client_proto_list_len, ret);
@@ -1547,7 +1592,12 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
- if ((limit - ret - 4 - el) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the SRTP type and extension length
+ * + SRTP profiles length
+ */
+ if (CHECKLEN(ret, 4 + el, limit))
return NULL;
s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1587,6 +1637,17 @@ unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf,
else
hlen = 0;
+ /*-
+ * check for enough space. Strictly speaking we know we've already
+ * got enough space because to get here the message size is < 0x200,
+ * but we know that we've allocated far more than that in the buffer
+ * - but for consistency and robustness we're going to check anyway.
+ *
+ * 4 bytes for the padding type and extension length
+ * + padding length
+ */
+ if (CHECKLEN(ret, 4 + hlen, limit))
+ return NULL;
s2n(TLSEXT_TYPE_padding, ret);
s2n(hlen, ret);
memset(ret, 0, hlen);
@@ -1644,7 +1705,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
return NULL;
}
- if ((limit - ret - 4 - el) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the reneg type and extension length
+ * + reneg data length
+ */
+ if (CHECKLEN(ret, 4 + el, limit))
return NULL;
s2n(TLSEXT_TYPE_renegotiate, ret);
@@ -1664,19 +1730,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
/*
* Add TLS extension ECPointFormats to the ServerHello message
*/
- long lenmax;
tls1_get_formatlist(s, &plist, &plistlen);
- if ((lenmax = limit - ret - 5) < 0)
- return NULL;
- if (plistlen > (size_t)lenmax)
- return NULL;
if (plistlen > 255) {
SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR);
return NULL;
}
+ /*-
+ * check for enough space.
+ * 4 bytes for the ec points format type and extension length
+ * 1 byte for the points format list length
+ * + length of points format list
+ */
+ if (CHECKLEN(ret, 5 + plistlen, limit))
+ return NULL;
+
s2n(TLSEXT_TYPE_ec_point_formats, ret);
s2n(plistlen + 1, ret);
*(ret++) = (unsigned char)plistlen;
@@ -1691,14 +1761,25 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
# endif /* OPENSSL_NO_EC */
if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- if ((long)(limit - ret - 4) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the Ticket type and extension length
+ */
+ if (CHECKLEN(ret, 4, limit))
return NULL;
s2n(TLSEXT_TYPE_session_ticket, ret);
s2n(0, ret);
+ } else {
+ /* if we don't add the above TLSEXT, we can't add a session ticket later */
+ s->tlsext_ticket_expected = 0;
}
if (s->tlsext_status_expected) {
- if ((long)(limit - ret - 4) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the Status request type and extension length
+ */
+ if (CHECKLEN(ret, 4, limit))
return NULL;
s2n(TLSEXT_TYPE_status_request, ret);
s2n(0, ret);
@@ -1726,7 +1807,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
- if ((limit - ret - 4 - el) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the SRTP profiles type and extension length
+ * + length of the SRTP profiles list
+ */
+ if (CHECKLEN(ret, 4 + el, limit))
return NULL;
s2n(TLSEXT_TYPE_use_srtp, ret);
@@ -1751,16 +1837,23 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08,
0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17
};
- if (limit - ret < 36)
+
+ /* check for enough space. */
+ if (CHECKLEN(ret, sizeof(cryptopro_ext), limit))
return NULL;
- memcpy(ret, cryptopro_ext, 36);
- ret += 36;
+ memcpy(ret, cryptopro_ext, sizeof(cryptopro_ext));
+ ret += sizeof(cryptopro_ext);
}
# ifndef OPENSSL_NO_HEARTBEATS
/* Add Heartbeat extension if we've received one */
if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) {
- if ((limit - ret - 4 - 1) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the Heartbeat type and extension length
+ * 1 byte for the mode
+ */
+ if (CHECKLEN(ret, 5, limit))
return NULL;
s2n(TLSEXT_TYPE_heartbeat, ret);
s2n(1, ret);
@@ -1789,7 +1882,12 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
s->
ctx->next_protos_advertised_cb_arg);
if (r == SSL_TLSEXT_ERR_OK) {
- if ((long)(limit - ret - 4 - npalen) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the NPN type and extension length
+ * + length of protocols list
+ */
+ if (CHECKLEN(ret, 4 + npalen, limit))
return NULL;
s2n(TLSEXT_TYPE_next_proto_neg, ret);
s2n(npalen, ret);
@@ -1804,9 +1902,16 @@ unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf,
if (s->s3->alpn_selected) {
const unsigned char *selected = s->s3->alpn_selected;
- unsigned len = s->s3->alpn_selected_len;
+ size_t len = s->s3->alpn_selected_len;
- if ((long)(limit - ret - 4 - 2 - 1 - len) < 0)
+ /*-
+ * check for enough space.
+ * 4 bytes for the ALPN type and extension length
+ * 2 bytes for ALPN data length
+ * 1 byte for selected protocol length
+ * + length of the selected protocol
+ */
+ if (CHECKLEN(ret, 7 + len, limit))
return NULL;
s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
s2n(3 + len, ret);
@@ -1867,11 +1972,11 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
0x02, 0x03, /* SHA-1/ECDSA */
};
- if (data >= (limit - 2))
+ if (limit - data <= 2)
return;
data += 2;
- if (data > (limit - 4))
+ if (limit - data < 4)
return;
n2s(data, type);
n2s(data, size);
@@ -1879,7 +1984,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
if (type != TLSEXT_TYPE_server_name)
return;
- if (data + size > limit)
+ if (limit - data < size)
return;
data += size;
@@ -1887,7 +1992,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
const size_t len1 = sizeof(kSafariExtensionsBlock);
const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
- if (data + len1 + len2 != limit)
+ if (limit - data != (int)(len1 + len2))
return;
if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
return;
@@ -1896,7 +2001,7 @@ static void ssl_check_for_safari(SSL *s, const unsigned char *data,
} else {
const size_t len = sizeof(kSafariExtensionsBlock);
- if (data + len != limit)
+ if (limit - data != (int)(len))
return;
if (memcmp(data, kSafariExtensionsBlock, len) != 0)
return;
@@ -1966,11 +2071,10 @@ static int tls1_alpn_handle_client_hello(SSL *s, const unsigned char *data,
/*
* Process the ALPN extension in a ClientHello.
- * ret: a pointer to the TLSEXT return value: SSL_TLSEXT_ERR_*
* al: a pointer to the alert value to send in the event of a failure.
- * returns 1 on success, 0 on failure: al/ret set only on failure
+ * returns 1 on success, 0 on failure: al set only on failure
*/
-static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
+static int tls1_alpn_handle_client_hello_late(SSL *s, int *al)
{
const unsigned char *selected = NULL;
unsigned char selected_len = 0;
@@ -1986,7 +2090,6 @@ static int tls1_alpn_handle_client_hello_late(SSL *s, int *ret, int *al)
s->s3->alpn_selected = OPENSSL_malloc(selected_len);
if (s->s3->alpn_selected == NULL) {
*al = SSL_AD_INTERNAL_ERROR;
- *ret = SSL_TLSEXT_ERR_ALERT_FATAL;
return 0;
}
memcpy(s->s3->alpn_selected, selected, selected_len);
@@ -2053,19 +2156,19 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
if (data == limit)
goto ri_check;
- if (data > (limit - 2))
+ if (limit - data < 2)
goto err;
n2s(data, len);
- if (data + len != limit)
+ if (limit - data != len)
goto err;
- while (data <= (limit - 4)) {
+ while (limit - data >= 4) {
n2s(data, type);
n2s(data, size);
- if (data + size > (limit))
+ if (limit - data < size)
goto err;
# if 0
fprintf(stderr, "Received extension type %d size %d\n", type, size);
@@ -2316,6 +2419,23 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
size -= 2;
if (dsize > size)
goto err;
+
+ /*
+ * We remove any OCSP_RESPIDs from a previous handshake
+ * to prevent unbounded memory growth - CVE-2016-6304
+ */
+ sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids,
+ OCSP_RESPID_free);
+ if (dsize > 0) {
+ s->tlsext_ocsp_ids = sk_OCSP_RESPID_new_null();
+ if (s->tlsext_ocsp_ids == NULL) {
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+ } else {
+ s->tlsext_ocsp_ids = NULL;
+ }
+
while (dsize > 0) {
OCSP_RESPID *id;
int idsize;
@@ -2335,13 +2455,6 @@ static int ssl_scan_clienthello_tlsext(SSL *s, unsigned char **p,
OCSP_RESPID_free(id);
goto err;
}
- if (!s->tlsext_ocsp_ids
- && !(s->tlsext_ocsp_ids =
- sk_OCSP_RESPID_new_null())) {
- OCSP_RESPID_free(id);
- *al = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) {
OCSP_RESPID_free(id);
*al = SSL_AD_INTERNAL_ERROR;
@@ -2472,18 +2585,18 @@ static int ssl_scan_clienthello_custom_tlsext(SSL *s,
if (s->hit || s->cert->srv_ext.meths_count == 0)
return 1;
- if (data >= limit - 2)
+ if (limit - data <= 2)
return 1;
n2s(data, len);
- if (data > limit - len)
+ if (limit - data < len)
return 1;
- while (data <= limit - 4) {
+ while (limit - data >= 4) {
n2s(data, type);
n2s(data, size);
- if (data + size > limit)
+ if (limit - data < size)
return 1;
if (custom_ext_parse(s, 1 /* server */ , type, data, size, al) <= 0)
return 0;
@@ -2569,20 +2682,20 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
# endif
- if (data >= (d + n - 2))
+ if ((d + n) - data <= 2)
goto ri_check;
n2s(data, length);
- if (data + length != d + n) {
+ if ((d + n) - data != length) {
*al = SSL_AD_DECODE_ERROR;
return 0;
}
- while (data <= (d + n - 4)) {
+ while ((d + n) - data >= 4) {
n2s(data, type);
n2s(data, size);
- if (data + size > (d + n))
+ if ((d + n) - data < size)
goto ri_check;
if (s->tlsext_debug_cb)
@@ -2712,6 +2825,11 @@ static int ssl_scan_serverhello_tlsext(SSL *s, unsigned char **p,
*al = TLS1_AD_INTERNAL_ERROR;
return 0;
}
+ /*
+ * Could be non-NULL if server has sent multiple NPN extensions in
+ * a single Serverhello
+ */
+ OPENSSL_free(s->next_proto_negotiated);
s->next_proto_negotiated = OPENSSL_malloc(selected_len);
if (!s->next_proto_negotiated) {
*al = TLS1_AD_INTERNAL_ERROR;
@@ -3049,10 +3167,12 @@ int tls1_set_server_sigalgs(SSL *s)
return 0;
}
-int ssl_check_clienthello_tlsext_late(SSL *s)
+/*
+ * Upon success, returns 1.
+ * Upon failure, returns 0 and sets |al| to the appropriate fatal alert.
+ */
+int ssl_check_clienthello_tlsext_late(SSL *s, int *al)
{
- int ret = SSL_TLSEXT_ERR_OK;
- int al;
/*
* If status request then ask callback what to do. Note: this must be
@@ -3061,58 +3181,41 @@ int ssl_check_clienthello_tlsext_late(SSL *s)
* influence which certificate is sent
*/
if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) {
- int r;
+ int ret;
CERT_PKEY *certpkey;
certpkey = ssl_get_server_send_pkey(s);
/* If no certificate can't return certificate status */
- if (certpkey == NULL) {
- s->tlsext_status_expected = 0;
- return 1;
- }
- /*
- * Set current certificate to one we will use so SSL_get_certificate
- * et al can pick it up.
- */
- s->cert->key = certpkey;
- r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
- switch (r) {
- /* We don't want to send a status request response */
- case SSL_TLSEXT_ERR_NOACK:
- s->tlsext_status_expected = 0;
- break;
- /* status request response should be sent */
- case SSL_TLSEXT_ERR_OK:
- if (s->tlsext_ocsp_resp)
- s->tlsext_status_expected = 1;
- else
+ if (certpkey != NULL) {
+ /*
+ * Set current certificate to one we will use so SSL_get_certificate
+ * et al can pick it up.
+ */
+ s->cert->key = certpkey;
+ ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg);
+ switch (ret) {
+ /* We don't want to send a status request response */
+ case SSL_TLSEXT_ERR_NOACK:
s->tlsext_status_expected = 0;
- break;
- /* something bad happened */
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ret = SSL_TLSEXT_ERR_ALERT_FATAL;
- al = SSL_AD_INTERNAL_ERROR;
- goto err;
+ break;
+ /* status request response should be sent */
+ case SSL_TLSEXT_ERR_OK:
+ if (s->tlsext_ocsp_resp)
+ s->tlsext_status_expected = 1;
+ break;
+ /* something bad happened */
+ case SSL_TLSEXT_ERR_ALERT_FATAL:
+ default:
+ *al = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
}
- } else
- s->tlsext_status_expected = 0;
-
- if (!tls1_alpn_handle_client_hello_late(s, &ret, &al)) {
- goto err;
}
- err:
- switch (ret) {
- case SSL_TLSEXT_ERR_ALERT_FATAL:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
- return -1;
-
- case SSL_TLSEXT_ERR_ALERT_WARNING:
- ssl3_send_alert(s, SSL3_AL_WARNING, al);
- return 1;
-
- default:
- return 1;
+ if (!tls1_alpn_handle_client_hello_late(s, al)) {
+ return 0;
}
+
+ return 1;
}
int ssl_check_serverhello_tlsext(SSL *s)
@@ -3307,29 +3410,33 @@ int tls1_process_ticket(SSL *s, unsigned char *session_id, int len,
/* Skip past DTLS cookie */
if (SSL_IS_DTLS(s)) {
i = *(p++);
- p += i;
- if (p >= limit)
+
+ if (limit - p <= i)
return -1;
+
+ p += i;
}
/* Skip past cipher list */
n2s(p, i);
- p += i;
- if (p >= limit)
+ if (limit - p <= i)
return -1;
+ p += i;
+
/* Skip past compression algorithm list */
i = *(p++);
- p += i;
- if (p > limit)
+ if (limit - p < i)
return -1;
+ p += i;
+
/* Now at start of extensions */
- if ((p + 2) >= limit)
+ if (limit - p <= 2)
return 0;
n2s(p, i);
- while ((p + 4) <= limit) {
+ while (limit - p >= 4) {
unsigned short type, size;
n2s(p, type);
n2s(p, size);
- if (p + size > limit)
+ if (limit - p < size)
return 0;
if (type == TLSEXT_TYPE_session_ticket) {
int r;
@@ -3397,9 +3504,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
HMAC_CTX hctx;
EVP_CIPHER_CTX ctx;
SSL_CTX *tctx = s->initial_ctx;
- /* Need at least keyname + iv + some encrypted data */
- if (eticklen < 48)
- return 2;
+
/* Initialize session ticket encryption and HMAC contexts */
HMAC_CTX_init(&hctx);
EVP_CIPHER_CTX_init(&ctx);
@@ -3433,6 +3538,13 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
if (mlen < 0) {
goto err;
}
+ /* Sanity check ticket length: must exceed keyname + IV + HMAC */
+ if (eticklen <= 16 + EVP_CIPHER_CTX_iv_length(&ctx) + mlen) {
+ HMAC_CTX_cleanup(&hctx);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ return 2;
+ }
+
eticklen -= mlen;
/* Check HMAC of encrypted ticket */
if (HMAC_Update(&hctx, etick, eticklen) <= 0
@@ -3465,8 +3577,14 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
p = sdec;
sess = d2i_SSL_SESSION(NULL, &p, slen);
+ slen -= p - sdec;
OPENSSL_free(sdec);
if (sess) {
+ /* Some additional consistency checks */
+ if (slen != 0 || sess->session_id_length != 0) {
+ SSL_SESSION_free(sess);
+ return 2;
+ }
/*
* The session ID, if non-empty, is used by some clients to detect
* that the ticket has been accepted. So we copy it to the session
@@ -3694,7 +3812,7 @@ static int tls1_set_shared_sigalgs(SSL *s)
conf = c->conf_sigalgs;
conflen = c->conf_sigalgslen;
} else
- conflen = tls12_get_psigalgs(s, &conf);
+ conflen = tls12_get_psigalgs(s, 0, &conf);
if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE || is_suiteb) {
pref = conf;
preflen = conflen;
@@ -3902,7 +4020,7 @@ int tls1_process_heartbeat(SSL *s)
memcpy(bp, pl, payload);
bp += payload;
/* Random padding */
- if (RAND_pseudo_bytes(bp, padding) < 0) {
+ if (RAND_bytes(bp, padding) <= 0) {
OPENSSL_free(buffer);
return -1;
}
@@ -3980,6 +4098,8 @@ int tls1_heartbeat(SSL *s)
* - Padding
*/
buf = OPENSSL_malloc(1 + 2 + payload + padding);
+ if (buf == NULL)
+ return -1;
p = buf;
/* Message Type */
*p++ = TLS1_HB_REQUEST;
@@ -3988,13 +4108,13 @@ int tls1_heartbeat(SSL *s)
/* Sequence number */
s2n(s->tlsext_hb_seq, p);
/* 16 random bytes */
- if (RAND_pseudo_bytes(p, 16) < 0) {
+ if (RAND_bytes(p, 16) <= 0) {
SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
goto err;
}
p += 16;
/* Random padding */
- if (RAND_pseudo_bytes(p, padding) < 0) {
+ if (RAND_bytes(p, padding) <= 0) {
SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR);
goto err;
}
diff --git a/thirdparty/opus/celt/arch.h b/thirdparty/opus/celt/arch.h
index 9f74ddd267..8ceab5fe10 100644
--- a/thirdparty/opus/celt/arch.h
+++ b/thirdparty/opus/celt/arch.h
@@ -78,6 +78,15 @@ static OPUS_INLINE void _celt_fatal(const char *str, const char *file, int line)
#define UADD32(a,b) ((a)+(b))
#define USUB32(a,b) ((a)-(b))
+/* Set this if opus_int64 is a native type of the CPU. */
+/* Assume that all LP64 architectures have fast 64-bit types; also x86_64
+ (which can be ILP32 for x32) and Win64 (which is LLP64). */
+#if defined(__x86_64__) || defined(__LP64__) || defined(_WIN64)
+#define OPUS_FAST_INT64 1
+#else
+#define OPUS_FAST_INT64 0
+#endif
+
#define PRINT_MIPS(file)
#ifdef FIXED_POINT
@@ -118,7 +127,9 @@ static OPUS_INLINE opus_int16 SAT16(opus_int32 x) {
#include "fixed_generic.h"
-#ifdef OPUS_ARM_INLINE_EDSP
+#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
+#include "arm/fixed_arm64.h"
+#elif OPUS_ARM_INLINE_EDSP
#include "arm/fixed_armv5e.h"
#elif defined (OPUS_ARM_INLINE_ASM)
#include "arm/fixed_armv4.h"
diff --git a/thirdparty/opus/celt/arm/arm_celt_map.c b/thirdparty/opus/celt/arm/arm_celt_map.c
index ee6c244786..4d4d069a86 100644
--- a/thirdparty/opus/celt/arm/arm_celt_map.c
+++ b/thirdparty/opus/celt/arm/arm_celt_map.c
@@ -36,6 +36,9 @@
#if defined(OPUS_HAVE_RTCD)
# if defined(FIXED_POINT)
+# if ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
+ (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
+ (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int , int) = {
celt_pitch_xcorr_c, /* ARMv4 */
@@ -43,8 +46,10 @@ opus_val32 (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
MAY_HAVE_MEDIA(celt_pitch_xcorr), /* Media */
MAY_HAVE_NEON(celt_pitch_xcorr) /* NEON */
};
+
+# endif
# else /* !FIXED_POINT */
-# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
const opus_val16 *, opus_val32 *, int, int) = {
celt_pitch_xcorr_c, /* ARMv4 */
@@ -55,6 +60,23 @@ void (*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
# endif
# endif /* FIXED_POINT */
+#if defined(FIXED_POINT) && defined(OPUS_HAVE_RTCD) && \
+ defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR)
+
+void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
+ const opus_val16 *x,
+ const opus_val16 *y,
+ opus_val32 sum[4],
+ int len
+) = {
+ xcorr_kernel_c, /* ARMv4 */
+ xcorr_kernel_c, /* EDSP */
+ xcorr_kernel_c, /* Media */
+ xcorr_kernel_neon_fixed, /* Neon */
+};
+
+#endif
+
# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
# if defined(HAVE_ARM_NE10)
# if defined(CUSTOM_MODES)
diff --git a/thirdparty/opus/celt/arm/armcpu.c b/thirdparty/opus/celt/arm/armcpu.c
index 5e5d10c344..694a63b78e 100644
--- a/thirdparty/opus/celt/arm/armcpu.c
+++ b/thirdparty/opus/celt/arm/armcpu.c
@@ -37,11 +37,12 @@
#include "cpu_support.h"
#include "os_support.h"
#include "opus_types.h"
+#include "arch.h"
-#define OPUS_CPU_ARM_V4 (1)
-#define OPUS_CPU_ARM_EDSP (1<<1)
-#define OPUS_CPU_ARM_MEDIA (1<<2)
-#define OPUS_CPU_ARM_NEON (1<<3)
+#define OPUS_CPU_ARM_V4_FLAG (1<<OPUS_ARCH_ARM_V4)
+#define OPUS_CPU_ARM_EDSP_FLAG (1<<OPUS_ARCH_ARM_EDSP)
+#define OPUS_CPU_ARM_MEDIA_FLAG (1<<OPUS_ARCH_ARM_MEDIA)
+#define OPUS_CPU_ARM_NEON_FLAG (1<<OPUS_ARCH_ARM_NEON)
#if defined(_MSC_VER)
/*For GetExceptionCode() and EXCEPTION_ILLEGAL_INSTRUCTION.*/
@@ -55,20 +56,22 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
/* MSVC has no OPUS_INLINE __asm support for ARM, but it does let you __emit
* instructions via their assembled hex code.
* All of these instructions should be essentially nops. */
-# if defined(OPUS_ARM_MAY_HAVE_EDSP)
+# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
+ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
__try{
/*PLD [r13]*/
__emit(0xF5DDF000);
- flags|=OPUS_CPU_ARM_EDSP;
+ flags|=OPUS_CPU_ARM_EDSP_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
}
-# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
+# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
+ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
__try{
/*SHADD8 r3,r3,r3*/
__emit(0xE6333F93);
- flags|=OPUS_CPU_ARM_MEDIA;
+ flags|=OPUS_CPU_ARM_MEDIA_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
@@ -77,7 +80,7 @@ static OPUS_INLINE opus_uint32 opus_cpu_capabilities(void){
__try{
/*VORR q0,q0,q0*/
__emit(0xF2200150);
- flags|=OPUS_CPU_ARM_NEON;
+ flags|=OPUS_CPU_ARM_NEON_FLAG;
}
__except(GetExceptionCode()==EXCEPTION_ILLEGAL_INSTRUCTION){
/*Ignore exception.*/
@@ -107,26 +110,26 @@ opus_uint32 opus_cpu_capabilities(void)
while(fgets(buf, 512, cpuinfo) != NULL)
{
-# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+# if defined(OPUS_ARM_MAY_HAVE_EDSP) || defined(OPUS_ARM_MAY_HAVE_MEDIA) \
+ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
/* Search for edsp and neon flag */
if(memcmp(buf, "Features", 8) == 0)
{
char *p;
-# if defined(OPUS_ARM_MAY_HAVE_EDSP)
p = strstr(buf, " edsp");
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
- flags |= OPUS_CPU_ARM_EDSP;
-# endif
+ flags |= OPUS_CPU_ARM_EDSP_FLAG;
# if defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
p = strstr(buf, " neon");
if(p != NULL && (p[5] == ' ' || p[5] == '\n'))
- flags |= OPUS_CPU_ARM_NEON;
+ flags |= OPUS_CPU_ARM_NEON_FLAG;
# endif
}
# endif
-# if defined(OPUS_ARM_MAY_HAVE_MEDIA)
+# if defined(OPUS_ARM_MAY_HAVE_MEDIA) \
+ || defined(OPUS_ARM_MAY_HAVE_NEON) || defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
/* Search for media capabilities (>= ARMv6) */
if(memcmp(buf, "CPU architecture:", 17) == 0)
{
@@ -134,7 +137,7 @@ opus_uint32 opus_cpu_capabilities(void)
version = atoi(buf+17);
if(version >= 6)
- flags |= OPUS_CPU_ARM_MEDIA;
+ flags |= OPUS_CPU_ARM_MEDIA_FLAG;
}
# endif
}
@@ -156,18 +159,26 @@ int opus_select_arch(void)
opus_uint32 flags = opus_cpu_capabilities();
int arch = 0;
- if(!(flags & OPUS_CPU_ARM_EDSP))
+ if(!(flags & OPUS_CPU_ARM_EDSP_FLAG)) {
+ /* Asserts ensure arch values are sequential */
+ celt_assert(arch == OPUS_ARCH_ARM_V4);
return arch;
+ }
arch++;
- if(!(flags & OPUS_CPU_ARM_MEDIA))
+ if(!(flags & OPUS_CPU_ARM_MEDIA_FLAG)) {
+ celt_assert(arch == OPUS_ARCH_ARM_EDSP);
return arch;
+ }
arch++;
- if(!(flags & OPUS_CPU_ARM_NEON))
+ if(!(flags & OPUS_CPU_ARM_NEON_FLAG)) {
+ celt_assert(arch == OPUS_ARCH_ARM_MEDIA);
return arch;
+ }
arch++;
+ celt_assert(arch == OPUS_ARCH_ARM_NEON);
return arch;
}
diff --git a/thirdparty/opus/celt/arm/armcpu.h b/thirdparty/opus/celt/arm/armcpu.h
index ac5744606e..820262ff5f 100644
--- a/thirdparty/opus/celt/arm/armcpu.h
+++ b/thirdparty/opus/celt/arm/armcpu.h
@@ -66,6 +66,12 @@
# if defined(OPUS_HAVE_RTCD)
int opus_select_arch(void);
+
+#define OPUS_ARCH_ARM_V4 (0)
+#define OPUS_ARCH_ARM_EDSP (1)
+#define OPUS_ARCH_ARM_MEDIA (2)
+#define OPUS_ARCH_ARM_NEON (3)
+
# endif
#endif
diff --git a/thirdparty/opus/celt/arm/celt_neon_intr.c b/thirdparty/opus/celt/arm/celt_neon_intr.c
index 47dce15ba5..47bbe3dc22 100644
--- a/thirdparty/opus/celt/arm/celt_neon_intr.c
+++ b/thirdparty/opus/celt/arm/celt_neon_intr.c
@@ -37,7 +37,66 @@
#include <arm_neon.h>
#include "../pitch.h"
-#if !defined(FIXED_POINT)
+#if defined(FIXED_POINT)
+void xcorr_kernel_neon_fixed(const opus_val16 * x, const opus_val16 * y, opus_val32 sum[4], int len)
+{
+ int j;
+ int32x4_t a = vld1q_s32(sum);
+ /* Load y[0...3] */
+ /* This requires len>0 to always be valid (which we assert in the C code). */
+ int16x4_t y0 = vld1_s16(y);
+ y += 4;
+
+ for (j = 0; j + 8 <= len; j += 8)
+ {
+ /* Load x[0...7] */
+ int16x8_t xx = vld1q_s16(x);
+ int16x4_t x0 = vget_low_s16(xx);
+ int16x4_t x4 = vget_high_s16(xx);
+ /* Load y[4...11] */
+ int16x8_t yy = vld1q_s16(y);
+ int16x4_t y4 = vget_low_s16(yy);
+ int16x4_t y8 = vget_high_s16(yy);
+ int32x4_t a0 = vmlal_lane_s16(a, y0, x0, 0);
+ int32x4_t a1 = vmlal_lane_s16(a0, y4, x4, 0);
+
+ int16x4_t y1 = vext_s16(y0, y4, 1);
+ int16x4_t y5 = vext_s16(y4, y8, 1);
+ int32x4_t a2 = vmlal_lane_s16(a1, y1, x0, 1);
+ int32x4_t a3 = vmlal_lane_s16(a2, y5, x4, 1);
+
+ int16x4_t y2 = vext_s16(y0, y4, 2);
+ int16x4_t y6 = vext_s16(y4, y8, 2);
+ int32x4_t a4 = vmlal_lane_s16(a3, y2, x0, 2);
+ int32x4_t a5 = vmlal_lane_s16(a4, y6, x4, 2);
+
+ int16x4_t y3 = vext_s16(y0, y4, 3);
+ int16x4_t y7 = vext_s16(y4, y8, 3);
+ int32x4_t a6 = vmlal_lane_s16(a5, y3, x0, 3);
+ int32x4_t a7 = vmlal_lane_s16(a6, y7, x4, 3);
+
+ y0 = y8;
+ a = a7;
+ x += 8;
+ y += 8;
+ }
+
+ for (; j < len; j++)
+ {
+ int16x4_t x0 = vld1_dup_s16(x); /* load next x */
+ int32x4_t a0 = vmlal_s16(a, y0, x0);
+
+ int16x4_t y4 = vld1_dup_s16(y); /* load next y */
+ y0 = vext_s16(y0, y4, 1);
+ a = a0;
+ x++;
+ y++;
+ }
+
+ vst1q_s32(sum, a);
+}
+
+#else
/*
* Function: xcorr_kernel_neon_float
* ---------------------------------
diff --git a/thirdparty/opus/celt/arm/pitch_arm.h b/thirdparty/opus/celt/arm/pitch_arm.h
index 8626ed75b9..14331169ee 100644
--- a/thirdparty/opus/celt/arm/pitch_arm.h
+++ b/thirdparty/opus/celt/arm/pitch_arm.h
@@ -46,10 +46,53 @@ opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch);
# endif
-# if !defined(OPUS_HAVE_RTCD)
+# if defined(OPUS_HAVE_RTCD) && \
+ ((defined(OPUS_ARM_MAY_HAVE_NEON) && !defined(OPUS_ARM_PRESUME_NEON)) || \
+ (defined(OPUS_ARM_MAY_HAVE_MEDIA) && !defined(OPUS_ARM_PRESUME_MEDIA)) || \
+ (defined(OPUS_ARM_MAY_HAVE_EDSP) && !defined(OPUS_ARM_PRESUME_EDSP)))
+extern opus_val32
+(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
+ const opus_val16 *, opus_val32 *, int, int);
+# define OVERRIDE_PITCH_XCORR (1)
+# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+ ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
+ xcorr, len, max_pitch))
+
+# elif defined(OPUS_ARM_PRESUME_EDSP) || \
+ defined(OPUS_ARM_PRESUME_MEDIA) || \
+ defined(OPUS_ARM_PRESUME_NEON)
# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((void)(arch),PRESUME_NEON(celt_pitch_xcorr)(_x, _y, xcorr, len, max_pitch))
+
+# endif
+
+# if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
+void xcorr_kernel_neon_fixed(
+ const opus_val16 *x,
+ const opus_val16 *y,
+ opus_val32 sum[4],
+ int len);
+# endif
+
+# if defined(OPUS_HAVE_RTCD) && \
+ (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+
+extern void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
+ const opus_val16 *x,
+ const opus_val16 *y,
+ opus_val32 sum[4],
+ int len);
+
+# define OVERRIDE_XCORR_KERNEL (1)
+# define xcorr_kernel(x, y, sum, len, arch) \
+ ((*XCORR_KERNEL_IMPL[(arch) & OPUS_ARCHMASK])(x, y, sum, len))
+
+# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+# define OVERRIDE_XCORR_KERNEL (1)
+# define xcorr_kernel(x, y, sum, len, arch) \
+ ((void)arch, xcorr_kernel_neon_fixed(x, y, sum, len))
+
# endif
#else /* Start !FIXED_POINT */
@@ -57,12 +100,27 @@ opus_val32 celt_pitch_xcorr_edsp(const opus_val16 *_x, const opus_val16 *_y,
#if defined(OPUS_ARM_MAY_HAVE_NEON_INTR)
void celt_pitch_xcorr_float_neon(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch);
-#if !defined(OPUS_HAVE_RTCD) || defined(OPUS_ARM_PRESUME_NEON_INTR)
-#define OVERRIDE_PITCH_XCORR (1)
+#endif
+
+# if defined(OPUS_HAVE_RTCD) && \
+ (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) && !defined(OPUS_ARM_PRESUME_NEON_INTR))
+extern void
+(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
+ const opus_val16 *, opus_val32 *, int, int);
+
+# define OVERRIDE_PITCH_XCORR (1)
+# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
+ ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
+ xcorr, len, max_pitch))
+
+# elif defined(OPUS_ARM_PRESUME_NEON_INTR)
+
+# define OVERRIDE_PITCH_XCORR (1)
# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
((void)(arch),celt_pitch_xcorr_float_neon(_x, _y, xcorr, len, max_pitch))
-#endif
-#endif
+
+# endif
#endif /* end !FIXED_POINT */
+
#endif
diff --git a/thirdparty/opus/celt/bands.c b/thirdparty/opus/celt/bands.c
index 25f229e267..87eaa6c031 100644
--- a/thirdparty/opus/celt/bands.c
+++ b/thirdparty/opus/celt/bands.c
@@ -414,7 +414,7 @@ static void stereo_merge(celt_norm * OPUS_RESTRICT X, celt_norm * OPUS_RESTRICT
/* Compensating for the mid normalization */
xp = MULT16_32_Q15(mid, xp);
/* mid and side are in Q15, not Q14 like X and Y */
- mid2 = SHR32(mid, 1);
+ mid2 = SHR16(mid, 1);
El = MULT16_16(mid2, mid2) + side - 2*xp;
Er = MULT16_16(mid2, mid2) + side + 2*xp;
if (Er < QCONST32(6e-4f, 28) || El < QCONST32(6e-4f, 28))
@@ -714,7 +714,7 @@ static void compute_theta(struct band_ctx *ctx, struct split_ctx *sctx,
if (qn!=1)
{
if (encode)
- itheta = (itheta*qn+8192)>>14;
+ itheta = (itheta*(opus_int32)qn+8192)>>14;
/* Entropy coding of the angle. We use a uniform pdf for the
time split, a step for stereo, and a triangular one for the rest. */
diff --git a/thirdparty/opus/celt/celt.h b/thirdparty/opus/celt/celt.h
index a423b95046..d1f7eb690d 100644
--- a/thirdparty/opus/celt/celt.h
+++ b/thirdparty/opus/celt/celt.h
@@ -209,7 +209,7 @@ void comb_filter_const_c(opus_val32 *y, opus_val32 *x, int T, int N,
#endif
#ifndef OVERRIDE_COMB_FILTER_CONST
-# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
+# define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
((void)(arch),comb_filter_const_c(y, x, T, N, g10, g11, g12))
#endif
diff --git a/thirdparty/opus/celt/celt_decoder.c b/thirdparty/opus/celt/celt_decoder.c
index b688f2a4e3..b978bb34d1 100644
--- a/thirdparty/opus/celt/celt_decoder.c
+++ b/thirdparty/opus/celt/celt_decoder.c
@@ -82,6 +82,7 @@ struct OpusCustomDecoder {
int error;
int last_pitch_index;
int loss_count;
+ int skip_plc;
int postfilter_period;
int postfilter_period_old;
opus_val16 postfilter_gain;
@@ -164,8 +165,6 @@ OPUS_CUSTOM_NOSTATIC int opus_custom_decoder_init(CELTDecoder *st, const CELTMod
st->signalling = 1;
st->arch = opus_select_arch();
- st->loss_count = 0;
-
opus_custom_decoder_ctl(st, OPUS_RESET_STATE);
return OPUS_OK;
@@ -447,7 +446,7 @@ static void celt_decode_lost(CELTDecoder * OPUS_RESTRICT st, int N, int LM)
loss_count = st->loss_count;
start = st->start;
- noise_based = loss_count >= 5 || start != 0;
+ noise_based = loss_count >= 5 || start != 0 || st->skip_plc;
if (noise_based)
{
/* Noise-based PLC/CNG */
@@ -832,6 +831,10 @@ int celt_decode_with_ec(CELTDecoder * OPUS_RESTRICT st, const unsigned char *dat
return frame_size/st->downsample;
}
+ /* Check if there are at least two packets received consecutively before
+ * turning on the pitch-based PLC */
+ st->skip_plc = st->loss_count != 0;
+
if (dec == NULL)
{
ec_dec_init(&_dec,(unsigned char*)data,len);
@@ -1198,6 +1201,7 @@ int opus_custom_decoder_ctl(CELTDecoder * OPUS_RESTRICT st, int request, ...)
((char*)&st->DECODER_RESET_START - (char*)st));
for (i=0;i<2*st->mode->nbEBands;i++)
oldLogE[i]=oldLogE2[i]=-QCONST16(28.f,DB_SHIFT);
+ st->skip_plc = 1;
}
break;
case OPUS_GET_PITCH_REQUEST:
diff --git a/thirdparty/opus/celt/celt_encoder.c b/thirdparty/opus/celt/celt_encoder.c
index 41fbfd49c8..3ee7a4d3f7 100644
--- a/thirdparty/opus/celt/celt_encoder.c
+++ b/thirdparty/opus/celt/celt_encoder.c
@@ -1175,10 +1175,10 @@ static int run_prefilter(CELTEncoder *st, celt_sig *in, celt_sig *prefilter_mem,
if (N>COMBFILTER_MAXPERIOD)
{
- OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
+ OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD, pre[c]+N, COMBFILTER_MAXPERIOD);
} else {
OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD, prefilter_mem+c*COMBFILTER_MAXPERIOD+N, COMBFILTER_MAXPERIOD-N);
- OPUS_MOVE(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
+ OPUS_COPY(prefilter_mem+c*COMBFILTER_MAXPERIOD+COMBFILTER_MAXPERIOD-N, pre[c]+COMBFILTER_MAXPERIOD, N);
}
} while (++c<CC);
@@ -1281,12 +1281,15 @@ static int compute_vbr(const CELTMode *mode, AnalysisInfo *analysis, opus_int32
if ((!has_surround_mask||lfe) && (constrained_vbr || bitrate<64000))
{
- opus_val16 rate_factor;
+ opus_val16 rate_factor = Q15ONE;
+ if (bitrate < 64000)
+ {
#ifdef FIXED_POINT
- rate_factor = MAX16(0,(bitrate-32000));
+ rate_factor = MAX16(0,(bitrate-32000));
#else
- rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000));
+ rate_factor = MAX16(0,(1.f/32768)*(bitrate-32000));
#endif
+ }
if (constrained_vbr)
rate_factor = MIN16(rate_factor, QCONST16(0.67f, 15));
target = base_target + (opus_int32)MULT16_32_Q15(rate_factor, target-base_target);
diff --git a/thirdparty/opus/celt/celt_lpc.c b/thirdparty/opus/celt/celt_lpc.c
index f02145af0d..b410a21c5f 100644
--- a/thirdparty/opus/celt/celt_lpc.c
+++ b/thirdparty/opus/celt/celt_lpc.c
@@ -49,8 +49,7 @@ int p
float *lpc = _lpc;
#endif
- for (i = 0; i < p; i++)
- lpc[i] = 0;
+ OPUS_CLEAR(lpc, p);
if (ac[0] != 0)
{
for (i = 0; i < p; i++) {
diff --git a/thirdparty/opus/celt/cwrs.c b/thirdparty/opus/celt/cwrs.c
index 2fa9f89cd6..9722f0ac86 100644
--- a/thirdparty/opus/celt/cwrs.c
+++ b/thirdparty/opus/celt/cwrs.c
@@ -74,7 +74,7 @@ int log2_frac(opus_uint32 val, int frac)
/*Although derived separately, the pulse vector coding scheme is equivalent to
a Pyramid Vector Quantizer \cite{Fis86}.
Some additional notes about an early version appear at
- http://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
+ https://people.xiph.org/~tterribe/notes/cwrs.html, but the codebook ordering
and the definitions of some terms have evolved since that was written.
The conversion from a pulse vector to an integer index (encoding) and back
diff --git a/thirdparty/opus/celt/fixed_generic.h b/thirdparty/opus/celt/fixed_generic.h
index ac67d37ce8..1cfd6d6989 100644
--- a/thirdparty/opus/celt/fixed_generic.h
+++ b/thirdparty/opus/celt/fixed_generic.h
@@ -37,16 +37,32 @@
#define MULT16_16SU(a,b) ((opus_val32)(opus_val16)(a)*(opus_val32)(opus_uint16)(b))
/** 16x32 multiplication, followed by a 16-bit shift right. Results fits in 32 bits */
+#if OPUS_FAST_INT64
+#define MULT16_32_Q16(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),16))
+#else
#define MULT16_32_Q16(a,b) ADD32(MULT16_16((a),SHR((b),16)), SHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
+#endif
/** 16x32 multiplication, followed by a 16-bit shift right (round-to-nearest). Results fits in 32 bits */
+#if OPUS_FAST_INT64
+#define MULT16_32_P16(a,b) ((opus_val32)PSHR((opus_int64)((opus_val16)(a))*(b),16))
+#else
#define MULT16_32_P16(a,b) ADD32(MULT16_16((a),SHR((b),16)), PSHR(MULT16_16SU((a),((b)&0x0000ffff)),16))
+#endif
/** 16x32 multiplication, followed by a 15-bit shift right. Results fits in 32 bits */
+#if OPUS_FAST_INT64
+#define MULT16_32_Q15(a,b) ((opus_val32)SHR((opus_int64)((opus_val16)(a))*(b),15))
+#else
#define MULT16_32_Q15(a,b) ADD32(SHL(MULT16_16((a),SHR((b),16)),1), SHR(MULT16_16SU((a),((b)&0x0000ffff)),15))
+#endif
/** 32x32 multiplication, followed by a 31-bit shift right. Results fits in 32 bits */
+#if OPUS_FAST_INT64
+#define MULT32_32_Q31(a,b) ((opus_val32)SHR((opus_int64)(a)*(opus_int64)(b),31))
+#else
#define MULT32_32_Q31(a,b) ADD32(ADD32(SHL(MULT16_16(SHR((a),16),SHR((b),16)),1), SHR(MULT16_16SU(SHR((a),16),((b)&0x0000ffff)),15)), SHR(MULT16_16SU(SHR((b),16),((a)&0x0000ffff)),15))
+#endif
/** Compile-time conversion of float constant to 16-bit value */
#define QCONST16(x,bits) ((opus_val16)(.5+(x)*(((opus_val32)1)<<(bits))))
diff --git a/thirdparty/opus/celt/kiss_fft.c b/thirdparty/opus/celt/kiss_fft.c
index 4ed37d2bb7..1f8fd05321 100644
--- a/thirdparty/opus/celt/kiss_fft.c
+++ b/thirdparty/opus/celt/kiss_fft.c
@@ -191,7 +191,7 @@ static void kf_bfly3(
kiss_fft_cpx * Fout_beg = Fout;
#ifdef FIXED_POINT
- epi3.r = -16384;
+ /*epi3.r = -16384;*/ /* Unused */
epi3.i = -28378;
#else
epi3 = st->twiddles[fstride*m];
diff --git a/thirdparty/opus/celt/mathops.c b/thirdparty/opus/celt/mathops.c
index 3f8c5dcc0e..21a01f52e4 100644
--- a/thirdparty/opus/celt/mathops.c
+++ b/thirdparty/opus/celt/mathops.c
@@ -164,7 +164,7 @@ opus_val16 celt_cos_norm(opus_val32 x)
{
return _celt_cos_pi_2(EXTRACT16(x));
} else {
- return NEG32(_celt_cos_pi_2(EXTRACT16(65536-x)));
+ return NEG16(_celt_cos_pi_2(EXTRACT16(65536-x)));
}
} else {
if (x&0x0000ffff)
diff --git a/thirdparty/opus/celt/pitch.c b/thirdparty/opus/celt/pitch.c
index 1d89cb0342..bf46e7d562 100644
--- a/thirdparty/opus/celt/pitch.c
+++ b/thirdparty/opus/celt/pitch.c
@@ -412,6 +412,41 @@ void pitch_search(const opus_val16 * OPUS_RESTRICT x_lp, opus_val16 * OPUS_RESTR
RESTORE_STACK;
}
+#ifdef FIXED_POINT
+static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy)
+{
+ opus_val32 x2y2;
+ int sx, sy, shift;
+ opus_val32 g;
+ opus_val16 den;
+ if (xy == 0 || xx == 0 || yy == 0)
+ return 0;
+ sx = celt_ilog2(xx)-14;
+ sy = celt_ilog2(yy)-14;
+ shift = sx + sy;
+ x2y2 = MULT16_16_Q14(VSHR32(xx, sx), VSHR32(yy, sy));
+ if (shift & 1) {
+ if (x2y2 < 32768)
+ {
+ x2y2 <<= 1;
+ shift--;
+ } else {
+ x2y2 >>= 1;
+ shift++;
+ }
+ }
+ den = celt_rsqrt_norm(x2y2);
+ g = MULT16_32_Q15(den, xy);
+ g = VSHR32(g, (shift>>1)-1);
+ return EXTRACT16(MIN32(g, Q15ONE));
+}
+#else
+static opus_val16 compute_pitch_gain(opus_val32 xy, opus_val32 xx, opus_val32 yy)
+{
+ return xy/celt_sqrt(1+xx*yy);
+}
+#endif
+
static const int second_check[16] = {0, 0, 3, 2, 3, 2, 5, 2, 3, 2, 3, 2, 5, 2, 3, 2};
opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
int N, int *T0_, int prev_period, opus_val16 prev_gain, int arch)
@@ -450,18 +485,7 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
yy = yy_lookup[T0];
best_xy = xy;
best_yy = yy;
-#ifdef FIXED_POINT
- {
- opus_val32 x2y2;
- int sh, t;
- x2y2 = 1+HALF32(MULT32_32_Q31(xx,yy));
- sh = celt_ilog2(x2y2)>>1;
- t = VSHR32(x2y2, 2*(sh-7));
- g = g0 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
- }
-#else
- g = g0 = xy/celt_sqrt(1+xx*yy);
-#endif
+ g = g0 = compute_pitch_gain(xy, xx, yy);
/* Look for any pitch at T/k */
for (k=2;k<=15;k++)
{
@@ -484,24 +508,13 @@ opus_val16 remove_doubling(opus_val16 *x, int maxperiod, int minperiod,
T1b = celt_udiv(2*second_check[k]*T0+k, 2*k);
}
dual_inner_prod(x, &x[-T1], &x[-T1b], N, &xy, &xy2, arch);
- xy += xy2;
- yy = yy_lookup[T1] + yy_lookup[T1b];
-#ifdef FIXED_POINT
- {
- opus_val32 x2y2;
- int sh, t;
- x2y2 = 1+MULT32_32_Q31(xx,yy);
- sh = celt_ilog2(x2y2)>>1;
- t = VSHR32(x2y2, 2*(sh-7));
- g1 = VSHR32(MULT16_32_Q15(celt_rsqrt_norm(t), xy),sh+1);
- }
-#else
- g1 = xy/celt_sqrt(1+2.f*xx*1.f*yy);
-#endif
+ xy = HALF32(xy + xy2);
+ yy = HALF32(yy_lookup[T1] + yy_lookup[T1b]);
+ g1 = compute_pitch_gain(xy, xx, yy);
if (abs(T1-prev_period)<=1)
cont = prev_gain;
else if (abs(T1-prev_period)<=2 && 5*k*k < T0)
- cont = HALF32(prev_gain);
+ cont = HALF16(prev_gain);
else
cont = 0;
thresh = MAX16(QCONST16(.3f,15), MULT16_16_Q15(QCONST16(.7f,15),g0)-cont);
diff --git a/thirdparty/opus/celt/pitch.h b/thirdparty/opus/celt/pitch.h
index 65a77a6ecc..d3503532a0 100644
--- a/thirdparty/opus/celt/pitch.h
+++ b/thirdparty/opus/celt/pitch.h
@@ -187,25 +187,6 @@ celt_pitch_xcorr_c(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch);
#if !defined(OVERRIDE_PITCH_XCORR)
-/*Is run-time CPU detection enabled on this platform?*/
-# if defined(OPUS_HAVE_RTCD) && (defined(OPUS_ARM_ASM) \
- || (defined(OPUS_ARM_MAY_HAVE_NEON_INTR) \
- && !defined(OPUS_ARM_PRESUME_NEON_INTR)))
-extern
-# if defined(FIXED_POINT)
-opus_val32
-# else
-void
-# endif
-(*const CELT_PITCH_XCORR_IMPL[OPUS_ARCHMASK+1])(const opus_val16 *,
- const opus_val16 *, opus_val32 *, int, int);
-
-# define OVERRIDE_PITCH_XCORR
-# define celt_pitch_xcorr(_x, _y, xcorr, len, max_pitch, arch) \
- ((*CELT_PITCH_XCORR_IMPL[(arch)&OPUS_ARCHMASK])(_x, _y, \
- xcorr, len, max_pitch))
-# else
-
#ifdef FIXED_POINT
opus_val32
#else
@@ -214,7 +195,6 @@ void
celt_pitch_xcorr(const opus_val16 *_x, const opus_val16 *_y,
opus_val32 *xcorr, int len, int max_pitch, int arch);
-# endif
#endif
#endif
diff --git a/thirdparty/opus/celt/rate.c b/thirdparty/opus/celt/rate.c
index b28d8feccd..7dfa5be8a6 100644
--- a/thirdparty/opus/celt/rate.c
+++ b/thirdparty/opus/celt/rate.c
@@ -296,7 +296,7 @@ static OPUS_INLINE int interp_bits2pulses(const CELTMode *m, int start, int end,
done = 0;
for (j=end;j-->start;)
{
- int tmp = bits1[j] + (lo*bits2[j]>>ALLOC_STEPS);
+ int tmp = bits1[j] + ((opus_int32)lo*bits2[j]>>ALLOC_STEPS);
if (tmp < thresh[j] && !done)
{
if (tmp >= alloc_floor)
diff --git a/thirdparty/opus/celt/vq.c b/thirdparty/opus/celt/vq.c
index f358396065..d29f38fd8e 100644
--- a/thirdparty/opus/celt/vq.c
+++ b/thirdparty/opus/celt/vq.c
@@ -271,7 +271,7 @@ unsigned alg_quant(celt_norm *X, int N, int K, int spread, int B, ec_enc *enc
best_id = 0;
/* The squared magnitude term gets added anyway, so we might as well
add it outside the loop */
- yy = ADD32(yy, 1);
+ yy = ADD16(yy, 1);
j=0;
do {
opus_val16 Rxy, Ryy;
diff --git a/thirdparty/opus/celt/x86/pitch_sse.h b/thirdparty/opus/celt/x86/pitch_sse.h
index d4cbeb8b9c..e5f87ab51a 100644
--- a/thirdparty/opus/celt/x86/pitch_sse.h
+++ b/thirdparty/opus/celt/x86/pitch_sse.h
@@ -102,21 +102,21 @@ opus_val32 celt_inner_prod_sse(
#if defined(OPUS_X86_PRESUME_SSE4_1) && defined(FIXED_POINT)
#define OVERRIDE_CELT_INNER_PROD
#define celt_inner_prod(x, y, N, arch) \
- ((void)arch, celt_inner_prod_sse4_1(x, y, N))
+ ((void)arch, celt_inner_prod_sse4_1(x, y, N))
#elif defined(OPUS_X86_PRESUME_SSE2) && defined(FIXED_POINT) && !defined(OPUS_X86_MAY_HAVE_SSE4_1)
#define OVERRIDE_CELT_INNER_PROD
#define celt_inner_prod(x, y, N, arch) \
- ((void)arch, celt_inner_prod_sse2(x, y, N))
+ ((void)arch, celt_inner_prod_sse2(x, y, N))
#elif defined(OPUS_X86_PRESUME_SSE) && !defined(FIXED_POINT)
#define OVERRIDE_CELT_INNER_PROD
#define celt_inner_prod(x, y, N, arch) \
- ((void)arch, celt_inner_prod_sse(x, y, N))
+ ((void)arch, celt_inner_prod_sse(x, y, N))
#elif ((defined(OPUS_X86_MAY_HAVE_SSE4_1) || defined(OPUS_X86_MAY_HAVE_SSE2)) && defined(FIXED_POINT)) || \
- (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))
+ (defined(OPUS_X86_MAY_HAVE_SSE) && !defined(FIXED_POINT))
extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
const opus_val16 *x,
@@ -138,19 +138,19 @@ extern opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
#undef comb_filter_const
void dual_inner_prod_sse(const opus_val16 *x,
- const opus_val16 *y01,
- const opus_val16 *y02,
- int N,
- opus_val32 *xy1,
- opus_val32 *xy2);
+ const opus_val16 *y01,
+ const opus_val16 *y02,
+ int N,
+ opus_val32 *xy1,
+ opus_val32 *xy2);
void comb_filter_const_sse(opus_val32 *y,
- opus_val32 *x,
- int T,
- int N,
- opus_val16 g10,
- opus_val16 g11,
- opus_val16 g12);
+ opus_val32 *x,
+ int T,
+ int N,
+ opus_val16 g10,
+ opus_val16 g11,
+ opus_val16 g12);
#if defined(OPUS_X86_PRESUME_SSE)
@@ -169,7 +169,7 @@ extern void (*const DUAL_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
opus_val32 *xy1,
opus_val32 *xy2);
-#define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
+#define dual_inner_prod(x, y01, y02, N, xy1, xy2, arch) \
((*DUAL_INNER_PROD_IMPL[(arch) & OPUS_ARCHMASK])(x, y01, y02, N, xy1, xy2))
extern void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(
@@ -181,7 +181,7 @@ extern void (*const COMB_FILTER_CONST_IMPL[OPUS_ARCHMASK + 1])(
opus_val16 g11,
opus_val16 g12);
-#define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
+#define comb_filter_const(y, x, T, N, g10, g11, g12, arch) \
((*COMB_FILTER_CONST_IMPL[(arch) & OPUS_ARCHMASK])(y, x, T, N, g10, g11, g12))
#define NON_STATIC_COMB_FILTER_CONST_C
diff --git a/thirdparty/opus/celt/x86/x86_celt_map.c b/thirdparty/opus/celt/x86/x86_celt_map.c
index 8e5e449275..47ba41b9ee 100644
--- a/thirdparty/opus/celt/x86/x86_celt_map.c
+++ b/thirdparty/opus/celt/x86/x86_celt_map.c
@@ -72,7 +72,7 @@ void (*const XCORR_KERNEL_IMPL[OPUS_ARCHMASK + 1])(
#endif
#if (defined(OPUS_X86_MAY_HAVE_SSE4_1) && !defined(OPUS_X86_PRESUME_SSE4_1)) || \
- (!defined(OPUS_X86_MAY_HAVE_SSE_4_1) && defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2))
+ (!defined(OPUS_X86_MAY_HAVE_SSE_4_1) && defined(OPUS_X86_MAY_HAVE_SSE2) && !defined(OPUS_X86_PRESUME_SSE2))
opus_val32 (*const CELT_INNER_PROD_IMPL[OPUS_ARCHMASK + 1])(
const opus_val16 *x,
diff --git a/thirdparty/opus/celt/x86/x86cpu.c b/thirdparty/opus/celt/x86/x86cpu.c
index 555a576b8a..080eb25e41 100644
--- a/thirdparty/opus/celt/x86/x86cpu.c
+++ b/thirdparty/opus/celt/x86/x86cpu.c
@@ -46,7 +46,7 @@
#include <intrin.h>
static _inline void cpuid(unsigned int CPUInfo[4], unsigned int InfoType)
{
- __cpuid((int*)CPUInfo, InfoType);
+ __cpuid((int*)CPUInfo, InfoType);
}
#else
diff --git a/thirdparty/opus/opus_multistream_encoder.c b/thirdparty/opus/opus_multistream_encoder.c
index e722e31ab8..1698223a16 100644
--- a/thirdparty/opus/opus_multistream_encoder.c
+++ b/thirdparty/opus/opus_multistream_encoder.c
@@ -277,7 +277,7 @@ void surround_analysis(const CELTMode *celt_mode, const void *pcm, opus_val16 *b
sum = celt_inner_prod(in, in, frame_size+overlap, 0);
/* This should filter out both NaNs and ridiculous signals that could
cause NaNs further down. */
- if (!(sum < 1e9f) || celt_isnan(sum))
+ if (!(sum < 1e18f) || celt_isnan(sum))
{
OPUS_CLEAR(in, frame_size+overlap);
preemph_mem[c] = 0;
diff --git a/thirdparty/opus/silk/CNG.c b/thirdparty/opus/silk/CNG.c
index 61787c2302..8443ad63bb 100644
--- a/thirdparty/opus/silk/CNG.c
+++ b/thirdparty/opus/silk/CNG.c
@@ -34,9 +34,8 @@ POSSIBILITY OF SUCH DAMAGE.
/* Generates excitation for CNG LPC synthesis */
static OPUS_INLINE void silk_CNG_exc(
- opus_int32 exc_Q10[], /* O CNG excitation signal Q10 */
+ opus_int32 exc_Q14[], /* O CNG excitation signal Q10 */
opus_int32 exc_buf_Q14[], /* I Random samples buffer Q10 */
- opus_int32 Gain_Q16, /* I Gain to apply */
opus_int length, /* I Length */
opus_int32 *rand_seed /* I/O Seed to random index generator */
)
@@ -55,7 +54,7 @@ static OPUS_INLINE void silk_CNG_exc(
idx = (opus_int)( silk_RSHIFT( seed, 24 ) & exc_mask );
silk_assert( idx >= 0 );
silk_assert( idx <= CNG_BUF_MASK_MAX );
- exc_Q10[ i ] = (opus_int16)silk_SAT16( silk_SMULWW( exc_buf_Q14[ idx ], Gain_Q16 >> 4 ) );
+ exc_Q14[ i ] = exc_buf_Q14[ idx ];
}
*rand_seed = seed;
}
@@ -85,7 +84,7 @@ void silk_CNG(
)
{
opus_int i, subfr;
- opus_int32 sum_Q6, max_Gain_Q16, gain_Q16;
+ opus_int32 LPC_pred_Q10, max_Gain_Q16, gain_Q16, gain_Q10;
opus_int16 A_Q12[ MAX_LPC_ORDER ];
silk_CNG_struct *psCNG = &psDec->sCNG;
SAVE_STACK;
@@ -124,8 +123,8 @@ void silk_CNG(
/* Add CNG when packet is lost or during DTX */
if( psDec->lossCnt ) {
- VARDECL( opus_int32, CNG_sig_Q10 );
- ALLOC( CNG_sig_Q10, length + MAX_LPC_ORDER, opus_int32 );
+ VARDECL( opus_int32, CNG_sig_Q14 );
+ ALLOC( CNG_sig_Q14, length + MAX_LPC_ORDER, opus_int32 );
/* Generate CNG excitation */
gain_Q16 = silk_SMULWW( psDec->sPLC.randScale_Q14, psDec->sPLC.prevGain_Q16[1] );
@@ -138,42 +137,46 @@ void silk_CNG(
gain_Q16 = silk_SUB_LSHIFT32(silk_SMULWW( psCNG->CNG_smth_Gain_Q16, psCNG->CNG_smth_Gain_Q16 ), gain_Q16, 5 );
gain_Q16 = silk_LSHIFT32( silk_SQRT_APPROX( gain_Q16 ), 8 );
}
- silk_CNG_exc( CNG_sig_Q10 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, gain_Q16, length, &psCNG->rand_seed );
+ gain_Q10 = silk_RSHIFT( gain_Q16, 6 );
+
+ silk_CNG_exc( CNG_sig_Q14 + MAX_LPC_ORDER, psCNG->CNG_exc_buf_Q14, length, &psCNG->rand_seed );
/* Convert CNG NLSF to filter representation */
silk_NLSF2A( A_Q12, psCNG->CNG_smth_NLSF_Q15, psDec->LPC_order );
/* Generate CNG signal, by synthesis filtering */
- silk_memcpy( CNG_sig_Q10, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
+ silk_memcpy( CNG_sig_Q14, psCNG->CNG_synth_state, MAX_LPC_ORDER * sizeof( opus_int32 ) );
for( i = 0; i < length; i++ ) {
silk_assert( psDec->LPC_order == 10 || psDec->LPC_order == 16 );
/* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
- sum_Q6 = silk_RSHIFT( psDec->LPC_order, 1 );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
+ LPC_pred_Q10 = silk_RSHIFT( psDec->LPC_order, 1 );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 1 ], A_Q12[ 0 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 2 ], A_Q12[ 1 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 3 ], A_Q12[ 2 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 4 ], A_Q12[ 3 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 5 ], A_Q12[ 4 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 6 ], A_Q12[ 5 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 7 ], A_Q12[ 6 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 8 ], A_Q12[ 7 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 9 ], A_Q12[ 8 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 10 ], A_Q12[ 9 ] );
if( psDec->LPC_order == 16 ) {
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
- sum_Q6 = silk_SMLAWB( sum_Q6, CNG_sig_Q10[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 11 ], A_Q12[ 10 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 12 ], A_Q12[ 11 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 13 ], A_Q12[ 12 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 14 ], A_Q12[ 13 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 15 ], A_Q12[ 14 ] );
+ LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, CNG_sig_Q14[ MAX_LPC_ORDER + i - 16 ], A_Q12[ 15 ] );
}
/* Update states */
- CNG_sig_Q10[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q10[ MAX_LPC_ORDER + i ], sum_Q6, 4 );
-
- frame[ i ] = silk_ADD_SAT16( frame[ i ], silk_RSHIFT_ROUND( CNG_sig_Q10[ MAX_LPC_ORDER + i ], 10 ) );
+ CNG_sig_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT( CNG_sig_Q14[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
+
+ /* Scale with Gain and add to input signal */
+ frame[ i ] = (opus_int16)silk_ADD_SAT16( frame[ i ], silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( CNG_sig_Q14[ MAX_LPC_ORDER + i ], gain_Q10 ), 8 ) ) );
+
}
- silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q10[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
+ silk_memcpy( psCNG->CNG_synth_state, &CNG_sig_Q14[ length ], MAX_LPC_ORDER * sizeof( opus_int32 ) );
} else {
silk_memset( psCNG->CNG_synth_state, 0, psDec->LPC_order * sizeof( opus_int32 ) );
}
diff --git a/thirdparty/opus/silk/NLSF_del_dec_quant.c b/thirdparty/opus/silk/NLSF_del_dec_quant.c
index c3b9efccfa..de88fee060 100644
--- a/thirdparty/opus/silk/NLSF_del_dec_quant.c
+++ b/thirdparty/opus/silk/NLSF_del_dec_quant.c
@@ -46,8 +46,9 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
)
{
opus_int i, j, nStates, ind_tmp, ind_min_max, ind_max_min, in_Q10, res_Q10;
- opus_int pred_Q10, diff_Q10, out0_Q10, out1_Q10, rate0_Q5, rate1_Q5;
- opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25, pred_coef_Q16;
+ opus_int pred_Q10, diff_Q10, rate0_Q5, rate1_Q5;
+ opus_int16 out0_Q10, out1_Q10;
+ opus_int32 RD_tmp_Q25, min_Q25, min_max_Q25, max_min_Q25;
opus_int ind_sort[ NLSF_QUANT_DEL_DEC_STATES ];
opus_int8 ind[ NLSF_QUANT_DEL_DEC_STATES ][ MAX_LPC_ORDER ];
opus_int16 prev_out_Q10[ 2 * NLSF_QUANT_DEL_DEC_STATES ];
@@ -74,8 +75,8 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
out0_Q10 = silk_ADD16( out0_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
out1_Q10 = silk_ADD16( out1_Q10, SILK_FIX_CONST( NLSF_QUANT_LEVEL_ADJ, 10 ) );
}
- out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out0_Q10, quant_step_size_Q16 );
- out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_SMULWB( (opus_int32)out1_Q10, quant_step_size_Q16 );
+ out0_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out0_Q10, quant_step_size_Q16 ), 16 );
+ out1_Q10_table[ i + NLSF_QUANT_MAX_AMPLITUDE_EXT ] = silk_RSHIFT( silk_SMULBB( out1_Q10, quant_step_size_Q16 ), 16 );
}
silk_assert( (NLSF_QUANT_DEL_DEC_STATES & (NLSF_QUANT_DEL_DEC_STATES-1)) == 0 ); /* must be power of two */
@@ -85,12 +86,11 @@ opus_int32 silk_NLSF_del_dec_quant( /* O Returns
prev_out_Q10[ 0 ] = 0;
for( i = order - 1; ; i-- ) {
rates_Q5 = &ec_rates_Q5[ ec_ix[ i ] ];
- pred_coef_Q16 = silk_LSHIFT( (opus_int32)pred_coef_Q8[ i ], 8 );
in_Q10 = x_Q10[ i ];
for( j = 0; j < nStates; j++ ) {
- pred_Q10 = silk_SMULWB( pred_coef_Q16, prev_out_Q10[ j ] );
+ pred_Q10 = silk_RSHIFT( silk_SMULBB( (opus_int16)pred_coef_Q8[ i ], prev_out_Q10[ j ] ), 8 );
res_Q10 = silk_SUB16( in_Q10, pred_Q10 );
- ind_tmp = silk_SMULWB( (opus_int32)inv_quant_step_size_Q6, res_Q10 );
+ ind_tmp = silk_RSHIFT( silk_SMULBB( inv_quant_step_size_Q6, res_Q10 ), 16 );
ind_tmp = silk_LIMIT( ind_tmp, -NLSF_QUANT_MAX_AMPLITUDE_EXT, NLSF_QUANT_MAX_AMPLITUDE_EXT-1 );
ind[ j ][ i ] = (opus_int8)ind_tmp;
diff --git a/thirdparty/opus/silk/NLSF_encode.c b/thirdparty/opus/silk/NLSF_encode.c
index 03a036fda2..f03c3f1c35 100644
--- a/thirdparty/opus/silk/NLSF_encode.c
+++ b/thirdparty/opus/silk/NLSF_encode.c
@@ -46,7 +46,7 @@ opus_int32 silk_NLSF_encode( /* O Returns
)
{
opus_int i, s, ind1, bestIndex, prob_Q8, bits_q7;
- opus_int32 W_tmp_Q9;
+ opus_int32 W_tmp_Q9, ret;
VARDECL( opus_int32, err_Q26 );
VARDECL( opus_int32, RD_Q25 );
VARDECL( opus_int, tempIndices1 );
@@ -131,6 +131,7 @@ opus_int32 silk_NLSF_encode( /* O Returns
/* Decode */
silk_NLSF_decode( pNLSF_Q15, NLSFIndices, psNLSF_CB );
+ ret = RD_Q25[ 0 ];
RESTORE_STACK;
- return RD_Q25[ 0 ];
+ return ret;
}
diff --git a/thirdparty/opus/silk/NSQ.c b/thirdparty/opus/silk/NSQ.c
index a065884070..43e3fee7e0 100644
--- a/thirdparty/opus/silk/NSQ.c
+++ b/thirdparty/opus/silk/NSQ.c
@@ -31,6 +31,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main.h"
#include "stack_alloc.h"
+#include "NSQ.h"
+
static OPUS_INLINE void silk_nsq_scale_states(
const silk_encoder_state *psEncC, /* I Encoder State */
@@ -66,7 +68,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer(
opus_int offset_Q10, /* I */
opus_int length, /* I Input length */
opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
- opus_int predictLPCOrder /* I Prediction filter order */
+ opus_int predictLPCOrder, /* I Prediction filter order */
+ int arch /* I Architecture */
);
#endif
@@ -155,7 +158,7 @@ void silk_NSQ_c
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
- offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );
+ offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
x_Q3 += psEncC->subfr_length;
pulses += psEncC->subfr_length;
@@ -198,15 +201,19 @@ void silk_noise_shape_quantizer(
opus_int offset_Q10, /* I */
opus_int length, /* I Input length */
opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
- opus_int predictLPCOrder /* I Prediction filter order */
+ opus_int predictLPCOrder, /* I Prediction filter order */
+ int arch /* I Architecture */
)
{
- opus_int i, j;
+ opus_int i;
opus_int32 LTP_pred_Q13, LPC_pred_Q10, n_AR_Q12, n_LTP_Q13;
opus_int32 n_LF_Q12, r_Q10, rr_Q10, q1_Q0, q1_Q10, q2_Q10, rd1_Q20, rd2_Q20;
opus_int32 exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
opus_int32 *psLPC_Q14, *shp_lag_ptr, *pred_lag_ptr;
+#ifdef silk_short_prediction_create_arch_coef
+ opus_int32 a_Q12_arch[MAX_LPC_ORDER];
+#endif
shp_lag_ptr = &NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - lag + HARM_SHAPE_FIR_TAPS / 2 ];
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
@@ -215,32 +222,16 @@ void silk_noise_shape_quantizer(
/* Set up short term AR state */
psLPC_Q14 = &NSQ->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 ];
+#ifdef silk_short_prediction_create_arch_coef
+ silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
+#endif
+
for( i = 0; i < length; i++ ) {
/* Generate dither */
NSQ->rand_seed = silk_RAND( NSQ->rand_seed );
/* Short-term prediction */
- silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
- /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
- LPC_pred_Q10 = silk_RSHIFT( predictLPCOrder, 1 );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
- if( predictLPCOrder == 16 ) {
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
- LPC_pred_Q10 = silk_SMLAWB( LPC_pred_Q10, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
- }
+ LPC_pred_Q10 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
/* Long-term prediction */
if( signalType == TYPE_VOICED ) {
@@ -259,23 +250,8 @@ void silk_noise_shape_quantizer(
/* Noise shape feedback */
silk_assert( ( shapingLPCOrder & 1 ) == 0 ); /* check that order is even */
- tmp2 = psLPC_Q14[ 0 ];
- tmp1 = NSQ->sAR2_Q14[ 0 ];
- NSQ->sAR2_Q14[ 0 ] = tmp2;
- n_AR_Q12 = silk_RSHIFT( shapingLPCOrder, 1 );
- n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ 0 ] );
- for( j = 2; j < shapingLPCOrder; j += 2 ) {
- tmp2 = NSQ->sAR2_Q14[ j - 1 ];
- NSQ->sAR2_Q14[ j - 1 ] = tmp1;
- n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ j - 1 ] );
- tmp1 = NSQ->sAR2_Q14[ j + 0 ];
- NSQ->sAR2_Q14[ j + 0 ] = tmp2;
- n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp2, AR_shp_Q13[ j ] );
- }
- NSQ->sAR2_Q14[ shapingLPCOrder - 1 ] = tmp1;
- n_AR_Q12 = silk_SMLAWB( n_AR_Q12, tmp1, AR_shp_Q13[ shapingLPCOrder - 1 ] );
+ n_AR_Q12 = silk_NSQ_noise_shape_feedback_loop(psLPC_Q14, NSQ->sAR2_Q14, AR_shp_Q13, shapingLPCOrder, arch);
- n_AR_Q12 = silk_LSHIFT32( n_AR_Q12, 1 ); /* Q11 -> Q12 */
n_AR_Q12 = silk_SMLAWB( n_AR_Q12, NSQ->sLF_AR_shp_Q14, Tilt_Q14 );
n_LF_Q12 = silk_SMULWB( NSQ->sLTP_shp_Q14[ NSQ->sLTP_shp_buf_idx - 1 ], LF_shp_Q14 );
diff --git a/thirdparty/opus/silk/NSQ_del_dec.c b/thirdparty/opus/silk/NSQ_del_dec.c
index aff560c221..ab6feeac98 100644
--- a/thirdparty/opus/silk/NSQ_del_dec.c
+++ b/thirdparty/opus/silk/NSQ_del_dec.c
@@ -31,6 +31,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "main.h"
#include "stack_alloc.h"
+#include "NSQ.h"
+
typedef struct {
opus_int32 sLPC_Q14[ MAX_SUB_FRAME_LENGTH + NSQ_LPC_BUF_LENGTH ];
@@ -106,7 +108,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
- opus_int decisionDelay /* I */
+ opus_int decisionDelay, /* I */
+ int arch /* I */
);
void silk_NSQ_del_dec_c(
@@ -260,7 +263,7 @@ void silk_NSQ_del_dec_c(
silk_noise_shape_quantizer_del_dec( NSQ, psDelDec, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15,
delayedGain_Q10, A_Q12, B_Q14, AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ],
Gains_Q16[ k ], Lambda_Q10, offset_Q10, psEncC->subfr_length, subfr++, psEncC->shapingLPCOrder,
- psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay );
+ psEncC->predictLPCOrder, psEncC->warping_Q16, psEncC->nStatesDelayedDecision, &smpl_buf_idx, decisionDelay, psEncC->arch );
x_Q3 += psEncC->subfr_length;
pulses += psEncC->subfr_length;
@@ -333,7 +336,8 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
- opus_int decisionDelay /* I */
+ opus_int decisionDelay, /* I */
+ int arch /* I */
)
{
opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
@@ -343,6 +347,10 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
opus_int32 q1_Q0, q1_Q10, q2_Q10, exc_Q14, LPC_exc_Q14, xq_Q14, Gain_Q10;
opus_int32 tmp1, tmp2, sLF_AR_shp_Q14;
opus_int32 *pred_lag_ptr, *shp_lag_ptr, *psLPC_Q14;
+#ifdef silk_short_prediction_create_arch_coef
+ opus_int32 a_Q12_arch[MAX_LPC_ORDER];
+#endif
+
VARDECL( NSQ_sample_pair, psSampleState );
NSQ_del_dec_struct *psDD;
NSQ_sample_struct *psSS;
@@ -355,6 +363,10 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
pred_lag_ptr = &sLTP_Q15[ NSQ->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
Gain_Q10 = silk_RSHIFT( Gain_Q16, 6 );
+#ifdef silk_short_prediction_create_arch_coef
+ silk_short_prediction_create_arch_coef(a_Q12_arch, a_Q12, predictLPCOrder);
+#endif
+
for( i = 0; i < length; i++ ) {
/* Perform common calculations used in all states */
@@ -398,27 +410,7 @@ static OPUS_INLINE void silk_noise_shape_quantizer_del_dec(
/* Pointer used in short term prediction and shaping */
psLPC_Q14 = &psDD->sLPC_Q14[ NSQ_LPC_BUF_LENGTH - 1 + i ];
/* Short-term prediction */
- silk_assert( predictLPCOrder == 10 || predictLPCOrder == 16 );
- /* Avoids introducing a bias because silk_SMLAWB() always rounds to -inf */
- LPC_pred_Q14 = silk_RSHIFT( predictLPCOrder, 1 );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ 0 ], a_Q12[ 0 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -1 ], a_Q12[ 1 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -2 ], a_Q12[ 2 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -3 ], a_Q12[ 3 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -4 ], a_Q12[ 4 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -5 ], a_Q12[ 5 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -6 ], a_Q12[ 6 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -7 ], a_Q12[ 7 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -8 ], a_Q12[ 8 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -9 ], a_Q12[ 9 ] );
- if( predictLPCOrder == 16 ) {
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -10 ], a_Q12[ 10 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -11 ], a_Q12[ 11 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -12 ], a_Q12[ 12 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -13 ], a_Q12[ 13 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -14 ], a_Q12[ 14 ] );
- LPC_pred_Q14 = silk_SMLAWB( LPC_pred_Q14, psLPC_Q14[ -15 ], a_Q12[ 15 ] );
- }
+ LPC_pred_Q14 = silk_noise_shape_quantizer_short_prediction(psLPC_Q14, a_Q12, a_Q12_arch, predictLPCOrder, arch);
LPC_pred_Q14 = silk_LSHIFT( LPC_pred_Q14, 4 ); /* Q10 -> Q14 */
/* Noise shape feedback */
diff --git a/thirdparty/opus/silk/PLC.c b/thirdparty/opus/silk/PLC.c
index 34a94bc313..fb6ea887b7 100644
--- a/thirdparty/opus/silk/PLC.c
+++ b/thirdparty/opus/silk/PLC.c
@@ -365,7 +365,8 @@ static OPUS_INLINE void silk_PLC_conceal(
}
/* Add prediction to LPC excitation */
- sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], LPC_pred_Q10, 4 );
+ sLPC_Q14_ptr[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ],
+ silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ));
/* Scale with Gain */
frame[ i ] = (opus_int16)silk_SAT16( silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14_ptr[ MAX_LPC_ORDER + i ], prevGain_Q10[ 1 ] ), 8 ) ) );
diff --git a/thirdparty/opus/silk/decode_core.c b/thirdparty/opus/silk/decode_core.c
index b88991e349..e569c0e72b 100644
--- a/thirdparty/opus/silk/decode_core.c
+++ b/thirdparty/opus/silk/decode_core.c
@@ -219,7 +219,7 @@ void silk_decode_core(
}
/* Add prediction to LPC excitation */
- sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_LSHIFT32( pres_Q14[ i ], LPC_pred_Q10, 4 );
+ sLPC_Q14[ MAX_LPC_ORDER + i ] = silk_ADD_SAT32( pres_Q14[ i ], silk_LSHIFT_SAT32( LPC_pred_Q10, 4 ) );
/* Scale with gain */
pxq[ i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( silk_SMULWW( sLPC_Q14[ MAX_LPC_ORDER + i ], Gain_Q10 ), 8 ) );
diff --git a/thirdparty/opus/silk/fixed/burg_modified_FIX.c b/thirdparty/opus/silk/fixed/burg_modified_FIX.c
index 4878553b65..17d0e0993c 100644
--- a/thirdparty/opus/silk/fixed/burg_modified_FIX.c
+++ b/thirdparty/opus/silk/fixed/burg_modified_FIX.c
@@ -150,8 +150,11 @@ void silk_burg_modified_c(
C_first_row[ k ] = silk_MLA( C_first_row[ k ], x1, x_ptr[ n - k - 1 ] ); /* Q( -rshifts ) */
C_last_row[ k ] = silk_MLA( C_last_row[ k ], x2, x_ptr[ subfr_length - n + k ] ); /* Q( -rshifts ) */
Atmp1 = silk_RSHIFT_ROUND( Af_QA[ k ], QA - 17 ); /* Q17 */
- tmp1 = silk_MLA( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
- tmp2 = silk_MLA( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
+ /* We sometimes have get overflows in the multiplications (even beyond +/- 2^32),
+ but they cancel each other and the real result seems to always fit in a 32-bit
+ signed integer. This was determined experimentally, not theoretically (unfortunately). */
+ tmp1 = silk_MLA_ovflw( tmp1, x_ptr[ n - k - 1 ], Atmp1 ); /* Q17 */
+ tmp2 = silk_MLA_ovflw( tmp2, x_ptr[ subfr_length - n + k ], Atmp1 ); /* Q17 */
}
tmp1 = -tmp1; /* Q17 */
tmp2 = -tmp2; /* Q17 */
@@ -200,12 +203,14 @@ void silk_burg_modified_c(
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
- /* Newton-Raphson iteration */
- rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
- rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
- if( num < 0 ) {
- /* Ensure adjusted reflection coefficients has the original sign */
- rc_Q31 = -rc_Q31;
+ if( rc_Q31 > 0 ) {
+ /* Newton-Raphson iteration */
+ rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
+ rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
+ if( num < 0 ) {
+ /* Ensure adjusted reflection coefficients has the original sign */
+ rc_Q31 = -rc_Q31;
+ }
}
invGain_Q30 = minInvGain_Q30;
reached_max_gain = 1;
diff --git a/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c b/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c
index 3756095fbe..3c3583c5fc 100644
--- a/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c
+++ b/thirdparty/opus/silk/fixed/x86/burg_modified_FIX_sse.c
@@ -300,12 +300,14 @@ void silk_burg_modified_sse4_1(
/* Max prediction gain exceeded; set reflection coefficient such that max prediction gain is exactly hit */
tmp2 = ( (opus_int32)1 << 30 ) - silk_DIV32_varQ( minInvGain_Q30, invGain_Q30, 30 ); /* Q30 */
rc_Q31 = silk_SQRT_APPROX( tmp2 ); /* Q15 */
- /* Newton-Raphson iteration */
- rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
- rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
- if( num < 0 ) {
- /* Ensure adjusted reflection coefficients has the original sign */
- rc_Q31 = -rc_Q31;
+ if( rc_Q31 > 0 ) {
+ /* Newton-Raphson iteration */
+ rc_Q31 = silk_RSHIFT32( rc_Q31 + silk_DIV32( tmp2, rc_Q31 ), 1 ); /* Q15 */
+ rc_Q31 = silk_LSHIFT32( rc_Q31, 16 ); /* Q31 */
+ if( num < 0 ) {
+ /* Ensure adjusted reflection coefficients has the original sign */
+ rc_Q31 = -rc_Q31;
+ }
}
invGain_Q30 = minInvGain_Q30;
reached_max_gain = 1;
diff --git a/thirdparty/opus/silk/macros.h b/thirdparty/opus/silk/macros.h
index bc30303466..d3ca347520 100644
--- a/thirdparty/opus/silk/macros.h
+++ b/thirdparty/opus/silk/macros.h
@@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "opus_types.h"
#include "opus_defines.h"
+#include "arch.h"
#if OPUS_GNUC_PREREQ(3, 0)
#define opus_likely(x) (__builtin_expect(!!(x), 1))
@@ -43,31 +44,32 @@ POSSIBILITY OF SUCH DAMAGE.
#define opus_unlikely(x) (!!(x))
#endif
-/* Set this if opus_int64 is a native type of the CPU. */
-#define OPUS_FAST_INT64 (defined(__x86_64__) || defined(__LP64__) || defined(_WIN64))
-
/* This is an OPUS_INLINE header file for general platform. */
/* (a32 * (opus_int32)((opus_int16)(b32))) >> 16 output have to be 32bit int */
#if OPUS_FAST_INT64
-#define silk_SMULWB(a32, b32) (((a32) * (opus_int64)((opus_int16)(b32))) >> 16)
+#define silk_SMULWB(a32, b32) ((opus_int32)(((a32) * (opus_int64)((opus_int16)(b32))) >> 16))
#else
#define silk_SMULWB(a32, b32) ((((a32) >> 16) * (opus_int32)((opus_int16)(b32))) + ((((a32) & 0x0000FFFF) * (opus_int32)((opus_int16)(b32))) >> 16))
#endif
/* a32 + (b32 * (opus_int32)((opus_int16)(c32))) >> 16 output have to be 32bit int */
#if OPUS_FAST_INT64
-#define silk_SMLAWB(a32, b32, c32) ((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16))
+#define silk_SMLAWB(a32, b32, c32) ((opus_int32)((a32) + (((b32) * (opus_int64)((opus_int16)(c32))) >> 16)))
#else
#define silk_SMLAWB(a32, b32, c32) ((a32) + ((((b32) >> 16) * (opus_int32)((opus_int16)(c32))) + ((((b32) & 0x0000FFFF) * (opus_int32)((opus_int16)(c32))) >> 16)))
#endif
/* (a32 * (b32 >> 16)) >> 16 */
+#if OPUS_FAST_INT64
+#define silk_SMULWT(a32, b32) ((opus_int32)(((a32) * (opus_int64)((b32) >> 16)) >> 16))
+#else
#define silk_SMULWT(a32, b32) (((a32) >> 16) * ((b32) >> 16) + ((((a32) & 0x0000FFFF) * ((b32) >> 16)) >> 16))
+#endif
/* a32 + (b32 * (c32 >> 16)) >> 16 */
#if OPUS_FAST_INT64
-#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16))
+#define silk_SMLAWT(a32, b32, c32) ((opus_int32)((a32) + (((b32) * ((opus_int64)(c32) >> 16)) >> 16)))
#else
#define silk_SMLAWT(a32, b32, c32) ((a32) + (((b32) >> 16) * ((c32) >> 16)) + ((((b32) & 0x0000FFFF) * ((c32) >> 16)) >> 16))
#endif
@@ -89,14 +91,14 @@ POSSIBILITY OF SUCH DAMAGE.
/* (a32 * b32) >> 16 */
#if OPUS_FAST_INT64
-#define silk_SMULWW(a32, b32) (((opus_int64)(a32) * (b32)) >> 16)
+#define silk_SMULWW(a32, b32) ((opus_int32)(((opus_int64)(a32) * (b32)) >> 16))
#else
#define silk_SMULWW(a32, b32) silk_MLA(silk_SMULWB((a32), (b32)), (a32), silk_RSHIFT_ROUND((b32), 16))
#endif
/* a32 + ((b32 * c32) >> 16) */
#if OPUS_FAST_INT64
-#define silk_SMLAWW(a32, b32, c32) ((a32) + (((opus_int64)(b32) * (c32)) >> 16))
+#define silk_SMLAWW(a32, b32, c32) ((opus_int32)((a32) + (((opus_int64)(b32) * (c32)) >> 16)))
#else
#define silk_SMLAWW(a32, b32, c32) silk_MLA(silk_SMLAWB((a32), (b32), (c32)), (b32), silk_RSHIFT_ROUND((c32), 16))
#endif
@@ -149,5 +151,9 @@ static OPUS_INLINE opus_int32 silk_CLZ32(opus_int32 in32)
#include "arm/macros_armv5e.h"
#endif
+#ifdef OPUS_ARM_PRESUME_AARCH64_NEON_INTR
+#include "arm/macros_arm64.h"
+#endif
+
#endif /* SILK_MACROS_H */
diff --git a/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h b/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
index f6afd923e8..ad1cfe2a9b 100644
--- a/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
+++ b/thirdparty/opus/silk/mips/NSQ_del_dec_mipsr1.h
@@ -62,7 +62,8 @@ static inline void silk_noise_shape_quantizer_del_dec(
opus_int warping_Q16, /* I */
opus_int nStatesDelayedDecision, /* I Number of states in decision tree */
opus_int *smpl_buf_idx, /* I Index to newest samples in buffers */
- opus_int decisionDelay /* I */
+ opus_int decisionDelay, /* I */
+ int arch /* I */
)
{
opus_int i, j, k, Winner_ind, RDmin_ind, RDmax_ind, last_smple_idx;
@@ -82,6 +83,9 @@ static inline void silk_noise_shape_quantizer_del_dec(
opus_int32 cur, prev, next;
+ /*Unused.*/
+ (void)arch;
+
//Intialize b_Q14 variables
b_Q14_0 = b_Q14[ 0 ];
b_Q14_1 = b_Q14[ 1 ];
diff --git a/thirdparty/opus/silk/process_NLSFs.c b/thirdparty/opus/silk/process_NLSFs.c
index c27cf03046..0ab71f0163 100644
--- a/thirdparty/opus/silk/process_NLSFs.c
+++ b/thirdparty/opus/silk/process_NLSFs.c
@@ -41,7 +41,7 @@ void silk_process_NLSFs(
{
opus_int i, doInterpolate;
opus_int NLSF_mu_Q20;
- opus_int32 i_sqr_Q15;
+ opus_int16 i_sqr_Q15;
opus_int16 pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
opus_int16 pNLSFW_QW[ MAX_LPC_ORDER ];
opus_int16 pNLSFW0_temp_QW[ MAX_LPC_ORDER ];
@@ -79,7 +79,8 @@ void silk_process_NLSFs(
/* Update NLSF weights with contribution from first half */
i_sqr_Q15 = silk_LSHIFT( silk_SMULBB( psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2 ), 11 );
for( i = 0; i < psEncC->predictLPCOrder; i++ ) {
- pNLSFW_QW[ i ] = silk_SMLAWB( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15 );
+ pNLSFW_QW[ i ] = silk_ADD16( silk_RSHIFT( pNLSFW_QW[ i ], 1 ), silk_RSHIFT(
+ silk_SMULBB( pNLSFW0_temp_QW[ i ], i_sqr_Q15 ), 16) );
silk_assert( pNLSFW_QW[ i ] >= 1 );
}
}
@@ -100,6 +101,7 @@ void silk_process_NLSFs(
} else {
/* Copy LPC coefficients for first half from second half */
+ silk_assert( psEncC->predictLPCOrder <= MAX_LPC_ORDER );
silk_memcpy( PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof( opus_int16 ) );
}
}
diff --git a/thirdparty/opus/silk/sort.c b/thirdparty/opus/silk/sort.c
index 8670dbdd02..7187c9efb1 100644
--- a/thirdparty/opus/silk/sort.c
+++ b/thirdparty/opus/silk/sort.c
@@ -33,7 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
/* Best case: O(n) for an already sorted array */
/* Worst case: O(n^2) for an inversely sorted array */
/* */
-/* Shell short: http://en.wikipedia.org/wiki/Shell_sort */
+/* Shell short: https://en.wikipedia.org/wiki/Shell_sort */
#include "SigProc_FIX.h"
diff --git a/thirdparty/opus/silk/stereo_LR_to_MS.c b/thirdparty/opus/silk/stereo_LR_to_MS.c
index 42906e6f67..dda0298de2 100644
--- a/thirdparty/opus/silk/stereo_LR_to_MS.c
+++ b/thirdparty/opus/silk/stereo_LR_to_MS.c
@@ -77,7 +77,7 @@ void silk_stereo_LR_to_MS(
ALLOC( LP_mid, frame_length, opus_int16 );
ALLOC( HP_mid, frame_length, opus_int16 );
for( n = 0; n < frame_length; n++ ) {
- sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
+ sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 2 );
LP_mid[ n ] = sum;
HP_mid[ n ] = mid[ n + 1 ] - sum;
}
@@ -86,7 +86,7 @@ void silk_stereo_LR_to_MS(
ALLOC( LP_side, frame_length, opus_int16 );
ALLOC( HP_side, frame_length, opus_int16 );
for( n = 0; n < frame_length; n++ ) {
- sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
+ sum = silk_RSHIFT_ROUND( silk_ADD_LSHIFT( side[ n ] + (opus_int32)side[ n + 2 ], side[ n + 1 ], 1 ), 2 );
LP_side[ n ] = sum;
HP_side[ n ] = side[ n + 1 ] - sum;
}
@@ -207,7 +207,7 @@ void silk_stereo_LR_to_MS(
pred0_Q13 += delta0_Q13;
pred1_Q13 += delta1_Q13;
w_Q24 += deltaw_Q24;
- sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
+ sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
@@ -217,7 +217,7 @@ void silk_stereo_LR_to_MS(
pred1_Q13 = -pred_Q13[ 1 ];
w_Q24 = silk_LSHIFT( width_Q14, 10 );
for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
- sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
+ sum = silk_LSHIFT( silk_ADD_LSHIFT( mid[ n ] + (opus_int32)mid[ n + 2 ], mid[ n + 1 ], 1 ), 9 ); /* Q11 */
sum = silk_SMLAWB( silk_SMULWB( w_Q24, side[ n + 1 ] ), sum, pred0_Q13 ); /* Q8 */
sum = silk_SMLAWB( sum, silk_LSHIFT( (opus_int32)mid[ n + 1 ], 11 ), pred1_Q13 ); /* Q8 */
x2[ n - 1 ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( sum, 8 ) );
diff --git a/thirdparty/opus/silk/x86/NSQ_sse.c b/thirdparty/opus/silk/x86/NSQ_sse.c
index 72f34fd6fc..bb3c5f1955 100644
--- a/thirdparty/opus/silk/x86/NSQ_sse.c
+++ b/thirdparty/opus/silk/x86/NSQ_sse.c
@@ -221,7 +221,7 @@ void silk_NSQ_sse4_1(
{
silk_noise_shape_quantizer( NSQ, psIndices->signalType, x_sc_Q10, pulses, pxq, sLTP_Q15, A_Q12, B_Q14,
AR_shp_Q13, lag, HarmShapeFIRPacked_Q14, Tilt_Q14[ k ], LF_shp_Q14[ k ], Gains_Q16[ k ], Lambda_Q10,
- offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder );
+ offset_Q10, psEncC->subfr_length, psEncC->shapingLPCOrder, psEncC->predictLPCOrder, psEncC->arch );
}
x_Q3 += psEncC->subfr_length;
diff --git a/thirdparty/opus/silk/x86/main_sse.h b/thirdparty/opus/silk/x86/main_sse.h
index afd5ec26e1..d8d61310ed 100644
--- a/thirdparty/opus/silk/x86/main_sse.h
+++ b/thirdparty/opus/silk/x86/main_sse.h
@@ -207,7 +207,8 @@ void silk_noise_shape_quantizer(
opus_int offset_Q10, /* I */
opus_int length, /* I Input length */
opus_int shapingLPCOrder, /* I Noise shaping AR filter order */
- opus_int predictLPCOrder /* I Prediction filter order */
+ opus_int predictLPCOrder, /* I Prediction filter order */
+ int arch /* I Architecture */
);
/**************************/
diff --git a/thirdparty/rg-etc1/rg_etc1.cpp b/thirdparty/rg-etc1/rg_etc1.cpp
deleted file mode 100644
index 8e28b53f9d..0000000000
--- a/thirdparty/rg-etc1/rg_etc1.cpp
+++ /dev/null
@@ -1,2446 +0,0 @@
-// File: rg_etc1.cpp - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich <richgel99@gmail.com>
-// Please see ZLIB license at the end of rg_etc1.h.
-//
-// For more information Ericsson Texture Compression (ETC/ETC1), see:
-// http://www.khronos.org/registry/gles/extensions/OES/OES_compressed_ETC1_RGB8_texture.txt
-//
-// v1.04 - 5/15/14 - Fix signed vs. unsigned subtraction problem (noticed when compiled with gcc) in pack_etc1_block_init().
-// This issue would cause an assert when this func. was called in debug. (Note this module was developed/testing with MSVC,
-// I still need to test it throughly when compiled with gcc.)
-//
-// v1.03 - 5/12/13 - Initial public release
-#include "rg_etc1.h"
-
-#include <stdlib.h>
-#include <memory.h>
-#include <assert.h>
-//#include <stdio.h>
-#include <math.h>
-
-#pragma warning (disable: 4201) // nonstandard extension used : nameless struct/union
-
-#if defined(_DEBUG) || defined(DEBUG)
-#define RG_ETC1_BUILD_DEBUG
-#endif
-
-#define RG_ETC1_ASSERT assert
-
-namespace rg_etc1
-{
- typedef unsigned char uint8;
- typedef unsigned short uint16;
- typedef unsigned int uint;
- typedef unsigned int uint32;
- typedef long long int64;
- typedef unsigned long long uint64;
-
- const uint32 cUINT32_MAX = 0xFFFFFFFFU;
- const uint64 cUINT64_MAX = 0xFFFFFFFFFFFFFFFFULL; //0xFFFFFFFFFFFFFFFFui64;
-
- template<typename T> inline T minimum(T a, T b) { return (a < b) ? a : b; }
- template<typename T> inline T minimum(T a, T b, T c) { return minimum(minimum(a, b), c); }
- template<typename T> inline T maximum(T a, T b) { return (a > b) ? a : b; }
- template<typename T> inline T maximum(T a, T b, T c) { return maximum(maximum(a, b), c); }
- template<typename T> inline T clamp(T value, T low, T high) { return (value < low) ? low : ((value > high) ? high : value); }
- template<typename T> inline T square(T value) { return value * value; }
- template<typename T> inline void zero_object(T& obj) { memset((void*)&obj, 0, sizeof(obj)); }
- template<typename T> inline void zero_this(T* pObj) { memset((void*)pObj, 0, sizeof(*pObj)); }
-
- template<class T, size_t N> T decay_array_to_subtype(T (&a)[N]);
-
-#define RG_ETC1_ARRAY_SIZE(X) (sizeof(X) / sizeof(decay_array_to_subtype(X)))
-
- enum eNoClamp { cNoClamp };
-
- struct color_quad_u8
- {
- static inline int clamp(int v) { if (v & 0xFFFFFF00U) v = (~(static_cast<int>(v) >> 31)) & 0xFF; return v; }
-
- struct component_traits { enum { cSigned = false, cFloat = false, cMin = 0U, cMax = 255U }; };
-
- public:
- typedef unsigned char component_t;
- typedef int parameter_t;
-
- enum { cNumComps = 4 };
-
- union
- {
- struct
- {
- component_t r;
- component_t g;
- component_t b;
- component_t a;
- };
-
- component_t c[cNumComps];
-
- uint32 m_u32;
- };
-
- inline color_quad_u8()
- {
- }
-
- inline color_quad_u8(const color_quad_u8& other) : m_u32(other.m_u32)
- {
- }
-
- explicit inline color_quad_u8(parameter_t y, parameter_t alpha = component_traits::cMax)
- {
- set(y, alpha);
- }
-
- inline color_quad_u8(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax)
- {
- set(red, green, blue, alpha);
- }
-
- explicit inline color_quad_u8(eNoClamp, parameter_t y, parameter_t alpha = component_traits::cMax)
- {
- set_noclamp_y_alpha(y, alpha);
- }
-
- inline color_quad_u8(eNoClamp, parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax)
- {
- set_noclamp_rgba(red, green, blue, alpha);
- }
-
- inline void clear()
- {
- m_u32 = 0;
- }
-
- inline color_quad_u8& operator= (const color_quad_u8& other)
- {
- m_u32 = other.m_u32;
- return *this;
- }
-
- inline color_quad_u8& set_rgb(const color_quad_u8& other)
- {
- r = other.r;
- g = other.g;
- b = other.b;
- return *this;
- }
-
- inline color_quad_u8& operator= (parameter_t y)
- {
- set(y, component_traits::cMax);
- return *this;
- }
-
- inline color_quad_u8& set(parameter_t y, parameter_t alpha = component_traits::cMax)
- {
- y = clamp(y);
- alpha = clamp(alpha);
- r = static_cast<component_t>(y);
- g = static_cast<component_t>(y);
- b = static_cast<component_t>(y);
- a = static_cast<component_t>(alpha);
- return *this;
- }
-
- inline color_quad_u8& set_noclamp_y_alpha(parameter_t y, parameter_t alpha = component_traits::cMax)
- {
- RG_ETC1_ASSERT( (y >= component_traits::cMin) && (y <= component_traits::cMax) );
- RG_ETC1_ASSERT( (alpha >= component_traits::cMin) && (alpha <= component_traits::cMax) );
-
- r = static_cast<component_t>(y);
- g = static_cast<component_t>(y);
- b = static_cast<component_t>(y);
- a = static_cast<component_t>(alpha);
- return *this;
- }
-
- inline color_quad_u8& set(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha = component_traits::cMax)
- {
- r = static_cast<component_t>(clamp(red));
- g = static_cast<component_t>(clamp(green));
- b = static_cast<component_t>(clamp(blue));
- a = static_cast<component_t>(clamp(alpha));
- return *this;
- }
-
- inline color_quad_u8& set_noclamp_rgba(parameter_t red, parameter_t green, parameter_t blue, parameter_t alpha)
- {
- RG_ETC1_ASSERT( (red >= component_traits::cMin) && (red <= component_traits::cMax) );
- RG_ETC1_ASSERT( (green >= component_traits::cMin) && (green <= component_traits::cMax) );
- RG_ETC1_ASSERT( (blue >= component_traits::cMin) && (blue <= component_traits::cMax) );
- RG_ETC1_ASSERT( (alpha >= component_traits::cMin) && (alpha <= component_traits::cMax) );
-
- r = static_cast<component_t>(red);
- g = static_cast<component_t>(green);
- b = static_cast<component_t>(blue);
- a = static_cast<component_t>(alpha);
- return *this;
- }
-
- inline color_quad_u8& set_noclamp_rgb(parameter_t red, parameter_t green, parameter_t blue)
- {
- RG_ETC1_ASSERT( (red >= component_traits::cMin) && (red <= component_traits::cMax) );
- RG_ETC1_ASSERT( (green >= component_traits::cMin) && (green <= component_traits::cMax) );
- RG_ETC1_ASSERT( (blue >= component_traits::cMin) && (blue <= component_traits::cMax) );
-
- r = static_cast<component_t>(red);
- g = static_cast<component_t>(green);
- b = static_cast<component_t>(blue);
- return *this;
- }
-
- static inline parameter_t get_min_comp() { return component_traits::cMin; }
- static inline parameter_t get_max_comp() { return component_traits::cMax; }
- static inline bool get_comps_are_signed() { return component_traits::cSigned; }
-
- inline component_t operator[] (uint i) const { RG_ETC1_ASSERT(i < cNumComps); return c[i]; }
- inline component_t& operator[] (uint i) { RG_ETC1_ASSERT(i < cNumComps); return c[i]; }
-
- inline color_quad_u8& set_component(uint i, parameter_t f)
- {
- RG_ETC1_ASSERT(i < cNumComps);
-
- c[i] = static_cast<component_t>(clamp(f));
-
- return *this;
- }
-
- inline color_quad_u8& set_grayscale(parameter_t l)
- {
- component_t x = static_cast<component_t>(clamp(l));
- c[0] = x;
- c[1] = x;
- c[2] = x;
- return *this;
- }
-
- inline color_quad_u8& clamp(const color_quad_u8& l, const color_quad_u8& h)
- {
- for (uint i = 0; i < cNumComps; i++)
- c[i] = static_cast<component_t>(rg_etc1::clamp<parameter_t>(c[i], l[i], h[i]));
- return *this;
- }
-
- inline color_quad_u8& clamp(parameter_t l, parameter_t h)
- {
- for (uint i = 0; i < cNumComps; i++)
- c[i] = static_cast<component_t>(rg_etc1::clamp<parameter_t>(c[i], l, h));
- return *this;
- }
-
- // Returns CCIR 601 luma (consistent with color_utils::RGB_To_Y).
- inline parameter_t get_luma() const
- {
- return static_cast<parameter_t>((19595U * r + 38470U * g + 7471U * b + 32768U) >> 16U);
- }
-
- // Returns REC 709 luma.
- inline parameter_t get_luma_rec709() const
- {
- return static_cast<parameter_t>((13938U * r + 46869U * g + 4729U * b + 32768U) >> 16U);
- }
-
- inline uint squared_distance_rgb(const color_quad_u8& c) const
- {
- return rg_etc1::square(r - c.r) + rg_etc1::square(g - c.g) + rg_etc1::square(b - c.b);
- }
-
- inline uint squared_distance_rgba(const color_quad_u8& c) const
- {
- return rg_etc1::square(r - c.r) + rg_etc1::square(g - c.g) + rg_etc1::square(b - c.b) + rg_etc1::square(a - c.a);
- }
-
- inline bool rgb_equals(const color_quad_u8& rhs) const
- {
- return (r == rhs.r) && (g == rhs.g) && (b == rhs.b);
- }
-
- inline bool operator== (const color_quad_u8& rhs) const
- {
- return m_u32 == rhs.m_u32;
- }
-
- color_quad_u8& operator+= (const color_quad_u8& other)
- {
- for (uint i = 0; i < 4; i++)
- c[i] = static_cast<component_t>(clamp(c[i] + other.c[i]));
- return *this;
- }
-
- color_quad_u8& operator-= (const color_quad_u8& other)
- {
- for (uint i = 0; i < 4; i++)
- c[i] = static_cast<component_t>(clamp(c[i] - other.c[i]));
- return *this;
- }
-
- friend color_quad_u8 operator+ (const color_quad_u8& lhs, const color_quad_u8& rhs)
- {
- color_quad_u8 result(lhs);
- result += rhs;
- return result;
- }
-
- friend color_quad_u8 operator- (const color_quad_u8& lhs, const color_quad_u8& rhs)
- {
- color_quad_u8 result(lhs);
- result -= rhs;
- return result;
- }
- }; // class color_quad_u8
-
- struct vec3F
- {
- float m_s[3];
-
- inline vec3F() { }
- inline vec3F(float s) { m_s[0] = s; m_s[1] = s; m_s[2] = s; }
- inline vec3F(float x, float y, float z) { m_s[0] = x; m_s[1] = y; m_s[2] = z; }
-
- inline float operator[] (uint i) const { RG_ETC1_ASSERT(i < 3); return m_s[i]; }
-
- inline vec3F& operator += (const vec3F& other) { for (uint i = 0; i < 3; i++) m_s[i] += other.m_s[i]; return *this; }
-
- inline vec3F& operator *= (float s) { for (uint i = 0; i < 3; i++) m_s[i] *= s; return *this; }
- };
-
- enum etc_constants
- {
- cETC1BytesPerBlock = 8U,
-
- cETC1SelectorBits = 2U,
- cETC1SelectorValues = 1U << cETC1SelectorBits,
- cETC1SelectorMask = cETC1SelectorValues - 1U,
-
- cETC1BlockShift = 2U,
- cETC1BlockSize = 1U << cETC1BlockShift,
-
- cETC1LSBSelectorIndicesBitOffset = 0,
- cETC1MSBSelectorIndicesBitOffset = 16,
-
- cETC1FlipBitOffset = 32,
- cETC1DiffBitOffset = 33,
-
- cETC1IntenModifierNumBits = 3,
- cETC1IntenModifierValues = 1 << cETC1IntenModifierNumBits,
- cETC1RightIntenModifierTableBitOffset = 34,
- cETC1LeftIntenModifierTableBitOffset = 37,
-
- // Base+Delta encoding (5 bit bases, 3 bit delta)
- cETC1BaseColorCompNumBits = 5,
- cETC1BaseColorCompMax = 1 << cETC1BaseColorCompNumBits,
-
- cETC1DeltaColorCompNumBits = 3,
- cETC1DeltaColorComp = 1 << cETC1DeltaColorCompNumBits,
- cETC1DeltaColorCompMax = 1 << cETC1DeltaColorCompNumBits,
-
- cETC1BaseColor5RBitOffset = 59,
- cETC1BaseColor5GBitOffset = 51,
- cETC1BaseColor5BBitOffset = 43,
-
- cETC1DeltaColor3RBitOffset = 56,
- cETC1DeltaColor3GBitOffset = 48,
- cETC1DeltaColor3BBitOffset = 40,
-
- // Absolute (non-delta) encoding (two 4-bit per component bases)
- cETC1AbsColorCompNumBits = 4,
- cETC1AbsColorCompMax = 1 << cETC1AbsColorCompNumBits,
-
- cETC1AbsColor4R1BitOffset = 60,
- cETC1AbsColor4G1BitOffset = 52,
- cETC1AbsColor4B1BitOffset = 44,
-
- cETC1AbsColor4R2BitOffset = 56,
- cETC1AbsColor4G2BitOffset = 48,
- cETC1AbsColor4B2BitOffset = 40,
-
- cETC1ColorDeltaMin = -4,
- cETC1ColorDeltaMax = 3,
-
- // Delta3:
- // 0 1 2 3 4 5 6 7
- // 000 001 010 011 100 101 110 111
- // 0 1 2 3 -4 -3 -2 -1
- };
-
- static uint8 g_quant5_tab[256+16];
-
- static const int g_etc1_inten_tables[cETC1IntenModifierValues][cETC1SelectorValues] =
- {
- { -8, -2, 2, 8 }, { -17, -5, 5, 17 }, { -29, -9, 9, 29 }, { -42, -13, 13, 42 },
- { -60, -18, 18, 60 }, { -80, -24, 24, 80 }, { -106, -33, 33, 106 }, { -183, -47, 47, 183 }
- };
-
- static const uint8 g_etc1_to_selector_index[cETC1SelectorValues] = { 2, 3, 1, 0 };
- static const uint8 g_selector_index_to_etc1[cETC1SelectorValues] = { 3, 2, 0, 1 };
-
- // Given an ETC1 diff/inten_table/selector, and an 8-bit desired color, this table encodes the best packed_color in the low byte, and the abs error in the high byte.
- static uint16 g_etc1_inverse_lookup[2*8*4][256]; // [diff/inten_table/selector][desired_color]
-
- // g_color8_to_etc_block_config[color][table_index] = Supplies for each 8-bit color value a list of packed ETC1 diff/intensity table/selectors/packed_colors that map to that color.
- // To pack: diff | (inten << 1) | (selector << 4) | (packed_c << 8)
- static const uint16 g_color8_to_etc_block_config_0_255[2][33] =
- {
- { 0x0000, 0x0010, 0x0002, 0x0012, 0x0004, 0x0014, 0x0006, 0x0016, 0x0008, 0x0018, 0x000A, 0x001A, 0x000C, 0x001C, 0x000E, 0x001E,
- 0x0001, 0x0011, 0x0003, 0x0013, 0x0005, 0x0015, 0x0007, 0x0017, 0x0009, 0x0019, 0x000B, 0x001B, 0x000D, 0x001D, 0x000F, 0x001F, 0xFFFF },
- { 0x0F20, 0x0F30, 0x0E32, 0x0F22, 0x0E34, 0x0F24, 0x0D36, 0x0F26, 0x0C38, 0x0E28, 0x0B3A, 0x0E2A, 0x093C, 0x0E2C, 0x053E, 0x0D2E,
- 0x1E31, 0x1F21, 0x1D33, 0x1F23, 0x1C35, 0x1E25, 0x1A37, 0x1E27, 0x1839, 0x1D29, 0x163B, 0x1C2B, 0x133D, 0x1B2D, 0x093F, 0x1A2F, 0xFFFF },
- };
-
- // Really only [254][11].
- static const uint16 g_color8_to_etc_block_config_1_to_254[254][12] =
- {
- { 0x021C, 0x0D0D, 0xFFFF }, { 0x0020, 0x0021, 0x0A0B, 0x061F, 0xFFFF }, { 0x0113, 0x0217, 0xFFFF }, { 0x0116, 0x031E,
- 0x0B0E, 0x0405, 0xFFFF }, { 0x0022, 0x0204, 0x050A, 0x0023, 0xFFFF }, { 0x0111, 0x0319, 0x0809, 0x170F, 0xFFFF }, {
- 0x0303, 0x0215, 0x0607, 0xFFFF }, { 0x0030, 0x0114, 0x0408, 0x0031, 0x0201, 0x051D, 0xFFFF }, { 0x0100, 0x0024, 0x0306,
- 0x0025, 0x041B, 0x0E0D, 0xFFFF }, { 0x021A, 0x0121, 0x0B0B, 0x071F, 0xFFFF }, { 0x0213, 0x0317, 0xFFFF }, { 0x0112,
- 0x0505, 0xFFFF }, { 0x0026, 0x070C, 0x0123, 0x0027, 0xFFFF }, { 0x0211, 0x0909, 0xFFFF }, { 0x0110, 0x0315, 0x0707,
- 0x0419, 0x180F, 0xFFFF }, { 0x0218, 0x0131, 0x0301, 0x0403, 0x061D, 0xFFFF }, { 0x0032, 0x0202, 0x0033, 0x0125, 0x051B,
- 0x0F0D, 0xFFFF }, { 0x0028, 0x031C, 0x0221, 0x0029, 0xFFFF }, { 0x0120, 0x0313, 0x0C0B, 0x081F, 0xFFFF }, { 0x0605,
- 0x0417, 0xFFFF }, { 0x0216, 0x041E, 0x0C0E, 0x0223, 0x0127, 0xFFFF }, { 0x0122, 0x0304, 0x060A, 0x0311, 0x0A09, 0xFFFF
- }, { 0x0519, 0x190F, 0xFFFF }, { 0x002A, 0x0231, 0x0503, 0x0415, 0x0807, 0x002B, 0x071D, 0xFFFF }, { 0x0130, 0x0214,
- 0x0508, 0x0401, 0x0133, 0x0225, 0x061B, 0xFFFF }, { 0x0200, 0x0124, 0x0406, 0x0321, 0x0129, 0x100D, 0xFFFF }, { 0x031A,
- 0x0D0B, 0x091F, 0xFFFF }, { 0x0413, 0x0705, 0x0517, 0xFFFF }, { 0x0212, 0x0034, 0x0323, 0x0035, 0x0227, 0xFFFF }, {
- 0x0126, 0x080C, 0x0B09, 0xFFFF }, { 0x0411, 0x0619, 0x1A0F, 0xFFFF }, { 0x0210, 0x0331, 0x0603, 0x0515, 0x0907, 0x012B,
- 0xFFFF }, { 0x0318, 0x002C, 0x0501, 0x0233, 0x0325, 0x071B, 0x002D, 0x081D, 0xFFFF }, { 0x0132, 0x0302, 0x0229, 0x110D,
- 0xFFFF }, { 0x0128, 0x041C, 0x0421, 0x0E0B, 0x0A1F, 0xFFFF }, { 0x0220, 0x0513, 0x0617, 0xFFFF }, { 0x0135, 0x0805,
- 0x0327, 0xFFFF }, { 0x0316, 0x051E, 0x0D0E, 0x0423, 0xFFFF }, { 0x0222, 0x0404, 0x070A, 0x0511, 0x0719, 0x0C09, 0x1B0F,
- 0xFFFF }, { 0x0703, 0x0615, 0x0A07, 0x022B, 0xFFFF }, { 0x012A, 0x0431, 0x0601, 0x0333, 0x012D, 0x091D, 0xFFFF }, {
- 0x0230, 0x0314, 0x0036, 0x0608, 0x0425, 0x0037, 0x0329, 0x081B, 0x120D, 0xFFFF }, { 0x0300, 0x0224, 0x0506, 0x0521,
- 0x0F0B, 0x0B1F, 0xFFFF }, { 0x041A, 0x0613, 0x0717, 0xFFFF }, { 0x0235, 0x0905, 0xFFFF }, { 0x0312, 0x0134, 0x0523,
- 0x0427, 0xFFFF }, { 0x0226, 0x090C, 0x002E, 0x0611, 0x0D09, 0x002F, 0xFFFF }, { 0x0715, 0x0B07, 0x0819, 0x032B, 0x1C0F,
- 0xFFFF }, { 0x0310, 0x0531, 0x0701, 0x0803, 0x022D, 0x0A1D, 0xFFFF }, { 0x0418, 0x012C, 0x0433, 0x0525, 0x0137, 0x091B,
- 0x130D, 0xFFFF }, { 0x0232, 0x0402, 0x0621, 0x0429, 0xFFFF }, { 0x0228, 0x051C, 0x0713, 0x100B, 0x0C1F, 0xFFFF }, {
- 0x0320, 0x0335, 0x0A05, 0x0817, 0xFFFF }, { 0x0623, 0x0527, 0xFFFF }, { 0x0416, 0x061E, 0x0E0E, 0x0711, 0x0E09, 0x012F,
- 0xFFFF }, { 0x0322, 0x0504, 0x080A, 0x0919, 0x1D0F, 0xFFFF }, { 0x0631, 0x0903, 0x0815, 0x0C07, 0x042B, 0x032D, 0x0B1D,
- 0xFFFF }, { 0x022A, 0x0801, 0x0533, 0x0625, 0x0237, 0x0A1B, 0xFFFF }, { 0x0330, 0x0414, 0x0136, 0x0708, 0x0721, 0x0529,
- 0x140D, 0xFFFF }, { 0x0400, 0x0324, 0x0606, 0x0038, 0x0039, 0x110B, 0x0D1F, 0xFFFF }, { 0x051A, 0x0813, 0x0B05, 0x0917,
- 0xFFFF }, { 0x0723, 0x0435, 0x0627, 0xFFFF }, { 0x0412, 0x0234, 0x0F09, 0x022F, 0xFFFF }, { 0x0326, 0x0A0C, 0x012E,
- 0x0811, 0x0A19, 0x1E0F, 0xFFFF }, { 0x0731, 0x0A03, 0x0915, 0x0D07, 0x052B, 0xFFFF }, { 0x0410, 0x0901, 0x0633, 0x0725,
- 0x0337, 0x0B1B, 0x042D, 0x0C1D, 0xFFFF }, { 0x0518, 0x022C, 0x0629, 0x150D, 0xFFFF }, { 0x0332, 0x0502, 0x0821, 0x0139,
- 0x120B, 0x0E1F, 0xFFFF }, { 0x0328, 0x061C, 0x0913, 0x0A17, 0xFFFF }, { 0x0420, 0x0535, 0x0C05, 0x0727, 0xFFFF }, {
- 0x0823, 0x032F, 0xFFFF }, { 0x0516, 0x071E, 0x0F0E, 0x0911, 0x0B19, 0x1009, 0x1F0F, 0xFFFF }, { 0x0422, 0x0604, 0x090A,
- 0x0B03, 0x0A15, 0x0E07, 0x062B, 0xFFFF }, { 0x0831, 0x0A01, 0x0733, 0x052D, 0x0D1D, 0xFFFF }, { 0x032A, 0x0825, 0x0437,
- 0x0729, 0x0C1B, 0x160D, 0xFFFF }, { 0x0430, 0x0514, 0x0236, 0x0808, 0x0921, 0x0239, 0x130B, 0x0F1F, 0xFFFF }, { 0x0500,
- 0x0424, 0x0706, 0x0138, 0x0A13, 0x0B17, 0xFFFF }, { 0x061A, 0x0635, 0x0D05, 0xFFFF }, { 0x0923, 0x0827, 0xFFFF }, {
- 0x0512, 0x0334, 0x003A, 0x0A11, 0x1109, 0x003B, 0x042F, 0xFFFF }, { 0x0426, 0x0B0C, 0x022E, 0x0B15, 0x0F07, 0x0C19,
- 0x072B, 0xFFFF }, { 0x0931, 0x0B01, 0x0C03, 0x062D, 0x0E1D, 0xFFFF }, { 0x0510, 0x0833, 0x0925, 0x0537, 0x0D1B, 0x170D,
- 0xFFFF }, { 0x0618, 0x032C, 0x0A21, 0x0339, 0x0829, 0xFFFF }, { 0x0432, 0x0602, 0x0B13, 0x140B, 0x101F, 0xFFFF }, {
- 0x0428, 0x071C, 0x0735, 0x0E05, 0x0C17, 0xFFFF }, { 0x0520, 0x0A23, 0x0927, 0xFFFF }, { 0x0B11, 0x1209, 0x013B, 0x052F,
- 0xFFFF }, { 0x0616, 0x081E, 0x0D19, 0xFFFF }, { 0x0522, 0x0704, 0x0A0A, 0x0A31, 0x0D03, 0x0C15, 0x1007, 0x082B, 0x072D,
- 0x0F1D, 0xFFFF }, { 0x0C01, 0x0933, 0x0A25, 0x0637, 0x0E1B, 0xFFFF }, { 0x042A, 0x0B21, 0x0929, 0x180D, 0xFFFF }, {
- 0x0530, 0x0614, 0x0336, 0x0908, 0x0439, 0x150B, 0x111F, 0xFFFF }, { 0x0600, 0x0524, 0x0806, 0x0238, 0x0C13, 0x0F05,
- 0x0D17, 0xFFFF }, { 0x071A, 0x0B23, 0x0835, 0x0A27, 0xFFFF }, { 0x1309, 0x023B, 0x062F, 0xFFFF }, { 0x0612, 0x0434,
- 0x013A, 0x0C11, 0x0E19, 0xFFFF }, { 0x0526, 0x0C0C, 0x032E, 0x0B31, 0x0E03, 0x0D15, 0x1107, 0x092B, 0xFFFF }, { 0x0D01,
- 0x0A33, 0x0B25, 0x0737, 0x0F1B, 0x082D, 0x101D, 0xFFFF }, { 0x0610, 0x0A29, 0x190D, 0xFFFF }, { 0x0718, 0x042C, 0x0C21,
- 0x0539, 0x160B, 0x121F, 0xFFFF }, { 0x0532, 0x0702, 0x0D13, 0x0E17, 0xFFFF }, { 0x0528, 0x081C, 0x0935, 0x1005, 0x0B27,
- 0xFFFF }, { 0x0620, 0x0C23, 0x033B, 0x072F, 0xFFFF }, { 0x0D11, 0x0F19, 0x1409, 0xFFFF }, { 0x0716, 0x003C, 0x091E,
- 0x0F03, 0x0E15, 0x1207, 0x0A2B, 0x003D, 0xFFFF }, { 0x0622, 0x0804, 0x0B0A, 0x0C31, 0x0E01, 0x0B33, 0x092D, 0x111D,
- 0xFFFF }, { 0x0C25, 0x0837, 0x0B29, 0x101B, 0x1A0D, 0xFFFF }, { 0x052A, 0x0D21, 0x0639, 0x170B, 0x131F, 0xFFFF }, {
- 0x0630, 0x0714, 0x0436, 0x0A08, 0x0E13, 0x0F17, 0xFFFF }, { 0x0700, 0x0624, 0x0906, 0x0338, 0x0A35, 0x1105, 0xFFFF }, {
- 0x081A, 0x0D23, 0x0C27, 0xFFFF }, { 0x0E11, 0x1509, 0x043B, 0x082F, 0xFFFF }, { 0x0712, 0x0534, 0x023A, 0x0F15, 0x1307,
- 0x1019, 0x0B2B, 0x013D, 0xFFFF }, { 0x0626, 0x0D0C, 0x042E, 0x0D31, 0x0F01, 0x1003, 0x0A2D, 0x121D, 0xFFFF }, { 0x0C33,
- 0x0D25, 0x0937, 0x111B, 0x1B0D, 0xFFFF }, { 0x0710, 0x0E21, 0x0739, 0x0C29, 0xFFFF }, { 0x0818, 0x052C, 0x0F13, 0x180B,
- 0x141F, 0xFFFF }, { 0x0632, 0x0802, 0x0B35, 0x1205, 0x1017, 0xFFFF }, { 0x0628, 0x091C, 0x0E23, 0x0D27, 0xFFFF }, {
- 0x0720, 0x0F11, 0x1609, 0x053B, 0x092F, 0xFFFF }, { 0x1119, 0x023D, 0xFFFF }, { 0x0816, 0x013C, 0x0A1E, 0x0E31, 0x1103,
- 0x1015, 0x1407, 0x0C2B, 0x0B2D, 0x131D, 0xFFFF }, { 0x0722, 0x0904, 0x0C0A, 0x1001, 0x0D33, 0x0E25, 0x0A37, 0x121B,
- 0xFFFF }, { 0x0F21, 0x0D29, 0x1C0D, 0xFFFF }, { 0x062A, 0x0839, 0x190B, 0x151F, 0xFFFF }, { 0x0730, 0x0814, 0x0536,
- 0x0B08, 0x1013, 0x1305, 0x1117, 0xFFFF }, { 0x0800, 0x0724, 0x0A06, 0x0438, 0x0F23, 0x0C35, 0x0E27, 0xFFFF }, { 0x091A,
- 0x1709, 0x063B, 0x0A2F, 0xFFFF }, { 0x1011, 0x1219, 0x033D, 0xFFFF }, { 0x0812, 0x0634, 0x033A, 0x0F31, 0x1203, 0x1115,
- 0x1507, 0x0D2B, 0xFFFF }, { 0x0726, 0x0E0C, 0x052E, 0x1101, 0x0E33, 0x0F25, 0x0B37, 0x131B, 0x0C2D, 0x141D, 0xFFFF }, {
- 0x0E29, 0x1D0D, 0xFFFF }, { 0x0810, 0x1021, 0x0939, 0x1A0B, 0x161F, 0xFFFF }, { 0x0918, 0x062C, 0x1113, 0x1217, 0xFFFF
- }, { 0x0732, 0x0902, 0x0D35, 0x1405, 0x0F27, 0xFFFF }, { 0x0728, 0x0A1C, 0x1023, 0x073B, 0x0B2F, 0xFFFF }, { 0x0820,
- 0x1111, 0x1319, 0x1809, 0xFFFF }, { 0x1303, 0x1215, 0x1607, 0x0E2B, 0x043D, 0xFFFF }, { 0x0916, 0x023C, 0x0B1E, 0x1031,
- 0x1201, 0x0F33, 0x0D2D, 0x151D, 0xFFFF }, { 0x0822, 0x0A04, 0x0D0A, 0x1025, 0x0C37, 0x0F29, 0x141B, 0x1E0D, 0xFFFF }, {
- 0x1121, 0x0A39, 0x1B0B, 0x171F, 0xFFFF }, { 0x072A, 0x1213, 0x1317, 0xFFFF }, { 0x0830, 0x0914, 0x0636, 0x0C08, 0x0E35,
- 0x1505, 0xFFFF }, { 0x0900, 0x0824, 0x0B06, 0x0538, 0x1123, 0x1027, 0xFFFF }, { 0x0A1A, 0x1211, 0x1909, 0x083B, 0x0C2F,
- 0xFFFF }, { 0x1315, 0x1707, 0x1419, 0x0F2B, 0x053D, 0xFFFF }, { 0x0912, 0x0734, 0x043A, 0x1131, 0x1301, 0x1403, 0x0E2D,
- 0x161D, 0xFFFF }, { 0x0826, 0x0F0C, 0x062E, 0x1033, 0x1125, 0x0D37, 0x151B, 0x1F0D, 0xFFFF }, { 0x1221, 0x0B39, 0x1029,
- 0xFFFF }, { 0x0910, 0x1313, 0x1C0B, 0x181F, 0xFFFF }, { 0x0A18, 0x072C, 0x0F35, 0x1605, 0x1417, 0xFFFF }, { 0x0832,
- 0x0A02, 0x1223, 0x1127, 0xFFFF }, { 0x0828, 0x0B1C, 0x1311, 0x1A09, 0x093B, 0x0D2F, 0xFFFF }, { 0x0920, 0x1519, 0x063D,
- 0xFFFF }, { 0x1231, 0x1503, 0x1415, 0x1807, 0x102B, 0x0F2D, 0x171D, 0xFFFF }, { 0x0A16, 0x033C, 0x0C1E, 0x1401, 0x1133,
- 0x1225, 0x0E37, 0x161B, 0xFFFF }, { 0x0922, 0x0B04, 0x0E0A, 0x1321, 0x1129, 0xFFFF }, { 0x0C39, 0x1D0B, 0x191F, 0xFFFF
- }, { 0x082A, 0x1413, 0x1705, 0x1517, 0xFFFF }, { 0x0930, 0x0A14, 0x0736, 0x0D08, 0x1323, 0x1035, 0x1227, 0xFFFF }, {
- 0x0A00, 0x0924, 0x0C06, 0x0638, 0x1B09, 0x0A3B, 0x0E2F, 0xFFFF }, { 0x0B1A, 0x1411, 0x1619, 0x073D, 0xFFFF }, { 0x1331,
- 0x1603, 0x1515, 0x1907, 0x112B, 0xFFFF }, { 0x0A12, 0x0834, 0x053A, 0x1501, 0x1233, 0x1325, 0x0F37, 0x171B, 0x102D,
- 0x181D, 0xFFFF }, { 0x0926, 0x072E, 0x1229, 0xFFFF }, { 0x1421, 0x0D39, 0x1E0B, 0x1A1F, 0xFFFF }, { 0x0A10, 0x1513,
- 0x1617, 0xFFFF }, { 0x0B18, 0x082C, 0x1135, 0x1805, 0x1327, 0xFFFF }, { 0x0932, 0x0B02, 0x1423, 0x0B3B, 0x0F2F, 0xFFFF
- }, { 0x0928, 0x0C1C, 0x1511, 0x1719, 0x1C09, 0xFFFF }, { 0x0A20, 0x1703, 0x1615, 0x1A07, 0x122B, 0x083D, 0xFFFF }, {
- 0x1431, 0x1601, 0x1333, 0x112D, 0x191D, 0xFFFF }, { 0x0B16, 0x043C, 0x0D1E, 0x1425, 0x1037, 0x1329, 0x181B, 0xFFFF }, {
- 0x0A22, 0x0C04, 0x0F0A, 0x1521, 0x0E39, 0x1F0B, 0x1B1F, 0xFFFF }, { 0x1613, 0x1717, 0xFFFF }, { 0x092A, 0x1235, 0x1905,
- 0xFFFF }, { 0x0A30, 0x0B14, 0x0836, 0x0E08, 0x1523, 0x1427, 0xFFFF }, { 0x0B00, 0x0A24, 0x0D06, 0x0738, 0x1611, 0x1D09,
- 0x0C3B, 0x102F, 0xFFFF }, { 0x0C1A, 0x1715, 0x1B07, 0x1819, 0x132B, 0x093D, 0xFFFF }, { 0x1531, 0x1701, 0x1803, 0x122D,
- 0x1A1D, 0xFFFF }, { 0x0B12, 0x0934, 0x063A, 0x1433, 0x1525, 0x1137, 0x191B, 0xFFFF }, { 0x0A26, 0x003E, 0x082E, 0x1621,
- 0x0F39, 0x1429, 0x003F, 0xFFFF }, { 0x1713, 0x1C1F, 0xFFFF }, { 0x0B10, 0x1335, 0x1A05, 0x1817, 0xFFFF }, { 0x0C18,
- 0x092C, 0x1623, 0x1527, 0xFFFF }, { 0x0A32, 0x0C02, 0x1711, 0x1E09, 0x0D3B, 0x112F, 0xFFFF }, { 0x0A28, 0x0D1C, 0x1919,
- 0x0A3D, 0xFFFF }, { 0x0B20, 0x1631, 0x1903, 0x1815, 0x1C07, 0x142B, 0x132D, 0x1B1D, 0xFFFF }, { 0x1801, 0x1533, 0x1625,
- 0x1237, 0x1A1B, 0xFFFF }, { 0x0C16, 0x053C, 0x0E1E, 0x1721, 0x1529, 0x013F, 0xFFFF }, { 0x0B22, 0x0D04, 0x1039, 0x1D1F,
- 0xFFFF }, { 0x1813, 0x1B05, 0x1917, 0xFFFF }, { 0x0A2A, 0x1723, 0x1435, 0x1627, 0xFFFF }, { 0x0B30, 0x0C14, 0x0936,
- 0x0F08, 0x1F09, 0x0E3B, 0x122F, 0xFFFF }, { 0x0C00, 0x0B24, 0x0E06, 0x0838, 0x1811, 0x1A19, 0x0B3D, 0xFFFF }, { 0x0D1A,
- 0x1731, 0x1A03, 0x1915, 0x1D07, 0x152B, 0xFFFF }, { 0x1901, 0x1633, 0x1725, 0x1337, 0x1B1B, 0x142D, 0x1C1D, 0xFFFF }, {
- 0x0C12, 0x0A34, 0x073A, 0x1629, 0x023F, 0xFFFF }, { 0x0B26, 0x013E, 0x092E, 0x1821, 0x1139, 0x1E1F, 0xFFFF }, { 0x1913,
- 0x1A17, 0xFFFF }, { 0x0C10, 0x1535, 0x1C05, 0x1727, 0xFFFF }, { 0x0D18, 0x0A2C, 0x1823, 0x0F3B, 0x132F, 0xFFFF }, {
- 0x0B32, 0x0D02, 0x1911, 0x1B19, 0xFFFF }, { 0x0B28, 0x0E1C, 0x1B03, 0x1A15, 0x1E07, 0x162B, 0x0C3D, 0xFFFF }, { 0x0C20,
- 0x1831, 0x1A01, 0x1733, 0x152D, 0x1D1D, 0xFFFF }, { 0x1825, 0x1437, 0x1729, 0x1C1B, 0x033F, 0xFFFF }, { 0x0D16, 0x063C,
- 0x0F1E, 0x1921, 0x1239, 0x1F1F, 0xFFFF }, { 0x0C22, 0x0E04, 0x1A13, 0x1B17, 0xFFFF }, { 0x1635, 0x1D05, 0xFFFF }, {
- 0x0B2A, 0x1923, 0x1827, 0xFFFF }, { 0x0C30, 0x0D14, 0x0A36, 0x1A11, 0x103B, 0x142F, 0xFFFF }, { 0x0D00, 0x0C24, 0x0F06,
- 0x0938, 0x1B15, 0x1F07, 0x1C19, 0x172B, 0x0D3D, 0xFFFF }, { 0x0E1A, 0x1931, 0x1B01, 0x1C03, 0x162D, 0x1E1D, 0xFFFF }, {
- 0x1833, 0x1925, 0x1537, 0x1D1B, 0xFFFF }, { 0x0D12, 0x0B34, 0x083A, 0x1A21, 0x1339, 0x1829, 0x043F, 0xFFFF }, { 0x0C26,
- 0x023E, 0x0A2E, 0x1B13, 0xFFFF }, { 0x1735, 0x1E05, 0x1C17, 0xFFFF }, { 0x0D10, 0x1A23, 0x1927, 0xFFFF }, { 0x0E18,
- 0x0B2C, 0x1B11, 0x113B, 0x152F, 0xFFFF }, { 0x0C32, 0x0E02, 0x1D19, 0x0E3D, 0xFFFF }, { 0x0C28, 0x0F1C, 0x1A31, 0x1D03,
- 0x1C15, 0x182B, 0x172D, 0x1F1D, 0xFFFF }, { 0x0D20, 0x1C01, 0x1933, 0x1A25, 0x1637, 0x1E1B, 0xFFFF }, { 0x1B21, 0x1929,
- 0x053F, 0xFFFF }, { 0x0E16, 0x073C, 0x1439, 0xFFFF }, { 0x0D22, 0x0F04, 0x1C13, 0x1F05, 0x1D17, 0xFFFF }, { 0x1B23,
- 0x1835, 0x1A27, 0xFFFF }, { 0x0C2A, 0x123B, 0x162F, 0xFFFF }, { 0x0D30, 0x0E14, 0x0B36, 0x1C11, 0x1E19, 0x0F3D, 0xFFFF
- }, { 0x0E00, 0x0D24, 0x0A38, 0x1B31, 0x1E03, 0x1D15, 0x192B, 0xFFFF }, { 0x0F1A, 0x1D01, 0x1A33, 0x1B25, 0x1737, 0x1F1B,
- 0x182D, 0xFFFF }, { 0x1A29, 0x063F, 0xFFFF }, { 0x0E12, 0x0C34, 0x093A, 0x1C21, 0x1539, 0xFFFF }, { 0x0D26, 0x033E,
- 0x0B2E, 0x1D13, 0x1E17, 0xFFFF }, { 0x1935, 0x1B27, 0xFFFF }, { 0x0E10, 0x1C23, 0x133B, 0x172F, 0xFFFF }, { 0x0F18,
- 0x0C2C, 0x1D11, 0x1F19, 0xFFFF }, { 0x0D32, 0x0F02, 0x1F03, 0x1E15, 0x1A2B, 0x103D, 0xFFFF }, { 0x0D28, 0x1C31, 0x1E01,
- 0x1B33, 0x192D, 0xFFFF }, { 0x0E20, 0x1C25, 0x1837, 0x1B29, 0x073F, 0xFFFF }, { 0x1D21, 0x1639, 0xFFFF }, { 0x0F16,
- 0x083C, 0x1E13, 0x1F17, 0xFFFF }, { 0x0E22, 0x1A35, 0xFFFF }, { 0x1D23, 0x1C27, 0xFFFF }, { 0x0D2A, 0x1E11, 0x143B,
- 0x182F, 0xFFFF }, { 0x0E30, 0x0F14, 0x0C36, 0x1F15, 0x1B2B, 0x113D, 0xFFFF }, { 0x0F00, 0x0E24, 0x0B38, 0x1D31, 0x1F01,
- 0x1A2D, 0xFFFF }, { 0x1C33, 0x1D25, 0x1937, 0xFFFF }, { 0x1E21, 0x1739, 0x1C29, 0x083F, 0xFFFF }, { 0x0F12, 0x0D34,
- 0x0A3A, 0x1F13, 0xFFFF }, { 0x0E26, 0x043E, 0x0C2E, 0x1B35, 0xFFFF }, { 0x1E23, 0x1D27, 0xFFFF }, { 0x0F10, 0x1F11,
- 0x153B, 0x192F, 0xFFFF }, { 0x0D2C, 0x123D, 0xFFFF },
- };
-
- struct etc1_block
- {
- // big endian uint64:
- // bit ofs: 56 48 40 32 24 16 8 0
- // byte ofs: b0, b1, b2, b3, b4, b5, b6, b7
- union
- {
- uint64 m_uint64;
- uint8 m_bytes[8];
- };
-
- uint8 m_low_color[2];
- uint8 m_high_color[2];
-
- enum { cNumSelectorBytes = 4 };
- uint8 m_selectors[cNumSelectorBytes];
-
- inline void clear()
- {
- zero_this(this);
- }
-
- inline uint get_byte_bits(uint ofs, uint num) const
- {
- RG_ETC1_ASSERT((ofs + num) <= 64U);
- RG_ETC1_ASSERT(num && (num <= 8U));
- RG_ETC1_ASSERT((ofs >> 3) == ((ofs + num - 1) >> 3));
- const uint byte_ofs = 7 - (ofs >> 3);
- const uint byte_bit_ofs = ofs & 7;
- return (m_bytes[byte_ofs] >> byte_bit_ofs) & ((1 << num) - 1);
- }
-
- inline void set_byte_bits(uint ofs, uint num, uint bits)
- {
- RG_ETC1_ASSERT((ofs + num) <= 64U);
- RG_ETC1_ASSERT(num && (num < 32U));
- RG_ETC1_ASSERT((ofs >> 3) == ((ofs + num - 1) >> 3));
- RG_ETC1_ASSERT(bits < (1U << num));
- const uint byte_ofs = 7 - (ofs >> 3);
- const uint byte_bit_ofs = ofs & 7;
- const uint mask = (1 << num) - 1;
- m_bytes[byte_ofs] &= ~(mask << byte_bit_ofs);
- m_bytes[byte_ofs] |= (bits << byte_bit_ofs);
- }
-
- // false = left/right subblocks
- // true = upper/lower subblocks
- inline bool get_flip_bit() const
- {
- return (m_bytes[3] & 1) != 0;
- }
-
- inline void set_flip_bit(bool flip)
- {
- m_bytes[3] &= ~1;
- m_bytes[3] |= static_cast<uint8>(flip);
- }
-
- inline bool get_diff_bit() const
- {
- return (m_bytes[3] & 2) != 0;
- }
-
- inline void set_diff_bit(bool diff)
- {
- m_bytes[3] &= ~2;
- m_bytes[3] |= (static_cast<uint>(diff) << 1);
- }
-
- // Returns intensity modifier table (0-7) used by subblock subblock_id.
- // subblock_id=0 left/top (CW 1), 1=right/bottom (CW 2)
- inline uint get_inten_table(uint subblock_id) const
- {
- RG_ETC1_ASSERT(subblock_id < 2);
- const uint ofs = subblock_id ? 2 : 5;
- return (m_bytes[3] >> ofs) & 7;
- }
-
- // Sets intensity modifier table (0-7) used by subblock subblock_id (0 or 1)
- inline void set_inten_table(uint subblock_id, uint t)
- {
- RG_ETC1_ASSERT(subblock_id < 2);
- RG_ETC1_ASSERT(t < 8);
- const uint ofs = subblock_id ? 2 : 5;
- m_bytes[3] &= ~(7 << ofs);
- m_bytes[3] |= (t << ofs);
- }
-
- // Returned selector value ranges from 0-3 and is a direct index into g_etc1_inten_tables.
- inline uint get_selector(uint x, uint y) const
- {
- RG_ETC1_ASSERT((x | y) < 4);
-
- const uint bit_index = x * 4 + y;
- const uint byte_bit_ofs = bit_index & 7;
- const uint8 *p = &m_bytes[7 - (bit_index >> 3)];
- const uint lsb = (p[0] >> byte_bit_ofs) & 1;
- const uint msb = (p[-2] >> byte_bit_ofs) & 1;
- const uint val = lsb | (msb << 1);
-
- return g_etc1_to_selector_index[val];
- }
-
- // Selector "val" ranges from 0-3 and is a direct index into g_etc1_inten_tables.
- inline void set_selector(uint x, uint y, uint val)
- {
- RG_ETC1_ASSERT((x | y | val) < 4);
- const uint bit_index = x * 4 + y;
-
- uint8 *p = &m_bytes[7 - (bit_index >> 3)];
-
- const uint byte_bit_ofs = bit_index & 7;
- const uint mask = 1 << byte_bit_ofs;
-
- const uint etc1_val = g_selector_index_to_etc1[val];
-
- const uint lsb = etc1_val & 1;
- const uint msb = etc1_val >> 1;
-
- p[0] &= ~mask;
- p[0] |= (lsb << byte_bit_ofs);
-
- p[-2] &= ~mask;
- p[-2] |= (msb << byte_bit_ofs);
- }
-
- inline void set_base4_color(uint idx, uint16 c)
- {
- if (idx)
- {
- set_byte_bits(cETC1AbsColor4R2BitOffset, 4, (c >> 8) & 15);
- set_byte_bits(cETC1AbsColor4G2BitOffset, 4, (c >> 4) & 15);
- set_byte_bits(cETC1AbsColor4B2BitOffset, 4, c & 15);
- }
- else
- {
- set_byte_bits(cETC1AbsColor4R1BitOffset, 4, (c >> 8) & 15);
- set_byte_bits(cETC1AbsColor4G1BitOffset, 4, (c >> 4) & 15);
- set_byte_bits(cETC1AbsColor4B1BitOffset, 4, c & 15);
- }
- }
-
- inline uint16 get_base4_color(uint idx) const
- {
- uint r, g, b;
- if (idx)
- {
- r = get_byte_bits(cETC1AbsColor4R2BitOffset, 4);
- g = get_byte_bits(cETC1AbsColor4G2BitOffset, 4);
- b = get_byte_bits(cETC1AbsColor4B2BitOffset, 4);
- }
- else
- {
- r = get_byte_bits(cETC1AbsColor4R1BitOffset, 4);
- g = get_byte_bits(cETC1AbsColor4G1BitOffset, 4);
- b = get_byte_bits(cETC1AbsColor4B1BitOffset, 4);
- }
- return static_cast<uint16>(b | (g << 4U) | (r << 8U));
- }
-
- inline void set_base5_color(uint16 c)
- {
- set_byte_bits(cETC1BaseColor5RBitOffset, 5, (c >> 10) & 31);
- set_byte_bits(cETC1BaseColor5GBitOffset, 5, (c >> 5) & 31);
- set_byte_bits(cETC1BaseColor5BBitOffset, 5, c & 31);
- }
-
- inline uint16 get_base5_color() const
- {
- const uint r = get_byte_bits(cETC1BaseColor5RBitOffset, 5);
- const uint g = get_byte_bits(cETC1BaseColor5GBitOffset, 5);
- const uint b = get_byte_bits(cETC1BaseColor5BBitOffset, 5);
- return static_cast<uint16>(b | (g << 5U) | (r << 10U));
- }
-
- void set_delta3_color(uint16 c)
- {
- set_byte_bits(cETC1DeltaColor3RBitOffset, 3, (c >> 6) & 7);
- set_byte_bits(cETC1DeltaColor3GBitOffset, 3, (c >> 3) & 7);
- set_byte_bits(cETC1DeltaColor3BBitOffset, 3, c & 7);
- }
-
- inline uint16 get_delta3_color() const
- {
- const uint r = get_byte_bits(cETC1DeltaColor3RBitOffset, 3);
- const uint g = get_byte_bits(cETC1DeltaColor3GBitOffset, 3);
- const uint b = get_byte_bits(cETC1DeltaColor3BBitOffset, 3);
- return static_cast<uint16>(b | (g << 3U) | (r << 6U));
- }
-
- // Base color 5
- static uint16 pack_color5(const color_quad_u8& color, bool scaled, uint bias = 127U);
- static uint16 pack_color5(uint r, uint g, uint b, bool scaled, uint bias = 127U);
-
- static color_quad_u8 unpack_color5(uint16 packed_color5, bool scaled, uint alpha = 255U);
- static void unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color, bool scaled);
-
- static bool unpack_color5(color_quad_u8& result, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha = 255U);
- static bool unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha = 255U);
-
- // Delta color 3
- // Inputs range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax)
- static uint16 pack_delta3(int r, int g, int b);
-
- // Results range from -4 to 3 (cETC1ColorDeltaMin to cETC1ColorDeltaMax)
- static void unpack_delta3(int& r, int& g, int& b, uint16 packed_delta3);
-
- // Abs color 4
- static uint16 pack_color4(const color_quad_u8& color, bool scaled, uint bias = 127U);
- static uint16 pack_color4(uint r, uint g, uint b, bool scaled, uint bias = 127U);
-
- static color_quad_u8 unpack_color4(uint16 packed_color4, bool scaled, uint alpha = 255U);
- static void unpack_color4(uint& r, uint& g, uint& b, uint16 packed_color4, bool scaled);
-
- // subblock colors
- static void get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint table_idx);
- static bool get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint16 packed_delta3, uint table_idx);
- static void get_abs_subblock_colors(color_quad_u8* pDst, uint16 packed_color4, uint table_idx);
-
- static inline void unscaled_to_scaled_color(color_quad_u8& dst, const color_quad_u8& src, bool color4)
- {
- if (color4)
- {
- dst.r = src.r | (src.r << 4);
- dst.g = src.g | (src.g << 4);
- dst.b = src.b | (src.b << 4);
- }
- else
- {
- dst.r = (src.r >> 2) | (src.r << 3);
- dst.g = (src.g >> 2) | (src.g << 3);
- dst.b = (src.b >> 2) | (src.b << 3);
- }
- dst.a = src.a;
- }
- };
-
- // Returns pointer to sorted array.
- template<typename T, typename Q>
- T* indirect_radix_sort(uint num_indices, T* pIndices0, T* pIndices1, const Q* pKeys, uint key_ofs, uint key_size, bool init_indices)
- {
- RG_ETC1_ASSERT((key_ofs >= 0) && (key_ofs < sizeof(T)));
- RG_ETC1_ASSERT((key_size >= 1) && (key_size <= 4));
-
- if (init_indices)
- {
- T* p = pIndices0;
- T* q = pIndices0 + (num_indices >> 1) * 2;
- uint i;
- for (i = 0; p != q; p += 2, i += 2)
- {
- p[0] = static_cast<T>(i);
- p[1] = static_cast<T>(i + 1);
- }
-
- if (num_indices & 1)
- *p = static_cast<T>(i);
- }
-
- uint hist[256 * 4];
-
- memset(hist, 0, sizeof(hist[0]) * 256 * key_size);
-
-#define RG_ETC1_GET_KEY(p) (*(const uint*)((const uint8*)(pKeys + *(p)) + key_ofs))
-#define RG_ETC1_GET_KEY_FROM_INDEX(i) (*(const uint*)((const uint8*)(pKeys + (i)) + key_ofs))
-
- if (key_size == 4)
- {
- T* p = pIndices0;
- T* q = pIndices0 + num_indices;
- for ( ; p != q; p++)
- {
- const uint key = RG_ETC1_GET_KEY(p);
-
- hist[ key & 0xFF]++;
- hist[256 + ((key >> 8) & 0xFF)]++;
- hist[512 + ((key >> 16) & 0xFF)]++;
- hist[768 + ((key >> 24) & 0xFF)]++;
- }
- }
- else if (key_size == 3)
- {
- T* p = pIndices0;
- T* q = pIndices0 + num_indices;
- for ( ; p != q; p++)
- {
- const uint key = RG_ETC1_GET_KEY(p);
-
- hist[ key & 0xFF]++;
- hist[256 + ((key >> 8) & 0xFF)]++;
- hist[512 + ((key >> 16) & 0xFF)]++;
- }
- }
- else if (key_size == 2)
- {
- T* p = pIndices0;
- T* q = pIndices0 + (num_indices >> 1) * 2;
-
- for ( ; p != q; p += 2)
- {
- const uint key0 = RG_ETC1_GET_KEY(p);
- const uint key1 = RG_ETC1_GET_KEY(p+1);
-
- hist[ key0 & 0xFF]++;
- hist[256 + ((key0 >> 8) & 0xFF)]++;
-
- hist[ key1 & 0xFF]++;
- hist[256 + ((key1 >> 8) & 0xFF)]++;
- }
-
- if (num_indices & 1)
- {
- const uint key = RG_ETC1_GET_KEY(p);
-
- hist[ key & 0xFF]++;
- hist[256 + ((key >> 8) & 0xFF)]++;
- }
- }
- else
- {
- RG_ETC1_ASSERT(key_size == 1);
- if (key_size != 1)
- return NULL;
-
- T* p = pIndices0;
- T* q = pIndices0 + (num_indices >> 1) * 2;
-
- for ( ; p != q; p += 2)
- {
- const uint key0 = RG_ETC1_GET_KEY(p);
- const uint key1 = RG_ETC1_GET_KEY(p+1);
-
- hist[key0 & 0xFF]++;
- hist[key1 & 0xFF]++;
- }
-
- if (num_indices & 1)
- {
- const uint key = RG_ETC1_GET_KEY(p);
-
- hist[key & 0xFF]++;
- }
- }
-
- T* pCur = pIndices0;
- T* pNew = pIndices1;
-
- for (uint pass = 0; pass < key_size; pass++)
- {
- const uint* pHist = &hist[pass << 8];
-
- uint offsets[256];
-
- uint cur_ofs = 0;
- for (uint i = 0; i < 256; i += 2)
- {
- offsets[i] = cur_ofs;
- cur_ofs += pHist[i];
-
- offsets[i+1] = cur_ofs;
- cur_ofs += pHist[i+1];
- }
-
- const uint pass_shift = pass << 3;
-
- T* p = pCur;
- T* q = pCur + (num_indices >> 1) * 2;
-
- for ( ; p != q; p += 2)
- {
- uint index0 = p[0];
- uint index1 = p[1];
-
- uint c0 = (RG_ETC1_GET_KEY_FROM_INDEX(index0) >> pass_shift) & 0xFF;
- uint c1 = (RG_ETC1_GET_KEY_FROM_INDEX(index1) >> pass_shift) & 0xFF;
-
- if (c0 == c1)
- {
- uint dst_offset0 = offsets[c0];
-
- offsets[c0] = dst_offset0 + 2;
-
- pNew[dst_offset0] = static_cast<T>(index0);
- pNew[dst_offset0 + 1] = static_cast<T>(index1);
- }
- else
- {
- uint dst_offset0 = offsets[c0]++;
- uint dst_offset1 = offsets[c1]++;
-
- pNew[dst_offset0] = static_cast<T>(index0);
- pNew[dst_offset1] = static_cast<T>(index1);
- }
- }
-
- if (num_indices & 1)
- {
- uint index = *p;
- uint c = (RG_ETC1_GET_KEY_FROM_INDEX(index) >> pass_shift) & 0xFF;
-
- uint dst_offset = offsets[c];
- offsets[c] = dst_offset + 1;
-
- pNew[dst_offset] = static_cast<T>(index);
- }
-
- T* t = pCur;
- pCur = pNew;
- pNew = t;
- }
-
- return pCur;
- }
-
-#undef RG_ETC1_GET_KEY
-#undef RG_ETC1_GET_KEY_FROM_INDEX
-
- uint16 etc1_block::pack_color5(const color_quad_u8& color, bool scaled, uint bias)
- {
- return pack_color5(color.r, color.g, color.b, scaled, bias);
- }
-
- uint16 etc1_block::pack_color5(uint r, uint g, uint b, bool scaled, uint bias)
- {
- if (scaled)
- {
- r = (r * 31U + bias) / 255U;
- g = (g * 31U + bias) / 255U;
- b = (b * 31U + bias) / 255U;
- }
-
- r = rg_etc1::minimum(r, 31U);
- g = rg_etc1::minimum(g, 31U);
- b = rg_etc1::minimum(b, 31U);
-
- return static_cast<uint16>(b | (g << 5U) | (r << 10U));
- }
-
- color_quad_u8 etc1_block::unpack_color5(uint16 packed_color5, bool scaled, uint alpha)
- {
- uint b = packed_color5 & 31U;
- uint g = (packed_color5 >> 5U) & 31U;
- uint r = (packed_color5 >> 10U) & 31U;
-
- if (scaled)
- {
- b = (b << 3U) | (b >> 2U);
- g = (g << 3U) | (g >> 2U);
- r = (r << 3U) | (r >> 2U);
- }
-
- return color_quad_u8(cNoClamp, r, g, b, rg_etc1::minimum(alpha, 255U));
- }
-
- void etc1_block::unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, bool scaled)
- {
- color_quad_u8 c(unpack_color5(packed_color5, scaled, 0));
- r = c.r;
- g = c.g;
- b = c.b;
- }
-
- bool etc1_block::unpack_color5(color_quad_u8& result, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha)
- {
- int dc_r, dc_g, dc_b;
- unpack_delta3(dc_r, dc_g, dc_b, packed_delta3);
-
- int b = (packed_color5 & 31U) + dc_b;
- int g = ((packed_color5 >> 5U) & 31U) + dc_g;
- int r = ((packed_color5 >> 10U) & 31U) + dc_r;
-
- bool success = true;
- if (static_cast<uint>(r | g | b) > 31U)
- {
- success = false;
- r = rg_etc1::clamp<int>(r, 0, 31);
- g = rg_etc1::clamp<int>(g, 0, 31);
- b = rg_etc1::clamp<int>(b, 0, 31);
- }
-
- if (scaled)
- {
- b = (b << 3U) | (b >> 2U);
- g = (g << 3U) | (g >> 2U);
- r = (r << 3U) | (r >> 2U);
- }
-
- result.set_noclamp_rgba(r, g, b, rg_etc1::minimum(alpha, 255U));
- return success;
- }
-
- bool etc1_block::unpack_color5(uint& r, uint& g, uint& b, uint16 packed_color5, uint16 packed_delta3, bool scaled, uint alpha)
- {
- color_quad_u8 result;
- const bool success = unpack_color5(result, packed_color5, packed_delta3, scaled, alpha);
- r = result.r;
- g = result.g;
- b = result.b;
- return success;
- }
-
- uint16 etc1_block::pack_delta3(int r, int g, int b)
- {
- RG_ETC1_ASSERT((r >= cETC1ColorDeltaMin) && (r <= cETC1ColorDeltaMax));
- RG_ETC1_ASSERT((g >= cETC1ColorDeltaMin) && (g <= cETC1ColorDeltaMax));
- RG_ETC1_ASSERT((b >= cETC1ColorDeltaMin) && (b <= cETC1ColorDeltaMax));
- if (r < 0) r += 8;
- if (g < 0) g += 8;
- if (b < 0) b += 8;
- return static_cast<uint16>(b | (g << 3) | (r << 6));
- }
-
- void etc1_block::unpack_delta3(int& r, int& g, int& b, uint16 packed_delta3)
- {
- r = (packed_delta3 >> 6) & 7;
- g = (packed_delta3 >> 3) & 7;
- b = packed_delta3 & 7;
- if (r >= 4) r -= 8;
- if (g >= 4) g -= 8;
- if (b >= 4) b -= 8;
- }
-
- uint16 etc1_block::pack_color4(const color_quad_u8& color, bool scaled, uint bias)
- {
- return pack_color4(color.r, color.g, color.b, scaled, bias);
- }
-
- uint16 etc1_block::pack_color4(uint r, uint g, uint b, bool scaled, uint bias)
- {
- if (scaled)
- {
- r = (r * 15U + bias) / 255U;
- g = (g * 15U + bias) / 255U;
- b = (b * 15U + bias) / 255U;
- }
-
- r = rg_etc1::minimum(r, 15U);
- g = rg_etc1::minimum(g, 15U);
- b = rg_etc1::minimum(b, 15U);
-
- return static_cast<uint16>(b | (g << 4U) | (r << 8U));
- }
-
- color_quad_u8 etc1_block::unpack_color4(uint16 packed_color4, bool scaled, uint alpha)
- {
- uint b = packed_color4 & 15U;
- uint g = (packed_color4 >> 4U) & 15U;
- uint r = (packed_color4 >> 8U) & 15U;
-
- if (scaled)
- {
- b = (b << 4U) | b;
- g = (g << 4U) | g;
- r = (r << 4U) | r;
- }
-
- return color_quad_u8(cNoClamp, r, g, b, rg_etc1::minimum(alpha, 255U));
- }
-
- void etc1_block::unpack_color4(uint& r, uint& g, uint& b, uint16 packed_color4, bool scaled)
- {
- color_quad_u8 c(unpack_color4(packed_color4, scaled, 0));
- r = c.r;
- g = c.g;
- b = c.b;
- }
-
- void etc1_block::get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint table_idx)
- {
- RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues);
- const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0];
-
- uint r, g, b;
- unpack_color5(r, g, b, packed_color5, true);
-
- const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b);
-
- const int y0 = pInten_modifer_table[0];
- pDst[0].set(ir + y0, ig + y0, ib + y0);
-
- const int y1 = pInten_modifer_table[1];
- pDst[1].set(ir + y1, ig + y1, ib + y1);
-
- const int y2 = pInten_modifer_table[2];
- pDst[2].set(ir + y2, ig + y2, ib + y2);
-
- const int y3 = pInten_modifer_table[3];
- pDst[3].set(ir + y3, ig + y3, ib + y3);
- }
-
- bool etc1_block::get_diff_subblock_colors(color_quad_u8* pDst, uint16 packed_color5, uint16 packed_delta3, uint table_idx)
- {
- RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues);
- const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0];
-
- uint r, g, b;
- bool success = unpack_color5(r, g, b, packed_color5, packed_delta3, true);
-
- const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b);
-
- const int y0 = pInten_modifer_table[0];
- pDst[0].set(ir + y0, ig + y0, ib + y0);
-
- const int y1 = pInten_modifer_table[1];
- pDst[1].set(ir + y1, ig + y1, ib + y1);
-
- const int y2 = pInten_modifer_table[2];
- pDst[2].set(ir + y2, ig + y2, ib + y2);
-
- const int y3 = pInten_modifer_table[3];
- pDst[3].set(ir + y3, ig + y3, ib + y3);
-
- return success;
- }
-
- void etc1_block::get_abs_subblock_colors(color_quad_u8* pDst, uint16 packed_color4, uint table_idx)
- {
- RG_ETC1_ASSERT(table_idx < cETC1IntenModifierValues);
- const int *pInten_modifer_table = &g_etc1_inten_tables[table_idx][0];
-
- uint r, g, b;
- unpack_color4(r, g, b, packed_color4, true);
-
- const int ir = static_cast<int>(r), ig = static_cast<int>(g), ib = static_cast<int>(b);
-
- const int y0 = pInten_modifer_table[0];
- pDst[0].set(ir + y0, ig + y0, ib + y0);
-
- const int y1 = pInten_modifer_table[1];
- pDst[1].set(ir + y1, ig + y1, ib + y1);
-
- const int y2 = pInten_modifer_table[2];
- pDst[2].set(ir + y2, ig + y2, ib + y2);
-
- const int y3 = pInten_modifer_table[3];
- pDst[3].set(ir + y3, ig + y3, ib + y3);
- }
-
- bool unpack_etc1_block(const void* pETC1_block, unsigned int* pDst_pixels_rgba, bool preserve_alpha)
- {
- color_quad_u8* pDst = reinterpret_cast<color_quad_u8*>(pDst_pixels_rgba);
- const etc1_block& block = *static_cast<const etc1_block*>(pETC1_block);
-
- const bool diff_flag = block.get_diff_bit();
- const bool flip_flag = block.get_flip_bit();
- const uint table_index0 = block.get_inten_table(0);
- const uint table_index1 = block.get_inten_table(1);
-
- color_quad_u8 subblock_colors0[4];
- color_quad_u8 subblock_colors1[4];
- bool success = true;
-
- if (diff_flag)
- {
- const uint16 base_color5 = block.get_base5_color();
- const uint16 delta_color3 = block.get_delta3_color();
- etc1_block::get_diff_subblock_colors(subblock_colors0, base_color5, table_index0);
-
- if (!etc1_block::get_diff_subblock_colors(subblock_colors1, base_color5, delta_color3, table_index1))
- success = false;
- }
- else
- {
- const uint16 base_color4_0 = block.get_base4_color(0);
- etc1_block::get_abs_subblock_colors(subblock_colors0, base_color4_0, table_index0);
-
- const uint16 base_color4_1 = block.get_base4_color(1);
- etc1_block::get_abs_subblock_colors(subblock_colors1, base_color4_1, table_index1);
- }
-
- if (preserve_alpha)
- {
- if (flip_flag)
- {
- for (uint y = 0; y < 2; y++)
- {
- pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]);
- pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]);
- pDst[2].set_rgb(subblock_colors0[block.get_selector(2, y)]);
- pDst[3].set_rgb(subblock_colors0[block.get_selector(3, y)]);
- pDst += 4;
- }
-
- for (uint y = 2; y < 4; y++)
- {
- pDst[0].set_rgb(subblock_colors1[block.get_selector(0, y)]);
- pDst[1].set_rgb(subblock_colors1[block.get_selector(1, y)]);
- pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]);
- pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]);
- pDst += 4;
- }
- }
- else
- {
- for (uint y = 0; y < 4; y++)
- {
- pDst[0].set_rgb(subblock_colors0[block.get_selector(0, y)]);
- pDst[1].set_rgb(subblock_colors0[block.get_selector(1, y)]);
- pDst[2].set_rgb(subblock_colors1[block.get_selector(2, y)]);
- pDst[3].set_rgb(subblock_colors1[block.get_selector(3, y)]);
- pDst += 4;
- }
- }
- }
- else
- {
- if (flip_flag)
- {
- // 0000
- // 0000
- // 1111
- // 1111
- for (uint y = 0; y < 2; y++)
- {
- pDst[0] = subblock_colors0[block.get_selector(0, y)];
- pDst[1] = subblock_colors0[block.get_selector(1, y)];
- pDst[2] = subblock_colors0[block.get_selector(2, y)];
- pDst[3] = subblock_colors0[block.get_selector(3, y)];
- pDst += 4;
- }
-
- for (uint y = 2; y < 4; y++)
- {
- pDst[0] = subblock_colors1[block.get_selector(0, y)];
- pDst[1] = subblock_colors1[block.get_selector(1, y)];
- pDst[2] = subblock_colors1[block.get_selector(2, y)];
- pDst[3] = subblock_colors1[block.get_selector(3, y)];
- pDst += 4;
- }
- }
- else
- {
- // 0011
- // 0011
- // 0011
- // 0011
- for (uint y = 0; y < 4; y++)
- {
- pDst[0] = subblock_colors0[block.get_selector(0, y)];
- pDst[1] = subblock_colors0[block.get_selector(1, y)];
- pDst[2] = subblock_colors1[block.get_selector(2, y)];
- pDst[3] = subblock_colors1[block.get_selector(3, y)];
- pDst += 4;
- }
- }
- }
-
- return success;
- }
-
- struct etc1_solution_coordinates
- {
- inline etc1_solution_coordinates() :
- m_unscaled_color(0, 0, 0, 0),
- m_inten_table(0),
- m_color4(false)
- {
- }
-
- inline etc1_solution_coordinates(uint r, uint g, uint b, uint inten_table, bool color4) :
- m_unscaled_color(r, g, b, 255),
- m_inten_table(inten_table),
- m_color4(color4)
- {
- }
-
- inline etc1_solution_coordinates(const color_quad_u8& c, uint inten_table, bool color4) :
- m_unscaled_color(c),
- m_inten_table(inten_table),
- m_color4(color4)
- {
- }
-
- inline etc1_solution_coordinates(const etc1_solution_coordinates& other)
- {
- *this = other;
- }
-
- inline etc1_solution_coordinates& operator= (const etc1_solution_coordinates& rhs)
- {
- m_unscaled_color = rhs.m_unscaled_color;
- m_inten_table = rhs.m_inten_table;
- m_color4 = rhs.m_color4;
- return *this;
- }
-
- inline void clear()
- {
- m_unscaled_color.clear();
- m_inten_table = 0;
- m_color4 = false;
- }
-
- inline color_quad_u8 get_scaled_color() const
- {
- int br, bg, bb;
- if (m_color4)
- {
- br = m_unscaled_color.r | (m_unscaled_color.r << 4);
- bg = m_unscaled_color.g | (m_unscaled_color.g << 4);
- bb = m_unscaled_color.b | (m_unscaled_color.b << 4);
- }
- else
- {
- br = (m_unscaled_color.r >> 2) | (m_unscaled_color.r << 3);
- bg = (m_unscaled_color.g >> 2) | (m_unscaled_color.g << 3);
- bb = (m_unscaled_color.b >> 2) | (m_unscaled_color.b << 3);
- }
- return color_quad_u8(br, bg, bb);
- }
-
- inline void get_block_colors(color_quad_u8* pBlock_colors)
- {
- int br, bg, bb;
- if (m_color4)
- {
- br = m_unscaled_color.r | (m_unscaled_color.r << 4);
- bg = m_unscaled_color.g | (m_unscaled_color.g << 4);
- bb = m_unscaled_color.b | (m_unscaled_color.b << 4);
- }
- else
- {
- br = (m_unscaled_color.r >> 2) | (m_unscaled_color.r << 3);
- bg = (m_unscaled_color.g >> 2) | (m_unscaled_color.g << 3);
- bb = (m_unscaled_color.b >> 2) | (m_unscaled_color.b << 3);
- }
- const int* pInten_table = g_etc1_inten_tables[m_inten_table];
- pBlock_colors[0].set(br + pInten_table[0], bg + pInten_table[0], bb + pInten_table[0]);
- pBlock_colors[1].set(br + pInten_table[1], bg + pInten_table[1], bb + pInten_table[1]);
- pBlock_colors[2].set(br + pInten_table[2], bg + pInten_table[2], bb + pInten_table[2]);
- pBlock_colors[3].set(br + pInten_table[3], bg + pInten_table[3], bb + pInten_table[3]);
- }
-
- color_quad_u8 m_unscaled_color;
- uint m_inten_table;
- bool m_color4;
- };
-
- class etc1_optimizer
- {
- etc1_optimizer(const etc1_optimizer&);
- etc1_optimizer& operator= (const etc1_optimizer&);
-
- public:
- etc1_optimizer()
- {
- clear();
- }
-
- void clear()
- {
- m_pParams = NULL;
- m_pResult = NULL;
- m_pSorted_luma = NULL;
- m_pSorted_luma_indices = NULL;
- }
-
- struct params : etc1_pack_params
- {
- params()
- {
- clear();
- }
-
- params(const etc1_pack_params& base_params) :
- etc1_pack_params(base_params)
- {
- clear_optimizer_params();
- }
-
- void clear()
- {
- etc1_pack_params::clear();
- clear_optimizer_params();
- }
-
- void clear_optimizer_params()
- {
- m_num_src_pixels = 0;
- m_pSrc_pixels = 0;
-
- m_use_color4 = false;
- static const int s_default_scan_delta[] = { 0 };
- m_pScan_deltas = s_default_scan_delta;
- m_scan_delta_size = 1;
-
- m_base_color5.clear();
- m_constrain_against_base_color5 = false;
- }
-
- uint m_num_src_pixels;
- const color_quad_u8* m_pSrc_pixels;
-
- bool m_use_color4;
- const int* m_pScan_deltas;
- uint m_scan_delta_size;
-
- color_quad_u8 m_base_color5;
- bool m_constrain_against_base_color5;
- };
-
- struct results
- {
- uint64 m_error;
- color_quad_u8 m_block_color_unscaled;
- uint m_block_inten_table;
- uint m_n;
- uint8* m_pSelectors;
- bool m_block_color4;
-
- inline results& operator= (const results& rhs)
- {
- m_block_color_unscaled = rhs.m_block_color_unscaled;
- m_block_color4 = rhs.m_block_color4;
- m_block_inten_table = rhs.m_block_inten_table;
- m_error = rhs.m_error;
- RG_ETC1_ASSERT(m_n == rhs.m_n);
- memcpy(m_pSelectors, rhs.m_pSelectors, rhs.m_n);
- return *this;
- }
- };
-
- void init(const params& params, results& result);
- bool compute();
-
- private:
- struct potential_solution
- {
- potential_solution() : m_coords(), m_error(cUINT64_MAX), m_valid(false)
- {
- }
-
- etc1_solution_coordinates m_coords;
- uint8 m_selectors[8];
- uint64 m_error;
- bool m_valid;
-
- void clear()
- {
- m_coords.clear();
- m_error = cUINT64_MAX;
- m_valid = false;
- }
- };
-
- const params* m_pParams;
- results* m_pResult;
-
- int m_limit;
-
- vec3F m_avg_color;
- int m_br, m_bg, m_bb;
- uint16 m_luma[8];
- uint32 m_sorted_luma[2][8];
- const uint32* m_pSorted_luma_indices;
- uint32* m_pSorted_luma;
-
- uint8 m_selectors[8];
- uint8 m_best_selectors[8];
-
- potential_solution m_best_solution;
- potential_solution m_trial_solution;
- uint8 m_temp_selectors[8];
-
- bool evaluate_solution(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution);
- bool evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution);
- };
-
- bool etc1_optimizer::compute()
- {
- const uint n = m_pParams->m_num_src_pixels;
- const int scan_delta_size = m_pParams->m_scan_delta_size;
-
- // Scan through a subset of the 3D lattice centered around the avg block color trying each 3D (555 or 444) lattice point as a potential block color.
- // Each time a better solution is found try to refine the current solution's block color based of the current selectors and intensity table index.
- for (int zdi = 0; zdi < scan_delta_size; zdi++)
- {
- const int zd = m_pParams->m_pScan_deltas[zdi];
- const int mbb = m_bb + zd;
- if (mbb < 0) continue; else if (mbb > m_limit) break;
-
- for (int ydi = 0; ydi < scan_delta_size; ydi++)
- {
- const int yd = m_pParams->m_pScan_deltas[ydi];
- const int mbg = m_bg + yd;
- if (mbg < 0) continue; else if (mbg > m_limit) break;
-
- for (int xdi = 0; xdi < scan_delta_size; xdi++)
- {
- const int xd = m_pParams->m_pScan_deltas[xdi];
- const int mbr = m_br + xd;
- if (mbr < 0) continue; else if (mbr > m_limit) break;
-
- etc1_solution_coordinates coords(mbr, mbg, mbb, 0, m_pParams->m_use_color4);
- if (m_pParams->m_quality == cHighQuality)
- {
- if (!evaluate_solution(coords, m_trial_solution, &m_best_solution))
- continue;
- }
- else
- {
- if (!evaluate_solution_fast(coords, m_trial_solution, &m_best_solution))
- continue;
- }
-
- // Now we have the input block, the avg. color of the input pixels, a set of trial selector indices, and the block color+intensity index.
- // Now, for each component, attempt to refine the current solution by solving a simple linear equation. For example, for 4 colors:
- // The goal is:
- // pixel0 - (block_color+inten_table[selector0]) + pixel1 - (block_color+inten_table[selector1]) + pixel2 - (block_color+inten_table[selector2]) + pixel3 - (block_color+inten_table[selector3]) = 0
- // Rearranging this:
- // (pixel0 + pixel1 + pixel2 + pixel3) - (block_color+inten_table[selector0]) - (block_color+inten_table[selector1]) - (block_color+inten_table[selector2]) - (block_color+inten_table[selector3]) = 0
- // (pixel0 + pixel1 + pixel2 + pixel3) - block_color - inten_table[selector0] - block_color-inten_table[selector1] - block_color-inten_table[selector2] - block_color-inten_table[selector3] = 0
- // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - inten_table[selector0] - inten_table[selector1] - inten_table[selector2] - inten_table[selector3] = 0
- // (pixel0 + pixel1 + pixel2 + pixel3) - 4*block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3]) = 0
- // (pixel0 + pixel1 + pixel2 + pixel3)/4 - block_color - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4 = 0
- // block_color = (pixel0 + pixel1 + pixel2 + pixel3)/4 - (inten_table[selector0] + inten_table[selector1] + inten_table[selector2] + inten_table[selector3])/4
- // So what this means:
- // optimal_block_color = avg_input - avg_inten_delta
- // So the optimal block color can be computed by taking the average block color and subtracting the current average of the intensity delta.
- // Unfortunately, optimal_block_color must then be quantized to 555 or 444 so it's not always possible to improve matters using this formula.
- // Also, the above formula is for unclamped intensity deltas. The actual implementation takes into account clamping.
-
- const uint max_refinement_trials = (m_pParams->m_quality == cLowQuality) ? 2 : (((xd | yd | zd) == 0) ? 4 : 2);
- for (uint refinement_trial = 0; refinement_trial < max_refinement_trials; refinement_trial++)
- {
- const uint8* pSelectors = m_best_solution.m_selectors;
- const int* pInten_table = g_etc1_inten_tables[m_best_solution.m_coords.m_inten_table];
-
- int delta_sum_r = 0, delta_sum_g = 0, delta_sum_b = 0;
- const color_quad_u8 base_color(m_best_solution.m_coords.get_scaled_color());
- for (uint r = 0; r < n; r++)
- {
- const uint s = *pSelectors++;
- const int yd = pInten_table[s];
- // Compute actual delta being applied to each pixel, taking into account clamping.
- delta_sum_r += rg_etc1::clamp<int>(base_color.r + yd, 0, 255) - base_color.r;
- delta_sum_g += rg_etc1::clamp<int>(base_color.g + yd, 0, 255) - base_color.g;
- delta_sum_b += rg_etc1::clamp<int>(base_color.b + yd, 0, 255) - base_color.b;
- }
- if ((!delta_sum_r) && (!delta_sum_g) && (!delta_sum_b))
- break;
- const float avg_delta_r_f = static_cast<float>(delta_sum_r) / n;
- const float avg_delta_g_f = static_cast<float>(delta_sum_g) / n;
- const float avg_delta_b_f = static_cast<float>(delta_sum_b) / n;
- const int br1 = rg_etc1::clamp<int>(static_cast<uint>((m_avg_color[0] - avg_delta_r_f) * m_limit / 255.0f + .5f), 0, m_limit);
- const int bg1 = rg_etc1::clamp<int>(static_cast<uint>((m_avg_color[1] - avg_delta_g_f) * m_limit / 255.0f + .5f), 0, m_limit);
- const int bb1 = rg_etc1::clamp<int>(static_cast<uint>((m_avg_color[2] - avg_delta_b_f) * m_limit / 255.0f + .5f), 0, m_limit);
-
- bool skip = false;
-
- if ((mbr == br1) && (mbg == bg1) && (mbb == bb1))
- skip = true;
- else if ((br1 == m_best_solution.m_coords.m_unscaled_color.r) && (bg1 == m_best_solution.m_coords.m_unscaled_color.g) && (bb1 == m_best_solution.m_coords.m_unscaled_color.b))
- skip = true;
- else if ((m_br == br1) && (m_bg == bg1) && (m_bb == bb1))
- skip = true;
-
- if (skip)
- break;
-
- etc1_solution_coordinates coords1(br1, bg1, bb1, 0, m_pParams->m_use_color4);
- if (m_pParams->m_quality == cHighQuality)
- {
- if (!evaluate_solution(coords1, m_trial_solution, &m_best_solution))
- break;
- }
- else
- {
- if (!evaluate_solution_fast(coords1, m_trial_solution, &m_best_solution))
- break;
- }
-
- } // refinement_trial
-
- } // xdi
- } // ydi
- } // zdi
-
- if (!m_best_solution.m_valid)
- {
- m_pResult->m_error = cUINT32_MAX;
- return false;
- }
-
- const uint8* pSelectors = m_best_solution.m_selectors;
-
-#ifdef RG_ETC1_BUILD_DEBUG
- {
- color_quad_u8 block_colors[4];
- m_best_solution.m_coords.get_block_colors(block_colors);
-
- const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels;
- uint64 actual_error = 0;
- for (uint i = 0; i < n; i++)
- actual_error += pSrc_pixels[i].squared_distance_rgb(block_colors[pSelectors[i]]);
-
- RG_ETC1_ASSERT(actual_error == m_best_solution.m_error);
- }
-#endif
-
- m_pResult->m_error = m_best_solution.m_error;
-
- m_pResult->m_block_color_unscaled = m_best_solution.m_coords.m_unscaled_color;
- m_pResult->m_block_color4 = m_best_solution.m_coords.m_color4;
-
- m_pResult->m_block_inten_table = m_best_solution.m_coords.m_inten_table;
- memcpy(m_pResult->m_pSelectors, pSelectors, n);
- m_pResult->m_n = n;
-
- return true;
- }
-
- void etc1_optimizer::init(const params& p, results& r)
- {
- // This version is hardcoded for 8 pixel subblocks.
- RG_ETC1_ASSERT(p.m_num_src_pixels == 8);
-
- m_pParams = &p;
- m_pResult = &r;
-
- const uint n = 8;
-
- m_limit = m_pParams->m_use_color4 ? 15 : 31;
-
- vec3F avg_color(0.0f);
-
- for (uint i = 0; i < n; i++)
- {
- const color_quad_u8& c = m_pParams->m_pSrc_pixels[i];
- const vec3F fc(c.r, c.g, c.b);
-
- avg_color += fc;
-
- m_luma[i] = static_cast<uint16>(c.r + c.g + c.b);
- m_sorted_luma[0][i] = i;
- }
- avg_color *= (1.0f / static_cast<float>(n));
- m_avg_color = avg_color;
-
- m_br = rg_etc1::clamp<int>(static_cast<uint>(m_avg_color[0] * m_limit / 255.0f + .5f), 0, m_limit);
- m_bg = rg_etc1::clamp<int>(static_cast<uint>(m_avg_color[1] * m_limit / 255.0f + .5f), 0, m_limit);
- m_bb = rg_etc1::clamp<int>(static_cast<uint>(m_avg_color[2] * m_limit / 255.0f + .5f), 0, m_limit);
-
- if (m_pParams->m_quality <= cMediumQuality)
- {
- m_pSorted_luma_indices = indirect_radix_sort(n, m_sorted_luma[0], m_sorted_luma[1], m_luma, 0, sizeof(m_luma[0]), false);
- m_pSorted_luma = m_sorted_luma[0];
- if (m_pSorted_luma_indices == m_sorted_luma[0])
- m_pSorted_luma = m_sorted_luma[1];
-
- for (uint i = 0; i < n; i++)
- m_pSorted_luma[i] = m_luma[m_pSorted_luma_indices[i]];
- }
-
- m_best_solution.m_coords.clear();
- m_best_solution.m_valid = false;
- m_best_solution.m_error = cUINT64_MAX;
- }
-
- bool etc1_optimizer::evaluate_solution(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution)
- {
- trial_solution.m_valid = false;
-
- if (m_pParams->m_constrain_against_base_color5)
- {
- const int dr = coords.m_unscaled_color.r - m_pParams->m_base_color5.r;
- const int dg = coords.m_unscaled_color.g - m_pParams->m_base_color5.g;
- const int db = coords.m_unscaled_color.b - m_pParams->m_base_color5.b;
-
- if ((rg_etc1::minimum(dr, dg, db) < cETC1ColorDeltaMin) || (rg_etc1::maximum(dr, dg, db) > cETC1ColorDeltaMax))
- return false;
- }
-
- const color_quad_u8 base_color(coords.get_scaled_color());
-
- const uint n = 8;
-
- trial_solution.m_error = cUINT64_MAX;
-
- for (uint inten_table = 0; inten_table < cETC1IntenModifierValues; inten_table++)
- {
- const int* pInten_table = g_etc1_inten_tables[inten_table];
-
- color_quad_u8 block_colors[4];
- for (uint s = 0; s < 4; s++)
- {
- const int yd = pInten_table[s];
- block_colors[s].set(base_color.r + yd, base_color.g + yd, base_color.b + yd, 0);
- }
-
- uint64 total_error = 0;
-
- const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels;
- for (uint c = 0; c < n; c++)
- {
- const color_quad_u8& src_pixel = *pSrc_pixels++;
-
- uint best_selector_index = 0;
- uint best_error = rg_etc1::square(src_pixel.r - block_colors[0].r) + rg_etc1::square(src_pixel.g - block_colors[0].g) + rg_etc1::square(src_pixel.b - block_colors[0].b);
-
- uint trial_error = rg_etc1::square(src_pixel.r - block_colors[1].r) + rg_etc1::square(src_pixel.g - block_colors[1].g) + rg_etc1::square(src_pixel.b - block_colors[1].b);
- if (trial_error < best_error)
- {
- best_error = trial_error;
- best_selector_index = 1;
- }
-
- trial_error = rg_etc1::square(src_pixel.r - block_colors[2].r) + rg_etc1::square(src_pixel.g - block_colors[2].g) + rg_etc1::square(src_pixel.b - block_colors[2].b);
- if (trial_error < best_error)
- {
- best_error = trial_error;
- best_selector_index = 2;
- }
-
- trial_error = rg_etc1::square(src_pixel.r - block_colors[3].r) + rg_etc1::square(src_pixel.g - block_colors[3].g) + rg_etc1::square(src_pixel.b - block_colors[3].b);
- if (trial_error < best_error)
- {
- best_error = trial_error;
- best_selector_index = 3;
- }
-
- m_temp_selectors[c] = static_cast<uint8>(best_selector_index);
-
- total_error += best_error;
- if (total_error >= trial_solution.m_error)
- break;
- }
-
- if (total_error < trial_solution.m_error)
- {
- trial_solution.m_error = total_error;
- trial_solution.m_coords.m_inten_table = inten_table;
- memcpy(trial_solution.m_selectors, m_temp_selectors, 8);
- trial_solution.m_valid = true;
- }
- }
- trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color;
- trial_solution.m_coords.m_color4 = m_pParams->m_use_color4;
-
- bool success = false;
- if (pBest_solution)
- {
- if (trial_solution.m_error < pBest_solution->m_error)
- {
- *pBest_solution = trial_solution;
- success = true;
- }
- }
-
- return success;
- }
-
- bool etc1_optimizer::evaluate_solution_fast(const etc1_solution_coordinates& coords, potential_solution& trial_solution, potential_solution* pBest_solution)
- {
- if (m_pParams->m_constrain_against_base_color5)
- {
- const int dr = coords.m_unscaled_color.r - m_pParams->m_base_color5.r;
- const int dg = coords.m_unscaled_color.g - m_pParams->m_base_color5.g;
- const int db = coords.m_unscaled_color.b - m_pParams->m_base_color5.b;
-
- if ((rg_etc1::minimum(dr, dg, db) < cETC1ColorDeltaMin) || (rg_etc1::maximum(dr, dg, db) > cETC1ColorDeltaMax))
- {
- trial_solution.m_valid = false;
- return false;
- }
- }
-
- const color_quad_u8 base_color(coords.get_scaled_color());
-
- const uint n = 8;
-
- trial_solution.m_error = cUINT64_MAX;
-
- for (int inten_table = cETC1IntenModifierValues - 1; inten_table >= 0; --inten_table)
- {
- const int* pInten_table = g_etc1_inten_tables[inten_table];
-
- uint block_inten[4];
- color_quad_u8 block_colors[4];
- for (uint s = 0; s < 4; s++)
- {
- const int yd = pInten_table[s];
- color_quad_u8 block_color(base_color.r + yd, base_color.g + yd, base_color.b + yd, 0);
- block_colors[s] = block_color;
- block_inten[s] = block_color.r + block_color.g + block_color.b;
- }
-
- // evaluate_solution_fast() enforces/assumesd a total ordering of the input colors along the intensity (1,1,1) axis to more quickly classify the inputs to selectors.
- // The inputs colors have been presorted along the projection onto this axis, and ETC1 block colors are always ordered along the intensity axis, so this classification is fast.
- // 0 1 2 3
- // 01 12 23
- const uint block_inten_midpoints[3] = { block_inten[0] + block_inten[1], block_inten[1] + block_inten[2], block_inten[2] + block_inten[3] };
-
- uint64 total_error = 0;
- const color_quad_u8* pSrc_pixels = m_pParams->m_pSrc_pixels;
- if ((m_pSorted_luma[n - 1] * 2) < block_inten_midpoints[0])
- {
- if (block_inten[0] > m_pSorted_luma[n - 1])
- {
- const uint min_error = labs(block_inten[0] - m_pSorted_luma[n - 1]);
- if (min_error >= trial_solution.m_error)
- continue;
- }
-
- memset(&m_temp_selectors[0], 0, n);
-
- for (uint c = 0; c < n; c++)
- total_error += block_colors[0].squared_distance_rgb(pSrc_pixels[c]);
- }
- else if ((m_pSorted_luma[0] * 2) >= block_inten_midpoints[2])
- {
- if (m_pSorted_luma[0] > block_inten[3])
- {
- const uint min_error = labs(m_pSorted_luma[0] - block_inten[3]);
- if (min_error >= trial_solution.m_error)
- continue;
- }
-
- memset(&m_temp_selectors[0], 3, n);
-
- for (uint c = 0; c < n; c++)
- total_error += block_colors[3].squared_distance_rgb(pSrc_pixels[c]);
- }
- else
- {
- uint cur_selector = 0, c;
- for (c = 0; c < n; c++)
- {
- const uint y = m_pSorted_luma[c];
- while ((y * 2) >= block_inten_midpoints[cur_selector])
- if (++cur_selector > 2)
- goto done;
- const uint sorted_pixel_index = m_pSorted_luma_indices[c];
- m_temp_selectors[sorted_pixel_index] = static_cast<uint8>(cur_selector);
- total_error += block_colors[cur_selector].squared_distance_rgb(pSrc_pixels[sorted_pixel_index]);
- }
-done:
- while (c < n)
- {
- const uint sorted_pixel_index = m_pSorted_luma_indices[c];
- m_temp_selectors[sorted_pixel_index] = 3;
- total_error += block_colors[3].squared_distance_rgb(pSrc_pixels[sorted_pixel_index]);
- ++c;
- }
- }
-
- if (total_error < trial_solution.m_error)
- {
- trial_solution.m_error = total_error;
- trial_solution.m_coords.m_inten_table = inten_table;
- memcpy(trial_solution.m_selectors, m_temp_selectors, n);
- trial_solution.m_valid = true;
- if (!total_error)
- break;
- }
- }
- trial_solution.m_coords.m_unscaled_color = coords.m_unscaled_color;
- trial_solution.m_coords.m_color4 = m_pParams->m_use_color4;
-
- bool success = false;
- if (pBest_solution)
- {
- if (trial_solution.m_error < pBest_solution->m_error)
- {
- *pBest_solution = trial_solution;
- success = true;
- }
- }
-
- return success;
- }
-
- static uint etc1_decode_value(uint diff, uint inten, uint selector, uint packed_c)
- {
- const uint limit = diff ? 32 : 16; limit;
- RG_ETC1_ASSERT((diff < 2) && (inten < 8) && (selector < 4) && (packed_c < limit));
- int c;
- if (diff)
- c = (packed_c >> 2) | (packed_c << 3);
- else
- c = packed_c | (packed_c << 4);
- c += g_etc1_inten_tables[inten][selector];
- c = rg_etc1::clamp<int>(c, 0, 255);
- return c;
- }
-
- static inline int mul_8bit(int a, int b) { int t = a*b + 128; return (t + (t >> 8)) >> 8; }
-
- void pack_etc1_block_init()
- {
- for (uint diff = 0; diff < 2; diff++)
- {
- const uint limit = diff ? 32 : 16;
-
- for (uint inten = 0; inten < 8; inten++)
- {
- for (uint selector = 0; selector < 4; selector++)
- {
- const uint inverse_table_index = diff + (inten << 1) + (selector << 4);
- for (uint color = 0; color < 256; color++)
- {
- uint best_error = cUINT32_MAX, best_packed_c = 0;
- for (uint packed_c = 0; packed_c < limit; packed_c++)
- {
- int v = etc1_decode_value(diff, inten, selector, packed_c);
- uint err = labs(v - static_cast<int>(color));
- if (err < best_error)
- {
- best_error = err;
- best_packed_c = packed_c;
- if (!best_error)
- break;
- }
- }
- RG_ETC1_ASSERT(best_error <= 255);
- g_etc1_inverse_lookup[inverse_table_index][color] = static_cast<uint16>(best_packed_c | (best_error << 8));
- }
- }
- }
- }
-
- uint expand5[32];
- for(int i = 0; i < 32; i++)
- expand5[i] = (i << 3) | (i >> 2);
-
- for(int i = 0; i < 256 + 16; i++)
- {
- int v = clamp<int>(i - 8, 0, 255);
- g_quant5_tab[i] = static_cast<uint8>(expand5[mul_8bit(v,31)]);
- }
- }
-
- // Packs solid color blocks efficiently using a set of small precomputed tables.
- // For random 888 inputs, MSE results are better than Erricson's ETC1 packer in "slow" mode ~9.5% of the time, is slightly worse only ~.01% of the time, and is equal the rest of the time.
- static uint64 pack_etc1_block_solid_color(etc1_block& block, const uint8* pColor, etc1_pack_params& pack_params)
- {
- pack_params;
- RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]);
-
- static uint s_next_comp[4] = { 1, 2, 0, 1 };
-
- uint best_error = cUINT32_MAX, best_i = 0;
- int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0;
-
- // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations that allow that 8-bit value to be encoded with no error.
- for (uint i = 0; i < 3; i++)
- {
- const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]];
-
- const int delta_range = 1;
- for (int delta = -delta_range; delta <= delta_range; delta++)
- {
- const int c_plus_delta = rg_etc1::clamp<int>(pColor[i] + delta, 0, 255);
-
- const uint16* pTable;
- if (!c_plus_delta)
- pTable = g_color8_to_etc_block_config_0_255[0];
- else if (c_plus_delta == 255)
- pTable = g_color8_to_etc_block_config_0_255[1];
- else
- pTable = g_color8_to_etc_block_config_1_to_254[c_plus_delta - 1];
-
- do
- {
- const uint x = *pTable++;
-
-#ifdef RG_ETC1_BUILD_DEBUG
- const uint diff = x & 1;
- const uint inten = (x >> 1) & 7;
- const uint selector = (x >> 4) & 3;
- const uint p0 = (x >> 8) & 255;
- RG_ETC1_ASSERT(etc1_decode_value(diff, inten, selector, p0) == (uint)c_plus_delta);
-#endif
-
- const uint16* pInverse_table = g_etc1_inverse_lookup[x & 0xFF];
- uint16 p1 = pInverse_table[c1];
- uint16 p2 = pInverse_table[c2];
- const uint trial_error = rg_etc1::square(c_plus_delta - pColor[i]) + rg_etc1::square(p1 >> 8) + rg_etc1::square(p2 >> 8);
- if (trial_error < best_error)
- {
- best_error = trial_error;
- best_x = x;
- best_packed_c1 = p1 & 0xFF;
- best_packed_c2 = p2 & 0xFF;
- best_i = i;
- if (!best_error)
- goto found_perfect_match;
- }
- } while (*pTable != 0xFFFF);
- }
- }
-found_perfect_match:
-
- const uint diff = best_x & 1;
- const uint inten = (best_x >> 1) & 7;
-
- block.m_bytes[3] = static_cast<uint8>(((inten | (inten << 3)) << 2) | (diff << 1));
-
- const uint etc1_selector = g_selector_index_to_etc1[(best_x >> 4) & 3];
- *reinterpret_cast<uint16*>(&block.m_bytes[4]) = (etc1_selector & 2) ? 0xFFFF : 0;
- *reinterpret_cast<uint16*>(&block.m_bytes[6]) = (etc1_selector & 1) ? 0xFFFF : 0;
-
- const uint best_packed_c0 = (best_x >> 8) & 255;
- if (diff)
- {
- block.m_bytes[best_i] = static_cast<uint8>(best_packed_c0 << 3);
- block.m_bytes[s_next_comp[best_i]] = static_cast<uint8>(best_packed_c1 << 3);
- block.m_bytes[s_next_comp[best_i+1]] = static_cast<uint8>(best_packed_c2 << 3);
- }
- else
- {
- block.m_bytes[best_i] = static_cast<uint8>(best_packed_c0 | (best_packed_c0 << 4));
- block.m_bytes[s_next_comp[best_i]] = static_cast<uint8>(best_packed_c1 | (best_packed_c1 << 4));
- block.m_bytes[s_next_comp[best_i+1]] = static_cast<uint8>(best_packed_c2 | (best_packed_c2 << 4));
- }
-
- return best_error;
- }
-
- static uint pack_etc1_block_solid_color_constrained(
- etc1_optimizer::results& results,
- uint num_colors, const uint8* pColor,
- etc1_pack_params& pack_params,
- bool use_diff,
- const color_quad_u8* pBase_color5_unscaled)
- {
- RG_ETC1_ASSERT(g_etc1_inverse_lookup[0][255]);
-
- pack_params;
- static uint s_next_comp[4] = { 1, 2, 0, 1 };
-
- uint best_error = cUINT32_MAX, best_i = 0;
- int best_x = 0, best_packed_c1 = 0, best_packed_c2 = 0;
-
- // For each possible 8-bit value, there is a precomputed list of diff/inten/selector configurations that allow that 8-bit value to be encoded with no error.
- for (uint i = 0; i < 3; i++)
- {
- const uint c1 = pColor[s_next_comp[i]], c2 = pColor[s_next_comp[i + 1]];
-
- const int delta_range = 1;
- for (int delta = -delta_range; delta <= delta_range; delta++)
- {
- const int c_plus_delta = rg_etc1::clamp<int>(pColor[i] + delta, 0, 255);
-
- const uint16* pTable;
- if (!c_plus_delta)
- pTable = g_color8_to_etc_block_config_0_255[0];
- else if (c_plus_delta == 255)
- pTable = g_color8_to_etc_block_config_0_255[1];
- else
- pTable = g_color8_to_etc_block_config_1_to_254[c_plus_delta - 1];
-
- do
- {
- const uint x = *pTable++;
- const uint diff = x & 1;
- if (static_cast<uint>(use_diff) != diff)
- {
- if (*pTable == 0xFFFF)
- break;
- continue;
- }
-
- if ((diff) && (pBase_color5_unscaled))
- {
- const int p0 = (x >> 8) & 255;
- int delta = p0 - static_cast<int>(pBase_color5_unscaled->c[i]);
- if ((delta < cETC1ColorDeltaMin) || (delta > cETC1ColorDeltaMax))
- {
- if (*pTable == 0xFFFF)
- break;
- continue;
- }
- }
-
-#ifdef RG_ETC1_BUILD_DEBUG
- {
- const uint inten = (x >> 1) & 7;
- const uint selector = (x >> 4) & 3;
- const uint p0 = (x >> 8) & 255;
- RG_ETC1_ASSERT(etc1_decode_value(diff, inten, selector, p0) == (uint)c_plus_delta);
- }
-#endif
-
- const uint16* pInverse_table = g_etc1_inverse_lookup[x & 0xFF];
- uint16 p1 = pInverse_table[c1];
- uint16 p2 = pInverse_table[c2];
-
- if ((diff) && (pBase_color5_unscaled))
- {
- int delta1 = (p1 & 0xFF) - static_cast<int>(pBase_color5_unscaled->c[s_next_comp[i]]);
- int delta2 = (p2 & 0xFF) - static_cast<int>(pBase_color5_unscaled->c[s_next_comp[i + 1]]);
- if ((delta1 < cETC1ColorDeltaMin) || (delta1 > cETC1ColorDeltaMax) || (delta2 < cETC1ColorDeltaMin) || (delta2 > cETC1ColorDeltaMax))
- {
- if (*pTable == 0xFFFF)
- break;
- continue;
- }
- }
-
- const uint trial_error = rg_etc1::square(c_plus_delta - pColor[i]) + rg_etc1::square(p1 >> 8) + rg_etc1::square(p2 >> 8);
- if (trial_error < best_error)
- {
- best_error = trial_error;
- best_x = x;
- best_packed_c1 = p1 & 0xFF;
- best_packed_c2 = p2 & 0xFF;
- best_i = i;
- if (!best_error)
- goto found_perfect_match;
- }
- } while (*pTable != 0xFFFF);
- }
- }
-found_perfect_match:
-
- if (best_error == cUINT32_MAX)
- return best_error;
-
- best_error *= num_colors;
-
- results.m_n = num_colors;
- results.m_block_color4 = !(best_x & 1);
- results.m_block_inten_table = (best_x >> 1) & 7;
- memset(results.m_pSelectors, (best_x >> 4) & 3, num_colors);
-
- const uint best_packed_c0 = (best_x >> 8) & 255;
- results.m_block_color_unscaled[best_i] = static_cast<uint8>(best_packed_c0);
- results.m_block_color_unscaled[s_next_comp[best_i]] = static_cast<uint8>(best_packed_c1);
- results.m_block_color_unscaled[s_next_comp[best_i + 1]] = static_cast<uint8>(best_packed_c2);
- results.m_error = best_error;
-
- return best_error;
- }
-
- // Function originally from RYG's public domain real-time DXT1 compressor, modified for 555.
- static void dither_block_555(color_quad_u8* dest, const color_quad_u8* block)
- {
- int err[8],*ep1 = err,*ep2 = err+4;
- uint8 *quant = g_quant5_tab+8;
-
- memset(dest, 0xFF, sizeof(color_quad_u8)*16);
-
- // process channels seperately
- for(int ch=0;ch<3;ch++)
- {
- uint8* bp = (uint8*)block;
- uint8* dp = (uint8*)dest;
-
- bp += ch; dp += ch;
-
- memset(err,0, sizeof(err));
- for(int y = 0; y < 4; y++)
- {
- // pixel 0
- dp[ 0] = quant[bp[ 0] + ((3*ep2[1] + 5*ep2[0]) >> 4)];
- ep1[0] = bp[ 0] - dp[ 0];
-
- // pixel 1
- dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)];
- ep1[1] = bp[ 4] - dp[ 4];
-
- // pixel 2
- dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)];
- ep1[2] = bp[ 8] - dp[ 8];
-
- // pixel 3
- dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)];
- ep1[3] = bp[12] - dp[12];
-
- // advance to next line
- int* tmp = ep1; ep1 = ep2; ep2 = tmp;
- bp += 16;
- dp += 16;
- }
- }
- }
-
- unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, etc1_pack_params& pack_params)
- {
- const color_quad_u8* pSrc_pixels = reinterpret_cast<const color_quad_u8*>(pSrc_pixels_rgba);
- etc1_block& dst_block = *static_cast<etc1_block*>(pETC1_block);
-
-#ifdef RG_ETC1_BUILD_DEBUG
- // Ensure all alpha values are 0xFF.
- for (uint i = 0; i < 16; i++)
- {
- RG_ETC1_ASSERT(pSrc_pixels[i].a == 255);
- }
-#endif
-
- color_quad_u8 src_pixel0(pSrc_pixels[0]);
-
- // Check for solid block.
- const uint32 first_pixel_u32 = pSrc_pixels->m_u32;
- int r;
- for (r = 15; r >= 1; --r)
- if (pSrc_pixels[r].m_u32 != first_pixel_u32)
- break;
- if (!r)
- return static_cast<unsigned int>(16 * pack_etc1_block_solid_color(dst_block, &pSrc_pixels[0].r, pack_params));
-
- color_quad_u8 dithered_pixels[16];
- if (pack_params.m_dithering)
- {
- dither_block_555(dithered_pixels, pSrc_pixels);
- pSrc_pixels = dithered_pixels;
- }
-
- etc1_optimizer optimizer;
-
- uint64 best_error = cUINT64_MAX;
- uint best_flip = false, best_use_color4 = false;
-
- uint8 best_selectors[2][8];
- etc1_optimizer::results best_results[2];
- for (uint i = 0; i < 2; i++)
- {
- best_results[i].m_n = 8;
- best_results[i].m_pSelectors = best_selectors[i];
- }
-
- uint8 selectors[3][8];
- etc1_optimizer::results results[3];
-
- for (uint i = 0; i < 3; i++)
- {
- results[i].m_n = 8;
- results[i].m_pSelectors = selectors[i];
- }
-
- color_quad_u8 subblock_pixels[8];
-
- etc1_optimizer::params params(pack_params);
- params.m_num_src_pixels = 8;
- params.m_pSrc_pixels = subblock_pixels;
-
- for (uint flip = 0; flip < 2; flip++)
- {
- for (uint use_color4 = 0; use_color4 < 2; use_color4++)
- {
- uint64 trial_error = 0;
-
- uint subblock;
- for (subblock = 0; subblock < 2; subblock++)
- {
- if (flip)
- memcpy(subblock_pixels, pSrc_pixels + subblock * 8, sizeof(color_quad_u8) * 8);
- else
- {
- const color_quad_u8* pSrc_col = pSrc_pixels + subblock * 2;
- subblock_pixels[0] = pSrc_col[0]; subblock_pixels[1] = pSrc_col[4]; subblock_pixels[2] = pSrc_col[8]; subblock_pixels[3] = pSrc_col[12];
- subblock_pixels[4] = pSrc_col[1]; subblock_pixels[5] = pSrc_col[5]; subblock_pixels[6] = pSrc_col[9]; subblock_pixels[7] = pSrc_col[13];
- }
-
- results[2].m_error = cUINT64_MAX;
- if ((params.m_quality >= cMediumQuality) && ((subblock) || (use_color4)))
- {
- const uint32 subblock_pixel0_u32 = subblock_pixels[0].m_u32;
- for (r = 7; r >= 1; --r)
- if (subblock_pixels[r].m_u32 != subblock_pixel0_u32)
- break;
- if (!r)
- {
- pack_etc1_block_solid_color_constrained(results[2], 8, &subblock_pixels[0].r, pack_params, !use_color4, (subblock && !use_color4) ? &results[0].m_block_color_unscaled : NULL);
- }
- }
-
- params.m_use_color4 = (use_color4 != 0);
- params.m_constrain_against_base_color5 = false;
-
- if ((!use_color4) && (subblock))
- {
- params.m_constrain_against_base_color5 = true;
- params.m_base_color5 = results[0].m_block_color_unscaled;
- }
-
- if (params.m_quality == cHighQuality)
- {
- static const int s_scan_delta_0_to_4[] = { -4, -3, -2, -1, 0, 1, 2, 3, 4 };
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_4);
- params.m_pScan_deltas = s_scan_delta_0_to_4;
- }
- else if (params.m_quality == cMediumQuality)
- {
- static const int s_scan_delta_0_to_1[] = { -1, 0, 1 };
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0_to_1);
- params.m_pScan_deltas = s_scan_delta_0_to_1;
- }
- else
- {
- static const int s_scan_delta_0[] = { 0 };
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_0);
- params.m_pScan_deltas = s_scan_delta_0;
- }
-
- optimizer.init(params, results[subblock]);
- if (!optimizer.compute())
- break;
-
- if (params.m_quality >= cMediumQuality)
- {
- // TODO: Fix fairly arbitrary/unrefined thresholds that control how far away to scan for potentially better solutions.
- const uint refinement_error_thresh0 = 3000;
- const uint refinement_error_thresh1 = 6000;
- if (results[subblock].m_error > refinement_error_thresh0)
- {
- if (params.m_quality == cMediumQuality)
- {
- static const int s_scan_delta_2_to_3[] = { -3, -2, 2, 3 };
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_2_to_3);
- params.m_pScan_deltas = s_scan_delta_2_to_3;
- }
- else
- {
- static const int s_scan_delta_5_to_5[] = { -5, 5 };
- static const int s_scan_delta_5_to_8[] = { -8, -7, -6, -5, 5, 6, 7, 8 };
- if (results[subblock].m_error > refinement_error_thresh1)
- {
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_8);
- params.m_pScan_deltas = s_scan_delta_5_to_8;
- }
- else
- {
- params.m_scan_delta_size = RG_ETC1_ARRAY_SIZE(s_scan_delta_5_to_5);
- params.m_pScan_deltas = s_scan_delta_5_to_5;
- }
- }
-
- if (!optimizer.compute())
- break;
- }
-
- if (results[2].m_error < results[subblock].m_error)
- results[subblock] = results[2];
- }
-
- trial_error += results[subblock].m_error;
- if (trial_error >= best_error)
- break;
- }
-
- if (subblock < 2)
- continue;
-
- best_error = trial_error;
- best_results[0] = results[0];
- best_results[1] = results[1];
- best_flip = flip;
- best_use_color4 = use_color4;
-
- } // use_color4
-
- } // flip
-
- int dr = best_results[1].m_block_color_unscaled.r - best_results[0].m_block_color_unscaled.r;
- int dg = best_results[1].m_block_color_unscaled.g - best_results[0].m_block_color_unscaled.g;
- int db = best_results[1].m_block_color_unscaled.b - best_results[0].m_block_color_unscaled.b;
- RG_ETC1_ASSERT(best_use_color4 || (rg_etc1::minimum(dr, dg, db) >= cETC1ColorDeltaMin) && (rg_etc1::maximum(dr, dg, db) <= cETC1ColorDeltaMax));
-
- if (best_use_color4)
- {
- dst_block.m_bytes[0] = static_cast<uint8>(best_results[1].m_block_color_unscaled.r | (best_results[0].m_block_color_unscaled.r << 4));
- dst_block.m_bytes[1] = static_cast<uint8>(best_results[1].m_block_color_unscaled.g | (best_results[0].m_block_color_unscaled.g << 4));
- dst_block.m_bytes[2] = static_cast<uint8>(best_results[1].m_block_color_unscaled.b | (best_results[0].m_block_color_unscaled.b << 4));
- }
- else
- {
- if (dr < 0) dr += 8; dst_block.m_bytes[0] = static_cast<uint8>((best_results[0].m_block_color_unscaled.r << 3) | dr);
- if (dg < 0) dg += 8; dst_block.m_bytes[1] = static_cast<uint8>((best_results[0].m_block_color_unscaled.g << 3) | dg);
- if (db < 0) db += 8; dst_block.m_bytes[2] = static_cast<uint8>((best_results[0].m_block_color_unscaled.b << 3) | db);
- }
-
- dst_block.m_bytes[3] = static_cast<uint8>( (best_results[1].m_block_inten_table << 2) | (best_results[0].m_block_inten_table << 5) | ((~best_use_color4 & 1) << 1) | best_flip );
-
- uint selector0 = 0, selector1 = 0;
- if (best_flip)
- {
- // flipped:
- // { 0, 0 }, { 1, 0 }, { 2, 0 }, { 3, 0 },
- // { 0, 1 }, { 1, 1 }, { 2, 1 }, { 3, 1 }
- //
- // { 0, 2 }, { 1, 2 }, { 2, 2 }, { 3, 2 },
- // { 0, 3 }, { 1, 3 }, { 2, 3 }, { 3, 3 }
- const uint8* pSelectors0 = best_results[0].m_pSelectors;
- const uint8* pSelectors1 = best_results[1].m_pSelectors;
- for (int x = 3; x >= 0; --x)
- {
- uint b;
- b = g_selector_index_to_etc1[pSelectors1[4 + x]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors1[x]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors0[4 + x]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors0[x]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
- }
- }
- else
- {
- // non-flipped:
- // { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 },
- // { 1, 0 }, { 1, 1 }, { 1, 2 }, { 1, 3 }
- //
- // { 2, 0 }, { 2, 1 }, { 2, 2 }, { 2, 3 },
- // { 3, 0 }, { 3, 1 }, { 3, 2 }, { 3, 3 }
- for (int subblock = 1; subblock >= 0; --subblock)
- {
- const uint8* pSelectors = best_results[subblock].m_pSelectors + 4;
- for (uint i = 0; i < 2; i++)
- {
- uint b;
- b = g_selector_index_to_etc1[pSelectors[3]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors[2]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors[1]];
- selector0 = (selector0 << 1) | (b & 1); selector1 = (selector1 << 1) | (b >> 1);
-
- b = g_selector_index_to_etc1[pSelectors[0]];
- selector0 = (selector0 << 1) | (b & 1);selector1 = (selector1 << 1) | (b >> 1);
-
- pSelectors -= 4;
- }
- }
- }
-
- dst_block.m_bytes[4] = static_cast<uint8>(selector1 >> 8); dst_block.m_bytes[5] = static_cast<uint8>(selector1 & 0xFF);
- dst_block.m_bytes[6] = static_cast<uint8>(selector0 >> 8); dst_block.m_bytes[7] = static_cast<uint8>(selector0 & 0xFF);
-
- return static_cast<unsigned int>(best_error);
- }
-
-} // namespace rg_etc1
diff --git a/thirdparty/rg-etc1/rg_etc1.h b/thirdparty/rg-etc1/rg_etc1.h
deleted file mode 100644
index 9ce89a6cc6..0000000000
--- a/thirdparty/rg-etc1/rg_etc1.h
+++ /dev/null
@@ -1,76 +0,0 @@
-// File: rg_etc1.h - Fast, high quality ETC1 block packer/unpacker - Rich Geldreich <richgel99@gmail.com>
-// Please see ZLIB license at the end of this file.
-#pragma once
-
-namespace rg_etc1
-{
- // Unpacks an 8-byte ETC1 compressed block to a block of 4x4 32bpp RGBA pixels.
- // Returns false if the block is invalid. Invalid blocks will still be unpacked with clamping.
- // This function is thread safe, and does not dynamically allocate any memory.
- // If preserve_alpha is true, the alpha channel of the destination pixels will not be overwritten. Otherwise, alpha will be set to 255.
- bool unpack_etc1_block(const void *pETC1_block, unsigned int* pDst_pixels_rgba, bool preserve_alpha = false);
-
- // Quality setting = the higher the quality, the slower.
- // To pack large textures, it is highly recommended to call pack_etc1_block() in parallel, on different blocks, from multiple threads (particularly when using cHighQuality).
- enum etc1_quality
- {
- cLowQuality,
- cMediumQuality,
- cHighQuality,
- };
-
- struct etc1_pack_params
- {
- etc1_quality m_quality;
- bool m_dithering;
-
- inline etc1_pack_params()
- {
- clear();
- }
-
- void clear()
- {
- m_quality = cHighQuality;
- m_dithering = false;
- }
- };
-
- // Important: pack_etc1_block_init() must be called before calling pack_etc1_block().
- void pack_etc1_block_init();
-
- // Packs a 4x4 block of 32bpp RGBA pixels to an 8-byte ETC1 block.
- // 32-bit RGBA pixels must always be arranged as (R,G,B,A) (R first, A last) in memory, independent of platform endianness. A should always be 255.
- // Returns squared error of result.
- // This function is thread safe, and does not dynamically allocate any memory.
- // pack_etc1_block() does not currently support "perceptual" colorspace metrics - it primarily optimizes for RGB RMSE.
- unsigned int pack_etc1_block(void* pETC1_block, const unsigned int* pSrc_pixels_rgba, etc1_pack_params& pack_params);
-
-} // namespace rg_etc1
-
-//------------------------------------------------------------------------------
-//
-// rg_etc1 uses the ZLIB license:
-// http://opensource.org/licenses/Zlib
-//
-// Copyright (c) 2012 Rich Geldreich
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would be
-// appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not be
-// misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-//------------------------------------------------------------------------------
diff --git a/thirdparty/tinyexr/tinyexr.cc b/thirdparty/tinyexr/tinyexr.cc
new file mode 100644
index 0000000000..969a6d505d
--- /dev/null
+++ b/thirdparty/tinyexr/tinyexr.cc
@@ -0,0 +1,2 @@
+#define TINYEXR_IMPLEMENTATION
+#include "tinyexr.h"
diff --git a/thirdparty/tinyexr/tinyexr.h b/thirdparty/tinyexr/tinyexr.h
new file mode 100644
index 0000000000..c82768be9a
--- /dev/null
+++ b/thirdparty/tinyexr/tinyexr.h
@@ -0,0 +1,12419 @@
+/*
+Copyright (c) 2014 - 2017, Syoyo Fujita
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Syoyo Fujita nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+// TinyEXR contains some OpenEXR code, which is licensed under ------------
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+// End of OpenEXR license -------------------------------------------------
+
+#ifndef TINYEXR_H_
+#define TINYEXR_H_
+
+//
+//
+// Do this:
+// #define TINYEXR_IMPLEMENTATION
+// before you include this file in *one* C or C++ file to create the
+// implementation.
+//
+// // i.e. it should look like this:
+// #include ...
+// #include ...
+// #include ...
+// #define TINYEXR_IMPLEMENTATION
+// #include "tinyexr.h"
+//
+//
+
+#include <stddef.h> // for size_t
+#include <stdint.h> // guess stdint.h is available(C99)
+
+// -- GODOT change for old MinGW on Travis CI --
+#if defined(__MINGW32__)
+#include <_mingw.h> // for __MINGW64_VERSION_MAJOR
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Use embedded miniz or not to decode ZIP format pixel. Linking with zlib
+// required if this flas is 0.
+#ifndef TINYEXR_USE_MINIZ
+#define TINYEXR_USE_MINIZ (1)
+#endif
+
+// Disable PIZ comporession when applying cpplint.
+#ifndef TINYEXR_USE_PIZ
+#define TINYEXR_USE_PIZ (1)
+#endif
+
+#ifndef TINYEXR_USE_ZFP
+#define TINYEXR_USE_ZFP (0) // TinyEXR extension.
+// http://computation.llnl.gov/projects/floating-point-compression
+#endif
+
+#define TINYEXR_SUCCESS (0)
+#define TINYEXR_ERROR_INVALID_MAGIC_NUMBER (-1)
+#define TINYEXR_ERROR_INVALID_EXR_VERSION (-2)
+#define TINYEXR_ERROR_INVALID_ARGUMENT (-3)
+#define TINYEXR_ERROR_INVALID_DATA (-4)
+#define TINYEXR_ERROR_INVALID_FILE (-5)
+#define TINYEXR_ERROR_INVALID_PARAMETER (-5)
+#define TINYEXR_ERROR_CANT_OPEN_FILE (-6)
+#define TINYEXR_ERROR_UNSUPPORTED_FORMAT (-7)
+#define TINYEXR_ERROR_INVALID_HEADER (-8)
+
+// @note { OpenEXR file format: http://www.openexr.com/openexrfilelayout.pdf }
+
+// pixel type: possible values are: UINT = 0 HALF = 1 FLOAT = 2
+#define TINYEXR_PIXELTYPE_UINT (0)
+#define TINYEXR_PIXELTYPE_HALF (1)
+#define TINYEXR_PIXELTYPE_FLOAT (2)
+
+#define TINYEXR_MAX_ATTRIBUTES (128)
+
+#define TINYEXR_COMPRESSIONTYPE_NONE (0)
+#define TINYEXR_COMPRESSIONTYPE_RLE (1)
+#define TINYEXR_COMPRESSIONTYPE_ZIPS (2)
+#define TINYEXR_COMPRESSIONTYPE_ZIP (3)
+#define TINYEXR_COMPRESSIONTYPE_PIZ (4)
+#define TINYEXR_COMPRESSIONTYPE_ZFP (128) // TinyEXR extension
+
+#define TINYEXR_ZFP_COMPRESSIONTYPE_RATE (0)
+#define TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION (1)
+#define TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY (2)
+
+#define TINYEXR_TILE_ONE_LEVEL (0)
+#define TINYEXR_TILE_MIPMAP_LEVELS (1)
+#define TINYEXR_TILE_RIPMAP_LEVELS (2)
+
+#define TINYEXR_TILE_ROUND_DOWN (0)
+#define TINYEXR_TILE_ROUND_UP (1)
+
+typedef struct _EXRVersion {
+ int version; // this must be 2
+ int tiled; // tile format image
+ int long_name; // long name attribute
+ int non_image; // deep image(EXR 2.0)
+ int multipart; // multi-part(EXR 2.0)
+} EXRVersion;
+
+typedef struct _EXRAttribute {
+ char name[256]; // name and type are up to 255 chars long.
+ char type[256];
+ unsigned char *value; // uint8_t*
+ int size;
+ int pad0;
+} EXRAttribute;
+
+typedef struct _EXRChannelInfo {
+ char name[256]; // less than 255 bytes long
+ int pixel_type;
+ int x_sampling;
+ int y_sampling;
+ unsigned char p_linear;
+ unsigned char pad[3];
+} EXRChannelInfo;
+
+typedef struct _EXRTile {
+ int offset_x;
+ int offset_y;
+ int level_x;
+ int level_y;
+
+ int width; // actual width in a tile.
+ int height; // actual height int a tile.
+
+ unsigned char **images; // image[channels][pixels]
+} EXRTile;
+
+typedef struct _EXRHeader {
+ float pixel_aspect_ratio;
+ int line_order;
+ int data_window[4];
+ int display_window[4];
+ float screen_window_center[2];
+ float screen_window_width;
+
+ int chunk_count;
+
+ // Properties for tiled format(`tiledesc`).
+ int tiled;
+ int tile_size_x;
+ int tile_size_y;
+ int tile_level_mode;
+ int tile_rounding_mode;
+
+ int long_name;
+ int non_image;
+ int multipart;
+ unsigned int header_len;
+
+ // Custom attributes(exludes required attributes(e.g. `channels`,
+ // `compression`, etc)
+ int num_custom_attributes;
+ EXRAttribute custom_attributes[TINYEXR_MAX_ATTRIBUTES];
+
+ EXRChannelInfo *channels; // [num_channels]
+
+ int *pixel_types; // Loaded pixel type(TINYEXR_PIXELTYPE_*) of `images` for
+ // each channel. This is overwritten with `requested_pixel_types` when
+ // loading.
+ int num_channels;
+
+ int compression_type; // compression type(TINYEXR_COMPRESSIONTYPE_*)
+ int *requested_pixel_types; // Filled initially by
+ // ParseEXRHeaderFrom(Meomory|File), then users
+ // can edit it(only valid for HALF pixel type
+ // channel)
+
+} EXRHeader;
+
+typedef struct _EXRMultiPartHeader {
+ int num_headers;
+ EXRHeader *headers;
+
+} EXRMultiPartHeader;
+
+typedef struct _EXRImage {
+ EXRTile *tiles; // Tiled pixel data. The application must reconstruct image
+ // from tiles manually. NULL if scanline format.
+ unsigned char **images; // image[channels][pixels]. NULL if tiled format.
+
+ int width;
+ int height;
+ int num_channels;
+
+ // Properties for tile format.
+ int num_tiles;
+
+} EXRImage;
+
+typedef struct _EXRMultiPartImage {
+ int num_images;
+ EXRImage *images;
+
+} EXRMultiPartImage;
+
+typedef struct _DeepImage {
+ const char **channel_names;
+ float ***image; // image[channels][scanlines][samples]
+ int **offset_table; // offset_table[scanline][offsets]
+ int num_channels;
+ int width;
+ int height;
+ int pad0;
+} DeepImage;
+
+// @deprecated { to be removed. }
+// Loads single-frame OpenEXR image. Assume EXR image contains RGB(A) channels.
+// Application must free image data as returned by `out_rgba`
+// Result image format is: float x RGBA x width x hight
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXR(float **out_rgba, int *width, int *height,
+ const char *filename, const char **err);
+
+// @deprecated { to be removed. }
+// Saves single-frame OpenEXR image. Assume EXR image contains RGB(A) channels.
+// components must be 3(RGB) or 4(RGBA).
+// Result image format is: float x RGB(A) x width x hight
+extern int SaveEXR(const float *data, int width, int height, int components,
+ const char *filename);
+
+// Initialize EXRHeader struct
+extern void InitEXRHeader(EXRHeader *exr_header);
+
+// Initialize EXRImage struct
+extern void InitEXRImage(EXRImage *exr_image);
+
+// Free's internal data of EXRHeader struct
+extern int FreeEXRHeader(EXRHeader *exr_header);
+
+// Free's internal data of EXRImage struct
+extern int FreeEXRImage(EXRImage *exr_image);
+
+// Parse EXR version header of a file.
+extern int ParseEXRVersionFromFile(EXRVersion *version, const char *filename);
+
+// Parse EXR version header from memory-mapped EXR data.
+extern int ParseEXRVersionFromMemory(EXRVersion *version,
+ const unsigned char *memory, size_t size);
+
+// Parse single-part OpenEXR header from a file and initialize `EXRHeader`.
+extern int ParseEXRHeaderFromFile(EXRHeader *header, const EXRVersion *version,
+ const char *filename, const char **err);
+
+// Parse single-part OpenEXR header from a memory and initialize `EXRHeader`.
+extern int ParseEXRHeaderFromMemory(EXRHeader *header,
+ const EXRVersion *version,
+ const unsigned char *memory, size_t size,
+ const char **err);
+
+// Parse multi-part OpenEXR headers from a file and initialize `EXRHeader*`
+// array.
+extern int ParseEXRMultipartHeaderFromFile(EXRHeader ***headers,
+ int *num_headers,
+ const EXRVersion *version,
+ const char *filename,
+ const char **err);
+
+// Parse multi-part OpenEXR headers from a memory and initialize `EXRHeader*`
+// array
+extern int ParseEXRMultipartHeaderFromMemory(EXRHeader ***headers,
+ int *num_headers,
+ const EXRVersion *version,
+ const unsigned char *memory,
+ size_t size, const char **err);
+
+// Loads single-part OpenEXR image from a file.
+// Application must setup `ParseEXRHeaderFromFile` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXRImageFromFile(EXRImage *image, const EXRHeader *header,
+ const char *filename, const char **err);
+
+// Loads single-part OpenEXR image from a memory.
+// Application must setup `EXRHeader` with
+// `ParseEXRHeaderFromMemory` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXRImageFromMemory(EXRImage *image, const EXRHeader *header,
+ const unsigned char *memory,
+ const size_t size, const char **err);
+
+// Loads multi-part OpenEXR image from a file.
+// Application must setup `ParseEXRMultipartHeaderFromFile` before calling this
+// function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXRMultipartImageFromFile(EXRImage *images,
+ const EXRHeader **headers,
+ unsigned int num_parts,
+ const char *filename,
+ const char **err);
+
+// Loads multi-part OpenEXR image from a memory.
+// Application must setup `EXRHeader*` array with
+// `ParseEXRMultipartHeaderFromMemory` before calling this function.
+// Application can free EXRImage using `FreeEXRImage`
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXRMultipartImageFromMemory(EXRImage *images,
+ const EXRHeader **headers,
+ unsigned int num_parts,
+ const unsigned char *memory,
+ const size_t size, const char **err);
+
+// Saves multi-channel, single-frame OpenEXR image to a file.
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int SaveEXRImageToFile(const EXRImage *image,
+ const EXRHeader *exr_header, const char *filename,
+ const char **err);
+
+// Saves multi-channel, single-frame OpenEXR image to a memory.
+// Image is compressed using EXRImage.compression value.
+// Return the number of bytes if succes.
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern size_t SaveEXRImageToMemory(const EXRImage *image,
+ const EXRHeader *exr_header,
+ unsigned char **memory, const char **err);
+
+// Loads single-frame OpenEXR deep image.
+// Application must free memory of variables in DeepImage(image, offset_table)
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadDeepEXR(DeepImage *out_image, const char *filename,
+ const char **err);
+
+// NOT YET IMPLEMENTED:
+// Saves single-frame OpenEXR deep image.
+// Returns negative value and may set error string in `err` when there's an
+// error
+// extern int SaveDeepEXR(const DeepImage *in_image, const char *filename,
+// const char **err);
+
+// NOT YET IMPLEMENTED:
+// Loads multi-part OpenEXR deep image.
+// Application must free memory of variables in DeepImage(image, offset_table)
+// extern int LoadMultiPartDeepEXR(DeepImage **out_image, int num_parts, const
+// char *filename,
+// const char **err);
+
+// For emscripten.
+// Loads single-frame OpenEXR image from memory. Assume EXR image contains
+// RGB(A) channels.
+// `out_rgba` must have enough memory(at least sizeof(float) x 4(RGBA) x width x
+// hight)
+// Returns negative value and may set error string in `err` when there's an
+// error
+extern int LoadEXRFromMemory(float *out_rgba, const unsigned char *memory,
+ size_t size, const char **err);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // TINYEXR_H_
+
+#ifdef TINYEXR_IMPLEMENTATION
+#ifndef TINYEXR_IMPLEMENTATION_DEIFNED
+#define TINYEXR_IMPLEMENTATION_DEIFNED
+
+#include <algorithm>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <sstream>
+
+#include <string>
+#include <vector>
+
+#if __cplusplus > 199711L
+// C++11
+#include <cstdint>
+#endif // __cplusplus > 199711L
+
+#ifdef _OPENMP
+#include <omp.h>
+#endif
+
+#if TINYEXR_USE_MINIZ
+#else
+#include "zlib.h"
+#endif
+
+#if TINYEXR_USE_ZFP
+#include "zfp.h"
+#endif
+
+namespace tinyexr {
+
+#if __cplusplus > 199711L
+// C++11
+typedef uint64_t tinyexr_uint64;
+typedef int64_t tinyexr_int64;
+#else
+// Although `long long` is not a standard type pre C++11, assume it is defined
+// as a compiler's extension.
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#endif
+typedef unsigned long long tinyexr_uint64;
+typedef long long tinyexr_int64;
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+#endif
+
+#if TINYEXR_USE_MINIZ
+
+namespace miniz {
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#pragma clang diagnostic ignored "-Wold-style-cast"
+#pragma clang diagnostic ignored "-Wpadded"
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+#pragma clang diagnostic ignored "-Wconversion"
+#ifdef __APPLE__
+#if __clang_major__ >= 8 && __clang__minor__ > 1
+#pragma clang diagnostic ignored "-Wcomma"
+#endif
+#endif
+#pragma clang diagnostic ignored "-Wunused-function"
+#endif
+
+/* miniz.c v1.15 - public domain deflate/inflate, zlib-subset, ZIP
+ reading/writing/appending, PNG writing
+ See "unlicense" statement at the end of this file.
+ Rich Geldreich <richgel99@gmail.com>, last updated Oct. 13, 2013
+ Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951:
+ http://www.ietf.org/rfc/rfc1951.txt
+
+ Most API's defined in miniz.c are optional. For example, to disable the
+ archive related functions just define
+ MINIZ_NO_ARCHIVE_APIS, or to get rid of all stdio usage define MINIZ_NO_STDIO
+ (see the list below for more macros).
+
+ * Change History
+ 10/13/13 v1.15 r4 - Interim bugfix release while I work on the next major
+ release with Zip64 support (almost there!):
+ - Critical fix for the MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY bug
+ (thanks kahmyong.moon@hp.com) which could cause locate files to not find
+ files. This bug
+ would only have occured in earlier versions if you explicitly used this
+ flag, OR if you used mz_zip_extract_archive_file_to_heap() or
+ mz_zip_add_mem_to_archive_file_in_place()
+ (which used this flag). If you can't switch to v1.15 but want to fix
+ this bug, just remove the uses of this flag from both helper funcs (and of
+ course don't use the flag).
+ - Bugfix in mz_zip_reader_extract_to_mem_no_alloc() from kymoon when
+ pUser_read_buf is not NULL and compressed size is > uncompressed size
+ - Fixing mz_zip_reader_extract_*() funcs so they don't try to extract
+ compressed data from directory entries, to account for weird zipfiles which
+ contain zero-size compressed data on dir entries.
+ Hopefully this fix won't cause any issues on weird zip archives,
+ because it assumes the low 16-bits of zip external attributes are DOS
+ attributes (which I believe they always are in practice).
+ - Fixing mz_zip_reader_is_file_a_directory() so it doesn't check the
+ internal attributes, just the filename and external attributes
+ - mz_zip_reader_init_file() - missing MZ_FCLOSE() call if the seek failed
+ - Added cmake support for Linux builds which builds all the examples,
+ tested with clang v3.3 and gcc v4.6.
+ - Clang fix for tdefl_write_image_to_png_file_in_memory() from toffaletti
+ - Merged MZ_FORCEINLINE fix from hdeanclark
+ - Fix <time.h> include before config #ifdef, thanks emil.brink
+ - Added tdefl_write_image_to_png_file_in_memory_ex(): supports Y flipping
+ (super useful for OpenGL apps), and explicit control over the compression
+ level (so you can
+ set it to 1 for real-time compression).
+ - Merged in some compiler fixes from paulharris's github repro.
+ - Retested this build under Windows (VS 2010, including static analysis),
+ tcc 0.9.26, gcc v4.6 and clang v3.3.
+ - Added example6.c, which dumps an image of the mandelbrot set to a PNG
+ file.
+ - Modified example2 to help test the
+ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY flag more.
+ - In r3: Bugfix to mz_zip_writer_add_file() found during merge: Fix
+ possible src file fclose() leak if alignment bytes+local header file write
+ faiiled
+ - In r4: Minor bugfix to mz_zip_writer_add_from_zip_reader():
+ Was pushing the wrong central dir header offset, appears harmless in this
+ release, but it became a problem in the zip64 branch
+ 5/20/12 v1.14 - MinGW32/64 GCC 4.6.1 compiler fixes: added MZ_FORCEINLINE,
+ #include <time.h> (thanks fermtect).
+ 5/19/12 v1.13 - From jason@cornsyrup.org and kelwert@mtu.edu - Fix
+ mz_crc32() so it doesn't compute the wrong CRC-32's when mz_ulong is 64-bit.
+ - Temporarily/locally slammed in "typedef unsigned long mz_ulong" and
+ re-ran a randomized regression test on ~500k files.
+ - Eliminated a bunch of warnings when compiling with GCC 32-bit/64.
+ - Ran all examples, miniz.c, and tinfl.c through MSVC 2008's /analyze
+ (static analysis) option and fixed all warnings (except for the silly
+ "Use of the comma-operator in a tested expression.." analysis warning,
+ which I purposely use to work around a MSVC compiler warning).
+ - Created 32-bit and 64-bit Codeblocks projects/workspace. Built and
+ tested Linux executables. The codeblocks workspace is compatible with
+ Linux+Win32/x64.
+ - Added miniz_tester solution/project, which is a useful little app
+ derived from LZHAM's tester app that I use as part of the regression test.
+ - Ran miniz.c and tinfl.c through another series of regression testing on
+ ~500,000 files and archives.
+ - Modified example5.c so it purposely disables a bunch of high-level
+ functionality (MINIZ_NO_STDIO, etc.). (Thanks to corysama for the
+ MINIZ_NO_STDIO bug report.)
+ - Fix ftell() usage in examples so they exit with an error on files which
+ are too large (a limitation of the examples, not miniz itself).
+ 4/12/12 v1.12 - More comments, added low-level example5.c, fixed a couple
+ minor level_and_flags issues in the archive API's.
+ level_and_flags can now be set to MZ_DEFAULT_COMPRESSION. Thanks to Bruce
+ Dawson <bruced@valvesoftware.com> for the feedback/bug report.
+ 5/28/11 v1.11 - Added statement from unlicense.org
+ 5/27/11 v1.10 - Substantial compressor optimizations:
+ - Level 1 is now ~4x faster than before. The L1 compressor's throughput
+ now varies between 70-110MB/sec. on a
+ - Core i7 (actual throughput varies depending on the type of data, and x64
+ vs. x86).
+ - Improved baseline L2-L9 compression perf. Also, greatly improved
+ compression perf. issues on some file types.
+ - Refactored the compression code for better readability and
+ maintainability.
+ - Added level 10 compression level (L10 has slightly better ratio than
+ level 9, but could have a potentially large
+ drop in throughput on some files).
+ 5/15/11 v1.09 - Initial stable release.
+
+ * Low-level Deflate/Inflate implementation notes:
+
+ Compression: Use the "tdefl" API's. The compressor supports raw, static,
+ and dynamic blocks, lazy or
+ greedy parsing, match length filtering, RLE-only, and Huffman-only streams.
+ It performs and compresses
+ approximately as well as zlib.
+
+ Decompression: Use the "tinfl" API's. The entire decompressor is
+ implemented as a single function
+ coroutine: see tinfl_decompress(). It supports decompression into a 32KB
+ (or larger power of 2) wrapping buffer, or into a memory
+ block large enough to hold the entire file.
+
+ The low-level tdefl/tinfl API's do not make any use of dynamic memory
+ allocation.
+
+ * zlib-style API notes:
+
+ miniz.c implements a fairly large subset of zlib. There's enough
+ functionality present for it to be a drop-in
+ zlib replacement in many apps:
+ The z_stream struct, optional memory allocation callbacks
+ deflateInit/deflateInit2/deflate/deflateReset/deflateEnd/deflateBound
+ inflateInit/inflateInit2/inflate/inflateEnd
+ compress, compress2, compressBound, uncompress
+ CRC-32, Adler-32 - Using modern, minimal code size, CPU cache friendly
+ routines.
+ Supports raw deflate streams or standard zlib streams with adler-32
+ checking.
+
+ Limitations:
+ The callback API's are not implemented yet. No support for gzip headers or
+ zlib static dictionaries.
+ I've tried to closely emulate zlib's various flavors of stream flushing
+ and return status codes, but
+ there are no guarantees that miniz.c pulls this off perfectly.
+
+ * PNG writing: See the tdefl_write_image_to_png_file_in_memory() function,
+ originally written by
+ Alex Evans. Supports 1-4 bytes/pixel images.
+
+ * ZIP archive API notes:
+
+ The ZIP archive API's where designed with simplicity and efficiency in
+ mind, with just enough abstraction to
+ get the job done with minimal fuss. There are simple API's to retrieve file
+ information, read files from
+ existing archives, create new archives, append new files to existing
+ archives, or clone archive data from
+ one archive to another. It supports archives located in memory or the heap,
+ on disk (using stdio.h),
+ or you can specify custom file read/write callbacks.
+
+ - Archive reading: Just call this function to read a single file from a
+ disk archive:
+
+ void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename, const
+ char *pArchive_name,
+ size_t *pSize, mz_uint zip_flags);
+
+ For more complex cases, use the "mz_zip_reader" functions. Upon opening an
+ archive, the entire central
+ directory is located and read as-is into memory, and subsequent file access
+ only occurs when reading individual files.
+
+ - Archives file scanning: The simple way is to use this function to scan a
+ loaded archive for a specific file:
+
+ int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName,
+ const char *pComment, mz_uint flags);
+
+ The locate operation can optionally check file comments too, which (as one
+ example) can be used to identify
+ multiple versions of the same file in an archive. This function uses a
+ simple linear search through the central
+ directory, so it's not very fast.
+
+ Alternately, you can iterate through all the files in an archive (using
+ mz_zip_reader_get_num_files()) and
+ retrieve detailed info on each file by calling mz_zip_reader_file_stat().
+
+ - Archive creation: Use the "mz_zip_writer" functions. The ZIP writer
+ immediately writes compressed file data
+ to disk and builds an exact image of the central directory in memory. The
+ central directory image is written
+ all at once at the end of the archive file when the archive is finalized.
+
+ The archive writer can optionally align each file's local header and file
+ data to any power of 2 alignment,
+ which can be useful when the archive will be read from optical media. Also,
+ the writer supports placing
+ arbitrary data blobs at the very beginning of ZIP archives. Archives
+ written using either feature are still
+ readable by any ZIP tool.
+
+ - Archive appending: The simple way to add a single file to an archive is
+ to call this function:
+
+ mz_bool mz_zip_add_mem_to_archive_file_in_place(const char *pZip_filename,
+ const char *pArchive_name,
+ const void *pBuf, size_t buf_size, const void *pComment, mz_uint16
+ comment_size, mz_uint level_and_flags);
+
+ The archive will be created if it doesn't already exist, otherwise it'll be
+ appended to.
+ Note the appending is done in-place and is not an atomic operation, so if
+ something goes wrong
+ during the operation it's possible the archive could be left without a
+ central directory (although the local
+ file headers and file data will be fine, so the archive will be
+ recoverable).
+
+ For more complex archive modification scenarios:
+ 1. The safest way is to use a mz_zip_reader to read the existing archive,
+ cloning only those bits you want to
+ preserve into a new archive using using the
+ mz_zip_writer_add_from_zip_reader() function (which compiles the
+ compressed file data as-is). When you're done, delete the old archive and
+ rename the newly written archive, and
+ you're done. This is safe but requires a bunch of temporary disk space or
+ heap memory.
+
+ 2. Or, you can convert an mz_zip_reader in-place to an mz_zip_writer using
+ mz_zip_writer_init_from_reader(),
+ append new files as needed, then finalize the archive which will write an
+ updated central directory to the
+ original archive. (This is basically what
+ mz_zip_add_mem_to_archive_file_in_place() does.) There's a
+ possibility that the archive's central directory could be lost with this
+ method if anything goes wrong, though.
+
+ - ZIP archive support limitations:
+ No zip64 or spanning support. Extraction functions can only handle
+ unencrypted, stored or deflated files.
+ Requires streams capable of seeking.
+
+ * This is a header file library, like stb_image.c. To get only a header file,
+ either cut and paste the
+ below header, or create miniz.h, #define MINIZ_HEADER_FILE_ONLY, and then
+ include miniz.c from it.
+
+ * Important: For best perf. be sure to customize the below macros for your
+ target platform:
+ #define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+ #define MINIZ_LITTLE_ENDIAN 1
+ #define MINIZ_HAS_64BIT_REGISTERS 1
+
+ * On platforms using glibc, Be sure to "#define _LARGEFILE64_SOURCE 1" before
+ including miniz.c to ensure miniz
+ uses the 64-bit variants: fopen64(), stat64(), etc. Otherwise you won't be
+ able to process large files
+ (i.e. 32-bit stat() fails for me on files > 0x7FFFFFFF bytes).
+*/
+
+#ifndef MINIZ_HEADER_INCLUDED
+#define MINIZ_HEADER_INCLUDED
+
+//#include <stdlib.h>
+
+// Defines to completely disable specific portions of miniz.c:
+// If all macros here are defined the only functionality remaining will be
+// CRC-32, adler-32, tinfl, and tdefl.
+
+// Define MINIZ_NO_STDIO to disable all usage and any functions which rely on
+// stdio for file I/O.
+//#define MINIZ_NO_STDIO
+
+// If MINIZ_NO_TIME is specified then the ZIP archive functions will not be able
+// to get the current time, or
+// get/set file times, and the C run-time funcs that get/set times won't be
+// called.
+// The current downside is the times written to your archives will be from 1979.
+#define MINIZ_NO_TIME
+
+// Define MINIZ_NO_ARCHIVE_APIS to disable all ZIP archive API's.
+#define MINIZ_NO_ARCHIVE_APIS
+
+// Define MINIZ_NO_ARCHIVE_APIS to disable all writing related ZIP archive
+// API's.
+//#define MINIZ_NO_ARCHIVE_WRITING_APIS
+
+// Define MINIZ_NO_ZLIB_APIS to remove all ZLIB-style compression/decompression
+// API's.
+//#define MINIZ_NO_ZLIB_APIS
+
+// Define MINIZ_NO_ZLIB_COMPATIBLE_NAME to disable zlib names, to prevent
+// conflicts against stock zlib.
+//#define MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+
+// Define MINIZ_NO_MALLOC to disable all calls to malloc, free, and realloc.
+// Note if MINIZ_NO_MALLOC is defined then the user must always provide custom
+// user alloc/free/realloc
+// callbacks to the zlib and archive API's, and a few stand-alone helper API's
+// which don't provide custom user
+// functions (such as tdefl_compress_mem_to_heap() and
+// tinfl_decompress_mem_to_heap()) won't work.
+//#define MINIZ_NO_MALLOC
+
+#if defined(__TINYC__) && (defined(__linux) || defined(__linux__))
+// TODO: Work around "error: include file 'sys\utime.h' when compiling with tcc
+// on Linux
+#define MINIZ_NO_TIME
+#endif
+
+#if !defined(MINIZ_NO_TIME) && !defined(MINIZ_NO_ARCHIVE_APIS)
+//#include <time.h>
+#endif
+
+#if defined(_M_IX86) || defined(_M_X64) || defined(__i386__) || \
+ defined(__i386) || defined(__i486__) || defined(__i486) || \
+ defined(i386) || defined(__ia64__) || defined(__x86_64__)
+// MINIZ_X86_OR_X64_CPU is only used to help set the below macros.
+#define MINIZ_X86_OR_X64_CPU 1
+#endif
+
+#if defined(__sparcv9)
+// Big endian
+#else
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
+// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
+#define MINIZ_LITTLE_ENDIAN 1
+#endif
+#endif
+
+#if MINIZ_X86_OR_X64_CPU
+// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 on CPU's that permit efficient
+// integer loads and stores from unaligned addresses.
+//#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
+#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES \
+ 0 // disable to suppress compiler warnings
+#endif
+
+#if defined(_M_X64) || defined(_WIN64) || defined(__MINGW64__) || \
+ defined(_LP64) || defined(__LP64__) || defined(__ia64__) || \
+ defined(__x86_64__)
+// Set MINIZ_HAS_64BIT_REGISTERS to 1 if operations on 64-bit integers are
+// reasonably fast (and don't involve compiler generated calls to helper
+// functions).
+#define MINIZ_HAS_64BIT_REGISTERS 1
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ------------------- zlib-style API Definitions.
+
+// For more compatibility with zlib, miniz.c uses unsigned long for some
+// parameters/struct members. Beware: mz_ulong can be either 32 or 64-bits!
+typedef unsigned long mz_ulong;
+
+// mz_free() internally uses the MZ_FREE() macro (which by default calls free()
+// unless you've modified the MZ_MALLOC macro) to release a block allocated from
+// the heap.
+void mz_free(void *p);
+
+#define MZ_ADLER32_INIT (1)
+// mz_adler32() returns the initial adler-32 value to use when called with
+// ptr==NULL.
+mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len);
+
+#define MZ_CRC32_INIT (0)
+// mz_crc32() returns the initial CRC-32 value to use when called with
+// ptr==NULL.
+mz_ulong mz_crc32(mz_ulong crc, const unsigned char *ptr, size_t buf_len);
+
+// Compression strategies.
+enum {
+ MZ_DEFAULT_STRATEGY = 0,
+ MZ_FILTERED = 1,
+ MZ_HUFFMAN_ONLY = 2,
+ MZ_RLE = 3,
+ MZ_FIXED = 4
+};
+
+// Method
+#define MZ_DEFLATED 8
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+// Heap allocation callbacks.
+// Note that mz_alloc_func parameter types purpsosely differ from zlib's:
+// items/size is size_t, not unsigned long.
+typedef void *(*mz_alloc_func)(void *opaque, size_t items, size_t size);
+typedef void (*mz_free_func)(void *opaque, void *address);
+typedef void *(*mz_realloc_func)(void *opaque, void *address, size_t items,
+ size_t size);
+
+#define MZ_VERSION "9.1.15"
+#define MZ_VERNUM 0x91F0
+#define MZ_VER_MAJOR 9
+#define MZ_VER_MINOR 1
+#define MZ_VER_REVISION 15
+#define MZ_VER_SUBREVISION 0
+
+// Flush values. For typical usage you only need MZ_NO_FLUSH and MZ_FINISH. The
+// other values are for advanced use (refer to the zlib docs).
+enum {
+ MZ_NO_FLUSH = 0,
+ MZ_PARTIAL_FLUSH = 1,
+ MZ_SYNC_FLUSH = 2,
+ MZ_FULL_FLUSH = 3,
+ MZ_FINISH = 4,
+ MZ_BLOCK = 5
+};
+
+// Return status codes. MZ_PARAM_ERROR is non-standard.
+enum {
+ MZ_OK = 0,
+ MZ_STREAM_END = 1,
+ MZ_NEED_DICT = 2,
+ MZ_ERRNO = -1,
+ MZ_STREAM_ERROR = -2,
+ MZ_DATA_ERROR = -3,
+ MZ_MEM_ERROR = -4,
+ MZ_BUF_ERROR = -5,
+ MZ_VERSION_ERROR = -6,
+ MZ_PARAM_ERROR = -10000
+};
+
+// Compression levels: 0-9 are the standard zlib-style levels, 10 is best
+// possible compression (not zlib compatible, and may be very slow),
+// MZ_DEFAULT_COMPRESSION=MZ_DEFAULT_LEVEL.
+enum {
+ MZ_NO_COMPRESSION = 0,
+ MZ_BEST_SPEED = 1,
+ MZ_BEST_COMPRESSION = 9,
+ MZ_UBER_COMPRESSION = 10,
+ MZ_DEFAULT_LEVEL = 6,
+ MZ_DEFAULT_COMPRESSION = -1
+};
+
+// Window bits
+#define MZ_DEFAULT_WINDOW_BITS 15
+
+struct mz_internal_state;
+
+// Compression/decompression stream struct.
+typedef struct mz_stream_s {
+ const unsigned char *next_in; // pointer to next byte to read
+ unsigned int avail_in; // number of bytes available at next_in
+ mz_ulong total_in; // total number of bytes consumed so far
+
+ unsigned char *next_out; // pointer to next byte to write
+ unsigned int avail_out; // number of bytes that can be written to next_out
+ mz_ulong total_out; // total number of bytes produced so far
+
+ char *msg; // error msg (unused)
+ struct mz_internal_state *state; // internal state, allocated by zalloc/zfree
+
+ mz_alloc_func
+ zalloc; // optional heap allocation function (defaults to malloc)
+ mz_free_func zfree; // optional heap free function (defaults to free)
+ void *opaque; // heap alloc function user pointer
+
+ int data_type; // data_type (unused)
+ mz_ulong adler; // adler32 of the source or uncompressed data
+ mz_ulong reserved; // not used
+} mz_stream;
+
+typedef mz_stream *mz_streamp;
+
+// Returns the version string of miniz.c.
+const char *mz_version(void);
+
+// mz_deflateInit() initializes a compressor with default options:
+// Parameters:
+// pStream must point to an initialized mz_stream struct.
+// level must be between [MZ_NO_COMPRESSION, MZ_BEST_COMPRESSION].
+// level 1 enables a specially optimized compression function that's been
+// optimized purely for performance, not ratio.
+// (This special func. is currently only enabled when
+// MINIZ_USE_UNALIGNED_LOADS_AND_STORES and MINIZ_LITTLE_ENDIAN are defined.)
+// Return values:
+// MZ_OK on success.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_PARAM_ERROR if the input parameters are bogus.
+// MZ_MEM_ERROR on out of memory.
+int mz_deflateInit(mz_streamp pStream, int level);
+
+// mz_deflateInit2() is like mz_deflate(), except with more control:
+// Additional parameters:
+// method must be MZ_DEFLATED
+// window_bits must be MZ_DEFAULT_WINDOW_BITS (to wrap the deflate stream with
+// zlib header/adler-32 footer) or -MZ_DEFAULT_WINDOW_BITS (raw deflate/no
+// header or footer)
+// mem_level must be between [1, 9] (it's checked but ignored by miniz.c)
+int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits,
+ int mem_level, int strategy);
+
+// Quickly resets a compressor without having to reallocate anything. Same as
+// calling mz_deflateEnd() followed by mz_deflateInit()/mz_deflateInit2().
+int mz_deflateReset(mz_streamp pStream);
+
+// mz_deflate() compresses the input to output, consuming as much of the input
+// and producing as much output as possible.
+// Parameters:
+// pStream is the stream to read from and write to. You must initialize/update
+// the next_in, avail_in, next_out, and avail_out members.
+// flush may be MZ_NO_FLUSH, MZ_PARTIAL_FLUSH/MZ_SYNC_FLUSH, MZ_FULL_FLUSH, or
+// MZ_FINISH.
+// Return values:
+// MZ_OK on success (when flushing, or if more input is needed but not
+// available, and/or there's more output to be written but the output buffer
+// is full).
+// MZ_STREAM_END if all input has been consumed and all output bytes have been
+// written. Don't call mz_deflate() on the stream anymore.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_PARAM_ERROR if one of the parameters is invalid.
+// MZ_BUF_ERROR if no forward progress is possible because the input and/or
+// output buffers are empty. (Fill up the input buffer or free up some output
+// space and try again.)
+int mz_deflate(mz_streamp pStream, int flush);
+
+// mz_deflateEnd() deinitializes a compressor:
+// Return values:
+// MZ_OK on success.
+// MZ_STREAM_ERROR if the stream is bogus.
+int mz_deflateEnd(mz_streamp pStream);
+
+// mz_deflateBound() returns a (very) conservative upper bound on the amount of
+// data that could be generated by deflate(), assuming flush is set to only
+// MZ_NO_FLUSH or MZ_FINISH.
+mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len);
+
+// Single-call compression functions mz_compress() and mz_compress2():
+// Returns MZ_OK on success, or one of the error codes from mz_deflate() on
+// failure.
+int mz_compress(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len);
+int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len, int level);
+
+// mz_compressBound() returns a (very) conservative upper bound on the amount of
+// data that could be generated by calling mz_compress().
+mz_ulong mz_compressBound(mz_ulong source_len);
+
+// Initializes a decompressor.
+int mz_inflateInit(mz_streamp pStream);
+
+// mz_inflateInit2() is like mz_inflateInit() with an additional option that
+// controls the window size and whether or not the stream has been wrapped with
+// a zlib header/footer:
+// window_bits must be MZ_DEFAULT_WINDOW_BITS (to parse zlib header/footer) or
+// -MZ_DEFAULT_WINDOW_BITS (raw deflate).
+int mz_inflateInit2(mz_streamp pStream, int window_bits);
+
+// Decompresses the input stream to the output, consuming only as much of the
+// input as needed, and writing as much to the output as possible.
+// Parameters:
+// pStream is the stream to read from and write to. You must initialize/update
+// the next_in, avail_in, next_out, and avail_out members.
+// flush may be MZ_NO_FLUSH, MZ_SYNC_FLUSH, or MZ_FINISH.
+// On the first call, if flush is MZ_FINISH it's assumed the input and output
+// buffers are both sized large enough to decompress the entire stream in a
+// single call (this is slightly faster).
+// MZ_FINISH implies that there are no more source bytes available beside
+// what's already in the input buffer, and that the output buffer is large
+// enough to hold the rest of the decompressed data.
+// Return values:
+// MZ_OK on success. Either more input is needed but not available, and/or
+// there's more output to be written but the output buffer is full.
+// MZ_STREAM_END if all needed input has been consumed and all output bytes
+// have been written. For zlib streams, the adler-32 of the decompressed data
+// has also been verified.
+// MZ_STREAM_ERROR if the stream is bogus.
+// MZ_DATA_ERROR if the deflate stream is invalid.
+// MZ_PARAM_ERROR if one of the parameters is invalid.
+// MZ_BUF_ERROR if no forward progress is possible because the input buffer is
+// empty but the inflater needs more input to continue, or if the output
+// buffer is not large enough. Call mz_inflate() again
+// with more input data, or with more room in the output buffer (except when
+// using single call decompression, described above).
+int mz_inflate(mz_streamp pStream, int flush);
+
+// Deinitializes a decompressor.
+int mz_inflateEnd(mz_streamp pStream);
+
+// Single-call decompression.
+// Returns MZ_OK on success, or one of the error codes from mz_inflate() on
+// failure.
+int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len);
+
+// Returns a string description of the specified error code, or NULL if the
+// error code is invalid.
+const char *mz_error(int err);
+
+// Redefine zlib-compatible names to miniz equivalents, so miniz.c can be used
+// as a drop-in replacement for the subset of zlib that miniz.c supports.
+// Define MINIZ_NO_ZLIB_COMPATIBLE_NAMES to disable zlib-compatibility if you
+// use zlib in the same project.
+#ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+typedef unsigned char Byte;
+typedef unsigned int uInt;
+typedef mz_ulong uLong;
+typedef Byte Bytef;
+typedef uInt uIntf;
+typedef char charf;
+typedef int intf;
+typedef void *voidpf;
+typedef uLong uLongf;
+typedef void *voidp;
+typedef void *const voidpc;
+#define Z_NULL 0
+#define Z_NO_FLUSH MZ_NO_FLUSH
+#define Z_PARTIAL_FLUSH MZ_PARTIAL_FLUSH
+#define Z_SYNC_FLUSH MZ_SYNC_FLUSH
+#define Z_FULL_FLUSH MZ_FULL_FLUSH
+#define Z_FINISH MZ_FINISH
+#define Z_BLOCK MZ_BLOCK
+#define Z_OK MZ_OK
+#define Z_STREAM_END MZ_STREAM_END
+#define Z_NEED_DICT MZ_NEED_DICT
+#define Z_ERRNO MZ_ERRNO
+#define Z_STREAM_ERROR MZ_STREAM_ERROR
+#define Z_DATA_ERROR MZ_DATA_ERROR
+#define Z_MEM_ERROR MZ_MEM_ERROR
+#define Z_BUF_ERROR MZ_BUF_ERROR
+#define Z_VERSION_ERROR MZ_VERSION_ERROR
+#define Z_PARAM_ERROR MZ_PARAM_ERROR
+#define Z_NO_COMPRESSION MZ_NO_COMPRESSION
+#define Z_BEST_SPEED MZ_BEST_SPEED
+#define Z_BEST_COMPRESSION MZ_BEST_COMPRESSION
+#define Z_DEFAULT_COMPRESSION MZ_DEFAULT_COMPRESSION
+#define Z_DEFAULT_STRATEGY MZ_DEFAULT_STRATEGY
+#define Z_FILTERED MZ_FILTERED
+#define Z_HUFFMAN_ONLY MZ_HUFFMAN_ONLY
+#define Z_RLE MZ_RLE
+#define Z_FIXED MZ_FIXED
+#define Z_DEFLATED MZ_DEFLATED
+#define Z_DEFAULT_WINDOW_BITS MZ_DEFAULT_WINDOW_BITS
+#define alloc_func mz_alloc_func
+#define free_func mz_free_func
+#define internal_state mz_internal_state
+#define z_stream mz_stream
+#define deflateInit mz_deflateInit
+#define deflateInit2 mz_deflateInit2
+#define deflateReset mz_deflateReset
+#define deflate mz_deflate
+#define deflateEnd mz_deflateEnd
+#define deflateBound mz_deflateBound
+#define compress mz_compress
+#define compress2 mz_compress2
+#define compressBound mz_compressBound
+#define inflateInit mz_inflateInit
+#define inflateInit2 mz_inflateInit2
+#define inflate mz_inflate
+#define inflateEnd mz_inflateEnd
+#define uncompress mz_uncompress
+#define crc32 mz_crc32
+#define adler32 mz_adler32
+#define MAX_WBITS 15
+#define MAX_MEM_LEVEL 9
+#define zError mz_error
+#define ZLIB_VERSION MZ_VERSION
+#define ZLIB_VERNUM MZ_VERNUM
+#define ZLIB_VER_MAJOR MZ_VER_MAJOR
+#define ZLIB_VER_MINOR MZ_VER_MINOR
+#define ZLIB_VER_REVISION MZ_VER_REVISION
+#define ZLIB_VER_SUBREVISION MZ_VER_SUBREVISION
+#define zlibVersion mz_version
+#define zlib_version mz_version()
+#endif // #ifndef MINIZ_NO_ZLIB_COMPATIBLE_NAMES
+
+#endif // MINIZ_NO_ZLIB_APIS
+
+// ------------------- Types and macros
+
+typedef unsigned char mz_uint8;
+typedef signed short mz_int16;
+typedef unsigned short mz_uint16;
+typedef unsigned int mz_uint32;
+typedef unsigned int mz_uint;
+typedef long long mz_int64;
+typedef unsigned long long mz_uint64;
+typedef int mz_bool;
+
+#define MZ_FALSE (0)
+#define MZ_TRUE (1)
+
+// An attempt to work around MSVC's spammy "warning C4127: conditional
+// expression is constant" message.
+#ifdef _MSC_VER
+#define MZ_MACRO_END while (0, 0)
+#else
+#define MZ_MACRO_END while (0)
+#endif
+
+// ------------------- ZIP archive reading/writing
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+
+enum {
+ MZ_ZIP_MAX_IO_BUF_SIZE = 64 * 1024,
+ MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE = 260,
+ MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE = 256
+};
+
+typedef struct {
+ mz_uint32 m_file_index;
+ mz_uint32 m_central_dir_ofs;
+ mz_uint16 m_version_made_by;
+ mz_uint16 m_version_needed;
+ mz_uint16 m_bit_flag;
+ mz_uint16 m_method;
+#ifndef MINIZ_NO_TIME
+ time_t m_time;
+#endif
+ mz_uint32 m_crc32;
+ mz_uint64 m_comp_size;
+ mz_uint64 m_uncomp_size;
+ mz_uint16 m_internal_attr;
+ mz_uint32 m_external_attr;
+ mz_uint64 m_local_header_ofs;
+ mz_uint32 m_comment_size;
+ char m_filename[MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE];
+ char m_comment[MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE];
+} mz_zip_archive_file_stat;
+
+typedef size_t (*mz_file_read_func)(void *pOpaque, mz_uint64 file_ofs,
+ void *pBuf, size_t n);
+typedef size_t (*mz_file_write_func)(void *pOpaque, mz_uint64 file_ofs,
+ const void *pBuf, size_t n);
+
+struct mz_zip_internal_state_tag;
+typedef struct mz_zip_internal_state_tag mz_zip_internal_state;
+
+typedef enum {
+ MZ_ZIP_MODE_INVALID = 0,
+ MZ_ZIP_MODE_READING = 1,
+ MZ_ZIP_MODE_WRITING = 2,
+ MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED = 3
+} mz_zip_mode;
+
+typedef struct mz_zip_archive_tag {
+ mz_uint64 m_archive_size;
+ mz_uint64 m_central_directory_file_ofs;
+ mz_uint m_total_files;
+ mz_zip_mode m_zip_mode;
+
+ mz_uint m_file_offset_alignment;
+
+ mz_alloc_func m_pAlloc;
+ mz_free_func m_pFree;
+ mz_realloc_func m_pRealloc;
+ void *m_pAlloc_opaque;
+
+ mz_file_read_func m_pRead;
+ mz_file_write_func m_pWrite;
+ void *m_pIO_opaque;
+
+ mz_zip_internal_state *m_pState;
+
+} mz_zip_archive;
+
+typedef enum {
+ MZ_ZIP_FLAG_CASE_SENSITIVE = 0x0100,
+ MZ_ZIP_FLAG_IGNORE_PATH = 0x0200,
+ MZ_ZIP_FLAG_COMPRESSED_DATA = 0x0400,
+ MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY = 0x0800
+} mz_zip_flags;
+
+// ZIP archive reading
+
+// Inits a ZIP archive reader.
+// These functions read and validate the archive's central directory.
+mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size,
+ mz_uint32 flags);
+mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem,
+ size_t size, mz_uint32 flags);
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename,
+ mz_uint32 flags);
+#endif
+
+// Returns the total number of files in the archive.
+mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip);
+
+// Returns detailed information about an archive file entry.
+mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index,
+ mz_zip_archive_file_stat *pStat);
+
+// Determines if an archive file entry is a directory entry.
+mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip,
+ mz_uint file_index);
+mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip,
+ mz_uint file_index);
+
+// Retrieves the filename of an archive file entry.
+// Returns the number of bytes written to pFilename, or if filename_buf_size is
+// 0 this function returns the number of bytes needed to fully store the
+// filename.
+mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index,
+ char *pFilename, mz_uint filename_buf_size);
+
+// Attempts to locates a file in the archive's central directory.
+// Valid flags: MZ_ZIP_FLAG_CASE_SENSITIVE, MZ_ZIP_FLAG_IGNORE_PATH
+// Returns -1 if the file cannot be found.
+int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName,
+ const char *pComment, mz_uint flags);
+
+// Extracts a archive file to a memory buffer using no memory allocation.
+mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
+ mz_uint file_index, void *pBuf,
+ size_t buf_size, mz_uint flags,
+ void *pUser_read_buf,
+ size_t user_read_buf_size);
+mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
+ mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size,
+ mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size);
+
+// Extracts a archive file to a memory buffer.
+mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index,
+ void *pBuf, size_t buf_size,
+ mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip,
+ const char *pFilename, void *pBuf,
+ size_t buf_size, mz_uint flags);
+
+// Extracts a archive file to a dynamically allocated heap buffer.
+void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index,
+ size_t *pSize, mz_uint flags);
+void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip,
+ const char *pFilename, size_t *pSize,
+ mz_uint flags);
+
+// Extracts a archive file using a callback function to output the file's data.
+mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
+ mz_uint file_index,
+ mz_file_write_func pCallback,
+ void *pOpaque, mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip,
+ const char *pFilename,
+ mz_file_write_func pCallback,
+ void *pOpaque, mz_uint flags);
+
+#ifndef MINIZ_NO_STDIO
+// Extracts a archive file to a disk file and sets its last accessed and
+// modified times.
+// This function only extracts files, not archive directory records.
+mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index,
+ const char *pDst_filename, mz_uint flags);
+mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip,
+ const char *pArchive_filename,
+ const char *pDst_filename,
+ mz_uint flags);
+#endif
+
+// Ends archive reading, freeing all allocations, and closing the input archive
+// file if mz_zip_reader_init_file() was used.
+mz_bool mz_zip_reader_end(mz_zip_archive *pZip);
+
+// ZIP archive writing
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+// Inits a ZIP archive writer.
+mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size);
+mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip,
+ size_t size_to_reserve_at_beginning,
+ size_t initial_allocation_size);
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename,
+ mz_uint64 size_to_reserve_at_beginning);
+#endif
+
+// Converts a ZIP archive reader object into a writer object, to allow efficient
+// in-place file appends to occur on an existing archive.
+// For archives opened using mz_zip_reader_init_file, pFilename must be the
+// archive's filename so it can be reopened for writing. If the file can't be
+// reopened, mz_zip_reader_end() will be called.
+// For archives opened using mz_zip_reader_init_mem, the memory block must be
+// growable using the realloc callback (which defaults to realloc unless you've
+// overridden it).
+// Finally, for archives opened using mz_zip_reader_init, the mz_zip_archive's
+// user provided m_pWrite function cannot be NULL.
+// Note: In-place archive modification is not recommended unless you know what
+// you're doing, because if execution stops or something goes wrong before
+// the archive is finalized the file's central directory will be hosed.
+mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip,
+ const char *pFilename);
+
+// Adds the contents of a memory buffer to an archive. These functions record
+// the current local time into the archive.
+// To add a directory entry, call this method with an archive name ending in a
+// forwardslash with empty buffer.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED,
+// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or
+// just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name,
+ const void *pBuf, size_t buf_size,
+ mz_uint level_and_flags);
+mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip,
+ const char *pArchive_name, const void *pBuf,
+ size_t buf_size, const void *pComment,
+ mz_uint16 comment_size,
+ mz_uint level_and_flags, mz_uint64 uncomp_size,
+ mz_uint32 uncomp_crc32);
+
+#ifndef MINIZ_NO_STDIO
+// Adds the contents of a disk file to an archive. This function also records
+// the disk file's modified time into the archive.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED,
+// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or
+// just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
+ const char *pSrc_filename, const void *pComment,
+ mz_uint16 comment_size, mz_uint level_and_flags);
+#endif
+
+// Adds a file to an archive by fully cloning the data from another archive.
+// This function fully clones the source file's compressed data (no
+// recompression), along with its full filename, extra data, and comment fields.
+mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip,
+ mz_zip_archive *pSource_zip,
+ mz_uint file_index);
+
+// Finalizes the archive by writing the central directory records followed by
+// the end of central directory record.
+// After an archive is finalized, the only valid call on the mz_zip_archive
+// struct is mz_zip_writer_end().
+// An archive must be manually finalized by calling this function for it to be
+// valid.
+mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip);
+mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf,
+ size_t *pSize);
+
+// Ends archive writing, freeing all allocations, and closing the output file if
+// mz_zip_writer_init_file() was used.
+// Note for the archive to be valid, it must have been finalized before ending.
+mz_bool mz_zip_writer_end(mz_zip_archive *pZip);
+
+// Misc. high-level helper functions:
+
+// mz_zip_add_mem_to_archive_file_in_place() efficiently (but not atomically)
+// appends a memory blob to a ZIP archive.
+// level_and_flags - compression level (0-10, see MZ_BEST_SPEED,
+// MZ_BEST_COMPRESSION, etc.) logically OR'd with zero or more mz_zip_flags, or
+// just set to MZ_DEFAULT_COMPRESSION.
+mz_bool mz_zip_add_mem_to_archive_file_in_place(
+ const char *pZip_filename, const char *pArchive_name, const void *pBuf,
+ size_t buf_size, const void *pComment, mz_uint16 comment_size,
+ mz_uint level_and_flags);
+
+// Reads a single file from an archive into a heap block.
+// Returns NULL on failure.
+void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
+ const char *pArchive_name,
+ size_t *pSize, mz_uint zip_flags);
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
+
+// ------------------- Low-level Decompression API Definitions
+
+// Decompression flags used by tinfl_decompress().
+// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and
+// ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the
+// input is a raw deflate stream.
+// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available
+// beyond the end of the supplied input buffer. If clear, the input buffer
+// contains all remaining input.
+// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large
+// enough to hold the entire decompressed stream. If clear, the output buffer is
+// at least the size of the dictionary (typically 32KB).
+// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the
+// decompressed bytes.
+enum {
+ TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
+ TINFL_FLAG_HAS_MORE_INPUT = 2,
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
+ TINFL_FLAG_COMPUTE_ADLER32 = 8
+};
+
+// High level decompression functions:
+// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block
+// allocated via malloc().
+// On entry:
+// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data
+// to decompress.
+// On return:
+// Function returns a pointer to the decompressed data, or NULL on failure.
+// *pOut_len will be set to the decompressed data's size, which could be larger
+// than src_buf_len on uncompressible data.
+// The caller must call mz_free() on the returned block when it's no longer
+// needed.
+void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len,
+ size_t *pOut_len, int flags);
+
+// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block
+// in memory.
+// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes
+// written on success.
+#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
+size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
+ const void *pSrc_buf, size_t src_buf_len,
+ int flags);
+
+// tinfl_decompress_mem_to_callback() decompresses a block in memory to an
+// internal 32KB buffer, and a user provided callback function will be called to
+// flush the buffer.
+// Returns 1 on success or 0 on failure.
+typedef int (*tinfl_put_buf_func_ptr)(const void *pBuf, int len, void *pUser);
+int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
+ tinfl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags);
+
+struct tinfl_decompressor_tag;
+typedef struct tinfl_decompressor_tag tinfl_decompressor;
+
+// Max size of LZ dictionary.
+#define TINFL_LZ_DICT_SIZE 32768
+
+// Return status.
+typedef enum {
+ TINFL_STATUS_BAD_PARAM = -3,
+ TINFL_STATUS_ADLER32_MISMATCH = -2,
+ TINFL_STATUS_FAILED = -1,
+ TINFL_STATUS_DONE = 0,
+ TINFL_STATUS_NEEDS_MORE_INPUT = 1,
+ TINFL_STATUS_HAS_MORE_OUTPUT = 2
+} tinfl_status;
+
+// Initializes the decompressor to its initial state.
+#define tinfl_init(r) \
+ do { \
+ (r)->m_state = 0; \
+ } \
+ MZ_MACRO_END
+#define tinfl_get_adler32(r) (r)->m_check_adler32
+
+// Main low-level decompressor coroutine function. This is the only function
+// actually needed for decompression. All the other functions are just
+// high-level helpers for improved usability.
+// This is a universal API, i.e. it can be used as a building block to build any
+// desired higher level decompression API. In the limit case, it can be called
+// once per every byte input or output.
+tinfl_status tinfl_decompress(tinfl_decompressor *r,
+ const mz_uint8 *pIn_buf_next,
+ size_t *pIn_buf_size, mz_uint8 *pOut_buf_start,
+ mz_uint8 *pOut_buf_next, size_t *pOut_buf_size,
+ const mz_uint32 decomp_flags);
+
+// Internal/private bits follow.
+enum {
+ TINFL_MAX_HUFF_TABLES = 3,
+ TINFL_MAX_HUFF_SYMBOLS_0 = 288,
+ TINFL_MAX_HUFF_SYMBOLS_1 = 32,
+ TINFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TINFL_FAST_LOOKUP_BITS = 10,
+ TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
+};
+
+typedef struct {
+ mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
+ mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE],
+ m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
+} tinfl_huff_table;
+
+#if MINIZ_HAS_64BIT_REGISTERS
+#define TINFL_USE_64BIT_BITBUF 1
+#endif
+
+#if TINFL_USE_64BIT_BITBUF
+typedef mz_uint64 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (64)
+#else
+typedef mz_uint32 tinfl_bit_buf_t;
+#define TINFL_BITBUF_SIZE (32)
+#endif
+
+struct tinfl_decompressor_tag {
+ mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type,
+ m_check_adler32, m_dist, m_counter, m_num_extra,
+ m_table_sizes[TINFL_MAX_HUFF_TABLES];
+ tinfl_bit_buf_t m_bit_buf;
+ size_t m_dist_from_out_buf_start;
+ tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
+ mz_uint8 m_raw_header[4],
+ m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
+};
+
+// ------------------- Low-level Compression API Definitions
+
+// Set TDEFL_LESS_MEMORY to 1 to use less memory (compression will be slightly
+// slower, and raw/dynamic blocks will be output more frequently).
+#define TDEFL_LESS_MEMORY 0
+
+// tdefl_init() compression flags logically OR'd together (low 12 bits contain
+// the max. number of probes per dictionary search):
+// TDEFL_DEFAULT_MAX_PROBES: The compressor defaults to 128 dictionary probes
+// per dictionary search. 0=Huffman only, 1=Huffman+LZ (fastest/crap
+// compression), 4095=Huffman+LZ (slowest/best compression).
+enum {
+ TDEFL_HUFFMAN_ONLY = 0,
+ TDEFL_DEFAULT_MAX_PROBES = 128,
+ TDEFL_MAX_PROBES_MASK = 0xFFF
+};
+
+// TDEFL_WRITE_ZLIB_HEADER: If set, the compressor outputs a zlib header before
+// the deflate data, and the Adler-32 of the source data at the end. Otherwise,
+// you'll get raw deflate data.
+// TDEFL_COMPUTE_ADLER32: Always compute the adler-32 of the input data (even
+// when not writing zlib headers).
+// TDEFL_GREEDY_PARSING_FLAG: Set to use faster greedy parsing, instead of more
+// efficient lazy parsing.
+// TDEFL_NONDETERMINISTIC_PARSING_FLAG: Enable to decrease the compressor's
+// initialization time to the minimum, but the output may vary from run to run
+// given the same input (depending on the contents of memory).
+// TDEFL_RLE_MATCHES: Only look for RLE matches (matches with a distance of 1)
+// TDEFL_FILTER_MATCHES: Discards matches <= 5 chars if enabled.
+// TDEFL_FORCE_ALL_STATIC_BLOCKS: Disable usage of optimized Huffman tables.
+// TDEFL_FORCE_ALL_RAW_BLOCKS: Only use raw (uncompressed) deflate blocks.
+// The low 12 bits are reserved to control the max # of hash probes per
+// dictionary lookup (see TDEFL_MAX_PROBES_MASK).
+enum {
+ TDEFL_WRITE_ZLIB_HEADER = 0x01000,
+ TDEFL_COMPUTE_ADLER32 = 0x02000,
+ TDEFL_GREEDY_PARSING_FLAG = 0x04000,
+ TDEFL_NONDETERMINISTIC_PARSING_FLAG = 0x08000,
+ TDEFL_RLE_MATCHES = 0x10000,
+ TDEFL_FILTER_MATCHES = 0x20000,
+ TDEFL_FORCE_ALL_STATIC_BLOCKS = 0x40000,
+ TDEFL_FORCE_ALL_RAW_BLOCKS = 0x80000
+};
+
+// High level compression functions:
+// tdefl_compress_mem_to_heap() compresses a block in memory to a heap block
+// allocated via malloc().
+// On entry:
+// pSrc_buf, src_buf_len: Pointer and size of source block to compress.
+// flags: The max match finder probes (default is 128) logically OR'd against
+// the above flags. Higher probes are slower but improve compression.
+// On return:
+// Function returns a pointer to the compressed data, or NULL on failure.
+// *pOut_len will be set to the compressed data's size, which could be larger
+// than src_buf_len on uncompressible data.
+// The caller must free() the returned block when it's no longer needed.
+void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len,
+ size_t *pOut_len, int flags);
+
+// tdefl_compress_mem_to_mem() compresses a block in memory to another block in
+// memory.
+// Returns 0 on failure.
+size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
+ const void *pSrc_buf, size_t src_buf_len,
+ int flags);
+
+// Compresses an image to a compressed PNG file in memory.
+// On entry:
+// pImage, w, h, and num_chans describe the image to compress. num_chans may be
+// 1, 2, 3, or 4.
+// The image pitch in bytes per scanline will be w*num_chans. The leftmost
+// pixel on the top scanline is stored first in memory.
+// level may range from [0,10], use MZ_NO_COMPRESSION, MZ_BEST_SPEED,
+// MZ_BEST_COMPRESSION, etc. or a decent default is MZ_DEFAULT_LEVEL
+// If flip is true, the image will be flipped on the Y axis (useful for OpenGL
+// apps).
+// On return:
+// Function returns a pointer to the compressed data, or NULL on failure.
+// *pLen_out will be set to the size of the PNG image file.
+// The caller must mz_free() the returned heap block (which will typically be
+// larger than *pLen_out) when it's no longer needed.
+void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w,
+ int h, int num_chans,
+ size_t *pLen_out,
+ mz_uint level, mz_bool flip);
+void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
+ int num_chans, size_t *pLen_out);
+
+// Output stream interface. The compressor uses this interface to write
+// compressed data. It'll typically be called TDEFL_OUT_BUF_SIZE at a time.
+typedef mz_bool (*tdefl_put_buf_func_ptr)(const void *pBuf, int len,
+ void *pUser);
+
+// tdefl_compress_mem_to_output() compresses a block to an output stream. The
+// above helpers use this function internally.
+mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len,
+ tdefl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags);
+
+enum {
+ TDEFL_MAX_HUFF_TABLES = 3,
+ TDEFL_MAX_HUFF_SYMBOLS_0 = 288,
+ TDEFL_MAX_HUFF_SYMBOLS_1 = 32,
+ TDEFL_MAX_HUFF_SYMBOLS_2 = 19,
+ TDEFL_LZ_DICT_SIZE = 32768,
+ TDEFL_LZ_DICT_SIZE_MASK = TDEFL_LZ_DICT_SIZE - 1,
+ TDEFL_MIN_MATCH_LEN = 3,
+ TDEFL_MAX_MATCH_LEN = 258
+};
+
+// TDEFL_OUT_BUF_SIZE MUST be large enough to hold a single entire compressed
+// output block (using static/fixed Huffman codes).
+#if TDEFL_LESS_MEMORY
+enum {
+ TDEFL_LZ_CODE_BUF_SIZE = 24 * 1024,
+ TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
+ TDEFL_MAX_HUFF_SYMBOLS = 288,
+ TDEFL_LZ_HASH_BITS = 12,
+ TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
+ TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
+ TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
+};
+#else
+enum {
+ TDEFL_LZ_CODE_BUF_SIZE = 64 * 1024,
+ TDEFL_OUT_BUF_SIZE = (TDEFL_LZ_CODE_BUF_SIZE * 13) / 10,
+ TDEFL_MAX_HUFF_SYMBOLS = 288,
+ TDEFL_LZ_HASH_BITS = 15,
+ TDEFL_LEVEL1_HASH_SIZE_MASK = 4095,
+ TDEFL_LZ_HASH_SHIFT = (TDEFL_LZ_HASH_BITS + 2) / 3,
+ TDEFL_LZ_HASH_SIZE = 1 << TDEFL_LZ_HASH_BITS
+};
+#endif
+
+// The low-level tdefl functions below may be used directly if the above helper
+// functions aren't flexible enough. The low-level functions don't make any heap
+// allocations, unlike the above helper functions.
+typedef enum {
+ TDEFL_STATUS_BAD_PARAM = -2,
+ TDEFL_STATUS_PUT_BUF_FAILED = -1,
+ TDEFL_STATUS_OKAY = 0,
+ TDEFL_STATUS_DONE = 1
+} tdefl_status;
+
+// Must map to MZ_NO_FLUSH, MZ_SYNC_FLUSH, etc. enums
+typedef enum {
+ TDEFL_NO_FLUSH = 0,
+ TDEFL_SYNC_FLUSH = 2,
+ TDEFL_FULL_FLUSH = 3,
+ TDEFL_FINISH = 4
+} tdefl_flush;
+
+// tdefl's compression state structure.
+typedef struct {
+ tdefl_put_buf_func_ptr m_pPut_buf_func;
+ void *m_pPut_buf_user;
+ mz_uint m_flags, m_max_probes[2];
+ int m_greedy_parsing;
+ mz_uint m_adler32, m_lookahead_pos, m_lookahead_size, m_dict_size;
+ mz_uint8 *m_pLZ_code_buf, *m_pLZ_flags, *m_pOutput_buf, *m_pOutput_buf_end;
+ mz_uint m_num_flags_left, m_total_lz_bytes, m_lz_code_buf_dict_pos, m_bits_in,
+ m_bit_buffer;
+ mz_uint m_saved_match_dist, m_saved_match_len, m_saved_lit,
+ m_output_flush_ofs, m_output_flush_remaining, m_finished, m_block_index,
+ m_wants_to_finish;
+ tdefl_status m_prev_return_status;
+ const void *m_pIn_buf;
+ void *m_pOut_buf;
+ size_t *m_pIn_buf_size, *m_pOut_buf_size;
+ tdefl_flush m_flush;
+ const mz_uint8 *m_pSrc;
+ size_t m_src_buf_left, m_out_buf_ofs;
+ mz_uint8 m_dict[TDEFL_LZ_DICT_SIZE + TDEFL_MAX_MATCH_LEN - 1];
+ mz_uint16 m_huff_count[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint16 m_huff_codes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_huff_code_sizes[TDEFL_MAX_HUFF_TABLES][TDEFL_MAX_HUFF_SYMBOLS];
+ mz_uint8 m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE];
+ mz_uint16 m_next[TDEFL_LZ_DICT_SIZE];
+ mz_uint16 m_hash[TDEFL_LZ_HASH_SIZE];
+ mz_uint8 m_output_buf[TDEFL_OUT_BUF_SIZE];
+} tdefl_compressor;
+
+// Initializes the compressor.
+// There is no corresponding deinit() function because the tdefl API's do not
+// dynamically allocate memory.
+// pBut_buf_func: If NULL, output data will be supplied to the specified
+// callback. In this case, the user should call the tdefl_compress_buffer() API
+// for compression.
+// If pBut_buf_func is NULL the user should always call the tdefl_compress()
+// API.
+// flags: See the above enums (TDEFL_HUFFMAN_ONLY, TDEFL_WRITE_ZLIB_HEADER,
+// etc.)
+tdefl_status tdefl_init(tdefl_compressor *d,
+ tdefl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags);
+
+// Compresses a block of data, consuming as much of the specified input buffer
+// as possible, and writing as much compressed data to the specified output
+// buffer as possible.
+tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf,
+ size_t *pIn_buf_size, void *pOut_buf,
+ size_t *pOut_buf_size, tdefl_flush flush);
+
+// tdefl_compress_buffer() is only usable when the tdefl_init() is called with a
+// non-NULL tdefl_put_buf_func_ptr.
+// tdefl_compress_buffer() always consumes the entire input buffer.
+tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf,
+ size_t in_buf_size, tdefl_flush flush);
+
+tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d);
+mz_uint32 tdefl_get_adler32(tdefl_compressor *d);
+
+// Can't use tdefl_create_comp_flags_from_zip_params if MINIZ_NO_ZLIB_APIS isn't
+// defined, because it uses some of its macros.
+#ifndef MINIZ_NO_ZLIB_APIS
+// Create tdefl_compress() flags given zlib-style compression parameters.
+// level may range from [0,10] (where 10 is absolute max compression, but may be
+// much slower on some files)
+// window_bits may be -15 (raw deflate) or 15 (zlib)
+// strategy may be either MZ_DEFAULT_STRATEGY, MZ_FILTERED, MZ_HUFFMAN_ONLY,
+// MZ_RLE, or MZ_FIXED
+mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
+ int strategy);
+#endif // #ifndef MINIZ_NO_ZLIB_APIS
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MINIZ_HEADER_INCLUDED
+
+// ------------------- End of Header: Implementation follows. (If you only want
+// the header, define MINIZ_HEADER_FILE_ONLY.)
+
+#ifndef MINIZ_HEADER_FILE_ONLY
+
+typedef unsigned char mz_validate_uint16[sizeof(mz_uint16) == 2 ? 1 : -1];
+typedef unsigned char mz_validate_uint32[sizeof(mz_uint32) == 4 ? 1 : -1];
+typedef unsigned char mz_validate_uint64[sizeof(mz_uint64) == 8 ? 1 : -1];
+
+//#include <assert.h>
+//#include <string.h>
+
+#define MZ_ASSERT(x) assert(x)
+
+#ifdef MINIZ_NO_MALLOC
+#define MZ_MALLOC(x) NULL
+#define MZ_FREE(x) (void)x, ((void)0)
+#define MZ_REALLOC(p, x) NULL
+#else
+#define MZ_MALLOC(x) malloc(x)
+#define MZ_FREE(x) free(x)
+#define MZ_REALLOC(p, x) realloc(p, x)
+#endif
+
+#define MZ_MAX(a, b) (((a) > (b)) ? (a) : (b))
+#define MZ_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
+#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
+#else
+#define MZ_READ_LE16(p) \
+ ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
+ ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
+#define MZ_READ_LE32(p) \
+ ((mz_uint32)(((const mz_uint8 *)(p))[0]) | \
+ ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | \
+ ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | \
+ ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
+#endif
+
+#ifdef _MSC_VER
+#define MZ_FORCEINLINE __forceinline
+#elif defined(__GNUC__)
+#define MZ_FORCEINLINE inline __attribute__((__always_inline__))
+#else
+#define MZ_FORCEINLINE inline
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ------------------- zlib-style API's
+
+mz_ulong mz_adler32(mz_ulong adler, const unsigned char *ptr, size_t buf_len) {
+ mz_uint32 i, s1 = (mz_uint32)(adler & 0xffff), s2 = (mz_uint32)(adler >> 16);
+ size_t block_len = buf_len % 5552;
+ if (!ptr) return MZ_ADLER32_INIT;
+ while (buf_len) {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
+ s1 += ptr[0], s2 += s1;
+ s1 += ptr[1], s2 += s1;
+ s1 += ptr[2], s2 += s1;
+ s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1;
+ s1 += ptr[5], s2 += s1;
+ s1 += ptr[6], s2 += s1;
+ s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U;
+ buf_len -= block_len;
+ block_len = 5552;
+ }
+ return (s2 << 16) + s1;
+}
+
+// Karl Malbrain's compact CRC-32. See "A compact CCITT crc16 and crc32 C
+// implementation that balances processor cache usage against speed":
+// http://www.geocities.com/malbrain/
+mz_ulong mz_crc32(mz_ulong crc, const mz_uint8 *ptr, size_t buf_len) {
+ static const mz_uint32 s_crc32[16] = {
+ 0, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4,
+ 0x4db26158, 0x5005713c, 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
+ 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c};
+ mz_uint32 crcu32 = (mz_uint32)crc;
+ if (!ptr) return MZ_CRC32_INIT;
+ crcu32 = ~crcu32;
+ while (buf_len--) {
+ mz_uint8 b = *ptr++;
+ crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b & 0xF)];
+ crcu32 = (crcu32 >> 4) ^ s_crc32[(crcu32 & 0xF) ^ (b >> 4)];
+ }
+ return ~crcu32;
+}
+
+void mz_free(void *p) { MZ_FREE(p); }
+
+#ifndef MINIZ_NO_ZLIB_APIS
+
+static void *def_alloc_func(void *opaque, size_t items, size_t size) {
+ (void)opaque, (void)items, (void)size;
+ return MZ_MALLOC(items * size);
+}
+static void def_free_func(void *opaque, void *address) {
+ (void)opaque, (void)address;
+ MZ_FREE(address);
+}
+static void *def_realloc_func(void *opaque, void *address, size_t items,
+ size_t size) {
+ (void)opaque, (void)address, (void)items, (void)size;
+ return MZ_REALLOC(address, items * size);
+}
+
+const char *mz_version(void) { return MZ_VERSION; }
+
+int mz_deflateInit(mz_streamp pStream, int level) {
+ return mz_deflateInit2(pStream, level, MZ_DEFLATED, MZ_DEFAULT_WINDOW_BITS, 9,
+ MZ_DEFAULT_STRATEGY);
+}
+
+int mz_deflateInit2(mz_streamp pStream, int level, int method, int window_bits,
+ int mem_level, int strategy) {
+ tdefl_compressor *pComp;
+ mz_uint comp_flags =
+ TDEFL_COMPUTE_ADLER32 |
+ tdefl_create_comp_flags_from_zip_params(level, window_bits, strategy);
+
+ if (!pStream) return MZ_STREAM_ERROR;
+ if ((method != MZ_DEFLATED) || ((mem_level < 1) || (mem_level > 9)) ||
+ ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
+ (-window_bits != MZ_DEFAULT_WINDOW_BITS)))
+ return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = MZ_ADLER32_INIT;
+ pStream->msg = NULL;
+ pStream->reserved = 0;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
+ if (!pStream->zfree) pStream->zfree = def_free_func;
+
+ pComp = (tdefl_compressor *)pStream->zalloc(pStream->opaque, 1,
+ sizeof(tdefl_compressor));
+ if (!pComp) return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pComp;
+
+ if (tdefl_init(pComp, NULL, NULL, comp_flags) != TDEFL_STATUS_OKAY) {
+ mz_deflateEnd(pStream);
+ return MZ_PARAM_ERROR;
+ }
+
+ return MZ_OK;
+}
+
+int mz_deflateReset(mz_streamp pStream) {
+ if ((!pStream) || (!pStream->state) || (!pStream->zalloc) ||
+ (!pStream->zfree))
+ return MZ_STREAM_ERROR;
+ pStream->total_in = pStream->total_out = 0;
+ tdefl_init((tdefl_compressor *)pStream->state, NULL, NULL,
+ ((tdefl_compressor *)pStream->state)->m_flags);
+ return MZ_OK;
+}
+
+int mz_deflate(mz_streamp pStream, int flush) {
+ size_t in_bytes, out_bytes;
+ mz_ulong orig_total_in, orig_total_out;
+ int mz_status = MZ_OK;
+
+ if ((!pStream) || (!pStream->state) || (flush < 0) || (flush > MZ_FINISH) ||
+ (!pStream->next_out))
+ return MZ_STREAM_ERROR;
+ if (!pStream->avail_out) return MZ_BUF_ERROR;
+
+ if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
+
+ if (((tdefl_compressor *)pStream->state)->m_prev_return_status ==
+ TDEFL_STATUS_DONE)
+ return (flush == MZ_FINISH) ? MZ_STREAM_END : MZ_BUF_ERROR;
+
+ orig_total_in = pStream->total_in;
+ orig_total_out = pStream->total_out;
+ for (;;) {
+ tdefl_status defl_status;
+ in_bytes = pStream->avail_in;
+ out_bytes = pStream->avail_out;
+
+ defl_status = tdefl_compress((tdefl_compressor *)pStream->state,
+ pStream->next_in, &in_bytes, pStream->next_out,
+ &out_bytes, (tdefl_flush)flush);
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tdefl_get_adler32((tdefl_compressor *)pStream->state);
+
+ pStream->next_out += (mz_uint)out_bytes;
+ pStream->avail_out -= (mz_uint)out_bytes;
+ pStream->total_out += (mz_uint)out_bytes;
+
+ if (defl_status < 0) {
+ mz_status = MZ_STREAM_ERROR;
+ break;
+ } else if (defl_status == TDEFL_STATUS_DONE) {
+ mz_status = MZ_STREAM_END;
+ break;
+ } else if (!pStream->avail_out)
+ break;
+ else if ((!pStream->avail_in) && (flush != MZ_FINISH)) {
+ if ((flush) || (pStream->total_in != orig_total_in) ||
+ (pStream->total_out != orig_total_out))
+ break;
+ return MZ_BUF_ERROR; // Can't make forward progress without some input.
+ }
+ }
+ return mz_status;
+}
+
+int mz_deflateEnd(mz_streamp pStream) {
+ if (!pStream) return MZ_STREAM_ERROR;
+ if (pStream->state) {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+mz_ulong mz_deflateBound(mz_streamp pStream, mz_ulong source_len) {
+ (void)pStream;
+ // This is really over conservative. (And lame, but it's actually pretty
+ // tricky to compute a true upper bound given the way tdefl's blocking works.)
+ return MZ_MAX(128 + (source_len * 110) / 100,
+ 128 + source_len + ((source_len / (31 * 1024)) + 1) * 5);
+}
+
+int mz_compress2(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len, int level) {
+ int status;
+ mz_stream stream;
+ memset(&stream, 0, sizeof(stream));
+
+ // In case mz_ulong is 64-bits (argh I hate longs).
+ if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)source_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_deflateInit(&stream, level);
+ if (status != MZ_OK) return status;
+
+ status = mz_deflate(&stream, MZ_FINISH);
+ if (status != MZ_STREAM_END) {
+ mz_deflateEnd(&stream);
+ return (status == MZ_OK) ? MZ_BUF_ERROR : status;
+ }
+
+ *pDest_len = stream.total_out;
+ return mz_deflateEnd(&stream);
+}
+
+int mz_compress(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len) {
+ return mz_compress2(pDest, pDest_len, pSource, source_len,
+ MZ_DEFAULT_COMPRESSION);
+}
+
+mz_ulong mz_compressBound(mz_ulong source_len) {
+ return mz_deflateBound(NULL, source_len);
+}
+
+typedef struct {
+ tinfl_decompressor m_decomp;
+ mz_uint m_dict_ofs, m_dict_avail, m_first_call, m_has_flushed;
+ int m_window_bits;
+ mz_uint8 m_dict[TINFL_LZ_DICT_SIZE];
+ tinfl_status m_last_status;
+} inflate_state;
+
+int mz_inflateInit2(mz_streamp pStream, int window_bits) {
+ inflate_state *pDecomp;
+ if (!pStream) return MZ_STREAM_ERROR;
+ if ((window_bits != MZ_DEFAULT_WINDOW_BITS) &&
+ (-window_bits != MZ_DEFAULT_WINDOW_BITS))
+ return MZ_PARAM_ERROR;
+
+ pStream->data_type = 0;
+ pStream->adler = 0;
+ pStream->msg = NULL;
+ pStream->total_in = 0;
+ pStream->total_out = 0;
+ pStream->reserved = 0;
+ if (!pStream->zalloc) pStream->zalloc = def_alloc_func;
+ if (!pStream->zfree) pStream->zfree = def_free_func;
+
+ pDecomp = (inflate_state *)pStream->zalloc(pStream->opaque, 1,
+ sizeof(inflate_state));
+ if (!pDecomp) return MZ_MEM_ERROR;
+
+ pStream->state = (struct mz_internal_state *)pDecomp;
+
+ tinfl_init(&pDecomp->m_decomp);
+ pDecomp->m_dict_ofs = 0;
+ pDecomp->m_dict_avail = 0;
+ pDecomp->m_last_status = TINFL_STATUS_NEEDS_MORE_INPUT;
+ pDecomp->m_first_call = 1;
+ pDecomp->m_has_flushed = 0;
+ pDecomp->m_window_bits = window_bits;
+
+ return MZ_OK;
+}
+
+int mz_inflateInit(mz_streamp pStream) {
+ return mz_inflateInit2(pStream, MZ_DEFAULT_WINDOW_BITS);
+}
+
+int mz_inflate(mz_streamp pStream, int flush) {
+ inflate_state *pState;
+ mz_uint n, first_call, decomp_flags = TINFL_FLAG_COMPUTE_ADLER32;
+ size_t in_bytes, out_bytes, orig_avail_in;
+ tinfl_status status;
+
+ if ((!pStream) || (!pStream->state)) return MZ_STREAM_ERROR;
+ if (flush == MZ_PARTIAL_FLUSH) flush = MZ_SYNC_FLUSH;
+ if ((flush) && (flush != MZ_SYNC_FLUSH) && (flush != MZ_FINISH))
+ return MZ_STREAM_ERROR;
+
+ pState = (inflate_state *)pStream->state;
+ if (pState->m_window_bits > 0) decomp_flags |= TINFL_FLAG_PARSE_ZLIB_HEADER;
+ orig_avail_in = pStream->avail_in;
+
+ first_call = pState->m_first_call;
+ pState->m_first_call = 0;
+ if (pState->m_last_status < 0) return MZ_DATA_ERROR;
+
+ if (pState->m_has_flushed && (flush != MZ_FINISH)) return MZ_STREAM_ERROR;
+ pState->m_has_flushed |= (flush == MZ_FINISH);
+
+ if ((flush == MZ_FINISH) && (first_call)) {
+ // MZ_FINISH on the first call implies that the input and output buffers are
+ // large enough to hold the entire compressed/decompressed file.
+ decomp_flags |= TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF;
+ in_bytes = pStream->avail_in;
+ out_bytes = pStream->avail_out;
+ status = tinfl_decompress(&pState->m_decomp, pStream->next_in, &in_bytes,
+ pStream->next_out, pStream->next_out, &out_bytes,
+ decomp_flags);
+ pState->m_last_status = status;
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+ pStream->next_out += (mz_uint)out_bytes;
+ pStream->avail_out -= (mz_uint)out_bytes;
+ pStream->total_out += (mz_uint)out_bytes;
+
+ if (status < 0)
+ return MZ_DATA_ERROR;
+ else if (status != TINFL_STATUS_DONE) {
+ pState->m_last_status = TINFL_STATUS_FAILED;
+ return MZ_BUF_ERROR;
+ }
+ return MZ_STREAM_END;
+ }
+ // flush != MZ_FINISH then we must assume there's more input.
+ if (flush != MZ_FINISH) decomp_flags |= TINFL_FLAG_HAS_MORE_INPUT;
+
+ if (pState->m_dict_avail) {
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n;
+ pStream->avail_out -= n;
+ pStream->total_out += n;
+ pState->m_dict_avail -= n;
+ pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+ return ((pState->m_last_status == TINFL_STATUS_DONE) &&
+ (!pState->m_dict_avail))
+ ? MZ_STREAM_END
+ : MZ_OK;
+ }
+
+ for (;;) {
+ in_bytes = pStream->avail_in;
+ out_bytes = TINFL_LZ_DICT_SIZE - pState->m_dict_ofs;
+
+ status = tinfl_decompress(
+ &pState->m_decomp, pStream->next_in, &in_bytes, pState->m_dict,
+ pState->m_dict + pState->m_dict_ofs, &out_bytes, decomp_flags);
+ pState->m_last_status = status;
+
+ pStream->next_in += (mz_uint)in_bytes;
+ pStream->avail_in -= (mz_uint)in_bytes;
+ pStream->total_in += (mz_uint)in_bytes;
+ pStream->adler = tinfl_get_adler32(&pState->m_decomp);
+
+ pState->m_dict_avail = (mz_uint)out_bytes;
+
+ n = MZ_MIN(pState->m_dict_avail, pStream->avail_out);
+ memcpy(pStream->next_out, pState->m_dict + pState->m_dict_ofs, n);
+ pStream->next_out += n;
+ pStream->avail_out -= n;
+ pStream->total_out += n;
+ pState->m_dict_avail -= n;
+ pState->m_dict_ofs = (pState->m_dict_ofs + n) & (TINFL_LZ_DICT_SIZE - 1);
+
+ if (status < 0)
+ return MZ_DATA_ERROR; // Stream is corrupted (there could be some
+ // uncompressed data left in the output dictionary -
+ // oh well).
+ else if ((status == TINFL_STATUS_NEEDS_MORE_INPUT) && (!orig_avail_in))
+ return MZ_BUF_ERROR; // Signal caller that we can't make forward progress
+ // without supplying more input or by setting flush
+ // to MZ_FINISH.
+ else if (flush == MZ_FINISH) {
+ // The output buffer MUST be large to hold the remaining uncompressed data
+ // when flush==MZ_FINISH.
+ if (status == TINFL_STATUS_DONE)
+ return pState->m_dict_avail ? MZ_BUF_ERROR : MZ_STREAM_END;
+ // status here must be TINFL_STATUS_HAS_MORE_OUTPUT, which means there's
+ // at least 1 more byte on the way. If there's no more room left in the
+ // output buffer then something is wrong.
+ else if (!pStream->avail_out)
+ return MZ_BUF_ERROR;
+ } else if ((status == TINFL_STATUS_DONE) || (!pStream->avail_in) ||
+ (!pStream->avail_out) || (pState->m_dict_avail))
+ break;
+ }
+
+ return ((status == TINFL_STATUS_DONE) && (!pState->m_dict_avail))
+ ? MZ_STREAM_END
+ : MZ_OK;
+}
+
+int mz_inflateEnd(mz_streamp pStream) {
+ if (!pStream) return MZ_STREAM_ERROR;
+ if (pStream->state) {
+ pStream->zfree(pStream->opaque, pStream->state);
+ pStream->state = NULL;
+ }
+ return MZ_OK;
+}
+
+int mz_uncompress(unsigned char *pDest, mz_ulong *pDest_len,
+ const unsigned char *pSource, mz_ulong source_len) {
+ mz_stream stream;
+ int status;
+ memset(&stream, 0, sizeof(stream));
+
+ // In case mz_ulong is 64-bits (argh I hate longs).
+ if ((source_len | *pDest_len) > 0xFFFFFFFFU) return MZ_PARAM_ERROR;
+
+ stream.next_in = pSource;
+ stream.avail_in = (mz_uint32)source_len;
+ stream.next_out = pDest;
+ stream.avail_out = (mz_uint32)*pDest_len;
+
+ status = mz_inflateInit(&stream);
+ if (status != MZ_OK) return status;
+
+ status = mz_inflate(&stream, MZ_FINISH);
+ if (status != MZ_STREAM_END) {
+ mz_inflateEnd(&stream);
+ return ((status == MZ_BUF_ERROR) && (!stream.avail_in)) ? MZ_DATA_ERROR
+ : status;
+ }
+ *pDest_len = stream.total_out;
+
+ return mz_inflateEnd(&stream);
+}
+
+const char *mz_error(int err) {
+ static struct {
+ int m_err;
+ const char *m_pDesc;
+ } s_error_descs[] = {{MZ_OK, ""},
+ {MZ_STREAM_END, "stream end"},
+ {MZ_NEED_DICT, "need dictionary"},
+ {MZ_ERRNO, "file error"},
+ {MZ_STREAM_ERROR, "stream error"},
+ {MZ_DATA_ERROR, "data error"},
+ {MZ_MEM_ERROR, "out of memory"},
+ {MZ_BUF_ERROR, "buf error"},
+ {MZ_VERSION_ERROR, "version error"},
+ {MZ_PARAM_ERROR, "parameter error"}};
+ mz_uint i;
+ for (i = 0; i < sizeof(s_error_descs) / sizeof(s_error_descs[0]); ++i)
+ if (s_error_descs[i].m_err == err) return s_error_descs[i].m_pDesc;
+ return NULL;
+}
+
+#endif // MINIZ_NO_ZLIB_APIS
+
+// ------------------- Low-level Decompression (completely independent from all
+// compression API's)
+
+#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
+#define TINFL_MEMSET(p, c, l) memset(p, c, l)
+
+#define TINFL_CR_BEGIN \
+ switch (r->m_state) { \
+ case 0:
+#define TINFL_CR_RETURN(state_index, result) \
+ do { \
+ status = result; \
+ r->m_state = state_index; \
+ goto common_exit; \
+ case state_index:; \
+ } \
+ MZ_MACRO_END
+#define TINFL_CR_RETURN_FOREVER(state_index, result) \
+ do { \
+ for (;;) { \
+ TINFL_CR_RETURN(state_index, result); \
+ } \
+ } \
+ MZ_MACRO_END
+#define TINFL_CR_FINISH }
+
+// TODO: If the caller has indicated that there's no more input, and we attempt
+// to read beyond the input buf, then something is wrong with the input because
+// the inflator never
+// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of
+// the stream with 0's in this scenario.
+#define TINFL_GET_BYTE(state_index, c) \
+ do { \
+ if (pIn_buf_cur >= pIn_buf_end) { \
+ for (;;) { \
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
+ TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
+ if (pIn_buf_cur < pIn_buf_end) { \
+ c = *pIn_buf_cur++; \
+ break; \
+ } \
+ } else { \
+ c = 0; \
+ break; \
+ } \
+ } \
+ } else \
+ c = *pIn_buf_cur++; \
+ } \
+ MZ_MACRO_END
+
+#define TINFL_NEED_BITS(state_index, n) \
+ do { \
+ mz_uint c; \
+ TINFL_GET_BYTE(state_index, c); \
+ bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
+ num_bits += 8; \
+ } while (num_bits < (mz_uint)(n))
+#define TINFL_SKIP_BITS(state_index, n) \
+ do { \
+ if (num_bits < (mz_uint)(n)) { \
+ TINFL_NEED_BITS(state_index, n); \
+ } \
+ bit_buf >>= (n); \
+ num_bits -= (n); \
+ } \
+ MZ_MACRO_END
+#define TINFL_GET_BITS(state_index, b, n) \
+ do { \
+ if (num_bits < (mz_uint)(n)) { \
+ TINFL_NEED_BITS(state_index, n); \
+ } \
+ b = bit_buf & ((1 << (n)) - 1); \
+ bit_buf >>= (n); \
+ num_bits -= (n); \
+ } \
+ MZ_MACRO_END
+
+// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes
+// remaining in the input buffer falls below 2.
+// It reads just enough bytes from the input stream that are needed to decode
+// the next Huffman code (and absolutely no more). It works by trying to fully
+// decode a
+// Huffman code by using whatever bits are currently present in the bit buffer.
+// If this fails, it reads another byte, and tries again until it succeeds or
+// until the
+// bit buffer contains >=15 bits (deflate's max. Huffman code size).
+#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
+ do { \
+ temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
+ if (temp >= 0) { \
+ code_len = temp >> 9; \
+ if ((code_len) && (num_bits >= code_len)) break; \
+ } else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while ((temp < 0) && (num_bits >= (code_len + 1))); \
+ if (temp >= 0) break; \
+ } \
+ TINFL_GET_BYTE(state_index, c); \
+ bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); \
+ num_bits += 8; \
+ } while (num_bits < 15);
+
+// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex
+// than you would initially expect because the zlib API expects the decompressor
+// to never read
+// beyond the final byte of the deflate stream. (In other words, when this macro
+// wants to read another byte from the input, it REALLY needs another byte in
+// order to fully
+// decode the next Huffman code.) Handling this properly is particularly
+// important on raw deflate (non-zlib) streams, which aren't followed by a byte
+// aligned adler-32.
+// The slow path is only executed at the very end of the input buffer.
+#define TINFL_HUFF_DECODE(state_index, sym, pHuff) \
+ do { \
+ int temp; \
+ mz_uint code_len, c; \
+ if (num_bits < 15) { \
+ if ((pIn_buf_end - pIn_buf_cur) < 2) { \
+ TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
+ } else { \
+ bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | \
+ (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); \
+ pIn_buf_cur += 2; \
+ num_bits += 16; \
+ } \
+ } \
+ if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= \
+ 0) \
+ code_len = temp >> 9, temp &= 511; \
+ else { \
+ code_len = TINFL_FAST_LOOKUP_BITS; \
+ do { \
+ temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
+ } while (temp < 0); \
+ } \
+ sym = temp; \
+ bit_buf >>= code_len; \
+ num_bits -= code_len; \
+ } \
+ MZ_MACRO_END
+
+tinfl_status tinfl_decompress(tinfl_decompressor *r,
+ const mz_uint8 *pIn_buf_next,
+ size_t *pIn_buf_size, mz_uint8 *pOut_buf_start,
+ mz_uint8 *pOut_buf_next, size_t *pOut_buf_size,
+ const mz_uint32 decomp_flags) {
+ static const int s_length_base[31] = {
+ 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+ 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+ static const int s_length_extra[31] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1,
+ 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
+ 4, 4, 5, 5, 5, 5, 0, 0, 0};
+ static const int s_dist_base[32] = {
+ 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33,
+ 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
+ 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0};
+ static const int s_dist_extra[32] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3,
+ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8,
+ 9, 9, 10, 10, 11, 11, 12, 12, 13, 13};
+ static const mz_uint8 s_length_dezigzag[19] = {
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+ static const int s_min_table_sizes[3] = {257, 1, 4};
+
+ tinfl_status status = TINFL_STATUS_FAILED;
+ mz_uint32 num_bits, dist, counter, num_extra;
+ tinfl_bit_buf_t bit_buf;
+ const mz_uint8 *pIn_buf_cur = pIn_buf_next,
+ *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
+ mz_uint8 *pOut_buf_cur = pOut_buf_next,
+ *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
+ size_t out_buf_size_mask =
+ (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)
+ ? (size_t)-1
+ : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1,
+ dist_from_out_buf_start;
+
+ // Ensure the output buffer's size is a power of 2, unless the output buffer
+ // is large enough to hold the entire output file (in which case it doesn't
+ // matter).
+ if (((out_buf_size_mask + 1) & out_buf_size_mask) ||
+ (pOut_buf_next < pOut_buf_start)) {
+ *pIn_buf_size = *pOut_buf_size = 0;
+ return TINFL_STATUS_BAD_PARAM;
+ }
+
+ num_bits = r->m_num_bits;
+ bit_buf = r->m_bit_buf;
+ dist = r->m_dist;
+ counter = r->m_counter;
+ num_extra = r->m_num_extra;
+ dist_from_out_buf_start = r->m_dist_from_out_buf_start;
+ TINFL_CR_BEGIN
+
+ bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0;
+ r->m_z_adler32 = r->m_check_adler32 = 1;
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
+ TINFL_GET_BYTE(1, r->m_zhdr0);
+ TINFL_GET_BYTE(2, r->m_zhdr1);
+ counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) ||
+ (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
+ if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
+ counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) ||
+ ((out_buf_size_mask + 1) <
+ (size_t)(1ULL << (8U + (r->m_zhdr0 >> 4)))));
+ if (counter) {
+ TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED);
+ }
+ }
+
+ do {
+ TINFL_GET_BITS(3, r->m_final, 3);
+ r->m_type = r->m_final >> 1;
+ if (r->m_type == 0) {
+ TINFL_SKIP_BITS(5, num_bits & 7);
+ for (counter = 0; counter < 4; ++counter) {
+ if (num_bits)
+ TINFL_GET_BITS(6, r->m_raw_header[counter], 8);
+ else
+ TINFL_GET_BYTE(7, r->m_raw_header[counter]);
+ }
+ if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) !=
+ (mz_uint)(0xFFFF ^
+ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) {
+ TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED);
+ }
+ while ((counter) && (num_bits)) {
+ TINFL_GET_BITS(51, dist, 8);
+ while (pOut_buf_cur >= pOut_buf_end) {
+ TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ = (mz_uint8)dist;
+ counter--;
+ }
+ while (counter) {
+ size_t n;
+ while (pOut_buf_cur >= pOut_buf_end) {
+ TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ while (pIn_buf_cur >= pIn_buf_end) {
+ if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) {
+ TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
+ } else {
+ TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
+ }
+ }
+ n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur),
+ (size_t)(pIn_buf_end - pIn_buf_cur)),
+ counter);
+ TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n);
+ pIn_buf_cur += n;
+ pOut_buf_cur += n;
+ counter -= (mz_uint)n;
+ }
+ } else if (r->m_type == 3) {
+ TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
+ } else {
+ if (r->m_type == 1) {
+ mz_uint8 *p = r->m_tables[0].m_code_size;
+ mz_uint i;
+ r->m_table_sizes[0] = 288;
+ r->m_table_sizes[1] = 32;
+ TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
+ for (i = 0; i <= 143; ++i) *p++ = 8;
+ for (; i <= 255; ++i) *p++ = 9;
+ for (; i <= 279; ++i) *p++ = 7;
+ for (; i <= 287; ++i) *p++ = 8;
+ } else {
+ for (counter = 0; counter < 3; counter++) {
+ TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]);
+ r->m_table_sizes[counter] += s_min_table_sizes[counter];
+ }
+ MZ_CLEAR_OBJ(r->m_tables[2].m_code_size);
+ for (counter = 0; counter < r->m_table_sizes[2]; counter++) {
+ mz_uint s;
+ TINFL_GET_BITS(14, s, 3);
+ r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s;
+ }
+ r->m_table_sizes[2] = 19;
+ }
+ for (; (int)r->m_type >= 0; r->m_type--) {
+ int tree_next, tree_cur;
+ tinfl_huff_table *pTable;
+ mz_uint i, j, used_syms, total, sym_index, next_code[17],
+ total_syms[16];
+ pTable = &r->m_tables[r->m_type];
+ MZ_CLEAR_OBJ(total_syms);
+ MZ_CLEAR_OBJ(pTable->m_look_up);
+ MZ_CLEAR_OBJ(pTable->m_tree);
+ for (i = 0; i < r->m_table_sizes[r->m_type]; ++i)
+ total_syms[pTable->m_code_size[i]]++;
+ used_syms = 0, total = 0;
+ next_code[0] = next_code[1] = 0;
+ for (i = 1; i <= 15; ++i) {
+ used_syms += total_syms[i];
+ next_code[i + 1] = (total = ((total + total_syms[i]) << 1));
+ }
+ if ((65536 != total) && (used_syms > 1)) {
+ TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
+ }
+ for (tree_next = -1, sym_index = 0;
+ sym_index < r->m_table_sizes[r->m_type]; ++sym_index) {
+ mz_uint rev_code = 0, l, cur_code,
+ code_size = pTable->m_code_size[sym_index];
+ if (!code_size) continue;
+ cur_code = next_code[code_size]++;
+ for (l = code_size; l > 0; l--, cur_code >>= 1)
+ rev_code = (rev_code << 1) | (cur_code & 1);
+ if (code_size <= TINFL_FAST_LOOKUP_BITS) {
+ mz_int16 k = (mz_int16)((code_size << 9) | sym_index);
+ while (rev_code < TINFL_FAST_LOOKUP_SIZE) {
+ pTable->m_look_up[rev_code] = k;
+ rev_code += (1 << code_size);
+ }
+ continue;
+ }
+ if (0 ==
+ (tree_cur = pTable->m_look_up[rev_code &
+ (TINFL_FAST_LOOKUP_SIZE - 1)])) {
+ pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] =
+ (mz_int16)tree_next;
+ tree_cur = tree_next;
+ tree_next -= 2;
+ }
+ rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
+ for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--) {
+ tree_cur -= ((rev_code >>= 1) & 1);
+ if (!pTable->m_tree[-tree_cur - 1]) {
+ pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next;
+ tree_cur = tree_next;
+ tree_next -= 2;
+ } else
+ tree_cur = pTable->m_tree[-tree_cur - 1];
+ }
+ tree_cur -= ((rev_code >>= 1) & 1);
+ pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
+ }
+ if (r->m_type == 2) {
+ for (counter = 0;
+ counter < (r->m_table_sizes[0] + r->m_table_sizes[1]);) {
+ mz_uint s;
+ TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]);
+ if (dist < 16) {
+ r->m_len_codes[counter++] = (mz_uint8)dist;
+ continue;
+ }
+ if ((dist == 16) && (!counter)) {
+ TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
+ }
+ num_extra = "\02\03\07"[dist - 16];
+ TINFL_GET_BITS(18, s, num_extra);
+ s += "\03\03\013"[dist - 16];
+ TINFL_MEMSET(r->m_len_codes + counter,
+ (dist == 16) ? r->m_len_codes[counter - 1] : 0, s);
+ counter += s;
+ }
+ if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter) {
+ TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
+ }
+ TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes,
+ r->m_table_sizes[0]);
+ TINFL_MEMCPY(r->m_tables[1].m_code_size,
+ r->m_len_codes + r->m_table_sizes[0],
+ r->m_table_sizes[1]);
+ }
+ }
+ for (;;) {
+ mz_uint8 *pSrc;
+ for (;;) {
+ if (((pIn_buf_end - pIn_buf_cur) < 4) ||
+ ((pOut_buf_end - pOut_buf_cur) < 2)) {
+ TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
+ if (counter >= 256) break;
+ while (pOut_buf_cur >= pOut_buf_end) {
+ TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ = (mz_uint8)counter;
+ } else {
+ int sym2;
+ mz_uint code_len;
+#if TINFL_USE_64BIT_BITBUF
+ if (num_bits < 30) {
+ bit_buf |=
+ (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 4;
+ num_bits += 32;
+ }
+#else
+ if (num_bits < 15) {
+ bit_buf |=
+ (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 2;
+ num_bits += 16;
+ }
+#endif
+ if ((sym2 =
+ r->m_tables[0]
+ .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
+ 0)
+ code_len = sym2 >> 9;
+ else {
+ code_len = TINFL_FAST_LOOKUP_BITS;
+ do {
+ sym2 = r->m_tables[0]
+ .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
+ } while (sym2 < 0);
+ }
+ counter = sym2;
+ bit_buf >>= code_len;
+ num_bits -= code_len;
+ if (counter & 256) break;
+
+#if !TINFL_USE_64BIT_BITBUF
+ if (num_bits < 15) {
+ bit_buf |=
+ (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits);
+ pIn_buf_cur += 2;
+ num_bits += 16;
+ }
+#endif
+ if ((sym2 =
+ r->m_tables[0]
+ .m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >=
+ 0)
+ code_len = sym2 >> 9;
+ else {
+ code_len = TINFL_FAST_LOOKUP_BITS;
+ do {
+ sym2 = r->m_tables[0]
+ .m_tree[~sym2 + ((bit_buf >> code_len++) & 1)];
+ } while (sym2 < 0);
+ }
+ bit_buf >>= code_len;
+ num_bits -= code_len;
+
+ pOut_buf_cur[0] = (mz_uint8)counter;
+ if (sym2 & 256) {
+ pOut_buf_cur++;
+ counter = sym2;
+ break;
+ }
+ pOut_buf_cur[1] = (mz_uint8)sym2;
+ pOut_buf_cur += 2;
+ }
+ }
+ if ((counter &= 511) == 256) break;
+
+ num_extra = s_length_extra[counter - 257];
+ counter = s_length_base[counter - 257];
+ if (num_extra) {
+ mz_uint extra_bits;
+ TINFL_GET_BITS(25, extra_bits, num_extra);
+ counter += extra_bits;
+ }
+
+ TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
+ num_extra = s_dist_extra[dist];
+ dist = s_dist_base[dist];
+ if (num_extra) {
+ mz_uint extra_bits;
+ TINFL_GET_BITS(27, extra_bits, num_extra);
+ dist += extra_bits;
+ }
+
+ dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
+ if ((dist > dist_from_out_buf_start) &&
+ (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) {
+ TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
+ }
+
+ pSrc = pOut_buf_start +
+ ((dist_from_out_buf_start - dist) & out_buf_size_mask);
+
+ if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end) {
+ while (counter--) {
+ while (pOut_buf_cur >= pOut_buf_end) {
+ TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT);
+ }
+ *pOut_buf_cur++ =
+ pOut_buf_start[(dist_from_out_buf_start++ - dist) &
+ out_buf_size_mask];
+ }
+ continue;
+ }
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+ else if ((counter >= 9) && (counter <= dist)) {
+ const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
+ do {
+ ((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
+ ((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
+ pOut_buf_cur += 8;
+ } while ((pSrc += 8) < pSrc_end);
+ if ((counter &= 7) < 3) {
+ if (counter) {
+ pOut_buf_cur[0] = pSrc[0];
+ if (counter > 1) pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ continue;
+ }
+ }
+#endif
+ do {
+ pOut_buf_cur[0] = pSrc[0];
+ pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur[2] = pSrc[2];
+ pOut_buf_cur += 3;
+ pSrc += 3;
+ } while ((int)(counter -= 3) > 2);
+ if ((int)counter > 0) {
+ pOut_buf_cur[0] = pSrc[0];
+ if ((int)counter > 1) pOut_buf_cur[1] = pSrc[1];
+ pOut_buf_cur += counter;
+ }
+ }
+ }
+ } while (!(r->m_final & 1));
+ if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) {
+ TINFL_SKIP_BITS(32, num_bits & 7);
+ for (counter = 0; counter < 4; ++counter) {
+ mz_uint s;
+ if (num_bits)
+ TINFL_GET_BITS(41, s, 8);
+ else
+ TINFL_GET_BYTE(42, s);
+ r->m_z_adler32 = (r->m_z_adler32 << 8) | s;
+ }
+ }
+ TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
+ TINFL_CR_FINISH
+
+common_exit:
+ r->m_num_bits = num_bits;
+ r->m_bit_buf = bit_buf;
+ r->m_dist = dist;
+ r->m_counter = counter;
+ r->m_num_extra = num_extra;
+ r->m_dist_from_out_buf_start = dist_from_out_buf_start;
+ *pIn_buf_size = pIn_buf_cur - pIn_buf_next;
+ *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
+ if ((decomp_flags &
+ (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) &&
+ (status >= 0)) {
+ const mz_uint8 *ptr = pOut_buf_next;
+ size_t buf_len = *pOut_buf_size;
+ mz_uint32 i, s1 = r->m_check_adler32 & 0xffff,
+ s2 = r->m_check_adler32 >> 16;
+ size_t block_len = buf_len % 5552;
+ while (buf_len) {
+ for (i = 0; i + 7 < block_len; i += 8, ptr += 8) {
+ s1 += ptr[0], s2 += s1;
+ s1 += ptr[1], s2 += s1;
+ s1 += ptr[2], s2 += s1;
+ s1 += ptr[3], s2 += s1;
+ s1 += ptr[4], s2 += s1;
+ s1 += ptr[5], s2 += s1;
+ s1 += ptr[6], s2 += s1;
+ s1 += ptr[7], s2 += s1;
+ }
+ for (; i < block_len; ++i) s1 += *ptr++, s2 += s1;
+ s1 %= 65521U, s2 %= 65521U;
+ buf_len -= block_len;
+ block_len = 5552;
+ }
+ r->m_check_adler32 = (s2 << 16) + s1;
+ if ((status == TINFL_STATUS_DONE) &&
+ (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) &&
+ (r->m_check_adler32 != r->m_z_adler32))
+ status = TINFL_STATUS_ADLER32_MISMATCH;
+ }
+ return status;
+}
+
+// Higher level helper functions.
+void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len,
+ size_t *pOut_len, int flags) {
+ tinfl_decompressor decomp;
+ void *pBuf = NULL, *pNew_buf;
+ size_t src_buf_ofs = 0, out_buf_capacity = 0;
+ *pOut_len = 0;
+ tinfl_init(&decomp);
+ for (;;) {
+ size_t src_buf_size = src_buf_len - src_buf_ofs,
+ dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
+ tinfl_status status = tinfl_decompress(
+ &decomp, (const mz_uint8 *)pSrc_buf + src_buf_ofs, &src_buf_size,
+ (mz_uint8 *)pBuf, pBuf ? (mz_uint8 *)pBuf + *pOut_len : NULL,
+ &dst_buf_size, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT)) {
+ MZ_FREE(pBuf);
+ *pOut_len = 0;
+ return NULL;
+ }
+ src_buf_ofs += src_buf_size;
+ *pOut_len += dst_buf_size;
+ if (status == TINFL_STATUS_DONE) break;
+ new_out_buf_capacity = out_buf_capacity * 2;
+ if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
+ pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
+ if (!pNew_buf) {
+ MZ_FREE(pBuf);
+ *pOut_len = 0;
+ return NULL;
+ }
+ pBuf = pNew_buf;
+ out_buf_capacity = new_out_buf_capacity;
+ }
+ return pBuf;
+}
+
+size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
+ const void *pSrc_buf, size_t src_buf_len,
+ int flags) {
+ tinfl_decompressor decomp;
+ tinfl_status status;
+ tinfl_init(&decomp);
+ status =
+ tinfl_decompress(&decomp, (const mz_uint8 *)pSrc_buf, &src_buf_len,
+ (mz_uint8 *)pOut_buf, (mz_uint8 *)pOut_buf, &out_buf_len,
+ (flags & ~TINFL_FLAG_HAS_MORE_INPUT) |
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
+ return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED
+ : out_buf_len;
+}
+
+int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size,
+ tinfl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags) {
+ int result = 0;
+ tinfl_decompressor decomp;
+ mz_uint8 *pDict = (mz_uint8 *)MZ_MALLOC(TINFL_LZ_DICT_SIZE);
+ size_t in_buf_ofs = 0, dict_ofs = 0;
+ if (!pDict) return TINFL_STATUS_FAILED;
+ tinfl_init(&decomp);
+ for (;;) {
+ size_t in_buf_size = *pIn_buf_size - in_buf_ofs,
+ dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
+ tinfl_status status =
+ tinfl_decompress(&decomp, (const mz_uint8 *)pIn_buf + in_buf_ofs,
+ &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
+ (flags &
+ ~(TINFL_FLAG_HAS_MORE_INPUT |
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
+ in_buf_ofs += in_buf_size;
+ if ((dst_buf_size) &&
+ (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
+ break;
+ if (status != TINFL_STATUS_HAS_MORE_OUTPUT) {
+ result = (status == TINFL_STATUS_DONE);
+ break;
+ }
+ dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
+ }
+ MZ_FREE(pDict);
+ *pIn_buf_size = in_buf_ofs;
+ return result;
+}
+
+// ------------------- Low-level Compression (independent from all decompression
+// API's)
+
+// Purposely making these tables static for faster init and thread safety.
+static const mz_uint16 s_tdefl_len_sym[256] = {
+ 257, 258, 259, 260, 261, 262, 263, 264, 265, 265, 266, 266, 267, 267, 268,
+ 268, 269, 269, 269, 269, 270, 270, 270, 270, 271, 271, 271, 271, 272, 272,
+ 272, 272, 273, 273, 273, 273, 273, 273, 273, 273, 274, 274, 274, 274, 274,
+ 274, 274, 274, 275, 275, 275, 275, 275, 275, 275, 275, 276, 276, 276, 276,
+ 276, 276, 276, 276, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277, 277,
+ 277, 277, 277, 277, 277, 278, 278, 278, 278, 278, 278, 278, 278, 278, 278,
+ 278, 278, 278, 278, 278, 278, 279, 279, 279, 279, 279, 279, 279, 279, 279,
+ 279, 279, 279, 279, 279, 279, 279, 280, 280, 280, 280, 280, 280, 280, 280,
+ 280, 280, 280, 280, 280, 280, 280, 280, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 281,
+ 281, 281, 281, 281, 281, 281, 281, 281, 281, 281, 282, 282, 282, 282, 282,
+ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282,
+ 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 282, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283,
+ 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 283, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 285};
+
+static const mz_uint8 s_tdefl_len_extra[256] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0};
+
+static const mz_uint8 s_tdefl_small_dist_sym[512] = {
+ 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8,
+ 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17,
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17};
+
+static const mz_uint8 s_tdefl_small_dist_extra[512] = {
+ 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7};
+
+static const mz_uint8 s_tdefl_large_dist_sym[128] = {
+ 0, 0, 18, 19, 20, 20, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23, 24, 24, 24,
+ 24, 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+ 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29};
+
+static const mz_uint8 s_tdefl_large_dist_extra[128] = {
+ 0, 0, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11,
+ 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+ 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+ 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13};
+
+// Radix sorts tdefl_sym_freq[] array by 16-bit key m_key. Returns ptr to sorted
+// values.
+typedef struct { mz_uint16 m_key, m_sym_index; } tdefl_sym_freq;
+static tdefl_sym_freq *tdefl_radix_sort_syms(mz_uint num_syms,
+ tdefl_sym_freq *pSyms0,
+ tdefl_sym_freq *pSyms1) {
+ mz_uint32 total_passes = 2, pass_shift, pass, i, hist[256 * 2];
+ tdefl_sym_freq *pCur_syms = pSyms0, *pNew_syms = pSyms1;
+ MZ_CLEAR_OBJ(hist);
+ for (i = 0; i < num_syms; i++) {
+ mz_uint freq = pSyms0[i].m_key;
+ hist[freq & 0xFF]++;
+ hist[256 + ((freq >> 8) & 0xFF)]++;
+ }
+ while ((total_passes > 1) && (num_syms == hist[(total_passes - 1) * 256]))
+ total_passes--;
+ for (pass_shift = 0, pass = 0; pass < total_passes; pass++, pass_shift += 8) {
+ const mz_uint32 *pHist = &hist[pass << 8];
+ mz_uint offsets[256], cur_ofs = 0;
+ for (i = 0; i < 256; i++) {
+ offsets[i] = cur_ofs;
+ cur_ofs += pHist[i];
+ }
+ for (i = 0; i < num_syms; i++)
+ pNew_syms[offsets[(pCur_syms[i].m_key >> pass_shift) & 0xFF]++] =
+ pCur_syms[i];
+ {
+ tdefl_sym_freq *t = pCur_syms;
+ pCur_syms = pNew_syms;
+ pNew_syms = t;
+ }
+ }
+ return pCur_syms;
+}
+
+// tdefl_calculate_minimum_redundancy() originally written by: Alistair Moffat,
+// alistair@cs.mu.oz.au, Jyrki Katajainen, jyrki@diku.dk, November 1996.
+static void tdefl_calculate_minimum_redundancy(tdefl_sym_freq *A, int n) {
+ int root, leaf, next, avbl, used, dpth;
+ if (n == 0)
+ return;
+ else if (n == 1) {
+ A[0].m_key = 1;
+ return;
+ }
+ A[0].m_key += A[1].m_key;
+ root = 0;
+ leaf = 2;
+ for (next = 1; next < n - 1; next++) {
+ if (leaf >= n || A[root].m_key < A[leaf].m_key) {
+ A[next].m_key = A[root].m_key;
+ A[root++].m_key = (mz_uint16)next;
+ } else
+ A[next].m_key = A[leaf++].m_key;
+ if (leaf >= n || (root < next && A[root].m_key < A[leaf].m_key)) {
+ A[next].m_key = (mz_uint16)(A[next].m_key + A[root].m_key);
+ A[root++].m_key = (mz_uint16)next;
+ } else
+ A[next].m_key = (mz_uint16)(A[next].m_key + A[leaf++].m_key);
+ }
+ A[n - 2].m_key = 0;
+ for (next = n - 3; next >= 0; next--)
+ A[next].m_key = A[A[next].m_key].m_key + 1;
+ avbl = 1;
+ used = dpth = 0;
+ root = n - 2;
+ next = n - 1;
+ while (avbl > 0) {
+ while (root >= 0 && (int)A[root].m_key == dpth) {
+ used++;
+ root--;
+ }
+ while (avbl > used) {
+ A[next--].m_key = (mz_uint16)(dpth);
+ avbl--;
+ }
+ avbl = 2 * used;
+ dpth++;
+ used = 0;
+ }
+}
+
+// Limits canonical Huffman code table's max code size.
+enum { TDEFL_MAX_SUPPORTED_HUFF_CODESIZE = 32 };
+static void tdefl_huffman_enforce_max_code_size(int *pNum_codes,
+ int code_list_len,
+ int max_code_size) {
+ int i;
+ mz_uint32 total = 0;
+ if (code_list_len <= 1) return;
+ for (i = max_code_size + 1; i <= TDEFL_MAX_SUPPORTED_HUFF_CODESIZE; i++)
+ pNum_codes[max_code_size] += pNum_codes[i];
+ for (i = max_code_size; i > 0; i--)
+ total += (((mz_uint32)pNum_codes[i]) << (max_code_size - i));
+ while (total != (1UL << max_code_size)) {
+ pNum_codes[max_code_size]--;
+ for (i = max_code_size - 1; i > 0; i--)
+ if (pNum_codes[i]) {
+ pNum_codes[i]--;
+ pNum_codes[i + 1] += 2;
+ break;
+ }
+ total--;
+ }
+}
+
+static void tdefl_optimize_huffman_table(tdefl_compressor *d, int table_num,
+ int table_len, int code_size_limit,
+ int static_table) {
+ int i, j, l, num_codes[1 + TDEFL_MAX_SUPPORTED_HUFF_CODESIZE];
+ mz_uint next_code[TDEFL_MAX_SUPPORTED_HUFF_CODESIZE + 1];
+ MZ_CLEAR_OBJ(num_codes);
+ if (static_table) {
+ for (i = 0; i < table_len; i++)
+ num_codes[d->m_huff_code_sizes[table_num][i]]++;
+ } else {
+ tdefl_sym_freq syms0[TDEFL_MAX_HUFF_SYMBOLS], syms1[TDEFL_MAX_HUFF_SYMBOLS],
+ *pSyms;
+ int num_used_syms = 0;
+ const mz_uint16 *pSym_count = &d->m_huff_count[table_num][0];
+ for (i = 0; i < table_len; i++)
+ if (pSym_count[i]) {
+ syms0[num_used_syms].m_key = (mz_uint16)pSym_count[i];
+ syms0[num_used_syms++].m_sym_index = (mz_uint16)i;
+ }
+
+ pSyms = tdefl_radix_sort_syms(num_used_syms, syms0, syms1);
+ tdefl_calculate_minimum_redundancy(pSyms, num_used_syms);
+
+ for (i = 0; i < num_used_syms; i++) num_codes[pSyms[i].m_key]++;
+
+ tdefl_huffman_enforce_max_code_size(num_codes, num_used_syms,
+ code_size_limit);
+
+ MZ_CLEAR_OBJ(d->m_huff_code_sizes[table_num]);
+ MZ_CLEAR_OBJ(d->m_huff_codes[table_num]);
+ for (i = 1, j = num_used_syms; i <= code_size_limit; i++)
+ for (l = num_codes[i]; l > 0; l--)
+ d->m_huff_code_sizes[table_num][pSyms[--j].m_sym_index] = (mz_uint8)(i);
+ }
+
+ next_code[1] = 0;
+ for (j = 0, i = 2; i <= code_size_limit; i++)
+ next_code[i] = j = ((j + num_codes[i - 1]) << 1);
+
+ for (i = 0; i < table_len; i++) {
+ mz_uint rev_code = 0, code, code_size;
+ if ((code_size = d->m_huff_code_sizes[table_num][i]) == 0) continue;
+ code = next_code[code_size]++;
+ for (l = code_size; l > 0; l--, code >>= 1)
+ rev_code = (rev_code << 1) | (code & 1);
+ d->m_huff_codes[table_num][i] = (mz_uint16)rev_code;
+ }
+}
+
+#define TDEFL_PUT_BITS(b, l) \
+ do { \
+ mz_uint bits = b; \
+ mz_uint len = l; \
+ MZ_ASSERT(bits <= ((1U << len) - 1U)); \
+ d->m_bit_buffer |= (bits << d->m_bits_in); \
+ d->m_bits_in += len; \
+ while (d->m_bits_in >= 8) { \
+ if (d->m_pOutput_buf < d->m_pOutput_buf_end) \
+ *d->m_pOutput_buf++ = (mz_uint8)(d->m_bit_buffer); \
+ d->m_bit_buffer >>= 8; \
+ d->m_bits_in -= 8; \
+ } \
+ } \
+ MZ_MACRO_END
+
+#define TDEFL_RLE_PREV_CODE_SIZE() \
+ { \
+ if (rle_repeat_count) { \
+ if (rle_repeat_count < 3) { \
+ d->m_huff_count[2][prev_code_size] = (mz_uint16)( \
+ d->m_huff_count[2][prev_code_size] + rle_repeat_count); \
+ while (rle_repeat_count--) \
+ packed_code_sizes[num_packed_code_sizes++] = prev_code_size; \
+ } else { \
+ d->m_huff_count[2][16] = (mz_uint16)(d->m_huff_count[2][16] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 16; \
+ packed_code_sizes[num_packed_code_sizes++] = \
+ (mz_uint8)(rle_repeat_count - 3); \
+ } \
+ rle_repeat_count = 0; \
+ } \
+ }
+
+#define TDEFL_RLE_ZERO_CODE_SIZE() \
+ { \
+ if (rle_z_count) { \
+ if (rle_z_count < 3) { \
+ d->m_huff_count[2][0] = \
+ (mz_uint16)(d->m_huff_count[2][0] + rle_z_count); \
+ while (rle_z_count--) packed_code_sizes[num_packed_code_sizes++] = 0; \
+ } else if (rle_z_count <= 10) { \
+ d->m_huff_count[2][17] = (mz_uint16)(d->m_huff_count[2][17] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 17; \
+ packed_code_sizes[num_packed_code_sizes++] = \
+ (mz_uint8)(rle_z_count - 3); \
+ } else { \
+ d->m_huff_count[2][18] = (mz_uint16)(d->m_huff_count[2][18] + 1); \
+ packed_code_sizes[num_packed_code_sizes++] = 18; \
+ packed_code_sizes[num_packed_code_sizes++] = \
+ (mz_uint8)(rle_z_count - 11); \
+ } \
+ rle_z_count = 0; \
+ } \
+ }
+
+static mz_uint8 s_tdefl_packed_code_size_syms_swizzle[] = {
+ 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+static void tdefl_start_dynamic_block(tdefl_compressor *d) {
+ int num_lit_codes, num_dist_codes, num_bit_lengths;
+ mz_uint i, total_code_sizes_to_pack, num_packed_code_sizes, rle_z_count,
+ rle_repeat_count, packed_code_sizes_index;
+ mz_uint8
+ code_sizes_to_pack[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
+ packed_code_sizes[TDEFL_MAX_HUFF_SYMBOLS_0 + TDEFL_MAX_HUFF_SYMBOLS_1],
+ prev_code_size = 0xFF;
+
+ d->m_huff_count[0][256] = 1;
+
+ tdefl_optimize_huffman_table(d, 0, TDEFL_MAX_HUFF_SYMBOLS_0, 15, MZ_FALSE);
+ tdefl_optimize_huffman_table(d, 1, TDEFL_MAX_HUFF_SYMBOLS_1, 15, MZ_FALSE);
+
+ for (num_lit_codes = 286; num_lit_codes > 257; num_lit_codes--)
+ if (d->m_huff_code_sizes[0][num_lit_codes - 1]) break;
+ for (num_dist_codes = 30; num_dist_codes > 1; num_dist_codes--)
+ if (d->m_huff_code_sizes[1][num_dist_codes - 1]) break;
+
+ memcpy(code_sizes_to_pack, &d->m_huff_code_sizes[0][0], num_lit_codes);
+ memcpy(code_sizes_to_pack + num_lit_codes, &d->m_huff_code_sizes[1][0],
+ num_dist_codes);
+ total_code_sizes_to_pack = num_lit_codes + num_dist_codes;
+ num_packed_code_sizes = 0;
+ rle_z_count = 0;
+ rle_repeat_count = 0;
+
+ memset(&d->m_huff_count[2][0], 0,
+ sizeof(d->m_huff_count[2][0]) * TDEFL_MAX_HUFF_SYMBOLS_2);
+ for (i = 0; i < total_code_sizes_to_pack; i++) {
+ mz_uint8 code_size = code_sizes_to_pack[i];
+ if (!code_size) {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ if (++rle_z_count == 138) {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ }
+ } else {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ if (code_size != prev_code_size) {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ d->m_huff_count[2][code_size] =
+ (mz_uint16)(d->m_huff_count[2][code_size] + 1);
+ packed_code_sizes[num_packed_code_sizes++] = code_size;
+ } else if (++rle_repeat_count == 6) {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ }
+ }
+ prev_code_size = code_size;
+ }
+ if (rle_repeat_count) {
+ TDEFL_RLE_PREV_CODE_SIZE();
+ } else {
+ TDEFL_RLE_ZERO_CODE_SIZE();
+ }
+
+ tdefl_optimize_huffman_table(d, 2, TDEFL_MAX_HUFF_SYMBOLS_2, 7, MZ_FALSE);
+
+ TDEFL_PUT_BITS(2, 2);
+
+ TDEFL_PUT_BITS(num_lit_codes - 257, 5);
+ TDEFL_PUT_BITS(num_dist_codes - 1, 5);
+
+ for (num_bit_lengths = 18; num_bit_lengths >= 0; num_bit_lengths--)
+ if (d->m_huff_code_sizes
+ [2][s_tdefl_packed_code_size_syms_swizzle[num_bit_lengths]])
+ break;
+ num_bit_lengths = MZ_MAX(4, (num_bit_lengths + 1));
+ TDEFL_PUT_BITS(num_bit_lengths - 4, 4);
+ for (i = 0; (int)i < num_bit_lengths; i++)
+ TDEFL_PUT_BITS(
+ d->m_huff_code_sizes[2][s_tdefl_packed_code_size_syms_swizzle[i]], 3);
+
+ for (packed_code_sizes_index = 0;
+ packed_code_sizes_index < num_packed_code_sizes;) {
+ mz_uint code = packed_code_sizes[packed_code_sizes_index++];
+ MZ_ASSERT(code < TDEFL_MAX_HUFF_SYMBOLS_2);
+ TDEFL_PUT_BITS(d->m_huff_codes[2][code], d->m_huff_code_sizes[2][code]);
+ if (code >= 16)
+ TDEFL_PUT_BITS(packed_code_sizes[packed_code_sizes_index++],
+ "\02\03\07"[code - 16]);
+ }
+}
+
+static void tdefl_start_static_block(tdefl_compressor *d) {
+ mz_uint i;
+ mz_uint8 *p = &d->m_huff_code_sizes[0][0];
+
+ for (i = 0; i <= 143; ++i) *p++ = 8;
+ for (; i <= 255; ++i) *p++ = 9;
+ for (; i <= 279; ++i) *p++ = 7;
+ for (; i <= 287; ++i) *p++ = 8;
+
+ memset(d->m_huff_code_sizes[1], 5, 32);
+
+ tdefl_optimize_huffman_table(d, 0, 288, 15, MZ_TRUE);
+ tdefl_optimize_huffman_table(d, 1, 32, 15, MZ_TRUE);
+
+ TDEFL_PUT_BITS(1, 2);
+}
+
+static const mz_uint mz_bitmasks[17] = {
+ 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
+ 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF};
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN && \
+ MINIZ_HAS_64BIT_REGISTERS
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) {
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+ mz_uint8 *pOutput_buf = d->m_pOutput_buf;
+ mz_uint8 *pLZ_code_buf_end = d->m_pLZ_code_buf;
+ mz_uint64 bit_buffer = d->m_bit_buffer;
+ mz_uint bits_in = d->m_bits_in;
+
+#define TDEFL_PUT_BITS_FAST(b, l) \
+ { \
+ bit_buffer |= (((mz_uint64)(b)) << bits_in); \
+ bits_in += (l); \
+ }
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < pLZ_code_buf_end;
+ flags >>= 1) {
+ if (flags == 1) flags = *pLZ_codes++ | 0x100;
+
+ if (flags & 1) {
+ mz_uint s0, s1, n0, n1, sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0],
+ match_dist = *(const mz_uint16 *)(pLZ_codes + 1);
+ pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
+ d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS_FAST(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
+ s_tdefl_len_extra[match_len]);
+
+ // This sequence coaxes MSVC into using cmov's vs. jmp's.
+ s0 = s_tdefl_small_dist_sym[match_dist & 511];
+ n0 = s_tdefl_small_dist_extra[match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[match_dist >> 8];
+ n1 = s_tdefl_large_dist_extra[match_dist >> 8];
+ sym = (match_dist < 512) ? s0 : s1;
+ num_extra_bits = (match_dist < 512) ? n0 : n1;
+
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[1][sym],
+ d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS_FAST(match_dist & mz_bitmasks[num_extra_bits],
+ num_extra_bits);
+ } else {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
+ d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
+ d->m_huff_code_sizes[0][lit]);
+
+ if (((flags & 2) == 0) && (pLZ_codes < pLZ_code_buf_end)) {
+ flags >>= 1;
+ lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS_FAST(d->m_huff_codes[0][lit],
+ d->m_huff_code_sizes[0][lit]);
+ }
+ }
+ }
+
+ if (pOutput_buf >= d->m_pOutput_buf_end) return MZ_FALSE;
+
+ *(mz_uint64 *)pOutput_buf = bit_buffer;
+ pOutput_buf += (bits_in >> 3);
+ bit_buffer >>= (bits_in & ~7);
+ bits_in &= 7;
+ }
+
+#undef TDEFL_PUT_BITS_FAST
+
+ d->m_pOutput_buf = pOutput_buf;
+ d->m_bits_in = 0;
+ d->m_bit_buffer = 0;
+
+ while (bits_in) {
+ mz_uint32 n = MZ_MIN(bits_in, 16);
+ TDEFL_PUT_BITS((mz_uint)bit_buffer & mz_bitmasks[n], n);
+ bit_buffer >>= n;
+ bits_in -= n;
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#else
+static mz_bool tdefl_compress_lz_codes(tdefl_compressor *d) {
+ mz_uint flags;
+ mz_uint8 *pLZ_codes;
+
+ flags = 1;
+ for (pLZ_codes = d->m_lz_code_buf; pLZ_codes < d->m_pLZ_code_buf;
+ flags >>= 1) {
+ if (flags == 1) flags = *pLZ_codes++ | 0x100;
+ if (flags & 1) {
+ mz_uint sym, num_extra_bits;
+ mz_uint match_len = pLZ_codes[0],
+ match_dist = (pLZ_codes[1] | (pLZ_codes[2] << 8));
+ pLZ_codes += 3;
+
+ MZ_ASSERT(d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][s_tdefl_len_sym[match_len]],
+ d->m_huff_code_sizes[0][s_tdefl_len_sym[match_len]]);
+ TDEFL_PUT_BITS(match_len & mz_bitmasks[s_tdefl_len_extra[match_len]],
+ s_tdefl_len_extra[match_len]);
+
+ if (match_dist < 512) {
+ sym = s_tdefl_small_dist_sym[match_dist];
+ num_extra_bits = s_tdefl_small_dist_extra[match_dist];
+ } else {
+ sym = s_tdefl_large_dist_sym[match_dist >> 8];
+ num_extra_bits = s_tdefl_large_dist_extra[match_dist >> 8];
+ }
+ MZ_ASSERT(d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(d->m_huff_codes[1][sym], d->m_huff_code_sizes[1][sym]);
+ TDEFL_PUT_BITS(match_dist & mz_bitmasks[num_extra_bits], num_extra_bits);
+ } else {
+ mz_uint lit = *pLZ_codes++;
+ MZ_ASSERT(d->m_huff_code_sizes[0][lit]);
+ TDEFL_PUT_BITS(d->m_huff_codes[0][lit], d->m_huff_code_sizes[0][lit]);
+ }
+ }
+
+ TDEFL_PUT_BITS(d->m_huff_codes[0][256], d->m_huff_code_sizes[0][256]);
+
+ return (d->m_pOutput_buf < d->m_pOutput_buf_end);
+}
+#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN &&
+ // MINIZ_HAS_64BIT_REGISTERS
+
+static mz_bool tdefl_compress_block(tdefl_compressor *d, mz_bool static_block) {
+ if (static_block)
+ tdefl_start_static_block(d);
+ else
+ tdefl_start_dynamic_block(d);
+ return tdefl_compress_lz_codes(d);
+}
+
+static int tdefl_flush_block(tdefl_compressor *d, int flush) {
+ mz_uint saved_bit_buf, saved_bits_in;
+ mz_uint8 *pSaved_output_buf;
+ mz_bool comp_block_succeeded = MZ_FALSE;
+ int n, use_raw_block =
+ ((d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS) != 0) &&
+ (d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size;
+ mz_uint8 *pOutput_buf_start =
+ ((d->m_pPut_buf_func == NULL) &&
+ ((*d->m_pOut_buf_size - d->m_out_buf_ofs) >= TDEFL_OUT_BUF_SIZE))
+ ? ((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs)
+ : d->m_output_buf;
+
+ d->m_pOutput_buf = pOutput_buf_start;
+ d->m_pOutput_buf_end = d->m_pOutput_buf + TDEFL_OUT_BUF_SIZE - 16;
+
+ MZ_ASSERT(!d->m_output_flush_remaining);
+ d->m_output_flush_ofs = 0;
+ d->m_output_flush_remaining = 0;
+
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> d->m_num_flags_left);
+ d->m_pLZ_code_buf -= (d->m_num_flags_left == 8);
+
+ if ((d->m_flags & TDEFL_WRITE_ZLIB_HEADER) && (!d->m_block_index)) {
+ TDEFL_PUT_BITS(0x78, 8);
+ TDEFL_PUT_BITS(0x01, 8);
+ }
+
+ TDEFL_PUT_BITS(flush == TDEFL_FINISH, 1);
+
+ pSaved_output_buf = d->m_pOutput_buf;
+ saved_bit_buf = d->m_bit_buffer;
+ saved_bits_in = d->m_bits_in;
+
+ if (!use_raw_block)
+ comp_block_succeeded =
+ tdefl_compress_block(d, (d->m_flags & TDEFL_FORCE_ALL_STATIC_BLOCKS) ||
+ (d->m_total_lz_bytes < 48));
+
+ // If the block gets expanded, forget the current contents of the output
+ // buffer and send a raw block instead.
+ if (((use_raw_block) ||
+ ((d->m_total_lz_bytes) && ((d->m_pOutput_buf - pSaved_output_buf + 1U) >=
+ d->m_total_lz_bytes))) &&
+ ((d->m_lookahead_pos - d->m_lz_code_buf_dict_pos) <= d->m_dict_size)) {
+ mz_uint i;
+ d->m_pOutput_buf = pSaved_output_buf;
+ d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ TDEFL_PUT_BITS(0, 2);
+ if (d->m_bits_in) {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ for (i = 2; i; --i, d->m_total_lz_bytes ^= 0xFFFF) {
+ TDEFL_PUT_BITS(d->m_total_lz_bytes & 0xFFFF, 16);
+ }
+ for (i = 0; i < d->m_total_lz_bytes; ++i) {
+ TDEFL_PUT_BITS(
+ d->m_dict[(d->m_lz_code_buf_dict_pos + i) & TDEFL_LZ_DICT_SIZE_MASK],
+ 8);
+ }
+ }
+ // Check for the extremely unlikely (if not impossible) case of the compressed
+ // block not fitting into the output buffer when using dynamic codes.
+ else if (!comp_block_succeeded) {
+ d->m_pOutput_buf = pSaved_output_buf;
+ d->m_bit_buffer = saved_bit_buf, d->m_bits_in = saved_bits_in;
+ tdefl_compress_block(d, MZ_TRUE);
+ }
+
+ if (flush) {
+ if (flush == TDEFL_FINISH) {
+ if (d->m_bits_in) {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ if (d->m_flags & TDEFL_WRITE_ZLIB_HEADER) {
+ mz_uint i, a = d->m_adler32;
+ for (i = 0; i < 4; i++) {
+ TDEFL_PUT_BITS((a >> 24) & 0xFF, 8);
+ a <<= 8;
+ }
+ }
+ } else {
+ mz_uint i, z = 0;
+ TDEFL_PUT_BITS(0, 3);
+ if (d->m_bits_in) {
+ TDEFL_PUT_BITS(0, 8 - d->m_bits_in);
+ }
+ for (i = 2; i; --i, z ^= 0xFFFF) {
+ TDEFL_PUT_BITS(z & 0xFFFF, 16);
+ }
+ }
+ }
+
+ MZ_ASSERT(d->m_pOutput_buf < d->m_pOutput_buf_end);
+
+ memset(&d->m_huff_count[0][0], 0,
+ sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0,
+ sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
+ d->m_pLZ_flags = d->m_lz_code_buf;
+ d->m_num_flags_left = 8;
+ d->m_lz_code_buf_dict_pos += d->m_total_lz_bytes;
+ d->m_total_lz_bytes = 0;
+ d->m_block_index++;
+
+ if ((n = (int)(d->m_pOutput_buf - pOutput_buf_start)) != 0) {
+ if (d->m_pPut_buf_func) {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ if (!(*d->m_pPut_buf_func)(d->m_output_buf, n, d->m_pPut_buf_user))
+ return (d->m_prev_return_status = TDEFL_STATUS_PUT_BUF_FAILED);
+ } else if (pOutput_buf_start == d->m_output_buf) {
+ int bytes_to_copy = (int)MZ_MIN(
+ (size_t)n, (size_t)(*d->m_pOut_buf_size - d->m_out_buf_ofs));
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs, d->m_output_buf,
+ bytes_to_copy);
+ d->m_out_buf_ofs += bytes_to_copy;
+ if ((n -= bytes_to_copy) != 0) {
+ d->m_output_flush_ofs = bytes_to_copy;
+ d->m_output_flush_remaining = n;
+ }
+ } else {
+ d->m_out_buf_ofs += n;
+ }
+ }
+
+ return d->m_output_flush_remaining;
+}
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
+static MZ_FORCEINLINE void tdefl_find_match(
+ tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
+ mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) {
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
+ match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
+ probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint16 *s = (const mz_uint16 *)(d->m_dict + pos), *p, *q;
+ mz_uint16 c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]),
+ s01 = TDEFL_READ_UNALIGNED_WORD(s);
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
+ if (max_match_len <= match_len) return;
+ for (;;) {
+ for (;;) {
+ if (--num_probes_left == 0) return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || \
+ ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
+ return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) \
+ break;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ }
+ if (!dist) break;
+ q = (const mz_uint16 *)(d->m_dict + probe_pos);
+ if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue;
+ p = s;
+ probe_len = 32;
+ do {
+ } while (
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (--probe_len > 0));
+ if (!probe_len) {
+ *pMatch_dist = dist;
+ *pMatch_len = MZ_MIN(max_match_len, TDEFL_MAX_MATCH_LEN);
+ break;
+ } else if ((probe_len = ((mz_uint)(p - s) * 2) +
+ (mz_uint)(*(const mz_uint8 *)p ==
+ *(const mz_uint8 *)q)) > match_len) {
+ *pMatch_dist = dist;
+ if ((*pMatch_len = match_len = MZ_MIN(max_match_len, probe_len)) ==
+ max_match_len)
+ break;
+ c01 = TDEFL_READ_UNALIGNED_WORD(&d->m_dict[pos + match_len - 1]);
+ }
+ }
+}
+#else
+static MZ_FORCEINLINE void tdefl_find_match(
+ tdefl_compressor *d, mz_uint lookahead_pos, mz_uint max_dist,
+ mz_uint max_match_len, mz_uint *pMatch_dist, mz_uint *pMatch_len) {
+ mz_uint dist, pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK,
+ match_len = *pMatch_len, probe_pos = pos, next_probe_pos,
+ probe_len;
+ mz_uint num_probes_left = d->m_max_probes[match_len >= 32];
+ const mz_uint8 *s = d->m_dict + pos, *p, *q;
+ mz_uint8 c0 = d->m_dict[pos + match_len], c1 = d->m_dict[pos + match_len - 1];
+ MZ_ASSERT(max_match_len <= TDEFL_MAX_MATCH_LEN);
+ if (max_match_len <= match_len) return;
+ for (;;) {
+ for (;;) {
+ if (--num_probes_left == 0) return;
+#define TDEFL_PROBE \
+ next_probe_pos = d->m_next[probe_pos]; \
+ if ((!next_probe_pos) || \
+ ((dist = (mz_uint16)(lookahead_pos - next_probe_pos)) > max_dist)) \
+ return; \
+ probe_pos = next_probe_pos & TDEFL_LZ_DICT_SIZE_MASK; \
+ if ((d->m_dict[probe_pos + match_len] == c0) && \
+ (d->m_dict[probe_pos + match_len - 1] == c1)) \
+ break;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ TDEFL_PROBE;
+ }
+ if (!dist) break;
+ p = s;
+ q = d->m_dict + probe_pos;
+ for (probe_len = 0; probe_len < max_match_len; probe_len++)
+ if (*p++ != *q++) break;
+ if (probe_len > match_len) {
+ *pMatch_dist = dist;
+ if ((*pMatch_len = match_len = probe_len) == max_match_len) return;
+ c0 = d->m_dict[pos + match_len];
+ c1 = d->m_dict[pos + match_len - 1];
+ }
+ }
+}
+#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+static mz_bool tdefl_compress_fast(tdefl_compressor *d) {
+ // Faster, minimally featured LZRW1-style match+parse loop with better
+ // register utilization. Intended for applications where raw throughput is
+ // valued more highly than ratio.
+ mz_uint lookahead_pos = d->m_lookahead_pos,
+ lookahead_size = d->m_lookahead_size, dict_size = d->m_dict_size,
+ total_lz_bytes = d->m_total_lz_bytes,
+ num_flags_left = d->m_num_flags_left;
+ mz_uint8 *pLZ_code_buf = d->m_pLZ_code_buf, *pLZ_flags = d->m_pLZ_flags;
+ mz_uint cur_pos = lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+
+ while ((d->m_src_buf_left) || ((d->m_flush) && (lookahead_size))) {
+ const mz_uint TDEFL_COMP_FAST_LOOKAHEAD_SIZE = 4096;
+ mz_uint dst_pos =
+ (lookahead_pos + lookahead_size) & TDEFL_LZ_DICT_SIZE_MASK;
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
+ d->m_src_buf_left, TDEFL_COMP_FAST_LOOKAHEAD_SIZE - lookahead_size);
+ d->m_src_buf_left -= num_bytes_to_process;
+ lookahead_size += num_bytes_to_process;
+
+ while (num_bytes_to_process) {
+ mz_uint32 n = MZ_MIN(TDEFL_LZ_DICT_SIZE - dst_pos, num_bytes_to_process);
+ memcpy(d->m_dict + dst_pos, d->m_pSrc, n);
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ memcpy(d->m_dict + TDEFL_LZ_DICT_SIZE + dst_pos, d->m_pSrc,
+ MZ_MIN(n, (TDEFL_MAX_MATCH_LEN - 1) - dst_pos));
+ d->m_pSrc += n;
+ dst_pos = (dst_pos + n) & TDEFL_LZ_DICT_SIZE_MASK;
+ num_bytes_to_process -= n;
+ }
+
+ dict_size = MZ_MIN(TDEFL_LZ_DICT_SIZE - lookahead_size, dict_size);
+ if ((!d->m_flush) && (lookahead_size < TDEFL_COMP_FAST_LOOKAHEAD_SIZE))
+ break;
+
+ while (lookahead_size >= 4) {
+ mz_uint cur_match_dist, cur_match_len = 1;
+ mz_uint8 *pCur_dict = d->m_dict + cur_pos;
+ mz_uint first_trigram = (*(const mz_uint32 *)pCur_dict) & 0xFFFFFF;
+ mz_uint hash =
+ (first_trigram ^ (first_trigram >> (24 - (TDEFL_LZ_HASH_BITS - 8)))) &
+ TDEFL_LEVEL1_HASH_SIZE_MASK;
+ mz_uint probe_pos = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)lookahead_pos;
+
+ if (((cur_match_dist = (mz_uint16)(lookahead_pos - probe_pos)) <=
+ dict_size) &&
+ ((*(const mz_uint32 *)(d->m_dict +
+ (probe_pos &= TDEFL_LZ_DICT_SIZE_MASK)) &
+ 0xFFFFFF) == first_trigram)) {
+ const mz_uint16 *p = (const mz_uint16 *)pCur_dict;
+ const mz_uint16 *q = (const mz_uint16 *)(d->m_dict + probe_pos);
+ mz_uint32 probe_len = 32;
+ do {
+ } while ((TDEFL_READ_UNALIGNED_WORD(++p) ==
+ TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) ==
+ TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) ==
+ TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (TDEFL_READ_UNALIGNED_WORD(++p) ==
+ TDEFL_READ_UNALIGNED_WORD(++q)) &&
+ (--probe_len > 0));
+ cur_match_len = ((mz_uint)(p - (const mz_uint16 *)pCur_dict) * 2) +
+ (mz_uint)(*(const mz_uint8 *)p == *(const mz_uint8 *)q);
+ if (!probe_len)
+ cur_match_len = cur_match_dist ? TDEFL_MAX_MATCH_LEN : 0;
+
+ if ((cur_match_len < TDEFL_MIN_MATCH_LEN) ||
+ ((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
+ (cur_match_dist >= 8U * 1024U))) {
+ cur_match_len = 1;
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ } else {
+ mz_uint32 s0, s1;
+ cur_match_len = MZ_MIN(cur_match_len, lookahead_size);
+
+ MZ_ASSERT((cur_match_len >= TDEFL_MIN_MATCH_LEN) &&
+ (cur_match_dist >= 1) &&
+ (cur_match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ cur_match_dist--;
+
+ pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
+ *(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
+ pLZ_code_buf += 3;
+ *pLZ_flags = (mz_uint8)((*pLZ_flags >> 1) | 0x80);
+
+ s0 = s_tdefl_small_dist_sym[cur_match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[cur_match_dist >> 8];
+ d->m_huff_count[1][(cur_match_dist < 512) ? s0 : s1]++;
+
+ d->m_huff_count[0][s_tdefl_len_sym[cur_match_len -
+ TDEFL_MIN_MATCH_LEN]]++;
+ }
+ } else {
+ *pLZ_code_buf++ = (mz_uint8)first_trigram;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ d->m_huff_count[0][(mz_uint8)first_trigram]++;
+ }
+
+ if (--num_flags_left == 0) {
+ num_flags_left = 8;
+ pLZ_flags = pLZ_code_buf++;
+ }
+
+ total_lz_bytes += cur_match_len;
+ lookahead_pos += cur_match_len;
+ dict_size = MZ_MIN(dict_size + cur_match_len, TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + cur_match_len) & TDEFL_LZ_DICT_SIZE_MASK;
+ MZ_ASSERT(lookahead_size >= cur_match_len);
+ lookahead_size -= cur_match_len;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
+ int n;
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes;
+ pLZ_code_buf = d->m_pLZ_code_buf;
+ pLZ_flags = d->m_pLZ_flags;
+ num_flags_left = d->m_num_flags_left;
+ }
+ }
+
+ while (lookahead_size) {
+ mz_uint8 lit = d->m_dict[cur_pos];
+
+ total_lz_bytes++;
+ *pLZ_code_buf++ = lit;
+ *pLZ_flags = (mz_uint8)(*pLZ_flags >> 1);
+ if (--num_flags_left == 0) {
+ num_flags_left = 8;
+ pLZ_flags = pLZ_code_buf++;
+ }
+
+ d->m_huff_count[0][lit]++;
+
+ lookahead_pos++;
+ dict_size = MZ_MIN(dict_size + 1, TDEFL_LZ_DICT_SIZE);
+ cur_pos = (cur_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
+ lookahead_size--;
+
+ if (pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) {
+ int n;
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ total_lz_bytes = d->m_total_lz_bytes;
+ pLZ_code_buf = d->m_pLZ_code_buf;
+ pLZ_flags = d->m_pLZ_flags;
+ num_flags_left = d->m_num_flags_left;
+ }
+ }
+ }
+
+ d->m_lookahead_pos = lookahead_pos;
+ d->m_lookahead_size = lookahead_size;
+ d->m_dict_size = dict_size;
+ d->m_total_lz_bytes = total_lz_bytes;
+ d->m_pLZ_code_buf = pLZ_code_buf;
+ d->m_pLZ_flags = pLZ_flags;
+ d->m_num_flags_left = num_flags_left;
+ return MZ_TRUE;
+}
+#endif // MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+
+static MZ_FORCEINLINE void tdefl_record_literal(tdefl_compressor *d,
+ mz_uint8 lit) {
+ d->m_total_lz_bytes++;
+ *d->m_pLZ_code_buf++ = lit;
+ *d->m_pLZ_flags = (mz_uint8)(*d->m_pLZ_flags >> 1);
+ if (--d->m_num_flags_left == 0) {
+ d->m_num_flags_left = 8;
+ d->m_pLZ_flags = d->m_pLZ_code_buf++;
+ }
+ d->m_huff_count[0][lit]++;
+}
+
+static MZ_FORCEINLINE void tdefl_record_match(tdefl_compressor *d,
+ mz_uint match_len,
+ mz_uint match_dist) {
+ mz_uint32 s0, s1;
+
+ MZ_ASSERT((match_len >= TDEFL_MIN_MATCH_LEN) && (match_dist >= 1) &&
+ (match_dist <= TDEFL_LZ_DICT_SIZE));
+
+ d->m_total_lz_bytes += match_len;
+
+ d->m_pLZ_code_buf[0] = (mz_uint8)(match_len - TDEFL_MIN_MATCH_LEN);
+
+ match_dist -= 1;
+ d->m_pLZ_code_buf[1] = (mz_uint8)(match_dist & 0xFF);
+ d->m_pLZ_code_buf[2] = (mz_uint8)(match_dist >> 8);
+ d->m_pLZ_code_buf += 3;
+
+ *d->m_pLZ_flags = (mz_uint8)((*d->m_pLZ_flags >> 1) | 0x80);
+ if (--d->m_num_flags_left == 0) {
+ d->m_num_flags_left = 8;
+ d->m_pLZ_flags = d->m_pLZ_code_buf++;
+ }
+
+ s0 = s_tdefl_small_dist_sym[match_dist & 511];
+ s1 = s_tdefl_large_dist_sym[(match_dist >> 8) & 127];
+ d->m_huff_count[1][(match_dist < 512) ? s0 : s1]++;
+
+ if (match_len >= TDEFL_MIN_MATCH_LEN)
+ d->m_huff_count[0][s_tdefl_len_sym[match_len - TDEFL_MIN_MATCH_LEN]]++;
+}
+
+static mz_bool tdefl_compress_normal(tdefl_compressor *d) {
+ const mz_uint8 *pSrc = d->m_pSrc;
+ size_t src_buf_left = d->m_src_buf_left;
+ tdefl_flush flush = d->m_flush;
+
+ while ((src_buf_left) || ((flush) && (d->m_lookahead_size))) {
+ mz_uint len_to_move, cur_match_dist, cur_match_len, cur_pos;
+ // Update dictionary and hash chains. Keeps the lookahead size equal to
+ // TDEFL_MAX_MATCH_LEN.
+ if ((d->m_lookahead_size + d->m_dict_size) >= (TDEFL_MIN_MATCH_LEN - 1)) {
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
+ TDEFL_LZ_DICT_SIZE_MASK,
+ ins_pos = d->m_lookahead_pos + d->m_lookahead_size - 2;
+ mz_uint hash = (d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
+ << TDEFL_LZ_HASH_SHIFT) ^
+ d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ mz_uint num_bytes_to_process = (mz_uint)MZ_MIN(
+ src_buf_left, TDEFL_MAX_MATCH_LEN - d->m_lookahead_size);
+ const mz_uint8 *pSrc_end = pSrc + num_bytes_to_process;
+ src_buf_left -= num_bytes_to_process;
+ d->m_lookahead_size += num_bytes_to_process;
+ while (pSrc != pSrc_end) {
+ mz_uint8 c = *pSrc++;
+ d->m_dict[dst_pos] = c;
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ hash = ((hash << TDEFL_LZ_HASH_SHIFT) ^ c) & (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)(ins_pos);
+ dst_pos = (dst_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK;
+ ins_pos++;
+ }
+ } else {
+ while ((src_buf_left) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) {
+ mz_uint8 c = *pSrc++;
+ mz_uint dst_pos = (d->m_lookahead_pos + d->m_lookahead_size) &
+ TDEFL_LZ_DICT_SIZE_MASK;
+ src_buf_left--;
+ d->m_dict[dst_pos] = c;
+ if (dst_pos < (TDEFL_MAX_MATCH_LEN - 1))
+ d->m_dict[TDEFL_LZ_DICT_SIZE + dst_pos] = c;
+ if ((++d->m_lookahead_size + d->m_dict_size) >= TDEFL_MIN_MATCH_LEN) {
+ mz_uint ins_pos = d->m_lookahead_pos + (d->m_lookahead_size - 1) - 2;
+ mz_uint hash = ((d->m_dict[ins_pos & TDEFL_LZ_DICT_SIZE_MASK]
+ << (TDEFL_LZ_HASH_SHIFT * 2)) ^
+ (d->m_dict[(ins_pos + 1) & TDEFL_LZ_DICT_SIZE_MASK]
+ << TDEFL_LZ_HASH_SHIFT) ^
+ c) &
+ (TDEFL_LZ_HASH_SIZE - 1);
+ d->m_next[ins_pos & TDEFL_LZ_DICT_SIZE_MASK] = d->m_hash[hash];
+ d->m_hash[hash] = (mz_uint16)(ins_pos);
+ }
+ }
+ }
+ d->m_dict_size =
+ MZ_MIN(TDEFL_LZ_DICT_SIZE - d->m_lookahead_size, d->m_dict_size);
+ if ((!flush) && (d->m_lookahead_size < TDEFL_MAX_MATCH_LEN)) break;
+
+ // Simple lazy/greedy parsing state machine.
+ len_to_move = 1;
+ cur_match_dist = 0;
+ cur_match_len =
+ d->m_saved_match_len ? d->m_saved_match_len : (TDEFL_MIN_MATCH_LEN - 1);
+ cur_pos = d->m_lookahead_pos & TDEFL_LZ_DICT_SIZE_MASK;
+ if (d->m_flags & (TDEFL_RLE_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS)) {
+ if ((d->m_dict_size) && (!(d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS))) {
+ mz_uint8 c = d->m_dict[(cur_pos - 1) & TDEFL_LZ_DICT_SIZE_MASK];
+ cur_match_len = 0;
+ while (cur_match_len < d->m_lookahead_size) {
+ if (d->m_dict[cur_pos + cur_match_len] != c) break;
+ cur_match_len++;
+ }
+ if (cur_match_len < TDEFL_MIN_MATCH_LEN)
+ cur_match_len = 0;
+ else
+ cur_match_dist = 1;
+ }
+ } else {
+ tdefl_find_match(d, d->m_lookahead_pos, d->m_dict_size,
+ d->m_lookahead_size, &cur_match_dist, &cur_match_len);
+ }
+ if (((cur_match_len == TDEFL_MIN_MATCH_LEN) &&
+ (cur_match_dist >= 8U * 1024U)) ||
+ (cur_pos == cur_match_dist) ||
+ ((d->m_flags & TDEFL_FILTER_MATCHES) && (cur_match_len <= 5))) {
+ cur_match_dist = cur_match_len = 0;
+ }
+ if (d->m_saved_match_len) {
+ if (cur_match_len > d->m_saved_match_len) {
+ tdefl_record_literal(d, (mz_uint8)d->m_saved_lit);
+ if (cur_match_len >= 128) {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ d->m_saved_match_len = 0;
+ len_to_move = cur_match_len;
+ } else {
+ d->m_saved_lit = d->m_dict[cur_pos];
+ d->m_saved_match_dist = cur_match_dist;
+ d->m_saved_match_len = cur_match_len;
+ }
+ } else {
+ tdefl_record_match(d, d->m_saved_match_len, d->m_saved_match_dist);
+ len_to_move = d->m_saved_match_len - 1;
+ d->m_saved_match_len = 0;
+ }
+ } else if (!cur_match_dist)
+ tdefl_record_literal(d,
+ d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)]);
+ else if ((d->m_greedy_parsing) || (d->m_flags & TDEFL_RLE_MATCHES) ||
+ (cur_match_len >= 128)) {
+ tdefl_record_match(d, cur_match_len, cur_match_dist);
+ len_to_move = cur_match_len;
+ } else {
+ d->m_saved_lit = d->m_dict[MZ_MIN(cur_pos, sizeof(d->m_dict) - 1)];
+ d->m_saved_match_dist = cur_match_dist;
+ d->m_saved_match_len = cur_match_len;
+ }
+ // Move the lookahead forward by len_to_move bytes.
+ d->m_lookahead_pos += len_to_move;
+ MZ_ASSERT(d->m_lookahead_size >= len_to_move);
+ d->m_lookahead_size -= len_to_move;
+ d->m_dict_size =
+ MZ_MIN(d->m_dict_size + len_to_move, (mz_uint)TDEFL_LZ_DICT_SIZE);
+ // Check if it's time to flush the current LZ codes to the internal output
+ // buffer.
+ if ((d->m_pLZ_code_buf > &d->m_lz_code_buf[TDEFL_LZ_CODE_BUF_SIZE - 8]) ||
+ ((d->m_total_lz_bytes > 31 * 1024) &&
+ (((((mz_uint)(d->m_pLZ_code_buf - d->m_lz_code_buf) * 115) >> 7) >=
+ d->m_total_lz_bytes) ||
+ (d->m_flags & TDEFL_FORCE_ALL_RAW_BLOCKS)))) {
+ int n;
+ d->m_pSrc = pSrc;
+ d->m_src_buf_left = src_buf_left;
+ if ((n = tdefl_flush_block(d, 0)) != 0)
+ return (n < 0) ? MZ_FALSE : MZ_TRUE;
+ }
+ }
+
+ d->m_pSrc = pSrc;
+ d->m_src_buf_left = src_buf_left;
+ return MZ_TRUE;
+}
+
+static tdefl_status tdefl_flush_output_buffer(tdefl_compressor *d) {
+ if (d->m_pIn_buf_size) {
+ *d->m_pIn_buf_size = d->m_pSrc - (const mz_uint8 *)d->m_pIn_buf;
+ }
+
+ if (d->m_pOut_buf_size) {
+ size_t n = MZ_MIN(*d->m_pOut_buf_size - d->m_out_buf_ofs,
+ d->m_output_flush_remaining);
+ memcpy((mz_uint8 *)d->m_pOut_buf + d->m_out_buf_ofs,
+ d->m_output_buf + d->m_output_flush_ofs, n);
+ d->m_output_flush_ofs += (mz_uint)n;
+ d->m_output_flush_remaining -= (mz_uint)n;
+ d->m_out_buf_ofs += n;
+
+ *d->m_pOut_buf_size = d->m_out_buf_ofs;
+ }
+
+ return (d->m_finished && !d->m_output_flush_remaining) ? TDEFL_STATUS_DONE
+ : TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_compress(tdefl_compressor *d, const void *pIn_buf,
+ size_t *pIn_buf_size, void *pOut_buf,
+ size_t *pOut_buf_size, tdefl_flush flush) {
+ if (!d) {
+ if (pIn_buf_size) *pIn_buf_size = 0;
+ if (pOut_buf_size) *pOut_buf_size = 0;
+ return TDEFL_STATUS_BAD_PARAM;
+ }
+
+ d->m_pIn_buf = pIn_buf;
+ d->m_pIn_buf_size = pIn_buf_size;
+ d->m_pOut_buf = pOut_buf;
+ d->m_pOut_buf_size = pOut_buf_size;
+ d->m_pSrc = (const mz_uint8 *)(pIn_buf);
+ d->m_src_buf_left = pIn_buf_size ? *pIn_buf_size : 0;
+ d->m_out_buf_ofs = 0;
+ d->m_flush = flush;
+
+ if (((d->m_pPut_buf_func != NULL) ==
+ ((pOut_buf != NULL) || (pOut_buf_size != NULL))) ||
+ (d->m_prev_return_status != TDEFL_STATUS_OKAY) ||
+ (d->m_wants_to_finish && (flush != TDEFL_FINISH)) ||
+ (pIn_buf_size && *pIn_buf_size && !pIn_buf) ||
+ (pOut_buf_size && *pOut_buf_size && !pOut_buf)) {
+ if (pIn_buf_size) *pIn_buf_size = 0;
+ if (pOut_buf_size) *pOut_buf_size = 0;
+ return (d->m_prev_return_status = TDEFL_STATUS_BAD_PARAM);
+ }
+ d->m_wants_to_finish |= (flush == TDEFL_FINISH);
+
+ if ((d->m_output_flush_remaining) || (d->m_finished))
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+
+#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ if (((d->m_flags & TDEFL_MAX_PROBES_MASK) == 1) &&
+ ((d->m_flags & TDEFL_GREEDY_PARSING_FLAG) != 0) &&
+ ((d->m_flags & (TDEFL_FILTER_MATCHES | TDEFL_FORCE_ALL_RAW_BLOCKS |
+ TDEFL_RLE_MATCHES)) == 0)) {
+ if (!tdefl_compress_fast(d)) return d->m_prev_return_status;
+ } else
+#endif // #if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
+ {
+ if (!tdefl_compress_normal(d)) return d->m_prev_return_status;
+ }
+
+ if ((d->m_flags & (TDEFL_WRITE_ZLIB_HEADER | TDEFL_COMPUTE_ADLER32)) &&
+ (pIn_buf))
+ d->m_adler32 =
+ (mz_uint32)mz_adler32(d->m_adler32, (const mz_uint8 *)pIn_buf,
+ d->m_pSrc - (const mz_uint8 *)pIn_buf);
+
+ if ((flush) && (!d->m_lookahead_size) && (!d->m_src_buf_left) &&
+ (!d->m_output_flush_remaining)) {
+ if (tdefl_flush_block(d, flush) < 0) return d->m_prev_return_status;
+ d->m_finished = (flush == TDEFL_FINISH);
+ if (flush == TDEFL_FULL_FLUSH) {
+ MZ_CLEAR_OBJ(d->m_hash);
+ MZ_CLEAR_OBJ(d->m_next);
+ d->m_dict_size = 0;
+ }
+ }
+
+ return (d->m_prev_return_status = tdefl_flush_output_buffer(d));
+}
+
+tdefl_status tdefl_compress_buffer(tdefl_compressor *d, const void *pIn_buf,
+ size_t in_buf_size, tdefl_flush flush) {
+ MZ_ASSERT(d->m_pPut_buf_func);
+ return tdefl_compress(d, pIn_buf, &in_buf_size, NULL, NULL, flush);
+}
+
+tdefl_status tdefl_init(tdefl_compressor *d,
+ tdefl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags) {
+ d->m_pPut_buf_func = pPut_buf_func;
+ d->m_pPut_buf_user = pPut_buf_user;
+ d->m_flags = (mz_uint)(flags);
+ d->m_max_probes[0] = 1 + ((flags & 0xFFF) + 2) / 3;
+ d->m_greedy_parsing = (flags & TDEFL_GREEDY_PARSING_FLAG) != 0;
+ d->m_max_probes[1] = 1 + (((flags & 0xFFF) >> 2) + 2) / 3;
+ if (!(flags & TDEFL_NONDETERMINISTIC_PARSING_FLAG)) MZ_CLEAR_OBJ(d->m_hash);
+ d->m_lookahead_pos = d->m_lookahead_size = d->m_dict_size =
+ d->m_total_lz_bytes = d->m_lz_code_buf_dict_pos = d->m_bits_in = 0;
+ d->m_output_flush_ofs = d->m_output_flush_remaining = d->m_finished =
+ d->m_block_index = d->m_bit_buffer = d->m_wants_to_finish = 0;
+ d->m_pLZ_code_buf = d->m_lz_code_buf + 1;
+ d->m_pLZ_flags = d->m_lz_code_buf;
+ d->m_num_flags_left = 8;
+ d->m_pOutput_buf = d->m_output_buf;
+ d->m_pOutput_buf_end = d->m_output_buf;
+ d->m_prev_return_status = TDEFL_STATUS_OKAY;
+ d->m_saved_match_dist = d->m_saved_match_len = d->m_saved_lit = 0;
+ d->m_adler32 = 1;
+ d->m_pIn_buf = NULL;
+ d->m_pOut_buf = NULL;
+ d->m_pIn_buf_size = NULL;
+ d->m_pOut_buf_size = NULL;
+ d->m_flush = TDEFL_NO_FLUSH;
+ d->m_pSrc = NULL;
+ d->m_src_buf_left = 0;
+ d->m_out_buf_ofs = 0;
+ memset(&d->m_huff_count[0][0], 0,
+ sizeof(d->m_huff_count[0][0]) * TDEFL_MAX_HUFF_SYMBOLS_0);
+ memset(&d->m_huff_count[1][0], 0,
+ sizeof(d->m_huff_count[1][0]) * TDEFL_MAX_HUFF_SYMBOLS_1);
+ return TDEFL_STATUS_OKAY;
+}
+
+tdefl_status tdefl_get_prev_return_status(tdefl_compressor *d) {
+ return d->m_prev_return_status;
+}
+
+mz_uint32 tdefl_get_adler32(tdefl_compressor *d) { return d->m_adler32; }
+
+mz_bool tdefl_compress_mem_to_output(const void *pBuf, size_t buf_len,
+ tdefl_put_buf_func_ptr pPut_buf_func,
+ void *pPut_buf_user, int flags) {
+ tdefl_compressor *pComp;
+ mz_bool succeeded;
+ if (((buf_len) && (!pBuf)) || (!pPut_buf_func)) return MZ_FALSE;
+ pComp = (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
+ if (!pComp) return MZ_FALSE;
+ succeeded = (tdefl_init(pComp, pPut_buf_func, pPut_buf_user, flags) ==
+ TDEFL_STATUS_OKAY);
+ succeeded =
+ succeeded && (tdefl_compress_buffer(pComp, pBuf, buf_len, TDEFL_FINISH) ==
+ TDEFL_STATUS_DONE);
+ MZ_FREE(pComp);
+ return succeeded;
+}
+
+typedef struct {
+ size_t m_size, m_capacity;
+ mz_uint8 *m_pBuf;
+ mz_bool m_expandable;
+} tdefl_output_buffer;
+
+static mz_bool tdefl_output_buffer_putter(const void *pBuf, int len,
+ void *pUser) {
+ tdefl_output_buffer *p = (tdefl_output_buffer *)pUser;
+ size_t new_size = p->m_size + len;
+ if (new_size > p->m_capacity) {
+ size_t new_capacity = p->m_capacity;
+ mz_uint8 *pNew_buf;
+ if (!p->m_expandable) return MZ_FALSE;
+ do {
+ new_capacity = MZ_MAX(128U, new_capacity << 1U);
+ } while (new_size > new_capacity);
+ pNew_buf = (mz_uint8 *)MZ_REALLOC(p->m_pBuf, new_capacity);
+ if (!pNew_buf) return MZ_FALSE;
+ p->m_pBuf = pNew_buf;
+ p->m_capacity = new_capacity;
+ }
+ memcpy((mz_uint8 *)p->m_pBuf + p->m_size, pBuf, len);
+ p->m_size = new_size;
+ return MZ_TRUE;
+}
+
+void *tdefl_compress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len,
+ size_t *pOut_len, int flags) {
+ tdefl_output_buffer out_buf;
+ MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_len)
+ return MZ_FALSE;
+ else
+ *pOut_len = 0;
+ out_buf.m_expandable = MZ_TRUE;
+ if (!tdefl_compress_mem_to_output(
+ pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
+ return NULL;
+ *pOut_len = out_buf.m_size;
+ return out_buf.m_pBuf;
+}
+
+size_t tdefl_compress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
+ const void *pSrc_buf, size_t src_buf_len,
+ int flags) {
+ tdefl_output_buffer out_buf;
+ MZ_CLEAR_OBJ(out_buf);
+ if (!pOut_buf) return 0;
+ out_buf.m_pBuf = (mz_uint8 *)pOut_buf;
+ out_buf.m_capacity = out_buf_len;
+ if (!tdefl_compress_mem_to_output(
+ pSrc_buf, src_buf_len, tdefl_output_buffer_putter, &out_buf, flags))
+ return 0;
+ return out_buf.m_size;
+}
+
+#ifndef MINIZ_NO_ZLIB_APIS
+static const mz_uint s_tdefl_num_probes[11] = {0, 1, 6, 32, 16, 32,
+ 128, 256, 512, 768, 1500};
+
+// level may actually range from [0,10] (10 is a "hidden" max level, where we
+// want a bit more compression and it's fine if throughput to fall off a cliff
+// on some files).
+mz_uint tdefl_create_comp_flags_from_zip_params(int level, int window_bits,
+ int strategy) {
+ mz_uint comp_flags =
+ s_tdefl_num_probes[(level >= 0) ? MZ_MIN(10, level) : MZ_DEFAULT_LEVEL] |
+ ((level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0);
+ if (window_bits > 0) comp_flags |= TDEFL_WRITE_ZLIB_HEADER;
+
+ if (!level)
+ comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS;
+ else if (strategy == MZ_FILTERED)
+ comp_flags |= TDEFL_FILTER_MATCHES;
+ else if (strategy == MZ_HUFFMAN_ONLY)
+ comp_flags &= ~TDEFL_MAX_PROBES_MASK;
+ else if (strategy == MZ_FIXED)
+ comp_flags |= TDEFL_FORCE_ALL_STATIC_BLOCKS;
+ else if (strategy == MZ_RLE)
+ comp_flags |= TDEFL_RLE_MATCHES;
+
+ return comp_flags;
+}
+#endif // MINIZ_NO_ZLIB_APIS
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable : 4204) // nonstandard extension used : non-constant
+ // aggregate initializer (also supported by GNU
+ // C and C99, so no big deal)
+#pragma warning(disable : 4244) // 'initializing': conversion from '__int64' to
+ // 'int', possible loss of data
+#pragma warning( \
+ disable : 4267) // 'argument': conversion from '__int64' to 'int',
+ // possible loss of data
+#pragma warning(disable : 4996) // 'strdup': The POSIX name for this item is
+ // deprecated. Instead, use the ISO C and C++
+ // conformant name: _strdup.
+#endif
+
+// Simple PNG writer function by Alex Evans, 2011. Released into the public
+// domain: https://gist.github.com/908299, more context at
+// http://altdevblogaday.org/2011/04/06/a-smaller-jpg-encoder/.
+// This is actually a modification of Alex's original code so PNG files
+// generated by this function pass pngcheck.
+void *tdefl_write_image_to_png_file_in_memory_ex(const void *pImage, int w,
+ int h, int num_chans,
+ size_t *pLen_out,
+ mz_uint level, mz_bool flip) {
+ // Using a local copy of this array here in case MINIZ_NO_ZLIB_APIS was
+ // defined.
+ static const mz_uint s_tdefl_png_num_probes[11] = {
+ 0, 1, 6, 32, 16, 32, 128, 256, 512, 768, 1500};
+ tdefl_compressor *pComp =
+ (tdefl_compressor *)MZ_MALLOC(sizeof(tdefl_compressor));
+ tdefl_output_buffer out_buf;
+ int i, bpl = w * num_chans, y, z;
+ mz_uint32 c;
+ *pLen_out = 0;
+ if (!pComp) return NULL;
+ MZ_CLEAR_OBJ(out_buf);
+ out_buf.m_expandable = MZ_TRUE;
+ out_buf.m_capacity = 57 + MZ_MAX(64, (1 + bpl) * h);
+ if (NULL == (out_buf.m_pBuf = (mz_uint8 *)MZ_MALLOC(out_buf.m_capacity))) {
+ MZ_FREE(pComp);
+ return NULL;
+ }
+ // write dummy header
+ for (z = 41; z; --z) tdefl_output_buffer_putter(&z, 1, &out_buf);
+ // compress image data
+ tdefl_init(
+ pComp, tdefl_output_buffer_putter, &out_buf,
+ s_tdefl_png_num_probes[MZ_MIN(10, level)] | TDEFL_WRITE_ZLIB_HEADER);
+ for (y = 0; y < h; ++y) {
+ tdefl_compress_buffer(pComp, &z, 1, TDEFL_NO_FLUSH);
+ tdefl_compress_buffer(pComp,
+ (mz_uint8 *)pImage + (flip ? (h - 1 - y) : y) * bpl,
+ bpl, TDEFL_NO_FLUSH);
+ }
+ if (tdefl_compress_buffer(pComp, NULL, 0, TDEFL_FINISH) !=
+ TDEFL_STATUS_DONE) {
+ MZ_FREE(pComp);
+ MZ_FREE(out_buf.m_pBuf);
+ return NULL;
+ }
+ // write real header
+ *pLen_out = out_buf.m_size - 41;
+ {
+ static const mz_uint8 chans[] = {0x00, 0x00, 0x04, 0x02, 0x06};
+ mz_uint8 pnghdr[41] = {0x89,
+ 0x50,
+ 0x4e,
+ 0x47,
+ 0x0d,
+ 0x0a,
+ 0x1a,
+ 0x0a,
+ 0x00,
+ 0x00,
+ 0x00,
+ 0x0d,
+ 0x49,
+ 0x48,
+ 0x44,
+ 0x52,
+ 0,
+ 0,
+ (mz_uint8)(w >> 8),
+ (mz_uint8)w,
+ 0,
+ 0,
+ (mz_uint8)(h >> 8),
+ (mz_uint8)h,
+ 8,
+ chans[num_chans],
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ (mz_uint8)(*pLen_out >> 24),
+ (mz_uint8)(*pLen_out >> 16),
+ (mz_uint8)(*pLen_out >> 8),
+ (mz_uint8)*pLen_out,
+ 0x49,
+ 0x44,
+ 0x41,
+ 0x54};
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, pnghdr + 12, 17);
+ for (i = 0; i < 4; ++i, c <<= 8)
+ ((mz_uint8 *)(pnghdr + 29))[i] = (mz_uint8)(c >> 24);
+ memcpy(out_buf.m_pBuf, pnghdr, 41);
+ }
+ // write footer (IDAT CRC-32, followed by IEND chunk)
+ if (!tdefl_output_buffer_putter(
+ "\0\0\0\0\0\0\0\0\x49\x45\x4e\x44\xae\x42\x60\x82", 16, &out_buf)) {
+ *pLen_out = 0;
+ MZ_FREE(pComp);
+ MZ_FREE(out_buf.m_pBuf);
+ return NULL;
+ }
+ c = (mz_uint32)mz_crc32(MZ_CRC32_INIT, out_buf.m_pBuf + 41 - 4,
+ *pLen_out + 4);
+ for (i = 0; i < 4; ++i, c <<= 8)
+ (out_buf.m_pBuf + out_buf.m_size - 16)[i] = (mz_uint8)(c >> 24);
+ // compute final size of file, grab compressed data buffer and return
+ *pLen_out += 57;
+ MZ_FREE(pComp);
+ return out_buf.m_pBuf;
+}
+void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
+ int num_chans, size_t *pLen_out) {
+ // Level 6 corresponds to TDEFL_DEFAULT_MAX_PROBES or MZ_DEFAULT_LEVEL (but we
+ // can't depend on MZ_DEFAULT_LEVEL being available in case the zlib API's
+ // where #defined out)
+ return tdefl_write_image_to_png_file_in_memory_ex(pImage, w, h, num_chans,
+ pLen_out, 6, MZ_FALSE);
+}
+
+// ------------------- .ZIP archive reading
+
+#ifndef MINIZ_NO_ARCHIVE_APIS
+#error "No arvhive APIs"
+
+#ifdef MINIZ_NO_STDIO
+#define MZ_FILE void *
+#else
+#include <stdio.h>
+#include <sys/stat.h>
+
+// -- GODOT change for old MinGW on Travis CI --
+//#if defined(_MSC_VER) || defined(__MINGW64__)
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+static FILE *mz_fopen(const char *pFilename, const char *pMode) {
+ FILE *pFile = NULL;
+ fopen_s(&pFile, pFilename, pMode);
+ return pFile;
+}
+static FILE *mz_freopen(const char *pPath, const char *pMode, FILE *pStream) {
+ FILE *pFile = NULL;
+ if (freopen_s(&pFile, pPath, pMode, pStream)) return NULL;
+ return pFile;
+}
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN mz_fopen
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 _ftelli64
+#define MZ_FSEEK64 _fseeki64
+#define MZ_FILE_STAT_STRUCT _stat
+#define MZ_FILE_STAT _stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN mz_freopen
+#define MZ_DELETE_FILE remove
+#elif defined(__MINGW32__)
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT _stat
+#define MZ_FILE_STAT _stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__TINYC__)
+#ifndef MINIZ_NO_TIME
+#include <sys/utime.h>
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftell
+#define MZ_FSEEK64 fseek
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#elif defined(__GNUC__) && defined(_LARGEFILE64_SOURCE) && _LARGEFILE64_SOURCE
+#ifndef MINIZ_NO_TIME
+#include <utime.h>
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen64(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello64
+#define MZ_FSEEK64 fseeko64
+#define MZ_FILE_STAT_STRUCT stat64
+#define MZ_FILE_STAT stat64
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(p, m, s) freopen64(p, m, s)
+#define MZ_DELETE_FILE remove
+#else
+#ifndef MINIZ_NO_TIME
+#include <utime.h>
+#endif
+#define MZ_FILE FILE
+#define MZ_FOPEN(f, m) fopen(f, m)
+#define MZ_FCLOSE fclose
+#define MZ_FREAD fread
+#define MZ_FWRITE fwrite
+#define MZ_FTELL64 ftello
+#define MZ_FSEEK64 fseeko
+#define MZ_FILE_STAT_STRUCT stat
+#define MZ_FILE_STAT stat
+#define MZ_FFLUSH fflush
+#define MZ_FREOPEN(f, m, s) freopen(f, m, s)
+#define MZ_DELETE_FILE remove
+#endif // #ifdef _MSC_VER
+#endif // #ifdef MINIZ_NO_STDIO
+
+#define MZ_TOLOWER(c) ((((c) >= 'A') && ((c) <= 'Z')) ? ((c) - 'A' + 'a') : (c))
+
+// Various ZIP archive enums. To completely avoid cross platform compiler
+// alignment and platform endian issues, miniz.c doesn't use structs for any of
+// this stuff.
+enum {
+ // ZIP archive identifiers and record sizes
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG = 0x06054b50,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIG = 0x02014b50,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIG = 0x04034b50,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE = 30,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE = 46,
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE = 22,
+ // Central directory header record offsets
+ MZ_ZIP_CDH_SIG_OFS = 0,
+ MZ_ZIP_CDH_VERSION_MADE_BY_OFS = 4,
+ MZ_ZIP_CDH_VERSION_NEEDED_OFS = 6,
+ MZ_ZIP_CDH_BIT_FLAG_OFS = 8,
+ MZ_ZIP_CDH_METHOD_OFS = 10,
+ MZ_ZIP_CDH_FILE_TIME_OFS = 12,
+ MZ_ZIP_CDH_FILE_DATE_OFS = 14,
+ MZ_ZIP_CDH_CRC32_OFS = 16,
+ MZ_ZIP_CDH_COMPRESSED_SIZE_OFS = 20,
+ MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS = 24,
+ MZ_ZIP_CDH_FILENAME_LEN_OFS = 28,
+ MZ_ZIP_CDH_EXTRA_LEN_OFS = 30,
+ MZ_ZIP_CDH_COMMENT_LEN_OFS = 32,
+ MZ_ZIP_CDH_DISK_START_OFS = 34,
+ MZ_ZIP_CDH_INTERNAL_ATTR_OFS = 36,
+ MZ_ZIP_CDH_EXTERNAL_ATTR_OFS = 38,
+ MZ_ZIP_CDH_LOCAL_HEADER_OFS = 42,
+ // Local directory header offsets
+ MZ_ZIP_LDH_SIG_OFS = 0,
+ MZ_ZIP_LDH_VERSION_NEEDED_OFS = 4,
+ MZ_ZIP_LDH_BIT_FLAG_OFS = 6,
+ MZ_ZIP_LDH_METHOD_OFS = 8,
+ MZ_ZIP_LDH_FILE_TIME_OFS = 10,
+ MZ_ZIP_LDH_FILE_DATE_OFS = 12,
+ MZ_ZIP_LDH_CRC32_OFS = 14,
+ MZ_ZIP_LDH_COMPRESSED_SIZE_OFS = 18,
+ MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS = 22,
+ MZ_ZIP_LDH_FILENAME_LEN_OFS = 26,
+ MZ_ZIP_LDH_EXTRA_LEN_OFS = 28,
+ // End of central directory offsets
+ MZ_ZIP_ECDH_SIG_OFS = 0,
+ MZ_ZIP_ECDH_NUM_THIS_DISK_OFS = 4,
+ MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS = 6,
+ MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS = 8,
+ MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS = 10,
+ MZ_ZIP_ECDH_CDIR_SIZE_OFS = 12,
+ MZ_ZIP_ECDH_CDIR_OFS_OFS = 16,
+ MZ_ZIP_ECDH_COMMENT_SIZE_OFS = 20,
+};
+
+typedef struct {
+ void *m_p;
+ size_t m_size, m_capacity;
+ mz_uint m_element_size;
+} mz_zip_array;
+
+struct mz_zip_internal_state_tag {
+ mz_zip_array m_central_dir;
+ mz_zip_array m_central_dir_offsets;
+ mz_zip_array m_sorted_central_dir_offsets;
+ MZ_FILE *m_pFile;
+ void *m_pMem;
+ size_t m_mem_size;
+ size_t m_mem_capacity;
+};
+
+#define MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(array_ptr, element_size) \
+ (array_ptr)->m_element_size = element_size
+#define MZ_ZIP_ARRAY_ELEMENT(array_ptr, element_type, index) \
+ ((element_type *)((array_ptr)->m_p))[index]
+
+static MZ_FORCEINLINE void mz_zip_array_clear(mz_zip_archive *pZip,
+ mz_zip_array *pArray) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pArray->m_p);
+ memset(pArray, 0, sizeof(mz_zip_array));
+}
+
+static mz_bool mz_zip_array_ensure_capacity(mz_zip_archive *pZip,
+ mz_zip_array *pArray,
+ size_t min_new_capacity,
+ mz_uint growing) {
+ void *pNew_p;
+ size_t new_capacity = min_new_capacity;
+ MZ_ASSERT(pArray->m_element_size);
+ if (pArray->m_capacity >= min_new_capacity) return MZ_TRUE;
+ if (growing) {
+ new_capacity = MZ_MAX(1, pArray->m_capacity);
+ while (new_capacity < min_new_capacity) new_capacity *= 2;
+ }
+ if (NULL == (pNew_p = pZip->m_pRealloc(pZip->m_pAlloc_opaque, pArray->m_p,
+ pArray->m_element_size, new_capacity)))
+ return MZ_FALSE;
+ pArray->m_p = pNew_p;
+ pArray->m_capacity = new_capacity;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_reserve(mz_zip_archive *pZip,
+ mz_zip_array *pArray,
+ size_t new_capacity,
+ mz_uint growing) {
+ if (new_capacity > pArray->m_capacity) {
+ if (!mz_zip_array_ensure_capacity(pZip, pArray, new_capacity, growing))
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_resize(mz_zip_archive *pZip,
+ mz_zip_array *pArray,
+ size_t new_size,
+ mz_uint growing) {
+ if (new_size > pArray->m_capacity) {
+ if (!mz_zip_array_ensure_capacity(pZip, pArray, new_size, growing))
+ return MZ_FALSE;
+ }
+ pArray->m_size = new_size;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_ensure_room(mz_zip_archive *pZip,
+ mz_zip_array *pArray,
+ size_t n) {
+ return mz_zip_array_reserve(pZip, pArray, pArray->m_size + n, MZ_TRUE);
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_array_push_back(mz_zip_archive *pZip,
+ mz_zip_array *pArray,
+ const void *pElements,
+ size_t n) {
+ size_t orig_size = pArray->m_size;
+ if (!mz_zip_array_resize(pZip, pArray, orig_size + n, MZ_TRUE))
+ return MZ_FALSE;
+ memcpy((mz_uint8 *)pArray->m_p + orig_size * pArray->m_element_size,
+ pElements, n * pArray->m_element_size);
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_TIME
+static time_t mz_zip_dos_to_time_t(int dos_time, int dos_date) {
+ struct tm tm;
+ memset(&tm, 0, sizeof(tm));
+ tm.tm_isdst = -1;
+ tm.tm_year = ((dos_date >> 9) & 127) + 1980 - 1900;
+ tm.tm_mon = ((dos_date >> 5) & 15) - 1;
+ tm.tm_mday = dos_date & 31;
+ tm.tm_hour = (dos_time >> 11) & 31;
+ tm.tm_min = (dos_time >> 5) & 63;
+ tm.tm_sec = (dos_time << 1) & 62;
+ return mktime(&tm);
+}
+
+static void mz_zip_time_to_dos_time(time_t time, mz_uint16 *pDOS_time,
+ mz_uint16 *pDOS_date) {
+#ifdef _MSC_VER
+ struct tm tm_struct;
+ struct tm *tm = &tm_struct;
+ errno_t err = localtime_s(tm, &time);
+ if (err) {
+ *pDOS_date = 0;
+ *pDOS_time = 0;
+ return;
+ }
+#else
+ struct tm *tm = localtime(&time);
+#endif
+ *pDOS_time = (mz_uint16)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) +
+ ((tm->tm_sec) >> 1));
+ *pDOS_date = (mz_uint16)(((tm->tm_year + 1900 - 1980) << 9) +
+ ((tm->tm_mon + 1) << 5) + tm->tm_mday);
+}
+#endif
+
+#ifndef MINIZ_NO_STDIO
+static mz_bool mz_zip_get_file_modified_time(const char *pFilename,
+ mz_uint16 *pDOS_time,
+ mz_uint16 *pDOS_date) {
+#ifdef MINIZ_NO_TIME
+ (void)pFilename;
+ *pDOS_date = *pDOS_time = 0;
+#else
+ struct MZ_FILE_STAT_STRUCT file_stat;
+ // On Linux with x86 glibc, this call will fail on large files (>= 0x80000000
+ // bytes) unless you compiled with _LARGEFILE64_SOURCE. Argh.
+ if (MZ_FILE_STAT(pFilename, &file_stat) != 0) return MZ_FALSE;
+ mz_zip_time_to_dos_time(file_stat.st_mtime, pDOS_time, pDOS_date);
+#endif // #ifdef MINIZ_NO_TIME
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_TIME
+static mz_bool mz_zip_set_file_times(const char *pFilename, time_t access_time,
+ time_t modified_time) {
+ struct utimbuf t;
+ t.actime = access_time;
+ t.modtime = modified_time;
+ return !utime(pFilename, &t);
+}
+#endif // #ifndef MINIZ_NO_TIME
+#endif // #ifndef MINIZ_NO_STDIO
+
+static mz_bool mz_zip_reader_init_internal(mz_zip_archive *pZip,
+ mz_uint32 flags) {
+ (void)flags;
+ if ((!pZip) || (pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return MZ_FALSE;
+
+ if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
+ if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
+ if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_READING;
+ pZip->m_archive_size = 0;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return MZ_FALSE;
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
+ sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
+ sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
+ sizeof(mz_uint32));
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE mz_bool
+mz_zip_reader_filename_less(const mz_zip_array *pCentral_dir_array,
+ const mz_zip_array *pCentral_dir_offsets,
+ mz_uint l_index, mz_uint r_index) {
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
+ pCentral_dir_array, mz_uint8,
+ MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
+ l_index)),
+ *pE;
+ const mz_uint8 *pR = &MZ_ZIP_ARRAY_ELEMENT(
+ pCentral_dir_array, mz_uint8,
+ MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32, r_index));
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS),
+ r_len = MZ_READ_LE16(pR + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pR += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE) {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break;
+ pL++;
+ pR++;
+ }
+ return (pL == pE) ? (l_len < r_len) : (l < r);
+}
+
+#define MZ_SWAP_UINT32(a, b) \
+ do { \
+ mz_uint32 t = a; \
+ a = b; \
+ b = t; \
+ } \
+ MZ_MACRO_END
+
+// Heap sort of lowercased filenames, used to help accelerate plain central
+// directory searches by mz_zip_reader_locate_file(). (Could also use qsort(),
+// but it could allocate memory.)
+static void mz_zip_reader_sort_central_dir_offsets_by_filename(
+ mz_zip_archive *pZip) {
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(
+ &pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+ const int size = pZip->m_total_files;
+ int start = (size - 2) >> 1, end;
+ while (start >= 0) {
+ int child, root = start;
+ for (;;) {
+ if ((child = (root << 1) + 1) >= size) break;
+ child +=
+ (((child + 1) < size) &&
+ (mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
+ pIndices[child], pIndices[child + 1])));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
+ pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
+ root = child;
+ }
+ start--;
+ }
+
+ end = size - 1;
+ while (end > 0) {
+ int child, root = 0;
+ MZ_SWAP_UINT32(pIndices[end], pIndices[0]);
+ for (;;) {
+ if ((child = (root << 1) + 1) >= end) break;
+ child +=
+ (((child + 1) < end) &&
+ mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
+ pIndices[child], pIndices[child + 1]));
+ if (!mz_zip_reader_filename_less(pCentral_dir, pCentral_dir_offsets,
+ pIndices[root], pIndices[child]))
+ break;
+ MZ_SWAP_UINT32(pIndices[root], pIndices[child]);
+ root = child;
+ }
+ end--;
+ }
+}
+
+static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip,
+ mz_uint32 flags) {
+ mz_uint cdir_size, num_this_disk, cdir_disk_index;
+ mz_uint64 cdir_ofs;
+ mz_int64 cur_file_ofs;
+ const mz_uint8 *p;
+ mz_uint32 buf_u32[4096 / sizeof(mz_uint32)];
+ mz_uint8 *pBuf = (mz_uint8 *)buf_u32;
+ mz_bool sort_central_dir =
+ ((flags & MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY) == 0);
+ // Basic sanity checks - reject files which are too small, and check the first
+ // 4 bytes of the file to make sure a local header is there.
+ if (pZip->m_archive_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ // Find the end of central directory record by scanning the file from the end
+ // towards the beginning.
+ cur_file_ofs =
+ MZ_MAX((mz_int64)pZip->m_archive_size - (mz_int64)sizeof(buf_u32), 0);
+ for (;;) {
+ int i,
+ n = (int)MZ_MIN(sizeof(buf_u32), pZip->m_archive_size - cur_file_ofs);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf, n) != (mz_uint)n)
+ return MZ_FALSE;
+ for (i = n - 4; i >= 0; --i)
+ if (MZ_READ_LE32(pBuf + i) == MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) break;
+ if (i >= 0) {
+ cur_file_ofs += i;
+ break;
+ }
+ if ((!cur_file_ofs) || ((pZip->m_archive_size - cur_file_ofs) >=
+ (0xFFFF + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)))
+ return MZ_FALSE;
+ cur_file_ofs = MZ_MAX(cur_file_ofs - (sizeof(buf_u32) - 3), 0);
+ }
+ // Read and verify the end of central directory record.
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) !=
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if ((MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_SIG_OFS) !=
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG) ||
+ ((pZip->m_total_files =
+ MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS)) !=
+ MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS)))
+ return MZ_FALSE;
+
+ num_this_disk = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_THIS_DISK_OFS);
+ cdir_disk_index = MZ_READ_LE16(pBuf + MZ_ZIP_ECDH_NUM_DISK_CDIR_OFS);
+ if (((num_this_disk | cdir_disk_index) != 0) &&
+ ((num_this_disk != 1) || (cdir_disk_index != 1)))
+ return MZ_FALSE;
+
+ if ((cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS)) <
+ pZip->m_total_files * MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+
+ cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
+ if ((cdir_ofs + (mz_uint64)cdir_size) > pZip->m_archive_size) return MZ_FALSE;
+
+ pZip->m_central_directory_file_ofs = cdir_ofs;
+
+ if (pZip->m_total_files) {
+ mz_uint i, n;
+
+ // Read the entire central directory into a heap block, and allocate another
+ // heap block to hold the unsorted central dir file record offsets, and
+ // another to hold the sorted indices.
+ if ((!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir, cdir_size,
+ MZ_FALSE)) ||
+ (!mz_zip_array_resize(pZip, &pZip->m_pState->m_central_dir_offsets,
+ pZip->m_total_files, MZ_FALSE)))
+ return MZ_FALSE;
+
+ if (sort_central_dir) {
+ if (!mz_zip_array_resize(pZip,
+ &pZip->m_pState->m_sorted_central_dir_offsets,
+ pZip->m_total_files, MZ_FALSE))
+ return MZ_FALSE;
+ }
+
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs,
+ pZip->m_pState->m_central_dir.m_p,
+ cdir_size) != cdir_size)
+ return MZ_FALSE;
+
+ // Now create an index into the central directory file records, do some
+ // basic sanity checking on each record, and check for zip64 entries (which
+ // are not yet supported).
+ p = (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p;
+ for (n = cdir_size, i = 0; i < pZip->m_total_files; ++i) {
+ mz_uint total_header_size, comp_size, decomp_size, disk_index;
+ if ((n < MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) ||
+ (MZ_READ_LE32(p) != MZ_ZIP_CENTRAL_DIR_HEADER_SIG))
+ return MZ_FALSE;
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
+ i) =
+ (mz_uint32)(p - (const mz_uint8 *)pZip->m_pState->m_central_dir.m_p);
+ if (sort_central_dir)
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_sorted_central_dir_offsets,
+ mz_uint32, i) = i;
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ decomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ if (((!MZ_READ_LE32(p + MZ_ZIP_CDH_METHOD_OFS)) &&
+ (decomp_size != comp_size)) ||
+ (decomp_size && !comp_size) || (decomp_size == 0xFFFFFFFF) ||
+ (comp_size == 0xFFFFFFFF))
+ return MZ_FALSE;
+ disk_index = MZ_READ_LE16(p + MZ_ZIP_CDH_DISK_START_OFS);
+ if ((disk_index != num_this_disk) && (disk_index != 1)) return MZ_FALSE;
+ if (((mz_uint64)MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS) +
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE + comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+ if ((total_header_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
+ MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
+ MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS)) >
+ n)
+ return MZ_FALSE;
+ n -= total_header_size;
+ p += total_header_size;
+ }
+ }
+
+ if (sort_central_dir)
+ mz_zip_reader_sort_central_dir_offsets_by_filename(pZip);
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_reader_init(mz_zip_archive *pZip, mz_uint64 size,
+ mz_uint32 flags) {
+ if ((!pZip) || (!pZip->m_pRead)) return MZ_FALSE;
+ if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE;
+ pZip->m_archive_size = size;
+ if (!mz_zip_reader_read_central_dir(pZip, flags)) {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+static size_t mz_zip_mem_read_func(void *pOpaque, mz_uint64 file_ofs,
+ void *pBuf, size_t n) {
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ size_t s = (file_ofs >= pZip->m_archive_size)
+ ? 0
+ : (size_t)MZ_MIN(pZip->m_archive_size - file_ofs, n);
+ memcpy(pBuf, (const mz_uint8 *)pZip->m_pState->m_pMem + file_ofs, s);
+ return s;
+}
+
+mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem,
+ size_t size, mz_uint32 flags) {
+ if (!mz_zip_reader_init_internal(pZip, flags)) return MZ_FALSE;
+ pZip->m_archive_size = size;
+ pZip->m_pRead = mz_zip_mem_read_func;
+ pZip->m_pIO_opaque = pZip;
+#ifdef __cplusplus
+ pZip->m_pState->m_pMem = const_cast<void *>(pMem);
+#else
+ pZip->m_pState->m_pMem = (void *)pMem;
+#endif
+ pZip->m_pState->m_mem_size = size;
+ if (!mz_zip_reader_read_central_dir(pZip, flags)) {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_read_func(void *pOpaque, mz_uint64 file_ofs,
+ void *pBuf, size_t n) {
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+ if (((mz_int64)file_ofs < 0) ||
+ (((cur_ofs != (mz_int64)file_ofs)) &&
+ (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+ return MZ_FREAD(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename,
+ mz_uint32 flags) {
+ mz_uint64 file_size;
+ MZ_FILE *pFile = MZ_FOPEN(pFilename, "rb");
+ if (!pFile) return MZ_FALSE;
+ if (MZ_FSEEK64(pFile, 0, SEEK_END)) {
+ MZ_FCLOSE(pFile);
+ return MZ_FALSE;
+ }
+ file_size = MZ_FTELL64(pFile);
+ if (!mz_zip_reader_init_internal(pZip, flags)) {
+ MZ_FCLOSE(pFile);
+ return MZ_FALSE;
+ }
+ pZip->m_pRead = mz_zip_file_read_func;
+ pZip->m_pIO_opaque = pZip;
+ pZip->m_pState->m_pFile = pFile;
+ pZip->m_archive_size = file_size;
+ if (!mz_zip_reader_read_central_dir(pZip, flags)) {
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip) {
+ return pZip ? pZip->m_total_files : 0;
+}
+
+static MZ_FORCEINLINE const mz_uint8 *mz_zip_reader_get_cdh(
+ mz_zip_archive *pZip, mz_uint file_index) {
+ if ((!pZip) || (!pZip->m_pState) || (file_index >= pZip->m_total_files) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return NULL;
+ return &MZ_ZIP_ARRAY_ELEMENT(
+ &pZip->m_pState->m_central_dir, mz_uint8,
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
+ file_index));
+}
+
+mz_bool mz_zip_reader_is_file_encrypted(mz_zip_archive *pZip,
+ mz_uint file_index) {
+ mz_uint m_bit_flag;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p) return MZ_FALSE;
+ m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ return (m_bit_flag & 1);
+}
+
+mz_bool mz_zip_reader_is_file_a_directory(mz_zip_archive *pZip,
+ mz_uint file_index) {
+ mz_uint filename_len, external_attr;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p) return MZ_FALSE;
+
+ // First see if the filename ends with a '/' character.
+ filename_len = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_len) {
+ if (*(p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_len - 1) == '/')
+ return MZ_TRUE;
+ }
+
+ // Bugfix: This code was also checking if the internal attribute was non-zero,
+ // which wasn't correct.
+ // Most/all zip writers (hopefully) set DOS file/directory attributes in the
+ // low 16-bits, so check for the DOS directory flag and ignore the source OS
+ // ID in the created by field.
+ // FIXME: Remove this check? Is it necessary - we already check the filename.
+ external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ if ((external_attr & 0x10) != 0) return MZ_TRUE;
+
+ return MZ_FALSE;
+}
+
+mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index,
+ mz_zip_archive_file_stat *pStat) {
+ mz_uint n;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if ((!p) || (!pStat)) return MZ_FALSE;
+
+ // Unpack the central directory record.
+ pStat->m_file_index = file_index;
+ pStat->m_central_dir_ofs = MZ_ZIP_ARRAY_ELEMENT(
+ &pZip->m_pState->m_central_dir_offsets, mz_uint32, file_index);
+ pStat->m_version_made_by = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_MADE_BY_OFS);
+ pStat->m_version_needed = MZ_READ_LE16(p + MZ_ZIP_CDH_VERSION_NEEDED_OFS);
+ pStat->m_bit_flag = MZ_READ_LE16(p + MZ_ZIP_CDH_BIT_FLAG_OFS);
+ pStat->m_method = MZ_READ_LE16(p + MZ_ZIP_CDH_METHOD_OFS);
+#ifndef MINIZ_NO_TIME
+ pStat->m_time =
+ mz_zip_dos_to_time_t(MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_TIME_OFS),
+ MZ_READ_LE16(p + MZ_ZIP_CDH_FILE_DATE_OFS));
+#endif
+ pStat->m_crc32 = MZ_READ_LE32(p + MZ_ZIP_CDH_CRC32_OFS);
+ pStat->m_comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ pStat->m_uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+ pStat->m_internal_attr = MZ_READ_LE16(p + MZ_ZIP_CDH_INTERNAL_ATTR_OFS);
+ pStat->m_external_attr = MZ_READ_LE32(p + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS);
+ pStat->m_local_header_ofs = MZ_READ_LE32(p + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+
+ // Copy as much of the filename and comment as possible.
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILENAME_SIZE - 1);
+ memcpy(pStat->m_filename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
+ pStat->m_filename[n] = '\0';
+
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ n = MZ_MIN(n, MZ_ZIP_MAX_ARCHIVE_FILE_COMMENT_SIZE - 1);
+ pStat->m_comment_size = n;
+ memcpy(pStat->m_comment, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
+ MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(p + MZ_ZIP_CDH_EXTRA_LEN_OFS),
+ n);
+ pStat->m_comment[n] = '\0';
+
+ return MZ_TRUE;
+}
+
+mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index,
+ char *pFilename, mz_uint filename_buf_size) {
+ mz_uint n;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ if (!p) {
+ if (filename_buf_size) pFilename[0] = '\0';
+ return 0;
+ }
+ n = MZ_READ_LE16(p + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ if (filename_buf_size) {
+ n = MZ_MIN(n, filename_buf_size - 1);
+ memcpy(pFilename, p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n);
+ pFilename[n] = '\0';
+ }
+ return n + 1;
+}
+
+static MZ_FORCEINLINE mz_bool mz_zip_reader_string_equal(const char *pA,
+ const char *pB,
+ mz_uint len,
+ mz_uint flags) {
+ mz_uint i;
+ if (flags & MZ_ZIP_FLAG_CASE_SENSITIVE) return 0 == memcmp(pA, pB, len);
+ for (i = 0; i < len; ++i)
+ if (MZ_TOLOWER(pA[i]) != MZ_TOLOWER(pB[i])) return MZ_FALSE;
+ return MZ_TRUE;
+}
+
+static MZ_FORCEINLINE int mz_zip_reader_filename_compare(
+ const mz_zip_array *pCentral_dir_array,
+ const mz_zip_array *pCentral_dir_offsets, mz_uint l_index, const char *pR,
+ mz_uint r_len) {
+ const mz_uint8 *pL = &MZ_ZIP_ARRAY_ELEMENT(
+ pCentral_dir_array, mz_uint8,
+ MZ_ZIP_ARRAY_ELEMENT(pCentral_dir_offsets, mz_uint32,
+ l_index)),
+ *pE;
+ mz_uint l_len = MZ_READ_LE16(pL + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ mz_uint8 l = 0, r = 0;
+ pL += MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ pE = pL + MZ_MIN(l_len, r_len);
+ while (pL < pE) {
+ if ((l = MZ_TOLOWER(*pL)) != (r = MZ_TOLOWER(*pR))) break;
+ pL++;
+ pR++;
+ }
+ return (pL == pE) ? (int)(l_len - r_len) : (l - r);
+}
+
+static int mz_zip_reader_locate_file_binary_search(mz_zip_archive *pZip,
+ const char *pFilename) {
+ mz_zip_internal_state *pState = pZip->m_pState;
+ const mz_zip_array *pCentral_dir_offsets = &pState->m_central_dir_offsets;
+ const mz_zip_array *pCentral_dir = &pState->m_central_dir;
+ mz_uint32 *pIndices = &MZ_ZIP_ARRAY_ELEMENT(
+ &pState->m_sorted_central_dir_offsets, mz_uint32, 0);
+ const int size = pZip->m_total_files;
+ const mz_uint filename_len = (mz_uint)strlen(pFilename);
+ int l = 0, h = size - 1;
+ while (l <= h) {
+ int m = (l + h) >> 1, file_index = pIndices[m],
+ comp =
+ mz_zip_reader_filename_compare(pCentral_dir, pCentral_dir_offsets,
+ file_index, pFilename, filename_len);
+ if (!comp)
+ return file_index;
+ else if (comp < 0)
+ l = m + 1;
+ else
+ h = m - 1;
+ }
+ return -1;
+}
+
+int mz_zip_reader_locate_file(mz_zip_archive *pZip, const char *pName,
+ const char *pComment, mz_uint flags) {
+ mz_uint file_index;
+ size_t name_len, comment_len;
+ if ((!pZip) || (!pZip->m_pState) || (!pName) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return -1;
+ if (((flags & (MZ_ZIP_FLAG_IGNORE_PATH | MZ_ZIP_FLAG_CASE_SENSITIVE)) == 0) &&
+ (!pComment) && (pZip->m_pState->m_sorted_central_dir_offsets.m_size))
+ return mz_zip_reader_locate_file_binary_search(pZip, pName);
+ name_len = strlen(pName);
+ if (name_len > 0xFFFF) return -1;
+ comment_len = pComment ? strlen(pComment) : 0;
+ if (comment_len > 0xFFFF) return -1;
+ for (file_index = 0; file_index < pZip->m_total_files; file_index++) {
+ const mz_uint8 *pHeader = &MZ_ZIP_ARRAY_ELEMENT(
+ &pZip->m_pState->m_central_dir, mz_uint8,
+ MZ_ZIP_ARRAY_ELEMENT(&pZip->m_pState->m_central_dir_offsets, mz_uint32,
+ file_index));
+ mz_uint filename_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_FILENAME_LEN_OFS);
+ const char *pFilename =
+ (const char *)pHeader + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE;
+ if (filename_len < name_len) continue;
+ if (comment_len) {
+ mz_uint file_extra_len = MZ_READ_LE16(pHeader + MZ_ZIP_CDH_EXTRA_LEN_OFS),
+ file_comment_len =
+ MZ_READ_LE16(pHeader + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ const char *pFile_comment = pFilename + filename_len + file_extra_len;
+ if ((file_comment_len != comment_len) ||
+ (!mz_zip_reader_string_equal(pComment, pFile_comment,
+ file_comment_len, flags)))
+ continue;
+ }
+ if ((flags & MZ_ZIP_FLAG_IGNORE_PATH) && (filename_len)) {
+ int ofs = filename_len - 1;
+ do {
+ if ((pFilename[ofs] == '/') || (pFilename[ofs] == '\\') ||
+ (pFilename[ofs] == ':'))
+ break;
+ } while (--ofs >= 0);
+ ofs++;
+ pFilename += ofs;
+ filename_len -= ofs;
+ }
+ if ((filename_len == name_len) &&
+ (mz_zip_reader_string_equal(pName, pFilename, filename_len, flags)))
+ return file_index;
+ }
+ return -1;
+}
+
+mz_bool mz_zip_reader_extract_to_mem_no_alloc(mz_zip_archive *pZip,
+ mz_uint file_index, void *pBuf,
+ size_t buf_size, mz_uint flags,
+ void *pUser_read_buf,
+ size_t user_read_buf_size) {
+ int status = TINFL_STATUS_DONE;
+ mz_uint64 needed_size, cur_file_ofs, comp_remaining,
+ out_buf_ofs = 0, read_buf_size, read_buf_ofs = 0, read_buf_avail;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf;
+ mz_uint32
+ local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) /
+ sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ tinfl_decompressor inflator;
+
+ if ((buf_size) && (!pBuf)) return MZ_FALSE;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE;
+
+ // Empty file, or a directory (but not always a directory - I've seen odd zips
+ // with directories that have compressed data which inflates to 0 bytes)
+ if (!file_stat.m_comp_size) return MZ_TRUE;
+
+ // Entry is a subdirectory (I've seen old zips with dir entries which have
+ // compressed deflate data which inflates to 0 bytes, but these entries claim
+ // to uncompress to 512 bytes in the headers).
+ // I'm torn how to handle this case - should it fail instead?
+ if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE;
+
+ // Encryption and patch files are not supported.
+ if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE;
+
+ // This function only supports stored and deflate.
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
+ (file_stat.m_method != MZ_DEFLATED))
+ return MZ_FALSE;
+
+ // Ensure supplied output buffer is large enough.
+ needed_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? file_stat.m_comp_size
+ : file_stat.m_uncomp_size;
+ if (buf_size < needed_size) return MZ_FALSE;
+
+ // Read and parse the local directory entry.
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
+ MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
+ // The file is stored or the caller has requested the compressed data.
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pBuf,
+ (size_t)needed_size) != needed_size)
+ return MZ_FALSE;
+ return ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) != 0) ||
+ (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf,
+ (size_t)file_stat.m_uncomp_size) == file_stat.m_crc32);
+ }
+
+ // Decompress the file either directly from memory or from a file input
+ // buffer.
+ tinfl_init(&inflator);
+
+ if (pZip->m_pState->m_pMem) {
+ // Read directly from the archive in memory.
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ } else if (pUser_read_buf) {
+ // Use a user provided read buffer.
+ if (!user_read_buf_size) return MZ_FALSE;
+ pRead_buf = (mz_uint8 *)pUser_read_buf;
+ read_buf_size = user_read_buf_size;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ } else {
+ // Temporarily allocate a read buffer.
+ read_buf_size =
+ MZ_MIN(file_stat.m_comp_size, (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE);
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
+ (read_buf_size > 0x7FFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (read_buf_size > 0x7FFFFFFF))
+#endif
+ return MZ_FALSE;
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
+ (size_t)read_buf_size)))
+ return MZ_FALSE;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ do {
+ size_t in_buf_size,
+ out_buf_size = (size_t)(file_stat.m_uncomp_size - out_buf_ofs);
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
+ (size_t)read_buf_avail) != read_buf_avail) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(
+ &inflator, (mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
+ (mz_uint8 *)pBuf, (mz_uint8 *)pBuf + out_buf_ofs, &out_buf_size,
+ TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF |
+ (comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0));
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+ out_buf_ofs += out_buf_size;
+ } while (status == TINFL_STATUS_NEEDS_MORE_INPUT);
+
+ if (status == TINFL_STATUS_DONE) {
+ // Make sure the entire file was decompressed, and check its CRC.
+ if ((out_buf_ofs != file_stat.m_uncomp_size) ||
+ (mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf,
+ (size_t)file_stat.m_uncomp_size) != file_stat.m_crc32))
+ status = TINFL_STATUS_FAILED;
+ }
+
+ if ((!pZip->m_pState->m_pMem) && (!pUser_read_buf))
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem_no_alloc(
+ mz_zip_archive *pZip, const char *pFilename, void *pBuf, size_t buf_size,
+ mz_uint flags, void *pUser_read_buf, size_t user_read_buf_size) {
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0) return MZ_FALSE;
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size,
+ flags, pUser_read_buf,
+ user_read_buf_size);
+}
+
+mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index,
+ void *pBuf, size_t buf_size,
+ mz_uint flags) {
+ return mz_zip_reader_extract_to_mem_no_alloc(pZip, file_index, pBuf, buf_size,
+ flags, NULL, 0);
+}
+
+mz_bool mz_zip_reader_extract_file_to_mem(mz_zip_archive *pZip,
+ const char *pFilename, void *pBuf,
+ size_t buf_size, mz_uint flags) {
+ return mz_zip_reader_extract_file_to_mem_no_alloc(pZip, pFilename, pBuf,
+ buf_size, flags, NULL, 0);
+}
+
+void *mz_zip_reader_extract_to_heap(mz_zip_archive *pZip, mz_uint file_index,
+ size_t *pSize, mz_uint flags) {
+ mz_uint64 comp_size, uncomp_size, alloc_size;
+ const mz_uint8 *p = mz_zip_reader_get_cdh(pZip, file_index);
+ void *pBuf;
+
+ if (pSize) *pSize = 0;
+ if (!p) return NULL;
+
+ comp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+ uncomp_size = MZ_READ_LE32(p + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS);
+
+ alloc_size = (flags & MZ_ZIP_FLAG_COMPRESSED_DATA) ? comp_size : uncomp_size;
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) && (alloc_size > 0x7FFFFFFF))
+#endif
+ return NULL;
+ if (NULL ==
+ (pBuf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, (size_t)alloc_size)))
+ return NULL;
+
+ if (!mz_zip_reader_extract_to_mem(pZip, file_index, pBuf, (size_t)alloc_size,
+ flags)) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return NULL;
+ }
+
+ if (pSize) *pSize = (size_t)alloc_size;
+ return pBuf;
+}
+
+void *mz_zip_reader_extract_file_to_heap(mz_zip_archive *pZip,
+ const char *pFilename, size_t *pSize,
+ mz_uint flags) {
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0) {
+ if (pSize) *pSize = 0;
+ return MZ_FALSE;
+ }
+ return mz_zip_reader_extract_to_heap(pZip, file_index, pSize, flags);
+}
+
+mz_bool mz_zip_reader_extract_to_callback(mz_zip_archive *pZip,
+ mz_uint file_index,
+ mz_file_write_func pCallback,
+ void *pOpaque, mz_uint flags) {
+ int status = TINFL_STATUS_DONE;
+ mz_uint file_crc32 = MZ_CRC32_INIT;
+ mz_uint64 read_buf_size, read_buf_ofs = 0, read_buf_avail, comp_remaining,
+ out_buf_ofs = 0, cur_file_ofs;
+ mz_zip_archive_file_stat file_stat;
+ void *pRead_buf = NULL;
+ void *pWrite_buf = NULL;
+ mz_uint32
+ local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) /
+ sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE;
+
+ // Empty file, or a directory (but not always a directory - I've seen odd zips
+ // with directories that have compressed data which inflates to 0 bytes)
+ if (!file_stat.m_comp_size) return MZ_TRUE;
+
+ // Entry is a subdirectory (I've seen old zips with dir entries which have
+ // compressed deflate data which inflates to 0 bytes, but these entries claim
+ // to uncompress to 512 bytes in the headers).
+ // I'm torn how to handle this case - should it fail instead?
+ if (mz_zip_reader_is_file_a_directory(pZip, file_index)) return MZ_TRUE;
+
+ // Encryption and patch files are not supported.
+ if (file_stat.m_bit_flag & (1 | 32)) return MZ_FALSE;
+
+ // This function only supports stored and deflate.
+ if ((!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (file_stat.m_method != 0) &&
+ (file_stat.m_method != MZ_DEFLATED))
+ return MZ_FALSE;
+
+ // Read and parse the local directory entry.
+ cur_file_ofs = file_stat.m_local_header_ofs;
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pLocal_header,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+
+ cur_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE +
+ MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ if ((cur_file_ofs + file_stat.m_comp_size) > pZip->m_archive_size)
+ return MZ_FALSE;
+
+ // Decompress the file either directly from memory or from a file input
+ // buffer.
+ if (pZip->m_pState->m_pMem) {
+ pRead_buf = (mz_uint8 *)pZip->m_pState->m_pMem + cur_file_ofs;
+ read_buf_size = read_buf_avail = file_stat.m_comp_size;
+ comp_remaining = 0;
+ } else {
+ read_buf_size =
+ MZ_MIN(file_stat.m_comp_size, (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (NULL == (pRead_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
+ (size_t)read_buf_size)))
+ return MZ_FALSE;
+ read_buf_avail = 0;
+ comp_remaining = file_stat.m_comp_size;
+ }
+
+ if ((flags & MZ_ZIP_FLAG_COMPRESSED_DATA) || (!file_stat.m_method)) {
+ // The file is stored or the caller has requested the compressed data.
+ if (pZip->m_pState->m_pMem) {
+#ifdef _MSC_VER
+ if (((0, sizeof(size_t) == sizeof(mz_uint32))) &&
+ (file_stat.m_comp_size > 0xFFFFFFFF))
+#else
+ if (((sizeof(size_t) == sizeof(mz_uint32))) &&
+ (file_stat.m_comp_size > 0xFFFFFFFF))
+#endif
+ return MZ_FALSE;
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
+ (size_t)file_stat.m_comp_size) != file_stat.m_comp_size)
+ status = TINFL_STATUS_FAILED;
+ else if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ file_crc32 =
+ (mz_uint32)mz_crc32(file_crc32, (const mz_uint8 *)pRead_buf,
+ (size_t)file_stat.m_comp_size);
+ cur_file_ofs += file_stat.m_comp_size;
+ out_buf_ofs += file_stat.m_comp_size;
+ comp_remaining = 0;
+ } else {
+ while (comp_remaining) {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
+ (size_t)read_buf_avail) != read_buf_avail) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+
+ if (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
+ file_crc32 = (mz_uint32)mz_crc32(
+ file_crc32, (const mz_uint8 *)pRead_buf, (size_t)read_buf_avail);
+
+ if (pCallback(pOpaque, out_buf_ofs, pRead_buf,
+ (size_t)read_buf_avail) != read_buf_avail) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ out_buf_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ }
+ }
+ } else {
+ tinfl_decompressor inflator;
+ tinfl_init(&inflator);
+
+ if (NULL == (pWrite_buf = pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1,
+ TINFL_LZ_DICT_SIZE)))
+ status = TINFL_STATUS_FAILED;
+ else {
+ do {
+ mz_uint8 *pWrite_buf_cur =
+ (mz_uint8 *)pWrite_buf + (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ size_t in_buf_size,
+ out_buf_size =
+ TINFL_LZ_DICT_SIZE - (out_buf_ofs & (TINFL_LZ_DICT_SIZE - 1));
+ if ((!read_buf_avail) && (!pZip->m_pState->m_pMem)) {
+ read_buf_avail = MZ_MIN(read_buf_size, comp_remaining);
+ if (pZip->m_pRead(pZip->m_pIO_opaque, cur_file_ofs, pRead_buf,
+ (size_t)read_buf_avail) != read_buf_avail) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ cur_file_ofs += read_buf_avail;
+ comp_remaining -= read_buf_avail;
+ read_buf_ofs = 0;
+ }
+
+ in_buf_size = (size_t)read_buf_avail;
+ status = tinfl_decompress(
+ &inflator, (const mz_uint8 *)pRead_buf + read_buf_ofs, &in_buf_size,
+ (mz_uint8 *)pWrite_buf, pWrite_buf_cur, &out_buf_size,
+ comp_remaining ? TINFL_FLAG_HAS_MORE_INPUT : 0);
+ read_buf_avail -= in_buf_size;
+ read_buf_ofs += in_buf_size;
+
+ if (out_buf_size) {
+ if (pCallback(pOpaque, out_buf_ofs, pWrite_buf_cur, out_buf_size) !=
+ out_buf_size) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ file_crc32 =
+ (mz_uint32)mz_crc32(file_crc32, pWrite_buf_cur, out_buf_size);
+ if ((out_buf_ofs += out_buf_size) > file_stat.m_uncomp_size) {
+ status = TINFL_STATUS_FAILED;
+ break;
+ }
+ }
+ } while ((status == TINFL_STATUS_NEEDS_MORE_INPUT) ||
+ (status == TINFL_STATUS_HAS_MORE_OUTPUT));
+ }
+ }
+
+ if ((status == TINFL_STATUS_DONE) &&
+ (!(flags & MZ_ZIP_FLAG_COMPRESSED_DATA))) {
+ // Make sure the entire file was decompressed, and check its CRC.
+ if ((out_buf_ofs != file_stat.m_uncomp_size) ||
+ (file_crc32 != file_stat.m_crc32))
+ status = TINFL_STATUS_FAILED;
+ }
+
+ if (!pZip->m_pState->m_pMem) pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ if (pWrite_buf) pZip->m_pFree(pZip->m_pAlloc_opaque, pWrite_buf);
+
+ return status == TINFL_STATUS_DONE;
+}
+
+mz_bool mz_zip_reader_extract_file_to_callback(mz_zip_archive *pZip,
+ const char *pFilename,
+ mz_file_write_func pCallback,
+ void *pOpaque, mz_uint flags) {
+ int file_index = mz_zip_reader_locate_file(pZip, pFilename, NULL, flags);
+ if (file_index < 0) return MZ_FALSE;
+ return mz_zip_reader_extract_to_callback(pZip, file_index, pCallback, pOpaque,
+ flags);
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_callback(void *pOpaque, mz_uint64 ofs,
+ const void *pBuf, size_t n) {
+ (void)ofs;
+ return MZ_FWRITE(pBuf, 1, n, (MZ_FILE *)pOpaque);
+}
+
+mz_bool mz_zip_reader_extract_to_file(mz_zip_archive *pZip, mz_uint file_index,
+ const char *pDst_filename,
+ mz_uint flags) {
+ mz_bool status;
+ mz_zip_archive_file_stat file_stat;
+ MZ_FILE *pFile;
+ if (!mz_zip_reader_file_stat(pZip, file_index, &file_stat)) return MZ_FALSE;
+ pFile = MZ_FOPEN(pDst_filename, "wb");
+ if (!pFile) return MZ_FALSE;
+ status = mz_zip_reader_extract_to_callback(
+ pZip, file_index, mz_zip_file_write_callback, pFile, flags);
+ if (MZ_FCLOSE(pFile) == EOF) return MZ_FALSE;
+#ifndef MINIZ_NO_TIME
+ if (status)
+ mz_zip_set_file_times(pDst_filename, file_stat.m_time, file_stat.m_time);
+#endif
+ return status;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_reader_end(mz_zip_archive *pZip) {
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return MZ_FALSE;
+
+ if (pZip->m_pState) {
+ mz_zip_internal_state *pState = pZip->m_pState;
+ pZip->m_pState = NULL;
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile) {
+ MZ_FCLOSE(pState->m_pFile);
+ pState->m_pFile = NULL;
+ }
+#endif // #ifndef MINIZ_NO_STDIO
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ }
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_reader_extract_file_to_file(mz_zip_archive *pZip,
+ const char *pArchive_filename,
+ const char *pDst_filename,
+ mz_uint flags) {
+ int file_index =
+ mz_zip_reader_locate_file(pZip, pArchive_filename, NULL, flags);
+ if (file_index < 0) return MZ_FALSE;
+ return mz_zip_reader_extract_to_file(pZip, file_index, pDst_filename, flags);
+}
+#endif
+
+// ------------------- .ZIP archive writing
+
+#ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+static void mz_write_le16(mz_uint8 *p, mz_uint16 v) {
+ p[0] = (mz_uint8)v;
+ p[1] = (mz_uint8)(v >> 8);
+}
+static void mz_write_le32(mz_uint8 *p, mz_uint32 v) {
+ p[0] = (mz_uint8)v;
+ p[1] = (mz_uint8)(v >> 8);
+ p[2] = (mz_uint8)(v >> 16);
+ p[3] = (mz_uint8)(v >> 24);
+}
+#define MZ_WRITE_LE16(p, v) mz_write_le16((mz_uint8 *)(p), (mz_uint16)(v))
+#define MZ_WRITE_LE32(p, v) mz_write_le32((mz_uint8 *)(p), (mz_uint32)(v))
+
+mz_bool mz_zip_writer_init(mz_zip_archive *pZip, mz_uint64 existing_size) {
+ if ((!pZip) || (pZip->m_pState) || (!pZip->m_pWrite) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_INVALID))
+ return MZ_FALSE;
+
+ if (pZip->m_file_offset_alignment) {
+ // Ensure user specified file offset alignment is a power of 2.
+ if (pZip->m_file_offset_alignment & (pZip->m_file_offset_alignment - 1))
+ return MZ_FALSE;
+ }
+
+ if (!pZip->m_pAlloc) pZip->m_pAlloc = def_alloc_func;
+ if (!pZip->m_pFree) pZip->m_pFree = def_free_func;
+ if (!pZip->m_pRealloc) pZip->m_pRealloc = def_realloc_func;
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+ pZip->m_archive_size = existing_size;
+ pZip->m_central_directory_file_ofs = 0;
+ pZip->m_total_files = 0;
+
+ if (NULL == (pZip->m_pState = (mz_zip_internal_state *)pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1, sizeof(mz_zip_internal_state))))
+ return MZ_FALSE;
+ memset(pZip->m_pState, 0, sizeof(mz_zip_internal_state));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir,
+ sizeof(mz_uint8));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_central_dir_offsets,
+ sizeof(mz_uint32));
+ MZ_ZIP_ARRAY_SET_ELEMENT_SIZE(&pZip->m_pState->m_sorted_central_dir_offsets,
+ sizeof(mz_uint32));
+ return MZ_TRUE;
+}
+
+static size_t mz_zip_heap_write_func(void *pOpaque, mz_uint64 file_ofs,
+ const void *pBuf, size_t n) {
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint64 new_size = MZ_MAX(file_ofs + n, pState->m_mem_size);
+#ifdef _MSC_VER
+ if ((!n) ||
+ ((0, sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
+#else
+ if ((!n) ||
+ ((sizeof(size_t) == sizeof(mz_uint32)) && (new_size > 0x7FFFFFFF)))
+#endif
+ return 0;
+ if (new_size > pState->m_mem_capacity) {
+ void *pNew_block;
+ size_t new_capacity = MZ_MAX(64, pState->m_mem_capacity);
+ while (new_capacity < new_size) new_capacity *= 2;
+ if (NULL == (pNew_block = pZip->m_pRealloc(
+ pZip->m_pAlloc_opaque, pState->m_pMem, 1, new_capacity)))
+ return 0;
+ pState->m_pMem = pNew_block;
+ pState->m_mem_capacity = new_capacity;
+ }
+ memcpy((mz_uint8 *)pState->m_pMem + file_ofs, pBuf, n);
+ pState->m_mem_size = (size_t)new_size;
+ return n;
+}
+
+mz_bool mz_zip_writer_init_heap(mz_zip_archive *pZip,
+ size_t size_to_reserve_at_beginning,
+ size_t initial_allocation_size) {
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ pZip->m_pIO_opaque = pZip;
+ if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE;
+ if (0 != (initial_allocation_size = MZ_MAX(initial_allocation_size,
+ size_to_reserve_at_beginning))) {
+ if (NULL == (pZip->m_pState->m_pMem = pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1, initial_allocation_size))) {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ pZip->m_pState->m_mem_capacity = initial_allocation_size;
+ }
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+static size_t mz_zip_file_write_func(void *pOpaque, mz_uint64 file_ofs,
+ const void *pBuf, size_t n) {
+ mz_zip_archive *pZip = (mz_zip_archive *)pOpaque;
+ mz_int64 cur_ofs = MZ_FTELL64(pZip->m_pState->m_pFile);
+ if (((mz_int64)file_ofs < 0) ||
+ (((cur_ofs != (mz_int64)file_ofs)) &&
+ (MZ_FSEEK64(pZip->m_pState->m_pFile, (mz_int64)file_ofs, SEEK_SET))))
+ return 0;
+ return MZ_FWRITE(pBuf, 1, n, pZip->m_pState->m_pFile);
+}
+
+mz_bool mz_zip_writer_init_file(mz_zip_archive *pZip, const char *pFilename,
+ mz_uint64 size_to_reserve_at_beginning) {
+ MZ_FILE *pFile;
+ pZip->m_pWrite = mz_zip_file_write_func;
+ pZip->m_pIO_opaque = pZip;
+ if (!mz_zip_writer_init(pZip, size_to_reserve_at_beginning)) return MZ_FALSE;
+ if (NULL == (pFile = MZ_FOPEN(pFilename, "wb"))) {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ pZip->m_pState->m_pFile = pFile;
+ if (size_to_reserve_at_beginning) {
+ mz_uint64 cur_ofs = 0;
+ char buf[4096];
+ MZ_CLEAR_OBJ(buf);
+ do {
+ size_t n = (size_t)MZ_MIN(sizeof(buf), size_to_reserve_at_beginning);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_ofs, buf, n) != n) {
+ mz_zip_writer_end(pZip);
+ return MZ_FALSE;
+ }
+ cur_ofs += n;
+ size_to_reserve_at_beginning -= n;
+ } while (size_to_reserve_at_beginning);
+ }
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_writer_init_from_reader(mz_zip_archive *pZip,
+ const char *pFilename) {
+ mz_zip_internal_state *pState;
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_READING))
+ return MZ_FALSE;
+ // No sense in trying to write to an archive that's already at the support max
+ // size
+ if ((pZip->m_total_files == 0xFFFF) ||
+ ((pZip->m_archive_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ if (pState->m_pFile) {
+#ifdef MINIZ_NO_STDIO
+ pFilename;
+ return MZ_FALSE;
+#else
+ // Archive is being read from stdio - try to reopen as writable.
+ if (pZip->m_pIO_opaque != pZip) return MZ_FALSE;
+ if (!pFilename) return MZ_FALSE;
+ pZip->m_pWrite = mz_zip_file_write_func;
+ if (NULL ==
+ (pState->m_pFile = MZ_FREOPEN(pFilename, "r+b", pState->m_pFile))) {
+ // The mz_zip_archive is now in a bogus state because pState->m_pFile is
+ // NULL, so just close it.
+ mz_zip_reader_end(pZip);
+ return MZ_FALSE;
+ }
+#endif // #ifdef MINIZ_NO_STDIO
+ } else if (pState->m_pMem) {
+ // Archive lives in a memory block. Assume it's from the heap that we can
+ // resize using the realloc callback.
+ if (pZip->m_pIO_opaque != pZip) return MZ_FALSE;
+ pState->m_mem_capacity = pState->m_mem_size;
+ pZip->m_pWrite = mz_zip_heap_write_func;
+ }
+ // Archive is being read via a user provided read function - make sure the
+ // user has specified a write function too.
+ else if (!pZip->m_pWrite)
+ return MZ_FALSE;
+
+ // Start writing new files at the archive's current central directory
+ // location.
+ pZip->m_archive_size = pZip->m_central_directory_file_ofs;
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING;
+ pZip->m_central_directory_file_ofs = 0;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_mem(mz_zip_archive *pZip, const char *pArchive_name,
+ const void *pBuf, size_t buf_size,
+ mz_uint level_and_flags) {
+ return mz_zip_writer_add_mem_ex(pZip, pArchive_name, pBuf, buf_size, NULL, 0,
+ level_and_flags, 0, 0);
+}
+
+typedef struct {
+ mz_zip_archive *m_pZip;
+ mz_uint64 m_cur_archive_file_ofs;
+ mz_uint64 m_comp_size;
+} mz_zip_writer_add_state;
+
+static mz_bool mz_zip_writer_add_put_buf_callback(const void *pBuf, int len,
+ void *pUser) {
+ mz_zip_writer_add_state *pState = (mz_zip_writer_add_state *)pUser;
+ if ((int)pState->m_pZip->m_pWrite(pState->m_pZip->m_pIO_opaque,
+ pState->m_cur_archive_file_ofs, pBuf,
+ len) != len)
+ return MZ_FALSE;
+ pState->m_cur_archive_file_ofs += len;
+ pState->m_comp_size += len;
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_create_local_dir_header(
+ mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size,
+ mz_uint16 extra_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
+ mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
+ mz_uint16 dos_time, mz_uint16 dos_date) {
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_LOCAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_SIG_OFS, MZ_ZIP_LOCAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_COMPRESSED_SIZE_OFS, comp_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_LDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_LDH_EXTRA_LEN_OFS, extra_size);
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_create_central_dir_header(
+ mz_zip_archive *pZip, mz_uint8 *pDst, mz_uint16 filename_size,
+ mz_uint16 extra_size, mz_uint16 comment_size, mz_uint64 uncomp_size,
+ mz_uint64 comp_size, mz_uint32 uncomp_crc32, mz_uint16 method,
+ mz_uint16 bit_flags, mz_uint16 dos_time, mz_uint16 dos_date,
+ mz_uint64 local_header_ofs, mz_uint32 ext_attributes) {
+ (void)pZip;
+ memset(pDst, 0, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_SIG_OFS, MZ_ZIP_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_VERSION_NEEDED_OFS, method ? 20 : 0);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_BIT_FLAG_OFS, bit_flags);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_METHOD_OFS, method);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_TIME_OFS, dos_time);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILE_DATE_OFS, dos_date);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_CRC32_OFS, uncomp_crc32);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS, comp_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_DECOMPRESSED_SIZE_OFS, uncomp_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_FILENAME_LEN_OFS, filename_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_EXTRA_LEN_OFS, extra_size);
+ MZ_WRITE_LE16(pDst + MZ_ZIP_CDH_COMMENT_LEN_OFS, comment_size);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_EXTERNAL_ATTR_OFS, ext_attributes);
+ MZ_WRITE_LE32(pDst + MZ_ZIP_CDH_LOCAL_HEADER_OFS, local_header_ofs);
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_add_to_central_dir(
+ mz_zip_archive *pZip, const char *pFilename, mz_uint16 filename_size,
+ const void *pExtra, mz_uint16 extra_size, const void *pComment,
+ mz_uint16 comment_size, mz_uint64 uncomp_size, mz_uint64 comp_size,
+ mz_uint32 uncomp_crc32, mz_uint16 method, mz_uint16 bit_flags,
+ mz_uint16 dos_time, mz_uint16 dos_date, mz_uint64 local_header_ofs,
+ mz_uint32 ext_attributes) {
+ mz_zip_internal_state *pState = pZip->m_pState;
+ mz_uint32 central_dir_ofs = (mz_uint32)pState->m_central_dir.m_size;
+ size_t orig_central_dir_size = pState->m_central_dir.m_size;
+ mz_uint8 central_dir_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+
+ // No zip64 support yet
+ if ((local_header_ofs > 0xFFFFFFFF) ||
+ (((mz_uint64)pState->m_central_dir.m_size +
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + extra_size +
+ comment_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_central_dir_header(
+ pZip, central_dir_header, filename_size, extra_size, comment_size,
+ uncomp_size, comp_size, uncomp_crc32, method, bit_flags, dos_time,
+ dos_date, local_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ if ((!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_dir_header,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pFilename,
+ filename_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pExtra,
+ extra_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir, pComment,
+ comment_size)) ||
+ (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets,
+ &central_dir_ofs, 1))) {
+ // Try to push the central directory array back into its original state.
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
+ MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ return MZ_TRUE;
+}
+
+static mz_bool mz_zip_writer_validate_archive_name(const char *pArchive_name) {
+ // Basic ZIP archive filename validity checks: Valid filenames cannot start
+ // with a forward slash, cannot contain a drive letter, and cannot use
+ // DOS-style backward slashes.
+ if (*pArchive_name == '/') return MZ_FALSE;
+ while (*pArchive_name) {
+ if ((*pArchive_name == '\\') || (*pArchive_name == ':')) return MZ_FALSE;
+ pArchive_name++;
+ }
+ return MZ_TRUE;
+}
+
+static mz_uint mz_zip_writer_compute_padding_needed_for_file_alignment(
+ mz_zip_archive *pZip) {
+ mz_uint32 n;
+ if (!pZip->m_file_offset_alignment) return 0;
+ n = (mz_uint32)(pZip->m_archive_size & (pZip->m_file_offset_alignment - 1));
+ return (pZip->m_file_offset_alignment - n) &
+ (pZip->m_file_offset_alignment - 1);
+}
+
+static mz_bool mz_zip_writer_write_zeros(mz_zip_archive *pZip,
+ mz_uint64 cur_file_ofs, mz_uint32 n) {
+ char buf[4096];
+ memset(buf, 0, MZ_MIN(sizeof(buf), n));
+ while (n) {
+ mz_uint32 s = MZ_MIN(sizeof(buf), n);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_file_ofs, buf, s) != s)
+ return MZ_FALSE;
+ cur_file_ofs += s;
+ n -= s;
+ }
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_add_mem_ex(mz_zip_archive *pZip,
+ const char *pArchive_name, const void *pBuf,
+ size_t buf_size, const void *pComment,
+ mz_uint16 comment_size,
+ mz_uint level_and_flags, mz_uint64 uncomp_size,
+ mz_uint32 uncomp_crc32) {
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0;
+ mz_uint level, ext_attributes = 0, num_alignment_padding_bytes;
+ mz_uint64 local_dir_header_ofs = pZip->m_archive_size,
+ cur_archive_file_ofs = pZip->m_archive_size, comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ tdefl_compressor *pComp = NULL;
+ mz_bool store_data_uncompressed;
+ mz_zip_internal_state *pState;
+
+ if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL;
+ level = level_and_flags & 0xF;
+ store_data_uncompressed =
+ ((!level) || (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA));
+
+ if ((!pZip) || (!pZip->m_pState) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || ((buf_size) && (!pBuf)) ||
+ (!pArchive_name) || ((comment_size) && (!pComment)) ||
+ (pZip->m_total_files == 0xFFFF) || (level > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ if ((!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) && (uncomp_size))
+ return MZ_FALSE;
+ // No zip64 support yet
+ if ((buf_size > 0xFFFFFFFF) || (uncomp_size > 0xFFFFFFFF)) return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE;
+
+#ifndef MINIZ_NO_TIME
+ {
+ time_t cur_time;
+ time(&cur_time);
+ mz_zip_time_to_dos_time(cur_time, &dos_time, &dos_date);
+ }
+#endif // #ifndef MINIZ_NO_TIME
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > 0xFFFF) return MZ_FALSE;
+
+ num_alignment_padding_bytes =
+ mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) ||
+ ((pZip->m_archive_size + num_alignment_padding_bytes +
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
+ comment_size + archive_name_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if ((archive_name_size) && (pArchive_name[archive_name_size - 1] == '/')) {
+ // Set DOS Subdirectory attribute bit.
+ ext_attributes |= 0x10;
+ // Subdirectories cannot contain data.
+ if ((buf_size) || (uncomp_size)) return MZ_FALSE;
+ }
+
+ // Try to do any allocations before writing to the archive, so if an
+ // allocation fails the file remains unmodified. (A good idea if we're doing
+ // an in-place modification.)
+ if ((!mz_zip_array_ensure_room(
+ pZip, &pState->m_central_dir,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size)) ||
+ (!mz_zip_array_ensure_room(pZip, &pState->m_central_dir_offsets, 1)))
+ return MZ_FALSE;
+
+ if ((!store_data_uncompressed) && (buf_size)) {
+ if (NULL == (pComp = (tdefl_compressor *)pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor))))
+ return MZ_FALSE;
+ }
+
+ if (!mz_zip_writer_write_zeros(
+ pZip, cur_archive_file_ofs,
+ num_alignment_padding_bytes + sizeof(local_dir_header))) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+ local_dir_header_ofs += num_alignment_padding_bytes;
+ if (pZip->m_file_offset_alignment) {
+ MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
+ 0);
+ }
+ cur_archive_file_ofs +=
+ num_alignment_padding_bytes + sizeof(local_dir_header);
+
+ MZ_CLEAR_OBJ(local_dir_header);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
+ archive_name_size) != archive_name_size) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+ cur_archive_file_ofs += archive_name_size;
+
+ if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA)) {
+ uncomp_crc32 =
+ (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
+ uncomp_size = buf_size;
+ if (uncomp_size <= 3) {
+ level = 0;
+ store_data_uncompressed = MZ_TRUE;
+ }
+ }
+
+ if (store_data_uncompressed) {
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pBuf,
+ buf_size) != buf_size) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+
+ cur_archive_file_ofs += buf_size;
+ comp_size = buf_size;
+
+ if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) method = MZ_DEFLATED;
+ } else if (buf_size) {
+ mz_zip_writer_add_state state;
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if ((tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
+ tdefl_create_comp_flags_from_zip_params(
+ level, -15, MZ_DEFAULT_STRATEGY)) !=
+ TDEFL_STATUS_OKAY) ||
+ (tdefl_compress_buffer(pComp, pBuf, buf_size, TDEFL_FINISH) !=
+ TDEFL_STATUS_DONE)) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ return MZ_FALSE;
+ }
+
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+
+ method = MZ_DEFLATED;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pComp = NULL;
+
+ // no zip64 support yet
+ if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_local_dir_header(
+ pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size,
+ comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
+ return MZ_FALSE;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
+ sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_add_to_central_dir(
+ pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment,
+ comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0,
+ dos_time, dos_date, local_dir_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name,
+ const char *pSrc_filename, const void *pComment,
+ mz_uint16 comment_size,
+ mz_uint level_and_flags) {
+ mz_uint uncomp_crc32 = MZ_CRC32_INIT, level, num_alignment_padding_bytes;
+ mz_uint16 method = 0, dos_time = 0, dos_date = 0, ext_attributes = 0;
+ mz_uint64 local_dir_header_ofs = pZip->m_archive_size,
+ cur_archive_file_ofs = pZip->m_archive_size, uncomp_size = 0,
+ comp_size = 0;
+ size_t archive_name_size;
+ mz_uint8 local_dir_header[MZ_ZIP_LOCAL_DIR_HEADER_SIZE];
+ MZ_FILE *pSrc_file = NULL;
+
+ if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL;
+ level = level_and_flags & 0xF;
+
+ if ((!pZip) || (!pZip->m_pState) ||
+ (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) || (!pArchive_name) ||
+ ((comment_size) && (!pComment)) || (level > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+ if (level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA) return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE;
+
+ archive_name_size = strlen(pArchive_name);
+ if (archive_name_size > 0xFFFF) return MZ_FALSE;
+
+ num_alignment_padding_bytes =
+ mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) ||
+ ((pZip->m_archive_size + num_alignment_padding_bytes +
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
+ comment_size + archive_name_size) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_get_file_modified_time(pSrc_filename, &dos_time, &dos_date))
+ return MZ_FALSE;
+
+ pSrc_file = MZ_FOPEN(pSrc_filename, "rb");
+ if (!pSrc_file) return MZ_FALSE;
+ MZ_FSEEK64(pSrc_file, 0, SEEK_END);
+ uncomp_size = MZ_FTELL64(pSrc_file);
+ MZ_FSEEK64(pSrc_file, 0, SEEK_SET);
+
+ if (uncomp_size > 0xFFFFFFFF) {
+ // No zip64 support yet
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ if (uncomp_size <= 3) level = 0;
+
+ if (!mz_zip_writer_write_zeros(
+ pZip, cur_archive_file_ofs,
+ num_alignment_padding_bytes + sizeof(local_dir_header))) {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ local_dir_header_ofs += num_alignment_padding_bytes;
+ if (pZip->m_file_offset_alignment) {
+ MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
+ 0);
+ }
+ cur_archive_file_ofs +=
+ num_alignment_padding_bytes + sizeof(local_dir_header);
+
+ MZ_CLEAR_OBJ(local_dir_header);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pArchive_name,
+ archive_name_size) != archive_name_size) {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ cur_archive_file_ofs += archive_name_size;
+
+ if (uncomp_size) {
+ mz_uint64 uncomp_remaining = uncomp_size;
+ void *pRead_buf =
+ pZip->m_pAlloc(pZip->m_pAlloc_opaque, 1, MZ_ZIP_MAX_IO_BUF_SIZE);
+ if (!pRead_buf) {
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ if (!level) {
+ while (uncomp_remaining) {
+ mz_uint n =
+ (mz_uint)MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE, uncomp_remaining);
+ if ((MZ_FREAD(pRead_buf, 1, n, pSrc_file) != n) ||
+ (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, pRead_buf,
+ n) != n)) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+ uncomp_crc32 =
+ (mz_uint32)mz_crc32(uncomp_crc32, (const mz_uint8 *)pRead_buf, n);
+ uncomp_remaining -= n;
+ cur_archive_file_ofs += n;
+ }
+ comp_size = uncomp_size;
+ } else {
+ mz_bool result = MZ_FALSE;
+ mz_zip_writer_add_state state;
+ tdefl_compressor *pComp = (tdefl_compressor *)pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1, sizeof(tdefl_compressor));
+ if (!pComp) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ state.m_pZip = pZip;
+ state.m_cur_archive_file_ofs = cur_archive_file_ofs;
+ state.m_comp_size = 0;
+
+ if (tdefl_init(pComp, mz_zip_writer_add_put_buf_callback, &state,
+ tdefl_create_comp_flags_from_zip_params(
+ level, -15, MZ_DEFAULT_STRATEGY)) !=
+ TDEFL_STATUS_OKAY) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ for (;;) {
+ size_t in_buf_size = (mz_uint32)MZ_MIN(uncomp_remaining,
+ (mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE);
+ tdefl_status status;
+
+ if (MZ_FREAD(pRead_buf, 1, in_buf_size, pSrc_file) != in_buf_size)
+ break;
+
+ uncomp_crc32 = (mz_uint32)mz_crc32(
+ uncomp_crc32, (const mz_uint8 *)pRead_buf, in_buf_size);
+ uncomp_remaining -= in_buf_size;
+
+ status = tdefl_compress_buffer(
+ pComp, pRead_buf, in_buf_size,
+ uncomp_remaining ? TDEFL_NO_FLUSH : TDEFL_FINISH);
+ if (status == TDEFL_STATUS_DONE) {
+ result = MZ_TRUE;
+ break;
+ } else if (status != TDEFL_STATUS_OKAY)
+ break;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pComp);
+
+ if (!result) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ MZ_FCLOSE(pSrc_file);
+ return MZ_FALSE;
+ }
+
+ comp_size = state.m_comp_size;
+ cur_archive_file_ofs = state.m_cur_archive_file_ofs;
+
+ method = MZ_DEFLATED;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pRead_buf);
+ }
+
+ MZ_FCLOSE(pSrc_file);
+ pSrc_file = NULL;
+
+ // no zip64 support yet
+ if ((comp_size > 0xFFFFFFFF) || (cur_archive_file_ofs > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_create_local_dir_header(
+ pZip, local_dir_header, (mz_uint16)archive_name_size, 0, uncomp_size,
+ comp_size, uncomp_crc32, method, 0, dos_time, dos_date))
+ return MZ_FALSE;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, local_dir_header_ofs, local_dir_header,
+ sizeof(local_dir_header)) != sizeof(local_dir_header))
+ return MZ_FALSE;
+
+ if (!mz_zip_writer_add_to_central_dir(
+ pZip, pArchive_name, (mz_uint16)archive_name_size, NULL, 0, pComment,
+ comment_size, uncomp_size, comp_size, uncomp_crc32, method, 0,
+ dos_time, dos_date, local_dir_header_ofs, ext_attributes))
+ return MZ_FALSE;
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_archive_file_ofs;
+
+ return MZ_TRUE;
+}
+#endif // #ifndef MINIZ_NO_STDIO
+
+mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip,
+ mz_zip_archive *pSource_zip,
+ mz_uint file_index) {
+ mz_uint n, bit_flags, num_alignment_padding_bytes;
+ mz_uint64 comp_bytes_remaining, local_dir_header_ofs;
+ mz_uint64 cur_src_file_ofs, cur_dst_file_ofs;
+ mz_uint32
+ local_header_u32[(MZ_ZIP_LOCAL_DIR_HEADER_SIZE + sizeof(mz_uint32) - 1) /
+ sizeof(mz_uint32)];
+ mz_uint8 *pLocal_header = (mz_uint8 *)local_header_u32;
+ mz_uint8 central_header[MZ_ZIP_CENTRAL_DIR_HEADER_SIZE];
+ size_t orig_central_dir_size;
+ mz_zip_internal_state *pState;
+ void *pBuf;
+ const mz_uint8 *pSrc_central_header;
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
+ return MZ_FALSE;
+ if (NULL ==
+ (pSrc_central_header = mz_zip_reader_get_cdh(pSource_zip, file_index)))
+ return MZ_FALSE;
+ pState = pZip->m_pState;
+
+ num_alignment_padding_bytes =
+ mz_zip_writer_compute_padding_needed_for_file_alignment(pZip);
+
+ // no zip64 support yet
+ if ((pZip->m_total_files == 0xFFFF) ||
+ ((pZip->m_archive_size + num_alignment_padding_bytes +
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE) >
+ 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ cur_src_file_ofs =
+ MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS);
+ cur_dst_file_ofs = pZip->m_archive_size;
+
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs,
+ pLocal_header, MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ if (MZ_READ_LE32(pLocal_header) != MZ_ZIP_LOCAL_DIR_HEADER_SIG)
+ return MZ_FALSE;
+ cur_src_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ if (!mz_zip_writer_write_zeros(pZip, cur_dst_file_ofs,
+ num_alignment_padding_bytes))
+ return MZ_FALSE;
+ cur_dst_file_ofs += num_alignment_padding_bytes;
+ local_dir_header_ofs = cur_dst_file_ofs;
+ if (pZip->m_file_offset_alignment) {
+ MZ_ASSERT((local_dir_header_ofs & (pZip->m_file_offset_alignment - 1)) ==
+ 0);
+ }
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pLocal_header,
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE) !=
+ MZ_ZIP_LOCAL_DIR_HEADER_SIZE)
+ return MZ_FALSE;
+ cur_dst_file_ofs += MZ_ZIP_LOCAL_DIR_HEADER_SIZE;
+
+ n = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_EXTRA_LEN_OFS);
+ comp_bytes_remaining =
+ n + MZ_READ_LE32(pSrc_central_header + MZ_ZIP_CDH_COMPRESSED_SIZE_OFS);
+
+ if (NULL == (pBuf = pZip->m_pAlloc(
+ pZip->m_pAlloc_opaque, 1,
+ (size_t)MZ_MAX(sizeof(mz_uint32) * 4,
+ MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE,
+ comp_bytes_remaining)))))
+ return MZ_FALSE;
+
+ while (comp_bytes_remaining) {
+ n = (mz_uint)MZ_MIN((mz_uint)MZ_ZIP_MAX_IO_BUF_SIZE, comp_bytes_remaining);
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
+ n) != n) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+ cur_src_file_ofs += n;
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+ cur_dst_file_ofs += n;
+
+ comp_bytes_remaining -= n;
+ }
+
+ bit_flags = MZ_READ_LE16(pLocal_header + MZ_ZIP_LDH_BIT_FLAG_OFS);
+ if (bit_flags & 8) {
+ // Copy data descriptor
+ if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf,
+ sizeof(mz_uint32) * 4) != sizeof(mz_uint32) * 4) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+
+ n = sizeof(mz_uint32) * ((MZ_READ_LE32(pBuf) == 0x08074b50) ? 4 : 3);
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_dst_file_ofs, pBuf, n) != n) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+ return MZ_FALSE;
+ }
+
+ cur_src_file_ofs += n;
+ cur_dst_file_ofs += n;
+ }
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pBuf);
+
+ // no zip64 support yet
+ if (cur_dst_file_ofs > 0xFFFFFFFF) return MZ_FALSE;
+
+ orig_central_dir_size = pState->m_central_dir.m_size;
+
+ memcpy(central_header, pSrc_central_header, MZ_ZIP_CENTRAL_DIR_HEADER_SIZE);
+ MZ_WRITE_LE32(central_header + MZ_ZIP_CDH_LOCAL_HEADER_OFS,
+ local_dir_header_ofs);
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir, central_header,
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE))
+ return MZ_FALSE;
+
+ n = MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
+ MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
+ MZ_READ_LE16(pSrc_central_header + MZ_ZIP_CDH_COMMENT_LEN_OFS);
+ if (!mz_zip_array_push_back(
+ pZip, &pState->m_central_dir,
+ pSrc_central_header + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE, n)) {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
+ MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ if (pState->m_central_dir.m_size > 0xFFFFFFFF) return MZ_FALSE;
+ n = (mz_uint32)orig_central_dir_size;
+ if (!mz_zip_array_push_back(pZip, &pState->m_central_dir_offsets, &n, 1)) {
+ mz_zip_array_resize(pZip, &pState->m_central_dir, orig_central_dir_size,
+ MZ_FALSE);
+ return MZ_FALSE;
+ }
+
+ pZip->m_total_files++;
+ pZip->m_archive_size = cur_dst_file_ofs;
+
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_archive(mz_zip_archive *pZip) {
+ mz_zip_internal_state *pState;
+ mz_uint64 central_dir_ofs, central_dir_size;
+ mz_uint8 hdr[MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE];
+
+ if ((!pZip) || (!pZip->m_pState) || (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+
+ // no zip64 support yet
+ if ((pZip->m_total_files > 0xFFFF) ||
+ ((pZip->m_archive_size + pState->m_central_dir.m_size +
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE) > 0xFFFFFFFF))
+ return MZ_FALSE;
+
+ central_dir_ofs = 0;
+ central_dir_size = 0;
+ if (pZip->m_total_files) {
+ // Write central directory
+ central_dir_ofs = pZip->m_archive_size;
+ central_dir_size = pState->m_central_dir.m_size;
+ pZip->m_central_directory_file_ofs = central_dir_ofs;
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, central_dir_ofs,
+ pState->m_central_dir.m_p,
+ (size_t)central_dir_size) != central_dir_size)
+ return MZ_FALSE;
+ pZip->m_archive_size += central_dir_size;
+ }
+
+ // Write end of central directory record
+ MZ_CLEAR_OBJ(hdr);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_SIG_OFS,
+ MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG);
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_NUM_ENTRIES_ON_DISK_OFS,
+ pZip->m_total_files);
+ MZ_WRITE_LE16(hdr + MZ_ZIP_ECDH_CDIR_TOTAL_ENTRIES_OFS, pZip->m_total_files);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_SIZE_OFS, central_dir_size);
+ MZ_WRITE_LE32(hdr + MZ_ZIP_ECDH_CDIR_OFS_OFS, central_dir_ofs);
+
+ if (pZip->m_pWrite(pZip->m_pIO_opaque, pZip->m_archive_size, hdr,
+ sizeof(hdr)) != sizeof(hdr))
+ return MZ_FALSE;
+#ifndef MINIZ_NO_STDIO
+ if ((pState->m_pFile) && (MZ_FFLUSH(pState->m_pFile) == EOF)) return MZ_FALSE;
+#endif // #ifndef MINIZ_NO_STDIO
+
+ pZip->m_archive_size += sizeof(hdr);
+
+ pZip->m_zip_mode = MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED;
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_finalize_heap_archive(mz_zip_archive *pZip, void **pBuf,
+ size_t *pSize) {
+ if ((!pZip) || (!pZip->m_pState) || (!pBuf) || (!pSize)) return MZ_FALSE;
+ if (pZip->m_pWrite != mz_zip_heap_write_func) return MZ_FALSE;
+ if (!mz_zip_writer_finalize_archive(pZip)) return MZ_FALSE;
+
+ *pBuf = pZip->m_pState->m_pMem;
+ *pSize = pZip->m_pState->m_mem_size;
+ pZip->m_pState->m_pMem = NULL;
+ pZip->m_pState->m_mem_size = pZip->m_pState->m_mem_capacity = 0;
+ return MZ_TRUE;
+}
+
+mz_bool mz_zip_writer_end(mz_zip_archive *pZip) {
+ mz_zip_internal_state *pState;
+ mz_bool status = MZ_TRUE;
+ if ((!pZip) || (!pZip->m_pState) || (!pZip->m_pAlloc) || (!pZip->m_pFree) ||
+ ((pZip->m_zip_mode != MZ_ZIP_MODE_WRITING) &&
+ (pZip->m_zip_mode != MZ_ZIP_MODE_WRITING_HAS_BEEN_FINALIZED)))
+ return MZ_FALSE;
+
+ pState = pZip->m_pState;
+ pZip->m_pState = NULL;
+ mz_zip_array_clear(pZip, &pState->m_central_dir);
+ mz_zip_array_clear(pZip, &pState->m_central_dir_offsets);
+ mz_zip_array_clear(pZip, &pState->m_sorted_central_dir_offsets);
+
+#ifndef MINIZ_NO_STDIO
+ if (pState->m_pFile) {
+ MZ_FCLOSE(pState->m_pFile);
+ pState->m_pFile = NULL;
+ }
+#endif // #ifndef MINIZ_NO_STDIO
+
+ if ((pZip->m_pWrite == mz_zip_heap_write_func) && (pState->m_pMem)) {
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState->m_pMem);
+ pState->m_pMem = NULL;
+ }
+
+ pZip->m_pFree(pZip->m_pAlloc_opaque, pState);
+ pZip->m_zip_mode = MZ_ZIP_MODE_INVALID;
+ return status;
+}
+
+#ifndef MINIZ_NO_STDIO
+mz_bool mz_zip_add_mem_to_archive_file_in_place(
+ const char *pZip_filename, const char *pArchive_name, const void *pBuf,
+ size_t buf_size, const void *pComment, mz_uint16 comment_size,
+ mz_uint level_and_flags) {
+ mz_bool status, created_new_archive = MZ_FALSE;
+ mz_zip_archive zip_archive;
+ struct MZ_FILE_STAT_STRUCT file_stat;
+ MZ_CLEAR_OBJ(zip_archive);
+ if ((int)level_and_flags < 0) level_and_flags = MZ_DEFAULT_LEVEL;
+ if ((!pZip_filename) || (!pArchive_name) || ((buf_size) && (!pBuf)) ||
+ ((comment_size) && (!pComment)) ||
+ ((level_and_flags & 0xF) > MZ_UBER_COMPRESSION))
+ return MZ_FALSE;
+ if (!mz_zip_writer_validate_archive_name(pArchive_name)) return MZ_FALSE;
+ if (MZ_FILE_STAT(pZip_filename, &file_stat) != 0) {
+ // Create a new archive.
+ if (!mz_zip_writer_init_file(&zip_archive, pZip_filename, 0))
+ return MZ_FALSE;
+ created_new_archive = MZ_TRUE;
+ } else {
+ // Append to an existing archive.
+ if (!mz_zip_reader_init_file(
+ &zip_archive, pZip_filename,
+ level_and_flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
+ return MZ_FALSE;
+ if (!mz_zip_writer_init_from_reader(&zip_archive, pZip_filename)) {
+ mz_zip_reader_end(&zip_archive);
+ return MZ_FALSE;
+ }
+ }
+ status =
+ mz_zip_writer_add_mem_ex(&zip_archive, pArchive_name, pBuf, buf_size,
+ pComment, comment_size, level_and_flags, 0, 0);
+ // Always finalize, even if adding failed for some reason, so we have a valid
+ // central directory. (This may not always succeed, but we can try.)
+ if (!mz_zip_writer_finalize_archive(&zip_archive)) status = MZ_FALSE;
+ if (!mz_zip_writer_end(&zip_archive)) status = MZ_FALSE;
+ if ((!status) && (created_new_archive)) {
+ // It's a new archive and something went wrong, so just delete it.
+ int ignoredStatus = MZ_DELETE_FILE(pZip_filename);
+ (void)ignoredStatus;
+ }
+ return status;
+}
+
+void *mz_zip_extract_archive_file_to_heap(const char *pZip_filename,
+ const char *pArchive_name,
+ size_t *pSize, mz_uint flags) {
+ int file_index;
+ mz_zip_archive zip_archive;
+ void *p = NULL;
+
+ if (pSize) *pSize = 0;
+
+ if ((!pZip_filename) || (!pArchive_name)) return NULL;
+
+ MZ_CLEAR_OBJ(zip_archive);
+ if (!mz_zip_reader_init_file(
+ &zip_archive, pZip_filename,
+ flags | MZ_ZIP_FLAG_DO_NOT_SORT_CENTRAL_DIRECTORY))
+ return NULL;
+
+ if ((file_index = mz_zip_reader_locate_file(&zip_archive, pArchive_name, NULL,
+ flags)) >= 0)
+ p = mz_zip_reader_extract_to_heap(&zip_archive, file_index, pSize, flags);
+
+ mz_zip_reader_end(&zip_archive);
+ return p;
+}
+
+#endif // #ifndef MINIZ_NO_STDIO
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_WRITING_APIS
+
+#endif // #ifndef MINIZ_NO_ARCHIVE_APIS
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // MINIZ_HEADER_FILE_ONLY
+
+/*
+ This is free and unencumbered software released into the public domain.
+
+ Anyone is free to copy, modify, publish, use, compile, sell, or
+ distribute this software, either in source code form or as a compiled
+ binary, for any purpose, commercial or non-commercial, and by any
+ means.
+
+ In jurisdictions that recognize copyright laws, the author or authors
+ of this software dedicate any and all copyright interest in the
+ software to the public domain. We make this dedication for the benefit
+ of the public at large and to the detriment of our heirs and
+ successors. We intend this dedication to be an overt act of
+ relinquishment in perpetuity of all present and future rights to this
+ software under copyright law.
+
+ 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 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.
+
+ For more information, please refer to <http://unlicense.org/>
+*/
+
+// ---------------------- end of miniz ----------------------------------------
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+}
+#else
+
+// Reuse MINIZ_LITTE_ENDIAN macro
+
+#if defined(__sparcv9)
+// Big endian
+#else
+#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || MINIZ_X86_OR_X64_CPU
+// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
+#define MINIZ_LITTLE_ENDIAN 1
+#endif
+#endif
+
+#endif // TINYEXR_USE_MINIZ
+
+// static bool IsBigEndian(void) {
+// union {
+// unsigned int i;
+// char c[4];
+// } bint = {0x01020304};
+//
+// return bint.c[0] == 1;
+//}
+
+static const int kEXRVersionSize = 8;
+
+static void swap2(unsigned short *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ unsigned short tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[1];
+ dst[1] = src[0];
+#endif
+}
+
+static void swap4(unsigned int *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ unsigned int tmp = *val;
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[3];
+ dst[1] = src[2];
+ dst[2] = src[1];
+ dst[3] = src[0];
+#endif
+}
+
+static void swap8(tinyexr::tinyexr_uint64 *val) {
+#ifdef MINIZ_LITTLE_ENDIAN
+ (void)val;
+#else
+ tinyexr::tinyexr_uint64 tmp = (*val);
+ unsigned char *dst = reinterpret_cast<unsigned char *>(val);
+ unsigned char *src = reinterpret_cast<unsigned char *>(&tmp);
+
+ dst[0] = src[7];
+ dst[1] = src[6];
+ dst[2] = src[5];
+ dst[3] = src[4];
+ dst[4] = src[3];
+ dst[5] = src[2];
+ dst[6] = src[1];
+ dst[7] = src[0];
+#endif
+}
+
+// https://gist.github.com/rygorous/2156668
+// Reuse MINIZ_LITTLE_ENDIAN flag from miniz.
+union FP32 {
+ unsigned int u;
+ float f;
+ struct {
+#if MINIZ_LITTLE_ENDIAN
+ unsigned int Mantissa : 23;
+ unsigned int Exponent : 8;
+ unsigned int Sign : 1;
+#else
+ unsigned int Sign : 1;
+ unsigned int Exponent : 8;
+ unsigned int Mantissa : 23;
+#endif
+ } s;
+};
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wpadded"
+#endif
+
+union FP16 {
+ unsigned short u;
+ struct {
+#if MINIZ_LITTLE_ENDIAN
+ unsigned int Mantissa : 10;
+ unsigned int Exponent : 5;
+ unsigned int Sign : 1;
+#else
+ unsigned int Sign : 1;
+ unsigned int Exponent : 5;
+ unsigned int Mantissa : 10;
+#endif
+ } s;
+};
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+
+static FP32 half_to_float(FP16 h) {
+ static const FP32 magic = {113 << 23};
+ static const unsigned int shifted_exp = 0x7c00
+ << 13; // exponent mask after shift
+ FP32 o;
+
+ o.u = (h.u & 0x7fffU) << 13U; // exponent/mantissa bits
+ unsigned int exp_ = shifted_exp & o.u; // just the exponent
+ o.u += (127 - 15) << 23; // exponent adjust
+
+ // handle exponent special cases
+ if (exp_ == shifted_exp) // Inf/NaN?
+ o.u += (128 - 16) << 23; // extra exp adjust
+ else if (exp_ == 0) // Zero/Denormal?
+ {
+ o.u += 1 << 23; // extra exp adjust
+ o.f -= magic.f; // renormalize
+ }
+
+ o.u |= (h.u & 0x8000U) << 16U; // sign bit
+ return o;
+}
+
+static FP16 float_to_half_full(FP32 f) {
+ FP16 o = {0};
+
+ // Based on ISPC reference code (with minor modifications)
+ if (f.s.Exponent == 0) // Signed zero/denormal (which will underflow)
+ o.s.Exponent = 0;
+ else if (f.s.Exponent == 255) // Inf or NaN (all exponent bits set)
+ {
+ o.s.Exponent = 31;
+ o.s.Mantissa = f.s.Mantissa ? 0x200 : 0; // NaN->qNaN and Inf->Inf
+ } else // Normalized number
+ {
+ // Exponent unbias the single, then bias the halfp
+ int newexp = f.s.Exponent - 127 + 15;
+ if (newexp >= 31) // Overflow, return signed infinity
+ o.s.Exponent = 31;
+ else if (newexp <= 0) // Underflow
+ {
+ if ((14 - newexp) <= 24) // Mantissa might be non-zero
+ {
+ unsigned int mant = f.s.Mantissa | 0x800000; // Hidden 1 bit
+ o.s.Mantissa = mant >> (14 - newexp);
+ if ((mant >> (13 - newexp)) & 1) // Check for rounding
+ o.u++; // Round, might overflow into exp bit, but this is OK
+ }
+ } else {
+ o.s.Exponent = static_cast<unsigned int>(newexp);
+ o.s.Mantissa = f.s.Mantissa >> 13;
+ if (f.s.Mantissa & 0x1000) // Check for rounding
+ o.u++; // Round, might overflow to inf, this is OK
+ }
+ }
+
+ o.s.Sign = f.s.Sign;
+ return o;
+}
+
+// NOTE: From OpenEXR code
+// #define IMF_INCREASING_Y 0
+// #define IMF_DECREASING_Y 1
+// #define IMF_RAMDOM_Y 2
+//
+// #define IMF_NO_COMPRESSION 0
+// #define IMF_RLE_COMPRESSION 1
+// #define IMF_ZIPS_COMPRESSION 2
+// #define IMF_ZIP_COMPRESSION 3
+// #define IMF_PIZ_COMPRESSION 4
+// #define IMF_PXR24_COMPRESSION 5
+// #define IMF_B44_COMPRESSION 6
+// #define IMF_B44A_COMPRESSION 7
+
+static const char *ReadString(std::string *s, const char *ptr) {
+ // Read untile NULL(\0).
+ const char *p = ptr;
+ const char *q = ptr;
+ while ((*q) != 0) q++;
+
+ (*s) = std::string(p, q);
+
+ return q + 1; // skip '\0'
+}
+
+static bool ReadAttribute(std::string *name, std::string *type,
+ std::vector<unsigned char> *data, size_t *marker_size,
+ const char *marker, size_t size) {
+ size_t name_len = strnlen(marker, size);
+ if (name_len == size) {
+ // String does not have a terminating character.
+ return false;
+ }
+ *name = std::string(marker, name_len);
+
+ marker += name_len + 1;
+ size -= name_len + 1;
+
+ size_t type_len = strnlen(marker, size);
+ if (type_len == size) {
+ return false;
+ }
+ *type = std::string(marker, type_len);
+
+ marker += type_len + 1;
+ size -= type_len + 1;
+
+ if (size < sizeof(uint32_t)) {
+ return false;
+ }
+
+ uint32_t data_len;
+ memcpy(&data_len, marker, sizeof(uint32_t));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+
+ marker += sizeof(uint32_t);
+ size -= sizeof(uint32_t);
+
+ if (size < data_len) {
+ return false;
+ }
+
+ data->resize(static_cast<size_t>(data_len));
+ memcpy(&data->at(0), marker, static_cast<size_t>(data_len));
+
+ *marker_size = name_len + 1 + type_len + 1 + sizeof(uint32_t) + data_len;
+ return true;
+}
+
+static void WriteAttributeToMemory(std::vector<unsigned char> *out,
+ const char *name, const char *type,
+ const unsigned char *data, int len) {
+ out->insert(out->end(), name, name + strlen(name) + 1);
+ out->insert(out->end(), type, type + strlen(type) + 1);
+
+ int outLen = len;
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&outLen));
+ out->insert(out->end(), reinterpret_cast<unsigned char *>(&outLen),
+ reinterpret_cast<unsigned char *>(&outLen) + sizeof(int));
+ out->insert(out->end(), data, data + len);
+}
+
+typedef struct {
+ std::string name; // less than 255 bytes long
+ int pixel_type;
+ int x_sampling;
+ int y_sampling;
+ unsigned char p_linear;
+ unsigned char pad[3];
+} ChannelInfo;
+
+typedef struct {
+ std::vector<tinyexr::ChannelInfo> channels;
+ std::vector<EXRAttribute> attributes;
+
+ int data_window[4];
+ int line_order;
+ int display_window[4];
+ float screen_window_center[2];
+ float screen_window_width;
+ float pixel_aspect_ratio;
+
+ int chunk_count;
+
+ // Tiled format
+ int tile_size_x;
+ int tile_size_y;
+ int tile_level_mode;
+ int tile_rounding_mode;
+
+ unsigned int header_len;
+
+ int compression_type;
+
+ void clear() {
+ channels.clear();
+ attributes.clear();
+
+ data_window[0] = 0;
+ data_window[1] = 0;
+ data_window[2] = 0;
+ data_window[3] = 0;
+ line_order = 0;
+ display_window[0] = 0;
+ display_window[1] = 0;
+ display_window[2] = 0;
+ display_window[3] = 0;
+ screen_window_center[0] = 0.0f;
+ screen_window_center[1] = 0.0f;
+ screen_window_width = 0.0f;
+ pixel_aspect_ratio = 0.0f;
+
+ chunk_count = 0;
+
+ // Tiled format
+ tile_size_x = 0;
+ tile_size_y = 0;
+ tile_level_mode = 0;
+ tile_rounding_mode = 0;
+
+ header_len = 0;
+ compression_type = 0;
+ }
+} HeaderInfo;
+
+static void ReadChannelInfo(std::vector<ChannelInfo> &channels,
+ const std::vector<unsigned char> &data) {
+ const char *p = reinterpret_cast<const char *>(&data.at(0));
+
+ for (;;) {
+ if ((*p) == 0) {
+ break;
+ }
+ ChannelInfo info;
+ p = ReadString(&info.name, p);
+
+ memcpy(&info.pixel_type, p, sizeof(int));
+ p += 4;
+ info.p_linear = static_cast<unsigned char>(p[0]); // uchar
+ p += 1 + 3; // reserved: uchar[3]
+ memcpy(&info.x_sampling, p, sizeof(int)); // int
+ p += 4;
+ memcpy(&info.y_sampling, p, sizeof(int)); // int
+ p += 4;
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.pixel_type));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.x_sampling));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info.y_sampling));
+
+ channels.push_back(info);
+ }
+}
+
+static void WriteChannelInfo(std::vector<unsigned char> &data,
+ const std::vector<ChannelInfo> &channels) {
+ size_t sz = 0;
+
+ // Calculate total size.
+ for (size_t c = 0; c < channels.size(); c++) {
+ sz += strlen(channels[c].name.c_str()) + 1; // +1 for \0
+ sz += 16; // 4 * int
+ }
+ data.resize(sz + 1);
+
+ unsigned char *p = &data.at(0);
+
+ for (size_t c = 0; c < channels.size(); c++) {
+ memcpy(p, channels[c].name.c_str(), strlen(channels[c].name.c_str()));
+ p += strlen(channels[c].name.c_str());
+ (*p) = '\0';
+ p++;
+
+ int pixel_type = channels[c].pixel_type;
+ int x_sampling = channels[c].x_sampling;
+ int y_sampling = channels[c].y_sampling;
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&pixel_type));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&x_sampling));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&y_sampling));
+
+ memcpy(p, &pixel_type, sizeof(int));
+ p += sizeof(int);
+
+ (*p) = channels[c].p_linear;
+ p += 4;
+
+ memcpy(p, &x_sampling, sizeof(int));
+ p += sizeof(int);
+
+ memcpy(p, &y_sampling, sizeof(int));
+ p += sizeof(int);
+ }
+
+ (*p) = '\0';
+}
+
+static void CompressZip(unsigned char *dst,
+ tinyexr::tinyexr_uint64 &compressedSize,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(src_size);
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfZipCompressor.cpp
+ //
+
+ //
+ // Reorder the pixel data.
+ //
+
+ const char *srcPtr = reinterpret_cast<const char *>(src);
+
+ {
+ char *t1 = reinterpret_cast<char *>(&tmpBuf.at(0));
+ char *t2 = reinterpret_cast<char *>(&tmpBuf.at(0)) + (src_size + 1) / 2;
+ const char *stop = srcPtr + src_size;
+
+ for (;;) {
+ if (srcPtr < stop)
+ *(t1++) = *(srcPtr++);
+ else
+ break;
+
+ if (srcPtr < stop)
+ *(t2++) = *(srcPtr++);
+ else
+ break;
+ }
+ }
+
+ //
+ // Predictor.
+ //
+
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + src_size;
+ int p = t[-1];
+
+ while (t < stop) {
+ int d = int(t[0]) - p + (128 + 256);
+ p = t[0];
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+#if TINYEXR_USE_MINIZ
+ //
+ // Compress the data using miniz
+ //
+
+ miniz::mz_ulong outSize = miniz::mz_compressBound(src_size);
+ int ret = miniz::mz_compress(
+ dst, &outSize, static_cast<const unsigned char *>(&tmpBuf.at(0)),
+ src_size);
+ assert(ret == miniz::MZ_OK);
+ (void)ret;
+
+ compressedSize = outSize;
+#else
+ uLong outSize = compressBound(static_cast<uLong>(src_size));
+ int ret = compress(dst, &outSize, static_cast<const Bytef *>(&tmpBuf.at(0)),
+ src_size);
+ assert(ret == Z_OK);
+
+ compressedSize = outSize;
+#endif
+}
+
+static void DecompressZip(unsigned char *dst,
+ unsigned long *uncompressed_size /* inout */,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(*uncompressed_size);
+
+#if TINYEXR_USE_MINIZ
+ int ret =
+ miniz::mz_uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
+ assert(ret == miniz::MZ_OK);
+ (void)ret;
+#else
+ int ret = uncompress(&tmpBuf.at(0), uncompressed_size, src, src_size);
+ assert(ret == Z_OK);
+ (void)ret;
+#endif
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfZipCompressor.cpp
+ //
+
+ // Predictor.
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + (*uncompressed_size);
+
+ while (t < stop) {
+ int d = int(t[-1]) + int(t[0]) - 128;
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // Reorder the pixel data.
+ {
+ const char *t1 = reinterpret_cast<const char *>(&tmpBuf.at(0));
+ const char *t2 = reinterpret_cast<const char *>(&tmpBuf.at(0)) +
+ (*uncompressed_size + 1) / 2;
+ char *s = reinterpret_cast<char *>(dst);
+ char *stop = s + (*uncompressed_size);
+
+ for (;;) {
+ if (s < stop)
+ *(s++) = *(t1++);
+ else
+ break;
+
+ if (s < stop)
+ *(s++) = *(t2++);
+ else
+ break;
+ }
+ }
+}
+
+// RLE code from OpenEXR --------------------------------------
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#endif
+
+const int MIN_RUN_LENGTH = 3;
+const int MAX_RUN_LENGTH = 127;
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+static int rleCompress(int inLength, const char in[], signed char out[]) {
+ const char *inEnd = in + inLength;
+ const char *runStart = in;
+ const char *runEnd = in + 1;
+ signed char *outWrite = out;
+
+ while (runStart < inEnd) {
+ while (runEnd < inEnd && *runStart == *runEnd &&
+ runEnd - runStart - 1 < MAX_RUN_LENGTH) {
+ ++runEnd;
+ }
+
+ if (runEnd - runStart >= MIN_RUN_LENGTH) {
+ //
+ // Compressable run
+ //
+
+ *outWrite++ = static_cast<char>(runEnd - runStart) - 1;
+ *outWrite++ = *(reinterpret_cast<const signed char *>(runStart));
+ runStart = runEnd;
+ } else {
+ //
+ // Uncompressable run
+ //
+
+ while (runEnd < inEnd &&
+ ((runEnd + 1 >= inEnd || *runEnd != *(runEnd + 1)) ||
+ (runEnd + 2 >= inEnd || *(runEnd + 1) != *(runEnd + 2))) &&
+ runEnd - runStart < MAX_RUN_LENGTH) {
+ ++runEnd;
+ }
+
+ *outWrite++ = static_cast<char>(runStart - runEnd);
+
+ while (runStart < runEnd) {
+ *outWrite++ = *(reinterpret_cast<const signed char *>(runStart++));
+ }
+ }
+
+ ++runEnd;
+ }
+
+ return static_cast<int>(outWrite - out);
+}
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the oncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+static int rleUncompress(int inLength, int maxLength, const signed char in[],
+ char out[]) {
+ char *outStart = out;
+
+ while (inLength > 0) {
+ if (*in < 0) {
+ int count = -(static_cast<int>(*in++));
+ inLength -= count + 1;
+
+ if (0 > (maxLength -= count)) return 0;
+
+ memcpy(out, in, count);
+ out += count;
+ in += count;
+ } else {
+ int count = *in++;
+ inLength -= 2;
+
+ if (0 > (maxLength -= count + 1)) return 0;
+
+ memset(out, *reinterpret_cast<const char *>(in), count + 1);
+ out += count + 1;
+
+ in++;
+ }
+ }
+
+ return static_cast<int>(out - outStart);
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif
+// End of RLE code from OpenEXR -----------------------------------
+
+static void CompressRle(unsigned char *dst,
+ tinyexr::tinyexr_uint64 &compressedSize,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(src_size);
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfRleCompressor.cpp
+ //
+
+ //
+ // Reorder the pixel data.
+ //
+
+ const char *srcPtr = reinterpret_cast<const char *>(src);
+
+ {
+ char *t1 = reinterpret_cast<char *>(&tmpBuf.at(0));
+ char *t2 = reinterpret_cast<char *>(&tmpBuf.at(0)) + (src_size + 1) / 2;
+ const char *stop = srcPtr + src_size;
+
+ for (;;) {
+ if (srcPtr < stop)
+ *(t1++) = *(srcPtr++);
+ else
+ break;
+
+ if (srcPtr < stop)
+ *(t2++) = *(srcPtr++);
+ else
+ break;
+ }
+ }
+
+ //
+ // Predictor.
+ //
+
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + src_size;
+ int p = t[-1];
+
+ while (t < stop) {
+ int d = int(t[0]) - p + (128 + 256);
+ p = t[0];
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // outSize will be (srcSiz * 3) / 2 at max.
+ int outSize = rleCompress(static_cast<int>(src_size),
+ reinterpret_cast<const char *>(&tmpBuf.at(0)),
+ reinterpret_cast<signed char *>(dst));
+ assert(outSize > 0);
+
+ compressedSize = static_cast<tinyexr::tinyexr_uint64>(outSize);
+}
+
+static void DecompressRle(unsigned char *dst,
+ const unsigned long uncompressed_size,
+ const unsigned char *src, unsigned long src_size) {
+ std::vector<unsigned char> tmpBuf(uncompressed_size);
+
+ int ret = rleUncompress(static_cast<int>(src_size),
+ static_cast<int>(uncompressed_size),
+ reinterpret_cast<const signed char *>(src),
+ reinterpret_cast<char *>(&tmpBuf.at(0)));
+ assert(ret == static_cast<int>(uncompressed_size));
+ (void)ret;
+
+ //
+ // Apply EXR-specific? postprocess. Grabbed from OpenEXR's
+ // ImfRleCompressor.cpp
+ //
+
+ // Predictor.
+ {
+ unsigned char *t = &tmpBuf.at(0) + 1;
+ unsigned char *stop = &tmpBuf.at(0) + uncompressed_size;
+
+ while (t < stop) {
+ int d = int(t[-1]) + int(t[0]) - 128;
+ t[0] = static_cast<unsigned char>(d);
+ ++t;
+ }
+ }
+
+ // Reorder the pixel data.
+ {
+ const char *t1 = reinterpret_cast<const char *>(&tmpBuf.at(0));
+ const char *t2 = reinterpret_cast<const char *>(&tmpBuf.at(0)) +
+ (uncompressed_size + 1) / 2;
+ char *s = reinterpret_cast<char *>(dst);
+ char *stop = s + uncompressed_size;
+
+ for (;;) {
+ if (s < stop)
+ *(s++) = *(t1++);
+ else
+ break;
+
+ if (s < stop)
+ *(s++) = *(t2++);
+ else
+ break;
+ }
+ }
+}
+
+#if TINYEXR_USE_PIZ
+
+#ifdef __clang__
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wc++11-long-long"
+#pragma clang diagnostic ignored "-Wold-style-cast"
+#pragma clang diagnostic ignored "-Wpadded"
+#pragma clang diagnostic ignored "-Wsign-conversion"
+#pragma clang diagnostic ignored "-Wc++11-extensions"
+#pragma clang diagnostic ignored "-Wconversion"
+#endif
+
+//
+// PIZ compress/uncompress, based on OpenEXR's ImfPizCompressor.cpp
+//
+// -----------------------------------------------------------------
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC)
+// (3 clause BSD license)
+//
+
+struct PIZChannelData {
+ unsigned short *start;
+ unsigned short *end;
+ int nx;
+ int ny;
+ int ys;
+ int size;
+};
+
+//-----------------------------------------------------------------------------
+//
+// 16-bit Haar Wavelet encoding and decoding
+//
+// The source code in this file is derived from the encoding
+// and decoding routines written by Christian Rouet for his
+// PIZ image file format.
+//
+//-----------------------------------------------------------------------------
+
+//
+// Wavelet basis functions without modulo arithmetic; they produce
+// the best compression ratios when the wavelet-transformed data are
+// Huffman-encoded, but the wavelet transform works only for 14-bit
+// data (untransformed data values must be less than (1 << 14)).
+//
+
+inline void wenc14(unsigned short a, unsigned short b, unsigned short &l,
+ unsigned short &h) {
+ short as = static_cast<short>(a);
+ short bs = static_cast<short>(b);
+
+ short ms = (as + bs) >> 1;
+ short ds = as - bs;
+
+ l = static_cast<unsigned short>(ms);
+ h = static_cast<unsigned short>(ds);
+}
+
+inline void wdec14(unsigned short l, unsigned short h, unsigned short &a,
+ unsigned short &b) {
+ short ls = static_cast<short>(l);
+ short hs = static_cast<short>(h);
+
+ int hi = hs;
+ int ai = ls + (hi & 1) + (hi >> 1);
+
+ short as = static_cast<short>(ai);
+ short bs = static_cast<short>(ai - hi);
+
+ a = static_cast<unsigned short>(as);
+ b = static_cast<unsigned short>(bs);
+}
+
+//
+// Wavelet basis functions with modulo arithmetic; they work with full
+// 16-bit data, but Huffman-encoding the wavelet-transformed data doesn't
+// compress the data quite as well.
+//
+
+const int NBITS = 16;
+const int A_OFFSET = 1 << (NBITS - 1);
+const int M_OFFSET = 1 << (NBITS - 1);
+const int MOD_MASK = (1 << NBITS) - 1;
+
+inline void wenc16(unsigned short a, unsigned short b, unsigned short &l,
+ unsigned short &h) {
+ int ao = (a + A_OFFSET) & MOD_MASK;
+ int m = ((ao + b) >> 1);
+ int d = ao - b;
+
+ if (d < 0) m = (m + M_OFFSET) & MOD_MASK;
+
+ d &= MOD_MASK;
+
+ l = static_cast<unsigned short>(m);
+ h = static_cast<unsigned short>(d);
+}
+
+inline void wdec16(unsigned short l, unsigned short h, unsigned short &a,
+ unsigned short &b) {
+ int m = l;
+ int d = h;
+ int bb = (m - (d >> 1)) & MOD_MASK;
+ int aa = (d + bb - A_OFFSET) & MOD_MASK;
+ b = static_cast<unsigned short>(bb);
+ a = static_cast<unsigned short>(aa);
+}
+
+//
+// 2D Wavelet encoding:
+//
+
+static void wav2Encode(
+ unsigned short *in, // io: values are transformed in place
+ int nx, // i : x size
+ int ox, // i : x offset
+ int ny, // i : y size
+ int oy, // i : y offset
+ unsigned short mx) // i : maximum in[x][y] value
+{
+ bool w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny : nx;
+ int p = 1; // == 1 << level
+ int p2 = 2; // == 1 << (level+1)
+
+ //
+ // Hierachical loop on smaller dimension n
+ //
+
+ while (p2 <= n) {
+ unsigned short *py = in;
+ unsigned short *ey = in + oy * (ny - p2);
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+ unsigned short i00, i01, i10, i11;
+
+ //
+ // Y loop
+ //
+
+ for (; py <= ey; py += oy2) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ //
+ // X loop
+ //
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+ unsigned short *p10 = px + oy1;
+ unsigned short *p11 = p10 + ox1;
+
+ //
+ // 2D wavelet encoding
+ //
+
+ if (w14) {
+ wenc14(*px, *p01, i00, i01);
+ wenc14(*p10, *p11, i10, i11);
+ wenc14(i00, i10, *px, *p10);
+ wenc14(i01, i11, *p01, *p11);
+ } else {
+ wenc16(*px, *p01, i00, i01);
+ wenc16(*p10, *p11, i10, i11);
+ wenc16(i00, i10, *px, *p10);
+ wenc16(i01, i11, *p01, *p11);
+ }
+ }
+
+ //
+ // Encode (1D) odd column (still in Y loop)
+ //
+
+ if (nx & p) {
+ unsigned short *p10 = px + oy1;
+
+ if (w14)
+ wenc14(*px, *p10, i00, *p10);
+ else
+ wenc16(*px, *p10, i00, *p10);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Encode (1D) odd line (must loop in X)
+ //
+
+ if (ny & p) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+
+ if (w14)
+ wenc14(*px, *p01, i00, *p01);
+ else
+ wenc16(*px, *p01, i00, *p01);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Next level
+ //
+
+ p = p2;
+ p2 <<= 1;
+ }
+}
+
+//
+// 2D Wavelet decoding:
+//
+
+static void wav2Decode(
+ unsigned short *in, // io: values are transformed in place
+ int nx, // i : x size
+ int ox, // i : x offset
+ int ny, // i : y size
+ int oy, // i : y offset
+ unsigned short mx) // i : maximum in[x][y] value
+{
+ bool w14 = (mx < (1 << 14));
+ int n = (nx > ny) ? ny : nx;
+ int p = 1;
+ int p2;
+
+ //
+ // Search max level
+ //
+
+ while (p <= n) p <<= 1;
+
+ p >>= 1;
+ p2 = p;
+ p >>= 1;
+
+ //
+ // Hierarchical loop on smaller dimension n
+ //
+
+ while (p >= 1) {
+ unsigned short *py = in;
+ unsigned short *ey = in + oy * (ny - p2);
+ int oy1 = oy * p;
+ int oy2 = oy * p2;
+ int ox1 = ox * p;
+ int ox2 = ox * p2;
+ unsigned short i00, i01, i10, i11;
+
+ //
+ // Y loop
+ //
+
+ for (; py <= ey; py += oy2) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ //
+ // X loop
+ //
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+ unsigned short *p10 = px + oy1;
+ unsigned short *p11 = p10 + ox1;
+
+ //
+ // 2D wavelet decoding
+ //
+
+ if (w14) {
+ wdec14(*px, *p10, i00, i10);
+ wdec14(*p01, *p11, i01, i11);
+ wdec14(i00, i01, *px, *p01);
+ wdec14(i10, i11, *p10, *p11);
+ } else {
+ wdec16(*px, *p10, i00, i10);
+ wdec16(*p01, *p11, i01, i11);
+ wdec16(i00, i01, *px, *p01);
+ wdec16(i10, i11, *p10, *p11);
+ }
+ }
+
+ //
+ // Decode (1D) odd column (still in Y loop)
+ //
+
+ if (nx & p) {
+ unsigned short *p10 = px + oy1;
+
+ if (w14)
+ wdec14(*px, *p10, i00, *p10);
+ else
+ wdec16(*px, *p10, i00, *p10);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Decode (1D) odd line (must loop in X)
+ //
+
+ if (ny & p) {
+ unsigned short *px = py;
+ unsigned short *ex = py + ox * (nx - p2);
+
+ for (; px <= ex; px += ox2) {
+ unsigned short *p01 = px + ox1;
+
+ if (w14)
+ wdec14(*px, *p01, i00, *p01);
+ else
+ wdec16(*px, *p01, i00, *p01);
+
+ *px = i00;
+ }
+ }
+
+ //
+ // Next level
+ //
+
+ p2 = p;
+ p >>= 1;
+ }
+}
+
+//-----------------------------------------------------------------------------
+//
+// 16-bit Huffman compression and decompression.
+//
+// The source code in this file is derived from the 8-bit
+// Huffman compression and decompression routines written
+// by Christian Rouet for his PIZ image file format.
+//
+//-----------------------------------------------------------------------------
+
+// Adds some modification for tinyexr.
+
+const int HUF_ENCBITS = 16; // literal (value) bit length
+const int HUF_DECBITS = 14; // decoding bit size (>= 8)
+
+const int HUF_ENCSIZE = (1 << HUF_ENCBITS) + 1; // encoding table size
+const int HUF_DECSIZE = 1 << HUF_DECBITS; // decoding table size
+const int HUF_DECMASK = HUF_DECSIZE - 1;
+
+struct HufDec { // short code long code
+ //-------------------------------
+ int len : 8; // code length 0
+ int lit : 24; // lit p size
+ int *p; // 0 lits
+};
+
+inline long long hufLength(long long code) { return code & 63; }
+
+inline long long hufCode(long long code) { return code >> 6; }
+
+inline void outputBits(int nBits, long long bits, long long &c, int &lc,
+ char *&out) {
+ c <<= nBits;
+ lc += nBits;
+
+ c |= bits;
+
+ while (lc >= 8) *out++ = static_cast<char>((c >> (lc -= 8)));
+}
+
+inline long long getBits(int nBits, long long &c, int &lc, const char *&in) {
+ while (lc < nBits) {
+ c = (c << 8) | *(reinterpret_cast<const unsigned char *>(in++));
+ lc += 8;
+ }
+
+ lc -= nBits;
+ return (c >> lc) & ((1 << nBits) - 1);
+}
+
+//
+// ENCODING TABLE BUILDING & (UN)PACKING
+//
+
+//
+// Build a "canonical" Huffman code table:
+// - for each (uncompressed) symbol, hcode contains the length
+// of the corresponding code (in the compressed data)
+// - canonical codes are computed and stored in hcode
+// - the rules for constructing canonical codes are as follows:
+// * shorter codes (if filled with zeroes to the right)
+// have a numerically higher value than longer codes
+// * for codes with the same length, numerical values
+// increase with numerical symbol values
+// - because the canonical code table can be constructed from
+// symbol lengths alone, the code table can be transmitted
+// without sending the actual code values
+// - see http://www.compressconsult.com/huffman/
+//
+
+static void hufCanonicalCodeTable(long long hcode[HUF_ENCSIZE]) {
+ long long n[59];
+
+ //
+ // For each i from 0 through 58, count the
+ // number of different codes of length i, and
+ // store the count in n[i].
+ //
+
+ for (int i = 0; i <= 58; ++i) n[i] = 0;
+
+ for (int i = 0; i < HUF_ENCSIZE; ++i) n[hcode[i]] += 1;
+
+ //
+ // For each i from 58 through 1, compute the
+ // numerically lowest code with length i, and
+ // store that code in n[i].
+ //
+
+ long long c = 0;
+
+ for (int i = 58; i > 0; --i) {
+ long long nc = ((c + n[i]) >> 1);
+ n[i] = c;
+ c = nc;
+ }
+
+ //
+ // hcode[i] contains the length, l, of the
+ // code for symbol i. Assign the next available
+ // code of length l to the symbol and store both
+ // l and the code in hcode[i].
+ //
+
+ for (int i = 0; i < HUF_ENCSIZE; ++i) {
+ int l = static_cast<int>(hcode[i]);
+
+ if (l > 0) hcode[i] = l | (n[l]++ << 6);
+ }
+}
+
+//
+// Compute Huffman codes (based on frq input) and store them in frq:
+// - code structure is : [63:lsb - 6:msb] | [5-0: bit length];
+// - max code length is 58 bits;
+// - codes outside the range [im-iM] have a null length (unused values);
+// - original frequencies are destroyed;
+// - encoding tables are used by hufEncode() and hufBuildDecTable();
+//
+
+struct FHeapCompare {
+ bool operator()(long long *a, long long *b) { return *a > *b; }
+};
+
+static void hufBuildEncTable(
+ long long *frq, // io: input frequencies [HUF_ENCSIZE], output table
+ int *im, // o: min frq index
+ int *iM) // o: max frq index
+{
+ //
+ // This function assumes that when it is called, array frq
+ // indicates the frequency of all possible symbols in the data
+ // that are to be Huffman-encoded. (frq[i] contains the number
+ // of occurrences of symbol i in the data.)
+ //
+ // The loop below does three things:
+ //
+ // 1) Finds the minimum and maximum indices that point
+ // to non-zero entries in frq:
+ //
+ // frq[im] != 0, and frq[i] == 0 for all i < im
+ // frq[iM] != 0, and frq[i] == 0 for all i > iM
+ //
+ // 2) Fills array fHeap with pointers to all non-zero
+ // entries in frq.
+ //
+ // 3) Initializes array hlink such that hlink[i] == i
+ // for all array entries.
+ //
+
+ int hlink[HUF_ENCSIZE];
+ long long *fHeap[HUF_ENCSIZE];
+
+ *im = 0;
+
+ while (!frq[*im]) (*im)++;
+
+ int nf = 0;
+
+ for (int i = *im; i < HUF_ENCSIZE; i++) {
+ hlink[i] = i;
+
+ if (frq[i]) {
+ fHeap[nf] = &frq[i];
+ nf++;
+ *iM = i;
+ }
+ }
+
+ //
+ // Add a pseudo-symbol, with a frequency count of 1, to frq;
+ // adjust the fHeap and hlink array accordingly. Function
+ // hufEncode() uses the pseudo-symbol for run-length encoding.
+ //
+
+ (*iM)++;
+ frq[*iM] = 1;
+ fHeap[nf] = &frq[*iM];
+ nf++;
+
+ //
+ // Build an array, scode, such that scode[i] contains the number
+ // of bits assigned to symbol i. Conceptually this is done by
+ // constructing a tree whose leaves are the symbols with non-zero
+ // frequency:
+ //
+ // Make a heap that contains all symbols with a non-zero frequency,
+ // with the least frequent symbol on top.
+ //
+ // Repeat until only one symbol is left on the heap:
+ //
+ // Take the two least frequent symbols off the top of the heap.
+ // Create a new node that has first two nodes as children, and
+ // whose frequency is the sum of the frequencies of the first
+ // two nodes. Put the new node back into the heap.
+ //
+ // The last node left on the heap is the root of the tree. For each
+ // leaf node, the distance between the root and the leaf is the length
+ // of the code for the corresponding symbol.
+ //
+ // The loop below doesn't actually build the tree; instead we compute
+ // the distances of the leaves from the root on the fly. When a new
+ // node is added to the heap, then that node's descendants are linked
+ // into a single linear list that starts at the new node, and the code
+ // lengths of the descendants (that is, their distance from the root
+ // of the tree) are incremented by one.
+ //
+
+ std::make_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ long long scode[HUF_ENCSIZE];
+ memset(scode, 0, sizeof(long long) * HUF_ENCSIZE);
+
+ while (nf > 1) {
+ //
+ // Find the indices, mm and m, of the two smallest non-zero frq
+ // values in fHeap, add the smallest frq to the second-smallest
+ // frq, and remove the smallest frq value from fHeap.
+ //
+
+ int mm = fHeap[0] - frq;
+ std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+ --nf;
+
+ int m = fHeap[0] - frq;
+ std::pop_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ frq[m] += frq[mm];
+ std::push_heap(&fHeap[0], &fHeap[nf], FHeapCompare());
+
+ //
+ // The entries in scode are linked into lists with the
+ // entries in hlink serving as "next" pointers and with
+ // the end of a list marked by hlink[j] == j.
+ //
+ // Traverse the lists that start at scode[m] and scode[mm].
+ // For each element visited, increment the length of the
+ // corresponding code by one bit. (If we visit scode[j]
+ // during the traversal, then the code for symbol j becomes
+ // one bit longer.)
+ //
+ // Merge the lists that start at scode[m] and scode[mm]
+ // into a single list that starts at scode[m].
+ //
+
+ //
+ // Add a bit to all codes in the first list.
+ //
+
+ for (int j = m;; j = hlink[j]) {
+ scode[j]++;
+
+ assert(scode[j] <= 58);
+
+ if (hlink[j] == j) {
+ //
+ // Merge the two lists.
+ //
+
+ hlink[j] = mm;
+ break;
+ }
+ }
+
+ //
+ // Add a bit to all codes in the second list
+ //
+
+ for (int j = mm;; j = hlink[j]) {
+ scode[j]++;
+
+ assert(scode[j] <= 58);
+
+ if (hlink[j] == j) break;
+ }
+ }
+
+ //
+ // Build a canonical Huffman code table, replacing the code
+ // lengths in scode with (code, code length) pairs. Copy the
+ // code table from scode into frq.
+ //
+
+ hufCanonicalCodeTable(scode);
+ memcpy(frq, scode, sizeof(long long) * HUF_ENCSIZE);
+}
+
+//
+// Pack an encoding table:
+// - only code lengths, not actual codes, are stored
+// - runs of zeroes are compressed as follows:
+//
+// unpacked packed
+// --------------------------------
+// 1 zero 0 (6 bits)
+// 2 zeroes 59
+// 3 zeroes 60
+// 4 zeroes 61
+// 5 zeroes 62
+// n zeroes (6 or more) 63 n-6 (6 + 8 bits)
+//
+
+const int SHORT_ZEROCODE_RUN = 59;
+const int LONG_ZEROCODE_RUN = 63;
+const int SHORTEST_LONG_RUN = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;
+const int LONGEST_LONG_RUN = 255 + SHORTEST_LONG_RUN;
+
+static void hufPackEncTable(
+ const long long *hcode, // i : encoding table [HUF_ENCSIZE]
+ int im, // i : min hcode index
+ int iM, // i : max hcode index
+ char **pcode) // o: ptr to packed table (updated)
+{
+ char *p = *pcode;
+ long long c = 0;
+ int lc = 0;
+
+ for (; im <= iM; im++) {
+ int l = hufLength(hcode[im]);
+
+ if (l == 0) {
+ int zerun = 1;
+
+ while ((im < iM) && (zerun < LONGEST_LONG_RUN)) {
+ if (hufLength(hcode[im + 1]) > 0) break;
+ im++;
+ zerun++;
+ }
+
+ if (zerun >= 2) {
+ if (zerun >= SHORTEST_LONG_RUN) {
+ outputBits(6, LONG_ZEROCODE_RUN, c, lc, p);
+ outputBits(8, zerun - SHORTEST_LONG_RUN, c, lc, p);
+ } else {
+ outputBits(6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p);
+ }
+ continue;
+ }
+ }
+
+ outputBits(6, l, c, lc, p);
+ }
+
+ if (lc > 0) *p++ = (unsigned char)(c << (8 - lc));
+
+ *pcode = p;
+}
+
+//
+// Unpack an encoding table packed by hufPackEncTable():
+//
+
+static bool hufUnpackEncTable(
+ const char **pcode, // io: ptr to packed table (updated)
+ int ni, // i : input size (in bytes)
+ int im, // i : min hcode index
+ int iM, // i : max hcode index
+ long long *hcode) // o: encoding table [HUF_ENCSIZE]
+{
+ memset(hcode, 0, sizeof(long long) * HUF_ENCSIZE);
+
+ const char *p = *pcode;
+ long long c = 0;
+ int lc = 0;
+
+ for (; im <= iM; im++) {
+ if (p - *pcode > ni) {
+ return false;
+ }
+
+ long long l = hcode[im] = getBits(6, c, lc, p); // code length
+
+ if (l == (long long)LONG_ZEROCODE_RUN) {
+ if (p - *pcode > ni) {
+ return false;
+ }
+
+ int zerun = getBits(8, c, lc, p) + SHORTEST_LONG_RUN;
+
+ if (im + zerun > iM + 1) {
+ return false;
+ }
+
+ while (zerun--) hcode[im++] = 0;
+
+ im--;
+ } else if (l >= (long long)SHORT_ZEROCODE_RUN) {
+ int zerun = l - SHORT_ZEROCODE_RUN + 2;
+
+ if (im + zerun > iM + 1) {
+ return false;
+ }
+
+ while (zerun--) hcode[im++] = 0;
+
+ im--;
+ }
+ }
+
+ *pcode = const_cast<char *>(p);
+
+ hufCanonicalCodeTable(hcode);
+
+ return true;
+}
+
+//
+// DECODING TABLE BUILDING
+//
+
+//
+// Clear a newly allocated decoding table so that it contains only zeroes.
+//
+
+static void hufClearDecTable(HufDec *hdecod) // io: (allocated by caller)
+// decoding table [HUF_DECSIZE]
+{
+ for (int i = 0; i < HUF_DECSIZE; i++) {
+ hdecod[i].len = 0;
+ hdecod[i].lit = 0;
+ hdecod[i].p = NULL;
+ }
+ // memset(hdecod, 0, sizeof(HufDec) * HUF_DECSIZE);
+}
+
+//
+// Build a decoding hash table based on the encoding table hcode:
+// - short codes (<= HUF_DECBITS) are resolved with a single table access;
+// - long code entry allocations are not optimized, because long codes are
+// unfrequent;
+// - decoding tables are used by hufDecode();
+//
+
+static bool hufBuildDecTable(const long long *hcode, // i : encoding table
+ int im, // i : min index in hcode
+ int iM, // i : max index in hcode
+ HufDec *hdecod) // o: (allocated by caller)
+// decoding table [HUF_DECSIZE]
+{
+ //
+ // Init hashtable & loop on all codes.
+ // Assumes that hufClearDecTable(hdecod) has already been called.
+ //
+
+ for (; im <= iM; im++) {
+ long long c = hufCode(hcode[im]);
+ int l = hufLength(hcode[im]);
+
+ if (c >> l) {
+ //
+ // Error: c is supposed to be an l-bit code,
+ // but c contains a value that is greater
+ // than the largest l-bit number.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ if (l > HUF_DECBITS) {
+ //
+ // Long code: add a secondary entry
+ //
+
+ HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
+
+ if (pl->len) {
+ //
+ // Error: a short code has already
+ // been stored in table entry *pl.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ pl->lit++;
+
+ if (pl->p) {
+ int *p = pl->p;
+ pl->p = new int[pl->lit];
+
+ for (int i = 0; i < pl->lit - 1; ++i) pl->p[i] = p[i];
+
+ delete[] p;
+ } else {
+ pl->p = new int[1];
+ }
+
+ pl->p[pl->lit - 1] = im;
+ } else if (l) {
+ //
+ // Short code: init all primary entries
+ //
+
+ HufDec *pl = hdecod + (c << (HUF_DECBITS - l));
+
+ for (long long i = 1ULL << (HUF_DECBITS - l); i > 0; i--, pl++) {
+ if (pl->len || pl->p) {
+ //
+ // Error: a short code or a long code has
+ // already been stored in table entry *pl.
+ //
+
+ // invalidTableEntry();
+ return false;
+ }
+
+ pl->len = l;
+ pl->lit = im;
+ }
+ }
+ }
+
+ return true;
+}
+
+//
+// Free the long code entries of a decoding table built by hufBuildDecTable()
+//
+
+static void hufFreeDecTable(HufDec *hdecod) // io: Decoding table
+{
+ for (int i = 0; i < HUF_DECSIZE; i++) {
+ if (hdecod[i].p) {
+ delete[] hdecod[i].p;
+ hdecod[i].p = 0;
+ }
+ }
+}
+
+//
+// ENCODING
+//
+
+inline void outputCode(long long code, long long &c, int &lc, char *&out) {
+ outputBits(hufLength(code), hufCode(code), c, lc, out);
+}
+
+inline void sendCode(long long sCode, int runCount, long long runCode,
+ long long &c, int &lc, char *&out) {
+ //
+ // Output a run of runCount instances of the symbol sCount.
+ // Output the symbols explicitly, or if that is shorter, output
+ // the sCode symbol once followed by a runCode symbol and runCount
+ // expressed as an 8-bit number.
+ //
+
+ if (hufLength(sCode) + hufLength(runCode) + 8 < hufLength(sCode) * runCount) {
+ outputCode(sCode, c, lc, out);
+ outputCode(runCode, c, lc, out);
+ outputBits(8, runCount, c, lc, out);
+ } else {
+ while (runCount-- >= 0) outputCode(sCode, c, lc, out);
+ }
+}
+
+//
+// Encode (compress) ni values based on the Huffman encoding table hcode:
+//
+
+static int hufEncode // return: output size (in bits)
+ (const long long *hcode, // i : encoding table
+ const unsigned short *in, // i : uncompressed input buffer
+ const int ni, // i : input buffer size (in bytes)
+ int rlc, // i : rl code
+ char *out) // o: compressed output buffer
+{
+ char *outStart = out;
+ long long c = 0; // bits not yet written to out
+ int lc = 0; // number of valid bits in c (LSB)
+ int s = in[0];
+ int cs = 0;
+
+ //
+ // Loop on input values
+ //
+
+ for (int i = 1; i < ni; i++) {
+ //
+ // Count same values or send code
+ //
+
+ if (s == in[i] && cs < 255) {
+ cs++;
+ } else {
+ sendCode(hcode[s], cs, hcode[rlc], c, lc, out);
+ cs = 0;
+ }
+
+ s = in[i];
+ }
+
+ //
+ // Send remaining code
+ //
+
+ sendCode(hcode[s], cs, hcode[rlc], c, lc, out);
+
+ if (lc) *out = (c << (8 - lc)) & 0xff;
+
+ return (out - outStart) * 8 + lc;
+}
+
+//
+// DECODING
+//
+
+//
+// In order to force the compiler to inline them,
+// getChar() and getCode() are implemented as macros
+// instead of "inline" functions.
+//
+
+#define getChar(c, lc, in) \
+ { \
+ c = (c << 8) | *(unsigned char *)(in++); \
+ lc += 8; \
+ }
+
+#define getCode(po, rlc, c, lc, in, out, oe) \
+ { \
+ if (po == rlc) { \
+ if (lc < 8) getChar(c, lc, in); \
+ \
+ lc -= 8; \
+ \
+ unsigned char cs = (c >> lc); \
+ \
+ if (out + cs > oe) return false; \
+ \
+ unsigned short s = out[-1]; \
+ \
+ while (cs-- > 0) *out++ = s; \
+ } else if (out < oe) { \
+ *out++ = po; \
+ } else { \
+ return false; \
+ } \
+ }
+
+//
+// Decode (uncompress) ni bits based on encoding & decoding tables:
+//
+
+static bool hufDecode(const long long *hcode, // i : encoding table
+ const HufDec *hdecod, // i : decoding table
+ const char *in, // i : compressed input buffer
+ int ni, // i : input size (in bits)
+ int rlc, // i : run-length code
+ int no, // i : expected output size (in bytes)
+ unsigned short *out) // o: uncompressed output buffer
+{
+ long long c = 0;
+ int lc = 0;
+ unsigned short *outb = out;
+ unsigned short *oe = out + no;
+ const char *ie = in + (ni + 7) / 8; // input byte size
+
+ //
+ // Loop on input bytes
+ //
+
+ while (in < ie) {
+ getChar(c, lc, in);
+
+ //
+ // Access decoding table
+ //
+
+ while (lc >= HUF_DECBITS) {
+ const HufDec pl = hdecod[(c >> (lc - HUF_DECBITS)) & HUF_DECMASK];
+
+ if (pl.len) {
+ //
+ // Get short code
+ //
+
+ lc -= pl.len;
+ getCode(pl.lit, rlc, c, lc, in, out, oe);
+ } else {
+ if (!pl.p) {
+ return false;
+ }
+ // invalidCode(); // wrong code
+
+ //
+ // Search long code
+ //
+
+ int j;
+
+ for (j = 0; j < pl.lit; j++) {
+ int l = hufLength(hcode[pl.p[j]]);
+
+ while (lc < l && in < ie) // get more bits
+ getChar(c, lc, in);
+
+ if (lc >= l) {
+ if (hufCode(hcode[pl.p[j]]) ==
+ ((c >> (lc - l)) & (((long long)(1) << l) - 1))) {
+ //
+ // Found : get long code
+ //
+
+ lc -= l;
+ getCode(pl.p[j], rlc, c, lc, in, out, oe);
+ break;
+ }
+ }
+ }
+
+ if (j == pl.lit) {
+ return false;
+ // invalidCode(); // Not found
+ }
+ }
+ }
+ }
+
+ //
+ // Get remaining (short) codes
+ //
+
+ int i = (8 - ni) & 7;
+ c >>= i;
+ lc -= i;
+
+ while (lc > 0) {
+ const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
+
+ if (pl.len) {
+ lc -= pl.len;
+ getCode(pl.lit, rlc, c, lc, in, out, oe);
+ } else {
+ return false;
+ // invalidCode(); // wrong (long) code
+ }
+ }
+
+ if (out - outb != no) {
+ return false;
+ }
+ // notEnoughData ();
+
+ return true;
+}
+
+static void countFrequencies(long long freq[HUF_ENCSIZE],
+ const unsigned short data[/*n*/], int n) {
+ for (int i = 0; i < HUF_ENCSIZE; ++i) freq[i] = 0;
+
+ for (int i = 0; i < n; ++i) ++freq[data[i]];
+}
+
+static void writeUInt(char buf[4], unsigned int i) {
+ unsigned char *b = (unsigned char *)buf;
+
+ b[0] = i;
+ b[1] = i >> 8;
+ b[2] = i >> 16;
+ b[3] = i >> 24;
+}
+
+static unsigned int readUInt(const char buf[4]) {
+ const unsigned char *b = (const unsigned char *)buf;
+
+ return (b[0] & 0x000000ff) | ((b[1] << 8) & 0x0000ff00) |
+ ((b[2] << 16) & 0x00ff0000) | ((b[3] << 24) & 0xff000000);
+}
+
+//
+// EXTERNAL INTERFACE
+//
+
+static int hufCompress(const unsigned short raw[], int nRaw,
+ char compressed[]) {
+ if (nRaw == 0) return 0;
+
+ long long freq[HUF_ENCSIZE];
+
+ countFrequencies(freq, raw, nRaw);
+
+ int im = 0;
+ int iM = 0;
+ hufBuildEncTable(freq, &im, &iM);
+
+ char *tableStart = compressed + 20;
+ char *tableEnd = tableStart;
+ hufPackEncTable(freq, im, iM, &tableEnd);
+ int tableLength = tableEnd - tableStart;
+
+ char *dataStart = tableEnd;
+ int nBits = hufEncode(freq, raw, nRaw, iM, dataStart);
+ int data_length = (nBits + 7) / 8;
+
+ writeUInt(compressed, im);
+ writeUInt(compressed + 4, iM);
+ writeUInt(compressed + 8, tableLength);
+ writeUInt(compressed + 12, nBits);
+ writeUInt(compressed + 16, 0); // room for future extensions
+
+ return dataStart + data_length - compressed;
+}
+
+static bool hufUncompress(const char compressed[], int nCompressed,
+ unsigned short raw[], int nRaw) {
+ if (nCompressed == 0) {
+ if (nRaw != 0) return false;
+
+ return false;
+ }
+
+ int im = readUInt(compressed);
+ int iM = readUInt(compressed + 4);
+ // int tableLength = readUInt (compressed + 8);
+ int nBits = readUInt(compressed + 12);
+
+ if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE) return false;
+
+ const char *ptr = compressed + 20;
+
+ //
+ // Fast decoder needs at least 2x64-bits of compressed data, and
+ // needs to be run-able on this platform. Otherwise, fall back
+ // to the original decoder
+ //
+
+ // if (FastHufDecoder::enabled() && nBits > 128)
+ //{
+ // FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM);
+ // fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw);
+ //}
+ // else
+ {
+ std::vector<long long> freq(HUF_ENCSIZE);
+ std::vector<HufDec> hdec(HUF_DECSIZE);
+
+ hufClearDecTable(&hdec.at(0));
+
+ hufUnpackEncTable(&ptr, nCompressed - (ptr - compressed), im, iM,
+ &freq.at(0));
+
+ {
+ if (nBits > 8 * (nCompressed - (ptr - compressed))) {
+ return false;
+ }
+
+ hufBuildDecTable(&freq.at(0), im, iM, &hdec.at(0));
+ hufDecode(&freq.at(0), &hdec.at(0), ptr, nBits, iM, nRaw, raw);
+ }
+ // catch (...)
+ //{
+ // hufFreeDecTable (hdec);
+ // throw;
+ //}
+
+ hufFreeDecTable(&hdec.at(0));
+ }
+
+ return true;
+}
+
+//
+// Functions to compress the range of values in the pixel data
+//
+
+const int USHORT_RANGE = (1 << 16);
+const int BITMAP_SIZE = (USHORT_RANGE >> 3);
+
+static void bitmapFromData(const unsigned short data[/*nData*/], int nData,
+ unsigned char bitmap[BITMAP_SIZE],
+ unsigned short &minNonZero,
+ unsigned short &maxNonZero) {
+ for (int i = 0; i < BITMAP_SIZE; ++i) bitmap[i] = 0;
+
+ for (int i = 0; i < nData; ++i) bitmap[data[i] >> 3] |= (1 << (data[i] & 7));
+
+ bitmap[0] &= ~1; // zero is not explicitly stored in
+ // the bitmap; we assume that the
+ // data always contain zeroes
+ minNonZero = BITMAP_SIZE - 1;
+ maxNonZero = 0;
+
+ for (int i = 0; i < BITMAP_SIZE; ++i) {
+ if (bitmap[i]) {
+ if (minNonZero > i) minNonZero = i;
+ if (maxNonZero < i) maxNonZero = i;
+ }
+ }
+}
+
+static unsigned short forwardLutFromBitmap(
+ const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) {
+ int k = 0;
+
+ for (int i = 0; i < USHORT_RANGE; ++i) {
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+ lut[i] = k++;
+ else
+ lut[i] = 0;
+ }
+
+ return k - 1; // maximum value stored in lut[],
+} // i.e. number of ones in bitmap minus 1
+
+static unsigned short reverseLutFromBitmap(
+ const unsigned char bitmap[BITMAP_SIZE], unsigned short lut[USHORT_RANGE]) {
+ int k = 0;
+
+ for (int i = 0; i < USHORT_RANGE; ++i) {
+ if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7)))) lut[k++] = i;
+ }
+
+ int n = k - 1;
+
+ while (k < USHORT_RANGE) lut[k++] = 0;
+
+ return n; // maximum k where lut[k] is non-zero,
+} // i.e. number of ones in bitmap minus 1
+
+static void applyLut(const unsigned short lut[USHORT_RANGE],
+ unsigned short data[/*nData*/], int nData) {
+ for (int i = 0; i < nData; ++i) data[i] = lut[data[i]];
+}
+
+#ifdef __clang__
+#pragma clang diagnostic pop
+#endif // __clang__
+
+static bool CompressPiz(unsigned char *outPtr, unsigned int &outSize,
+ const unsigned char *inPtr, size_t inSize,
+ const std::vector<ChannelInfo> &channelInfo,
+ int data_width, int num_lines) {
+ unsigned char bitmap[BITMAP_SIZE];
+ unsigned short minNonZero;
+ unsigned short maxNonZero;
+
+#if !MINIZ_LITTLE_ENDIAN
+ // @todo { PIZ compression on BigEndian architecture. }
+ assert(0);
+ return false;
+#endif
+
+ // Assume `inSize` is multiple of 2 or 4.
+ std::vector<unsigned short> tmpBuffer(inSize / sizeof(unsigned short));
+
+ std::vector<PIZChannelData> channelData(channelInfo.size());
+ unsigned short *tmpBufferEnd = &tmpBuffer.at(0);
+
+ for (size_t c = 0; c < channelData.size(); c++) {
+ PIZChannelData &cd = channelData[c];
+
+ cd.start = tmpBufferEnd;
+ cd.end = cd.start;
+
+ cd.nx = data_width;
+ cd.ny = num_lines;
+ // cd.ys = c.channel().ySampling;
+
+ size_t pixelSize = sizeof(int); // UINT and FLOAT
+ if (channelInfo[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ pixelSize = sizeof(short);
+ }
+
+ cd.size = static_cast<int>(pixelSize / sizeof(short));
+
+ tmpBufferEnd += cd.nx * cd.ny * cd.size;
+ }
+
+ const unsigned char *ptr = inPtr;
+ for (int y = 0; y < num_lines; ++y) {
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ // if (modp (y, cd.ys) != 0)
+ // continue;
+
+ size_t n = static_cast<size_t>(cd.nx * cd.size);
+ memcpy(cd.end, ptr, n * sizeof(unsigned short));
+ ptr += n * sizeof(unsigned short);
+ cd.end += n;
+ }
+ }
+
+ bitmapFromData(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()), bitmap,
+ minNonZero, maxNonZero);
+
+ unsigned short lut[USHORT_RANGE];
+ unsigned short maxValue = forwardLutFromBitmap(bitmap, lut);
+ applyLut(lut, &tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()));
+
+ //
+ // Store range compression info in _outBuffer
+ //
+
+ char *buf = reinterpret_cast<char *>(outPtr);
+
+ memcpy(buf, &minNonZero, sizeof(unsigned short));
+ buf += sizeof(unsigned short);
+ memcpy(buf, &maxNonZero, sizeof(unsigned short));
+ buf += sizeof(unsigned short);
+
+ if (minNonZero <= maxNonZero) {
+ memcpy(buf, reinterpret_cast<char *>(&bitmap[0] + minNonZero),
+ maxNonZero - minNonZero + 1);
+ buf += maxNonZero - minNonZero + 1;
+ }
+
+ //
+ // Apply wavelet encoding
+ //
+
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ for (int j = 0; j < cd.size; ++j) {
+ wav2Encode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size,
+ maxValue);
+ }
+ }
+
+ //
+ // Apply Huffman encoding; append the result to _outBuffer
+ //
+
+ // length header(4byte), then huff data. Initialize length header with zero,
+ // then later fill it by `length`.
+ char *lengthPtr = buf;
+ int zero = 0;
+ memcpy(buf, &zero, sizeof(int));
+ buf += sizeof(int);
+
+ int length =
+ hufCompress(&tmpBuffer.at(0), static_cast<int>(tmpBuffer.size()), buf);
+ memcpy(lengthPtr, &length, sizeof(int));
+
+ outSize = static_cast<unsigned int>(
+ (reinterpret_cast<unsigned char *>(buf) - outPtr) +
+ static_cast<unsigned int>(length));
+ return true;
+}
+
+static bool DecompressPiz(unsigned char *outPtr, const unsigned char *inPtr,
+ size_t tmpBufSize, int num_channels,
+ const EXRChannelInfo *channels, int data_width,
+ int num_lines) {
+ unsigned char bitmap[BITMAP_SIZE];
+ unsigned short minNonZero;
+ unsigned short maxNonZero;
+
+#if !MINIZ_LITTLE_ENDIAN
+ // @todo { PIZ compression on BigEndian architecture. }
+ assert(0);
+ return false;
+#endif
+
+ memset(bitmap, 0, BITMAP_SIZE);
+
+ const unsigned char *ptr = inPtr;
+ minNonZero = *(reinterpret_cast<const unsigned short *>(ptr));
+ maxNonZero = *(reinterpret_cast<const unsigned short *>(ptr + 2));
+ ptr += 4;
+
+ if (maxNonZero >= BITMAP_SIZE) {
+ return false;
+ }
+
+ if (minNonZero <= maxNonZero) {
+ memcpy(reinterpret_cast<char *>(&bitmap[0] + minNonZero), ptr,
+ maxNonZero - minNonZero + 1);
+ ptr += maxNonZero - minNonZero + 1;
+ }
+
+ unsigned short lut[USHORT_RANGE];
+ memset(lut, 0, sizeof(unsigned short) * USHORT_RANGE);
+ unsigned short maxValue = reverseLutFromBitmap(bitmap, lut);
+
+ //
+ // Huffman decoding
+ //
+
+ int length;
+
+ length = *(reinterpret_cast<const int *>(ptr));
+ ptr += sizeof(int);
+
+ std::vector<unsigned short> tmpBuffer(tmpBufSize);
+ hufUncompress(reinterpret_cast<const char *>(ptr), length, &tmpBuffer.at(0),
+ static_cast<int>(tmpBufSize));
+
+ //
+ // Wavelet decoding
+ //
+
+ std::vector<PIZChannelData> channelData(static_cast<size_t>(num_channels));
+
+ unsigned short *tmpBufferEnd = &tmpBuffer.at(0);
+
+ for (size_t i = 0; i < static_cast<size_t>(num_channels); ++i) {
+ const EXRChannelInfo &chan = channels[i];
+
+ size_t pixelSize = sizeof(int); // UINT and FLOAT
+ if (chan.pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ pixelSize = sizeof(short);
+ }
+
+ channelData[i].start = tmpBufferEnd;
+ channelData[i].end = channelData[i].start;
+ channelData[i].nx = data_width;
+ channelData[i].ny = num_lines;
+ // channelData[i].ys = 1;
+ channelData[i].size = static_cast<int>(pixelSize / sizeof(short));
+
+ tmpBufferEnd += channelData[i].nx * channelData[i].ny * channelData[i].size;
+ }
+
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ for (int j = 0; j < cd.size; ++j) {
+ wav2Decode(cd.start + j, cd.nx, cd.size, cd.ny, cd.nx * cd.size,
+ maxValue);
+ }
+ }
+
+ //
+ // Expand the pixel data to their original range
+ //
+
+ applyLut(lut, &tmpBuffer.at(0), static_cast<int>(tmpBufSize));
+
+ for (int y = 0; y < num_lines; y++) {
+ for (size_t i = 0; i < channelData.size(); ++i) {
+ PIZChannelData &cd = channelData[i];
+
+ // if (modp (y, cd.ys) != 0)
+ // continue;
+
+ size_t n = static_cast<size_t>(cd.nx * cd.size);
+ memcpy(outPtr, cd.end, static_cast<size_t>(n * sizeof(unsigned short)));
+ outPtr += n * sizeof(unsigned short);
+ cd.end += n;
+ }
+ }
+
+ return true;
+}
+#endif // TINYEXR_USE_PIZ
+
+#if TINYEXR_USE_ZFP
+struct ZFPCompressionParam {
+ double rate;
+ int precision;
+ double tolerance;
+ int type; // TINYEXR_ZFP_COMPRESSIONTYPE_*
+
+ ZFPCompressionParam() {
+ type = TINYEXR_ZFP_COMPRESSIONTYPE_RATE;
+ rate = 2.0;
+ precision = 0;
+ tolerance = 0.0f;
+ }
+};
+
+bool FindZFPCompressionParam(ZFPCompressionParam *param,
+ const EXRAttribute *attributes,
+ int num_attributes) {
+ bool foundType = false;
+
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionType") == 0) &&
+ (attributes[i].size == 1)) {
+ param->type = static_cast<int>(attributes[i].value[0]);
+
+ foundType = true;
+ }
+ }
+
+ if (!foundType) {
+ return false;
+ }
+
+ if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionRate") == 0) &&
+ (attributes[i].size == 8)) {
+ param->rate = *(reinterpret_cast<double *>(attributes[i].value));
+ return true;
+ }
+ }
+ } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionPrecision") == 0) &&
+ (attributes[i].size == 4)) {
+ param->rate = *(reinterpret_cast<int *>(attributes[i].value));
+ return true;
+ }
+ }
+ } else if (param->type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ for (int i = 0; i < num_attributes; i++) {
+ if ((strcmp(attributes[i].name, "zfpCompressionTolerance") == 0) &&
+ (attributes[i].size == 8)) {
+ param->tolerance = *(reinterpret_cast<double *>(attributes[i].value));
+ return true;
+ }
+ }
+ } else {
+ assert(0);
+ }
+
+ return false;
+}
+
+// Assume pixel format is FLOAT for all channels.
+static bool DecompressZfp(float *dst, int dst_width, int dst_num_lines,
+ int num_channels, const unsigned char *src,
+ unsigned long src_size,
+ const ZFPCompressionParam &param) {
+ size_t uncompressed_size = dst_width * dst_num_lines * num_channels;
+
+ zfp_stream *zfp = NULL;
+ zfp_field *field = NULL;
+
+ assert((dst_width % 4) == 0);
+ assert((dst_num_lines % 4) == 0);
+
+ if ((dst_width & 3U) || (dst_num_lines & 3U)) {
+ return false;
+ }
+
+ field =
+ zfp_field_2d(reinterpret_cast<void *>(const_cast<unsigned char *>(src)),
+ zfp_type_float, dst_width, dst_num_lines * num_channels);
+ zfp = zfp_stream_open(NULL);
+
+ if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, /* dimention */ 2,
+ /* write random access */ 0);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ } else {
+ assert(0);
+ }
+
+ size_t buf_size = zfp_stream_maximum_size(zfp, field);
+ std::vector<unsigned char> buf(buf_size);
+ memcpy(&buf.at(0), src, src_size);
+
+ bitstream *stream = stream_open(&buf.at(0), buf_size);
+ zfp_stream_set_bit_stream(zfp, stream);
+ zfp_stream_rewind(zfp);
+
+ size_t image_size = dst_width * dst_num_lines;
+
+ for (int c = 0; c < num_channels; c++) {
+ // decompress 4x4 pixel block.
+ for (int y = 0; y < dst_num_lines; y += 4) {
+ for (int x = 0; x < dst_width; x += 4) {
+ float fblock[16];
+ zfp_decode_block_float_2(zfp, fblock);
+ for (int j = 0; j < 4; j++) {
+ for (int i = 0; i < 4; i++) {
+ dst[c * image_size + ((y + j) * dst_width + (x + i))] =
+ fblock[j * 4 + i];
+ }
+ }
+ }
+ }
+ }
+
+ zfp_field_free(field);
+ zfp_stream_close(zfp);
+ stream_close(stream);
+
+ return true;
+}
+
+// Assume pixel format is FLOAT for all channels.
+bool CompressZfp(std::vector<unsigned char> *outBuf, unsigned int *outSize,
+ const float *inPtr, int width, int num_lines, int num_channels,
+ const ZFPCompressionParam &param) {
+ zfp_stream *zfp = NULL;
+ zfp_field *field = NULL;
+
+ assert((width % 4) == 0);
+ assert((num_lines % 4) == 0);
+
+ if ((width & 3U) || (num_lines & 3U)) {
+ return false;
+ }
+
+ // create input array.
+ field = zfp_field_2d(reinterpret_cast<void *>(const_cast<float *>(inPtr)),
+ zfp_type_float, width, num_lines * num_channels);
+
+ zfp = zfp_stream_open(NULL);
+
+ if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_RATE) {
+ zfp_stream_set_rate(zfp, param.rate, zfp_type_float, 2, 0);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_PRECISION) {
+ zfp_stream_set_precision(zfp, param.precision, zfp_type_float);
+ } else if (param.type == TINYEXR_ZFP_COMPRESSIONTYPE_ACCURACY) {
+ zfp_stream_set_accuracy(zfp, param.tolerance, zfp_type_float);
+ } else {
+ assert(0);
+ }
+
+ size_t buf_size = zfp_stream_maximum_size(zfp, field);
+
+ outBuf->resize(buf_size);
+
+ bitstream *stream = stream_open(&outBuf->at(0), buf_size);
+ zfp_stream_set_bit_stream(zfp, stream);
+ zfp_field_free(field);
+
+ size_t image_size = width * num_lines;
+
+ for (int c = 0; c < num_channels; c++) {
+ // compress 4x4 pixel block.
+ for (int y = 0; y < num_lines; y += 4) {
+ for (int x = 0; x < width; x += 4) {
+ float fblock[16];
+ for (int j = 0; j < 4; j++) {
+ for (int i = 0; i < 4; i++) {
+ fblock[j * 4 + i] =
+ inPtr[c * image_size + ((y + j) * width + (x + i))];
+ }
+ }
+ zfp_encode_block_float_2(zfp, fblock);
+ }
+ }
+ }
+
+ zfp_stream_flush(zfp);
+ (*outSize) = zfp_stream_compressed_size(zfp);
+
+ zfp_stream_close(zfp);
+
+ return true;
+}
+
+#endif
+
+//
+// -----------------------------------------------------------------
+//
+
+static void DecodePixelData(/* out */ unsigned char **out_images,
+ const int *requested_pixel_types,
+ const unsigned char *data_ptr, size_t data_len,
+ int compression_type, int line_order, int width,
+ int height, int x_stride, int y, int line_no,
+ int num_lines, size_t pixel_data_size,
+ size_t num_attributes,
+ const EXRAttribute *attributes, size_t num_channels,
+ const EXRChannelInfo *channels,
+ const std::vector<size_t> &channel_offset_list) {
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) { // PIZ
+#if TINYEXR_USE_PIZ
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(
+ static_cast<size_t>(width * num_lines) * pixel_data_size));
+ size_t tmpBufLen = static_cast<size_t>(
+ static_cast<size_t>(width * num_lines) * pixel_data_size);
+
+ bool ret = tinyexr::DecompressPiz(
+ reinterpret_cast<unsigned char *>(&outBuf.at(0)), data_ptr, tmpBufLen,
+ static_cast<int>(num_channels), channels, width, num_lines);
+
+ assert(ret);
+ (void)ret;
+
+ // For PIZ_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ FP16 hf;
+
+ hf.u = line_ptr[u];
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val = line_ptr[u];
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(&outBuf.at(
+ v * pixel_data_size * static_cast<size_t>(x_stride) +
+ channel_offset_list[c] * static_cast<size_t>(x_stride)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += static_cast<size_t>(
+ (height - 1 - (line_no + static_cast<int>(v)))) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ }
+#else
+ assert(0 && "PIZ is enabled in this build");
+#endif
+
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS ||
+ compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = static_cast<unsigned long>(outBuf.size());
+ assert(dstLen > 0);
+ tinyexr::DecompressZip(reinterpret_cast<unsigned char *>(&outBuf.at(0)),
+ &dstLen, data_ptr,
+ static_cast<unsigned long>(data_len));
+
+ // For ZIP_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * static_cast<size_t>(pixel_data_size) *
+ static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ tinyexr::FP16 hf;
+
+ hf.u = line_ptr[u];
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ tinyexr::FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val = line_ptr[u];
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ }
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) {
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = static_cast<unsigned long>(outBuf.size());
+ assert(dstLen > 0);
+ tinyexr::DecompressRle(reinterpret_cast<unsigned char *>(&outBuf.at(0)),
+ dstLen, data_ptr,
+ static_cast<unsigned long>(data_len));
+
+ // For RLE_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &outBuf.at(v * static_cast<size_t>(pixel_data_size) *
+ static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ tinyexr::FP16 hf;
+
+ hf.u = line_ptr[u];
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *image =
+ reinterpret_cast<unsigned short **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = hf.u;
+ } else { // HALF -> FLOAT
+ tinyexr::FP32 f32 = half_to_float(hf);
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = f32.f;
+ }
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT);
+
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const unsigned int *line_ptr = reinterpret_cast<unsigned int *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ unsigned int val = line_ptr[u];
+
+ tinyexr::swap4(&val);
+
+ unsigned int *image =
+ reinterpret_cast<unsigned int **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ }
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+ if (!FindZFPCompressionParam(&zfp_compression_param, attributes,
+ num_attributes)) {
+ assert(0);
+ return;
+ }
+
+ // Allocate original data size.
+ std::vector<unsigned char> outBuf(static_cast<size_t>(width) *
+ static_cast<size_t>(num_lines) *
+ pixel_data_size);
+
+ unsigned long dstLen = outBuf.size();
+ assert(dstLen > 0);
+ tinyexr::DecompressZfp(reinterpret_cast<float *>(&outBuf.at(0)), width,
+ num_lines, num_channels, data_ptr,
+ static_cast<unsigned long>(data_len),
+ zfp_compression_param);
+
+ // For ZFP_COMPRESSION:
+ // pixel sample data for channel 0 for scanline 0
+ // pixel sample data for channel 1 for scanline 0
+ // pixel sample data for channel ... for scanline 0
+ // pixel sample data for channel n for scanline 0
+ // pixel sample data for channel 0 for scanline 1
+ // pixel sample data for channel 1 for scanline 1
+ // pixel sample data for channel ... for scanline 1
+ // pixel sample data for channel n for scanline 1
+ // ...
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ assert(channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ assert(requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT);
+ for (size_t v = 0; v < static_cast<size_t>(num_lines); v++) {
+ const float *line_ptr = reinterpret_cast<float *>(
+ &outBuf.at(v * pixel_data_size * static_cast<size_t>(width) +
+ channel_offset_list[c] * static_cast<size_t>(width)));
+ for (size_t u = 0; u < static_cast<size_t>(width); u++) {
+ float val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ float *image = reinterpret_cast<float **>(out_images)[c];
+ if (line_order == 0) {
+ image += (static_cast<size_t>(line_no) + v) *
+ static_cast<size_t>(x_stride) +
+ u;
+ } else {
+ image += (static_cast<size_t>(height) - 1U -
+ (static_cast<size_t>(line_no) + v)) *
+ static_cast<size_t>(x_stride) +
+ u;
+ }
+ *image = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ }
+#else
+ (void)attributes;
+ (void)num_attributes;
+ (void)num_channels;
+ assert(0);
+#endif
+ } else if (compression_type == TINYEXR_COMPRESSIONTYPE_NONE) {
+ for (size_t c = 0; c < num_channels; c++) {
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ const unsigned short *line_ptr =
+ reinterpret_cast<const unsigned short *>(
+ data_ptr +
+ c * static_cast<size_t>(width) * sizeof(unsigned short));
+
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ unsigned short *outLine =
+ reinterpret_cast<unsigned short *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += y * x_stride;
+ } else {
+ outLine += (height - 1 - y) * x_stride;
+ }
+
+ for (int u = 0; u < width; u++) {
+ tinyexr::FP16 hf;
+
+ hf.u = line_ptr[u];
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ outLine[u] = hf.u;
+ }
+ } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ float *outLine = reinterpret_cast<float *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += y * x_stride;
+ } else {
+ outLine += (height - 1 - y) * x_stride;
+ }
+
+ for (int u = 0; u < width; u++) {
+ tinyexr::FP16 hf;
+
+ hf.u = line_ptr[u];
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&hf.u));
+
+ tinyexr::FP32 f32 = half_to_float(hf);
+
+ outLine[u] = f32.f;
+ }
+ } else {
+ assert(0);
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ const float *line_ptr = reinterpret_cast<const float *>(
+ data_ptr + c * static_cast<size_t>(width) * sizeof(float));
+
+ float *outLine = reinterpret_cast<float *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += y * x_stride;
+ } else {
+ outLine += (height - 1 - y) * x_stride;
+ }
+
+ for (int u = 0; u < width; u++) {
+ float val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ outLine[u] = val;
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ const unsigned int *line_ptr = reinterpret_cast<const unsigned int *>(
+ data_ptr + c * static_cast<size_t>(width) * sizeof(unsigned int));
+
+ unsigned int *outLine = reinterpret_cast<unsigned int *>(out_images[c]);
+ if (line_order == 0) {
+ outLine += y * x_stride;
+ } else {
+ outLine += (height - 1 - y) * x_stride;
+ }
+
+ for (int u = 0; u < width; u++) {
+ unsigned int val = line_ptr[u];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ outLine[u] = val;
+ }
+ }
+ }
+ }
+}
+
+static void DecodeTiledPixelData(
+ unsigned char **out_images, int *width, int *height,
+ const int *requested_pixel_types, const unsigned char *data_ptr,
+ size_t data_len, int compression_type, int line_order, int data_width,
+ int data_height, int tile_offset_x, int tile_offset_y, int tile_size_x,
+ int tile_size_y, size_t pixel_data_size, size_t num_attributes,
+ const EXRAttribute *attributes, size_t num_channels,
+ const EXRChannelInfo *channels,
+ const std::vector<size_t> &channel_offset_list) {
+ assert(tile_offset_x * tile_size_x < data_width);
+ assert(tile_offset_y * tile_size_y < data_height);
+
+ // Compute actual image size in a tile.
+ if ((tile_offset_x + 1) * tile_size_x >= data_width) {
+ (*width) = data_width - (tile_offset_x * tile_size_x);
+ } else {
+ (*width) = tile_size_x;
+ }
+
+ if ((tile_offset_y + 1) * tile_size_y >= data_height) {
+ (*height) = data_height - (tile_offset_y * tile_size_y);
+ } else {
+ (*height) = tile_size_y;
+ }
+
+ // Image size = tile size.
+ DecodePixelData(out_images, requested_pixel_types, data_ptr, data_len,
+ compression_type, line_order, (*width), tile_size_y,
+ /* stride */ tile_size_x, /* y */ 0, /* line_no */ 0,
+ (*height), pixel_data_size, num_attributes, attributes,
+ num_channels, channels, channel_offset_list);
+}
+
+static void ComputeChannelLayout(std::vector<size_t> *channel_offset_list,
+ int *pixel_data_size, size_t *channel_offset,
+ int num_channels,
+ const EXRChannelInfo *channels) {
+ channel_offset_list->resize(static_cast<size_t>(num_channels));
+
+ (*pixel_data_size) = 0;
+ (*channel_offset) = 0;
+
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ (*channel_offset_list)[c] = (*channel_offset);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ (*pixel_data_size) += sizeof(unsigned short);
+ (*channel_offset) += sizeof(unsigned short);
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ (*pixel_data_size) += sizeof(float);
+ (*channel_offset) += sizeof(float);
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ (*pixel_data_size) += sizeof(unsigned int);
+ (*channel_offset) += sizeof(unsigned int);
+ } else {
+ assert(0);
+ }
+ }
+}
+
+static unsigned char **AllocateImage(int num_channels,
+ const EXRChannelInfo *channels,
+ const int *requested_pixel_types,
+ int data_width, int data_height) {
+ unsigned char **images =
+ reinterpret_cast<unsigned char **>(static_cast<float **>(
+ malloc(sizeof(float *) * static_cast<size_t>(num_channels))));
+
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ size_t data_len =
+ static_cast<size_t>(data_width) * static_cast<size_t>(data_height);
+ if (channels[c].pixel_type == TINYEXR_PIXELTYPE_HALF) {
+ // pixel_data_size += sizeof(unsigned short);
+ // channel_offset += sizeof(unsigned short);
+ // Alloc internal image for half type.
+ if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ images[c] =
+ reinterpret_cast<unsigned char *>(static_cast<unsigned short *>(
+ malloc(sizeof(unsigned short) * data_len)));
+ } else if (requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<float *>(malloc(sizeof(float) * data_len)));
+ } else {
+ assert(0);
+ }
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_FLOAT) {
+ // pixel_data_size += sizeof(float);
+ // channel_offset += sizeof(float);
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<float *>(malloc(sizeof(float) * data_len)));
+ } else if (channels[c].pixel_type == TINYEXR_PIXELTYPE_UINT) {
+ // pixel_data_size += sizeof(unsigned int);
+ // channel_offset += sizeof(unsigned int);
+ images[c] = reinterpret_cast<unsigned char *>(
+ static_cast<unsigned int *>(malloc(sizeof(unsigned int) * data_len)));
+ } else {
+ assert(0);
+ }
+ }
+
+ return images;
+}
+
+static int ParseEXRHeader(HeaderInfo *info, bool *empty_header,
+ const EXRVersion *version, std::string *err,
+ const unsigned char *buf, size_t size) {
+ const char *marker = reinterpret_cast<const char *>(&buf[0]);
+
+ if (empty_header) {
+ (*empty_header) = false;
+ }
+
+ if (version->multipart) {
+ if (size > 0 && marker[0] == '\0') {
+ // End of header list.
+ if (empty_header) {
+ (*empty_header) = true;
+ }
+ return TINYEXR_SUCCESS;
+ }
+ }
+
+ // According to the spec, the header of every OpenEXR file must contain at
+ // least the following attributes:
+ //
+ // channels chlist
+ // compression compression
+ // dataWindow box2i
+ // displayWindow box2i
+ // lineOrder lineOrder
+ // pixelAspectRatio float
+ // screenWindowCenter v2f
+ // screenWindowWidth float
+ bool has_channels = false;
+ bool has_compression = false;
+ bool has_data_window = false;
+ bool has_display_window = false;
+ bool has_line_order = false;
+ bool has_pixel_aspect_ratio = false;
+ bool has_screen_window_center = false;
+ bool has_screen_window_width = false;
+
+ info->data_window[0] = 0;
+ info->data_window[1] = 0;
+ info->data_window[2] = 0;
+ info->data_window[3] = 0;
+ info->line_order = 0; // @fixme
+ info->display_window[0] = 0;
+ info->display_window[1] = 0;
+ info->display_window[2] = 0;
+ info->display_window[3] = 0;
+ info->screen_window_center[0] = 0.0f;
+ info->screen_window_center[1] = 0.0f;
+ info->screen_window_width = -1.0f;
+ info->pixel_aspect_ratio = -1.0f;
+
+ info->tile_size_x = -1;
+ info->tile_size_y = -1;
+ info->tile_level_mode = -1;
+ info->tile_rounding_mode = -1;
+
+ info->attributes.clear();
+
+ // Read attributes
+ size_t orig_size = size;
+ for (;;) {
+ if (0 == size) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ } else if (marker[0] == '\0') {
+ size--;
+ break;
+ }
+
+ std::string attr_name;
+ std::string attr_type;
+ std::vector<unsigned char> data;
+ size_t marker_size;
+ if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size,
+ marker, size)) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += marker_size;
+ size -= marker_size;
+
+ if (version->tiled && attr_name.compare("tiles") == 0) {
+ unsigned int x_size, y_size;
+ unsigned char tile_mode;
+ assert(data.size() == 9);
+ memcpy(&x_size, &data.at(0), sizeof(int));
+ memcpy(&y_size, &data.at(4), sizeof(int));
+ tile_mode = data[8];
+ tinyexr::swap4(&x_size);
+ tinyexr::swap4(&y_size);
+
+ info->tile_size_x = static_cast<int>(x_size);
+ info->tile_size_y = static_cast<int>(y_size);
+
+ // mode = levelMode + roundingMode * 16
+ info->tile_level_mode = tile_mode & 0x3;
+ info->tile_rounding_mode = (tile_mode >> 4) & 0x1;
+
+ } else if (attr_name.compare("compression") == 0) {
+ bool ok = false;
+ if ((data[0] >= TINYEXR_COMPRESSIONTYPE_NONE) &&
+ (data[0] < TINYEXR_COMPRESSIONTYPE_PIZ)) {
+ ok = true;
+ }
+
+ if (data[0] == TINYEXR_COMPRESSIONTYPE_PIZ) {
+#if TINYEXR_USE_PIZ
+ ok = true;
+#else
+ if (err) {
+ (*err) = "PIZ compression is not supported.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+#endif
+ }
+
+ if (data[0] == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ ok = true;
+#else
+ if (err) {
+ (*err) = "ZFP compression is not supported.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+#endif
+ }
+
+ if (!ok) {
+ if (err) {
+ (*err) = "Unknown compression type.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ info->compression_type = static_cast<int>(data[0]);
+ has_compression = true;
+
+ } else if (attr_name.compare("channels") == 0) {
+ // name: zero-terminated string, from 1 to 255 bytes long
+ // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2
+ // pLinear: unsigned char, possible values are 0 and 1
+ // reserved: three chars, should be zero
+ // xSampling: int
+ // ySampling: int
+
+ ReadChannelInfo(info->channels, data);
+
+ if (info->channels.size() < 1) {
+ if (err) {
+ (*err) = "# of channels is zero.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ has_channels = true;
+
+ } else if (attr_name.compare("dataWindow") == 0) {
+ memcpy(&info->data_window[0], &data.at(0), sizeof(int));
+ memcpy(&info->data_window[1], &data.at(4), sizeof(int));
+ memcpy(&info->data_window[2], &data.at(8), sizeof(int));
+ memcpy(&info->data_window[3], &data.at(12), sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[0]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[1]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[2]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->data_window[3]));
+
+ has_data_window = true;
+ } else if (attr_name.compare("displayWindow") == 0) {
+ memcpy(&info->display_window[0], &data.at(0), sizeof(int));
+ memcpy(&info->display_window[1], &data.at(4), sizeof(int));
+ memcpy(&info->display_window[2], &data.at(8), sizeof(int));
+ memcpy(&info->display_window[3], &data.at(12), sizeof(int));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->display_window[0]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->display_window[1]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->display_window[2]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->display_window[3]));
+
+ has_display_window = true;
+ } else if (attr_name.compare("lineOrder") == 0) {
+ info->line_order = static_cast<int>(data[0]);
+ has_line_order = true;
+ } else if (attr_name.compare("pixelAspectRatio") == 0) {
+ memcpy(&info->pixel_aspect_ratio, &data.at(0), sizeof(float));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->pixel_aspect_ratio));
+ has_pixel_aspect_ratio = true;
+ } else if (attr_name.compare("screenWindowCenter") == 0) {
+ memcpy(&info->screen_window_center[0], &data.at(0), sizeof(float));
+ memcpy(&info->screen_window_center[1], &data.at(4), sizeof(float));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->screen_window_center[0]));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->screen_window_center[1]));
+ has_screen_window_center = true;
+ } else if (attr_name.compare("screenWindowWidth") == 0) {
+ memcpy(&info->screen_window_width, &data.at(0), sizeof(float));
+ tinyexr::swap4(
+ reinterpret_cast<unsigned int *>(&info->screen_window_width));
+
+ has_screen_window_width = true;
+ } else if (attr_name.compare("chunkCount") == 0) {
+ memcpy(&info->chunk_count, &data.at(0), sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&info->chunk_count));
+ } else {
+ // Custom attribute(up to TINYEXR_MAX_ATTRIBUTES)
+ if (info->attributes.size() < TINYEXR_MAX_ATTRIBUTES) {
+ EXRAttribute attrib;
+ strncpy(attrib.name, attr_name.c_str(), 255);
+ attrib.name[255] = '\0';
+ strncpy(attrib.type, attr_type.c_str(), 255);
+ attrib.type[255] = '\0';
+ attrib.size = static_cast<int>(data.size());
+ attrib.value = static_cast<unsigned char *>(malloc(data.size()));
+ memcpy(reinterpret_cast<char *>(attrib.value), &data.at(0),
+ data.size());
+ info->attributes.push_back(attrib);
+ }
+ }
+ }
+
+ // Check if required attributes exist
+ {
+ std::stringstream ss_err;
+
+ if (!has_compression) {
+ ss_err << "\"compression\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_channels) {
+ ss_err << "\"channels\" attribute not found in the header." << std::endl;
+ }
+
+ if (!has_line_order) {
+ ss_err << "\"lineOrder\" attribute not found in the header." << std::endl;
+ }
+
+ if (!has_display_window) {
+ ss_err << "\"displayWindow\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_data_window) {
+ ss_err << "\"dataWindow\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_pixel_aspect_ratio) {
+ ss_err << "\"pixelAspectRatio\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_screen_window_width) {
+ ss_err << "\"screenWindowWidth\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!has_screen_window_center) {
+ ss_err << "\"screenWindowCenter\" attribute not found in the header."
+ << std::endl;
+ }
+
+ if (!(ss_err.str().empty())) {
+ if (err) {
+ (*err) += ss_err.str();
+ }
+ return TINYEXR_ERROR_INVALID_HEADER;
+ }
+ }
+
+ info->header_len = static_cast<unsigned int>(orig_size - size);
+
+ return TINYEXR_SUCCESS;
+}
+
+// C++ HeaderInfo to C EXRHeader conversion.
+static void ConvertHeader(EXRHeader *exr_header, const HeaderInfo &info) {
+ exr_header->pixel_aspect_ratio = info.pixel_aspect_ratio;
+ exr_header->screen_window_center[0] = info.screen_window_center[0];
+ exr_header->screen_window_center[1] = info.screen_window_center[1];
+ exr_header->screen_window_width = info.screen_window_width;
+ exr_header->chunk_count = info.chunk_count;
+ exr_header->display_window[0] = info.display_window[0];
+ exr_header->display_window[1] = info.display_window[1];
+ exr_header->display_window[2] = info.display_window[2];
+ exr_header->display_window[3] = info.display_window[3];
+ exr_header->data_window[0] = info.data_window[0];
+ exr_header->data_window[1] = info.data_window[1];
+ exr_header->data_window[2] = info.data_window[2];
+ exr_header->data_window[3] = info.data_window[3];
+ exr_header->line_order = info.line_order;
+ exr_header->compression_type = info.compression_type;
+
+ exr_header->tile_size_x = info.tile_size_x;
+ exr_header->tile_size_y = info.tile_size_y;
+ exr_header->tile_level_mode = info.tile_level_mode;
+ exr_header->tile_rounding_mode = info.tile_rounding_mode;
+
+ exr_header->num_channels = static_cast<int>(info.channels.size());
+
+ exr_header->channels = static_cast<EXRChannelInfo *>(malloc(
+ sizeof(EXRChannelInfo) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ strncpy(exr_header->channels[c].name, info.channels[c].name.c_str(), 255);
+ // manually add '\0' for safety.
+ exr_header->channels[c].name[255] = '\0';
+
+ exr_header->channels[c].pixel_type = info.channels[c].pixel_type;
+ exr_header->channels[c].p_linear = info.channels[c].p_linear;
+ exr_header->channels[c].x_sampling = info.channels[c].x_sampling;
+ exr_header->channels[c].y_sampling = info.channels[c].y_sampling;
+ }
+
+ exr_header->pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ exr_header->pixel_types[c] = info.channels[c].pixel_type;
+ }
+
+ // Initially fill with values of `pixel_types`
+ exr_header->requested_pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(exr_header->num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ exr_header->requested_pixel_types[c] = info.channels[c].pixel_type;
+ }
+
+ assert(info.attributes.size() < TINYEXR_MAX_ATTRIBUTES);
+ exr_header->num_custom_attributes = static_cast<int>(info.attributes.size());
+
+ for (size_t i = 0; i < info.attributes.size(); i++) {
+ memcpy(exr_header->custom_attributes[i].name, info.attributes[i].name, 256);
+ memcpy(exr_header->custom_attributes[i].type, info.attributes[i].type, 256);
+ exr_header->custom_attributes[i].size = info.attributes[i].size;
+ // Just copy poiner
+ exr_header->custom_attributes[i].value = info.attributes[i].value;
+ }
+
+ exr_header->header_len = info.header_len;
+}
+
+static int DecodeChunk(EXRImage *exr_image, const EXRHeader *exr_header,
+ const std::vector<tinyexr::tinyexr_uint64> &offsets,
+ const unsigned char *head) {
+ int num_channels = exr_header->num_channels;
+
+ int num_scanline_blocks = 1;
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanline_blocks = 32;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanline_blocks = 16;
+ }
+
+ int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1;
+ int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1;
+
+ size_t num_blocks = offsets.size();
+
+ std::vector<size_t> channel_offset_list;
+ int pixel_data_size = 0;
+ size_t channel_offset = 0;
+ tinyexr::ComputeChannelLayout(&channel_offset_list, &pixel_data_size,
+ &channel_offset, num_channels,
+ exr_header->channels);
+
+ if (exr_header->tiled) {
+ size_t num_tiles = offsets.size(); // = # of blocks
+
+ exr_image->tiles = static_cast<EXRTile *>(
+ malloc(sizeof(EXRTile) * static_cast<size_t>(num_tiles)));
+
+ for (size_t tile_idx = 0; tile_idx < num_tiles; tile_idx++) {
+ // Allocate memory for each tile.
+ exr_image->tiles[tile_idx].images = tinyexr::AllocateImage(
+ num_channels, exr_header->channels, exr_header->requested_pixel_types,
+ data_width, data_height);
+
+ // 16 byte: tile coordinates
+ // 4 byte : data size
+ // ~ : data(uncompressed or compressed)
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[tile_idx]);
+
+ int tile_coordinates[4];
+ memcpy(tile_coordinates, data_ptr, sizeof(int) * 4);
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[0]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[1]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[2]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&tile_coordinates[3]));
+
+ // @todo{ LoD }
+ assert(tile_coordinates[2] == 0);
+ assert(tile_coordinates[3] == 0);
+
+ int data_len;
+ memcpy(&data_len, data_ptr + 16,
+ sizeof(int)); // 16 = sizeof(tile_coordinates)
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+ assert(data_len >= 4);
+
+ // Move to data addr: 20 = 16 + 4;
+ data_ptr += 20;
+
+ tinyexr::DecodeTiledPixelData(
+ exr_image->tiles[tile_idx].images,
+ &(exr_image->tiles[tile_idx].width),
+ &(exr_image->tiles[tile_idx].height),
+ exr_header->requested_pixel_types, data_ptr,
+ static_cast<size_t>(data_len), exr_header->compression_type,
+ exr_header->line_order, data_width, data_height, tile_coordinates[0],
+ tile_coordinates[1], exr_header->tile_size_x, exr_header->tile_size_y,
+ static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels), exr_header->channels,
+ channel_offset_list);
+
+ exr_image->tiles[tile_idx].offset_x = tile_coordinates[0];
+ exr_image->tiles[tile_idx].offset_y = tile_coordinates[1];
+ exr_image->tiles[tile_idx].level_x = tile_coordinates[2];
+ exr_image->tiles[tile_idx].level_y = tile_coordinates[3];
+
+ exr_image->num_tiles = static_cast<int>(num_tiles);
+ }
+ } else { // scanline format
+
+ exr_image->images = tinyexr::AllocateImage(
+ num_channels, exr_header->channels, exr_header->requested_pixel_types,
+ data_width, data_height);
+
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+ for (int y = 0; y < static_cast<int>(num_blocks); y++) {
+ size_t y_idx = static_cast<size_t>(y);
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[y_idx]);
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(uncompressed or compressed)
+ int line_no;
+ memcpy(&line_no, data_ptr, sizeof(int));
+ int data_len;
+ memcpy(&data_len, data_ptr + 4, sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+
+ int end_line_no = (std::min)(line_no + num_scanline_blocks,
+ (exr_header->data_window[3] + 1));
+
+ int num_lines = end_line_no - line_no;
+ assert(num_lines > 0);
+
+ // Move to data addr: 8 = 4 + 4;
+ data_ptr += 8;
+
+ // Adjust line_no with data_window.bmin.y
+ line_no -= exr_header->data_window[1];
+
+ tinyexr::DecodePixelData(
+ exr_image->images, exr_header->requested_pixel_types, data_ptr,
+ static_cast<size_t>(data_len), exr_header->compression_type,
+ exr_header->line_order, data_width, data_height, data_width, y,
+ line_no, num_lines, static_cast<size_t>(pixel_data_size),
+ static_cast<size_t>(exr_header->num_custom_attributes),
+ exr_header->custom_attributes,
+ static_cast<size_t>(exr_header->num_channels), exr_header->channels,
+ channel_offset_list);
+ } // omp parallel
+ }
+
+ // Overwrite `pixel_type` with `requested_pixel_type`.
+ {
+ for (int c = 0; c < exr_header->num_channels; c++) {
+ exr_header->pixel_types[c] = exr_header->requested_pixel_types[c];
+ }
+ }
+
+ {
+ exr_image->num_channels = num_channels;
+
+ exr_image->width = data_width;
+ exr_image->height = data_height;
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+static bool ReconstructLineOffsets(
+ std::vector<tinyexr::tinyexr_uint64> *offsets, size_t n,
+ const unsigned char *head, const unsigned char *marker, const size_t size) {
+ assert(head < marker);
+ assert(offsets->size() == n);
+
+ for (size_t i = 0; i < n; i++) {
+ size_t offset = static_cast<size_t>(marker - head);
+ // Offset should not exceed whole EXR file/data size.
+ if (offset >= size) {
+ return false;
+ }
+
+ int y;
+ unsigned int data_len;
+
+ memcpy(&y, marker, sizeof(int));
+ memcpy(&data_len, marker + 4, sizeof(unsigned int));
+
+ if (data_len >= size) {
+ return false;
+ }
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data_len));
+
+ (*offsets)[i] = offset;
+
+ marker += data_len + 8; // 8 = 4 bytes(y) + 4 bytes(data_len)
+ }
+
+ return true;
+}
+
+static int DecodeEXRImage(EXRImage *exr_image, const EXRHeader *exr_header,
+ const unsigned char *head,
+ const unsigned char *marker, const size_t size,
+ const char **err) {
+ if (exr_image == NULL || exr_header == NULL || head == NULL ||
+ marker == NULL || (size <= tinyexr::kEXRVersionSize)) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ int num_scanline_blocks = 1;
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanline_blocks = 32;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanline_blocks = 16;
+ }
+
+ int data_width = exr_header->data_window[2] - exr_header->data_window[0] + 1;
+ int data_height = exr_header->data_window[3] - exr_header->data_window[1] + 1;
+
+ // Read offset tables.
+ size_t num_blocks;
+
+ if (exr_header->chunk_count > 0) {
+ // Use `chunkCount` attribute.
+ num_blocks = static_cast<size_t>(exr_header->chunk_count);
+ } else if (exr_header->tiled) {
+ // @todo { LoD }
+ size_t num_x_tiles = static_cast<size_t>(data_width) /
+ static_cast<size_t>(exr_header->tile_size_x);
+ if (num_x_tiles * static_cast<size_t>(exr_header->tile_size_x) <
+ static_cast<size_t>(data_width)) {
+ num_x_tiles++;
+ }
+ size_t num_y_tiles = static_cast<size_t>(data_height) /
+ static_cast<size_t>(exr_header->tile_size_y);
+ if (num_y_tiles * static_cast<size_t>(exr_header->tile_size_y) <
+ static_cast<size_t>(data_height)) {
+ num_y_tiles++;
+ }
+
+ num_blocks = num_x_tiles * num_y_tiles;
+ } else {
+ num_blocks = static_cast<size_t>(data_height) /
+ static_cast<size_t>(num_scanline_blocks);
+ if (num_blocks * static_cast<size_t>(num_scanline_blocks) <
+ static_cast<size_t>(data_height)) {
+ num_blocks++;
+ }
+ }
+
+ std::vector<tinyexr::tinyexr_uint64> offsets(num_blocks);
+
+ for (size_t y = 0; y < num_blocks; y++) {
+ tinyexr::tinyexr_uint64 offset;
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_uint64));
+ tinyexr::swap8(&offset);
+ if (offset >= size) {
+ if (err) {
+ (*err) = "Invalid offset value.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += sizeof(tinyexr::tinyexr_uint64); // = 8
+ offsets[y] = offset;
+ }
+
+ // If line offsets are invalid, we try to reconstruct it.
+ // See OpenEXR/IlmImf/ImfScanLineInputFile.cpp::readLineOffsets() for details.
+ for (size_t y = 0; y < num_blocks; y++) {
+ if (offsets[y] <= 0) {
+ // TODO(syoyo) Report as warning?
+ // if (err) {
+ // stringstream ss;
+ // ss << "Incomplete lineOffsets." << std::endl;
+ // (*err) += ss.str();
+ //}
+ bool ret =
+ ReconstructLineOffsets(&offsets, num_blocks, head, marker, size);
+ if (ret) {
+ // OK
+ break;
+ } else {
+ if (err) {
+ (*err) = "Cannot reconstruct lineOffset table.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+ }
+
+ return DecodeChunk(exr_image, exr_header, offsets, head);
+}
+
+} // namespace tinyexr
+
+int LoadEXR(float **out_rgba, int *width, int *height, const char *filename,
+ const char **err) {
+ if (out_rgba == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.\n";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+ InitEXRHeader(&exr_header);
+ InitEXRImage(&exr_image);
+
+ {
+ int ret = ParseEXRVersionFromFile(&exr_version, filename);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ if (exr_version.multipart || exr_version.non_image) {
+ if (err) {
+ (*err) = "Loading multipart or DeepImage is not supported yet.\n";
+ }
+ return TINYEXR_ERROR_INVALID_DATA; // @fixme.
+ }
+ }
+
+ {
+ int ret = ParseEXRHeaderFromFile(&exr_header, &exr_version, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+ }
+
+ // Read HALF channel as FLOAT.
+ for (int i = 0; i < exr_header.num_channels; i++) {
+ if (exr_header.pixel_types[i] == TINYEXR_PIXELTYPE_HALF) {
+ exr_header.requested_pixel_types[i] = TINYEXR_PIXELTYPE_FLOAT;
+ }
+ }
+
+ {
+ int ret = LoadEXRImageFromFile(&exr_image, &exr_header, filename, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ int idxA = -1;
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ if (strcmp(exr_header.channels[c].name, "R") == 0) {
+ idxR = c;
+ } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
+ idxG = c;
+ } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
+ idxB = c;
+ } else if (strcmp(exr_header.channels[c].name, "A") == 0) {
+ idxA = c;
+ }
+ }
+
+ if (idxR == -1) {
+ if (err) {
+ (*err) = "R channel not found\n";
+ }
+
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxG == -1) {
+ if (err) {
+ (*err) = "G channel not found\n";
+ }
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxB == -1) {
+ if (err) {
+ (*err) = "B channel not found\n";
+ }
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ (*out_rgba) = reinterpret_cast<float *>(
+ malloc(4 * sizeof(float) * static_cast<size_t>(exr_image.width) *
+ static_cast<size_t>(exr_image.height)));
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ (*out_rgba)[4 * i + 0] =
+ reinterpret_cast<float **>(exr_image.images)[idxR][i];
+ (*out_rgba)[4 * i + 1] =
+ reinterpret_cast<float **>(exr_image.images)[idxG][i];
+ (*out_rgba)[4 * i + 2] =
+ reinterpret_cast<float **>(exr_image.images)[idxB][i];
+ if (idxA != -1) {
+ (*out_rgba)[4 * i + 3] =
+ reinterpret_cast<float **>(exr_image.images)[idxA][i];
+ } else {
+ (*out_rgba)[4 * i + 3] = 1.0;
+ }
+ }
+
+ (*width) = exr_image.width;
+ (*height) = exr_image.height;
+
+ FreeEXRHeader(&exr_header);
+ FreeEXRImage(&exr_image);
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRHeaderFromMemory(EXRHeader *exr_header, const EXRVersion *version,
+ const unsigned char *memory, size_t size,
+ const char **err) {
+ if (memory == NULL || exr_header == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.\n";
+ }
+
+ // Invalid argument
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory + tinyexr::kEXRVersionSize;
+ size_t marker_size = size - tinyexr::kEXRVersionSize;
+
+ tinyexr::HeaderInfo info;
+ info.clear();
+
+ std::string err_str;
+ int ret = ParseEXRHeader(&info, NULL, version, &err_str, marker, marker_size);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err && !err_str.empty()) {
+ (*err) = strdup(err_str.c_str()); // May leak
+ }
+ }
+
+ ConvertHeader(exr_header, info);
+
+ // transfoer `tiled` from version.
+ exr_header->tiled = version->tiled;
+
+ return ret;
+}
+
+int LoadEXRFromMemory(float *out_rgba, const unsigned char *memory, size_t size,
+ const char **err) {
+ if (out_rgba == NULL || memory == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.\n";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ EXRVersion exr_version;
+ EXRImage exr_image;
+ EXRHeader exr_header;
+
+ InitEXRHeader(&exr_header);
+
+ int ret = ParseEXRVersionFromMemory(&exr_version, memory, size);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ ret = ParseEXRHeaderFromMemory(&exr_header, &exr_version, memory, size, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ InitEXRImage(&exr_image);
+ ret = LoadEXRImageFromMemory(&exr_image, &exr_header, memory, size, err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ // RGBA
+ int idxR = -1;
+ int idxG = -1;
+ int idxB = -1;
+ int idxA = -1;
+ for (int c = 0; c < exr_header.num_channels; c++) {
+ if (strcmp(exr_header.channels[c].name, "R") == 0) {
+ idxR = c;
+ } else if (strcmp(exr_header.channels[c].name, "G") == 0) {
+ idxG = c;
+ } else if (strcmp(exr_header.channels[c].name, "B") == 0) {
+ idxB = c;
+ } else if (strcmp(exr_header.channels[c].name, "A") == 0) {
+ idxA = c;
+ }
+ }
+
+ if (idxR == -1) {
+ if (err) {
+ (*err) = "R channel not found\n";
+ }
+
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxG == -1) {
+ if (err) {
+ (*err) = "G channel not found\n";
+ }
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ if (idxB == -1) {
+ if (err) {
+ (*err) = "B channel not found\n";
+ }
+ // @todo { free exr_image }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ // Assume `out_rgba` have enough memory allocated.
+ for (int i = 0; i < exr_image.width * exr_image.height; i++) {
+ out_rgba[4 * i + 0] = reinterpret_cast<float **>(exr_image.images)[idxR][i];
+ out_rgba[4 * i + 1] = reinterpret_cast<float **>(exr_image.images)[idxG][i];
+ out_rgba[4 * i + 2] = reinterpret_cast<float **>(exr_image.images)[idxB][i];
+ if (idxA > 0) {
+ out_rgba[4 * i + 3] =
+ reinterpret_cast<float **>(exr_image.images)[idxA][i];
+ } else {
+ out_rgba[4 * i + 3] = 1.0;
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadEXRImageFromFile(EXRImage *exr_image, const EXRHeader *exr_header,
+ const char *filename, const char **err) {
+ if (exr_image == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "rb");
+#else
+ FILE *fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot read file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+ (void)ret;
+ }
+
+ return LoadEXRImageFromMemory(exr_image, exr_header, &buf.at(0), filesize,
+ err);
+}
+
+int LoadEXRImageFromMemory(EXRImage *exr_image, const EXRHeader *exr_header,
+ const unsigned char *memory, const size_t size,
+ const char **err) {
+ if (exr_image == NULL || memory == NULL ||
+ (size < tinyexr::kEXRVersionSize)) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (exr_header->header_len == 0) {
+ if (err) {
+ (*err) = "EXRHeader is not initialized.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ const unsigned char *head = memory;
+ const unsigned char *marker = reinterpret_cast<const unsigned char *>(
+ memory + exr_header->header_len +
+ 8); // +8 for magic number + version header.
+ return tinyexr::DecodeEXRImage(exr_image, exr_header, head, marker, size,
+ err);
+}
+
+size_t SaveEXRImageToMemory(const EXRImage *exr_image,
+ const EXRHeader *exr_header,
+ unsigned char **memory_out, const char **err) {
+ if (exr_image == NULL || memory_out == NULL ||
+ exr_header->compression_type < 0) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return 0; // @fixme
+ }
+
+#if !TINYEXR_USE_PIZ
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ if (err) {
+ (*err) = "PIZ compression is not supported in this build.";
+ }
+ return 0;
+ }
+#endif
+
+#if !TINYEXR_USE_ZFP
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ if (err) {
+ (*err) = "ZFP compression is not supported in this build.";
+ }
+ return 0;
+ }
+#endif
+
+#if TINYEXR_USE_ZFP
+ for (size_t i = 0; i < static_cast<size_t>(exr_header->num_channels); i++) {
+ if (exr_header->requested_pixel_types[i] != TINYEXR_PIXELTYPE_FLOAT) {
+ if (err) {
+ (*err) = "Pixel type must be FLOAT for ZFP compression.";
+ }
+ return 0;
+ }
+ }
+#endif
+
+ std::vector<unsigned char> memory;
+
+ // Header
+ {
+ const char header[] = {0x76, 0x2f, 0x31, 0x01};
+ memory.insert(memory.end(), header, header + 4);
+ }
+
+ // Version, scanline.
+ {
+ char marker[] = {2, 0, 0, 0};
+ /* @todo
+ if (exr_header->tiled) {
+ marker[1] |= 0x2;
+ }
+ if (exr_header->long_name) {
+ marker[1] |= 0x4;
+ }
+ if (exr_header->non_image) {
+ marker[1] |= 0x8;
+ }
+ if (exr_header->multipart) {
+ marker[1] |= 0x10;
+ }
+ */
+ memory.insert(memory.end(), marker, marker + 4);
+ }
+
+ int num_scanlines = 1;
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanlines = 16;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ num_scanlines = 32;
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ num_scanlines = 16;
+ }
+
+ // Write attributes.
+ std::vector<tinyexr::ChannelInfo> channels;
+ {
+ std::vector<unsigned char> data;
+
+ for (int c = 0; c < exr_header->num_channels; c++) {
+ tinyexr::ChannelInfo info;
+ info.p_linear = 0;
+ info.pixel_type = exr_header->requested_pixel_types[c];
+ info.x_sampling = 1;
+ info.y_sampling = 1;
+ info.name = std::string(exr_header->channels[c].name);
+ channels.push_back(info);
+ }
+
+ tinyexr::WriteChannelInfo(data, channels);
+
+ tinyexr::WriteAttributeToMemory(&memory, "channels", "chlist", &data.at(0),
+ static_cast<int>(data.size()));
+ }
+
+ {
+ int comp = exr_header->compression_type;
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&comp));
+ tinyexr::WriteAttributeToMemory(
+ &memory, "compression", "compression",
+ reinterpret_cast<const unsigned char *>(&comp), 1);
+ }
+
+ {
+ int data[4] = {0, 0, exr_image->width - 1, exr_image->height - 1};
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[0]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[1]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[2]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&data[3]));
+ tinyexr::WriteAttributeToMemory(
+ &memory, "dataWindow", "box2i",
+ reinterpret_cast<const unsigned char *>(data), sizeof(int) * 4);
+ tinyexr::WriteAttributeToMemory(
+ &memory, "displayWindow", "box2i",
+ reinterpret_cast<const unsigned char *>(data), sizeof(int) * 4);
+ }
+
+ {
+ unsigned char line_order = 0; // @fixme { read line_order from EXRHeader }
+ tinyexr::WriteAttributeToMemory(&memory, "lineOrder", "lineOrder",
+ &line_order, 1);
+ }
+
+ {
+ float aspectRatio = 1.0f;
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&aspectRatio));
+ tinyexr::WriteAttributeToMemory(
+ &memory, "pixelAspectRatio", "float",
+ reinterpret_cast<const unsigned char *>(&aspectRatio), sizeof(float));
+ }
+
+ {
+ float center[2] = {0.0f, 0.0f};
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[0]));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&center[1]));
+ tinyexr::WriteAttributeToMemory(
+ &memory, "screenWindowCenter", "v2f",
+ reinterpret_cast<const unsigned char *>(center), 2 * sizeof(float));
+ }
+
+ {
+ float w = static_cast<float>(exr_image->width);
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
+ tinyexr::WriteAttributeToMemory(&memory, "screenWindowWidth", "float",
+ reinterpret_cast<const unsigned char *>(&w),
+ sizeof(float));
+ }
+
+ // Custom attributes
+ if (exr_header->num_custom_attributes > 0) {
+ for (int i = 0; i < exr_header->num_custom_attributes; i++) {
+ tinyexr::WriteAttributeToMemory(
+ &memory, exr_header->custom_attributes[i].name,
+ exr_header->custom_attributes[i].type,
+ reinterpret_cast<const unsigned char *>(
+ exr_header->custom_attributes[i].value),
+ exr_header->custom_attributes[i].size);
+ }
+ }
+
+ { // end of header
+ unsigned char e = 0;
+ memory.push_back(e);
+ }
+
+ int num_blocks = exr_image->height / num_scanlines;
+ if (num_blocks * num_scanlines < exr_image->height) {
+ num_blocks++;
+ }
+
+ std::vector<tinyexr::tinyexr_uint64> offsets(static_cast<size_t>(num_blocks));
+
+ size_t headerSize = memory.size();
+ tinyexr::tinyexr_uint64 offset =
+ headerSize +
+ static_cast<size_t>(num_blocks) *
+ sizeof(
+ tinyexr::tinyexr_int64); // sizeof(header) + sizeof(offsetTable)
+
+ std::vector<unsigned char> data;
+
+ std::vector<std::vector<unsigned char> > data_list(
+ static_cast<size_t>(num_blocks));
+ std::vector<size_t> channel_offset_list(
+ static_cast<size_t>(exr_header->num_channels));
+
+ int pixel_data_size = 0;
+ size_t channel_offset = 0;
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ channel_offset_list[c] = channel_offset;
+ if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ pixel_data_size += sizeof(unsigned short);
+ channel_offset += sizeof(unsigned short);
+ } else if (exr_header->requested_pixel_types[c] ==
+ TINYEXR_PIXELTYPE_FLOAT) {
+ pixel_data_size += sizeof(float);
+ channel_offset += sizeof(float);
+ } else if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_UINT) {
+ pixel_data_size += sizeof(unsigned int);
+ channel_offset += sizeof(unsigned int);
+ } else {
+ assert(0);
+ }
+ }
+
+#if TINYEXR_USE_ZFP
+ tinyexr::ZFPCompressionParam zfp_compression_param;
+
+ // Use ZFP compression parameter from custom attributes(if such a parameter
+ // exists)
+ {
+ bool ret = tinyexr::FindZFPCompressionParam(
+ &zfp_compression_param, exr_header->custom_attributes,
+ exr_header->num_custom_attributes);
+
+ if (!ret) {
+ // Use predefined compression parameter.
+ zfp_compression_param.type = 0;
+ zfp_compression_param.rate = 2;
+ }
+ }
+#endif
+
+// Use signed int since some OpenMP compiler doesn't allow unsigned type for
+// `parallel for`
+#ifdef _OPENMP
+#pragma omp parallel for
+#endif
+ for (int i = 0; i < num_blocks; i++) {
+ size_t ii = static_cast<size_t>(i);
+ int start_y = num_scanlines * i;
+ int endY = (std::min)(num_scanlines * (i + 1), exr_image->height);
+ int h = endY - start_y;
+
+ std::vector<unsigned char> buf(
+ static_cast<size_t>(exr_image->width * h * pixel_data_size));
+
+ for (size_t c = 0; c < static_cast<size_t>(exr_header->num_channels); c++) {
+ if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < exr_image->width; x++) {
+ tinyexr::FP16 h16;
+ h16.u = reinterpret_cast<unsigned short **>(
+ exr_image->images)[c][(y + start_y) * exr_image->width + x];
+
+ tinyexr::FP32 f32 = half_to_float(h16);
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&f32.f));
+
+ // Assume increasing Y
+ float *line_ptr = reinterpret_cast<float *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * exr_image->width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(exr_image->width)));
+ line_ptr[x] = f32.f;
+ }
+ }
+ } else if (exr_header->requested_pixel_types[c] ==
+ TINYEXR_PIXELTYPE_HALF) {
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < exr_image->width; x++) {
+ unsigned short val = reinterpret_cast<unsigned short **>(
+ exr_image->images)[c][(y + start_y) * exr_image->width + x];
+
+ tinyexr::swap2(&val);
+
+ // Assume increasing Y
+ unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &buf.at(static_cast<size_t>(pixel_data_size * y *
+ exr_image->width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(exr_image->width)));
+ line_ptr[x] = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+
+ } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_FLOAT) {
+ if (exr_header->requested_pixel_types[c] == TINYEXR_PIXELTYPE_HALF) {
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < exr_image->width; x++) {
+ tinyexr::FP32 f32;
+ f32.f = reinterpret_cast<float **>(
+ exr_image->images)[c][(y + start_y) * exr_image->width + x];
+
+ tinyexr::FP16 h16;
+ h16 = float_to_half_full(f32);
+
+ tinyexr::swap2(reinterpret_cast<unsigned short *>(&h16.u));
+
+ // Assume increasing Y
+ unsigned short *line_ptr = reinterpret_cast<unsigned short *>(
+ &buf.at(static_cast<size_t>(pixel_data_size * y *
+ exr_image->width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(exr_image->width)));
+ line_ptr[x] = h16.u;
+ }
+ }
+ } else if (exr_header->requested_pixel_types[c] ==
+ TINYEXR_PIXELTYPE_FLOAT) {
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < exr_image->width; x++) {
+ float val = reinterpret_cast<float **>(
+ exr_image->images)[c][(y + start_y) * exr_image->width + x];
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&val));
+
+ // Assume increasing Y
+ float *line_ptr = reinterpret_cast<float *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * exr_image->width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(exr_image->width)));
+ line_ptr[x] = val;
+ }
+ }
+ } else {
+ assert(0);
+ }
+ } else if (exr_header->pixel_types[c] == TINYEXR_PIXELTYPE_UINT) {
+ for (int y = 0; y < h; y++) {
+ for (int x = 0; x < exr_image->width; x++) {
+ unsigned int val = reinterpret_cast<unsigned int **>(
+ exr_image->images)[c][(y + start_y) * exr_image->width + x];
+
+ tinyexr::swap4(&val);
+
+ // Assume increasing Y
+ unsigned int *line_ptr = reinterpret_cast<unsigned int *>(&buf.at(
+ static_cast<size_t>(pixel_data_size * y * exr_image->width) +
+ channel_offset_list[c] *
+ static_cast<size_t>(exr_image->width)));
+ line_ptr[x] = val;
+ }
+ }
+ }
+ }
+
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_NONE) {
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(uncompressed)
+ std::vector<unsigned char> header(8);
+ unsigned int data_len = static_cast<unsigned int>(buf.size());
+ memcpy(&header.at(0), &start_y, sizeof(int));
+ memcpy(&header.at(4), &data_len, sizeof(unsigned int));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(0)));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(4)));
+
+ data_list[ii].insert(data_list[ii].end(), header.begin(), header.end());
+ data_list[ii].insert(data_list[ii].end(), buf.begin(),
+ buf.begin() + data_len);
+
+ } else if ((exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) {
+#if TINYEXR_USE_MINIZ
+ std::vector<unsigned char> block(tinyexr::miniz::mz_compressBound(
+ static_cast<unsigned long>(buf.size())));
+#else
+ std::vector<unsigned char> block(
+ compressBound(static_cast<uLong>(buf.size())));
+#endif
+ tinyexr::tinyexr_uint64 outSize = block.size();
+
+ tinyexr::CompressZip(&block.at(0), outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ static_cast<unsigned long>(buf.size()));
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ std::vector<unsigned char> header(8);
+ unsigned int data_len = static_cast<unsigned int>(outSize); // truncate
+ memcpy(&header.at(0), &start_y, sizeof(int));
+ memcpy(&header.at(4), &data_len, sizeof(unsigned int));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(0)));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(4)));
+
+ data_list[ii].insert(data_list[ii].end(), header.begin(), header.end());
+ data_list[ii].insert(data_list[ii].end(), block.begin(),
+ block.begin() + data_len);
+
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_RLE) {
+ // (buf.size() * 3) / 2 would be enough.
+ std::vector<unsigned char> block((buf.size() * 3) / 2);
+
+ tinyexr::tinyexr_uint64 outSize = block.size();
+
+ tinyexr::CompressRle(&block.at(0), outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ static_cast<unsigned long>(buf.size()));
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ std::vector<unsigned char> header(8);
+ unsigned int data_len = static_cast<unsigned int>(outSize); // truncate
+ memcpy(&header.at(0), &start_y, sizeof(int));
+ memcpy(&header.at(4), &data_len, sizeof(unsigned int));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(0)));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(4)));
+
+ data_list[ii].insert(data_list[ii].end(), header.begin(), header.end());
+ data_list[ii].insert(data_list[ii].end(), block.begin(),
+ block.begin() + data_len);
+
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+#if TINYEXR_USE_PIZ
+ unsigned int bufLen =
+ 1024 + static_cast<unsigned int>(
+ 1.2 * static_cast<unsigned int>(
+ buf.size())); // @fixme { compute good bound. }
+ std::vector<unsigned char> block(bufLen);
+ unsigned int outSize = static_cast<unsigned int>(block.size());
+
+ CompressPiz(&block.at(0), outSize,
+ reinterpret_cast<const unsigned char *>(&buf.at(0)),
+ buf.size(), channels, exr_image->width, h);
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ std::vector<unsigned char> header(8);
+ unsigned int data_len = outSize;
+ memcpy(&header.at(0), &start_y, sizeof(int));
+ memcpy(&header.at(4), &data_len, sizeof(unsigned int));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(0)));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(4)));
+
+ data_list[ii].insert(data_list[ii].end(), header.begin(), header.end());
+ data_list[ii].insert(data_list[ii].end(), block.begin(),
+ block.begin() + data_len);
+
+#else
+ assert(0);
+#endif
+ } else if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+#if TINYEXR_USE_ZFP
+ std::vector<unsigned char> block;
+ unsigned int outSize;
+
+ tinyexr::CompressZfp(
+ &block, &outSize, reinterpret_cast<const float *>(&buf.at(0)),
+ exr_image->width, h, exr_header->num_channels, zfp_compression_param);
+
+ // 4 byte: scan line
+ // 4 byte: data size
+ // ~ : pixel data(compressed)
+ std::vector<unsigned char> header(8);
+ unsigned int data_len = outSize;
+ memcpy(&header.at(0), &start_y, sizeof(int));
+ memcpy(&header.at(4), &data_len, sizeof(unsigned int));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(0)));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&header.at(4)));
+
+ data_list[ii].insert(data_list[ii].end(), header.begin(), header.end());
+ data_list[ii].insert(data_list[ii].end(), block.begin(),
+ block.begin() + data_len);
+
+#else
+ assert(0);
+#endif
+ } else {
+ assert(0);
+ }
+ } // omp parallel
+
+ for (size_t i = 0; i < static_cast<size_t>(num_blocks); i++) {
+ data.insert(data.end(), data_list[i].begin(), data_list[i].end());
+
+ offsets[i] = offset;
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offsets[i]));
+ offset += data_list[i].size();
+ }
+
+ {
+ memory.insert(
+ memory.end(), reinterpret_cast<unsigned char *>(&offsets.at(0)),
+ reinterpret_cast<unsigned char *>(&offsets.at(0)) +
+ sizeof(tinyexr::tinyexr_uint64) * static_cast<size_t>(num_blocks));
+ }
+
+ { memory.insert(memory.end(), data.begin(), data.end()); }
+
+ assert(memory.size() > 0);
+
+ (*memory_out) = static_cast<unsigned char *>(malloc(memory.size()));
+ memcpy((*memory_out), &memory.at(0), memory.size());
+
+ return memory.size(); // OK
+}
+
+int SaveEXRImageToFile(const EXRImage *exr_image, const EXRHeader *exr_header,
+ const char *filename, const char **err) {
+ if (exr_image == NULL || filename == NULL ||
+ exr_header->compression_type < 0) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+#if !TINYEXR_USE_PIZ
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_PIZ) {
+ if (err) {
+ (*err) = "PIZ compression is not supported in this build.";
+ }
+ return 0;
+ }
+#endif
+
+#if !TINYEXR_USE_ZFP
+ if (exr_header->compression_type == TINYEXR_COMPRESSIONTYPE_ZFP) {
+ if (err) {
+ (*err) = "ZFP compression is not supported in this build.";
+ }
+ return 0;
+ }
+#endif
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "wb");
+#else
+ FILE *fp = fopen(filename, "wb");
+#endif
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot write a file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ unsigned char *mem = NULL;
+ size_t mem_size = SaveEXRImageToMemory(exr_image, exr_header, &mem, err);
+
+ if ((mem_size > 0) && mem) {
+ fwrite(mem, 1, mem_size, fp);
+ }
+ free(mem);
+
+ fclose(fp);
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadDeepEXR(DeepImage *deep_image, const char *filename, const char **err) {
+ if (deep_image == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ FILE *fp = fopen(filename, "rb");
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot read file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ if (filesize == 0) {
+ fclose(fp);
+ if (err) {
+ (*err) = "File size is zero.";
+ }
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ std::vector<char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ (void)ret;
+ }
+ fclose(fp);
+
+ const char *head = &buf[0];
+ const char *marker = &buf[0];
+
+ // Header check.
+ {
+ const char header[] = {0x76, 0x2f, 0x31, 0x01};
+
+ if (memcmp(marker, header, 4) != 0) {
+ if (err) {
+ (*err) = "Invalid magic number.";
+ }
+ return TINYEXR_ERROR_INVALID_MAGIC_NUMBER;
+ }
+ marker += 4;
+ }
+
+ // Version, scanline.
+ {
+ // ver 2.0, scanline, deep bit on(0x800)
+ // must be [2, 0, 0, 0]
+ if (marker[0] != 2 || marker[1] != 8 || marker[2] != 0 || marker[3] != 0) {
+ if (err) {
+ (*err) = "Unsupported version or scanline.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ marker += 4;
+ }
+
+ int dx = -1;
+ int dy = -1;
+ int dw = -1;
+ int dh = -1;
+ int num_scanline_blocks = 1; // 16 for ZIP compression.
+ int compression_type = -1;
+ int num_channels = -1;
+ std::vector<tinyexr::ChannelInfo> channels;
+
+ // Read attributes
+ size_t size = filesize - tinyexr::kEXRVersionSize;
+ for (;;) {
+ if (0 == size) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ } else if (marker[0] == '\0') {
+ size--;
+ break;
+ }
+
+ std::string attr_name;
+ std::string attr_type;
+ std::vector<unsigned char> data;
+ size_t marker_size;
+ if (!tinyexr::ReadAttribute(&attr_name, &attr_type, &data, &marker_size,
+ marker, size)) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ marker += marker_size;
+ size -= marker_size;
+
+ if (attr_name.compare("compression") == 0) {
+ compression_type = data[0];
+ if (compression_type > TINYEXR_COMPRESSIONTYPE_PIZ) {
+ if (err) {
+ (*err) = "Unsupported compression type.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ if (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) {
+ num_scanline_blocks = 16;
+ }
+
+ } else if (attr_name.compare("channels") == 0) {
+ // name: zero-terminated string, from 1 to 255 bytes long
+ // pixel type: int, possible values are: UINT = 0 HALF = 1 FLOAT = 2
+ // pLinear: unsigned char, possible values are 0 and 1
+ // reserved: three chars, should be zero
+ // xSampling: int
+ // ySampling: int
+
+ tinyexr::ReadChannelInfo(channels, data);
+
+ num_channels = static_cast<int>(channels.size());
+
+ if (num_channels < 1) {
+ if (err) {
+ (*err) = "Invalid channels format.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ } else if (attr_name.compare("dataWindow") == 0) {
+ memcpy(&dx, &data.at(0), sizeof(int));
+ memcpy(&dy, &data.at(4), sizeof(int));
+ memcpy(&dw, &data.at(8), sizeof(int));
+ memcpy(&dh, &data.at(12), sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&dx));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&dy));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&dw));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&dh));
+
+ } else if (attr_name.compare("displayWindow") == 0) {
+ int x;
+ int y;
+ int w;
+ int h;
+ memcpy(&x, &data.at(0), sizeof(int));
+ memcpy(&y, &data.at(4), sizeof(int));
+ memcpy(&w, &data.at(8), sizeof(int));
+ memcpy(&h, &data.at(12), sizeof(int));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&x));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&y));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&w));
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&h));
+ }
+ }
+
+ assert(dx >= 0);
+ assert(dy >= 0);
+ assert(dw >= 0);
+ assert(dh >= 0);
+ assert(num_channels >= 1);
+
+ int data_width = dw - dx + 1;
+ int data_height = dh - dy + 1;
+
+ std::vector<float> image(
+ static_cast<size_t>(data_width * data_height * 4)); // 4 = RGBA
+
+ // Read offset tables.
+ int num_blocks = data_height / num_scanline_blocks;
+ if (num_blocks * num_scanline_blocks < data_height) {
+ num_blocks++;
+ }
+
+ std::vector<tinyexr::tinyexr_int64> offsets(static_cast<size_t>(num_blocks));
+
+ for (size_t y = 0; y < static_cast<size_t>(num_blocks); y++) {
+ tinyexr::tinyexr_int64 offset;
+ memcpy(&offset, marker, sizeof(tinyexr::tinyexr_int64));
+ tinyexr::swap8(reinterpret_cast<tinyexr::tinyexr_uint64 *>(&offset));
+ marker += sizeof(tinyexr::tinyexr_int64); // = 8
+ offsets[y] = offset;
+ }
+
+#if TINYEXR_USE_PIZ
+ if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_PIZ)) {
+#else
+ if ((compression_type == TINYEXR_COMPRESSIONTYPE_NONE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_RLE) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIPS) ||
+ (compression_type == TINYEXR_COMPRESSIONTYPE_ZIP)) {
+#endif
+ // OK
+ } else {
+ if (err) {
+ (*err) = "Unsupported format.";
+ }
+ return TINYEXR_ERROR_UNSUPPORTED_FORMAT;
+ }
+
+ deep_image->image = static_cast<float ***>(
+ malloc(sizeof(float **) * static_cast<size_t>(num_channels)));
+ for (int c = 0; c < num_channels; c++) {
+ deep_image->image[c] = static_cast<float **>(
+ malloc(sizeof(float *) * static_cast<size_t>(data_height)));
+ for (int y = 0; y < data_height; y++) {
+ }
+ }
+
+ deep_image->offset_table = static_cast<int **>(
+ malloc(sizeof(int *) * static_cast<size_t>(data_height)));
+ for (int y = 0; y < data_height; y++) {
+ deep_image->offset_table[y] = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(data_width)));
+ }
+
+ for (size_t y = 0; y < static_cast<size_t>(num_blocks); y++) {
+ const unsigned char *data_ptr =
+ reinterpret_cast<const unsigned char *>(head + offsets[y]);
+
+ // int: y coordinate
+ // int64: packed size of pixel offset table
+ // int64: packed size of sample data
+ // int64: unpacked size of sample data
+ // compressed pixel offset table
+ // compressed sample data
+ int line_no;
+ tinyexr::tinyexr_int64 packedOffsetTableSize;
+ tinyexr::tinyexr_int64 packedSampleDataSize;
+ tinyexr::tinyexr_int64 unpackedSampleDataSize;
+ memcpy(&line_no, data_ptr, sizeof(int));
+ memcpy(&packedOffsetTableSize, data_ptr + 4,
+ sizeof(tinyexr::tinyexr_int64));
+ memcpy(&packedSampleDataSize, data_ptr + 12,
+ sizeof(tinyexr::tinyexr_int64));
+ memcpy(&unpackedSampleDataSize, data_ptr + 20,
+ sizeof(tinyexr::tinyexr_int64));
+
+ tinyexr::swap4(reinterpret_cast<unsigned int *>(&line_no));
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedOffsetTableSize));
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&packedSampleDataSize));
+ tinyexr::swap8(
+ reinterpret_cast<tinyexr::tinyexr_uint64 *>(&unpackedSampleDataSize));
+
+ std::vector<int> pixelOffsetTable(static_cast<size_t>(data_width));
+
+ // decode pixel offset table.
+ {
+ unsigned long dstLen =
+ static_cast<unsigned long>(pixelOffsetTable.size() * sizeof(int));
+ tinyexr::DecompressZip(
+ reinterpret_cast<unsigned char *>(&pixelOffsetTable.at(0)), &dstLen,
+ data_ptr + 28, static_cast<unsigned long>(packedOffsetTableSize));
+
+ assert(dstLen == pixelOffsetTable.size() * sizeof(int));
+ for (size_t i = 0; i < static_cast<size_t>(data_width); i++) {
+ deep_image->offset_table[y][i] = pixelOffsetTable[i];
+ }
+ }
+
+ std::vector<unsigned char> sample_data(
+ static_cast<size_t>(unpackedSampleDataSize));
+
+ // decode sample data.
+ {
+ unsigned long dstLen = static_cast<unsigned long>(unpackedSampleDataSize);
+ tinyexr::DecompressZip(
+ reinterpret_cast<unsigned char *>(&sample_data.at(0)), &dstLen,
+ data_ptr + 28 + packedOffsetTableSize,
+ static_cast<unsigned long>(packedSampleDataSize));
+ assert(dstLen == static_cast<unsigned long>(unpackedSampleDataSize));
+ }
+
+ // decode sample
+ int sampleSize = -1;
+ std::vector<int> channel_offset_list(static_cast<size_t>(num_channels));
+ {
+ int channel_offset = 0;
+ for (size_t i = 0; i < static_cast<size_t>(num_channels); i++) {
+ channel_offset_list[i] = channel_offset;
+ if (channels[i].pixel_type == TINYEXR_PIXELTYPE_UINT) { // UINT
+ channel_offset += 4;
+ } else if (channels[i].pixel_type == TINYEXR_PIXELTYPE_HALF) { // half
+ channel_offset += 2;
+ } else if (channels[i].pixel_type ==
+ TINYEXR_PIXELTYPE_FLOAT) { // float
+ channel_offset += 4;
+ } else {
+ assert(0);
+ }
+ }
+ sampleSize = channel_offset;
+ }
+ assert(sampleSize >= 2);
+
+ assert(static_cast<size_t>(
+ pixelOffsetTable[static_cast<size_t>(data_width - 1)] *
+ sampleSize) == sample_data.size());
+ int samples_per_line = static_cast<int>(sample_data.size()) / sampleSize;
+
+ //
+ // Alloc memory
+ //
+
+ //
+ // pixel data is stored as image[channels][pixel_samples]
+ //
+ {
+ tinyexr::tinyexr_uint64 data_offset = 0;
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+ deep_image->image[c][y] = static_cast<float *>(
+ malloc(sizeof(float) * static_cast<size_t>(samples_per_line)));
+
+ if (channels[c].pixel_type == 0) { // UINT
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ unsigned int ui = *reinterpret_cast<unsigned int *>(
+ &sample_data.at(data_offset + x * sizeof(int)));
+ deep_image->image[c][y][x] = static_cast<float>(ui); // @fixme
+ }
+ data_offset +=
+ sizeof(unsigned int) * static_cast<size_t>(samples_per_line);
+ } else if (channels[c].pixel_type == 1) { // half
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ tinyexr::FP16 f16;
+ f16.u = *reinterpret_cast<unsigned short *>(
+ &sample_data.at(data_offset + x * sizeof(short)));
+ tinyexr::FP32 f32 = half_to_float(f16);
+ deep_image->image[c][y][x] = f32.f;
+ }
+ data_offset += sizeof(short) * static_cast<size_t>(samples_per_line);
+ } else { // float
+ for (size_t x = 0; x < static_cast<size_t>(samples_per_line); x++) {
+ float f = *reinterpret_cast<float *>(
+ &sample_data.at(data_offset + x * sizeof(float)));
+ deep_image->image[c][y][x] = f;
+ }
+ data_offset += sizeof(float) * static_cast<size_t>(samples_per_line);
+ }
+ }
+ }
+ } // y
+
+ deep_image->width = data_width;
+ deep_image->height = data_height;
+
+ deep_image->channel_names = static_cast<const char **>(
+ malloc(sizeof(const char *) * static_cast<size_t>(num_channels)));
+ for (size_t c = 0; c < static_cast<size_t>(num_channels); c++) {
+#ifdef _WIN32
+ deep_image->channel_names[c] = _strdup(channels[c].name.c_str());
+#else
+ deep_image->channel_names[c] = strdup(channels[c].name.c_str());
+#endif
+ }
+ deep_image->num_channels = num_channels;
+
+ return TINYEXR_SUCCESS;
+}
+
+void InitEXRImage(EXRImage *exr_image) {
+ if (exr_image == NULL) {
+ return;
+ }
+
+ exr_image->width = 0;
+ exr_image->height = 0;
+ exr_image->num_channels = 0;
+
+ exr_image->images = NULL;
+ exr_image->tiles = NULL;
+
+ exr_image->num_tiles = 0;
+}
+
+void InitEXRHeader(EXRHeader *exr_header) {
+ if (exr_header == NULL) {
+ return;
+ }
+
+ memset(exr_header, 0, sizeof(EXRHeader));
+}
+
+int FreeEXRHeader(EXRHeader *exr_header) {
+ if (exr_header == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (exr_header->channels) {
+ free(exr_header->channels);
+ }
+
+ if (exr_header->pixel_types) {
+ free(exr_header->pixel_types);
+ }
+
+ if (exr_header->requested_pixel_types) {
+ free(exr_header->requested_pixel_types);
+ }
+
+ for (int i = 0; i < exr_header->num_custom_attributes; i++) {
+ if (exr_header->custom_attributes[i].value) {
+ free(exr_header->custom_attributes[i].value);
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int FreeEXRImage(EXRImage *exr_image) {
+ if (exr_image == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ for (int i = 0; i < exr_image->num_channels; i++) {
+ if (exr_image->images && exr_image->images[i]) {
+ free(exr_image->images[i]);
+ }
+ }
+
+ if (exr_image->images) {
+ free(exr_image->images);
+ }
+
+ if (exr_image->tiles) {
+ for (int tid = 0; tid < exr_image->num_tiles; tid++) {
+ for (int i = 0; i < exr_image->num_channels; i++) {
+ if (exr_image->tiles[tid].images && exr_image->tiles[tid].images[i]) {
+ free(exr_image->tiles[tid].images[i]);
+ }
+ }
+ if (exr_image->tiles[tid].images) {
+ free(exr_image->tiles[tid].images);
+ }
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRHeaderFromFile(EXRHeader *exr_header, const EXRVersion *exr_version,
+ const char *filename, const char **err) {
+ if (exr_header == NULL || exr_version == NULL || filename == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "rb");
+#else
+ FILE *fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot read file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+
+ if (ret != filesize) {
+ if (err) {
+ (*err) = "fread error.";
+ }
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+ }
+
+ return ParseEXRHeaderFromMemory(exr_header, exr_version, &buf.at(0), filesize,
+ err);
+}
+
+int ParseEXRMultipartHeaderFromMemory(EXRHeader ***exr_headers,
+ int *num_headers,
+ const EXRVersion *exr_version,
+ const unsigned char *memory, size_t size,
+ const char **err) {
+ if (memory == NULL || exr_headers == NULL || num_headers == NULL ||
+ exr_version == NULL) {
+ // Invalid argument
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory + tinyexr::kEXRVersionSize;
+ size_t marker_size = size - tinyexr::kEXRVersionSize;
+
+ std::vector<tinyexr::HeaderInfo> infos;
+
+ for (;;) {
+ tinyexr::HeaderInfo info;
+ info.clear();
+
+ std::string err_str;
+ bool empty_header = false;
+ int ret = ParseEXRHeader(&info, &empty_header, exr_version, &err_str,
+ marker, marker_size);
+
+ if (ret != TINYEXR_SUCCESS) {
+ if (err) {
+ (*err) = strdup(err_str.c_str()); // may leak
+ }
+ return ret;
+ }
+
+ if (empty_header) {
+ marker += 1; // skip '\0'
+ break;
+ }
+
+ // `chunkCount` must exist in the header.
+ if (info.chunk_count == 0) {
+ if (err) {
+ (*err) = "`chunkCount' attribute is not found in the header.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ infos.push_back(info);
+
+ // move to next header.
+ marker += info.header_len;
+ size -= info.header_len;
+ }
+
+ // allocate memory for EXRHeader and create array of EXRHeader pointers.
+ (*exr_headers) =
+ static_cast<EXRHeader **>(malloc(sizeof(EXRHeader *) * infos.size()));
+ for (size_t i = 0; i < infos.size(); i++) {
+ EXRHeader *exr_header = static_cast<EXRHeader *>(malloc(sizeof(EXRHeader)));
+
+ ConvertHeader(exr_header, infos[i]);
+
+ // transfoer `tiled` from version.
+ exr_header->tiled = exr_version->tiled;
+
+ (*exr_headers)[i] = exr_header;
+ }
+
+ (*num_headers) = static_cast<int>(infos.size());
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRMultipartHeaderFromFile(EXRHeader ***exr_headers, int *num_headers,
+ const EXRVersion *exr_version,
+ const char *filename, const char **err) {
+ if (exr_headers == NULL || num_headers == NULL || exr_version == NULL ||
+ filename == NULL) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "rb");
+#else
+ FILE *fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot read file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+
+ if (ret != filesize) {
+ if (err) {
+ (*err) = "fread error.";
+ }
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+ }
+
+ return ParseEXRMultipartHeaderFromMemory(
+ exr_headers, num_headers, exr_version, &buf.at(0), filesize, err);
+}
+
+int ParseEXRVersionFromMemory(EXRVersion *version, const unsigned char *memory,
+ size_t size) {
+ if (version == NULL || memory == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ if (size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ const unsigned char *marker = memory;
+
+ // Header check.
+ {
+ const char header[] = {0x76, 0x2f, 0x31, 0x01};
+
+ if (memcmp(marker, header, 4) != 0) {
+ return TINYEXR_ERROR_INVALID_MAGIC_NUMBER;
+ }
+ marker += 4;
+ }
+
+ version->tiled = false;
+ version->long_name = false;
+ version->non_image = false;
+ version->multipart = false;
+
+ // Parse version header.
+ {
+ // must be 2
+ if (marker[0] != 2) {
+ return TINYEXR_ERROR_INVALID_EXR_VERSION;
+ }
+
+ if (version == NULL) {
+ return TINYEXR_SUCCESS; // May OK
+ }
+
+ version->version = 2;
+
+ if (marker[1] & 0x2) { // 9th bit
+ version->tiled = true;
+ }
+ if (marker[1] & 0x4) { // 10th bit
+ version->long_name = true;
+ }
+ if (marker[1] & 0x8) { // 11th bit
+ version->non_image = true; // (deep image)
+ }
+ if (marker[1] & 0x10) { // 12th bit
+ version->multipart = true;
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int ParseEXRVersionFromFile(EXRVersion *version, const char *filename) {
+ if (filename == NULL) {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "rb");
+#else
+ FILE *fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t file_size;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ file_size = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ if (file_size < tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ unsigned char buf[tinyexr::kEXRVersionSize];
+ size_t ret = fread(&buf[0], 1, tinyexr::kEXRVersionSize, fp);
+ fclose(fp);
+
+ if (ret != tinyexr::kEXRVersionSize) {
+ return TINYEXR_ERROR_INVALID_FILE;
+ }
+
+ return ParseEXRVersionFromMemory(version, buf, tinyexr::kEXRVersionSize);
+}
+
+int LoadEXRMultipartImageFromMemory(EXRImage *exr_images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts,
+ const unsigned char *memory,
+ const size_t size, const char **err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts == 0 ||
+ memory == NULL || (size <= tinyexr::kEXRVersionSize)) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ // compute total header size.
+ size_t total_header_size = 0;
+ for (unsigned int i = 0; i < num_parts; i++) {
+ if (exr_headers[i]->header_len == 0) {
+ if (err) {
+ (*err) = "EXRHeader is not initialized.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ total_header_size += exr_headers[i]->header_len;
+ }
+
+ const char *marker = reinterpret_cast<const char *>(
+ memory + total_header_size + 4 +
+ 4); // +8 for magic number and version header.
+
+ marker += 1; // Skip empty header.
+
+ // NOTE 1:
+ // In multipart image, There is 'part number' before chunk data.
+ // 4 byte : part number
+ // 4+ : chunk
+ //
+ // NOTE 2:
+ // EXR spec says 'part number' is 'unsigned long' but actually this is
+ // 'unsigned int(4 bytes)' in OpenEXR implementation...
+ // http://www.openexr.com/openexrfilelayout.pdf
+
+ // Load chunk offset table.
+ std::vector<std::vector<tinyexr::tinyexr_uint64> > chunk_offset_table_list;
+ for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
+ std::vector<tinyexr::tinyexr_uint64> offset_table(
+ static_cast<size_t>(exr_headers[i]->chunk_count));
+
+ for (size_t c = 0; c < offset_table.size(); c++) {
+ tinyexr::tinyexr_uint64 offset;
+ memcpy(&offset, marker, 8);
+ tinyexr::swap8(&offset);
+
+ if (offset >= size) {
+ if (err) {
+ (*err) = "Invalid offset size.";
+ }
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+
+ offset_table[c] = offset + 4; // +4 to skip 'part number'
+ marker += 8;
+ }
+
+ chunk_offset_table_list.push_back(offset_table);
+ }
+
+ // Decode image.
+ for (size_t i = 0; i < static_cast<size_t>(num_parts); i++) {
+ std::vector<tinyexr::tinyexr_uint64> &offset_table =
+ chunk_offset_table_list[i];
+
+ // First check 'part number' is identitical to 'i'
+ for (size_t c = 0; c < offset_table.size(); c++) {
+ const unsigned char *part_number_addr =
+ memory + offset_table[c] - 4; // -4 to move to 'part number' field.
+ unsigned int part_no;
+ memcpy(&part_no, part_number_addr, sizeof(unsigned int)); // 4
+ tinyexr::swap4(&part_no);
+
+ if (part_no != i) {
+ assert(0);
+ return TINYEXR_ERROR_INVALID_DATA;
+ }
+ }
+
+ int ret = tinyexr::DecodeChunk(&exr_images[i], exr_headers[i], offset_table,
+ memory);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+ }
+
+ return TINYEXR_SUCCESS;
+}
+
+int LoadEXRMultipartImageFromFile(EXRImage *exr_images,
+ const EXRHeader **exr_headers,
+ unsigned int num_parts, const char *filename,
+ const char **err) {
+ if (exr_images == NULL || exr_headers == NULL || num_parts == 0) {
+ if (err) {
+ (*err) = "Invalid argument.";
+ }
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+// -- GODOT change for old MinGW on Travis CI --
+//#ifdef _WIN32
+#if defined(_MSC_VER) || (defined(__MINGW32__) && __MINGW64_VERSION_MAJOR >= 3)
+// -- GODOT end --
+ FILE *fp = NULL;
+ fopen_s(&fp, filename, "rb");
+#else
+ FILE *fp = fopen(filename, "rb");
+#endif
+ if (!fp) {
+ if (err) {
+ (*err) = "Cannot read file.";
+ }
+ return TINYEXR_ERROR_CANT_OPEN_FILE;
+ }
+
+ size_t filesize;
+ // Compute size
+ fseek(fp, 0, SEEK_END);
+ filesize = static_cast<size_t>(ftell(fp));
+ fseek(fp, 0, SEEK_SET);
+
+ std::vector<unsigned char> buf(filesize); // @todo { use mmap }
+ {
+ size_t ret;
+ ret = fread(&buf[0], 1, filesize, fp);
+ assert(ret == filesize);
+ fclose(fp);
+ (void)ret;
+ }
+
+ return LoadEXRMultipartImageFromMemory(exr_images, exr_headers, num_parts,
+ &buf.at(0), filesize, err);
+}
+
+int SaveEXR(const float *data, int width, int height, int components,
+ const char *outfilename) {
+ if (components == 3 || components == 4) {
+ // OK
+ } else {
+ return TINYEXR_ERROR_INVALID_ARGUMENT;
+ }
+
+ // Assume at least 16x16 pixels.
+ if (width < 16) return TINYEXR_ERROR_INVALID_ARGUMENT;
+ if (height < 16) return TINYEXR_ERROR_INVALID_ARGUMENT;
+
+ EXRHeader header;
+ InitEXRHeader(&header);
+
+ EXRImage image;
+ InitEXRImage(&image);
+
+ image.num_channels = components;
+
+ std::vector<float> images[4];
+ images[0].resize(static_cast<size_t>(width * height));
+ images[1].resize(static_cast<size_t>(width * height));
+ images[2].resize(static_cast<size_t>(width * height));
+ images[3].resize(static_cast<size_t>(width * height));
+
+ // Split RGB(A)RGB(A)RGB(A)... into R, G and B(and A) layers
+ for (size_t i = 0; i < static_cast<size_t>(width * height); i++) {
+ images[0][i] = data[static_cast<size_t>(components) * i + 0];
+ images[1][i] = data[static_cast<size_t>(components) * i + 1];
+ images[2][i] = data[static_cast<size_t>(components) * i + 2];
+ if (components == 4) {
+ images[3][i] = data[static_cast<size_t>(components) * i + 3];
+ }
+ }
+
+ float *image_ptr[4] = {0, 0, 0, 0};
+ if (components == 4) {
+ image_ptr[0] = &(images[3].at(0)); // A
+ image_ptr[1] = &(images[2].at(0)); // B
+ image_ptr[2] = &(images[1].at(0)); // G
+ image_ptr[3] = &(images[0].at(0)); // R
+ } else {
+ image_ptr[0] = &(images[2].at(0)); // B
+ image_ptr[1] = &(images[1].at(0)); // G
+ image_ptr[2] = &(images[0].at(0)); // R
+ }
+
+ image.images = reinterpret_cast<unsigned char **>(image_ptr);
+ image.width = width;
+ image.height = height;
+
+ header.num_channels = components;
+ header.channels = static_cast<EXRChannelInfo *>(malloc(
+ sizeof(EXRChannelInfo) * static_cast<size_t>(header.num_channels)));
+ // Must be (A)BGR order, since most of EXR viewers expect this channel order.
+ if (components == 4) {
+ strncpy(header.channels[0].name, "A", 255);
+ header.channels[0].name[strlen("A")] = '\0';
+ strncpy(header.channels[1].name, "B", 255);
+ header.channels[1].name[strlen("B")] = '\0';
+ strncpy(header.channels[2].name, "G", 255);
+ header.channels[2].name[strlen("G")] = '\0';
+ strncpy(header.channels[3].name, "R", 255);
+ header.channels[3].name[strlen("R")] = '\0';
+ } else {
+ strncpy(header.channels[0].name, "B", 255);
+ header.channels[0].name[strlen("B")] = '\0';
+ strncpy(header.channels[1].name, "G", 255);
+ header.channels[1].name[strlen("G")] = '\0';
+ strncpy(header.channels[2].name, "R", 255);
+ header.channels[2].name[strlen("R")] = '\0';
+ }
+
+ header.pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ header.requested_pixel_types = static_cast<int *>(
+ malloc(sizeof(int) * static_cast<size_t>(header.num_channels)));
+ for (int i = 0; i < header.num_channels; i++) {
+ header.pixel_types[i] =
+ TINYEXR_PIXELTYPE_FLOAT; // pixel type of input image
+ header.requested_pixel_types[i] =
+ TINYEXR_PIXELTYPE_HALF; // pixel type of output image to be stored in
+ // .EXR
+ }
+
+ const char *err;
+ int ret = SaveEXRImageToFile(&image, &header, outfilename, &err);
+ if (ret != TINYEXR_SUCCESS) {
+ return ret;
+ }
+
+ free(header.channels);
+ free(header.pixel_types);
+ free(header.requested_pixel_types);
+
+ return ret;
+}
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif // TINYEXR_IMPLEMENTATION_DEIFNED
+#endif // TINYEXR_IMPLEMENTATION
diff --git a/thirdparty/zstd/LICENSE b/thirdparty/zstd/LICENSE
new file mode 100644
index 0000000000..a793a80289
--- /dev/null
+++ b/thirdparty/zstd/LICENSE
@@ -0,0 +1,30 @@
+BSD License
+
+For Zstandard software
+
+Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+ * Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution.
+
+ * Neither the name Facebook nor the names of its contributors may be used to
+ endorse or promote products derived from this software without specific
+ prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/thirdparty/zstd/PATENTS b/thirdparty/zstd/PATENTS
new file mode 100644
index 0000000000..15b4a2ea5c
--- /dev/null
+++ b/thirdparty/zstd/PATENTS
@@ -0,0 +1,33 @@
+Additional Grant of Patent Rights Version 2
+
+"Software" means the Zstandard software distributed by Facebook, Inc.
+
+Facebook, Inc. ("Facebook") hereby grants to each recipient of the Software
+("you") a perpetual, worldwide, royalty-free, non-exclusive, irrevocable
+(subject to the termination provision below) license under any Necessary
+Claims, to make, have made, use, sell, offer to sell, import, and otherwise
+transfer the Software. For avoidance of doubt, no license is granted under
+Facebook’s rights in any patent claims that are infringed by (i) modifications
+to the Software made by you or any third party or (ii) the Software in
+combination with any software or other technology.
+
+The license granted hereunder will terminate, automatically and without notice,
+if you (or any of your subsidiaries, corporate affiliates or agents) initiate
+directly or indirectly, or take a direct financial interest in, any Patent
+Assertion: (i) against Facebook or any of its subsidiaries or corporate
+affiliates, (ii) against any party if such Patent Assertion arises in whole or
+in part from any software, technology, product or service of Facebook or any of
+its subsidiaries or corporate affiliates, or (iii) against any party relating
+to the Software. Notwithstanding the foregoing, if Facebook or any of its
+subsidiaries or corporate affiliates files a lawsuit alleging patent
+infringement against you in the first instance, and you respond by filing a
+patent infringement counterclaim in that lawsuit against that party that is
+unrelated to the Software, the license granted hereunder will not terminate
+under section (i) of this paragraph due to such counterclaim.
+
+A "Necessary Claim" is a claim of a patent owned by Facebook that is
+necessarily infringed by the Software standing alone.
+
+A "Patent Assertion" is any lawsuit or other action alleging direct, indirect,
+or contributory infringement or inducement to infringe any patent, including a
+cross-claim or counterclaim.
diff --git a/thirdparty/zstd/README.md b/thirdparty/zstd/README.md
new file mode 100644
index 0000000000..7caee5fd3f
--- /dev/null
+++ b/thirdparty/zstd/README.md
@@ -0,0 +1,146 @@
+ __Zstandard__, or `zstd` as short version, is a fast lossless compression algorithm,
+ targeting real-time compression scenarios at zlib-level and better compression ratios.
+
+It is provided as an open-source BSD-licensed **C** library,
+and a command line utility producing and decoding `.zst` and `.gz` files.
+For other programming languages,
+you can consult a list of known ports on [Zstandard homepage](http://www.zstd.net/#other-languages).
+
+|Branch |Status |
+|------------|---------|
+|master | [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=master)](https://travis-ci.org/facebook/zstd) |
+|dev | [![Build Status](https://travis-ci.org/facebook/zstd.svg?branch=dev)](https://travis-ci.org/facebook/zstd) |
+
+As a reference, several fast compression algorithms were tested and compared
+on a server running Linux Debian (`Linux version 4.8.0-1-amd64`),
+with a Core i7-6700K CPU @ 4.0GHz,
+using [lzbench], an open-source in-memory benchmark by @inikep
+compiled with GCC 6.3.0,
+on the [Silesia compression corpus].
+
+[lzbench]: https://github.com/inikep/lzbench
+[Silesia compression corpus]: http://sun.aei.polsl.pl/~sdeor/index.php?page=silesia
+
+| Compressor name | Ratio | Compression| Decompress.|
+| --------------- | ------| -----------| ---------- |
+| **zstd 1.1.3 -1** | 2.877 | 430 MB/s | 1110 MB/s |
+| zlib 1.2.8 -1 | 2.743 | 110 MB/s | 400 MB/s |
+| brotli 0.5.2 -0 | 2.708 | 400 MB/s | 430 MB/s |
+| quicklz 1.5.0 -1 | 2.238 | 550 MB/s | 710 MB/s |
+| lzo1x 2.09 -1 | 2.108 | 650 MB/s | 830 MB/s |
+| lz4 1.7.5 | 2.101 | 720 MB/s | 3600 MB/s |
+| snappy 1.1.3 | 2.091 | 500 MB/s | 1650 MB/s |
+| lzf 3.6 -1 | 2.077 | 400 MB/s | 860 MB/s |
+
+[zlib]:http://www.zlib.net/
+[LZ4]: http://www.lz4.org/
+
+Zstd can also offer stronger compression ratios at the cost of compression speed.
+Speed vs Compression trade-off is configurable by small increments. Decompression speed is preserved and remains roughly the same at all settings, a property shared by most LZ compression algorithms, such as [zlib] or lzma.
+
+The following tests were run
+on a server running Linux Debian (`Linux version 4.8.0-1-amd64`)
+with a Core i7-6700K CPU @ 4.0GHz,
+using [lzbench], an open-source in-memory benchmark by @inikep
+compiled with GCC 6.3.0,
+on the [Silesia compression corpus].
+
+Compression Speed vs Ratio | Decompression Speed
+---------------------------|--------------------
+![Compression Speed vs Ratio](doc/images/Cspeed4.png "Compression Speed vs Ratio") | ![Decompression Speed](doc/images/Dspeed4.png "Decompression Speed")
+
+Several algorithms can produce higher compression ratios, but at slower speeds, falling outside of the graph.
+For a larger picture including very slow modes, [click on this link](doc/images/DCspeed5.png) .
+
+
+### The case for Small Data compression
+
+Previous charts provide results applicable to typical file and stream scenarios (several MB). Small data comes with different perspectives.
+
+The smaller the amount of data to compress, the more difficult it is to compress. This problem is common to all compression algorithms, and reason is, compression algorithms learn from past data how to compress future data. But at the beginning of a new data set, there is no "past" to build upon.
+
+To solve this situation, Zstd offers a __training mode__, which can be used to tune the algorithm for a selected type of data.
+Training Zstandard is achieved by provide it with a few samples (one file per sample). The result of this training is stored in a file called "dictionary", which must be loaded before compression and decompression.
+Using this dictionary, the compression ratio achievable on small data improves dramatically.
+
+The following example uses the `github-users` [sample set](https://github.com/facebook/zstd/releases/tag/v1.1.3), created from [github public API](https://developer.github.com/v3/users/#get-all-users).
+It consists of roughly 10K records weighting about 1KB each.
+
+Compression Ratio | Compression Speed | Decompression Speed
+------------------|-------------------|--------------------
+![Compression Ratio](doc/images/dict-cr.png "Compression Ratio") | ![Compression Speed](doc/images/dict-cs.png "Compression Speed") | ![Decompression Speed](doc/images/dict-ds.png "Decompression Speed")
+
+
+These compression gains are achieved while simultaneously providing _faster_ compression and decompression speeds.
+
+Training works if there is some correlation in a family of small data samples. The more data-specific a dictionary is, the more efficient it is (there is no _universal dictionary_).
+Hence, deploying one dictionary per type of data will provide the greatest benefits.
+Dictionary gains are mostly effective in the first few KB. Then, the compression algorithm will gradually use previously decoded content to better compress the rest of the file.
+
+#### Dictionary compression How To :
+
+1) Create the dictionary
+
+`zstd --train FullPathToTrainingSet/* -o dictionaryName`
+
+2) Compress with dictionary
+
+`zstd -D dictionaryName FILE`
+
+3) Decompress with dictionary
+
+`zstd -D dictionaryName --decompress FILE.zst`
+
+
+### Build
+
+Once you have the repository cloned, there are multiple ways provided to build Zstandard.
+
+#### Makefile
+
+If your system is compatible with a standard `make` (or `gmake`) binary generator,
+you can simply run it at the root directory.
+It will generate `zstd` within root directory.
+
+Other available options include :
+- `make install` : create and install zstd binary, library and man page
+- `make test` : create and run `zstd` and test tools on local platform
+
+#### cmake
+
+A `cmake` project generator is provided within `build/cmake`.
+It can generate Makefiles or other build scripts
+to create `zstd` binary, and `libzstd` dynamic and static libraries.
+
+#### Meson
+
+A Meson project is provided within `contrib/meson`.
+
+#### Visual Studio (Windows)
+
+Going into `build` directory, you will find additional possibilities :
+- Projects for Visual Studio 2005, 2008 and 2010
+ + VS2010 project is compatible with VS2012, VS2013 and VS2015
+- Automated build scripts for Visual compiler by @KrzysFR , in `build/VS_scripts`,
+ which will build `zstd` cli and `libzstd` library without any need to open Visual Studio solution.
+
+
+### Status
+
+Zstandard is currently deployed within Facebook. It is used daily to compress and decompress very large amounts of data in multiple formats and use cases.
+Zstandard is considered safe for production environments.
+
+### License
+
+Zstandard is [BSD-licensed](LICENSE). We also provide an [additional patent grant](PATENTS).
+
+### Contributing
+
+The "dev" branch is the one where all contributions will be merged before reaching "master".
+If you plan to propose a patch, please commit into the "dev" branch or its own feature branch.
+Direct commit to "master" are not permitted.
+For more information, please read [CONTRIBUTING](CONTRIBUTING.md).
+
+### Miscellaneous
+
+Zstd entropy stage is provided by [Huff0 and FSE, from Finite State Entropy library](https://github.com/Cyan4973/FiniteStateEntropy).
diff --git a/thirdparty/zstd/common/bitstream.h b/thirdparty/zstd/common/bitstream.h
new file mode 100644
index 0000000000..ca42850df3
--- /dev/null
+++ b/thirdparty/zstd/common/bitstream.h
@@ -0,0 +1,446 @@
+/* ******************************************************************
+ bitstream
+ Part of FSE library
+ header file (to include)
+ Copyright (C) 2013-2017, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+****************************************************************** */
+#ifndef BITSTREAM_H_MODULE
+#define BITSTREAM_H_MODULE
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/*
+* This API consists of small unitary functions, which must be inlined for best performance.
+* Since link-time-optimization is not available for all compilers,
+* these functions are defined into a .h to be included.
+*/
+
+/*-****************************************
+* Dependencies
+******************************************/
+#include "mem.h" /* unaligned access routines */
+#include "error_private.h" /* error codes and messages */
+
+
+/*-*************************************
+* Debug
+***************************************/
+#if defined(BIT_DEBUG) && (BIT_DEBUG>=1)
+# include <assert.h>
+#else
+# define assert(condition) ((void)0)
+#endif
+
+
+/*=========================================
+* Target specific
+=========================================*/
+#if defined(__BMI__) && defined(__GNUC__)
+# include <immintrin.h> /* support for bextr (experimental) */
+#endif
+
+#define STREAM_ACCUMULATOR_MIN_32 25
+#define STREAM_ACCUMULATOR_MIN_64 57
+#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
+
+/*-******************************************
+* bitStream encoding API (write forward)
+********************************************/
+/* bitStream can mix input from multiple sources.
+* A critical property of these streams is that they encode and decode in **reverse** direction.
+* So the first bit sequence you add will be the last to be read, like a LIFO stack.
+*/
+typedef struct
+{
+ size_t bitContainer;
+ unsigned bitPos;
+ char* startPtr;
+ char* ptr;
+ char* endPtr;
+} BIT_CStream_t;
+
+MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
+MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
+MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
+MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
+
+/* Start with initCStream, providing the size of buffer to write into.
+* bitStream will never write outside of this buffer.
+* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
+*
+* bits are first added to a local register.
+* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
+* Writing data into memory is an explicit operation, performed by the flushBits function.
+* Hence keep track how many bits are potentially stored into local register to avoid register overflow.
+* After a flushBits, a maximum of 7 bits might still be stored into local register.
+*
+* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
+*
+* Last operation is to close the bitStream.
+* The function returns the final size of CStream in bytes.
+* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
+*/
+
+
+/*-********************************************
+* bitStream decoding API (read backward)
+**********************************************/
+typedef struct
+{
+ size_t bitContainer;
+ unsigned bitsConsumed;
+ const char* ptr;
+ const char* start;
+ const char* limitPtr;
+} BIT_DStream_t;
+
+typedef enum { BIT_DStream_unfinished = 0,
+ BIT_DStream_endOfBuffer = 1,
+ BIT_DStream_completed = 2,
+ BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */
+ /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
+
+MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
+MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
+MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
+MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
+
+
+/* Start by invoking BIT_initDStream().
+* A chunk of the bitStream is then stored into a local register.
+* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
+* You can then retrieve bitFields stored into the local register, **in reverse order**.
+* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
+* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
+* Otherwise, it can be less than that, so proceed accordingly.
+* Checking if DStream has reached its end can be performed with BIT_endOfDStream().
+*/
+
+
+/*-****************************************
+* unsafe API
+******************************************/
+MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
+/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
+
+MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
+/* unsafe version; does not check buffer overflow */
+
+MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
+/* faster, but works only if nbBits >= 1 */
+
+
+
+/*-**************************************************************
+* Internal functions
+****************************************************************/
+MEM_STATIC unsigned BIT_highbit32 (register U32 val)
+{
+# if defined(_MSC_VER) /* Visual */
+ unsigned long r=0;
+ _BitScanReverse ( &r, val );
+ return (unsigned) r;
+# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
+ return 31 - __builtin_clz (val);
+# else /* Software version */
+ static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
+ 11, 14, 16, 18, 22, 25, 3, 30,
+ 8, 12, 20, 28, 15, 17, 24, 7,
+ 19, 27, 23, 6, 26, 5, 4, 31 };
+ U32 v = val;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
+# endif
+}
+
+/*===== Local Constants =====*/
+static const unsigned BIT_mask[] = { 0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F,
+ 0xFF, 0x1FF, 0x3FF, 0x7FF, 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF,
+ 0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
+ 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF }; /* up to 26 bits */
+
+
+/*-**************************************************************
+* bitStream encoding
+****************************************************************/
+/*! BIT_initCStream() :
+ * `dstCapacity` must be > sizeof(size_t)
+ * @return : 0 if success,
+ otherwise an error code (can be tested using ERR_isError() ) */
+MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
+ void* startPtr, size_t dstCapacity)
+{
+ bitC->bitContainer = 0;
+ bitC->bitPos = 0;
+ bitC->startPtr = (char*)startPtr;
+ bitC->ptr = bitC->startPtr;
+ bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
+ if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
+ return 0;
+}
+
+/*! BIT_addBits() :
+ can add up to 26 bits into `bitC`.
+ Does not check for register overflow ! */
+MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
+ size_t value, unsigned nbBits)
+{
+ bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
+ bitC->bitPos += nbBits;
+}
+
+/*! BIT_addBitsFast() :
+ * works only if `value` is _clean_, meaning all high bits above nbBits are 0 */
+MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
+ size_t value, unsigned nbBits)
+{
+ assert((value>>nbBits) == 0);
+ bitC->bitContainer |= value << bitC->bitPos;
+ bitC->bitPos += nbBits;
+}
+
+/*! BIT_flushBitsFast() :
+ * assumption : bitContainer has not overflowed
+ * unsafe version; does not check buffer overflow */
+MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
+{
+ size_t const nbBytes = bitC->bitPos >> 3;
+ assert( bitC->bitPos <= (sizeof(bitC->bitContainer)*8) );
+ MEM_writeLEST(bitC->ptr, bitC->bitContainer);
+ bitC->ptr += nbBytes;
+ assert(bitC->ptr <= bitC->endPtr);
+ bitC->bitPos &= 7;
+ bitC->bitContainer >>= nbBytes*8;
+}
+
+/*! BIT_flushBits() :
+ * assumption : bitContainer has not overflowed
+ * safe version; check for buffer overflow, and prevents it.
+ * note : does not signal buffer overflow.
+ * overflow will be revealed later on using BIT_closeCStream() */
+MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
+{
+ size_t const nbBytes = bitC->bitPos >> 3;
+ assert( bitC->bitPos <= (sizeof(bitC->bitContainer)*8) );
+ MEM_writeLEST(bitC->ptr, bitC->bitContainer);
+ bitC->ptr += nbBytes;
+ if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
+ bitC->bitPos &= 7;
+ bitC->bitContainer >>= nbBytes*8;
+}
+
+/*! BIT_closeCStream() :
+ * @return : size of CStream, in bytes,
+ or 0 if it could not fit into dstBuffer */
+MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
+{
+ BIT_addBitsFast(bitC, 1, 1); /* endMark */
+ BIT_flushBits(bitC);
+ if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
+ return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
+}
+
+
+/*-********************************************************
+* bitStream decoding
+**********************************************************/
+/*! BIT_initDStream() :
+* Initialize a BIT_DStream_t.
+* `bitD` : a pointer to an already allocated BIT_DStream_t structure.
+* `srcSize` must be the *exact* size of the bitStream, in bytes.
+* @return : size of stream (== srcSize) or an errorCode if a problem is detected
+*/
+MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
+{
+ if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
+
+ bitD->start = (const char*)srcBuffer;
+ bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
+
+ if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
+ bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
+ { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
+ bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
+ if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
+ } else {
+ bitD->ptr = bitD->start;
+ bitD->bitContainer = *(const BYTE*)(bitD->start);
+ switch(srcSize)
+ {
+ case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
+ case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
+ case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
+ case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
+ case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
+ case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
+ default:;
+ }
+ { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
+ bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
+ if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
+ bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
+ }
+
+ return srcSize;
+}
+
+MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
+{
+ return bitContainer >> start;
+}
+
+MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
+{
+#if defined(__BMI__) && defined(__GNUC__) && __GNUC__*1000+__GNUC_MINOR__ >= 4008 /* experimental */
+# if defined(__x86_64__)
+ if (sizeof(bitContainer)==8)
+ return _bextr_u64(bitContainer, start, nbBits);
+ else
+# endif
+ return _bextr_u32(bitContainer, start, nbBits);
+#else
+ return (bitContainer >> start) & BIT_mask[nbBits];
+#endif
+}
+
+MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
+{
+ return bitContainer & BIT_mask[nbBits];
+}
+
+/*! BIT_lookBits() :
+ * Provides next n bits from local register.
+ * local register is not modified.
+ * On 32-bits, maxNbBits==24.
+ * On 64-bits, maxNbBits==56.
+ * @return : value extracted
+ */
+ MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
+{
+#if defined(__BMI__) && defined(__GNUC__) /* experimental; fails if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8 */
+ return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
+#else
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
+ return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
+#endif
+}
+
+/*! BIT_lookBitsFast() :
+ * unsafe version; only works if nbBits >= 1 */
+MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
+{
+ U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
+ assert(nbBits >= 1);
+ return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
+}
+
+MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
+{
+ bitD->bitsConsumed += nbBits;
+}
+
+/*! BIT_readBits() :
+ * Read (consume) next n bits from local register and update.
+ * Pay attention to not read more than nbBits contained into local register.
+ * @return : extracted value.
+ */
+MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, U32 nbBits)
+{
+ size_t const value = BIT_lookBits(bitD, nbBits);
+ BIT_skipBits(bitD, nbBits);
+ return value;
+}
+
+/*! BIT_readBitsFast() :
+* unsafe version; only works only if nbBits >= 1 */
+MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, U32 nbBits)
+{
+ size_t const value = BIT_lookBitsFast(bitD, nbBits);
+ assert(nbBits >= 1);
+ BIT_skipBits(bitD, nbBits);
+ return value;
+}
+
+/*! BIT_reloadDStream() :
+* Refill `bitD` from buffer previously set in BIT_initDStream() .
+* This function is safe, it guarantees it will not read beyond src buffer.
+* @return : status of `BIT_DStream_t` internal register.
+ if status == BIT_DStream_unfinished, internal register is filled with >= (sizeof(bitD->bitContainer)*8 - 7) bits */
+MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
+{
+ if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
+ return BIT_DStream_overflow;
+
+ if (bitD->ptr >= bitD->limitPtr) {
+ bitD->ptr -= bitD->bitsConsumed >> 3;
+ bitD->bitsConsumed &= 7;
+ bitD->bitContainer = MEM_readLEST(bitD->ptr);
+ return BIT_DStream_unfinished;
+ }
+ if (bitD->ptr == bitD->start) {
+ if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
+ return BIT_DStream_completed;
+ }
+ /* start < ptr < limitPtr */
+ { U32 nbBytes = bitD->bitsConsumed >> 3;
+ BIT_DStream_status result = BIT_DStream_unfinished;
+ if (bitD->ptr - nbBytes < bitD->start) {
+ nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
+ result = BIT_DStream_endOfBuffer;
+ }
+ bitD->ptr -= nbBytes;
+ bitD->bitsConsumed -= nbBytes*8;
+ bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
+ return result;
+ }
+}
+
+/*! BIT_endOfDStream() :
+* @return Tells if DStream has exactly reached its end (all bits consumed).
+*/
+MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
+{
+ return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* BITSTREAM_H_MODULE */
diff --git a/thirdparty/zstd/common/entropy_common.c b/thirdparty/zstd/common/entropy_common.c
new file mode 100644
index 0000000000..b37a082fee
--- /dev/null
+++ b/thirdparty/zstd/common/entropy_common.c
@@ -0,0 +1,221 @@
+/*
+ Common functions of New Generation Entropy library
+ Copyright (C) 2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
+*************************************************************************** */
+
+/* *************************************
+* Dependencies
+***************************************/
+#include "mem.h"
+#include "error_private.h" /* ERR_*, ERROR */
+#define FSE_STATIC_LINKING_ONLY /* FSE_MIN_TABLELOG */
+#include "fse.h"
+#define HUF_STATIC_LINKING_ONLY /* HUF_TABLELOG_ABSOLUTEMAX */
+#include "huf.h"
+
+
+/*=== Version ===*/
+unsigned FSE_versionNumber(void) { return FSE_VERSION_NUMBER; }
+
+
+/*=== Error Management ===*/
+unsigned FSE_isError(size_t code) { return ERR_isError(code); }
+const char* FSE_getErrorName(size_t code) { return ERR_getErrorName(code); }
+
+unsigned HUF_isError(size_t code) { return ERR_isError(code); }
+const char* HUF_getErrorName(size_t code) { return ERR_getErrorName(code); }
+
+
+/*-**************************************************************
+* FSE NCount encoding-decoding
+****************************************************************/
+size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSVPtr, unsigned* tableLogPtr,
+ const void* headerBuffer, size_t hbSize)
+{
+ const BYTE* const istart = (const BYTE*) headerBuffer;
+ const BYTE* const iend = istart + hbSize;
+ const BYTE* ip = istart;
+ int nbBits;
+ int remaining;
+ int threshold;
+ U32 bitStream;
+ int bitCount;
+ unsigned charnum = 0;
+ int previous0 = 0;
+
+ if (hbSize < 4) return ERROR(srcSize_wrong);
+ bitStream = MEM_readLE32(ip);
+ nbBits = (bitStream & 0xF) + FSE_MIN_TABLELOG; /* extract tableLog */
+ if (nbBits > FSE_TABLELOG_ABSOLUTE_MAX) return ERROR(tableLog_tooLarge);
+ bitStream >>= 4;
+ bitCount = 4;
+ *tableLogPtr = nbBits;
+ remaining = (1<<nbBits)+1;
+ threshold = 1<<nbBits;
+ nbBits++;
+
+ while ((remaining>1) & (charnum<=*maxSVPtr)) {
+ if (previous0) {
+ unsigned n0 = charnum;
+ while ((bitStream & 0xFFFF) == 0xFFFF) {
+ n0 += 24;
+ if (ip < iend-5) {
+ ip += 2;
+ bitStream = MEM_readLE32(ip) >> bitCount;
+ } else {
+ bitStream >>= 16;
+ bitCount += 16;
+ } }
+ while ((bitStream & 3) == 3) {
+ n0 += 3;
+ bitStream >>= 2;
+ bitCount += 2;
+ }
+ n0 += bitStream & 3;
+ bitCount += 2;
+ if (n0 > *maxSVPtr) return ERROR(maxSymbolValue_tooSmall);
+ while (charnum < n0) normalizedCounter[charnum++] = 0;
+ if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
+ ip += bitCount>>3;
+ bitCount &= 7;
+ bitStream = MEM_readLE32(ip) >> bitCount;
+ } else {
+ bitStream >>= 2;
+ } }
+ { int const max = (2*threshold-1) - remaining;
+ int count;
+
+ if ((bitStream & (threshold-1)) < (U32)max) {
+ count = bitStream & (threshold-1);
+ bitCount += nbBits-1;
+ } else {
+ count = bitStream & (2*threshold-1);
+ if (count >= threshold) count -= max;
+ bitCount += nbBits;
+ }
+
+ count--; /* extra accuracy */
+ remaining -= count < 0 ? -count : count; /* -1 means +1 */
+ normalizedCounter[charnum++] = (short)count;
+ previous0 = !count;
+ while (remaining < threshold) {
+ nbBits--;
+ threshold >>= 1;
+ }
+
+ if ((ip <= iend-7) || (ip + (bitCount>>3) <= iend-4)) {
+ ip += bitCount>>3;
+ bitCount &= 7;
+ } else {
+ bitCount -= (int)(8 * (iend - 4 - ip));
+ ip = iend - 4;
+ }
+ bitStream = MEM_readLE32(ip) >> (bitCount & 31);
+ } } /* while ((remaining>1) & (charnum<=*maxSVPtr)) */
+ if (remaining != 1) return ERROR(corruption_detected);
+ if (bitCount > 32) return ERROR(corruption_detected);
+ *maxSVPtr = charnum-1;
+
+ ip += (bitCount+7)>>3;
+ return ip-istart;
+}
+
+
+/*! HUF_readStats() :
+ Read compact Huffman tree, saved by HUF_writeCTable().
+ `huffWeight` is destination buffer.
+ `rankStats` is assumed to be a table of at least HUF_TABLELOG_MAX U32.
+ @return : size read from `src` , or an error Code .
+ Note : Needed by HUF_readCTable() and HUF_readDTableX?() .
+*/
+size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize)
+{
+ U32 weightTotal;
+ const BYTE* ip = (const BYTE*) src;
+ size_t iSize;
+ size_t oSize;
+
+ if (!srcSize) return ERROR(srcSize_wrong);
+ iSize = ip[0];
+ /* memset(huffWeight, 0, hwSize); *//* is not necessary, even though some analyzer complain ... */
+
+ if (iSize >= 128) { /* special header */
+ oSize = iSize - 127;
+ iSize = ((oSize+1)/2);
+ if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
+ if (oSize >= hwSize) return ERROR(corruption_detected);
+ ip += 1;
+ { U32 n;
+ for (n=0; n<oSize; n+=2) {
+ huffWeight[n] = ip[n/2] >> 4;
+ huffWeight[n+1] = ip[n/2] & 15;
+ } } }
+ else { /* header compressed with FSE (normal case) */
+ FSE_DTable fseWorkspace[FSE_DTABLE_SIZE_U32(6)]; /* 6 is max possible tableLog for HUF header (maybe even 5, to be tested) */
+ if (iSize+1 > srcSize) return ERROR(srcSize_wrong);
+ oSize = FSE_decompress_wksp(huffWeight, hwSize-1, ip+1, iSize, fseWorkspace, 6); /* max (hwSize-1) values decoded, as last one is implied */
+ if (FSE_isError(oSize)) return oSize;
+ }
+
+ /* collect weight stats */
+ memset(rankStats, 0, (HUF_TABLELOG_MAX + 1) * sizeof(U32));
+ weightTotal = 0;
+ { U32 n; for (n=0; n<oSize; n++) {
+ if (huffWeight[n] >= HUF_TABLELOG_MAX) return ERROR(corruption_detected);
+ rankStats[huffWeight[n]]++;
+ weightTotal += (1 << huffWeight[n]) >> 1;
+ } }
+ if (weightTotal == 0) return ERROR(corruption_detected);
+
+ /* get last non-null symbol weight (implied, total must be 2^n) */
+ { U32 const tableLog = BIT_highbit32(weightTotal) + 1;
+ if (tableLog > HUF_TABLELOG_MAX) return ERROR(corruption_detected);
+ *tableLogPtr = tableLog;
+ /* determine last weight */
+ { U32 const total = 1 << tableLog;
+ U32 const rest = total - weightTotal;
+ U32 const verif = 1 << BIT_highbit32(rest);
+ U32 const lastWeight = BIT_highbit32(rest) + 1;
+ if (verif != rest) return ERROR(corruption_detected); /* last value must be a clean power of 2 */
+ huffWeight[oSize] = (BYTE)lastWeight;
+ rankStats[lastWeight]++;
+ } }
+
+ /* check tree construction validity */
+ if ((rankStats[1] < 2) || (rankStats[1] & 1)) return ERROR(corruption_detected); /* by construction : at least 2 elts of rank 1, must be even */
+
+ /* results */
+ *nbSymbolsPtr = (U32)(oSize+1);
+ return iSize+1;
+}
diff --git a/thirdparty/zstd/common/error_private.c b/thirdparty/zstd/common/error_private.c
new file mode 100644
index 0000000000..b3287245f1
--- /dev/null
+++ b/thirdparty/zstd/common/error_private.c
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/* The purpose of this file is to have a single list of error strings embedded in binary */
+
+#include "error_private.h"
+
+const char* ERR_getErrorString(ERR_enum code)
+{
+ static const char* const notErrorCode = "Unspecified error code";
+ switch( code )
+ {
+ case PREFIX(no_error): return "No error detected";
+ case PREFIX(GENERIC): return "Error (generic)";
+ case PREFIX(prefix_unknown): return "Unknown frame descriptor";
+ case PREFIX(version_unsupported): return "Version not supported";
+ case PREFIX(parameter_unknown): return "Unknown parameter type";
+ case PREFIX(frameParameter_unsupported): return "Unsupported frame parameter";
+ case PREFIX(frameParameter_unsupportedBy32bits): return "Frame parameter unsupported in 32-bits mode";
+ case PREFIX(frameParameter_windowTooLarge): return "Frame requires too much memory for decoding";
+ case PREFIX(compressionParameter_unsupported): return "Compression parameter is out of bound";
+ case PREFIX(init_missing): return "Context should be init first";
+ case PREFIX(memory_allocation): return "Allocation error : not enough memory";
+ case PREFIX(stage_wrong): return "Operation not authorized at current processing stage";
+ case PREFIX(dstSize_tooSmall): return "Destination buffer is too small";
+ case PREFIX(srcSize_wrong): return "Src size is incorrect";
+ case PREFIX(corruption_detected): return "Corrupted block detected";
+ case PREFIX(checksum_wrong): return "Restored data doesn't match checksum";
+ case PREFIX(tableLog_tooLarge): return "tableLog requires too much memory : unsupported";
+ case PREFIX(maxSymbolValue_tooLarge): return "Unsupported max Symbol Value : too large";
+ case PREFIX(maxSymbolValue_tooSmall): return "Specified maxSymbolValue is too small";
+ case PREFIX(dictionary_corrupted): return "Dictionary is corrupted";
+ case PREFIX(dictionary_wrong): return "Dictionary mismatch";
+ case PREFIX(dictionaryCreation_failed): return "Cannot create Dictionary from provided samples";
+ case PREFIX(maxCode):
+ default: return notErrorCode;
+ }
+}
diff --git a/thirdparty/zstd/common/error_private.h b/thirdparty/zstd/common/error_private.h
new file mode 100644
index 0000000000..1bc2e49548
--- /dev/null
+++ b/thirdparty/zstd/common/error_private.h
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+/* Note : this module is expected to remain private, do not expose it */
+
+#ifndef ERROR_H_MODULE
+#define ERROR_H_MODULE
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* ****************************************
+* Dependencies
+******************************************/
+#include <stddef.h> /* size_t */
+#include "zstd_errors.h" /* enum list */
+
+
+/* ****************************************
+* Compiler-specific
+******************************************/
+#if defined(__GNUC__)
+# define ERR_STATIC static __attribute__((unused))
+#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
+# define ERR_STATIC static inline
+#elif defined(_MSC_VER)
+# define ERR_STATIC static __inline
+#else
+# define ERR_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
+#endif
+
+
+/*-****************************************
+* Customization (error_public.h)
+******************************************/
+typedef ZSTD_ErrorCode ERR_enum;
+#define PREFIX(name) ZSTD_error_##name
+
+
+/*-****************************************
+* Error codes handling
+******************************************/
+#ifdef ERROR
+# undef ERROR /* reported already defined on VS 2015 (Rich Geldreich) */
+#endif
+#define ERROR(name) ((size_t)-PREFIX(name))
+
+ERR_STATIC unsigned ERR_isError(size_t code) { return (code > ERROR(maxCode)); }
+
+ERR_STATIC ERR_enum ERR_getErrorCode(size_t code) { if (!ERR_isError(code)) return (ERR_enum)0; return (ERR_enum) (0-code); }
+
+
+/*-****************************************
+* Error Strings
+******************************************/
+
+const char* ERR_getErrorString(ERR_enum code); /* error_private.c */
+
+ERR_STATIC const char* ERR_getErrorName(size_t code)
+{
+ return ERR_getErrorString(ERR_getErrorCode(code));
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ERROR_H_MODULE */
diff --git a/thirdparty/zstd/common/fse.h b/thirdparty/zstd/common/fse.h
new file mode 100644
index 0000000000..6d5d41def1
--- /dev/null
+++ b/thirdparty/zstd/common/fse.h
@@ -0,0 +1,698 @@
+/* ******************************************************************
+ FSE : Finite State Entropy codec
+ Public Prototypes declaration
+ Copyright (C) 2013-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+****************************************************************** */
+#ifndef FSE_H
+#define FSE_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/*-*****************************************
+* Dependencies
+******************************************/
+#include <stddef.h> /* size_t, ptrdiff_t */
+
+
+/*-*****************************************
+* FSE_PUBLIC_API : control library symbols visibility
+******************************************/
+#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
+# define FSE_PUBLIC_API __attribute__ ((visibility ("default")))
+#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
+# define FSE_PUBLIC_API __declspec(dllexport)
+#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
+# define FSE_PUBLIC_API __declspec(dllimport) /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
+#else
+# define FSE_PUBLIC_API
+#endif
+
+/*------ Version ------*/
+#define FSE_VERSION_MAJOR 0
+#define FSE_VERSION_MINOR 9
+#define FSE_VERSION_RELEASE 0
+
+#define FSE_LIB_VERSION FSE_VERSION_MAJOR.FSE_VERSION_MINOR.FSE_VERSION_RELEASE
+#define FSE_QUOTE(str) #str
+#define FSE_EXPAND_AND_QUOTE(str) FSE_QUOTE(str)
+#define FSE_VERSION_STRING FSE_EXPAND_AND_QUOTE(FSE_LIB_VERSION)
+
+#define FSE_VERSION_NUMBER (FSE_VERSION_MAJOR *100*100 + FSE_VERSION_MINOR *100 + FSE_VERSION_RELEASE)
+FSE_PUBLIC_API unsigned FSE_versionNumber(void); /**< library version number; to be used when checking dll version */
+
+/*-****************************************
+* FSE simple functions
+******************************************/
+/*! FSE_compress() :
+ Compress content of buffer 'src', of size 'srcSize', into destination buffer 'dst'.
+ 'dst' buffer must be already allocated. Compression runs faster is dstCapacity >= FSE_compressBound(srcSize).
+ @return : size of compressed data (<= dstCapacity).
+ Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
+ if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression instead.
+ if FSE_isError(return), compression failed (more details using FSE_getErrorName())
+*/
+FSE_PUBLIC_API size_t FSE_compress(void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize);
+
+/*! FSE_decompress():
+ Decompress FSE data from buffer 'cSrc', of size 'cSrcSize',
+ into already allocated destination buffer 'dst', of size 'dstCapacity'.
+ @return : size of regenerated data (<= maxDstSize),
+ or an error code, which can be tested using FSE_isError() .
+
+ ** Important ** : FSE_decompress() does not decompress non-compressible nor RLE data !!!
+ Why ? : making this distinction requires a header.
+ Header management is intentionally delegated to the user layer, which can better manage special cases.
+*/
+FSE_PUBLIC_API size_t FSE_decompress(void* dst, size_t dstCapacity,
+ const void* cSrc, size_t cSrcSize);
+
+
+/*-*****************************************
+* Tool functions
+******************************************/
+FSE_PUBLIC_API size_t FSE_compressBound(size_t size); /* maximum compressed size */
+
+/* Error Management */
+FSE_PUBLIC_API unsigned FSE_isError(size_t code); /* tells if a return value is an error code */
+FSE_PUBLIC_API const char* FSE_getErrorName(size_t code); /* provides error code string (useful for debugging) */
+
+
+/*-*****************************************
+* FSE advanced functions
+******************************************/
+/*! FSE_compress2() :
+ Same as FSE_compress(), but allows the selection of 'maxSymbolValue' and 'tableLog'
+ Both parameters can be defined as '0' to mean : use default value
+ @return : size of compressed data
+ Special values : if return == 0, srcData is not compressible => Nothing is stored within cSrc !!!
+ if return == 1, srcData is a single byte symbol * srcSize times. Use RLE compression.
+ if FSE_isError(return), it's an error code.
+*/
+FSE_PUBLIC_API size_t FSE_compress2 (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
+
+
+/*-*****************************************
+* FSE detailed API
+******************************************/
+/*!
+FSE_compress() does the following:
+1. count symbol occurrence from source[] into table count[]
+2. normalize counters so that sum(count[]) == Power_of_2 (2^tableLog)
+3. save normalized counters to memory buffer using writeNCount()
+4. build encoding table 'CTable' from normalized counters
+5. encode the data stream using encoding table 'CTable'
+
+FSE_decompress() does the following:
+1. read normalized counters with readNCount()
+2. build decoding table 'DTable' from normalized counters
+3. decode the data stream using decoding table 'DTable'
+
+The following API allows targeting specific sub-functions for advanced tasks.
+For example, it's possible to compress several blocks using the same 'CTable',
+or to save and provide normalized distribution using external method.
+*/
+
+/* *** COMPRESSION *** */
+
+/*! FSE_count():
+ Provides the precise count of each byte within a table 'count'.
+ 'count' is a table of unsigned int, of minimum size (*maxSymbolValuePtr+1).
+ *maxSymbolValuePtr will be updated if detected smaller than initial value.
+ @return : the count of the most frequent symbol (which is not identified).
+ if return == srcSize, there is only one symbol.
+ Can also return an error code, which can be tested with FSE_isError(). */
+FSE_PUBLIC_API size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
+
+/*! FSE_optimalTableLog():
+ dynamically downsize 'tableLog' when conditions are met.
+ It saves CPU time, by using smaller tables, while preserving or even improving compression ratio.
+ @return : recommended tableLog (necessarily <= 'maxTableLog') */
+FSE_PUBLIC_API unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
+
+/*! FSE_normalizeCount():
+ normalize counts so that sum(count[]) == Power_of_2 (2^tableLog)
+ 'normalizedCounter' is a table of short, of minimum size (maxSymbolValue+1).
+ @return : tableLog,
+ or an errorCode, which can be tested using FSE_isError() */
+FSE_PUBLIC_API size_t FSE_normalizeCount(short* normalizedCounter, unsigned tableLog, const unsigned* count, size_t srcSize, unsigned maxSymbolValue);
+
+/*! FSE_NCountWriteBound():
+ Provides the maximum possible size of an FSE normalized table, given 'maxSymbolValue' and 'tableLog'.
+ Typically useful for allocation purpose. */
+FSE_PUBLIC_API size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog);
+
+/*! FSE_writeNCount():
+ Compactly save 'normalizedCounter' into 'buffer'.
+ @return : size of the compressed table,
+ or an errorCode, which can be tested using FSE_isError(). */
+FSE_PUBLIC_API size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
+
+
+/*! Constructor and Destructor of FSE_CTable.
+ Note that FSE_CTable size depends on 'tableLog' and 'maxSymbolValue' */
+typedef unsigned FSE_CTable; /* don't allocate that. It's only meant to be more restrictive than void* */
+FSE_PUBLIC_API FSE_CTable* FSE_createCTable (unsigned tableLog, unsigned maxSymbolValue);
+FSE_PUBLIC_API void FSE_freeCTable (FSE_CTable* ct);
+
+/*! FSE_buildCTable():
+ Builds `ct`, which must be already allocated, using FSE_createCTable().
+ @return : 0, or an errorCode, which can be tested using FSE_isError() */
+FSE_PUBLIC_API size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
+
+/*! FSE_compress_usingCTable():
+ Compress `src` using `ct` into `dst` which must be already allocated.
+ @return : size of compressed data (<= `dstCapacity`),
+ or 0 if compressed data could not fit into `dst`,
+ or an errorCode, which can be tested using FSE_isError() */
+FSE_PUBLIC_API size_t FSE_compress_usingCTable (void* dst, size_t dstCapacity, const void* src, size_t srcSize, const FSE_CTable* ct);
+
+/*!
+Tutorial :
+----------
+The first step is to count all symbols. FSE_count() does this job very fast.
+Result will be saved into 'count', a table of unsigned int, which must be already allocated, and have 'maxSymbolValuePtr[0]+1' cells.
+'src' is a table of bytes of size 'srcSize'. All values within 'src' MUST be <= maxSymbolValuePtr[0]
+maxSymbolValuePtr[0] will be updated, with its real value (necessarily <= original value)
+FSE_count() will return the number of occurrence of the most frequent symbol.
+This can be used to know if there is a single symbol within 'src', and to quickly evaluate its compressibility.
+If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
+
+The next step is to normalize the frequencies.
+FSE_normalizeCount() will ensure that sum of frequencies is == 2 ^'tableLog'.
+It also guarantees a minimum of 1 to any Symbol with frequency >= 1.
+You can use 'tableLog'==0 to mean "use default tableLog value".
+If you are unsure of which tableLog value to use, you can ask FSE_optimalTableLog(),
+which will provide the optimal valid tableLog given sourceSize, maxSymbolValue, and a user-defined maximum (0 means "default").
+
+The result of FSE_normalizeCount() will be saved into a table,
+called 'normalizedCounter', which is a table of signed short.
+'normalizedCounter' must be already allocated, and have at least 'maxSymbolValue+1' cells.
+The return value is tableLog if everything proceeded as expected.
+It is 0 if there is a single symbol within distribution.
+If there is an error (ex: invalid tableLog value), the function will return an ErrorCode (which can be tested using FSE_isError()).
+
+'normalizedCounter' can be saved in a compact manner to a memory area using FSE_writeNCount().
+'buffer' must be already allocated.
+For guaranteed success, buffer size must be at least FSE_headerBound().
+The result of the function is the number of bytes written into 'buffer'.
+If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError(); ex : buffer size too small).
+
+'normalizedCounter' can then be used to create the compression table 'CTable'.
+The space required by 'CTable' must be already allocated, using FSE_createCTable().
+You can then use FSE_buildCTable() to fill 'CTable'.
+If there is an error, both functions will return an ErrorCode (which can be tested using FSE_isError()).
+
+'CTable' can then be used to compress 'src', with FSE_compress_usingCTable().
+Similar to FSE_count(), the convention is that 'src' is assumed to be a table of char of size 'srcSize'
+The function returns the size of compressed data (without header), necessarily <= `dstCapacity`.
+If it returns '0', compressed data could not fit into 'dst'.
+If there is an error, the function will return an ErrorCode (which can be tested using FSE_isError()).
+*/
+
+
+/* *** DECOMPRESSION *** */
+
+/*! FSE_readNCount():
+ Read compactly saved 'normalizedCounter' from 'rBuffer'.
+ @return : size read from 'rBuffer',
+ or an errorCode, which can be tested using FSE_isError().
+ maxSymbolValuePtr[0] and tableLogPtr[0] will also be updated with their respective values */
+FSE_PUBLIC_API size_t FSE_readNCount (short* normalizedCounter, unsigned* maxSymbolValuePtr, unsigned* tableLogPtr, const void* rBuffer, size_t rBuffSize);
+
+/*! Constructor and Destructor of FSE_DTable.
+ Note that its size depends on 'tableLog' */
+typedef unsigned FSE_DTable; /* don't allocate that. It's just a way to be more restrictive than void* */
+FSE_PUBLIC_API FSE_DTable* FSE_createDTable(unsigned tableLog);
+FSE_PUBLIC_API void FSE_freeDTable(FSE_DTable* dt);
+
+/*! FSE_buildDTable():
+ Builds 'dt', which must be already allocated, using FSE_createDTable().
+ return : 0, or an errorCode, which can be tested using FSE_isError() */
+FSE_PUBLIC_API size_t FSE_buildDTable (FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog);
+
+/*! FSE_decompress_usingDTable():
+ Decompress compressed source `cSrc` of size `cSrcSize` using `dt`
+ into `dst` which must be already allocated.
+ @return : size of regenerated data (necessarily <= `dstCapacity`),
+ or an errorCode, which can be tested using FSE_isError() */
+FSE_PUBLIC_API size_t FSE_decompress_usingDTable(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, const FSE_DTable* dt);
+
+/*!
+Tutorial :
+----------
+(Note : these functions only decompress FSE-compressed blocks.
+ If block is uncompressed, use memcpy() instead
+ If block is a single repeated byte, use memset() instead )
+
+The first step is to obtain the normalized frequencies of symbols.
+This can be performed by FSE_readNCount() if it was saved using FSE_writeNCount().
+'normalizedCounter' must be already allocated, and have at least 'maxSymbolValuePtr[0]+1' cells of signed short.
+In practice, that means it's necessary to know 'maxSymbolValue' beforehand,
+or size the table to handle worst case situations (typically 256).
+FSE_readNCount() will provide 'tableLog' and 'maxSymbolValue'.
+The result of FSE_readNCount() is the number of bytes read from 'rBuffer'.
+Note that 'rBufferSize' must be at least 4 bytes, even if useful information is less than that.
+If there is an error, the function will return an error code, which can be tested using FSE_isError().
+
+The next step is to build the decompression tables 'FSE_DTable' from 'normalizedCounter'.
+This is performed by the function FSE_buildDTable().
+The space required by 'FSE_DTable' must be already allocated using FSE_createDTable().
+If there is an error, the function will return an error code, which can be tested using FSE_isError().
+
+`FSE_DTable` can then be used to decompress `cSrc`, with FSE_decompress_usingDTable().
+`cSrcSize` must be strictly correct, otherwise decompression will fail.
+FSE_decompress_usingDTable() result will tell how many bytes were regenerated (<=`dstCapacity`).
+If there is an error, the function will return an error code, which can be tested using FSE_isError(). (ex: dst buffer too small)
+*/
+
+
+#ifdef FSE_STATIC_LINKING_ONLY
+
+/* *** Dependency *** */
+#include "bitstream.h"
+
+
+/* *****************************************
+* Static allocation
+*******************************************/
+/* FSE buffer bounds */
+#define FSE_NCOUNTBOUND 512
+#define FSE_BLOCKBOUND(size) (size + (size>>7))
+#define FSE_COMPRESSBOUND(size) (FSE_NCOUNTBOUND + FSE_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
+
+/* It is possible to statically allocate FSE CTable/DTable as a table of FSE_CTable/FSE_DTable using below macros */
+#define FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) (1 + (1<<(maxTableLog-1)) + ((maxSymbolValue+1)*2))
+#define FSE_DTABLE_SIZE_U32(maxTableLog) (1 + (1<<maxTableLog))
+
+/* or use the size to malloc() space directly. Pay attention to alignment restrictions though */
+#define FSE_CTABLE_SIZE(maxTableLog, maxSymbolValue) (FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) * sizeof(FSE_CTable))
+#define FSE_DTABLE_SIZE(maxTableLog) (FSE_DTABLE_SIZE_U32(maxTableLog) * sizeof(FSE_DTable))
+
+
+/* *****************************************
+* FSE advanced API
+*******************************************/
+/* FSE_count_wksp() :
+ * Same as FSE_count(), but using an externally provided scratch buffer.
+ * `workSpace` size must be table of >= `1024` unsigned
+ */
+size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize, unsigned* workSpace);
+
+/** FSE_countFast() :
+ * same as FSE_count(), but blindly trusts that all byte values within src are <= *maxSymbolValuePtr
+ */
+size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
+
+/* FSE_countFast_wksp() :
+ * Same as FSE_countFast(), but using an externally provided scratch buffer.
+ * `workSpace` must be a table of minimum `1024` unsigned
+ */
+size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize, unsigned* workSpace);
+
+/*! FSE_count_simple
+ * Same as FSE_countFast(), but does not use any additional memory (not even on stack).
+ * This function is unsafe, and will segfault if any value within `src` is `> *maxSymbolValuePtr` (presuming it's also the size of `count`).
+*/
+size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr, const void* src, size_t srcSize);
+
+
+
+unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus);
+/**< same as FSE_optimalTableLog(), which used `minus==2` */
+
+/* FSE_compress_wksp() :
+ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
+ * FSE_WKSP_SIZE_U32() provides the minimum size required for `workSpace` as a table of FSE_CTable.
+ */
+#define FSE_WKSP_SIZE_U32(maxTableLog, maxSymbolValue) ( FSE_CTABLE_SIZE_U32(maxTableLog, maxSymbolValue) + ((maxTableLog > 12) ? (1 << (maxTableLog - 2)) : 1024) )
+size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
+
+size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits);
+/**< build a fake FSE_CTable, designed for a flat distribution, where each symbol uses nbBits */
+
+size_t FSE_buildCTable_rle (FSE_CTable* ct, unsigned char symbolValue);
+/**< build a fake FSE_CTable, designed to compress always the same symbolValue */
+
+/* FSE_buildCTable_wksp() :
+ * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
+ * `wkspSize` must be >= `(1<<tableLog)`.
+ */
+size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
+
+size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits);
+/**< build a fake FSE_DTable, designed to read a flat distribution where each symbol uses nbBits */
+
+size_t FSE_buildDTable_rle (FSE_DTable* dt, unsigned char symbolValue);
+/**< build a fake FSE_DTable, designed to always generate the same symbolValue */
+
+size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog);
+/**< same as FSE_decompress(), using an externally allocated `workSpace` produced with `FSE_DTABLE_SIZE_U32(maxLog)` */
+
+
+/* *****************************************
+* FSE symbol compression API
+*******************************************/
+/*!
+ This API consists of small unitary functions, which highly benefit from being inlined.
+ Hence their body are included in next section.
+*/
+typedef struct {
+ ptrdiff_t value;
+ const void* stateTable;
+ const void* symbolTT;
+ unsigned stateLog;
+} FSE_CState_t;
+
+static void FSE_initCState(FSE_CState_t* CStatePtr, const FSE_CTable* ct);
+
+static void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* CStatePtr, unsigned symbol);
+
+static void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* CStatePtr);
+
+/**<
+These functions are inner components of FSE_compress_usingCTable().
+They allow the creation of custom streams, mixing multiple tables and bit sources.
+
+A key property to keep in mind is that encoding and decoding are done **in reverse direction**.
+So the first symbol you will encode is the last you will decode, like a LIFO stack.
+
+You will need a few variables to track your CStream. They are :
+
+FSE_CTable ct; // Provided by FSE_buildCTable()
+BIT_CStream_t bitStream; // bitStream tracking structure
+FSE_CState_t state; // State tracking structure (can have several)
+
+
+The first thing to do is to init bitStream and state.
+ size_t errorCode = BIT_initCStream(&bitStream, dstBuffer, maxDstSize);
+ FSE_initCState(&state, ct);
+
+Note that BIT_initCStream() can produce an error code, so its result should be tested, using FSE_isError();
+You can then encode your input data, byte after byte.
+FSE_encodeSymbol() outputs a maximum of 'tableLog' bits at a time.
+Remember decoding will be done in reverse direction.
+ FSE_encodeByte(&bitStream, &state, symbol);
+
+At any time, you can also add any bit sequence.
+Note : maximum allowed nbBits is 25, for compatibility with 32-bits decoders
+ BIT_addBits(&bitStream, bitField, nbBits);
+
+The above methods don't commit data to memory, they just store it into local register, for speed.
+Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
+Writing data to memory is a manual operation, performed by the flushBits function.
+ BIT_flushBits(&bitStream);
+
+Your last FSE encoding operation shall be to flush your last state value(s).
+ FSE_flushState(&bitStream, &state);
+
+Finally, you must close the bitStream.
+The function returns the size of CStream in bytes.
+If data couldn't fit into dstBuffer, it will return a 0 ( == not compressible)
+If there is an error, it returns an errorCode (which can be tested using FSE_isError()).
+ size_t size = BIT_closeCStream(&bitStream);
+*/
+
+
+/* *****************************************
+* FSE symbol decompression API
+*******************************************/
+typedef struct {
+ size_t state;
+ const void* table; /* precise table may vary, depending on U16 */
+} FSE_DState_t;
+
+
+static void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt);
+
+static unsigned char FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
+
+static unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr);
+
+/**<
+Let's now decompose FSE_decompress_usingDTable() into its unitary components.
+You will decode FSE-encoded symbols from the bitStream,
+and also any other bitFields you put in, **in reverse order**.
+
+You will need a few variables to track your bitStream. They are :
+
+BIT_DStream_t DStream; // Stream context
+FSE_DState_t DState; // State context. Multiple ones are possible
+FSE_DTable* DTablePtr; // Decoding table, provided by FSE_buildDTable()
+
+The first thing to do is to init the bitStream.
+ errorCode = BIT_initDStream(&DStream, srcBuffer, srcSize);
+
+You should then retrieve your initial state(s)
+(in reverse flushing order if you have several ones) :
+ errorCode = FSE_initDState(&DState, &DStream, DTablePtr);
+
+You can then decode your data, symbol after symbol.
+For information the maximum number of bits read by FSE_decodeSymbol() is 'tableLog'.
+Keep in mind that symbols are decoded in reverse order, like a LIFO stack (last in, first out).
+ unsigned char symbol = FSE_decodeSymbol(&DState, &DStream);
+
+You can retrieve any bitfield you eventually stored into the bitStream (in reverse order)
+Note : maximum allowed nbBits is 25, for 32-bits compatibility
+ size_t bitField = BIT_readBits(&DStream, nbBits);
+
+All above operations only read from local register (which size depends on size_t).
+Refueling the register from memory is manually performed by the reload method.
+ endSignal = FSE_reloadDStream(&DStream);
+
+BIT_reloadDStream() result tells if there is still some more data to read from DStream.
+BIT_DStream_unfinished : there is still some data left into the DStream.
+BIT_DStream_endOfBuffer : Dstream reached end of buffer. Its container may no longer be completely filled.
+BIT_DStream_completed : Dstream reached its exact end, corresponding in general to decompression completed.
+BIT_DStream_tooFar : Dstream went too far. Decompression result is corrupted.
+
+When reaching end of buffer (BIT_DStream_endOfBuffer), progress slowly, notably if you decode multiple symbols per loop,
+to properly detect the exact end of stream.
+After each decoded symbol, check if DStream is fully consumed using this simple test :
+ BIT_reloadDStream(&DStream) >= BIT_DStream_completed
+
+When it's done, verify decompression is fully completed, by checking both DStream and the relevant states.
+Checking if DStream has reached its end is performed by :
+ BIT_endOfDStream(&DStream);
+Check also the states. There might be some symbols left there, if some high probability ones (>50%) are possible.
+ FSE_endOfDState(&DState);
+*/
+
+
+/* *****************************************
+* FSE unsafe API
+*******************************************/
+static unsigned char FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD);
+/* faster, but works only if nbBits is always >= 1 (otherwise, result will be corrupted) */
+
+
+/* *****************************************
+* Implementation of inlined functions
+*******************************************/
+typedef struct {
+ int deltaFindState;
+ U32 deltaNbBits;
+} FSE_symbolCompressionTransform; /* total 8 bytes */
+
+MEM_STATIC void FSE_initCState(FSE_CState_t* statePtr, const FSE_CTable* ct)
+{
+ const void* ptr = ct;
+ const U16* u16ptr = (const U16*) ptr;
+ const U32 tableLog = MEM_read16(ptr);
+ statePtr->value = (ptrdiff_t)1<<tableLog;
+ statePtr->stateTable = u16ptr+2;
+ statePtr->symbolTT = ((const U32*)ct + 1 + (tableLog ? (1<<(tableLog-1)) : 1));
+ statePtr->stateLog = tableLog;
+}
+
+
+/*! FSE_initCState2() :
+* Same as FSE_initCState(), but the first symbol to include (which will be the last to be read)
+* uses the smallest state value possible, saving the cost of this symbol */
+MEM_STATIC void FSE_initCState2(FSE_CState_t* statePtr, const FSE_CTable* ct, U32 symbol)
+{
+ FSE_initCState(statePtr, ct);
+ { const FSE_symbolCompressionTransform symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
+ const U16* stateTable = (const U16*)(statePtr->stateTable);
+ U32 nbBitsOut = (U32)((symbolTT.deltaNbBits + (1<<15)) >> 16);
+ statePtr->value = (nbBitsOut << 16) - symbolTT.deltaNbBits;
+ statePtr->value = stateTable[(statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
+ }
+}
+
+MEM_STATIC void FSE_encodeSymbol(BIT_CStream_t* bitC, FSE_CState_t* statePtr, U32 symbol)
+{
+ FSE_symbolCompressionTransform const symbolTT = ((const FSE_symbolCompressionTransform*)(statePtr->symbolTT))[symbol];
+ const U16* const stateTable = (const U16*)(statePtr->stateTable);
+ U32 const nbBitsOut = (U32)((statePtr->value + symbolTT.deltaNbBits) >> 16);
+ BIT_addBits(bitC, statePtr->value, nbBitsOut);
+ statePtr->value = stateTable[ (statePtr->value >> nbBitsOut) + symbolTT.deltaFindState];
+}
+
+MEM_STATIC void FSE_flushCState(BIT_CStream_t* bitC, const FSE_CState_t* statePtr)
+{
+ BIT_addBits(bitC, statePtr->value, statePtr->stateLog);
+ BIT_flushBits(bitC);
+}
+
+
+/* ====== Decompression ====== */
+
+typedef struct {
+ U16 tableLog;
+ U16 fastMode;
+} FSE_DTableHeader; /* sizeof U32 */
+
+typedef struct
+{
+ unsigned short newState;
+ unsigned char symbol;
+ unsigned char nbBits;
+} FSE_decode_t; /* size == U32 */
+
+MEM_STATIC void FSE_initDState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD, const FSE_DTable* dt)
+{
+ const void* ptr = dt;
+ const FSE_DTableHeader* const DTableH = (const FSE_DTableHeader*)ptr;
+ DStatePtr->state = BIT_readBits(bitD, DTableH->tableLog);
+ BIT_reloadDStream(bitD);
+ DStatePtr->table = dt + 1;
+}
+
+MEM_STATIC BYTE FSE_peekSymbol(const FSE_DState_t* DStatePtr)
+{
+ FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
+ return DInfo.symbol;
+}
+
+MEM_STATIC void FSE_updateState(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
+{
+ FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
+ U32 const nbBits = DInfo.nbBits;
+ size_t const lowBits = BIT_readBits(bitD, nbBits);
+ DStatePtr->state = DInfo.newState + lowBits;
+}
+
+MEM_STATIC BYTE FSE_decodeSymbol(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
+{
+ FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
+ U32 const nbBits = DInfo.nbBits;
+ BYTE const symbol = DInfo.symbol;
+ size_t const lowBits = BIT_readBits(bitD, nbBits);
+
+ DStatePtr->state = DInfo.newState + lowBits;
+ return symbol;
+}
+
+/*! FSE_decodeSymbolFast() :
+ unsafe, only works if no symbol has a probability > 50% */
+MEM_STATIC BYTE FSE_decodeSymbolFast(FSE_DState_t* DStatePtr, BIT_DStream_t* bitD)
+{
+ FSE_decode_t const DInfo = ((const FSE_decode_t*)(DStatePtr->table))[DStatePtr->state];
+ U32 const nbBits = DInfo.nbBits;
+ BYTE const symbol = DInfo.symbol;
+ size_t const lowBits = BIT_readBitsFast(bitD, nbBits);
+
+ DStatePtr->state = DInfo.newState + lowBits;
+ return symbol;
+}
+
+MEM_STATIC unsigned FSE_endOfDState(const FSE_DState_t* DStatePtr)
+{
+ return DStatePtr->state == 0;
+}
+
+
+
+#ifndef FSE_COMMONDEFS_ONLY
+
+/* **************************************************************
+* Tuning parameters
+****************************************************************/
+/*!MEMORY_USAGE :
+* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
+* Increasing memory usage improves compression ratio
+* Reduced memory usage can improve speed, due to cache effect
+* Recommended max value is 14, for 16KB, which nicely fits into Intel x86 L1 cache */
+#ifndef FSE_MAX_MEMORY_USAGE
+# define FSE_MAX_MEMORY_USAGE 14
+#endif
+#ifndef FSE_DEFAULT_MEMORY_USAGE
+# define FSE_DEFAULT_MEMORY_USAGE 13
+#endif
+
+/*!FSE_MAX_SYMBOL_VALUE :
+* Maximum symbol value authorized.
+* Required for proper stack allocation */
+#ifndef FSE_MAX_SYMBOL_VALUE
+# define FSE_MAX_SYMBOL_VALUE 255
+#endif
+
+/* **************************************************************
+* template functions type & suffix
+****************************************************************/
+#define FSE_FUNCTION_TYPE BYTE
+#define FSE_FUNCTION_EXTENSION
+#define FSE_DECODE_TYPE FSE_decode_t
+
+
+#endif /* !FSE_COMMONDEFS_ONLY */
+
+
+/* ***************************************************************
+* Constants
+*****************************************************************/
+#define FSE_MAX_TABLELOG (FSE_MAX_MEMORY_USAGE-2)
+#define FSE_MAX_TABLESIZE (1U<<FSE_MAX_TABLELOG)
+#define FSE_MAXTABLESIZE_MASK (FSE_MAX_TABLESIZE-1)
+#define FSE_DEFAULT_TABLELOG (FSE_DEFAULT_MEMORY_USAGE-2)
+#define FSE_MIN_TABLELOG 5
+
+#define FSE_TABLELOG_ABSOLUTE_MAX 15
+#if FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX
+# error "FSE_MAX_TABLELOG > FSE_TABLELOG_ABSOLUTE_MAX is not supported"
+#endif
+
+#define FSE_TABLESTEP(tableSize) ((tableSize>>1) + (tableSize>>3) + 3)
+
+
+#endif /* FSE_STATIC_LINKING_ONLY */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* FSE_H */
diff --git a/thirdparty/zstd/common/fse_decompress.c b/thirdparty/zstd/common/fse_decompress.c
new file mode 100644
index 0000000000..8474a4c079
--- /dev/null
+++ b/thirdparty/zstd/common/fse_decompress.c
@@ -0,0 +1,328 @@
+/* ******************************************************************
+ FSE : Finite State Entropy decoder
+ Copyright (C) 2013-2015, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
+****************************************************************** */
+
+
+/* **************************************************************
+* Compiler specifics
+****************************************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE static __forceinline
+# include <intrin.h> /* For Visual 2005 */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* **************************************************************
+* Includes
+****************************************************************/
+#include <stdlib.h> /* malloc, free, qsort */
+#include <string.h> /* memcpy, memset */
+#include "bitstream.h"
+#define FSE_STATIC_LINKING_ONLY
+#include "fse.h"
+
+
+/* **************************************************************
+* Error Management
+****************************************************************/
+#define FSE_isError ERR_isError
+#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+
+/* check and forward error code */
+#define CHECK_F(f) { size_t const e = f; if (FSE_isError(e)) return e; }
+
+
+/* **************************************************************
+* Templates
+****************************************************************/
+/*
+ designed to be included
+ for type-specific functions (template emulation in C)
+ Objective is to write these functions only once, for improved maintenance
+*/
+
+/* safety checks */
+#ifndef FSE_FUNCTION_EXTENSION
+# error "FSE_FUNCTION_EXTENSION must be defined"
+#endif
+#ifndef FSE_FUNCTION_TYPE
+# error "FSE_FUNCTION_TYPE must be defined"
+#endif
+
+/* Function names */
+#define FSE_CAT(X,Y) X##Y
+#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
+#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
+
+
+/* Function templates */
+FSE_DTable* FSE_createDTable (unsigned tableLog)
+{
+ if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
+ return (FSE_DTable*)malloc( FSE_DTABLE_SIZE_U32(tableLog) * sizeof (U32) );
+}
+
+void FSE_freeDTable (FSE_DTable* dt)
+{
+ free(dt);
+}
+
+size_t FSE_buildDTable(FSE_DTable* dt, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
+{
+ void* const tdPtr = dt+1; /* because *dt is unsigned, 32-bits aligned on 32-bits */
+ FSE_DECODE_TYPE* const tableDecode = (FSE_DECODE_TYPE*) (tdPtr);
+ U16 symbolNext[FSE_MAX_SYMBOL_VALUE+1];
+
+ U32 const maxSV1 = maxSymbolValue + 1;
+ U32 const tableSize = 1 << tableLog;
+ U32 highThreshold = tableSize-1;
+
+ /* Sanity Checks */
+ if (maxSymbolValue > FSE_MAX_SYMBOL_VALUE) return ERROR(maxSymbolValue_tooLarge);
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
+
+ /* Init, lay down lowprob symbols */
+ { FSE_DTableHeader DTableH;
+ DTableH.tableLog = (U16)tableLog;
+ DTableH.fastMode = 1;
+ { S16 const largeLimit= (S16)(1 << (tableLog-1));
+ U32 s;
+ for (s=0; s<maxSV1; s++) {
+ if (normalizedCounter[s]==-1) {
+ tableDecode[highThreshold--].symbol = (FSE_FUNCTION_TYPE)s;
+ symbolNext[s] = 1;
+ } else {
+ if (normalizedCounter[s] >= largeLimit) DTableH.fastMode=0;
+ symbolNext[s] = normalizedCounter[s];
+ } } }
+ memcpy(dt, &DTableH, sizeof(DTableH));
+ }
+
+ /* Spread symbols */
+ { U32 const tableMask = tableSize-1;
+ U32 const step = FSE_TABLESTEP(tableSize);
+ U32 s, position = 0;
+ for (s=0; s<maxSV1; s++) {
+ int i;
+ for (i=0; i<normalizedCounter[s]; i++) {
+ tableDecode[position].symbol = (FSE_FUNCTION_TYPE)s;
+ position = (position + step) & tableMask;
+ while (position > highThreshold) position = (position + step) & tableMask; /* lowprob area */
+ } }
+ if (position!=0) return ERROR(GENERIC); /* position must reach all cells once, otherwise normalizedCounter is incorrect */
+ }
+
+ /* Build Decoding table */
+ { U32 u;
+ for (u=0; u<tableSize; u++) {
+ FSE_FUNCTION_TYPE const symbol = (FSE_FUNCTION_TYPE)(tableDecode[u].symbol);
+ U16 nextState = symbolNext[symbol]++;
+ tableDecode[u].nbBits = (BYTE) (tableLog - BIT_highbit32 ((U32)nextState) );
+ tableDecode[u].newState = (U16) ( (nextState << tableDecode[u].nbBits) - tableSize);
+ } }
+
+ return 0;
+}
+
+
+#ifndef FSE_COMMONDEFS_ONLY
+
+/*-*******************************************************
+* Decompression (Byte symbols)
+*********************************************************/
+size_t FSE_buildDTable_rle (FSE_DTable* dt, BYTE symbolValue)
+{
+ void* ptr = dt;
+ FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
+ void* dPtr = dt + 1;
+ FSE_decode_t* const cell = (FSE_decode_t*)dPtr;
+
+ DTableH->tableLog = 0;
+ DTableH->fastMode = 0;
+
+ cell->newState = 0;
+ cell->symbol = symbolValue;
+ cell->nbBits = 0;
+
+ return 0;
+}
+
+
+size_t FSE_buildDTable_raw (FSE_DTable* dt, unsigned nbBits)
+{
+ void* ptr = dt;
+ FSE_DTableHeader* const DTableH = (FSE_DTableHeader*)ptr;
+ void* dPtr = dt + 1;
+ FSE_decode_t* const dinfo = (FSE_decode_t*)dPtr;
+ const unsigned tableSize = 1 << nbBits;
+ const unsigned tableMask = tableSize - 1;
+ const unsigned maxSV1 = tableMask+1;
+ unsigned s;
+
+ /* Sanity checks */
+ if (nbBits < 1) return ERROR(GENERIC); /* min size */
+
+ /* Build Decoding Table */
+ DTableH->tableLog = (U16)nbBits;
+ DTableH->fastMode = 1;
+ for (s=0; s<maxSV1; s++) {
+ dinfo[s].newState = 0;
+ dinfo[s].symbol = (BYTE)s;
+ dinfo[s].nbBits = (BYTE)nbBits;
+ }
+
+ return 0;
+}
+
+FORCE_INLINE size_t FSE_decompress_usingDTable_generic(
+ void* dst, size_t maxDstSize,
+ const void* cSrc, size_t cSrcSize,
+ const FSE_DTable* dt, const unsigned fast)
+{
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* op = ostart;
+ BYTE* const omax = op + maxDstSize;
+ BYTE* const olimit = omax-3;
+
+ BIT_DStream_t bitD;
+ FSE_DState_t state1;
+ FSE_DState_t state2;
+
+ /* Init */
+ CHECK_F(BIT_initDStream(&bitD, cSrc, cSrcSize));
+
+ FSE_initDState(&state1, &bitD, dt);
+ FSE_initDState(&state2, &bitD, dt);
+
+#define FSE_GETSYMBOL(statePtr) fast ? FSE_decodeSymbolFast(statePtr, &bitD) : FSE_decodeSymbol(statePtr, &bitD)
+
+ /* 4 symbols per loop */
+ for ( ; (BIT_reloadDStream(&bitD)==BIT_DStream_unfinished) & (op<olimit) ; op+=4) {
+ op[0] = FSE_GETSYMBOL(&state1);
+
+ if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
+ BIT_reloadDStream(&bitD);
+
+ op[1] = FSE_GETSYMBOL(&state2);
+
+ if (FSE_MAX_TABLELOG*4+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
+ { if (BIT_reloadDStream(&bitD) > BIT_DStream_unfinished) { op+=2; break; } }
+
+ op[2] = FSE_GETSYMBOL(&state1);
+
+ if (FSE_MAX_TABLELOG*2+7 > sizeof(bitD.bitContainer)*8) /* This test must be static */
+ BIT_reloadDStream(&bitD);
+
+ op[3] = FSE_GETSYMBOL(&state2);
+ }
+
+ /* tail */
+ /* note : BIT_reloadDStream(&bitD) >= FSE_DStream_partiallyFilled; Ends at exactly BIT_DStream_completed */
+ while (1) {
+ if (op>(omax-2)) return ERROR(dstSize_tooSmall);
+ *op++ = FSE_GETSYMBOL(&state1);
+ if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
+ *op++ = FSE_GETSYMBOL(&state2);
+ break;
+ }
+
+ if (op>(omax-2)) return ERROR(dstSize_tooSmall);
+ *op++ = FSE_GETSYMBOL(&state2);
+ if (BIT_reloadDStream(&bitD)==BIT_DStream_overflow) {
+ *op++ = FSE_GETSYMBOL(&state1);
+ break;
+ } }
+
+ return op-ostart;
+}
+
+
+size_t FSE_decompress_usingDTable(void* dst, size_t originalSize,
+ const void* cSrc, size_t cSrcSize,
+ const FSE_DTable* dt)
+{
+ const void* ptr = dt;
+ const FSE_DTableHeader* DTableH = (const FSE_DTableHeader*)ptr;
+ const U32 fastMode = DTableH->fastMode;
+
+ /* select fast mode (static) */
+ if (fastMode) return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 1);
+ return FSE_decompress_usingDTable_generic(dst, originalSize, cSrc, cSrcSize, dt, 0);
+}
+
+
+size_t FSE_decompress_wksp(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize, FSE_DTable* workSpace, unsigned maxLog)
+{
+ const BYTE* const istart = (const BYTE*)cSrc;
+ const BYTE* ip = istart;
+ short counting[FSE_MAX_SYMBOL_VALUE+1];
+ unsigned tableLog;
+ unsigned maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
+
+ /* normal FSE decoding mode */
+ size_t const NCountLength = FSE_readNCount (counting, &maxSymbolValue, &tableLog, istart, cSrcSize);
+ if (FSE_isError(NCountLength)) return NCountLength;
+ //if (NCountLength >= cSrcSize) return ERROR(srcSize_wrong); /* too small input size; supposed to be already checked in NCountLength, only remaining case : NCountLength==cSrcSize */
+ if (tableLog > maxLog) return ERROR(tableLog_tooLarge);
+ ip += NCountLength;
+ cSrcSize -= NCountLength;
+
+ CHECK_F( FSE_buildDTable (workSpace, counting, maxSymbolValue, tableLog) );
+
+ return FSE_decompress_usingDTable (dst, dstCapacity, ip, cSrcSize, workSpace); /* always return, even if it is an error code */
+}
+
+
+typedef FSE_DTable DTable_max_t[FSE_DTABLE_SIZE_U32(FSE_MAX_TABLELOG)];
+
+size_t FSE_decompress(void* dst, size_t dstCapacity, const void* cSrc, size_t cSrcSize)
+{
+ DTable_max_t dt; /* Static analyzer seems unable to understand this table will be properly initialized later */
+ return FSE_decompress_wksp(dst, dstCapacity, cSrc, cSrcSize, dt, FSE_MAX_TABLELOG);
+}
+
+
+
+#endif /* FSE_COMMONDEFS_ONLY */
diff --git a/thirdparty/zstd/common/huf.h b/thirdparty/zstd/common/huf.h
new file mode 100644
index 0000000000..7873ca3d42
--- /dev/null
+++ b/thirdparty/zstd/common/huf.h
@@ -0,0 +1,283 @@
+/* ******************************************************************
+ Huffman coder, part of New Generation Entropy library
+ header file
+ Copyright (C) 2013-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
+****************************************************************** */
+#ifndef HUF_H_298734234
+#define HUF_H_298734234
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* *** Dependencies *** */
+#include <stddef.h> /* size_t */
+
+
+/* *** library symbols visibility *** */
+/* Note : when linking with -fvisibility=hidden on gcc, or by default on Visual,
+ * HUF symbols remain "private" (internal symbols for library only).
+ * Set macro FSE_DLL_EXPORT to 1 if you want HUF symbols visible on DLL interface */
+#if defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) && defined(__GNUC__) && (__GNUC__ >= 4)
+# define HUF_PUBLIC_API __attribute__ ((visibility ("default")))
+#elif defined(FSE_DLL_EXPORT) && (FSE_DLL_EXPORT==1) /* Visual expected */
+# define HUF_PUBLIC_API __declspec(dllexport)
+#elif defined(FSE_DLL_IMPORT) && (FSE_DLL_IMPORT==1)
+# define HUF_PUBLIC_API __declspec(dllimport) /* not required, just to generate faster code (saves a function pointer load from IAT and an indirect jump) */
+#else
+# define HUF_PUBLIC_API
+#endif
+
+
+/* *** simple functions *** */
+/**
+HUF_compress() :
+ Compress content from buffer 'src', of size 'srcSize', into buffer 'dst'.
+ 'dst' buffer must be already allocated.
+ Compression runs faster if `dstCapacity` >= HUF_compressBound(srcSize).
+ `srcSize` must be <= `HUF_BLOCKSIZE_MAX` == 128 KB.
+ @return : size of compressed data (<= `dstCapacity`).
+ Special values : if return == 0, srcData is not compressible => Nothing is stored within dst !!!
+ if return == 1, srcData is a single repeated byte symbol (RLE compression).
+ if HUF_isError(return), compression failed (more details using HUF_getErrorName())
+*/
+HUF_PUBLIC_API size_t HUF_compress(void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize);
+
+/**
+HUF_decompress() :
+ Decompress HUF data from buffer 'cSrc', of size 'cSrcSize',
+ into already allocated buffer 'dst', of minimum size 'dstSize'.
+ `originalSize` : **must** be the ***exact*** size of original (uncompressed) data.
+ Note : in contrast with FSE, HUF_decompress can regenerate
+ RLE (cSrcSize==1) and uncompressed (cSrcSize==dstSize) data,
+ because it knows size to regenerate.
+ @return : size of regenerated data (== originalSize),
+ or an error code, which can be tested using HUF_isError()
+*/
+HUF_PUBLIC_API size_t HUF_decompress(void* dst, size_t originalSize,
+ const void* cSrc, size_t cSrcSize);
+
+
+/* *** Tool functions *** */
+#define HUF_BLOCKSIZE_MAX (128 * 1024) /**< maximum input size for a single block compressed with HUF_compress */
+HUF_PUBLIC_API size_t HUF_compressBound(size_t size); /**< maximum compressed size (worst case) */
+
+/* Error Management */
+HUF_PUBLIC_API unsigned HUF_isError(size_t code); /**< tells if a return value is an error code */
+HUF_PUBLIC_API const char* HUF_getErrorName(size_t code); /**< provides error code string (useful for debugging) */
+
+
+/* *** Advanced function *** */
+
+/** HUF_compress2() :
+ * Same as HUF_compress(), but offers direct control over `maxSymbolValue` and `tableLog`.
+ * `tableLog` must be `<= HUF_TABLELOG_MAX` . */
+HUF_PUBLIC_API size_t HUF_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
+
+/** HUF_compress4X_wksp() :
+ * Same as HUF_compress2(), but uses externally allocated `workSpace`.
+ * `workspace` must have minimum alignment of 4, and be at least as large as following macro */
+#define HUF_WORKSPACE_SIZE (6 << 10)
+#define HUF_WORKSPACE_SIZE_U32 (HUF_WORKSPACE_SIZE / sizeof(U32))
+HUF_PUBLIC_API size_t HUF_compress4X_wksp (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize);
+
+
+
+/* ******************************************************************
+ * WARNING !!
+ * The following section contains advanced and experimental definitions
+ * which shall never be used in the context of dll
+ * because they are not guaranteed to remain stable in the future.
+ * Only consider them in association with static linking.
+ *******************************************************************/
+#ifdef HUF_STATIC_LINKING_ONLY
+
+/* *** Dependencies *** */
+#include "mem.h" /* U32 */
+
+
+/* *** Constants *** */
+#define HUF_TABLELOG_MAX 12 /* max configured tableLog (for static allocation); can be modified up to HUF_ABSOLUTEMAX_TABLELOG */
+#define HUF_TABLELOG_DEFAULT 11 /* tableLog by default, when not specified */
+#define HUF_SYMBOLVALUE_MAX 255
+
+#define HUF_TABLELOG_ABSOLUTEMAX 15 /* absolute limit of HUF_MAX_TABLELOG. Beyond that value, code does not work */
+#if (HUF_TABLELOG_MAX > HUF_TABLELOG_ABSOLUTEMAX)
+# error "HUF_TABLELOG_MAX is too large !"
+#endif
+
+
+/* ****************************************
+* Static allocation
+******************************************/
+/* HUF buffer bounds */
+#define HUF_CTABLEBOUND 129
+#define HUF_BLOCKBOUND(size) (size + (size>>8) + 8) /* only true when incompressible is pre-filtered with fast heuristic */
+#define HUF_COMPRESSBOUND(size) (HUF_CTABLEBOUND + HUF_BLOCKBOUND(size)) /* Macro version, useful for static allocation */
+
+/* static allocation of HUF's Compression Table */
+#define HUF_CTABLE_SIZE_U32(maxSymbolValue) ((maxSymbolValue)+1) /* Use tables of U32, for proper alignment */
+#define HUF_CTABLE_SIZE(maxSymbolValue) (HUF_CTABLE_SIZE_U32(maxSymbolValue) * sizeof(U32))
+#define HUF_CREATE_STATIC_CTABLE(name, maxSymbolValue) \
+ U32 name##hb[HUF_CTABLE_SIZE_U32(maxSymbolValue)]; \
+ void* name##hv = &(name##hb); \
+ HUF_CElt* name = (HUF_CElt*)(name##hv) /* no final ; */
+
+/* static allocation of HUF's DTable */
+typedef U32 HUF_DTable;
+#define HUF_DTABLE_SIZE(maxTableLog) (1 + (1<<(maxTableLog)))
+#define HUF_CREATE_STATIC_DTABLEX2(DTable, maxTableLog) \
+ HUF_DTable DTable[HUF_DTABLE_SIZE((maxTableLog)-1)] = { ((U32)((maxTableLog)-1) * 0x01000001) }
+#define HUF_CREATE_STATIC_DTABLEX4(DTable, maxTableLog) \
+ HUF_DTable DTable[HUF_DTABLE_SIZE(maxTableLog)] = { ((U32)(maxTableLog) * 0x01000001) }
+
+
+/* ****************************************
+* Advanced decompression functions
+******************************************/
+size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
+size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
+
+size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< decodes RLE and uncompressed */
+size_t HUF_decompress4X_hufOnly(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< considers RLE and uncompressed as errors */
+size_t HUF_decompress4X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
+size_t HUF_decompress4X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
+
+
+/* ****************************************
+* HUF detailed API
+******************************************/
+/*!
+HUF_compress() does the following:
+1. count symbol occurrence from source[] into table count[] using FSE_count()
+2. (optional) refine tableLog using HUF_optimalTableLog()
+3. build Huffman table from count using HUF_buildCTable()
+4. save Huffman table to memory buffer using HUF_writeCTable()
+5. encode the data stream using HUF_compress4X_usingCTable()
+
+The following API allows targeting specific sub-functions for advanced tasks.
+For example, it's possible to compress several blocks using the same 'CTable',
+or to save and regenerate 'CTable' using external methods.
+*/
+/* FSE_count() : find it within "fse.h" */
+unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue);
+typedef struct HUF_CElt_s HUF_CElt; /* incomplete type */
+size_t HUF_buildCTable (HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue, unsigned maxNbBits);
+size_t HUF_writeCTable (void* dst, size_t maxDstSize, const HUF_CElt* CTable, unsigned maxSymbolValue, unsigned huffLog);
+size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
+
+typedef enum {
+ HUF_repeat_none, /**< Cannot use the previous table */
+ HUF_repeat_check, /**< Can use the previous table but it must be checked. Note : The previous table must have been constructed by HUF_compress{1, 4}X_repeat */
+ HUF_repeat_valid /**< Can use the previous table and it is asumed to be valid */
+ } HUF_repeat;
+/** HUF_compress4X_repeat() :
+* Same as HUF_compress4X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
+* If it uses hufTable it does not modify hufTable or repeat.
+* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
+* If preferRepeat then the old table will always be used if valid. */
+size_t HUF_compress4X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
+
+/** HUF_buildCTable_wksp() :
+ * Same as HUF_buildCTable(), but using externally allocated scratch buffer.
+ * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
+ */
+size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize);
+
+/*! HUF_readStats() :
+ Read compact Huffman tree, saved by HUF_writeCTable().
+ `huffWeight` is destination buffer.
+ @return : size read from `src` , or an error Code .
+ Note : Needed by HUF_readCTable() and HUF_readDTableXn() . */
+size_t HUF_readStats(BYTE* huffWeight, size_t hwSize, U32* rankStats,
+ U32* nbSymbolsPtr, U32* tableLogPtr,
+ const void* src, size_t srcSize);
+
+/** HUF_readCTable() :
+* Loading a CTable saved with HUF_writeCTable() */
+size_t HUF_readCTable (HUF_CElt* CTable, unsigned maxSymbolValue, const void* src, size_t srcSize);
+
+
+/*
+HUF_decompress() does the following:
+1. select the decompression algorithm (X2, X4) based on pre-computed heuristics
+2. build Huffman table from save, using HUF_readDTableXn()
+3. decode 1 or 4 segments in parallel using HUF_decompressSXn_usingDTable
+*/
+
+/** HUF_selectDecoder() :
+* Tells which decoder is likely to decode faster,
+* based on a set of pre-determined metrics.
+* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
+* Assumption : 0 < cSrcSize < dstSize <= 128 KB */
+U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize);
+
+size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize);
+size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize);
+
+size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
+size_t HUF_decompress4X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
+size_t HUF_decompress4X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
+
+
+/* single stream variants */
+
+size_t HUF_compress1X (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog);
+size_t HUF_compress1X_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
+size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable);
+/** HUF_compress1X_repeat() :
+* Same as HUF_compress1X_wksp(), but considers using hufTable if *repeat != HUF_repeat_none.
+* If it uses hufTable it does not modify hufTable or repeat.
+* If it doesn't, it sets *repeat = HUF_repeat_none, and it sets hufTable to the table used.
+* If preferRepeat then the old table will always be used if valid. */
+size_t HUF_compress1X_repeat(void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize, HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat); /**< `workSpace` must be a table of at least HUF_WORKSPACE_SIZE_U32 unsigned */
+
+size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* single-symbol decoder */
+size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /* double-symbol decoder */
+
+size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
+size_t HUF_decompress1X2_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< single-symbol decoder */
+size_t HUF_decompress1X4_DCtx(HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize); /**< double-symbols decoder */
+
+size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable); /**< automatic selection of sing or double symbol decoder, based on DTable */
+size_t HUF_decompress1X2_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
+size_t HUF_decompress1X4_usingDTable(void* dst, size_t maxDstSize, const void* cSrc, size_t cSrcSize, const HUF_DTable* DTable);
+
+#endif /* HUF_STATIC_LINKING_ONLY */
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* HUF_H_298734234 */
diff --git a/thirdparty/zstd/common/mem.h b/thirdparty/zstd/common/mem.h
new file mode 100644
index 0000000000..4773a8b930
--- /dev/null
+++ b/thirdparty/zstd/common/mem.h
@@ -0,0 +1,373 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#ifndef MEM_H_MODULE
+#define MEM_H_MODULE
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*-****************************************
+* Dependencies
+******************************************/
+#include <stddef.h> /* size_t, ptrdiff_t */
+#include <string.h> /* memcpy */
+
+
+/*-****************************************
+* Compiler specifics
+******************************************/
+#if defined(_MSC_VER) /* Visual Studio */
+# include <stdlib.h> /* _byteswap_ulong */
+# include <intrin.h> /* _byteswap_* */
+#endif
+#if defined(__GNUC__)
+# define MEM_STATIC static __inline __attribute__((unused))
+#elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
+# define MEM_STATIC static inline
+#elif defined(_MSC_VER)
+# define MEM_STATIC static __inline
+#else
+# define MEM_STATIC static /* this version may generate warnings for unused static functions; disable the relevant warning */
+#endif
+
+/* code only tested on 32 and 64 bits systems */
+#define MEM_STATIC_ASSERT(c) { enum { MEM_static_assert = 1/(int)(!!(c)) }; }
+MEM_STATIC void MEM_check(void) { MEM_STATIC_ASSERT((sizeof(size_t)==4) || (sizeof(size_t)==8)); }
+
+
+/*-**************************************************************
+* Basic Types
+*****************************************************************/
+#if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef int16_t S16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+ typedef int64_t S64;
+ typedef intptr_t iPtrDiff;
+ typedef uintptr_t uPtrDiff;
+#else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef signed short S16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64;
+ typedef signed long long S64;
+ typedef ptrdiff_t iPtrDiff;
+ typedef size_t uPtrDiff;
+#endif
+
+
+/*-**************************************************************
+* Memory I/O
+*****************************************************************/
+/* MEM_FORCE_MEMORY_ACCESS :
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+ * The below switch allow to select different access method for improved performance.
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
+ * Method 1 : `__packed` statement. It depends on compiler extension (i.e., not portable).
+ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+ * Method 2 : direct access. This method is portable but violate C standard.
+ * It can generate buggy code on targets depending on alignment.
+ * In some circumstances, it's the only known way to get the most performance (i.e. GCC + ARMv6)
+ * See http://fastcompression.blogspot.fr/2015/08/accessing-unaligned-memory.html for details.
+ * Prefer these methods in priority order (0 > 1 > 2)
+ */
+#ifndef MEM_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
+# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+# define MEM_FORCE_MEMORY_ACCESS 2
+# elif defined(__INTEL_COMPILER) || defined(__GNUC__)
+# define MEM_FORCE_MEMORY_ACCESS 1
+# endif
+#endif
+
+MEM_STATIC unsigned MEM_32bits(void) { return sizeof(size_t)==4; }
+MEM_STATIC unsigned MEM_64bits(void) { return sizeof(size_t)==8; }
+
+MEM_STATIC unsigned MEM_isLittleEndian(void)
+{
+ const union { U32 u; BYTE c[4]; } one = { 1 }; /* don't use static : performance detrimental */
+ return one.c[0];
+}
+
+#if defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==2)
+
+/* violates C standard, by lying on structure alignment.
+Only use if no other choice to achieve best performance on target platform */
+MEM_STATIC U16 MEM_read16(const void* memPtr) { return *(const U16*) memPtr; }
+MEM_STATIC U32 MEM_read32(const void* memPtr) { return *(const U32*) memPtr; }
+MEM_STATIC U64 MEM_read64(const void* memPtr) { return *(const U64*) memPtr; }
+MEM_STATIC U64 MEM_readST(const void* memPtr) { return *(const size_t*) memPtr; }
+
+MEM_STATIC void MEM_write16(void* memPtr, U16 value) { *(U16*)memPtr = value; }
+MEM_STATIC void MEM_write32(void* memPtr, U32 value) { *(U32*)memPtr = value; }
+MEM_STATIC void MEM_write64(void* memPtr, U64 value) { *(U64*)memPtr = value; }
+
+#elif defined(MEM_FORCE_MEMORY_ACCESS) && (MEM_FORCE_MEMORY_ACCESS==1)
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+#if defined(_MSC_VER) || (defined(__INTEL_COMPILER) && defined(WIN32))
+ __pragma( pack(push, 1) )
+ typedef union { U16 u16; U32 u32; U64 u64; size_t st; } unalign;
+ __pragma( pack(pop) )
+#else
+ typedef union { U16 u16; U32 u32; U64 u64; size_t st; } __attribute__((packed)) unalign;
+#endif
+
+MEM_STATIC U16 MEM_read16(const void* ptr) { return ((const unalign*)ptr)->u16; }
+MEM_STATIC U32 MEM_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
+MEM_STATIC U64 MEM_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
+MEM_STATIC U64 MEM_readST(const void* ptr) { return ((const unalign*)ptr)->st; }
+
+MEM_STATIC void MEM_write16(void* memPtr, U16 value) { ((unalign*)memPtr)->u16 = value; }
+MEM_STATIC void MEM_write32(void* memPtr, U32 value) { ((unalign*)memPtr)->u32 = value; }
+MEM_STATIC void MEM_write64(void* memPtr, U64 value) { ((unalign*)memPtr)->u64 = value; }
+
+#else
+
+/* default method, safe and standard.
+ can sometimes prove slower */
+
+MEM_STATIC U16 MEM_read16(const void* memPtr)
+{
+ U16 val; memcpy(&val, memPtr, sizeof(val)); return val;
+}
+
+MEM_STATIC U32 MEM_read32(const void* memPtr)
+{
+ U32 val; memcpy(&val, memPtr, sizeof(val)); return val;
+}
+
+MEM_STATIC U64 MEM_read64(const void* memPtr)
+{
+ U64 val; memcpy(&val, memPtr, sizeof(val)); return val;
+}
+
+MEM_STATIC size_t MEM_readST(const void* memPtr)
+{
+ size_t val; memcpy(&val, memPtr, sizeof(val)); return val;
+}
+
+MEM_STATIC void MEM_write16(void* memPtr, U16 value)
+{
+ memcpy(memPtr, &value, sizeof(value));
+}
+
+MEM_STATIC void MEM_write32(void* memPtr, U32 value)
+{
+ memcpy(memPtr, &value, sizeof(value));
+}
+
+MEM_STATIC void MEM_write64(void* memPtr, U64 value)
+{
+ memcpy(memPtr, &value, sizeof(value));
+}
+
+#endif /* MEM_FORCE_MEMORY_ACCESS */
+
+MEM_STATIC U32 MEM_swap32(U32 in)
+{
+#if defined(_MSC_VER) /* Visual Studio */
+ return _byteswap_ulong(in);
+#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
+ return __builtin_bswap32(in);
+#else
+ return ((in << 24) & 0xff000000 ) |
+ ((in << 8) & 0x00ff0000 ) |
+ ((in >> 8) & 0x0000ff00 ) |
+ ((in >> 24) & 0x000000ff );
+#endif
+}
+
+MEM_STATIC U64 MEM_swap64(U64 in)
+{
+#if defined(_MSC_VER) /* Visual Studio */
+ return _byteswap_uint64(in);
+#elif defined (__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 403)
+ return __builtin_bswap64(in);
+#else
+ return ((in << 56) & 0xff00000000000000ULL) |
+ ((in << 40) & 0x00ff000000000000ULL) |
+ ((in << 24) & 0x0000ff0000000000ULL) |
+ ((in << 8) & 0x000000ff00000000ULL) |
+ ((in >> 8) & 0x00000000ff000000ULL) |
+ ((in >> 24) & 0x0000000000ff0000ULL) |
+ ((in >> 40) & 0x000000000000ff00ULL) |
+ ((in >> 56) & 0x00000000000000ffULL);
+#endif
+}
+
+MEM_STATIC size_t MEM_swapST(size_t in)
+{
+ if (MEM_32bits())
+ return (size_t)MEM_swap32((U32)in);
+ else
+ return (size_t)MEM_swap64((U64)in);
+}
+
+/*=== Little endian r/w ===*/
+
+MEM_STATIC U16 MEM_readLE16(const void* memPtr)
+{
+ if (MEM_isLittleEndian())
+ return MEM_read16(memPtr);
+ else {
+ const BYTE* p = (const BYTE*)memPtr;
+ return (U16)(p[0] + (p[1]<<8));
+ }
+}
+
+MEM_STATIC void MEM_writeLE16(void* memPtr, U16 val)
+{
+ if (MEM_isLittleEndian()) {
+ MEM_write16(memPtr, val);
+ } else {
+ BYTE* p = (BYTE*)memPtr;
+ p[0] = (BYTE)val;
+ p[1] = (BYTE)(val>>8);
+ }
+}
+
+MEM_STATIC U32 MEM_readLE24(const void* memPtr)
+{
+ return MEM_readLE16(memPtr) + (((const BYTE*)memPtr)[2] << 16);
+}
+
+MEM_STATIC void MEM_writeLE24(void* memPtr, U32 val)
+{
+ MEM_writeLE16(memPtr, (U16)val);
+ ((BYTE*)memPtr)[2] = (BYTE)(val>>16);
+}
+
+MEM_STATIC U32 MEM_readLE32(const void* memPtr)
+{
+ if (MEM_isLittleEndian())
+ return MEM_read32(memPtr);
+ else
+ return MEM_swap32(MEM_read32(memPtr));
+}
+
+MEM_STATIC void MEM_writeLE32(void* memPtr, U32 val32)
+{
+ if (MEM_isLittleEndian())
+ MEM_write32(memPtr, val32);
+ else
+ MEM_write32(memPtr, MEM_swap32(val32));
+}
+
+MEM_STATIC U64 MEM_readLE64(const void* memPtr)
+{
+ if (MEM_isLittleEndian())
+ return MEM_read64(memPtr);
+ else
+ return MEM_swap64(MEM_read64(memPtr));
+}
+
+MEM_STATIC void MEM_writeLE64(void* memPtr, U64 val64)
+{
+ if (MEM_isLittleEndian())
+ MEM_write64(memPtr, val64);
+ else
+ MEM_write64(memPtr, MEM_swap64(val64));
+}
+
+MEM_STATIC size_t MEM_readLEST(const void* memPtr)
+{
+ if (MEM_32bits())
+ return (size_t)MEM_readLE32(memPtr);
+ else
+ return (size_t)MEM_readLE64(memPtr);
+}
+
+MEM_STATIC void MEM_writeLEST(void* memPtr, size_t val)
+{
+ if (MEM_32bits())
+ MEM_writeLE32(memPtr, (U32)val);
+ else
+ MEM_writeLE64(memPtr, (U64)val);
+}
+
+/*=== Big endian r/w ===*/
+
+MEM_STATIC U32 MEM_readBE32(const void* memPtr)
+{
+ if (MEM_isLittleEndian())
+ return MEM_swap32(MEM_read32(memPtr));
+ else
+ return MEM_read32(memPtr);
+}
+
+MEM_STATIC void MEM_writeBE32(void* memPtr, U32 val32)
+{
+ if (MEM_isLittleEndian())
+ MEM_write32(memPtr, MEM_swap32(val32));
+ else
+ MEM_write32(memPtr, val32);
+}
+
+MEM_STATIC U64 MEM_readBE64(const void* memPtr)
+{
+ if (MEM_isLittleEndian())
+ return MEM_swap64(MEM_read64(memPtr));
+ else
+ return MEM_read64(memPtr);
+}
+
+MEM_STATIC void MEM_writeBE64(void* memPtr, U64 val64)
+{
+ if (MEM_isLittleEndian())
+ MEM_write64(memPtr, MEM_swap64(val64));
+ else
+ MEM_write64(memPtr, val64);
+}
+
+MEM_STATIC size_t MEM_readBEST(const void* memPtr)
+{
+ if (MEM_32bits())
+ return (size_t)MEM_readBE32(memPtr);
+ else
+ return (size_t)MEM_readBE64(memPtr);
+}
+
+MEM_STATIC void MEM_writeBEST(void* memPtr, size_t val)
+{
+ if (MEM_32bits())
+ MEM_writeBE32(memPtr, (U32)val);
+ else
+ MEM_writeBE64(memPtr, (U64)val);
+}
+
+
+/* function safe only for comparisons */
+MEM_STATIC U32 MEM_readMINMATCH(const void* memPtr, U32 length)
+{
+ switch (length)
+ {
+ default :
+ case 4 : return MEM_read32(memPtr);
+ case 3 : if (MEM_isLittleEndian())
+ return MEM_read32(memPtr)<<8;
+ else
+ return MEM_read32(memPtr)>>8;
+ }
+}
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* MEM_H_MODULE */
diff --git a/thirdparty/zstd/common/pool.c b/thirdparty/zstd/common/pool.c
new file mode 100644
index 0000000000..e439fe1b0d
--- /dev/null
+++ b/thirdparty/zstd/common/pool.c
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+/* ====== Dependencies ======= */
+#include <stddef.h> /* size_t */
+#include <stdlib.h> /* malloc, calloc, free */
+#include "pool.h"
+
+/* ====== Compiler specifics ====== */
+#if defined(_MSC_VER)
+# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
+#endif
+
+
+#ifdef ZSTD_MULTITHREAD
+
+#include "threading.h" /* pthread adaptation */
+
+/* A job is a function and an opaque argument */
+typedef struct POOL_job_s {
+ POOL_function function;
+ void *opaque;
+} POOL_job;
+
+struct POOL_ctx_s {
+ /* Keep track of the threads */
+ pthread_t *threads;
+ size_t numThreads;
+
+ /* The queue is a circular buffer */
+ POOL_job *queue;
+ size_t queueHead;
+ size_t queueTail;
+ size_t queueSize;
+ /* The mutex protects the queue */
+ pthread_mutex_t queueMutex;
+ /* Condition variable for pushers to wait on when the queue is full */
+ pthread_cond_t queuePushCond;
+ /* Condition variables for poppers to wait on when the queue is empty */
+ pthread_cond_t queuePopCond;
+ /* Indicates if the queue is shutting down */
+ int shutdown;
+};
+
+/* POOL_thread() :
+ Work thread for the thread pool.
+ Waits for jobs and executes them.
+ @returns : NULL on failure else non-null.
+*/
+static void* POOL_thread(void* opaque) {
+ POOL_ctx* const ctx = (POOL_ctx*)opaque;
+ if (!ctx) { return NULL; }
+ for (;;) {
+ /* Lock the mutex and wait for a non-empty queue or until shutdown */
+ pthread_mutex_lock(&ctx->queueMutex);
+ while (ctx->queueHead == ctx->queueTail && !ctx->shutdown) {
+ pthread_cond_wait(&ctx->queuePopCond, &ctx->queueMutex);
+ }
+ /* empty => shutting down: so stop */
+ if (ctx->queueHead == ctx->queueTail) {
+ pthread_mutex_unlock(&ctx->queueMutex);
+ return opaque;
+ }
+ /* Pop a job off the queue */
+ { POOL_job const job = ctx->queue[ctx->queueHead];
+ ctx->queueHead = (ctx->queueHead + 1) % ctx->queueSize;
+ /* Unlock the mutex, signal a pusher, and run the job */
+ pthread_mutex_unlock(&ctx->queueMutex);
+ pthread_cond_signal(&ctx->queuePushCond);
+ job.function(job.opaque);
+ }
+ }
+ /* Unreachable */
+}
+
+POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
+ POOL_ctx *ctx;
+ /* Check the parameters */
+ if (!numThreads || !queueSize) { return NULL; }
+ /* Allocate the context and zero initialize */
+ ctx = (POOL_ctx *)calloc(1, sizeof(POOL_ctx));
+ if (!ctx) { return NULL; }
+ /* Initialize the job queue.
+ * It needs one extra space since one space is wasted to differentiate empty
+ * and full queues.
+ */
+ ctx->queueSize = queueSize + 1;
+ ctx->queue = (POOL_job *)malloc(ctx->queueSize * sizeof(POOL_job));
+ ctx->queueHead = 0;
+ ctx->queueTail = 0;
+ pthread_mutex_init(&ctx->queueMutex, NULL);
+ pthread_cond_init(&ctx->queuePushCond, NULL);
+ pthread_cond_init(&ctx->queuePopCond, NULL);
+ ctx->shutdown = 0;
+ /* Allocate space for the thread handles */
+ ctx->threads = (pthread_t *)malloc(numThreads * sizeof(pthread_t));
+ ctx->numThreads = 0;
+ /* Check for errors */
+ if (!ctx->threads || !ctx->queue) { POOL_free(ctx); return NULL; }
+ /* Initialize the threads */
+ { size_t i;
+ for (i = 0; i < numThreads; ++i) {
+ if (pthread_create(&ctx->threads[i], NULL, &POOL_thread, ctx)) {
+ ctx->numThreads = i;
+ POOL_free(ctx);
+ return NULL;
+ } }
+ ctx->numThreads = numThreads;
+ }
+ return ctx;
+}
+
+/*! POOL_join() :
+ Shutdown the queue, wake any sleeping threads, and join all of the threads.
+*/
+static void POOL_join(POOL_ctx *ctx) {
+ /* Shut down the queue */
+ pthread_mutex_lock(&ctx->queueMutex);
+ ctx->shutdown = 1;
+ pthread_mutex_unlock(&ctx->queueMutex);
+ /* Wake up sleeping threads */
+ pthread_cond_broadcast(&ctx->queuePushCond);
+ pthread_cond_broadcast(&ctx->queuePopCond);
+ /* Join all of the threads */
+ { size_t i;
+ for (i = 0; i < ctx->numThreads; ++i) {
+ pthread_join(ctx->threads[i], NULL);
+ } }
+}
+
+void POOL_free(POOL_ctx *ctx) {
+ if (!ctx) { return; }
+ POOL_join(ctx);
+ pthread_mutex_destroy(&ctx->queueMutex);
+ pthread_cond_destroy(&ctx->queuePushCond);
+ pthread_cond_destroy(&ctx->queuePopCond);
+ if (ctx->queue) free(ctx->queue);
+ if (ctx->threads) free(ctx->threads);
+ free(ctx);
+}
+
+void POOL_add(void *ctxVoid, POOL_function function, void *opaque) {
+ POOL_ctx *ctx = (POOL_ctx *)ctxVoid;
+ if (!ctx) { return; }
+
+ pthread_mutex_lock(&ctx->queueMutex);
+ { POOL_job const job = {function, opaque};
+ /* Wait until there is space in the queue for the new job */
+ size_t newTail = (ctx->queueTail + 1) % ctx->queueSize;
+ while (ctx->queueHead == newTail && !ctx->shutdown) {
+ pthread_cond_wait(&ctx->queuePushCond, &ctx->queueMutex);
+ newTail = (ctx->queueTail + 1) % ctx->queueSize;
+ }
+ /* The queue is still going => there is space */
+ if (!ctx->shutdown) {
+ ctx->queue[ctx->queueTail] = job;
+ ctx->queueTail = newTail;
+ }
+ }
+ pthread_mutex_unlock(&ctx->queueMutex);
+ pthread_cond_signal(&ctx->queuePopCond);
+}
+
+#else /* ZSTD_MULTITHREAD not defined */
+/* No multi-threading support */
+
+/* We don't need any data, but if it is empty malloc() might return NULL. */
+struct POOL_ctx_s {
+ int data;
+};
+
+POOL_ctx *POOL_create(size_t numThreads, size_t queueSize) {
+ (void)numThreads;
+ (void)queueSize;
+ return (POOL_ctx *)malloc(sizeof(POOL_ctx));
+}
+
+void POOL_free(POOL_ctx *ctx) {
+ if (ctx) free(ctx);
+}
+
+void POOL_add(void *ctx, POOL_function function, void *opaque) {
+ (void)ctx;
+ function(opaque);
+}
+
+#endif /* ZSTD_MULTITHREAD */
diff --git a/thirdparty/zstd/common/pool.h b/thirdparty/zstd/common/pool.h
new file mode 100644
index 0000000000..50cb25b12c
--- /dev/null
+++ b/thirdparty/zstd/common/pool.h
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+#ifndef POOL_H
+#define POOL_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+#include <stddef.h> /* size_t */
+
+typedef struct POOL_ctx_s POOL_ctx;
+
+/*! POOL_create() :
+ Create a thread pool with at most `numThreads` threads.
+ `numThreads` must be at least 1.
+ The maximum number of queued jobs before blocking is `queueSize`.
+ `queueSize` must be at least 1.
+ @return : The POOL_ctx pointer on success else NULL.
+*/
+POOL_ctx *POOL_create(size_t numThreads, size_t queueSize);
+
+/*! POOL_free() :
+ Free a thread pool returned by POOL_create().
+*/
+void POOL_free(POOL_ctx *ctx);
+
+/*! POOL_function :
+ The function type that can be added to a thread pool.
+*/
+typedef void (*POOL_function)(void *);
+/*! POOL_add_function :
+ The function type for a generic thread pool add function.
+*/
+typedef void (*POOL_add_function)(void *, POOL_function, void *);
+
+/*! POOL_add() :
+ Add the job `function(opaque)` to the thread pool.
+ Possibly blocks until there is room in the queue.
+ Note : The function may be executed asynchronously, so `opaque` must live until the function has been completed.
+*/
+void POOL_add(void *ctx, POOL_function function, void *opaque);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif
diff --git a/thirdparty/zstd/common/threading.c b/thirdparty/zstd/common/threading.c
new file mode 100644
index 0000000000..32d58796a9
--- /dev/null
+++ b/thirdparty/zstd/common/threading.c
@@ -0,0 +1,80 @@
+
+/**
+ * Copyright (c) 2016 Tino Reichardt
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * You can contact the author at:
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ */
+
+/**
+ * This file will hold wrapper for systems, which do not support pthreads
+ */
+
+/* When ZSTD_MULTITHREAD is not defined, this file would become an empty translation unit.
+* Include some ISO C header code to prevent this and portably avoid related warnings.
+* (Visual C++: C4206 / GCC: -Wpedantic / Clang: -Wempty-translation-unit)
+*/
+#include <stddef.h>
+
+
+#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
+
+/**
+ * Windows minimalist Pthread Wrapper, based on :
+ * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ */
+
+
+/* === Dependencies === */
+#include <process.h>
+#include <errno.h>
+#include "threading.h"
+
+
+/* === Implementation === */
+
+static unsigned __stdcall worker(void *arg)
+{
+ pthread_t* const thread = (pthread_t*) arg;
+ thread->arg = thread->start_routine(thread->arg);
+ return 0;
+}
+
+int pthread_create(pthread_t* thread, const void* unused,
+ void* (*start_routine) (void*), void* arg)
+{
+ (void)unused;
+ thread->arg = arg;
+ thread->start_routine = start_routine;
+ thread->handle = (HANDLE) _beginthreadex(NULL, 0, worker, thread, 0, NULL);
+
+ if (!thread->handle)
+ return errno;
+ else
+ return 0;
+}
+
+int _pthread_join(pthread_t * thread, void **value_ptr)
+{
+ DWORD result;
+
+ if (!thread->handle) return 0;
+
+ result = WaitForSingleObject(thread->handle, INFINITE);
+ switch (result) {
+ case WAIT_OBJECT_0:
+ if (value_ptr) *value_ptr = thread->arg;
+ return 0;
+ case WAIT_ABANDONED:
+ return EINVAL;
+ default:
+ return GetLastError();
+ }
+}
+
+#endif /* ZSTD_MULTITHREAD */
diff --git a/thirdparty/zstd/common/threading.h b/thirdparty/zstd/common/threading.h
new file mode 100644
index 0000000000..c0086139ea
--- /dev/null
+++ b/thirdparty/zstd/common/threading.h
@@ -0,0 +1,104 @@
+
+/**
+ * Copyright (c) 2016 Tino Reichardt
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ *
+ * You can contact the author at:
+ * - zstdmt source repository: https://github.com/mcmilk/zstdmt
+ */
+
+#ifndef THREADING_H_938743
+#define THREADING_H_938743
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#if defined(ZSTD_MULTITHREAD) && defined(_WIN32)
+
+/**
+ * Windows minimalist Pthread Wrapper, based on :
+ * http://www.cse.wustl.edu/~schmidt/win32-cv-1.html
+ */
+#ifdef WINVER
+# undef WINVER
+#endif
+#define WINVER 0x0600
+
+#ifdef _WIN32_WINNT
+# undef _WIN32_WINNT
+#endif
+#define _WIN32_WINNT 0x0600
+
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+/* mutex */
+#define pthread_mutex_t CRITICAL_SECTION
+#define pthread_mutex_init(a,b) InitializeCriticalSection((a))
+#define pthread_mutex_destroy(a) DeleteCriticalSection((a))
+#define pthread_mutex_lock(a) EnterCriticalSection((a))
+#define pthread_mutex_unlock(a) LeaveCriticalSection((a))
+
+/* condition variable */
+#define pthread_cond_t CONDITION_VARIABLE
+#define pthread_cond_init(a, b) InitializeConditionVariable((a))
+#define pthread_cond_destroy(a) /* No delete */
+#define pthread_cond_wait(a, b) SleepConditionVariableCS((a), (b), INFINITE)
+#define pthread_cond_signal(a) WakeConditionVariable((a))
+#define pthread_cond_broadcast(a) WakeAllConditionVariable((a))
+
+/* pthread_create() and pthread_join() */
+typedef struct {
+ HANDLE handle;
+ void* (*start_routine)(void*);
+ void* arg;
+} pthread_t;
+
+int pthread_create(pthread_t* thread, const void* unused,
+ void* (*start_routine) (void*), void* arg);
+
+#define pthread_join(a, b) _pthread_join(&(a), (b))
+int _pthread_join(pthread_t* thread, void** value_ptr);
+
+/**
+ * add here more wrappers as required
+ */
+
+
+#elif defined(ZSTD_MULTITHREAD) /* posix assumed ; need a better detection method */
+/* === POSIX Systems === */
+# include <pthread.h>
+
+#else /* ZSTD_MULTITHREAD not defined */
+/* No multithreading support */
+
+#define pthread_mutex_t int /* #define rather than typedef, as sometimes pthread support is implicit, resulting in duplicated symbols */
+#define pthread_mutex_init(a,b)
+#define pthread_mutex_destroy(a)
+#define pthread_mutex_lock(a)
+#define pthread_mutex_unlock(a)
+
+#define pthread_cond_t int
+#define pthread_cond_init(a,b)
+#define pthread_cond_destroy(a)
+#define pthread_cond_wait(a,b)
+#define pthread_cond_signal(a)
+#define pthread_cond_broadcast(a)
+
+/* do not use pthread_t */
+
+#endif /* ZSTD_MULTITHREAD */
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* THREADING_H_938743 */
diff --git a/thirdparty/zstd/common/xxhash.c b/thirdparty/zstd/common/xxhash.c
new file mode 100644
index 0000000000..eb44222c5f
--- /dev/null
+++ b/thirdparty/zstd/common/xxhash.c
@@ -0,0 +1,869 @@
+/*
+* xxHash - Fast Hash algorithm
+* Copyright (C) 2012-2016, Yann Collet
+*
+* BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions are
+* met:
+*
+* * Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+* * Redistributions in binary form must reproduce the above
+* copyright notice, this list of conditions and the following disclaimer
+* in the documentation and/or other materials provided with the
+* distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+* You can contact the author at :
+* - xxHash homepage: http://www.xxhash.com
+* - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+
+/* *************************************
+* Tuning parameters
+***************************************/
+/*!XXH_FORCE_MEMORY_ACCESS :
+ * By default, access to unaligned memory is controlled by `memcpy()`, which is safe and portable.
+ * Unfortunately, on some target/compiler combinations, the generated assembly is sub-optimal.
+ * The below switch allow to select different access method for improved performance.
+ * Method 0 (default) : use `memcpy()`. Safe and portable.
+ * Method 1 : `__packed` statement. It depends on compiler extension (ie, not portable).
+ * This method is safe if your compiler supports it, and *generally* as fast or faster than `memcpy`.
+ * Method 2 : direct access. This method doesn't depend on compiler but violate C standard.
+ * It can generate buggy code on targets which do not support unaligned memory accesses.
+ * But in some circumstances, it's the only known way to get the most performance (ie GCC + ARMv6)
+ * See http://stackoverflow.com/a/32095106/646947 for details.
+ * Prefer these methods in priority order (0 > 1 > 2)
+ */
+#ifndef XXH_FORCE_MEMORY_ACCESS /* can be defined externally, on command line for example */
+# if defined(__GNUC__) && ( defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) )
+# define XXH_FORCE_MEMORY_ACCESS 2
+# elif (defined(__INTEL_COMPILER) && !defined(WIN32)) || \
+ (defined(__GNUC__) && ( defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__) ))
+# define XXH_FORCE_MEMORY_ACCESS 1
+# endif
+#endif
+
+/*!XXH_ACCEPT_NULL_INPUT_POINTER :
+ * If the input pointer is a null pointer, xxHash default behavior is to trigger a memory access error, since it is a bad pointer.
+ * When this option is enabled, xxHash output for null input pointers will be the same as a null-length input.
+ * By default, this option is disabled. To enable it, uncomment below define :
+ */
+/* #define XXH_ACCEPT_NULL_INPUT_POINTER 1 */
+
+/*!XXH_FORCE_NATIVE_FORMAT :
+ * By default, xxHash library provides endian-independant Hash values, based on little-endian convention.
+ * Results are therefore identical for little-endian and big-endian CPU.
+ * This comes at a performance cost for big-endian CPU, since some swapping is required to emulate little-endian format.
+ * Should endian-independance be of no importance for your application, you may set the #define below to 1,
+ * to improve speed for Big-endian CPU.
+ * This option has no impact on Little_Endian CPU.
+ */
+#ifndef XXH_FORCE_NATIVE_FORMAT /* can be defined externally */
+# define XXH_FORCE_NATIVE_FORMAT 0
+#endif
+
+/*!XXH_FORCE_ALIGN_CHECK :
+ * This is a minor performance trick, only useful with lots of very small keys.
+ * It means : check for aligned/unaligned input.
+ * The check costs one initial branch per hash; set to 0 when the input data
+ * is guaranteed to be aligned.
+ */
+#ifndef XXH_FORCE_ALIGN_CHECK /* can be defined externally */
+# if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
+# define XXH_FORCE_ALIGN_CHECK 0
+# else
+# define XXH_FORCE_ALIGN_CHECK 1
+# endif
+#endif
+
+
+/* *************************************
+* Includes & Memory related functions
+***************************************/
+/* Modify the local functions below should you wish to use some other memory routines */
+/* for malloc(), free() */
+#include <stdlib.h>
+static void* XXH_malloc(size_t s) { return malloc(s); }
+static void XXH_free (void* p) { free(p); }
+/* for memcpy() */
+#include <string.h>
+static void* XXH_memcpy(void* dest, const void* src, size_t size) { return memcpy(dest,src,size); }
+
+#ifndef XXH_STATIC_LINKING_ONLY
+# define XXH_STATIC_LINKING_ONLY
+#endif
+#include "xxhash.h"
+
+
+/* *************************************
+* Compiler Specific Options
+***************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# define FORCE_INLINE static __forceinline
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* *************************************
+* Basic Types
+***************************************/
+#ifndef MEM_MODULE
+# define MEM_MODULE
+# if !defined (__VMS) && (defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */) )
+# include <stdint.h>
+ typedef uint8_t BYTE;
+ typedef uint16_t U16;
+ typedef uint32_t U32;
+ typedef int32_t S32;
+ typedef uint64_t U64;
+# else
+ typedef unsigned char BYTE;
+ typedef unsigned short U16;
+ typedef unsigned int U32;
+ typedef signed int S32;
+ typedef unsigned long long U64; /* if your compiler doesn't support unsigned long long, replace by another 64-bit type here. Note that xxhash.h will also need to be updated. */
+# endif
+#endif
+
+
+#if (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==2))
+
+/* Force direct memory access. Only works on CPU which support unaligned memory access in hardware */
+static U32 XXH_read32(const void* memPtr) { return *(const U32*) memPtr; }
+static U64 XXH_read64(const void* memPtr) { return *(const U64*) memPtr; }
+
+#elif (defined(XXH_FORCE_MEMORY_ACCESS) && (XXH_FORCE_MEMORY_ACCESS==1))
+
+/* __pack instructions are safer, but compiler specific, hence potentially problematic for some compilers */
+/* currently only defined for gcc and icc */
+typedef union { U32 u32; U64 u64; } __attribute__((packed)) unalign;
+
+static U32 XXH_read32(const void* ptr) { return ((const unalign*)ptr)->u32; }
+static U64 XXH_read64(const void* ptr) { return ((const unalign*)ptr)->u64; }
+
+#else
+
+/* portable and safe solution. Generally efficient.
+ * see : http://stackoverflow.com/a/32095106/646947
+ */
+
+static U32 XXH_read32(const void* memPtr)
+{
+ U32 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+static U64 XXH_read64(const void* memPtr)
+{
+ U64 val;
+ memcpy(&val, memPtr, sizeof(val));
+ return val;
+}
+
+#endif /* XXH_FORCE_DIRECT_MEMORY_ACCESS */
+
+
+/* ****************************************
+* Compiler-specific Functions and Macros
+******************************************/
+#define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
+
+/* Note : although _rotl exists for minGW (GCC under windows), performance seems poor */
+#if defined(_MSC_VER)
+# define XXH_rotl32(x,r) _rotl(x,r)
+# define XXH_rotl64(x,r) _rotl64(x,r)
+#else
+# define XXH_rotl32(x,r) ((x << r) | (x >> (32 - r)))
+# define XXH_rotl64(x,r) ((x << r) | (x >> (64 - r)))
+#endif
+
+#if defined(_MSC_VER) /* Visual Studio */
+# define XXH_swap32 _byteswap_ulong
+# define XXH_swap64 _byteswap_uint64
+#elif GCC_VERSION >= 403
+# define XXH_swap32 __builtin_bswap32
+# define XXH_swap64 __builtin_bswap64
+#else
+static U32 XXH_swap32 (U32 x)
+{
+ return ((x << 24) & 0xff000000 ) |
+ ((x << 8) & 0x00ff0000 ) |
+ ((x >> 8) & 0x0000ff00 ) |
+ ((x >> 24) & 0x000000ff );
+}
+static U64 XXH_swap64 (U64 x)
+{
+ return ((x << 56) & 0xff00000000000000ULL) |
+ ((x << 40) & 0x00ff000000000000ULL) |
+ ((x << 24) & 0x0000ff0000000000ULL) |
+ ((x << 8) & 0x000000ff00000000ULL) |
+ ((x >> 8) & 0x00000000ff000000ULL) |
+ ((x >> 24) & 0x0000000000ff0000ULL) |
+ ((x >> 40) & 0x000000000000ff00ULL) |
+ ((x >> 56) & 0x00000000000000ffULL);
+}
+#endif
+
+
+/* *************************************
+* Architecture Macros
+***************************************/
+typedef enum { XXH_bigEndian=0, XXH_littleEndian=1 } XXH_endianess;
+
+/* XXH_CPU_LITTLE_ENDIAN can be defined externally, for example on the compiler command line */
+#ifndef XXH_CPU_LITTLE_ENDIAN
+ static const int g_one = 1;
+# define XXH_CPU_LITTLE_ENDIAN (*(const char*)(&g_one))
+#endif
+
+
+/* ***************************
+* Memory reads
+*****************************/
+typedef enum { XXH_aligned, XXH_unaligned } XXH_alignment;
+
+FORCE_INLINE U32 XXH_readLE32_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read32(ptr) : XXH_swap32(XXH_read32(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U32*)ptr : XXH_swap32(*(const U32*)ptr);
+}
+
+FORCE_INLINE U32 XXH_readLE32(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE32_align(ptr, endian, XXH_unaligned);
+}
+
+static U32 XXH_readBE32(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap32(XXH_read32(ptr)) : XXH_read32(ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64_align(const void* ptr, XXH_endianess endian, XXH_alignment align)
+{
+ if (align==XXH_unaligned)
+ return endian==XXH_littleEndian ? XXH_read64(ptr) : XXH_swap64(XXH_read64(ptr));
+ else
+ return endian==XXH_littleEndian ? *(const U64*)ptr : XXH_swap64(*(const U64*)ptr);
+}
+
+FORCE_INLINE U64 XXH_readLE64(const void* ptr, XXH_endianess endian)
+{
+ return XXH_readLE64_align(ptr, endian, XXH_unaligned);
+}
+
+static U64 XXH_readBE64(const void* ptr)
+{
+ return XXH_CPU_LITTLE_ENDIAN ? XXH_swap64(XXH_read64(ptr)) : XXH_read64(ptr);
+}
+
+
+/* *************************************
+* Macros
+***************************************/
+#define XXH_STATIC_ASSERT(c) { enum { XXH_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+
+
+/* *************************************
+* Constants
+***************************************/
+static const U32 PRIME32_1 = 2654435761U;
+static const U32 PRIME32_2 = 2246822519U;
+static const U32 PRIME32_3 = 3266489917U;
+static const U32 PRIME32_4 = 668265263U;
+static const U32 PRIME32_5 = 374761393U;
+
+static const U64 PRIME64_1 = 11400714785074694791ULL;
+static const U64 PRIME64_2 = 14029467366897019727ULL;
+static const U64 PRIME64_3 = 1609587929392839161ULL;
+static const U64 PRIME64_4 = 9650029242287828579ULL;
+static const U64 PRIME64_5 = 2870177450012600261ULL;
+
+XXH_PUBLIC_API unsigned XXH_versionNumber (void) { return XXH_VERSION_NUMBER; }
+
+
+/* **************************
+* Utils
+****************************/
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dstState, const XXH32_state_t* restrict srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dstState, const XXH64_state_t* restrict srcState)
+{
+ memcpy(dstState, srcState, sizeof(*dstState));
+}
+
+
+/* ***************************
+* Simple Hash Functions
+*****************************/
+
+static U32 XXH32_round(U32 seed, U32 input)
+{
+ seed += input * PRIME32_2;
+ seed = XXH_rotl32(seed, 13);
+ seed *= PRIME32_1;
+ return seed;
+}
+
+FORCE_INLINE U32 XXH32_endian_align(const void* input, size_t len, U32 seed, XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* bEnd = p + len;
+ U32 h32;
+#define XXH_get32bits(p) XXH_readLE32_align(p, endian, align)
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)16;
+ }
+#endif
+
+ if (len>=16) {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = seed + PRIME32_1 + PRIME32_2;
+ U32 v2 = seed + PRIME32_2;
+ U32 v3 = seed + 0;
+ U32 v4 = seed - PRIME32_1;
+
+ do {
+ v1 = XXH32_round(v1, XXH_get32bits(p)); p+=4;
+ v2 = XXH32_round(v2, XXH_get32bits(p)); p+=4;
+ v3 = XXH32_round(v3, XXH_get32bits(p)); p+=4;
+ v4 = XXH32_round(v4, XXH_get32bits(p)); p+=4;
+ } while (p<=limit);
+
+ h32 = XXH_rotl32(v1, 1) + XXH_rotl32(v2, 7) + XXH_rotl32(v3, 12) + XXH_rotl32(v4, 18);
+ } else {
+ h32 = seed + PRIME32_5;
+ }
+
+ h32 += (U32) len;
+
+ while (p+4<=bEnd) {
+ h32 += XXH_get32bits(p) * PRIME32_3;
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4 ;
+ p+=4;
+ }
+
+ while (p<bEnd) {
+ h32 += (*p) * PRIME32_5;
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1 ;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32 (const void* input, size_t len, unsigned int seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH32_CREATESTATE_STATIC(state);
+ XXH32_reset(state, seed);
+ XXH32_update(state, input, len);
+ return XXH32_digest(state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 3) == 0) { /* Input is 4-bytes aligned, leverage the speed benefit */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH32_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+
+static U64 XXH64_round(U64 acc, U64 input)
+{
+ acc += input * PRIME64_2;
+ acc = XXH_rotl64(acc, 31);
+ acc *= PRIME64_1;
+ return acc;
+}
+
+static U64 XXH64_mergeRound(U64 acc, U64 val)
+{
+ val = XXH64_round(0, val);
+ acc ^= val;
+ acc = acc * PRIME64_1 + PRIME64_4;
+ return acc;
+}
+
+FORCE_INLINE U64 XXH64_endian_align(const void* input, size_t len, U64 seed, XXH_endianess endian, XXH_alignment align)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+ U64 h64;
+#define XXH_get64bits(p) XXH_readLE64_align(p, endian, align)
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (p==NULL) {
+ len=0;
+ bEnd=p=(const BYTE*)(size_t)32;
+ }
+#endif
+
+ if (len>=32) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = seed + PRIME64_1 + PRIME64_2;
+ U64 v2 = seed + PRIME64_2;
+ U64 v3 = seed + 0;
+ U64 v4 = seed - PRIME64_1;
+
+ do {
+ v1 = XXH64_round(v1, XXH_get64bits(p)); p+=8;
+ v2 = XXH64_round(v2, XXH_get64bits(p)); p+=8;
+ v3 = XXH64_round(v3, XXH_get64bits(p)); p+=8;
+ v4 = XXH64_round(v4, XXH_get64bits(p)); p+=8;
+ } while (p<=limit);
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+
+ } else {
+ h64 = seed + PRIME64_5;
+ }
+
+ h64 += (U64) len;
+
+ while (p+8<=bEnd) {
+ U64 const k1 = XXH64_round(0, XXH_get64bits(p));
+ h64 ^= k1;
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
+ p+=8;
+ }
+
+ if (p+4<=bEnd) {
+ h64 ^= (U64)(XXH_get32bits(p)) * PRIME64_1;
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+ p+=4;
+ }
+
+ while (p<bEnd) {
+ h64 ^= (*p) * PRIME64_5;
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
+ p++;
+ }
+
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+
+ return h64;
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64 (const void* input, size_t len, unsigned long long seed)
+{
+#if 0
+ /* Simple version, good for code maintenance, but unfortunately slow for small inputs */
+ XXH64_CREATESTATE_STATIC(state);
+ XXH64_reset(state, seed);
+ XXH64_update(state, input, len);
+ return XXH64_digest(state);
+#else
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if (XXH_FORCE_ALIGN_CHECK) {
+ if ((((size_t)input) & 7)==0) { /* Input is aligned, let's leverage the speed advantage */
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_aligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_aligned);
+ } }
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_endian_align(input, len, seed, XXH_littleEndian, XXH_unaligned);
+ else
+ return XXH64_endian_align(input, len, seed, XXH_bigEndian, XXH_unaligned);
+#endif
+}
+
+
+/* **************************************************
+* Advanced Hash Functions
+****************************************************/
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void)
+{
+ return (XXH32_state_t*)XXH_malloc(sizeof(XXH32_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void)
+{
+ return (XXH64_state_t*)XXH_malloc(sizeof(XXH64_state_t));
+}
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr)
+{
+ XXH_free(statePtr);
+ return XXH_OK;
+}
+
+
+/*** Hash feed ***/
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset(XXH32_state_t* statePtr, unsigned int seed)
+{
+ XXH32_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state)-4); /* do not write into reserved, for future removal */
+ state.v1 = seed + PRIME32_1 + PRIME32_2;
+ state.v2 = seed + PRIME32_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME32_1;
+ memcpy(statePtr, &state, sizeof(state));
+ return XXH_OK;
+}
+
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset(XXH64_state_t* statePtr, unsigned long long seed)
+{
+ XXH64_state_t state; /* using a local state to memcpy() in order to avoid strict-aliasing warnings */
+ memset(&state, 0, sizeof(state)-8); /* do not write into reserved, for future removal */
+ state.v1 = seed + PRIME64_1 + PRIME64_2;
+ state.v2 = seed + PRIME64_2;
+ state.v3 = seed + 0;
+ state.v4 = seed - PRIME64_1;
+ memcpy(statePtr, &state, sizeof(state));
+ return XXH_OK;
+}
+
+
+FORCE_INLINE XXH_errorcode XXH32_update_endian (XXH32_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (input==NULL) return XXH_ERROR;
+#endif
+
+ state->total_len_32 += (unsigned)len;
+ state->large_len |= (len>=16) | (state->total_len_32>=16);
+
+ if (state->memsize + len < 16) { /* fill in tmp buffer */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, len);
+ state->memsize += (unsigned)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* some data left from previous update */
+ XXH_memcpy((BYTE*)(state->mem32) + state->memsize, input, 16-state->memsize);
+ { const U32* p32 = state->mem32;
+ state->v1 = XXH32_round(state->v1, XXH_readLE32(p32, endian)); p32++;
+ state->v2 = XXH32_round(state->v2, XXH_readLE32(p32, endian)); p32++;
+ state->v3 = XXH32_round(state->v3, XXH_readLE32(p32, endian)); p32++;
+ state->v4 = XXH32_round(state->v4, XXH_readLE32(p32, endian)); p32++;
+ }
+ p += 16-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p <= bEnd-16) {
+ const BYTE* const limit = bEnd - 16;
+ U32 v1 = state->v1;
+ U32 v2 = state->v2;
+ U32 v3 = state->v3;
+ U32 v4 = state->v4;
+
+ do {
+ v1 = XXH32_round(v1, XXH_readLE32(p, endian)); p+=4;
+ v2 = XXH32_round(v2, XXH_readLE32(p, endian)); p+=4;
+ v3 = XXH32_round(v3, XXH_readLE32(p, endian)); p+=4;
+ v4 = XXH32_round(v4, XXH_readLE32(p, endian)); p+=4;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem32, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH32_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+
+FORCE_INLINE U32 XXH32_digest_endian (const XXH32_state_t* state, XXH_endianess endian)
+{
+ const BYTE * p = (const BYTE*)state->mem32;
+ const BYTE* const bEnd = (const BYTE*)(state->mem32) + state->memsize;
+ U32 h32;
+
+ if (state->large_len) {
+ h32 = XXH_rotl32(state->v1, 1) + XXH_rotl32(state->v2, 7) + XXH_rotl32(state->v3, 12) + XXH_rotl32(state->v4, 18);
+ } else {
+ h32 = state->v3 /* == seed */ + PRIME32_5;
+ }
+
+ h32 += state->total_len_32;
+
+ while (p+4<=bEnd) {
+ h32 += XXH_readLE32(p, endian) * PRIME32_3;
+ h32 = XXH_rotl32(h32, 17) * PRIME32_4;
+ p+=4;
+ }
+
+ while (p<bEnd) {
+ h32 += (*p) * PRIME32_5;
+ h32 = XXH_rotl32(h32, 11) * PRIME32_1;
+ p++;
+ }
+
+ h32 ^= h32 >> 15;
+ h32 *= PRIME32_2;
+ h32 ^= h32 >> 13;
+ h32 *= PRIME32_3;
+ h32 ^= h32 >> 16;
+
+ return h32;
+}
+
+
+XXH_PUBLIC_API unsigned int XXH32_digest (const XXH32_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH32_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH32_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+
+/* **** XXH64 **** */
+
+FORCE_INLINE XXH_errorcode XXH64_update_endian (XXH64_state_t* state, const void* input, size_t len, XXH_endianess endian)
+{
+ const BYTE* p = (const BYTE*)input;
+ const BYTE* const bEnd = p + len;
+
+#ifdef XXH_ACCEPT_NULL_INPUT_POINTER
+ if (input==NULL) return XXH_ERROR;
+#endif
+
+ state->total_len += len;
+
+ if (state->memsize + len < 32) { /* fill in tmp buffer */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, len);
+ state->memsize += (U32)len;
+ return XXH_OK;
+ }
+
+ if (state->memsize) { /* tmp buffer is full */
+ XXH_memcpy(((BYTE*)state->mem64) + state->memsize, input, 32-state->memsize);
+ state->v1 = XXH64_round(state->v1, XXH_readLE64(state->mem64+0, endian));
+ state->v2 = XXH64_round(state->v2, XXH_readLE64(state->mem64+1, endian));
+ state->v3 = XXH64_round(state->v3, XXH_readLE64(state->mem64+2, endian));
+ state->v4 = XXH64_round(state->v4, XXH_readLE64(state->mem64+3, endian));
+ p += 32-state->memsize;
+ state->memsize = 0;
+ }
+
+ if (p+32 <= bEnd) {
+ const BYTE* const limit = bEnd - 32;
+ U64 v1 = state->v1;
+ U64 v2 = state->v2;
+ U64 v3 = state->v3;
+ U64 v4 = state->v4;
+
+ do {
+ v1 = XXH64_round(v1, XXH_readLE64(p, endian)); p+=8;
+ v2 = XXH64_round(v2, XXH_readLE64(p, endian)); p+=8;
+ v3 = XXH64_round(v3, XXH_readLE64(p, endian)); p+=8;
+ v4 = XXH64_round(v4, XXH_readLE64(p, endian)); p+=8;
+ } while (p<=limit);
+
+ state->v1 = v1;
+ state->v2 = v2;
+ state->v3 = v3;
+ state->v4 = v4;
+ }
+
+ if (p < bEnd) {
+ XXH_memcpy(state->mem64, p, (size_t)(bEnd-p));
+ state->memsize = (unsigned)(bEnd-p);
+ }
+
+ return XXH_OK;
+}
+
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* state_in, const void* input, size_t len)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_update_endian(state_in, input, len, XXH_littleEndian);
+ else
+ return XXH64_update_endian(state_in, input, len, XXH_bigEndian);
+}
+
+
+
+FORCE_INLINE U64 XXH64_digest_endian (const XXH64_state_t* state, XXH_endianess endian)
+{
+ const BYTE * p = (const BYTE*)state->mem64;
+ const BYTE* const bEnd = (const BYTE*)state->mem64 + state->memsize;
+ U64 h64;
+
+ if (state->total_len >= 32) {
+ U64 const v1 = state->v1;
+ U64 const v2 = state->v2;
+ U64 const v3 = state->v3;
+ U64 const v4 = state->v4;
+
+ h64 = XXH_rotl64(v1, 1) + XXH_rotl64(v2, 7) + XXH_rotl64(v3, 12) + XXH_rotl64(v4, 18);
+ h64 = XXH64_mergeRound(h64, v1);
+ h64 = XXH64_mergeRound(h64, v2);
+ h64 = XXH64_mergeRound(h64, v3);
+ h64 = XXH64_mergeRound(h64, v4);
+ } else {
+ h64 = state->v3 + PRIME64_5;
+ }
+
+ h64 += (U64) state->total_len;
+
+ while (p+8<=bEnd) {
+ U64 const k1 = XXH64_round(0, XXH_readLE64(p, endian));
+ h64 ^= k1;
+ h64 = XXH_rotl64(h64,27) * PRIME64_1 + PRIME64_4;
+ p+=8;
+ }
+
+ if (p+4<=bEnd) {
+ h64 ^= (U64)(XXH_readLE32(p, endian)) * PRIME64_1;
+ h64 = XXH_rotl64(h64, 23) * PRIME64_2 + PRIME64_3;
+ p+=4;
+ }
+
+ while (p<bEnd) {
+ h64 ^= (*p) * PRIME64_5;
+ h64 = XXH_rotl64(h64, 11) * PRIME64_1;
+ p++;
+ }
+
+ h64 ^= h64 >> 33;
+ h64 *= PRIME64_2;
+ h64 ^= h64 >> 29;
+ h64 *= PRIME64_3;
+ h64 ^= h64 >> 32;
+
+ return h64;
+}
+
+
+XXH_PUBLIC_API unsigned long long XXH64_digest (const XXH64_state_t* state_in)
+{
+ XXH_endianess endian_detected = (XXH_endianess)XXH_CPU_LITTLE_ENDIAN;
+
+ if ((endian_detected==XXH_littleEndian) || XXH_FORCE_NATIVE_FORMAT)
+ return XXH64_digest_endian(state_in, XXH_littleEndian);
+ else
+ return XXH64_digest_endian(state_in, XXH_bigEndian);
+}
+
+
+/* **************************
+* Canonical representation
+****************************/
+
+/*! Default XXH result types are basic unsigned 32 and 64 bits.
+* The canonical representation follows human-readable write convention, aka big-endian (large digits first).
+* These functions allow transformation of hash result into and from its canonical format.
+* This way, hash values can be written into a file or buffer, and remain comparable across different systems and programs.
+*/
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH32_canonical_t) == sizeof(XXH32_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap32(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash)
+{
+ XXH_STATIC_ASSERT(sizeof(XXH64_canonical_t) == sizeof(XXH64_hash_t));
+ if (XXH_CPU_LITTLE_ENDIAN) hash = XXH_swap64(hash);
+ memcpy(dst, &hash, sizeof(*dst));
+}
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src)
+{
+ return XXH_readBE32(src);
+}
+
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src)
+{
+ return XXH_readBE64(src);
+}
diff --git a/thirdparty/zstd/common/xxhash.h b/thirdparty/zstd/common/xxhash.h
new file mode 100644
index 0000000000..9bad1f59f6
--- /dev/null
+++ b/thirdparty/zstd/common/xxhash.h
@@ -0,0 +1,305 @@
+/*
+ xxHash - Extremely Fast Hash algorithm
+ Header File
+ Copyright (C) 2012-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - xxHash source repository : https://github.com/Cyan4973/xxHash
+*/
+
+/* Notice extracted from xxHash homepage :
+
+xxHash is an extremely fast Hash algorithm, running at RAM speed limits.
+It also successfully passes all tests from the SMHasher suite.
+
+Comparison (single thread, Windows Seven 32 bits, using SMHasher on a Core 2 Duo @3GHz)
+
+Name Speed Q.Score Author
+xxHash 5.4 GB/s 10
+CrapWow 3.2 GB/s 2 Andrew
+MumurHash 3a 2.7 GB/s 10 Austin Appleby
+SpookyHash 2.0 GB/s 10 Bob Jenkins
+SBox 1.4 GB/s 9 Bret Mulvey
+Lookup3 1.2 GB/s 9 Bob Jenkins
+SuperFastHash 1.2 GB/s 1 Paul Hsieh
+CityHash64 1.05 GB/s 10 Pike & Alakuijala
+FNV 0.55 GB/s 5 Fowler, Noll, Vo
+CRC32 0.43 GB/s 9
+MD5-32 0.33 GB/s 10 Ronald L. Rivest
+SHA1-32 0.28 GB/s 10
+
+Q.Score is a measure of quality of the hash function.
+It depends on successfully passing SMHasher test set.
+10 is a perfect score.
+
+A 64-bits version, named XXH64, is available since r35.
+It offers much better speed, but for 64-bits applications only.
+Name Speed on 64 bits Speed on 32 bits
+XXH64 13.8 GB/s 1.9 GB/s
+XXH32 6.8 GB/s 6.0 GB/s
+*/
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#ifndef XXHASH_H_5627135585666179
+#define XXHASH_H_5627135585666179 1
+
+
+/* ****************************
+* Definitions
+******************************/
+#include <stddef.h> /* size_t */
+typedef enum { XXH_OK=0, XXH_ERROR } XXH_errorcode;
+
+
+/* ****************************
+* API modifier
+******************************/
+/** XXH_PRIVATE_API
+* This is useful if you want to include xxhash functions in `static` mode
+* in order to inline them, and remove their symbol from the public list.
+* Methodology :
+* #define XXH_PRIVATE_API
+* #include "xxhash.h"
+* `xxhash.c` is automatically included.
+* It's not useful to compile and link it as a separate module anymore.
+*/
+#ifdef XXH_PRIVATE_API
+# ifndef XXH_STATIC_LINKING_ONLY
+# define XXH_STATIC_LINKING_ONLY
+# endif
+# if defined(__GNUC__)
+# define XXH_PUBLIC_API static __inline __attribute__((unused))
+# elif defined (__cplusplus) || (defined (__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) /* C99 */)
+# define XXH_PUBLIC_API static inline
+# elif defined(_MSC_VER)
+# define XXH_PUBLIC_API static __inline
+# else
+# define XXH_PUBLIC_API static /* this version may generate warnings for unused static functions; disable the relevant warning */
+# endif
+#else
+# define XXH_PUBLIC_API /* do nothing */
+#endif /* XXH_PRIVATE_API */
+
+/*!XXH_NAMESPACE, aka Namespace Emulation :
+
+If you want to include _and expose_ xxHash functions from within your own library,
+but also want to avoid symbol collisions with another library which also includes xxHash,
+
+you can use XXH_NAMESPACE, to automatically prefix any public symbol from xxhash library
+with the value of XXH_NAMESPACE (so avoid to keep it NULL and avoid numeric values).
+
+Note that no change is required within the calling program as long as it includes `xxhash.h` :
+regular symbol name will be automatically translated by this header.
+*/
+#ifdef XXH_NAMESPACE
+# define XXH_CAT(A,B) A##B
+# define XXH_NAME2(A,B) XXH_CAT(A,B)
+# define XXH32 XXH_NAME2(XXH_NAMESPACE, XXH32)
+# define XXH64 XXH_NAME2(XXH_NAMESPACE, XXH64)
+# define XXH_versionNumber XXH_NAME2(XXH_NAMESPACE, XXH_versionNumber)
+# define XXH32_createState XXH_NAME2(XXH_NAMESPACE, XXH32_createState)
+# define XXH64_createState XXH_NAME2(XXH_NAMESPACE, XXH64_createState)
+# define XXH32_freeState XXH_NAME2(XXH_NAMESPACE, XXH32_freeState)
+# define XXH64_freeState XXH_NAME2(XXH_NAMESPACE, XXH64_freeState)
+# define XXH32_reset XXH_NAME2(XXH_NAMESPACE, XXH32_reset)
+# define XXH64_reset XXH_NAME2(XXH_NAMESPACE, XXH64_reset)
+# define XXH32_update XXH_NAME2(XXH_NAMESPACE, XXH32_update)
+# define XXH64_update XXH_NAME2(XXH_NAMESPACE, XXH64_update)
+# define XXH32_digest XXH_NAME2(XXH_NAMESPACE, XXH32_digest)
+# define XXH64_digest XXH_NAME2(XXH_NAMESPACE, XXH64_digest)
+# define XXH32_copyState XXH_NAME2(XXH_NAMESPACE, XXH32_copyState)
+# define XXH64_copyState XXH_NAME2(XXH_NAMESPACE, XXH64_copyState)
+# define XXH32_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH32_canonicalFromHash)
+# define XXH64_canonicalFromHash XXH_NAME2(XXH_NAMESPACE, XXH64_canonicalFromHash)
+# define XXH32_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH32_hashFromCanonical)
+# define XXH64_hashFromCanonical XXH_NAME2(XXH_NAMESPACE, XXH64_hashFromCanonical)
+#endif
+
+
+/* *************************************
+* Version
+***************************************/
+#define XXH_VERSION_MAJOR 0
+#define XXH_VERSION_MINOR 6
+#define XXH_VERSION_RELEASE 2
+#define XXH_VERSION_NUMBER (XXH_VERSION_MAJOR *100*100 + XXH_VERSION_MINOR *100 + XXH_VERSION_RELEASE)
+XXH_PUBLIC_API unsigned XXH_versionNumber (void);
+
+
+/* ****************************
+* Simple Hash Functions
+******************************/
+typedef unsigned int XXH32_hash_t;
+typedef unsigned long long XXH64_hash_t;
+
+XXH_PUBLIC_API XXH32_hash_t XXH32 (const void* input, size_t length, unsigned int seed);
+XXH_PUBLIC_API XXH64_hash_t XXH64 (const void* input, size_t length, unsigned long long seed);
+
+/*!
+XXH32() :
+ Calculate the 32-bits hash of sequence "length" bytes stored at memory address "input".
+ The memory between input & input+length must be valid (allocated and read-accessible).
+ "seed" can be used to alter the result predictably.
+ Speed on Core 2 Duo @ 3 GHz (single thread, SMHasher benchmark) : 5.4 GB/s
+XXH64() :
+ Calculate the 64-bits hash of sequence of length "len" stored at memory address "input".
+ "seed" can be used to alter the result predictably.
+ This function runs 2x faster on 64-bits systems, but slower on 32-bits systems (see benchmark).
+*/
+
+
+/* ****************************
+* Streaming Hash Functions
+******************************/
+typedef struct XXH32_state_s XXH32_state_t; /* incomplete type */
+typedef struct XXH64_state_s XXH64_state_t; /* incomplete type */
+
+/*! State allocation, compatible with dynamic libraries */
+
+XXH_PUBLIC_API XXH32_state_t* XXH32_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH32_freeState(XXH32_state_t* statePtr);
+
+XXH_PUBLIC_API XXH64_state_t* XXH64_createState(void);
+XXH_PUBLIC_API XXH_errorcode XXH64_freeState(XXH64_state_t* statePtr);
+
+
+/* hash streaming */
+
+XXH_PUBLIC_API XXH_errorcode XXH32_reset (XXH32_state_t* statePtr, unsigned int seed);
+XXH_PUBLIC_API XXH_errorcode XXH32_update (XXH32_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH32_hash_t XXH32_digest (const XXH32_state_t* statePtr);
+
+XXH_PUBLIC_API XXH_errorcode XXH64_reset (XXH64_state_t* statePtr, unsigned long long seed);
+XXH_PUBLIC_API XXH_errorcode XXH64_update (XXH64_state_t* statePtr, const void* input, size_t length);
+XXH_PUBLIC_API XXH64_hash_t XXH64_digest (const XXH64_state_t* statePtr);
+
+/*
+These functions generate the xxHash of an input provided in multiple segments.
+Note that, for small input, they are slower than single-call functions, due to state management.
+For small input, prefer `XXH32()` and `XXH64()` .
+
+XXH state must first be allocated, using XXH*_createState() .
+
+Start a new hash by initializing state with a seed, using XXH*_reset().
+
+Then, feed the hash state by calling XXH*_update() as many times as necessary.
+Obviously, input must be allocated and read accessible.
+The function returns an error code, with 0 meaning OK, and any other value meaning there is an error.
+
+Finally, a hash value can be produced anytime, by using XXH*_digest().
+This function returns the nn-bits hash as an int or long long.
+
+It's still possible to continue inserting input into the hash state after a digest,
+and generate some new hashes later on, by calling again XXH*_digest().
+
+When done, free XXH state space if it was allocated dynamically.
+*/
+
+
+/* **************************
+* Utils
+****************************/
+#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) /* ! C99 */
+# define restrict /* disable restrict */
+#endif
+
+XXH_PUBLIC_API void XXH32_copyState(XXH32_state_t* restrict dst_state, const XXH32_state_t* restrict src_state);
+XXH_PUBLIC_API void XXH64_copyState(XXH64_state_t* restrict dst_state, const XXH64_state_t* restrict src_state);
+
+
+/* **************************
+* Canonical representation
+****************************/
+/* Default result type for XXH functions are primitive unsigned 32 and 64 bits.
+* The canonical representation uses human-readable write convention, aka big-endian (large digits first).
+* These functions allow transformation of hash result into and from its canonical format.
+* This way, hash values can be written into a file / memory, and remain comparable on different systems and programs.
+*/
+typedef struct { unsigned char digest[4]; } XXH32_canonical_t;
+typedef struct { unsigned char digest[8]; } XXH64_canonical_t;
+
+XXH_PUBLIC_API void XXH32_canonicalFromHash(XXH32_canonical_t* dst, XXH32_hash_t hash);
+XXH_PUBLIC_API void XXH64_canonicalFromHash(XXH64_canonical_t* dst, XXH64_hash_t hash);
+
+XXH_PUBLIC_API XXH32_hash_t XXH32_hashFromCanonical(const XXH32_canonical_t* src);
+XXH_PUBLIC_API XXH64_hash_t XXH64_hashFromCanonical(const XXH64_canonical_t* src);
+
+#endif /* XXHASH_H_5627135585666179 */
+
+
+
+/* ================================================================================================
+ This section contains definitions which are not guaranteed to remain stable.
+ They may change in future versions, becoming incompatible with a different version of the library.
+ They shall only be used with static linking.
+ Never use these definitions in association with dynamic linking !
+=================================================================================================== */
+#if defined(XXH_STATIC_LINKING_ONLY) && !defined(XXH_STATIC_H_3543687687345)
+#define XXH_STATIC_H_3543687687345
+
+/* These definitions are only meant to allow allocation of XXH state
+ statically, on stack, or in a struct for example.
+ Do not use members directly. */
+
+ struct XXH32_state_s {
+ unsigned total_len_32;
+ unsigned large_len;
+ unsigned v1;
+ unsigned v2;
+ unsigned v3;
+ unsigned v4;
+ unsigned mem32[4]; /* buffer defined as U32 for alignment */
+ unsigned memsize;
+ unsigned reserved; /* never read nor write, will be removed in a future version */
+ }; /* typedef'd to XXH32_state_t */
+
+ struct XXH64_state_s {
+ unsigned long long total_len;
+ unsigned long long v1;
+ unsigned long long v2;
+ unsigned long long v3;
+ unsigned long long v4;
+ unsigned long long mem64[4]; /* buffer defined as U64 for alignment */
+ unsigned memsize;
+ unsigned reserved[2]; /* never read nor write, will be removed in a future version */
+ }; /* typedef'd to XXH64_state_t */
+
+
+# ifdef XXH_PRIVATE_API
+# include "xxhash.c" /* include xxhash functions as `static`, for inlining */
+# endif
+
+#endif /* XXH_STATIC_LINKING_ONLY && XXH_STATIC_H_3543687687345 */
+
+
+#if defined (__cplusplus)
+}
+#endif
diff --git a/thirdparty/zstd/common/zstd_common.c b/thirdparty/zstd/common/zstd_common.c
new file mode 100644
index 0000000000..8408a589ae
--- /dev/null
+++ b/thirdparty/zstd/common/zstd_common.c
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+
+/*-*************************************
+* Dependencies
+***************************************/
+#include <stdlib.h> /* malloc */
+#include "error_private.h"
+#define ZSTD_STATIC_LINKING_ONLY
+#include "zstd.h" /* declaration of ZSTD_isError, ZSTD_getErrorName, ZSTD_getErrorCode, ZSTD_getErrorString, ZSTD_versionNumber */
+
+
+/*-****************************************
+* Version
+******************************************/
+unsigned ZSTD_versionNumber (void) { return ZSTD_VERSION_NUMBER; }
+
+
+/*-****************************************
+* ZSTD Error Management
+******************************************/
+/*! ZSTD_isError() :
+* tells if a return value is an error code */
+unsigned ZSTD_isError(size_t code) { return ERR_isError(code); }
+
+/*! ZSTD_getErrorName() :
+* provides error code string from function result (useful for debugging) */
+const char* ZSTD_getErrorName(size_t code) { return ERR_getErrorName(code); }
+
+/*! ZSTD_getError() :
+* convert a `size_t` function result into a proper ZSTD_errorCode enum */
+ZSTD_ErrorCode ZSTD_getErrorCode(size_t code) { return ERR_getErrorCode(code); }
+
+/*! ZSTD_getErrorString() :
+* provides error code string from enum */
+const char* ZSTD_getErrorString(ZSTD_ErrorCode code) { return ERR_getErrorString(code); }
+
+
+/*=**************************************************************
+* Custom allocator
+****************************************************************/
+/* default uses stdlib */
+void* ZSTD_defaultAllocFunction(void* opaque, size_t size)
+{
+ void* address = malloc(size);
+ (void)opaque;
+ return address;
+}
+
+void ZSTD_defaultFreeFunction(void* opaque, void* address)
+{
+ (void)opaque;
+ free(address);
+}
+
+void* ZSTD_malloc(size_t size, ZSTD_customMem customMem)
+{
+ return customMem.customAlloc(customMem.opaque, size);
+}
+
+void ZSTD_free(void* ptr, ZSTD_customMem customMem)
+{
+ if (ptr!=NULL)
+ customMem.customFree(customMem.opaque, ptr);
+}
diff --git a/thirdparty/zstd/common/zstd_errors.h b/thirdparty/zstd/common/zstd_errors.h
new file mode 100644
index 0000000000..3d579d9693
--- /dev/null
+++ b/thirdparty/zstd/common/zstd_errors.h
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#ifndef ZSTD_ERRORS_H_398273423
+#define ZSTD_ERRORS_H_398273423
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*===== dependency =====*/
+#include <stddef.h> /* size_t */
+
+
+/* ===== ZSTDERRORLIB_API : control library symbols visibility ===== */
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define ZSTDERRORLIB_VISIBILITY __attribute__ ((visibility ("default")))
+#else
+# define ZSTDERRORLIB_VISIBILITY
+#endif
+#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
+# define ZSTDERRORLIB_API __declspec(dllexport) ZSTDERRORLIB_VISIBILITY
+#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
+# define ZSTDERRORLIB_API __declspec(dllimport) ZSTDERRORLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
+#else
+# define ZSTDERRORLIB_API ZSTDERRORLIB_VISIBILITY
+#endif
+
+/*-****************************************
+* error codes list
+******************************************/
+typedef enum {
+ ZSTD_error_no_error,
+ ZSTD_error_GENERIC,
+ ZSTD_error_prefix_unknown,
+ ZSTD_error_version_unsupported,
+ ZSTD_error_parameter_unknown,
+ ZSTD_error_frameParameter_unsupported,
+ ZSTD_error_frameParameter_unsupportedBy32bits,
+ ZSTD_error_frameParameter_windowTooLarge,
+ ZSTD_error_compressionParameter_unsupported,
+ ZSTD_error_init_missing,
+ ZSTD_error_memory_allocation,
+ ZSTD_error_stage_wrong,
+ ZSTD_error_dstSize_tooSmall,
+ ZSTD_error_srcSize_wrong,
+ ZSTD_error_corruption_detected,
+ ZSTD_error_checksum_wrong,
+ ZSTD_error_tableLog_tooLarge,
+ ZSTD_error_maxSymbolValue_tooLarge,
+ ZSTD_error_maxSymbolValue_tooSmall,
+ ZSTD_error_dictionary_corrupted,
+ ZSTD_error_dictionary_wrong,
+ ZSTD_error_dictionaryCreation_failed,
+ ZSTD_error_maxCode
+} ZSTD_ErrorCode;
+
+/*! ZSTD_getErrorCode() :
+ convert a `size_t` function result into a `ZSTD_ErrorCode` enum type,
+ which can be used to compare directly with enum list published into "error_public.h" */
+ZSTDERRORLIB_API ZSTD_ErrorCode ZSTD_getErrorCode(size_t functionResult);
+ZSTDERRORLIB_API const char* ZSTD_getErrorString(ZSTD_ErrorCode code);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTD_ERRORS_H_398273423 */
diff --git a/thirdparty/zstd/common/zstd_internal.h b/thirdparty/zstd/common/zstd_internal.h
new file mode 100644
index 0000000000..2533333ba8
--- /dev/null
+++ b/thirdparty/zstd/common/zstd_internal.h
@@ -0,0 +1,284 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#ifndef ZSTD_CCOMMON_H_MODULE
+#define ZSTD_CCOMMON_H_MODULE
+
+/*-*******************************************************
+* Compiler specifics
+*********************************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE static __forceinline
+# include <intrin.h> /* For Visual 2005 */
+# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# pragma warning(disable : 4324) /* disable: C4324: padded structure */
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+#ifdef _MSC_VER
+# define FORCE_NOINLINE static __declspec(noinline)
+#else
+# ifdef __GNUC__
+# define FORCE_NOINLINE static __attribute__((__noinline__))
+# else
+# define FORCE_NOINLINE static
+# endif
+#endif
+
+
+/*-*************************************
+* Dependencies
+***************************************/
+#include "mem.h"
+#include "error_private.h"
+#define ZSTD_STATIC_LINKING_ONLY
+#include "zstd.h"
+#ifndef XXH_STATIC_LINKING_ONLY
+# define XXH_STATIC_LINKING_ONLY /* XXH64_state_t */
+#endif
+#include "xxhash.h" /* XXH_reset, update, digest */
+
+
+/*-*************************************
+* shared macros
+***************************************/
+#undef MIN
+#undef MAX
+#define MIN(a,b) ((a)<(b) ? (a) : (b))
+#define MAX(a,b) ((a)>(b) ? (a) : (b))
+#define CHECK_F(f) { size_t const errcod = f; if (ERR_isError(errcod)) return errcod; } /* check and Forward error code */
+#define CHECK_E(f, e) { size_t const errcod = f; if (ERR_isError(errcod)) return ERROR(e); } /* check and send Error code */
+
+
+/*-*************************************
+* Common constants
+***************************************/
+#define ZSTD_OPT_NUM (1<<12)
+#define ZSTD_DICT_MAGIC 0xEC30A437 /* v0.7+ */
+
+#define ZSTD_REP_NUM 3 /* number of repcodes */
+#define ZSTD_REP_CHECK (ZSTD_REP_NUM) /* number of repcodes to check by the optimal parser */
+#define ZSTD_REP_MOVE (ZSTD_REP_NUM-1)
+#define ZSTD_REP_MOVE_OPT (ZSTD_REP_NUM)
+static const U32 repStartValue[ZSTD_REP_NUM] = { 1, 4, 8 };
+
+#define KB *(1 <<10)
+#define MB *(1 <<20)
+#define GB *(1U<<30)
+
+#define BIT7 128
+#define BIT6 64
+#define BIT5 32
+#define BIT4 16
+#define BIT1 2
+#define BIT0 1
+
+#define ZSTD_WINDOWLOG_ABSOLUTEMIN 10
+static const size_t ZSTD_fcs_fieldSize[4] = { 0, 2, 4, 8 };
+static const size_t ZSTD_did_fieldSize[4] = { 0, 1, 2, 4 };
+
+#define ZSTD_BLOCKHEADERSIZE 3 /* C standard doesn't allow `static const` variable to be init using another `static const` variable */
+static const size_t ZSTD_blockHeaderSize = ZSTD_BLOCKHEADERSIZE;
+typedef enum { bt_raw, bt_rle, bt_compressed, bt_reserved } blockType_e;
+
+#define MIN_SEQUENCES_SIZE 1 /* nbSeq==0 */
+#define MIN_CBLOCK_SIZE (1 /*litCSize*/ + 1 /* RLE or RAW */ + MIN_SEQUENCES_SIZE /* nbSeq==0 */) /* for a non-null block */
+
+#define HufLog 12
+typedef enum { set_basic, set_rle, set_compressed, set_repeat } symbolEncodingType_e;
+
+#define LONGNBSEQ 0x7F00
+
+#define MINMATCH 3
+
+#define Litbits 8
+#define MaxLit ((1<<Litbits) - 1)
+#define MaxML 52
+#define MaxLL 35
+#define MaxOff 28
+#define MaxSeq MAX(MaxLL, MaxML) /* Assumption : MaxOff < MaxLL,MaxML */
+#define MLFSELog 9
+#define LLFSELog 9
+#define OffFSELog 8
+
+static const U32 LL_bits[MaxLL+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 3, 3, 4, 6, 7, 8, 9,10,11,12,
+ 13,14,15,16 };
+static const S16 LL_defaultNorm[MaxLL+1] = { 4, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 1, 1, 1, 1, 1,
+ -1,-1,-1,-1 };
+#define LL_DEFAULTNORMLOG 6 /* for static allocation */
+static const U32 LL_defaultNormLog = LL_DEFAULTNORMLOG;
+
+static const U32 ML_bits[MaxML+1] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 7, 8, 9,10,11,
+ 12,13,14,15,16 };
+static const S16 ML_defaultNorm[MaxML+1] = { 1, 4, 3, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,
+ -1,-1,-1,-1,-1 };
+#define ML_DEFAULTNORMLOG 6 /* for static allocation */
+static const U32 ML_defaultNormLog = ML_DEFAULTNORMLOG;
+
+static const S16 OF_defaultNorm[MaxOff+1] = { 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,-1,-1,-1,-1,-1 };
+#define OF_DEFAULTNORMLOG 5 /* for static allocation */
+static const U32 OF_defaultNormLog = OF_DEFAULTNORMLOG;
+
+
+/*-*******************************************
+* Shared functions to include for inlining
+*********************************************/
+static void ZSTD_copy8(void* dst, const void* src) { memcpy(dst, src, 8); }
+#define COPY8(d,s) { ZSTD_copy8(d,s); d+=8; s+=8; }
+
+/*! ZSTD_wildcopy() :
+* custom version of memcpy(), can copy up to 7 bytes too many (8 bytes if length==0) */
+#define WILDCOPY_OVERLENGTH 8
+MEM_STATIC void ZSTD_wildcopy(void* dst, const void* src, ptrdiff_t length)
+{
+ const BYTE* ip = (const BYTE*)src;
+ BYTE* op = (BYTE*)dst;
+ BYTE* const oend = op + length;
+ do
+ COPY8(op, ip)
+ while (op < oend);
+}
+
+MEM_STATIC void ZSTD_wildcopy_e(void* dst, const void* src, void* dstEnd) /* should be faster for decoding, but strangely, not verified on all platform */
+{
+ const BYTE* ip = (const BYTE*)src;
+ BYTE* op = (BYTE*)dst;
+ BYTE* const oend = (BYTE*)dstEnd;
+ do
+ COPY8(op, ip)
+ while (op < oend);
+}
+
+
+/*-*******************************************
+* Private interfaces
+*********************************************/
+typedef struct ZSTD_stats_s ZSTD_stats_t;
+
+typedef struct {
+ U32 off;
+ U32 len;
+} ZSTD_match_t;
+
+typedef struct {
+ U32 price;
+ U32 off;
+ U32 mlen;
+ U32 litlen;
+ U32 rep[ZSTD_REP_NUM];
+} ZSTD_optimal_t;
+
+
+typedef struct seqDef_s {
+ U32 offset;
+ U16 litLength;
+ U16 matchLength;
+} seqDef;
+
+
+typedef struct {
+ seqDef* sequencesStart;
+ seqDef* sequences;
+ BYTE* litStart;
+ BYTE* lit;
+ BYTE* llCode;
+ BYTE* mlCode;
+ BYTE* ofCode;
+ U32 longLengthID; /* 0 == no longLength; 1 == Lit.longLength; 2 == Match.longLength; */
+ U32 longLengthPos;
+ /* opt */
+ ZSTD_optimal_t* priceTable;
+ ZSTD_match_t* matchTable;
+ U32* matchLengthFreq;
+ U32* litLengthFreq;
+ U32* litFreq;
+ U32* offCodeFreq;
+ U32 matchLengthSum;
+ U32 matchSum;
+ U32 litLengthSum;
+ U32 litSum;
+ U32 offCodeSum;
+ U32 log2matchLengthSum;
+ U32 log2matchSum;
+ U32 log2litLengthSum;
+ U32 log2litSum;
+ U32 log2offCodeSum;
+ U32 factor;
+ U32 staticPrices;
+ U32 cachedPrice;
+ U32 cachedLitLength;
+ const BYTE* cachedLiterals;
+} seqStore_t;
+
+const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx);
+void ZSTD_seqToCodes(const seqStore_t* seqStorePtr);
+int ZSTD_isSkipFrame(ZSTD_DCtx* dctx);
+
+/* custom memory allocation functions */
+void* ZSTD_defaultAllocFunction(void* opaque, size_t size);
+void ZSTD_defaultFreeFunction(void* opaque, void* address);
+#ifndef ZSTD_DLL_IMPORT
+static const ZSTD_customMem defaultCustomMem = { ZSTD_defaultAllocFunction, ZSTD_defaultFreeFunction, NULL };
+#endif
+void* ZSTD_malloc(size_t size, ZSTD_customMem customMem);
+void ZSTD_free(void* ptr, ZSTD_customMem customMem);
+
+
+/*====== common function ======*/
+
+MEM_STATIC U32 ZSTD_highbit32(U32 val)
+{
+# if defined(_MSC_VER) /* Visual */
+ unsigned long r=0;
+ _BitScanReverse(&r, val);
+ return (unsigned)r;
+# elif defined(__GNUC__) && (__GNUC__ >= 3) /* GCC Intrinsic */
+ return 31 - __builtin_clz(val);
+# else /* Software version */
+ static const int DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
+ U32 v = val;
+ int r;
+ v |= v >> 1;
+ v |= v >> 2;
+ v |= v >> 4;
+ v |= v >> 8;
+ v |= v >> 16;
+ r = DeBruijnClz[(U32)(v * 0x07C4ACDDU) >> 27];
+ return r;
+# endif
+}
+
+
+/* hidden functions */
+
+/* ZSTD_invalidateRepCodes() :
+ * ensures next compression will not use repcodes from previous block.
+ * Note : only works with regular variant;
+ * do not use with extDict variant ! */
+void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx);
+
+
+#endif /* ZSTD_CCOMMON_H_MODULE */
diff --git a/thirdparty/zstd/compress/fse_compress.c b/thirdparty/zstd/compress/fse_compress.c
new file mode 100644
index 0000000000..26e8052ddc
--- /dev/null
+++ b/thirdparty/zstd/compress/fse_compress.c
@@ -0,0 +1,857 @@
+/* ******************************************************************
+ FSE : Finite State Entropy encoder
+ Copyright (C) 2013-2015, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - FSE source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
+****************************************************************** */
+
+/* **************************************************************
+* Compiler specifics
+****************************************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE static __forceinline
+# include <intrin.h> /* For Visual 2005 */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* **************************************************************
+* Includes
+****************************************************************/
+#include <stdlib.h> /* malloc, free, qsort */
+#include <string.h> /* memcpy, memset */
+#include <stdio.h> /* printf (debug) */
+#include "bitstream.h"
+#define FSE_STATIC_LINKING_ONLY
+#include "fse.h"
+
+
+/* **************************************************************
+* Error Management
+****************************************************************/
+#define FSE_STATIC_ASSERT(c) { enum { FSE_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+
+
+/* **************************************************************
+* Templates
+****************************************************************/
+/*
+ designed to be included
+ for type-specific functions (template emulation in C)
+ Objective is to write these functions only once, for improved maintenance
+*/
+
+/* safety checks */
+#ifndef FSE_FUNCTION_EXTENSION
+# error "FSE_FUNCTION_EXTENSION must be defined"
+#endif
+#ifndef FSE_FUNCTION_TYPE
+# error "FSE_FUNCTION_TYPE must be defined"
+#endif
+
+/* Function names */
+#define FSE_CAT(X,Y) X##Y
+#define FSE_FUNCTION_NAME(X,Y) FSE_CAT(X,Y)
+#define FSE_TYPE_NAME(X,Y) FSE_CAT(X,Y)
+
+
+/* Function templates */
+
+/* FSE_buildCTable_wksp() :
+ * Same as FSE_buildCTable(), but using an externally allocated scratch buffer (`workSpace`).
+ * wkspSize should be sized to handle worst case situation, which is `1<<max_tableLog * sizeof(FSE_FUNCTION_TYPE)`
+ * workSpace must also be properly aligned with FSE_FUNCTION_TYPE requirements
+ */
+size_t FSE_buildCTable_wksp(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
+{
+ U32 const tableSize = 1 << tableLog;
+ U32 const tableMask = tableSize - 1;
+ void* const ptr = ct;
+ U16* const tableU16 = ( (U16*) ptr) + 2;
+ void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableLog ? tableSize>>1 : 1) ;
+ FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
+ U32 const step = FSE_TABLESTEP(tableSize);
+ U32 cumul[FSE_MAX_SYMBOL_VALUE+2];
+
+ FSE_FUNCTION_TYPE* const tableSymbol = (FSE_FUNCTION_TYPE*)workSpace;
+ U32 highThreshold = tableSize-1;
+
+ /* CTable header */
+ if (((size_t)1 << tableLog) * sizeof(FSE_FUNCTION_TYPE) > wkspSize) return ERROR(tableLog_tooLarge);
+ tableU16[-2] = (U16) tableLog;
+ tableU16[-1] = (U16) maxSymbolValue;
+
+ /* For explanations on how to distribute symbol values over the table :
+ * http://fastcompression.blogspot.fr/2014/02/fse-distributing-symbol-values.html */
+
+ /* symbol start positions */
+ { U32 u;
+ cumul[0] = 0;
+ for (u=1; u<=maxSymbolValue+1; u++) {
+ if (normalizedCounter[u-1]==-1) { /* Low proba symbol */
+ cumul[u] = cumul[u-1] + 1;
+ tableSymbol[highThreshold--] = (FSE_FUNCTION_TYPE)(u-1);
+ } else {
+ cumul[u] = cumul[u-1] + normalizedCounter[u-1];
+ } }
+ cumul[maxSymbolValue+1] = tableSize+1;
+ }
+
+ /* Spread symbols */
+ { U32 position = 0;
+ U32 symbol;
+ for (symbol=0; symbol<=maxSymbolValue; symbol++) {
+ int nbOccurences;
+ for (nbOccurences=0; nbOccurences<normalizedCounter[symbol]; nbOccurences++) {
+ tableSymbol[position] = (FSE_FUNCTION_TYPE)symbol;
+ position = (position + step) & tableMask;
+ while (position > highThreshold) position = (position + step) & tableMask; /* Low proba area */
+ } }
+
+ if (position!=0) return ERROR(GENERIC); /* Must have gone through all positions */
+ }
+
+ /* Build table */
+ { U32 u; for (u=0; u<tableSize; u++) {
+ FSE_FUNCTION_TYPE s = tableSymbol[u]; /* note : static analyzer may not understand tableSymbol is properly initialized */
+ tableU16[cumul[s]++] = (U16) (tableSize+u); /* TableU16 : sorted by symbol order; gives next state value */
+ } }
+
+ /* Build Symbol Transformation Table */
+ { unsigned total = 0;
+ unsigned s;
+ for (s=0; s<=maxSymbolValue; s++) {
+ switch (normalizedCounter[s])
+ {
+ case 0: break;
+
+ case -1:
+ case 1:
+ symbolTT[s].deltaNbBits = (tableLog << 16) - (1<<tableLog);
+ symbolTT[s].deltaFindState = total - 1;
+ total ++;
+ break;
+ default :
+ {
+ U32 const maxBitsOut = tableLog - BIT_highbit32 (normalizedCounter[s]-1);
+ U32 const minStatePlus = normalizedCounter[s] << maxBitsOut;
+ symbolTT[s].deltaNbBits = (maxBitsOut << 16) - minStatePlus;
+ symbolTT[s].deltaFindState = total - normalizedCounter[s];
+ total += normalizedCounter[s];
+ } } } }
+
+ return 0;
+}
+
+
+size_t FSE_buildCTable(FSE_CTable* ct, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
+{
+ FSE_FUNCTION_TYPE tableSymbol[FSE_MAX_TABLESIZE]; /* memset() is not necessary, even if static analyzer complain about it */
+ return FSE_buildCTable_wksp(ct, normalizedCounter, maxSymbolValue, tableLog, tableSymbol, sizeof(tableSymbol));
+}
+
+
+
+#ifndef FSE_COMMONDEFS_ONLY
+
+/*-**************************************************************
+* FSE NCount encoding-decoding
+****************************************************************/
+size_t FSE_NCountWriteBound(unsigned maxSymbolValue, unsigned tableLog)
+{
+ size_t const maxHeaderSize = (((maxSymbolValue+1) * tableLog) >> 3) + 3;
+ return maxSymbolValue ? maxHeaderSize : FSE_NCOUNTBOUND; /* maxSymbolValue==0 ? use default */
+}
+
+static size_t FSE_writeNCount_generic (void* header, size_t headerBufferSize,
+ const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog,
+ unsigned writeIsSafe)
+{
+ BYTE* const ostart = (BYTE*) header;
+ BYTE* out = ostart;
+ BYTE* const oend = ostart + headerBufferSize;
+ int nbBits;
+ const int tableSize = 1 << tableLog;
+ int remaining;
+ int threshold;
+ U32 bitStream;
+ int bitCount;
+ unsigned charnum = 0;
+ int previous0 = 0;
+
+ bitStream = 0;
+ bitCount = 0;
+ /* Table Size */
+ bitStream += (tableLog-FSE_MIN_TABLELOG) << bitCount;
+ bitCount += 4;
+
+ /* Init */
+ remaining = tableSize+1; /* +1 for extra accuracy */
+ threshold = tableSize;
+ nbBits = tableLog+1;
+
+ while (remaining>1) { /* stops at 1 */
+ if (previous0) {
+ unsigned start = charnum;
+ while (!normalizedCounter[charnum]) charnum++;
+ while (charnum >= start+24) {
+ start+=24;
+ bitStream += 0xFFFFU << bitCount;
+ if ((!writeIsSafe) && (out > oend-2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
+ out[0] = (BYTE) bitStream;
+ out[1] = (BYTE)(bitStream>>8);
+ out+=2;
+ bitStream>>=16;
+ }
+ while (charnum >= start+3) {
+ start+=3;
+ bitStream += 3 << bitCount;
+ bitCount += 2;
+ }
+ bitStream += (charnum-start) << bitCount;
+ bitCount += 2;
+ if (bitCount>16) {
+ if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
+ out[0] = (BYTE)bitStream;
+ out[1] = (BYTE)(bitStream>>8);
+ out += 2;
+ bitStream >>= 16;
+ bitCount -= 16;
+ } }
+ { int count = normalizedCounter[charnum++];
+ int const max = (2*threshold-1)-remaining;
+ remaining -= count < 0 ? -count : count;
+ count++; /* +1 for extra accuracy */
+ if (count>=threshold) count += max; /* [0..max[ [max..threshold[ (...) [threshold+max 2*threshold[ */
+ bitStream += count << bitCount;
+ bitCount += nbBits;
+ bitCount -= (count<max);
+ previous0 = (count==1);
+ if (remaining<1) return ERROR(GENERIC);
+ while (remaining<threshold) nbBits--, threshold>>=1;
+ }
+ if (bitCount>16) {
+ if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
+ out[0] = (BYTE)bitStream;
+ out[1] = (BYTE)(bitStream>>8);
+ out += 2;
+ bitStream >>= 16;
+ bitCount -= 16;
+ } }
+
+ /* flush remaining bitStream */
+ if ((!writeIsSafe) && (out > oend - 2)) return ERROR(dstSize_tooSmall); /* Buffer overflow */
+ out[0] = (BYTE)bitStream;
+ out[1] = (BYTE)(bitStream>>8);
+ out+= (bitCount+7) /8;
+
+ if (charnum > maxSymbolValue + 1) return ERROR(GENERIC);
+
+ return (out-ostart);
+}
+
+
+size_t FSE_writeNCount (void* buffer, size_t bufferSize, const short* normalizedCounter, unsigned maxSymbolValue, unsigned tableLog)
+{
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported */
+ if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported */
+
+ if (bufferSize < FSE_NCountWriteBound(maxSymbolValue, tableLog))
+ return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 0);
+
+ return FSE_writeNCount_generic(buffer, bufferSize, normalizedCounter, maxSymbolValue, tableLog, 1);
+}
+
+
+
+/*-**************************************************************
+* Counting histogram
+****************************************************************/
+/*! FSE_count_simple
+ This function counts byte values within `src`, and store the histogram into table `count`.
+ It doesn't use any additional memory.
+ But this function is unsafe : it doesn't check that all values within `src` can fit into `count`.
+ For this reason, prefer using a table `count` with 256 elements.
+ @return : count of most numerous element
+*/
+size_t FSE_count_simple(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* src, size_t srcSize)
+{
+ const BYTE* ip = (const BYTE*)src;
+ const BYTE* const end = ip + srcSize;
+ unsigned maxSymbolValue = *maxSymbolValuePtr;
+ unsigned max=0;
+
+ memset(count, 0, (maxSymbolValue+1)*sizeof(*count));
+ if (srcSize==0) { *maxSymbolValuePtr = 0; return 0; }
+
+ while (ip<end) count[*ip++]++;
+
+ while (!count[maxSymbolValue]) maxSymbolValue--;
+ *maxSymbolValuePtr = maxSymbolValue;
+
+ { U32 s; for (s=0; s<=maxSymbolValue; s++) if (count[s] > max) max = count[s]; }
+
+ return (size_t)max;
+}
+
+
+/* FSE_count_parallel_wksp() :
+ * Same as FSE_count_parallel(), but using an externally provided scratch buffer.
+ * `workSpace` size must be a minimum of `1024 * sizeof(unsigned)`` */
+static size_t FSE_count_parallel_wksp(
+ unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize,
+ unsigned checkMax, unsigned* const workSpace)
+{
+ const BYTE* ip = (const BYTE*)source;
+ const BYTE* const iend = ip+sourceSize;
+ unsigned maxSymbolValue = *maxSymbolValuePtr;
+ unsigned max=0;
+ U32* const Counting1 = workSpace;
+ U32* const Counting2 = Counting1 + 256;
+ U32* const Counting3 = Counting2 + 256;
+ U32* const Counting4 = Counting3 + 256;
+
+ memset(Counting1, 0, 4*256*sizeof(unsigned));
+
+ /* safety checks */
+ if (!sourceSize) {
+ memset(count, 0, maxSymbolValue + 1);
+ *maxSymbolValuePtr = 0;
+ return 0;
+ }
+ if (!maxSymbolValue) maxSymbolValue = 255; /* 0 == default */
+
+ /* by stripes of 16 bytes */
+ { U32 cached = MEM_read32(ip); ip += 4;
+ while (ip < iend-15) {
+ U32 c = cached; cached = MEM_read32(ip); ip += 4;
+ Counting1[(BYTE) c ]++;
+ Counting2[(BYTE)(c>>8) ]++;
+ Counting3[(BYTE)(c>>16)]++;
+ Counting4[ c>>24 ]++;
+ c = cached; cached = MEM_read32(ip); ip += 4;
+ Counting1[(BYTE) c ]++;
+ Counting2[(BYTE)(c>>8) ]++;
+ Counting3[(BYTE)(c>>16)]++;
+ Counting4[ c>>24 ]++;
+ c = cached; cached = MEM_read32(ip); ip += 4;
+ Counting1[(BYTE) c ]++;
+ Counting2[(BYTE)(c>>8) ]++;
+ Counting3[(BYTE)(c>>16)]++;
+ Counting4[ c>>24 ]++;
+ c = cached; cached = MEM_read32(ip); ip += 4;
+ Counting1[(BYTE) c ]++;
+ Counting2[(BYTE)(c>>8) ]++;
+ Counting3[(BYTE)(c>>16)]++;
+ Counting4[ c>>24 ]++;
+ }
+ ip-=4;
+ }
+
+ /* finish last symbols */
+ while (ip<iend) Counting1[*ip++]++;
+
+ if (checkMax) { /* verify stats will fit into destination table */
+ U32 s; for (s=255; s>maxSymbolValue; s--) {
+ Counting1[s] += Counting2[s] + Counting3[s] + Counting4[s];
+ if (Counting1[s]) return ERROR(maxSymbolValue_tooSmall);
+ } }
+
+ { U32 s; for (s=0; s<=maxSymbolValue; s++) {
+ count[s] = Counting1[s] + Counting2[s] + Counting3[s] + Counting4[s];
+ if (count[s] > max) max = count[s];
+ } }
+
+ while (!count[maxSymbolValue]) maxSymbolValue--;
+ *maxSymbolValuePtr = maxSymbolValue;
+ return (size_t)max;
+}
+
+/* FSE_countFast_wksp() :
+ * Same as FSE_countFast(), but using an externally provided scratch buffer.
+ * `workSpace` size must be table of >= `1024` unsigned */
+size_t FSE_countFast_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize, unsigned* workSpace)
+{
+ if (sourceSize < 1500) return FSE_count_simple(count, maxSymbolValuePtr, source, sourceSize);
+ return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 0, workSpace);
+}
+
+/* fast variant (unsafe : won't check if src contains values beyond count[] limit) */
+size_t FSE_countFast(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize)
+{
+ unsigned tmpCounters[1024];
+ return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, tmpCounters);
+}
+
+/* FSE_count_wksp() :
+ * Same as FSE_count(), but using an externally provided scratch buffer.
+ * `workSpace` size must be table of >= `1024` unsigned */
+size_t FSE_count_wksp(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* source, size_t sourceSize, unsigned* workSpace)
+{
+ if (*maxSymbolValuePtr < 255)
+ return FSE_count_parallel_wksp(count, maxSymbolValuePtr, source, sourceSize, 1, workSpace);
+ *maxSymbolValuePtr = 255;
+ return FSE_countFast_wksp(count, maxSymbolValuePtr, source, sourceSize, workSpace);
+}
+
+size_t FSE_count(unsigned* count, unsigned* maxSymbolValuePtr,
+ const void* src, size_t srcSize)
+{
+ unsigned tmpCounters[1024];
+ return FSE_count_wksp(count, maxSymbolValuePtr, src, srcSize, tmpCounters);
+}
+
+
+
+/*-**************************************************************
+* FSE Compression Code
+****************************************************************/
+/*! FSE_sizeof_CTable() :
+ FSE_CTable is a variable size structure which contains :
+ `U16 tableLog;`
+ `U16 maxSymbolValue;`
+ `U16 nextStateNumber[1 << tableLog];` // This size is variable
+ `FSE_symbolCompressionTransform symbolTT[maxSymbolValue+1];` // This size is variable
+Allocation is manual (C standard does not support variable-size structures).
+*/
+size_t FSE_sizeof_CTable (unsigned maxSymbolValue, unsigned tableLog)
+{
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
+ return FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
+}
+
+FSE_CTable* FSE_createCTable (unsigned maxSymbolValue, unsigned tableLog)
+{
+ size_t size;
+ if (tableLog > FSE_TABLELOG_ABSOLUTE_MAX) tableLog = FSE_TABLELOG_ABSOLUTE_MAX;
+ size = FSE_CTABLE_SIZE_U32 (tableLog, maxSymbolValue) * sizeof(U32);
+ return (FSE_CTable*)malloc(size);
+}
+
+void FSE_freeCTable (FSE_CTable* ct) { free(ct); }
+
+/* provides the minimum logSize to safely represent a distribution */
+static unsigned FSE_minTableLog(size_t srcSize, unsigned maxSymbolValue)
+{
+ U32 minBitsSrc = BIT_highbit32((U32)(srcSize - 1)) + 1;
+ U32 minBitsSymbols = BIT_highbit32(maxSymbolValue) + 2;
+ U32 minBits = minBitsSrc < minBitsSymbols ? minBitsSrc : minBitsSymbols;
+ return minBits;
+}
+
+unsigned FSE_optimalTableLog_internal(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue, unsigned minus)
+{
+ U32 maxBitsSrc = BIT_highbit32((U32)(srcSize - 1)) - minus;
+ U32 tableLog = maxTableLog;
+ U32 minBits = FSE_minTableLog(srcSize, maxSymbolValue);
+ if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
+ if (maxBitsSrc < tableLog) tableLog = maxBitsSrc; /* Accuracy can be reduced */
+ if (minBits > tableLog) tableLog = minBits; /* Need a minimum to safely represent all symbol values */
+ if (tableLog < FSE_MIN_TABLELOG) tableLog = FSE_MIN_TABLELOG;
+ if (tableLog > FSE_MAX_TABLELOG) tableLog = FSE_MAX_TABLELOG;
+ return tableLog;
+}
+
+unsigned FSE_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
+{
+ return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 2);
+}
+
+
+/* Secondary normalization method.
+ To be used when primary method fails. */
+
+static size_t FSE_normalizeM2(short* norm, U32 tableLog, const unsigned* count, size_t total, U32 maxSymbolValue)
+{
+ short const NOT_YET_ASSIGNED = -2;
+ U32 s;
+ U32 distributed = 0;
+ U32 ToDistribute;
+
+ /* Init */
+ U32 const lowThreshold = (U32)(total >> tableLog);
+ U32 lowOne = (U32)((total * 3) >> (tableLog + 1));
+
+ for (s=0; s<=maxSymbolValue; s++) {
+ if (count[s] == 0) {
+ norm[s]=0;
+ continue;
+ }
+ if (count[s] <= lowThreshold) {
+ norm[s] = -1;
+ distributed++;
+ total -= count[s];
+ continue;
+ }
+ if (count[s] <= lowOne) {
+ norm[s] = 1;
+ distributed++;
+ total -= count[s];
+ continue;
+ }
+
+ norm[s]=NOT_YET_ASSIGNED;
+ }
+ ToDistribute = (1 << tableLog) - distributed;
+
+ if ((total / ToDistribute) > lowOne) {
+ /* risk of rounding to zero */
+ lowOne = (U32)((total * 3) / (ToDistribute * 2));
+ for (s=0; s<=maxSymbolValue; s++) {
+ if ((norm[s] == NOT_YET_ASSIGNED) && (count[s] <= lowOne)) {
+ norm[s] = 1;
+ distributed++;
+ total -= count[s];
+ continue;
+ } }
+ ToDistribute = (1 << tableLog) - distributed;
+ }
+
+ if (distributed == maxSymbolValue+1) {
+ /* all values are pretty poor;
+ probably incompressible data (should have already been detected);
+ find max, then give all remaining points to max */
+ U32 maxV = 0, maxC = 0;
+ for (s=0; s<=maxSymbolValue; s++)
+ if (count[s] > maxC) maxV=s, maxC=count[s];
+ norm[maxV] += (short)ToDistribute;
+ return 0;
+ }
+
+ if (total == 0) {
+ /* all of the symbols were low enough for the lowOne or lowThreshold */
+ for (s=0; ToDistribute > 0; s = (s+1)%(maxSymbolValue+1))
+ if (norm[s] > 0) ToDistribute--, norm[s]++;
+ return 0;
+ }
+
+ { U64 const vStepLog = 62 - tableLog;
+ U64 const mid = (1ULL << (vStepLog-1)) - 1;
+ U64 const rStep = ((((U64)1<<vStepLog) * ToDistribute) + mid) / total; /* scale on remaining */
+ U64 tmpTotal = mid;
+ for (s=0; s<=maxSymbolValue; s++) {
+ if (norm[s]==NOT_YET_ASSIGNED) {
+ U64 const end = tmpTotal + (count[s] * rStep);
+ U32 const sStart = (U32)(tmpTotal >> vStepLog);
+ U32 const sEnd = (U32)(end >> vStepLog);
+ U32 const weight = sEnd - sStart;
+ if (weight < 1)
+ return ERROR(GENERIC);
+ norm[s] = (short)weight;
+ tmpTotal = end;
+ } } }
+
+ return 0;
+}
+
+
+size_t FSE_normalizeCount (short* normalizedCounter, unsigned tableLog,
+ const unsigned* count, size_t total,
+ unsigned maxSymbolValue)
+{
+ /* Sanity checks */
+ if (tableLog==0) tableLog = FSE_DEFAULT_TABLELOG;
+ if (tableLog < FSE_MIN_TABLELOG) return ERROR(GENERIC); /* Unsupported size */
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge); /* Unsupported size */
+ if (tableLog < FSE_minTableLog(total, maxSymbolValue)) return ERROR(GENERIC); /* Too small tableLog, compression potentially impossible */
+
+ { U32 const rtbTable[] = { 0, 473195, 504333, 520860, 550000, 700000, 750000, 830000 };
+ U64 const scale = 62 - tableLog;
+ U64 const step = ((U64)1<<62) / total; /* <== here, one division ! */
+ U64 const vStep = 1ULL<<(scale-20);
+ int stillToDistribute = 1<<tableLog;
+ unsigned s;
+ unsigned largest=0;
+ short largestP=0;
+ U32 lowThreshold = (U32)(total >> tableLog);
+
+ for (s=0; s<=maxSymbolValue; s++) {
+ if (count[s] == total) return 0; /* rle special case */
+ if (count[s] == 0) { normalizedCounter[s]=0; continue; }
+ if (count[s] <= lowThreshold) {
+ normalizedCounter[s] = -1;
+ stillToDistribute--;
+ } else {
+ short proba = (short)((count[s]*step) >> scale);
+ if (proba<8) {
+ U64 restToBeat = vStep * rtbTable[proba];
+ proba += (count[s]*step) - ((U64)proba<<scale) > restToBeat;
+ }
+ if (proba > largestP) largestP=proba, largest=s;
+ normalizedCounter[s] = proba;
+ stillToDistribute -= proba;
+ } }
+ if (-stillToDistribute >= (normalizedCounter[largest] >> 1)) {
+ /* corner case, need another normalization method */
+ size_t const errorCode = FSE_normalizeM2(normalizedCounter, tableLog, count, total, maxSymbolValue);
+ if (FSE_isError(errorCode)) return errorCode;
+ }
+ else normalizedCounter[largest] += (short)stillToDistribute;
+ }
+
+#if 0
+ { /* Print Table (debug) */
+ U32 s;
+ U32 nTotal = 0;
+ for (s=0; s<=maxSymbolValue; s++)
+ printf("%3i: %4i \n", s, normalizedCounter[s]);
+ for (s=0; s<=maxSymbolValue; s++)
+ nTotal += abs(normalizedCounter[s]);
+ if (nTotal != (1U<<tableLog))
+ printf("Warning !!! Total == %u != %u !!!", nTotal, 1U<<tableLog);
+ getchar();
+ }
+#endif
+
+ return tableLog;
+}
+
+
+/* fake FSE_CTable, for raw (uncompressed) input */
+size_t FSE_buildCTable_raw (FSE_CTable* ct, unsigned nbBits)
+{
+ const unsigned tableSize = 1 << nbBits;
+ const unsigned tableMask = tableSize - 1;
+ const unsigned maxSymbolValue = tableMask;
+ void* const ptr = ct;
+ U16* const tableU16 = ( (U16*) ptr) + 2;
+ void* const FSCT = ((U32*)ptr) + 1 /* header */ + (tableSize>>1); /* assumption : tableLog >= 1 */
+ FSE_symbolCompressionTransform* const symbolTT = (FSE_symbolCompressionTransform*) (FSCT);
+ unsigned s;
+
+ /* Sanity checks */
+ if (nbBits < 1) return ERROR(GENERIC); /* min size */
+
+ /* header */
+ tableU16[-2] = (U16) nbBits;
+ tableU16[-1] = (U16) maxSymbolValue;
+
+ /* Build table */
+ for (s=0; s<tableSize; s++)
+ tableU16[s] = (U16)(tableSize + s);
+
+ /* Build Symbol Transformation Table */
+ { const U32 deltaNbBits = (nbBits << 16) - (1 << nbBits);
+ for (s=0; s<=maxSymbolValue; s++) {
+ symbolTT[s].deltaNbBits = deltaNbBits;
+ symbolTT[s].deltaFindState = s-1;
+ } }
+
+ return 0;
+}
+
+/* fake FSE_CTable, for rle input (always same symbol) */
+size_t FSE_buildCTable_rle (FSE_CTable* ct, BYTE symbolValue)
+{
+ void* ptr = ct;
+ U16* tableU16 = ( (U16*) ptr) + 2;
+ void* FSCTptr = (U32*)ptr + 2;
+ FSE_symbolCompressionTransform* symbolTT = (FSE_symbolCompressionTransform*) FSCTptr;
+
+ /* header */
+ tableU16[-2] = (U16) 0;
+ tableU16[-1] = (U16) symbolValue;
+
+ /* Build table */
+ tableU16[0] = 0;
+ tableU16[1] = 0; /* just in case */
+
+ /* Build Symbol Transformation Table */
+ symbolTT[symbolValue].deltaNbBits = 0;
+ symbolTT[symbolValue].deltaFindState = 0;
+
+ return 0;
+}
+
+
+static size_t FSE_compress_usingCTable_generic (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ const FSE_CTable* ct, const unsigned fast)
+{
+ const BYTE* const istart = (const BYTE*) src;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* ip=iend;
+
+ BIT_CStream_t bitC;
+ FSE_CState_t CState1, CState2;
+
+ /* init */
+ if (srcSize <= 2) return 0;
+ { size_t const initError = BIT_initCStream(&bitC, dst, dstSize);
+ if (FSE_isError(initError)) return 0; /* not enough space available to write a bitstream */ }
+
+#define FSE_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
+
+ if (srcSize & 1) {
+ FSE_initCState2(&CState1, ct, *--ip);
+ FSE_initCState2(&CState2, ct, *--ip);
+ FSE_encodeSymbol(&bitC, &CState1, *--ip);
+ FSE_FLUSHBITS(&bitC);
+ } else {
+ FSE_initCState2(&CState2, ct, *--ip);
+ FSE_initCState2(&CState1, ct, *--ip);
+ }
+
+ /* join to mod 4 */
+ srcSize -= 2;
+ if ((sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) && (srcSize & 2)) { /* test bit 2 */
+ FSE_encodeSymbol(&bitC, &CState2, *--ip);
+ FSE_encodeSymbol(&bitC, &CState1, *--ip);
+ FSE_FLUSHBITS(&bitC);
+ }
+
+ /* 2 or 4 encoding per loop */
+ while ( ip>istart ) {
+
+ FSE_encodeSymbol(&bitC, &CState2, *--ip);
+
+ if (sizeof(bitC.bitContainer)*8 < FSE_MAX_TABLELOG*2+7 ) /* this test must be static */
+ FSE_FLUSHBITS(&bitC);
+
+ FSE_encodeSymbol(&bitC, &CState1, *--ip);
+
+ if (sizeof(bitC.bitContainer)*8 > FSE_MAX_TABLELOG*4+7 ) { /* this test must be static */
+ FSE_encodeSymbol(&bitC, &CState2, *--ip);
+ FSE_encodeSymbol(&bitC, &CState1, *--ip);
+ }
+
+ FSE_FLUSHBITS(&bitC);
+ }
+
+ FSE_flushCState(&bitC, &CState2);
+ FSE_flushCState(&bitC, &CState1);
+ return BIT_closeCStream(&bitC);
+}
+
+size_t FSE_compress_usingCTable (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ const FSE_CTable* ct)
+{
+ unsigned const fast = (dstSize >= FSE_BLOCKBOUND(srcSize));
+
+ if (fast)
+ return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 1);
+ else
+ return FSE_compress_usingCTable_generic(dst, dstSize, src, srcSize, ct, 0);
+}
+
+
+size_t FSE_compressBound(size_t size) { return FSE_COMPRESSBOUND(size); }
+
+#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
+#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
+
+/* FSE_compress_wksp() :
+ * Same as FSE_compress2(), but using an externally allocated scratch buffer (`workSpace`).
+ * `wkspSize` size must be `(1<<tableLog)`.
+ */
+size_t FSE_compress_wksp (void* dst, size_t dstSize, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog, void* workSpace, size_t wkspSize)
+{
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* op = ostart;
+ BYTE* const oend = ostart + dstSize;
+
+ U32 count[FSE_MAX_SYMBOL_VALUE+1];
+ S16 norm[FSE_MAX_SYMBOL_VALUE+1];
+ FSE_CTable* CTable = (FSE_CTable*)workSpace;
+ size_t const CTableSize = FSE_CTABLE_SIZE_U32(tableLog, maxSymbolValue);
+ void* scratchBuffer = (void*)(CTable + CTableSize);
+ size_t const scratchBufferSize = wkspSize - (CTableSize * sizeof(FSE_CTable));
+
+ /* init conditions */
+ if (wkspSize < FSE_WKSP_SIZE_U32(tableLog, maxSymbolValue)) return ERROR(tableLog_tooLarge);
+ if (srcSize <= 1) return 0; /* Not compressible */
+ if (!maxSymbolValue) maxSymbolValue = FSE_MAX_SYMBOL_VALUE;
+ if (!tableLog) tableLog = FSE_DEFAULT_TABLELOG;
+
+ /* Scan input and build symbol stats */
+ { CHECK_V_F(maxCount, FSE_count_wksp(count, &maxSymbolValue, src, srcSize, (unsigned*)scratchBuffer) );
+ if (maxCount == srcSize) return 1; /* only a single symbol in src : rle */
+ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
+ if (maxCount < (srcSize >> 7)) return 0; /* Heuristic : not compressible enough */
+ }
+
+ tableLog = FSE_optimalTableLog(tableLog, srcSize, maxSymbolValue);
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, srcSize, maxSymbolValue) );
+
+ /* Write table description header */
+ { CHECK_V_F(nc_err, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
+ op += nc_err;
+ }
+
+ /* Compress */
+ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, scratchBufferSize) );
+ { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, src, srcSize, CTable) );
+ if (cSize == 0) return 0; /* not enough space for compressed data */
+ op += cSize;
+ }
+
+ /* check compressibility */
+ if ( (size_t)(op-ostart) >= srcSize-1 ) return 0;
+
+ return op-ostart;
+}
+
+typedef struct {
+ FSE_CTable CTable_max[FSE_CTABLE_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)];
+ BYTE scratchBuffer[1 << FSE_MAX_TABLELOG];
+} fseWkspMax_t;
+
+size_t FSE_compress2 (void* dst, size_t dstCapacity, const void* src, size_t srcSize, unsigned maxSymbolValue, unsigned tableLog)
+{
+ fseWkspMax_t scratchBuffer;
+ FSE_STATIC_ASSERT(sizeof(scratchBuffer) >= FSE_WKSP_SIZE_U32(FSE_MAX_TABLELOG, FSE_MAX_SYMBOL_VALUE)); /* compilation failures here means scratchBuffer is not large enough */
+ if (tableLog > FSE_MAX_TABLELOG) return ERROR(tableLog_tooLarge);
+ return FSE_compress_wksp(dst, dstCapacity, src, srcSize, maxSymbolValue, tableLog, &scratchBuffer, sizeof(scratchBuffer));
+}
+
+size_t FSE_compress (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ return FSE_compress2(dst, dstCapacity, src, srcSize, FSE_MAX_SYMBOL_VALUE, FSE_DEFAULT_TABLELOG);
+}
+
+
+#endif /* FSE_COMMONDEFS_ONLY */
diff --git a/thirdparty/zstd/compress/huf_compress.c b/thirdparty/zstd/compress/huf_compress.c
new file mode 100644
index 0000000000..fe11aafb8f
--- /dev/null
+++ b/thirdparty/zstd/compress/huf_compress.c
@@ -0,0 +1,684 @@
+/* ******************************************************************
+ Huffman encoder, part of New Generation Entropy library
+ Copyright (C) 2013-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
+****************************************************************** */
+
+/* **************************************************************
+* Compiler specifics
+****************************************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+#endif
+
+
+/* **************************************************************
+* Includes
+****************************************************************/
+#include <string.h> /* memcpy, memset */
+#include <stdio.h> /* printf (debug) */
+#include "bitstream.h"
+#define FSE_STATIC_LINKING_ONLY /* FSE_optimalTableLog_internal */
+#include "fse.h" /* header compression */
+#define HUF_STATIC_LINKING_ONLY
+#include "huf.h"
+
+
+/* **************************************************************
+* Error Management
+****************************************************************/
+#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+#define CHECK_V_F(e, f) size_t const e = f; if (ERR_isError(e)) return f
+#define CHECK_F(f) { CHECK_V_F(_var_err__, f); }
+
+
+/* **************************************************************
+* Utils
+****************************************************************/
+unsigned HUF_optimalTableLog(unsigned maxTableLog, size_t srcSize, unsigned maxSymbolValue)
+{
+ return FSE_optimalTableLog_internal(maxTableLog, srcSize, maxSymbolValue, 1);
+}
+
+
+/* *******************************************************
+* HUF : Huffman block compression
+*********************************************************/
+/* HUF_compressWeights() :
+ * Same as FSE_compress(), but dedicated to huff0's weights compression.
+ * The use case needs much less stack memory.
+ * Note : all elements within weightTable are supposed to be <= HUF_TABLELOG_MAX.
+ */
+#define MAX_FSE_TABLELOG_FOR_HUFF_HEADER 6
+size_t HUF_compressWeights (void* dst, size_t dstSize, const void* weightTable, size_t wtSize)
+{
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* op = ostart;
+ BYTE* const oend = ostart + dstSize;
+
+ U32 maxSymbolValue = HUF_TABLELOG_MAX;
+ U32 tableLog = MAX_FSE_TABLELOG_FOR_HUFF_HEADER;
+
+ FSE_CTable CTable[FSE_CTABLE_SIZE_U32(MAX_FSE_TABLELOG_FOR_HUFF_HEADER, HUF_TABLELOG_MAX)];
+ BYTE scratchBuffer[1<<MAX_FSE_TABLELOG_FOR_HUFF_HEADER];
+
+ U32 count[HUF_TABLELOG_MAX+1];
+ S16 norm[HUF_TABLELOG_MAX+1];
+
+ /* init conditions */
+ if (wtSize <= 1) return 0; /* Not compressible */
+
+ /* Scan input and build symbol stats */
+ { CHECK_V_F(maxCount, FSE_count_simple(count, &maxSymbolValue, weightTable, wtSize) );
+ if (maxCount == wtSize) return 1; /* only a single symbol in src : rle */
+ if (maxCount == 1) return 0; /* each symbol present maximum once => not compressible */
+ }
+
+ tableLog = FSE_optimalTableLog(tableLog, wtSize, maxSymbolValue);
+ CHECK_F( FSE_normalizeCount(norm, tableLog, count, wtSize, maxSymbolValue) );
+
+ /* Write table description header */
+ { CHECK_V_F(hSize, FSE_writeNCount(op, oend-op, norm, maxSymbolValue, tableLog) );
+ op += hSize;
+ }
+
+ /* Compress */
+ CHECK_F( FSE_buildCTable_wksp(CTable, norm, maxSymbolValue, tableLog, scratchBuffer, sizeof(scratchBuffer)) );
+ { CHECK_V_F(cSize, FSE_compress_usingCTable(op, oend - op, weightTable, wtSize, CTable) );
+ if (cSize == 0) return 0; /* not enough space for compressed data */
+ op += cSize;
+ }
+
+ return op-ostart;
+}
+
+
+struct HUF_CElt_s {
+ U16 val;
+ BYTE nbBits;
+}; /* typedef'd to HUF_CElt within "huf.h" */
+
+/*! HUF_writeCTable() :
+ `CTable` : Huffman tree to save, using huf representation.
+ @return : size of saved CTable */
+size_t HUF_writeCTable (void* dst, size_t maxDstSize,
+ const HUF_CElt* CTable, U32 maxSymbolValue, U32 huffLog)
+{
+ BYTE bitsToWeight[HUF_TABLELOG_MAX + 1]; /* precomputed conversion table */
+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX];
+ BYTE* op = (BYTE*)dst;
+ U32 n;
+
+ /* check conditions */
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(maxSymbolValue_tooLarge);
+
+ /* convert to weight */
+ bitsToWeight[0] = 0;
+ for (n=1; n<huffLog+1; n++)
+ bitsToWeight[n] = (BYTE)(huffLog + 1 - n);
+ for (n=0; n<maxSymbolValue; n++)
+ huffWeight[n] = bitsToWeight[CTable[n].nbBits];
+
+ /* attempt weights compression by FSE */
+ { CHECK_V_F(hSize, HUF_compressWeights(op+1, maxDstSize-1, huffWeight, maxSymbolValue) );
+ if ((hSize>1) & (hSize < maxSymbolValue/2)) { /* FSE compressed */
+ op[0] = (BYTE)hSize;
+ return hSize+1;
+ } }
+
+ /* write raw values as 4-bits (max : 15) */
+ if (maxSymbolValue > (256-128)) return ERROR(GENERIC); /* should not happen : likely means source cannot be compressed */
+ if (((maxSymbolValue+1)/2) + 1 > maxDstSize) return ERROR(dstSize_tooSmall); /* not enough space within dst buffer */
+ op[0] = (BYTE)(128 /*special case*/ + (maxSymbolValue-1));
+ huffWeight[maxSymbolValue] = 0; /* to be sure it doesn't cause msan issue in final combination */
+ for (n=0; n<maxSymbolValue; n+=2)
+ op[(n/2)+1] = (BYTE)((huffWeight[n] << 4) + huffWeight[n+1]);
+ return ((maxSymbolValue+1)/2) + 1;
+}
+
+
+size_t HUF_readCTable (HUF_CElt* CTable, U32 maxSymbolValue, const void* src, size_t srcSize)
+{
+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1]; /* init not required, even though some static analyzer may complain */
+ U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
+ U32 tableLog = 0;
+ U32 nbSymbols = 0;
+
+ /* get symbol weights */
+ CHECK_V_F(readSize, HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX+1, rankVal, &nbSymbols, &tableLog, src, srcSize));
+
+ /* check result */
+ if (tableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
+ if (nbSymbols > maxSymbolValue+1) return ERROR(maxSymbolValue_tooSmall);
+
+ /* Prepare base value per rank */
+ { U32 n, nextRankStart = 0;
+ for (n=1; n<=tableLog; n++) {
+ U32 current = nextRankStart;
+ nextRankStart += (rankVal[n] << (n-1));
+ rankVal[n] = current;
+ } }
+
+ /* fill nbBits */
+ { U32 n; for (n=0; n<nbSymbols; n++) {
+ const U32 w = huffWeight[n];
+ CTable[n].nbBits = (BYTE)(tableLog + 1 - w);
+ } }
+
+ /* fill val */
+ { U16 nbPerRank[HUF_TABLELOG_MAX+2] = {0}; /* support w=0=>n=tableLog+1 */
+ U16 valPerRank[HUF_TABLELOG_MAX+2] = {0};
+ { U32 n; for (n=0; n<nbSymbols; n++) nbPerRank[CTable[n].nbBits]++; }
+ /* determine stating value per rank */
+ valPerRank[tableLog+1] = 0; /* for w==0 */
+ { U16 min = 0;
+ U32 n; for (n=tableLog; n>0; n--) { /* start at n=tablelog <-> w=1 */
+ valPerRank[n] = min; /* get starting value within each rank */
+ min += nbPerRank[n];
+ min >>= 1;
+ } }
+ /* assign value within rank, symbol order */
+ { U32 n; for (n=0; n<=maxSymbolValue; n++) CTable[n].val = valPerRank[CTable[n].nbBits]++; }
+ }
+
+ return readSize;
+}
+
+
+typedef struct nodeElt_s {
+ U32 count;
+ U16 parent;
+ BYTE byte;
+ BYTE nbBits;
+} nodeElt;
+
+static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
+{
+ const U32 largestBits = huffNode[lastNonNull].nbBits;
+ if (largestBits <= maxNbBits) return largestBits; /* early exit : no elt > maxNbBits */
+
+ /* there are several too large elements (at least >= 2) */
+ { int totalCost = 0;
+ const U32 baseCost = 1 << (largestBits - maxNbBits);
+ U32 n = lastNonNull;
+
+ while (huffNode[n].nbBits > maxNbBits) {
+ totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
+ huffNode[n].nbBits = (BYTE)maxNbBits;
+ n --;
+ } /* n stops at huffNode[n].nbBits <= maxNbBits */
+ while (huffNode[n].nbBits == maxNbBits) n--; /* n end at index of smallest symbol using < maxNbBits */
+
+ /* renorm totalCost */
+ totalCost >>= (largestBits - maxNbBits); /* note : totalCost is necessarily a multiple of baseCost */
+
+ /* repay normalized cost */
+ { U32 const noSymbol = 0xF0F0F0F0;
+ U32 rankLast[HUF_TABLELOG_MAX+2];
+ int pos;
+
+ /* Get pos of last (smallest) symbol per rank */
+ memset(rankLast, 0xF0, sizeof(rankLast));
+ { U32 currentNbBits = maxNbBits;
+ for (pos=n ; pos >= 0; pos--) {
+ if (huffNode[pos].nbBits >= currentNbBits) continue;
+ currentNbBits = huffNode[pos].nbBits; /* < maxNbBits */
+ rankLast[maxNbBits-currentNbBits] = pos;
+ } }
+
+ while (totalCost > 0) {
+ U32 nBitsToDecrease = BIT_highbit32(totalCost) + 1;
+ for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
+ U32 highPos = rankLast[nBitsToDecrease];
+ U32 lowPos = rankLast[nBitsToDecrease-1];
+ if (highPos == noSymbol) continue;
+ if (lowPos == noSymbol) break;
+ { U32 const highTotal = huffNode[highPos].count;
+ U32 const lowTotal = 2 * huffNode[lowPos].count;
+ if (highTotal <= lowTotal) break;
+ } }
+ /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
+ while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol)) /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
+ nBitsToDecrease ++;
+ totalCost -= 1 << (nBitsToDecrease-1);
+ if (rankLast[nBitsToDecrease-1] == noSymbol)
+ rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease]; /* this rank is no longer empty */
+ huffNode[rankLast[nBitsToDecrease]].nbBits ++;
+ if (rankLast[nBitsToDecrease] == 0) /* special case, reached largest symbol */
+ rankLast[nBitsToDecrease] = noSymbol;
+ else {
+ rankLast[nBitsToDecrease]--;
+ if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
+ rankLast[nBitsToDecrease] = noSymbol; /* this rank is now empty */
+ } } /* while (totalCost > 0) */
+
+ while (totalCost < 0) { /* Sometimes, cost correction overshoot */
+ if (rankLast[1] == noSymbol) { /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
+ while (huffNode[n].nbBits == maxNbBits) n--;
+ huffNode[n+1].nbBits--;
+ rankLast[1] = n+1;
+ totalCost++;
+ continue;
+ }
+ huffNode[ rankLast[1] + 1 ].nbBits--;
+ rankLast[1]++;
+ totalCost ++;
+ } } } /* there are several too large elements (at least >= 2) */
+
+ return maxNbBits;
+}
+
+
+typedef struct {
+ U32 base;
+ U32 current;
+} rankPos;
+
+static void HUF_sort(nodeElt* huffNode, const U32* count, U32 maxSymbolValue)
+{
+ rankPos rank[32];
+ U32 n;
+
+ memset(rank, 0, sizeof(rank));
+ for (n=0; n<=maxSymbolValue; n++) {
+ U32 r = BIT_highbit32(count[n] + 1);
+ rank[r].base ++;
+ }
+ for (n=30; n>0; n--) rank[n-1].base += rank[n].base;
+ for (n=0; n<32; n++) rank[n].current = rank[n].base;
+ for (n=0; n<=maxSymbolValue; n++) {
+ U32 const c = count[n];
+ U32 const r = BIT_highbit32(c+1) + 1;
+ U32 pos = rank[r].current++;
+ while ((pos > rank[r].base) && (c > huffNode[pos-1].count)) huffNode[pos]=huffNode[pos-1], pos--;
+ huffNode[pos].count = c;
+ huffNode[pos].byte = (BYTE)n;
+ }
+}
+
+
+/** HUF_buildCTable_wksp() :
+ * Same as HUF_buildCTable(), but using externally allocated scratch buffer.
+ * `workSpace` must be aligned on 4-bytes boundaries, and be at least as large as a table of 1024 unsigned.
+ */
+#define STARTNODE (HUF_SYMBOLVALUE_MAX+1)
+typedef nodeElt huffNodeTable[2*HUF_SYMBOLVALUE_MAX+1 +1];
+size_t HUF_buildCTable_wksp (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits, void* workSpace, size_t wkspSize)
+{
+ nodeElt* const huffNode0 = (nodeElt*)workSpace;
+ nodeElt* const huffNode = huffNode0+1;
+ U32 n, nonNullRank;
+ int lowS, lowN;
+ U16 nodeNb = STARTNODE;
+ U32 nodeRoot;
+
+ /* safety checks */
+ if (wkspSize < sizeof(huffNodeTable)) return ERROR(GENERIC); /* workSpace is not large enough */
+ if (maxNbBits == 0) maxNbBits = HUF_TABLELOG_DEFAULT;
+ if (maxSymbolValue > HUF_SYMBOLVALUE_MAX) return ERROR(GENERIC);
+ memset(huffNode0, 0, sizeof(huffNodeTable));
+
+ /* sort, decreasing order */
+ HUF_sort(huffNode, count, maxSymbolValue);
+
+ /* init for parents */
+ nonNullRank = maxSymbolValue;
+ while(huffNode[nonNullRank].count == 0) nonNullRank--;
+ lowS = nonNullRank; nodeRoot = nodeNb + lowS - 1; lowN = nodeNb;
+ huffNode[nodeNb].count = huffNode[lowS].count + huffNode[lowS-1].count;
+ huffNode[lowS].parent = huffNode[lowS-1].parent = nodeNb;
+ nodeNb++; lowS-=2;
+ for (n=nodeNb; n<=nodeRoot; n++) huffNode[n].count = (U32)(1U<<30);
+ huffNode0[0].count = (U32)(1U<<31); /* fake entry, strong barrier */
+
+ /* create parents */
+ while (nodeNb <= nodeRoot) {
+ U32 n1 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
+ U32 n2 = (huffNode[lowS].count < huffNode[lowN].count) ? lowS-- : lowN++;
+ huffNode[nodeNb].count = huffNode[n1].count + huffNode[n2].count;
+ huffNode[n1].parent = huffNode[n2].parent = nodeNb;
+ nodeNb++;
+ }
+
+ /* distribute weights (unlimited tree height) */
+ huffNode[nodeRoot].nbBits = 0;
+ for (n=nodeRoot-1; n>=STARTNODE; n--)
+ huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
+ for (n=0; n<=nonNullRank; n++)
+ huffNode[n].nbBits = huffNode[ huffNode[n].parent ].nbBits + 1;
+
+ /* enforce maxTableLog */
+ maxNbBits = HUF_setMaxHeight(huffNode, nonNullRank, maxNbBits);
+
+ /* fill result into tree (val, nbBits) */
+ { U16 nbPerRank[HUF_TABLELOG_MAX+1] = {0};
+ U16 valPerRank[HUF_TABLELOG_MAX+1] = {0};
+ if (maxNbBits > HUF_TABLELOG_MAX) return ERROR(GENERIC); /* check fit into table */
+ for (n=0; n<=nonNullRank; n++)
+ nbPerRank[huffNode[n].nbBits]++;
+ /* determine stating value per rank */
+ { U16 min = 0;
+ for (n=maxNbBits; n>0; n--) {
+ valPerRank[n] = min; /* get starting value within each rank */
+ min += nbPerRank[n];
+ min >>= 1;
+ } }
+ for (n=0; n<=maxSymbolValue; n++)
+ tree[huffNode[n].byte].nbBits = huffNode[n].nbBits; /* push nbBits per symbol, symbol order */
+ for (n=0; n<=maxSymbolValue; n++)
+ tree[n].val = valPerRank[tree[n].nbBits]++; /* assign value within rank, symbol order */
+ }
+
+ return maxNbBits;
+}
+
+/** HUF_buildCTable() :
+ * Note : count is used before tree is written, so they can safely overlap
+ */
+size_t HUF_buildCTable (HUF_CElt* tree, const U32* count, U32 maxSymbolValue, U32 maxNbBits)
+{
+ huffNodeTable nodeTable;
+ return HUF_buildCTable_wksp(tree, count, maxSymbolValue, maxNbBits, nodeTable, sizeof(nodeTable));
+}
+
+static size_t HUF_estimateCompressedSize(HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue)
+{
+ size_t nbBits = 0;
+ int s;
+ for (s = 0; s <= (int)maxSymbolValue; ++s) {
+ nbBits += CTable[s].nbBits * count[s];
+ }
+ return nbBits >> 3;
+}
+
+static int HUF_validateCTable(const HUF_CElt* CTable, const unsigned* count, unsigned maxSymbolValue) {
+ int bad = 0;
+ int s;
+ for (s = 0; s <= (int)maxSymbolValue; ++s) {
+ bad |= (count[s] != 0) & (CTable[s].nbBits == 0);
+ }
+ return !bad;
+}
+
+static void HUF_encodeSymbol(BIT_CStream_t* bitCPtr, U32 symbol, const HUF_CElt* CTable)
+{
+ BIT_addBitsFast(bitCPtr, CTable[symbol].val, CTable[symbol].nbBits);
+}
+
+size_t HUF_compressBound(size_t size) { return HUF_COMPRESSBOUND(size); }
+
+#define HUF_FLUSHBITS(s) (fast ? BIT_flushBitsFast(s) : BIT_flushBits(s))
+
+#define HUF_FLUSHBITS_1(stream) \
+ if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*2+7) HUF_FLUSHBITS(stream)
+
+#define HUF_FLUSHBITS_2(stream) \
+ if (sizeof((stream)->bitContainer)*8 < HUF_TABLELOG_MAX*4+7) HUF_FLUSHBITS(stream)
+
+size_t HUF_compress1X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
+{
+ const BYTE* ip = (const BYTE*) src;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstSize;
+ BYTE* op = ostart;
+ size_t n;
+ const unsigned fast = (dstSize >= HUF_BLOCKBOUND(srcSize));
+ BIT_CStream_t bitC;
+
+ /* init */
+ if (dstSize < 8) return 0; /* not enough space to compress */
+ { size_t const initErr = BIT_initCStream(&bitC, op, oend-op);
+ if (HUF_isError(initErr)) return 0; }
+
+ n = srcSize & ~3; /* join to mod 4 */
+ switch (srcSize & 3)
+ {
+ case 3 : HUF_encodeSymbol(&bitC, ip[n+ 2], CTable);
+ HUF_FLUSHBITS_2(&bitC);
+ case 2 : HUF_encodeSymbol(&bitC, ip[n+ 1], CTable);
+ HUF_FLUSHBITS_1(&bitC);
+ case 1 : HUF_encodeSymbol(&bitC, ip[n+ 0], CTable);
+ HUF_FLUSHBITS(&bitC);
+ case 0 :
+ default: ;
+ }
+
+ for (; n>0; n-=4) { /* note : n&3==0 at this stage */
+ HUF_encodeSymbol(&bitC, ip[n- 1], CTable);
+ HUF_FLUSHBITS_1(&bitC);
+ HUF_encodeSymbol(&bitC, ip[n- 2], CTable);
+ HUF_FLUSHBITS_2(&bitC);
+ HUF_encodeSymbol(&bitC, ip[n- 3], CTable);
+ HUF_FLUSHBITS_1(&bitC);
+ HUF_encodeSymbol(&bitC, ip[n- 4], CTable);
+ HUF_FLUSHBITS(&bitC);
+ }
+
+ return BIT_closeCStream(&bitC);
+}
+
+
+size_t HUF_compress4X_usingCTable(void* dst, size_t dstSize, const void* src, size_t srcSize, const HUF_CElt* CTable)
+{
+ size_t const segmentSize = (srcSize+3)/4; /* first 3 segments */
+ const BYTE* ip = (const BYTE*) src;
+ const BYTE* const iend = ip + srcSize;
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* const oend = ostart + dstSize;
+ BYTE* op = ostart;
+
+ if (dstSize < 6 + 1 + 1 + 1 + 8) return 0; /* minimum space to compress successfully */
+ if (srcSize < 12) return 0; /* no saving possible : too small input */
+ op += 6; /* jumpTable */
+
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
+ if (cSize==0) return 0;
+ MEM_writeLE16(ostart, (U16)cSize);
+ op += cSize;
+ }
+
+ ip += segmentSize;
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
+ if (cSize==0) return 0;
+ MEM_writeLE16(ostart+2, (U16)cSize);
+ op += cSize;
+ }
+
+ ip += segmentSize;
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, segmentSize, CTable) );
+ if (cSize==0) return 0;
+ MEM_writeLE16(ostart+4, (U16)cSize);
+ op += cSize;
+ }
+
+ ip += segmentSize;
+ { CHECK_V_F(cSize, HUF_compress1X_usingCTable(op, oend-op, ip, iend-ip, CTable) );
+ if (cSize==0) return 0;
+ op += cSize;
+ }
+
+ return op-ostart;
+}
+
+
+static size_t HUF_compressCTable_internal(
+ BYTE* const ostart, BYTE* op, BYTE* const oend,
+ const void* src, size_t srcSize,
+ unsigned singleStream, const HUF_CElt* CTable)
+{
+ size_t const cSize = singleStream ?
+ HUF_compress1X_usingCTable(op, oend - op, src, srcSize, CTable) :
+ HUF_compress4X_usingCTable(op, oend - op, src, srcSize, CTable);
+ if (HUF_isError(cSize)) { return cSize; }
+ if (cSize==0) { return 0; } /* uncompressible */
+ op += cSize;
+ /* check compressibility */
+ if ((size_t)(op-ostart) >= srcSize-1) { return 0; }
+ return op-ostart;
+}
+
+
+/* `workSpace` must a table of at least 1024 unsigned */
+static size_t HUF_compress_internal (
+ void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ unsigned singleStream,
+ void* workSpace, size_t wkspSize,
+ HUF_CElt* oldHufTable, HUF_repeat* repeat, int preferRepeat)
+{
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstSize;
+ BYTE* op = ostart;
+
+ U32* count;
+ size_t const countSize = sizeof(U32) * (HUF_SYMBOLVALUE_MAX + 1);
+ HUF_CElt* CTable;
+ size_t const CTableSize = sizeof(HUF_CElt) * (HUF_SYMBOLVALUE_MAX + 1);
+
+ /* checks & inits */
+ if (wkspSize < sizeof(huffNodeTable) + countSize + CTableSize) return ERROR(GENERIC);
+ if (!srcSize) return 0; /* Uncompressed (note : 1 means rle, so first byte must be correct) */
+ if (!dstSize) return 0; /* cannot fit within dst budget */
+ if (srcSize > HUF_BLOCKSIZE_MAX) return ERROR(srcSize_wrong); /* current block size limit */
+ if (huffLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
+ if (!maxSymbolValue) maxSymbolValue = HUF_SYMBOLVALUE_MAX;
+ if (!huffLog) huffLog = HUF_TABLELOG_DEFAULT;
+
+ count = (U32*)workSpace;
+ workSpace = (BYTE*)workSpace + countSize;
+ wkspSize -= countSize;
+ CTable = (HUF_CElt*)workSpace;
+ workSpace = (BYTE*)workSpace + CTableSize;
+ wkspSize -= CTableSize;
+
+ /* Heuristic : If we don't need to check the validity of the old table use the old table for small inputs */
+ if (preferRepeat && repeat && *repeat == HUF_repeat_valid) {
+ return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
+ }
+
+ /* Scan input and build symbol stats */
+ { CHECK_V_F(largest, FSE_count_wksp (count, &maxSymbolValue, (const BYTE*)src, srcSize, (U32*)workSpace) );
+ if (largest == srcSize) { *ostart = ((const BYTE*)src)[0]; return 1; } /* single symbol, rle */
+ if (largest <= (srcSize >> 7)+1) return 0; /* Fast heuristic : not compressible enough */
+ }
+
+ /* Check validity of previous table */
+ if (repeat && *repeat == HUF_repeat_check && !HUF_validateCTable(oldHufTable, count, maxSymbolValue)) {
+ *repeat = HUF_repeat_none;
+ }
+ /* Heuristic : use existing table for small inputs */
+ if (preferRepeat && repeat && *repeat != HUF_repeat_none) {
+ return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
+ }
+
+ /* Build Huffman Tree */
+ huffLog = HUF_optimalTableLog(huffLog, srcSize, maxSymbolValue);
+ { CHECK_V_F(maxBits, HUF_buildCTable_wksp (CTable, count, maxSymbolValue, huffLog, workSpace, wkspSize) );
+ huffLog = (U32)maxBits;
+ /* Zero the unused symbols so we can check it for validity */
+ memset(CTable + maxSymbolValue + 1, 0, CTableSize - (maxSymbolValue + 1) * sizeof(HUF_CElt));
+ }
+
+ /* Write table description header */
+ { CHECK_V_F(hSize, HUF_writeCTable (op, dstSize, CTable, maxSymbolValue, huffLog) );
+ /* Check if using the previous table will be beneficial */
+ if (repeat && *repeat != HUF_repeat_none) {
+ size_t const oldSize = HUF_estimateCompressedSize(oldHufTable, count, maxSymbolValue);
+ size_t const newSize = HUF_estimateCompressedSize(CTable, count, maxSymbolValue);
+ if (oldSize <= hSize + newSize || hSize + 12 >= srcSize) {
+ return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, oldHufTable);
+ }
+ }
+ /* Use the new table */
+ if (hSize + 12ul >= srcSize) { return 0; }
+ op += hSize;
+ if (repeat) { *repeat = HUF_repeat_none; }
+ if (oldHufTable) { memcpy(oldHufTable, CTable, CTableSize); } /* Save the new table */
+ }
+ return HUF_compressCTable_internal(ostart, op, oend, src, srcSize, singleStream, CTable);
+}
+
+
+size_t HUF_compress1X_wksp (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ void* workSpace, size_t wkspSize)
+{
+ return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, NULL, NULL, 0);
+}
+
+size_t HUF_compress1X_repeat (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ void* workSpace, size_t wkspSize,
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
+{
+ return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 1 /* single stream */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
+}
+
+size_t HUF_compress1X (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog)
+{
+ unsigned workSpace[1024];
+ return HUF_compress1X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
+}
+
+size_t HUF_compress4X_wksp (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ void* workSpace, size_t wkspSize)
+{
+ return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, NULL, NULL, 0);
+}
+
+size_t HUF_compress4X_repeat (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog,
+ void* workSpace, size_t wkspSize,
+ HUF_CElt* hufTable, HUF_repeat* repeat, int preferRepeat)
+{
+ return HUF_compress_internal(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, 0 /* 4 streams */, workSpace, wkspSize, hufTable, repeat, preferRepeat);
+}
+
+size_t HUF_compress2 (void* dst, size_t dstSize,
+ const void* src, size_t srcSize,
+ unsigned maxSymbolValue, unsigned huffLog)
+{
+ unsigned workSpace[1024];
+ return HUF_compress4X_wksp(dst, dstSize, src, srcSize, maxSymbolValue, huffLog, workSpace, sizeof(workSpace));
+}
+
+size_t HUF_compress (void* dst, size_t maxDstSize, const void* src, size_t srcSize)
+{
+ return HUF_compress2(dst, maxDstSize, src, (U32)srcSize, 255, HUF_TABLELOG_DEFAULT);
+}
diff --git a/thirdparty/zstd/compress/zstd_compress.c b/thirdparty/zstd/compress/zstd_compress.c
new file mode 100644
index 0000000000..c08b315dab
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_compress.c
@@ -0,0 +1,3598 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+/*-*************************************
+* Dependencies
+***************************************/
+#include <string.h> /* memset */
+#include "mem.h"
+#define FSE_STATIC_LINKING_ONLY /* FSE_encodeSymbol */
+#include "fse.h"
+#define HUF_STATIC_LINKING_ONLY
+#include "huf.h"
+#include "zstd_internal.h" /* includes zstd.h */
+
+
+/*-*************************************
+* Debug
+***************************************/
+#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=1)
+# include <assert.h>
+#else
+# define assert(condition) ((void)0)
+#endif
+
+#define ZSTD_STATIC_ASSERT(c) { enum { ZSTD_static_assert = 1/(int)(!!(c)) }; }
+
+#if defined(ZSTD_DEBUG) && (ZSTD_DEBUG>=2)
+# include <stdio.h>
+ static unsigned g_debugLevel = ZSTD_DEBUG;
+# define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
+#else
+# define DEBUGLOG(l, ...) {} /* disabled */
+#endif
+
+
+/*-*************************************
+* Constants
+***************************************/
+static const U32 g_searchStrength = 8; /* control skip over incompressible data */
+#define HASH_READ_SIZE 8
+typedef enum { ZSTDcs_created=0, ZSTDcs_init, ZSTDcs_ongoing, ZSTDcs_ending } ZSTD_compressionStage_e;
+
+/* entropy tables always have same size */
+static size_t const hufCTable_size = HUF_CTABLE_SIZE(255);
+static size_t const litlengthCTable_size = FSE_CTABLE_SIZE(LLFSELog, MaxLL);
+static size_t const offcodeCTable_size = FSE_CTABLE_SIZE(OffFSELog, MaxOff);
+static size_t const matchlengthCTable_size = FSE_CTABLE_SIZE(MLFSELog, MaxML);
+static size_t const entropyScratchSpace_size = HUF_WORKSPACE_SIZE;
+
+
+/*-*************************************
+* Helper functions
+***************************************/
+size_t ZSTD_compressBound(size_t srcSize) {
+ size_t const lowLimit = 256 KB;
+ size_t const margin = (srcSize < lowLimit) ? (lowLimit-srcSize) >> 12 : 0; /* from 64 to 0 */
+ return srcSize + (srcSize >> 8) + margin;
+}
+
+
+/*-*************************************
+* Sequence storage
+***************************************/
+static void ZSTD_resetSeqStore(seqStore_t* ssPtr)
+{
+ ssPtr->lit = ssPtr->litStart;
+ ssPtr->sequences = ssPtr->sequencesStart;
+ ssPtr->longLengthID = 0;
+}
+
+
+/*-*************************************
+* Context memory management
+***************************************/
+struct ZSTD_CCtx_s {
+ const BYTE* nextSrc; /* next block here to continue on current prefix */
+ const BYTE* base; /* All regular indexes relative to this position */
+ const BYTE* dictBase; /* extDict indexes relative to this position */
+ U32 dictLimit; /* below that point, need extDict */
+ U32 lowLimit; /* below that point, no more data */
+ U32 nextToUpdate; /* index from which to continue dictionary update */
+ U32 nextToUpdate3; /* index from which to continue dictionary update */
+ U32 hashLog3; /* dispatch table : larger == faster, more memory */
+ U32 loadedDictEnd; /* index of end of dictionary */
+ U32 forceWindow; /* force back-references to respect limit of 1<<wLog, even for dictionary */
+ U32 forceRawDict; /* Force loading dictionary in "content-only" mode (no header analysis) */
+ ZSTD_compressionStage_e stage;
+ U32 rep[ZSTD_REP_NUM];
+ U32 repToConfirm[ZSTD_REP_NUM];
+ U32 dictID;
+ ZSTD_parameters params;
+ void* workSpace;
+ size_t workSpaceSize;
+ size_t blockSize;
+ U64 frameContentSize;
+ U64 consumedSrcSize;
+ XXH64_state_t xxhState;
+ ZSTD_customMem customMem;
+
+ seqStore_t seqStore; /* sequences storage ptrs */
+ U32* hashTable;
+ U32* hashTable3;
+ U32* chainTable;
+ HUF_repeat hufCTable_repeatMode;
+ HUF_CElt* hufCTable;
+ U32 fseCTables_ready;
+ FSE_CTable* offcodeCTable;
+ FSE_CTable* matchlengthCTable;
+ FSE_CTable* litlengthCTable;
+ unsigned* entropyScratchSpace;
+};
+
+ZSTD_CCtx* ZSTD_createCCtx(void)
+{
+ return ZSTD_createCCtx_advanced(defaultCustomMem);
+}
+
+ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem)
+{
+ ZSTD_CCtx* cctx;
+
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ cctx = (ZSTD_CCtx*) ZSTD_malloc(sizeof(ZSTD_CCtx), customMem);
+ if (!cctx) return NULL;
+ memset(cctx, 0, sizeof(ZSTD_CCtx));
+ cctx->customMem = customMem;
+ return cctx;
+}
+
+size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx)
+{
+ if (cctx==NULL) return 0; /* support free on NULL */
+ ZSTD_free(cctx->workSpace, cctx->customMem);
+ ZSTD_free(cctx, cctx->customMem);
+ return 0; /* reserved as a potential error code in the future */
+}
+
+size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx)
+{
+ if (cctx==NULL) return 0; /* support sizeof on NULL */
+ return sizeof(*cctx) + cctx->workSpaceSize;
+}
+
+size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value)
+{
+ switch(param)
+ {
+ case ZSTD_p_forceWindow : cctx->forceWindow = value>0; cctx->loadedDictEnd = 0; return 0;
+ case ZSTD_p_forceRawDict : cctx->forceRawDict = value>0; return 0;
+ default: return ERROR(parameter_unknown);
+ }
+}
+
+const seqStore_t* ZSTD_getSeqStore(const ZSTD_CCtx* ctx) /* hidden interface */
+{
+ return &(ctx->seqStore);
+}
+
+static ZSTD_parameters ZSTD_getParamsFromCCtx(const ZSTD_CCtx* cctx)
+{
+ return cctx->params;
+}
+
+
+/** ZSTD_checkParams() :
+ ensure param values remain within authorized range.
+ @return : 0, or an error code if one value is beyond authorized range */
+size_t ZSTD_checkCParams(ZSTD_compressionParameters cParams)
+{
+# define CLAMPCHECK(val,min,max) { if ((val<min) | (val>max)) return ERROR(compressionParameter_unsupported); }
+ CLAMPCHECK(cParams.windowLog, ZSTD_WINDOWLOG_MIN, ZSTD_WINDOWLOG_MAX);
+ CLAMPCHECK(cParams.chainLog, ZSTD_CHAINLOG_MIN, ZSTD_CHAINLOG_MAX);
+ CLAMPCHECK(cParams.hashLog, ZSTD_HASHLOG_MIN, ZSTD_HASHLOG_MAX);
+ CLAMPCHECK(cParams.searchLog, ZSTD_SEARCHLOG_MIN, ZSTD_SEARCHLOG_MAX);
+ CLAMPCHECK(cParams.searchLength, ZSTD_SEARCHLENGTH_MIN, ZSTD_SEARCHLENGTH_MAX);
+ CLAMPCHECK(cParams.targetLength, ZSTD_TARGETLENGTH_MIN, ZSTD_TARGETLENGTH_MAX);
+ if ((U32)(cParams.strategy) > (U32)ZSTD_btopt2) return ERROR(compressionParameter_unsupported);
+ return 0;
+}
+
+
+/** ZSTD_cycleLog() :
+ * condition for correct operation : hashLog > 1 */
+static U32 ZSTD_cycleLog(U32 hashLog, ZSTD_strategy strat)
+{
+ U32 const btScale = ((U32)strat >= (U32)ZSTD_btlazy2);
+ return hashLog - btScale;
+}
+
+/** ZSTD_adjustCParams() :
+ optimize `cPar` for a given input (`srcSize` and `dictSize`).
+ mostly downsizing to reduce memory consumption and initialization.
+ Both `srcSize` and `dictSize` are optional (use 0 if unknown),
+ but if both are 0, no optimization can be done.
+ Note : cPar is considered validated at this stage. Use ZSTD_checkParams() to ensure that. */
+ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize)
+{
+ if (srcSize+dictSize == 0) return cPar; /* no size information available : no adjustment */
+
+ /* resize params, to use less memory when necessary */
+ { U32 const minSrcSize = (srcSize==0) ? 500 : 0;
+ U64 const rSize = srcSize + dictSize + minSrcSize;
+ if (rSize < ((U64)1<<ZSTD_WINDOWLOG_MAX)) {
+ U32 const srcLog = MAX(ZSTD_HASHLOG_MIN, ZSTD_highbit32((U32)(rSize)-1) + 1);
+ if (cPar.windowLog > srcLog) cPar.windowLog = srcLog;
+ } }
+ if (cPar.hashLog > cPar.windowLog) cPar.hashLog = cPar.windowLog;
+ { U32 const cycleLog = ZSTD_cycleLog(cPar.chainLog, cPar.strategy);
+ if (cycleLog > cPar.windowLog) cPar.chainLog -= (cycleLog - cPar.windowLog);
+ }
+
+ if (cPar.windowLog < ZSTD_WINDOWLOG_ABSOLUTEMIN) cPar.windowLog = ZSTD_WINDOWLOG_ABSOLUTEMIN; /* required for frame header */
+
+ return cPar;
+}
+
+
+size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams)
+{
+ size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << cParams.windowLog);
+ U32 const divider = (cParams.searchLength==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
+
+ size_t const chainSize = (cParams.strategy == ZSTD_fast) ? 0 : (1 << cParams.chainLog);
+ size_t const hSize = ((size_t)1) << cParams.hashLog;
+ U32 const hashLog3 = (cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, cParams.windowLog);
+ size_t const h3Size = ((size_t)1) << hashLog3;
+ size_t const entropySpace = hufCTable_size + litlengthCTable_size
+ + offcodeCTable_size + matchlengthCTable_size
+ + entropyScratchSpace_size;
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+
+ size_t const optSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits))*sizeof(U32)
+ + (ZSTD_OPT_NUM+1)*(sizeof(ZSTD_match_t) + sizeof(ZSTD_optimal_t));
+ size_t const neededSpace = entropySpace + tableSpace + tokenSpace
+ + (((cParams.strategy == ZSTD_btopt) || (cParams.strategy == ZSTD_btopt2)) ? optSpace : 0);
+
+ return sizeof(ZSTD_CCtx) + neededSpace;
+}
+
+
+static U32 ZSTD_equivalentParams(ZSTD_parameters param1, ZSTD_parameters param2)
+{
+ return (param1.cParams.hashLog == param2.cParams.hashLog)
+ & (param1.cParams.chainLog == param2.cParams.chainLog)
+ & (param1.cParams.strategy == param2.cParams.strategy)
+ & ((param1.cParams.searchLength==3) == (param2.cParams.searchLength==3));
+}
+
+/*! ZSTD_continueCCtx() :
+ reuse CCtx without reset (note : requires no dictionary) */
+static size_t ZSTD_continueCCtx(ZSTD_CCtx* cctx, ZSTD_parameters params, U64 frameContentSize)
+{
+ U32 const end = (U32)(cctx->nextSrc - cctx->base);
+ cctx->params = params;
+ cctx->frameContentSize = frameContentSize;
+ cctx->consumedSrcSize = 0;
+ cctx->lowLimit = end;
+ cctx->dictLimit = end;
+ cctx->nextToUpdate = end+1;
+ cctx->stage = ZSTDcs_init;
+ cctx->dictID = 0;
+ cctx->loadedDictEnd = 0;
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = repStartValue[i]; }
+ cctx->seqStore.litLengthSum = 0; /* force reset of btopt stats */
+ XXH64_reset(&cctx->xxhState, 0);
+ return 0;
+}
+
+typedef enum { ZSTDcrp_continue, ZSTDcrp_noMemset, ZSTDcrp_fullReset } ZSTD_compResetPolicy_e;
+
+/*! ZSTD_resetCCtx_internal() :
+ note : `params` must be validated */
+static size_t ZSTD_resetCCtx_internal (ZSTD_CCtx* zc,
+ ZSTD_parameters params, U64 frameContentSize,
+ ZSTD_compResetPolicy_e const crp)
+{
+ if (crp == ZSTDcrp_continue)
+ if (ZSTD_equivalentParams(params, zc->params)) {
+ zc->fseCTables_ready = 0;
+ zc->hufCTable_repeatMode = HUF_repeat_none;
+ return ZSTD_continueCCtx(zc, params, frameContentSize);
+ }
+
+ { size_t const blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, (size_t)1 << params.cParams.windowLog);
+ U32 const divider = (params.cParams.searchLength==3) ? 3 : 4;
+ size_t const maxNbSeq = blockSize / divider;
+ size_t const tokenSpace = blockSize + 11*maxNbSeq;
+ size_t const chainSize = (params.cParams.strategy == ZSTD_fast) ? 0 : (1 << params.cParams.chainLog);
+ size_t const hSize = ((size_t)1) << params.cParams.hashLog;
+ U32 const hashLog3 = (params.cParams.searchLength>3) ? 0 : MIN(ZSTD_HASHLOG3_MAX, params.cParams.windowLog);
+ size_t const h3Size = ((size_t)1) << hashLog3;
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+ void* ptr;
+
+ /* Check if workSpace is large enough, alloc a new one if needed */
+ { size_t const entropySpace = hufCTable_size + litlengthCTable_size
+ + offcodeCTable_size + matchlengthCTable_size
+ + entropyScratchSpace_size;
+ size_t const optPotentialSpace = ((MaxML+1) + (MaxLL+1) + (MaxOff+1) + (1<<Litbits)) * sizeof(U32)
+ + (ZSTD_OPT_NUM+1) * (sizeof(ZSTD_match_t)+sizeof(ZSTD_optimal_t));
+ size_t const optSpace = ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) ? optPotentialSpace : 0;
+ size_t const neededSpace = entropySpace + optSpace + tableSpace + tokenSpace;
+ if (zc->workSpaceSize < neededSpace) {
+ zc->workSpaceSize = 0;
+ ZSTD_free(zc->workSpace, zc->customMem);
+ zc->workSpace = ZSTD_malloc(neededSpace, zc->customMem);
+ if (zc->workSpace == NULL) return ERROR(memory_allocation);
+ zc->workSpaceSize = neededSpace;
+ ptr = zc->workSpace;
+
+ /* entropy space */
+ zc->hufCTable = (HUF_CElt*)ptr;
+ ptr = (char*)zc->hufCTable + hufCTable_size; /* note : HUF_CElt* is incomplete type, size is estimated via macro */
+ zc->offcodeCTable = (FSE_CTable*) ptr;
+ ptr = (char*)ptr + offcodeCTable_size;
+ zc->matchlengthCTable = (FSE_CTable*) ptr;
+ ptr = (char*)ptr + matchlengthCTable_size;
+ zc->litlengthCTable = (FSE_CTable*) ptr;
+ ptr = (char*)ptr + litlengthCTable_size;
+ assert(((size_t)ptr & 3) == 0); /* ensure correct alignment */
+ zc->entropyScratchSpace = (unsigned*) ptr;
+ } }
+
+ /* init params */
+ zc->params = params;
+ zc->blockSize = blockSize;
+ zc->frameContentSize = frameContentSize;
+ zc->consumedSrcSize = 0;
+
+ XXH64_reset(&zc->xxhState, 0);
+ zc->stage = ZSTDcs_init;
+ zc->dictID = 0;
+ zc->loadedDictEnd = 0;
+ zc->fseCTables_ready = 0;
+ zc->hufCTable_repeatMode = HUF_repeat_none;
+ zc->nextToUpdate = 1;
+ zc->nextSrc = NULL;
+ zc->base = NULL;
+ zc->dictBase = NULL;
+ zc->dictLimit = 0;
+ zc->lowLimit = 0;
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = repStartValue[i]; }
+ zc->hashLog3 = hashLog3;
+ zc->seqStore.litLengthSum = 0;
+
+ /* ensure entropy tables are close together at the beginning */
+ assert((void*)zc->hufCTable == zc->workSpace);
+ assert((char*)zc->offcodeCTable == (char*)zc->hufCTable + hufCTable_size);
+ assert((char*)zc->matchlengthCTable == (char*)zc->offcodeCTable + offcodeCTable_size);
+ assert((char*)zc->litlengthCTable == (char*)zc->matchlengthCTable + matchlengthCTable_size);
+ assert((char*)zc->entropyScratchSpace == (char*)zc->litlengthCTable + litlengthCTable_size);
+ ptr = (char*)zc->entropyScratchSpace + entropyScratchSpace_size;
+
+ /* opt parser space */
+ if ((params.cParams.strategy == ZSTD_btopt) || (params.cParams.strategy == ZSTD_btopt2)) {
+ assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
+ zc->seqStore.litFreq = (U32*)ptr;
+ zc->seqStore.litLengthFreq = zc->seqStore.litFreq + (1<<Litbits);
+ zc->seqStore.matchLengthFreq = zc->seqStore.litLengthFreq + (MaxLL+1);
+ zc->seqStore.offCodeFreq = zc->seqStore.matchLengthFreq + (MaxML+1);
+ ptr = zc->seqStore.offCodeFreq + (MaxOff+1);
+ zc->seqStore.matchTable = (ZSTD_match_t*)ptr;
+ ptr = zc->seqStore.matchTable + ZSTD_OPT_NUM+1;
+ zc->seqStore.priceTable = (ZSTD_optimal_t*)ptr;
+ ptr = zc->seqStore.priceTable + ZSTD_OPT_NUM+1;
+ }
+
+ /* table Space */
+ if (crp!=ZSTDcrp_noMemset) memset(ptr, 0, tableSpace); /* reset tables only */
+ assert(((size_t)ptr & 3) == 0); /* ensure ptr is properly aligned */
+ zc->hashTable = (U32*)(ptr);
+ zc->chainTable = zc->hashTable + hSize;
+ zc->hashTable3 = zc->chainTable + chainSize;
+ ptr = zc->hashTable3 + h3Size;
+
+ /* sequences storage */
+ zc->seqStore.sequencesStart = (seqDef*)ptr;
+ ptr = zc->seqStore.sequencesStart + maxNbSeq;
+ zc->seqStore.llCode = (BYTE*) ptr;
+ zc->seqStore.mlCode = zc->seqStore.llCode + maxNbSeq;
+ zc->seqStore.ofCode = zc->seqStore.mlCode + maxNbSeq;
+ zc->seqStore.litStart = zc->seqStore.ofCode + maxNbSeq;
+
+ return 0;
+ }
+}
+
+/* ZSTD_invalidateRepCodes() :
+ * ensures next compression will not use repcodes from previous block.
+ * Note : only works with regular variant;
+ * do not use with extDict variant ! */
+void ZSTD_invalidateRepCodes(ZSTD_CCtx* cctx) {
+ int i;
+ for (i=0; i<ZSTD_REP_NUM; i++) cctx->rep[i] = 0;
+}
+
+
+/*! ZSTD_copyCCtx_internal() :
+ * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
+ * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
+ * pledgedSrcSize=0 means "empty" if fParams.contentSizeFlag=1
+ * @return : 0, or an error code */
+size_t ZSTD_copyCCtx_internal(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx,
+ ZSTD_frameParameters fParams, unsigned long long pledgedSrcSize)
+{
+ if (srcCCtx->stage!=ZSTDcs_init) return ERROR(stage_wrong);
+
+ memcpy(&dstCCtx->customMem, &srcCCtx->customMem, sizeof(ZSTD_customMem));
+ { ZSTD_parameters params = srcCCtx->params;
+ params.fParams = fParams;
+ DEBUGLOG(5, "ZSTD_resetCCtx_internal : dictIDFlag : %u \n", !fParams.noDictIDFlag);
+ ZSTD_resetCCtx_internal(dstCCtx, params, pledgedSrcSize, ZSTDcrp_noMemset);
+ }
+
+ /* copy tables */
+ { size_t const chainSize = (srcCCtx->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << srcCCtx->params.cParams.chainLog);
+ size_t const hSize = (size_t)1 << srcCCtx->params.cParams.hashLog;
+ size_t const h3Size = (size_t)1 << srcCCtx->hashLog3;
+ size_t const tableSpace = (chainSize + hSize + h3Size) * sizeof(U32);
+ assert((U32*)dstCCtx->chainTable == (U32*)dstCCtx->hashTable + hSize); /* chainTable must follow hashTable */
+ assert((U32*)dstCCtx->hashTable3 == (U32*)dstCCtx->chainTable + chainSize);
+ memcpy(dstCCtx->hashTable, srcCCtx->hashTable, tableSpace); /* presumes all tables follow each other */
+ }
+
+ /* copy dictionary offsets */
+ dstCCtx->nextToUpdate = srcCCtx->nextToUpdate;
+ dstCCtx->nextToUpdate3= srcCCtx->nextToUpdate3;
+ dstCCtx->nextSrc = srcCCtx->nextSrc;
+ dstCCtx->base = srcCCtx->base;
+ dstCCtx->dictBase = srcCCtx->dictBase;
+ dstCCtx->dictLimit = srcCCtx->dictLimit;
+ dstCCtx->lowLimit = srcCCtx->lowLimit;
+ dstCCtx->loadedDictEnd= srcCCtx->loadedDictEnd;
+ dstCCtx->dictID = srcCCtx->dictID;
+
+ /* copy entropy tables */
+ dstCCtx->fseCTables_ready = srcCCtx->fseCTables_ready;
+ if (srcCCtx->fseCTables_ready) {
+ memcpy(dstCCtx->litlengthCTable, srcCCtx->litlengthCTable, litlengthCTable_size);
+ memcpy(dstCCtx->matchlengthCTable, srcCCtx->matchlengthCTable, matchlengthCTable_size);
+ memcpy(dstCCtx->offcodeCTable, srcCCtx->offcodeCTable, offcodeCTable_size);
+ }
+ dstCCtx->hufCTable_repeatMode = srcCCtx->hufCTable_repeatMode;
+ if (srcCCtx->hufCTable_repeatMode) {
+ memcpy(dstCCtx->hufCTable, srcCCtx->hufCTable, hufCTable_size);
+ }
+
+ return 0;
+}
+
+/*! ZSTD_copyCCtx() :
+ * Duplicate an existing context `srcCCtx` into another one `dstCCtx`.
+ * Only works during stage ZSTDcs_init (i.e. after creation, but before first call to ZSTD_compressContinue()).
+ * pledgedSrcSize==0 means "unknown".
+* @return : 0, or an error code */
+size_t ZSTD_copyCCtx(ZSTD_CCtx* dstCCtx, const ZSTD_CCtx* srcCCtx, unsigned long long pledgedSrcSize)
+{
+ ZSTD_frameParameters fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
+ fParams.contentSizeFlag = pledgedSrcSize>0;
+
+ return ZSTD_copyCCtx_internal(dstCCtx, srcCCtx, fParams, pledgedSrcSize);
+}
+
+
+/*! ZSTD_reduceTable() :
+ * reduce table indexes by `reducerValue` */
+static void ZSTD_reduceTable (U32* const table, U32 const size, U32 const reducerValue)
+{
+ U32 u;
+ for (u=0 ; u < size ; u++) {
+ if (table[u] < reducerValue) table[u] = 0;
+ else table[u] -= reducerValue;
+ }
+}
+
+/*! ZSTD_reduceIndex() :
+* rescale all indexes to avoid future overflow (indexes are U32) */
+static void ZSTD_reduceIndex (ZSTD_CCtx* zc, const U32 reducerValue)
+{
+ { U32 const hSize = 1 << zc->params.cParams.hashLog;
+ ZSTD_reduceTable(zc->hashTable, hSize, reducerValue); }
+
+ { U32 const chainSize = (zc->params.cParams.strategy == ZSTD_fast) ? 0 : (1 << zc->params.cParams.chainLog);
+ ZSTD_reduceTable(zc->chainTable, chainSize, reducerValue); }
+
+ { U32 const h3Size = (zc->hashLog3) ? 1 << zc->hashLog3 : 0;
+ ZSTD_reduceTable(zc->hashTable3, h3Size, reducerValue); }
+}
+
+
+/*-*******************************************************
+* Block entropic compression
+*********************************************************/
+
+/* See doc/zstd_compression_format.md for detailed format description */
+
+size_t ZSTD_noCompressBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ if (srcSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
+ memcpy((BYTE*)dst + ZSTD_blockHeaderSize, src, srcSize);
+ MEM_writeLE24(dst, (U32)(srcSize << 2) + (U32)bt_raw);
+ return ZSTD_blockHeaderSize+srcSize;
+}
+
+
+static size_t ZSTD_noCompressLiterals (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ BYTE* const ostart = (BYTE* const)dst;
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
+
+ if (srcSize + flSize > dstCapacity) return ERROR(dstSize_tooSmall);
+
+ switch(flSize)
+ {
+ case 1: /* 2 - 1 - 5 */
+ ostart[0] = (BYTE)((U32)set_basic + (srcSize<<3));
+ break;
+ case 2: /* 2 - 2 - 12 */
+ MEM_writeLE16(ostart, (U16)((U32)set_basic + (1<<2) + (srcSize<<4)));
+ break;
+ default: /*note : should not be necessary : flSize is within {1,2,3} */
+ case 3: /* 2 - 2 - 20 */
+ MEM_writeLE32(ostart, (U32)((U32)set_basic + (3<<2) + (srcSize<<4)));
+ break;
+ }
+
+ memcpy(ostart + flSize, src, srcSize);
+ return srcSize + flSize;
+}
+
+static size_t ZSTD_compressRleLiteralsBlock (void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ BYTE* const ostart = (BYTE* const)dst;
+ U32 const flSize = 1 + (srcSize>31) + (srcSize>4095);
+
+ (void)dstCapacity; /* dstCapacity already guaranteed to be >=4, hence large enough */
+
+ switch(flSize)
+ {
+ case 1: /* 2 - 1 - 5 */
+ ostart[0] = (BYTE)((U32)set_rle + (srcSize<<3));
+ break;
+ case 2: /* 2 - 2 - 12 */
+ MEM_writeLE16(ostart, (U16)((U32)set_rle + (1<<2) + (srcSize<<4)));
+ break;
+ default: /*note : should not be necessary : flSize is necessarily within {1,2,3} */
+ case 3: /* 2 - 2 - 20 */
+ MEM_writeLE32(ostart, (U32)((U32)set_rle + (3<<2) + (srcSize<<4)));
+ break;
+ }
+
+ ostart[flSize] = *(const BYTE*)src;
+ return flSize+1;
+}
+
+
+static size_t ZSTD_minGain(size_t srcSize) { return (srcSize >> 6) + 2; }
+
+static size_t ZSTD_compressLiterals (ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ size_t const minGain = ZSTD_minGain(srcSize);
+ size_t const lhSize = 3 + (srcSize >= 1 KB) + (srcSize >= 16 KB);
+ BYTE* const ostart = (BYTE*)dst;
+ U32 singleStream = srcSize < 256;
+ symbolEncodingType_e hType = set_compressed;
+ size_t cLitSize;
+
+
+ /* small ? don't even attempt compression (speed opt) */
+# define LITERAL_NOENTROPY 63
+ { size_t const minLitSize = zc->hufCTable_repeatMode == HUF_repeat_valid ? 6 : LITERAL_NOENTROPY;
+ if (srcSize <= minLitSize) return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
+ }
+
+ if (dstCapacity < lhSize+1) return ERROR(dstSize_tooSmall); /* not enough space for compression */
+ { HUF_repeat repeat = zc->hufCTable_repeatMode;
+ int const preferRepeat = zc->params.cParams.strategy < ZSTD_lazy ? srcSize <= 1024 : 0;
+ if (repeat == HUF_repeat_valid && lhSize == 3) singleStream = 1;
+ cLitSize = singleStream ? HUF_compress1X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
+ zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat)
+ : HUF_compress4X_repeat(ostart+lhSize, dstCapacity-lhSize, src, srcSize, 255, 11,
+ zc->entropyScratchSpace, entropyScratchSpace_size, zc->hufCTable, &repeat, preferRepeat);
+ if (repeat != HUF_repeat_none) { hType = set_repeat; } /* reused the existing table */
+ else { zc->hufCTable_repeatMode = HUF_repeat_check; } /* now have a table to reuse */
+ }
+
+ if ((cLitSize==0) | (cLitSize >= srcSize - minGain)) {
+ zc->hufCTable_repeatMode = HUF_repeat_none;
+ return ZSTD_noCompressLiterals(dst, dstCapacity, src, srcSize);
+ }
+ if (cLitSize==1) {
+ zc->hufCTable_repeatMode = HUF_repeat_none;
+ return ZSTD_compressRleLiteralsBlock(dst, dstCapacity, src, srcSize);
+ }
+
+ /* Build header */
+ switch(lhSize)
+ {
+ case 3: /* 2 - 2 - 10 - 10 */
+ { U32 const lhc = hType + ((!singleStream) << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<14);
+ MEM_writeLE24(ostart, lhc);
+ break;
+ }
+ case 4: /* 2 - 2 - 14 - 14 */
+ { U32 const lhc = hType + (2 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<18);
+ MEM_writeLE32(ostart, lhc);
+ break;
+ }
+ default: /* should not be necessary, lhSize is only {3,4,5} */
+ case 5: /* 2 - 2 - 18 - 18 */
+ { U32 const lhc = hType + (3 << 2) + ((U32)srcSize<<4) + ((U32)cLitSize<<22);
+ MEM_writeLE32(ostart, lhc);
+ ostart[4] = (BYTE)(cLitSize >> 10);
+ break;
+ }
+ }
+ return lhSize+cLitSize;
+}
+
+static const BYTE LL_Code[64] = { 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 16, 17, 17, 18, 18, 19, 19,
+ 20, 20, 20, 20, 21, 21, 21, 21,
+ 22, 22, 22, 22, 22, 22, 22, 22,
+ 23, 23, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24 };
+
+static const BYTE ML_Code[128] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 36, 36, 37, 37, 37, 37,
+ 38, 38, 38, 38, 38, 38, 38, 38, 39, 39, 39, 39, 39, 39, 39, 39,
+ 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
+ 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
+ 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42 };
+
+
+void ZSTD_seqToCodes(const seqStore_t* seqStorePtr)
+{
+ BYTE const LL_deltaCode = 19;
+ BYTE const ML_deltaCode = 36;
+ const seqDef* const sequences = seqStorePtr->sequencesStart;
+ BYTE* const llCodeTable = seqStorePtr->llCode;
+ BYTE* const ofCodeTable = seqStorePtr->ofCode;
+ BYTE* const mlCodeTable = seqStorePtr->mlCode;
+ U32 const nbSeq = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ U32 u;
+ for (u=0; u<nbSeq; u++) {
+ U32 const llv = sequences[u].litLength;
+ U32 const mlv = sequences[u].matchLength;
+ llCodeTable[u] = (llv> 63) ? (BYTE)ZSTD_highbit32(llv) + LL_deltaCode : LL_Code[llv];
+ ofCodeTable[u] = (BYTE)ZSTD_highbit32(sequences[u].offset);
+ mlCodeTable[u] = (mlv>127) ? (BYTE)ZSTD_highbit32(mlv) + ML_deltaCode : ML_Code[mlv];
+ }
+ if (seqStorePtr->longLengthID==1)
+ llCodeTable[seqStorePtr->longLengthPos] = MaxLL;
+ if (seqStorePtr->longLengthID==2)
+ mlCodeTable[seqStorePtr->longLengthPos] = MaxML;
+}
+
+MEM_STATIC size_t ZSTD_compressSequences (ZSTD_CCtx* zc,
+ void* dst, size_t dstCapacity,
+ size_t srcSize)
+{
+ const int longOffsets = zc->params.cParams.windowLog > STREAM_ACCUMULATOR_MIN;
+ const seqStore_t* seqStorePtr = &(zc->seqStore);
+ U32 count[MaxSeq+1];
+ S16 norm[MaxSeq+1];
+ FSE_CTable* CTable_LitLength = zc->litlengthCTable;
+ FSE_CTable* CTable_OffsetBits = zc->offcodeCTable;
+ FSE_CTable* CTable_MatchLength = zc->matchlengthCTable;
+ U32 LLtype, Offtype, MLtype; /* compressed, raw or rle */
+ const seqDef* const sequences = seqStorePtr->sequencesStart;
+ const BYTE* const ofCodeTable = seqStorePtr->ofCode;
+ const BYTE* const llCodeTable = seqStorePtr->llCode;
+ const BYTE* const mlCodeTable = seqStorePtr->mlCode;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* const oend = ostart + dstCapacity;
+ BYTE* op = ostart;
+ size_t const nbSeq = seqStorePtr->sequences - seqStorePtr->sequencesStart;
+ BYTE* seqHead;
+ BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
+
+ /* Compress literals */
+ { const BYTE* const literals = seqStorePtr->litStart;
+ size_t const litSize = seqStorePtr->lit - literals;
+ size_t const cSize = ZSTD_compressLiterals(zc, op, dstCapacity, literals, litSize);
+ if (ZSTD_isError(cSize)) return cSize;
+ op += cSize;
+ }
+
+ /* Sequences Header */
+ if ((oend-op) < 3 /*max nbSeq Size*/ + 1 /*seqHead */) return ERROR(dstSize_tooSmall);
+ if (nbSeq < 0x7F) *op++ = (BYTE)nbSeq;
+ else if (nbSeq < LONGNBSEQ) op[0] = (BYTE)((nbSeq>>8) + 0x80), op[1] = (BYTE)nbSeq, op+=2;
+ else op[0]=0xFF, MEM_writeLE16(op+1, (U16)(nbSeq - LONGNBSEQ)), op+=3;
+ if (nbSeq==0) goto _check_compressibility;
+
+ /* seqHead : flags for FSE encoding type */
+ seqHead = op++;
+
+#define MIN_SEQ_FOR_DYNAMIC_FSE 64
+#define MAX_SEQ_FOR_STATIC_FSE 1000
+
+ /* convert length/distances into codes */
+ ZSTD_seqToCodes(seqStorePtr);
+
+ /* CTable for Literal Lengths */
+ { U32 max = MaxLL;
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, llCodeTable, nbSeq, zc->entropyScratchSpace);
+ if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
+ *op++ = llCodeTable[0];
+ FSE_buildCTable_rle(CTable_LitLength, (BYTE)max);
+ LLtype = set_rle;
+ } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ LLtype = set_repeat;
+ } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (LL_defaultNormLog-1)))) {
+ FSE_buildCTable_wksp(CTable_LitLength, LL_defaultNorm, MaxLL, LL_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
+ LLtype = set_basic;
+ } else {
+ size_t nbSeq_1 = nbSeq;
+ const U32 tableLog = FSE_optimalTableLog(LLFSELog, nbSeq, max);
+ if (count[llCodeTable[nbSeq-1]]>1) { count[llCodeTable[nbSeq-1]]--; nbSeq_1--; }
+ FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
+ { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
+ if (FSE_isError(NCountSize)) return NCountSize;
+ op += NCountSize; }
+ FSE_buildCTable_wksp(CTable_LitLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
+ LLtype = set_compressed;
+ } }
+
+ /* CTable for Offsets */
+ { U32 max = MaxOff;
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, ofCodeTable, nbSeq, zc->entropyScratchSpace);
+ if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
+ *op++ = ofCodeTable[0];
+ FSE_buildCTable_rle(CTable_OffsetBits, (BYTE)max);
+ Offtype = set_rle;
+ } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ Offtype = set_repeat;
+ } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (OF_defaultNormLog-1)))) {
+ FSE_buildCTable_wksp(CTable_OffsetBits, OF_defaultNorm, MaxOff, OF_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
+ Offtype = set_basic;
+ } else {
+ size_t nbSeq_1 = nbSeq;
+ const U32 tableLog = FSE_optimalTableLog(OffFSELog, nbSeq, max);
+ if (count[ofCodeTable[nbSeq-1]]>1) { count[ofCodeTable[nbSeq-1]]--; nbSeq_1--; }
+ FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
+ { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
+ if (FSE_isError(NCountSize)) return NCountSize;
+ op += NCountSize; }
+ FSE_buildCTable_wksp(CTable_OffsetBits, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
+ Offtype = set_compressed;
+ } }
+
+ /* CTable for MatchLengths */
+ { U32 max = MaxML;
+ size_t const mostFrequent = FSE_countFast_wksp(count, &max, mlCodeTable, nbSeq, zc->entropyScratchSpace);
+ if ((mostFrequent == nbSeq) && (nbSeq > 2)) {
+ *op++ = *mlCodeTable;
+ FSE_buildCTable_rle(CTable_MatchLength, (BYTE)max);
+ MLtype = set_rle;
+ } else if ((zc->fseCTables_ready) && (nbSeq < MAX_SEQ_FOR_STATIC_FSE)) {
+ MLtype = set_repeat;
+ } else if ((nbSeq < MIN_SEQ_FOR_DYNAMIC_FSE) || (mostFrequent < (nbSeq >> (ML_defaultNormLog-1)))) {
+ FSE_buildCTable_wksp(CTable_MatchLength, ML_defaultNorm, MaxML, ML_defaultNormLog, scratchBuffer, sizeof(scratchBuffer));
+ MLtype = set_basic;
+ } else {
+ size_t nbSeq_1 = nbSeq;
+ const U32 tableLog = FSE_optimalTableLog(MLFSELog, nbSeq, max);
+ if (count[mlCodeTable[nbSeq-1]]>1) { count[mlCodeTable[nbSeq-1]]--; nbSeq_1--; }
+ FSE_normalizeCount(norm, tableLog, count, nbSeq_1, max);
+ { size_t const NCountSize = FSE_writeNCount(op, oend-op, norm, max, tableLog); /* overflow protected */
+ if (FSE_isError(NCountSize)) return NCountSize;
+ op += NCountSize; }
+ FSE_buildCTable_wksp(CTable_MatchLength, norm, max, tableLog, scratchBuffer, sizeof(scratchBuffer));
+ MLtype = set_compressed;
+ } }
+
+ *seqHead = (BYTE)((LLtype<<6) + (Offtype<<4) + (MLtype<<2));
+ zc->fseCTables_ready = 0;
+
+ /* Encoding Sequences */
+ { BIT_CStream_t blockStream;
+ FSE_CState_t stateMatchLength;
+ FSE_CState_t stateOffsetBits;
+ FSE_CState_t stateLitLength;
+
+ CHECK_E(BIT_initCStream(&blockStream, op, oend-op), dstSize_tooSmall); /* not enough space remaining */
+
+ /* first symbols */
+ FSE_initCState2(&stateMatchLength, CTable_MatchLength, mlCodeTable[nbSeq-1]);
+ FSE_initCState2(&stateOffsetBits, CTable_OffsetBits, ofCodeTable[nbSeq-1]);
+ FSE_initCState2(&stateLitLength, CTable_LitLength, llCodeTable[nbSeq-1]);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].litLength, LL_bits[llCodeTable[nbSeq-1]]);
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
+ BIT_addBits(&blockStream, sequences[nbSeq-1].matchLength, ML_bits[mlCodeTable[nbSeq-1]]);
+ if (MEM_32bits()) BIT_flushBits(&blockStream);
+ if (longOffsets) {
+ U32 const ofBits = ofCodeTable[nbSeq-1];
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ if (extraBits) {
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, extraBits);
+ BIT_flushBits(&blockStream);
+ }
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset >> extraBits,
+ ofBits - extraBits);
+ } else {
+ BIT_addBits(&blockStream, sequences[nbSeq-1].offset, ofCodeTable[nbSeq-1]);
+ }
+ BIT_flushBits(&blockStream);
+
+ { size_t n;
+ for (n=nbSeq-2 ; n<nbSeq ; n--) { /* intentional underflow */
+ BYTE const llCode = llCodeTable[n];
+ BYTE const ofCode = ofCodeTable[n];
+ BYTE const mlCode = mlCodeTable[n];
+ U32 const llBits = LL_bits[llCode];
+ U32 const ofBits = ofCode; /* 32b*/ /* 64b*/
+ U32 const mlBits = ML_bits[mlCode];
+ /* (7)*/ /* (7)*/
+ FSE_encodeSymbol(&blockStream, &stateOffsetBits, ofCode); /* 15 */ /* 15 */
+ FSE_encodeSymbol(&blockStream, &stateMatchLength, mlCode); /* 24 */ /* 24 */
+ if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
+ FSE_encodeSymbol(&blockStream, &stateLitLength, llCode); /* 16 */ /* 33 */
+ if (MEM_32bits() || (ofBits+mlBits+llBits >= 64-7-(LLFSELog+MLFSELog+OffFSELog)))
+ BIT_flushBits(&blockStream); /* (7)*/
+ BIT_addBits(&blockStream, sequences[n].litLength, llBits);
+ if (MEM_32bits() && ((llBits+mlBits)>24)) BIT_flushBits(&blockStream);
+ BIT_addBits(&blockStream, sequences[n].matchLength, mlBits);
+ if (MEM_32bits()) BIT_flushBits(&blockStream); /* (7)*/
+ if (longOffsets) {
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN-1);
+ if (extraBits) {
+ BIT_addBits(&blockStream, sequences[n].offset, extraBits);
+ BIT_flushBits(&blockStream); /* (7)*/
+ }
+ BIT_addBits(&blockStream, sequences[n].offset >> extraBits,
+ ofBits - extraBits); /* 31 */
+ } else {
+ BIT_addBits(&blockStream, sequences[n].offset, ofBits); /* 31 */
+ }
+ BIT_flushBits(&blockStream); /* (7)*/
+ } }
+
+ FSE_flushCState(&blockStream, &stateMatchLength);
+ FSE_flushCState(&blockStream, &stateOffsetBits);
+ FSE_flushCState(&blockStream, &stateLitLength);
+
+ { size_t const streamSize = BIT_closeCStream(&blockStream);
+ if (streamSize==0) return ERROR(dstSize_tooSmall); /* not enough space */
+ op += streamSize;
+ } }
+
+ /* check compressibility */
+_check_compressibility:
+ { size_t const minGain = ZSTD_minGain(srcSize);
+ size_t const maxCSize = srcSize - minGain;
+ if ((size_t)(op-ostart) >= maxCSize) {
+ zc->hufCTable_repeatMode = HUF_repeat_none;
+ return 0;
+ } }
+
+ /* confirm repcodes */
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) zc->rep[i] = zc->repToConfirm[i]; }
+
+ return op - ostart;
+}
+
+#if 0 /* for debug */
+# define STORESEQ_DEBUG
+#include <stdio.h> /* fprintf */
+U32 g_startDebug = 0;
+const BYTE* g_start = NULL;
+#endif
+
+/*! ZSTD_storeSeq() :
+ Store a sequence (literal length, literals, offset code and match length code) into seqStore_t.
+ `offsetCode` : distance to match, or 0 == repCode.
+ `matchCode` : matchLength - MINMATCH
+*/
+MEM_STATIC void ZSTD_storeSeq(seqStore_t* seqStorePtr, size_t litLength, const void* literals, U32 offsetCode, size_t matchCode)
+{
+#ifdef STORESEQ_DEBUG
+ if (g_startDebug) {
+ const U32 pos = (U32)((const BYTE*)literals - g_start);
+ if (g_start==NULL) g_start = (const BYTE*)literals;
+ if ((pos > 1895000) && (pos < 1895300))
+ DEBUGLOG(5, "Cpos %6u :%5u literals & match %3u bytes at distance %6u \n",
+ pos, (U32)litLength, (U32)matchCode+MINMATCH, (U32)offsetCode);
+ }
+#endif
+ /* copy Literals */
+ ZSTD_wildcopy(seqStorePtr->lit, literals, litLength);
+ seqStorePtr->lit += litLength;
+
+ /* literal Length */
+ if (litLength>0xFFFF) {
+ seqStorePtr->longLengthID = 1;
+ seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ }
+ seqStorePtr->sequences[0].litLength = (U16)litLength;
+
+ /* match offset */
+ seqStorePtr->sequences[0].offset = offsetCode + 1;
+
+ /* match Length */
+ if (matchCode>0xFFFF) {
+ seqStorePtr->longLengthID = 2;
+ seqStorePtr->longLengthPos = (U32)(seqStorePtr->sequences - seqStorePtr->sequencesStart);
+ }
+ seqStorePtr->sequences[0].matchLength = (U16)matchCode;
+
+ seqStorePtr->sequences++;
+}
+
+
+/*-*************************************
+* Match length counter
+***************************************/
+static unsigned ZSTD_NbCommonBytes (register size_t val)
+{
+ if (MEM_isLittleEndian()) {
+ if (MEM_64bits()) {
+# if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long r = 0;
+ _BitScanForward64( &r, (U64)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_ctzll((U64)val) >> 3);
+# else
+ static const int DeBruijnBytePos[64] = { 0, 0, 0, 0, 0, 1, 1, 2,
+ 0, 3, 1, 3, 1, 4, 2, 7,
+ 0, 2, 3, 6, 1, 5, 3, 5,
+ 1, 3, 4, 4, 2, 5, 6, 7,
+ 7, 0, 1, 2, 3, 3, 4, 6,
+ 2, 6, 5, 5, 3, 4, 5, 6,
+ 7, 1, 2, 4, 6, 4, 4, 5,
+ 7, 2, 6, 5, 7, 6, 7, 7 };
+ return DeBruijnBytePos[((U64)((val & -(long long)val) * 0x0218A392CDABBD3FULL)) >> 58];
+# endif
+ } else { /* 32 bits */
+# if defined(_MSC_VER)
+ unsigned long r=0;
+ _BitScanForward( &r, (U32)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_ctz((U32)val) >> 3);
+# else
+ static const int DeBruijnBytePos[32] = { 0, 0, 3, 0, 3, 1, 3, 0,
+ 3, 2, 2, 1, 3, 2, 0, 1,
+ 3, 3, 1, 2, 2, 2, 2, 0,
+ 3, 1, 2, 0, 1, 0, 1, 1 };
+ return DeBruijnBytePos[((U32)((val & -(S32)val) * 0x077CB531U)) >> 27];
+# endif
+ }
+ } else { /* Big Endian CPU */
+ if (MEM_64bits()) {
+# if defined(_MSC_VER) && defined(_WIN64)
+ unsigned long r = 0;
+ _BitScanReverse64( &r, val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_clzll(val) >> 3);
+# else
+ unsigned r;
+ const unsigned n32 = sizeof(size_t)*4; /* calculate this way due to compiler complaining in 32-bits mode */
+ if (!(val>>n32)) { r=4; } else { r=0; val>>=n32; }
+ if (!(val>>16)) { r+=2; val>>=8; } else { val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ } else { /* 32 bits */
+# if defined(_MSC_VER)
+ unsigned long r = 0;
+ _BitScanReverse( &r, (unsigned long)val );
+ return (unsigned)(r>>3);
+# elif defined(__GNUC__) && (__GNUC__ >= 3)
+ return (__builtin_clz((U32)val) >> 3);
+# else
+ unsigned r;
+ if (!(val>>16)) { r=2; val>>=8; } else { r=0; val>>=24; }
+ r += (!val);
+ return r;
+# endif
+ } }
+}
+
+
+static size_t ZSTD_count(const BYTE* pIn, const BYTE* pMatch, const BYTE* const pInLimit)
+{
+ const BYTE* const pStart = pIn;
+ const BYTE* const pInLoopLimit = pInLimit - (sizeof(size_t)-1);
+
+ while (pIn < pInLoopLimit) {
+ size_t const diff = MEM_readST(pMatch) ^ MEM_readST(pIn);
+ if (!diff) { pIn+=sizeof(size_t); pMatch+=sizeof(size_t); continue; }
+ pIn += ZSTD_NbCommonBytes(diff);
+ return (size_t)(pIn - pStart);
+ }
+ if (MEM_64bits()) if ((pIn<(pInLimit-3)) && (MEM_read32(pMatch) == MEM_read32(pIn))) { pIn+=4; pMatch+=4; }
+ if ((pIn<(pInLimit-1)) && (MEM_read16(pMatch) == MEM_read16(pIn))) { pIn+=2; pMatch+=2; }
+ if ((pIn<pInLimit) && (*pMatch == *pIn)) pIn++;
+ return (size_t)(pIn - pStart);
+}
+
+/** ZSTD_count_2segments() :
+* can count match length with `ip` & `match` in 2 different segments.
+* convention : on reaching mEnd, match count continue starting from iStart
+*/
+static size_t ZSTD_count_2segments(const BYTE* ip, const BYTE* match, const BYTE* iEnd, const BYTE* mEnd, const BYTE* iStart)
+{
+ const BYTE* const vEnd = MIN( ip + (mEnd - match), iEnd);
+ size_t const matchLength = ZSTD_count(ip, match, vEnd);
+ if (match + matchLength != mEnd) return matchLength;
+ return matchLength + ZSTD_count(ip+matchLength, iStart, iEnd);
+}
+
+
+/*-*************************************
+* Hashes
+***************************************/
+static const U32 prime3bytes = 506832829U;
+static U32 ZSTD_hash3(U32 u, U32 h) { return ((u << (32-24)) * prime3bytes) >> (32-h) ; }
+MEM_STATIC size_t ZSTD_hash3Ptr(const void* ptr, U32 h) { return ZSTD_hash3(MEM_readLE32(ptr), h); } /* only in zstd_opt.h */
+
+static const U32 prime4bytes = 2654435761U;
+static U32 ZSTD_hash4(U32 u, U32 h) { return (u * prime4bytes) >> (32-h) ; }
+static size_t ZSTD_hash4Ptr(const void* ptr, U32 h) { return ZSTD_hash4(MEM_read32(ptr), h); }
+
+static const U64 prime5bytes = 889523592379ULL;
+static size_t ZSTD_hash5(U64 u, U32 h) { return (size_t)(((u << (64-40)) * prime5bytes) >> (64-h)) ; }
+static size_t ZSTD_hash5Ptr(const void* p, U32 h) { return ZSTD_hash5(MEM_readLE64(p), h); }
+
+static const U64 prime6bytes = 227718039650203ULL;
+static size_t ZSTD_hash6(U64 u, U32 h) { return (size_t)(((u << (64-48)) * prime6bytes) >> (64-h)) ; }
+static size_t ZSTD_hash6Ptr(const void* p, U32 h) { return ZSTD_hash6(MEM_readLE64(p), h); }
+
+static const U64 prime7bytes = 58295818150454627ULL;
+static size_t ZSTD_hash7(U64 u, U32 h) { return (size_t)(((u << (64-56)) * prime7bytes) >> (64-h)) ; }
+static size_t ZSTD_hash7Ptr(const void* p, U32 h) { return ZSTD_hash7(MEM_readLE64(p), h); }
+
+static const U64 prime8bytes = 0xCF1BBCDCB7A56463ULL;
+static size_t ZSTD_hash8(U64 u, U32 h) { return (size_t)(((u) * prime8bytes) >> (64-h)) ; }
+static size_t ZSTD_hash8Ptr(const void* p, U32 h) { return ZSTD_hash8(MEM_readLE64(p), h); }
+
+static size_t ZSTD_hashPtr(const void* p, U32 hBits, U32 mls)
+{
+ switch(mls)
+ {
+ default:
+ case 4: return ZSTD_hash4Ptr(p, hBits);
+ case 5: return ZSTD_hash5Ptr(p, hBits);
+ case 6: return ZSTD_hash6Ptr(p, hBits);
+ case 7: return ZSTD_hash7Ptr(p, hBits);
+ case 8: return ZSTD_hash8Ptr(p, hBits);
+ }
+}
+
+
+/*-*************************************
+* Fast Scan
+***************************************/
+static void ZSTD_fillHashTable (ZSTD_CCtx* zc, const void* end, const U32 mls)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hBits = zc->params.cParams.hashLog;
+ const BYTE* const base = zc->base;
+ const BYTE* ip = base + zc->nextToUpdate;
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
+ const size_t fastHashFillStep = 3;
+
+ while(ip <= iend) {
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip - base);
+ ip += fastHashFillStep;
+ }
+}
+
+
+FORCE_INLINE
+void ZSTD_compressBlock_fast_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashTable = cctx->hashTable;
+ U32 const hBits = cctx->params.cParams.hashLog;
+ seqStore_t* seqStorePtr = &(cctx->seqStore);
+ const BYTE* const base = cctx->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = cctx->dictLimit;
+ const BYTE* const lowest = base + lowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
+ U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
+ U32 offsetSaved = 0;
+
+ /* init */
+ ip += (ip==lowest);
+ { U32 const maxRep = (U32)(ip-lowest);
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ }
+
+ /* Main Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
+ size_t mLength;
+ size_t const h = ZSTD_hashPtr(ip, hBits, mls);
+ U32 const current = (U32)(ip-base);
+ U32 const matchIndex = hashTable[h];
+ const BYTE* match = base + matchIndex;
+ hashTable[h] = current; /* update hash table */
+
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ U32 offset;
+ if ( (matchIndex <= lowestIndex) || (MEM_read32(match) != MEM_read32(ip)) ) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
+ offset = (U32)(ip-match);
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ offset_2 = offset_1;
+ offset_1 = offset;
+
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ }
+
+ /* match found */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2; /* here because current+2 could be > iend-8 */
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ( (offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = (U32)(ip-base);
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
+ ip += rLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } } }
+
+ /* save reps for next block */
+ cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
+ cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+static void ZSTD_compressBlock_fast(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ const U32 mls = ctx->params.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_fast_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+static void ZSTD_compressBlock_fast_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* hashTable = ctx->hashTable;
+ const U32 hBits = ctx->params.cParams.hashLog;
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const base = ctx->base;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const dictStart = dictBase + lowestIndex;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const lowPrefixPtr = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
+
+ /* Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
+ const size_t h = ZSTD_hashPtr(ip, hBits, mls);
+ const U32 matchIndex = hashTable[h];
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
+ const BYTE* match = matchBase + matchIndex;
+ const U32 current = (U32)(ip-base);
+ const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
+ const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* repMatch = repBase + repIndex;
+ size_t mLength;
+ hashTable[h] = current; /* update hash table */
+
+ if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
+ const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ if ( (matchIndex < lowestIndex) ||
+ (MEM_read32(match) != MEM_read32(ip)) ) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+ { const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
+ U32 offset;
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ offset = current - matchIndex;
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ } }
+
+ /* found a match : store it */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashTable[ZSTD_hashPtr(base+current+2, hBits, mls)] = current+2;
+ hashTable[ZSTD_hashPtr(ip-2, hBits, mls)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - offset_2;
+ const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
+ hashTable[ZSTD_hashPtr(ip, hBits, mls)] = current2;
+ ip += repLength2;
+ anchor = ip;
+ continue;
+ }
+ break;
+ } } }
+
+ /* save reps for next block */
+ ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+static void ZSTD_compressBlock_fast_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ U32 const mls = ctx->params.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_fast_extDict_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+/*-*************************************
+* Double Fast
+***************************************/
+static void ZSTD_fillDoubleHashTable (ZSTD_CCtx* cctx, const void* end, const U32 mls)
+{
+ U32* const hashLarge = cctx->hashTable;
+ U32 const hBitsL = cctx->params.cParams.hashLog;
+ U32* const hashSmall = cctx->chainTable;
+ U32 const hBitsS = cctx->params.cParams.chainLog;
+ const BYTE* const base = cctx->base;
+ const BYTE* ip = base + cctx->nextToUpdate;
+ const BYTE* const iend = ((const BYTE*)end) - HASH_READ_SIZE;
+ const size_t fastHashFillStep = 3;
+
+ while(ip <= iend) {
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip - base);
+ hashLarge[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip - base);
+ ip += fastHashFillStep;
+ }
+}
+
+
+FORCE_INLINE
+void ZSTD_compressBlock_doubleFast_generic(ZSTD_CCtx* cctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashLong = cctx->hashTable;
+ const U32 hBitsL = cctx->params.cParams.hashLog;
+ U32* const hashSmall = cctx->chainTable;
+ const U32 hBitsS = cctx->params.cParams.chainLog;
+ seqStore_t* seqStorePtr = &(cctx->seqStore);
+ const BYTE* const base = cctx->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = cctx->dictLimit;
+ const BYTE* const lowest = base + lowestIndex;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - HASH_READ_SIZE;
+ U32 offset_1=cctx->rep[0], offset_2=cctx->rep[1];
+ U32 offsetSaved = 0;
+
+ /* init */
+ ip += (ip==lowest);
+ { U32 const maxRep = (U32)(ip-lowest);
+ if (offset_2 > maxRep) offsetSaved = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) offsetSaved = offset_1, offset_1 = 0;
+ }
+
+ /* Main Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because repcode check at (ip+1) */
+ size_t mLength;
+ size_t const h2 = ZSTD_hashPtr(ip, hBitsL, 8);
+ size_t const h = ZSTD_hashPtr(ip, hBitsS, mls);
+ U32 const current = (U32)(ip-base);
+ U32 const matchIndexL = hashLong[h2];
+ U32 const matchIndexS = hashSmall[h];
+ const BYTE* matchLong = base + matchIndexL;
+ const BYTE* match = base + matchIndexS;
+ hashLong[h2] = hashSmall[h] = current; /* update hash tables */
+
+ assert(offset_1 <= current); /* supposed guaranteed by construction */
+ if ((offset_1 > 0) & (MEM_read32(ip+1-offset_1) == MEM_read32(ip+1))) {
+ /* favor repcode */
+ mLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ U32 offset;
+ if ( (matchIndexL > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip)) ) {
+ mLength = ZSTD_count(ip+8, matchLong+8, iend) + 8;
+ offset = (U32)(ip-matchLong);
+ while (((ip>anchor) & (matchLong>lowest)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
+ } else if ( (matchIndexS > lowestIndex) && (MEM_read32(match) == MEM_read32(ip)) ) {
+ size_t const hl3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
+ U32 const matchIndexL3 = hashLong[hl3];
+ const BYTE* matchL3 = base + matchIndexL3;
+ hashLong[hl3] = current + 1;
+ if ( (matchIndexL3 > lowestIndex) && (MEM_read64(matchL3) == MEM_read64(ip+1)) ) {
+ mLength = ZSTD_count(ip+9, matchL3+8, iend) + 8;
+ ip++;
+ offset = (U32)(ip-matchL3);
+ while (((ip>anchor) & (matchL3>lowest)) && (ip[-1] == matchL3[-1])) { ip--; matchL3--; mLength++; } /* catch up */
+ } else {
+ mLength = ZSTD_count(ip+4, match+4, iend) + 4;
+ offset = (U32)(ip-match);
+ while (((ip>anchor) & (match>lowest)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ }
+ } else {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ }
+
+ offset_2 = offset_1;
+ offset_1 = offset;
+
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+ }
+
+ /* match found */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] =
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2; /* here because current+2 could be > iend-8 */
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] =
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
+
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ( (offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ size_t const rLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ { U32 const tmpOff = offset_2; offset_2 = offset_1; offset_1 = tmpOff; } /* swap offset_2 <=> offset_1 */
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = (U32)(ip-base);
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = (U32)(ip-base);
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, rLength-MINMATCH);
+ ip += rLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } } }
+
+ /* save reps for next block */
+ cctx->repToConfirm[0] = offset_1 ? offset_1 : offsetSaved;
+ cctx->repToConfirm[1] = offset_2 ? offset_2 : offsetSaved;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+static void ZSTD_compressBlock_doubleFast(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ const U32 mls = ctx->params.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_doubleFast_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+static void ZSTD_compressBlock_doubleFast_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 mls)
+{
+ U32* const hashLong = ctx->hashTable;
+ U32 const hBitsL = ctx->params.cParams.hashLog;
+ U32* const hashSmall = ctx->chainTable;
+ U32 const hBitsS = ctx->params.cParams.chainLog;
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const base = ctx->base;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const dictStart = dictBase + lowestIndex;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const lowPrefixPtr = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ U32 offset_1=ctx->rep[0], offset_2=ctx->rep[1];
+
+ /* Search Loop */
+ while (ip < ilimit) { /* < instead of <=, because (ip+1) */
+ const size_t hSmall = ZSTD_hashPtr(ip, hBitsS, mls);
+ const U32 matchIndex = hashSmall[hSmall];
+ const BYTE* matchBase = matchIndex < dictLimit ? dictBase : base;
+ const BYTE* match = matchBase + matchIndex;
+
+ const size_t hLong = ZSTD_hashPtr(ip, hBitsL, 8);
+ const U32 matchLongIndex = hashLong[hLong];
+ const BYTE* matchLongBase = matchLongIndex < dictLimit ? dictBase : base;
+ const BYTE* matchLong = matchLongBase + matchLongIndex;
+
+ const U32 current = (U32)(ip-base);
+ const U32 repIndex = current + 1 - offset_1; /* offset_1 expected <= current +1 */
+ const BYTE* repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* repMatch = repBase + repIndex;
+ size_t mLength;
+ hashSmall[hSmall] = hashLong[hLong] = current; /* update hash table */
+
+ if ( (((U32)((dictLimit-1) - repIndex) >= 3) /* intentional underflow */ & (repIndex > lowestIndex))
+ && (MEM_read32(repMatch) == MEM_read32(ip+1)) ) {
+ const BYTE* repMatchEnd = repIndex < dictLimit ? dictEnd : iend;
+ mLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repMatchEnd, lowPrefixPtr) + 4;
+ ip++;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, 0, mLength-MINMATCH);
+ } else {
+ if ((matchLongIndex > lowestIndex) && (MEM_read64(matchLong) == MEM_read64(ip))) {
+ const BYTE* matchEnd = matchLongIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchLongIndex < dictLimit ? dictStart : lowPrefixPtr;
+ U32 offset;
+ mLength = ZSTD_count_2segments(ip+8, matchLong+8, iend, matchEnd, lowPrefixPtr) + 8;
+ offset = current - matchLongIndex;
+ while (((ip>anchor) & (matchLong>lowMatchPtr)) && (ip[-1] == matchLong[-1])) { ip--; matchLong--; mLength++; } /* catch up */
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+
+ } else if ((matchIndex > lowestIndex) && (MEM_read32(match) == MEM_read32(ip))) {
+ size_t const h3 = ZSTD_hashPtr(ip+1, hBitsL, 8);
+ U32 const matchIndex3 = hashLong[h3];
+ const BYTE* const match3Base = matchIndex3 < dictLimit ? dictBase : base;
+ const BYTE* match3 = match3Base + matchIndex3;
+ U32 offset;
+ hashLong[h3] = current + 1;
+ if ( (matchIndex3 > lowestIndex) && (MEM_read64(match3) == MEM_read64(ip+1)) ) {
+ const BYTE* matchEnd = matchIndex3 < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex3 < dictLimit ? dictStart : lowPrefixPtr;
+ mLength = ZSTD_count_2segments(ip+9, match3+8, iend, matchEnd, lowPrefixPtr) + 8;
+ ip++;
+ offset = current+1 - matchIndex3;
+ while (((ip>anchor) & (match3>lowMatchPtr)) && (ip[-1] == match3[-1])) { ip--; match3--; mLength++; } /* catch up */
+ } else {
+ const BYTE* matchEnd = matchIndex < dictLimit ? dictEnd : iend;
+ const BYTE* lowMatchPtr = matchIndex < dictLimit ? dictStart : lowPrefixPtr;
+ mLength = ZSTD_count_2segments(ip+4, match+4, iend, matchEnd, lowPrefixPtr) + 4;
+ offset = current - matchIndex;
+ while (((ip>anchor) & (match>lowMatchPtr)) && (ip[-1] == match[-1])) { ip--; match--; mLength++; } /* catch up */
+ }
+ offset_2 = offset_1;
+ offset_1 = offset;
+ ZSTD_storeSeq(seqStorePtr, ip-anchor, anchor, offset + ZSTD_REP_MOVE, mLength-MINMATCH);
+
+ } else {
+ ip += ((ip-anchor) >> g_searchStrength) + 1;
+ continue;
+ } }
+
+ /* found a match : store it */
+ ip += mLength;
+ anchor = ip;
+
+ if (ip <= ilimit) {
+ /* Fill Table */
+ hashSmall[ZSTD_hashPtr(base+current+2, hBitsS, mls)] = current+2;
+ hashLong[ZSTD_hashPtr(base+current+2, hBitsL, 8)] = current+2;
+ hashSmall[ZSTD_hashPtr(ip-2, hBitsS, mls)] = (U32)(ip-2-base);
+ hashLong[ZSTD_hashPtr(ip-2, hBitsL, 8)] = (U32)(ip-2-base);
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ U32 const current2 = (U32)(ip-base);
+ U32 const repIndex2 = current2 - offset_2;
+ const BYTE* repMatch2 = repIndex2 < dictLimit ? dictBase + repIndex2 : base + repIndex2;
+ if ( (((U32)((dictLimit-1) - repIndex2) >= 3) & (repIndex2 > lowestIndex)) /* intentional overflow */
+ && (MEM_read32(repMatch2) == MEM_read32(ip)) ) {
+ const BYTE* const repEnd2 = repIndex2 < dictLimit ? dictEnd : iend;
+ size_t const repLength2 = ZSTD_count_2segments(ip+4, repMatch2+4, iend, repEnd2, lowPrefixPtr) + 4;
+ U32 tmpOffset = offset_2; offset_2 = offset_1; offset_1 = tmpOffset; /* swap offset_2 <=> offset_1 */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, repLength2-MINMATCH);
+ hashSmall[ZSTD_hashPtr(ip, hBitsS, mls)] = current2;
+ hashLong[ZSTD_hashPtr(ip, hBitsL, 8)] = current2;
+ ip += repLength2;
+ anchor = ip;
+ continue;
+ }
+ break;
+ } } }
+
+ /* save reps for next block */
+ ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+static void ZSTD_compressBlock_doubleFast_extDict(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize)
+{
+ U32 const mls = ctx->params.cParams.searchLength;
+ switch(mls)
+ {
+ default: /* includes case 3 */
+ case 4 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 4); return;
+ case 5 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 5); return;
+ case 6 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 6); return;
+ case 7 :
+ ZSTD_compressBlock_doubleFast_extDict_generic(ctx, src, srcSize, 7); return;
+ }
+}
+
+
+/*-*************************************
+* Binary Tree search
+***************************************/
+/** ZSTD_insertBt1() : add one or multiple positions to tree.
+* ip : assumed <= iend-8 .
+* @return : nb of positions added */
+static U32 ZSTD_insertBt1(ZSTD_CCtx* zc, const BYTE* const ip, const U32 mls, const BYTE* const iend, U32 nbCompares,
+ U32 extDict)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hashLog = zc->params.cParams.hashLog;
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const bt = zc->chainTable;
+ U32 const btLog = zc->params.cParams.chainLog - 1;
+ U32 const btMask = (1 << btLog) - 1;
+ U32 matchIndex = hashTable[h];
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* match;
+ const U32 current = (U32)(ip-base);
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = smallerPtr + 1;
+ U32 dummy32; /* to be nullified at the end */
+ U32 const windowLow = zc->lowLimit;
+ U32 matchEndIdx = current+8;
+ size_t bestLength = 8;
+#ifdef ZSTD_C_PREDICT
+ U32 predictedSmall = *(bt + 2*((current-1)&btMask) + 0);
+ U32 predictedLarge = *(bt + 2*((current-1)&btMask) + 1);
+ predictedSmall += (predictedSmall>0);
+ predictedLarge += (predictedLarge>0);
+#endif /* ZSTD_C_PREDICT */
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* const nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+
+#ifdef ZSTD_C_PREDICT /* note : can create issues when hlog small <= 11 */
+ const U32* predictPtr = bt + 2*((matchIndex-1) & btMask); /* written this way, as bt is a roll buffer */
+ if (matchIndex == predictedSmall) {
+ /* no need to check length, result known */
+ *smallerPtr = matchIndex;
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ predictedSmall = predictPtr[1] + (predictPtr[1]>0);
+ continue;
+ }
+ if (matchIndex == predictedLarge) {
+ *largerPtr = matchIndex;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ predictedLarge = predictPtr[0] + (predictPtr[0]>0);
+ continue;
+ }
+#endif
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength])
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ bestLength = matchLength;
+ if (matchLength > matchEndIdx - matchIndex)
+ matchEndIdx = matchIndex + (U32)matchLength;
+ }
+
+ if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
+ break; /* drop , to guarantee consistency ; miss a bit of compression, but other solutions can corrupt the tree */
+
+ if (match[matchLength] < ip[matchLength]) { /* necessarily within correct buffer */
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+ if (bestLength > 384) return MIN(192, (U32)(bestLength - 384)); /* speed optimization */
+ if (matchEndIdx > current + 8) return matchEndIdx - current - 8;
+ return 1;
+}
+
+
+static size_t ZSTD_insertBtAndFindBestMatch (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iend,
+ size_t* offsetPtr,
+ U32 nbCompares, const U32 mls,
+ U32 extDict)
+{
+ U32* const hashTable = zc->hashTable;
+ U32 const hashLog = zc->params.cParams.hashLog;
+ size_t const h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const bt = zc->chainTable;
+ U32 const btLog = zc->params.cParams.chainLog - 1;
+ U32 const btMask = (1 << btLog) - 1;
+ U32 matchIndex = hashTable[h];
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const U32 current = (U32)(ip-base);
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ const U32 windowLow = zc->lowLimit;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = bt + 2*(current&btMask) + 1;
+ U32 matchEndIdx = current+8;
+ U32 dummy32; /* to be nullified at the end */
+ size_t bestLength = 0;
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* const nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+ const BYTE* match;
+
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength])
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iend) +1;
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iend, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ if (matchLength > matchEndIdx - matchIndex)
+ matchEndIdx = matchIndex + (U32)matchLength;
+ if ( (4*(int)(matchLength-bestLength)) > (int)(ZSTD_highbit32(current-matchIndex+1) - ZSTD_highbit32((U32)offsetPtr[0]+1)) )
+ bestLength = matchLength, *offsetPtr = ZSTD_REP_MOVE + current - matchIndex;
+ if (ip+matchLength == iend) /* equal : no way to know if inf or sup */
+ break; /* drop, to guarantee consistency (miss a little bit of compression) */
+ }
+
+ if (match[matchLength] < ip[matchLength]) {
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+
+ zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
+ return bestLength;
+}
+
+
+static void ZSTD_updateTree(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while(idx < target)
+ idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 0);
+}
+
+/** ZSTD_BtFindBestMatch() : Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 0);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+ case 5 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+ case 7 :
+ case 6 : return ZSTD_BtFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+ }
+}
+
+
+static void ZSTD_updateTree_extDict(ZSTD_CCtx* zc, const BYTE* const ip, const BYTE* const iend, const U32 nbCompares, const U32 mls)
+{
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while (idx < target) idx += ZSTD_insertBt1(zc, base+idx, mls, iend, nbCompares, 1);
+}
+
+
+/** Tree updater, providing best match */
+static size_t ZSTD_BtFindBestMatch_extDict (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndFindBestMatch(zc, ip, iLimit, offsetPtr, maxNbAttempts, mls, 1);
+}
+
+
+static size_t ZSTD_BtFindBestMatch_selectMLS_extDict (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4);
+ case 5 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5);
+ case 7 :
+ case 6 : return ZSTD_BtFindBestMatch_extDict(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6);
+ }
+}
+
+
+
+/* *********************************
+* Hash Chain
+***********************************/
+#define NEXT_IN_CHAIN(d, mask) chainTable[(d) & mask]
+
+/* Update chains up to ip (excluded)
+ Assumption : always within prefix (i.e. not within extDict) */
+FORCE_INLINE
+U32 ZSTD_insertAndFindFirstIndex (ZSTD_CCtx* zc, const BYTE* ip, U32 mls)
+{
+ U32* const hashTable = zc->hashTable;
+ const U32 hashLog = zc->params.cParams.hashLog;
+ U32* const chainTable = zc->chainTable;
+ const U32 chainMask = (1 << zc->params.cParams.chainLog) - 1;
+ const BYTE* const base = zc->base;
+ const U32 target = (U32)(ip - base);
+ U32 idx = zc->nextToUpdate;
+
+ while(idx < target) { /* catch up */
+ size_t const h = ZSTD_hashPtr(base+idx, hashLog, mls);
+ NEXT_IN_CHAIN(idx, chainMask) = hashTable[h];
+ hashTable[h] = idx;
+ idx++;
+ }
+
+ zc->nextToUpdate = target;
+ return hashTable[ZSTD_hashPtr(ip, hashLog, mls)];
+}
+
+
+
+FORCE_INLINE /* inlining is important to hardwire a hot branch (template emulation) */
+size_t ZSTD_HcFindBestMatch_generic (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* const ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 mls, const U32 extDict)
+{
+ U32* const chainTable = zc->chainTable;
+ const U32 chainSize = (1 << zc->params.cParams.chainLog);
+ const U32 chainMask = chainSize-1;
+ const BYTE* const base = zc->base;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const U32 lowLimit = zc->lowLimit;
+ const U32 current = (U32)(ip-base);
+ const U32 minChain = current > chainSize ? current - chainSize : 0;
+ int nbAttempts=maxNbAttempts;
+ size_t ml=4-1;
+
+ /* HC4 match finder */
+ U32 matchIndex = ZSTD_insertAndFindFirstIndex (zc, ip, mls);
+
+ for ( ; (matchIndex>lowLimit) & (nbAttempts>0) ; nbAttempts--) {
+ const BYTE* match;
+ size_t currentMl=0;
+ if ((!extDict) || matchIndex >= dictLimit) {
+ match = base + matchIndex;
+ if (match[ml] == ip[ml]) /* potentially better */
+ currentMl = ZSTD_count(ip, match, iLimit);
+ } else {
+ match = dictBase + matchIndex;
+ if (MEM_read32(match) == MEM_read32(ip)) /* assumption : matchIndex <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+4, match+4, iLimit, dictEnd, prefixStart) + 4;
+ }
+
+ /* save best solution */
+ if (currentMl > ml) {
+ ml = currentMl;
+ *offsetPtr = current - matchIndex + ZSTD_REP_MOVE;
+ if (ip+currentMl == iLimit) break; /* best possible, avoids read overflow on next attempt */
+ }
+
+ if (matchIndex <= minChain) break;
+ matchIndex = NEXT_IN_CHAIN(matchIndex, chainMask);
+ }
+
+ return ml;
+}
+
+
+FORCE_INLINE size_t ZSTD_HcFindBestMatch_selectMLS (
+ ZSTD_CCtx* zc,
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 0);
+ case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 0);
+ case 7 :
+ case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 0);
+ }
+}
+
+
+FORCE_INLINE size_t ZSTD_HcFindBestMatch_extDict_selectMLS (
+ ZSTD_CCtx* zc,
+ const BYTE* ip, const BYTE* const iLimit,
+ size_t* offsetPtr,
+ const U32 maxNbAttempts, const U32 matchLengthSearch)
+{
+ switch(matchLengthSearch)
+ {
+ default : /* includes case 3 */
+ case 4 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 4, 1);
+ case 5 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 5, 1);
+ case 7 :
+ case 6 : return ZSTD_HcFindBestMatch_generic(zc, ip, iLimit, offsetPtr, maxNbAttempts, 6, 1);
+ }
+}
+
+
+/* *******************************
+* Common parser - lazy strategy
+*********************************/
+FORCE_INLINE
+void ZSTD_compressBlock_lazy_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 searchMethod, const U32 depth)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base + ctx->dictLimit;
+
+ U32 const maxSearches = 1 << ctx->params.cParams.searchLog;
+ U32 const mls = ctx->params.cParams.searchLength;
+
+ typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
+ size_t* offsetPtr,
+ U32 maxNbAttempts, U32 matchLengthSearch);
+ searchMax_f const searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS : ZSTD_HcFindBestMatch_selectMLS;
+ U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1], savedOffset=0;
+
+ /* init */
+ ip += (ip==base);
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ { U32 const maxRep = (U32)(ip-base);
+ if (offset_2 > maxRep) savedOffset = offset_2, offset_2 = 0;
+ if (offset_1 > maxRep) savedOffset = offset_1, offset_1 = 0;
+ }
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ size_t matchLength=0;
+ size_t offset=0;
+ const BYTE* start=ip+1;
+
+ /* check repCode */
+ if ((offset_1>0) & (MEM_read32(ip+1) == MEM_read32(ip+1 - offset_1))) {
+ /* repcode : we take it */
+ matchLength = ZSTD_count(ip+1+4, ip+1+4-offset_1, iend) + 4;
+ if (depth==0) goto _storeSequence;
+ }
+
+ /* first search (depth 0) */
+ { size_t offsetFound = 99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
+ if (ml2 > matchLength)
+ matchLength = ml2, start = ip, offset=offsetFound;
+ }
+
+ if (matchLength < 4) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
+ continue;
+ }
+
+ /* let's try to find a better solution */
+ if (depth>=1)
+ while (ip<ilimit) {
+ ip ++;
+ if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ size_t const mlRep = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
+ int const gain2 = (int)(mlRep * 3);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((mlRep >= 4) && (gain2 > gain1))
+ matchLength = mlRep, offset = 0, start = ip;
+ }
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue; /* search a better one */
+ } }
+
+ /* let's find an even better one */
+ if ((depth==2) && (ip<ilimit)) {
+ ip ++;
+ if ((offset) && ((offset_1>0) & (MEM_read32(ip) == MEM_read32(ip - offset_1)))) {
+ size_t const ml2 = ZSTD_count(ip+4, ip+4-offset_1, iend) + 4;
+ int const gain2 = (int)(ml2 * 4);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((ml2 >= 4) && (gain2 > gain1))
+ matchLength = ml2, offset = 0, start = ip;
+ }
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue;
+ } } }
+ break; /* nothing found : store previous solution */
+ }
+
+ /* catch up */
+ if (offset) {
+ while ( (start > anchor)
+ && (start > base+offset-ZSTD_REP_MOVE)
+ && (start[-1] == start[-1-offset+ZSTD_REP_MOVE]) ) /* only search for offset within prefix */
+ { start--; matchLength++; }
+ offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ }
+
+ /* store sequence */
+_storeSequence:
+ { size_t const litLength = start - anchor;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
+ anchor = ip = start + matchLength;
+ }
+
+ /* check immediate repcode */
+ while ( (ip <= ilimit)
+ && ((offset_2>0)
+ & (MEM_read32(ip) == MEM_read32(ip - offset_2)) )) {
+ /* store sequence */
+ matchLength = ZSTD_count(ip+4, ip+4-offset_2, iend) + 4;
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap repcodes */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
+ ip += matchLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ } }
+
+ /* Save reps for next block */
+ ctx->repToConfirm[0] = offset_1 ? offset_1 : savedOffset;
+ ctx->repToConfirm[1] = offset_2 ? offset_2 : savedOffset;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+static void ZSTD_compressBlock_btlazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 1, 2);
+}
+
+static void ZSTD_compressBlock_lazy2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 2);
+}
+
+static void ZSTD_compressBlock_lazy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 1);
+}
+
+static void ZSTD_compressBlock_greedy(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_generic(ctx, src, srcSize, 0, 0);
+}
+
+
+FORCE_INLINE
+void ZSTD_compressBlock_lazy_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize,
+ const U32 searchMethod, const U32 depth)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const U32 dictLimit = ctx->dictLimit;
+ const U32 lowestIndex = ctx->lowLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const dictStart = dictBase + ctx->lowLimit;
+
+ const U32 maxSearches = 1 << ctx->params.cParams.searchLog;
+ const U32 mls = ctx->params.cParams.searchLength;
+
+ typedef size_t (*searchMax_f)(ZSTD_CCtx* zc, const BYTE* ip, const BYTE* iLimit,
+ size_t* offsetPtr,
+ U32 maxNbAttempts, U32 matchLengthSearch);
+ searchMax_f searchMax = searchMethod ? ZSTD_BtFindBestMatch_selectMLS_extDict : ZSTD_HcFindBestMatch_extDict_selectMLS;
+
+ U32 offset_1 = ctx->rep[0], offset_2 = ctx->rep[1];
+
+ /* init */
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ip += (ip == prefixStart);
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ size_t matchLength=0;
+ size_t offset=0;
+ const BYTE* start=ip+1;
+ U32 current = (U32)(ip-base);
+
+ /* check repCode */
+ { const U32 repIndex = (U32)(current+1 - offset_1);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip+1) == MEM_read32(repMatch)) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ matchLength = ZSTD_count_2segments(ip+1+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ if (depth==0) goto _storeSequence;
+ } }
+
+ /* first search (depth 0) */
+ { size_t offsetFound = 99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offsetFound, maxSearches, mls);
+ if (ml2 > matchLength)
+ matchLength = ml2, start = ip, offset=offsetFound;
+ }
+
+ if (matchLength < 4) {
+ ip += ((ip-anchor) >> g_searchStrength) + 1; /* jump faster over incompressible sections */
+ continue;
+ }
+
+ /* let's try to find a better solution */
+ if (depth>=1)
+ while (ip<ilimit) {
+ ip ++;
+ current++;
+ /* check repCode */
+ if (offset) {
+ const U32 repIndex = (U32)(current - offset_1);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ int const gain2 = (int)(repLength * 3);
+ int const gain1 = (int)(matchLength*3 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((repLength >= 4) && (gain2 > gain1))
+ matchLength = repLength, offset = 0, start = ip;
+ } }
+
+ /* search match, depth 1 */
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 4);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue; /* search a better one */
+ } }
+
+ /* let's find an even better one */
+ if ((depth==2) && (ip<ilimit)) {
+ ip ++;
+ current++;
+ /* check repCode */
+ if (offset) {
+ const U32 repIndex = (U32)(current - offset_1);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ size_t const repLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ int const gain2 = (int)(repLength * 4);
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 1);
+ if ((repLength >= 4) && (gain2 > gain1))
+ matchLength = repLength, offset = 0, start = ip;
+ } }
+
+ /* search match, depth 2 */
+ { size_t offset2=99999999;
+ size_t const ml2 = searchMax(ctx, ip, iend, &offset2, maxSearches, mls);
+ int const gain2 = (int)(ml2*4 - ZSTD_highbit32((U32)offset2+1)); /* raw approx */
+ int const gain1 = (int)(matchLength*4 - ZSTD_highbit32((U32)offset+1) + 7);
+ if ((ml2 >= 4) && (gain2 > gain1)) {
+ matchLength = ml2, offset = offset2, start = ip;
+ continue;
+ } } }
+ break; /* nothing found : store previous solution */
+ }
+
+ /* catch up */
+ if (offset) {
+ U32 const matchIndex = (U32)((start-base) - (offset - ZSTD_REP_MOVE));
+ const BYTE* match = (matchIndex < dictLimit) ? dictBase + matchIndex : base + matchIndex;
+ const BYTE* const mStart = (matchIndex < dictLimit) ? dictStart : prefixStart;
+ while ((start>anchor) && (match>mStart) && (start[-1] == match[-1])) { start--; match--; matchLength++; } /* catch up */
+ offset_2 = offset_1; offset_1 = (U32)(offset - ZSTD_REP_MOVE);
+ }
+
+ /* store sequence */
+_storeSequence:
+ { size_t const litLength = start - anchor;
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, (U32)offset, matchLength-MINMATCH);
+ anchor = ip = start + matchLength;
+ }
+
+ /* check immediate repcode */
+ while (ip <= ilimit) {
+ const U32 repIndex = (U32)((ip-base) - offset_2);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex > lowestIndex)) /* intentional overflow */
+ if (MEM_read32(ip) == MEM_read32(repMatch)) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ matchLength = ZSTD_count_2segments(ip+4, repMatch+4, iend, repEnd, prefixStart) + 4;
+ offset = offset_2; offset_2 = offset_1; offset_1 = (U32)offset; /* swap offset history */
+ ZSTD_storeSeq(seqStorePtr, 0, anchor, 0, matchLength-MINMATCH);
+ ip += matchLength;
+ anchor = ip;
+ continue; /* faster when present ... (?) */
+ }
+ break;
+ } }
+
+ /* Save reps for next block */
+ ctx->repToConfirm[0] = offset_1; ctx->repToConfirm[1] = offset_2;
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+void ZSTD_compressBlock_greedy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 0);
+}
+
+static void ZSTD_compressBlock_lazy_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 1);
+}
+
+static void ZSTD_compressBlock_lazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 0, 2);
+}
+
+static void ZSTD_compressBlock_btlazy2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+ ZSTD_compressBlock_lazy_extDict_generic(ctx, src, srcSize, 1, 2);
+}
+
+
+/* The optimal parser */
+#include "zstd_opt.h"
+
+static void ZSTD_compressBlock_btopt(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+#ifdef ZSTD_OPT_H_91842398743
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 0);
+#else
+ (void)ctx; (void)src; (void)srcSize;
+ return;
+#endif
+}
+
+static void ZSTD_compressBlock_btopt2(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+#ifdef ZSTD_OPT_H_91842398743
+ ZSTD_compressBlock_opt_generic(ctx, src, srcSize, 1);
+#else
+ (void)ctx; (void)src; (void)srcSize;
+ return;
+#endif
+}
+
+static void ZSTD_compressBlock_btopt_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+#ifdef ZSTD_OPT_H_91842398743
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 0);
+#else
+ (void)ctx; (void)src; (void)srcSize;
+ return;
+#endif
+}
+
+static void ZSTD_compressBlock_btopt2_extDict(ZSTD_CCtx* ctx, const void* src, size_t srcSize)
+{
+#ifdef ZSTD_OPT_H_91842398743
+ ZSTD_compressBlock_opt_extDict_generic(ctx, src, srcSize, 1);
+#else
+ (void)ctx; (void)src; (void)srcSize;
+ return;
+#endif
+}
+
+
+typedef void (*ZSTD_blockCompressor) (ZSTD_CCtx* ctx, const void* src, size_t srcSize);
+
+static ZSTD_blockCompressor ZSTD_selectBlockCompressor(ZSTD_strategy strat, int extDict)
+{
+ static const ZSTD_blockCompressor blockCompressor[2][8] = {
+ { ZSTD_compressBlock_fast, ZSTD_compressBlock_doubleFast, ZSTD_compressBlock_greedy,
+ ZSTD_compressBlock_lazy, ZSTD_compressBlock_lazy2, ZSTD_compressBlock_btlazy2,
+ ZSTD_compressBlock_btopt, ZSTD_compressBlock_btopt2 },
+ { ZSTD_compressBlock_fast_extDict, ZSTD_compressBlock_doubleFast_extDict, ZSTD_compressBlock_greedy_extDict,
+ ZSTD_compressBlock_lazy_extDict,ZSTD_compressBlock_lazy2_extDict, ZSTD_compressBlock_btlazy2_extDict,
+ ZSTD_compressBlock_btopt_extDict, ZSTD_compressBlock_btopt2_extDict }
+ };
+
+ return blockCompressor[extDict][(U32)strat];
+}
+
+
+static size_t ZSTD_compressBlock_internal(ZSTD_CCtx* zc, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ ZSTD_blockCompressor const blockCompressor = ZSTD_selectBlockCompressor(zc->params.cParams.strategy, zc->lowLimit < zc->dictLimit);
+ const BYTE* const base = zc->base;
+ const BYTE* const istart = (const BYTE*)src;
+ const U32 current = (U32)(istart-base);
+ if (srcSize < MIN_CBLOCK_SIZE+ZSTD_blockHeaderSize+1) return 0; /* don't even attempt compression below a certain srcSize */
+ ZSTD_resetSeqStore(&(zc->seqStore));
+ if (current > zc->nextToUpdate + 384)
+ zc->nextToUpdate = current - MIN(192, (U32)(current - zc->nextToUpdate - 384)); /* limited update after finding a very long match */
+ blockCompressor(zc, src, srcSize);
+ return ZSTD_compressSequences(zc, dst, dstCapacity, srcSize);
+}
+
+
+/*! ZSTD_compress_generic() :
+* Compress a chunk of data into one or multiple blocks.
+* All blocks will be terminated, all input will be consumed.
+* Function will issue an error if there is not enough `dstCapacity` to hold the compressed content.
+* Frame is supposed already started (header already produced)
+* @return : compressed size, or an error code
+*/
+static size_t ZSTD_compress_generic (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ U32 lastFrameChunk)
+{
+ size_t blockSize = cctx->blockSize;
+ size_t remaining = srcSize;
+ const BYTE* ip = (const BYTE*)src;
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* op = ostart;
+ U32 const maxDist = 1 << cctx->params.cParams.windowLog;
+
+ if (cctx->params.fParams.checksumFlag && srcSize)
+ XXH64_update(&cctx->xxhState, src, srcSize);
+
+ while (remaining) {
+ U32 const lastBlock = lastFrameChunk & (blockSize >= remaining);
+ size_t cSize;
+
+ if (dstCapacity < ZSTD_blockHeaderSize + MIN_CBLOCK_SIZE)
+ return ERROR(dstSize_tooSmall); /* not enough space to store compressed block */
+ if (remaining < blockSize) blockSize = remaining;
+
+ /* preemptive overflow correction */
+ if (cctx->lowLimit > (3U<<29)) {
+ U32 const cycleMask = (1 << ZSTD_cycleLog(cctx->params.cParams.hashLog, cctx->params.cParams.strategy)) - 1;
+ U32 const current = (U32)(ip - cctx->base);
+ U32 const newCurrent = (current & cycleMask) + (1 << cctx->params.cParams.windowLog);
+ U32 const correction = current - newCurrent;
+ ZSTD_STATIC_ASSERT(ZSTD_WINDOWLOG_MAX_64 <= 30);
+ ZSTD_reduceIndex(cctx, correction);
+ cctx->base += correction;
+ cctx->dictBase += correction;
+ cctx->lowLimit -= correction;
+ cctx->dictLimit -= correction;
+ if (cctx->nextToUpdate < correction) cctx->nextToUpdate = 0;
+ else cctx->nextToUpdate -= correction;
+ }
+
+ if ((U32)(ip+blockSize - cctx->base) > cctx->loadedDictEnd + maxDist) {
+ /* enforce maxDist */
+ U32 const newLowLimit = (U32)(ip+blockSize - cctx->base) - maxDist;
+ if (cctx->lowLimit < newLowLimit) cctx->lowLimit = newLowLimit;
+ if (cctx->dictLimit < cctx->lowLimit) cctx->dictLimit = cctx->lowLimit;
+ }
+
+ cSize = ZSTD_compressBlock_internal(cctx, op+ZSTD_blockHeaderSize, dstCapacity-ZSTD_blockHeaderSize, ip, blockSize);
+ if (ZSTD_isError(cSize)) return cSize;
+
+ if (cSize == 0) { /* block is not compressible */
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_raw)<<1) + (U32)(blockSize << 3);
+ if (blockSize + ZSTD_blockHeaderSize > dstCapacity) return ERROR(dstSize_tooSmall);
+ MEM_writeLE32(op, cBlockHeader24); /* no pb, 4th byte will be overwritten */
+ memcpy(op + ZSTD_blockHeaderSize, ip, blockSize);
+ cSize = ZSTD_blockHeaderSize+blockSize;
+ } else {
+ U32 const cBlockHeader24 = lastBlock + (((U32)bt_compressed)<<1) + (U32)(cSize << 3);
+ MEM_writeLE24(op, cBlockHeader24);
+ cSize += ZSTD_blockHeaderSize;
+ }
+
+ remaining -= blockSize;
+ dstCapacity -= cSize;
+ ip += blockSize;
+ op += cSize;
+ }
+
+ if (lastFrameChunk && (op>ostart)) cctx->stage = ZSTDcs_ending;
+ return op-ostart;
+}
+
+
+static size_t ZSTD_writeFrameHeader(void* dst, size_t dstCapacity,
+ ZSTD_parameters params, U64 pledgedSrcSize, U32 dictID)
+{ BYTE* const op = (BYTE*)dst;
+ U32 const dictIDSizeCodeLength = (dictID>0) + (dictID>=256) + (dictID>=65536); /* 0-3 */
+ U32 const dictIDSizeCode = params.fParams.noDictIDFlag ? 0 : dictIDSizeCodeLength; /* 0-3 */
+ U32 const checksumFlag = params.fParams.checksumFlag>0;
+ U32 const windowSize = 1U << params.cParams.windowLog;
+ U32 const singleSegment = params.fParams.contentSizeFlag && (windowSize >= pledgedSrcSize);
+ BYTE const windowLogByte = (BYTE)((params.cParams.windowLog - ZSTD_WINDOWLOG_ABSOLUTEMIN) << 3);
+ U32 const fcsCode = params.fParams.contentSizeFlag ?
+ (pledgedSrcSize>=256) + (pledgedSrcSize>=65536+256) + (pledgedSrcSize>=0xFFFFFFFFU) : /* 0-3 */
+ 0;
+ BYTE const frameHeaderDecriptionByte = (BYTE)(dictIDSizeCode + (checksumFlag<<2) + (singleSegment<<5) + (fcsCode<<6) );
+ size_t pos;
+
+ if (dstCapacity < ZSTD_frameHeaderSize_max) return ERROR(dstSize_tooSmall);
+ DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDFlag : %u \n", !params.fParams.noDictIDFlag);
+ DEBUGLOG(5, "ZSTD_writeFrameHeader : dictID : %u \n", dictID);
+ DEBUGLOG(5, "ZSTD_writeFrameHeader : dictIDSizeCode : %u \n", dictIDSizeCode);
+
+ MEM_writeLE32(dst, ZSTD_MAGICNUMBER);
+ op[4] = frameHeaderDecriptionByte; pos=5;
+ if (!singleSegment) op[pos++] = windowLogByte;
+ switch(dictIDSizeCode)
+ {
+ default: /* impossible */
+ case 0 : break;
+ case 1 : op[pos] = (BYTE)(dictID); pos++; break;
+ case 2 : MEM_writeLE16(op+pos, (U16)dictID); pos+=2; break;
+ case 3 : MEM_writeLE32(op+pos, dictID); pos+=4; break;
+ }
+ switch(fcsCode)
+ {
+ default: /* impossible */
+ case 0 : if (singleSegment) op[pos++] = (BYTE)(pledgedSrcSize); break;
+ case 1 : MEM_writeLE16(op+pos, (U16)(pledgedSrcSize-256)); pos+=2; break;
+ case 2 : MEM_writeLE32(op+pos, (U32)(pledgedSrcSize)); pos+=4; break;
+ case 3 : MEM_writeLE64(op+pos, (U64)(pledgedSrcSize)); pos+=8; break;
+ }
+ return pos;
+}
+
+
+static size_t ZSTD_compressContinue_internal (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ U32 frame, U32 lastFrameChunk)
+{
+ const BYTE* const ip = (const BYTE*) src;
+ size_t fhSize = 0;
+
+ if (cctx->stage==ZSTDcs_created) return ERROR(stage_wrong); /* missing init (ZSTD_compressBegin) */
+
+ if (frame && (cctx->stage==ZSTDcs_init)) {
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, cctx->frameContentSize, cctx->dictID);
+ if (ZSTD_isError(fhSize)) return fhSize;
+ dstCapacity -= fhSize;
+ dst = (char*)dst + fhSize;
+ cctx->stage = ZSTDcs_ongoing;
+ }
+
+ /* Check if blocks follow each other */
+ if (src != cctx->nextSrc) {
+ /* not contiguous */
+ ptrdiff_t const delta = cctx->nextSrc - ip;
+ cctx->lowLimit = cctx->dictLimit;
+ cctx->dictLimit = (U32)(cctx->nextSrc - cctx->base);
+ cctx->dictBase = cctx->base;
+ cctx->base -= delta;
+ cctx->nextToUpdate = cctx->dictLimit;
+ if (cctx->dictLimit - cctx->lowLimit < HASH_READ_SIZE) cctx->lowLimit = cctx->dictLimit; /* too small extDict */
+ }
+
+ /* if input and dictionary overlap : reduce dictionary (area presumed modified by input) */
+ if ((ip+srcSize > cctx->dictBase + cctx->lowLimit) & (ip < cctx->dictBase + cctx->dictLimit)) {
+ ptrdiff_t const highInputIdx = (ip + srcSize) - cctx->dictBase;
+ U32 const lowLimitMax = (highInputIdx > (ptrdiff_t)cctx->dictLimit) ? cctx->dictLimit : (U32)highInputIdx;
+ cctx->lowLimit = lowLimitMax;
+ }
+
+ cctx->nextSrc = ip + srcSize;
+
+ if (srcSize) {
+ size_t const cSize = frame ?
+ ZSTD_compress_generic (cctx, dst, dstCapacity, src, srcSize, lastFrameChunk) :
+ ZSTD_compressBlock_internal (cctx, dst, dstCapacity, src, srcSize);
+ if (ZSTD_isError(cSize)) return cSize;
+ cctx->consumedSrcSize += srcSize;
+ return cSize + fhSize;
+ } else
+ return fhSize;
+}
+
+
+size_t ZSTD_compressContinue (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 0 /* last chunk */);
+}
+
+
+size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx)
+{
+ return MIN (ZSTD_BLOCKSIZE_ABSOLUTEMAX, 1 << cctx->params.cParams.windowLog);
+}
+
+size_t ZSTD_compressBlock(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ size_t const blockSizeMax = ZSTD_getBlockSizeMax(cctx);
+ if (srcSize > blockSizeMax) return ERROR(srcSize_wrong);
+ return ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 0 /* frame mode */, 0 /* last chunk */);
+}
+
+/*! ZSTD_loadDictionaryContent() :
+ * @return : 0, or an error code
+ */
+static size_t ZSTD_loadDictionaryContent(ZSTD_CCtx* zc, const void* src, size_t srcSize)
+{
+ const BYTE* const ip = (const BYTE*) src;
+ const BYTE* const iend = ip + srcSize;
+
+ /* input becomes current prefix */
+ zc->lowLimit = zc->dictLimit;
+ zc->dictLimit = (U32)(zc->nextSrc - zc->base);
+ zc->dictBase = zc->base;
+ zc->base += ip - zc->nextSrc;
+ zc->nextToUpdate = zc->dictLimit;
+ zc->loadedDictEnd = zc->forceWindow ? 0 : (U32)(iend - zc->base);
+
+ zc->nextSrc = iend;
+ if (srcSize <= HASH_READ_SIZE) return 0;
+
+ switch(zc->params.cParams.strategy)
+ {
+ case ZSTD_fast:
+ ZSTD_fillHashTable (zc, iend, zc->params.cParams.searchLength);
+ break;
+
+ case ZSTD_dfast:
+ ZSTD_fillDoubleHashTable (zc, iend, zc->params.cParams.searchLength);
+ break;
+
+ case ZSTD_greedy:
+ case ZSTD_lazy:
+ case ZSTD_lazy2:
+ if (srcSize >= HASH_READ_SIZE)
+ ZSTD_insertAndFindFirstIndex(zc, iend-HASH_READ_SIZE, zc->params.cParams.searchLength);
+ break;
+
+ case ZSTD_btlazy2:
+ case ZSTD_btopt:
+ case ZSTD_btopt2:
+ if (srcSize >= HASH_READ_SIZE)
+ ZSTD_updateTree(zc, iend-HASH_READ_SIZE, iend, 1 << zc->params.cParams.searchLog, zc->params.cParams.searchLength);
+ break;
+
+ default:
+ return ERROR(GENERIC); /* strategy doesn't exist; impossible */
+ }
+
+ zc->nextToUpdate = (U32)(iend - zc->base);
+ return 0;
+}
+
+
+/* Dictionaries that assign zero probability to symbols that show up causes problems
+ when FSE encoding. Refuse dictionaries that assign zero probability to symbols
+ that we may encounter during compression.
+ NOTE: This behavior is not standard and could be improved in the future. */
+static size_t ZSTD_checkDictNCount(short* normalizedCounter, unsigned dictMaxSymbolValue, unsigned maxSymbolValue) {
+ U32 s;
+ if (dictMaxSymbolValue < maxSymbolValue) return ERROR(dictionary_corrupted);
+ for (s = 0; s <= maxSymbolValue; ++s) {
+ if (normalizedCounter[s] == 0) return ERROR(dictionary_corrupted);
+ }
+ return 0;
+}
+
+
+/* Dictionary format :
+ * See :
+ * https://github.com/facebook/zstd/blob/master/doc/zstd_compression_format.md#dictionary-format
+ */
+/*! ZSTD_loadZstdDictionary() :
+ * @return : 0, or an error code
+ * assumptions : magic number supposed already checked
+ * dictSize supposed > 8
+ */
+static size_t ZSTD_loadZstdDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+{
+ const BYTE* dictPtr = (const BYTE*)dict;
+ const BYTE* const dictEnd = dictPtr + dictSize;
+ short offcodeNCount[MaxOff+1];
+ unsigned offcodeMaxValue = MaxOff;
+ BYTE scratchBuffer[1<<MAX(MLFSELog,LLFSELog)];
+
+ dictPtr += 4; /* skip magic number */
+ cctx->dictID = cctx->params.fParams.noDictIDFlag ? 0 : MEM_readLE32(dictPtr);
+ dictPtr += 4;
+
+ { size_t const hufHeaderSize = HUF_readCTable(cctx->hufCTable, 255, dictPtr, dictEnd-dictPtr);
+ if (HUF_isError(hufHeaderSize)) return ERROR(dictionary_corrupted);
+ dictPtr += hufHeaderSize;
+ }
+
+ { unsigned offcodeLog;
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
+ if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
+ /* Defer checking offcodeMaxValue because we need to know the size of the dictionary content */
+ CHECK_E( FSE_buildCTable_wksp(cctx->offcodeCTable, offcodeNCount, offcodeMaxValue, offcodeLog, scratchBuffer, sizeof(scratchBuffer)),
+ dictionary_corrupted);
+ dictPtr += offcodeHeaderSize;
+ }
+
+ { short matchlengthNCount[MaxML+1];
+ unsigned matchlengthMaxValue = MaxML, matchlengthLog;
+ size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
+ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
+ /* Every match length code must have non-zero probability */
+ CHECK_F( ZSTD_checkDictNCount(matchlengthNCount, matchlengthMaxValue, MaxML));
+ CHECK_E( FSE_buildCTable_wksp(cctx->matchlengthCTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog, scratchBuffer, sizeof(scratchBuffer)),
+ dictionary_corrupted);
+ dictPtr += matchlengthHeaderSize;
+ }
+
+ { short litlengthNCount[MaxLL+1];
+ unsigned litlengthMaxValue = MaxLL, litlengthLog;
+ size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
+ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
+ /* Every literal length code must have non-zero probability */
+ CHECK_F( ZSTD_checkDictNCount(litlengthNCount, litlengthMaxValue, MaxLL));
+ CHECK_E( FSE_buildCTable_wksp(cctx->litlengthCTable, litlengthNCount, litlengthMaxValue, litlengthLog, scratchBuffer, sizeof(scratchBuffer)),
+ dictionary_corrupted);
+ dictPtr += litlengthHeaderSize;
+ }
+
+ if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
+ cctx->rep[0] = MEM_readLE32(dictPtr+0);
+ cctx->rep[1] = MEM_readLE32(dictPtr+4);
+ cctx->rep[2] = MEM_readLE32(dictPtr+8);
+ dictPtr += 12;
+
+ { size_t const dictContentSize = (size_t)(dictEnd - dictPtr);
+ U32 offcodeMax = MaxOff;
+ if (dictContentSize <= ((U32)-1) - 128 KB) {
+ U32 const maxOffset = (U32)dictContentSize + 128 KB; /* The maximum offset that must be supported */
+ offcodeMax = ZSTD_highbit32(maxOffset); /* Calculate minimum offset code required to represent maxOffset */
+ }
+ /* All offset values <= dictContentSize + 128 KB must be representable */
+ CHECK_F (ZSTD_checkDictNCount(offcodeNCount, offcodeMaxValue, MIN(offcodeMax, MaxOff)));
+ /* All repCodes must be <= dictContentSize and != 0*/
+ { U32 u;
+ for (u=0; u<3; u++) {
+ if (cctx->rep[u] == 0) return ERROR(dictionary_corrupted);
+ if (cctx->rep[u] > dictContentSize) return ERROR(dictionary_corrupted);
+ } }
+
+ cctx->fseCTables_ready = 1;
+ cctx->hufCTable_repeatMode = HUF_repeat_valid;
+ return ZSTD_loadDictionaryContent(cctx, dictPtr, dictContentSize);
+ }
+}
+
+/** ZSTD_compress_insertDictionary() :
+* @return : 0, or an error code */
+static size_t ZSTD_compress_insertDictionary(ZSTD_CCtx* cctx, const void* dict, size_t dictSize)
+{
+ if ((dict==NULL) || (dictSize<=8)) return 0;
+
+ /* dict as pure content */
+ if ((MEM_readLE32(dict) != ZSTD_DICT_MAGIC) || (cctx->forceRawDict))
+ return ZSTD_loadDictionaryContent(cctx, dict, dictSize);
+
+ /* dict as zstd dictionary */
+ return ZSTD_loadZstdDictionary(cctx, dict, dictSize);
+}
+
+/*! ZSTD_compressBegin_internal() :
+* @return : 0, or an error code */
+static size_t ZSTD_compressBegin_internal(ZSTD_CCtx* cctx,
+ const void* dict, size_t dictSize,
+ ZSTD_parameters params, U64 pledgedSrcSize)
+{
+ ZSTD_compResetPolicy_e const crp = dictSize ? ZSTDcrp_fullReset : ZSTDcrp_continue;
+ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
+ CHECK_F(ZSTD_resetCCtx_internal(cctx, params, pledgedSrcSize, crp));
+ return ZSTD_compress_insertDictionary(cctx, dict, dictSize);
+}
+
+
+/*! ZSTD_compressBegin_advanced() :
+* @return : 0, or an error code */
+size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx,
+ const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ /* compression parameters verification and optimization */
+ CHECK_F(ZSTD_checkCParams(params.cParams));
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, pledgedSrcSize);
+}
+
+
+size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel)
+{
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
+ return ZSTD_compressBegin_internal(cctx, dict, dictSize, params, 0);
+}
+
+
+size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel)
+{
+ return ZSTD_compressBegin_usingDict(cctx, NULL, 0, compressionLevel);
+}
+
+
+/*! ZSTD_writeEpilogue() :
+* Ends a frame.
+* @return : nb of bytes written into dst (or an error code) */
+static size_t ZSTD_writeEpilogue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity)
+{
+ BYTE* const ostart = (BYTE*)dst;
+ BYTE* op = ostart;
+ size_t fhSize = 0;
+
+ if (cctx->stage == ZSTDcs_created) return ERROR(stage_wrong); /* init missing */
+
+ /* special case : empty frame */
+ if (cctx->stage == ZSTDcs_init) {
+ fhSize = ZSTD_writeFrameHeader(dst, dstCapacity, cctx->params, 0, 0);
+ if (ZSTD_isError(fhSize)) return fhSize;
+ dstCapacity -= fhSize;
+ op += fhSize;
+ cctx->stage = ZSTDcs_ongoing;
+ }
+
+ if (cctx->stage != ZSTDcs_ending) {
+ /* write one last empty block, make it the "last" block */
+ U32 const cBlockHeader24 = 1 /* last block */ + (((U32)bt_raw)<<1) + 0;
+ if (dstCapacity<4) return ERROR(dstSize_tooSmall);
+ MEM_writeLE32(op, cBlockHeader24);
+ op += ZSTD_blockHeaderSize;
+ dstCapacity -= ZSTD_blockHeaderSize;
+ }
+
+ if (cctx->params.fParams.checksumFlag) {
+ U32 const checksum = (U32) XXH64_digest(&cctx->xxhState);
+ if (dstCapacity<4) return ERROR(dstSize_tooSmall);
+ MEM_writeLE32(op, checksum);
+ op += 4;
+ }
+
+ cctx->stage = ZSTDcs_created; /* return to "created but no init" status */
+ return op-ostart;
+}
+
+
+size_t ZSTD_compressEnd (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ size_t endResult;
+ size_t const cSize = ZSTD_compressContinue_internal(cctx, dst, dstCapacity, src, srcSize, 1 /* frame mode */, 1 /* last chunk */);
+ if (ZSTD_isError(cSize)) return cSize;
+ endResult = ZSTD_writeEpilogue(cctx, (char*)dst + cSize, dstCapacity-cSize);
+ if (ZSTD_isError(endResult)) return endResult;
+ if (cctx->params.fParams.contentSizeFlag) { /* control src size */
+ if (cctx->frameContentSize != cctx->consumedSrcSize) return ERROR(srcSize_wrong);
+ }
+ return cSize + endResult;
+}
+
+
+static size_t ZSTD_compress_internal (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_parameters params)
+{
+ CHECK_F(ZSTD_compressBegin_internal(cctx, dict, dictSize, params, srcSize));
+ return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
+}
+
+size_t ZSTD_compress_advanced (ZSTD_CCtx* ctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_parameters params)
+{
+ CHECK_F(ZSTD_checkCParams(params.cParams));
+ return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
+}
+
+size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize,
+ const void* dict, size_t dictSize, int compressionLevel)
+{
+ ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, dict ? dictSize : 0);
+ params.fParams.contentSizeFlag = 1;
+ return ZSTD_compress_internal(ctx, dst, dstCapacity, src, srcSize, dict, dictSize, params);
+}
+
+size_t ZSTD_compressCCtx (ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
+{
+ return ZSTD_compress_usingDict(ctx, dst, dstCapacity, src, srcSize, NULL, 0, compressionLevel);
+}
+
+size_t ZSTD_compress(void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel)
+{
+ size_t result;
+ ZSTD_CCtx ctxBody;
+ memset(&ctxBody, 0, sizeof(ctxBody));
+ memcpy(&ctxBody.customMem, &defaultCustomMem, sizeof(ZSTD_customMem));
+ result = ZSTD_compressCCtx(&ctxBody, dst, dstCapacity, src, srcSize, compressionLevel);
+ ZSTD_free(ctxBody.workSpace, defaultCustomMem); /* can't free ctxBody itself, as it's on stack; free only heap content */
+ return result;
+}
+
+
+/* ===== Dictionary API ===== */
+
+struct ZSTD_CDict_s {
+ void* dictBuffer;
+ const void* dictContent;
+ size_t dictContentSize;
+ ZSTD_CCtx* refContext;
+}; /* typedef'd tp ZSTD_CDict within "zstd.h" */
+
+size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict)
+{
+ if (cdict==NULL) return 0; /* support sizeof on NULL */
+ return ZSTD_sizeof_CCtx(cdict->refContext) + (cdict->dictBuffer ? cdict->dictContentSize : 0) + sizeof(*cdict);
+}
+
+static ZSTD_parameters ZSTD_makeParams(ZSTD_compressionParameters cParams, ZSTD_frameParameters fParams)
+{
+ ZSTD_parameters params;
+ params.cParams = cParams;
+ params.fParams = fParams;
+ return params;
+}
+
+ZSTD_CDict* ZSTD_createCDict_advanced(const void* dictBuffer, size_t dictSize, unsigned byReference,
+ ZSTD_compressionParameters cParams, ZSTD_customMem customMem)
+{
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ { ZSTD_CDict* const cdict = (ZSTD_CDict*) ZSTD_malloc(sizeof(ZSTD_CDict), customMem);
+ ZSTD_CCtx* const cctx = ZSTD_createCCtx_advanced(customMem);
+
+ if (!cdict || !cctx) {
+ ZSTD_free(cdict, customMem);
+ ZSTD_freeCCtx(cctx);
+ return NULL;
+ }
+
+ if ((byReference) || (!dictBuffer) || (!dictSize)) {
+ cdict->dictBuffer = NULL;
+ cdict->dictContent = dictBuffer;
+ } else {
+ void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
+ if (!internalBuffer) { ZSTD_free(cctx, customMem); ZSTD_free(cdict, customMem); return NULL; }
+ memcpy(internalBuffer, dictBuffer, dictSize);
+ cdict->dictBuffer = internalBuffer;
+ cdict->dictContent = internalBuffer;
+ }
+
+ { ZSTD_frameParameters const fParams = { 0 /* contentSizeFlag */, 0 /* checksumFlag */, 0 /* noDictIDFlag */ }; /* dummy */
+ ZSTD_parameters const params = ZSTD_makeParams(cParams, fParams);
+ size_t const errorCode = ZSTD_compressBegin_advanced(cctx, cdict->dictContent, dictSize, params, 0);
+ if (ZSTD_isError(errorCode)) {
+ ZSTD_free(cdict->dictBuffer, customMem);
+ ZSTD_free(cdict, customMem);
+ ZSTD_freeCCtx(cctx);
+ return NULL;
+ } }
+
+ cdict->refContext = cctx;
+ cdict->dictContentSize = dictSize;
+ return cdict;
+ }
+}
+
+ZSTD_CDict* ZSTD_createCDict(const void* dict, size_t dictSize, int compressionLevel)
+{
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
+ ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
+ return ZSTD_createCDict_advanced(dict, dictSize, 0, cParams, allocator);
+}
+
+ZSTD_CDict* ZSTD_createCDict_byReference(const void* dict, size_t dictSize, int compressionLevel)
+{
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
+ ZSTD_compressionParameters cParams = ZSTD_getCParams(compressionLevel, 0, dictSize);
+ return ZSTD_createCDict_advanced(dict, dictSize, 1, cParams, allocator);
+}
+
+size_t ZSTD_freeCDict(ZSTD_CDict* cdict)
+{
+ if (cdict==NULL) return 0; /* support free on NULL */
+ { ZSTD_customMem const cMem = cdict->refContext->customMem;
+ ZSTD_freeCCtx(cdict->refContext);
+ ZSTD_free(cdict->dictBuffer, cMem);
+ ZSTD_free(cdict, cMem);
+ return 0;
+ }
+}
+
+static ZSTD_parameters ZSTD_getParamsFromCDict(const ZSTD_CDict* cdict) {
+ return ZSTD_getParamsFromCCtx(cdict->refContext);
+}
+
+/* ZSTD_compressBegin_usingCDict_advanced() :
+ * cdict must be != NULL */
+size_t ZSTD_compressBegin_usingCDict_advanced(
+ ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict,
+ ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize)
+{
+ if (cdict==NULL) return ERROR(GENERIC); /* does not support NULL cdict */
+ DEBUGLOG(5, "ZSTD_compressBegin_usingCDict_advanced : dictIDFlag == %u \n", !fParams.noDictIDFlag);
+ if (cdict->dictContentSize)
+ CHECK_F( ZSTD_copyCCtx_internal(cctx, cdict->refContext, fParams, pledgedSrcSize) )
+ else {
+ ZSTD_parameters params = cdict->refContext->params;
+ params.fParams = fParams;
+ CHECK_F(ZSTD_compressBegin_internal(cctx, NULL, 0, params, pledgedSrcSize));
+ }
+ return 0;
+}
+
+/* ZSTD_compressBegin_usingCDict() :
+ * pledgedSrcSize=0 means "unknown"
+ * if pledgedSrcSize>0, it will enable contentSizeFlag */
+size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict)
+{
+ ZSTD_frameParameters const fParams = { 0 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
+ DEBUGLOG(5, "ZSTD_compressBegin_usingCDict : dictIDFlag == %u \n", !fParams.noDictIDFlag);
+ return ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, 0);
+}
+
+size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict, ZSTD_frameParameters fParams)
+{
+ CHECK_F (ZSTD_compressBegin_usingCDict_advanced(cctx, cdict, fParams, srcSize)); /* will check if cdict != NULL */
+ return ZSTD_compressEnd(cctx, dst, dstCapacity, src, srcSize);
+}
+
+/*! ZSTD_compress_usingCDict() :
+ * Compression using a digested Dictionary.
+ * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
+ * Note that compression parameters are decided at CDict creation time
+ * while frame parameters are hardcoded */
+size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict)
+{
+ ZSTD_frameParameters const fParams = { 1 /*content*/, 0 /*checksum*/, 0 /*noDictID*/ };
+ return ZSTD_compress_usingCDict_advanced(cctx, dst, dstCapacity, src, srcSize, cdict, fParams);
+}
+
+
+
+/* ******************************************************************
+* Streaming
+********************************************************************/
+
+typedef enum { zcss_init, zcss_load, zcss_flush, zcss_final } ZSTD_cStreamStage;
+
+struct ZSTD_CStream_s {
+ ZSTD_CCtx* cctx;
+ ZSTD_CDict* cdictLocal;
+ const ZSTD_CDict* cdict;
+ char* inBuff;
+ size_t inBuffSize;
+ size_t inToCompress;
+ size_t inBuffPos;
+ size_t inBuffTarget;
+ size_t blockSize;
+ char* outBuff;
+ size_t outBuffSize;
+ size_t outBuffContentSize;
+ size_t outBuffFlushedSize;
+ ZSTD_cStreamStage stage;
+ U32 checksum;
+ U32 frameEnded;
+ U64 pledgedSrcSize;
+ ZSTD_parameters params;
+ ZSTD_customMem customMem;
+}; /* typedef'd to ZSTD_CStream within "zstd.h" */
+
+ZSTD_CStream* ZSTD_createCStream(void)
+{
+ return ZSTD_createCStream_advanced(defaultCustomMem);
+}
+
+ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem)
+{
+ ZSTD_CStream* zcs;
+
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ zcs = (ZSTD_CStream*)ZSTD_malloc(sizeof(ZSTD_CStream), customMem);
+ if (zcs==NULL) return NULL;
+ memset(zcs, 0, sizeof(ZSTD_CStream));
+ memcpy(&zcs->customMem, &customMem, sizeof(ZSTD_customMem));
+ zcs->cctx = ZSTD_createCCtx_advanced(customMem);
+ if (zcs->cctx == NULL) { ZSTD_freeCStream(zcs); return NULL; }
+ return zcs;
+}
+
+size_t ZSTD_freeCStream(ZSTD_CStream* zcs)
+{
+ if (zcs==NULL) return 0; /* support free on NULL */
+ { ZSTD_customMem const cMem = zcs->customMem;
+ ZSTD_freeCCtx(zcs->cctx);
+ zcs->cctx = NULL;
+ ZSTD_freeCDict(zcs->cdictLocal);
+ zcs->cdictLocal = NULL;
+ ZSTD_free(zcs->inBuff, cMem);
+ zcs->inBuff = NULL;
+ ZSTD_free(zcs->outBuff, cMem);
+ zcs->outBuff = NULL;
+ ZSTD_free(zcs, cMem);
+ return 0;
+ }
+}
+
+
+/*====== Initialization ======*/
+
+size_t ZSTD_CStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
+
+size_t ZSTD_CStreamOutSize(void)
+{
+ return ZSTD_compressBound(ZSTD_BLOCKSIZE_ABSOLUTEMAX) + ZSTD_blockHeaderSize + 4 /* 32-bits hash */ ;
+}
+
+static size_t ZSTD_resetCStream_internal(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
+{
+ if (zcs->inBuffSize==0) return ERROR(stage_wrong); /* zcs has not been init at least once => can't reset */
+
+ DEBUGLOG(5, "ZSTD_resetCStream_internal : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
+
+ if (zcs->cdict) CHECK_F(ZSTD_compressBegin_usingCDict_advanced(zcs->cctx, zcs->cdict, zcs->params.fParams, pledgedSrcSize))
+ else CHECK_F(ZSTD_compressBegin_internal(zcs->cctx, NULL, 0, zcs->params, pledgedSrcSize));
+
+ zcs->inToCompress = 0;
+ zcs->inBuffPos = 0;
+ zcs->inBuffTarget = zcs->blockSize;
+ zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
+ zcs->stage = zcss_load;
+ zcs->frameEnded = 0;
+ zcs->pledgedSrcSize = pledgedSrcSize;
+ return 0; /* ready to go */
+}
+
+size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize)
+{
+
+ zcs->params.fParams.contentSizeFlag = (pledgedSrcSize > 0);
+ DEBUGLOG(5, "ZSTD_resetCStream : dictIDFlag == %u \n", !zcs->params.fParams.noDictIDFlag);
+ return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
+}
+
+/* ZSTD_initCStream_internal() :
+ * params are supposed validated at this stage
+ * and zcs->cdict is supposed to be correct */
+static size_t ZSTD_initCStream_stage2(ZSTD_CStream* zcs,
+ const ZSTD_parameters params,
+ unsigned long long pledgedSrcSize)
+{
+ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
+
+ /* allocate buffers */
+ { size_t const neededInBuffSize = (size_t)1 << params.cParams.windowLog;
+ if (zcs->inBuffSize < neededInBuffSize) {
+ zcs->inBuffSize = 0;
+ ZSTD_free(zcs->inBuff, zcs->customMem);
+ zcs->inBuff = (char*) ZSTD_malloc(neededInBuffSize, zcs->customMem);
+ if (zcs->inBuff == NULL) return ERROR(memory_allocation);
+ zcs->inBuffSize = neededInBuffSize;
+ }
+ zcs->blockSize = MIN(ZSTD_BLOCKSIZE_ABSOLUTEMAX, neededInBuffSize);
+ }
+ if (zcs->outBuffSize < ZSTD_compressBound(zcs->blockSize)+1) {
+ size_t const outBuffSize = ZSTD_compressBound(zcs->blockSize)+1;
+ zcs->outBuffSize = 0;
+ ZSTD_free(zcs->outBuff, zcs->customMem);
+ zcs->outBuff = (char*) ZSTD_malloc(outBuffSize, zcs->customMem);
+ if (zcs->outBuff == NULL) return ERROR(memory_allocation);
+ zcs->outBuffSize = outBuffSize;
+ }
+
+ zcs->checksum = params.fParams.checksumFlag > 0;
+ zcs->params = params;
+
+ DEBUGLOG(5, "ZSTD_initCStream_stage2 : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
+ return ZSTD_resetCStream_internal(zcs, pledgedSrcSize);
+}
+
+/* ZSTD_initCStream_usingCDict_advanced() :
+ * same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
+size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams)
+{
+ if (!cdict) return ERROR(GENERIC); /* cannot handle NULL cdict (does not know what to do) */
+ { ZSTD_parameters params = ZSTD_getParamsFromCDict(cdict);
+ params.fParams = fParams;
+ zcs->cdict = cdict;
+ return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
+ }
+}
+
+/* note : cdict must outlive compression session */
+size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict)
+{
+ ZSTD_frameParameters const fParams = { 0 /* content */, 0 /* checksum */, 0 /* noDictID */ };
+ return ZSTD_initCStream_usingCDict_advanced(zcs, cdict, 0, fParams);
+}
+
+static size_t ZSTD_initCStream_internal(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ assert(!ZSTD_isError(ZSTD_checkCParams(params.cParams)));
+ zcs->cdict = NULL;
+
+ if (dict && dictSize >= 8) {
+ ZSTD_freeCDict(zcs->cdictLocal);
+ zcs->cdictLocal = ZSTD_createCDict_advanced(dict, dictSize, 0 /* copy */, params.cParams, zcs->customMem);
+ if (zcs->cdictLocal == NULL) return ERROR(memory_allocation);
+ zcs->cdict = zcs->cdictLocal;
+ }
+
+ DEBUGLOG(5, "ZSTD_initCStream_internal : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
+ return ZSTD_initCStream_stage2(zcs, params, pledgedSrcSize);
+}
+
+size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs,
+ const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ CHECK_F( ZSTD_checkCParams(params.cParams) );
+ DEBUGLOG(5, "ZSTD_initCStream_advanced : dictIDFlag == %u \n", !params.fParams.noDictIDFlag);
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, params, pledgedSrcSize);
+}
+
+size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel)
+{
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, dictSize);
+ return ZSTD_initCStream_internal(zcs, dict, dictSize, params, 0);
+}
+
+size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize)
+{
+ ZSTD_parameters params = ZSTD_getParams(compressionLevel, pledgedSrcSize, 0);
+ params.fParams.contentSizeFlag = (pledgedSrcSize>0);
+ return ZSTD_initCStream_internal(zcs, NULL, 0, params, pledgedSrcSize);
+}
+
+size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel)
+{
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
+ return ZSTD_initCStream_internal(zcs, NULL, 0, params, 0);
+}
+
+size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs)
+{
+ if (zcs==NULL) return 0; /* support sizeof on NULL */
+ return sizeof(*zcs) + ZSTD_sizeof_CCtx(zcs->cctx) + ZSTD_sizeof_CDict(zcs->cdictLocal) + zcs->outBuffSize + zcs->inBuffSize;
+}
+
+/*====== Compression ======*/
+
+typedef enum { zsf_gather, zsf_flush, zsf_end } ZSTD_flush_e;
+
+MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ size_t const length = MIN(dstCapacity, srcSize);
+ memcpy(dst, src, length);
+ return length;
+}
+
+static size_t ZSTD_compressStream_generic(ZSTD_CStream* zcs,
+ void* dst, size_t* dstCapacityPtr,
+ const void* src, size_t* srcSizePtr,
+ ZSTD_flush_e const flush)
+{
+ U32 someMoreWork = 1;
+ const char* const istart = (const char*)src;
+ const char* const iend = istart + *srcSizePtr;
+ const char* ip = istart;
+ char* const ostart = (char*)dst;
+ char* const oend = ostart + *dstCapacityPtr;
+ char* op = ostart;
+
+ while (someMoreWork) {
+ switch(zcs->stage)
+ {
+ case zcss_init: return ERROR(init_missing); /* call ZBUFF_compressInit() first ! */
+
+ case zcss_load:
+ /* complete inBuffer */
+ { size_t const toLoad = zcs->inBuffTarget - zcs->inBuffPos;
+ size_t const loaded = ZSTD_limitCopy(zcs->inBuff + zcs->inBuffPos, toLoad, ip, iend-ip);
+ zcs->inBuffPos += loaded;
+ ip += loaded;
+ if ( (zcs->inBuffPos==zcs->inToCompress) || (!flush && (toLoad != loaded)) ) {
+ someMoreWork = 0; break; /* not enough input to get a full block : stop there, wait for more */
+ } }
+ /* compress current block (note : this stage cannot be stopped in the middle) */
+ { void* cDst;
+ size_t cSize;
+ size_t const iSize = zcs->inBuffPos - zcs->inToCompress;
+ size_t oSize = oend-op;
+ if (oSize >= ZSTD_compressBound(iSize))
+ cDst = op; /* compress directly into output buffer (avoid flush stage) */
+ else
+ cDst = zcs->outBuff, oSize = zcs->outBuffSize;
+ cSize = (flush == zsf_end) ?
+ ZSTD_compressEnd(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize) :
+ ZSTD_compressContinue(zcs->cctx, cDst, oSize, zcs->inBuff + zcs->inToCompress, iSize);
+ if (ZSTD_isError(cSize)) return cSize;
+ if (flush == zsf_end) zcs->frameEnded = 1;
+ /* prepare next block */
+ zcs->inBuffTarget = zcs->inBuffPos + zcs->blockSize;
+ if (zcs->inBuffTarget > zcs->inBuffSize)
+ zcs->inBuffPos = 0, zcs->inBuffTarget = zcs->blockSize; /* note : inBuffSize >= blockSize */
+ zcs->inToCompress = zcs->inBuffPos;
+ if (cDst == op) { op += cSize; break; } /* no need to flush */
+ zcs->outBuffContentSize = cSize;
+ zcs->outBuffFlushedSize = 0;
+ zcs->stage = zcss_flush; /* pass-through to flush stage */
+ }
+
+ case zcss_flush:
+ { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
+ size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
+ op += flushed;
+ zcs->outBuffFlushedSize += flushed;
+ if (toFlush!=flushed) { someMoreWork = 0; break; } /* dst too small to store flushed data : stop there */
+ zcs->outBuffContentSize = zcs->outBuffFlushedSize = 0;
+ zcs->stage = zcss_load;
+ break;
+ }
+
+ case zcss_final:
+ someMoreWork = 0; /* do nothing */
+ break;
+
+ default:
+ return ERROR(GENERIC); /* impossible */
+ }
+ }
+
+ *srcSizePtr = ip - istart;
+ *dstCapacityPtr = op - ostart;
+ if (zcs->frameEnded) return 0;
+ { size_t hintInSize = zcs->inBuffTarget - zcs->inBuffPos;
+ if (hintInSize==0) hintInSize = zcs->blockSize;
+ return hintInSize;
+ }
+}
+
+size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
+{
+ size_t sizeRead = input->size - input->pos;
+ size_t sizeWritten = output->size - output->pos;
+ size_t const result = ZSTD_compressStream_generic(zcs,
+ (char*)(output->dst) + output->pos, &sizeWritten,
+ (const char*)(input->src) + input->pos, &sizeRead, zsf_gather);
+ input->pos += sizeRead;
+ output->pos += sizeWritten;
+ return result;
+}
+
+
+/*====== Finalize ======*/
+
+/*! ZSTD_flushStream() :
+* @return : amount of data remaining to flush */
+size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
+{
+ size_t srcSize = 0;
+ size_t sizeWritten = output->size - output->pos;
+ size_t const result = ZSTD_compressStream_generic(zcs,
+ (char*)(output->dst) + output->pos, &sizeWritten,
+ &srcSize, &srcSize, /* use a valid src address instead of NULL */
+ zsf_flush);
+ output->pos += sizeWritten;
+ if (ZSTD_isError(result)) return result;
+ return zcs->outBuffContentSize - zcs->outBuffFlushedSize; /* remaining to flush */
+}
+
+
+size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output)
+{
+ BYTE* const ostart = (BYTE*)(output->dst) + output->pos;
+ BYTE* const oend = (BYTE*)(output->dst) + output->size;
+ BYTE* op = ostart;
+
+ if (zcs->stage != zcss_final) {
+ /* flush whatever remains */
+ size_t srcSize = 0;
+ size_t sizeWritten = output->size - output->pos;
+ size_t const notEnded = ZSTD_compressStream_generic(zcs, ostart, &sizeWritten,
+ &srcSize /* use a valid src address instead of NULL */, &srcSize, zsf_end);
+ size_t const remainingToFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
+ op += sizeWritten;
+ if (remainingToFlush) {
+ output->pos += sizeWritten;
+ return remainingToFlush + ZSTD_BLOCKHEADERSIZE /* final empty block */ + (zcs->checksum * 4);
+ }
+ /* create epilogue */
+ zcs->stage = zcss_final;
+ zcs->outBuffContentSize = !notEnded ? 0 :
+ /* write epilogue, including final empty block, into outBuff */
+ ZSTD_compressEnd(zcs->cctx, zcs->outBuff, zcs->outBuffSize, NULL, 0);
+ if (ZSTD_isError(zcs->outBuffContentSize)) return zcs->outBuffContentSize;
+ }
+
+ /* flush epilogue */
+ { size_t const toFlush = zcs->outBuffContentSize - zcs->outBuffFlushedSize;
+ size_t const flushed = ZSTD_limitCopy(op, oend-op, zcs->outBuff + zcs->outBuffFlushedSize, toFlush);
+ op += flushed;
+ zcs->outBuffFlushedSize += flushed;
+ output->pos += op-ostart;
+ if (toFlush==flushed) zcs->stage = zcss_init; /* end reached */
+ return toFlush - flushed;
+ }
+}
+
+
+
+/*-===== Pre-defined compression levels =====-*/
+
+#define ZSTD_DEFAULT_CLEVEL 1
+#define ZSTD_MAX_CLEVEL 22
+int ZSTD_maxCLevel(void) { return ZSTD_MAX_CLEVEL; }
+
+static const ZSTD_compressionParameters ZSTD_defaultCParameters[4][ZSTD_MAX_CLEVEL+1] = {
+{ /* "default" */
+ /* W, C, H, S, L, TL, strat */
+ { 18, 12, 12, 1, 7, 16, ZSTD_fast }, /* level 0 - never used */
+ { 19, 13, 14, 1, 7, 16, ZSTD_fast }, /* level 1 */
+ { 19, 15, 16, 1, 6, 16, ZSTD_fast }, /* level 2 */
+ { 20, 16, 17, 1, 5, 16, ZSTD_dfast }, /* level 3.*/
+ { 20, 18, 18, 1, 5, 16, ZSTD_dfast }, /* level 4.*/
+ { 20, 15, 18, 3, 5, 16, ZSTD_greedy }, /* level 5 */
+ { 21, 16, 19, 2, 5, 16, ZSTD_lazy }, /* level 6 */
+ { 21, 17, 20, 3, 5, 16, ZSTD_lazy }, /* level 7 */
+ { 21, 18, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 8 */
+ { 21, 20, 20, 3, 5, 16, ZSTD_lazy2 }, /* level 9 */
+ { 21, 19, 21, 4, 5, 16, ZSTD_lazy2 }, /* level 10 */
+ { 22, 20, 22, 4, 5, 16, ZSTD_lazy2 }, /* level 11 */
+ { 22, 20, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 12 */
+ { 22, 21, 22, 5, 5, 16, ZSTD_lazy2 }, /* level 13 */
+ { 22, 21, 22, 6, 5, 16, ZSTD_lazy2 }, /* level 14 */
+ { 22, 21, 21, 5, 5, 16, ZSTD_btlazy2 }, /* level 15 */
+ { 23, 22, 22, 5, 5, 16, ZSTD_btlazy2 }, /* level 16 */
+ { 23, 21, 22, 4, 5, 24, ZSTD_btopt }, /* level 17 */
+ { 23, 22, 22, 5, 4, 32, ZSTD_btopt }, /* level 18 */
+ { 23, 23, 22, 6, 3, 48, ZSTD_btopt }, /* level 19 */
+ { 25, 25, 23, 7, 3, 64, ZSTD_btopt2 }, /* level 20 */
+ { 26, 26, 23, 7, 3,256, ZSTD_btopt2 }, /* level 21 */
+ { 27, 27, 25, 9, 3,512, ZSTD_btopt2 }, /* level 22 */
+},
+{ /* for srcSize <= 256 KB */
+ /* W, C, H, S, L, T, strat */
+ { 0, 0, 0, 0, 0, 0, ZSTD_fast }, /* level 0 - not used */
+ { 18, 13, 14, 1, 6, 8, ZSTD_fast }, /* level 1 */
+ { 18, 14, 13, 1, 5, 8, ZSTD_dfast }, /* level 2 */
+ { 18, 16, 15, 1, 5, 8, ZSTD_dfast }, /* level 3 */
+ { 18, 15, 17, 1, 5, 8, ZSTD_greedy }, /* level 4.*/
+ { 18, 16, 17, 4, 5, 8, ZSTD_greedy }, /* level 5.*/
+ { 18, 16, 17, 3, 5, 8, ZSTD_lazy }, /* level 6.*/
+ { 18, 17, 17, 4, 4, 8, ZSTD_lazy }, /* level 7 */
+ { 18, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
+ { 18, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
+ { 18, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
+ { 18, 18, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 11.*/
+ { 18, 18, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 12.*/
+ { 18, 19, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13 */
+ { 18, 18, 18, 4, 4, 16, ZSTD_btopt }, /* level 14.*/
+ { 18, 18, 18, 4, 3, 16, ZSTD_btopt }, /* level 15.*/
+ { 18, 19, 18, 6, 3, 32, ZSTD_btopt }, /* level 16.*/
+ { 18, 19, 18, 8, 3, 64, ZSTD_btopt }, /* level 17.*/
+ { 18, 19, 18, 9, 3,128, ZSTD_btopt }, /* level 18.*/
+ { 18, 19, 18, 10, 3,256, ZSTD_btopt }, /* level 19.*/
+ { 18, 19, 18, 11, 3,512, ZSTD_btopt2 }, /* level 20.*/
+ { 18, 19, 18, 12, 3,512, ZSTD_btopt2 }, /* level 21.*/
+ { 18, 19, 18, 13, 3,512, ZSTD_btopt2 }, /* level 22.*/
+},
+{ /* for srcSize <= 128 KB */
+ /* W, C, H, S, L, T, strat */
+ { 17, 12, 12, 1, 7, 8, ZSTD_fast }, /* level 0 - not used */
+ { 17, 12, 13, 1, 6, 8, ZSTD_fast }, /* level 1 */
+ { 17, 13, 16, 1, 5, 8, ZSTD_fast }, /* level 2 */
+ { 17, 16, 16, 2, 5, 8, ZSTD_dfast }, /* level 3 */
+ { 17, 13, 15, 3, 4, 8, ZSTD_greedy }, /* level 4 */
+ { 17, 15, 17, 4, 4, 8, ZSTD_greedy }, /* level 5 */
+ { 17, 16, 17, 3, 4, 8, ZSTD_lazy }, /* level 6 */
+ { 17, 15, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 7 */
+ { 17, 17, 17, 4, 4, 8, ZSTD_lazy2 }, /* level 8 */
+ { 17, 17, 17, 5, 4, 8, ZSTD_lazy2 }, /* level 9 */
+ { 17, 17, 17, 6, 4, 8, ZSTD_lazy2 }, /* level 10 */
+ { 17, 17, 17, 7, 4, 8, ZSTD_lazy2 }, /* level 11 */
+ { 17, 17, 17, 8, 4, 8, ZSTD_lazy2 }, /* level 12 */
+ { 17, 18, 17, 6, 4, 8, ZSTD_btlazy2 }, /* level 13.*/
+ { 17, 17, 17, 7, 3, 8, ZSTD_btopt }, /* level 14.*/
+ { 17, 17, 17, 7, 3, 16, ZSTD_btopt }, /* level 15.*/
+ { 17, 18, 17, 7, 3, 32, ZSTD_btopt }, /* level 16.*/
+ { 17, 18, 17, 7, 3, 64, ZSTD_btopt }, /* level 17.*/
+ { 17, 18, 17, 7, 3,256, ZSTD_btopt }, /* level 18.*/
+ { 17, 18, 17, 8, 3,256, ZSTD_btopt }, /* level 19.*/
+ { 17, 18, 17, 9, 3,256, ZSTD_btopt2 }, /* level 20.*/
+ { 17, 18, 17, 10, 3,256, ZSTD_btopt2 }, /* level 21.*/
+ { 17, 18, 17, 11, 3,512, ZSTD_btopt2 }, /* level 22.*/
+},
+{ /* for srcSize <= 16 KB */
+ /* W, C, H, S, L, T, strat */
+ { 14, 12, 12, 1, 7, 6, ZSTD_fast }, /* level 0 - not used */
+ { 14, 14, 14, 1, 6, 6, ZSTD_fast }, /* level 1 */
+ { 14, 14, 14, 1, 4, 6, ZSTD_fast }, /* level 2 */
+ { 14, 14, 14, 1, 4, 6, ZSTD_dfast }, /* level 3.*/
+ { 14, 14, 14, 4, 4, 6, ZSTD_greedy }, /* level 4.*/
+ { 14, 14, 14, 3, 4, 6, ZSTD_lazy }, /* level 5.*/
+ { 14, 14, 14, 4, 4, 6, ZSTD_lazy2 }, /* level 6 */
+ { 14, 14, 14, 5, 4, 6, ZSTD_lazy2 }, /* level 7 */
+ { 14, 14, 14, 6, 4, 6, ZSTD_lazy2 }, /* level 8.*/
+ { 14, 15, 14, 6, 4, 6, ZSTD_btlazy2 }, /* level 9.*/
+ { 14, 15, 14, 3, 3, 6, ZSTD_btopt }, /* level 10.*/
+ { 14, 15, 14, 6, 3, 8, ZSTD_btopt }, /* level 11.*/
+ { 14, 15, 14, 6, 3, 16, ZSTD_btopt }, /* level 12.*/
+ { 14, 15, 14, 6, 3, 24, ZSTD_btopt }, /* level 13.*/
+ { 14, 15, 15, 6, 3, 48, ZSTD_btopt }, /* level 14.*/
+ { 14, 15, 15, 6, 3, 64, ZSTD_btopt }, /* level 15.*/
+ { 14, 15, 15, 6, 3, 96, ZSTD_btopt }, /* level 16.*/
+ { 14, 15, 15, 6, 3,128, ZSTD_btopt }, /* level 17.*/
+ { 14, 15, 15, 6, 3,256, ZSTD_btopt }, /* level 18.*/
+ { 14, 15, 15, 7, 3,256, ZSTD_btopt }, /* level 19.*/
+ { 14, 15, 15, 8, 3,256, ZSTD_btopt2 }, /* level 20.*/
+ { 14, 15, 15, 9, 3,256, ZSTD_btopt2 }, /* level 21.*/
+ { 14, 15, 15, 10, 3,256, ZSTD_btopt2 }, /* level 22.*/
+},
+};
+
+/*! ZSTD_getCParams() :
+* @return ZSTD_compressionParameters structure for a selected compression level, `srcSize` and `dictSize`.
+* Size values are optional, provide 0 if not known or unused */
+ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long srcSize, size_t dictSize)
+{
+ ZSTD_compressionParameters cp;
+ size_t const addedSize = srcSize ? 0 : 500;
+ U64 const rSize = srcSize+dictSize ? srcSize+dictSize+addedSize : (U64)-1;
+ U32 const tableID = (rSize <= 256 KB) + (rSize <= 128 KB) + (rSize <= 16 KB); /* intentional underflow for srcSizeHint == 0 */
+ if (compressionLevel <= 0) compressionLevel = ZSTD_DEFAULT_CLEVEL; /* 0 == default; no negative compressionLevel yet */
+ if (compressionLevel > ZSTD_MAX_CLEVEL) compressionLevel = ZSTD_MAX_CLEVEL;
+ cp = ZSTD_defaultCParameters[tableID][compressionLevel];
+ if (MEM_32bits()) { /* auto-correction, for 32-bits mode */
+ if (cp.windowLog > ZSTD_WINDOWLOG_MAX) cp.windowLog = ZSTD_WINDOWLOG_MAX;
+ if (cp.chainLog > ZSTD_CHAINLOG_MAX) cp.chainLog = ZSTD_CHAINLOG_MAX;
+ if (cp.hashLog > ZSTD_HASHLOG_MAX) cp.hashLog = ZSTD_HASHLOG_MAX;
+ }
+ cp = ZSTD_adjustCParams(cp, srcSize, dictSize);
+ return cp;
+}
+
+/*! ZSTD_getParams() :
+* same as ZSTD_getCParams(), but @return a `ZSTD_parameters` object (instead of `ZSTD_compressionParameters`).
+* All fields of `ZSTD_frameParameters` are set to default (0) */
+ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long srcSize, size_t dictSize) {
+ ZSTD_parameters params;
+ ZSTD_compressionParameters const cParams = ZSTD_getCParams(compressionLevel, srcSize, dictSize);
+ memset(&params, 0, sizeof(params));
+ params.cParams = cParams;
+ return params;
+}
diff --git a/thirdparty/zstd/compress/zstd_opt.h b/thirdparty/zstd/compress/zstd_opt.h
new file mode 100644
index 0000000000..5437611912
--- /dev/null
+++ b/thirdparty/zstd/compress/zstd_opt.h
@@ -0,0 +1,921 @@
+/**
+ * Copyright (c) 2016-present, Przemyslaw Skibinski, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+/* Note : this file is intended to be included within zstd_compress.c */
+
+
+#ifndef ZSTD_OPT_H_91842398743
+#define ZSTD_OPT_H_91842398743
+
+
+#define ZSTD_LITFREQ_ADD 2
+#define ZSTD_FREQ_DIV 4
+#define ZSTD_MAX_PRICE (1<<30)
+
+/*-*************************************
+* Price functions for optimal parser
+***************************************/
+FORCE_INLINE void ZSTD_setLog2Prices(seqStore_t* ssPtr)
+{
+ ssPtr->log2matchLengthSum = ZSTD_highbit32(ssPtr->matchLengthSum+1);
+ ssPtr->log2litLengthSum = ZSTD_highbit32(ssPtr->litLengthSum+1);
+ ssPtr->log2litSum = ZSTD_highbit32(ssPtr->litSum+1);
+ ssPtr->log2offCodeSum = ZSTD_highbit32(ssPtr->offCodeSum+1);
+ ssPtr->factor = 1 + ((ssPtr->litSum>>5) / ssPtr->litLengthSum) + ((ssPtr->litSum<<1) / (ssPtr->litSum + ssPtr->matchSum));
+}
+
+
+MEM_STATIC void ZSTD_rescaleFreqs(seqStore_t* ssPtr, const BYTE* src, size_t srcSize)
+{
+ unsigned u;
+
+ ssPtr->cachedLiterals = NULL;
+ ssPtr->cachedPrice = ssPtr->cachedLitLength = 0;
+ ssPtr->staticPrices = 0;
+
+ if (ssPtr->litLengthSum == 0) {
+ if (srcSize <= 1024) ssPtr->staticPrices = 1;
+
+ for (u=0; u<=MaxLit; u++)
+ ssPtr->litFreq[u] = 0;
+ for (u=0; u<srcSize; u++)
+ ssPtr->litFreq[src[u]]++;
+
+ ssPtr->litSum = 0;
+ ssPtr->litLengthSum = MaxLL+1;
+ ssPtr->matchLengthSum = MaxML+1;
+ ssPtr->offCodeSum = (MaxOff+1);
+ ssPtr->matchSum = (ZSTD_LITFREQ_ADD<<Litbits);
+
+ for (u=0; u<=MaxLit; u++) {
+ ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>ZSTD_FREQ_DIV);
+ ssPtr->litSum += ssPtr->litFreq[u];
+ }
+ for (u=0; u<=MaxLL; u++)
+ ssPtr->litLengthFreq[u] = 1;
+ for (u=0; u<=MaxML; u++)
+ ssPtr->matchLengthFreq[u] = 1;
+ for (u=0; u<=MaxOff; u++)
+ ssPtr->offCodeFreq[u] = 1;
+ } else {
+ ssPtr->matchLengthSum = 0;
+ ssPtr->litLengthSum = 0;
+ ssPtr->offCodeSum = 0;
+ ssPtr->matchSum = 0;
+ ssPtr->litSum = 0;
+
+ for (u=0; u<=MaxLit; u++) {
+ ssPtr->litFreq[u] = 1 + (ssPtr->litFreq[u]>>(ZSTD_FREQ_DIV+1));
+ ssPtr->litSum += ssPtr->litFreq[u];
+ }
+ for (u=0; u<=MaxLL; u++) {
+ ssPtr->litLengthFreq[u] = 1 + (ssPtr->litLengthFreq[u]>>(ZSTD_FREQ_DIV+1));
+ ssPtr->litLengthSum += ssPtr->litLengthFreq[u];
+ }
+ for (u=0; u<=MaxML; u++) {
+ ssPtr->matchLengthFreq[u] = 1 + (ssPtr->matchLengthFreq[u]>>ZSTD_FREQ_DIV);
+ ssPtr->matchLengthSum += ssPtr->matchLengthFreq[u];
+ ssPtr->matchSum += ssPtr->matchLengthFreq[u] * (u + 3);
+ }
+ ssPtr->matchSum *= ZSTD_LITFREQ_ADD;
+ for (u=0; u<=MaxOff; u++) {
+ ssPtr->offCodeFreq[u] = 1 + (ssPtr->offCodeFreq[u]>>ZSTD_FREQ_DIV);
+ ssPtr->offCodeSum += ssPtr->offCodeFreq[u];
+ }
+ }
+
+ ZSTD_setLog2Prices(ssPtr);
+}
+
+
+FORCE_INLINE U32 ZSTD_getLiteralPrice(seqStore_t* ssPtr, U32 litLength, const BYTE* literals)
+{
+ U32 price, u;
+
+ if (ssPtr->staticPrices)
+ return ZSTD_highbit32((U32)litLength+1) + (litLength*6);
+
+ if (litLength == 0)
+ return ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[0]+1);
+
+ /* literals */
+ if (ssPtr->cachedLiterals == literals) {
+ U32 const additional = litLength - ssPtr->cachedLitLength;
+ const BYTE* literals2 = ssPtr->cachedLiterals + ssPtr->cachedLitLength;
+ price = ssPtr->cachedPrice + additional * ssPtr->log2litSum;
+ for (u=0; u < additional; u++)
+ price -= ZSTD_highbit32(ssPtr->litFreq[literals2[u]]+1);
+ ssPtr->cachedPrice = price;
+ ssPtr->cachedLitLength = litLength;
+ } else {
+ price = litLength * ssPtr->log2litSum;
+ for (u=0; u < litLength; u++)
+ price -= ZSTD_highbit32(ssPtr->litFreq[literals[u]]+1);
+
+ if (litLength >= 12) {
+ ssPtr->cachedLiterals = literals;
+ ssPtr->cachedPrice = price;
+ ssPtr->cachedLitLength = litLength;
+ }
+ }
+
+ /* literal Length */
+ { const BYTE LL_deltaCode = 19;
+ const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
+ price += LL_bits[llCode] + ssPtr->log2litLengthSum - ZSTD_highbit32(ssPtr->litLengthFreq[llCode]+1);
+ }
+
+ return price;
+}
+
+
+FORCE_INLINE U32 ZSTD_getPrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength, const int ultra)
+{
+ /* offset */
+ U32 price;
+ BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
+
+ if (seqStorePtr->staticPrices)
+ return ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + ZSTD_highbit32((U32)matchLength+1) + 16 + offCode;
+
+ price = offCode + seqStorePtr->log2offCodeSum - ZSTD_highbit32(seqStorePtr->offCodeFreq[offCode]+1);
+ if (!ultra && offCode >= 20) price += (offCode-19)*2;
+
+ /* match Length */
+ { const BYTE ML_deltaCode = 36;
+ const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
+ price += ML_bits[mlCode] + seqStorePtr->log2matchLengthSum - ZSTD_highbit32(seqStorePtr->matchLengthFreq[mlCode]+1);
+ }
+
+ return price + ZSTD_getLiteralPrice(seqStorePtr, litLength, literals) + seqStorePtr->factor;
+}
+
+
+MEM_STATIC void ZSTD_updatePrice(seqStore_t* seqStorePtr, U32 litLength, const BYTE* literals, U32 offset, U32 matchLength)
+{
+ U32 u;
+
+ /* literals */
+ seqStorePtr->litSum += litLength*ZSTD_LITFREQ_ADD;
+ for (u=0; u < litLength; u++)
+ seqStorePtr->litFreq[literals[u]] += ZSTD_LITFREQ_ADD;
+
+ /* literal Length */
+ { const BYTE LL_deltaCode = 19;
+ const BYTE llCode = (litLength>63) ? (BYTE)ZSTD_highbit32(litLength) + LL_deltaCode : LL_Code[litLength];
+ seqStorePtr->litLengthFreq[llCode]++;
+ seqStorePtr->litLengthSum++;
+ }
+
+ /* match offset */
+ { BYTE const offCode = (BYTE)ZSTD_highbit32(offset+1);
+ seqStorePtr->offCodeSum++;
+ seqStorePtr->offCodeFreq[offCode]++;
+ }
+
+ /* match Length */
+ { const BYTE ML_deltaCode = 36;
+ const BYTE mlCode = (matchLength>127) ? (BYTE)ZSTD_highbit32(matchLength) + ML_deltaCode : ML_Code[matchLength];
+ seqStorePtr->matchLengthFreq[mlCode]++;
+ seqStorePtr->matchLengthSum++;
+ }
+
+ ZSTD_setLog2Prices(seqStorePtr);
+}
+
+
+#define SET_PRICE(pos, mlen_, offset_, litlen_, price_) \
+ { \
+ while (last_pos < pos) { opt[last_pos+1].price = ZSTD_MAX_PRICE; last_pos++; } \
+ opt[pos].mlen = mlen_; \
+ opt[pos].off = offset_; \
+ opt[pos].litlen = litlen_; \
+ opt[pos].price = price_; \
+ }
+
+
+
+/* Update hashTable3 up to ip (excluded)
+ Assumption : always within prefix (i.e. not within extDict) */
+FORCE_INLINE
+U32 ZSTD_insertAndFindFirstIndexHash3 (ZSTD_CCtx* zc, const BYTE* ip)
+{
+ U32* const hashTable3 = zc->hashTable3;
+ U32 const hashLog3 = zc->hashLog3;
+ const BYTE* const base = zc->base;
+ U32 idx = zc->nextToUpdate3;
+ const U32 target = zc->nextToUpdate3 = (U32)(ip - base);
+ const size_t hash3 = ZSTD_hash3Ptr(ip, hashLog3);
+
+ while(idx < target) {
+ hashTable3[ZSTD_hash3Ptr(base+idx, hashLog3)] = idx;
+ idx++;
+ }
+
+ return hashTable3[hash3];
+}
+
+
+/*-*************************************
+* Binary Tree search
+***************************************/
+static U32 ZSTD_insertBtAndGetAllMatches (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ U32 nbCompares, const U32 mls,
+ U32 extDict, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ const BYTE* const base = zc->base;
+ const U32 current = (U32)(ip-base);
+ const U32 hashLog = zc->params.cParams.hashLog;
+ const size_t h = ZSTD_hashPtr(ip, hashLog, mls);
+ U32* const hashTable = zc->hashTable;
+ U32 matchIndex = hashTable[h];
+ U32* const bt = zc->chainTable;
+ const U32 btLog = zc->params.cParams.chainLog - 1;
+ const U32 btMask= (1U << btLog) - 1;
+ size_t commonLengthSmaller=0, commonLengthLarger=0;
+ const BYTE* const dictBase = zc->dictBase;
+ const U32 dictLimit = zc->dictLimit;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const U32 btLow = btMask >= current ? 0 : current - btMask;
+ const U32 windowLow = zc->lowLimit;
+ U32* smallerPtr = bt + 2*(current&btMask);
+ U32* largerPtr = bt + 2*(current&btMask) + 1;
+ U32 matchEndIdx = current+8;
+ U32 dummy32; /* to be nullified at the end */
+ U32 mnum = 0;
+
+ const U32 minMatch = (mls == 3) ? 3 : 4;
+ size_t bestLength = minMatchLen-1;
+
+ if (minMatch == 3) { /* HC3 match finder */
+ U32 const matchIndex3 = ZSTD_insertAndFindFirstIndexHash3 (zc, ip);
+ if (matchIndex3>windowLow && (current - matchIndex3 < (1<<18))) {
+ const BYTE* match;
+ size_t currentMl=0;
+ if ((!extDict) || matchIndex3 >= dictLimit) {
+ match = base + matchIndex3;
+ if (match[bestLength] == ip[bestLength]) currentMl = ZSTD_count(ip, match, iLimit);
+ } else {
+ match = dictBase + matchIndex3;
+ if (MEM_readMINMATCH(match, MINMATCH) == MEM_readMINMATCH(ip, MINMATCH)) /* assumption : matchIndex3 <= dictLimit-4 (by table construction) */
+ currentMl = ZSTD_count_2segments(ip+MINMATCH, match+MINMATCH, iLimit, dictEnd, prefixStart) + MINMATCH;
+ }
+
+ /* save best solution */
+ if (currentMl > bestLength) {
+ bestLength = currentMl;
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex3;
+ matches[mnum].len = (U32)currentMl;
+ mnum++;
+ if (currentMl > ZSTD_OPT_NUM) goto update;
+ if (ip+currentMl == iLimit) goto update; /* best possible, and avoid read overflow*/
+ }
+ }
+ }
+
+ hashTable[h] = current; /* Update Hash Table */
+
+ while (nbCompares-- && (matchIndex > windowLow)) {
+ U32* nextPtr = bt + 2*(matchIndex & btMask);
+ size_t matchLength = MIN(commonLengthSmaller, commonLengthLarger); /* guaranteed minimum nb of common bytes */
+ const BYTE* match;
+
+ if ((!extDict) || (matchIndex+matchLength >= dictLimit)) {
+ match = base + matchIndex;
+ if (match[matchLength] == ip[matchLength]) {
+ matchLength += ZSTD_count(ip+matchLength+1, match+matchLength+1, iLimit) +1;
+ }
+ } else {
+ match = dictBase + matchIndex;
+ matchLength += ZSTD_count_2segments(ip+matchLength, match+matchLength, iLimit, dictEnd, prefixStart);
+ if (matchIndex+matchLength >= dictLimit)
+ match = base + matchIndex; /* to prepare for next usage of match[matchLength] */
+ }
+
+ if (matchLength > bestLength) {
+ if (matchLength > matchEndIdx - matchIndex) matchEndIdx = matchIndex + (U32)matchLength;
+ bestLength = matchLength;
+ matches[mnum].off = ZSTD_REP_MOVE_OPT + current - matchIndex;
+ matches[mnum].len = (U32)matchLength;
+ mnum++;
+ if (matchLength > ZSTD_OPT_NUM) break;
+ if (ip+matchLength == iLimit) /* equal : no way to know if inf or sup */
+ break; /* drop, to guarantee consistency (miss a little bit of compression) */
+ }
+
+ if (match[matchLength] < ip[matchLength]) {
+ /* match is smaller than current */
+ *smallerPtr = matchIndex; /* update smaller idx */
+ commonLengthSmaller = matchLength; /* all smaller will now have at least this guaranteed common length */
+ if (matchIndex <= btLow) { smallerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ smallerPtr = nextPtr+1; /* new "smaller" => larger of match */
+ matchIndex = nextPtr[1]; /* new matchIndex larger than previous (closer to current) */
+ } else {
+ /* match is larger than current */
+ *largerPtr = matchIndex;
+ commonLengthLarger = matchLength;
+ if (matchIndex <= btLow) { largerPtr=&dummy32; break; } /* beyond tree size, stop the search */
+ largerPtr = nextPtr;
+ matchIndex = nextPtr[0];
+ } }
+
+ *smallerPtr = *largerPtr = 0;
+
+update:
+ zc->nextToUpdate = (matchEndIdx > current + 8) ? matchEndIdx - 8 : current+1;
+ return mnum;
+}
+
+
+/** Tree updater, providing best match */
+static U32 ZSTD_BtGetAllMatches (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 0, matches, minMatchLen);
+}
+
+
+static U32 ZSTD_BtGetAllMatches_selectMLS (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iHighLimit,
+ const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ switch(matchLengthSearch)
+ {
+ case 3 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
+ default :
+ case 4 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
+ case 5 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
+ case 7 :
+ case 6 : return ZSTD_BtGetAllMatches(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
+ }
+}
+
+/** Tree updater, providing best match */
+static U32 ZSTD_BtGetAllMatches_extDict (
+ ZSTD_CCtx* zc,
+ const BYTE* const ip, const BYTE* const iLimit,
+ const U32 maxNbAttempts, const U32 mls, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ if (ip < zc->base + zc->nextToUpdate) return 0; /* skipped area */
+ ZSTD_updateTree_extDict(zc, ip, iLimit, maxNbAttempts, mls);
+ return ZSTD_insertBtAndGetAllMatches(zc, ip, iLimit, maxNbAttempts, mls, 1, matches, minMatchLen);
+}
+
+
+static U32 ZSTD_BtGetAllMatches_selectMLS_extDict (
+ ZSTD_CCtx* zc, /* Index table will be updated */
+ const BYTE* ip, const BYTE* const iHighLimit,
+ const U32 maxNbAttempts, const U32 matchLengthSearch, ZSTD_match_t* matches, const U32 minMatchLen)
+{
+ switch(matchLengthSearch)
+ {
+ case 3 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 3, matches, minMatchLen);
+ default :
+ case 4 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 4, matches, minMatchLen);
+ case 5 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 5, matches, minMatchLen);
+ case 7 :
+ case 6 : return ZSTD_BtGetAllMatches_extDict(zc, ip, iHighLimit, maxNbAttempts, 6, matches, minMatchLen);
+ }
+}
+
+
+/*-*******************************
+* Optimal parser
+*********************************/
+FORCE_INLINE
+void ZSTD_compressBlock_opt_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize, const int ultra)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const BYTE* const prefixStart = base + ctx->dictLimit;
+
+ const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
+ const U32 sufficient_len = ctx->params.cParams.targetLength;
+ const U32 mls = ctx->params.cParams.searchLength;
+ const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
+
+ ZSTD_optimal_t* opt = seqStorePtr->priceTable;
+ ZSTD_match_t* matches = seqStorePtr->matchTable;
+ const BYTE* inr;
+ U32 offset, rep[ZSTD_REP_NUM];
+
+ /* init */
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize);
+ ip += (ip==prefixStart);
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ U32 cur, match_num, last_pos, litlen, price;
+ U32 u, mlen, best_mlen, best_off, litLength;
+ memset(opt, 0, sizeof(ZSTD_optimal_t));
+ last_pos = 0;
+ litlen = (U32)(ip - anchor);
+
+ /* check repCode */
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
+ for (i=(ip == anchor); i<last_i; i++) {
+ const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[i];
+ if ( (repCur > 0) && (repCur < (S32)(ip-prefixStart))
+ && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(ip - repCur, minMatch))) {
+ mlen = (U32)ZSTD_count(ip+minMatch, ip+minMatch-repCur, iend) + minMatch;
+ if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
+ goto _storeSequence;
+ }
+ best_off = i - (ip == anchor);
+ do {
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, ip, iend, maxSearches, mls, matches, minMatch);
+
+ if (!last_pos && !match_num) { ip++; continue; }
+
+ if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ cur = 0;
+ last_pos = 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = 0 */
+ best_mlen = (last_pos) ? last_pos : minMatch;
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+ while (mlen <= best_mlen) {
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, matches[u].off, litlen, price); /* note : macro modifies last_pos */
+ mlen++;
+ } }
+
+ if (last_pos < minMatch) { ip++; continue; }
+
+ /* initialize opt[0] */
+ { U32 i ; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
+ opt[0].mlen = 1;
+ opt[0].litlen = litlen;
+
+ /* check further positions */
+ for (cur = 1; cur <= last_pos; cur++) {
+ inr = ip + cur;
+
+ if (opt[cur-1].mlen == 1) {
+ litlen = opt[cur-1].litlen + 1;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen);
+ } else
+ price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor);
+ } else {
+ litlen = 1;
+ price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
+ }
+
+ if (cur > last_pos || price <= opt[cur].price)
+ SET_PRICE(cur, 1, 0, litlen, price);
+
+ if (cur == last_pos) break;
+
+ if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
+ continue;
+
+ mlen = opt[cur].mlen;
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
+ opt[cur].rep[2] = opt[cur-mlen].rep[1];
+ opt[cur].rep[1] = opt[cur-mlen].rep[0];
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
+ } else {
+ opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
+ opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
+ }
+
+ best_mlen = minMatch;
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
+ for (i=(opt[cur].mlen != 1); i<last_i; i++) { /* check rep */
+ const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i];
+ if ( (repCur > 0) && (repCur < (S32)(inr-prefixStart))
+ && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(inr - repCur, minMatch))) {
+ mlen = (U32)ZSTD_count(inr+minMatch, inr+minMatch - repCur, iend) + minMatch;
+
+ if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (opt[cur].mlen != 1);
+ if (mlen > best_mlen) best_mlen = mlen;
+
+ do {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
+ } else
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
+ SET_PRICE(cur + mlen, mlen, i, litlen, price);
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS(ctx, inr, iend, maxSearches, mls, matches, best_mlen);
+
+ if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = cur */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+
+ while (mlen <= best_mlen) {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen)
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
+ else
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
+ SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
+
+ mlen++;
+ } } }
+
+ best_mlen = opt[last_pos].mlen;
+ best_off = opt[last_pos].off;
+ cur = last_pos - best_mlen;
+
+ /* store sequence */
+_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
+ opt[0].mlen = 1;
+
+ while (1) {
+ mlen = opt[cur].mlen;
+ offset = opt[cur].off;
+ opt[cur].mlen = best_mlen;
+ opt[cur].off = best_off;
+ best_mlen = mlen;
+ best_off = offset;
+ if (mlen > cur) break;
+ cur -= mlen;
+ }
+
+ for (u = 0; u <= last_pos;) {
+ u += opt[u].mlen;
+ }
+
+ for (cur=0; cur < last_pos; ) {
+ mlen = opt[cur].mlen;
+ if (mlen == 1) { ip++; cur++; continue; }
+ offset = opt[cur].off;
+ cur += mlen;
+ litLength = (U32)(ip - anchor);
+
+ if (offset > ZSTD_REP_MOVE_OPT) {
+ rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
+ offset--;
+ } else {
+ if (offset != 0) {
+ best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
+ if (offset != 1) rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = best_off;
+ }
+ if (litLength==0) offset--;
+ }
+
+ ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ anchor = ip = ip + mlen;
+ } } /* for (cur=0; cur < last_pos; ) */
+
+ /* Save reps for next block */
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) ctx->repToConfirm[i] = rep[i]; }
+
+ /* Last Literals */
+ { size_t const lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+
+FORCE_INLINE
+void ZSTD_compressBlock_opt_extDict_generic(ZSTD_CCtx* ctx,
+ const void* src, size_t srcSize, const int ultra)
+{
+ seqStore_t* seqStorePtr = &(ctx->seqStore);
+ const BYTE* const istart = (const BYTE*)src;
+ const BYTE* ip = istart;
+ const BYTE* anchor = istart;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* const ilimit = iend - 8;
+ const BYTE* const base = ctx->base;
+ const U32 lowestIndex = ctx->lowLimit;
+ const U32 dictLimit = ctx->dictLimit;
+ const BYTE* const prefixStart = base + dictLimit;
+ const BYTE* const dictBase = ctx->dictBase;
+ const BYTE* const dictEnd = dictBase + dictLimit;
+
+ const U32 maxSearches = 1U << ctx->params.cParams.searchLog;
+ const U32 sufficient_len = ctx->params.cParams.targetLength;
+ const U32 mls = ctx->params.cParams.searchLength;
+ const U32 minMatch = (ctx->params.cParams.searchLength == 3) ? 3 : 4;
+
+ ZSTD_optimal_t* opt = seqStorePtr->priceTable;
+ ZSTD_match_t* matches = seqStorePtr->matchTable;
+ const BYTE* inr;
+
+ /* init */
+ U32 offset, rep[ZSTD_REP_NUM];
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) rep[i]=ctx->rep[i]; }
+
+ ctx->nextToUpdate3 = ctx->nextToUpdate;
+ ZSTD_rescaleFreqs(seqStorePtr, (const BYTE*)src, srcSize);
+ ip += (ip==prefixStart);
+
+ /* Match Loop */
+ while (ip < ilimit) {
+ U32 cur, match_num, last_pos, litlen, price;
+ U32 u, mlen, best_mlen, best_off, litLength;
+ U32 current = (U32)(ip-base);
+ memset(opt, 0, sizeof(ZSTD_optimal_t));
+ last_pos = 0;
+ opt[0].litlen = (U32)(ip - anchor);
+
+ /* check repCode */
+ { U32 i, last_i = ZSTD_REP_CHECK + (ip==anchor);
+ for (i = (ip==anchor); i<last_i; i++) {
+ const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : rep[i];
+ const U32 repIndex = (U32)(current - repCur);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if ( (repCur > 0 && repCur <= (S32)current)
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
+ && (MEM_readMINMATCH(ip, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
+ /* repcode detected we should take it */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ mlen = (U32)ZSTD_count_2segments(ip+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
+
+ if (mlen > sufficient_len || mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; cur = 0; last_pos = 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (ip==anchor);
+ litlen = opt[0].litlen;
+ do {
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, i, litlen, price); /* note : macro modifies last_pos */
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, ip, iend, maxSearches, mls, matches, minMatch); /* first search (depth 0) */
+
+ if (!last_pos && !match_num) { ip++; continue; }
+
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) opt[0].rep[i] = rep[i]; }
+ opt[0].mlen = 1;
+
+ if (match_num && (matches[match_num-1].len > sufficient_len || matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ cur = 0;
+ last_pos = 1;
+ goto _storeSequence;
+ }
+
+ best_mlen = (last_pos) ? last_pos : minMatch;
+
+ /* set prices using matches at position = 0 */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+ litlen = opt[0].litlen;
+ while (mlen <= best_mlen) {
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ if (mlen > last_pos || price < opt[mlen].price)
+ SET_PRICE(mlen, mlen, matches[u].off, litlen, price);
+ mlen++;
+ } }
+
+ if (last_pos < minMatch) {
+ ip++; continue;
+ }
+
+ /* check further positions */
+ for (cur = 1; cur <= last_pos; cur++) {
+ inr = ip + cur;
+
+ if (opt[cur-1].mlen == 1) {
+ litlen = opt[cur-1].litlen + 1;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-litlen);
+ } else
+ price = ZSTD_getLiteralPrice(seqStorePtr, litlen, anchor);
+ } else {
+ litlen = 1;
+ price = opt[cur - 1].price + ZSTD_getLiteralPrice(seqStorePtr, litlen, inr-1);
+ }
+
+ if (cur > last_pos || price <= opt[cur].price)
+ SET_PRICE(cur, 1, 0, litlen, price);
+
+ if (cur == last_pos) break;
+
+ if (inr > ilimit) /* last match must start at a minimum distance of 8 from oend */
+ continue;
+
+ mlen = opt[cur].mlen;
+ if (opt[cur].off > ZSTD_REP_MOVE_OPT) {
+ opt[cur].rep[2] = opt[cur-mlen].rep[1];
+ opt[cur].rep[1] = opt[cur-mlen].rep[0];
+ opt[cur].rep[0] = opt[cur].off - ZSTD_REP_MOVE_OPT;
+ } else {
+ opt[cur].rep[2] = (opt[cur].off > 1) ? opt[cur-mlen].rep[1] : opt[cur-mlen].rep[2];
+ opt[cur].rep[1] = (opt[cur].off > 0) ? opt[cur-mlen].rep[0] : opt[cur-mlen].rep[1];
+ opt[cur].rep[0] = ((opt[cur].off==ZSTD_REP_MOVE_OPT) && (mlen != 1)) ? (opt[cur-mlen].rep[0] - 1) : (opt[cur-mlen].rep[opt[cur].off]);
+ }
+
+ best_mlen = minMatch;
+ { U32 i, last_i = ZSTD_REP_CHECK + (mlen != 1);
+ for (i = (mlen != 1); i<last_i; i++) {
+ const S32 repCur = (i==ZSTD_REP_MOVE_OPT) ? (opt[cur].rep[0] - 1) : opt[cur].rep[i];
+ const U32 repIndex = (U32)(current+cur - repCur);
+ const BYTE* const repBase = repIndex < dictLimit ? dictBase : base;
+ const BYTE* const repMatch = repBase + repIndex;
+ if ( (repCur > 0 && repCur <= (S32)(current+cur))
+ && (((U32)((dictLimit-1) - repIndex) >= 3) & (repIndex>lowestIndex)) /* intentional overflow */
+ && (MEM_readMINMATCH(inr, minMatch) == MEM_readMINMATCH(repMatch, minMatch)) ) {
+ /* repcode detected */
+ const BYTE* const repEnd = repIndex < dictLimit ? dictEnd : iend;
+ mlen = (U32)ZSTD_count_2segments(inr+minMatch, repMatch+minMatch, iend, repEnd, prefixStart) + minMatch;
+
+ if (mlen > sufficient_len || cur + mlen >= ZSTD_OPT_NUM) {
+ best_mlen = mlen; best_off = i; last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ best_off = i - (opt[cur].mlen != 1);
+ if (mlen > best_mlen) best_mlen = mlen;
+
+ do {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen) {
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, inr-litlen, best_off, mlen - MINMATCH, ultra);
+ } else
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, best_off, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, best_off, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || price <= opt[cur + mlen].price)
+ SET_PRICE(cur + mlen, mlen, i, litlen, price);
+ mlen--;
+ } while (mlen >= minMatch);
+ } } }
+
+ match_num = ZSTD_BtGetAllMatches_selectMLS_extDict(ctx, inr, iend, maxSearches, mls, matches, minMatch);
+
+ if (match_num > 0 && (matches[match_num-1].len > sufficient_len || cur + matches[match_num-1].len >= ZSTD_OPT_NUM)) {
+ best_mlen = matches[match_num-1].len;
+ best_off = matches[match_num-1].off;
+ last_pos = cur + 1;
+ goto _storeSequence;
+ }
+
+ /* set prices using matches at position = cur */
+ for (u = 0; u < match_num; u++) {
+ mlen = (u>0) ? matches[u-1].len+1 : best_mlen;
+ best_mlen = matches[u].len;
+
+ while (mlen <= best_mlen) {
+ if (opt[cur].mlen == 1) {
+ litlen = opt[cur].litlen;
+ if (cur > litlen)
+ price = opt[cur - litlen].price + ZSTD_getPrice(seqStorePtr, litlen, ip+cur-litlen, matches[u].off-1, mlen - MINMATCH, ultra);
+ else
+ price = ZSTD_getPrice(seqStorePtr, litlen, anchor, matches[u].off-1, mlen - MINMATCH, ultra);
+ } else {
+ litlen = 0;
+ price = opt[cur].price + ZSTD_getPrice(seqStorePtr, 0, NULL, matches[u].off-1, mlen - MINMATCH, ultra);
+ }
+
+ if (cur + mlen > last_pos || (price < opt[cur + mlen].price))
+ SET_PRICE(cur + mlen, mlen, matches[u].off, litlen, price);
+
+ mlen++;
+ } } } /* for (cur = 1; cur <= last_pos; cur++) */
+
+ best_mlen = opt[last_pos].mlen;
+ best_off = opt[last_pos].off;
+ cur = last_pos - best_mlen;
+
+ /* store sequence */
+_storeSequence: /* cur, last_pos, best_mlen, best_off have to be set */
+ opt[0].mlen = 1;
+
+ while (1) {
+ mlen = opt[cur].mlen;
+ offset = opt[cur].off;
+ opt[cur].mlen = best_mlen;
+ opt[cur].off = best_off;
+ best_mlen = mlen;
+ best_off = offset;
+ if (mlen > cur) break;
+ cur -= mlen;
+ }
+
+ for (u = 0; u <= last_pos; ) {
+ u += opt[u].mlen;
+ }
+
+ for (cur=0; cur < last_pos; ) {
+ mlen = opt[cur].mlen;
+ if (mlen == 1) { ip++; cur++; continue; }
+ offset = opt[cur].off;
+ cur += mlen;
+ litLength = (U32)(ip - anchor);
+
+ if (offset > ZSTD_REP_MOVE_OPT) {
+ rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = offset - ZSTD_REP_MOVE_OPT;
+ offset--;
+ } else {
+ if (offset != 0) {
+ best_off = (offset==ZSTD_REP_MOVE_OPT) ? (rep[0] - 1) : (rep[offset]);
+ if (offset != 1) rep[2] = rep[1];
+ rep[1] = rep[0];
+ rep[0] = best_off;
+ }
+
+ if (litLength==0) offset--;
+ }
+
+ ZSTD_updatePrice(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ ZSTD_storeSeq(seqStorePtr, litLength, anchor, offset, mlen-MINMATCH);
+ anchor = ip = ip + mlen;
+ } } /* for (cur=0; cur < last_pos; ) */
+
+ /* Save reps for next block */
+ { int i; for (i=0; i<ZSTD_REP_NUM; i++) ctx->repToConfirm[i] = rep[i]; }
+
+ /* Last Literals */
+ { size_t lastLLSize = iend - anchor;
+ memcpy(seqStorePtr->lit, anchor, lastLLSize);
+ seqStorePtr->lit += lastLLSize;
+ }
+}
+
+#endif /* ZSTD_OPT_H_91842398743 */
diff --git a/thirdparty/zstd/compress/zstdmt_compress.c b/thirdparty/zstd/compress/zstdmt_compress.c
new file mode 100644
index 0000000000..fc7f52a290
--- /dev/null
+++ b/thirdparty/zstd/compress/zstdmt_compress.c
@@ -0,0 +1,751 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+/* ====== Tuning parameters ====== */
+#define ZSTDMT_NBTHREADS_MAX 128
+
+
+/* ====== Compiler specifics ====== */
+#if defined(_MSC_VER)
+# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
+#endif
+
+
+/* ====== Dependencies ====== */
+#include <stdlib.h> /* malloc */
+#include <string.h> /* memcpy */
+#include "pool.h" /* threadpool */
+#include "threading.h" /* mutex */
+#include "zstd_internal.h" /* MIN, ERROR, ZSTD_*, ZSTD_highbit32 */
+#include "zstdmt_compress.h"
+
+
+/* ====== Debug ====== */
+#if 0
+
+# include <stdio.h>
+# include <unistd.h>
+# include <sys/times.h>
+ static unsigned g_debugLevel = 5;
+# define DEBUGLOGRAW(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __VA_ARGS__); }
+# define DEBUGLOG(l, ...) if (l<=g_debugLevel) { fprintf(stderr, __FILE__ ": "); fprintf(stderr, __VA_ARGS__); fprintf(stderr, " \n"); }
+
+# define DEBUG_PRINTHEX(l,p,n) { \
+ unsigned debug_u; \
+ for (debug_u=0; debug_u<(n); debug_u++) \
+ DEBUGLOGRAW(l, "%02X ", ((const unsigned char*)(p))[debug_u]); \
+ DEBUGLOGRAW(l, " \n"); \
+}
+
+static unsigned long long GetCurrentClockTimeMicroseconds(void)
+{
+ static clock_t _ticksPerSecond = 0;
+ if (_ticksPerSecond <= 0) _ticksPerSecond = sysconf(_SC_CLK_TCK);
+
+ { struct tms junk; clock_t newTicks = (clock_t) times(&junk);
+ return ((((unsigned long long)newTicks)*(1000000))/_ticksPerSecond); }
+}
+
+#define MUTEX_WAIT_TIME_DLEVEL 5
+#define PTHREAD_MUTEX_LOCK(mutex) \
+if (g_debugLevel>=MUTEX_WAIT_TIME_DLEVEL) { \
+ unsigned long long const beforeTime = GetCurrentClockTimeMicroseconds(); \
+ pthread_mutex_lock(mutex); \
+ { unsigned long long const afterTime = GetCurrentClockTimeMicroseconds(); \
+ unsigned long long const elapsedTime = (afterTime-beforeTime); \
+ if (elapsedTime > 1000) { /* or whatever threshold you like; I'm using 1 millisecond here */ \
+ DEBUGLOG(MUTEX_WAIT_TIME_DLEVEL, "Thread took %llu microseconds to acquire mutex %s \n", \
+ elapsedTime, #mutex); \
+ } } \
+} else pthread_mutex_lock(mutex);
+
+#else
+
+# define DEBUGLOG(l, ...) {} /* disabled */
+# define PTHREAD_MUTEX_LOCK(m) pthread_mutex_lock(m)
+# define DEBUG_PRINTHEX(l,p,n) {}
+
+#endif
+
+
+/* ===== Buffer Pool ===== */
+
+typedef struct buffer_s {
+ void* start;
+ size_t size;
+} buffer_t;
+
+static const buffer_t g_nullBuffer = { NULL, 0 };
+
+typedef struct ZSTDMT_bufferPool_s {
+ unsigned totalBuffers;
+ unsigned nbBuffers;
+ buffer_t bTable[1]; /* variable size */
+} ZSTDMT_bufferPool;
+
+static ZSTDMT_bufferPool* ZSTDMT_createBufferPool(unsigned nbThreads)
+{
+ unsigned const maxNbBuffers = 2*nbThreads + 2;
+ ZSTDMT_bufferPool* const bufPool = (ZSTDMT_bufferPool*)calloc(1, sizeof(ZSTDMT_bufferPool) + (maxNbBuffers-1) * sizeof(buffer_t));
+ if (bufPool==NULL) return NULL;
+ bufPool->totalBuffers = maxNbBuffers;
+ bufPool->nbBuffers = 0;
+ return bufPool;
+}
+
+static void ZSTDMT_freeBufferPool(ZSTDMT_bufferPool* bufPool)
+{
+ unsigned u;
+ if (!bufPool) return; /* compatibility with free on NULL */
+ for (u=0; u<bufPool->totalBuffers; u++)
+ free(bufPool->bTable[u].start);
+ free(bufPool);
+}
+
+/* assumption : invocation from main thread only ! */
+static buffer_t ZSTDMT_getBuffer(ZSTDMT_bufferPool* pool, size_t bSize)
+{
+ if (pool->nbBuffers) { /* try to use an existing buffer */
+ buffer_t const buf = pool->bTable[--(pool->nbBuffers)];
+ size_t const availBufferSize = buf.size;
+ if ((availBufferSize >= bSize) & (availBufferSize <= 10*bSize)) /* large enough, but not too much */
+ return buf;
+ free(buf.start); /* size conditions not respected : scratch this buffer and create a new one */
+ }
+ /* create new buffer */
+ { buffer_t buffer;
+ void* const start = malloc(bSize);
+ if (start==NULL) bSize = 0;
+ buffer.start = start; /* note : start can be NULL if malloc fails ! */
+ buffer.size = bSize;
+ return buffer;
+ }
+}
+
+/* store buffer for later re-use, up to pool capacity */
+static void ZSTDMT_releaseBuffer(ZSTDMT_bufferPool* pool, buffer_t buf)
+{
+ if (buf.start == NULL) return; /* release on NULL */
+ if (pool->nbBuffers < pool->totalBuffers) {
+ pool->bTable[pool->nbBuffers++] = buf; /* store for later re-use */
+ return;
+ }
+ /* Reached bufferPool capacity (should not happen) */
+ free(buf.start);
+}
+
+
+/* ===== CCtx Pool ===== */
+
+typedef struct {
+ unsigned totalCCtx;
+ unsigned availCCtx;
+ ZSTD_CCtx* cctx[1]; /* variable size */
+} ZSTDMT_CCtxPool;
+
+/* assumption : CCtxPool invocation only from main thread */
+
+/* note : all CCtx borrowed from the pool should be released back to the pool _before_ freeing the pool */
+static void ZSTDMT_freeCCtxPool(ZSTDMT_CCtxPool* pool)
+{
+ unsigned u;
+ for (u=0; u<pool->totalCCtx; u++)
+ ZSTD_freeCCtx(pool->cctx[u]); /* note : compatible with free on NULL */
+ free(pool);
+}
+
+/* ZSTDMT_createCCtxPool() :
+ * implies nbThreads >= 1 , checked by caller ZSTDMT_createCCtx() */
+static ZSTDMT_CCtxPool* ZSTDMT_createCCtxPool(unsigned nbThreads)
+{
+ ZSTDMT_CCtxPool* const cctxPool = (ZSTDMT_CCtxPool*) calloc(1, sizeof(ZSTDMT_CCtxPool) + (nbThreads-1)*sizeof(ZSTD_CCtx*));
+ if (!cctxPool) return NULL;
+ cctxPool->totalCCtx = nbThreads;
+ cctxPool->availCCtx = 1; /* at least one cctx for single-thread mode */
+ cctxPool->cctx[0] = ZSTD_createCCtx();
+ if (!cctxPool->cctx[0]) { ZSTDMT_freeCCtxPool(cctxPool); return NULL; }
+ DEBUGLOG(1, "cctxPool created, with %u threads", nbThreads);
+ return cctxPool;
+}
+
+static ZSTD_CCtx* ZSTDMT_getCCtx(ZSTDMT_CCtxPool* pool)
+{
+ if (pool->availCCtx) {
+ pool->availCCtx--;
+ return pool->cctx[pool->availCCtx];
+ }
+ return ZSTD_createCCtx(); /* note : can be NULL, when creation fails ! */
+}
+
+static void ZSTDMT_releaseCCtx(ZSTDMT_CCtxPool* pool, ZSTD_CCtx* cctx)
+{
+ if (cctx==NULL) return; /* compatibility with release on NULL */
+ if (pool->availCCtx < pool->totalCCtx)
+ pool->cctx[pool->availCCtx++] = cctx;
+ else
+ /* pool overflow : should not happen, since totalCCtx==nbThreads */
+ ZSTD_freeCCtx(cctx);
+}
+
+
+/* ===== Thread worker ===== */
+
+typedef struct {
+ buffer_t buffer;
+ size_t filled;
+} inBuff_t;
+
+typedef struct {
+ ZSTD_CCtx* cctx;
+ buffer_t src;
+ const void* srcStart;
+ size_t srcSize;
+ size_t dictSize;
+ buffer_t dstBuff;
+ size_t cSize;
+ size_t dstFlushed;
+ unsigned firstChunk;
+ unsigned lastChunk;
+ unsigned jobCompleted;
+ unsigned jobScanned;
+ pthread_mutex_t* jobCompleted_mutex;
+ pthread_cond_t* jobCompleted_cond;
+ ZSTD_parameters params;
+ ZSTD_CDict* cdict;
+ unsigned long long fullFrameSize;
+} ZSTDMT_jobDescription;
+
+/* ZSTDMT_compressChunk() : POOL_function type */
+void ZSTDMT_compressChunk(void* jobDescription)
+{
+ ZSTDMT_jobDescription* const job = (ZSTDMT_jobDescription*)jobDescription;
+ const void* const src = (const char*)job->srcStart + job->dictSize;
+ buffer_t const dstBuff = job->dstBuff;
+ DEBUGLOG(3, "job (first:%u) (last:%u) : dictSize %u, srcSize %u",
+ job->firstChunk, job->lastChunk, (U32)job->dictSize, (U32)job->srcSize);
+ if (job->cdict) { /* should only happen for first segment */
+ size_t const initError = ZSTD_compressBegin_usingCDict_advanced(job->cctx, job->cdict, job->params.fParams, job->fullFrameSize);
+ if (job->cdict) DEBUGLOG(3, "using CDict ");
+ if (ZSTD_isError(initError)) { job->cSize = initError; goto _endJob; }
+ } else { /* srcStart points at reloaded section */
+ if (!job->firstChunk) job->params.fParams.contentSizeFlag = 0; /* ensure no srcSize control */
+ { size_t const dictModeError = ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceRawDict, 1); /* Force loading dictionary in "content-only" mode (no header analysis) */
+ size_t const initError = ZSTD_compressBegin_advanced(job->cctx, job->srcStart, job->dictSize, job->params, job->fullFrameSize);
+ if (ZSTD_isError(initError) || ZSTD_isError(dictModeError)) { job->cSize = initError; goto _endJob; }
+ ZSTD_setCCtxParameter(job->cctx, ZSTD_p_forceWindow, 1);
+ } }
+ if (!job->firstChunk) { /* flush and overwrite frame header when it's not first segment */
+ size_t const hSize = ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, 0);
+ if (ZSTD_isError(hSize)) { job->cSize = hSize; goto _endJob; }
+ ZSTD_invalidateRepCodes(job->cctx);
+ }
+
+ DEBUGLOG(4, "Compressing : ");
+ DEBUG_PRINTHEX(4, job->srcStart, 12);
+ job->cSize = (job->lastChunk) ?
+ ZSTD_compressEnd (job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize) :
+ ZSTD_compressContinue(job->cctx, dstBuff.start, dstBuff.size, src, job->srcSize);
+ DEBUGLOG(3, "compressed %u bytes into %u bytes (first:%u) (last:%u)",
+ (unsigned)job->srcSize, (unsigned)job->cSize, job->firstChunk, job->lastChunk);
+ DEBUGLOG(5, "dstBuff.size : %u ; => %s", (U32)dstBuff.size, ZSTD_getErrorName(job->cSize));
+
+_endJob:
+ PTHREAD_MUTEX_LOCK(job->jobCompleted_mutex);
+ job->jobCompleted = 1;
+ job->jobScanned = 0;
+ pthread_cond_signal(job->jobCompleted_cond);
+ pthread_mutex_unlock(job->jobCompleted_mutex);
+}
+
+
+/* ------------------------------------------ */
+/* ===== Multi-threaded compression ===== */
+/* ------------------------------------------ */
+
+struct ZSTDMT_CCtx_s {
+ POOL_ctx* factory;
+ ZSTDMT_bufferPool* buffPool;
+ ZSTDMT_CCtxPool* cctxPool;
+ pthread_mutex_t jobCompleted_mutex;
+ pthread_cond_t jobCompleted_cond;
+ size_t targetSectionSize;
+ size_t marginSize;
+ size_t inBuffSize;
+ size_t dictSize;
+ size_t targetDictSize;
+ inBuff_t inBuff;
+ ZSTD_parameters params;
+ XXH64_state_t xxhState;
+ unsigned nbThreads;
+ unsigned jobIDMask;
+ unsigned doneJobID;
+ unsigned nextJobID;
+ unsigned frameEnded;
+ unsigned allJobsCompleted;
+ unsigned overlapRLog;
+ unsigned long long frameContentSize;
+ size_t sectionSize;
+ ZSTD_CDict* cdict;
+ ZSTD_CStream* cstream;
+ ZSTDMT_jobDescription jobs[1]; /* variable size (must lies at the end) */
+};
+
+ZSTDMT_CCtx *ZSTDMT_createCCtx(unsigned nbThreads)
+{
+ ZSTDMT_CCtx* cctx;
+ U32 const minNbJobs = nbThreads + 2;
+ U32 const nbJobsLog2 = ZSTD_highbit32(minNbJobs) + 1;
+ U32 const nbJobs = 1 << nbJobsLog2;
+ DEBUGLOG(5, "nbThreads : %u ; minNbJobs : %u ; nbJobsLog2 : %u ; nbJobs : %u \n",
+ nbThreads, minNbJobs, nbJobsLog2, nbJobs);
+ if ((nbThreads < 1) | (nbThreads > ZSTDMT_NBTHREADS_MAX)) return NULL;
+ cctx = (ZSTDMT_CCtx*) calloc(1, sizeof(ZSTDMT_CCtx) + nbJobs*sizeof(ZSTDMT_jobDescription));
+ if (!cctx) return NULL;
+ cctx->nbThreads = nbThreads;
+ cctx->jobIDMask = nbJobs - 1;
+ cctx->allJobsCompleted = 1;
+ cctx->sectionSize = 0;
+ cctx->overlapRLog = 3;
+ cctx->factory = POOL_create(nbThreads, 1);
+ cctx->buffPool = ZSTDMT_createBufferPool(nbThreads);
+ cctx->cctxPool = ZSTDMT_createCCtxPool(nbThreads);
+ if (!cctx->factory | !cctx->buffPool | !cctx->cctxPool) { /* one object was not created */
+ ZSTDMT_freeCCtx(cctx);
+ return NULL;
+ }
+ if (nbThreads==1) {
+ cctx->cstream = ZSTD_createCStream();
+ if (!cctx->cstream) {
+ ZSTDMT_freeCCtx(cctx); return NULL;
+ } }
+ pthread_mutex_init(&cctx->jobCompleted_mutex, NULL); /* Todo : check init function return */
+ pthread_cond_init(&cctx->jobCompleted_cond, NULL);
+ DEBUGLOG(4, "mt_cctx created, for %u threads \n", nbThreads);
+ return cctx;
+}
+
+/* ZSTDMT_releaseAllJobResources() :
+ * Ensure all workers are killed first. */
+static void ZSTDMT_releaseAllJobResources(ZSTDMT_CCtx* mtctx)
+{
+ unsigned jobID;
+ for (jobID=0; jobID <= mtctx->jobIDMask; jobID++) {
+ ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[jobID].dstBuff);
+ mtctx->jobs[jobID].dstBuff = g_nullBuffer;
+ ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[jobID].src);
+ mtctx->jobs[jobID].src = g_nullBuffer;
+ ZSTDMT_releaseCCtx(mtctx->cctxPool, mtctx->jobs[jobID].cctx);
+ mtctx->jobs[jobID].cctx = NULL;
+ }
+ memset(mtctx->jobs, 0, (mtctx->jobIDMask+1)*sizeof(ZSTDMT_jobDescription));
+ ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->inBuff.buffer);
+ mtctx->inBuff.buffer = g_nullBuffer;
+ mtctx->allJobsCompleted = 1;
+}
+
+size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* mtctx)
+{
+ if (mtctx==NULL) return 0; /* compatible with free on NULL */
+ POOL_free(mtctx->factory);
+ if (!mtctx->allJobsCompleted) ZSTDMT_releaseAllJobResources(mtctx); /* stop workers first */
+ ZSTDMT_freeBufferPool(mtctx->buffPool); /* release job resources into pools first */
+ ZSTDMT_freeCCtxPool(mtctx->cctxPool);
+ ZSTD_freeCDict(mtctx->cdict);
+ ZSTD_freeCStream(mtctx->cstream);
+ pthread_mutex_destroy(&mtctx->jobCompleted_mutex);
+ pthread_cond_destroy(&mtctx->jobCompleted_cond);
+ free(mtctx);
+ return 0;
+}
+
+size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value)
+{
+ switch(parameter)
+ {
+ case ZSTDMT_p_sectionSize :
+ mtctx->sectionSize = value;
+ return 0;
+ case ZSTDMT_p_overlapSectionLog :
+ DEBUGLOG(4, "ZSTDMT_p_overlapSectionLog : %u", value);
+ mtctx->overlapRLog = (value >= 9) ? 0 : 9 - value;
+ return 0;
+ default :
+ return ERROR(compressionParameter_unsupported);
+ }
+}
+
+
+/* ------------------------------------------ */
+/* ===== Multi-threaded compression ===== */
+/* ------------------------------------------ */
+
+size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* mtctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ int compressionLevel)
+{
+ ZSTD_parameters params = ZSTD_getParams(compressionLevel, srcSize, 0);
+ U32 const overlapLog = (compressionLevel >= ZSTD_maxCLevel()) ? 0 : 3;
+ size_t const overlapSize = (size_t)1 << (params.cParams.windowLog - overlapLog);
+ size_t const chunkTargetSize = (size_t)1 << (params.cParams.windowLog + 2);
+ unsigned const nbChunksMax = (unsigned)(srcSize / chunkTargetSize) + 1;
+ unsigned nbChunks = MIN(nbChunksMax, mtctx->nbThreads);
+ size_t const proposedChunkSize = (srcSize + (nbChunks-1)) / nbChunks;
+ size_t const avgChunkSize = ((proposedChunkSize & 0x1FFFF) < 0xFFFF) ? proposedChunkSize + 0xFFFF : proposedChunkSize; /* avoid too small last block */
+ size_t remainingSrcSize = srcSize;
+ const char* const srcStart = (const char*)src;
+ unsigned const compressWithinDst = (dstCapacity >= ZSTD_compressBound(srcSize)) ? nbChunks : (unsigned)(dstCapacity / ZSTD_compressBound(avgChunkSize)); /* presumes avgChunkSize >= 256 KB, which should be the case */
+ size_t frameStartPos = 0, dstBufferPos = 0;
+
+ DEBUGLOG(3, "windowLog : %2u => chunkTargetSize : %u bytes ", params.cParams.windowLog, (U32)chunkTargetSize);
+ DEBUGLOG(2, "nbChunks : %2u (chunkSize : %u bytes) ", nbChunks, (U32)avgChunkSize);
+ params.fParams.contentSizeFlag = 1;
+
+ if (nbChunks==1) { /* fallback to single-thread mode */
+ ZSTD_CCtx* const cctx = mtctx->cctxPool->cctx[0];
+ return ZSTD_compressCCtx(cctx, dst, dstCapacity, src, srcSize, compressionLevel);
+ }
+
+ { unsigned u;
+ for (u=0; u<nbChunks; u++) {
+ size_t const chunkSize = MIN(remainingSrcSize, avgChunkSize);
+ size_t const dstBufferCapacity = ZSTD_compressBound(chunkSize);
+ buffer_t const dstAsBuffer = { (char*)dst + dstBufferPos, dstBufferCapacity };
+ buffer_t const dstBuffer = u < compressWithinDst ? dstAsBuffer : ZSTDMT_getBuffer(mtctx->buffPool, dstBufferCapacity);
+ ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(mtctx->cctxPool);
+ size_t dictSize = u ? overlapSize : 0;
+
+ if ((cctx==NULL) || (dstBuffer.start==NULL)) {
+ mtctx->jobs[u].cSize = ERROR(memory_allocation); /* job result */
+ mtctx->jobs[u].jobCompleted = 1;
+ nbChunks = u+1;
+ break; /* let's wait for previous jobs to complete, but don't start new ones */
+ }
+
+ mtctx->jobs[u].srcStart = srcStart + frameStartPos - dictSize;
+ mtctx->jobs[u].dictSize = dictSize;
+ mtctx->jobs[u].srcSize = chunkSize;
+ mtctx->jobs[u].fullFrameSize = srcSize;
+ mtctx->jobs[u].params = params;
+ mtctx->jobs[u].dstBuff = dstBuffer;
+ mtctx->jobs[u].cctx = cctx;
+ mtctx->jobs[u].firstChunk = (u==0);
+ mtctx->jobs[u].lastChunk = (u==nbChunks-1);
+ mtctx->jobs[u].jobCompleted = 0;
+ mtctx->jobs[u].jobCompleted_mutex = &mtctx->jobCompleted_mutex;
+ mtctx->jobs[u].jobCompleted_cond = &mtctx->jobCompleted_cond;
+
+ DEBUGLOG(3, "posting job %u (%u bytes)", u, (U32)chunkSize);
+ DEBUG_PRINTHEX(3, mtctx->jobs[u].srcStart, 12);
+ POOL_add(mtctx->factory, ZSTDMT_compressChunk, &mtctx->jobs[u]);
+
+ frameStartPos += chunkSize;
+ dstBufferPos += dstBufferCapacity;
+ remainingSrcSize -= chunkSize;
+ } }
+ /* note : since nbChunks <= nbThreads, all jobs should be running immediately in parallel */
+
+ { unsigned chunkID;
+ size_t error = 0, dstPos = 0;
+ for (chunkID=0; chunkID<nbChunks; chunkID++) {
+ DEBUGLOG(3, "waiting for chunk %u ", chunkID);
+ PTHREAD_MUTEX_LOCK(&mtctx->jobCompleted_mutex);
+ while (mtctx->jobs[chunkID].jobCompleted==0) {
+ DEBUGLOG(4, "waiting for jobCompleted signal from chunk %u", chunkID);
+ pthread_cond_wait(&mtctx->jobCompleted_cond, &mtctx->jobCompleted_mutex);
+ }
+ pthread_mutex_unlock(&mtctx->jobCompleted_mutex);
+ DEBUGLOG(3, "ready to write chunk %u ", chunkID);
+
+ ZSTDMT_releaseCCtx(mtctx->cctxPool, mtctx->jobs[chunkID].cctx);
+ mtctx->jobs[chunkID].cctx = NULL;
+ mtctx->jobs[chunkID].srcStart = NULL;
+ { size_t const cSize = mtctx->jobs[chunkID].cSize;
+ if (ZSTD_isError(cSize)) error = cSize;
+ if ((!error) && (dstPos + cSize > dstCapacity)) error = ERROR(dstSize_tooSmall);
+ if (chunkID) { /* note : chunk 0 is already written directly into dst */
+ if (!error)
+ memmove((char*)dst + dstPos, mtctx->jobs[chunkID].dstBuff.start, cSize); /* may overlap if chunk decompressed within dst */
+ if (chunkID >= compressWithinDst) /* otherwise, it decompresses within dst */
+ ZSTDMT_releaseBuffer(mtctx->buffPool, mtctx->jobs[chunkID].dstBuff);
+ mtctx->jobs[chunkID].dstBuff = g_nullBuffer;
+ }
+ dstPos += cSize ;
+ }
+ }
+ if (!error) DEBUGLOG(3, "compressed size : %u ", (U32)dstPos);
+ return error ? error : dstPos;
+ }
+
+}
+
+
+/* ====================================== */
+/* ======= Streaming API ======= */
+/* ====================================== */
+
+static void ZSTDMT_waitForAllJobsCompleted(ZSTDMT_CCtx* zcs) {
+ while (zcs->doneJobID < zcs->nextJobID) {
+ unsigned const jobID = zcs->doneJobID & zcs->jobIDMask;
+ PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex);
+ while (zcs->jobs[jobID].jobCompleted==0) {
+ DEBUGLOG(4, "waiting for jobCompleted signal from chunk %u", zcs->doneJobID); /* we want to block when waiting for data to flush */
+ pthread_cond_wait(&zcs->jobCompleted_cond, &zcs->jobCompleted_mutex);
+ }
+ pthread_mutex_unlock(&zcs->jobCompleted_mutex);
+ zcs->doneJobID++;
+ }
+}
+
+
+static size_t ZSTDMT_initCStream_internal(ZSTDMT_CCtx* zcs,
+ const void* dict, size_t dictSize, unsigned updateDict,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ ZSTD_customMem const cmem = { NULL, NULL, NULL };
+ DEBUGLOG(3, "Started new compression, with windowLog : %u", params.cParams.windowLog);
+ if (zcs->nbThreads==1) return ZSTD_initCStream_advanced(zcs->cstream, dict, dictSize, params, pledgedSrcSize);
+ if (zcs->allJobsCompleted == 0) { /* previous job not correctly finished */
+ ZSTDMT_waitForAllJobsCompleted(zcs);
+ ZSTDMT_releaseAllJobResources(zcs);
+ zcs->allJobsCompleted = 1;
+ }
+ zcs->params = params;
+ if (updateDict) {
+ ZSTD_freeCDict(zcs->cdict); zcs->cdict = NULL;
+ if (dict && dictSize) {
+ zcs->cdict = ZSTD_createCDict_advanced(dict, dictSize, 0, params.cParams, cmem);
+ if (zcs->cdict == NULL) return ERROR(memory_allocation);
+ } }
+ zcs->frameContentSize = pledgedSrcSize;
+ zcs->targetDictSize = (zcs->overlapRLog>=9) ? 0 : (size_t)1 << (zcs->params.cParams.windowLog - zcs->overlapRLog);
+ DEBUGLOG(4, "overlapRLog : %u ", zcs->overlapRLog);
+ DEBUGLOG(3, "overlap Size : %u KB", (U32)(zcs->targetDictSize>>10));
+ zcs->targetSectionSize = zcs->sectionSize ? zcs->sectionSize : (size_t)1 << (zcs->params.cParams.windowLog + 2);
+ zcs->targetSectionSize = MAX(ZSTDMT_SECTION_SIZE_MIN, zcs->targetSectionSize);
+ zcs->targetSectionSize = MAX(zcs->targetDictSize, zcs->targetSectionSize);
+ DEBUGLOG(3, "Section Size : %u KB", (U32)(zcs->targetSectionSize>>10));
+ zcs->marginSize = zcs->targetSectionSize >> 2;
+ zcs->inBuffSize = zcs->targetDictSize + zcs->targetSectionSize + zcs->marginSize;
+ zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize);
+ if (zcs->inBuff.buffer.start == NULL) return ERROR(memory_allocation);
+ zcs->inBuff.filled = 0;
+ zcs->dictSize = 0;
+ zcs->doneJobID = 0;
+ zcs->nextJobID = 0;
+ zcs->frameEnded = 0;
+ zcs->allJobsCompleted = 0;
+ if (params.fParams.checksumFlag) XXH64_reset(&zcs->xxhState, 0);
+ return 0;
+}
+
+size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* zcs,
+ const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize)
+{
+ return ZSTDMT_initCStream_internal(zcs, dict, dictSize, 1, params, pledgedSrcSize);
+}
+
+/* ZSTDMT_resetCStream() :
+ * pledgedSrcSize is optional and can be zero == unknown */
+size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* zcs, unsigned long long pledgedSrcSize)
+{
+ if (zcs->nbThreads==1) return ZSTD_resetCStream(zcs->cstream, pledgedSrcSize);
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, 0, zcs->params, pledgedSrcSize);
+}
+
+size_t ZSTDMT_initCStream(ZSTDMT_CCtx* zcs, int compressionLevel) {
+ ZSTD_parameters const params = ZSTD_getParams(compressionLevel, 0, 0);
+ return ZSTDMT_initCStream_internal(zcs, NULL, 0, 1, params, 0);
+}
+
+
+static size_t ZSTDMT_createCompressionJob(ZSTDMT_CCtx* zcs, size_t srcSize, unsigned endFrame)
+{
+ size_t const dstBufferCapacity = ZSTD_compressBound(srcSize);
+ buffer_t const dstBuffer = ZSTDMT_getBuffer(zcs->buffPool, dstBufferCapacity);
+ ZSTD_CCtx* const cctx = ZSTDMT_getCCtx(zcs->cctxPool);
+ unsigned const jobID = zcs->nextJobID & zcs->jobIDMask;
+
+ if ((cctx==NULL) || (dstBuffer.start==NULL)) {
+ zcs->jobs[jobID].jobCompleted = 1;
+ zcs->nextJobID++;
+ ZSTDMT_waitForAllJobsCompleted(zcs);
+ ZSTDMT_releaseAllJobResources(zcs);
+ return ERROR(memory_allocation);
+ }
+
+ DEBUGLOG(4, "preparing job %u to compress %u bytes with %u preload ", zcs->nextJobID, (U32)srcSize, (U32)zcs->dictSize);
+ zcs->jobs[jobID].src = zcs->inBuff.buffer;
+ zcs->jobs[jobID].srcStart = zcs->inBuff.buffer.start;
+ zcs->jobs[jobID].srcSize = srcSize;
+ zcs->jobs[jobID].dictSize = zcs->dictSize; /* note : zcs->inBuff.filled is presumed >= srcSize + dictSize */
+ zcs->jobs[jobID].params = zcs->params;
+ if (zcs->nextJobID) zcs->jobs[jobID].params.fParams.checksumFlag = 0; /* do not calculate checksum within sections, just keep it in header for first section */
+ zcs->jobs[jobID].cdict = zcs->nextJobID==0 ? zcs->cdict : NULL;
+ zcs->jobs[jobID].fullFrameSize = zcs->frameContentSize;
+ zcs->jobs[jobID].dstBuff = dstBuffer;
+ zcs->jobs[jobID].cctx = cctx;
+ zcs->jobs[jobID].firstChunk = (zcs->nextJobID==0);
+ zcs->jobs[jobID].lastChunk = endFrame;
+ zcs->jobs[jobID].jobCompleted = 0;
+ zcs->jobs[jobID].dstFlushed = 0;
+ zcs->jobs[jobID].jobCompleted_mutex = &zcs->jobCompleted_mutex;
+ zcs->jobs[jobID].jobCompleted_cond = &zcs->jobCompleted_cond;
+
+ /* get a new buffer for next input */
+ if (!endFrame) {
+ size_t const newDictSize = MIN(srcSize + zcs->dictSize, zcs->targetDictSize);
+ zcs->inBuff.buffer = ZSTDMT_getBuffer(zcs->buffPool, zcs->inBuffSize);
+ if (zcs->inBuff.buffer.start == NULL) { /* not enough memory to allocate next input buffer */
+ zcs->jobs[jobID].jobCompleted = 1;
+ zcs->nextJobID++;
+ ZSTDMT_waitForAllJobsCompleted(zcs);
+ ZSTDMT_releaseAllJobResources(zcs);
+ return ERROR(memory_allocation);
+ }
+ DEBUGLOG(5, "inBuff filled to %u", (U32)zcs->inBuff.filled);
+ zcs->inBuff.filled -= srcSize + zcs->dictSize - newDictSize;
+ DEBUGLOG(5, "new job : filled to %u, with %u dict and %u src", (U32)zcs->inBuff.filled, (U32)newDictSize, (U32)(zcs->inBuff.filled - newDictSize));
+ memmove(zcs->inBuff.buffer.start, (const char*)zcs->jobs[jobID].srcStart + zcs->dictSize + srcSize - newDictSize, zcs->inBuff.filled);
+ DEBUGLOG(5, "new inBuff pre-filled");
+ zcs->dictSize = newDictSize;
+ } else {
+ zcs->inBuff.buffer = g_nullBuffer;
+ zcs->inBuff.filled = 0;
+ zcs->dictSize = 0;
+ zcs->frameEnded = 1;
+ if (zcs->nextJobID == 0)
+ zcs->params.fParams.checksumFlag = 0; /* single chunk : checksum is calculated directly within worker thread */
+ }
+
+ DEBUGLOG(3, "posting job %u : %u bytes (end:%u) (note : doneJob = %u=>%u)", zcs->nextJobID, (U32)zcs->jobs[jobID].srcSize, zcs->jobs[jobID].lastChunk, zcs->doneJobID, zcs->doneJobID & zcs->jobIDMask);
+ POOL_add(zcs->factory, ZSTDMT_compressChunk, &zcs->jobs[jobID]); /* this call is blocking when thread worker pool is exhausted */
+ zcs->nextJobID++;
+ return 0;
+}
+
+
+/* ZSTDMT_flushNextJob() :
+ * output : will be updated with amount of data flushed .
+ * blockToFlush : if >0, the function will block and wait if there is no data available to flush .
+ * @return : amount of data remaining within internal buffer, 1 if unknown but > 0, 0 if no more, or an error code */
+static size_t ZSTDMT_flushNextJob(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsigned blockToFlush)
+{
+ unsigned const wJobID = zcs->doneJobID & zcs->jobIDMask;
+ if (zcs->doneJobID == zcs->nextJobID) return 0; /* all flushed ! */
+ PTHREAD_MUTEX_LOCK(&zcs->jobCompleted_mutex);
+ while (zcs->jobs[wJobID].jobCompleted==0) {
+ DEBUGLOG(5, "waiting for jobCompleted signal from job %u", zcs->doneJobID);
+ if (!blockToFlush) { pthread_mutex_unlock(&zcs->jobCompleted_mutex); return 0; } /* nothing ready to be flushed => skip */
+ pthread_cond_wait(&zcs->jobCompleted_cond, &zcs->jobCompleted_mutex); /* block when nothing available to flush */
+ }
+ pthread_mutex_unlock(&zcs->jobCompleted_mutex);
+ /* compression job completed : output can be flushed */
+ { ZSTDMT_jobDescription job = zcs->jobs[wJobID];
+ if (!job.jobScanned) {
+ if (ZSTD_isError(job.cSize)) {
+ DEBUGLOG(5, "compression error detected ");
+ ZSTDMT_waitForAllJobsCompleted(zcs);
+ ZSTDMT_releaseAllJobResources(zcs);
+ return job.cSize;
+ }
+ ZSTDMT_releaseCCtx(zcs->cctxPool, job.cctx);
+ zcs->jobs[wJobID].cctx = NULL;
+ DEBUGLOG(5, "zcs->params.fParams.checksumFlag : %u ", zcs->params.fParams.checksumFlag);
+ if (zcs->params.fParams.checksumFlag) {
+ XXH64_update(&zcs->xxhState, (const char*)job.srcStart + job.dictSize, job.srcSize);
+ if (zcs->frameEnded && (zcs->doneJobID+1 == zcs->nextJobID)) { /* write checksum at end of last section */
+ U32 const checksum = (U32)XXH64_digest(&zcs->xxhState);
+ DEBUGLOG(4, "writing checksum : %08X \n", checksum);
+ MEM_writeLE32((char*)job.dstBuff.start + job.cSize, checksum);
+ job.cSize += 4;
+ zcs->jobs[wJobID].cSize += 4;
+ } }
+ ZSTDMT_releaseBuffer(zcs->buffPool, job.src);
+ zcs->jobs[wJobID].srcStart = NULL;
+ zcs->jobs[wJobID].src = g_nullBuffer;
+ zcs->jobs[wJobID].jobScanned = 1;
+ }
+ { size_t const toWrite = MIN(job.cSize - job.dstFlushed, output->size - output->pos);
+ DEBUGLOG(4, "Flushing %u bytes from job %u ", (U32)toWrite, zcs->doneJobID);
+ memcpy((char*)output->dst + output->pos, (const char*)job.dstBuff.start + job.dstFlushed, toWrite);
+ output->pos += toWrite;
+ job.dstFlushed += toWrite;
+ }
+ if (job.dstFlushed == job.cSize) { /* output buffer fully flushed => move to next one */
+ ZSTDMT_releaseBuffer(zcs->buffPool, job.dstBuff);
+ zcs->jobs[wJobID].dstBuff = g_nullBuffer;
+ zcs->jobs[wJobID].jobCompleted = 0;
+ zcs->doneJobID++;
+ } else {
+ zcs->jobs[wJobID].dstFlushed = job.dstFlushed;
+ }
+ /* return value : how many bytes left in buffer ; fake it to 1 if unknown but >0 */
+ if (job.cSize > job.dstFlushed) return (job.cSize - job.dstFlushed);
+ if (zcs->doneJobID < zcs->nextJobID) return 1; /* still some buffer to flush */
+ zcs->allJobsCompleted = zcs->frameEnded; /* frame completed and entirely flushed */
+ return 0; /* everything flushed */
+} }
+
+
+size_t ZSTDMT_compressStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
+{
+ size_t const newJobThreshold = zcs->dictSize + zcs->targetSectionSize + zcs->marginSize;
+ if (zcs->frameEnded) return ERROR(stage_wrong); /* current frame being ended. Only flush is allowed. Restart with init */
+ if (zcs->nbThreads==1) return ZSTD_compressStream(zcs->cstream, output, input);
+
+ /* fill input buffer */
+ { size_t const toLoad = MIN(input->size - input->pos, zcs->inBuffSize - zcs->inBuff.filled);
+ memcpy((char*)zcs->inBuff.buffer.start + zcs->inBuff.filled, input->src, toLoad);
+ input->pos += toLoad;
+ zcs->inBuff.filled += toLoad;
+ }
+
+ if ( (zcs->inBuff.filled >= newJobThreshold) /* filled enough : let's compress */
+ && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) { /* avoid overwriting job round buffer */
+ CHECK_F( ZSTDMT_createCompressionJob(zcs, zcs->targetSectionSize, 0) );
+ }
+
+ /* check for data to flush */
+ CHECK_F( ZSTDMT_flushNextJob(zcs, output, (zcs->inBuff.filled == zcs->inBuffSize)) ); /* block if it wasn't possible to create new job due to saturation */
+
+ /* recommended next input size : fill current input buffer */
+ return zcs->inBuffSize - zcs->inBuff.filled; /* note : could be zero when input buffer is fully filled and no more availability to create new job */
+}
+
+
+static size_t ZSTDMT_flushStream_internal(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output, unsigned endFrame)
+{
+ size_t const srcSize = zcs->inBuff.filled - zcs->dictSize;
+
+ if (srcSize) DEBUGLOG(4, "flushing : %u bytes left to compress", (U32)srcSize);
+ if ( ((srcSize > 0) || (endFrame && !zcs->frameEnded))
+ && (zcs->nextJobID <= zcs->doneJobID + zcs->jobIDMask) ) {
+ CHECK_F( ZSTDMT_createCompressionJob(zcs, srcSize, endFrame) );
+ }
+
+ /* check if there is any data available to flush */
+ DEBUGLOG(5, "zcs->doneJobID : %u ; zcs->nextJobID : %u ", zcs->doneJobID, zcs->nextJobID);
+ return ZSTDMT_flushNextJob(zcs, output, 1);
+}
+
+
+size_t ZSTDMT_flushStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
+{
+ if (zcs->nbThreads==1) return ZSTD_flushStream(zcs->cstream, output);
+ return ZSTDMT_flushStream_internal(zcs, output, 0);
+}
+
+size_t ZSTDMT_endStream(ZSTDMT_CCtx* zcs, ZSTD_outBuffer* output)
+{
+ if (zcs->nbThreads==1) return ZSTD_endStream(zcs->cstream, output);
+ return ZSTDMT_flushStream_internal(zcs, output, 1);
+}
diff --git a/thirdparty/zstd/compress/zstdmt_compress.h b/thirdparty/zstd/compress/zstdmt_compress.h
new file mode 100644
index 0000000000..27f78ee031
--- /dev/null
+++ b/thirdparty/zstd/compress/zstdmt_compress.h
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+ #ifndef ZSTDMT_COMPRESS_H
+ #define ZSTDMT_COMPRESS_H
+
+ #if defined (__cplusplus)
+ extern "C" {
+ #endif
+
+
+/* Note : All prototypes defined in this file shall be considered experimental.
+ * There is no guarantee of API continuity (yet) on any of these prototypes */
+
+/* === Dependencies === */
+#include <stddef.h> /* size_t */
+#define ZSTD_STATIC_LINKING_ONLY /* ZSTD_parameters */
+#include "zstd.h" /* ZSTD_inBuffer, ZSTD_outBuffer, ZSTDLIB_API */
+
+
+/* === Simple one-pass functions === */
+
+typedef struct ZSTDMT_CCtx_s ZSTDMT_CCtx;
+ZSTDLIB_API ZSTDMT_CCtx* ZSTDMT_createCCtx(unsigned nbThreads);
+ZSTDLIB_API size_t ZSTDMT_freeCCtx(ZSTDMT_CCtx* cctx);
+
+ZSTDLIB_API size_t ZSTDMT_compressCCtx(ZSTDMT_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ int compressionLevel);
+
+
+/* === Streaming functions === */
+
+ZSTDLIB_API size_t ZSTDMT_initCStream(ZSTDMT_CCtx* mtctx, int compressionLevel);
+ZSTDLIB_API size_t ZSTDMT_resetCStream(ZSTDMT_CCtx* mtctx, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be zero == unknown */
+
+ZSTDLIB_API size_t ZSTDMT_compressStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+
+ZSTDLIB_API size_t ZSTDMT_flushStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
+ZSTDLIB_API size_t ZSTDMT_endStream(ZSTDMT_CCtx* mtctx, ZSTD_outBuffer* output); /**< @return : 0 == all flushed; >0 : still some data to be flushed; or an error code (ZSTD_isError()) */
+
+
+/* === Advanced functions and parameters === */
+
+#ifndef ZSTDMT_SECTION_SIZE_MIN
+# define ZSTDMT_SECTION_SIZE_MIN (1U << 20) /* 1 MB - Minimum size of each compression job */
+#endif
+
+ZSTDLIB_API size_t ZSTDMT_initCStream_advanced(ZSTDMT_CCtx* mtctx, const void* dict, size_t dictSize, /**< dict can be released after init, a local copy is preserved within zcs */
+ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be zero == unknown */
+
+/* ZSDTMT_parameter :
+ * List of parameters that can be set using ZSTDMT_setMTCtxParameter() */
+typedef enum {
+ ZSTDMT_p_sectionSize, /* size of input "section". Each section is compressed in parallel. 0 means default, which is dynamically determined within compression functions */
+ ZSTDMT_p_overlapSectionLog /* Log of overlapped section; 0 == no overlap, 6(default) == use 1/8th of window, >=9 == use full window */
+} ZSDTMT_parameter;
+
+/* ZSTDMT_setMTCtxParameter() :
+ * allow setting individual parameters, one at a time, among a list of enums defined in ZSTDMT_parameter.
+ * The function must be called typically after ZSTD_createCCtx().
+ * Parameters not explicitly reset by ZSTDMT_init*() remain the same in consecutive compression sessions.
+ * @return : 0, or an error code (which can be tested using ZSTD_isError()) */
+ZSTDLIB_API size_t ZSTDMT_setMTCtxParameter(ZSTDMT_CCtx* mtctx, ZSDTMT_parameter parameter, unsigned value);
+
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* ZSTDMT_COMPRESS_H */
diff --git a/thirdparty/zstd/decompress/huf_decompress.c b/thirdparty/zstd/decompress/huf_decompress.c
new file mode 100644
index 0000000000..ea35c36201
--- /dev/null
+++ b/thirdparty/zstd/decompress/huf_decompress.c
@@ -0,0 +1,888 @@
+/* ******************************************************************
+ Huffman decoder, part of New Generation Entropy library
+ Copyright (C) 2013-2016, Yann Collet.
+
+ BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following disclaimer
+ in the documentation and/or other materials provided with the
+ distribution.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+ You can contact the author at :
+ - FSE+HUF source repository : https://github.com/Cyan4973/FiniteStateEntropy
+ - Public forum : https://groups.google.com/forum/#!forum/lz4c
+****************************************************************** */
+
+/* **************************************************************
+* Compiler specifics
+****************************************************************/
+#ifdef _MSC_VER /* Visual Studio */
+# define FORCE_INLINE static __forceinline
+# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
+#else
+# if defined (__cplusplus) || defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
+# ifdef __GNUC__
+# define FORCE_INLINE static inline __attribute__((always_inline))
+# else
+# define FORCE_INLINE static inline
+# endif
+# else
+# define FORCE_INLINE static
+# endif /* __STDC_VERSION__ */
+#endif
+
+
+/* **************************************************************
+* Dependencies
+****************************************************************/
+#include <string.h> /* memcpy, memset */
+#include "bitstream.h" /* BIT_* */
+#include "fse.h" /* header compression */
+#define HUF_STATIC_LINKING_ONLY
+#include "huf.h"
+
+
+/* **************************************************************
+* Error Management
+****************************************************************/
+#define HUF_STATIC_ASSERT(c) { enum { HUF_static_assert = 1/(int)(!!(c)) }; } /* use only *after* variable declarations */
+
+
+/*-***************************/
+/* generic DTableDesc */
+/*-***************************/
+
+typedef struct { BYTE maxTableLog; BYTE tableType; BYTE tableLog; BYTE reserved; } DTableDesc;
+
+static DTableDesc HUF_getDTableDesc(const HUF_DTable* table)
+{
+ DTableDesc dtd;
+ memcpy(&dtd, table, sizeof(dtd));
+ return dtd;
+}
+
+
+/*-***************************/
+/* single-symbol decoding */
+/*-***************************/
+
+typedef struct { BYTE byte; BYTE nbBits; } HUF_DEltX2; /* single-symbol decoding */
+
+size_t HUF_readDTableX2 (HUF_DTable* DTable, const void* src, size_t srcSize)
+{
+ BYTE huffWeight[HUF_SYMBOLVALUE_MAX + 1];
+ U32 rankVal[HUF_TABLELOG_ABSOLUTEMAX + 1]; /* large enough for values from 0 to 16 */
+ U32 tableLog = 0;
+ U32 nbSymbols = 0;
+ size_t iSize;
+ void* const dtPtr = DTable + 1;
+ HUF_DEltX2* const dt = (HUF_DEltX2*)dtPtr;
+
+ HUF_STATIC_ASSERT(sizeof(DTableDesc) == sizeof(HUF_DTable));
+ /* memset(huffWeight, 0, sizeof(huffWeight)); */ /* is not necessary, even though some analyzer complain ... */
+
+ iSize = HUF_readStats(huffWeight, HUF_SYMBOLVALUE_MAX + 1, rankVal, &nbSymbols, &tableLog, src, srcSize);
+ if (HUF_isError(iSize)) return iSize;
+
+ /* Table header */
+ { DTableDesc dtd = HUF_getDTableDesc(DTable);
+ if (tableLog > (U32)(dtd.maxTableLog+1)) return ERROR(tableLog_tooLarge); /* DTable too small, Huffman tree cannot fit in */
+ dtd.tableType = 0;
+ dtd.tableLog = (BYTE)tableLog;
+ memcpy(DTable, &dtd, sizeof(dtd));
+ }
+
+ /* Calculate starting value for each rank */
+ { U32 n, nextRankStart = 0;
+ for (n=1; n<tableLog+1; n++) {
+ U32 const current = nextRankStart;
+ nextRankStart += (rankVal[n] << (n-1));
+ rankVal[n] = current;
+ } }
+
+ /* fill DTable */
+ { U32 n;
+ for (n=0; n<nbSymbols; n++) {
+ U32 const w = huffWeight[n];
+ U32 const length = (1 << w) >> 1;
+ U32 u;
+ HUF_DEltX2 D;
+ D.byte = (BYTE)n; D.nbBits = (BYTE)(tableLog + 1 - w);
+ for (u = rankVal[w]; u < rankVal[w] + length; u++)
+ dt[u] = D;
+ rankVal[w] += length;
+ } }
+
+ return iSize;
+}
+
+
+static BYTE HUF_decodeSymbolX2(BIT_DStream_t* Dstream, const HUF_DEltX2* dt, const U32 dtLog)
+{
+ size_t const val = BIT_lookBitsFast(Dstream, dtLog); /* note : dtLog >= 1 */
+ BYTE const c = dt[val].byte;
+ BIT_skipBits(Dstream, dt[val].nbBits);
+ return c;
+}
+
+#define HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr) \
+ *ptr++ = HUF_decodeSymbolX2(DStreamPtr, dt, dtLog)
+
+#define HUF_DECODE_SYMBOLX2_1(ptr, DStreamPtr) \
+ if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
+ HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
+
+#define HUF_DECODE_SYMBOLX2_2(ptr, DStreamPtr) \
+ if (MEM_64bits()) \
+ HUF_DECODE_SYMBOLX2_0(ptr, DStreamPtr)
+
+FORCE_INLINE size_t HUF_decodeStreamX2(BYTE* p, BIT_DStream_t* const bitDPtr, BYTE* const pEnd, const HUF_DEltX2* const dt, const U32 dtLog)
+{
+ BYTE* const pStart = p;
+
+ /* up to 4 symbols at a time */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p <= pEnd-4)) {
+ HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_1(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+ }
+
+ /* closer to the end */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) && (p < pEnd))
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+
+ /* no more data to retrieve from bitstream, hence no need to reload */
+ while (p < pEnd)
+ HUF_DECODE_SYMBOLX2_0(p, bitDPtr);
+
+ return pEnd-pStart;
+}
+
+static size_t HUF_decompress1X2_usingDTable_internal(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ BYTE* op = (BYTE*)dst;
+ BYTE* const oend = op + dstSize;
+ const void* dtPtr = DTable + 1;
+ const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
+ BIT_DStream_t bitD;
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ U32 const dtLog = dtd.tableLog;
+
+ { size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
+ if (HUF_isError(errorCode)) return errorCode; }
+
+ HUF_decodeStreamX2(op, &bitD, oend, dt, dtLog);
+
+ /* check */
+ if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
+
+ return dstSize;
+}
+
+size_t HUF_decompress1X2_usingDTable(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ if (dtd.tableType != 0) return ERROR(GENERIC);
+ return HUF_decompress1X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+
+size_t HUF_decompress1X2_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ const BYTE* ip = (const BYTE*) cSrc;
+
+ size_t const hSize = HUF_readDTableX2 (DCtx, cSrc, cSrcSize);
+ if (HUF_isError(hSize)) return hSize;
+ if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
+ ip += hSize; cSrcSize -= hSize;
+
+ return HUF_decompress1X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
+}
+
+size_t HUF_decompress1X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress1X2_DCtx (DTable, dst, dstSize, cSrc, cSrcSize);
+}
+
+
+static size_t HUF_decompress4X2_usingDTable_internal(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ /* Check */
+ if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
+
+ { const BYTE* const istart = (const BYTE*) cSrc;
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* const oend = ostart + dstSize;
+ const void* const dtPtr = DTable + 1;
+ const HUF_DEltX2* const dt = (const HUF_DEltX2*)dtPtr;
+
+ /* Init */
+ BIT_DStream_t bitD1;
+ BIT_DStream_t bitD2;
+ BIT_DStream_t bitD3;
+ BIT_DStream_t bitD4;
+ size_t const length1 = MEM_readLE16(istart);
+ size_t const length2 = MEM_readLE16(istart+2);
+ size_t const length3 = MEM_readLE16(istart+4);
+ size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
+ const BYTE* const istart1 = istart + 6; /* jumpTable */
+ const BYTE* const istart2 = istart1 + length1;
+ const BYTE* const istart3 = istart2 + length2;
+ const BYTE* const istart4 = istart3 + length3;
+ const size_t segmentSize = (dstSize+3) / 4;
+ BYTE* const opStart2 = ostart + segmentSize;
+ BYTE* const opStart3 = opStart2 + segmentSize;
+ BYTE* const opStart4 = opStart3 + segmentSize;
+ BYTE* op1 = ostart;
+ BYTE* op2 = opStart2;
+ BYTE* op3 = opStart3;
+ BYTE* op4 = opStart4;
+ U32 endSignal;
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ U32 const dtLog = dtd.tableLog;
+
+ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
+ { size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
+ if (HUF_isError(errorCode)) return errorCode; }
+
+ /* 16-32 symbols per loop (4-8 symbols per stream) */
+ endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
+ for ( ; (endSignal==BIT_DStream_unfinished) && (op4<(oend-7)) ; ) {
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX2_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX2_0(op2, &bitD2);
+ HUF_DECODE_SYMBOLX2_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX2_0(op4, &bitD4);
+ endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
+ }
+
+ /* check corruption */
+ if (op1 > opStart2) return ERROR(corruption_detected);
+ if (op2 > opStart3) return ERROR(corruption_detected);
+ if (op3 > opStart4) return ERROR(corruption_detected);
+ /* note : op4 supposed already verified within main loop */
+
+ /* finish bitStreams one by one */
+ HUF_decodeStreamX2(op1, &bitD1, opStart2, dt, dtLog);
+ HUF_decodeStreamX2(op2, &bitD2, opStart3, dt, dtLog);
+ HUF_decodeStreamX2(op3, &bitD3, opStart4, dt, dtLog);
+ HUF_decodeStreamX2(op4, &bitD4, oend, dt, dtLog);
+
+ /* check */
+ endSignal = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
+ if (!endSignal) return ERROR(corruption_detected);
+
+ /* decoded size */
+ return dstSize;
+ }
+}
+
+
+size_t HUF_decompress4X2_usingDTable(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ if (dtd.tableType != 0) return ERROR(GENERIC);
+ return HUF_decompress4X2_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+
+
+size_t HUF_decompress4X2_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ const BYTE* ip = (const BYTE*) cSrc;
+
+ size_t const hSize = HUF_readDTableX2 (dctx, cSrc, cSrcSize);
+ if (HUF_isError(hSize)) return hSize;
+ if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
+ ip += hSize; cSrcSize -= hSize;
+
+ return HUF_decompress4X2_usingDTable_internal (dst, dstSize, ip, cSrcSize, dctx);
+}
+
+size_t HUF_decompress4X2 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX2(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress4X2_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+
+
+/* *************************/
+/* double-symbols decoding */
+/* *************************/
+typedef struct { U16 sequence; BYTE nbBits; BYTE length; } HUF_DEltX4; /* double-symbols decoding */
+
+typedef struct { BYTE symbol; BYTE weight; } sortedSymbol_t;
+
+/* HUF_fillDTableX4Level2() :
+ * `rankValOrigin` must be a table of at least (HUF_TABLELOG_MAX + 1) U32 */
+static void HUF_fillDTableX4Level2(HUF_DEltX4* DTable, U32 sizeLog, const U32 consumed,
+ const U32* rankValOrigin, const int minWeight,
+ const sortedSymbol_t* sortedSymbols, const U32 sortedListSize,
+ U32 nbBitsBaseline, U16 baseSeq)
+{
+ HUF_DEltX4 DElt;
+ U32 rankVal[HUF_TABLELOG_MAX + 1];
+
+ /* get pre-calculated rankVal */
+ memcpy(rankVal, rankValOrigin, sizeof(rankVal));
+
+ /* fill skipped values */
+ if (minWeight>1) {
+ U32 i, skipSize = rankVal[minWeight];
+ MEM_writeLE16(&(DElt.sequence), baseSeq);
+ DElt.nbBits = (BYTE)(consumed);
+ DElt.length = 1;
+ for (i = 0; i < skipSize; i++)
+ DTable[i] = DElt;
+ }
+
+ /* fill DTable */
+ { U32 s; for (s=0; s<sortedListSize; s++) { /* note : sortedSymbols already skipped */
+ const U32 symbol = sortedSymbols[s].symbol;
+ const U32 weight = sortedSymbols[s].weight;
+ const U32 nbBits = nbBitsBaseline - weight;
+ const U32 length = 1 << (sizeLog-nbBits);
+ const U32 start = rankVal[weight];
+ U32 i = start;
+ const U32 end = start + length;
+
+ MEM_writeLE16(&(DElt.sequence), (U16)(baseSeq + (symbol << 8)));
+ DElt.nbBits = (BYTE)(nbBits + consumed);
+ DElt.length = 2;
+ do { DTable[i++] = DElt; } while (i<end); /* since length >= 1 */
+
+ rankVal[weight] += length;
+ } }
+}
+
+typedef U32 rankVal_t[HUF_TABLELOG_MAX][HUF_TABLELOG_MAX + 1];
+
+static void HUF_fillDTableX4(HUF_DEltX4* DTable, const U32 targetLog,
+ const sortedSymbol_t* sortedList, const U32 sortedListSize,
+ const U32* rankStart, rankVal_t rankValOrigin, const U32 maxWeight,
+ const U32 nbBitsBaseline)
+{
+ U32 rankVal[HUF_TABLELOG_MAX + 1];
+ const int scaleLog = nbBitsBaseline - targetLog; /* note : targetLog >= srcLog, hence scaleLog <= 1 */
+ const U32 minBits = nbBitsBaseline - maxWeight;
+ U32 s;
+
+ memcpy(rankVal, rankValOrigin, sizeof(rankVal));
+
+ /* fill DTable */
+ for (s=0; s<sortedListSize; s++) {
+ const U16 symbol = sortedList[s].symbol;
+ const U32 weight = sortedList[s].weight;
+ const U32 nbBits = nbBitsBaseline - weight;
+ const U32 start = rankVal[weight];
+ const U32 length = 1 << (targetLog-nbBits);
+
+ if (targetLog-nbBits >= minBits) { /* enough room for a second symbol */
+ U32 sortedRank;
+ int minWeight = nbBits + scaleLog;
+ if (minWeight < 1) minWeight = 1;
+ sortedRank = rankStart[minWeight];
+ HUF_fillDTableX4Level2(DTable+start, targetLog-nbBits, nbBits,
+ rankValOrigin[nbBits], minWeight,
+ sortedList+sortedRank, sortedListSize-sortedRank,
+ nbBitsBaseline, symbol);
+ } else {
+ HUF_DEltX4 DElt;
+ MEM_writeLE16(&(DElt.sequence), symbol);
+ DElt.nbBits = (BYTE)(nbBits);
+ DElt.length = 1;
+ { U32 const end = start + length;
+ U32 u;
+ for (u = start; u < end; u++) DTable[u] = DElt;
+ } }
+ rankVal[weight] += length;
+ }
+}
+
+size_t HUF_readDTableX4 (HUF_DTable* DTable, const void* src, size_t srcSize)
+{
+ BYTE weightList[HUF_SYMBOLVALUE_MAX + 1];
+ sortedSymbol_t sortedSymbol[HUF_SYMBOLVALUE_MAX + 1];
+ U32 rankStats[HUF_TABLELOG_MAX + 1] = { 0 };
+ U32 rankStart0[HUF_TABLELOG_MAX + 2] = { 0 };
+ U32* const rankStart = rankStart0+1;
+ rankVal_t rankVal;
+ U32 tableLog, maxW, sizeOfSort, nbSymbols;
+ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ U32 const maxTableLog = dtd.maxTableLog;
+ size_t iSize;
+ void* dtPtr = DTable+1; /* force compiler to avoid strict-aliasing */
+ HUF_DEltX4* const dt = (HUF_DEltX4*)dtPtr;
+
+ HUF_STATIC_ASSERT(sizeof(HUF_DEltX4) == sizeof(HUF_DTable)); /* if compiler fails here, assertion is wrong */
+ if (maxTableLog > HUF_TABLELOG_MAX) return ERROR(tableLog_tooLarge);
+ /* memset(weightList, 0, sizeof(weightList)); */ /* is not necessary, even though some analyzer complain ... */
+
+ iSize = HUF_readStats(weightList, HUF_SYMBOLVALUE_MAX + 1, rankStats, &nbSymbols, &tableLog, src, srcSize);
+ if (HUF_isError(iSize)) return iSize;
+
+ /* check result */
+ if (tableLog > maxTableLog) return ERROR(tableLog_tooLarge); /* DTable can't fit code depth */
+
+ /* find maxWeight */
+ for (maxW = tableLog; rankStats[maxW]==0; maxW--) {} /* necessarily finds a solution before 0 */
+
+ /* Get start index of each weight */
+ { U32 w, nextRankStart = 0;
+ for (w=1; w<maxW+1; w++) {
+ U32 current = nextRankStart;
+ nextRankStart += rankStats[w];
+ rankStart[w] = current;
+ }
+ rankStart[0] = nextRankStart; /* put all 0w symbols at the end of sorted list*/
+ sizeOfSort = nextRankStart;
+ }
+
+ /* sort symbols by weight */
+ { U32 s;
+ for (s=0; s<nbSymbols; s++) {
+ U32 const w = weightList[s];
+ U32 const r = rankStart[w]++;
+ sortedSymbol[r].symbol = (BYTE)s;
+ sortedSymbol[r].weight = (BYTE)w;
+ }
+ rankStart[0] = 0; /* forget 0w symbols; this is beginning of weight(1) */
+ }
+
+ /* Build rankVal */
+ { U32* const rankVal0 = rankVal[0];
+ { int const rescale = (maxTableLog-tableLog) - 1; /* tableLog <= maxTableLog */
+ U32 nextRankVal = 0;
+ U32 w;
+ for (w=1; w<maxW+1; w++) {
+ U32 current = nextRankVal;
+ nextRankVal += rankStats[w] << (w+rescale);
+ rankVal0[w] = current;
+ } }
+ { U32 const minBits = tableLog+1 - maxW;
+ U32 consumed;
+ for (consumed = minBits; consumed < maxTableLog - minBits + 1; consumed++) {
+ U32* const rankValPtr = rankVal[consumed];
+ U32 w;
+ for (w = 1; w < maxW+1; w++) {
+ rankValPtr[w] = rankVal0[w] >> consumed;
+ } } } }
+
+ HUF_fillDTableX4(dt, maxTableLog,
+ sortedSymbol, sizeOfSort,
+ rankStart0, rankVal, maxW,
+ tableLog+1);
+
+ dtd.tableLog = (BYTE)maxTableLog;
+ dtd.tableType = 1;
+ memcpy(DTable, &dtd, sizeof(dtd));
+ return iSize;
+}
+
+
+static U32 HUF_decodeSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
+{
+ size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
+ memcpy(op, dt+val, 2);
+ BIT_skipBits(DStream, dt[val].nbBits);
+ return dt[val].length;
+}
+
+static U32 HUF_decodeLastSymbolX4(void* op, BIT_DStream_t* DStream, const HUF_DEltX4* dt, const U32 dtLog)
+{
+ size_t const val = BIT_lookBitsFast(DStream, dtLog); /* note : dtLog >= 1 */
+ memcpy(op, dt+val, 1);
+ if (dt[val].length==1) BIT_skipBits(DStream, dt[val].nbBits);
+ else {
+ if (DStream->bitsConsumed < (sizeof(DStream->bitContainer)*8)) {
+ BIT_skipBits(DStream, dt[val].nbBits);
+ if (DStream->bitsConsumed > (sizeof(DStream->bitContainer)*8))
+ DStream->bitsConsumed = (sizeof(DStream->bitContainer)*8); /* ugly hack; works only because it's the last symbol. Note : can't easily extract nbBits from just this symbol */
+ } }
+ return 1;
+}
+
+
+#define HUF_DECODE_SYMBOLX4_0(ptr, DStreamPtr) \
+ ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
+
+#define HUF_DECODE_SYMBOLX4_1(ptr, DStreamPtr) \
+ if (MEM_64bits() || (HUF_TABLELOG_MAX<=12)) \
+ ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
+
+#define HUF_DECODE_SYMBOLX4_2(ptr, DStreamPtr) \
+ if (MEM_64bits()) \
+ ptr += HUF_decodeSymbolX4(ptr, DStreamPtr, dt, dtLog)
+
+FORCE_INLINE size_t HUF_decodeStreamX4(BYTE* p, BIT_DStream_t* bitDPtr, BYTE* const pEnd, const HUF_DEltX4* const dt, const U32 dtLog)
+{
+ BYTE* const pStart = p;
+
+ /* up to 8 symbols at a time */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p < pEnd-(sizeof(bitDPtr->bitContainer)-1))) {
+ HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX4_1(p, bitDPtr);
+ HUF_DECODE_SYMBOLX4_2(p, bitDPtr);
+ HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
+ }
+
+ /* closer to end : up to 2 symbols at a time */
+ while ((BIT_reloadDStream(bitDPtr) == BIT_DStream_unfinished) & (p <= pEnd-2))
+ HUF_DECODE_SYMBOLX4_0(p, bitDPtr);
+
+ while (p <= pEnd-2)
+ HUF_DECODE_SYMBOLX4_0(p, bitDPtr); /* no need to reload : reached the end of DStream */
+
+ if (p < pEnd)
+ p += HUF_decodeLastSymbolX4(p, bitDPtr, dt, dtLog);
+
+ return p-pStart;
+}
+
+
+static size_t HUF_decompress1X4_usingDTable_internal(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ BIT_DStream_t bitD;
+
+ /* Init */
+ { size_t const errorCode = BIT_initDStream(&bitD, cSrc, cSrcSize);
+ if (HUF_isError(errorCode)) return errorCode;
+ }
+
+ /* decode */
+ { BYTE* const ostart = (BYTE*) dst;
+ BYTE* const oend = ostart + dstSize;
+ const void* const dtPtr = DTable+1; /* force compiler to not use strict-aliasing */
+ const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ HUF_decodeStreamX4(ostart, &bitD, oend, dt, dtd.tableLog);
+ }
+
+ /* check */
+ if (!BIT_endOfDStream(&bitD)) return ERROR(corruption_detected);
+
+ /* decoded size */
+ return dstSize;
+}
+
+size_t HUF_decompress1X4_usingDTable(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ if (dtd.tableType != 1) return ERROR(GENERIC);
+ return HUF_decompress1X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+
+size_t HUF_decompress1X4_DCtx (HUF_DTable* DCtx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ const BYTE* ip = (const BYTE*) cSrc;
+
+ size_t const hSize = HUF_readDTableX4 (DCtx, cSrc, cSrcSize);
+ if (HUF_isError(hSize)) return hSize;
+ if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
+ ip += hSize; cSrcSize -= hSize;
+
+ return HUF_decompress1X4_usingDTable_internal (dst, dstSize, ip, cSrcSize, DCtx);
+}
+
+size_t HUF_decompress1X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress1X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+
+static size_t HUF_decompress4X4_usingDTable_internal(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ if (cSrcSize < 10) return ERROR(corruption_detected); /* strict minimum : jump table + 1 byte per stream */
+
+ { const BYTE* const istart = (const BYTE*) cSrc;
+ BYTE* const ostart = (BYTE*) dst;
+ BYTE* const oend = ostart + dstSize;
+ const void* const dtPtr = DTable+1;
+ const HUF_DEltX4* const dt = (const HUF_DEltX4*)dtPtr;
+
+ /* Init */
+ BIT_DStream_t bitD1;
+ BIT_DStream_t bitD2;
+ BIT_DStream_t bitD3;
+ BIT_DStream_t bitD4;
+ size_t const length1 = MEM_readLE16(istart);
+ size_t const length2 = MEM_readLE16(istart+2);
+ size_t const length3 = MEM_readLE16(istart+4);
+ size_t const length4 = cSrcSize - (length1 + length2 + length3 + 6);
+ const BYTE* const istart1 = istart + 6; /* jumpTable */
+ const BYTE* const istart2 = istart1 + length1;
+ const BYTE* const istart3 = istart2 + length2;
+ const BYTE* const istart4 = istart3 + length3;
+ size_t const segmentSize = (dstSize+3) / 4;
+ BYTE* const opStart2 = ostart + segmentSize;
+ BYTE* const opStart3 = opStart2 + segmentSize;
+ BYTE* const opStart4 = opStart3 + segmentSize;
+ BYTE* op1 = ostart;
+ BYTE* op2 = opStart2;
+ BYTE* op3 = opStart3;
+ BYTE* op4 = opStart4;
+ U32 endSignal;
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ U32 const dtLog = dtd.tableLog;
+
+ if (length4 > cSrcSize) return ERROR(corruption_detected); /* overflow */
+ { size_t const errorCode = BIT_initDStream(&bitD1, istart1, length1);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD2, istart2, length2);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD3, istart3, length3);
+ if (HUF_isError(errorCode)) return errorCode; }
+ { size_t const errorCode = BIT_initDStream(&bitD4, istart4, length4);
+ if (HUF_isError(errorCode)) return errorCode; }
+
+ /* 16-32 symbols per loop (4-8 symbols per stream) */
+ endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
+ for ( ; (endSignal==BIT_DStream_unfinished) & (op4<(oend-(sizeof(bitD4.bitContainer)-1))) ; ) {
+ HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX4_1(op1, &bitD1);
+ HUF_DECODE_SYMBOLX4_1(op2, &bitD2);
+ HUF_DECODE_SYMBOLX4_1(op3, &bitD3);
+ HUF_DECODE_SYMBOLX4_1(op4, &bitD4);
+ HUF_DECODE_SYMBOLX4_2(op1, &bitD1);
+ HUF_DECODE_SYMBOLX4_2(op2, &bitD2);
+ HUF_DECODE_SYMBOLX4_2(op3, &bitD3);
+ HUF_DECODE_SYMBOLX4_2(op4, &bitD4);
+ HUF_DECODE_SYMBOLX4_0(op1, &bitD1);
+ HUF_DECODE_SYMBOLX4_0(op2, &bitD2);
+ HUF_DECODE_SYMBOLX4_0(op3, &bitD3);
+ HUF_DECODE_SYMBOLX4_0(op4, &bitD4);
+
+ endSignal = BIT_reloadDStream(&bitD1) | BIT_reloadDStream(&bitD2) | BIT_reloadDStream(&bitD3) | BIT_reloadDStream(&bitD4);
+ }
+
+ /* check corruption */
+ if (op1 > opStart2) return ERROR(corruption_detected);
+ if (op2 > opStart3) return ERROR(corruption_detected);
+ if (op3 > opStart4) return ERROR(corruption_detected);
+ /* note : op4 already verified within main loop */
+
+ /* finish bitStreams one by one */
+ HUF_decodeStreamX4(op1, &bitD1, opStart2, dt, dtLog);
+ HUF_decodeStreamX4(op2, &bitD2, opStart3, dt, dtLog);
+ HUF_decodeStreamX4(op3, &bitD3, opStart4, dt, dtLog);
+ HUF_decodeStreamX4(op4, &bitD4, oend, dt, dtLog);
+
+ /* check */
+ { U32 const endCheck = BIT_endOfDStream(&bitD1) & BIT_endOfDStream(&bitD2) & BIT_endOfDStream(&bitD3) & BIT_endOfDStream(&bitD4);
+ if (!endCheck) return ERROR(corruption_detected); }
+
+ /* decoded size */
+ return dstSize;
+ }
+}
+
+
+size_t HUF_decompress4X4_usingDTable(
+ void* dst, size_t dstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc dtd = HUF_getDTableDesc(DTable);
+ if (dtd.tableType != 1) return ERROR(GENERIC);
+ return HUF_decompress4X4_usingDTable_internal(dst, dstSize, cSrc, cSrcSize, DTable);
+}
+
+
+size_t HUF_decompress4X4_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ const BYTE* ip = (const BYTE*) cSrc;
+
+ size_t hSize = HUF_readDTableX4 (dctx, cSrc, cSrcSize);
+ if (HUF_isError(hSize)) return hSize;
+ if (hSize >= cSrcSize) return ERROR(srcSize_wrong);
+ ip += hSize; cSrcSize -= hSize;
+
+ return HUF_decompress4X4_usingDTable_internal(dst, dstSize, ip, cSrcSize, dctx);
+}
+
+size_t HUF_decompress4X4 (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ HUF_CREATE_STATIC_DTABLEX4(DTable, HUF_TABLELOG_MAX);
+ return HUF_decompress4X4_DCtx(DTable, dst, dstSize, cSrc, cSrcSize);
+}
+
+
+/* ********************************/
+/* Generic decompression selector */
+/* ********************************/
+
+size_t HUF_decompress1X_usingDTable(void* dst, size_t maxDstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ return dtd.tableType ? HUF_decompress1X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
+ HUF_decompress1X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
+}
+
+size_t HUF_decompress4X_usingDTable(void* dst, size_t maxDstSize,
+ const void* cSrc, size_t cSrcSize,
+ const HUF_DTable* DTable)
+{
+ DTableDesc const dtd = HUF_getDTableDesc(DTable);
+ return dtd.tableType ? HUF_decompress4X4_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable) :
+ HUF_decompress4X2_usingDTable_internal(dst, maxDstSize, cSrc, cSrcSize, DTable);
+}
+
+
+typedef struct { U32 tableTime; U32 decode256Time; } algo_time_t;
+static const algo_time_t algoTime[16 /* Quantization */][3 /* single, double, quad */] =
+{
+ /* single, double, quad */
+ {{0,0}, {1,1}, {2,2}}, /* Q==0 : impossible */
+ {{0,0}, {1,1}, {2,2}}, /* Q==1 : impossible */
+ {{ 38,130}, {1313, 74}, {2151, 38}}, /* Q == 2 : 12-18% */
+ {{ 448,128}, {1353, 74}, {2238, 41}}, /* Q == 3 : 18-25% */
+ {{ 556,128}, {1353, 74}, {2238, 47}}, /* Q == 4 : 25-32% */
+ {{ 714,128}, {1418, 74}, {2436, 53}}, /* Q == 5 : 32-38% */
+ {{ 883,128}, {1437, 74}, {2464, 61}}, /* Q == 6 : 38-44% */
+ {{ 897,128}, {1515, 75}, {2622, 68}}, /* Q == 7 : 44-50% */
+ {{ 926,128}, {1613, 75}, {2730, 75}}, /* Q == 8 : 50-56% */
+ {{ 947,128}, {1729, 77}, {3359, 77}}, /* Q == 9 : 56-62% */
+ {{1107,128}, {2083, 81}, {4006, 84}}, /* Q ==10 : 62-69% */
+ {{1177,128}, {2379, 87}, {4785, 88}}, /* Q ==11 : 69-75% */
+ {{1242,128}, {2415, 93}, {5155, 84}}, /* Q ==12 : 75-81% */
+ {{1349,128}, {2644,106}, {5260,106}}, /* Q ==13 : 81-87% */
+ {{1455,128}, {2422,124}, {4174,124}}, /* Q ==14 : 87-93% */
+ {{ 722,128}, {1891,145}, {1936,146}}, /* Q ==15 : 93-99% */
+};
+
+/** HUF_selectDecoder() :
+* Tells which decoder is likely to decode faster,
+* based on a set of pre-determined metrics.
+* @return : 0==HUF_decompress4X2, 1==HUF_decompress4X4 .
+* Assumption : 0 < cSrcSize < dstSize <= 128 KB */
+U32 HUF_selectDecoder (size_t dstSize, size_t cSrcSize)
+{
+ /* decoder timing evaluation */
+ U32 const Q = (U32)(cSrcSize * 16 / dstSize); /* Q < 16 since dstSize > cSrcSize */
+ U32 const D256 = (U32)(dstSize >> 8);
+ U32 const DTime0 = algoTime[Q][0].tableTime + (algoTime[Q][0].decode256Time * D256);
+ U32 DTime1 = algoTime[Q][1].tableTime + (algoTime[Q][1].decode256Time * D256);
+ DTime1 += DTime1 >> 3; /* advantage to algorithm using less memory, for cache eviction */
+
+ return DTime1 < DTime0;
+}
+
+
+typedef size_t (*decompressionAlgo)(void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize);
+
+size_t HUF_decompress (void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ static const decompressionAlgo decompress[2] = { HUF_decompress4X2, HUF_decompress4X4 };
+
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
+ if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+ return decompress[algoNb](dst, dstSize, cSrc, cSrcSize);
+ }
+}
+
+size_t HUF_decompress4X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
+ if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+ return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
+ HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
+ }
+}
+
+size_t HUF_decompress4X_hufOnly (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if ((cSrcSize >= dstSize) || (cSrcSize <= 1)) return ERROR(corruption_detected); /* invalid */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+ return algoNb ? HUF_decompress4X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
+ HUF_decompress4X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
+ }
+}
+
+size_t HUF_decompress1X_DCtx (HUF_DTable* dctx, void* dst, size_t dstSize, const void* cSrc, size_t cSrcSize)
+{
+ /* validation checks */
+ if (dstSize == 0) return ERROR(dstSize_tooSmall);
+ if (cSrcSize > dstSize) return ERROR(corruption_detected); /* invalid */
+ if (cSrcSize == dstSize) { memcpy(dst, cSrc, dstSize); return dstSize; } /* not compressed */
+ if (cSrcSize == 1) { memset(dst, *(const BYTE*)cSrc, dstSize); return dstSize; } /* RLE */
+
+ { U32 const algoNb = HUF_selectDecoder(dstSize, cSrcSize);
+ return algoNb ? HUF_decompress1X4_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) :
+ HUF_decompress1X2_DCtx(dctx, dst, dstSize, cSrc, cSrcSize) ;
+ }
+}
diff --git a/thirdparty/zstd/decompress/zstd_decompress.c b/thirdparty/zstd/decompress/zstd_decompress.c
new file mode 100644
index 0000000000..910f9ab783
--- /dev/null
+++ b/thirdparty/zstd/decompress/zstd_decompress.c
@@ -0,0 +1,2376 @@
+/**
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+
+/* ***************************************************************
+* Tuning parameters
+*****************************************************************/
+/*!
+ * HEAPMODE :
+ * Select how default decompression function ZSTD_decompress() will allocate memory,
+ * in memory stack (0), or in memory heap (1, requires malloc())
+ */
+#ifndef ZSTD_HEAPMODE
+# define ZSTD_HEAPMODE 1
+#endif
+
+/*!
+* LEGACY_SUPPORT :
+* if set to 1, ZSTD_decompress() can decode older formats (v0.1+)
+*/
+#ifndef ZSTD_LEGACY_SUPPORT
+# define ZSTD_LEGACY_SUPPORT 0
+#endif
+
+/*!
+* MAXWINDOWSIZE_DEFAULT :
+* maximum window size accepted by DStream, by default.
+* Frames requiring more memory will be rejected.
+*/
+#ifndef ZSTD_MAXWINDOWSIZE_DEFAULT
+# define ZSTD_MAXWINDOWSIZE_DEFAULT ((1 << ZSTD_WINDOWLOG_MAX) + 1) /* defined within zstd.h */
+#endif
+
+
+/*-*******************************************************
+* Dependencies
+*********************************************************/
+#include <string.h> /* memcpy, memmove, memset */
+#include "mem.h" /* low level memory routines */
+#define FSE_STATIC_LINKING_ONLY
+#include "fse.h"
+#define HUF_STATIC_LINKING_ONLY
+#include "huf.h"
+#include "zstd_internal.h"
+
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
+# include "zstd_legacy.h"
+#endif
+
+
+#if defined(_MSC_VER)
+# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
+# define ZSTD_PREFETCH(ptr) _mm_prefetch((const char*)ptr, _MM_HINT_T0)
+#elif defined(__GNUC__)
+# define ZSTD_PREFETCH(ptr) __builtin_prefetch(ptr, 0, 0)
+#else
+# define ZSTD_PREFETCH(ptr) /* disabled */
+#endif
+
+/*-*************************************
+* Macros
+***************************************/
+#define ZSTD_isError ERR_isError /* for inlining */
+#define FSE_isError ERR_isError
+#define HUF_isError ERR_isError
+
+
+/*_*******************************************************
+* Memory operations
+**********************************************************/
+static void ZSTD_copy4(void* dst, const void* src) { memcpy(dst, src, 4); }
+
+
+/*-*************************************************************
+* Context management
+***************************************************************/
+typedef enum { ZSTDds_getFrameHeaderSize, ZSTDds_decodeFrameHeader,
+ ZSTDds_decodeBlockHeader, ZSTDds_decompressBlock,
+ ZSTDds_decompressLastBlock, ZSTDds_checkChecksum,
+ ZSTDds_decodeSkippableHeader, ZSTDds_skipFrame } ZSTD_dStage;
+
+typedef struct {
+ FSE_DTable LLTable[FSE_DTABLE_SIZE_U32(LLFSELog)];
+ FSE_DTable OFTable[FSE_DTABLE_SIZE_U32(OffFSELog)];
+ FSE_DTable MLTable[FSE_DTABLE_SIZE_U32(MLFSELog)];
+ HUF_DTable hufTable[HUF_DTABLE_SIZE(HufLog)]; /* can accommodate HUF_decompress4X */
+ U32 rep[ZSTD_REP_NUM];
+} ZSTD_entropyTables_t;
+
+struct ZSTD_DCtx_s
+{
+ const FSE_DTable* LLTptr;
+ const FSE_DTable* MLTptr;
+ const FSE_DTable* OFTptr;
+ const HUF_DTable* HUFptr;
+ ZSTD_entropyTables_t entropy;
+ const void* previousDstEnd; /* detect continuity */
+ const void* base; /* start of current segment */
+ const void* vBase; /* virtual start of previous segment if it was just before current one */
+ const void* dictEnd; /* end of previous segment */
+ size_t expected;
+ ZSTD_frameParams fParams;
+ blockType_e bType; /* used in ZSTD_decompressContinue(), to transfer blockType between header decoding and block decoding stages */
+ ZSTD_dStage stage;
+ U32 litEntropy;
+ U32 fseEntropy;
+ XXH64_state_t xxhState;
+ size_t headerSize;
+ U32 dictID;
+ const BYTE* litPtr;
+ ZSTD_customMem customMem;
+ size_t litSize;
+ size_t rleSize;
+ BYTE litBuffer[ZSTD_BLOCKSIZE_ABSOLUTEMAX + WILDCOPY_OVERLENGTH];
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX];
+}; /* typedef'd to ZSTD_DCtx within "zstd.h" */
+
+size_t ZSTD_sizeof_DCtx (const ZSTD_DCtx* dctx) { return (dctx==NULL) ? 0 : sizeof(ZSTD_DCtx); }
+
+size_t ZSTD_estimateDCtxSize(void) { return sizeof(ZSTD_DCtx); }
+
+size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx)
+{
+ dctx->expected = ZSTD_frameHeaderSize_prefix;
+ dctx->stage = ZSTDds_getFrameHeaderSize;
+ dctx->previousDstEnd = NULL;
+ dctx->base = NULL;
+ dctx->vBase = NULL;
+ dctx->dictEnd = NULL;
+ dctx->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
+ dctx->litEntropy = dctx->fseEntropy = 0;
+ dctx->dictID = 0;
+ MEM_STATIC_ASSERT(sizeof(dctx->entropy.rep) == sizeof(repStartValue));
+ memcpy(dctx->entropy.rep, repStartValue, sizeof(repStartValue)); /* initial repcodes */
+ dctx->LLTptr = dctx->entropy.LLTable;
+ dctx->MLTptr = dctx->entropy.MLTable;
+ dctx->OFTptr = dctx->entropy.OFTable;
+ dctx->HUFptr = dctx->entropy.hufTable;
+ return 0;
+}
+
+ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem)
+{
+ ZSTD_DCtx* dctx;
+
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ dctx = (ZSTD_DCtx*)ZSTD_malloc(sizeof(ZSTD_DCtx), customMem);
+ if (!dctx) return NULL;
+ memcpy(&dctx->customMem, &customMem, sizeof(customMem));
+ ZSTD_decompressBegin(dctx);
+ return dctx;
+}
+
+ZSTD_DCtx* ZSTD_createDCtx(void)
+{
+ return ZSTD_createDCtx_advanced(defaultCustomMem);
+}
+
+size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx)
+{
+ if (dctx==NULL) return 0; /* support free on NULL */
+ ZSTD_free(dctx, dctx->customMem);
+ return 0; /* reserved as a potential error code in the future */
+}
+
+void ZSTD_copyDCtx(ZSTD_DCtx* dstDCtx, const ZSTD_DCtx* srcDCtx)
+{
+ size_t const workSpaceSize = (ZSTD_BLOCKSIZE_ABSOLUTEMAX+WILDCOPY_OVERLENGTH) + ZSTD_frameHeaderSize_max;
+ memcpy(dstDCtx, srcDCtx, sizeof(ZSTD_DCtx) - workSpaceSize); /* no need to copy workspace */
+}
+
+static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict);
+
+
+/*-*************************************************************
+* Decompression section
+***************************************************************/
+
+/*! ZSTD_isFrame() :
+ * Tells if the content of `buffer` starts with a valid Frame Identifier.
+ * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
+ * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
+ * Note 3 : Skippable Frame Identifiers are considered valid. */
+unsigned ZSTD_isFrame(const void* buffer, size_t size)
+{
+ if (size < 4) return 0;
+ { U32 const magic = MEM_readLE32(buffer);
+ if (magic == ZSTD_MAGICNUMBER) return 1;
+ if ((magic & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) return 1;
+ }
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
+ if (ZSTD_isLegacy(buffer, size)) return 1;
+#endif
+ return 0;
+}
+
+
+/** ZSTD_frameHeaderSize() :
+* srcSize must be >= ZSTD_frameHeaderSize_prefix.
+* @return : size of the Frame Header */
+static size_t ZSTD_frameHeaderSize(const void* src, size_t srcSize)
+{
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong);
+ { BYTE const fhd = ((const BYTE*)src)[4];
+ U32 const dictID= fhd & 3;
+ U32 const singleSegment = (fhd >> 5) & 1;
+ U32 const fcsId = fhd >> 6;
+ return ZSTD_frameHeaderSize_prefix + !singleSegment + ZSTD_did_fieldSize[dictID] + ZSTD_fcs_fieldSize[fcsId]
+ + (singleSegment && !fcsId);
+ }
+}
+
+
+/** ZSTD_getFrameParams() :
+* decode Frame Header, or require larger `srcSize`.
+* @return : 0, `fparamsPtr` is correctly filled,
+* >0, `srcSize` is too small, result is expected `srcSize`,
+* or an error code, which can be tested using ZSTD_isError() */
+size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize)
+{
+ const BYTE* ip = (const BYTE*)src;
+
+ if (srcSize < ZSTD_frameHeaderSize_prefix) return ZSTD_frameHeaderSize_prefix;
+ if (MEM_readLE32(src) != ZSTD_MAGICNUMBER) {
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+ if (srcSize < ZSTD_skippableHeaderSize) return ZSTD_skippableHeaderSize; /* magic number + skippable frame length */
+ memset(fparamsPtr, 0, sizeof(*fparamsPtr));
+ fparamsPtr->frameContentSize = MEM_readLE32((const char *)src + 4);
+ fparamsPtr->windowSize = 0; /* windowSize==0 means a frame is skippable */
+ return 0;
+ }
+ return ERROR(prefix_unknown);
+ }
+
+ /* ensure there is enough `srcSize` to fully read/decode frame header */
+ { size_t const fhsize = ZSTD_frameHeaderSize(src, srcSize);
+ if (srcSize < fhsize) return fhsize; }
+
+ { BYTE const fhdByte = ip[4];
+ size_t pos = 5;
+ U32 const dictIDSizeCode = fhdByte&3;
+ U32 const checksumFlag = (fhdByte>>2)&1;
+ U32 const singleSegment = (fhdByte>>5)&1;
+ U32 const fcsID = fhdByte>>6;
+ U32 const windowSizeMax = 1U << ZSTD_WINDOWLOG_MAX;
+ U32 windowSize = 0;
+ U32 dictID = 0;
+ U64 frameContentSize = 0;
+ if ((fhdByte & 0x08) != 0) return ERROR(frameParameter_unsupported); /* reserved bits, which must be zero */
+ if (!singleSegment) {
+ BYTE const wlByte = ip[pos++];
+ U32 const windowLog = (wlByte >> 3) + ZSTD_WINDOWLOG_ABSOLUTEMIN;
+ if (windowLog > ZSTD_WINDOWLOG_MAX) return ERROR(frameParameter_windowTooLarge); /* avoids issue with 1 << windowLog */
+ windowSize = (1U << windowLog);
+ windowSize += (windowSize >> 3) * (wlByte&7);
+ }
+
+ switch(dictIDSizeCode)
+ {
+ default: /* impossible */
+ case 0 : break;
+ case 1 : dictID = ip[pos]; pos++; break;
+ case 2 : dictID = MEM_readLE16(ip+pos); pos+=2; break;
+ case 3 : dictID = MEM_readLE32(ip+pos); pos+=4; break;
+ }
+ switch(fcsID)
+ {
+ default: /* impossible */
+ case 0 : if (singleSegment) frameContentSize = ip[pos]; break;
+ case 1 : frameContentSize = MEM_readLE16(ip+pos)+256; break;
+ case 2 : frameContentSize = MEM_readLE32(ip+pos); break;
+ case 3 : frameContentSize = MEM_readLE64(ip+pos); break;
+ }
+ if (!windowSize) windowSize = (U32)frameContentSize;
+ if (windowSize > windowSizeMax) return ERROR(frameParameter_windowTooLarge);
+ fparamsPtr->frameContentSize = frameContentSize;
+ fparamsPtr->windowSize = windowSize;
+ fparamsPtr->dictID = dictID;
+ fparamsPtr->checksumFlag = checksumFlag;
+ }
+ return 0;
+}
+
+/** ZSTD_getFrameContentSize() :
+* compatible with legacy mode
+* @return : decompressed size of the single frame pointed to be `src` if known, otherwise
+* - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
+* - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
+unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize)
+{
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
+ if (ZSTD_isLegacy(src, srcSize)) {
+ unsigned long long const ret = ZSTD_getDecompressedSize_legacy(src, srcSize);
+ return ret == 0 ? ZSTD_CONTENTSIZE_UNKNOWN : ret;
+ }
+#endif
+ {
+ ZSTD_frameParams fParams;
+ if (ZSTD_getFrameParams(&fParams, src, srcSize) != 0) return ZSTD_CONTENTSIZE_ERROR;
+ if (fParams.windowSize == 0) {
+ /* Either skippable or empty frame, size == 0 either way */
+ return 0;
+ } else if (fParams.frameContentSize != 0) {
+ return fParams.frameContentSize;
+ } else {
+ return ZSTD_CONTENTSIZE_UNKNOWN;
+ }
+ }
+}
+
+/** ZSTD_findDecompressedSize() :
+ * compatible with legacy mode
+ * `srcSize` must be the exact length of some number of ZSTD compressed and/or
+ * skippable frames
+ * @return : decompressed size of the frames contained */
+unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize)
+{
+ {
+ unsigned long long totalDstSize = 0;
+ while (srcSize >= ZSTD_frameHeaderSize_prefix) {
+ const U32 magicNumber = MEM_readLE32(src);
+
+ if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+ size_t skippableSize;
+ if (srcSize < ZSTD_skippableHeaderSize)
+ return ERROR(srcSize_wrong);
+ skippableSize = MEM_readLE32((const BYTE *)src + 4) +
+ ZSTD_skippableHeaderSize;
+ if (srcSize < skippableSize) {
+ return ZSTD_CONTENTSIZE_ERROR;
+ }
+
+ src = (const BYTE *)src + skippableSize;
+ srcSize -= skippableSize;
+ continue;
+ }
+
+ {
+ unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
+ if (ret >= ZSTD_CONTENTSIZE_ERROR) return ret;
+
+ /* check for overflow */
+ if (totalDstSize + ret < totalDstSize) return ZSTD_CONTENTSIZE_ERROR;
+ totalDstSize += ret;
+ }
+ {
+ size_t const frameSrcSize = ZSTD_findFrameCompressedSize(src, srcSize);
+ if (ZSTD_isError(frameSrcSize)) {
+ return ZSTD_CONTENTSIZE_ERROR;
+ }
+
+ src = (const BYTE *)src + frameSrcSize;
+ srcSize -= frameSrcSize;
+ }
+ }
+
+ if (srcSize) {
+ return ZSTD_CONTENTSIZE_ERROR;
+ }
+
+ return totalDstSize;
+ }
+}
+
+/** ZSTD_getDecompressedSize() :
+* compatible with legacy mode
+* @return : decompressed size if known, 0 otherwise
+ note : 0 can mean any of the following :
+ - decompressed size is not present within frame header
+ - frame header unknown / not supported
+ - frame header not complete (`srcSize` too small) */
+unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize)
+{
+ unsigned long long const ret = ZSTD_getFrameContentSize(src, srcSize);
+ return ret >= ZSTD_CONTENTSIZE_ERROR ? 0 : ret;
+}
+
+
+/** ZSTD_decodeFrameHeader() :
+* `headerSize` must be the size provided by ZSTD_frameHeaderSize().
+* @return : 0 if success, or an error code, which can be tested using ZSTD_isError() */
+static size_t ZSTD_decodeFrameHeader(ZSTD_DCtx* dctx, const void* src, size_t headerSize)
+{
+ size_t const result = ZSTD_getFrameParams(&(dctx->fParams), src, headerSize);
+ if (ZSTD_isError(result)) return result; /* invalid header */
+ if (result>0) return ERROR(srcSize_wrong); /* headerSize too small */
+ if (dctx->fParams.dictID && (dctx->dictID != dctx->fParams.dictID)) return ERROR(dictionary_wrong);
+ if (dctx->fParams.checksumFlag) XXH64_reset(&dctx->xxhState, 0);
+ return 0;
+}
+
+
+typedef struct
+{
+ blockType_e blockType;
+ U32 lastBlock;
+ U32 origSize;
+} blockProperties_t;
+
+/*! ZSTD_getcBlockSize() :
+* Provides the size of compressed block from block header `src` */
+size_t ZSTD_getcBlockSize(const void* src, size_t srcSize,
+ blockProperties_t* bpPtr)
+{
+ if (srcSize < ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
+ { U32 const cBlockHeader = MEM_readLE24(src);
+ U32 const cSize = cBlockHeader >> 3;
+ bpPtr->lastBlock = cBlockHeader & 1;
+ bpPtr->blockType = (blockType_e)((cBlockHeader >> 1) & 3);
+ bpPtr->origSize = cSize; /* only useful for RLE */
+ if (bpPtr->blockType == bt_rle) return 1;
+ if (bpPtr->blockType == bt_reserved) return ERROR(corruption_detected);
+ return cSize;
+ }
+}
+
+
+static size_t ZSTD_copyRawBlock(void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ if (srcSize > dstCapacity) return ERROR(dstSize_tooSmall);
+ memcpy(dst, src, srcSize);
+ return srcSize;
+}
+
+
+static size_t ZSTD_setRleBlock(void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ size_t regenSize)
+{
+ if (srcSize != 1) return ERROR(srcSize_wrong);
+ if (regenSize > dstCapacity) return ERROR(dstSize_tooSmall);
+ memset(dst, *(const BYTE*)src, regenSize);
+ return regenSize;
+}
+
+/*! ZSTD_decodeLiteralsBlock() :
+ @return : nb of bytes read from src (< srcSize ) */
+size_t ZSTD_decodeLiteralsBlock(ZSTD_DCtx* dctx,
+ const void* src, size_t srcSize) /* note : srcSize < BLOCKSIZE */
+{
+ if (srcSize < MIN_CBLOCK_SIZE) return ERROR(corruption_detected);
+
+ { const BYTE* const istart = (const BYTE*) src;
+ symbolEncodingType_e const litEncType = (symbolEncodingType_e)(istart[0] & 3);
+
+ switch(litEncType)
+ {
+ case set_repeat:
+ if (dctx->litEntropy==0) return ERROR(dictionary_corrupted);
+ /* fall-through */
+ case set_compressed:
+ if (srcSize < 5) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need up to 5 for case 3 */
+ { size_t lhSize, litSize, litCSize;
+ U32 singleStream=0;
+ U32 const lhlCode = (istart[0] >> 2) & 3;
+ U32 const lhc = MEM_readLE32(istart);
+ switch(lhlCode)
+ {
+ case 0: case 1: default: /* note : default is impossible, since lhlCode into [0..3] */
+ /* 2 - 2 - 10 - 10 */
+ singleStream = !lhlCode;
+ lhSize = 3;
+ litSize = (lhc >> 4) & 0x3FF;
+ litCSize = (lhc >> 14) & 0x3FF;
+ break;
+ case 2:
+ /* 2 - 2 - 14 - 14 */
+ lhSize = 4;
+ litSize = (lhc >> 4) & 0x3FFF;
+ litCSize = lhc >> 18;
+ break;
+ case 3:
+ /* 2 - 2 - 18 - 18 */
+ lhSize = 5;
+ litSize = (lhc >> 4) & 0x3FFFF;
+ litCSize = (lhc >> 22) + (istart[4] << 10);
+ break;
+ }
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
+ if (litCSize + lhSize > srcSize) return ERROR(corruption_detected);
+
+ if (HUF_isError((litEncType==set_repeat) ?
+ ( singleStream ?
+ HUF_decompress1X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) :
+ HUF_decompress4X_usingDTable(dctx->litBuffer, litSize, istart+lhSize, litCSize, dctx->HUFptr) ) :
+ ( singleStream ?
+ HUF_decompress1X2_DCtx(dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize) :
+ HUF_decompress4X_hufOnly (dctx->entropy.hufTable, dctx->litBuffer, litSize, istart+lhSize, litCSize)) ))
+ return ERROR(corruption_detected);
+
+ dctx->litPtr = dctx->litBuffer;
+ dctx->litSize = litSize;
+ dctx->litEntropy = 1;
+ if (litEncType==set_compressed) dctx->HUFptr = dctx->entropy.hufTable;
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
+ return litCSize + lhSize;
+ }
+
+ case set_basic:
+ { size_t litSize, lhSize;
+ U32 const lhlCode = ((istart[0]) >> 2) & 3;
+ switch(lhlCode)
+ {
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
+ lhSize = 1;
+ litSize = istart[0] >> 3;
+ break;
+ case 1:
+ lhSize = 2;
+ litSize = MEM_readLE16(istart) >> 4;
+ break;
+ case 3:
+ lhSize = 3;
+ litSize = MEM_readLE24(istart) >> 4;
+ break;
+ }
+
+ if (lhSize+litSize+WILDCOPY_OVERLENGTH > srcSize) { /* risk reading beyond src buffer with wildcopy */
+ if (litSize+lhSize > srcSize) return ERROR(corruption_detected);
+ memcpy(dctx->litBuffer, istart+lhSize, litSize);
+ dctx->litPtr = dctx->litBuffer;
+ dctx->litSize = litSize;
+ memset(dctx->litBuffer + dctx->litSize, 0, WILDCOPY_OVERLENGTH);
+ return lhSize+litSize;
+ }
+ /* direct reference into compressed stream */
+ dctx->litPtr = istart+lhSize;
+ dctx->litSize = litSize;
+ return lhSize+litSize;
+ }
+
+ case set_rle:
+ { U32 const lhlCode = ((istart[0]) >> 2) & 3;
+ size_t litSize, lhSize;
+ switch(lhlCode)
+ {
+ case 0: case 2: default: /* note : default is impossible, since lhlCode into [0..3] */
+ lhSize = 1;
+ litSize = istart[0] >> 3;
+ break;
+ case 1:
+ lhSize = 2;
+ litSize = MEM_readLE16(istart) >> 4;
+ break;
+ case 3:
+ lhSize = 3;
+ litSize = MEM_readLE24(istart) >> 4;
+ if (srcSize<4) return ERROR(corruption_detected); /* srcSize >= MIN_CBLOCK_SIZE == 3; here we need lhSize+1 = 4 */
+ break;
+ }
+ if (litSize > ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(corruption_detected);
+ memset(dctx->litBuffer, istart[lhSize], litSize + WILDCOPY_OVERLENGTH);
+ dctx->litPtr = dctx->litBuffer;
+ dctx->litSize = litSize;
+ return lhSize+1;
+ }
+ default:
+ return ERROR(corruption_detected); /* impossible */
+ }
+ }
+}
+
+
+typedef union {
+ FSE_decode_t realData;
+ U32 alignedBy4;
+} FSE_decode_t4;
+
+/* Default FSE distribution table for Literal Lengths */
+static const FSE_decode_t4 LL_defaultDTable[(1<<LL_DEFAULTNORMLOG)+1] = {
+ { { LL_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
+ /* base, symbol, bits */
+ { { 0, 0, 4 } }, { { 16, 0, 4 } }, { { 32, 1, 5 } }, { { 0, 3, 5 } },
+ { { 0, 4, 5 } }, { { 0, 6, 5 } }, { { 0, 7, 5 } }, { { 0, 9, 5 } },
+ { { 0, 10, 5 } }, { { 0, 12, 5 } }, { { 0, 14, 6 } }, { { 0, 16, 5 } },
+ { { 0, 18, 5 } }, { { 0, 19, 5 } }, { { 0, 21, 5 } }, { { 0, 22, 5 } },
+ { { 0, 24, 5 } }, { { 32, 25, 5 } }, { { 0, 26, 5 } }, { { 0, 27, 6 } },
+ { { 0, 29, 6 } }, { { 0, 31, 6 } }, { { 32, 0, 4 } }, { { 0, 1, 4 } },
+ { { 0, 2, 5 } }, { { 32, 4, 5 } }, { { 0, 5, 5 } }, { { 32, 7, 5 } },
+ { { 0, 8, 5 } }, { { 32, 10, 5 } }, { { 0, 11, 5 } }, { { 0, 13, 6 } },
+ { { 32, 16, 5 } }, { { 0, 17, 5 } }, { { 32, 19, 5 } }, { { 0, 20, 5 } },
+ { { 32, 22, 5 } }, { { 0, 23, 5 } }, { { 0, 25, 4 } }, { { 16, 25, 4 } },
+ { { 32, 26, 5 } }, { { 0, 28, 6 } }, { { 0, 30, 6 } }, { { 48, 0, 4 } },
+ { { 16, 1, 4 } }, { { 32, 2, 5 } }, { { 32, 3, 5 } }, { { 32, 5, 5 } },
+ { { 32, 6, 5 } }, { { 32, 8, 5 } }, { { 32, 9, 5 } }, { { 32, 11, 5 } },
+ { { 32, 12, 5 } }, { { 0, 15, 6 } }, { { 32, 17, 5 } }, { { 32, 18, 5 } },
+ { { 32, 20, 5 } }, { { 32, 21, 5 } }, { { 32, 23, 5 } }, { { 32, 24, 5 } },
+ { { 0, 35, 6 } }, { { 0, 34, 6 } }, { { 0, 33, 6 } }, { { 0, 32, 6 } },
+}; /* LL_defaultDTable */
+
+/* Default FSE distribution table for Match Lengths */
+static const FSE_decode_t4 ML_defaultDTable[(1<<ML_DEFAULTNORMLOG)+1] = {
+ { { ML_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
+ /* base, symbol, bits */
+ { { 0, 0, 6 } }, { { 0, 1, 4 } }, { { 32, 2, 5 } }, { { 0, 3, 5 } },
+ { { 0, 5, 5 } }, { { 0, 6, 5 } }, { { 0, 8, 5 } }, { { 0, 10, 6 } },
+ { { 0, 13, 6 } }, { { 0, 16, 6 } }, { { 0, 19, 6 } }, { { 0, 22, 6 } },
+ { { 0, 25, 6 } }, { { 0, 28, 6 } }, { { 0, 31, 6 } }, { { 0, 33, 6 } },
+ { { 0, 35, 6 } }, { { 0, 37, 6 } }, { { 0, 39, 6 } }, { { 0, 41, 6 } },
+ { { 0, 43, 6 } }, { { 0, 45, 6 } }, { { 16, 1, 4 } }, { { 0, 2, 4 } },
+ { { 32, 3, 5 } }, { { 0, 4, 5 } }, { { 32, 6, 5 } }, { { 0, 7, 5 } },
+ { { 0, 9, 6 } }, { { 0, 12, 6 } }, { { 0, 15, 6 } }, { { 0, 18, 6 } },
+ { { 0, 21, 6 } }, { { 0, 24, 6 } }, { { 0, 27, 6 } }, { { 0, 30, 6 } },
+ { { 0, 32, 6 } }, { { 0, 34, 6 } }, { { 0, 36, 6 } }, { { 0, 38, 6 } },
+ { { 0, 40, 6 } }, { { 0, 42, 6 } }, { { 0, 44, 6 } }, { { 32, 1, 4 } },
+ { { 48, 1, 4 } }, { { 16, 2, 4 } }, { { 32, 4, 5 } }, { { 32, 5, 5 } },
+ { { 32, 7, 5 } }, { { 32, 8, 5 } }, { { 0, 11, 6 } }, { { 0, 14, 6 } },
+ { { 0, 17, 6 } }, { { 0, 20, 6 } }, { { 0, 23, 6 } }, { { 0, 26, 6 } },
+ { { 0, 29, 6 } }, { { 0, 52, 6 } }, { { 0, 51, 6 } }, { { 0, 50, 6 } },
+ { { 0, 49, 6 } }, { { 0, 48, 6 } }, { { 0, 47, 6 } }, { { 0, 46, 6 } },
+}; /* ML_defaultDTable */
+
+/* Default FSE distribution table for Offset Codes */
+static const FSE_decode_t4 OF_defaultDTable[(1<<OF_DEFAULTNORMLOG)+1] = {
+ { { OF_DEFAULTNORMLOG, 1, 1 } }, /* header : tableLog, fastMode, fastMode */
+ /* base, symbol, bits */
+ { { 0, 0, 5 } }, { { 0, 6, 4 } },
+ { { 0, 9, 5 } }, { { 0, 15, 5 } },
+ { { 0, 21, 5 } }, { { 0, 3, 5 } },
+ { { 0, 7, 4 } }, { { 0, 12, 5 } },
+ { { 0, 18, 5 } }, { { 0, 23, 5 } },
+ { { 0, 5, 5 } }, { { 0, 8, 4 } },
+ { { 0, 14, 5 } }, { { 0, 20, 5 } },
+ { { 0, 2, 5 } }, { { 16, 7, 4 } },
+ { { 0, 11, 5 } }, { { 0, 17, 5 } },
+ { { 0, 22, 5 } }, { { 0, 4, 5 } },
+ { { 16, 8, 4 } }, { { 0, 13, 5 } },
+ { { 0, 19, 5 } }, { { 0, 1, 5 } },
+ { { 16, 6, 4 } }, { { 0, 10, 5 } },
+ { { 0, 16, 5 } }, { { 0, 28, 5 } },
+ { { 0, 27, 5 } }, { { 0, 26, 5 } },
+ { { 0, 25, 5 } }, { { 0, 24, 5 } },
+}; /* OF_defaultDTable */
+
+/*! ZSTD_buildSeqTable() :
+ @return : nb bytes read from src,
+ or an error code if it fails, testable with ZSTD_isError()
+*/
+static size_t ZSTD_buildSeqTable(FSE_DTable* DTableSpace, const FSE_DTable** DTablePtr,
+ symbolEncodingType_e type, U32 max, U32 maxLog,
+ const void* src, size_t srcSize,
+ const FSE_decode_t4* defaultTable, U32 flagRepeatTable)
+{
+ const void* const tmpPtr = defaultTable; /* bypass strict aliasing */
+ switch(type)
+ {
+ case set_rle :
+ if (!srcSize) return ERROR(srcSize_wrong);
+ if ( (*(const BYTE*)src) > max) return ERROR(corruption_detected);
+ FSE_buildDTable_rle(DTableSpace, *(const BYTE*)src);
+ *DTablePtr = DTableSpace;
+ return 1;
+ case set_basic :
+ *DTablePtr = (const FSE_DTable*)tmpPtr;
+ return 0;
+ case set_repeat:
+ if (!flagRepeatTable) return ERROR(corruption_detected);
+ return 0;
+ default : /* impossible */
+ case set_compressed :
+ { U32 tableLog;
+ S16 norm[MaxSeq+1];
+ size_t const headerSize = FSE_readNCount(norm, &max, &tableLog, src, srcSize);
+ if (FSE_isError(headerSize)) return ERROR(corruption_detected);
+ if (tableLog > maxLog) return ERROR(corruption_detected);
+ FSE_buildDTable(DTableSpace, norm, max, tableLog);
+ *DTablePtr = DTableSpace;
+ return headerSize;
+ } }
+}
+
+size_t ZSTD_decodeSeqHeaders(ZSTD_DCtx* dctx, int* nbSeqPtr,
+ const void* src, size_t srcSize)
+{
+ const BYTE* const istart = (const BYTE* const)src;
+ const BYTE* const iend = istart + srcSize;
+ const BYTE* ip = istart;
+
+ /* check */
+ if (srcSize < MIN_SEQUENCES_SIZE) return ERROR(srcSize_wrong);
+
+ /* SeqHead */
+ { int nbSeq = *ip++;
+ if (!nbSeq) { *nbSeqPtr=0; return 1; }
+ if (nbSeq > 0x7F) {
+ if (nbSeq == 0xFF) {
+ if (ip+2 > iend) return ERROR(srcSize_wrong);
+ nbSeq = MEM_readLE16(ip) + LONGNBSEQ, ip+=2;
+ } else {
+ if (ip >= iend) return ERROR(srcSize_wrong);
+ nbSeq = ((nbSeq-0x80)<<8) + *ip++;
+ }
+ }
+ *nbSeqPtr = nbSeq;
+ }
+
+ /* FSE table descriptors */
+ if (ip+4 > iend) return ERROR(srcSize_wrong); /* minimum possible size */
+ { symbolEncodingType_e const LLtype = (symbolEncodingType_e)(*ip >> 6);
+ symbolEncodingType_e const OFtype = (symbolEncodingType_e)((*ip >> 4) & 3);
+ symbolEncodingType_e const MLtype = (symbolEncodingType_e)((*ip >> 2) & 3);
+ ip++;
+
+ /* Build DTables */
+ { size_t const llhSize = ZSTD_buildSeqTable(dctx->entropy.LLTable, &dctx->LLTptr,
+ LLtype, MaxLL, LLFSELog,
+ ip, iend-ip, LL_defaultDTable, dctx->fseEntropy);
+ if (ZSTD_isError(llhSize)) return ERROR(corruption_detected);
+ ip += llhSize;
+ }
+ { size_t const ofhSize = ZSTD_buildSeqTable(dctx->entropy.OFTable, &dctx->OFTptr,
+ OFtype, MaxOff, OffFSELog,
+ ip, iend-ip, OF_defaultDTable, dctx->fseEntropy);
+ if (ZSTD_isError(ofhSize)) return ERROR(corruption_detected);
+ ip += ofhSize;
+ }
+ { size_t const mlhSize = ZSTD_buildSeqTable(dctx->entropy.MLTable, &dctx->MLTptr,
+ MLtype, MaxML, MLFSELog,
+ ip, iend-ip, ML_defaultDTable, dctx->fseEntropy);
+ if (ZSTD_isError(mlhSize)) return ERROR(corruption_detected);
+ ip += mlhSize;
+ }
+ }
+
+ return ip-istart;
+}
+
+
+typedef struct {
+ size_t litLength;
+ size_t matchLength;
+ size_t offset;
+ const BYTE* match;
+} seq_t;
+
+typedef struct {
+ BIT_DStream_t DStream;
+ FSE_DState_t stateLL;
+ FSE_DState_t stateOffb;
+ FSE_DState_t stateML;
+ size_t prevOffset[ZSTD_REP_NUM];
+ const BYTE* base;
+ size_t pos;
+ uPtrDiff gotoDict;
+} seqState_t;
+
+
+FORCE_NOINLINE
+size_t ZSTD_execSequenceLast7(BYTE* op,
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
+{
+ BYTE* const oLitEnd = op + sequence.litLength;
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
+ const BYTE* match = oLitEnd - sequence.offset;
+
+ /* check */
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
+ if (oLitEnd <= oend_w) return ERROR(GENERIC); /* Precondition */
+
+ /* copy literals */
+ if (op < oend_w) {
+ ZSTD_wildcopy(op, *litPtr, oend_w - op);
+ *litPtr += oend_w - op;
+ op = oend_w;
+ }
+ while (op < oLitEnd) *op++ = *(*litPtr)++;
+
+ /* copy Match */
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
+ /* offset beyond prefix */
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
+ match = dictEnd - (base-match);
+ if (match + sequence.matchLength <= dictEnd) {
+ memmove(oLitEnd, match, sequence.matchLength);
+ return sequenceLength;
+ }
+ /* span extDict & currentPrefixSegment */
+ { size_t const length1 = dictEnd - match;
+ memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = base;
+ } }
+ while (op < oMatchEnd) *op++ = *match++;
+ return sequenceLength;
+}
+
+
+static seq_t ZSTD_decodeSequence(seqState_t* seqState)
+{
+ seq_t seq;
+
+ U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
+ U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
+
+ U32 const llBits = LL_bits[llCode];
+ U32 const mlBits = ML_bits[mlCode];
+ U32 const ofBits = ofCode;
+ U32 const totalBits = llBits+mlBits+ofBits;
+
+ static const U32 LL_base[MaxLL+1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 18, 20, 22, 24, 28, 32, 40,
+ 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
+ 0x2000, 0x4000, 0x8000, 0x10000 };
+
+ static const U32 ML_base[MaxML+1] = {
+ 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 37, 39, 41, 43, 47, 51, 59,
+ 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
+ 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
+
+ static const U32 OF_base[MaxOff+1] = {
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
+
+ /* sequence */
+ { size_t offset;
+ if (!ofCode)
+ offset = 0;
+ else {
+ offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
+ }
+
+ if (ofCode <= 1) {
+ offset += (llCode==0);
+ if (offset) {
+ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset = temp;
+ } else {
+ offset = seqState->prevOffset[0];
+ }
+ } else {
+ seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset;
+ }
+ seq.offset = offset;
+ }
+
+ seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
+ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
+
+ seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
+ if (MEM_32bits() ||
+ (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
+
+ /* ANS state update */
+ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
+ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
+ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
+
+ return seq;
+}
+
+
+FORCE_INLINE
+size_t ZSTD_execSequence(BYTE* op,
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
+{
+ BYTE* const oLitEnd = op + sequence.litLength;
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
+ const BYTE* match = oLitEnd - sequence.offset;
+
+ /* check */
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
+
+ /* copy Literals */
+ ZSTD_copy8(op, *litPtr);
+ if (sequence.litLength > 8)
+ ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ op = oLitEnd;
+ *litPtr = iLitEnd; /* update for next sequence */
+
+ /* copy Match */
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
+ /* offset beyond prefix -> go into extDict */
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
+ match = dictEnd + (match - base);
+ if (match + sequence.matchLength <= dictEnd) {
+ memmove(oLitEnd, match, sequence.matchLength);
+ return sequenceLength;
+ }
+ /* span extDict & currentPrefixSegment */
+ { size_t const length1 = dictEnd - match;
+ memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = base;
+ if (op > oend_w || sequence.matchLength < MINMATCH) {
+ U32 i;
+ for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
+ return sequenceLength;
+ }
+ } }
+ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
+
+ /* match within prefix */
+ if (sequence.offset < 8) {
+ /* close range match, overlap */
+ static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
+ int const sub2 = dec64table[sequence.offset];
+ op[0] = match[0];
+ op[1] = match[1];
+ op[2] = match[2];
+ op[3] = match[3];
+ match += dec32table[sequence.offset];
+ ZSTD_copy4(op+4, match);
+ match -= sub2;
+ } else {
+ ZSTD_copy8(op, match);
+ }
+ op += 8; match += 8;
+
+ if (oMatchEnd > oend-(16-MINMATCH)) {
+ if (op < oend_w) {
+ ZSTD_wildcopy(op, match, oend_w - op);
+ match += oend_w - op;
+ op = oend_w;
+ }
+ while (op < oMatchEnd) *op++ = *match++;
+ } else {
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
+ }
+ return sequenceLength;
+}
+
+
+static size_t ZSTD_decompressSequences(
+ ZSTD_DCtx* dctx,
+ void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize)
+{
+ const BYTE* ip = (const BYTE*)seqStart;
+ const BYTE* const iend = ip + seqSize;
+ BYTE* const ostart = (BYTE* const)dst;
+ BYTE* const oend = ostart + maxDstSize;
+ BYTE* op = ostart;
+ const BYTE* litPtr = dctx->litPtr;
+ const BYTE* const litEnd = litPtr + dctx->litSize;
+ const BYTE* const base = (const BYTE*) (dctx->base);
+ const BYTE* const vBase = (const BYTE*) (dctx->vBase);
+ const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
+ int nbSeq;
+
+ /* Build Decoding Tables */
+ { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
+ if (ZSTD_isError(seqHSize)) return seqHSize;
+ ip += seqHSize;
+ }
+
+ /* Regen sequences */
+ if (nbSeq) {
+ seqState_t seqState;
+ dctx->fseEntropy = 1;
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
+ CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
+ FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
+ FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
+ FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
+
+ for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && nbSeq ; ) {
+ nbSeq--;
+ { seq_t const sequence = ZSTD_decodeSequence(&seqState);
+ size_t const oneSeqSize = ZSTD_execSequence(op, oend, sequence, &litPtr, litEnd, base, vBase, dictEnd);
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ op += oneSeqSize;
+ } }
+
+ /* check if reached exact end */
+ if (nbSeq) return ERROR(corruption_detected);
+ /* save reps for next block */
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
+ }
+
+ /* last literal segment */
+ { size_t const lastLLSize = litEnd - litPtr;
+ if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
+ memcpy(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
+
+ return op-ostart;
+}
+
+
+FORCE_INLINE seq_t ZSTD_decodeSequenceLong_generic(seqState_t* seqState, int const longOffsets)
+{
+ seq_t seq;
+
+ U32 const llCode = FSE_peekSymbol(&seqState->stateLL);
+ U32 const mlCode = FSE_peekSymbol(&seqState->stateML);
+ U32 const ofCode = FSE_peekSymbol(&seqState->stateOffb); /* <= maxOff, by table construction */
+
+ U32 const llBits = LL_bits[llCode];
+ U32 const mlBits = ML_bits[mlCode];
+ U32 const ofBits = ofCode;
+ U32 const totalBits = llBits+mlBits+ofBits;
+
+ static const U32 LL_base[MaxLL+1] = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 18, 20, 22, 24, 28, 32, 40,
+ 48, 64, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000,
+ 0x2000, 0x4000, 0x8000, 0x10000 };
+
+ static const U32 ML_base[MaxML+1] = {
+ 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18,
+ 19, 20, 21, 22, 23, 24, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 37, 39, 41, 43, 47, 51, 59,
+ 67, 83, 99, 0x83, 0x103, 0x203, 0x403, 0x803,
+ 0x1003, 0x2003, 0x4003, 0x8003, 0x10003 };
+
+ static const U32 OF_base[MaxOff+1] = {
+ 0, 1, 1, 5, 0xD, 0x1D, 0x3D, 0x7D,
+ 0xFD, 0x1FD, 0x3FD, 0x7FD, 0xFFD, 0x1FFD, 0x3FFD, 0x7FFD,
+ 0xFFFD, 0x1FFFD, 0x3FFFD, 0x7FFFD, 0xFFFFD, 0x1FFFFD, 0x3FFFFD, 0x7FFFFD,
+ 0xFFFFFD, 0x1FFFFFD, 0x3FFFFFD, 0x7FFFFFD, 0xFFFFFFD };
+
+ /* sequence */
+ { size_t offset;
+ if (!ofCode)
+ offset = 0;
+ else {
+ if (longOffsets) {
+ int const extraBits = ofBits - MIN(ofBits, STREAM_ACCUMULATOR_MIN);
+ offset = OF_base[ofCode] + (BIT_readBitsFast(&seqState->DStream, ofBits - extraBits) << extraBits);
+ if (MEM_32bits() || extraBits) BIT_reloadDStream(&seqState->DStream);
+ if (extraBits) offset += BIT_readBitsFast(&seqState->DStream, extraBits);
+ } else {
+ offset = OF_base[ofCode] + BIT_readBitsFast(&seqState->DStream, ofBits); /* <= (ZSTD_WINDOWLOG_MAX-1) bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream);
+ }
+ }
+
+ if (ofCode <= 1) {
+ offset += (llCode==0);
+ if (offset) {
+ size_t temp = (offset==3) ? seqState->prevOffset[0] - 1 : seqState->prevOffset[offset];
+ temp += !temp; /* 0 is not valid; input is corrupted; force offset to 1 */
+ if (offset != 1) seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset = temp;
+ } else {
+ offset = seqState->prevOffset[0];
+ }
+ } else {
+ seqState->prevOffset[2] = seqState->prevOffset[1];
+ seqState->prevOffset[1] = seqState->prevOffset[0];
+ seqState->prevOffset[0] = offset;
+ }
+ seq.offset = offset;
+ }
+
+ seq.matchLength = ML_base[mlCode] + ((mlCode>31) ? BIT_readBitsFast(&seqState->DStream, mlBits) : 0); /* <= 16 bits */
+ if (MEM_32bits() && (mlBits+llBits>24)) BIT_reloadDStream(&seqState->DStream);
+
+ seq.litLength = LL_base[llCode] + ((llCode>15) ? BIT_readBitsFast(&seqState->DStream, llBits) : 0); /* <= 16 bits */
+ if (MEM_32bits() ||
+ (totalBits > 64 - 7 - (LLFSELog+MLFSELog+OffFSELog)) ) BIT_reloadDStream(&seqState->DStream);
+
+ { size_t const pos = seqState->pos + seq.litLength;
+ seq.match = seqState->base + pos - seq.offset; /* single memory segment */
+ if (seq.offset > pos) seq.match += seqState->gotoDict; /* separate memory segment */
+ seqState->pos = pos + seq.matchLength;
+ }
+
+ /* ANS state update */
+ FSE_updateState(&seqState->stateLL, &seqState->DStream); /* <= 9 bits */
+ FSE_updateState(&seqState->stateML, &seqState->DStream); /* <= 9 bits */
+ if (MEM_32bits()) BIT_reloadDStream(&seqState->DStream); /* <= 18 bits */
+ FSE_updateState(&seqState->stateOffb, &seqState->DStream); /* <= 8 bits */
+
+ return seq;
+}
+
+static seq_t ZSTD_decodeSequenceLong(seqState_t* seqState, unsigned const windowSize) {
+ if (ZSTD_highbit32(windowSize) > STREAM_ACCUMULATOR_MIN) {
+ return ZSTD_decodeSequenceLong_generic(seqState, 1);
+ } else {
+ return ZSTD_decodeSequenceLong_generic(seqState, 0);
+ }
+}
+
+FORCE_INLINE
+size_t ZSTD_execSequenceLong(BYTE* op,
+ BYTE* const oend, seq_t sequence,
+ const BYTE** litPtr, const BYTE* const litLimit,
+ const BYTE* const base, const BYTE* const vBase, const BYTE* const dictEnd)
+{
+ BYTE* const oLitEnd = op + sequence.litLength;
+ size_t const sequenceLength = sequence.litLength + sequence.matchLength;
+ BYTE* const oMatchEnd = op + sequenceLength; /* risk : address space overflow (32-bits) */
+ BYTE* const oend_w = oend - WILDCOPY_OVERLENGTH;
+ const BYTE* const iLitEnd = *litPtr + sequence.litLength;
+ const BYTE* match = sequence.match;
+
+ /* check */
+#if 1
+ if (oMatchEnd>oend) return ERROR(dstSize_tooSmall); /* last match must start at a minimum distance of WILDCOPY_OVERLENGTH from oend */
+ if (iLitEnd > litLimit) return ERROR(corruption_detected); /* over-read beyond lit buffer */
+ if (oLitEnd>oend_w) return ZSTD_execSequenceLast7(op, oend, sequence, litPtr, litLimit, base, vBase, dictEnd);
+#endif
+
+ /* copy Literals */
+ ZSTD_copy8(op, *litPtr);
+ if (sequence.litLength > 8)
+ ZSTD_wildcopy(op+8, (*litPtr)+8, sequence.litLength - 8); /* note : since oLitEnd <= oend-WILDCOPY_OVERLENGTH, no risk of overwrite beyond oend */
+ op = oLitEnd;
+ *litPtr = iLitEnd; /* update for next sequence */
+
+ /* copy Match */
+#if 1
+ if (sequence.offset > (size_t)(oLitEnd - base)) {
+ /* offset beyond prefix */
+ if (sequence.offset > (size_t)(oLitEnd - vBase)) return ERROR(corruption_detected);
+ if (match + sequence.matchLength <= dictEnd) {
+ memmove(oLitEnd, match, sequence.matchLength);
+ return sequenceLength;
+ }
+ /* span extDict & currentPrefixSegment */
+ { size_t const length1 = dictEnd - match;
+ memmove(oLitEnd, match, length1);
+ op = oLitEnd + length1;
+ sequence.matchLength -= length1;
+ match = base;
+ if (op > oend_w || sequence.matchLength < MINMATCH) {
+ U32 i;
+ for (i = 0; i < sequence.matchLength; ++i) op[i] = match[i];
+ return sequenceLength;
+ }
+ } }
+ /* Requirement: op <= oend_w && sequence.matchLength >= MINMATCH */
+#endif
+
+ /* match within prefix */
+ if (sequence.offset < 8) {
+ /* close range match, overlap */
+ static const U32 dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 }; /* added */
+ static const int dec64table[] = { 8, 8, 8, 7, 8, 9,10,11 }; /* subtracted */
+ int const sub2 = dec64table[sequence.offset];
+ op[0] = match[0];
+ op[1] = match[1];
+ op[2] = match[2];
+ op[3] = match[3];
+ match += dec32table[sequence.offset];
+ ZSTD_copy4(op+4, match);
+ match -= sub2;
+ } else {
+ ZSTD_copy8(op, match);
+ }
+ op += 8; match += 8;
+
+ if (oMatchEnd > oend-(16-MINMATCH)) {
+ if (op < oend_w) {
+ ZSTD_wildcopy(op, match, oend_w - op);
+ match += oend_w - op;
+ op = oend_w;
+ }
+ while (op < oMatchEnd) *op++ = *match++;
+ } else {
+ ZSTD_wildcopy(op, match, (ptrdiff_t)sequence.matchLength-8); /* works even if matchLength < 8 */
+ }
+ return sequenceLength;
+}
+
+static size_t ZSTD_decompressSequencesLong(
+ ZSTD_DCtx* dctx,
+ void* dst, size_t maxDstSize,
+ const void* seqStart, size_t seqSize)
+{
+ const BYTE* ip = (const BYTE*)seqStart;
+ const BYTE* const iend = ip + seqSize;
+ BYTE* const ostart = (BYTE* const)dst;
+ BYTE* const oend = ostart + maxDstSize;
+ BYTE* op = ostart;
+ const BYTE* litPtr = dctx->litPtr;
+ const BYTE* const litEnd = litPtr + dctx->litSize;
+ const BYTE* const base = (const BYTE*) (dctx->base);
+ const BYTE* const vBase = (const BYTE*) (dctx->vBase);
+ const BYTE* const dictEnd = (const BYTE*) (dctx->dictEnd);
+ unsigned const windowSize = dctx->fParams.windowSize;
+ int nbSeq;
+
+ /* Build Decoding Tables */
+ { size_t const seqHSize = ZSTD_decodeSeqHeaders(dctx, &nbSeq, ip, seqSize);
+ if (ZSTD_isError(seqHSize)) return seqHSize;
+ ip += seqHSize;
+ }
+
+ /* Regen sequences */
+ if (nbSeq) {
+#define STORED_SEQS 4
+#define STOSEQ_MASK (STORED_SEQS-1)
+#define ADVANCED_SEQS 4
+ seq_t sequences[STORED_SEQS];
+ int const seqAdvance = MIN(nbSeq, ADVANCED_SEQS);
+ seqState_t seqState;
+ int seqNb;
+ dctx->fseEntropy = 1;
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) seqState.prevOffset[i] = dctx->entropy.rep[i]; }
+ seqState.base = base;
+ seqState.pos = (size_t)(op-base);
+ seqState.gotoDict = (uPtrDiff)dictEnd - (uPtrDiff)base; /* cast to avoid undefined behaviour */
+ CHECK_E(BIT_initDStream(&seqState.DStream, ip, iend-ip), corruption_detected);
+ FSE_initDState(&seqState.stateLL, &seqState.DStream, dctx->LLTptr);
+ FSE_initDState(&seqState.stateOffb, &seqState.DStream, dctx->OFTptr);
+ FSE_initDState(&seqState.stateML, &seqState.DStream, dctx->MLTptr);
+
+ /* prepare in advance */
+ for (seqNb=0; (BIT_reloadDStream(&seqState.DStream) <= BIT_DStream_completed) && seqNb<seqAdvance; seqNb++) {
+ sequences[seqNb] = ZSTD_decodeSequenceLong(&seqState, windowSize);
+ }
+ if (seqNb<seqAdvance) return ERROR(corruption_detected);
+
+ /* decode and decompress */
+ for ( ; (BIT_reloadDStream(&(seqState.DStream)) <= BIT_DStream_completed) && seqNb<nbSeq ; seqNb++) {
+ seq_t const sequence = ZSTD_decodeSequenceLong(&seqState, windowSize);
+ size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[(seqNb-ADVANCED_SEQS) & STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ ZSTD_PREFETCH(sequence.match);
+ sequences[seqNb&STOSEQ_MASK] = sequence;
+ op += oneSeqSize;
+ }
+ if (seqNb<nbSeq) return ERROR(corruption_detected);
+
+ /* finish queue */
+ seqNb -= seqAdvance;
+ for ( ; seqNb<nbSeq ; seqNb++) {
+ size_t const oneSeqSize = ZSTD_execSequenceLong(op, oend, sequences[seqNb&STOSEQ_MASK], &litPtr, litEnd, base, vBase, dictEnd);
+ if (ZSTD_isError(oneSeqSize)) return oneSeqSize;
+ op += oneSeqSize;
+ }
+
+ /* save reps for next block */
+ { U32 i; for (i=0; i<ZSTD_REP_NUM; i++) dctx->entropy.rep[i] = (U32)(seqState.prevOffset[i]); }
+ }
+
+ /* last literal segment */
+ { size_t const lastLLSize = litEnd - litPtr;
+ if (lastLLSize > (size_t)(oend-op)) return ERROR(dstSize_tooSmall);
+ memcpy(op, litPtr, lastLLSize);
+ op += lastLLSize;
+ }
+
+ return op-ostart;
+}
+
+
+static size_t ZSTD_decompressBlock_internal(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{ /* blockType == blockCompressed */
+ const BYTE* ip = (const BYTE*)src;
+
+ if (srcSize >= ZSTD_BLOCKSIZE_ABSOLUTEMAX) return ERROR(srcSize_wrong);
+
+ /* Decode literals section */
+ { size_t const litCSize = ZSTD_decodeLiteralsBlock(dctx, src, srcSize);
+ if (ZSTD_isError(litCSize)) return litCSize;
+ ip += litCSize;
+ srcSize -= litCSize;
+ }
+ if (sizeof(size_t) > 4) /* do not enable prefetching on 32-bits x86, as it's performance detrimental */
+ /* likely because of register pressure */
+ /* if that's the correct cause, then 32-bits ARM should be affected differently */
+ /* it would be good to test this on ARM real hardware, to see if prefetch version improves speed */
+ if (dctx->fParams.windowSize > (1<<23))
+ return ZSTD_decompressSequencesLong(dctx, dst, dstCapacity, ip, srcSize);
+ return ZSTD_decompressSequences(dctx, dst, dstCapacity, ip, srcSize);
+}
+
+
+static void ZSTD_checkContinuity(ZSTD_DCtx* dctx, const void* dst)
+{
+ if (dst != dctx->previousDstEnd) { /* not contiguous */
+ dctx->dictEnd = dctx->previousDstEnd;
+ dctx->vBase = (const char*)dst - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
+ dctx->base = dst;
+ dctx->previousDstEnd = dst;
+ }
+}
+
+size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize)
+{
+ size_t dSize;
+ ZSTD_checkContinuity(dctx, dst);
+ dSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
+ dctx->previousDstEnd = (char*)dst + dSize;
+ return dSize;
+}
+
+
+/** ZSTD_insertBlock() :
+ insert `src` block into `dctx` history. Useful to track uncompressed blocks. */
+ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize)
+{
+ ZSTD_checkContinuity(dctx, blockStart);
+ dctx->previousDstEnd = (const char*)blockStart + blockSize;
+ return blockSize;
+}
+
+
+size_t ZSTD_generateNxBytes(void* dst, size_t dstCapacity, BYTE byte, size_t length)
+{
+ if (length > dstCapacity) return ERROR(dstSize_tooSmall);
+ memset(dst, byte, length);
+ return length;
+}
+
+/** ZSTD_findFrameCompressedSize() :
+ * compatible with legacy mode
+ * `src` must point to the start of a ZSTD frame, ZSTD legacy frame, or skippable frame
+ * `srcSize` must be at least as large as the frame contained
+ * @return : the compressed size of the frame starting at `src` */
+size_t ZSTD_findFrameCompressedSize(const void *src, size_t srcSize)
+{
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
+ if (ZSTD_isLegacy(src, srcSize)) return ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
+#endif
+ if (srcSize >= ZSTD_skippableHeaderSize &&
+ (MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+ return ZSTD_skippableHeaderSize + MEM_readLE32((const BYTE*)src + 4);
+ } else {
+ const BYTE* ip = (const BYTE*)src;
+ const BYTE* const ipstart = ip;
+ size_t remainingSize = srcSize;
+ ZSTD_frameParams fParams;
+
+ size_t const headerSize = ZSTD_frameHeaderSize(ip, remainingSize);
+ if (ZSTD_isError(headerSize)) return headerSize;
+
+ /* Frame Header */
+ { size_t const ret = ZSTD_getFrameParams(&fParams, ip, remainingSize);
+ if (ZSTD_isError(ret)) return ret;
+ if (ret > 0) return ERROR(srcSize_wrong);
+ }
+
+ ip += headerSize;
+ remainingSize -= headerSize;
+
+ /* Loop on each block */
+ while (1) {
+ blockProperties_t blockProperties;
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
+ if (ZSTD_isError(cBlockSize)) return cBlockSize;
+
+ if (ZSTD_blockHeaderSize + cBlockSize > remainingSize) return ERROR(srcSize_wrong);
+
+ ip += ZSTD_blockHeaderSize + cBlockSize;
+ remainingSize -= ZSTD_blockHeaderSize + cBlockSize;
+
+ if (blockProperties.lastBlock) break;
+ }
+
+ if (fParams.checksumFlag) { /* Frame content checksum */
+ if (remainingSize < 4) return ERROR(srcSize_wrong);
+ ip += 4;
+ remainingSize -= 4;
+ }
+
+ return ip - ipstart;
+ }
+}
+
+/*! ZSTD_decompressFrame() :
+* @dctx must be properly initialized */
+static size_t ZSTD_decompressFrame(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void** srcPtr, size_t *srcSizePtr)
+{
+ const BYTE* ip = (const BYTE*)(*srcPtr);
+ BYTE* const ostart = (BYTE* const)dst;
+ BYTE* const oend = ostart + dstCapacity;
+ BYTE* op = ostart;
+ size_t remainingSize = *srcSizePtr;
+
+ /* check */
+ if (remainingSize < ZSTD_frameHeaderSize_min+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
+
+ /* Frame Header */
+ { size_t const frameHeaderSize = ZSTD_frameHeaderSize(ip, ZSTD_frameHeaderSize_prefix);
+ if (ZSTD_isError(frameHeaderSize)) return frameHeaderSize;
+ if (remainingSize < frameHeaderSize+ZSTD_blockHeaderSize) return ERROR(srcSize_wrong);
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, ip, frameHeaderSize));
+ ip += frameHeaderSize; remainingSize -= frameHeaderSize;
+ }
+
+ /* Loop on each block */
+ while (1) {
+ size_t decodedSize;
+ blockProperties_t blockProperties;
+ size_t const cBlockSize = ZSTD_getcBlockSize(ip, remainingSize, &blockProperties);
+ if (ZSTD_isError(cBlockSize)) return cBlockSize;
+
+ ip += ZSTD_blockHeaderSize;
+ remainingSize -= ZSTD_blockHeaderSize;
+ if (cBlockSize > remainingSize) return ERROR(srcSize_wrong);
+
+ switch(blockProperties.blockType)
+ {
+ case bt_compressed:
+ decodedSize = ZSTD_decompressBlock_internal(dctx, op, oend-op, ip, cBlockSize);
+ break;
+ case bt_raw :
+ decodedSize = ZSTD_copyRawBlock(op, oend-op, ip, cBlockSize);
+ break;
+ case bt_rle :
+ decodedSize = ZSTD_generateNxBytes(op, oend-op, *ip, blockProperties.origSize);
+ break;
+ case bt_reserved :
+ default:
+ return ERROR(corruption_detected);
+ }
+
+ if (ZSTD_isError(decodedSize)) return decodedSize;
+ if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, op, decodedSize);
+ op += decodedSize;
+ ip += cBlockSize;
+ remainingSize -= cBlockSize;
+ if (blockProperties.lastBlock) break;
+ }
+
+ if (dctx->fParams.checksumFlag) { /* Frame content checksum verification */
+ U32 const checkCalc = (U32)XXH64_digest(&dctx->xxhState);
+ U32 checkRead;
+ if (remainingSize<4) return ERROR(checksum_wrong);
+ checkRead = MEM_readLE32(ip);
+ if (checkRead != checkCalc) return ERROR(checksum_wrong);
+ ip += 4;
+ remainingSize -= 4;
+ }
+
+ /* Allow caller to get size read */
+ *srcPtr = ip;
+ *srcSizePtr = remainingSize;
+ return op-ostart;
+}
+
+static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict);
+static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict);
+
+static size_t ZSTD_decompressMultiFrame(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void *dict, size_t dictSize,
+ const ZSTD_DDict* ddict)
+{
+ void* const dststart = dst;
+
+ if (ddict) {
+ if (dict) {
+ /* programmer error, these two cases should be mutually exclusive */
+ return ERROR(GENERIC);
+ }
+
+ dict = ZSTD_DDictDictContent(ddict);
+ dictSize = ZSTD_DDictDictSize(ddict);
+ }
+
+ while (srcSize >= ZSTD_frameHeaderSize_prefix) {
+ U32 magicNumber;
+
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
+ if (ZSTD_isLegacy(src, srcSize)) {
+ size_t decodedSize;
+ size_t const frameSize = ZSTD_findFrameCompressedSizeLegacy(src, srcSize);
+ if (ZSTD_isError(frameSize)) return frameSize;
+
+ decodedSize = ZSTD_decompressLegacy(dst, dstCapacity, src, frameSize, dict, dictSize);
+
+ dst = (BYTE*)dst + decodedSize;
+ dstCapacity -= decodedSize;
+
+ src = (const BYTE*)src + frameSize;
+ srcSize -= frameSize;
+
+ continue;
+ }
+#endif
+
+ magicNumber = MEM_readLE32(src);
+ if (magicNumber != ZSTD_MAGICNUMBER) {
+ if ((magicNumber & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) {
+ size_t skippableSize;
+ if (srcSize < ZSTD_skippableHeaderSize)
+ return ERROR(srcSize_wrong);
+ skippableSize = MEM_readLE32((const BYTE *)src + 4) +
+ ZSTD_skippableHeaderSize;
+ if (srcSize < skippableSize) {
+ return ERROR(srcSize_wrong);
+ }
+
+ src = (const BYTE *)src + skippableSize;
+ srcSize -= skippableSize;
+ continue;
+ } else {
+ return ERROR(prefix_unknown);
+ }
+ }
+
+ if (ddict) {
+ /* we were called from ZSTD_decompress_usingDDict */
+ ZSTD_refDDict(dctx, ddict);
+ } else {
+ /* this will initialize correctly with no dict if dict == NULL, so
+ * use this in all cases but ddict */
+ CHECK_F(ZSTD_decompressBegin_usingDict(dctx, dict, dictSize));
+ }
+ ZSTD_checkContinuity(dctx, dst);
+
+ { const size_t res = ZSTD_decompressFrame(dctx, dst, dstCapacity,
+ &src, &srcSize);
+ if (ZSTD_isError(res)) return res;
+ /* don't need to bounds check this, ZSTD_decompressFrame will have
+ * already */
+ dst = (BYTE*)dst + res;
+ dstCapacity -= res;
+ }
+ }
+
+ if (srcSize) return ERROR(srcSize_wrong); /* input not entirely consumed */
+
+ return (BYTE*)dst - (BYTE*)dststart;
+}
+
+size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict, size_t dictSize)
+{
+ return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize, dict, dictSize, NULL);
+}
+
+
+size_t ZSTD_decompressDCtx(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ return ZSTD_decompress_usingDict(dctx, dst, dstCapacity, src, srcSize, NULL, 0);
+}
+
+
+size_t ZSTD_decompress(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+#if defined(ZSTD_HEAPMODE) && (ZSTD_HEAPMODE==1)
+ size_t regenSize;
+ ZSTD_DCtx* const dctx = ZSTD_createDCtx();
+ if (dctx==NULL) return ERROR(memory_allocation);
+ regenSize = ZSTD_decompressDCtx(dctx, dst, dstCapacity, src, srcSize);
+ ZSTD_freeDCtx(dctx);
+ return regenSize;
+#else /* stack mode */
+ ZSTD_DCtx dctx;
+ return ZSTD_decompressDCtx(&dctx, dst, dstCapacity, src, srcSize);
+#endif
+}
+
+
+/*-**************************************
+* Advanced Streaming Decompression API
+* Bufferless and synchronous
+****************************************/
+size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx) { return dctx->expected; }
+
+ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx) {
+ switch(dctx->stage)
+ {
+ default: /* should not happen */
+ case ZSTDds_getFrameHeaderSize:
+ case ZSTDds_decodeFrameHeader:
+ return ZSTDnit_frameHeader;
+ case ZSTDds_decodeBlockHeader:
+ return ZSTDnit_blockHeader;
+ case ZSTDds_decompressBlock:
+ return ZSTDnit_block;
+ case ZSTDds_decompressLastBlock:
+ return ZSTDnit_lastBlock;
+ case ZSTDds_checkChecksum:
+ return ZSTDnit_checksum;
+ case ZSTDds_decodeSkippableHeader:
+ case ZSTDds_skipFrame:
+ return ZSTDnit_skippableFrame;
+ }
+}
+
+int ZSTD_isSkipFrame(ZSTD_DCtx* dctx) { return dctx->stage == ZSTDds_skipFrame; } /* for zbuff */
+
+/** ZSTD_decompressContinue() :
+* @return : nb of bytes generated into `dst` (necessarily <= `dstCapacity)
+* or an error code, which can be tested using ZSTD_isError() */
+size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ /* Sanity check */
+ if (srcSize != dctx->expected) return ERROR(srcSize_wrong);
+ if (dstCapacity) ZSTD_checkContinuity(dctx, dst);
+
+ switch (dctx->stage)
+ {
+ case ZSTDds_getFrameHeaderSize :
+ if (srcSize != ZSTD_frameHeaderSize_prefix) return ERROR(srcSize_wrong); /* impossible */
+ if ((MEM_readLE32(src) & 0xFFFFFFF0U) == ZSTD_MAGIC_SKIPPABLE_START) { /* skippable frame */
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
+ dctx->expected = ZSTD_skippableHeaderSize - ZSTD_frameHeaderSize_prefix; /* magic number + skippable frame length */
+ dctx->stage = ZSTDds_decodeSkippableHeader;
+ return 0;
+ }
+ dctx->headerSize = ZSTD_frameHeaderSize(src, ZSTD_frameHeaderSize_prefix);
+ if (ZSTD_isError(dctx->headerSize)) return dctx->headerSize;
+ memcpy(dctx->headerBuffer, src, ZSTD_frameHeaderSize_prefix);
+ if (dctx->headerSize > ZSTD_frameHeaderSize_prefix) {
+ dctx->expected = dctx->headerSize - ZSTD_frameHeaderSize_prefix;
+ dctx->stage = ZSTDds_decodeFrameHeader;
+ return 0;
+ }
+ dctx->expected = 0; /* not necessary to copy more */
+
+ case ZSTDds_decodeFrameHeader:
+ memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
+ CHECK_F(ZSTD_decodeFrameHeader(dctx, dctx->headerBuffer, dctx->headerSize));
+ dctx->expected = ZSTD_blockHeaderSize;
+ dctx->stage = ZSTDds_decodeBlockHeader;
+ return 0;
+
+ case ZSTDds_decodeBlockHeader:
+ { blockProperties_t bp;
+ size_t const cBlockSize = ZSTD_getcBlockSize(src, ZSTD_blockHeaderSize, &bp);
+ if (ZSTD_isError(cBlockSize)) return cBlockSize;
+ dctx->expected = cBlockSize;
+ dctx->bType = bp.blockType;
+ dctx->rleSize = bp.origSize;
+ if (cBlockSize) {
+ dctx->stage = bp.lastBlock ? ZSTDds_decompressLastBlock : ZSTDds_decompressBlock;
+ return 0;
+ }
+ /* empty block */
+ if (bp.lastBlock) {
+ if (dctx->fParams.checksumFlag) {
+ dctx->expected = 4;
+ dctx->stage = ZSTDds_checkChecksum;
+ } else {
+ dctx->expected = 0; /* end of frame */
+ dctx->stage = ZSTDds_getFrameHeaderSize;
+ }
+ } else {
+ dctx->expected = 3; /* go directly to next header */
+ dctx->stage = ZSTDds_decodeBlockHeader;
+ }
+ return 0;
+ }
+ case ZSTDds_decompressLastBlock:
+ case ZSTDds_decompressBlock:
+ { size_t rSize;
+ switch(dctx->bType)
+ {
+ case bt_compressed:
+ rSize = ZSTD_decompressBlock_internal(dctx, dst, dstCapacity, src, srcSize);
+ break;
+ case bt_raw :
+ rSize = ZSTD_copyRawBlock(dst, dstCapacity, src, srcSize);
+ break;
+ case bt_rle :
+ rSize = ZSTD_setRleBlock(dst, dstCapacity, src, srcSize, dctx->rleSize);
+ break;
+ case bt_reserved : /* should never happen */
+ default:
+ return ERROR(corruption_detected);
+ }
+ if (ZSTD_isError(rSize)) return rSize;
+ if (dctx->fParams.checksumFlag) XXH64_update(&dctx->xxhState, dst, rSize);
+
+ if (dctx->stage == ZSTDds_decompressLastBlock) { /* end of frame */
+ if (dctx->fParams.checksumFlag) { /* another round for frame checksum */
+ dctx->expected = 4;
+ dctx->stage = ZSTDds_checkChecksum;
+ } else {
+ dctx->expected = 0; /* ends here */
+ dctx->stage = ZSTDds_getFrameHeaderSize;
+ }
+ } else {
+ dctx->stage = ZSTDds_decodeBlockHeader;
+ dctx->expected = ZSTD_blockHeaderSize;
+ dctx->previousDstEnd = (char*)dst + rSize;
+ }
+ return rSize;
+ }
+ case ZSTDds_checkChecksum:
+ { U32 const h32 = (U32)XXH64_digest(&dctx->xxhState);
+ U32 const check32 = MEM_readLE32(src); /* srcSize == 4, guaranteed by dctx->expected */
+ if (check32 != h32) return ERROR(checksum_wrong);
+ dctx->expected = 0;
+ dctx->stage = ZSTDds_getFrameHeaderSize;
+ return 0;
+ }
+ case ZSTDds_decodeSkippableHeader:
+ { memcpy(dctx->headerBuffer + ZSTD_frameHeaderSize_prefix, src, dctx->expected);
+ dctx->expected = MEM_readLE32(dctx->headerBuffer + 4);
+ dctx->stage = ZSTDds_skipFrame;
+ return 0;
+ }
+ case ZSTDds_skipFrame:
+ { dctx->expected = 0;
+ dctx->stage = ZSTDds_getFrameHeaderSize;
+ return 0;
+ }
+ default:
+ return ERROR(GENERIC); /* impossible */
+ }
+}
+
+
+static size_t ZSTD_refDictContent(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
+{
+ dctx->dictEnd = dctx->previousDstEnd;
+ dctx->vBase = (const char*)dict - ((const char*)(dctx->previousDstEnd) - (const char*)(dctx->base));
+ dctx->base = dict;
+ dctx->previousDstEnd = (const char*)dict + dictSize;
+ return 0;
+}
+
+/* ZSTD_loadEntropy() :
+ * dict : must point at beginning of a valid zstd dictionary
+ * @return : size of entropy tables read */
+static size_t ZSTD_loadEntropy(ZSTD_entropyTables_t* entropy, const void* const dict, size_t const dictSize)
+{
+ const BYTE* dictPtr = (const BYTE*)dict;
+ const BYTE* const dictEnd = dictPtr + dictSize;
+
+ if (dictSize <= 8) return ERROR(dictionary_corrupted);
+ dictPtr += 8; /* skip header = magic + dictID */
+
+
+ { size_t const hSize = HUF_readDTableX4(entropy->hufTable, dictPtr, dictEnd-dictPtr);
+ if (HUF_isError(hSize)) return ERROR(dictionary_corrupted);
+ dictPtr += hSize;
+ }
+
+ { short offcodeNCount[MaxOff+1];
+ U32 offcodeMaxValue = MaxOff, offcodeLog;
+ size_t const offcodeHeaderSize = FSE_readNCount(offcodeNCount, &offcodeMaxValue, &offcodeLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(offcodeHeaderSize)) return ERROR(dictionary_corrupted);
+ if (offcodeLog > OffFSELog) return ERROR(dictionary_corrupted);
+ CHECK_E(FSE_buildDTable(entropy->OFTable, offcodeNCount, offcodeMaxValue, offcodeLog), dictionary_corrupted);
+ dictPtr += offcodeHeaderSize;
+ }
+
+ { short matchlengthNCount[MaxML+1];
+ unsigned matchlengthMaxValue = MaxML, matchlengthLog;
+ size_t const matchlengthHeaderSize = FSE_readNCount(matchlengthNCount, &matchlengthMaxValue, &matchlengthLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(matchlengthHeaderSize)) return ERROR(dictionary_corrupted);
+ if (matchlengthLog > MLFSELog) return ERROR(dictionary_corrupted);
+ CHECK_E(FSE_buildDTable(entropy->MLTable, matchlengthNCount, matchlengthMaxValue, matchlengthLog), dictionary_corrupted);
+ dictPtr += matchlengthHeaderSize;
+ }
+
+ { short litlengthNCount[MaxLL+1];
+ unsigned litlengthMaxValue = MaxLL, litlengthLog;
+ size_t const litlengthHeaderSize = FSE_readNCount(litlengthNCount, &litlengthMaxValue, &litlengthLog, dictPtr, dictEnd-dictPtr);
+ if (FSE_isError(litlengthHeaderSize)) return ERROR(dictionary_corrupted);
+ if (litlengthLog > LLFSELog) return ERROR(dictionary_corrupted);
+ CHECK_E(FSE_buildDTable(entropy->LLTable, litlengthNCount, litlengthMaxValue, litlengthLog), dictionary_corrupted);
+ dictPtr += litlengthHeaderSize;
+ }
+
+ if (dictPtr+12 > dictEnd) return ERROR(dictionary_corrupted);
+ { int i;
+ size_t const dictContentSize = (size_t)(dictEnd - (dictPtr+12));
+ for (i=0; i<3; i++) {
+ U32 const rep = MEM_readLE32(dictPtr); dictPtr += 4;
+ if (rep==0 || rep >= dictContentSize) return ERROR(dictionary_corrupted);
+ entropy->rep[i] = rep;
+ } }
+
+ return dictPtr - (const BYTE*)dict;
+}
+
+static size_t ZSTD_decompress_insertDictionary(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
+{
+ if (dictSize < 8) return ZSTD_refDictContent(dctx, dict, dictSize);
+ { U32 const magic = MEM_readLE32(dict);
+ if (magic != ZSTD_DICT_MAGIC) {
+ return ZSTD_refDictContent(dctx, dict, dictSize); /* pure content mode */
+ } }
+ dctx->dictID = MEM_readLE32((const char*)dict + 4);
+
+ /* load entropy tables */
+ { size_t const eSize = ZSTD_loadEntropy(&dctx->entropy, dict, dictSize);
+ if (ZSTD_isError(eSize)) return ERROR(dictionary_corrupted);
+ dict = (const char*)dict + eSize;
+ dictSize -= eSize;
+ }
+ dctx->litEntropy = dctx->fseEntropy = 1;
+
+ /* reference dictionary content */
+ return ZSTD_refDictContent(dctx, dict, dictSize);
+}
+
+size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize)
+{
+ CHECK_F(ZSTD_decompressBegin(dctx));
+ if (dict && dictSize) CHECK_E(ZSTD_decompress_insertDictionary(dctx, dict, dictSize), dictionary_corrupted);
+ return 0;
+}
+
+
+/* ====== ZSTD_DDict ====== */
+
+struct ZSTD_DDict_s {
+ void* dictBuffer;
+ const void* dictContent;
+ size_t dictSize;
+ ZSTD_entropyTables_t entropy;
+ U32 dictID;
+ U32 entropyPresent;
+ ZSTD_customMem cMem;
+}; /* typedef'd to ZSTD_DDict within "zstd.h" */
+
+static const void* ZSTD_DDictDictContent(const ZSTD_DDict* ddict)
+{
+ return ddict->dictContent;
+}
+
+static size_t ZSTD_DDictDictSize(const ZSTD_DDict* ddict)
+{
+ return ddict->dictSize;
+}
+
+static void ZSTD_refDDict(ZSTD_DCtx* dstDCtx, const ZSTD_DDict* ddict)
+{
+ ZSTD_decompressBegin(dstDCtx); /* init */
+ if (ddict) { /* support refDDict on NULL */
+ dstDCtx->dictID = ddict->dictID;
+ dstDCtx->base = ddict->dictContent;
+ dstDCtx->vBase = ddict->dictContent;
+ dstDCtx->dictEnd = (const BYTE*)ddict->dictContent + ddict->dictSize;
+ dstDCtx->previousDstEnd = dstDCtx->dictEnd;
+ if (ddict->entropyPresent) {
+ dstDCtx->litEntropy = 1;
+ dstDCtx->fseEntropy = 1;
+ dstDCtx->LLTptr = ddict->entropy.LLTable;
+ dstDCtx->MLTptr = ddict->entropy.MLTable;
+ dstDCtx->OFTptr = ddict->entropy.OFTable;
+ dstDCtx->HUFptr = ddict->entropy.hufTable;
+ dstDCtx->entropy.rep[0] = ddict->entropy.rep[0];
+ dstDCtx->entropy.rep[1] = ddict->entropy.rep[1];
+ dstDCtx->entropy.rep[2] = ddict->entropy.rep[2];
+ } else {
+ dstDCtx->litEntropy = 0;
+ dstDCtx->fseEntropy = 0;
+ }
+ }
+}
+
+static size_t ZSTD_loadEntropy_inDDict(ZSTD_DDict* ddict)
+{
+ ddict->dictID = 0;
+ ddict->entropyPresent = 0;
+ if (ddict->dictSize < 8) return 0;
+ { U32 const magic = MEM_readLE32(ddict->dictContent);
+ if (magic != ZSTD_DICT_MAGIC) return 0; /* pure content mode */
+ }
+ ddict->dictID = MEM_readLE32((const char*)ddict->dictContent + 4);
+
+ /* load entropy tables */
+ CHECK_E( ZSTD_loadEntropy(&ddict->entropy, ddict->dictContent, ddict->dictSize), dictionary_corrupted );
+ ddict->entropyPresent = 1;
+ return 0;
+}
+
+
+ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize, unsigned byReference, ZSTD_customMem customMem)
+{
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ { ZSTD_DDict* const ddict = (ZSTD_DDict*) ZSTD_malloc(sizeof(ZSTD_DDict), customMem);
+ if (!ddict) return NULL;
+ ddict->cMem = customMem;
+
+ if ((byReference) || (!dict) || (!dictSize)) {
+ ddict->dictBuffer = NULL;
+ ddict->dictContent = dict;
+ } else {
+ void* const internalBuffer = ZSTD_malloc(dictSize, customMem);
+ if (!internalBuffer) { ZSTD_freeDDict(ddict); return NULL; }
+ memcpy(internalBuffer, dict, dictSize);
+ ddict->dictBuffer = internalBuffer;
+ ddict->dictContent = internalBuffer;
+ }
+ ddict->dictSize = dictSize;
+ ddict->entropy.hufTable[0] = (HUF_DTable)((HufLog)*0x1000001); /* cover both little and big endian */
+ /* parse dictionary content */
+ { size_t const errorCode = ZSTD_loadEntropy_inDDict(ddict);
+ if (ZSTD_isError(errorCode)) {
+ ZSTD_freeDDict(ddict);
+ return NULL;
+ } }
+
+ return ddict;
+ }
+}
+
+/*! ZSTD_createDDict() :
+* Create a digested dictionary, to start decompression without startup delay.
+* `dict` content is copied inside DDict.
+* Consequently, `dict` can be released after `ZSTD_DDict` creation */
+ZSTD_DDict* ZSTD_createDDict(const void* dict, size_t dictSize)
+{
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
+ return ZSTD_createDDict_advanced(dict, dictSize, 0, allocator);
+}
+
+
+/*! ZSTD_createDDict_byReference() :
+ * Create a digested dictionary, to start decompression without startup delay.
+ * Dictionary content is simply referenced, it will be accessed during decompression.
+ * Warning : dictBuffer must outlive DDict (DDict must be freed before dictBuffer) */
+ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize)
+{
+ ZSTD_customMem const allocator = { NULL, NULL, NULL };
+ return ZSTD_createDDict_advanced(dictBuffer, dictSize, 1, allocator);
+}
+
+
+size_t ZSTD_freeDDict(ZSTD_DDict* ddict)
+{
+ if (ddict==NULL) return 0; /* support free on NULL */
+ { ZSTD_customMem const cMem = ddict->cMem;
+ ZSTD_free(ddict->dictBuffer, cMem);
+ ZSTD_free(ddict, cMem);
+ return 0;
+ }
+}
+
+size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict)
+{
+ if (ddict==NULL) return 0; /* support sizeof on NULL */
+ return sizeof(*ddict) + (ddict->dictBuffer ? ddict->dictSize : 0) ;
+}
+
+/*! ZSTD_getDictID_fromDict() :
+ * Provides the dictID stored within dictionary.
+ * if @return == 0, the dictionary is not conformant with Zstandard specification.
+ * It can still be loaded, but as a content-only dictionary. */
+unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize)
+{
+ if (dictSize < 8) return 0;
+ if (MEM_readLE32(dict) != ZSTD_DICT_MAGIC) return 0;
+ return MEM_readLE32((const char*)dict + 4);
+}
+
+/*! ZSTD_getDictID_fromDDict() :
+ * Provides the dictID of the dictionary loaded into `ddict`.
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
+unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict)
+{
+ if (ddict==NULL) return 0;
+ return ZSTD_getDictID_fromDict(ddict->dictContent, ddict->dictSize);
+}
+
+/*! ZSTD_getDictID_fromFrame() :
+ * Provides the dictID required to decompresse frame stored within `src`.
+ * If @return == 0, the dictID could not be decoded.
+ * This could for one of the following reasons :
+ * - The frame does not require a dictionary (most common case).
+ * - The frame was built with dictID intentionally removed.
+ * Needed dictionary is a hidden information.
+ * Note : this use case also happens when using a non-conformant dictionary.
+ * - `srcSize` is too small, and as a result, frame header could not be decoded.
+ * Note : possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`.
+ * - This is not a Zstandard frame.
+ * When identifying the exact failure cause, it's possible to use
+ * ZSTD_getFrameParams(), which will provide a more precise error code. */
+unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize)
+{
+ ZSTD_frameParams zfp = { 0 , 0 , 0 , 0 };
+ size_t const hError = ZSTD_getFrameParams(&zfp, src, srcSize);
+ if (ZSTD_isError(hError)) return 0;
+ return zfp.dictID;
+}
+
+
+/*! ZSTD_decompress_usingDDict() :
+* Decompression using a pre-digested Dictionary
+* Use dictionary without significant overhead. */
+size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_DDict* ddict)
+{
+ /* pass content and size in case legacy frames are encountered */
+ return ZSTD_decompressMultiFrame(dctx, dst, dstCapacity, src, srcSize,
+ NULL, 0,
+ ddict);
+}
+
+
+/*=====================================
+* Streaming decompression
+*====================================*/
+
+typedef enum { zdss_init, zdss_loadHeader,
+ zdss_read, zdss_load, zdss_flush } ZSTD_dStreamStage;
+
+/* *** Resource management *** */
+struct ZSTD_DStream_s {
+ ZSTD_DCtx* dctx;
+ ZSTD_DDict* ddictLocal;
+ const ZSTD_DDict* ddict;
+ ZSTD_frameParams fParams;
+ ZSTD_dStreamStage stage;
+ char* inBuff;
+ size_t inBuffSize;
+ size_t inPos;
+ size_t maxWindowSize;
+ char* outBuff;
+ size_t outBuffSize;
+ size_t outStart;
+ size_t outEnd;
+ size_t blockSize;
+ BYTE headerBuffer[ZSTD_FRAMEHEADERSIZE_MAX]; /* tmp buffer to store frame header */
+ size_t lhSize;
+ ZSTD_customMem customMem;
+ void* legacyContext;
+ U32 previousLegacyVersion;
+ U32 legacyVersion;
+ U32 hostageByte;
+}; /* typedef'd to ZSTD_DStream within "zstd.h" */
+
+
+ZSTD_DStream* ZSTD_createDStream(void)
+{
+ return ZSTD_createDStream_advanced(defaultCustomMem);
+}
+
+ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem)
+{
+ ZSTD_DStream* zds;
+
+ if (!customMem.customAlloc && !customMem.customFree) customMem = defaultCustomMem;
+ if (!customMem.customAlloc || !customMem.customFree) return NULL;
+
+ zds = (ZSTD_DStream*) ZSTD_malloc(sizeof(ZSTD_DStream), customMem);
+ if (zds==NULL) return NULL;
+ memset(zds, 0, sizeof(ZSTD_DStream));
+ memcpy(&zds->customMem, &customMem, sizeof(ZSTD_customMem));
+ zds->dctx = ZSTD_createDCtx_advanced(customMem);
+ if (zds->dctx == NULL) { ZSTD_freeDStream(zds); return NULL; }
+ zds->stage = zdss_init;
+ zds->maxWindowSize = ZSTD_MAXWINDOWSIZE_DEFAULT;
+ return zds;
+}
+
+size_t ZSTD_freeDStream(ZSTD_DStream* zds)
+{
+ if (zds==NULL) return 0; /* support free on null */
+ { ZSTD_customMem const cMem = zds->customMem;
+ ZSTD_freeDCtx(zds->dctx);
+ zds->dctx = NULL;
+ ZSTD_freeDDict(zds->ddictLocal);
+ zds->ddictLocal = NULL;
+ ZSTD_free(zds->inBuff, cMem);
+ zds->inBuff = NULL;
+ ZSTD_free(zds->outBuff, cMem);
+ zds->outBuff = NULL;
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT >= 1)
+ if (zds->legacyContext)
+ ZSTD_freeLegacyStreamContext(zds->legacyContext, zds->previousLegacyVersion);
+#endif
+ ZSTD_free(zds, cMem);
+ return 0;
+ }
+}
+
+
+/* *** Initialization *** */
+
+size_t ZSTD_DStreamInSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX + ZSTD_blockHeaderSize; }
+size_t ZSTD_DStreamOutSize(void) { return ZSTD_BLOCKSIZE_ABSOLUTEMAX; }
+
+size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize)
+{
+ zds->stage = zdss_loadHeader;
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
+ ZSTD_freeDDict(zds->ddictLocal);
+ if (dict && dictSize >= 8) {
+ zds->ddictLocal = ZSTD_createDDict(dict, dictSize);
+ if (zds->ddictLocal == NULL) return ERROR(memory_allocation);
+ } else zds->ddictLocal = NULL;
+ zds->ddict = zds->ddictLocal;
+ zds->legacyVersion = 0;
+ zds->hostageByte = 0;
+ return ZSTD_frameHeaderSize_prefix;
+}
+
+size_t ZSTD_initDStream(ZSTD_DStream* zds)
+{
+ return ZSTD_initDStream_usingDict(zds, NULL, 0);
+}
+
+/* ZSTD_initDStream_usingDDict() :
+ * ddict will just be referenced, and must outlive decompression session */
+size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict)
+{
+ size_t const initResult = ZSTD_initDStream(zds);
+ zds->ddict = ddict;
+ return initResult;
+}
+
+size_t ZSTD_resetDStream(ZSTD_DStream* zds)
+{
+ zds->stage = zdss_loadHeader;
+ zds->lhSize = zds->inPos = zds->outStart = zds->outEnd = 0;
+ zds->legacyVersion = 0;
+ zds->hostageByte = 0;
+ return ZSTD_frameHeaderSize_prefix;
+}
+
+size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds,
+ ZSTD_DStreamParameter_e paramType, unsigned paramValue)
+{
+ switch(paramType)
+ {
+ default : return ERROR(parameter_unknown);
+ case DStream_p_maxWindowSize : zds->maxWindowSize = paramValue ? paramValue : (U32)(-1); break;
+ }
+ return 0;
+}
+
+
+size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds)
+{
+ if (zds==NULL) return 0; /* support sizeof NULL */
+ return sizeof(*zds)
+ + ZSTD_sizeof_DCtx(zds->dctx)
+ + ZSTD_sizeof_DDict(zds->ddictLocal)
+ + zds->inBuffSize + zds->outBuffSize;
+}
+
+
+/* ***** Decompression ***** */
+
+MEM_STATIC size_t ZSTD_limitCopy(void* dst, size_t dstCapacity, const void* src, size_t srcSize)
+{
+ size_t const length = MIN(dstCapacity, srcSize);
+ memcpy(dst, src, length);
+ return length;
+}
+
+
+size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input)
+{
+ const char* const istart = (const char*)(input->src) + input->pos;
+ const char* const iend = (const char*)(input->src) + input->size;
+ const char* ip = istart;
+ char* const ostart = (char*)(output->dst) + output->pos;
+ char* const oend = (char*)(output->dst) + output->size;
+ char* op = ostart;
+ U32 someMoreWork = 1;
+
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
+ if (zds->legacyVersion)
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
+#endif
+
+ while (someMoreWork) {
+ switch(zds->stage)
+ {
+ case zdss_init :
+ ZSTD_resetDStream(zds); /* transparent reset on starting decoding a new frame */
+ /* fall-through */
+
+ case zdss_loadHeader :
+ { size_t const hSize = ZSTD_getFrameParams(&zds->fParams, zds->headerBuffer, zds->lhSize);
+ if (ZSTD_isError(hSize))
+#if defined(ZSTD_LEGACY_SUPPORT) && (ZSTD_LEGACY_SUPPORT>=1)
+ { U32 const legacyVersion = ZSTD_isLegacy(istart, iend-istart);
+ if (legacyVersion) {
+ const void* const dict = zds->ddict ? zds->ddict->dictContent : NULL;
+ size_t const dictSize = zds->ddict ? zds->ddict->dictSize : 0;
+ CHECK_F(ZSTD_initLegacyStream(&zds->legacyContext, zds->previousLegacyVersion, legacyVersion,
+ dict, dictSize));
+ zds->legacyVersion = zds->previousLegacyVersion = legacyVersion;
+ return ZSTD_decompressLegacyStream(zds->legacyContext, zds->legacyVersion, output, input);
+ } else {
+ return hSize; /* error */
+ } }
+#else
+ return hSize;
+#endif
+ if (hSize != 0) { /* need more input */
+ size_t const toLoad = hSize - zds->lhSize; /* if hSize!=0, hSize > zds->lhSize */
+ if (toLoad > (size_t)(iend-ip)) { /* not enough input to load full header */
+ memcpy(zds->headerBuffer + zds->lhSize, ip, iend-ip);
+ zds->lhSize += iend-ip;
+ input->pos = input->size;
+ return (MAX(ZSTD_frameHeaderSize_min, hSize) - zds->lhSize) + ZSTD_blockHeaderSize; /* remaining header bytes + next block header */
+ }
+ memcpy(zds->headerBuffer + zds->lhSize, ip, toLoad); zds->lhSize = hSize; ip += toLoad;
+ break;
+ } }
+
+ /* check for single-pass mode opportunity */
+ if (zds->fParams.frameContentSize && zds->fParams.windowSize /* skippable frame if == 0 */
+ && (U64)(size_t)(oend-op) >= zds->fParams.frameContentSize) {
+ size_t const cSize = ZSTD_findFrameCompressedSize(istart, iend-istart);
+ if (cSize <= (size_t)(iend-istart)) {
+ size_t const decompressedSize = ZSTD_decompress_usingDDict(zds->dctx, op, oend-op, istart, cSize, zds->ddict);
+ if (ZSTD_isError(decompressedSize)) return decompressedSize;
+ ip = istart + cSize;
+ op += decompressedSize;
+ zds->dctx->expected = 0;
+ zds->stage = zdss_init;
+ someMoreWork = 0;
+ break;
+ } }
+
+ /* Consume header */
+ ZSTD_refDDict(zds->dctx, zds->ddict);
+ { size_t const h1Size = ZSTD_nextSrcSizeToDecompress(zds->dctx); /* == ZSTD_frameHeaderSize_prefix */
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer, h1Size));
+ { size_t const h2Size = ZSTD_nextSrcSizeToDecompress(zds->dctx);
+ CHECK_F(ZSTD_decompressContinue(zds->dctx, NULL, 0, zds->headerBuffer+h1Size, h2Size));
+ } }
+
+ zds->fParams.windowSize = MAX(zds->fParams.windowSize, 1U << ZSTD_WINDOWLOG_ABSOLUTEMIN);
+ if (zds->fParams.windowSize > zds->maxWindowSize) return ERROR(frameParameter_windowTooLarge);
+
+ /* Adapt buffer sizes to frame header instructions */
+ { size_t const blockSize = MIN(zds->fParams.windowSize, ZSTD_BLOCKSIZE_ABSOLUTEMAX);
+ size_t const neededOutSize = zds->fParams.windowSize + blockSize + WILDCOPY_OVERLENGTH * 2;
+ zds->blockSize = blockSize;
+ if (zds->inBuffSize < blockSize) {
+ ZSTD_free(zds->inBuff, zds->customMem);
+ zds->inBuffSize = 0;
+ zds->inBuff = (char*)ZSTD_malloc(blockSize, zds->customMem);
+ if (zds->inBuff == NULL) return ERROR(memory_allocation);
+ zds->inBuffSize = blockSize;
+ }
+ if (zds->outBuffSize < neededOutSize) {
+ ZSTD_free(zds->outBuff, zds->customMem);
+ zds->outBuffSize = 0;
+ zds->outBuff = (char*)ZSTD_malloc(neededOutSize, zds->customMem);
+ if (zds->outBuff == NULL) return ERROR(memory_allocation);
+ zds->outBuffSize = neededOutSize;
+ } }
+ zds->stage = zdss_read;
+ /* pass-through */
+
+ case zdss_read:
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
+ if (neededInSize==0) { /* end of frame */
+ zds->stage = zdss_init;
+ someMoreWork = 0;
+ break;
+ }
+ if ((size_t)(iend-ip) >= neededInSize) { /* decode directly from src */
+ const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
+ zds->outBuff + zds->outStart, (isSkipFrame ? 0 : zds->outBuffSize - zds->outStart),
+ ip, neededInSize);
+ if (ZSTD_isError(decodedSize)) return decodedSize;
+ ip += neededInSize;
+ if (!decodedSize && !isSkipFrame) break; /* this was just a header */
+ zds->outEnd = zds->outStart + decodedSize;
+ zds->stage = zdss_flush;
+ break;
+ }
+ if (ip==iend) { someMoreWork = 0; break; } /* no more input */
+ zds->stage = zdss_load;
+ /* pass-through */
+ }
+
+ case zdss_load:
+ { size_t const neededInSize = ZSTD_nextSrcSizeToDecompress(zds->dctx);
+ size_t const toLoad = neededInSize - zds->inPos; /* should always be <= remaining space within inBuff */
+ size_t loadedSize;
+ if (toLoad > zds->inBuffSize - zds->inPos) return ERROR(corruption_detected); /* should never happen */
+ loadedSize = ZSTD_limitCopy(zds->inBuff + zds->inPos, toLoad, ip, iend-ip);
+ ip += loadedSize;
+ zds->inPos += loadedSize;
+ if (loadedSize < toLoad) { someMoreWork = 0; break; } /* not enough input, wait for more */
+
+ /* decode loaded input */
+ { const int isSkipFrame = ZSTD_isSkipFrame(zds->dctx);
+ size_t const decodedSize = ZSTD_decompressContinue(zds->dctx,
+ zds->outBuff + zds->outStart, zds->outBuffSize - zds->outStart,
+ zds->inBuff, neededInSize);
+ if (ZSTD_isError(decodedSize)) return decodedSize;
+ zds->inPos = 0; /* input is consumed */
+ if (!decodedSize && !isSkipFrame) { zds->stage = zdss_read; break; } /* this was just a header */
+ zds->outEnd = zds->outStart + decodedSize;
+ zds->stage = zdss_flush;
+ /* pass-through */
+ } }
+
+ case zdss_flush:
+ { size_t const toFlushSize = zds->outEnd - zds->outStart;
+ size_t const flushedSize = ZSTD_limitCopy(op, oend-op, zds->outBuff + zds->outStart, toFlushSize);
+ op += flushedSize;
+ zds->outStart += flushedSize;
+ if (flushedSize == toFlushSize) { /* flush completed */
+ zds->stage = zdss_read;
+ if (zds->outStart + zds->blockSize > zds->outBuffSize)
+ zds->outStart = zds->outEnd = 0;
+ break;
+ }
+ /* cannot complete flush */
+ someMoreWork = 0;
+ break;
+ }
+ default: return ERROR(GENERIC); /* impossible */
+ } }
+
+ /* result */
+ input->pos += (size_t)(ip-istart);
+ output->pos += (size_t)(op-ostart);
+ { size_t nextSrcSizeHint = ZSTD_nextSrcSizeToDecompress(zds->dctx);
+ if (!nextSrcSizeHint) { /* frame fully decoded */
+ if (zds->outEnd == zds->outStart) { /* output fully flushed */
+ if (zds->hostageByte) {
+ if (input->pos >= input->size) { zds->stage = zdss_read; return 1; } /* can't release hostage (not present) */
+ input->pos++; /* release hostage */
+ }
+ return 0;
+ }
+ if (!zds->hostageByte) { /* output not fully flushed; keep last byte as hostage; will be released when all output is flushed */
+ input->pos--; /* note : pos > 0, otherwise, impossible to finish reading last block */
+ zds->hostageByte=1;
+ }
+ return 1;
+ }
+ nextSrcSizeHint += ZSTD_blockHeaderSize * (ZSTD_nextInputType(zds->dctx) == ZSTDnit_block); /* preload header of next block */
+ if (zds->inPos > nextSrcSizeHint) return ERROR(GENERIC); /* should never happen */
+ nextSrcSizeHint -= zds->inPos; /* already loaded*/
+ return nextSrcSizeHint;
+ }
+}
diff --git a/thirdparty/zstd/zstd.h b/thirdparty/zstd/zstd.h
new file mode 100644
index 0000000000..f8050c1361
--- /dev/null
+++ b/thirdparty/zstd/zstd.h
@@ -0,0 +1,795 @@
+/*
+ * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#ifndef ZSTD_H_235446
+#define ZSTD_H_235446
+
+/* ====== Dependency ======*/
+#include <stddef.h> /* size_t */
+
+
+/* ===== ZSTDLIB_API : control library symbols visibility ===== */
+#if defined(__GNUC__) && (__GNUC__ >= 4)
+# define ZSTDLIB_VISIBILITY __attribute__ ((visibility ("default")))
+#else
+# define ZSTDLIB_VISIBILITY
+#endif
+#if defined(ZSTD_DLL_EXPORT) && (ZSTD_DLL_EXPORT==1)
+# define ZSTDLIB_API __declspec(dllexport) ZSTDLIB_VISIBILITY
+#elif defined(ZSTD_DLL_IMPORT) && (ZSTD_DLL_IMPORT==1)
+# define ZSTDLIB_API __declspec(dllimport) ZSTDLIB_VISIBILITY /* It isn't required but allows to generate better code, saving a function pointer load from the IAT and an indirect jump.*/
+#else
+# define ZSTDLIB_API ZSTDLIB_VISIBILITY
+#endif
+
+
+/*******************************************************************************************************
+ Introduction
+
+ zstd, short for Zstandard, is a fast lossless compression algorithm, targeting real-time compression scenarios
+ at zlib-level and better compression ratios. The zstd compression library provides in-memory compression and
+ decompression functions. The library supports compression levels from 1 up to ZSTD_maxCLevel() which is 22.
+ Levels >= 20, labeled `--ultra`, should be used with caution, as they require more memory.
+ Compression can be done in:
+ - a single step (described as Simple API)
+ - a single step, reusing a context (described as Explicit memory management)
+ - unbounded multiple steps (described as Streaming compression)
+ The compression ratio achievable on small data can be highly improved using compression with a dictionary in:
+ - a single step (described as Simple dictionary API)
+ - a single step, reusing a dictionary (described as Fast dictionary API)
+
+ Advanced experimental functions can be accessed using #define ZSTD_STATIC_LINKING_ONLY before including zstd.h.
+ These APIs shall never be used with a dynamic library.
+ They are not "stable", their definition may change in the future. Only static linking is allowed.
+*********************************************************************************************************/
+
+/*------ Version ------*/
+#define ZSTD_VERSION_MAJOR 1
+#define ZSTD_VERSION_MINOR 2
+#define ZSTD_VERSION_RELEASE 0
+
+#define ZSTD_LIB_VERSION ZSTD_VERSION_MAJOR.ZSTD_VERSION_MINOR.ZSTD_VERSION_RELEASE
+#define ZSTD_QUOTE(str) #str
+#define ZSTD_EXPAND_AND_QUOTE(str) ZSTD_QUOTE(str)
+#define ZSTD_VERSION_STRING ZSTD_EXPAND_AND_QUOTE(ZSTD_LIB_VERSION)
+
+#define ZSTD_VERSION_NUMBER (ZSTD_VERSION_MAJOR *100*100 + ZSTD_VERSION_MINOR *100 + ZSTD_VERSION_RELEASE)
+ZSTDLIB_API unsigned ZSTD_versionNumber(void); /**< library version number; to be used when checking dll version */
+
+
+/***************************************
+* Simple API
+***************************************/
+/*! ZSTD_compress() :
+ * Compresses `src` content as a single zstd compressed frame into already allocated `dst`.
+ * Hint : compression runs faster if `dstCapacity` >= `ZSTD_compressBound(srcSize)`.
+ * @return : compressed size written into `dst` (<= `dstCapacity),
+ * or an error code if it fails (which can be tested using ZSTD_isError()). */
+ZSTDLIB_API size_t ZSTD_compress( void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ int compressionLevel);
+
+/*! ZSTD_decompress() :
+ * `compressedSize` : must be the _exact_ size of some number of compressed and/or skippable frames.
+ * `dstCapacity` is an upper bound of originalSize.
+ * If user cannot imply a maximum upper bound, it's better to use streaming mode to decompress data.
+ * @return : the number of bytes decompressed into `dst` (<= `dstCapacity`),
+ * or an errorCode if it fails (which can be tested using ZSTD_isError()). */
+ZSTDLIB_API size_t ZSTD_decompress( void* dst, size_t dstCapacity,
+ const void* src, size_t compressedSize);
+
+/*! ZSTD_getDecompressedSize() :
+ * NOTE: This function is planned to be obsolete, in favour of ZSTD_getFrameContentSize.
+ * ZSTD_getFrameContentSize functions the same way, returning the decompressed size of a single
+ * frame, but distinguishes empty frames from frames with an unknown size, or errors.
+ *
+ * Additionally, ZSTD_findDecompressedSize can be used instead. It can handle multiple
+ * concatenated frames in one buffer, and so is more general.
+ * As a result however, it requires more computation and entire frames to be passed to it,
+ * as opposed to ZSTD_getFrameContentSize which requires only a single frame's header.
+ *
+ * 'src' is the start of a zstd compressed frame.
+ * @return : content size to be decompressed, as a 64-bits value _if known_, 0 otherwise.
+ * note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
+ * When `return==0`, data to decompress could be any size.
+ * In which case, it's necessary to use streaming mode to decompress data.
+ * Optionally, application can still use ZSTD_decompress() while relying on implied limits.
+ * (For example, data may be necessarily cut into blocks <= 16 KB).
+ * note 2 : decompressed size is always present when compression is done with ZSTD_compress()
+ * note 3 : decompressed size can be very large (64-bits value),
+ * potentially larger than what local system can handle as a single memory segment.
+ * In which case, it's necessary to use streaming mode to decompress data.
+ * note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
+ * Always ensure result fits within application's authorized limits.
+ * Each application can set its own limits.
+ * note 5 : when `return==0`, if precise failure cause is needed, use ZSTD_getFrameParams() to know more. */
+ZSTDLIB_API unsigned long long ZSTD_getDecompressedSize(const void* src, size_t srcSize);
+
+
+/*====== Helper functions ======*/
+ZSTDLIB_API int ZSTD_maxCLevel(void); /*!< maximum compression level available */
+ZSTDLIB_API size_t ZSTD_compressBound(size_t srcSize); /*!< maximum compressed size in worst case scenario */
+ZSTDLIB_API unsigned ZSTD_isError(size_t code); /*!< tells if a `size_t` function result is an error code */
+ZSTDLIB_API const char* ZSTD_getErrorName(size_t code); /*!< provides readable string from an error code */
+
+
+/***************************************
+* Explicit memory management
+***************************************/
+/*= Compression context
+ * When compressing many times,
+ * it is recommended to allocate a context just once, and re-use it for each successive compression operation.
+ * This will make workload friendlier for system's memory.
+ * Use one context per thread for parallel execution in multi-threaded environments. */
+typedef struct ZSTD_CCtx_s ZSTD_CCtx;
+ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx(void);
+ZSTDLIB_API size_t ZSTD_freeCCtx(ZSTD_CCtx* cctx);
+
+/*! ZSTD_compressCCtx() :
+ * Same as ZSTD_compress(), requires an allocated ZSTD_CCtx (see ZSTD_createCCtx()). */
+ZSTDLIB_API size_t ZSTD_compressCCtx(ZSTD_CCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize, int compressionLevel);
+
+/*= Decompression context
+ * When decompressing many times,
+ * it is recommended to allocate a context just once, and re-use it for each successive compression operation.
+ * This will make workload friendlier for system's memory.
+ * Use one context per thread for parallel execution in multi-threaded environments. */
+typedef struct ZSTD_DCtx_s ZSTD_DCtx;
+ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx(void);
+ZSTDLIB_API size_t ZSTD_freeDCtx(ZSTD_DCtx* dctx);
+
+/*! ZSTD_decompressDCtx() :
+ * Same as ZSTD_decompress(), requires an allocated ZSTD_DCtx (see ZSTD_createDCtx()). */
+ZSTDLIB_API size_t ZSTD_decompressDCtx(ZSTD_DCtx* ctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+
+/**************************
+* Simple dictionary API
+***************************/
+/*! ZSTD_compress_usingDict() :
+* Compression using a predefined Dictionary (see dictBuilder/zdict.h).
+* Note : This function loads the dictionary, resulting in significant startup delay.
+* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
+ZSTDLIB_API size_t ZSTD_compress_usingDict(ZSTD_CCtx* ctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ int compressionLevel);
+
+/*! ZSTD_decompress_usingDict() :
+* Decompression using a predefined Dictionary (see dictBuilder/zdict.h).
+* Dictionary must be identical to the one used during compression.
+* Note : This function loads the dictionary, resulting in significant startup delay.
+* Note : When `dict == NULL || dictSize < 8` no dictionary is used. */
+ZSTDLIB_API size_t ZSTD_decompress_usingDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize);
+
+
+/****************************
+* Fast dictionary API
+****************************/
+typedef struct ZSTD_CDict_s ZSTD_CDict;
+
+/*! ZSTD_createCDict() :
+* When compressing multiple messages / blocks with the same dictionary, it's recommended to load it just once.
+* ZSTD_createCDict() will create a digested dictionary, ready to start future compression operations without startup delay.
+* ZSTD_CDict can be created once and used by multiple threads concurrently, as its usage is read-only.
+* `dictBuffer` can be released after ZSTD_CDict creation, as its content is copied within CDict */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict(const void* dictBuffer, size_t dictSize, int compressionLevel);
+
+/*! ZSTD_freeCDict() :
+* Function frees memory allocated by ZSTD_createCDict(). */
+ZSTDLIB_API size_t ZSTD_freeCDict(ZSTD_CDict* CDict);
+
+/*! ZSTD_compress_usingCDict() :
+ * Compression using a digested Dictionary.
+ * Faster startup than ZSTD_compress_usingDict(), recommended when same dictionary is used multiple times.
+ * Note that compression level is decided during dictionary creation.
+ * Frame parameters are hardcoded (dictID=yes, contentSize=yes, checksum=no) */
+ZSTDLIB_API size_t ZSTD_compress_usingCDict(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict);
+
+
+typedef struct ZSTD_DDict_s ZSTD_DDict;
+
+/*! ZSTD_createDDict() :
+* Create a digested dictionary, ready to start decompression operation without startup delay.
+* dictBuffer can be released after DDict creation, as its content is copied inside DDict */
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict(const void* dictBuffer, size_t dictSize);
+
+/*! ZSTD_freeDDict() :
+* Function frees memory allocated with ZSTD_createDDict() */
+ZSTDLIB_API size_t ZSTD_freeDDict(ZSTD_DDict* ddict);
+
+/*! ZSTD_decompress_usingDDict() :
+* Decompression using a digested Dictionary.
+* Faster startup than ZSTD_decompress_usingDict(), recommended when same dictionary is used multiple times. */
+ZSTDLIB_API size_t ZSTD_decompress_usingDDict(ZSTD_DCtx* dctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_DDict* ddict);
+
+
+/****************************
+* Streaming
+****************************/
+
+typedef struct ZSTD_inBuffer_s {
+ const void* src; /**< start of input buffer */
+ size_t size; /**< size of input buffer */
+ size_t pos; /**< position where reading stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_inBuffer;
+
+typedef struct ZSTD_outBuffer_s {
+ void* dst; /**< start of output buffer */
+ size_t size; /**< size of output buffer */
+ size_t pos; /**< position where writing stopped. Will be updated. Necessarily 0 <= pos <= size */
+} ZSTD_outBuffer;
+
+
+
+/*-***********************************************************************
+* Streaming compression - HowTo
+*
+* A ZSTD_CStream object is required to track streaming operation.
+* Use ZSTD_createCStream() and ZSTD_freeCStream() to create/release resources.
+* ZSTD_CStream objects can be reused multiple times on consecutive compression operations.
+* It is recommended to re-use ZSTD_CStream in situations where many streaming operations will be achieved consecutively,
+* since it will play nicer with system's memory, by re-using already allocated memory.
+* Use one separate ZSTD_CStream per thread for parallel execution.
+*
+* Start a new compression by initializing ZSTD_CStream.
+* Use ZSTD_initCStream() to start a new compression operation.
+* Use ZSTD_initCStream_usingDict() or ZSTD_initCStream_usingCDict() for a compression which requires a dictionary (experimental section)
+*
+* Use ZSTD_compressStream() repetitively to consume input stream.
+* The function will automatically update both `pos` fields.
+* Note that it may not consume the entire input, in which case `pos < size`,
+* and it's up to the caller to present again remaining data.
+* @return : a size hint, preferred nb of bytes to use as input for next function call
+* or an error code, which can be tested using ZSTD_isError().
+* Note 1 : it's just a hint, to help latency a little, any other value will work fine.
+* Note 2 : size hint is guaranteed to be <= ZSTD_CStreamInSize()
+*
+* At any moment, it's possible to flush whatever data remains within internal buffer, using ZSTD_flushStream().
+* `output->pos` will be updated.
+* Note that some content might still be left within internal buffer if `output->size` is too small.
+* @return : nb of bytes still present within internal buffer (0 if it's empty)
+* or an error code, which can be tested using ZSTD_isError().
+*
+* ZSTD_endStream() instructs to finish a frame.
+* It will perform a flush and write frame epilogue.
+* The epilogue is required for decoders to consider a frame completed.
+* Similar to ZSTD_flushStream(), it may not be able to flush the full content if `output->size` is too small.
+* In which case, call again ZSTD_endStream() to complete the flush.
+* @return : nb of bytes still present within internal buffer (0 if it's empty, hence compression completed)
+* or an error code, which can be tested using ZSTD_isError().
+*
+* *******************************************************************/
+
+typedef struct ZSTD_CStream_s ZSTD_CStream;
+/*===== ZSTD_CStream management functions =====*/
+ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream(void);
+ZSTDLIB_API size_t ZSTD_freeCStream(ZSTD_CStream* zcs);
+
+/*===== Streaming compression functions =====*/
+ZSTDLIB_API size_t ZSTD_initCStream(ZSTD_CStream* zcs, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+ZSTDLIB_API size_t ZSTD_flushStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+ZSTDLIB_API size_t ZSTD_endStream(ZSTD_CStream* zcs, ZSTD_outBuffer* output);
+
+ZSTDLIB_API size_t ZSTD_CStreamInSize(void); /**< recommended size for input buffer */
+ZSTDLIB_API size_t ZSTD_CStreamOutSize(void); /**< recommended size for output buffer. Guarantee to successfully flush at least one complete compressed block in all circumstances. */
+
+
+
+/*-***************************************************************************
+* Streaming decompression - HowTo
+*
+* A ZSTD_DStream object is required to track streaming operations.
+* Use ZSTD_createDStream() and ZSTD_freeDStream() to create/release resources.
+* ZSTD_DStream objects can be re-used multiple times.
+*
+* Use ZSTD_initDStream() to start a new decompression operation,
+* or ZSTD_initDStream_usingDict() if decompression requires a dictionary.
+* @return : recommended first input size
+*
+* Use ZSTD_decompressStream() repetitively to consume your input.
+* The function will update both `pos` fields.
+* If `input.pos < input.size`, some input has not been consumed.
+* It's up to the caller to present again remaining data.
+* If `output.pos < output.size`, decoder has flushed everything it could.
+* @return : 0 when a frame is completely decoded and fully flushed,
+* an error code, which can be tested using ZSTD_isError(),
+* any other value > 0, which means there is still some decoding to do to complete current frame.
+* The return value is a suggested next input size (a hint to improve latency) that will never load more than the current frame.
+* *******************************************************************************/
+
+typedef struct ZSTD_DStream_s ZSTD_DStream;
+/*===== ZSTD_DStream management functions =====*/
+ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream(void);
+ZSTDLIB_API size_t ZSTD_freeDStream(ZSTD_DStream* zds);
+
+/*===== Streaming decompression functions =====*/
+ZSTDLIB_API size_t ZSTD_initDStream(ZSTD_DStream* zds);
+ZSTDLIB_API size_t ZSTD_decompressStream(ZSTD_DStream* zds, ZSTD_outBuffer* output, ZSTD_inBuffer* input);
+
+ZSTDLIB_API size_t ZSTD_DStreamInSize(void); /*!< recommended size for input buffer */
+ZSTDLIB_API size_t ZSTD_DStreamOutSize(void); /*!< recommended size for output buffer. Guarantee to successfully flush at least one complete block in all circumstances. */
+
+#endif /* ZSTD_H_235446 */
+
+
+#if defined(ZSTD_STATIC_LINKING_ONLY) && !defined(ZSTD_H_ZSTD_STATIC_LINKING_ONLY)
+#define ZSTD_H_ZSTD_STATIC_LINKING_ONLY
+
+/****************************************************************************************
+ * START OF ADVANCED AND EXPERIMENTAL FUNCTIONS
+ * The definitions in this section are considered experimental.
+ * They should never be used with a dynamic library, as they may change in the future.
+ * They are provided for advanced usages.
+ * Use them only in association with static linking.
+ * ***************************************************************************************/
+
+/* --- Constants ---*/
+#define ZSTD_MAGICNUMBER 0xFD2FB528 /* >= v0.8.0 */
+#define ZSTD_MAGIC_SKIPPABLE_START 0x184D2A50U
+
+#define ZSTD_CONTENTSIZE_UNKNOWN (0ULL - 1)
+#define ZSTD_CONTENTSIZE_ERROR (0ULL - 2)
+
+#define ZSTD_WINDOWLOG_MAX_32 27
+#define ZSTD_WINDOWLOG_MAX_64 27
+#define ZSTD_WINDOWLOG_MAX ((unsigned)(sizeof(size_t) == 4 ? ZSTD_WINDOWLOG_MAX_32 : ZSTD_WINDOWLOG_MAX_64))
+#define ZSTD_WINDOWLOG_MIN 10
+#define ZSTD_HASHLOG_MAX ZSTD_WINDOWLOG_MAX
+#define ZSTD_HASHLOG_MIN 6
+#define ZSTD_CHAINLOG_MAX (ZSTD_WINDOWLOG_MAX+1)
+#define ZSTD_CHAINLOG_MIN ZSTD_HASHLOG_MIN
+#define ZSTD_HASHLOG3_MAX 17
+#define ZSTD_SEARCHLOG_MAX (ZSTD_WINDOWLOG_MAX-1)
+#define ZSTD_SEARCHLOG_MIN 1
+#define ZSTD_SEARCHLENGTH_MAX 7 /* only for ZSTD_fast, other strategies are limited to 6 */
+#define ZSTD_SEARCHLENGTH_MIN 3 /* only for ZSTD_btopt, other strategies are limited to 4 */
+#define ZSTD_TARGETLENGTH_MIN 4
+#define ZSTD_TARGETLENGTH_MAX 999
+
+#define ZSTD_FRAMEHEADERSIZE_MAX 18 /* for static allocation */
+#define ZSTD_FRAMEHEADERSIZE_MIN 6
+static const size_t ZSTD_frameHeaderSize_prefix = 5;
+static const size_t ZSTD_frameHeaderSize_min = ZSTD_FRAMEHEADERSIZE_MIN;
+static const size_t ZSTD_frameHeaderSize_max = ZSTD_FRAMEHEADERSIZE_MAX;
+static const size_t ZSTD_skippableHeaderSize = 8; /* magic number + skippable frame length */
+
+
+/*--- Advanced types ---*/
+typedef enum { ZSTD_fast, ZSTD_dfast, ZSTD_greedy, ZSTD_lazy, ZSTD_lazy2, ZSTD_btlazy2, ZSTD_btopt, ZSTD_btopt2 } ZSTD_strategy; /* from faster to stronger */
+
+typedef struct {
+ unsigned windowLog; /**< largest match distance : larger == more compression, more memory needed during decompression */
+ unsigned chainLog; /**< fully searched segment : larger == more compression, slower, more memory (useless for fast) */
+ unsigned hashLog; /**< dispatch table : larger == faster, more memory */
+ unsigned searchLog; /**< nb of searches : larger == more compression, slower */
+ unsigned searchLength; /**< match length searched : larger == faster decompression, sometimes less compression */
+ unsigned targetLength; /**< acceptable match size for optimal parser (only) : larger == more compression, slower */
+ ZSTD_strategy strategy;
+} ZSTD_compressionParameters;
+
+typedef struct {
+ unsigned contentSizeFlag; /**< 1: content size will be in frame header (when known) */
+ unsigned checksumFlag; /**< 1: generate a 32-bits checksum at end of frame, for error detection */
+ unsigned noDictIDFlag; /**< 1: no dictID will be saved into frame header (if dictionary compression) */
+} ZSTD_frameParameters;
+
+typedef struct {
+ ZSTD_compressionParameters cParams;
+ ZSTD_frameParameters fParams;
+} ZSTD_parameters;
+
+/*= Custom memory allocation functions */
+typedef void* (*ZSTD_allocFunction) (void* opaque, size_t size);
+typedef void (*ZSTD_freeFunction) (void* opaque, void* address);
+typedef struct { ZSTD_allocFunction customAlloc; ZSTD_freeFunction customFree; void* opaque; } ZSTD_customMem;
+
+/***************************************
+* Compressed size functions
+***************************************/
+
+/*! ZSTD_findFrameCompressedSize() :
+ * `src` should point to the start of a ZSTD encoded frame or skippable frame
+ * `srcSize` must be at least as large as the frame
+ * @return : the compressed size of the frame pointed to by `src`, suitable to pass to
+ * `ZSTD_decompress` or similar, or an error code if given invalid input. */
+ZSTDLIB_API size_t ZSTD_findFrameCompressedSize(const void* src, size_t srcSize);
+
+/***************************************
+* Decompressed size functions
+***************************************/
+/*! ZSTD_getFrameContentSize() :
+* `src` should point to the start of a ZSTD encoded frame
+* `srcSize` must be at least as large as the frame header. A value greater than or equal
+* to `ZSTD_frameHeaderSize_max` is guaranteed to be large enough in all cases.
+* @return : decompressed size of the frame pointed to be `src` if known, otherwise
+* - ZSTD_CONTENTSIZE_UNKNOWN if the size cannot be determined
+* - ZSTD_CONTENTSIZE_ERROR if an error occurred (e.g. invalid magic number, srcSize too small) */
+ZSTDLIB_API unsigned long long ZSTD_getFrameContentSize(const void *src, size_t srcSize);
+
+/*! ZSTD_findDecompressedSize() :
+* `src` should point the start of a series of ZSTD encoded and/or skippable frames
+* `srcSize` must be the _exact_ size of this series
+* (i.e. there should be a frame boundary exactly `srcSize` bytes after `src`)
+* @return : the decompressed size of all data in the contained frames, as a 64-bit value _if known_
+* - if the decompressed size cannot be determined: ZSTD_CONTENTSIZE_UNKNOWN
+* - if an error occurred: ZSTD_CONTENTSIZE_ERROR
+*
+* note 1 : decompressed size is an optional field, that may not be present, especially in streaming mode.
+* When `return==ZSTD_CONTENTSIZE_UNKNOWN`, data to decompress could be any size.
+* In which case, it's necessary to use streaming mode to decompress data.
+* Optionally, application can still use ZSTD_decompress() while relying on implied limits.
+* (For example, data may be necessarily cut into blocks <= 16 KB).
+* note 2 : decompressed size is always present when compression is done with ZSTD_compress()
+* note 3 : decompressed size can be very large (64-bits value),
+* potentially larger than what local system can handle as a single memory segment.
+* In which case, it's necessary to use streaming mode to decompress data.
+* note 4 : If source is untrusted, decompressed size could be wrong or intentionally modified.
+* Always ensure result fits within application's authorized limits.
+* Each application can set its own limits.
+* note 5 : ZSTD_findDecompressedSize handles multiple frames, and so it must traverse the input to
+* read each contained frame header. This is efficient as most of the data is skipped,
+* however it does mean that all frame data must be present and valid. */
+ZSTDLIB_API unsigned long long ZSTD_findDecompressedSize(const void* src, size_t srcSize);
+
+
+/***************************************
+* Advanced compression functions
+***************************************/
+/*! ZSTD_estimateCCtxSize() :
+ * Gives the amount of memory allocated for a ZSTD_CCtx given a set of compression parameters.
+ * `frameContentSize` is an optional parameter, provide `0` if unknown */
+ZSTDLIB_API size_t ZSTD_estimateCCtxSize(ZSTD_compressionParameters cParams);
+
+/*! ZSTD_createCCtx_advanced() :
+ * Create a ZSTD compression context using external alloc and free functions */
+ZSTDLIB_API ZSTD_CCtx* ZSTD_createCCtx_advanced(ZSTD_customMem customMem);
+
+/*! ZSTD_sizeofCCtx() :
+ * Gives the amount of memory used by a given ZSTD_CCtx */
+ZSTDLIB_API size_t ZSTD_sizeof_CCtx(const ZSTD_CCtx* cctx);
+
+typedef enum {
+ ZSTD_p_forceWindow, /* Force back-references to remain < windowSize, even when referencing Dictionary content (default:0) */
+ ZSTD_p_forceRawDict /* Force loading dictionary in "content-only" mode (no header analysis) */
+} ZSTD_CCtxParameter;
+/*! ZSTD_setCCtxParameter() :
+ * Set advanced parameters, selected through enum ZSTD_CCtxParameter
+ * @result : 0, or an error code (which can be tested with ZSTD_isError()) */
+ZSTDLIB_API size_t ZSTD_setCCtxParameter(ZSTD_CCtx* cctx, ZSTD_CCtxParameter param, unsigned value);
+
+/*! ZSTD_createCDict_byReference() :
+ * Create a digested dictionary for compression
+ * Dictionary content is simply referenced, and therefore stays in dictBuffer.
+ * It is important that dictBuffer outlives CDict, it must remain read accessible throughout the lifetime of CDict */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_byReference(const void* dictBuffer, size_t dictSize, int compressionLevel);
+
+/*! ZSTD_createCDict_advanced() :
+ * Create a ZSTD_CDict using external alloc and free, and customized compression parameters */
+ZSTDLIB_API ZSTD_CDict* ZSTD_createCDict_advanced(const void* dict, size_t dictSize, unsigned byReference,
+ ZSTD_compressionParameters cParams, ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_CDict() :
+ * Gives the amount of memory used by a given ZSTD_sizeof_CDict */
+ZSTDLIB_API size_t ZSTD_sizeof_CDict(const ZSTD_CDict* cdict);
+
+/*! ZSTD_getCParams() :
+* @return ZSTD_compressionParameters structure for a selected compression level and estimated srcSize.
+* `estimatedSrcSize` value is optional, select 0 if not known */
+ZSTDLIB_API ZSTD_compressionParameters ZSTD_getCParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+
+/*! ZSTD_getParams() :
+* same as ZSTD_getCParams(), but @return a full `ZSTD_parameters` object instead of sub-component `ZSTD_compressionParameters`.
+* All fields of `ZSTD_frameParameters` are set to default (0) */
+ZSTDLIB_API ZSTD_parameters ZSTD_getParams(int compressionLevel, unsigned long long estimatedSrcSize, size_t dictSize);
+
+/*! ZSTD_checkCParams() :
+* Ensure param values remain within authorized range */
+ZSTDLIB_API size_t ZSTD_checkCParams(ZSTD_compressionParameters params);
+
+/*! ZSTD_adjustCParams() :
+* optimize params for a given `srcSize` and `dictSize`.
+* both values are optional, select `0` if unknown. */
+ZSTDLIB_API ZSTD_compressionParameters ZSTD_adjustCParams(ZSTD_compressionParameters cPar, unsigned long long srcSize, size_t dictSize);
+
+/*! ZSTD_compress_advanced() :
+* Same as ZSTD_compress_usingDict(), with fine-tune control over each compression parameter */
+ZSTDLIB_API size_t ZSTD_compress_advanced (ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const void* dict,size_t dictSize,
+ ZSTD_parameters params);
+
+/*! ZSTD_compress_usingCDict_advanced() :
+* Same as ZSTD_compress_usingCDict(), with fine-tune control over frame parameters */
+ZSTDLIB_API size_t ZSTD_compress_usingCDict_advanced(ZSTD_CCtx* cctx,
+ void* dst, size_t dstCapacity,
+ const void* src, size_t srcSize,
+ const ZSTD_CDict* cdict, ZSTD_frameParameters fParams);
+
+
+/*--- Advanced decompression functions ---*/
+
+/*! ZSTD_isFrame() :
+ * Tells if the content of `buffer` starts with a valid Frame Identifier.
+ * Note : Frame Identifier is 4 bytes. If `size < 4`, @return will always be 0.
+ * Note 2 : Legacy Frame Identifiers are considered valid only if Legacy Support is enabled.
+ * Note 3 : Skippable Frame Identifiers are considered valid. */
+ZSTDLIB_API unsigned ZSTD_isFrame(const void* buffer, size_t size);
+
+/*! ZSTD_estimateDCtxSize() :
+ * Gives the potential amount of memory allocated to create a ZSTD_DCtx */
+ZSTDLIB_API size_t ZSTD_estimateDCtxSize(void);
+
+/*! ZSTD_createDCtx_advanced() :
+ * Create a ZSTD decompression context using external alloc and free functions */
+ZSTDLIB_API ZSTD_DCtx* ZSTD_createDCtx_advanced(ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_DCtx() :
+ * Gives the amount of memory used by a given ZSTD_DCtx */
+ZSTDLIB_API size_t ZSTD_sizeof_DCtx(const ZSTD_DCtx* dctx);
+
+/*! ZSTD_createDDict_byReference() :
+ * Create a digested dictionary, ready to start decompression operation without startup delay.
+ * Dictionary content is simply referenced, and therefore stays in dictBuffer.
+ * It is important that dictBuffer outlives DDict, it must remain read accessible throughout the lifetime of DDict */
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_byReference(const void* dictBuffer, size_t dictSize);
+
+/*! ZSTD_createDDict_advanced() :
+ * Create a ZSTD_DDict using external alloc and free, optionally by reference */
+ZSTDLIB_API ZSTD_DDict* ZSTD_createDDict_advanced(const void* dict, size_t dictSize,
+ unsigned byReference, ZSTD_customMem customMem);
+
+/*! ZSTD_sizeof_DDict() :
+ * Gives the amount of memory used by a given ZSTD_DDict */
+ZSTDLIB_API size_t ZSTD_sizeof_DDict(const ZSTD_DDict* ddict);
+
+/*! ZSTD_getDictID_fromDict() :
+ * Provides the dictID stored within dictionary.
+ * if @return == 0, the dictionary is not conformant with Zstandard specification.
+ * It can still be loaded, but as a content-only dictionary. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromDict(const void* dict, size_t dictSize);
+
+/*! ZSTD_getDictID_fromDDict() :
+ * Provides the dictID of the dictionary loaded into `ddict`.
+ * If @return == 0, the dictionary is not conformant to Zstandard specification, or empty.
+ * Non-conformant dictionaries can still be loaded, but as content-only dictionaries. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromDDict(const ZSTD_DDict* ddict);
+
+/*! ZSTD_getDictID_fromFrame() :
+ * Provides the dictID required to decompressed the frame stored within `src`.
+ * If @return == 0, the dictID could not be decoded.
+ * This could for one of the following reasons :
+ * - The frame does not require a dictionary to be decoded (most common case).
+ * - The frame was built with dictID intentionally removed. Whatever dictionary is necessary is a hidden information.
+ * Note : this use case also happens when using a non-conformant dictionary.
+ * - `srcSize` is too small, and as a result, the frame header could not be decoded (only possible if `srcSize < ZSTD_FRAMEHEADERSIZE_MAX`).
+ * - This is not a Zstandard frame.
+ * When identifying the exact failure cause, it's possible to use ZSTD_getFrameParams(), which will provide a more precise error code. */
+ZSTDLIB_API unsigned ZSTD_getDictID_fromFrame(const void* src, size_t srcSize);
+
+
+/********************************************************************
+* Advanced streaming functions
+********************************************************************/
+
+/*===== Advanced Streaming compression functions =====*/
+ZSTDLIB_API ZSTD_CStream* ZSTD_createCStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_API size_t ZSTD_sizeof_CStream(const ZSTD_CStream* zcs); /**< size of CStream is variable, depending primarily on compression level */
+ZSTDLIB_API size_t ZSTD_initCStream_srcSize(ZSTD_CStream* zcs, int compressionLevel, unsigned long long pledgedSrcSize); /**< pledgedSrcSize must be correct, a size of 0 means unknown. for a frame size of 0 use initCStream_advanced */
+ZSTDLIB_API size_t ZSTD_initCStream_usingDict(ZSTD_CStream* zcs, const void* dict, size_t dictSize, int compressionLevel); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
+ZSTDLIB_API size_t ZSTD_initCStream_advanced(ZSTD_CStream* zcs, const void* dict, size_t dictSize,
+ ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
+ZSTDLIB_API size_t ZSTD_initCStream_usingCDict(ZSTD_CStream* zcs, const ZSTD_CDict* cdict); /**< note : cdict will just be referenced, and must outlive compression session */
+ZSTDLIB_API size_t ZSTD_initCStream_usingCDict_advanced(ZSTD_CStream* zcs, const ZSTD_CDict* cdict, unsigned long long pledgedSrcSize, ZSTD_frameParameters fParams); /**< same as ZSTD_initCStream_usingCDict(), with control over frame parameters */
+
+/*! ZSTD_resetCStream() :
+ * start a new compression job, using same parameters from previous job.
+ * This is typically useful to skip dictionary loading stage, since it will re-use it in-place..
+ * Note that zcs must be init at least once before using ZSTD_resetCStream().
+ * pledgedSrcSize==0 means "srcSize unknown".
+ * If pledgedSrcSize > 0, its value must be correct, as it will be written in header, and controlled at the end.
+ * @return : 0, or an error code (which can be tested using ZSTD_isError()) */
+ZSTDLIB_API size_t ZSTD_resetCStream(ZSTD_CStream* zcs, unsigned long long pledgedSrcSize);
+
+
+/*===== Advanced Streaming decompression functions =====*/
+typedef enum { DStream_p_maxWindowSize } ZSTD_DStreamParameter_e;
+ZSTDLIB_API ZSTD_DStream* ZSTD_createDStream_advanced(ZSTD_customMem customMem);
+ZSTDLIB_API size_t ZSTD_initDStream_usingDict(ZSTD_DStream* zds, const void* dict, size_t dictSize); /**< note: a dict will not be used if dict == NULL or dictSize < 8 */
+ZSTDLIB_API size_t ZSTD_setDStreamParameter(ZSTD_DStream* zds, ZSTD_DStreamParameter_e paramType, unsigned paramValue);
+ZSTDLIB_API size_t ZSTD_initDStream_usingDDict(ZSTD_DStream* zds, const ZSTD_DDict* ddict); /**< note : ddict will just be referenced, and must outlive decompression session */
+ZSTDLIB_API size_t ZSTD_resetDStream(ZSTD_DStream* zds); /**< re-use decompression parameters from previous init; saves dictionary loading */
+ZSTDLIB_API size_t ZSTD_sizeof_DStream(const ZSTD_DStream* zds);
+
+
+/*********************************************************************
+* Buffer-less and synchronous inner streaming functions
+*
+* This is an advanced API, giving full control over buffer management, for users which need direct control over memory.
+* But it's also a complex one, with many restrictions (documented below).
+* Prefer using normal streaming API for an easier experience
+********************************************************************* */
+
+/**
+ Buffer-less streaming compression (synchronous mode)
+
+ A ZSTD_CCtx object is required to track streaming operations.
+ Use ZSTD_createCCtx() / ZSTD_freeCCtx() to manage resource.
+ ZSTD_CCtx object can be re-used multiple times within successive compression operations.
+
+ Start by initializing a context.
+ Use ZSTD_compressBegin(), or ZSTD_compressBegin_usingDict() for dictionary compression,
+ or ZSTD_compressBegin_advanced(), for finer parameter control.
+ It's also possible to duplicate a reference context which has already been initialized, using ZSTD_copyCCtx()
+
+ Then, consume your input using ZSTD_compressContinue().
+ There are some important considerations to keep in mind when using this advanced function :
+ - ZSTD_compressContinue() has no internal buffer. It uses externally provided buffer only.
+ - Interface is synchronous : input is consumed entirely and produce 1+ (or more) compressed blocks.
+ - Caller must ensure there is enough space in `dst` to store compressed data under worst case scenario.
+ Worst case evaluation is provided by ZSTD_compressBound().
+ ZSTD_compressContinue() doesn't guarantee recover after a failed compression.
+ - ZSTD_compressContinue() presumes prior input ***is still accessible and unmodified*** (up to maximum distance size, see WindowLog).
+ It remembers all previous contiguous blocks, plus one separated memory segment (which can itself consists of multiple contiguous blocks)
+ - ZSTD_compressContinue() detects that prior input has been overwritten when `src` buffer overlaps.
+ In which case, it will "discard" the relevant memory section from its history.
+
+ Finish a frame with ZSTD_compressEnd(), which will write the last block(s) and optional checksum.
+ It's possible to use srcSize==0, in which case, it will write a final empty block to end the frame.
+ Without last block mark, frames will be considered unfinished (corrupted) by decoders.
+
+ `ZSTD_CCtx` object can be re-used (ZSTD_compressBegin()) to compress some new frame.
+*/
+
+/*===== Buffer-less streaming compression functions =====*/
+ZSTDLIB_API size_t ZSTD_compressBegin(ZSTD_CCtx* cctx, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressBegin_usingDict(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, int compressionLevel);
+ZSTDLIB_API size_t ZSTD_compressBegin_advanced(ZSTD_CCtx* cctx, const void* dict, size_t dictSize, ZSTD_parameters params, unsigned long long pledgedSrcSize); /**< pledgedSrcSize is optional and can be 0 (meaning unknown). note: if the contentSizeFlag is set, pledgedSrcSize == 0 means the source size is actually 0 */
+ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict(ZSTD_CCtx* cctx, const ZSTD_CDict* cdict); /**< note: fails if cdict==NULL */
+ZSTDLIB_API size_t ZSTD_compressBegin_usingCDict_advanced(ZSTD_CCtx* const cctx, const ZSTD_CDict* const cdict, ZSTD_frameParameters const fParams, unsigned long long const pledgedSrcSize); /* compression parameters are already set within cdict. pledgedSrcSize=0 means null-size */
+ZSTDLIB_API size_t ZSTD_copyCCtx(ZSTD_CCtx* cctx, const ZSTD_CCtx* preparedCCtx, unsigned long long pledgedSrcSize); /**< note: if pledgedSrcSize can be 0, indicating unknown size. if it is non-zero, it must be accurate. for 0 size frames, use compressBegin_advanced */
+
+ZSTDLIB_API size_t ZSTD_compressContinue(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_compressEnd(ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+
+
+
+/*-
+ Buffer-less streaming decompression (synchronous mode)
+
+ A ZSTD_DCtx object is required to track streaming operations.
+ Use ZSTD_createDCtx() / ZSTD_freeDCtx() to manage it.
+ A ZSTD_DCtx object can be re-used multiple times.
+
+ First typical operation is to retrieve frame parameters, using ZSTD_getFrameParams().
+ It fills a ZSTD_frameParams structure which provide important information to correctly decode the frame,
+ such as the minimum rolling buffer size to allocate to decompress data (`windowSize`),
+ and the dictionary ID used.
+ (Note : content size is optional, it may not be present. 0 means : content size unknown).
+ Note that these values could be wrong, either because of data malformation, or because an attacker is spoofing deliberate false information.
+ As a consequence, check that values remain within valid application range, especially `windowSize`, before allocation.
+ Each application can set its own limit, depending on local restrictions. For extended interoperability, it is recommended to support at least 8 MB.
+ Frame parameters are extracted from the beginning of the compressed frame.
+ Data fragment must be large enough to ensure successful decoding, typically `ZSTD_frameHeaderSize_max` bytes.
+ @result : 0 : successful decoding, the `ZSTD_frameParams` structure is correctly filled.
+ >0 : `srcSize` is too small, please provide at least @result bytes on next attempt.
+ errorCode, which can be tested using ZSTD_isError().
+
+ Start decompression, with ZSTD_decompressBegin() or ZSTD_decompressBegin_usingDict().
+ Alternatively, you can copy a prepared context, using ZSTD_copyDCtx().
+
+ Then use ZSTD_nextSrcSizeToDecompress() and ZSTD_decompressContinue() alternatively.
+ ZSTD_nextSrcSizeToDecompress() tells how many bytes to provide as 'srcSize' to ZSTD_decompressContinue().
+ ZSTD_decompressContinue() requires this _exact_ amount of bytes, or it will fail.
+
+ @result of ZSTD_decompressContinue() is the number of bytes regenerated within 'dst' (necessarily <= dstCapacity).
+ It can be zero, which is not an error; it just means ZSTD_decompressContinue() has decoded some metadata item.
+ It can also be an error code, which can be tested with ZSTD_isError().
+
+ ZSTD_decompressContinue() needs previous data blocks during decompression, up to `windowSize`.
+ They should preferably be located contiguously, prior to current block.
+ Alternatively, a round buffer of sufficient size is also possible. Sufficient size is determined by frame parameters.
+ ZSTD_decompressContinue() is very sensitive to contiguity,
+ if 2 blocks don't follow each other, make sure that either the compressor breaks contiguity at the same place,
+ or that previous contiguous segment is large enough to properly handle maximum back-reference.
+
+ A frame is fully decoded when ZSTD_nextSrcSizeToDecompress() returns zero.
+ Context can then be reset to start a new decompression.
+
+ Note : it's possible to know if next input to present is a header or a block, using ZSTD_nextInputType().
+ This information is not required to properly decode a frame.
+
+ == Special case : skippable frames ==
+
+ Skippable frames allow integration of user-defined data into a flow of concatenated frames.
+ Skippable frames will be ignored (skipped) by a decompressor. The format of skippable frames is as follows :
+ a) Skippable frame ID - 4 Bytes, Little endian format, any value from 0x184D2A50 to 0x184D2A5F
+ b) Frame Size - 4 Bytes, Little endian format, unsigned 32-bits
+ c) Frame Content - any content (User Data) of length equal to Frame Size
+ For skippable frames ZSTD_decompressContinue() always returns 0.
+ For skippable frames ZSTD_getFrameParams() returns fparamsPtr->windowLog==0 what means that a frame is skippable.
+ Note : If fparamsPtr->frameContentSize==0, it is ambiguous: the frame might actually be a Zstd encoded frame with no content.
+ For purposes of decompression, it is valid in both cases to skip the frame using
+ ZSTD_findFrameCompressedSize to find its size in bytes.
+ It also returns Frame Size as fparamsPtr->frameContentSize.
+*/
+
+typedef struct {
+ unsigned long long frameContentSize;
+ unsigned windowSize;
+ unsigned dictID;
+ unsigned checksumFlag;
+} ZSTD_frameParams;
+
+/*===== Buffer-less streaming decompression functions =====*/
+ZSTDLIB_API size_t ZSTD_getFrameParams(ZSTD_frameParams* fparamsPtr, const void* src, size_t srcSize); /**< doesn't consume input, see details below */
+ZSTDLIB_API size_t ZSTD_decompressBegin(ZSTD_DCtx* dctx);
+ZSTDLIB_API size_t ZSTD_decompressBegin_usingDict(ZSTD_DCtx* dctx, const void* dict, size_t dictSize);
+ZSTDLIB_API void ZSTD_copyDCtx(ZSTD_DCtx* dctx, const ZSTD_DCtx* preparedDCtx);
+ZSTDLIB_API size_t ZSTD_nextSrcSizeToDecompress(ZSTD_DCtx* dctx);
+ZSTDLIB_API size_t ZSTD_decompressContinue(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+typedef enum { ZSTDnit_frameHeader, ZSTDnit_blockHeader, ZSTDnit_block, ZSTDnit_lastBlock, ZSTDnit_checksum, ZSTDnit_skippableFrame } ZSTD_nextInputType_e;
+ZSTDLIB_API ZSTD_nextInputType_e ZSTD_nextInputType(ZSTD_DCtx* dctx);
+
+/**
+ Block functions
+
+ Block functions produce and decode raw zstd blocks, without frame metadata.
+ Frame metadata cost is typically ~18 bytes, which can be non-negligible for very small blocks (< 100 bytes).
+ User will have to take in charge required information to regenerate data, such as compressed and content sizes.
+
+ A few rules to respect :
+ - Compressing and decompressing require a context structure
+ + Use ZSTD_createCCtx() and ZSTD_createDCtx()
+ - It is necessary to init context before starting
+ + compression : any ZSTD_compressBegin*() variant, including with dictionary
+ + decompression : any ZSTD_decompressBegin*() variant, including with dictionary
+ + copyCCtx() and copyDCtx() can be used too
+ - Block size is limited, it must be <= ZSTD_getBlockSizeMax() <= ZSTD_BLOCKSIZE_ABSOLUTEMAX
+ + If input is larger than a block size, it's necessary to split input data into multiple blocks
+ + For inputs larger than a single block size, consider using the regular ZSTD_compress() instead.
+ Frame metadata is not that costly, and quickly becomes negligible as source size grows larger.
+ - When a block is considered not compressible enough, ZSTD_compressBlock() result will be zero.
+ In which case, nothing is produced into `dst`.
+ + User must test for such outcome and deal directly with uncompressed data
+ + ZSTD_decompressBlock() doesn't accept uncompressed data as input !!!
+ + In case of multiple successive blocks, should some of them be uncompressed,
+ decoder must be informed of their existence in order to follow proper history.
+ Use ZSTD_insertBlock() for such a case.
+*/
+
+#define ZSTD_BLOCKSIZE_ABSOLUTEMAX (128 * 1024) /* define, for static allocation */
+/*===== Raw zstd block functions =====*/
+ZSTDLIB_API size_t ZSTD_getBlockSizeMax(ZSTD_CCtx* cctx);
+ZSTDLIB_API size_t ZSTD_compressBlock (ZSTD_CCtx* cctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_decompressBlock(ZSTD_DCtx* dctx, void* dst, size_t dstCapacity, const void* src, size_t srcSize);
+ZSTDLIB_API size_t ZSTD_insertBlock(ZSTD_DCtx* dctx, const void* blockStart, size_t blockSize); /**< insert block into `dctx` history. Useful for uncompressed blocks */
+
+
+#endif /* ZSTD_H_ZSTD_STATIC_LINKING_ONLY */
+
+#if defined (__cplusplus)
+}
+#endif