diff --git a/build/genie.lua b/build/genie.lua index a023bf2..2b2665f 100644 --- a/build/genie.lua +++ b/build/genie.lua @@ -58,26 +58,28 @@ solution "Symmetry" ------------------------- -- Game ------------------------- - project "Game" + project "Symmetry" kind "ConsoleApp" targetname "Symmetry" language "C" - files { "../src/common/**.c", "../src/common/**.h", "../src/game/**.c", "../src/game/**.h"} - defines {"GAME"} - + files { "../src/common/**.c", "../src/common/**.h", "../src/system/**.c", "../src/system/**.h", "../src/game/**.h", "../src/game/**.c"} + includedirs {"../include/common"} + defines {"USE_GLAD"} + configuration "linux" - includedirs {"../include/linux/sdl2/", "../include/common/soloud/", "../include/linux/"} - libdirs {"../lib/linux/sdl2/", "../lib/linux/soloud/", "../lib/linux/ode/"} - linkoptions {"'-Wl,-rpath,$$ORIGIN'"} - links {"SDL2", "m", "ode", "pthread"} + includedirs {"../include/linux/sdl2/", "../include/common/soloud/", "../include/linux/"} + libdirs {"../lib/linux/sdl2/", "../lib/linux/soloud/", "../lib/linux/ode/"} + linkoptions {"'-Wl,-rpath,$$ORIGIN'"} + links {"SDL2", "m", "ode", "pthread"} configuration {"windows", "vs2017"} - includedirs {"../include/windows/sdl2/", "../include/common/soloud/", "../include/windows/"} - libdirs {"../lib/windows/sdl2/", "../lib/windows/soloud/", "../lib/windows/ode/"} - links {"SDL2"} + includedirs {"../include/windows/sdl2/", "../include/common/soloud/", "../include/windows/"} + libdirs {"../lib/windows/sdl2/", "../lib/windows/soloud/", "../lib/windows/ode/"} + links {"SDL2"} configuration "Debug" - links {"soloud_x64_d"} + links {"soloud_x64_d"} + defines {"GL_DEBUG_CONTEXT"} configuration "Release" links {"soloud_x64"} @@ -90,7 +92,6 @@ solution "Symmetry" "copy ..\\..\\lib\\windows\\ode\\ode_double.dll release\\ /Y", "xcopy ..\\..\\assets ..\\..\\bin\\assets /s /e /h /i /y /d", "copy release\\Symmetry.exe ..\\..\\bin\\ /Y", - "copy release\\libSymmetry.dll ..\\..\\bin\\ /Y", "copy release\\SDL2.dll ..\\..\\bin\\ /Y", "copy release\\soloud_x64.dll ..\\..\\bin\\ /Y", "copy release\\ode_double.dll ..\\..\\bin\\ /Y", @@ -110,28 +111,6 @@ solution "Symmetry" "mklink /D debug\\assets ..\\..\\..\\assets" } links {"ode_doubled"} - ------------------------- - -- libSymmetry - ------------------------- - project "Library" - kind "SharedLib" - language "C" - targetname "Symmetry_Game" - defines {"GAME_LIB", "USE_GLAD"} - includedirs {"../include/common"} - files { "../src/common/**.c", "../src/common/**.h", "../src/libsymmetry/**.h", "../src/libsymmetry/**.c" } - - configuration {"windows", "vs2017"} - includedirs {"../include/windows/sdl2/"} - flags "NoImportLib" - - - configuration {"linux"} - includedirs {"../include/linux/sdl2/"} - - configuration "Debug" - defines {"GL_DEBUG_CONTEXT"} - newaction { trigger = "build_addon", diff --git a/src/common/common.h b/src/common/common.h deleted file mode 100755 index b29da09..0000000 --- a/src/common/common.h +++ /dev/null @@ -1,242 +0,0 @@ -#ifndef COMMON_H -#define COMMON_H - -#include - -#include "num_types.h" - -#ifdef GAME_LIB -extern struct Platform_Api* platform; -#endif - -#ifdef GAME -extern struct Game_Api game; -#endif - -struct Window; -struct Hashmap; -struct Sound_Source_Buffer; - -//Physics Decls -typedef void* Rigidbody; -typedef void* Collision_Shape; -typedef void (*RigidbodyMoveCB)(Rigidbody); -typedef void (*RigidbodyColCB)(Rigidbody, Rigidbody); - -// Function Pointer decls -typedef void (*Keyboard_Event_Func) (int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt); -typedef void (*Mousebutton_Event_Func) (int button, int state, int x, int y, int8 num_clicks); -typedef void (*Mousemotion_Event_Func) (int x, int y, int xrel, int yrel); -typedef void (*Mousewheel_Event_Func) (int x, int y); -typedef void (*Windowresize_Event_Func) (int x, int y); -typedef void (*Textinput_Event_Func) (const char* text); - -enum Directory_Type -{ - DIRT_USER, /* User directory or preferences directory */ - DIRT_INSTALL, /* Directory where the game's assets are, usually alongside the game's executable where the game is installed */ - DIRT_EXECUTABLE, /* Directory where the game's executable is located */ - DIRT_COUNT -}; - -enum Sound_Source_Type -{ - ST_WAV = 0, - ST_WAV_STREAM -}; - -enum Sound_Attenuation_Type -{ - SA_NONE = 0, // No attenuation - SA_INVERSE, // Inverse distance attenuation model - SA_LINEAR, // Linear distance attenuation model - SA_EXPONENTIAL // Exponential distance attenuation model -}; - -enum Collision_Shape_Type -{ - CST_BOX = 0, - CST_SPHERE, - CST_CYLINDER, - CST_CAPSULE, - CST_PLANE, - CST_TRIMESH, - CST_UNKNOWN -}; - -struct Raycast_Hit -{ - int entity_id; - float normal_x, normal_y, normal_z; -}; - -struct Physics_Api -{ - void (*init)(void); - void (*cleanup)(void); - void (*step)(float); - void (*gravity_set)(float x, float y, float z); - void (*gravity_get)(float* x, float* y, float* z); - - void (*cs_remove)(Collision_Shape shape); - void (*cs_data_set)(Collision_Shape shape, void* data); - void* (*cs_data_get)(Collision_Shape shape); - int (*cs_type_get)(Collision_Shape shape); - - Collision_Shape (*cs_plane_create)(float a, float b, float c, float d); - void (*cs_plane_params_set)(Collision_Shape shape, float a, float b, float c, float d); - void (*cs_plane_params_get)(Collision_Shape shape, float* a, float* b, float* c, float* d); - - Collision_Shape (*cs_box_create)(float x, float y, float z); - void (*cs_box_params_set)(Collision_Shape shape, float x, float y, float z); - void (*cs_box_params_get)(Collision_Shape shape, float* x, float* y, float* z); - - Collision_Shape (*cs_sphere_create)(float radius); - void (*cs_shpere_radius_set)(Collision_Shape shape, float radius); - float (*cs_sphere_radius_get)(Collision_Shape shape); - - Collision_Shape (*cs_capsule_create)(float radius, float length); - void (*cs_capsule_params_set)(Collision_Shape shape, float radius, float length); - void (*cs_capsule_params_get)(Collision_Shape shape, float* radius, float* length); - - Collision_Shape (*cs_ray_create)(float length, bool first_contact, bool backface_cull); - bool (*cs_ray_cast)(Collision_Shape ray, - struct Raycast_Hit* out_rayhit, - float pos_x, float pos_y, float pos_z, - float dir_x, float dir_y, float dir_z); - - void (*cs_position_set)(Collision_Shape shape, float x, float y, float z); - void (*cs_position_get)(Collision_Shape shape, float* x, float* y, float* z); - void (*cs_rotation_set)(Collision_Shape shape, float x, float y, float z, float w); - void (*cs_rotation_get)(Collision_Shape shape, float* x, float* y, float* z, float* w); - - void (*body_remove)(Rigidbody body); - Rigidbody (*body_box_create)(float length, float width, float height); - Rigidbody (*body_sphere_create)(float radius); - Rigidbody (*body_capsule_create)(float radius, float height); - Collision_Shape (*body_cs_get)(Rigidbody body); - void (*body_cs_set)(Rigidbody body, Collision_Shape shape); - void (*body_position_set)(Rigidbody body, float x, float y, float z); - void (*body_position_get)(Rigidbody body, float* x, float* y, float* z); - void (*body_rotation_set)(Rigidbody body, float x, float y, float z, float w); - void (*body_rotation_get)(Rigidbody body, float* x, float* y, float* z, float* w); - void (*body_set_moved_callback)(RigidbodyMoveCB callback); - void (*body_set_collision_callback)(RigidbodyColCB callback); - void (*body_kinematic_set)(Rigidbody body); - void (*body_mass_set)(Rigidbody body, float mass); - float (*body_mass_get)(Rigidbody body); - void* (*body_data_get)(Rigidbody body); - void (*body_data_set)(Rigidbody body, void* data); - void (*body_force_add)(Rigidbody body, float fx, float fy, float fz); -}; - -struct Sound_Api -{ - void (*update_3d)(void); - void (*volume_set)(float volume); - void (*listener_update)(float apos_x, float apos_y, float apos_z, - float afwd_x, float afwd_y, float afwd_z, - float aup_x, float aup_y, float aup_z); - - void (*source_instance_update_position)(uint source_instance, float apos_x, float apos_y, float apos_z); - uint (*source_instance_create)(struct Sound_Source_Buffer* source, bool is3d); - void (*source_instance_destroy)(uint source_instance); - void (*source_instance_volume_set)(uint source_instance, float volume); - void (*source_instance_loop_set)(uint source_instance, bool loop); - void (*source_instance_play)(uint source_instance); - void (*source_instance_pause)(uint source_instance); - void (*source_instance_rewind)(uint source_instance); - void (*source_instance_stop)(uint source_instance); - void (*source_instance_min_max_distance_set)(uint source_instance, float min_distance, float max_distance); - void (*source_instance_attenuation_set)(uint source_instance, int attenuation_type, float rolloff_factor); - float (*source_instance_volume_get)(uint source_instance); - bool (*source_instance_loop_get)(uint source_instance); - bool (*source_instance_is_paused)(uint source_instance); - - struct Sound_Source_Buffer* (*source_create)(const char* filename, int type); - struct Sound_Source_Buffer* (*source_get)(const char* name); - void (*source_destroy)(const char* buffer_name); - void (*source_volume_set)(struct Sound_Source_Buffer* source, float volume); - void (*source_loop_set)(struct Sound_Source_Buffer* source, bool loop); - void (*source_stop_all)(struct Sound_Source_Buffer* source); - void (*source_min_max_distance_set)(struct Sound_Source_Buffer* source, float min_distance, float max_distance); -}; - -struct Window_Api -{ - struct Window* (*create)(const char* title, int width, int height, int msaa, int msaa_levels); - void (*destroy)(struct Window* window); - void (*show)(struct Window* window); - void (*hide)(struct Window* window); - void (*raise)(struct Window* window); - void (*make_context_current)(struct Window* window); - void (*set_size)(struct Window* window, int width, int height); - void (*get_size)(struct Window* window, int* out_width, int* out_height); - void (*get_drawable_size)(struct Window* window, int* out_width, int* out_height); - void (*swap_buffers)(struct Window* window); - int (*fullscreen_set)(struct Window* window, int fullscreen); -}; - -struct File_Api -{ - char* (*read)(const int directory_type, const char* path, const char* mode, long* file_size); - FILE* (*open)(const int directory_type, const char* path, const char* mode); - bool (*copy)(const int directory_type, const char* source, const char* destination); - bool (*delete)(const int directory_type, const char* filename); -}; - -struct Config_Api -{ - bool (*load)(const char* filename, int directory_type); - bool (*save)(const char* filename, int directory_types); - struct Hashmap* (*get)(void); -}; - -struct Log_Api -{ - FILE* (*file_handle_get)(void); -}; - -struct Platform_Api -{ - // General platform api - void (*poll_events)(bool* out_quit); - void (*keyboard_callback_set)(Keyboard_Event_Func func); - void (*mousebutton_callback_set)(Mousebutton_Event_Func func); - void (*mousemotion_callback_set)(Mousemotion_Event_Func func); - void (*mousewheel_callback_set)(Mousewheel_Event_Func func); - void (*windowresize_callback_set)(Windowresize_Event_Func func); - void (*textinput_callback_set)(Textinput_Event_Func func); - int (*is_key_pressed)(int key); - int (*mousebutton_state_get)(uint button); - void (*mouse_position_get)(int* x, int* y); - void (*mouse_delta_get)(int* x, int* y); - void (*mouse_position_set)(struct Window* window, int x, int y); - void (*mouse_global_position_set)(int x, int y); - void (*mouse_relative_mode_set)(int relative_mode); - int (*mouse_relative_mode_get)(void); - uint32 (*ticks_get)(void); - char* (*install_directory_get)(void); - char* (*user_directory_get)(const char* organization, const char* application); - void (*clipboard_text_set)(const char* text); - char* (*clipboard_text_get)(void); - int (*key_from_name)(const char* key_name); - const char* (*key_name_get)(int key); - void* (*load_function_gl)(const char* name); - void (*reload_game_lib)(void); - - struct Window_Api window; - struct Sound_Api sound; - struct File_Api file; - struct Config_Api config; - struct Log_Api log; - struct Physics_Api physics; -}; - -struct Game_Api -{ - bool (*init)(struct Window*, struct Platform_Api* platform_api); - void (*cleanup)(void); -}; - -#endif diff --git a/src/common/log.c b/src/common/log.c index 0651a74..60834d7 100755 --- a/src/common/log.c +++ b/src/common/log.c @@ -145,16 +145,6 @@ void log_error(const char* context, const char* error, ...) fflush(log_file); } -FILE* log_file_handle_get(void) -{ - return log_file; -} - -void log_file_handle_set(FILE* file) -{ - log_file = file; -} - void log_message_callback_set(Log_Message_CB callback) { if(callback) diff --git a/src/common/log.h b/src/common/log.h index 0515484..2f15b65 100755 --- a/src/common/log.h +++ b/src/common/log.h @@ -15,8 +15,6 @@ void log_warning(const char* message, ...); void log_error(const char* context, const char* error, ...); void log_to_stdout(const char* message, ...); /* Only use when logging is not initialized */ void log_raw(const char* str, ...); -FILE* log_file_handle_get(void); -void log_file_handle_set(FILE* file); void log_message_callback_set(Log_Message_CB callback); void log_warning_callback_set(Log_Warning_CB callback); void log_error_callback_set(Log_Error_CB callback); diff --git a/src/common/parser.h b/src/common/parser.h index 13212b9..ad79bfd 100755 --- a/src/common/parser.h +++ b/src/common/parser.h @@ -1,38 +1,39 @@ -#ifndef PARSER_H -#define PARSER_H - -#include "common.h" - -enum Parser_Object_Type -{ - PO_CONFIG, - PO_ENTITY, - PO_MATERIAL, - PO_MODEL, - PO_KEY, - PO_UNKNOWN -}; - -struct Parser_Object -{ - int type; - struct Hashmap* data; -}; - -struct Parser -{ - struct Parser_Object* objects; -}; - -typedef void (*Parser_Assign_Func)(const char* key, const char* value, const char* filename, int current_line); - -bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line); -struct Parser* parser_load_objects(FILE* file, const char* filename); -void parser_free(struct Parser* parser); -struct Parser* parser_new(void); -struct Parser_Object* parser_object_new(struct Parser* parser, int type); -bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename); +#ifndef PARSER_H +#define PARSER_H + +#include +#include + +enum Parser_Object_Type +{ + PO_CONFIG, + PO_ENTITY, + PO_MATERIAL, + PO_MODEL, + PO_KEY, + PO_UNKNOWN +}; + +struct Parser_Object +{ + int type; + struct Hashmap* data; +}; + +struct Parser +{ + struct Parser_Object* objects; +}; + +typedef void (*Parser_Assign_Func)(const char* key, const char* value, const char* filename, int current_line); + +bool parser_load(FILE* file, const char* filename, Parser_Assign_Func assign_func, bool return_on_emptyline, int current_line); +struct Parser* parser_load_objects(FILE* file, const char* filename); +void parser_free(struct Parser* parser); +struct Parser* parser_new(void); +struct Parser_Object* parser_object_new(struct Parser* parser, int type); +bool parser_write_objects(struct Parser* parser, FILE* file, const char* filename); int parser_object_type_from_str(const char* str); -const char* parser_object_type_to_str(int type); - -#endif +const char* parser_object_type_to_str(int type); + +#endif diff --git a/src/libsymmetry/bounding_volumes.c b/src/game/bounding_volumes.c similarity index 100% rename from src/libsymmetry/bounding_volumes.c rename to src/game/bounding_volumes.c diff --git a/src/libsymmetry/bounding_volumes.h b/src/game/bounding_volumes.h similarity index 100% rename from src/libsymmetry/bounding_volumes.h rename to src/game/bounding_volumes.h diff --git a/src/libsymmetry/camera.c b/src/game/camera.c similarity index 98% rename from src/libsymmetry/camera.c rename to src/game/camera.c index f33609b..5634c20 100755 --- a/src/libsymmetry/camera.c +++ b/src/game/camera.c @@ -11,6 +11,7 @@ #include "../common/utils.h" #include "../common/log.h" #include "gl_load.h" +#include "../system/platform.h" #include #include @@ -92,7 +93,7 @@ void camera_update_proj(struct Camera* camera) { int width, height; struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); + window_get_size(game_state->window, &width, &height); mat4_ortho(&camera->proj_mat, -width / camera->zoom, width / camera->zoom, @@ -209,7 +210,7 @@ struct Ray camera_screen_coord_to_ray(struct Camera* camera, int mouse_x, int mo int win_width = 0, win_height = 0; struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &win_width, &win_height); + window_get_size(game_state->window, &win_width, &win_height); float normalized_x = (2.f * (float)mouse_x) / (float)win_width - 1.f; float normalized_y = 1.f - (2.f * (float)mouse_y) / (float)win_height; diff --git a/src/libsymmetry/camera.h b/src/game/camera.h similarity index 100% rename from src/libsymmetry/camera.h rename to src/game/camera.h diff --git a/src/libsymmetry/console.c b/src/game/console.c similarity index 97% rename from src/libsymmetry/console.c rename to src/game/console.c index 9e3fe82..76e5bfb 100755 --- a/src/libsymmetry/console.c +++ b/src/game/console.c @@ -2,7 +2,7 @@ #include "gui.h" #include "game.h" #include "../common/log.h" -#include "../common/common.h" +#include "../system/platform.h" #include #include @@ -50,7 +50,7 @@ void console_update(struct Console* console, struct Gui_State* gui_state, float struct Game_State* game_state = game_state_get(); int win_width = 0, win_height = 0; - platform->window.get_drawable_size(game_state->window, &win_width, &win_height); + window_get_drawable_size(game_state->window, &win_width, &win_height); int half_height = win_height / 2; if(nk_begin_titled(context, "Console", "Console", nk_recti(0, 0, win_width, half_height), NK_WINDOW_SCROLL_AUTO_HIDE)) diff --git a/src/libsymmetry/console.h b/src/game/console.h similarity index 100% rename from src/libsymmetry/console.h rename to src/game/console.h diff --git a/src/libsymmetry/editor.c b/src/game/editor.c similarity index 99% rename from src/libsymmetry/editor.c rename to src/game/editor.c index fd60f2b..fb6a5a1 100755 --- a/src/libsymmetry/editor.c +++ b/src/game/editor.c @@ -19,10 +19,12 @@ #include "../common/variant.h" #include "../common/num_types.h" #include "../common/string_utils.h" -#include "../common/common.h" #include "bounding_volumes.h" #include "input.h" #include "scene.h" +#include "../system/file_io.h" +#include "../system/config_vars.h" +#include "../system/platform.h" #include #include @@ -91,7 +93,7 @@ void editor_init_camera(void) editor_camera->clear_color.z = 0.9f; editor_camera->clear_color.w = 1.f; - struct Hashmap* config = platform->config.get(); + struct Hashmap* config = config_vars_get(); int render_width = hashmap_int_get(config, "render_width"); int render_height = hashmap_int_get(config, "render_height"); camera_attach_fbo(editor_camera, render_width, render_height, true, true, true); @@ -183,7 +185,7 @@ void editor_update(float dt) struct Gui_State* gui_state = gui_state_get(); struct nk_context* context = &gui_state->context; int win_width = 0, win_height = 0; - platform->window.get_drawable_size(game_state->window, &win_width, &win_height); + window_get_drawable_size(game_state->window, &win_width, &win_height); int half_width = win_width / 2, half_height = win_height / 2; static int window_flags = NK_WINDOW_BORDER | NK_WINDOW_CLOSABLE | @@ -221,7 +223,7 @@ void editor_update(float dt) if(nk_button_label(context, "Render Settings")) editor_state.renderer_settings_window = !editor_state.renderer_settings_window; if(nk_button_label(context, "Save config")) - platform->config.save("config.symtres", DIRT_USER); + config_vars_save("config.symtres", DIRT_USER); nk_spacing(context, 1); nk_labelf(context, NK_TEXT_ALIGN_RIGHT | NK_TEXT_ALIGN_MIDDLE, "FPS : %.d", fps); } diff --git a/src/libsymmetry/editor.h b/src/game/editor.h similarity index 100% rename from src/libsymmetry/editor.h rename to src/game/editor.h diff --git a/src/libsymmetry/entity.c b/src/game/entity.c similarity index 92% rename from src/libsymmetry/entity.c rename to src/game/entity.c index c6e1972..f1c447e 100755 --- a/src/libsymmetry/entity.c +++ b/src/game/entity.c @@ -11,9 +11,10 @@ #include "framebuffer.h" #include "scene.h" #include "../common/variant.h" -#include "../common/common.h" #include "../common/parser.h" #include "../common/hashmap.h" +#include "../system/file_io.h" +#include "../system/physics.h" #include #include @@ -196,7 +197,7 @@ bool entity_write(struct Entity* entity, struct Parser_Object* object) bool entity_save(struct Entity* entity, const char* filename, int directory_type) { - FILE* entity_file = platform->file.open(directory_type, filename, "w"); + FILE* entity_file = io_file_open(directory_type, filename, "w"); if(!entity_file) { log_error("entity:save", "Failed to open entity file %s for writing"); @@ -453,7 +454,7 @@ struct Entity* entity_read(struct Parser_Object* object) bool entity_load(const char* filename, int directory_type) { - FILE* entity_file = platform->file.open(directory_type, filename, "rb"); + FILE* entity_file = io_file_open(directory_type, filename, "rb"); if(!entity_file) { log_error("entity:load", "Failed to open entity file %s for reading", filename); @@ -521,12 +522,12 @@ const char* entity_type_name_get(struct Entity* entity) void entity_rigidbody_on_move(Rigidbody body) { - struct Entity* entity = platform->physics.body_data_get(body); + struct Entity* entity = physics_body_data_get(body); vec3 pos = {0.f}; quat rot = {0.f}; - platform->physics.body_position_get(body, &pos.x, &pos.y, &pos.z); - platform->physics.body_rotation_get(body, &rot.x, &rot.y, &rot.z, &rot.w); + physics_body_position_get(body, &pos.x, &pos.y, &pos.z); + physics_body_rotation_get(body, &rot.x, &rot.y, &rot.z, &rot.w); quat_assign(&entity->transform.rotation, &rot); transform_set_position(entity, &pos); @@ -540,12 +541,12 @@ void entity_rigidbody_on_collision(Rigidbody body_A, Rigidbody body_B) if(body_A) { - ent_A = platform->physics.body_data_get(body_A); + ent_A = physics_body_data_get(body_A); } if(body_B) { - ent_B = platform->physics.body_data_get(body_B); + ent_B = physics_body_data_get(body_B); } //if(ent_A && ent_A->collision.on_collision) @@ -573,27 +574,27 @@ void entity_rigidbody_set(struct Entity * entity, struct Collision* collision, R { if(collision->rigidbody) { - platform->physics.body_remove(collision->rigidbody); + physics_body_remove(collision->rigidbody); } else if(collision->collision_shape) { - platform->physics.cs_remove(collision->collision_shape); + physics_cs_remove(collision->collision_shape); } collision->rigidbody = NULL; collision->collision_shape = NULL; } collision->rigidbody = body; - collision->collision_shape = platform->physics.body_cs_get(body); + collision->collision_shape = physics_body_cs_get(body); vec3 abs_pos = {0.f, 0.f, 0.f}; quat abs_rot = {0.f, 0.f, 0.f, 1.f}; transform_get_absolute_position(entity, &abs_pos); transform_get_absolute_rot(entity, &abs_rot); - platform->physics.body_rotation_set(body, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); - platform->physics.body_position_set(body, abs_pos.x, abs_pos.y, abs_pos.z); - platform->physics.body_data_set(body, entity); + physics_body_rotation_set(body, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); + physics_body_position_set(body, abs_pos.x, abs_pos.y, abs_pos.z); + physics_body_data_set(body, entity); } void entity_collision_shape_set(struct Entity* entity, struct Collision* collision, Collision_Shape shape) @@ -604,18 +605,18 @@ void entity_collision_shape_set(struct Entity* entity, struct Collision* collisi { if(collision->rigidbody) { - platform->physics.body_remove(collision->rigidbody); + physics_body_remove(collision->rigidbody); } else if(collision->collision_shape) { - platform->physics.cs_remove(collision->collision_shape); + physics_cs_remove(collision->collision_shape); } collision->rigidbody = NULL; collision->collision_shape = NULL; } collision->collision_shape = shape; - platform->physics.cs_data_set(shape, entity); + physics_cs_data_set(shape, entity); } void entity_rename(struct Entity* entity, const char* new_name) diff --git a/src/libsymmetry/entity.h b/src/game/entity.h similarity index 98% rename from src/libsymmetry/entity.h rename to src/game/entity.h index 88ab4fa..03fa3e7 100755 --- a/src/libsymmetry/entity.h +++ b/src/game/entity.h @@ -3,7 +3,8 @@ #include "../common/linmath.h" #include "../common/num_types.h" -#include "../common/common.h" +#include "../system/physics.h" +#include "../system/sound.h" #include "material.h" #define MAX_ENTITY_NAME_LEN 128 diff --git a/src/libsymmetry/event.h b/src/game/event.h similarity index 100% rename from src/libsymmetry/event.h rename to src/game/event.h diff --git a/src/libsymmetry/framebuffer.c b/src/game/framebuffer.c similarity index 100% rename from src/libsymmetry/framebuffer.c rename to src/game/framebuffer.c diff --git a/src/libsymmetry/framebuffer.h b/src/game/framebuffer.h similarity index 100% rename from src/libsymmetry/framebuffer.h rename to src/game/framebuffer.h diff --git a/src/libsymmetry/game.c b/src/game/game.c similarity index 95% rename from src/libsymmetry/game.c rename to src/game/game.c index d5e6391..3e47e3f 100755 --- a/src/libsymmetry/game.c +++ b/src/game/game.c @@ -30,7 +30,8 @@ #include "../common/parser.h" #include "../common/hashmap.h" #include "../common/variant.h" -#include "../common/common.h" +#include "../system/physics.h" +#include "../system/platform.h" #include "im_render.h" #define UNUSED(a) (void)a @@ -41,7 +42,6 @@ #define MAX_FRAME_TIME 0.5f -static bool game_run(void); static void game_update(float dt, bool* window_should_close); static void game_post_update(float dt); static void game_render(void); @@ -55,23 +55,14 @@ static void on_box_move(Rigidbody body); static void on_collision_test(struct Entity* this_ent, struct Entity* other_ent, Rigidbody body, Rigidbody body2); static struct Game_State* game_state = NULL; -struct Platform_Api* platform = NULL; -bool game_init(struct Window* window, struct Platform_Api* platform_api) +bool game_init(struct Window* window) { - if(!platform_api) - { - log_error("game:init", "Platform api not passed in!"); - return false; - } - - platform = malloc(sizeof(*platform)); - memcpy(platform, platform_api, sizeof(*platform_api)); game_state = malloc(sizeof(*game_state)); if(!game_state) { log_error("game:init", "Out of memory, failed to allocate game_state"); - return 0; + return false; } else { @@ -82,7 +73,6 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) game_state->scene = calloc(1, sizeof(*game_state->scene)); game_state->console = calloc(1, sizeof(*game_state->console)); - log_file_handle_set(platform->log.file_handle_get()); log_message_callback_set(game_on_log_message); log_warning_callback_set(game_on_log_warning); log_error_callback_set(game_on_log_error); @@ -105,10 +95,10 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) gui_init(); console_init(game_state->console); geom_init(); - platform->physics.init(); - platform->physics.gravity_set(0.f, -9.8f, 0.f); - platform->physics.body_set_moved_callback(entity_rigidbody_on_move); - platform->physics.body_set_collision_callback(entity_rigidbody_on_collision); + physics_init(); + physics_gravity_set(0.f, -9.8f, 0.f); + physics_body_set_moved_callback(entity_rigidbody_on_move); + physics_body_set_collision_callback(entity_rigidbody_on_collision); editor_init(); renderer_init(game_state->renderer); @@ -118,7 +108,7 @@ bool game_init(struct Window* window, struct Platform_Api* platform_api) /* Debug scene setup */ game_scene_setup(); game_state->is_initialized = true; - return game_run(); + return game_state->is_initialized; } void game_scene_setup(void) @@ -490,23 +480,23 @@ void game_debug(float dt) bool game_run(void) { - uint32 last_time = platform->ticks_get(); - bool should_window_close = 0; + uint32 last_time = platform_ticks_get(); + bool should_window_close = false; while(!should_window_close) { - uint32 curr_time = platform->ticks_get(); + uint32 curr_time = platform_ticks_get(); float delta_time = (float)(curr_time - last_time) / 1000.f; last_time = curr_time; if(delta_time > MAX_FRAME_TIME) delta_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */ gui_input_begin(); - platform->poll_events(&should_window_close); + platform_poll_events(&should_window_close); gui_input_end(); game_update(delta_time, &should_window_close); game_post_update(delta_time); game_render(); - platform->window.swap_buffers(game_state->window); + window_swap_buffers(game_state->window); } return true; } @@ -514,8 +504,8 @@ bool game_run(void) void game_update(float dt, bool* window_should_close) { if(input_is_key_pressed(KEY_ESCAPE)) *window_should_close = true; - if(input_map_state_get("Window_Fullscreen", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 1); - if(input_map_state_get("Window_Maximize", KS_RELEASED)) platform->window.fullscreen_set(game_state->window, 0); + if(input_map_state_get("Window_Fullscreen", KS_RELEASED)) window_fullscreen_set(game_state->window, true); + if(input_map_state_get("Window_Maximize", KS_RELEASED)) window_fullscreen_set(game_state->window, false); if(input_map_state_get("Console_Toggle", KS_RELEASED)) console_toggle(game_state->console); if(input_map_state_get("Editor_Toggle", KS_RELEASED)) { @@ -531,13 +521,6 @@ void game_update(float dt, bool* window_should_close) game_state->scene->active_camera_index = CAM_EDITOR; } } - - if(input_map_state_get("Reload_Game_Lib", KS_RELEASED)) - { - *window_should_close = true; - platform->reload_game_lib(); - return; - } //game_debug(dt); //game_debug_gui(dt); @@ -545,7 +528,7 @@ void game_update(float dt, bool* window_should_close) scene_update(game_state->scene, dt); if(game_state->game_mode == GAME_MODE_GAME) { - platform->physics.step(dt); + physics_step(dt); } else if(game_state->game_mode == GAME_MODE_EDITOR) { @@ -557,7 +540,7 @@ void game_post_update(float dt) { input_post_update(); scene_post_update(game_state->scene); - platform->sound.update_3d(); + sound_update_3d(); } void game_debug_gui(float dt) @@ -1908,11 +1891,7 @@ void game_cleanup(void) game_state = NULL; } - if(platform) - { - platform->physics.cleanup(); - free(platform); - } + physics_cleanup(); } struct Game_State* game_state_get(void) diff --git a/src/libsymmetry/game.h b/src/game/game.h similarity index 60% rename from src/libsymmetry/game.h rename to src/game/game.h index 734c766..7633dbf 100755 --- a/src/libsymmetry/game.h +++ b/src/game/game.h @@ -3,14 +3,7 @@ #include -#if defined(_MSC_VER) - #define SYMMETRY_EXPORT __declspec(dllexport) -#else - #define SYMMETRY_EXPORT -#endif - struct Window; -struct Platform_Api; struct Renderer; struct Scene; struct Entity; @@ -36,8 +29,9 @@ struct Game_State }; -struct Game_State* game_state_get(void); -SYMMETRY_EXPORT bool game_init(struct Window* window, struct Platform_Api* platform_api); -SYMMETRY_EXPORT void game_cleanup(void); +struct Game_State* game_state_get(void); +bool game_init(struct Window* window); +bool game_run(void); +void game_cleanup(void); #endif diff --git a/src/libsymmetry/geometry.c b/src/game/geometry.c similarity index 95% rename from src/libsymmetry/geometry.c rename to src/game/geometry.c index 3bf46a6..21380c2 100755 --- a/src/libsymmetry/geometry.c +++ b/src/game/geometry.c @@ -4,7 +4,7 @@ #include "../common/log.h" #include "renderer.h" #include "transform.h" -#include "../common/common.h" +#include "../system/file_io.h" #include "gl_load.h" #include @@ -229,7 +229,7 @@ static int load_from_file(struct Geometry* geometry, const char* filename) int success = 1; char* full_path = str_new("models/%s", filename); - FILE* file = platform->file.open(DIRT_INSTALL, full_path, "rb"); + FILE* file = io_file_open(DIRT_INSTALL, full_path, "rb"); free(full_path); if(file) { @@ -363,8 +363,8 @@ int geom_render_in_frustum(int index, struct Entity* entity, enum Geometry_Draw_Mode draw_mode) { - vec3 abs_pos, abs_scale; - transform_get_absolute_position(entity, &abs_pos); + vec3 abs_pos, abs_scale; + transform_get_absolute_position(entity, &abs_pos); transform_get_absolute_scale(entity, &abs_scale); struct Geometry* geometry = &geometry_list[index]; diff --git a/src/libsymmetry/geometry.h b/src/game/geometry.h similarity index 100% rename from src/libsymmetry/geometry.h rename to src/game/geometry.h diff --git a/src/libsymmetry/gl_load.c b/src/game/gl_load.c similarity index 95% rename from src/libsymmetry/gl_load.c rename to src/game/gl_load.c index 43171e4..60f8491 100755 --- a/src/libsymmetry/gl_load.c +++ b/src/game/gl_load.c @@ -1,7 +1,6 @@ #include "gl_load.h" #include "../common/log.h" -#include "../common/common.h" - +#include "../system/platform.h" #ifndef USE_GLAD @@ -30,7 +29,7 @@ bool gl_load_extentions(void) { bool success = true; #ifdef USE_GLAD - if(!gladLoadGLLoader(platform->load_function_gl)) + if(!gladLoadGLLoader(platform_load_function_gl)) success = false; #else diff --git a/src/libsymmetry/gl_load.h b/src/game/gl_load.h similarity index 100% rename from src/libsymmetry/gl_load.h rename to src/game/gl_load.h diff --git a/src/libsymmetry/glad.c b/src/game/glad.c similarity index 100% rename from src/libsymmetry/glad.c rename to src/game/glad.c diff --git a/src/libsymmetry/gui.c b/src/game/gui.c similarity index 98% rename from src/libsymmetry/gui.c rename to src/game/gui.c index e874967..4a881f8 100755 --- a/src/libsymmetry/gui.c +++ b/src/game/gui.c @@ -8,7 +8,8 @@ #include "input.h" #include "renderer.h" #include "../common/string_utils.h" -#include "../common/common.h" +#include "../system/platform.h" +#include "../system/file_io.h" #include #include @@ -88,7 +89,7 @@ bool gui_init(void) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); glBindVertexArray(0); - platform->textinput_callback_set(&gui_handle_textinput_event); + platform_textinput_callback_set(&gui_handle_textinput_event); //gui_font_set("Ubuntu-R.ttf", 14); //gui_font_set("FiraSans-Regular.ttf", 14); gui_font_set("roboto_condensed.ttf", 18); @@ -132,8 +133,8 @@ void gui_render(enum nk_anti_aliasing AA) mat4_identity(&gui_mat); struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); - platform->window.get_drawable_size(game_state->window, &display_width, &display_height); + window_get_size(game_state->window, &width, &height); + window_get_drawable_size(game_state->window, &display_width, &display_height); mat4_ortho(&gui_mat, 0.f, display_width, display_height, 0.f, -100.f, 100.f); scale.x = (float)display_width/(float)width; @@ -226,7 +227,7 @@ void gui_render(enum nk_anti_aliasing AA) void gui_handle_clipbard_paste(nk_handle usr, struct nk_text_edit *edit) { - char *text = platform->clipboard_text_get(); + char *text = platform_clipboard_text_get(); if(text) { nk_textedit_paste(edit, text, nk_strlen(text)); @@ -244,7 +245,7 @@ void gui_handle_clipbard_copy(nk_handle usr, const char *text, int len) if (!str) return; memcpy(str, text, (size_t)len); str[len] = '\0'; - platform->clipboard_text_set(str); + platform_clipboard_text_set(str); free(str); } @@ -372,7 +373,7 @@ void gui_font_set(const char* font_name, float font_size) struct nk_font_atlas* atlas = &gui_state->atlas; long size = 0; char* font_file_name = str_new("fonts/%s", font_name); - char* font_data = platform->file.read(DIRT_INSTALL, font_file_name, "rb", &size); + char* font_data = io_file_read(DIRT_INSTALL, font_file_name, "rb", &size); free(font_file_name); if(!font_data) { diff --git a/src/libsymmetry/gui.h b/src/game/gui.h similarity index 100% rename from src/libsymmetry/gui.h rename to src/game/gui.h diff --git a/src/libsymmetry/im_render.c b/src/game/im_render.c similarity index 100% rename from src/libsymmetry/im_render.c rename to src/game/im_render.c diff --git a/src/libsymmetry/im_render.h b/src/game/im_render.h similarity index 100% rename from src/libsymmetry/im_render.h rename to src/game/im_render.h diff --git a/src/libsymmetry/input.c b/src/game/input.c similarity index 90% rename from src/libsymmetry/input.c rename to src/game/input.c index d7e9725..6010b52 100755 --- a/src/libsymmetry/input.c +++ b/src/game/input.c @@ -6,10 +6,11 @@ #include "../common/log.h" #include "gui.h" #include "../common/string_utils.h" -#include "../common/common.h" #include "../common/hashmap.h" #include "../common/variant.h" #include "../common/parser.h" +#include "../system/platform.h" +#include "../system/file_io.h" static void input_on_key(int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt); static void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks); @@ -20,10 +21,10 @@ static struct Hashmap* key_bindings = NULL; void input_init(void) { - platform->keyboard_callback_set(&input_on_key); - platform->mousebutton_callback_set(&input_on_mousebutton); - platform->mousemotion_callback_set(&input_on_mousemotion); - platform->mousewheel_callback_set(&input_on_mousewheel); + platform_keyboard_callback_set(&input_on_key); + platform_mousebutton_callback_set(&input_on_mousebutton); + platform_mousemotion_callback_set(&input_on_mousemotion); + platform_mousewheel_callback_set(&input_on_mousewheel); key_bindings = hashmap_new(); @@ -43,7 +44,6 @@ void input_init(void) struct Key_Binding console_toggle_keys = {KEY_TILDE, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; struct Key_Binding win_fullscr_keys = {KEY_F11, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; struct Key_Binding win_max_keys = {KEY_F12, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; - struct Key_Binding reload_game_keys = {KEY_F5, KMOD_NONE, KEY_NONE, KMOD_NONE, KS_INACTIVE}; input_map_create("Move_Forward", forward_keys); input_map_create("Move_Backward", backward_keys); input_map_create("Move_Up", up_keys); @@ -59,7 +59,6 @@ void input_init(void) input_map_create("Console_Toggle", console_toggle_keys); input_map_create("Window_Fullscreen", win_fullscr_keys); input_map_create("Window_Maximize", win_max_keys); - input_map_create("Reload_Game_Lib", reload_game_keys); if(!input_keybinds_load("keybindings.symtres", DIRT_USER)) { @@ -89,7 +88,7 @@ void input_cleanup(void) bool input_keybinds_load(const char* filename, int directory_type) { - FILE* key_file = platform->file.open(directory_type, filename, "rb"); + FILE* key_file = io_file_open(directory_type, filename, "rb"); if(!key_file) { log_error("input:keybinds_load", "Could not open %s", filename); @@ -121,7 +120,7 @@ bool input_keybinds_load(const char* filename, int directory_type) if(hashmap_value_exists(object->data, "name")) name_temp = hashmap_str_get(object->data, "name"); if(hashmap_value_exists(object->data, "key_primary")) { - int key = platform->key_from_name(hashmap_str_get(object->data, "key_primary")); + int key = platform_key_from_name(hashmap_str_get(object->data, "key_primary")); if(key != KEY_UNKNOWN) { key_binding.key_primary = key; @@ -130,7 +129,7 @@ bool input_keybinds_load(const char* filename, int directory_type) if(hashmap_value_exists(object->data, "key_secondary")) { - int key = platform->key_from_name(hashmap_str_get(object->data, "key_secondary")); + int key = platform_key_from_name(hashmap_str_get(object->data, "key_secondary")); if(key != KEY_UNKNOWN) { key_binding.key_secondary = key; @@ -212,12 +211,12 @@ bool input_keybinds_save(const char* filename, int directory_type) bool mods_secondary_alt = ((key_binding->mods_secondary & KMD_ALT) == KMD_ALT) ? true : false; hashmap_str_set(object->data, "name", key); - hashmap_str_set(object->data, "key_primary", key_binding->key_primary == KEY_NONE ? "NONE" : platform->key_name_get(key_binding->key_primary)); + hashmap_str_set(object->data, "key_primary", key_binding->key_primary == KEY_NONE ? "NONE" : platform_key_name_get(key_binding->key_primary)); hashmap_bool_set(object->data, "mods_primary_ctrl", mods_primary_ctrl); hashmap_bool_set(object->data, "mods_primary_shift", mods_primary_shift); hashmap_bool_set(object->data, "mods_primary_alt", mods_primary_alt); - hashmap_str_set(object->data, "key_secondary", key_binding->key_secondary == KEY_NONE ? "NONE" : platform->key_name_get(key_binding->key_secondary)); + hashmap_str_set(object->data, "key_secondary", key_binding->key_secondary == KEY_NONE ? "NONE" : platform_key_name_get(key_binding->key_secondary)); hashmap_bool_set(object->data, "mods_secondary_ctrl", mods_secondary_ctrl); hashmap_bool_set(object->data, "mods_secondary_shift", mods_secondary_shift); hashmap_bool_set(object->data, "mods_secondary_alt", mods_secondary_alt); @@ -227,7 +226,7 @@ bool input_keybinds_save(const char* filename, int directory_type) bool write_success = false; - FILE* key_file = platform->file.open(directory_type, filename, "w"); + FILE* key_file = io_file_open(directory_type, filename, "w"); if(!key_file) { log_error("input:keybinds_save", "Could not open %s", filename); @@ -265,12 +264,12 @@ void input_on_mousewheel(int x, int y) void input_mouse_pos_get(int* xpos, int* ypos) { assert(xpos && ypos); - platform->mouse_position_get(xpos, ypos); + platform_mouse_position_get(xpos, ypos); } void input_mouse_pos_set(int xpos, int ypos) { - platform->mouse_global_position_set(xpos, ypos); + platform_mouse_global_position_set(xpos, ypos); } void input_on_key(int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt) @@ -315,7 +314,7 @@ void input_on_mousebutton(int button, int state, int x, int y, int8 num_clicks) void input_mouse_mode_set(enum Mouse_Mode mode) { - platform->mouse_relative_mode_set(mode == MM_NORMAL ? 0 : 1); + platform_mouse_relative_mode_set(mode == MM_NORMAL ? 0 : 1); } bool input_map_state_get(const char* name, int state) @@ -354,12 +353,12 @@ bool input_map_create(const char* name, struct Key_Binding key_combination) bool input_is_key_pressed(int key) { - return platform->is_key_pressed(key); + return platform_is_key_pressed(key); } bool input_mousebutton_state_get(uint button, int state_type) { - int current_state = platform->mousebutton_state_get(button); + int current_state = platform_mousebutton_state_get(button); return state_type == current_state ? true : false; } @@ -428,12 +427,12 @@ bool input_map_name_set(const char* name, const char* new_name) int input_mouse_mode_get(void) { int mouse_mode = MM_NORMAL; - if(platform->mouse_relative_mode_get()) mouse_mode = MM_RELATIVE; + if(platform_mouse_relative_mode_get()) mouse_mode = MM_RELATIVE; return mouse_mode; } void input_mouse_delta_get(int* xpos, int* ypos) { - platform->mouse_delta_get(xpos, ypos); + platform_mouse_delta_get(xpos, ypos); } diff --git a/src/libsymmetry/input.h b/src/game/input.h similarity index 100% rename from src/libsymmetry/input.h rename to src/game/input.h diff --git a/src/libsymmetry/light.c b/src/game/light.c similarity index 100% rename from src/libsymmetry/light.c rename to src/game/light.c diff --git a/src/libsymmetry/light.h b/src/game/light.h similarity index 100% rename from src/libsymmetry/light.h rename to src/game/light.h diff --git a/src/game/main.c b/src/game/main.c deleted file mode 100755 index 307852c..0000000 --- a/src/game/main.c +++ /dev/null @@ -1,323 +0,0 @@ -#include -#include - -#include "../common/log.h" -#include "sound.h" -#include "platform.h" -#include "physics.h" -#include "file_io.h" -#include "config_vars.h" -#include "../common/hashmap.h" -#include "../common/common.h" - -static struct Platform_Api platform_api; -static struct Window* window = NULL; -static bool reload_game = false; -#if defined(_MSC_VER) -static const char* lib_name = "Symmetry_Game.dll"; -static const char* lib_copy_name = "Symmetry_Game.copy.dll"; -#elif defined(__MINGW32__) || defined(__MINGW64__) -static const char* lib_name = "Symmetry_Game.dll"; -static const char* lib_copy_name = "Symmetry_Game.copy.dll"; -#endif - -void* game_lib_handle = NULL; -struct Game_Api game; - -bool init(void); -void cleanup(void); -bool game_lib_load(void); -void game_lib_reload(void); - -int main(int argc, char** args) -{ - if(!init()) - { - log_to_stdout("ERR:(Main) Could not initialize"); - } - else - { - platform_api = (struct Platform_Api) - { - .poll_events = &platform_poll_events, - .keyboard_callback_set = &platform_keyboard_callback_set, - .mousebutton_callback_set = &platform_mousebutton_callback_set, - .mousemotion_callback_set = &platform_mousemotion_callback_set, - .mousewheel_callback_set = &platform_mousewheel_callback_set, - .windowresize_callback_set = &platform_windowresize_callback_set, - .textinput_callback_set = &platform_textinput_callback_set, - .is_key_pressed = &platform_is_key_pressed, - .mousebutton_state_get = &platform_mousebutton_state_get, - .mouse_position_get = &platform_mouse_position_get, - .mouse_delta_get = &platform_mouse_delta_get, - .mouse_position_set = &platform_mouse_position_set, - .mouse_global_position_set = &platform_mouse_global_position_set, - .mouse_relative_mode_set = &platform_mouse_relative_mode_set, - .mouse_relative_mode_get = &platform_mouse_relative_mode_get, - .ticks_get = &platform_ticks_get, - .install_directory_get = &platform_install_directory_get, - .user_directory_get = &platform_user_directory_get, - .clipboard_text_set = &platform_clipboard_text_set, - .clipboard_text_get = &platform_clipboard_text_get, - .key_from_name = &platform_key_from_name, - .key_name_get = &platform_key_name_get, - .load_function_gl = &platform_load_function_gl, - .reload_game_lib = &game_lib_reload, - .sound = - { - .update_3d = &sound_update_3d, - .volume_set = &sound_volume_set, - .listener_update = &sound_listener_update, - .source_instance_update_position = &sound_source_instance_update_position, - .source_instance_create = &sound_source_instance_create, - .source_instance_destroy = &sound_source_instance_destroy, - .source_instance_volume_set = &sound_source_instance_volume_set, - .source_instance_loop_set = &sound_source_instance_loop_set, - .source_instance_play = &sound_source_instance_play, - .source_instance_pause = &sound_source_instance_pause, - .source_instance_rewind = &sound_source_instance_rewind, - .source_instance_stop = &sound_source_instance_stop, - .source_instance_min_max_distance_set = &sound_source_instance_min_max_distance_set, - .source_instance_attenuation_set = &sound_source_instance_attenuation_set, - .source_instance_volume_get = &sound_source_instance_volume_get, - .source_instance_loop_get = &sound_source_instance_loop_get, - .source_instance_is_paused = &sound_source_instance_is_paused, - .source_create = &sound_source_create, - .source_get = &sound_source_get, - .source_destroy = &sound_source_destroy, - .source_volume_set = &sound_source_volume_set, - .source_loop_set = &sound_source_loop_set, - .source_stop_all = &sound_source_stop_all, - .source_min_max_distance_set = &sound_source_min_max_distance_set - }, - .window = - { - .create = &window_create, - .destroy = &window_destroy, - .show = &window_show, - .raise = &window_raise, - .make_context_current = &window_make_context_current, - .set_size = &window_set_size, - .get_size = &window_get_size, - .get_drawable_size = &window_get_drawable_size, - .swap_buffers = &window_swap_buffers, - .fullscreen_set = &window_fullscreen_set - }, - .file = - { - .read = &io_file_read, - .open = &io_file_open, - .copy = &io_file_copy, - .delete = &io_file_delete - }, - .config = - { - .load = &config_vars_load, - .save = &config_vars_save, - .get = &config_vars_get - }, - .log = - { - .file_handle_get = &log_file_handle_get - }, - .physics = - { - .init = &physics_init, - .cleanup = &physics_cleanup, - .step = &physics_step, - .gravity_set = &physics_gravity_set, - .gravity_get = &physics_gravity_get, - - .body_position_set = &physics_body_position_set, - .body_position_get = &physics_body_position_get, - .body_rotation_set = &physics_body_rotation_set, - .body_rotation_get = &physics_body_rotation_get, - .body_kinematic_set = &physics_body_kinematic_set, - .body_mass_set = &physics_body_mass_set, - .body_mass_get = &physics_body_mass_get, - .body_data_set = &physics_body_data_set, - .body_data_get = &physics_body_data_get, - .body_set_moved_callback = &physics_body_set_moved_callback, - .body_set_collision_callback = &physics_body_set_collision_callback, - .body_force_add = &physics_body_force_add, - .body_box_create = &physics_body_box_create, - .body_sphere_create = &physics_body_sphere_create, - .body_capsule_create = &physics_body_capsule_create, - .body_remove = &physics_body_remove, - .body_cs_set = &physics_body_cs_set, - .body_cs_get = &physics_body_cs_get, - - .cs_box_create = &physics_cs_box_create, - .cs_plane_create = &physics_cs_plane_create, - .cs_sphere_create = &physics_cs_sphere_create, - .cs_capsule_create = &physics_cs_capsule_create, - .cs_remove = &physics_cs_remove, - .cs_position_set = &physics_cs_position_set, - .cs_position_get = &physics_cs_position_get, - .cs_rotation_set = &physics_cs_rotation_set, - .cs_rotation_get = &physics_cs_rotation_get, - .cs_type_get = &physics_cs_type_get, - .cs_data_set = &physics_cs_data_set, - .cs_data_get = &physics_cs_data_get, - .cs_plane_params_get = &physics_cs_plane_params_get, - .cs_capsule_params_get = &physics_cs_capsule_params_get, - .cs_box_params_get = &physics_cs_box_params_get, - .cs_sphere_radius_get = &physics_cs_sphere_radius_get, - .cs_plane_params_set = &physics_cs_plane_params_set, - .cs_capsule_params_set = &physics_cs_capsule_params_set, - .cs_box_params_set = &physics_cs_box_params_set, - .cs_shpere_radius_set = &physics_cs_sphere_radius_set, - .cs_ray_create = &physics_cs_ray_create, - .cs_ray_cast = &physics_cs_ray_cast - } - }; - - if(!game_lib_load()) - log_error("main", "Failed to load game library"); - else - { - bool done = false; - while(!done) - { - bool game_init_status = game.init(window, &platform_api); - if(!game_init_status) - { - log_error("main", "Game init failed"); - } - - if(reload_game) - { - reload_game = false; - if(game_lib_handle) - { - if(game.cleanup) game.cleanup(); - platform_unload_library(game_lib_handle); - game_lib_handle = NULL; - game.cleanup = NULL; - game.init = NULL; -#if defined(_MSC_VER) - if(!io_file_delete(DIRT_EXECUTABLE, lib_copy_name)) - { - done = true; - continue; - } -#endif - } - - if(!game_lib_load()) - { - log_error("main", "Failed to load game library"); - done = true; - } - } - else - { - done = true; - } - } - } - } - - exit(EXIT_SUCCESS); -} - -bool init(void) -{ - if(atexit(cleanup) != 0) - { - log_to_stdout("ERR: (main:init) Could not register cleanup func with atexit"); - return false; - } - - config_vars_init(); - if(!platform_init()) return false; - - char* install_path = platform_install_directory_get(); - char* user_path = platform_user_directory_get("SS_Games", "Symmetry"); - log_init("Log.txt", user_path); - io_file_init(install_path, user_path); - free(install_path); - free(user_path); - if(!config_vars_load("config.symtres", DIRT_USER)) - { - log_error("main:init", "Could not load config, reverting to defaults"); - config_vars_save("config.symtres", DIRT_USER); - } - - if(!platform_init_video()) return false; - - if(!platform_load_gl(NULL)) - { - log_error("main:init", "Initializing OpenGL failed"); - return false; - } - - struct Hashmap* cvars = config_vars_get(); - int width = hashmap_int_get(cvars, "render_width"); - int height = hashmap_int_get(cvars, "render_height"); - int msaa = hashmap_bool_get(cvars, "msaa_enabled"); - int msaa_levels = hashmap_int_get(cvars, "msaa_levels"); - window = window_create("Symmetry", width, height, msaa, msaa_levels); - if(!window) - { - log_error("main:init", "Window creation failed"); - return false; - } - - if(!sound_init()) - { - log_error("main:init", "Failed to initialize sound"); - return false; - } - - return true; -} - -void cleanup(void) -{ - if(game.cleanup) game.cleanup(); - if(game_lib_handle) platform_unload_library(game_lib_handle); - if(window) window_destroy(window); - log_reset_all_callbacks(); // Now that the game library has been unloaded, reset all callbacks to stubs so we don't crash on exit - sound_cleanup(); - platform_unload_gl(); - platform_cleanup(); - config_vars_cleanup(); - io_file_cleanup(); - log_message("Program exiting!"); - log_cleanup(); -} - -void game_lib_reload(void) -{ - reload_game = true; -} - -bool game_lib_load(void) -{ -#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"); - return false; - } - - game_lib_handle = platform_load_library("Symmetry_Game.copy"); -#else - game_lib_handle = platform_load_library("Symmetry_Game"); -#endif - if(!game_lib_handle) - { - log_error("main:game_lib_load", "Failed to load game library"); - return false; - } - - log_message("Game library loaded"); - game.init = platform_load_function(game_lib_handle, "game_init"); - game.cleanup = platform_load_function(game_lib_handle, "game_cleanup"); - if(!game.init && !game.cleanup) - return false; - - log_message("Game api loaded"); - return true; -} diff --git a/src/libsymmetry/material.c b/src/game/material.c similarity index 100% rename from src/libsymmetry/material.c rename to src/game/material.c diff --git a/src/libsymmetry/material.h b/src/game/material.h similarity index 100% rename from src/libsymmetry/material.h rename to src/game/material.h diff --git a/src/libsymmetry/model.c b/src/game/model.c similarity index 100% rename from src/libsymmetry/model.c rename to src/game/model.c diff --git a/src/libsymmetry/model.h b/src/game/model.h similarity index 100% rename from src/libsymmetry/model.h rename to src/game/model.h diff --git a/src/libsymmetry/player.c b/src/game/player.c similarity index 95% rename from src/libsymmetry/player.c rename to src/game/player.c index 8bd7753..09fc77f 100755 --- a/src/libsymmetry/player.c +++ b/src/game/player.c @@ -3,12 +3,13 @@ #include "input.h" #include "../common/utils.h" #include "transform.h" -#include "../common/common.h" #include "camera.h" #include "bounding_volumes.h" #include "../common/hashmap.h" #include "../common/log.h" #include "entity.h" +#include "../system/config_vars.h" + void player_init(struct Player* player, struct Scene* scene) { @@ -17,7 +18,7 @@ void player_init(struct Player* player, struct Scene* scene) player->base.id = 1; player->base.type = ET_PLAYER; - struct Hashmap* config = platform->config.get(); + struct Hashmap* config = config_vars_get(); player->move_speed = hashmap_int_get(config, "player_move_speed"); player->move_speed_multiplier = hashmap_int_get(config, "player_move_speed_multiplier"); player->turn_speed = hashmap_int_get(config, "player_turn_speed"); @@ -75,7 +76,7 @@ void player_update(struct Player* player, struct Scene* scene, float dt) if(input_mousebutton_state_get(MSB_RIGHT, KS_PRESSED)) { int mouse_x = 0, mouse_y = 0; - platform->mouse_position_get(&mouse_x, &mouse_y); + platform_mouse_position_get(&mouse_x, &mouse_y); struct Ray ray = camera_screen_coord_to_ray(player->camera_node, mouse_x, mouse_y); log_message("Ray: %.3f, %.3f, %.3f", ray.direction.x, ray.direction.y, ray.direction.z); diff --git a/src/libsymmetry/player.h b/src/game/player.h similarity index 100% rename from src/libsymmetry/player.h rename to src/game/player.h diff --git a/src/libsymmetry/renderer.c b/src/game/renderer.c similarity index 95% rename from src/libsymmetry/renderer.c rename to src/game/renderer.c index 273a7c8..a3c45b0 100755 --- a/src/libsymmetry/renderer.c +++ b/src/game/renderer.c @@ -21,7 +21,8 @@ #include "sprite.h" #include "im_render.h" #include "../common/variant.h" -#include "../common/common.h" +#include "../system/platform.h" +#include "../system/config_vars.h" #include "scene.h" #include @@ -39,9 +40,9 @@ void renderer_init(struct Renderer* renderer) glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glCullFace(GL_BACK); - platform->windowresize_callback_set(on_framebuffer_size_change); + platform_windowresize_callback_set(on_framebuffer_size_change); - struct Hashmap* cvars = platform->config.get(); + struct Hashmap* cvars = config_vars_get(); renderer->settings.fog.mode = hashmap_int_get(cvars, "fog_mode"); renderer->settings.fog.density = hashmap_float_get(cvars, "fog_density"); renderer->settings.fog.start_dist = hashmap_float_get(cvars, "fog_start_dist"); @@ -85,7 +86,7 @@ void renderer_init(struct Renderer* renderer) int width = -1, height = -1; struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); + window_get_size(game_state->window, &width, &height); renderer->def_albedo_tex = texture_create("def_albedo_texture", TU_DIFFUSE, width, height, @@ -327,7 +328,7 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) struct Camera* active_camera = &scene->cameras[scene->active_camera_index]; int width, height; struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); + window_get_size(game_state->window, &width, &height); glViewport(0, 0, width, height); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); shader_bind(renderer->composition_shader); @@ -338,7 +339,7 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) shader_unbind(); /* Debug Render */ - struct Hashmap* cvars = platform->config.get(); + struct Hashmap* cvars = config_vars_get(); if(hashmap_bool_get(cvars, "debug_draw_enabled")) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -378,28 +379,28 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) quat rot = {0.f, 0.f, 0.f, 1.f }; if(mesh->collision.rigidbody) { - platform->physics.body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z); - platform->physics.body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w); + physics_body_position_get(mesh->collision.rigidbody, &pos.x, &pos.y, &pos.z); + physics_body_rotation_get(mesh->collision.rigidbody, &rot.x, &rot.y, &rot.z, &rot.w); } else { - platform->physics.cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z); - platform->physics.cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w); + physics_cs_position_get(mesh->collision.collision_shape, &pos.x, &pos.y, &pos.z); + physics_cs_rotation_get(mesh->collision.collision_shape, &rot.x, &rot.y, &rot.z, &rot.w); } - int collision_shape_type = platform->physics.cs_type_get(mesh->collision.collision_shape); + int collision_shape_type = physics_cs_type_get(mesh->collision.collision_shape); switch(collision_shape_type) { case CST_SPHERE: { - float radius = platform->physics.cs_sphere_radius_get(mesh->collision.collision_shape); + float radius = physics_cs_sphere_radius_get(mesh->collision.collision_shape); im_sphere(radius, pos, rot, physics_draw_color, GDM_TRIANGLES); } break; case CST_BOX: { float x = 0.f, y = 0.f, z = 0.f; - platform->physics.cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z); + physics_cs_box_params_get(mesh->collision.collision_shape, &x, &y, &z); im_box(x, y, z, pos, rot, physics_draw_color, GDM_TRIANGLES); }; break; @@ -419,7 +420,7 @@ void renderer_draw(struct Renderer* renderer, struct Scene* scene) mat4_identity(&ortho_mat); int width, height; struct Game_State* game_state = game_state_get(); - platform->window.get_size(game_state->window, &width, &height); + window_get_size(game_state->window, &width, &height); mat4_ortho(&ortho_mat, 0.f, (float)width, (float)height, 0.f, -10.f, 10.f); shader_set_uniform_mat4(renderer->sprite_batch->shader, "mvp", &ortho_mat); diff --git a/src/libsymmetry/renderer.h b/src/game/renderer.h similarity index 100% rename from src/libsymmetry/renderer.h rename to src/game/renderer.h diff --git a/src/game/scene.c b/src/game/scene.c new file mode 100755 index 0000000..3d7ebdd --- /dev/null +++ b/src/game/scene.c @@ -0,0 +1,710 @@ +#include "scene.h" +#include "../common/array.h" +#include "entity.h" +#include "../common/log.h" +#include "transform.h" +#include "camera.h" +#include "../common/parser.h" +#include "model.h" +#include "light.h" +#include "player.h" +#include "game.h" +#include "bounding_volumes.h" +#include "geometry.h" +#include "editor.h" +#include "../system/sound.h" +#include "../system/physics.h" + +#include +#include +#include + +void scene_init(struct Scene* scene) +{ + assert(scene); + //Initialize the root entity + entity_init(&scene->root_entity, "ROOT_ENTITY", NULL); + scene->root_entity.active = true; + scene->root_entity.id = 0; + scene->root_entity.type = ET_ROOT; + + for(int i = 0; i < MAX_ENTITIES; i++) entity_reset(&scene->entities[i], i); + for(int i = 0; i < MAX_LIGHTS; i++) + { + entity_reset(&scene->lights[i], i); + scene->lights[i].type = ET_LIGHT; + } + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + entity_reset(&scene->static_meshes[i], i); + struct Static_Mesh* mesh = &scene->static_meshes[i]; + mesh->collision.collision_shape = NULL; + mesh->collision.rigidbody = NULL; + mesh->collision.on_collision = NULL; + mesh->model.geometry_index = -1; + mesh->model.material = NULL; + } + for(int i = 0; i < MAX_SOUND_SOURCES; i++) entity_reset(&scene->sound_sources[i], i); + for(int i = 0; i < MAX_CAMERAS; i++) + { + entity_init(&scene->cameras[i], NULL, &scene->root_entity); + camera_init(&scene->cameras[i], 1024, 768); + scene->cameras[i].base.id = i; + } + + player_init(&scene->player, scene); + editor_init_camera(); + + 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) +{ + return false; +} + +bool scene_save(struct Scene* scene, const char* filename, int dir_type) +{ + return false; +} + +void scene_destroy(struct Scene* scene) +{ + assert(scene); + + for(int i = 0; i < MAX_ENTITIES; i++) scene_entity_remove(scene, &scene->entities[i]); + for(int i = 0; i < MAX_CAMERAS; i++) scene_camera_remove(scene, &scene->cameras[i]); + for(int i = 0; i < MAX_LIGHTS; i++) scene_light_remove(scene, &scene->lights[i]); + for(int i = 0; i < MAX_STATIC_MESHES; i++) scene_static_mesh_remove(scene, &scene->static_meshes[i]); + for(int i = 0; i < MAX_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]); + player_destroy(&scene->player); + entity_reset(&scene->root_entity, 0); + scene->root_entity.active = false; +} + +void scene_update(struct Scene* scene, float dt) +{ + if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); +} + +void scene_post_update(struct Scene* scene) +{ + assert(scene); + + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) continue; + + if(entity->marked_for_deletion) + { + scene_entity_remove(scene, entity); + continue; + } + + if(entity->transform.is_modified) entity->transform.is_modified = false; + } + + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* camera = &scene->cameras[i]; + if(!camera->base.active) continue; + + if(camera->base.marked_for_deletion) + { + scene_camera_remove(scene, camera); + continue; + } + + if(camera->base.transform.is_modified) + { + camera_update_view(camera); + camera->base.transform.is_modified = false; + } + } + + for(int i = 0; i < MAX_SOUND_SOURCES; i++) + { + struct Sound_Source* sound_source = &scene->sound_sources[i]; + if(!sound_source->base.active) continue; + + if(sound_source->base.marked_for_deletion) + { + scene_sound_source_remove(scene, sound_source); + continue; + } + + if(sound_source->base.transform.is_modified) + { + vec3 abs_pos = { 0.f, 0.f, 0.f }; + transform_get_absolute_position(&sound_source->base, &abs_pos); + sound_source_instance_update_position(sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); + sound_source->base.transform.is_modified = false; + } + } + + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* static_mesh = &scene->static_meshes[i]; + if(!static_mesh->base.active) continue; + + if(static_mesh->base.marked_for_deletion) + { + scene_static_mesh_remove(scene, static_mesh); + continue; + } + + if(static_mesh->base.transform.is_modified) + { + if(static_mesh->collision.rigidbody && static_mesh->base.transform.sync_physics) + { + quat abs_rot = { 0.f, 0.f, 0.f, 1.f }; + vec3 abs_pos = { 0.f, 0.f, 0.f }; + transform_get_absolute_rot(&static_mesh->base, &abs_rot); + transform_get_absolute_position(&static_mesh->base, &abs_pos); + physics_body_rotation_set(static_mesh->collision.rigidbody, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); + physics_body_position_set(static_mesh->collision.rigidbody, abs_pos.x, abs_pos.y, abs_pos.z); + } + static_mesh->base.transform.sync_physics = false; + static_mesh->base.transform.is_modified = false; + } + } + + for(int i = 0; i < MAX_LIGHTS; i++) + { + struct Light* light = &scene->lights[i]; + if(!light->base.active) continue; + + if(light->base.marked_for_deletion) + { + scene_light_remove(scene, light); + continue; + } + + if(light->base.transform.is_modified) light->base.transform.is_modified = false; + } + + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) continue; + } + + if(scene->player.base.transform.is_modified) + { + vec3 abs_pos = { 0.f, 0.f, 0.f }; + vec3 abs_fwd = { 0.f, 0.f, -1.f }; + vec3 abs_up = { 0.f, 1.f, 0.f }; + transform_get_absolute_position(&scene->player, &abs_pos); + transform_get_absolute_forward(&scene->player, &abs_fwd); + transform_get_absolute_up(&scene->player, &abs_up); + + sound_listener_update(abs_pos.x, abs_pos.y, abs_pos.z, + abs_fwd.x, abs_fwd.y, abs_fwd.z, + abs_up.x, abs_up.y, abs_up.z); + scene->player.base.transform.is_modified = false; + } +} + +struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct Entity* parent) +{ + assert(scene); + + struct Entity* new_entity = NULL; + for(int i = 0; i < MAX_ENTITIES; i++) + { + struct Entity* entity = &scene->entities[i]; + if(!entity->active) + { + new_entity = entity; + break; + } + } + + if(new_entity) + { + if(!parent) + parent = &scene->root_entity; + entity_init(new_entity, name, parent); + } + else + { + log_error("scene:entity_create", "Max entity limit reached!"); + } + + return new_entity; +} + +struct Light* scene_light_create(struct Scene* scene, const char* name, struct Entity* parent, int light_type) +{ + assert(scene); + struct Light* new_light = NULL; + for(int i = 0; i < MAX_LIGHTS; i++) + { + struct Light* light = &scene->lights[i]; + if(!light->base.active) + { + new_light = light; + break; + } + } + + if(new_light) + { + entity_init(&new_light->base, name, parent ? parent : &scene->root_entity); + new_light->base.type = ET_LIGHT; + light_init(new_light, light_type); + } + else + { + log_error("scene:light_create", "Max light limit reached!"); + } + + return new_light; +} + +struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct Entity* parent, int width, int height) +{ + assert(scene); + struct Camera* new_camera = NULL; + for(int i = 0; i < MAX_CAMERAS; i++) + { + struct Camera* camera = &scene->cameras[i]; + if(!camera->base.active) + { + new_camera = camera; + break; + } + } + + if(new_camera) + { + entity_init(&new_camera->base, name, parent ? parent : &scene->root_entity); + new_camera->base.type = ET_CAMERA; + camera_init(new_camera, width, height); + } + else + { + log_error("scene:camera_create", "Max camera limit reached!"); + } + + return new_camera; +} + +struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type) +{ + assert(scene); + struct Static_Mesh* new_static_mesh = NULL; + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* static_mesh = &scene->static_meshes[i]; + if(!static_mesh->base.active) + { + new_static_mesh = static_mesh; + break; + } + } + + if(new_static_mesh) + { + entity_init(&new_static_mesh->base, name, parent ? parent : &scene->root_entity); + new_static_mesh->base.type = ET_STATIC_MESH; + model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); + // TODO: handle creating collision mesh for the model at creation + } + else + { + log_error("scene:model_create", "Max model limit reached!"); + } + + return new_static_mesh; +} + +struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* name, struct Entity* parent, const char* filename, int type, bool loop, bool play) +{ + assert(scene && filename); + struct Sound_Source* new_sound_source = NULL; + for(int i = 0; i < MAX_SOUND_SOURCES; i++) + { + struct Sound_Source* sound_source = &scene->static_meshes[i]; + if(!sound_source->base.active) + { + new_sound_source = sound_source; + break; + } + } + + if(new_sound_source) + { + entity_init(&new_sound_source->base, name, parent ? parent : &scene->root_entity); + new_sound_source->base.type = ET_SOUND_SOURCE; + struct Entity* entity = &new_sound_source->base; + + new_sound_source->source_buffer = sound_source_create(filename, type); + if(!new_sound_source->source_buffer) + { + log_error("entity:sync_sound_params", "Failed to load file '%s' to provide sound source for entity %s", filename, entity->name); + new_sound_source->source_instance = 0; + return new_sound_source; + } + + new_sound_source->source_instance = sound_source_instance_create(new_sound_source->source_buffer, true); + vec3 abs_pos = { 0.f, 0.f, 0.f }; + vec3 abs_fwd = { 0.f, 0.f, -1.f }; + vec3 abs_up = { 0.f, 1.f, 0.f }; + transform_get_absolute_position(entity, &abs_pos); + transform_get_absolute_forward(entity, &abs_fwd); + transform_get_absolute_up(entity, &abs_up); + sound_source_instance_update_position(new_sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); + + new_sound_source->loop = loop; + new_sound_source->min_distance = 0.f; + new_sound_source->max_distance = 10.f; + new_sound_source->playing = play; + new_sound_source->attenuation_type = SA_INVERSE; + new_sound_source->rolloff_factor = 0.95f; + new_sound_source->volume = 1.f; + new_sound_source->type = type; + + sound_source_instance_loop_set(new_sound_source->source_instance, new_sound_source->loop); + sound_source_instance_min_max_distance_set(new_sound_source->source_instance, new_sound_source->min_distance, new_sound_source->max_distance); + sound_source_instance_attenuation_set(new_sound_source->source_instance, new_sound_source->attenuation_type, new_sound_source->rolloff_factor); + sound_source_instance_volume_set(new_sound_source->source_instance, new_sound_source->volume); + + sound_update_3d(); + if(new_sound_source->playing) sound_source_instance_play(new_sound_source->source_instance); + } + else + { + log_error("scene:sound_source_create", "Max sound source limit reached!"); + } + + return new_sound_source; +} + +void scene_entity_remove(struct Scene* scene, struct Entity* entity) +{ + assert(scene && entity && entity->id >= 0); + + if(!entity->active) return; + + transform_destroy(entity); + entity->active = false; + entity->editor_selected = false; + entity->marked_for_deletion = false; + memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); +} + +void scene_light_remove(struct Scene* scene, struct Light* light) +{ + assert(scene && light); + scene_entity_remove(scene, &light->base); +} + +void scene_camera_remove(struct Scene* scene, struct Camera* camera) +{ + assert(scene && camera); + scene_entity_remove(scene, &camera->base); +} + +void scene_static_mesh_remove(struct Scene* scene, struct Static_Mesh* mesh) +{ + assert(scene && mesh); + + mesh->collision.on_collision = NULL; + if(mesh->collision.collision_shape) physics_cs_remove(mesh->collision.collision_shape); + if(mesh->collision.rigidbody) physics_body_remove(mesh->collision.rigidbody); + + model_reset(&mesh->model, mesh); + scene_entity_remove(scene, &mesh->base); +} + +void scene_sound_source_remove(struct Scene* scene, struct Sound_Source* source) +{ + assert(scene && source); + + sound_source_instance_destroy(source->source_instance); + source->source_instance = 0; + scene_entity_remove(scene, &source->base); +} + +struct Entity* scene_entity_find(struct Scene* scene, const char* name) +{ + assert(scene && name); + struct Entity* entity = NULL; + + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0) + { + entity = &scene->entities[i]; + break; + } + } + + return entity; +} + +struct Light* scene_light_find(struct Scene* scene, const char* name) +{ + assert(scene && name); + struct Light* light = NULL; + + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0) + { + light = &scene->lights[i]; + break; + } + } + + return light; +} + +struct Camera* scene_camera_find(struct Scene* scene, const char* name) +{ + assert(scene && name); + struct Camera* camera = NULL; + + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0) + { + camera = &scene->cameras[i]; + break; + } + } + + return camera; +} + +struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name) +{ + assert(scene && name); + struct Static_Mesh* static_mesh = NULL; + + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0) + { + static_mesh = &scene->static_meshes[i]; + break; + } + } + + return static_mesh; +} + +struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name) +{ + assert(scene && name); + struct Sound_Source* sound_source = NULL; + + for(int i = 0; i < MAX_ENTITIES; i++) + { + if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0) + { + sound_source = &scene->sound_sources[i]; + break; + } + } + + return sound_source; +} + +struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) +{ + assert(scene && id != -1 && type < ET_MAX); + + struct Entity* entity = NULL; + + switch(type) + { + case ET_DEFAULT: entity = &scene->entities[id]; break; + case ET_CAMERA: entity = &scene->cameras[id]; break; + case ET_LIGHT: entity = &scene->lights[id]; break; + case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; + case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; + case ET_PLAYER: entity = &scene->player; break; + case ET_ROOT: entity = &scene->root_entity; break; + } + + return entity; +} + +void* scene_find(struct Scene* scene, const char* name) +{ + void* entity = NULL; + + entity = scene_entity_find(scene, name); + if(entity) return entity; + + entity = scene_light_find(scene, name); + if(entity) return entity; + + entity = scene_camera_find(scene, name); + if(entity) return entity; + + entity = scene_static_mesh_find(scene, name); + if(entity) return entity; + + return entity; +} + +void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity) +{ + assert(scene && entity); + transform_parent_set(entity, &scene->root_entity, true); +} + +void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent) +{ + assert(scene && entity && parent); + transform_parent_set(entity, parent, true); +} + +void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results) +{ + assert(out_results); + + memset(&out_results[0], '\0', sizeof(struct Entity*) * MAX_RAYCAST_ENTITIES_INTERSECT); + out_results->num_entities_intersected = 0; + + for(int i = 0; i < MAX_STATIC_MESHES; i++) + { + struct Static_Mesh* mesh = &scene->static_meshes[i]; + if(!mesh->base.active) continue; + vec3 abs_pos = { 0.f }; + transform_get_absolute_position(mesh, &abs_pos); + + struct Geometry* geometry = geom_get(mesh->model.geometry_index); + if(bv_intersect_sphere_ray(&geometry->bounding_sphere, &abs_pos, ray)) + { + out_results->entities_intersected[out_results->num_entities_intersected] = &mesh->base; + out_results->num_entities_intersected++; + } + } +} + + + + + + + + + + + + + + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool scene_load_(const char* filename, int directory_type) +{ + // FILE* entity_file = platform->file.open(directory_type, filename, "r"); + //if(!entity_file) + //{ + // log_error("scene:load", "Failed to open scenefile %s for reading", filename); + // return false; + //} + + //int count = 0; + //int eof_char = -1; + //while(!feof(entity_file)) + //{ + // if(eof_char != -1) ungetc(eof_char, entity_file); + // struct Entity* new_entity = NULL; + // new_entity = entity_read(entity_file); + // if(!new_entity) + // { + // log_error("scene:load", "Error reading entity"); + // } + // else + // { + // log_message("Loaded %s", new_entity->name); + // count++; + // } + // eof_char = fgetc(entity_file); + // /* To check end of file, we get the next character and before beginning + // loop we check if eof occured, feof only returns true if the last read + // was an eof. If it wasn't eof then we return the character back to the + // stream and carry on. */ + //} + + //log_message("%d entites loaded from %s", count, filename); + //fclose(entity_file); + return entity_load(filename, directory_type); +} + +bool scene_save_(const char* filename, int directory_type) +{ + bool success = false; + /*FILE* scene_file = platform->file.open(directory_type, filename, "w"); + if(!scene_file) + { + log_error("scene:save", "Failed to create scenefile %s for writing", filename); + return false; + } + + struct Parser* parser = parser_new(); + if(!parser) + { + log_error("scene:save", "Could not create Parser"); + fclose(scene_file); + return false; + } + + int* entities_to_write = array_new(int); + array_push(entities_to_write, root_node, int); + + bool done = false; + int count = 0; + while(!done) + { + struct Entity* entity = entity_get(entities_to_write[0]); + struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); + if(!object) + { + log_error("scene:save", "Failed to create parser object for %s", entity->name); + continue; + } + + if(!entity_write(entity, object)) + { + log_error("scene:save", "Failed to write '%s' into parser object", entity->name); + continue; + } + + log_message("Entity '%s' written to file", entity->name); + count++; + for(int i = 0; i < array_len(entity->transform.children); i++) + array_push(entities_to_write, entity->transform.children[i], int); + + array_remove_at(entities_to_write, 0); + if(array_len(entities_to_write) == 0) done = true; + } + + if(parser_write_objects(parser, scene_file, filename)) + { + log_message("%d entities written to %s", count, filename); + } + else + { + log_error("scene:save", "Failed to write scene to %s", filename); + success = false; + } + + array_free(entities_to_write); + parser_free(parser); + fclose(scene_file);*/ + + return success; +} diff --git a/src/libsymmetry/scene.h b/src/game/scene.h similarity index 100% rename from src/libsymmetry/scene.h rename to src/game/scene.h diff --git a/src/libsymmetry/shader.c b/src/game/shader.c similarity index 96% rename from src/libsymmetry/shader.c rename to src/game/shader.c index 6d488bc..ccc94d6 100755 --- a/src/libsymmetry/shader.c +++ b/src/game/shader.c @@ -6,7 +6,7 @@ #include "renderer.h" #include "texture.h" #include "gl_load.h" -#include "../common/common.h" +#include "../system/file_io.h" #include #include @@ -52,7 +52,7 @@ char* run_preprocessor(char* shader_text) { char* path = str_new("shaders/"); path = str_concat(path, filename); - char* file_contents = platform->file.read(DIRT_INSTALL, path, "rb", NULL); + char* file_contents = io_file_read(DIRT_INSTALL, path, "rb", NULL); if(file_contents) { char* shader_text_new = str_new("%s\n%s", file_contents, shader_text); @@ -84,8 +84,8 @@ int shader_create(const char* vert_shader_name, const char* frag_shader_name) GLuint vert_shader = glCreateShader(GL_VERTEX_SHADER); GLuint frag_shader = glCreateShader(GL_FRAGMENT_SHADER); - char* vert_source = platform->file.read(DIRT_INSTALL, vs_path, "rb", NULL); - char* frag_source = platform->file.read(DIRT_INSTALL, fs_path, "rb", NULL); + char* vert_source = io_file_read(DIRT_INSTALL, vs_path, "rb", NULL); + char* frag_source = io_file_read(DIRT_INSTALL, fs_path, "rb", NULL); assert(vert_source != NULL); assert(frag_source != NULL); diff --git a/src/libsymmetry/shader.h b/src/game/shader.h similarity index 100% rename from src/libsymmetry/shader.h rename to src/game/shader.h diff --git a/src/libsymmetry/sprite.c b/src/game/sprite.c similarity index 100% rename from src/libsymmetry/sprite.c rename to src/game/sprite.c diff --git a/src/libsymmetry/sprite.h b/src/game/sprite.h similarity index 100% rename from src/libsymmetry/sprite.h rename to src/game/sprite.h diff --git a/src/libsymmetry/texture.c b/src/game/texture.c similarity index 99% rename from src/libsymmetry/texture.c rename to src/game/texture.c index 1a2efd5..add0fbe 100755 --- a/src/libsymmetry/texture.c +++ b/src/game/texture.c @@ -5,7 +5,7 @@ #include "../common/num_types.h" #include "renderer.h" #include "gl_load.h" -#include "../common/common.h" +#include "../system/file_io.h" #include #include @@ -68,7 +68,7 @@ int texture_create_from_file(const char* filename, int texture_unit) } /* If texture not already loaded then try to load it */ char* full_path = str_new("textures/%s", filename); - FILE* file = platform->file.open(DIRT_INSTALL, full_path, "rb"); + FILE* file = io_file_open(DIRT_INSTALL, full_path, "rb"); int img_load_success = -1; if(file) diff --git a/src/libsymmetry/texture.h b/src/game/texture.h similarity index 100% rename from src/libsymmetry/texture.h rename to src/game/texture.h diff --git a/src/libsymmetry/transform.c b/src/game/transform.c similarity index 100% rename from src/libsymmetry/transform.c rename to src/game/transform.c diff --git a/src/libsymmetry/transform.h b/src/game/transform.h similarity index 100% rename from src/libsymmetry/transform.h rename to src/game/transform.h diff --git a/src/libsymmetry/scene.c b/src/libsymmetry/scene.c deleted file mode 100755 index 1a52fe0..0000000 --- a/src/libsymmetry/scene.c +++ /dev/null @@ -1,709 +0,0 @@ -#include "scene.h" -#include "../common/array.h" -#include "entity.h" -#include "../common/log.h" -#include "transform.h" -#include "camera.h" -#include "../common/common.h" -#include "../common/parser.h" -#include "model.h" -#include "light.h" -#include "player.h" -#include "game.h" -#include "bounding_volumes.h" -#include "geometry.h" -#include "editor.h" - -#include -#include -#include - -void scene_init(struct Scene* scene) -{ - assert(scene); - //Initialize the root entity - entity_init(&scene->root_entity, "ROOT_ENTITY", NULL); - scene->root_entity.active = true; - scene->root_entity.id = 0; - scene->root_entity.type = ET_ROOT; - - for(int i = 0; i < MAX_ENTITIES; i++) entity_reset(&scene->entities[i], i); - for(int i = 0; i < MAX_LIGHTS; i++) - { - entity_reset(&scene->lights[i], i); - scene->lights[i].type = ET_LIGHT; - } - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - entity_reset(&scene->static_meshes[i], i); - struct Static_Mesh* mesh = &scene->static_meshes[i]; - mesh->collision.collision_shape = NULL; - mesh->collision.rigidbody = NULL; - mesh->collision.on_collision = NULL; - mesh->model.geometry_index = -1; - mesh->model.material = NULL; - } - for(int i = 0; i < MAX_SOUND_SOURCES; i++) entity_reset(&scene->sound_sources[i], i); - for(int i = 0; i < MAX_CAMERAS; i++) - { - entity_init(&scene->cameras[i], NULL, &scene->root_entity); - camera_init(&scene->cameras[i], 1024, 768); - scene->cameras[i].base.id = i; - } - - player_init(&scene->player, scene); - editor_init_camera(); - - 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) -{ - return false; -} - -bool scene_save(struct Scene* scene, const char* filename, int dir_type) -{ - return false; -} - -void scene_destroy(struct Scene* scene) -{ - assert(scene); - - for(int i = 0; i < MAX_ENTITIES; i++) scene_entity_remove(scene, &scene->entities[i]); - for(int i = 0; i < MAX_CAMERAS; i++) scene_camera_remove(scene, &scene->cameras[i]); - for(int i = 0; i < MAX_LIGHTS; i++) scene_light_remove(scene, &scene->lights[i]); - for(int i = 0; i < MAX_STATIC_MESHES; i++) scene_static_mesh_remove(scene, &scene->static_meshes[i]); - for(int i = 0; i < MAX_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]); - player_destroy(&scene->player); - entity_reset(&scene->root_entity, 0); - scene->root_entity.active = false; -} - -void scene_update(struct Scene* scene, float dt) -{ - if(game_state_get()->game_mode == GAME_MODE_GAME) player_update(&scene->player, scene, dt); -} - -void scene_post_update(struct Scene* scene) -{ - assert(scene); - - for(int i = 0; i < MAX_ENTITIES; i++) - { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; - - if(entity->marked_for_deletion) - { - scene_entity_remove(scene, entity); - continue; - } - - if(entity->transform.is_modified) entity->transform.is_modified = false; - } - - for(int i = 0; i < MAX_CAMERAS; i++) - { - struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) continue; - - if(camera->base.marked_for_deletion) - { - scene_camera_remove(scene, camera); - continue; - } - - if(camera->base.transform.is_modified) - { - camera_update_view(camera); - camera->base.transform.is_modified = false; - } - } - - for(int i = 0; i < MAX_SOUND_SOURCES; i++) - { - struct Sound_Source* sound_source = &scene->sound_sources[i]; - if(!sound_source->base.active) continue; - - if(sound_source->base.marked_for_deletion) - { - scene_sound_source_remove(scene, sound_source); - continue; - } - - if(sound_source->base.transform.is_modified) - { - vec3 abs_pos = {0.f, 0.f, 0.f}; - transform_get_absolute_position(&sound_source->base, &abs_pos); - platform->sound.source_instance_update_position(sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); - sound_source->base.transform.is_modified = false; - } - } - - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) continue; - - if(static_mesh->base.marked_for_deletion) - { - scene_static_mesh_remove(scene, static_mesh); - continue; - } - - if(static_mesh->base.transform.is_modified) - { - if(static_mesh->collision.rigidbody && static_mesh->base.transform.sync_physics) - { - quat abs_rot = { 0.f, 0.f, 0.f, 1.f }; - vec3 abs_pos = {0.f, 0.f, 0.f}; - transform_get_absolute_rot(&static_mesh->base, &abs_rot); - transform_get_absolute_position(&static_mesh->base, &abs_pos); - platform->physics.body_rotation_set(static_mesh->collision.rigidbody, abs_rot.x, abs_rot.y, abs_rot.z, abs_rot.w); - platform->physics.body_position_set(static_mesh->collision.rigidbody, abs_pos.x, abs_pos.y, abs_pos.z); - } - static_mesh->base.transform.sync_physics = false; - static_mesh->base.transform.is_modified = false; - } - } - - for(int i = 0; i < MAX_LIGHTS; i++) - { - struct Light* light = &scene->lights[i]; - if(!light->base.active) continue; - - if(light->base.marked_for_deletion) - { - scene_light_remove(scene, light); - continue; - } - - if(light->base.transform.is_modified) light->base.transform.is_modified = false; - } - - for(int i = 0; i < MAX_ENTITIES; i++) - { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) continue; - } - - if(scene->player.base.transform.is_modified) - { - vec3 abs_pos = {0.f, 0.f, 0.f}; - vec3 abs_fwd = {0.f, 0.f, -1.f}; - vec3 abs_up = {0.f, 1.f, 0.f}; - transform_get_absolute_position(&scene->player, &abs_pos); - transform_get_absolute_forward(&scene->player, &abs_fwd); - transform_get_absolute_up(&scene->player, &abs_up); - - platform->sound.listener_update(abs_pos.x, abs_pos.y, abs_pos.z, - abs_fwd.x, abs_fwd.y, abs_fwd.z, - abs_up.x, abs_up.y, abs_up.z); - scene->player.base.transform.is_modified = false; - } -} - -struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct Entity* parent) -{ - assert(scene); - - struct Entity* new_entity = NULL; - for(int i = 0; i < MAX_ENTITIES; i++) - { - struct Entity* entity = &scene->entities[i]; - if(!entity->active) - { - new_entity = entity; - break; - } - } - - if(new_entity) - { - if(!parent) - parent = &scene->root_entity; - entity_init(new_entity, name, parent); - } - else - { - log_error("scene:entity_create", "Max entity limit reached!"); - } - - return new_entity; -} - -struct Light* scene_light_create(struct Scene* scene, const char* name, struct Entity* parent, int light_type) -{ - assert(scene); - struct Light* new_light = NULL; - for(int i = 0; i < MAX_LIGHTS; i++) - { - struct Light* light = &scene->lights[i]; - if(!light->base.active) - { - new_light = light; - break; - } - } - - if(new_light) - { - entity_init(&new_light->base, name, parent ? parent : &scene->root_entity); - new_light->base.type = ET_LIGHT; - light_init(new_light, light_type); - } - else - { - log_error("scene:light_create", "Max light limit reached!"); - } - - return new_light; -} - -struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct Entity* parent, int width, int height) -{ - assert(scene); - struct Camera* new_camera = NULL; - for(int i = 0; i < MAX_CAMERAS; i++) - { - struct Camera* camera = &scene->cameras[i]; - if(!camera->base.active) - { - new_camera = camera; - break; - } - } - - if(new_camera) - { - entity_init(&new_camera->base, name, parent ? parent : &scene->root_entity); - new_camera->base.type = ET_CAMERA; - camera_init(new_camera, width, height); - } - else - { - log_error("scene:camera_create", "Max camera limit reached!"); - } - - return new_camera; -} - -struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* name, struct Entity* parent, const char* geometry_name, int material_type) -{ - assert(scene); - struct Static_Mesh* new_static_mesh = NULL; - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - struct Static_Mesh* static_mesh = &scene->static_meshes[i]; - if(!static_mesh->base.active) - { - new_static_mesh = static_mesh; - break; - } - } - - if(new_static_mesh) - { - entity_init(&new_static_mesh->base, name, parent ? parent : &scene->root_entity); - new_static_mesh->base.type = ET_STATIC_MESH; - model_init(&new_static_mesh->model, new_static_mesh, geometry_name, material_type); - // TODO: handle creating collision mesh for the model at creation - } - else - { - log_error("scene:model_create", "Max model limit reached!"); - } - - return new_static_mesh; -} - -struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char* name, struct Entity* parent, const char* filename, int type, bool loop, bool play) -{ - assert(scene && filename); - struct Sound_Source* new_sound_source = NULL; - for(int i = 0; i < MAX_SOUND_SOURCES; i++) - { - struct Sound_Source* sound_source = &scene->static_meshes[i]; - if(!sound_source->base.active) - { - new_sound_source = sound_source; - break; - } - } - - if(new_sound_source) - { - entity_init(&new_sound_source->base, name, parent ? parent : &scene->root_entity); - new_sound_source->base.type = ET_SOUND_SOURCE; - struct Entity* entity = &new_sound_source->base; - - new_sound_source->source_buffer = platform->sound.source_create(filename, type); - if(!new_sound_source->source_buffer) - { - log_error("entity:sync_sound_params", "Failed to load file '%s' to provide sound source for entity %s", filename, entity->name); - new_sound_source->source_instance = 0; - return new_sound_source; - } - - new_sound_source->source_instance = platform->sound.source_instance_create(new_sound_source->source_buffer, true); - vec3 abs_pos = {0.f, 0.f, 0.f}; - vec3 abs_fwd = {0.f, 0.f, -1.f}; - vec3 abs_up = {0.f, 1.f, 0.f}; - transform_get_absolute_position(entity, &abs_pos); - transform_get_absolute_forward(entity, &abs_fwd); - transform_get_absolute_up(entity, &abs_up); - platform->sound.source_instance_update_position(new_sound_source->source_instance, abs_pos.x, abs_pos.y, abs_pos.z); - - new_sound_source->loop = loop; - new_sound_source->min_distance = 0.f; - new_sound_source->max_distance = 10.f; - new_sound_source->playing = play; - new_sound_source->attenuation_type = SA_INVERSE; - new_sound_source->rolloff_factor = 0.95f; - new_sound_source->volume = 1.f; - new_sound_source->type = type; - - platform->sound.source_instance_loop_set(new_sound_source->source_instance, new_sound_source->loop); - platform->sound.source_instance_min_max_distance_set(new_sound_source->source_instance, new_sound_source->min_distance, new_sound_source->max_distance); - platform->sound.source_instance_attenuation_set(new_sound_source->source_instance, new_sound_source->attenuation_type, new_sound_source->rolloff_factor); - platform->sound.source_instance_volume_set(new_sound_source->source_instance, new_sound_source->volume); - - platform->sound.update_3d(); - if(new_sound_source->playing) platform->sound.source_instance_play(new_sound_source->source_instance); - } - else - { - log_error("scene:sound_source_create", "Max sound source limit reached!"); - } - - return new_sound_source; -} - -void scene_entity_remove(struct Scene* scene, struct Entity* entity) -{ - assert(scene && entity && entity->id >= 0); - - if(!entity->active) return; - - transform_destroy(entity); - entity->active = false; - entity->editor_selected = false; - entity->marked_for_deletion = false; - memset(entity->name, '\0', MAX_ENTITY_NAME_LEN); -} - -void scene_light_remove(struct Scene* scene, struct Light* light) -{ - assert(scene && light); - scene_entity_remove(scene, &light->base); -} - -void scene_camera_remove(struct Scene* scene, struct Camera* camera) -{ - assert(scene && camera); - scene_entity_remove(scene, &camera->base); -} - -void scene_static_mesh_remove(struct Scene* scene, struct Static_Mesh* mesh) -{ - assert(scene && mesh); - - mesh->collision.on_collision = NULL; - if(mesh->collision.collision_shape) platform->physics.cs_remove(mesh->collision.collision_shape); - if(mesh->collision.rigidbody) platform->physics.body_remove(mesh->collision.rigidbody); - - model_reset(&mesh->model, mesh); - scene_entity_remove(scene, &mesh->base); -} - -void scene_sound_source_remove(struct Scene* scene, struct Sound_Source* source) -{ - assert(scene && source); - - platform->sound.source_instance_destroy(source->source_instance); - source->source_instance = 0; - scene_entity_remove(scene, &source->base); -} - -struct Entity* scene_entity_find(struct Scene* scene, const char* name) -{ - assert(scene && name); - struct Entity* entity = NULL; - - for(int i = 0; i < MAX_ENTITIES; i++) - { - if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0) - { - entity = &scene->entities[i]; - break; - } - } - - return entity; -} - -struct Light* scene_light_find(struct Scene* scene, const char* name) -{ - assert(scene && name); - struct Light* light = NULL; - - for(int i = 0; i < MAX_ENTITIES; i++) - { - if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - light = &scene->lights[i]; - break; - } - } - - return light; -} - -struct Camera* scene_camera_find(struct Scene* scene, const char* name) -{ - assert(scene && name); - struct Camera* camera = NULL; - - for(int i = 0; i < MAX_ENTITIES; i++) - { - if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - camera = &scene->cameras[i]; - break; - } - } - - return camera; -} - -struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name) -{ - assert(scene && name); - struct Static_Mesh* static_mesh = NULL; - - for(int i = 0; i < MAX_ENTITIES; i++) - { - if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - static_mesh = &scene->static_meshes[i]; - break; - } - } - - return static_mesh; -} - -struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* name) -{ - assert(scene && name); - struct Sound_Source* sound_source = NULL; - - for(int i = 0; i < MAX_ENTITIES; i++) - { - if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0) - { - sound_source = &scene->sound_sources[i]; - break; - } - } - - return sound_source; -} - -struct Entity* scene_base_entity_get(struct Scene* scene, int id, int type) -{ - assert(scene && id != -1 && type < ET_MAX); - - struct Entity* entity = NULL; - - switch(type) - { - case ET_DEFAULT: entity = &scene->entities[id]; break; - case ET_CAMERA: entity = &scene->cameras[id]; break; - case ET_LIGHT: entity = &scene->lights[id]; break; - case ET_STATIC_MESH: entity = &scene->static_meshes[id]; break; - case ET_SOUND_SOURCE: entity = &scene->sound_sources[id]; break; - case ET_PLAYER: entity = &scene->player; break; - case ET_ROOT: entity = &scene->root_entity; break; - } - - return entity; -} - -void* scene_find(struct Scene* scene, const char* name) -{ - void* entity = NULL; - - entity = scene_entity_find(scene, name); - if(entity) return entity; - - entity = scene_light_find(scene, name); - if(entity) return entity; - - entity = scene_camera_find(scene, name); - if(entity) return entity; - - entity = scene_static_mesh_find(scene, name); - if(entity) return entity; - - return entity; -} - -void scene_entity_parent_reset(struct Scene* scene, struct Entity* entity) -{ - assert(scene && entity); - transform_parent_set(entity, &scene->root_entity, true); -} - -void scene_entity_parent_set(struct Scene* scene, struct Entity* entity, struct Entity* parent) -{ - assert(scene && entity && parent); - transform_parent_set(entity, parent, true); -} - -void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Result* out_results) -{ - assert(out_results); - - memset(&out_results[0], '\0', sizeof(struct Entity*) * MAX_RAYCAST_ENTITIES_INTERSECT); - out_results->num_entities_intersected = 0; - - for(int i = 0; i < MAX_STATIC_MESHES; i++) - { - struct Static_Mesh* mesh = &scene->static_meshes[i]; - if(!mesh->base.active) continue; - vec3 abs_pos = {0.f}; - transform_get_absolute_position(mesh, &abs_pos); - - struct Geometry* geometry = geom_get(mesh->model.geometry_index); - if(bv_intersect_sphere_ray(&geometry->bounding_sphere, &abs_pos, ray)) - { - out_results->entities_intersected[out_results->num_entities_intersected] = &mesh->base; - out_results->num_entities_intersected++; - } - } -} - - - - - - - - - - - - - - - - - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool scene_load_(const char* filename, int directory_type) -{ - // FILE* entity_file = platform->file.open(directory_type, filename, "r"); - //if(!entity_file) - //{ - // log_error("scene:load", "Failed to open scenefile %s for reading", filename); - // return false; - //} - - //int count = 0; - //int eof_char = -1; - //while(!feof(entity_file)) - //{ - // if(eof_char != -1) ungetc(eof_char, entity_file); - // struct Entity* new_entity = NULL; - // new_entity = entity_read(entity_file); - // if(!new_entity) - // { - // log_error("scene:load", "Error reading entity"); - // } - // else - // { - // log_message("Loaded %s", new_entity->name); - // count++; - // } - // eof_char = fgetc(entity_file); - // /* To check end of file, we get the next character and before beginning - // loop we check if eof occured, feof only returns true if the last read - // was an eof. If it wasn't eof then we return the character back to the - // stream and carry on. */ - //} - - //log_message("%d entites loaded from %s", count, filename); - //fclose(entity_file); - return entity_load(filename, directory_type); -} - -bool scene_save_(const char* filename, int directory_type) -{ - bool success = false; - /*FILE* scene_file = platform->file.open(directory_type, filename, "w"); - if(!scene_file) - { - log_error("scene:save", "Failed to create scenefile %s for writing", filename); - return false; - } - - struct Parser* parser = parser_new(); - if(!parser) - { - log_error("scene:save", "Could not create Parser"); - fclose(scene_file); - return false; - } - - int* entities_to_write = array_new(int); - array_push(entities_to_write, root_node, int); - - bool done = false; - int count = 0; - while(!done) - { - struct Entity* entity = entity_get(entities_to_write[0]); - struct Parser_Object* object = parser_object_new(parser, PO_ENTITY); - if(!object) - { - log_error("scene:save", "Failed to create parser object for %s", entity->name); - continue; - } - - if(!entity_write(entity, object)) - { - log_error("scene:save", "Failed to write '%s' into parser object", entity->name); - continue; - } - - log_message("Entity '%s' written to file", entity->name); - count++; - for(int i = 0; i < array_len(entity->transform.children); i++) - array_push(entities_to_write, entity->transform.children[i], int); - - array_remove_at(entities_to_write, 0); - if(array_len(entities_to_write) == 0) done = true; - } - - if(parser_write_objects(parser, scene_file, filename)) - { - log_message("%d entities written to %s", count, filename); - } - else - { - log_error("scene:save", "Failed to write scene to %s", filename); - success = false; - } - - array_free(entities_to_write); - parser_free(parser); - fclose(scene_file);*/ - - return success; -} diff --git a/src/game/config_vars.c b/src/system/config_vars.c similarity index 100% rename from src/game/config_vars.c rename to src/system/config_vars.c diff --git a/src/game/config_vars.h b/src/system/config_vars.h similarity index 100% rename from src/game/config_vars.h rename to src/system/config_vars.h diff --git a/src/game/file_io.c b/src/system/file_io.c similarity index 100% rename from src/game/file_io.c rename to src/system/file_io.c diff --git a/src/game/file_io.h b/src/system/file_io.h similarity index 58% rename from src/game/file_io.h rename to src/system/file_io.h index 2ec46ef..e2384ae 100755 --- a/src/game/file_io.h +++ b/src/system/file_io.h @@ -1,7 +1,16 @@ #ifndef FILE_IO_H #define FILE_IO_H -#include "../common/common.h" +#include +#include + +enum Directory_Type +{ + DIRT_USER, /* User directory or preferences directory */ + DIRT_INSTALL, /* Directory where the game's assets are, usually alongside the game's executable where the game is installed */ + DIRT_EXECUTABLE, /* Directory where the game's executable is located */ + DIRT_COUNT +}; void io_file_init(const char* install_dir, const char* user_dir); void io_file_cleanup(void); diff --git a/src/system/main.c b/src/system/main.c new file mode 100755 index 0000000..0888859 --- /dev/null +++ b/src/system/main.c @@ -0,0 +1,109 @@ +#include +#include + +#include "../common/log.h" +#include "sound.h" +#include "platform.h" +#include "physics.h" +#include "file_io.h" +#include "config_vars.h" +#include "../common/hashmap.h" +#include "../game/game.h" + +struct Wndow; +static struct Window* window; + +bool init(void); +void cleanup(void); + +int main(int argc, char** args) +{ + if(!init(window)) + { + log_to_stdout("ERR:(Main) Could not initialize"); + } + else + { + bool done = false; + while(!done) + { + bool game_init_status = game_init(window); + if(!game_init_status) + { + log_error("main", "Game init failed"); + } + else + { + done = game_run(); + } + } + } + + exit(EXIT_SUCCESS); +} + +bool init(void) +{ + if(atexit(cleanup) != 0) + { + log_to_stdout("ERR: (main:init) Could not register cleanup func with atexit"); + return false; + } + + config_vars_init(); + if(!platform_init()) return false; + + char* install_path = platform_install_directory_get(); + char* user_path = platform_user_directory_get("SS_Games", "Symmetry"); + log_init("Log.txt", user_path); + io_file_init(install_path, user_path); + free(install_path); + free(user_path); + if(!config_vars_load("config.symtres", DIRT_USER)) + { + log_error("main:init", "Could not load config, reverting to defaults"); + config_vars_save("config.symtres", DIRT_USER); + } + + if(!platform_init_video()) return false; + + if(!platform_load_gl(NULL)) + { + log_error("main:init", "Initializing OpenGL failed"); + return false; + } + + struct Hashmap* cvars = config_vars_get(); + int width = hashmap_int_get(cvars, "render_width"); + int height = hashmap_int_get(cvars, "render_height"); + int msaa = hashmap_bool_get(cvars, "msaa_enabled"); + int msaa_levels = hashmap_int_get(cvars, "msaa_levels"); + window = window_create("Symmetry", width, height, msaa, msaa_levels); + if(!window) + { + log_error("main:init", "Window creation failed"); + return false; + } + + if(!sound_init()) + { + log_error("main:init", "Failed to initialize sound"); + return false; + } + + return true; +} + +void cleanup(void) +{ + game_cleanup(); + if(window) window_destroy(window); + log_reset_all_callbacks(); // Now that the game library has been unloaded, reset all callbacks to stubs so we don't crash on exit + sound_cleanup(); + platform_unload_gl(); + platform_cleanup(); + config_vars_cleanup(); + io_file_cleanup(); + log_message("Program exiting!"); + log_cleanup(); +} \ No newline at end of file diff --git a/src/game/physics.c b/src/system/physics.c similarity index 100% rename from src/game/physics.c rename to src/system/physics.c diff --git a/src/game/physics.h b/src/system/physics.h similarity index 87% rename from src/game/physics.h rename to src/system/physics.h index 536542a..d93b837 100755 --- a/src/game/physics.h +++ b/src/system/physics.h @@ -1,7 +1,30 @@ #ifndef PHYSICS_H #define PHYSICS_H -#include "../common/common.h" +#include + +typedef void* Rigidbody; +typedef void* Collision_Shape; +typedef void(*RigidbodyMoveCB)(Rigidbody); +typedef void(*RigidbodyColCB)(Rigidbody, Rigidbody); + +enum Collision_Shape_Type +{ + CST_BOX = 0, + CST_SPHERE, + CST_CYLINDER, + CST_CAPSULE, + CST_PLANE, + CST_TRIMESH, + CST_UNKNOWN +}; + +struct Raycast_Hit +{ + int entity_id; + float normal_x, normal_y, normal_z; +}; + void physics_init(void); void physics_cleanup(void); diff --git a/src/game/platform.c b/src/system/platform.c similarity index 98% rename from src/game/platform.c rename to src/system/platform.c index e21ba55..d185c10 100755 --- a/src/game/platform.c +++ b/src/system/platform.c @@ -15,7 +15,7 @@ struct Window { void* sdl_window; SDL_GLContext gl_context; - int is_fullscreen; + bool is_fullscreen; }; struct Platform_State @@ -106,14 +106,14 @@ struct Window* window_create(const char* title, int width, int height, int msaa, return new_window; } -int window_fullscreen_set(struct Window* window, int fullscreen) +bool window_fullscreen_set(struct Window* window, bool fullscreen) { - int success = 0; + int success = false; int rc = SDL_SetWindowFullscreen(window->sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0); if(rc == 0) { - window->is_fullscreen = fullscreen ? 1 : 0; - success = 1; + window->is_fullscreen = fullscreen; + success = true; log_message("Window set to %s mode", fullscreen ? "fullscreen" : "windowed"); int w, h; window_get_size(window, &w, &h); diff --git a/src/game/platform.h b/src/system/platform.h similarity index 81% rename from src/game/platform.h rename to src/system/platform.h index d4ae149..595ad2e 100755 --- a/src/game/platform.h +++ b/src/system/platform.h @@ -1,7 +1,15 @@ #ifndef PLATFORM_H #define PLATFORM_H -#include "../common/common.h" +#include +#include "../common/num_types.h" + +typedef void(*Keyboard_Event_Func) (int key, int scancode, int state, int repeat, int mod_ctrl, int mod_shift, int mod_alt); +typedef void(*Mousebutton_Event_Func) (int button, int state, int x, int y, int8 num_clicks); +typedef void(*Mousemotion_Event_Func) (int x, int y, int xrel, int yrel); +typedef void(*Mousewheel_Event_Func) (int x, int y); +typedef void(*Windowresize_Event_Func) (int x, int y); +typedef void(*Textinput_Event_Func) (const char* text); enum Video_Drivers_Linux { @@ -23,7 +31,7 @@ void window_set_size(struct Window* window, int width, int height); void window_get_size(struct Window* window, int* out_width, int* out_height); void window_get_drawable_size(struct Window* window, int* out_width, int* out_height); void window_swap_buffers(struct Window* window); -int window_fullscreen_set(struct Window* window, int fullscreen); +bool window_fullscreen_set(struct Window* window, bool fullscreen); // Platform functions bool platform_init(void); diff --git a/src/game/sound.c b/src/system/sound.c similarity index 100% rename from src/game/sound.c rename to src/system/sound.c diff --git a/src/game/sound.h b/src/system/sound.h similarity index 87% rename from src/game/sound.h rename to src/system/sound.h index 5c1cb68..efe9578 100755 --- a/src/game/sound.h +++ b/src/system/sound.h @@ -3,6 +3,20 @@ #include "../common/num_types.h" +enum Sound_Source_Type +{ + ST_WAV = 0, + ST_WAV_STREAM +}; + +enum Sound_Attenuation_Type +{ + SA_NONE = 0, // No attenuation + SA_INVERSE, // Inverse distance attenuation model + SA_LINEAR, // Linear distance attenuation model + SA_EXPONENTIAL // Exponential distance attenuation model +}; + struct Sound_Source_Buffer; bool sound_init(void); diff --git a/todo.txt b/todo.txt index 00b1792..d6d1d16 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,6 @@ Todo: - Add warning to genie build script when running on windows and WindowsSdkVersion cannot be found. This happens when the script is not run from vcvarsall command prompt - ? Rethink/remove the game executable and game library split. + - Improve README and add a screenshot to make the repository ready for making it public - Refactor all global application state into 'Application_Context' struct. A single global instance of which is available everywhere ? Improve bounding sphere calculation - Change the way lights are set as uniforms to remove snprintf calls per frame for every light attribute @@ -191,3 +191,4 @@ Done: * Replace all renderer_check_gl calls with GL_CHECK macro * Fixed Console bug when enabled in editor mode * Migrated from bitbucket to github and from mercurial back to git + * Removed the game executable and game library split.