Implemented command to save scene to file

dev
Shariq Shah 6 years ago
parent a5f9184a4e
commit 651cbf1883
  1. 4
      src/common/parser.c
  2. 2
      src/common/parser.h
  3. 21
      src/game/console.c
  4. 51
      src/game/scene.c
  5. 5
      src/game/scene.h
  6. 2
      todo.txt

@ -243,6 +243,8 @@ int parser_object_type_from_str(const char* str)
else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL; else if(strncmp(str, "Material", HASH_MAX_KEY_LEN) == 0) object_type = PO_MATERIAL;
else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG; else if(strncmp(str, "Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_CONFIG;
else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY; else if(strncmp(str, "Key", HASH_MAX_KEY_LEN) == 0) object_type = PO_KEY;
else if(strncmp(str, "Scene_Entity_Entry", HASH_MAX_KEY_LEN) == 0) object_type = PO_SCENE_ENTITY_ENTRY;
else if(strncmp(str, "Scene_Config", HASH_MAX_KEY_LEN) == 0) object_type = PO_SCENE_CONFIG;
return object_type; return object_type;
} }
@ -257,6 +259,8 @@ const char* parser_object_type_to_str(int type)
case PO_CONFIG: return "Config"; case PO_CONFIG: return "Config";
case PO_KEY: return "Key"; case PO_KEY: return "Key";
case PO_UNKNOWN: return "Unknown"; case PO_UNKNOWN: return "Unknown";
case PO_SCENE_CONFIG: return "Scene_Config";
case PO_SCENE_ENTITY_ENTRY: return "Scene_Entity_Entry";
default: return "Unknown"; default: return "Unknown";
} }
} }

@ -8,6 +8,8 @@ enum Parser_Object_Type
{ {
PO_CONFIG, PO_CONFIG,
PO_ENTITY, PO_ENTITY,
PO_SCENE_CONFIG,
PO_SCENE_ENTITY_ENTRY,
PO_MATERIAL, PO_MATERIAL,
PO_MODEL, PO_MODEL,
PO_KEY, PO_KEY,

@ -15,6 +15,7 @@ static struct nk_color console_message_color[CMT_MAX];
static int console_filter(const struct nk_text_edit *box, nk_rune unicode); static int console_filter(const struct nk_text_edit *box, nk_rune unicode);
static void console_command_scene_save(struct Console* console, const char* command);
static void console_command_entity_save(struct Console* console, const char* command); static void console_command_entity_save(struct Console* console, const char* command);
static void console_command_entity_load(struct Console* console, const char* command); static void console_command_entity_load(struct Console* console, const char* command);
static void console_command_help(struct Console* console, const char* command); static void console_command_help(struct Console* console, const char* command);
@ -43,6 +44,7 @@ void console_init(struct Console* console)
} }
console->console_commands = hashmap_new(); console->console_commands = hashmap_new();
hashmap_ptr_set(console->console_commands, "scene_save", &console_command_scene_save);
hashmap_ptr_set(console->console_commands, "entity_save", &console_command_entity_save); hashmap_ptr_set(console->console_commands, "entity_save", &console_command_entity_save);
hashmap_ptr_set(console->console_commands, "entity_load", &console_command_entity_load); hashmap_ptr_set(console->console_commands, "entity_load", &console_command_entity_load);
hashmap_ptr_set(console->console_commands, "help", &console_command_help); hashmap_ptr_set(console->console_commands, "help", &console_command_help);
@ -224,3 +226,22 @@ void console_command_help(struct Console* console, const char* command)
} }
log_message("======================================"); log_message("======================================");
} }
void console_command_scene_save(struct Console* console, const char* command)
{
char filename[MAX_FILENAME_LEN];
memset(filename, '\0', MAX_FILENAME_LEN);
int params_read = sscanf(command, "%s", filename);
if(params_read != 1)
{
log_warning("Invalid parameters for command");
log_warning("Usage: scene_save [file name]");
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))
log_error("scene_save", "Command failed");
}

@ -15,6 +15,8 @@
#include "../system/sound.h" #include "../system/sound.h"
#include "../system/physics.h" #include "../system/physics.h"
#include "../system/platform.h" #include "../system/platform.h"
#include "../common/hashmap.h"
#include "renderer.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -64,14 +66,59 @@ void scene_init(struct Scene* scene)
scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR; scene->active_camera_index = game_state_get()->game_mode == GAME_MODE_GAME ? CAM_GAME : CAM_EDITOR;
} }
bool scene_load(struct Scene* scene, const char* filename, int dir_type) bool scene_load(struct Scene* scene, const char* filename, int directory_type)
{ {
return false; return false;
} }
bool scene_save(struct Scene* scene, const char* filename, int dir_type) bool scene_save(struct Scene* scene, const char* filename, int directory_type)
{ {
FILE* scene_file = io_file_open(directory_type, filename, "w");
if(!scene_file)
{
log_error("scene:save", "Failed to open scene file %s for writing");
return false; return false;
}
struct Parser* parser = parser_new();
//Start by saving the scene configuration information
struct Parser_Object* scene_config_object = parser_object_new(parser, PO_SCENE_CONFIG);
struct Render_Settings* render_settings = &game_state_get()->renderer->settings;
struct Hashmap* scene_data = scene_config_object->data;
hashmap_int_set(scene_data, "fog_type", render_settings->fog.mode);
hashmap_float_set(scene_data, "fog_density", render_settings->fog.density);
hashmap_float_set(scene_data, "fog_start_distance", render_settings->fog.start_dist);
hashmap_float_set(scene_data, "fog_max_distance", render_settings->fog.max_dist);
hashmap_vec3_set(scene_data, "fog_color", &render_settings->fog.color);
hashmap_vec3_set(scene_data, "ambient_light", &render_settings->ambient_light);
hashmap_vec4_set(scene_data, "debug_draw_color", &render_settings->debug_draw_color);
hashmap_bool_set(scene_data, "debug_draw_enabled", render_settings->debug_draw_enabled);
hashmap_int_set(scene_data, "debug_draw_mode", render_settings->debug_draw_mode);
hashmap_bool_set(scene_data, "debug_draw_physics", render_settings->debug_draw_physics);
for(int i = 0; i < MAX_ENTITIES; i++)
{
struct Entity* entity = &scene->entities[i];
if(!entity->active)
continue;
struct Parser_Object* object = parser_object_new(parser, PO_ENTITY);
if(!entity_write(entity, object, false))
{
log_error("scene:save", "Failed to save entity : %s to file : %s", entity->name, filename);
parser_free(parser);
fclose(scene_file);
return false;
}
}
if(parser_write_objects(parser, scene_file, filename))
log_message("Scene saved to %s", filename);
parser_free(parser);
fclose(scene_file);
return true;
} }
void scene_destroy(struct Scene* scene) void scene_destroy(struct Scene* scene)

@ -15,7 +15,6 @@ struct Raycast_Result;
struct Scene struct Scene
{ {
struct Render_Settings renderer_profile;
struct Entity root_entity; struct Entity root_entity;
struct Player player; struct Player player;
struct Entity entities[MAX_ENTITIES]; struct Entity entities[MAX_ENTITIES];
@ -27,8 +26,8 @@ struct Scene
}; };
void scene_init(struct Scene* scene); void scene_init(struct Scene* scene);
bool scene_load(struct Scene* scene, const char* filename, int dir_type); bool scene_load(struct Scene* scene, const char* filename, int directory_type);
bool scene_save(struct Scene* scene, const char* filename, int dir_type); bool scene_save(struct Scene* scene, const char* filename, int directory_type);
void scene_destroy(struct Scene* scene); void scene_destroy(struct Scene* scene);
void scene_update(struct Scene* scene, float dt); void scene_update(struct Scene* scene, float dt);
void scene_post_update(struct Scene* scene); void scene_post_update(struct Scene* scene);

@ -1,9 +1,11 @@
Todo: Todo:
- Implement entitie storing a reference or name of file they've been loaded from to help when they're being saved
- Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode - Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode
- Scene read/write to file with scene file only containing names of - Scene read/write to file with scene file only containing names of
entity archetypes entity archetypes
- Console command to read/write scene to/from file - Console command to read/write scene to/from file
- Editor functionality to read/write scene to/from file - 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 - 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 - Allow picking and selecting other entity types in editor i.e. the ones that don't have meshes
- Separate entity types in entity heirarchy view by the entity type or use a tree view to show parent/child relation or use different colours for different entity types - Separate entity types in entity heirarchy view by the entity type or use a tree view to show parent/child relation or use different colours for different entity types

Loading…
Cancel
Save