Implmented event subscription with a particular object. Added scene load event and configured enemy entities to use that to aquire pointers to child entities after scene is loaded

dev
Shariq Shah 6 years ago
parent ddfbbbfa2d
commit 8bebda53e5
  1. 23
      src/common/limits.h
  2. 2
      src/common/version.h
  3. 2
      src/game/console.c
  4. 16
      src/game/editor.c
  5. 46
      src/game/enemy.c
  6. 16
      src/game/entity.c
  7. 5
      src/game/entity.h
  8. 109
      src/game/event.c
  9. 38
      src/game/event.h
  10. 2
      src/game/material.c
  11. 3
      src/game/material.h
  12. 2
      src/game/player.c
  13. 8
      src/game/renderer.c
  14. 117
      src/game/scene.c
  15. 23
      src/game/scene.h
  16. 2
      src/system/file_io.h
  17. 4
      todo.txt

@ -0,0 +1,23 @@
#ifndef SYMMETRY_LIMITS_H
#define SYMMETRY_LIMITS_H
#define MAX_ENTITY_NAME_LEN 128
#define MAX_FILENAME_LEN 128
#define MAX_EVENTS 128
#define MAX_EVENT_SUBSCRIPTIONS 256
#define MAX_SCENE_ENTITIES 32
#define MAX_SCENE_LIGHTS 30
#define MAX_SCENE_CAMERAS 2
#define MAX_SCENE_STATIC_MESHES 1024
#define MAX_SCENE_SOUND_SOURCES 128
#define MAX_SCENE_ENTITY_ARCHETYPES 32
#define MAX_SCENE_ENEMIES 64
#define MAX_UNIFORM_NAME_LEN 64
#define MAX_MATERIAL_REGISTERED_STATIC_MESHES 1024
#endif

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */ /* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1 #define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 315 #define SYMMETRY_VERSION_REVISION 316
#define SYMMETRY_VERSION_BRANCH "dev" #define SYMMETRY_VERSION_BRANCH "dev"
#endif #endif

@ -260,7 +260,7 @@ void console_command_entity_load(struct Console* console, const char* command)
return; return;
} }
struct Entity* new_entity = entity_load(filename, DIRT_INSTALL); struct Entity* new_entity = entity_load(filename, DIRT_INSTALL, true);
if(!new_entity) if(!new_entity)
{ {
log_error("entity_load", "Could not create entity from '%s'", filename); log_error("entity_load", "Could not create entity from '%s'", filename);

@ -1692,42 +1692,42 @@ void editor_window_scene_hierarchy(struct nk_context* context, struct Editor* ed
{ {
if(nk_tree_push(context, NK_TREE_TAB, "Cameras", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Cameras", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
editor_show_entity_in_list(editor, context, scene, &scene->cameras[i]); editor_show_entity_in_list(editor, context, scene, &scene->cameras[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Lights", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Lights", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_SCENE_LIGHTS; i++)
editor_show_entity_in_list(editor, context, scene, &scene->lights[i]); editor_show_entity_in_list(editor, context, scene, &scene->lights[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Static Meshes", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Static Meshes", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]); editor_show_entity_in_list(editor, context, scene, &scene->static_meshes[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Sound Sources", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Sound Sources", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_SOUND_SOURCES; i++) for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++)
editor_show_entity_in_list(editor, context, scene, &scene->sound_sources[i]); editor_show_entity_in_list(editor, context, scene, &scene->sound_sources[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Enemies", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Enemies", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
editor_show_entity_in_list(editor, context, scene, &scene->enemies[i]); editor_show_entity_in_list(editor, context, scene, &scene->enemies[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED)) if(nk_tree_push(context, NK_TREE_TAB, "Entities", NK_MAXIMIZED))
{ {
for(int i = 0; i < MAX_ENTITIES; i++) for(int i = 0; i < MAX_SCENE_ENTITIES; i++)
editor_show_entity_in_list(editor, context, scene, &scene->entities[i]); editor_show_entity_in_list(editor, context, scene, &scene->entities[i]);
nk_tree_pop(context); nk_tree_pop(context);
} }
@ -2431,7 +2431,7 @@ void editor_entity_dialog(struct Editor* editor, struct nk_context* context)
} }
else else
{ {
struct Entity* new_entity = entity_load(entity_filename, DIRT_INSTALL); struct Entity* new_entity = entity_load(entity_filename, DIRT_INSTALL, true);
if(new_entity) if(new_entity)
{ {
editor_entity_select(editor, new_entity); editor_entity_select(editor, new_entity);
@ -2451,7 +2451,7 @@ void editor_entity_dialog(struct Editor* editor, struct nk_context* context)
} }
else else
{ {
struct Entity* new_entity = entity_load(entity_filename, DIRT_INSTALL); struct Entity* new_entity = entity_load(entity_filename, DIRT_INSTALL, true);
if(new_entity) if(new_entity)
{ {
editor_entity_select(editor, new_entity); editor_entity_select(editor, new_entity);

@ -6,9 +6,12 @@
#include "../common/log.h" #include "../common/log.h"
#include "../common/hashmap.h" #include "../common/hashmap.h"
#include "../common/parser.h" #include "../common/parser.h"
#include "event.h"
#include <string.h> #include <string.h>
static void enemy_on_scene_loaded(struct Event* event, void* enemy_ptr);
void enemy_init(struct Enemy* enemy, int type) void enemy_init(struct Enemy* enemy, int type)
{ {
struct Game_State* game_state = game_state_get(); struct Game_State* game_state = game_state_get();
@ -36,8 +39,8 @@ void enemy_init(struct Enemy* enemy, int type)
enemy->Turret.turn_speed = 10.f; enemy->Turret.turn_speed = 10.f;
enemy->health = 100; enemy->health = 100;
enemy->damage = 10; enemy->damage = 10;
weapon_sound = scene_sound_source_create(scene, weapon_name_buffer, enemy, "sounds/bullet_1.wav", ST_WAV, false, false); //weapon_sound = scene_sound_source_create(scene, weapon_name_buffer, enemy, "sounds/bullet_1.wav", ST_WAV, false, false);
mesh = scene_static_mesh_create(scene, mesh_name_buffer, enemy, "suzanne.symbres", MAT_BLINN); //mesh = scene_static_mesh_create(scene, mesh_name_buffer, enemy, "suzanne.symbres", MAT_BLINN);
break; break;
} }
default: default:
@ -45,16 +48,16 @@ void enemy_init(struct Enemy* enemy, int type)
break; break;
} }
enemy->weapon_sound = weapon_sound ? weapon_sound : NULL; //enemy->weapon_sound = weapon_sound ? weapon_sound : NULL;
if(!weapon_sound) //if(!weapon_sound)
log_error("enemy:init", "Failed to add weapon sound for %s", enemy->base.name); // log_error("enemy:init", "Failed to add weapon sound for %s", enemy->base.name);
enemy->mesh = mesh ? mesh : NULL; //enemy->mesh = mesh ? mesh : NULL;
if(!mesh) //if(!mesh)
log_error("enemy:init", "Failed to add mesh from file for %s", enemy->base.name); // log_error("enemy:init", "Failed to add mesh from file for %s", enemy->base.name);
if(enemy->mesh) enemy->mesh->base.flags |= EF_TRANSIENT; struct Event_Manager* event_manager = game_state->event_manager;
if(enemy->weapon_sound) enemy->weapon_sound->base.flags |= EF_TRANSIENT; event_manager_subscribe_with_object(event_manager, EVT_SCENE_LOADED, &enemy_on_scene_loaded, (void*)enemy);
} }
void enemy_weapon_sound_set(struct Enemy* enemy, const char* sound_filename, int type) void enemy_weapon_sound_set(struct Enemy* enemy, const char* sound_filename, int type)
@ -98,6 +101,9 @@ void enemy_reset(struct Enemy* enemy)
enemy->type = -1; enemy->type = -1;
enemy->damage = 0; enemy->damage = 0;
enemy->health = 0; enemy->health = 0;
struct Event_Manager* event_manager = game_state_get()->event_manager;
event_manager_unsubscribe_with_object(event_manager, EVT_SCENE_LOADED, &enemy_on_scene_loaded, (void*)enemy);
} }
struct Enemy* enemy_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity) struct Enemy* enemy_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity)
@ -143,3 +149,23 @@ void enemy_write(struct Enemy* enemy, struct Hashmap* entity_data)
break; break;
} }
} }
void enemy_on_scene_loaded(struct Event* event, void* enemy_ptr)
{
struct Enemy* enemy = (struct Enemy*)enemy_ptr;
// Assign pointers to mesh and sound child entities
for(int i = 0; i < array_len(enemy->base.transform.children); i++)
{
struct Entity* child = enemy->base.transform.children[i];
if(child->type == ET_STATIC_MESH)
enemy->mesh = (struct Static_Mesh*)child;
else if(child->type == ET_SOUND_SOURCE)
enemy->weapon_sound = (struct Sound_Source*)child;
}
if(enemy->mesh) enemy->mesh->base.flags |= EF_TRANSIENT;
if(enemy->weapon_sound) enemy->weapon_sound->base.flags |= EF_TRANSIENT;
// Do other post-scene-load initialization stuff per enemy type here
}

@ -19,6 +19,7 @@
#include "game.h" #include "game.h"
#include "texture.h" #include "texture.h"
#include "enemy.h" #include "enemy.h"
#include "event.h"
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -538,7 +539,7 @@ struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_e
return new_entity; return new_entity;
} }
struct Entity* entity_load(const char* filename, int directory_type) struct Entity* entity_load(const char* filename, int directory_type, bool send_on_load_event)
{ {
char prefixed_filename[MAX_FILENAME_LEN + 16]; char prefixed_filename[MAX_FILENAME_LEN + 16];
snprintf(prefixed_filename, MAX_FILENAME_LEN + 16, "entities/%s.symtres", filename); snprintf(prefixed_filename, MAX_FILENAME_LEN + 16, "entities/%s.symtres", filename);
@ -595,6 +596,19 @@ struct Entity* entity_load(const char* filename, int directory_type)
} }
} }
// Send simulated scene loaded event since this entity has been loaded while the scene has already been loaded
if(send_on_load_event)
{
struct Game_State* game_state = game_state_get();
struct Event_Manager* event_manager = game_state->event_manager;
struct Event on_scene_loaded_event =
{
.type = EVT_SCENE_LOADED,
};
strncpy(on_scene_loaded_event.scene_load.filename, game_state->scene->filename, MAX_FILENAME_LEN);
event_manager_send_event_entity(event_manager, &on_scene_loaded_event, parent_entity);
}
parser_free(parsed_file); parser_free(parsed_file);
fclose(entity_file); fclose(entity_file);
return parent_entity; return parent_entity;

@ -7,8 +7,7 @@
#include "../system/sound.h" #include "../system/sound.h"
#include "bounding_volumes.h" #include "bounding_volumes.h"
#include "material.h" #include "material.h"
#include "../common/limits.h"
#define MAX_ENTITY_NAME_LEN 128
struct Entity; struct Entity;
@ -212,7 +211,7 @@ struct Enemy
void entity_init(struct Entity* entity, const char* name, struct Entity* parent); void entity_init(struct Entity* entity, const char* name, struct Entity* parent);
void entity_reset(struct Entity* entity, int id); void entity_reset(struct Entity* entity, int id);
bool entity_save(struct Entity* entity, const char* filename, int directory_type); bool entity_save(struct Entity* entity, const char* filename, int directory_type);
struct Entity* entity_load(const char* filename, int directory_type); struct Entity* entity_load(const char* filename, int directory_type, bool send_on_scene_load_event);
bool entity_write(struct Entity* entity, struct Parser_Object* object, bool write_transform); bool entity_write(struct Entity* entity, struct Parser_Object* object, bool write_transform);
struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_entity); struct Entity* entity_read(struct Parser_Object* object, struct Entity* parent_entity);
const char* entity_type_name_get(struct Entity* entity); const char* entity_type_name_get(struct Entity* entity);

@ -10,13 +10,12 @@ void event_manager_init(struct Event_Manager* event_manager)
{ {
assert(event_manager); assert(event_manager);
memset(event_manager->event_subsciptions, '\0', sizeof(struct Event_Subscription) * MAX_EVENT_SUBSCRIPTIONS);
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++) for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{ {
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i]; struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
memset(subscription, '\0', sizeof(struct Event_Subscription)); memset(subscription, 0, sizeof(struct Event_Subscription));
subscription->event_type = EVT_NONE; subscription->event_type = EVT_NONE;
subscription->type = EST_NONE;
} }
for(int i = 0; i < MAX_EVENTS; i++) for(int i = 0; i < MAX_EVENTS; i++)
@ -38,7 +37,7 @@ void event_manager_subscribe(struct Event_Manager* event_manager, int event_type
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++) for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{ {
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i]; struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->event_type == event_type && subscription->handler == handler_func) if(subscription->type == EST_WITHOUT_OBJECT && subscription->event_type == event_type && subscription->handler == handler_func)
{ {
log_message("Already subscibed to %s event", event_name_get(event_type)); log_message("Already subscibed to %s event", event_name_get(event_type));
subscribed = true; subscribed = true;
@ -53,8 +52,9 @@ void event_manager_subscribe(struct Event_Manager* event_manager, int event_type
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++) for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{ {
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i]; struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->event_type == EVT_NONE) if(subscription->type == EST_NONE)
{ {
subscription->type = EST_WITHOUT_OBJECT;
subscription->event_type = event_type; subscription->event_type = event_type;
subscription->handler = handler_func; subscription->handler = handler_func;
subscribed = true; subscribed = true;
@ -69,17 +69,38 @@ void event_manager_subscribe(struct Event_Manager* event_manager, int event_type
log_error("event_manager:subscribe", "Could not subscribe to %s event", event_name_get(event_type)); log_error("event_manager:subscribe", "Could not subscribe to %s event", event_name_get(event_type));
} }
void event_manager_unsubscribe(struct Event_Manager* event_manager, int event_type, Event_Handler subscriber) void event_manager_unsubscribe(struct Event_Manager* event_manager, int event_type, Event_Handler handler_func)
{ {
assert(event_manager && event_type < EVT_MAX); assert(event_manager && event_type < EVT_MAX);
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++) for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{ {
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i]; struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->event_type == event_type && subscription->handler == subscriber) if(subscription->type != EST_WITHOUT_OBJECT) continue;
if(subscription->event_type == event_type && subscription->handler == handler_func)
{ {
subscription->handler = NULL; subscription->handler = NULL;
subscription->event_type = EVT_NONE; subscription->event_type = EVT_NONE;
subscription->type = EST_NONE;
break;
}
}
}
void event_manager_unsubscribe_with_object(struct Event_Manager* event_manager, int event_type, Event_Handler_Object handler_func, void* subscriber)
{
assert(event_manager && event_type < EVT_MAX);
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->type != EST_WITH_OBJECT) continue;
if(subscription->event_type == event_type && subscription->handler_with_object == handler_func && subscription->subscriber == subscriber)
{
subscription->handler_with_object = NULL;
subscription->event_type = EVT_NONE;
subscription->type = EST_NONE;
subscription->subscriber = NULL;
break; break;
} }
} }
@ -212,9 +233,20 @@ void event_manager_poll_events(struct Event_Manager* event_manager, bool* out_qu
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++) for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{ {
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i]; struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->type == EST_NONE) continue;
if(subscription->event_type == user_event->type) if(subscription->event_type == user_event->type)
{ {
if(subscription->handler) subscription->handler(user_event); if(subscription->type == EST_WITHOUT_OBJECT)
{
if(subscription->handler)
subscription->handler(user_event);
}
else if(subscription->type == EST_WITH_OBJECT)
{
if(subscription->handler_with_object)
subscription->handler_with_object(user_event, subscription->subscriber);
}
} }
} }
@ -228,6 +260,49 @@ void event_manager_poll_events(struct Event_Manager* event_manager, bool* out_qu
} }
} }
void event_manager_subscribe_with_object(struct Event_Manager* event_manager, int event_type, Event_Handler_Object handler_func, void* subscriber)
{
assert(event_manager && event_type < EVT_MAX && event_type > EVT_NONE);
//Check if this handler/subscriber already exists
bool subscribed = false;
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->type == EST_WITH_OBJECT && subscription->event_type == event_type && subscription->handler_with_object == handler_func && subscription->subscriber != subscriber)
{
log_message("Already subscibed to %s event", event_name_get(event_type));
subscribed = true;
break;
}
}
//Now that we've established that we are not subscribed already we find an empty slot and
//create a new subscription there
if(!subscribed)
{
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->type == EST_NONE)
{
subscription->type = EST_WITH_OBJECT;
subscription->event_type = event_type;
subscription->handler_with_object = handler_func;
subscription->subscriber = subscriber;
subscribed = true;
break;
}
}
}
//if subscribed is still not true, it can only mean that all the existing slots are taken
//Show an error message in that case
if(!subscribed)
log_error("event_manager:subscribe_with_obejct", "Could not subscribe to %s event", event_name_get(event_type));
}
void event_manager_cleanup(struct Event_Manager* event_manager) void event_manager_cleanup(struct Event_Manager* event_manager)
{ {
@ -248,7 +323,25 @@ const char* event_name_get(int event_type)
case EVT_MOUSEWHEEL: return "Mouse Wheel"; case EVT_MOUSEWHEEL: return "Mouse Wheel";
case EVT_WINDOW_RESIZED: return "Window Resized"; case EVT_WINDOW_RESIZED: return "Window Resized";
case EVT_TEXT_INPUT: return "Text Input"; case EVT_TEXT_INPUT: return "Text Input";
case EVT_SCENE_LOADED: return "Scene Loaded";
case EVT_MAX: return "Max Number of Events"; case EVT_MAX: return "Max Number of Events";
default: return "Invalid event_type"; default: return "Invalid event_type";
} }
} }
void event_manager_send_event_entity(struct Event_Manager* event_manager, struct Event* event, struct Entity* entity)
{
// Check if this entity has a subscription, if it does,
// call the registered callback with this entity as the parameter to simulate an event
for(int i = 0; i < MAX_EVENT_SUBSCRIPTIONS; i++)
{
struct Event_Subscription* subscription = &event_manager->event_subsciptions[i];
if(subscription->type != EST_WITH_OBJECT) continue;
if(subscription->event_type == event->type && subscription->subscriber == entity && subscription->handler_with_object)
{
subscription->handler_with_object(event, (void*)entity);
break;
}
}
}

@ -3,11 +3,13 @@
#include "../common/linmath.h" #include "../common/linmath.h"
#include "../common/num_types.h" #include "../common/num_types.h"
#include "../common/limits.h"
struct Entity;
typedef void (*Event_Handler) (const struct Event* event); typedef void (*Event_Handler) (const struct Event* event);
typedef void (*Event_Handler_Object) (const struct Event* event, void* subscriber);
#define MAX_EVENTS 128
#define MAX_EVENT_SUBSCRIPTIONS 256
enum Event_Types enum Event_Types
{ {
@ -20,9 +22,17 @@ enum Event_Types
EVT_MOUSEWHEEL, EVT_MOUSEWHEEL,
EVT_WINDOW_RESIZED, EVT_WINDOW_RESIZED,
EVT_TEXT_INPUT, EVT_TEXT_INPUT,
EVT_SCENE_LOADED,
EVT_MAX EVT_MAX
}; };
enum Event_Subscription_Type
{
EST_NONE = 0,
EST_WITHOUT_OBJECT,
EST_WITH_OBJECT
};
struct Key_Event struct Key_Event
{ {
int scancode; int scancode;
@ -68,6 +78,11 @@ struct Window_Resized_Event
int height; int height;
}; };
struct Scene_Loaded_Event
{
char filename[MAX_FILENAME_LEN];
};
struct Event struct Event
{ {
int type; int type;
@ -79,15 +94,29 @@ struct Event
struct Mousemotion_Event mousemotion; struct Mousemotion_Event mousemotion;
struct Text_Input_Event text_input; struct Text_Input_Event text_input;
struct Window_Resized_Event window_resize; struct Window_Resized_Event window_resize;
struct Scene_Loaded_Event scene_load;
}; };
}; };
struct Event_Subscription struct Event_Subscription
{ {
int type;
int event_type; int event_type;
union
{
struct
{
Event_Handler handler; Event_Handler handler;
}; };
struct
{
Event_Handler_Object handler_with_object;
void* subscriber;
};
};
};
struct Event_Manager struct Event_Manager
{ {
struct Event event_pool[MAX_EVENTS]; struct Event event_pool[MAX_EVENTS];
@ -96,10 +125,13 @@ struct Event_Manager
}; };
void event_manager_init(struct Event_Manager* event_manager); void event_manager_init(struct Event_Manager* event_manager);
void event_manager_subscribe(struct Event_Manager* event_manager, int event_type, Event_Handler subscriber); void event_manager_subscribe(struct Event_Manager* event_manager, int event_type, Event_Handler event_handler_func);
void event_manager_subscribe_with_object(struct Event_Manager* event_manager, int event_type, Event_Handler_Object handler_func, void* subscriber);
void event_manager_unsubscribe(struct Event_Manager* event_manager, int event_type, Event_Handler subscriber); void event_manager_unsubscribe(struct Event_Manager* event_manager, int event_type, Event_Handler subscriber);
void event_manager_unsubscribe_with_object(struct Event_Manager* event_manager, int event_type, Event_Handler_Object handler_func, void* subscriber);
struct Event* event_manager_create_new_event(struct Event_Manager* event_manager); struct Event* event_manager_create_new_event(struct Event_Manager* event_manager);
void event_manager_send_event(struct Event_Manager* event_manager, struct Event* event); void event_manager_send_event(struct Event_Manager* event_manager, struct Event* event);
void event_manager_send_event_entity(struct Event_Manager* event_manager, struct Event* event, struct Entity* entity);
void event_manager_poll_events(struct Event_Manager* event_manager, bool* out_quit); void event_manager_poll_events(struct Event_Manager* event_manager, bool* out_quit);
void event_manager_cleanup(struct Event_Manager* event_manager); void event_manager_cleanup(struct Event_Manager* event_manager);
const char* event_name_get(int event_type); const char* event_name_get(int event_type);

@ -27,7 +27,7 @@ bool material_init(struct Material* material, int material_type)
{ {
material->lit = true; material->lit = true;
char custom_defines[64]; char custom_defines[64];
snprintf(custom_defines, 64, "#define MAX_LIGHTS %d", MAX_LIGHTS); snprintf(custom_defines, 64, "#define MAX_LIGHTS %d", MAX_SCENE_LIGHTS);
material->shader = shader_create("blinn_phong.vert", "blinn_phong.frag", custom_defines); material->shader = shader_create("blinn_phong.vert", "blinn_phong.frag", custom_defines);
if(material->shader == -1) if(material->shader == -1)

@ -4,11 +4,10 @@
#include "../common/linmath.h" #include "../common/linmath.h"
#include "../common/num_types.h" #include "../common/num_types.h"
#include "../common/variant.h" #include "../common/variant.h"
#include "../common/limits.h"
struct Static_Mesh; struct Static_Mesh;
#define MAX_UNIFORM_NAME_LEN 64
#define MAX_MATERIAL_REGISTERED_STATIC_MESHES 1024
struct Uniform struct Uniform
{ {

@ -267,7 +267,7 @@ void player_on_mousebutton_released(const struct Event* event)
vec3_scale(&collision_point, &collision_point, distance); vec3_scale(&collision_point, &collision_point, distance);
vec3_add(&collision_point, &collision_point, &bullet_ray.origin); vec3_add(&collision_point, &collision_point, &bullet_ray.origin);
//struct Static_Mesh* bullet = scene_static_mesh_create(game_state_get()->scene, "bullet", NULL, "cube.symbres", MAT_UNSHADED); //struct Static_Mesh* bullet = scene_static_mesh_create(game_state_get()->scene, "bullet", NULL, "cube.symbres", MAT_UNSHADED);
struct Light* bullet = entity_load("Spot", DIRT_INSTALL); struct Light* bullet = entity_load("Spot", DIRT_INSTALL, true);
if(bullet) transform_set_position(bullet, &collision_point); if(bullet) transform_set_position(bullet, &collision_point);
sound_source_play(game_state->sound, player->weapon_sound); sound_source_play(game_state->sound, player->weapon_sound);
} }

@ -103,7 +103,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
char uniform_name[MAX_UNIFORM_NAME_LEN]; char uniform_name[MAX_UNIFORM_NAME_LEN];
memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN); memset(uniform_name, '\0', MAX_UNIFORM_NAME_LEN);
int light_count = -1; int light_count = -1;
for(int j = 0; j < MAX_LIGHTS; j++) for(int j = 0; j < MAX_SCENE_LIGHTS; j++)
{ {
struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */ struct Light* light = &scene->lights[j]; /* TODO: Cull lights according to camera frustum */
if(!(light->base.flags & EF_ACTIVE) || !light->valid) continue; if(!(light->base.flags & EF_ACTIVE) || !light->valid) continue;
@ -253,7 +253,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
{ {
static mat4 mvp; static mat4 mvp;
shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &renderer->settings.debug_draw_color); shader_set_uniform_vec4(renderer->debug_shader, "debug_color", &renderer->settings.debug_draw_color);
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
struct Static_Mesh* mesh = &scene->static_meshes[i]; struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!(mesh->base.flags & EF_ACTIVE)) continue; if(!(mesh->base.flags & EF_ACTIVE)) continue;
@ -274,7 +274,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
if(renderer->settings.debug_draw_physics) if(renderer->settings.debug_draw_physics)
{ {
static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f }; static vec4 physics_draw_color = { 0.f, 0.f, 1.f, 1.f };
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
struct Static_Mesh* mesh = &scene->static_meshes[i]; struct Static_Mesh* mesh = &scene->static_meshes[i];
if(!(mesh->base.flags & EF_ACTIVE) || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue; if(!(mesh->base.flags & EF_ACTIVE) || (!mesh->collision.collision_shape && !mesh->collision.rigidbody)) continue;
@ -361,7 +361,7 @@ void renderer_on_framebuffer_size_changed(const struct Event* event)
struct Scene* scene = game_state_get()->scene; struct Scene* scene = game_state_get()->scene;
float aspect = (float)width / (float)height; float aspect = (float)width / (float)height;
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
{ {
struct Camera* viewer = &scene->cameras[i]; struct Camera* viewer = &scene->cameras[i];
if(viewer->resizeable) if(viewer->resizeable)

@ -19,6 +19,7 @@
#include "renderer.h" #include "renderer.h"
#include "sound_source.h" #include "sound_source.h"
#include "enemy.h" #include "enemy.h"
#include "event.h"
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>
@ -41,14 +42,14 @@ void scene_init(struct Scene* scene)
scene->root_entity.id = 0; scene->root_entity.id = 0;
scene->root_entity.type = ET_ROOT; 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_SCENE_ENTITIES; i++) entity_reset(&scene->entities[i], i);
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_SCENE_LIGHTS; i++)
{ {
entity_reset(&scene->lights[i], i); entity_reset(&scene->lights[i], i);
scene->lights[i].type = ET_LIGHT; scene->lights[i].type = ET_LIGHT;
} }
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
entity_reset(&scene->static_meshes[i], i); entity_reset(&scene->static_meshes[i], i);
struct Static_Mesh* mesh = &scene->static_meshes[i]; struct Static_Mesh* mesh = &scene->static_meshes[i];
@ -59,11 +60,11 @@ void scene_init(struct Scene* scene)
mesh->model.material = NULL; 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_SCENE_SOUND_SOURCES; i++) entity_reset(&scene->sound_sources[i], i);
int width = 1280, height = 720; int width = 1280, height = 720;
window_get_drawable_size(game_state->window, &width, &height); window_get_drawable_size(game_state->window, &width, &height);
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
{ {
entity_init(&scene->cameras[i], NULL, &scene->root_entity); entity_init(&scene->cameras[i], NULL, &scene->root_entity);
camera_init(&scene->cameras[i], width, height); camera_init(&scene->cameras[i], width, height);
@ -71,10 +72,10 @@ void scene_init(struct Scene* scene)
scene->cameras[i].base.id = i; scene->cameras[i].base.id = i;
} }
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) for(int i = 0; i < MAX_SCENE_ENTITY_ARCHETYPES; i++)
memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN); memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN);
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{ {
entity_reset(&scene->enemies[i], i); entity_reset(&scene->enemies[i], i);
scene->enemies->base.type = ET_ENEMY; scene->enemies->base.type = ET_ENEMY;
@ -156,7 +157,7 @@ bool scene_load(struct Scene* scene, const char* filename, int directory_type)
struct Hashmap* entity_entry_data = object->data; struct Hashmap* entity_entry_data = object->data;
if(hashmap_value_exists(object->data, "filename")) if(hashmap_value_exists(object->data, "filename"))
{ {
struct Entity* loaded_entity = entity_load(hashmap_str_get(entity_entry_data, "filename"), DIRT_INSTALL); struct Entity* loaded_entity = entity_load(hashmap_str_get(entity_entry_data, "filename"), DIRT_INSTALL, false);
if(loaded_entity) if(loaded_entity)
{ {
vec3 position = { 0.f, 0.f, 0.f }; vec3 position = { 0.f, 0.f, 0.f };
@ -208,6 +209,16 @@ bool scene_load(struct Scene* scene, const char* filename, int directory_type)
parser_free(parsed_file); parser_free(parsed_file);
fclose(scene_file); fclose(scene_file);
strncpy(scene->filename, filename, MAX_FILENAME_LEN); strncpy(scene->filename, filename, MAX_FILENAME_LEN);
if(num_objects_loaded > 0)
{
struct Event_Manager* event_manager = game_state_get()->event_manager;
struct Event* scene_loaded_event = event_manager_create_new_event(event_manager);
scene_loaded_event->type = EVT_SCENE_LOADED;
memset(scene_loaded_event->scene_load.filename, '\0', MAX_FILENAME_LEN);
strncpy(scene_loaded_event->scene_load.filename, filename, MAX_FILENAME_LEN);
event_manager_send_event(event_manager, scene_loaded_event);
}
return num_objects_loaded > 0 ? true : false; return num_objects_loaded > 0 ? true : false;
} }
@ -267,32 +278,32 @@ void scene_write_entity_list(struct Scene* scene, int entity_type, struct Parser
switch(entity_type) switch(entity_type)
{ {
case ET_DEFAULT: case ET_DEFAULT:
max_length = MAX_ENTITIES; max_length = MAX_SCENE_ENTITIES;
entity = &scene->entities[0]; entity = &scene->entities[0];
stride = sizeof(struct Entity); stride = sizeof(struct Entity);
break; break;
case ET_LIGHT: case ET_LIGHT:
max_length = MAX_LIGHTS; max_length = MAX_SCENE_LIGHTS;
entity = &scene->lights[0].base; entity = &scene->lights[0].base;
stride = sizeof(struct Light); stride = sizeof(struct Light);
break; break;
case ET_STATIC_MESH: case ET_STATIC_MESH:
max_length = MAX_STATIC_MESHES; max_length = MAX_SCENE_STATIC_MESHES;
entity = &scene->static_meshes[0].base; entity = &scene->static_meshes[0].base;
stride = sizeof(struct Static_Mesh); stride = sizeof(struct Static_Mesh);
break; break;
case ET_CAMERA: case ET_CAMERA:
max_length = MAX_CAMERAS; max_length = MAX_SCENE_CAMERAS;
entity = &scene->cameras[0].base; entity = &scene->cameras[0].base;
stride = sizeof(struct Camera); stride = sizeof(struct Camera);
break; break;
case ET_SOUND_SOURCE: case ET_SOUND_SOURCE:
max_length = MAX_SOUND_SOURCES; max_length = MAX_SCENE_SOUND_SOURCES;
entity = &scene->sound_sources[0].base; entity = &scene->sound_sources[0].base;
stride = sizeof(struct Sound_Source); stride = sizeof(struct Sound_Source);
break; break;
case ET_ENEMY: case ET_ENEMY:
max_length = MAX_ENEMIES; max_length = MAX_SCENE_ENEMIES;
entity = &scene->enemies[0].base; entity = &scene->enemies[0].base;
stride = sizeof(struct Enemy); stride = sizeof(struct Enemy);
break; break;
@ -338,13 +349,13 @@ void scene_destroy(struct Scene* scene)
{ {
assert(scene); assert(scene);
for(int i = 0; i < MAX_ENTITIES; i++) scene_entity_base_remove(scene, &scene->entities[i]); for(int i = 0; i < MAX_SCENE_ENTITIES; i++) scene_entity_base_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_SCENE_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_SCENE_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_SCENE_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]); for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++) scene_sound_source_remove(scene, &scene->sound_sources[i]);
for(int i = 0; i < MAX_ENEMIES; i++) scene_enemy_remove(scene, &scene->enemies[i]); for(int i = 0; i < MAX_SCENE_ENEMIES; i++) scene_enemy_remove(scene, &scene->enemies[i]);
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN); for(int i = 0; i < MAX_SCENE_ENTITY_ARCHETYPES; i++) memset(&scene->entity_archetypes[i][0], '\0', MAX_FILENAME_LEN);
player_destroy(&scene->player); player_destroy(&scene->player);
entity_reset(&scene->root_entity, 0); entity_reset(&scene->root_entity, 0);
scene->root_entity.flags &= ~EF_ACTIVE; scene->root_entity.flags &= ~EF_ACTIVE;
@ -355,7 +366,7 @@ void scene_update(struct Scene* scene, float dt)
if(game_state_get()->game_mode == GAME_MODE_GAME) if(game_state_get()->game_mode == GAME_MODE_GAME)
{ {
player_update(&scene->player, scene, dt); player_update(&scene->player, scene, dt);
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{ {
if(scene->enemies[i].base.flags & EF_ACTIVE) if(scene->enemies[i].base.flags & EF_ACTIVE)
enemy_update(&scene->enemies[i], scene, dt); enemy_update(&scene->enemies[i], scene, dt);
@ -368,7 +379,7 @@ void scene_post_update(struct Scene* scene)
assert(scene); assert(scene);
struct Sound* sound = game_state_get()->sound; struct Sound* sound = game_state_get()->sound;
for(int i = 0; i < MAX_ENTITIES; i++) for(int i = 0; i < MAX_SCENE_ENTITIES; i++)
{ {
struct Entity* entity = &scene->entities[i]; struct Entity* entity = &scene->entities[i];
if(!(entity->flags & EF_ACTIVE)) continue; if(!(entity->flags & EF_ACTIVE)) continue;
@ -382,7 +393,7 @@ void scene_post_update(struct Scene* scene)
if(entity->transform.is_modified) entity->transform.is_modified = false; if(entity->transform.is_modified) entity->transform.is_modified = false;
} }
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
{ {
struct Camera* camera = &scene->cameras[i]; struct Camera* camera = &scene->cameras[i];
if(!(camera->base.flags & EF_ACTIVE)) continue; if(!(camera->base.flags & EF_ACTIVE)) continue;
@ -400,7 +411,7 @@ void scene_post_update(struct Scene* scene)
} }
} }
for(int i = 0; i < MAX_SOUND_SOURCES; i++) for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++)
{ {
struct Sound_Source* sound_source = &scene->sound_sources[i]; struct Sound_Source* sound_source = &scene->sound_sources[i];
if(!(sound_source->base.flags & EF_ACTIVE)) continue; if(!(sound_source->base.flags & EF_ACTIVE)) continue;
@ -418,7 +429,7 @@ void scene_post_update(struct Scene* scene)
} }
} }
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
struct Static_Mesh* static_mesh = &scene->static_meshes[i]; struct Static_Mesh* static_mesh = &scene->static_meshes[i];
if(!(static_mesh->base.flags & EF_ACTIVE)) continue; if(!(static_mesh->base.flags & EF_ACTIVE)) continue;
@ -445,7 +456,7 @@ void scene_post_update(struct Scene* scene)
} }
} }
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_SCENE_LIGHTS; i++)
{ {
struct Light* light = &scene->lights[i]; struct Light* light = &scene->lights[i];
if(!(light->base.flags & EF_ACTIVE)) continue; if(!(light->base.flags & EF_ACTIVE)) continue;
@ -459,7 +470,7 @@ void scene_post_update(struct Scene* scene)
if(light->base.transform.is_modified) light->base.transform.is_modified = false; if(light->base.transform.is_modified) light->base.transform.is_modified = false;
} }
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{ {
struct Enemy* enemy = &scene->enemies[i]; struct Enemy* enemy = &scene->enemies[i];
if(!(enemy->base.flags & EF_ACTIVE)) continue; if(!(enemy->base.flags & EF_ACTIVE)) continue;
@ -483,7 +494,7 @@ struct Entity* scene_entity_create(struct Scene* scene, const char* name, struct
assert(scene); assert(scene);
struct Entity* new_entity = NULL; struct Entity* new_entity = NULL;
for(int i = 0; i < MAX_ENTITIES; i++) for(int i = 0; i < MAX_SCENE_ENTITIES; i++)
{ {
struct Entity* entity = &scene->entities[i]; struct Entity* entity = &scene->entities[i];
if(!(entity->flags & EF_ACTIVE)) if(!(entity->flags & EF_ACTIVE))
@ -511,7 +522,7 @@ struct Light* scene_light_create(struct Scene* scene, const char* name, struct E
{ {
assert(scene); assert(scene);
struct Light* new_light = NULL; struct Light* new_light = NULL;
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_SCENE_LIGHTS; i++)
{ {
struct Light* light = &scene->lights[i]; struct Light* light = &scene->lights[i];
if(!(light->base.flags & EF_ACTIVE)) if(!(light->base.flags & EF_ACTIVE))
@ -539,7 +550,7 @@ struct Camera* scene_camera_create(struct Scene* scene, const char* name, struct
{ {
assert(scene); assert(scene);
struct Camera* new_camera = NULL; struct Camera* new_camera = NULL;
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
{ {
struct Camera* camera = &scene->cameras[i]; struct Camera* camera = &scene->cameras[i];
if(!(camera->base.flags & EF_ACTIVE)) if(!(camera->base.flags & EF_ACTIVE))
@ -567,7 +578,7 @@ struct Static_Mesh* scene_static_mesh_create(struct Scene* scene, const char* na
{ {
assert(scene); assert(scene);
struct Static_Mesh* new_static_mesh = NULL; struct Static_Mesh* new_static_mesh = NULL;
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
struct Static_Mesh* static_mesh = &scene->static_meshes[i]; struct Static_Mesh* static_mesh = &scene->static_meshes[i];
if(!(static_mesh->base.flags & EF_ACTIVE)) if(!(static_mesh->base.flags & EF_ACTIVE))
@ -599,7 +610,7 @@ struct Sound_Source* scene_sound_source_create(struct Scene* scene, const char*
assert(scene && filename); assert(scene && filename);
struct Sound* sound = game_state_get()->sound; struct Sound* sound = game_state_get()->sound;
struct Sound_Source* new_sound_source = NULL; struct Sound_Source* new_sound_source = NULL;
for(int i = 0; i < MAX_SOUND_SOURCES; i++) for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++)
{ {
struct Sound_Source* sound_source = &scene->sound_sources[i]; struct Sound_Source* sound_source = &scene->sound_sources[i];
if(!(sound_source->base.flags & EF_ACTIVE)) if(!(sound_source->base.flags & EF_ACTIVE))
@ -657,7 +668,7 @@ struct Enemy* scene_enemy_create(struct Scene* scene, const char* name, struct E
{ {
assert(scene); assert(scene);
struct Enemy* new_enemy = NULL; struct Enemy* new_enemy = NULL;
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{ {
struct Enemy* enemy = &scene->enemies[i]; struct Enemy* enemy = &scene->enemies[i];
if(!(enemy->base.flags & EF_ACTIVE)) if(!(enemy->base.flags & EF_ACTIVE))
@ -738,7 +749,7 @@ struct Entity* scene_entity_find(struct Scene* scene, const char* name)
assert(scene && name); assert(scene && name);
struct Entity* entity = NULL; struct Entity* entity = NULL;
for(int i = 0; i < MAX_ENTITIES; i++) for(int i = 0; i < MAX_SCENE_ENTITIES; i++)
{ {
if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->entities[i].name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -755,7 +766,7 @@ struct Light* scene_light_find(struct Scene* scene, const char* name)
assert(scene && name); assert(scene && name);
struct Light* light = NULL; struct Light* light = NULL;
for(int i = 0; i < MAX_LIGHTS; i++) for(int i = 0; i < MAX_SCENE_LIGHTS; i++)
{ {
if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->lights[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -772,7 +783,7 @@ struct Camera* scene_camera_find(struct Scene* scene, const char* name)
assert(scene && name); assert(scene && name);
struct Camera* camera = NULL; struct Camera* camera = NULL;
for(int i = 0; i < MAX_CAMERAS; i++) for(int i = 0; i < MAX_SCENE_CAMERAS; i++)
{ {
if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->cameras[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -789,7 +800,7 @@ struct Static_Mesh* scene_static_mesh_find(struct Scene* scene, const char* name
assert(scene && name); assert(scene && name);
struct Static_Mesh* static_mesh = NULL; struct Static_Mesh* static_mesh = NULL;
for(int i = 0; i < MAX_STATIC_MESHES; i++) for(int i = 0; i < MAX_SCENE_STATIC_MESHES; i++)
{ {
if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->static_meshes[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -806,7 +817,7 @@ struct Sound_Source* scene_sound_source_find(struct Scene* scene, const char* na
assert(scene && name); assert(scene && name);
struct Sound_Source* sound_source = NULL; struct Sound_Source* sound_source = NULL;
for(int i = 0; i < MAX_SOUND_SOURCES; i++) for(int i = 0; i < MAX_SCENE_SOUND_SOURCES; i++)
{ {
if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->sound_sources[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -823,7 +834,7 @@ struct Enemy* scene_enemy_get(struct Scene* scene, const char* name)
assert(scene && name); assert(scene && name);
struct Enemy* enemy = NULL; struct Enemy* enemy = NULL;
for(int i = 0; i < MAX_ENEMIES; i++) for(int i = 0; i < MAX_SCENE_ENEMIES; i++)
{ {
if(strncmp(name, scene->enemies[i].base.name, MAX_ENTITY_NAME_LEN) == 0) if(strncmp(name, scene->enemies[i].base.name, MAX_ENTITY_NAME_LEN) == 0)
{ {
@ -906,31 +917,31 @@ void scene_ray_intersect(struct Scene* scene, struct Ray* ray, struct Raycast_Re
{ {
case ET_DEFAULT: case ET_DEFAULT:
if(!(ray_mask & ERM_DEFAULT)) continue; if(!(ray_mask & ERM_DEFAULT)) continue;
max_length = MAX_ENTITIES; max_length = MAX_SCENE_ENTITIES;
entity = &scene->entities[0]; entity = &scene->entities[0];
stride = sizeof(struct Entity); stride = sizeof(struct Entity);
break; break;
case ET_LIGHT: case ET_LIGHT:
if(!(ray_mask & ERM_LIGHT)) continue; if(!(ray_mask & ERM_LIGHT)) continue;
max_length = MAX_LIGHTS; max_length = MAX_SCENE_LIGHTS;
entity = &scene->lights[0].base; entity = &scene->lights[0].base;
stride = sizeof(struct Light); stride = sizeof(struct Light);
break; break;
case ET_STATIC_MESH: case ET_STATIC_MESH:
if(!(ray_mask & ERM_STATIC_MESH)) continue; if(!(ray_mask & ERM_STATIC_MESH)) continue;
max_length = MAX_STATIC_MESHES; max_length = MAX_SCENE_STATIC_MESHES;
entity = &scene->static_meshes[0].base; entity = &scene->static_meshes[0].base;
stride = sizeof(struct Static_Mesh); stride = sizeof(struct Static_Mesh);
break; break;
case ET_CAMERA: case ET_CAMERA:
if(!(ray_mask & ERM_CAMERA)) continue; if(!(ray_mask & ERM_CAMERA)) continue;
max_length = MAX_CAMERAS; max_length = MAX_SCENE_CAMERAS;
entity = &scene->cameras[0].base; entity = &scene->cameras[0].base;
stride = sizeof(struct Camera); stride = sizeof(struct Camera);
break; break;
case ET_SOUND_SOURCE: case ET_SOUND_SOURCE:
if(!(ray_mask & ERM_SOUND_SOURCE)) continue; if(!(ray_mask & ERM_SOUND_SOURCE)) continue;
max_length = MAX_SOUND_SOURCES; max_length = MAX_SCENE_SOUND_SOURCES;
entity = &scene->sound_sources[0].base; entity = &scene->sound_sources[0].base;
stride = sizeof(struct Sound_Source); stride = sizeof(struct Sound_Source);
break; break;
@ -981,31 +992,31 @@ struct Entity* scene_ray_intersect_closest(struct Scene* scene, struct Ray* ray,
{ {
case ET_DEFAULT: case ET_DEFAULT:
if(!(ray_mask & ERM_DEFAULT)) continue; if(!(ray_mask & ERM_DEFAULT)) continue;
max_length = MAX_ENTITIES; max_length = MAX_SCENE_ENTITIES;
entity = &scene->entities[0]; entity = &scene->entities[0];
stride = sizeof(struct Entity); stride = sizeof(struct Entity);
break; break;
case ET_LIGHT: case ET_LIGHT:
if(!(ray_mask & ERM_LIGHT)) continue; if(!(ray_mask & ERM_LIGHT)) continue;
max_length = MAX_LIGHTS; max_length = MAX_SCENE_LIGHTS;
entity = &scene->lights[0].base; entity = &scene->lights[0].base;
stride = sizeof(struct Light); stride = sizeof(struct Light);
break; break;
case ET_STATIC_MESH: case ET_STATIC_MESH:
if(!(ray_mask & ERM_STATIC_MESH)) continue; if(!(ray_mask & ERM_STATIC_MESH)) continue;
max_length = MAX_STATIC_MESHES; max_length = MAX_SCENE_STATIC_MESHES;
entity = &scene->static_meshes[0].base; entity = &scene->static_meshes[0].base;
stride = sizeof(struct Static_Mesh); stride = sizeof(struct Static_Mesh);
break; break;
case ET_CAMERA: case ET_CAMERA:
if(!(ray_mask & ERM_CAMERA)) continue; if(!(ray_mask & ERM_CAMERA)) continue;
max_length = MAX_CAMERAS; max_length = MAX_SCENE_CAMERAS;
entity = &scene->cameras[0].base; entity = &scene->cameras[0].base;
stride = sizeof(struct Camera); stride = sizeof(struct Camera);
break; break;
case ET_SOUND_SOURCE: case ET_SOUND_SOURCE:
if(!(ray_mask & ERM_SOUND_SOURCE)) continue; if(!(ray_mask & ERM_SOUND_SOURCE)) continue;
max_length = MAX_SOUND_SOURCES; max_length = MAX_SCENE_SOUND_SOURCES;
entity = &scene->sound_sources[0].base; entity = &scene->sound_sources[0].base;
stride = sizeof(struct Sound_Source); stride = sizeof(struct Sound_Source);
break; break;
@ -1068,7 +1079,7 @@ int scene_entity_archetype_add(struct Scene* scene, const char* filename)
// check if we have already added this archetype, if we have, return that index // check if we have already added this archetype, if we have, return that index
// otherwise add it and return the index // otherwise add it and return the index
int index = -1; int index = -1;
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) for(int i = 0; i < MAX_SCENE_ENTITY_ARCHETYPES; i++)
{ {
if(strncmp(filename, &scene->entity_archetypes[i][0], MAX_FILENAME_LEN) == 0) if(strncmp(filename, &scene->entity_archetypes[i][0], MAX_FILENAME_LEN) == 0)
{ {
@ -1079,7 +1090,7 @@ int scene_entity_archetype_add(struct Scene* scene, const char* filename)
if(index == -1) if(index == -1)
{ {
for(int i = 0; i < MAX_ENTITY_ARCHETYPES; i++) for(int i = 0; i < MAX_SCENE_ENTITY_ARCHETYPES; i++)
{ {
if(scene->entity_archetypes[i][0] == '\0') if(scene->entity_archetypes[i][0] == '\0')
{ {
@ -1103,7 +1114,7 @@ struct Entity* scene_entity_duplicate(struct Scene* scene, struct Entity* entity
struct Entity* new_entity = NULL; struct Entity* new_entity = NULL;
if(entity->archetype_index != -1) if(entity->archetype_index != -1)
{ {
new_entity = entity_load(scene->entity_archetypes[entity->archetype_index], DIRT_INSTALL); new_entity = entity_load(scene->entity_archetypes[entity->archetype_index], DIRT_INSTALL, true);
if(new_entity) scene_entity_parent_set(scene, new_entity, entity->transform.parent); if(new_entity) scene_entity_parent_set(scene, new_entity, entity->transform.parent);
return new_entity; return new_entity;
} }

@ -3,14 +3,7 @@
#include "entity.h" #include "entity.h"
#include "renderer.h" #include "renderer.h"
#include "../common/limits.h"
#define MAX_ENTITIES 32
#define MAX_LIGHTS 30
#define MAX_CAMERAS 2
#define MAX_STATIC_MESHES 1024
#define MAX_SOUND_SOURCES 128
#define MAX_ENTITY_ARCHETYPES 32
#define MAX_ENEMIES 64
struct Ray; struct Ray;
struct Raycast_Result; struct Raycast_Result;
@ -20,13 +13,13 @@ struct Scene
char filename[MAX_FILENAME_LEN]; char filename[MAX_FILENAME_LEN];
struct Entity root_entity; struct Entity root_entity;
struct Player player; struct Player player;
struct Entity entities[MAX_ENTITIES]; struct Entity entities[MAX_SCENE_ENTITIES];
struct Static_Mesh static_meshes[MAX_STATIC_MESHES]; struct Static_Mesh static_meshes[MAX_SCENE_STATIC_MESHES];
struct Camera cameras[MAX_CAMERAS]; struct Camera cameras[MAX_SCENE_CAMERAS];
struct Light lights[MAX_LIGHTS]; struct Light lights[MAX_SCENE_LIGHTS];
struct Sound_Source sound_sources[MAX_SOUND_SOURCES]; struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES];
struct Enemy enemies[MAX_ENEMIES]; struct Enemy enemies[MAX_SCENE_ENEMIES];
char entity_archetypes[MAX_ENTITY_ARCHETYPES][MAX_FILENAME_LEN]; char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN];
int active_camera_index; int active_camera_index;
}; };

@ -4,7 +4,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#define MAX_FILENAME_LEN 128 #include "../common/limits.h"
enum Directory_Type enum Directory_Type
{ {

@ -1,5 +1,4 @@
Todo: Todo:
- Imlement reading/writing enemy mesh and weapon sound to file and resetting it in code
- Enemy ray casting and shooting - Enemy ray casting and shooting
- Player shooting - Player shooting
- Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded - Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded
@ -34,6 +33,7 @@ Todo:
- Command to reload entities only - Command to reload entities only
- Serialize player, camera properties to file - Serialize player, camera properties to file
- Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode - Change mouse behaviour to lock cursor when looking around so as not to interfere with gui elements when in editor mode
- Resource manager that loads/unloads/reloads all types of assets and caches them when required so that we don't end up constantly loading files from disk
- Folder management api to create/delete folders when none exist. Dirent would suffice for our simple needs? - Folder management api to create/delete folders when none exist. Dirent would suffice for our simple needs?
? Entity creator window to create new types of entities and write them ? Entity creator window to create new types of entities and write them
to disk to disk
@ -402,3 +402,5 @@ Done:
* Screen mouse coordinates to world-coordinates for aiming * Screen mouse coordinates to world-coordinates for aiming
* Sound source entity functions that automatically track if handles are valid and create/update as necessary * Sound source entity functions that automatically track if handles are valid and create/update as necessary
* Apply sound source properties to source instance whenever a new instance is created * Apply sound source properties to source instance whenever a new instance is created
* Imlemented reading/writing enemy mesh and weapon sound to file and resetting it in code
* Implemented on_load and on_update callbacks for enemies. Different enemy types have different callbacks that are assigned when they are created.
Loading…
Cancel
Save