diff --git a/assets/test_scene.symtres b/assets/test_scene.symtres deleted file mode 100755 index cb81d28..0000000 --- a/assets/test_scene.symtres +++ /dev/null @@ -1,455 +0,0 @@ -Entity -{ - type : 2 - scale : 1.000 1.000 1.000 - rotation : 0.000 0.000 0.000 1.000 - is_listener : false - position : 0.000 0.000 0.000 - parent : NONE - name : ROOT - renderable : false -} - -Entity -{ - type : 3 - scale : 1.000 1.000 1.000 - fov : 60.0000 - rotation : 0.000 0.000 0.000 1.000 - zoom : 1.0000 - fbo_has_render_tex : true - resizeable : true - nearz : 0.1000 - is_listener : false - position : 10.000 5.000 100.000 - farz : 1000.0000 - fbo_height : 720 - parent : ROOT - ortho : false - fbo_width : 1280 - fbo_has_depth_tex : true - name : player - renderable : false - has_fbo : true - clear_color : 0.300 0.600 0.900 1.000 -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : sphere.symbres - is_listener : false - position : 0.000 50.000 0.000 - parent : ROOT - name : Model_Entity - renderable : true -} - -Entity -{ - type : 5 - scale : 400.000 2.000 400.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 0.000 0.000 0.000 - parent : ROOT - name : Ground - renderable : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.500 0.500 0.167 - radius : 20.0000 - is_listener : false - position : 40.000 0.000 120.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.111 0.333 0.250 - radius : 20.0000 - is_listener : false - position : 180.000 0.000 80.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.200 0.111 0.125 - radius : 20.0000 - is_listener : false - position : 100.000 0.000 160.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.500 0.167 0.100 - radius : 20.0000 - is_listener : false - position : 40.000 0.000 200.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 1.000 1.000 0.111 - radius : 20.0000 - is_listener : false - position : 20.000 0.000 180.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.167 0.125 1.000 - radius : 20.0000 - is_listener : false - position : 120.000 0.000 20.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 1.000 1.000 0.333 - radius : 20.0000 - is_listener : false - position : 20.000 0.000 60.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.143 0.167 0.200 - radius : 20.0000 - is_listener : false - position : 140.000 0.000 100.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.167 0.333 0.167 - radius : 20.0000 - is_listener : false - position : 120.000 0.000 120.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 4 - scale : 1.000 1.000 1.000 - inner_angle : 0.3491 - falloff : 1.5000 - light_type : 2 - depth_bias : 0.0005 - rotation : 0.000 0.000 0.000 1.000 - cast_shadow : false - intensity : 1.0000 - color : 0.125 0.250 0.100 - radius : 20.0000 - is_listener : false - position : 160.000 0.000 200.000 - outer_angle : 0.5236 - parent : ROOT - name : Light_Ent - pcf_enabled : false - renderable : false - valid : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 9.000 0.000 3.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : sphere.symbres - is_listener : false - position : 3.000 10.000 4.000 - parent : ROOT - name : Sphere_Ent - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 9.000 0.000 5.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 9.000 0.000 6.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 10.000 0.000 1.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 9.000 0.000 8.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 4.000 0.000 4.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 6.000 0.000 1.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 10.000 0.000 5.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 5 - scale : 1.000 1.000 1.000 - material : Blinn_Phong - rotation : 0.000 0.000 0.000 1.000 - geometry : default.pamesh - is_listener : false - position : 6.000 0.000 9.000 - parent : Model_Entity - name : Suzanne - renderable : true -} - -Entity -{ - type : 6 - scale : 1.000 1.000 1.000 - volume : 0.5000 - rolloff_factor : 0.9500 - rotation : 0.000 0.000 0.000 1.000 - loop : true - sound_min_distance : 1.0000 - playing : true - is_listener : false - position : 0.000 0.000 0.000 - source_filename : sounds/teh_beatz.wav - parent : Suzanne - sound_type : 0 - sound_max_distance : 10.0000 - name : Sound_Ent - sound_attenuation_type : 1 - renderable : false -} - diff --git a/src/game/console.c b/src/game/console.c index d3598d3..b29cb11 100755 --- a/src/game/console.c +++ b/src/game/console.c @@ -301,9 +301,7 @@ void console_command_scene_save(struct Console* console, const char* command) return; } - char full_filename[MAX_FILENAME_LEN]; - snprintf(full_filename, MAX_FILENAME_LEN, "scenes/%s.symtres", filename); - if(!scene_save(game_state_get()->scene, full_filename, DIRT_INSTALL)) + if(!scene_save(game_state_get()->scene, filename, DIRT_INSTALL)) log_error("scene_save", "Command failed"); } @@ -320,9 +318,7 @@ void console_command_scene_load(struct Console* console, const char* command) return; } - char full_filename[MAX_FILENAME_LEN]; - snprintf(full_filename, MAX_FILENAME_LEN, "scenes/%s.symtres", filename); - if(!scene_load(game_state_get()->scene, full_filename, DIRT_INSTALL)) + if(!scene_load(game_state_get()->scene, filename, DIRT_INSTALL)) log_error("scene_load", "Command failed"); } diff --git a/src/game/editor.c b/src/game/editor.c index 1880b62..4b84408 100755 --- a/src/game/editor.c +++ b/src/game/editor.c @@ -94,6 +94,8 @@ static void editor_axis_set(struct Editor* editor, int axis); static void editor_entity_select(struct Editor* editor, struct Entity* entity); static void editor_tool_set(struct Editor* editor, int mode); static void editor_tool_reset(struct Editor* editor); +static void editor_scene_dialog(struct Editor* editor, struct nk_context* context); +static void editor_entity_dialog(struct Editor* editor, struct nk_context* context); void editor_init(struct Editor* editor) { @@ -101,6 +103,8 @@ void editor_init(struct Editor* editor) editor->window_settings_editor = 0; editor->window_property_inspector = 0; editor->window_scene_heirarchy = 0; + editor->window_scene_dialog = 0; + editor->window_entity_dialog = 0; editor->camera_looking_around = 0; editor->selected_entity = NULL; editor->hovered_entity = NULL; @@ -128,6 +132,8 @@ void editor_init(struct Editor* editor) editor->picking_enabled = true; editor->draw_cursor_entity = false; editor->tool_scale_started = false; + editor->entity_operation_save = false; + editor->scene_operation_save = false; vec4_fill(&editor->cursor_entity_color, 0.f, 1.f, 1.f, 0.7f); vec4_fill(&editor->hovered_entity_color, 0.53, 0.87, 0.28, 0.5f); @@ -339,11 +345,41 @@ void editor_update(struct Editor* editor, float dt) nk_layout_row_begin(context, NK_DYNAMIC, editor->top_panel_height - 5, 8); nk_layout_row_push(context, 0.03f); - if(nk_menu_begin_label(context, "File", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, nk_vec2(150, 100))) + if(nk_menu_begin_label(context, "File", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE, nk_vec2(150, 150))) { nk_layout_row_dynamic(context, row_height, 1); - nk_menu_item_label(context, "Open", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); - nk_menu_item_label(context, "Save", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE); + if(nk_menu_item_label(context, "New Scene", NK_TEXT_ALIGN_MIDDLE | NK_TEXT_ALIGN_LEFT)) + { + struct Scene* scene = game_state->scene; + scene_destroy(scene); + scene_post_update(scene); + scene_init(scene); + } + + if(nk_menu_item_label(context, "Load Scene", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) + { + editor->window_scene_dialog = editor->window_scene_dialog == 0 ? 1 : 0; + editor->scene_operation_save = false; + } + + if(nk_menu_item_label(context, "Save Scene", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) + { + editor->window_scene_dialog = editor->window_scene_dialog == 0 ? 1 : 0; + editor->scene_operation_save = true; + } + + if(nk_menu_item_label(context, "Load Entity", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) + { + editor->window_entity_dialog = editor->window_entity_dialog == 0 ? 1 : 0; + editor->entity_operation_save = false; + } + + if(nk_menu_item_label(context, "Save Entity", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) + { + editor->window_entity_dialog = editor->window_entity_dialog == 0 ? 1 : 0; + editor->entity_operation_save = true; + } + if(nk_menu_item_label(context, "Back to Game", NK_TEXT_ALIGN_LEFT | NK_TEXT_ALIGN_MIDDLE)) { game_state->game_mode = GAME_MODE_GAME; @@ -368,6 +404,8 @@ void editor_update(struct Editor* editor, float dt) int debug_vars_visible = debug_vars->visible; nk_layout_row_dynamic(context, row_height, 1); nk_checkbox_label(context, "Scene Heirarchy", &editor->window_scene_heirarchy); + + nk_checkbox_label(context, "Property Inspector", &editor->window_property_inspector); nk_checkbox_label(context, "Debug Variables", &debug_vars_visible); if(debug_vars_visible != (int)debug_vars->visible) @@ -675,6 +713,92 @@ void editor_update(struct Editor* editor, float dt) } } + if(editor->window_scene_dialog) editor_scene_dialog(editor, context); +} + +void editor_scene_dialog(struct Editor* editor, struct nk_context* context) +{ + struct Game_State* game_state = game_state_get(); + struct Scene* scene = game_state->scene; + bool save = editor->scene_operation_save; + int row_height = 25; + int popup_x = 0; + int popup_y = 0; + int popup_width = 200; + int popup_height = 200; + int display_width = 0; + int display_height = 0; + int popup_flags = NK_WINDOW_TITLE | NK_WINDOW_BORDER; + window_get_drawable_size(game_state_get()->window, &display_width, &display_height); + popup_x = (display_width / 2) - (popup_width / 2); + popup_y = (display_height / 2) - (popup_height / 2); + + int background_window_flags = NK_WINDOW_BACKGROUND; + int previous_opacity = context->style.window.fixed_background.data.color.a; + context->style.window.fixed_background.data.color.a = 120; + if(nk_begin(context, save ? "Scene Save" : "Scene Load", nk_recti(0, 0, display_width, display_height), background_window_flags)) + { + nk_window_set_focus(context, save ? "Scene Save" : "Scene Load"); + if(nk_popup_begin(context, NK_POPUP_DYNAMIC, save ? "Save Scene" : "Load Scene", popup_flags, nk_recti(popup_x, popup_y, popup_width, popup_height))) + { + nk_layout_row_dynamic(context, row_height, 1); + nk_label(context, "Enter the name of the scene:", NK_TEXT_ALIGN_CENTERED | NK_TEXT_ALIGN_MIDDLE); + + static char scene_filename[MAX_FILENAME_LEN]; + static bool copy_scene_filename = true; + + if(copy_scene_filename) + { + memset(scene_filename, '\0', MAX_FILENAME_LEN); + } + + int scene_filename_flags = NK_EDIT_SIG_ENTER | NK_EDIT_GOTO_END_ON_ACTIVATE | NK_EDIT_FIELD; + int scene_filename_state = nk_edit_string_zero_terminated(context, scene_filename_flags, scene_filename, MAX_FILENAME_LEN, NULL); + if(scene_filename_state & NK_EDIT_ACTIVATED) + { + copy_scene_filename = false; + } + else if(scene_filename_state & NK_EDIT_COMMITED) + { + if(save) + scene_save(scene, scene_filename, DIRT_INSTALL); + else + scene_load(scene, scene_filename, DIRT_INSTALL); + copy_scene_filename = true; + editor->window_scene_dialog = 0; + nk_popup_close(context); + } + + nk_layout_row_dynamic(context, row_height, 3); + if(nk_button_label(context, "OK")) + { + if(save) + scene_save(scene, scene_filename, DIRT_INSTALL); + else + scene_load(scene, scene_filename, DIRT_INSTALL); + copy_scene_filename = true; + editor->window_scene_dialog = 0; + nk_popup_close(context); + } + + nk_spacing(context, 1); + + if(nk_button_label(context, "Cancel")) + { + copy_scene_filename = true; + editor->window_scene_dialog = 0; + nk_popup_close(context); + } + + nk_popup_end(context); + } + nk_end(context); + } + else + { + editor->window_scene_dialog = 0; + } + context->style.window.fixed_background.data.color.a = previous_opacity; } void editor_on_mousebutton_release(const struct Event* event) @@ -2044,3 +2168,7 @@ void editor_window_settings_editor(struct nk_context* context, struct Editor* ed nk_end(context); } +void editor_entity_dialog(struct Editor* editor, struct nk_context* context) +{ + +} diff --git a/src/game/editor.h b/src/game/editor.h index 5dd9722..808029c 100755 --- a/src/game/editor.h +++ b/src/game/editor.h @@ -15,6 +15,8 @@ struct Editor int window_settings_editor; int window_scene_heirarchy; int window_property_inspector; + int window_scene_dialog; + int window_entity_dialog; int camera_looking_around; struct Entity* selected_entity; struct Static_Mesh* cursor_entity; @@ -52,6 +54,8 @@ struct Editor vec4 axis_color_y; vec4 axis_color_z; bool picking_enabled; + bool scene_operation_save; + bool entity_operation_save; }; void editor_init(struct Editor* editor_state); diff --git a/src/game/game.c b/src/game/game.c index b0f251f..e914803 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -118,7 +118,7 @@ bool game_init(struct Window* window, struct Hashmap* cvars) /* Debug scene setup */ //game_scene_setup(); - scene_load(game_state->scene, "scenes/default.symtres", DIRT_INSTALL); + scene_load(game_state->scene, "default", DIRT_INSTALL); game_state->is_initialized = true; return game_state->is_initialized; } diff --git a/src/game/scene.c b/src/game/scene.c index f50a7b9..5c01554 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -78,7 +78,9 @@ void scene_init(struct Scene* scene) bool scene_load(struct Scene* scene, const char* filename, int directory_type) { - FILE* scene_file = io_file_open(directory_type, filename, "rb"); + char prefixed_filename[MAX_FILENAME_LEN + 16]; + snprintf(prefixed_filename, MAX_FILENAME_LEN + 16, "scenes/%s.symtres", filename); + FILE* scene_file = io_file_open(directory_type, prefixed_filename, "rb"); if(!scene_file) { log_error("scene:load", "Failed to open scene file %s for reading"); @@ -197,7 +199,9 @@ bool scene_load(struct Scene* scene, const char* filename, int directory_type) bool scene_save(struct Scene* scene, const char* filename, int directory_type) { - FILE* scene_file = io_file_open(directory_type, filename, "w"); + char prefixed_filename[MAX_FILENAME_LEN + 16]; + snprintf(prefixed_filename, MAX_FILENAME_LEN + 16, "scenes/%s.symtres", filename); + FILE* scene_file = io_file_open(directory_type, prefixed_filename, "w"); if(!scene_file) { log_error("scene:save", "Failed to open scene file %s for writing"); diff --git a/todo.txt b/todo.txt index b7870c8..11eafad 100644 --- a/todo.txt +++ b/todo.txt @@ -12,7 +12,6 @@ Todo: - Multisampled buffers to bring back aa - Implement behaviour that avoids writing normal entities that do not have children or parent to file to avoid inconsistencies when loading them - Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode - - Editor functionality to read/write scene to/from file - Folder management api to create/delete folders when none exist. Dirent would suffice for our simple needs? - Display default mesh when selected entity type in editor does not have a mesh - Allow picking and selecting other entity types in editor i.e. the ones that don't have meshes @@ -370,4 +369,5 @@ Done: * Command history in console * Added button to reset local transformations for selected entity in property inspector * Implmented renaming scene objects in editor - * Implemented setting/resetting parent entity for entity \ No newline at end of file + * Implemented setting/resetting parent entity for entity + * Editor functionality to read/write scene to/from file \ No newline at end of file