2017-02-13 02:52:02 +01:00
# include "editor_export_godot3.h"
# include "editor_node.h"
# include "io/resource_format_xml.h"
# include "io/resource_format_binary.h"
# include "scene/resources/scene_format_text.h"
static const char * prop_renames [ ] [ 2 ] = {
{ " script/script " , " script " } ,
{ " pause/pause_mode " , " pause_mode " } ,
{ " anchor/left " , " anchor_left " } ,
{ " anchor/right " , " anchor_right " } ,
{ " anchor/bottom " , " anchor_bottom " } ,
{ " anchor/top " , " anchor_top " } ,
{ " focus_neighbour/left " , " focus_neighbour_left " } ,
{ " focus_neighbour/right " , " focus_neighbour_right " } ,
{ " focus_neighbour/bottom " , " focus_neighbour_bottom " } ,
{ " focus_neighbour/top " , " focus_neighbour_top " } ,
{ " focus/ignore_mouse " , " focus_ignore_mouse " } ,
{ " focus/stop_mouse " , " focus_stop_mouse " } ,
{ " size_flags/horizontal " , " size_flags_horizontal " } ,
{ " size_flags/vertical " , " size_flags_vertical " } ,
{ " size_flags/stretch_ratio " , " size_flags_stretch_ratio " } ,
{ " theme/theme " , " theme " } ,
{ " visibility/visible " , " visible " } ,
{ " visibility/behind_parent " , " show_behind_parent " } ,
{ " visibility/on_top " , " show_on_top " } ,
{ " visibility/light_mask " , " light_mask " } ,
{ " material/material " , " material " } ,
{ " material/use_parent " , " use_parent_material " } ,
{ " resource/path " , " resource_path " } ,
{ " resource/name " , " resource_name " } ,
{ " collision/layers " , " collision_layers " } ,
{ " collision/mask " , " collision_mask " } ,
{ " limit/left " , " limit_left " } ,
{ " limit/right " , " limit_right " } ,
{ " limit/bottom " , " limit_bottom " } ,
{ " limit/top " , " limit_top " } ,
{ " limit/smoothed " , " limit_smoothed " } ,
{ " draw_margin/h_enabled " , " draw_margin_h_enabled " } ,
{ " draw_margin/v_enabled " , " draw_margin_v_enabled " } ,
{ " smoothing/enable " , " smoothing_enabled " } ,
{ " smoothing/speed " , " smoothing_speed " } ,
{ " drag_margin/left " , " drag_margin_left " } ,
{ " drag_margin/top " , " drag_margin_top " } ,
{ " drag_margin/right " , " drag_margin_right " } ,
{ " drag_margin/bottom " , " drag_margin_bottom " } ,
{ " input/pickable " , " input_pickable " } ,
{ " bias/bias " , " bias " } ,
{ " collision/exclude_nodes " , " disable_collision " } ,
{ " range/height " , " range_height " } ,
{ " range/z_min " , " range_z_min " } ,
{ " range/z_max " , " range_z_max " } ,
{ " range/layer_max " , " range_layer_max " } ,
{ " range/item_cull_mask " , " range_item_cull_max " } ,
{ " shadow/enabled " , " shadow_enabled " } ,
{ " shadow/color " , " shadow_color " } ,
{ " shadow/buffer_size " , " shadow_buffer_size " } ,
{ " shadow/gradient_length " , " shadow_gradient_length " } ,
{ " shadow/filter " , " shadow_filter " } ,
{ " shadow/item_cull_mask " , " shadow_item_cull_mask " } ,
{ " transform/pos " , " position " } ,
{ " transform/rot " , " rotation " } ,
{ " transform/scale " , " scale " } ,
{ " z/z " , " z " } ,
{ " z/relative " , " z_as_relative " } ,
{ " scroll/offset " , " scroll_offset " } ,
{ " scroll/base_offset " , " scroll_base_offset " } ,
{ " scroll/base_scale " , " scroll_base_scale " } ,
{ " scroll/limit_begin " , " scroll_limit_begin " } ,
{ " scroll/limit_end " , " scroll_limit_end " } ,
{ " scroll/ignore_camera_zoom " , " scroll_ignore_camera_zoom " } ,
{ " motion/scale " , " motion_scale " } ,
{ " motion/offset " , " motion_offset " } ,
{ " motion/mirroring " , " motion_mirroring " } ,
{ " collision/layers " , " collision_layer " } ,
{ " collision/mask " , " collision_mask " } ,
{ " texture/texture " , " texture " } ,
{ " texture/offset " , " texture_offset " } ,
{ " texture/rotation " , " texture_rotation " } ,
{ " texture/scale " , " texture_scale " } ,
{ " invert/enable " , " invert_enable " } ,
{ " invert/border " , " invert_border " } ,
{ " config/polyphony " , " polyphony " } ,
{ " config/samples " , " samples " } ,
{ " config/pitch_random " , " random_pitch " } ,
{ " params/volume_db " , " volume_db " } ,
{ " params/pitch_scale " , " pitch_scale " } ,
{ " params/attenuation/min_distance " , " attenuation_min_distance " } ,
{ " params/attenuation/max_distance " , " attenuation_max_distance " } ,
{ " params/attenuation/distance_exp " , " attenuation_distance_exp " } ,
{ " cell/size " , " cell_size " } ,
{ " cell/quadrant_size " , " cell_quadrant_size " } ,
{ " cell/half_offset " , " cell_half_offset " } ,
{ " cell/tile_origin " , " cell_tile_origin " } ,
{ " cell/y_sort " , " cell_y_sort " } ,
{ " collision/use_kinematic " , " collision_use_kinematic " } ,
{ " collision/friction " , " collision_friction " } ,
{ " collision/bounce " , " collision_bounce " } ,
{ " collision/layers " , " collision_layers " } ,
{ " collision/mask " , " collision_mask " } ,
{ " occluder/light_mask " , " occluder_light_mask " } ,
{ " enabler/pause_animations " , " pause_animations " } ,
{ " enabler/freeze_bodies " , " freeze_bodies " } ,
{ " enabler/pause_particles " , " pause_particles " } ,
{ " enabler/pause_animated_sprites " , " pause_animated_sprites " } ,
{ " enabler/process_parent " , " process_parent " } ,
{ " enabler/fixed_process_parent " , " fixed_process_parent " } ,
{ " sort/enabled " , " sort_enabled " } ,
{ " collision/layers " , " collision_layers " } ,
{ " collision/mask " , " collision_mask " } ,
{ " input/ray_pickable " , " input_ray_pickable " } ,
{ " input/capture_on_drag " , " input_capture_on_drag " } ,
{ " light/color " , " light_color " } ,
{ " light/energy " , " light_energy " } ,
{ " light/negative " , " light_negative " } ,
{ " light/specular " , " light_specular " } ,
{ " light/cull_mask " , " light_cull_mask " } ,
{ " shadow/enabled " , " shadow_enabled " } ,
{ " shadow/color " , " shadow_color " } ,
{ " shadow/bias " , " shadow_bias " } ,
{ " shadow/max_distance " , " shadow_max_distance " } ,
{ " editor/editor_only " , " editor_only " } ,
{ " directional_shadow/mode " , " directional_shadow_mode " } ,
{ " directional_shadow/split_1 " , " directional_shadow_split_1 " } ,
{ " directional_shadow/split_2 " , " directional_shadow_split_2 " } ,
{ " directional_shadow/split_3 " , " directional_shadow_split_3 " } ,
{ " directional_shadow/blend_splits " , " directional_shadow_blend_splits " } ,
{ " directional_shadow/normal_bias " , " directional_shadow_normal_bias " } ,
{ " directional_shadow/bias_split_scale " , " directional_shadow_bias_split_scale " } ,
{ " omni/range " , " omni_range " } ,
{ " omni/attenuation " , " omni_attenuation " } ,
{ " omni/shadow_mode " , " omni_shadow_mode " } ,
{ " omni/shadow_detail " , " omni_shadow_detail " } ,
{ " spot/range " , " spot_range " } ,
{ " spot/attenuation " , " spot_attenuation " } ,
{ " spot/angle " , " spot_angle " } ,
{ " spot/spot_attenuation " , " spot_angle_attenuation " } ,
{ " mesh/mesh " , " mesh " } ,
{ " mesh/skeleton " , " skeleton " } ,
{ " collision/layers " , " collision_layer " } ,
{ " collision/mask " , " collision_mask " } ,
{ " quad/axis " , " axis " } ,
{ " quad/size " , " size " } ,
{ " quad/offset " , " offset " } ,
{ " quad/centered " , " centered " } ,
{ " transform/local " , " transform " } ,
{ " transform/transiation " , " translation " } ,
{ " transform/rotation " , " rotation " } ,
{ " transform/scale " , " scale " } ,
{ " visibility/visible " , " visible " } ,
{ " params/volume_db " , " volume_db " } ,
{ " params/pitch_scale " , " pitch_scale " } ,
{ " params/attenuation/min_distance " , " attenuation_min_distance " } ,
{ " params/attenuation/max_distance " , " attenuation_max_distance " } ,
{ " params/attenuation/distance_exp " , " attenuation_distance_exp " } ,
{ " params/emission_cone/degrees " , " emission_cone_degrees " } ,
{ " params/emission_cone/attenuation_db " , " emission_cone_attenuation_db " } ,
{ " config/polyphony " , " polyphony " } ,
{ " config/samples " , " samples " } ,
{ " flags/transparent " , " transparent " } ,
{ " flags/shaded " , " shaded " } ,
{ " flags/alpha_cut " , " alpha_cut " } ,
{ " type/traction " , " use_as_traction " } ,
{ " type/steering " , " use_as_steering " } ,
{ " wheel/radius " , " wheel_radius " } ,
{ " wheel/rest_length " , " wheel_rest_length " } ,
{ " wheel/friction_slip " , " wheel_friction_sleep " } ,
{ " suspension/travel " , " suspension_travel " } ,
{ " suspension/stiffness " , " suspension_stiffness " } ,
{ " suspension/max_force " , " suspension_max_force " } ,
{ " damping/compression " , " damping_compression " } ,
{ " damping/relaxation " , " damping_relaxation " } ,
{ " motion/engine_force " , " engine_force " } ,
{ " motion/breake " , " breake " } ,
{ " motion/steering " , " steering " } ,
{ " body/mass " , " mass " } ,
{ " body/friction " , " friction " } ,
{ " enabler/pause_animations " , " pause_animations " } ,
{ " enabler/freeze_bodies " , " freeze_bodies " } ,
{ " geometry/material_override " , " material_override " } ,
{ " geometry/cast_shadow " , " cast_shadow " } ,
{ " geometry/extra_cull_margin " , " extra_cull_margin " } ,
{ " geometry/billboard " , " use_as_billboard " } ,
{ " geometry/billboard_y " , " use_as_y_billboard " } ,
{ " geometry/depth_scale " , " use_depth_scale " } ,
{ " geometry/visible_in_all_rooms " , " visible_in_all_rooms " } ,
{ " geometry/use_baked_light " , " use_in_baked_light " } ,
{ " playback/process_mode " , " playback_process_mode " } ,
{ " playback/default_blend_time " , " playback_default_blend_time " } ,
{ " root/root " , " root_node " } ,
{ " playback/process_mode " , " playback_process_mode " } ,
{ " stream/stream " , " stream " } ,
{ " stream/play " , " play " } ,
{ " stream/loop " , " loop " } ,
{ " stream/volume_db " , " volume_db " } ,
{ " stream/pitch_scale " , " pitch_scale " } ,
{ " stream/tempo_scale " , " tempo_scale " } ,
{ " stream/autoplay " , " autoplay " } ,
{ " stream/paused " , " paused " } ,
{ " stream/stream " , " stream " } ,
{ " stream/play " , " play " } ,
{ " stream/loop " , " loop " } ,
{ " stream/volume_db " , " volume_db " } ,
{ " stream/autoplay " , " autoplay " } ,
{ " stream/paused " , " paused " } ,
{ " stream/loop_restart_time " , " loop_restart_time " } ,
{ " stream/buffering_ms " , " buffering_ms " } ,
{ " stream/stream " , " stream " } ,
{ " stream/play " , " play " } ,
{ " stream/loop " , " loop " } ,
{ " stream/volume_db " , " volume_db " } ,
{ " stream/autoplay " , " autoplay " } ,
{ " stream/paused " , " paused " } ,
{ " stream/loop_restart_time " , " loop_restart_time " } ,
{ " stream/buffering_ms " , " buffering_ms " } ,
{ " window/title " , " window_title " } ,
{ " dialog/text " , " dialog_text " } ,
{ " dialog/hide_on_ok " , " dialog_hide_on_ok " } ,
{ " placeholder/text " , " placeholder_text " } ,
{ " placeholder/alpha " , " placeholder_alpha " } ,
{ " caret/caret_blink " , " caret_blink " } ,
{ " caret/caret_blink_speed " , " caret_blink_speed " } ,
{ " patch_margin/left " , " patch_margin_left " } ,
{ " patch_margin/right " , " patch_margin_right " } ,
{ " patch_margin/top " , " patch_margin_top " } ,
{ " patch_margin/bottom " , " patch_margin_bottom " } ,
{ " popup/exclusive " , " popup_exclusive " } ,
{ " percent/visible " , " percent_visible " } ,
{ " range/min " , " min_value " } ,
{ " range/max " , " max_value " } ,
{ " range/step " , " step " } ,
{ " range/page " , " page " } ,
{ " range/value " , " value " } ,
{ " range/exp_edit " , " exp_edit " } ,
{ " range/rounded " , " rounded " } ,
{ " velocity/linear " , " linear_velocity " } ,
{ " velocity/angular " , " angular_velocity " } ,
{ " damp_override_linear " , " linear_damp " } ,
{ " damp_override_angular " , " angular_damp " } ,
{ " velocity/linear " , " linear_velocity " } ,
{ " velocity/angular " , " angular_velocity " } ,
{ " damp_override_linear " , " linear_damp " } ,
{ " damp_override_angular " , " angular_damp " } ,
{ " playback/process_mode " , " playback_process_mode " } ,
{ " bbcode/enabled " , " bbcode_enabled " } ,
{ " bbcode/bbcode " , " bbcode_text " } ,
{ " scroll/horizontal " , " scroll_horizontal " } ,
{ " scroll/vertical " , " scroll_vertical " } ,
{ " split/offset " , " split_offset " } ,
{ " split/collapsed " , " collapsed " } ,
{ " split/dragger_visibility " , " dragger_visibility " } ,
{ " caret/block_caret " , " caret_block_mode " } ,
{ " caret/caret_blink " , " caret_blink " } ,
{ " caret/caret_blink_speed " , " caret_blink_speed " } ,
{ " textures/normal " , " texture_normal " } ,
{ " textures/pressed " , " texture_pressed " } ,
{ " textures/hover " , " texture_hover " } ,
{ " textures/disabled " , " texture_disabled " } ,
{ " textures/focused " , " texture_focused " } ,
{ " textures/click_mask " , " texture_click_mask " } ,
{ " params/scale " , " texture_scale " } ,
{ " params/modulate " , " self_modulate " } ,
{ " texture/under " , " texture_under " } ,
{ " texture/over " , " texture_over " } ,
{ " texture/progress " , " texture_progress " } ,
{ " mode " , " fill_mode " } ,
{ " radial_fill/initial_angle " , " radial_initial_angle " } ,
{ " radial_fill/fill_degrees " , " radial_fill_degrees " } ,
{ " radial_fill/center_offset " , " radial_center_offset " } ,
{ " stream/audio_track " , " audio_track " } ,
{ " stream/stream " , " stream " } ,
{ " stream/volume_db " , " volume_db " } ,
{ " stream/autoplay " , " stream_autoplay " } ,
{ " stream/paused " , " stream_paused " } ,
{ " font/size " , " size " } ,
{ " extra_spacing/top " , " extra_spacing_top " } ,
{ " extra_spacing/bottom " , " extra_spacing_bottom " } ,
{ " extra_spacing/char " , " extra_spacing_char " } ,
{ " extra_spacing/space " , " extra_spacing_space " } ,
{ " font/use_mipmaps " , " use_mipmaps " } ,
{ " font/use_filter " , " use_filter " } ,
{ " font/font " , " font_data " } ,
{ " content_margin/left " , " content_margin_left " } ,
{ " content_margin/right " , " content_margin_right " } ,
{ " content_margin/bottom " , " content_margin_bottom " } ,
{ " content_margin/top " , " content_margin_top " } ,
{ " margin/left " , " margin_left " } ,
{ " margin/top " , " margin_top " } ,
{ " margin/bottom " , " margin_bottom " } ,
{ " margin/right " , " margin_right " } ,
{ " expand_margin/left " , " expand_margin_left " } ,
{ " expand_margin/top " , " expand_margin_top " } ,
{ " expand_margin/bottom " , " expand_margin_bottom " } ,
{ " expand_margin/right " , " expand_margin_right " } ,
{ " modulate/color " , " modulate_color " } ,
{ " modulate " , " self_modulate " } ,
2017-02-15 12:29:11 +01:00
{ " cell/size " , " cell_size " } ,
{ " cell/octant_size " , " cell_octant_size " } ,
{ " cell/center_x " , " cell_center_x " } ,
{ " cell/center_y " , " cell_center_y " } ,
{ " cell/center_z " , " cell_center_z " } ,
{ " cell/scale " , " cell_scale " } ,
2017-02-13 02:52:02 +01:00
{ NULL , NULL }
} ;
static const char * type_renames [ ] [ 2 ] = {
{ " SpatialPlayer " , " Spatial " } ,
{ " SpatialSamplePlayer " , " Spatial " } ,
{ " SpatialStreamPlayer " , " Spatial " } ,
2017-02-15 12:29:11 +01:00
{ " Particles " , " Spatial " } ,
2017-02-13 02:52:02 +01:00
{ " SamplePlayer " , " Node " } ,
{ " SamplePlayer2D " , " Node2D " } ,
{ " SoundPlayer2D " , " Node2D " } ,
{ " StreamPlayer2D " , " Node2D " } ,
2017-02-15 12:29:11 +01:00
{ " Particles2D " , " Node2D " } ,
2017-02-13 02:52:02 +01:00
{ " SampleLibrary " , " Resource " } ,
{ " TextureFrame " , " TextureRect " } ,
2017-02-15 12:29:11 +01:00
{ " FixedMaterial " , " FixedSpatialMaterial " } ,
2017-02-13 02:52:02 +01:00
{ NULL , NULL }
} ;
static const char * signal_renames [ ] [ 2 ] = {
{ " 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 " } ,
{ NULL , NULL }
} ;
void EditorExportGodot3 : : _find_files ( EditorFileSystemDirectory * p_dir , List < String > * r_files ) {
for ( int i = 0 ; i < p_dir - > get_subdir_count ( ) ; i + + ) {
_find_files ( p_dir - > get_subdir ( i ) , r_files ) ;
}
for ( int i = 0 ; i < p_dir - > get_file_count ( ) ; i + + ) {
r_files - > push_back ( p_dir - > get_file_path ( i ) ) ;
}
}
void EditorExportGodot3 : : _rename_properties ( const String & p_type , List < ExportData : : PropertyData > * p_props ) {
for ( List < ExportData : : PropertyData > : : Element * E = p_props - > front ( ) ; E ; E = E - > next ( ) ) {
if ( prop_rename_map . has ( E - > get ( ) . name ) ) {
E - > get ( ) . name = prop_rename_map [ E - > get ( ) . name ] ;
}
}
}
void EditorExportGodot3 : : _convert_resources ( ExportData & resource ) {
for ( int i = 0 ; i < resource . resources . size ( ) ; i + + ) {
_rename_properties ( resource . resources [ i ] . type , & resource . resources [ i ] . properties ) ;
if ( type_rename_map . has ( resource . resources [ i ] . type ) ) {
resource . resources [ i ] . type = type_rename_map [ resource . resources [ i ] . type ] ;
}
}
for ( int i = 0 ; i < resource . nodes . size ( ) ; i + + ) {
_rename_properties ( resource . nodes [ i ] . type , & resource . nodes [ i ] . properties ) ;
if ( type_rename_map . has ( resource . nodes [ i ] . type ) ) {
resource . nodes [ i ] . type = type_rename_map [ resource . nodes [ i ] . type ] ;
}
}
for ( int i = 0 ; i < resource . connections . size ( ) ; i + + ) {
if ( signal_rename_map . has ( resource . connections [ i ] . signal ) ) {
resource . connections [ i ] . signal = signal_rename_map [ resource . connections [ i ] . signal ] ;
}
}
}
void EditorExportGodot3 : : _unpack_packed_scene ( ExportData & resource ) {
Dictionary d ;
for ( List < ExportData : : PropertyData > : : Element * E = resource . resources [ resource . resources . size ( ) - 1 ] . properties . front ( ) ; E ; E = E - > next ( ) ) {
if ( E - > get ( ) . name = = " _bundled " ) {
d = E - > get ( ) . value ;
}
}
ERR_FAIL_COND ( d . empty ( ) ) ;
ERR_FAIL_COND ( ! d . has ( " names " ) ) ;
ERR_FAIL_COND ( ! d . has ( " variants " ) ) ;
ERR_FAIL_COND ( ! d . has ( " node_count " ) ) ;
ERR_FAIL_COND ( ! d . has ( " nodes " ) ) ;
ERR_FAIL_COND ( ! d . has ( " conn_count " ) ) ;
ERR_FAIL_COND ( ! d . has ( " conns " ) ) ;
Vector < String > names ;
DVector < String > snames = d [ " names " ] ;
if ( snames . size ( ) ) {
int namecount = snames . size ( ) ;
names . resize ( namecount ) ;
DVector < String > : : Read r = snames . read ( ) ;
for ( int i = 0 ; i < names . size ( ) ; i + + )
names [ i ] = r [ i ] ;
}
Array variants = d [ " variants " ] ;
resource . nodes . resize ( d [ " node_count " ] ) ;
int nc = resource . nodes . size ( ) ;
if ( nc ) {
DVector < int > snodes = d [ " nodes " ] ;
DVector < int > : : Read r = snodes . read ( ) ;
int idx = 0 ;
for ( int i = 0 ; i < nc ; i + + ) {
int parent = r [ idx + + ] ;
int owner = r [ idx + + ] ;
int type = r [ idx + + ] ;
int name = r [ idx + + ] ;
int instance = r [ idx + + ] ;
2017-02-15 12:29:11 +01:00
ExportData : : NodeData & node_data = resource . nodes [ i ] ;
2017-02-13 02:52:02 +01:00
node_data . text_data = false ;
node_data . name = names [ name ] ;
2017-02-15 12:29:11 +01:00
if ( type = = 0x7FFFFFFF ) {
node_data . instanced = true ;
print_line ( " name: " + node_data . name + " is instanced " ) ;
} else {
node_data . instanced = false ;
node_data . type = names [ type ] ;
print_line ( " name: " + node_data . name + " type " + node_data . type ) ;
}
2017-02-13 02:52:02 +01:00
node_data . parent_int = parent ;
node_data . owner_int = owner ;
if ( instance > = 0 ) {
node_data . instance_is_placeholder = instance & SceneState : : FLAG_INSTANCE_IS_PLACEHOLDER ;
node_data . instance = variants [ instance & SceneState : : FLAG_MASK ] ;
}
int prop_count = r [ idx + + ] ;
for ( int j = 0 ; j < prop_count ; j + + ) {
int prop_name = r [ idx + + ] ;
int prop_value = r [ idx + + ] ;
ExportData : : PropertyData pdata ;
pdata . name = names [ prop_name ] ;
pdata . value = variants [ prop_value ] ;
node_data . properties . push_back ( pdata ) ;
}
int group_count = r [ idx + + ] ;
for ( int j = 0 ; j < group_count ; j + + ) {
int group_name = r [ idx + + ] ;
node_data . groups . push_back ( names [ group_name ] ) ;
}
}
}
int cc = d [ " conn_count " ] ;
if ( cc ) {
DVector < int > sconns = d [ " conns " ] ;
DVector < int > : : Read r = sconns . read ( ) ;
int idx = 0 ;
for ( int i = 0 ; i < cc ; i + + ) {
ExportData : : Connection conn ;
conn . from_int = r [ idx + + ] ;
conn . to_int = r [ idx + + ] ;
conn . signal = names [ r [ idx + + ] ] ;
conn . method = names [ r [ idx + + ] ] ;
conn . flags = r [ idx + + ] ;
int bindcount = r [ idx + + ] ;
for ( int j = 0 ; j < bindcount ; j + + ) {
conn . binds . push_back ( variants [ r [ idx + + ] ] ) ;
}
resource . connections . push_back ( conn ) ;
}
}
Array np ;
if ( d . has ( " node_paths " ) ) {
np = d [ " node_paths " ] ;
}
for ( int i = 0 ; i < np . size ( ) ; i + + ) {
resource . node_paths . push_back ( np [ i ] ) ;
}
Array ei ;
if ( d . has ( " editable_instances " ) ) {
ei = d [ " editable_instances " ] ;
for ( int i = 0 ; i < ei . size ( ) ; i + + ) {
resource . editables . push_back ( ei [ i ] ) ;
}
}
if ( d . has ( " base_scene " ) ) {
resource . base_scene = variants [ d [ " base_scene " ] ] ;
}
resource . resources . resize ( resource . resources . size ( ) - 1 ) ; //erase packed
}
void EditorExportGodot3 : : _pack_packed_scene ( ExportData & resource ) {
pack_names . clear ( ) ;
pack_values . clear ( ) ;
Dictionary d ;
d [ " node_count " ] = resource . nodes . size ( ) ;
Vector < int > node_data ;
for ( int i = 0 ; i < resource . nodes . size ( ) ; i + + ) {
const ExportData : : NodeData & node = resource . nodes [ i ] ;
node_data . push_back ( node . parent_int ) ;
node_data . push_back ( node . owner_int ) ;
2017-02-15 12:29:11 +01:00
if ( node . instanced ) {
node_data . push_back ( 0x7FFFFFFF ) ;
} else {
int name = _pack_name ( node . type ) ;
print_line ( " packing type: " + String ( node . type ) + " goes to name " + itos ( name ) ) ;
node_data . push_back ( name ) ;
}
2017-02-13 02:52:02 +01:00
node_data . push_back ( _pack_name ( node . name ) ) ;
int instance = - 1 ;
if ( node . instance ! = String ( ) ) {
instance = _pack_value ( node . instance ) ;
if ( node . instance_is_placeholder ) {
instance | = SceneState : : FLAG_INSTANCE_IS_PLACEHOLDER ;
}
}
node_data . push_back ( instance ) ;
node_data . push_back ( node . properties . size ( ) ) ;
for ( int j = 0 ; j < node . properties . size ( ) ; j + + ) {
node_data . push_back ( _pack_name ( node . properties [ j ] . name ) ) ;
node_data . push_back ( _pack_value ( node . properties [ j ] . value ) ) ;
}
node_data . push_back ( node . groups . size ( ) ) ;
for ( int j = 0 ; j < node . groups . size ( ) ; j + + ) {
node_data . push_back ( _pack_name ( node . groups [ j ] ) ) ;
}
}
d [ " nodes " ] = node_data ;
d [ " conn_count " ] = resource . connections . size ( ) ;
Vector < int > connections ;
for ( int i = 0 ; i < resource . connections . size ( ) ; i + + ) {
const ExportData : : Connection & conn = resource . connections [ i ] ;
connections . push_back ( conn . from_int ) ;
connections . push_back ( conn . to_int ) ;
connections . push_back ( _pack_name ( conn . signal ) ) ;
connections . push_back ( _pack_name ( conn . method ) ) ;
connections . push_back ( conn . flags ) ;
connections . push_back ( conn . binds . size ( ) ) ;
for ( int j = 0 ; j < conn . binds . size ( ) ; j + + ) {
connections . push_back ( _pack_value ( conn . binds [ j ] ) ) ;
}
}
2017-02-15 12:29:11 +01:00
d [ " conns " ] = connections ;
2017-02-13 02:52:02 +01:00
Array np ;
for ( int i = 0 ; i < resource . node_paths . size ( ) ; i + + ) {
np . push_back ( resource . node_paths [ i ] ) ;
}
d [ " node_paths " ] = np ;
Array ei ;
for ( int i = 0 ; i < resource . editables . size ( ) ; i + + ) {
ei . push_back ( resource . editables [ i ] ) ;
}
d [ " editable_instances " ] = ei ;
if ( resource . base_scene . get_type ( ) ) {
d [ " base_scene " ] = _pack_value ( resource . base_scene ) ;
}
DVector < String > names ;
names . resize ( pack_names . size ( ) ) ;
{
DVector < String > : : Write w = names . write ( ) ;
for ( Map < String , int > : : Element * E = pack_names . front ( ) ; E ; E = E - > next ( ) ) {
w [ E - > get ( ) ] = E - > key ( ) ;
}
}
d [ " names " ] = names ;
Array values ;
2017-02-15 12:29:11 +01:00
values . resize ( pack_values . size ( ) ) ;
2017-02-13 02:52:02 +01:00
const Variant * K = NULL ;
while ( ( K = pack_values . next ( K ) ) ) {
2017-02-15 12:29:11 +01:00
int index = pack_values [ * K ] ;
values [ index ] = * K ;
2017-02-13 02:52:02 +01:00
}
d [ " variants " ] = values ;
ExportData : : ResourceData packed_scene ;
packed_scene . type = " PackedScene " ;
packed_scene . index = - 1 ;
ExportData : : PropertyData pd ;
pd . name = " _bundled " ;
pd . value = d ;
packed_scene . properties . push_back ( pd ) ;
resource . resources . push_back ( packed_scene ) ;
resource . nodes . clear ( ) ;
resource . connections . clear ( ) ;
resource . editables . clear ( ) ;
resource . node_paths . clear ( ) ; ;
resource . base_scene = Variant ( ) ;
}
static String rtosfix ( double p_value ) {
if ( p_value = = 0.0 )
return " 0 " ; //avoid negative zero (-0) being written, which may annoy git, svn, etc. for changes when they don't exist.
else
return rtoss ( p_value ) ;
}
Error EditorExportGodot3 : : _get_property_as_text ( const Variant & p_variant , String & p_string ) {
switch ( p_variant . get_type ( ) ) {
case Variant : : NIL : {
p_string + = ( " null " ) ;
} break ;
case Variant : : BOOL : {
p_string + = ( p_variant . operator bool ( ) ? " true " : " false " ) ;
} break ;
case Variant : : INT : {
p_string + = ( itos ( p_variant . operator int ( ) ) ) ;
} break ;
case Variant : : REAL : {
String s = rtosfix ( p_variant . operator real_t ( ) ) ;
if ( s . find ( " . " ) = = - 1 & & s . find ( " e " ) = = - 1 )
s + = " .0 " ;
p_string + = ( s ) ;
} break ;
case Variant : : STRING : {
String str = p_variant ;
if ( str . begins_with ( " @RESLOCAL: " ) ) {
p_string + = " SubResource( " + str . get_slice ( " : " , 1 ) + " ) " ;
} else if ( str . begins_with ( " @RESEXTERNAL: " ) ) {
p_string + = " ExtResource( " + str . get_slice ( " : " , 1 ) + " ) " ;
} else {
str = " \" " + str . c_escape_multiline ( ) + " \" " ;
p_string + = ( str ) ;
}
} break ;
case Variant : : VECTOR2 : {
Vector2 v = p_variant ;
p_string + = ( " Vector2( " + rtosfix ( v . x ) + " , " + rtosfix ( v . y ) + " ) " ) ;
} break ;
case Variant : : RECT2 : {
Rect2 aabb = p_variant ;
p_string + = ( " Rect2( " + rtosfix ( aabb . pos . x ) + " , " + rtosfix ( aabb . pos . y ) + " , " + rtosfix ( aabb . size . x ) + " , " + rtosfix ( aabb . size . y ) + " ) " ) ;
} break ;
case Variant : : VECTOR3 : {
Vector3 v = p_variant ;
p_string + = ( " Vector3( " + rtosfix ( v . x ) + " , " + rtosfix ( v . y ) + " , " + rtosfix ( v . z ) + " ) " ) ;
} break ;
case Variant : : PLANE : {
Plane p = p_variant ;
p_string + = ( " Plane( " + rtosfix ( p . normal . x ) + " , " + rtosfix ( p . normal . y ) + " , " + rtosfix ( p . normal . z ) + " , " + rtosfix ( p . d ) + " ) " ) ;
} break ;
case Variant : : _AABB : {
Rect3 aabb = p_variant ;
p_string + = ( " 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 ) + " ) " ) ;
} break ;
case Variant : : QUAT : {
Quat quat = p_variant ;
p_string + = ( " Quat( " + rtosfix ( quat . x ) + " , " + rtosfix ( quat . y ) + " , " + rtosfix ( quat . z ) + " , " + rtosfix ( quat . w ) + " ) " ) ;
} break ;
case Variant : : MATRIX32 : {
String s = " Transform2D( " ;
Matrix32 m3 = p_variant ;
for ( int i = 0 ; i < 3 ; i + + ) {
for ( int j = 0 ; j < 2 ; j + + ) {
if ( i ! = 0 | | j ! = 0 )
s + = " , " ;
s + = rtosfix ( m3 . elements [ i ] [ j ] ) ;
}
}
p_string + = ( s + " ) " ) ;
} break ;
case Variant : : MATRIX3 : {
String s = " Basis( " ;
Matrix3 m3 = p_variant ;
for ( int i = 0 ; i < 3 ; i + + ) {
for ( int j = 0 ; j < 3 ; j + + ) {
if ( i ! = 0 | | j ! = 0 )
s + = " , " ;
s + = rtosfix ( m3 . elements [ i ] [ j ] ) ;
}
}
p_string + = ( s + " ) " ) ;
} break ;
case Variant : : TRANSFORM : {
String s = " Transform( " ;
Transform t = p_variant ;
Matrix3 & m3 = t . basis ;
for ( int i = 0 ; i < 3 ; i + + ) {
for ( int j = 0 ; j < 3 ; j + + ) {
if ( i ! = 0 | | j ! = 0 )
s + = " , " ;
s + = rtosfix ( m3 . elements [ i ] [ j ] ) ;
}
}
s = s + " , " + rtosfix ( t . origin . x ) + " , " + rtosfix ( t . origin . y ) + " , " + rtosfix ( t . origin . z ) ;
p_string + = ( s + " ) " ) ;
} break ;
// misc types
case Variant : : COLOR : {
Color c = p_variant ;
p_string + = ( " 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_string + = ( " Image() " ) ;
break ;
}
String imgstr = " Image() " ;
p_string + = imgstr ; //do not convert this for now
/*imgstr+=itos(img.get_width());
imgstr + = " , " + itos ( img . get_height ( ) ) ;
imgstr + = " , " + String ( img . get_mipmaps ( ) ? " true " : " false " ) ;
imgstr + = " , " + Image : : get_format_name ( img . get_format ( ) ) ;
String s ;
2017-02-15 12:29:11 +01:00
DVector < uint8_t > data = img . get_data ( ) ;
2017-02-13 02:52:02 +01:00
int len = data . size ( ) ;
2017-02-15 12:29:11 +01:00
DVector < uint8_t > : : Read r = data . read ( ) ;
2017-02-13 02:52:02 +01:00
const uint8_t * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
s + = " , " ;
s + = itos ( ptr [ i ] ) ;
}
imgstr + = " , " ;
p_string + = ( imgstr ) ;
p_string + = ( s ) ;
p_string + = ( " ) " ) ; */
} break ;
case Variant : : NODE_PATH : {
String str = p_variant ;
str = " NodePath( \" " + str . c_escape ( ) + " \" ) " ;
p_string + = ( str ) ;
} break ;
case Variant : : OBJECT : {
//should never arrive here!
ERR_FAIL_V ( ERR_BUG ) ;
} 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 : : JOYSTICK_BUTTON : {
str + = " JBUTTON, " + itos ( ev . joy_button . button_index ) ;
} break ;
case InputEvent : : JOYSTICK_MOTION : {
str + = " JAXIS, " + itos ( ev . joy_motion . axis ) + " , " + itos ( ev . joy_motion . axis_value ) ;
} break ;
case InputEvent : : NONE : {
str + = " NONE " ;
} break ;
default : { }
}
str + = " ) " ;
p_string + = ( str ) ; //will be added later
} break ;
case Variant : : DICTIONARY : {
Dictionary dict = p_variant ;
List < Variant > keys ;
dict . get_key_list ( & keys ) ;
keys . sort ( ) ;
p_string + = ( " { \n " ) ;
for ( List < Variant > : : Element * E = keys . front ( ) ; E ; E = E - > next ( ) ) {
/*
if ( ! _check_type ( dict [ E - > get ( ) ] ) )
continue ;
*/
_get_property_as_text ( E - > get ( ) , p_string ) ;
p_string + = ( " : " ) ;
_get_property_as_text ( dict [ E - > get ( ) ] , p_string ) ;
if ( E - > next ( ) )
p_string + = ( " , \n " ) ;
}
p_string + = ( " \n } " ) ;
} break ;
case Variant : : ARRAY : {
p_string + = ( " [ " ) ;
Array array = p_variant ;
int len = array . size ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
_get_property_as_text ( array [ i ] , p_string ) ;
}
p_string + = ( " ] " ) ;
} break ;
case Variant : : RAW_ARRAY : {
p_string + = ( " PoolByteArray( " ) ;
String s ;
DVector < uint8_t > data = p_variant ;
int len = data . size ( ) ;
DVector < uint8_t > : : Read r = data . read ( ) ;
const uint8_t * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( itos ( ptr [ i ] ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : INT_ARRAY : {
p_string + = ( " PoolIntArray( " ) ;
DVector < int > data = p_variant ;
int len = data . size ( ) ;
DVector < int > : : Read r = data . read ( ) ;
const int * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( itos ( ptr [ i ] ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : REAL_ARRAY : {
p_string + = ( " PoolFloatArray( " ) ;
DVector < real_t > data = p_variant ;
int len = data . size ( ) ;
DVector < real_t > : : Read r = data . read ( ) ;
const real_t * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( rtosfix ( ptr [ i ] ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : STRING_ARRAY : {
p_string + = ( " PoolStringArray( " ) ;
DVector < String > data = p_variant ;
int len = data . size ( ) ;
DVector < String > : : Read r = data . read ( ) ;
const String * ptr = r . ptr ( ) ;
String s ;
//write_string("\n");
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
String str = ptr [ i ] ;
p_string + = ( " \" " + str . c_escape ( ) + " \" " ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : VECTOR2_ARRAY : {
p_string + = ( " PoolVector2Array( " ) ;
DVector < Vector2 > data = p_variant ;
int len = data . size ( ) ;
DVector < Vector2 > : : Read r = data . read ( ) ;
const Vector2 * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( rtosfix ( ptr [ i ] . x ) + " , " + rtosfix ( ptr [ i ] . y ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : VECTOR3_ARRAY : {
p_string + = ( " PoolVector3Array( " ) ;
DVector < Vector3 > data = p_variant ;
int len = data . size ( ) ;
DVector < Vector3 > : : Read r = data . read ( ) ;
const Vector3 * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( rtosfix ( ptr [ i ] . x ) + " , " + rtosfix ( ptr [ i ] . y ) + " , " + rtosfix ( ptr [ i ] . z ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
case Variant : : COLOR_ARRAY : {
p_string + = ( " PoolColorArray( " ) ;
DVector < Color > data = p_variant ;
int len = data . size ( ) ;
DVector < Color > : : Read r = data . read ( ) ;
const Color * ptr = r . ptr ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
if ( i > 0 )
p_string + = ( " , " ) ;
p_string + = ( rtosfix ( ptr [ i ] . r ) + " , " + rtosfix ( ptr [ i ] . g ) + " , " + rtosfix ( ptr [ i ] . b ) + " , " + rtosfix ( ptr [ i ] . a ) ) ;
}
p_string + = ( " ) " ) ;
} break ;
default : { }
}
return OK ;
}
void EditorExportGodot3 : : _save_text ( const String & p_path , ExportData & resource ) {
FileAccessRef f = FileAccess : : open ( p_path , FileAccess : : WRITE ) ;
if ( resource . nodes . size ( ) ) {
f - > store_line ( " [gd_scene load_steps= " + itos ( resource . nodes . size ( ) + resource . resources . size ( ) ) + " format=2] \n " ) ;
} else {
f - > store_line ( " [gd_resource type= \" " + resource . resources [ resource . resources . size ( ) - 1 ] . type + " \" load_steps= " + itos ( resource . resources . size ( ) ) + " format=2] \n " ) ;
}
for ( Map < int , ExportData : : Dependency > : : Element * E = resource . dependencies . front ( ) ; E ; E = E - > next ( ) ) {
f - > store_line ( " [ext_resource type= \" " + E - > get ( ) . type + " \" path= \" " + E - > get ( ) . path + " \" id= " + itos ( E - > key ( ) ) + " ] \n " ) ;
}
for ( int i = 0 ; i < resource . resources . size ( ) ; i + + ) {
if ( resource . nodes . size ( ) | | i < resource . resources . size ( ) - 1 ) {
f - > store_line ( " \n [sub_resource type= \" " + resource . resources [ i ] . type + " \" id= " + itos ( resource . resources [ i ] . index ) + " ] \n " ) ;
} else {
f - > store_line ( " \n [resource] \n " ) ;
}
for ( List < ExportData : : PropertyData > : : Element * E = resource . resources [ i ] . properties . front ( ) ; E ; E = E - > next ( ) ) {
String prop ;
_get_property_as_text ( E - > get ( ) . value , prop ) ;
f - > store_line ( E - > get ( ) . name + " = " + prop ) ;
}
}
for ( int i = 0 ; i < resource . nodes . size ( ) ; i + + ) {
String node_txt = " \n [node " ;
if ( resource . nodes [ i ] . name ! = String ( ) ) {
node_txt + = " name= \" " + String ( resource . nodes [ i ] . name ) . c_escape ( ) + " \" " ;
}
if ( resource . nodes [ i ] . parent ! = NodePath ( ) ) {
node_txt + = " parent= \" " + String ( resource . nodes [ i ] . parent ) . c_escape ( ) + " \" " ;
}
if ( resource . nodes [ i ] . owner ! = NodePath ( ) ) {
node_txt + = " owner= \" " + String ( resource . nodes [ i ] . owner ) . c_escape ( ) + " \" " ;
}
if ( resource . nodes [ i ] . type ! = String ( ) ) {
node_txt + = " type= \" " + resource . nodes [ i ] . type + " \" " ;
}
if ( resource . nodes [ i ] . instance ! = String ( ) ) {
String prop ;
_get_property_as_text ( resource . nodes [ i ] . instance , prop ) ;
node_txt + = " instance= " + prop + " " ;
}
node_txt + = " ] \n " ;
f - > store_line ( node_txt ) ;
for ( List < ExportData : : PropertyData > : : Element * E = resource . nodes [ i ] . properties . front ( ) ; E ; E = E - > next ( ) ) {
String prop ;
_get_property_as_text ( E - > get ( ) . value , prop ) ;
f - > store_line ( E - > get ( ) . name + " = " + prop ) ;
}
}
for ( int i = 0 ; i < resource . connections . size ( ) ; i + + ) {
String prop ;
_get_property_as_text ( resource . connections [ i ] . binds , prop ) ;
f - > store_line ( " \n [connection signal= \" " + resource . connections [ i ] . signal + " \" from= \" " + String ( resource . connections [ i ] . from ) . c_escape ( ) + " \" to= \" " + String ( resource . connections [ i ] . to ) . c_escape ( ) + " \" method= \" " + resource . connections [ i ] . method + " \" binds= " + prop + " ] " ) ;
}
for ( int i = 0 ; i < resource . editables . size ( ) ; i + + ) {
f - > store_line ( " [editable path= \" " + String ( resource . editables [ i ] ) . c_escape ( ) + " \" ] " ) ;
}
}
2017-02-15 12:29:11 +01:00
enum {
//numbering must be different from variant, in case new variant types are added (variant must be always contiguous for jumptable optimization)
VARIANT_NIL = 1 ,
VARIANT_BOOL = 2 ,
VARIANT_INT = 3 ,
VARIANT_REAL = 4 ,
VARIANT_STRING = 5 ,
VARIANT_VECTOR2 = 10 ,
VARIANT_RECT2 = 11 ,
VARIANT_VECTOR3 = 12 ,
VARIANT_PLANE = 13 ,
VARIANT_QUAT = 14 ,
VARIANT_AABB = 15 ,
VARIANT_MATRIX3 = 16 ,
VARIANT_TRANSFORM = 17 ,
VARIANT_MATRIX32 = 18 ,
VARIANT_COLOR = 20 ,
VARIANT_IMAGE = 21 ,
VARIANT_NODE_PATH = 22 ,
VARIANT_RID = 23 ,
VARIANT_OBJECT = 24 ,
VARIANT_INPUT_EVENT = 25 ,
VARIANT_DICTIONARY = 26 ,
VARIANT_ARRAY = 30 ,
VARIANT_RAW_ARRAY = 31 ,
VARIANT_INT_ARRAY = 32 ,
VARIANT_REAL_ARRAY = 33 ,
VARIANT_STRING_ARRAY = 34 ,
VARIANT_VECTOR3_ARRAY = 35 ,
VARIANT_COLOR_ARRAY = 36 ,
VARIANT_VECTOR2_ARRAY = 37 ,
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 ,
OBJECT_EXTERNAL_RESOURCE_INDEX = 3 ,
//version 2: added 64 bits support for float and int
FORMAT_VERSION = 2 ,
FORMAT_VERSION_CAN_RENAME_DEPS = 1
} ;
enum {
IMAGE_FORMAT_L8 , //luminance
IMAGE_FORMAT_LA8 , //luminance-alpha
IMAGE_FORMAT_R8 ,
IMAGE_FORMAT_RG8 ,
IMAGE_FORMAT_RGB8 ,
IMAGE_FORMAT_RGBA8 ,
IMAGE_FORMAT_RGB565 , //16 bit
IMAGE_FORMAT_RGBA4444 ,
IMAGE_FORMAT_RGBA5551 ,
IMAGE_FORMAT_RF , //float
IMAGE_FORMAT_RGF ,
IMAGE_FORMAT_RGBF ,
IMAGE_FORMAT_RGBAF ,
IMAGE_FORMAT_RH , //half float
IMAGE_FORMAT_RGH ,
IMAGE_FORMAT_RGBH ,
IMAGE_FORMAT_RGBAH ,
IMAGE_FORMAT_DXT1 , //s3tc bc1
IMAGE_FORMAT_DXT3 , //bc2
IMAGE_FORMAT_DXT5 , //bc3
IMAGE_FORMAT_ATI1 , //bc4
IMAGE_FORMAT_ATI2 , //bc5
IMAGE_FORMAT_BPTC_RGBA , //btpc bc6h
IMAGE_FORMAT_BPTC_RGBF , //float /
IMAGE_FORMAT_BPTC_RGBFU , //unsigned float
IMAGE_FORMAT_PVRTC2 , //pvrtc
IMAGE_FORMAT_PVRTC2A ,
IMAGE_FORMAT_PVRTC4 ,
IMAGE_FORMAT_PVRTC4A ,
IMAGE_FORMAT_ETC , //etc1
IMAGE_FORMAT_ETC2_R11 , //etc2
IMAGE_FORMAT_ETC2_R11S , //signed, NOT srgb.
IMAGE_FORMAT_ETC2_RG11 ,
IMAGE_FORMAT_ETC2_RG11S ,
IMAGE_FORMAT_ETC2_RGB8 ,
IMAGE_FORMAT_ETC2_RGBA8 ,
IMAGE_FORMAT_ETC2_RGB8A1 ,
} ;
static void _pad_buffer ( int p_bytes , FileAccess * f ) {
int extra = 4 - ( p_bytes % 4 ) ;
if ( extra < 4 ) {
for ( int i = 0 ; i < extra ; i + + )
f - > store_8 ( 0 ) ; //pad to 32
}
}
static void save_unicode_string ( const String & p_string , FileAccess * f , bool p_hi_bit = false ) {
CharString utf8 = p_string . utf8 ( ) ;
f - > store_32 ( uint32_t ( utf8 . length ( ) + 1 ) | ( p_hi_bit ? 0x80000000 : 0 ) ) ;
f - > store_buffer ( ( const uint8_t * ) utf8 . get_data ( ) , utf8 . length ( ) + 1 ) ;
}
void EditorExportGodot3 : : _save_binary_property ( const Variant & p_property , FileAccess * f ) {
switch ( p_property . get_type ( ) ) {
case Variant : : NIL : {
f - > store_32 ( VARIANT_NIL ) ;
// don't store anything
} break ;
case Variant : : BOOL : {
f - > store_32 ( VARIANT_BOOL ) ;
bool val = p_property ;
f - > store_32 ( val ) ;
} break ;
case Variant : : INT : {
f - > store_32 ( VARIANT_INT ) ;
int val = p_property ;
f - > store_32 ( int32_t ( val ) ) ;
} break ;
case Variant : : REAL : {
f - > store_32 ( VARIANT_REAL ) ;
f - > store_real ( p_property ) ;
} break ;
case Variant : : STRING : {
String str = p_property ;
if ( str . begins_with ( " @RESLOCAL: " ) ) {
f - > store_32 ( VARIANT_OBJECT ) ;
f - > store_32 ( OBJECT_INTERNAL_RESOURCE ) ;
f - > store_32 ( str . get_slice ( " : " , 1 ) . to_int ( ) ) ;
print_line ( " SAVE RES LOCAL: " + itos ( str . get_slice ( " : " , 1 ) . to_int ( ) ) ) ;
} else if ( str . begins_with ( " @RESEXTERNAL: " ) ) {
f - > store_32 ( VARIANT_OBJECT ) ;
f - > store_32 ( OBJECT_EXTERNAL_RESOURCE_INDEX ) ;
f - > store_32 ( str . get_slice ( " : " , 1 ) . to_int ( ) ) ;
print_line ( " SAVE RES EXTERNAL: " + itos ( str . get_slice ( " : " , 1 ) . to_int ( ) ) ) ;
} else {
f - > store_32 ( VARIANT_STRING ) ;
save_unicode_string ( str , f ) ;
}
} break ;
case Variant : : VECTOR2 : {
f - > store_32 ( VARIANT_VECTOR2 ) ;
Vector2 val = p_property ;
f - > store_real ( val . x ) ;
f - > store_real ( val . y ) ;
} break ;
case Variant : : RECT2 : {
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 . size . x ) ;
f - > store_real ( val . size . y ) ;
} break ;
case Variant : : VECTOR3 : {
f - > store_32 ( VARIANT_VECTOR3 ) ;
Vector3 val = p_property ;
f - > store_real ( val . x ) ;
f - > store_real ( val . y ) ;
f - > store_real ( val . z ) ;
} break ;
case Variant : : PLANE : {
f - > store_32 ( VARIANT_PLANE ) ;
Plane val = p_property ;
f - > store_real ( val . normal . x ) ;
f - > store_real ( val . normal . y ) ;
f - > store_real ( val . normal . z ) ;
f - > store_real ( val . d ) ;
} break ;
case Variant : : QUAT : {
f - > store_32 ( VARIANT_QUAT ) ;
Quat val = p_property ;
f - > store_real ( val . x ) ;
f - > store_real ( val . y ) ;
f - > store_real ( val . z ) ;
f - > store_real ( val . w ) ;
} break ;
case Variant : : _AABB : {
f - > store_32 ( VARIANT_AABB ) ;
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 . size . x ) ;
f - > store_real ( val . size . y ) ;
f - > store_real ( val . size . z ) ;
} break ;
case Variant : : MATRIX32 : {
f - > store_32 ( VARIANT_MATRIX32 ) ;
Matrix32 val = p_property ;
f - > store_real ( val . elements [ 0 ] . x ) ;
f - > store_real ( val . elements [ 0 ] . y ) ;
f - > store_real ( val . elements [ 1 ] . x ) ;
f - > store_real ( val . elements [ 1 ] . y ) ;
f - > store_real ( val . elements [ 2 ] . x ) ;
f - > store_real ( val . elements [ 2 ] . y ) ;
} break ;
case Variant : : MATRIX3 : {
f - > store_32 ( VARIANT_MATRIX3 ) ;
Matrix3 val = p_property ;
f - > store_real ( val . elements [ 0 ] . x ) ;
f - > store_real ( val . elements [ 0 ] . y ) ;
f - > store_real ( val . elements [ 0 ] . z ) ;
f - > store_real ( val . elements [ 1 ] . x ) ;
f - > store_real ( val . elements [ 1 ] . y ) ;
f - > store_real ( val . elements [ 1 ] . z ) ;
f - > store_real ( val . elements [ 2 ] . x ) ;
f - > store_real ( val . elements [ 2 ] . y ) ;
f - > store_real ( val . elements [ 2 ] . z ) ;
} break ;
case Variant : : TRANSFORM : {
f - > store_32 ( VARIANT_TRANSFORM ) ;
Transform val = p_property ;
f - > store_real ( val . basis . elements [ 0 ] . x ) ;
f - > store_real ( val . basis . elements [ 0 ] . y ) ;
f - > store_real ( val . basis . elements [ 0 ] . z ) ;
f - > store_real ( val . basis . elements [ 1 ] . x ) ;
f - > store_real ( val . basis . elements [ 1 ] . y ) ;
f - > store_real ( val . basis . elements [ 1 ] . z ) ;
f - > store_real ( val . basis . elements [ 2 ] . x ) ;
f - > store_real ( val . basis . elements [ 2 ] . y ) ;
f - > store_real ( val . basis . elements [ 2 ] . z ) ;
f - > store_real ( val . origin . x ) ;
f - > store_real ( val . origin . y ) ;
f - > store_real ( val . origin . z ) ;
} break ;
case Variant : : COLOR : {
f - > store_32 ( VARIANT_COLOR ) ;
Color val = p_property ;
f - > store_real ( val . r ) ;
f - > store_real ( val . g ) ;
f - > store_real ( val . b ) ;
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 ;
}
f - > store_32 ( IMAGE_ENCODING_RAW ) ;
f - > store_32 ( val . get_width ( ) ) ;
f - > store_32 ( val . get_height ( ) ) ;
f - > store_32 ( val . get_mipmaps ( ) ? 1 : 0 ) ;
switch ( val . get_format ( ) ) {
case Image : : FORMAT_GRAYSCALE : f - > store_32 ( IMAGE_FORMAT_L8 ) ; break ; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
case Image : : FORMAT_INTENSITY : f - > store_32 ( IMAGE_FORMAT_L8 ) ; break ; ///< one byte per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255
case Image : : FORMAT_GRAYSCALE_ALPHA : f - > store_32 ( IMAGE_FORMAT_LA8 ) ; break ; ///< two bytes per pixel: f->store_32(IMAGE_FORMAT_ ); break; 0-255. alpha 0-255
case Image : : FORMAT_RGB : f - > store_32 ( IMAGE_FORMAT_RGB8 ) ; break ; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B
case Image : : FORMAT_RGBA : f - > store_32 ( IMAGE_FORMAT_RGBA8 ) ; break ; ///< one byte R: f->store_32(IMAGE_FORMAT_ ); break; one byte G: f->store_32(IMAGE_FORMAT_ ); break; one byte B: f->store_32(IMAGE_FORMAT_ ); break; one byte A
case Image : : FORMAT_BC1 : f - > store_32 ( IMAGE_FORMAT_DXT1 ) ; break ; // DXT1
case Image : : FORMAT_BC2 : f - > store_32 ( IMAGE_FORMAT_DXT3 ) ; break ; // DXT3
case Image : : FORMAT_BC3 : f - > store_32 ( IMAGE_FORMAT_DXT5 ) ; break ; // DXT5
case Image : : FORMAT_BC4 : f - > store_32 ( IMAGE_FORMAT_ATI1 ) ; break ; // ATI1
case Image : : FORMAT_BC5 : f - > store_32 ( IMAGE_FORMAT_ATI2 ) ; break ; // ATI2
case Image : : FORMAT_PVRTC2 : f - > store_32 ( IMAGE_FORMAT_PVRTC2 ) ; break ;
case Image : : FORMAT_PVRTC2_ALPHA : f - > store_32 ( IMAGE_FORMAT_PVRTC2A ) ; break ;
case Image : : FORMAT_PVRTC4 : f - > store_32 ( IMAGE_FORMAT_PVRTC4 ) ; break ;
case Image : : FORMAT_PVRTC4_ALPHA : f - > store_32 ( IMAGE_FORMAT_PVRTC4A ) ; break ;
case Image : : FORMAT_ETC : f - > store_32 ( IMAGE_FORMAT_ETC ) ; break ; // regular ETC: f->store_32(IMAGE_FORMAT_ ); break; no transparency
default : f - > store_32 ( IMAGE_FORMAT_L8 ) ; break ;
}
int dlen = val . get_data ( ) . size ( ) ;
f - > store_32 ( dlen ) ;
DVector < uint8_t > : : Read r = val . get_data ( ) . read ( ) ;
f - > store_buffer ( r . ptr ( ) , dlen ) ;
_pad_buffer ( dlen , f ) ;
} break ;
case Variant : : NODE_PATH : {
f - > store_32 ( VARIANT_NODE_PATH ) ;
NodePath np = p_property ;
f - > store_16 ( np . get_name_count ( ) ) ;
uint16_t snc = np . get_subname_count ( ) ;
if ( np . is_absolute ( ) )
snc | = 0x8000 ;
f - > store_16 ( snc ) ;
for ( int i = 0 ; i < np . get_name_count ( ) ; i + + ) {
save_unicode_string ( np . get_name ( i ) , f , true ) ;
}
for ( int i = 0 ; i < np . get_subname_count ( ) ; i + + ) {
save_unicode_string ( np . get_subname ( i ) , f , true ) ;
}
save_unicode_string ( np . get_property ( ) , f , true ) ;
} break ;
case Variant : : _RID : {
f - > store_32 ( VARIANT_RID ) ;
WARN_PRINT ( " Can't save RIDs " ) ;
RID val = p_property ;
f - > store_32 ( val . get_id ( ) ) ;
} break ;
case Variant : : OBJECT : {
ERR_FAIL ( ) ;
} 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 ) ;
Dictionary d = p_property ;
f - > store_32 ( uint32_t ( d . size ( ) ) ) ;
List < Variant > keys ;
d . get_key_list ( & keys ) ;
for ( List < Variant > : : Element * E = keys . front ( ) ; E ; E = E - > next ( ) ) {
/*
if ( ! _check_type ( dict [ E - > get ( ) ] ) )
continue ;
*/
_save_binary_property ( E - > get ( ) , f ) ;
_save_binary_property ( d [ E - > get ( ) ] , f ) ;
}
} break ;
case Variant : : ARRAY : {
f - > store_32 ( VARIANT_ARRAY ) ;
Array a = p_property ;
f - > store_32 ( uint32_t ( a . size ( ) ) ) ;
for ( int i = 0 ; i < a . size ( ) ; i + + ) {
_save_binary_property ( a [ i ] , f ) ;
}
} break ;
case Variant : : RAW_ARRAY : {
f - > store_32 ( VARIANT_RAW_ARRAY ) ;
DVector < uint8_t > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < uint8_t > : : Read r = arr . read ( ) ;
f - > store_buffer ( r . ptr ( ) , len ) ;
_pad_buffer ( len , f ) ;
} break ;
case Variant : : INT_ARRAY : {
f - > store_32 ( VARIANT_INT_ARRAY ) ;
DVector < int > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < int > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + )
f - > store_32 ( r [ i ] ) ;
} break ;
case Variant : : REAL_ARRAY : {
f - > store_32 ( VARIANT_REAL_ARRAY ) ;
DVector < real_t > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < real_t > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
f - > store_real ( r [ i ] ) ;
}
} break ;
case Variant : : STRING_ARRAY : {
f - > store_32 ( VARIANT_STRING_ARRAY ) ;
DVector < String > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < String > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
save_unicode_string ( r [ i ] , f ) ;
}
} break ;
case Variant : : VECTOR3_ARRAY : {
f - > store_32 ( VARIANT_VECTOR3_ARRAY ) ;
DVector < Vector3 > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < Vector3 > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
f - > store_real ( r [ i ] . x ) ;
f - > store_real ( r [ i ] . y ) ;
f - > store_real ( r [ i ] . z ) ;
}
} break ;
case Variant : : VECTOR2_ARRAY : {
f - > store_32 ( VARIANT_VECTOR2_ARRAY ) ;
DVector < Vector2 > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < Vector2 > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
f - > store_real ( r [ i ] . x ) ;
f - > store_real ( r [ i ] . y ) ;
}
} break ;
case Variant : : COLOR_ARRAY : {
f - > store_32 ( VARIANT_COLOR_ARRAY ) ;
DVector < Color > arr = p_property ;
int len = arr . size ( ) ;
f - > store_32 ( len ) ;
DVector < Color > : : Read r = arr . read ( ) ;
for ( int i = 0 ; i < len ; i + + ) {
f - > store_real ( r [ i ] . r ) ;
f - > store_real ( r [ i ] . g ) ;
f - > store_real ( r [ i ] . b ) ;
f - > store_real ( r [ i ] . a ) ;
}
} break ;
default : {
ERR_EXPLAIN ( " Invalid variant " ) ;
ERR_FAIL ( ) ;
}
}
}
2017-02-13 02:52:02 +01:00
void EditorExportGodot3 : : _save_binary ( const String & p_path , ExportData & resource ) {
2017-02-15 12:29:11 +01:00
FileAccessRef f = FileAccess : : open ( p_path , FileAccess : : WRITE ) ;
ERR_FAIL_COND ( ! f . operator - > ( ) ) ;
//save header compressed
static const uint8_t header [ 4 ] = { ' R ' , ' S ' , ' R ' , ' C ' } ;
f - > store_buffer ( header , 4 ) ;
f - > store_32 ( 0 ) ;
f - > store_32 ( 0 ) ; //64 bits file, false for now
f - > store_32 ( 3 ) ; //major
f - > store_32 ( 0 ) ; //minor
f - > store_32 ( 2 ) ; //format version (2 is for 3.0)
//f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed
save_unicode_string ( resource . resources [ resource . resources . size ( ) - 1 ] . type , f . operator - > ( ) ) ;
for ( int i = 0 ; i < 16 ; i + + )
f - > store_32 ( 0 ) ; // unused
f - > store_32 ( 0 ) ; //no names saved
f - > store_32 ( resource . dependencies . size ( ) ) ; //amount of external resources
for ( Map < int , ExportData : : Dependency > : : Element * E = resource . dependencies . front ( ) ; E ; E = E - > next ( ) ) {
save_unicode_string ( E - > get ( ) . type , f . operator - > ( ) ) ;
save_unicode_string ( E - > get ( ) . path , f . operator - > ( ) ) ;
}
// save internal resource table
Vector < uint64_t > ofs_pos ;
f - > store_32 ( resource . resources . size ( ) ) ; //amount of internal resources
for ( int i = 0 ; i < resource . resources . size ( ) ; i + + ) {
save_unicode_string ( " local:// " + itos ( resource . resources [ i ] . index ) , f . operator - > ( ) ) ;
ofs_pos . push_back ( f - > get_pos ( ) ) ;
f - > store_64 ( 0 ) ;
}
Vector < uint64_t > ofs_table ;
// int saved_idx=0;
//now actually save the resources
for ( int i = 0 ; i < resource . resources . size ( ) ; i + + ) {
ofs_table . push_back ( f - > get_pos ( ) ) ;
save_unicode_string ( resource . resources [ i ] . type , f . operator - > ( ) ) ;
f - > store_32 ( resource . resources [ i ] . properties . size ( ) ) ;
2017-02-13 02:52:02 +01:00
2017-02-15 12:29:11 +01:00
for ( List < ExportData : : PropertyData > : : Element * E = resource . resources [ i ] . properties . front ( ) ; E ; E = E - > next ( ) ) {
save_unicode_string ( E - > get ( ) . name , f . operator - > ( ) , true ) ;
_save_binary_property ( E - > get ( ) . value , f . operator - > ( ) ) ;
}
}
for ( int i = 0 ; i < ofs_table . size ( ) ; i + + ) {
f - > seek ( ofs_pos [ i ] ) ;
f - > store_64 ( ofs_table [ i ] ) ;
}
f - > seek_end ( ) ;
f - > store_buffer ( ( const uint8_t * ) " RSRC " , 4 ) ; //magic at end
ERR_FAIL_COND ( f - > get_error ( ) ! = OK ) ;
2017-02-13 02:52:02 +01:00
}
void EditorExportGodot3 : : _save_config ( const String & p_path ) {
FileAccessRef f = FileAccess : : open ( p_path . plus_file ( " godot.cfg " ) , FileAccess : : WRITE ) ;
f - > store_line ( " [application] \n " ) ;
String name = Globals : : get_singleton ( ) - > get ( " application/name " ) ;
f - > store_line ( " name= \" " + name . c_escape ( ) + " \" " ) ;
String main_scene = Globals : : get_singleton ( ) - > get ( " application/main_scene " ) ;
f - > store_line ( " main_scene= \" " + _replace_resource ( main_scene ) . c_escape ( ) + " \" " ) ;
2017-02-15 12:29:11 +01:00
List < PropertyInfo > props ;
Globals : : get_singleton ( ) - > get_property_list ( & props ) ;
f - > store_line ( " [input] \n " ) ;
for ( List < PropertyInfo > : : Element * E = props . front ( ) ; E ; E = E - > next ( ) ) {
if ( ! E - > get ( ) . name . begins_with ( " input/ " ) )
continue ;
String prop ;
_get_property_as_text ( Globals : : get_singleton ( ) - > get ( E - > get ( ) . name ) , prop ) ;
String what = E - > get ( ) . name . get_slice ( " / " , 1 ) ;
f - > store_line ( what + " = " + prop ) ;
}
2017-02-13 02:52:02 +01:00
}
Error EditorExportGodot3 : : export_godot3 ( const String & p_path ) {
List < String > files ;
_find_files ( EditorFileSystem : : get_singleton ( ) - > get_filesystem ( ) , & files ) ;
EditorProgress progress ( " exporting " , " Exporting Godot 3.0 " , files . size ( ) ) ;
//find XML resources
resource_replace_map . clear ( ) ;
Set < String > xml_extensions ;
Set < String > binary_extensions ;
Set < String > text_extensions ;
{
List < String > xml_exts ;
ResourceFormatLoaderXML : : singleton - > get_recognized_extensions ( & xml_exts ) ;
for ( List < String > : : Element * E = xml_exts . front ( ) ; E ; E = E - > next ( ) ) {
xml_extensions . insert ( E - > get ( ) ) ;
}
}
{
List < String > binary_exts ;
ResourceFormatLoaderBinary : : singleton - > get_recognized_extensions ( & binary_exts ) ;
for ( List < String > : : Element * E = binary_exts . front ( ) ; E ; E = E - > next ( ) ) {
binary_extensions . insert ( E - > get ( ) ) ;
}
}
{
List < String > text_exts ;
ResourceFormatLoaderText : : singleton - > get_recognized_extensions ( & text_exts ) ;
for ( List < String > : : Element * E = text_exts . front ( ) ; E ; E = E - > next ( ) ) {
text_extensions . insert ( E - > get ( ) ) ;
}
}
for ( List < String > : : Element * E = files . front ( ) ; E ; E = E - > next ( ) ) {
String file = E - > get ( ) ;
if ( xml_extensions . has ( file . extension ( ) . to_lower ( ) ) ) {
if ( ResourceLoader : : get_resource_type ( file ) = = " PackedScene " ) {
resource_replace_map [ file ] = file . basename ( ) + " .tscn " ;
} else {
resource_replace_map [ file ] = file . basename ( ) + " .tres " ;
}
}
}
DirAccess * directory = DirAccess : : create ( DirAccess : : ACCESS_FILESYSTEM ) ;
if ( directory - > change_dir ( p_path ) ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( ERR_CANT_OPEN ) ;
}
int idx = 0 ;
for ( List < String > : : Element * E = files . front ( ) ; E ; E = E - > next ( ) ) {
String path = E - > get ( ) ;
String extension = path . extension ( ) . to_lower ( ) ;
String target_path ;
bool repack = false ;
target_path = p_path . plus_file ( path . replace ( " res:// " , " " ) ) ;
progress . step ( target_path . get_file ( ) , idx + + ) ;
print_line ( " exporting: " + target_path ) ;
if ( directory - > make_dir_recursive ( target_path . get_base_dir ( ) ) ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( ERR_CANT_CREATE ) ;
}
ExportData resource_data ;
if ( xml_extensions . has ( extension ) ) {
Error err = ResourceLoader : : get_export_data ( path , resource_data ) ;
if ( err ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( err ) ;
}
} else if ( text_extensions . has ( extension ) ) {
Error err = ResourceLoader : : get_export_data ( path , resource_data ) ;
if ( err ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( err ) ;
}
} else if ( binary_extensions . has ( extension ) ) {
Error err = ResourceLoader : : get_export_data ( path , resource_data ) ;
if ( err ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( err ) ;
}
} else {
//single file, copy it
Error err = directory - > copy ( path , target_path ) ;
if ( err ! = OK ) {
memdelete ( directory ) ;
ERR_FAIL_V ( err ) ;
}
continue ; //no longer needed to do anything, just copied the file!
}
if ( resource_data . nodes . size ( ) = = 0 & & resource_data . resources [ resource_data . resources . size ( ) - 1 ] . type = = " PackedScene " ) {
//must unpack a PackedScene
_unpack_packed_scene ( resource_data ) ;
repack = true ;
}
_convert_resources ( resource_data ) ;
if ( repack ) {
_pack_packed_scene ( resource_data ) ;
}
if ( xml_extensions . has ( extension ) ) {
String save_path = resource_replace_map [ target_path ] ;
_save_text ( save_path , resource_data ) ;
} else if ( text_extensions . has ( extension ) ) {
_save_text ( target_path , resource_data ) ;
} else if ( binary_extensions . has ( extension ) ) {
_save_binary ( target_path , resource_data ) ;
}
}
memdelete ( directory ) ;
_save_config ( p_path ) ;
return OK ;
}
EditorExportGodot3 : : EditorExportGodot3 ( ) {
int idx = 0 ;
while ( prop_renames [ idx ] [ 0 ] ! = NULL ) {
prop_rename_map [ prop_renames [ idx ] [ 0 ] ] = prop_renames [ idx ] [ 1 ] ;
idx + + ;
}
idx = 0 ;
while ( type_renames [ idx ] [ 0 ] ! = NULL ) {
type_rename_map [ type_renames [ idx ] [ 0 ] ] = type_renames [ idx ] [ 1 ] ;
idx + + ;
}
idx = 0 ;
while ( signal_renames [ idx ] [ 0 ] ! = NULL ) {
signal_rename_map [ signal_renames [ idx ] [ 0 ] ] = signal_renames [ idx ] [ 1 ] ;
idx + + ;
}
}