Removed game/library split, the game now compiles as one executable only.

dev
Shariq Shah 7 years ago
parent eae1436cbb
commit a79189b18e
  1. 31
      build/genie.lua
  2. 242
      src/common/common.h
  3. 10
      src/common/log.c
  4. 2
      src/common/log.h
  5. 3
      src/common/parser.h
  6. 0
      src/game/bounding_volumes.c
  7. 0
      src/game/bounding_volumes.h
  8. 5
      src/game/camera.c
  9. 0
      src/game/camera.h
  10. 4
      src/game/console.c
  11. 0
      src/game/console.h
  12. 10
      src/game/editor.c
  13. 0
      src/game/editor.h
  14. 35
      src/game/entity.c
  15. 3
      src/game/entity.h
  16. 0
      src/game/event.h
  17. 0
      src/game/framebuffer.c
  18. 0
      src/game/framebuffer.h
  19. 59
      src/game/game.c
  20. 12
      src/game/game.h
  21. 4
      src/game/geometry.c
  22. 0
      src/game/geometry.h
  23. 5
      src/game/gl_load.c
  24. 0
      src/game/gl_load.h
  25. 0
      src/game/glad.c
  26. 15
      src/game/gui.c
  27. 0
      src/game/gui.h
  28. 0
      src/game/im_render.c
  29. 0
      src/game/im_render.h
  30. 39
      src/game/input.c
  31. 0
      src/game/input.h
  32. 0
      src/game/light.c
  33. 0
      src/game/light.h
  34. 323
      src/game/main.c
  35. 0
      src/game/material.c
  36. 0
      src/game/material.h
  37. 0
      src/game/model.c
  38. 0
      src/game/model.h
  39. 7
      src/game/player.c
  40. 0
      src/game/player.h
  41. 29
      src/game/renderer.c
  42. 0
      src/game/renderer.h
  43. 710
      src/game/scene.c
  44. 0
      src/game/scene.h
  45. 8
      src/game/shader.c
  46. 0
      src/game/shader.h
  47. 0
      src/game/sprite.c
  48. 0
      src/game/sprite.h
  49. 4
      src/game/texture.c
  50. 0
      src/game/texture.h
  51. 0
      src/game/transform.c
  52. 0
      src/game/transform.h
  53. 709
      src/libsymmetry/scene.c
  54. 0
      src/system/config_vars.c
  55. 0
      src/system/config_vars.h
  56. 0
      src/system/file_io.c
  57. 11
      src/system/file_io.h
  58. 109
      src/system/main.c
  59. 0
      src/system/physics.c
  60. 25
      src/system/physics.h
  61. 10
      src/system/platform.c
  62. 12
      src/system/platform.h
  63. 0
      src/system/sound.c
  64. 14
      src/system/sound.h
  65. 3
      todo.txt

@ -58,12 +58,13 @@ 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/"}
@ -78,6 +79,7 @@ solution "Symmetry"
configuration "Debug"
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",

@ -1,242 +0,0 @@
#ifndef COMMON_H
#define COMMON_H
#include <stdio.h>
#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

@ -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)

@ -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);

@ -1,7 +1,8 @@
#ifndef PARSER_H
#define PARSER_H
#include "common.h"
#include <stdio.h>
#include <stdbool.h>
enum Parser_Object_Type
{

@ -11,6 +11,7 @@
#include "../common/utils.h"
#include "../common/log.h"
#include "gl_load.h"
#include "../system/platform.h"
#include <assert.h>
#include <stdio.h>
@ -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;

@ -2,7 +2,7 @@
#include "gui.h"
#include "game.h"
#include "../common/log.h"
#include "../common/common.h"
#include "../system/platform.h"
#include <assert.h>
#include <string.h>
@ -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))

@ -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 <stdio.h>
#include <stdlib.h>
@ -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);
}

@ -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 <stdlib.h>
#include <string.h>
@ -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)

@ -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

@ -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))
{
@ -532,20 +522,13 @@ void game_update(float dt, bool* window_should_close)
}
}
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);
console_update(game_state->console, gui_state_get(), dt);
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)

@ -3,14 +3,7 @@
#include <stdbool.h>
#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;
@ -37,7 +30,8 @@ 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);
bool game_init(struct Window* window);
bool game_run(void);
void game_cleanup(void);
#endif

@ -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 <stdlib.h>
@ -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)
{

@ -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

@ -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 <string.h>
#include <stdlib.h>
@ -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)
{

@ -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);
}

@ -1,323 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}

@ -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);

@ -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 <string.h>
@ -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);

@ -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 <assert.h>
#include <string.h>
#include <stdlib.h>
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;
}

@ -6,7 +6,7 @@
#include "renderer.h"
#include "texture.h"
#include "gl_load.h"
#include "../common/common.h"
#include "../system/file_io.h"
#include <stdio.h>
#include <stdlib.h>
@ -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);

@ -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 <assert.h>
#include <string.h>
@ -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)

@ -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 <assert.h>
#include <string.h>
#include <stdlib.h>
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;
}

@ -1,7 +1,16 @@
#ifndef FILE_IO_H
#define FILE_IO_H
#include "../common/common.h"
#include <stdbool.h>
#include <stdio.h>
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);

@ -0,0 +1,109 @@
#include <stdio.h>
#include <stdlib.h>
#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();
}

@ -1,7 +1,30 @@
#ifndef PHYSICS_H
#define PHYSICS_H
#include "../common/common.h"
#include <stdbool.h>
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);

@ -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);

@ -1,7 +1,15 @@
#ifndef PLATFORM_H
#define PLATFORM_H
#include "../common/common.h"
#include <stdbool.h>
#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);

@ -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);

@ -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.

Loading…
Cancel
Save