From 83255ae28168ddfe2a2354fa91d37d8ef1df6c5a Mon Sep 17 00:00:00 2001 From: Shariq Shah Date: Thu, 28 Sep 2017 00:07:40 +0500 Subject: [PATCH] Implemented better handling of finding opening and closing braces in new parser --- README.md | 6 ++ src/common/parser.c | 52 +++++++--- src/game/config_vars.c | 2 +- src/game/main.c | 4 +- src/libsymmetry/entity.c | 2 +- src/libsymmetry/game.c | 210 +++++++++++++++++++-------------------- src/libsymmetry/scene.c | 8 +- 7 files changed, 161 insertions(+), 123 deletions(-) diff --git a/README.md b/README.md index 19ae4cd..85066b6 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ - ### Keybindings ``` + # All keys are parsed by comparing the output of SDL_GetKeyname # Each line represents a keybinding Move_Forward: W @@ -60,6 +61,7 @@ # Single modifier keys are allowed but multiple modifier keys without corresponding # non-modifier key are not allowed Sprint: Left Shift + ``` - ### Level/Scene @@ -100,6 +102,7 @@ - Fat entites with all related properties, i.e. position, mesh etc in them. Easy to serialize, memory friendly, simple to implement but would require significant changes to the current codebase, for example: ``` + struct Entity { int type; @@ -126,11 +129,13 @@ } } }; + ``` - Change component implementation by using anonymous unions to simulate interfaces. e.g ``` + struct Component { int type; @@ -141,6 +146,7 @@ struct Camera {....}; } } + ``` - Use handles for assets diff --git a/src/common/parser.c b/src/common/parser.c index 87e7a84..89304a6 100644 --- a/src/common/parser.c +++ b/src/common/parser.c @@ -107,37 +107,62 @@ bool parser_load_objects(FILE* file, const char* filename) continue; } + // Check if type string is valid + int type_str_len = strnlen(type_str, HASH_MAX_KEY_LEN); + if(type_str_len < 3 || strncmp(type_str, "{", HASH_MAX_KEY_LEN) == 0 || strncmp(type_str, "}", HASH_MAX_KEY_LEN) == 0) + { + log_warning("Invalid object type '%s' on line %d", type_str, current_line); + continue; + } + long obj_beginning = -1; long obj_ending = -1; - int obj_begin_expexted_at = current_line + 1; + int obj_begin_expexted_at = current_line; bool found_next_before_current_ended = false; /* Opening brace and closing brace */ - while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + char c = ' '; + int line_len = strnlen(line_buffer, MAX_LINE_LEN); + int seek_amount = line_len - type_str_len; + fseek(file, -seek_amount, SEEK_CUR); + while(!feof(file)) { - current_line++; - if(strchr(line_buffer, '{')) + c = fgetc(file); + if(c == '\n') { - obj_beginning = ftell(file) - strlen(line_buffer); - while(fgets(line_buffer, MAX_LINE_LEN - 1, file)) + current_line++; + continue; + } + + if(c == '{') + { + obj_beginning = ftell(file) - 1; + c = ' '; + while(!feof(file)) { - current_line++; + c = fgetc(file); + if(c == '\n') + { + current_line++; + continue; + } + /* check if we found opening brace of next object, - if this is true then it means that this object is missing - it's closing brace and we should stop */ - if(strchr(line_buffer, '{')) + if this is true then it means that this object is missing + it's closing brace and we should stop */ + if(c == '{') { found_next_before_current_ended = true; break; } - - if(strchr(line_buffer, '}')) + + if(c == '}') { obj_ending = ftell(file); break; } } - if(obj_ending) break; + if(obj_ending != -1) break; } } @@ -157,6 +182,7 @@ bool parser_load_objects(FILE* file, const char* filename) } memset(obj_str, '\0', 1024); + memset(line_buffer, '\0', MAX_LINE_LEN); fseek(file, obj_beginning, SEEK_SET); fread(obj_str, obj_ending - obj_beginning, 1, file); log_to_stdout("Object found\nType: %s\n%s\n\n", type_str, obj_str); diff --git a/src/game/config_vars.c b/src/game/config_vars.c index 5ad4876..00373c6 100644 --- a/src/game/config_vars.c +++ b/src/game/config_vars.c @@ -60,7 +60,7 @@ void config_on_parser_assign(const char* key, const char* value, const char* fil bool config_vars_load(const char* filename, int directory_type) { bool success = false; - FILE* config_file = io_file_open(directory_type, filename, "r"); + FILE* config_file = io_file_open(directory_type, filename, "rb"); if(!config_file) { log_error("config:vars_load", "Could not open %s", filename); diff --git a/src/game/main.c b/src/game/main.c index ff87a96..296a4ca 100644 --- a/src/game/main.c +++ b/src/game/main.c @@ -12,7 +12,7 @@ static struct Platform_Api platform_api; static struct Window* window = NULL; static bool reload_game = false; -#if defined(__MSC_VER) +#if defined(_MSC_VER) static const char* lib_name = "libSymmetry.dll"; static const char* lib_copy_name = "libSymmetry.copy.dll"; #elif defined(__MINGW32__) || defined(__MINGW64__) @@ -232,7 +232,7 @@ void game_lib_reload(void) bool game_lib_load(void) { -#if defined(__MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) +#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__) if(!io_file_copy(DIRT_EXECUTABLE, lib_name, lib_copy_name)) { log_error("main:game_lib_load", "Failed to copy dll"); diff --git a/src/libsymmetry/entity.c b/src/libsymmetry/entity.c index 3a876a5..5076f6c 100644 --- a/src/libsymmetry/entity.c +++ b/src/libsymmetry/entity.c @@ -626,7 +626,7 @@ struct Entity* entity_read(FILE* file) struct Entity* entity_load(const char* filename, int directory_type) { - FILE* entity_file = platform->file.open(directory_type, filename, "r"); + FILE* entity_file = platform->file.open(directory_type, filename, "rb"); if(!entity_file) { log_error("entity:load", "Failed to open entity file %s for writing", filename); diff --git a/src/libsymmetry/game.c b/src/libsymmetry/game.c index f0c61a7..0530261 100644 --- a/src/libsymmetry/game.c +++ b/src/libsymmetry/game.c @@ -105,110 +105,110 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) void scene_setup(void) { - /* struct Entity* player = scene_add_new("player", ET_CAMERA); */ - /* game_state->player_node = player->id; */ - /* vec3 viewer_pos = {10, 5, 100}; */ - /* transform_set_position(player, &viewer_pos); */ - /* int render_width, render_height; */ - /* render_width = 1024; */ - /* render_height = 768; */ - /* camera_create(player, render_width, render_height); */ - /* camera_attach_fbo(player, render_width, render_height, 1, 1, 1); */ - /* vec4_fill(&player->camera.clear_color, 0.3f, 0.6f, 0.9f, 1.0f); */ - - /* vec4 color = {1.f, 1.f, 1.f, 1.f }; */ - /* struct Entity* new_ent = scene_add_new("Model_Entity", ET_STATIC_MESH); */ - /* vec3 position = {0, 0, -5}; */ - /* transform_translate(new_ent, &position, TS_WORLD); */ - /* new_ent->renderable = true; */ - /* model_create(new_ent, "default.pamesh", "Blinn_Phong"); */ - /* model_set_material_param(new_ent, "diffuse_color", &color); */ - /* int tex = texture_create_from_file("white.tga", TU_DIFFUSE); */ - /* model_set_material_param(new_ent, "diffuse_texture", &tex); */ - /* vec3 scale = {1, 1, 1}; */ - /* transform_scale(new_ent, &scale); */ - - /* /\* struct Entity* sound_ent = scene_add_as_child("Sound_ENT", ET_SOUND_SOURCE, new_ent->id); *\/ */ - /* /\* struct Sound_Source* sound_source = &sound_ent->sound_source; *\/ */ - /* /\* platform->sound.source_create(true, 1, &sound_source->source_handle, &sound_source->buffer_handles[0]); *\/ */ - /* /\* platform->sound.source_load_wav(sound_source->source_handle, *\/ */ - /* /\* sound_source->buffer_handles[0], *\/ */ - /* /\* "BigExplosion.wav"); *\/ */ - /* /\* //sound_source_relative_set(source, true); *\/ */ - /* /\* platform->sound.source_volume_set(sound_source->source_handle, 1.f); *\/ */ - /* /\* platform->sound.source_loop_set(sound_source->source_handle, true); *\/ */ - /* /\* platform->sound.source_play(sound_source->source_handle); *\/ */ - - /* int parent_node = new_ent->id; */ - /* int num_suz = 10; */ - /* srand(time(NULL)); */ - /* for(int i = 0; i < num_suz; i++) */ - /* { */ - /* int x = rand() % num_suz; */ - /* int y = rand() % num_suz; */ - /* int z = rand() % num_suz; */ - /* x++; y++; z++; */ - /* struct Entity* suz = scene_add_as_child("Suzanne", ET_STATIC_MESH, parent_node); */ - /* //struct Entity* suz = scene_add_new("Suzanne", ET_STATIC_MESH); */ - /* suz->renderable = true; */ - /* model_create(suz, "default.pamesh", "Blinn_Phong"); */ - /* model_set_material_param(suz, "diffuse_color", &color); */ - /* float spec_str = 80.f; */ - /* model_set_material_param(suz, "specular_strength", &spec_str); */ - /* vec3 s_pos = {x, 0, z}; */ - /* transform_translate(suz, &s_pos, TS_WORLD); */ - /* } */ - - - /* struct Entity* ground = scene_add_new("Ground", ET_STATIC_MESH); */ - /* ground->renderable = true; */ - /* model_create(ground, "default.pamesh", "Blinn_Phong"); */ - /* model_set_material_param(ground, "diffuse_color", &color); */ - /* int white_tex = texture_create_from_file("white.tga", TU_DIFFUSE); */ - /* model_set_material_param(ground, "diffuse_texture", &white_tex); */ - /* float spec_str = 80.f; */ - /* model_set_material_param(ground, "specular_strength", &spec_str); */ - /* vec3 pos = {0, -5, 0}; */ - /* vec3 scale_ground = {400.f, 2.f, 400.f}; */ - /* transform_set_position(ground, &pos); */ - /* transform_scale(ground, &scale_ground); */ - - /* /\* struct Entity* screen = scene_add_new("Screen", NULL); *\/ */ - /* /\* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); *\/ */ - /* /\* screen_model->geometry_index = geom_find("Quad"); *\/ */ - /* /\* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); *\/ */ - /* /\* struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); *\/ */ - /* /\* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); *\/ */ - /* /\* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); *\/ */ - /* /\* cam->nearz = 0.1f; *\/ */ - /* /\* cam->farz = 50.f; *\/ */ - /* /\* camera_update_proj(cam); *\/ */ - /* /\* camera_attach_fbo(cam, 128, 128, 1, 1, 0); *\/ */ - /* /\* model_set_material_param(screen_model, "diffuse_color", &color); *\/ */ - /* /\* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); *\/ */ - - /* const int MAX_LIGHTS = 3; */ - /* for(int i = 0; i < MAX_LIGHTS; i++) */ - /* { */ - /* int x = rand() % MAX_LIGHTS; */ - /* int z = rand() % MAX_LIGHTS; */ - /* x++; z++; */ - /* struct Entity* light_ent = scene_add_new("Light_Ent", ET_LIGHT); */ - /* vec3 lt_pos = {x * 20, 0, z * 20}; */ - /* transform_set_position(light_ent, <_pos); */ - /* light_create(light_ent, LT_POINT); */ - /* vec3_fill(&light_ent->light.color, 1.f / (float)x, 1.f / ((rand() % 10) + 1.f), 1.f / (float)z); */ - /* light_ent->light.intensity = 1.f; */ - /* } */ - - /* /\* log_message("Sizeof Entity : %d", sizeof(struct Entity)); *\/ */ - - /* /\* struct Entity* light_ent = entity_find("Ground"); *\/ */ - /* /\* entity_save(light_ent, "ground.ent", DT_INSTALL); *\/ */ - - /* scene_save("test.scene", DIRT_INSTALL); */ - - /* //struct Entity* light = entity_load("light.ent", DT_INSTALL); */ + //struct Entity* player = scene_add_new("player", ET_CAMERA); + //game_state->player_node = player->id; + //vec3 viewer_pos = {10, 5, 100}; + //transform_set_position(player, &viewer_pos); + //int render_width, render_height; + //render_width = 1024; + //render_height = 768; + //camera_create(player, render_width, render_height); + //camera_attach_fbo(player, render_width, render_height, 1, 1, 1); + //vec4_fill(&player->camera.clear_color, 0.3f, 0.6f, 0.9f, 1.0f); + + //vec4 color = {1.f, 1.f, 1.f, 1.f }; + //struct Entity* new_ent = scene_add_new("Model_Entity", ET_STATIC_MESH); + //vec3 position = {0, 0, -5}; + //transform_translate(new_ent, &position, TS_WORLD); + //new_ent->renderable = true; + //model_create(new_ent, "default.pamesh", "Blinn_Phong"); + //model_set_material_param(new_ent, "diffuse_color", &color); + //int tex = texture_create_from_file("white.tga", TU_DIFFUSE); + //model_set_material_param(new_ent, "diffuse_texture", &tex); + //vec3 scale = {1, 1, 1}; + //transform_scale(new_ent, &scale); + + ///* struct Entity* sound_ent = scene_add_as_child("Sound_ENT", ET_SOUND_SOURCE, new_ent->id); */ + // /* struct Sound_Source* sound_source = &sound_ent->sound_source; */ + // /* platform->sound.source_create(true, 1, &sound_source->source_handle, &sound_source->buffer_handles[0]); */ + // /* platform->sound.source_load_wav(sound_source->source_handle, */ + // /* sound_source->buffer_handles[0], */ + // /* "BigExplosion.wav"); */ + ///* //sound_source_relative_set(source, true); */ + // /* platform->sound.source_volume_set(sound_source->source_handle, 1.f); */ + // /* platform->sound.source_loop_set(sound_source->source_handle, true); */ + // /* platform->sound.source_play(sound_source->source_handle); */ + + //int parent_node = new_ent->id; + //int num_suz = 10; + //srand(time(NULL)); + //for(int i = 0; i < num_suz; i++) + //{ + // int x = rand() % num_suz; + // int y = rand() % num_suz; + // int z = rand() % num_suz; + // x++; y++; z++; + // struct Entity* suz = scene_add_as_child("Suzanne", ET_STATIC_MESH, parent_node); + // //struct Entity* suz = scene_add_new("Suzanne", ET_STATIC_MESH); + // suz->renderable = true; + // model_create(suz, "default.pamesh", "Blinn_Phong"); + // model_set_material_param(suz, "diffuse_color", &color); + // float spec_str = 80.f; + // model_set_material_param(suz, "specular_strength", &spec_str); + // vec3 s_pos = {x, 0, z}; + // transform_translate(suz, &s_pos, TS_WORLD); + //} + // + + //struct Entity* ground = scene_add_new("Ground", ET_STATIC_MESH); + //ground->renderable = true; + //model_create(ground, "default.pamesh", "Blinn_Phong"); + //model_set_material_param(ground, "diffuse_color", &color); + //int white_tex = texture_create_from_file("white.tga", TU_DIFFUSE); + //model_set_material_param(ground, "diffuse_texture", &white_tex); + //float spec_str = 80.f; + //model_set_material_param(ground, "specular_strength", &spec_str); + //vec3 pos = {0, -5, 0}; + //vec3 scale_ground = {400.f, 2.f, 400.f}; + //transform_set_position(ground, &pos); + //transform_scale(ground, &scale_ground); + + ///* struct Entity* screen = scene_add_new("Screen", NULL); */ + ///* struct Model* screen_model = entity_component_add(screen, C_MODEL, NULL, NULL); */ + ///* screen_model->geometry_index = geom_find("Quad"); */ + ///* struct Entity* screen_camera = scene_add_as_child("Screen_Camera", NULL, screen->node); */ + ///* struct Transform* screen_camera_tran = entity_component_get(screen_camera, C_TRANSFORM); */ + ///* transform_rotate(screen_camera_tran, &UNIT_Y, 180.f, TS_WORLD); */ + ///* struct Camera* cam = entity_component_add(screen_camera, C_CAMERA, 50, 50); */ + ///* cam->nearz = 0.1f; */ + ///* cam->farz = 50.f; */ + ///* camera_update_proj(cam); */ + ///* camera_attach_fbo(cam, 128, 128, 1, 1, 0); */ + ///* model_set_material_param(screen_model, "diffuse_color", &color); */ + ///* model_set_material_param(screen_model, "diffuse_texture", &cam->render_tex); */ + + //const int MAX_LIGHTS = 3; + //for(int i = 0; i < MAX_LIGHTS; i++) + //{ + // int x = rand() % MAX_LIGHTS; + // int z = rand() % MAX_LIGHTS; + // x++; z++; + // struct Entity* light_ent = scene_add_new("Light_Ent", ET_LIGHT); + // vec3 lt_pos = {x * 20, 0, z * 20}; + // transform_set_position(light_ent, <_pos); + // light_create(light_ent, LT_POINT); + // vec3_fill(&light_ent->light.color, 1.f / (float)x, 1.f / ((rand() % 10) + 1.f), 1.f / (float)z); + // light_ent->light.intensity = 1.f; + //} + + /* log_message("Sizeof Entity : %d", sizeof(struct Entity)); */ + + /* struct Entity* light_ent = entity_find("Ground"); */ + /* entity_save(light_ent, "ground.ent", DT_INSTALL); */ + + //scene_save("test.scene", DIRT_INSTALL); + + //struct Entity* light = entity_load("light.ent", DT_INSTALL); if(scene_load("test.scene", DIRT_INSTALL)) { @@ -217,7 +217,7 @@ void scene_setup(void) game_state->player_node = player->id; } - FILE* obj_file = platform->file.open(DIRT_INSTALL, "obj_test.symtres", "r"); + FILE* obj_file = platform->file.open(DIRT_INSTALL, "test_scene.symtres", "rb"); if(obj_file) { parser_load_objects(obj_file, "obj_test.symtres"); diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c index f3a4da0..4482c36 100644 --- a/src/libsymmetry/scene.c +++ b/src/libsymmetry/scene.c @@ -19,6 +19,12 @@ void scene_init(void) struct Entity* scene_add_new(const char* name, const int type) { + if(root_node == -1) + { + log_warning("No root node in scene"); + struct Entity* root = entity_create("ROOT", ET_ROOT, -1); + root_node = root->id; + } return scene_add_as_child(name, type, root_node); } @@ -124,7 +130,7 @@ struct Entity* scene_get_parent(struct Entity* entity) bool scene_load(const char* filename, int directory_type) { - FILE* entity_file = platform->file.open(directory_type, filename, "r"); + FILE* entity_file = platform->file.open(directory_type, filename, "rb"); if(!entity_file) { log_error("scene:load", "Failed to open scenefile %s for reading", filename);