diff --git a/src/common/hashmap.c b/src/common/hashmap.c index d8ebbb8..2a2a956 100755 --- a/src/common/hashmap.c +++ b/src/common/hashmap.c @@ -147,6 +147,12 @@ void hashmap_int_set(struct Hashmap* hashmap, const char* key, const int value) variant_assign_int(&new_entry->value, value); } +void hashmap_uint_set(struct Hashmap* hashmap, const char* key, const uint value) +{ + struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); + variant_assign_uint(&new_entry->value, value); +} + void hashmap_double_set(struct Hashmap* hashmap, const char* key, const double value) { struct Hashmap_Entry* new_entry = hashmap_entry_new(hashmap, key); @@ -239,6 +245,13 @@ int hashmap_int_get(const struct Hashmap* hashmap, const char* key) return variant->val_int; } +uint hashmap_uint_get(const struct Hashmap* hashmap, const char* key) +{ + struct Variant* variant = hashmap_value_get(hashmap, key); + if(variant->type == VT_STR) variant_from_str(variant, variant->val_str, VT_UINT); + return variant->val_uint; +} + double hashmap_double_get(const struct Hashmap* hashmap, const char* key) { struct Variant* variant = hashmap_value_get(hashmap, key); diff --git a/src/common/hashmap.h b/src/common/hashmap.h index 5b7edbe..dcd72a1 100755 --- a/src/common/hashmap.h +++ b/src/common/hashmap.h @@ -4,9 +4,8 @@ #include "linmath.h" #include "num_types.h" #include "array.h" +#include "limits.h" -#define HASH_MAP_NUM_BUCKETS 10 -#define HASH_MAX_KEY_LEN 128 struct Hashmap; struct Variant; @@ -21,6 +20,7 @@ struct Variant* hashmap_value_get(const struct Hashmap* hashmap, const char* key void hashmap_float_set(struct Hashmap* hashmap, const char* key, const float value); void hashmap_int_set(struct Hashmap* hashmap, const char* key, const int value); +void hashmap_uint_set(struct Hashmap* hashmap, const char* key, const uint value); void hashmap_double_set(struct Hashmap* hashmap, const char* key, const double value); void hashmap_bool_set(struct Hashmap* hashmap, const char* key, const bool value); void hashmap_vec2_set(struct Hashmap* hashmap, const char* key, const vec2* value); @@ -37,6 +37,7 @@ void hashmap_ptr_set(struct Hashmap* hashmap, const char* key, void* value) float hashmap_float_get(const struct Hashmap* hashmap, const char* key); int hashmap_int_get(const struct Hashmap* hashmap, const char* key); +uint hashmap_uint_get(const struct Hashmap* hashmap, const char* key); double hashmap_double_get(const struct Hashmap* hashmap, const char* key); bool hashmap_bool_get(const struct Hashmap* hashmap, const char* key); vec2 hashmap_vec2_get(const struct Hashmap* hashmap, const char* key); diff --git a/src/common/limits.h b/src/common/limits.h index a7b14be..62ff676 100644 --- a/src/common/limits.h +++ b/src/common/limits.h @@ -36,4 +36,7 @@ #define MAX_DEBUG_VARS_PER_FRAME_NUMERIC 64 #define MAX_DEBUG_VARS_PER_FRAME_TEXTURES 8 +#define HASH_MAP_NUM_BUCKETS 10 +#define HASH_MAX_KEY_LEN 128 + #endif diff --git a/src/common/version.h b/src/common/version.h index 639fe46..a22f902 100755 --- a/src/common/version.h +++ b/src/common/version.h @@ -4,7 +4,7 @@ /* Auto generated version file. DO NOT MODIFY */ #define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MINOR 1 -#define SYMMETRY_VERSION_REVISION 345 +#define SYMMETRY_VERSION_REVISION 346 #define SYMMETRY_VERSION_BRANCH "dev" #endif \ No newline at end of file diff --git a/src/game/entity.h b/src/game/entity.h index 2bbdfa2..7ccb543 100755 --- a/src/game/entity.h +++ b/src/game/entity.h @@ -209,6 +209,7 @@ struct Player float min_downward_distance; float min_forward_distance; bool grounded; + bool can_jump; }; struct Enemy diff --git a/src/game/event.c b/src/game/event.c index 3e1dac2..505fb12 100644 --- a/src/game/event.c +++ b/src/game/event.c @@ -327,6 +327,8 @@ const char* event_name_get(int event_type) case EVT_TEXT_INPUT: return "Text Input"; case EVT_SCENE_LOADED: return "Scene Loaded"; case EVT_TRIGGER: return "Trigger Activated"; + case EVT_INPUT_MAP_PRESSED: return "Input Map Pressed"; + case EVT_INPUT_MAP_RELEASED: return "Input Map Released"; case EVT_MAX: return "Max Number of Events"; default: return "Invalid event_type"; } diff --git a/src/game/event.h b/src/game/event.h index f549f56..2e42465 100755 --- a/src/game/event.h +++ b/src/game/event.h @@ -25,6 +25,8 @@ enum Event_Types EVT_TEXT_INPUT, EVT_SCENE_LOADED, EVT_TRIGGER, + EVT_INPUT_MAP_PRESSED, + EVT_INPUT_MAP_RELEASED, EVT_MAX }; @@ -35,6 +37,11 @@ enum Event_Subscription_Type EST_WITH_OBJECT }; +struct Input_Map_Event +{ + char name[HASH_MAX_KEY_LEN]; +}; + struct Key_Event { int scancode; @@ -103,6 +110,7 @@ struct Event struct Window_Resized_Event window_resize; struct Scene_Loaded_Event scene_load; struct Trigger_Event trigger; + struct Input_Map_Event input_map; }; }; diff --git a/src/game/input.c b/src/game/input.c index c227826..ebf13a4 100755 --- a/src/game/input.c +++ b/src/game/input.c @@ -283,6 +283,7 @@ void input_on_key(const struct Event* event) if(mod_shift) mods |= KMD_SHIFT; if(mod_alt) mods |= KMD_ALT; + struct Event_Manager* event_manager = game_state_get()->event_manager; char* map_key = NULL; struct Variant* value = NULL; HASHMAP_FOREACH(key_bindings, map_key, value) @@ -292,6 +293,10 @@ void input_on_key(const struct Event* event) if(key_binding->key_primary == key && (key_binding->mods_primary & mods) == key_binding->mods_primary) { key_binding->state = event->type == EVT_KEY_PRESSED ? KS_PRESSED : KS_RELEASED; + struct Event* input_map_event = event_manager_create_new_event(event_manager); + input_map_event->type = event->type == EVT_KEY_PRESSED ? EVT_INPUT_MAP_PRESSED : EVT_INPUT_MAP_RELEASED; + strncpy(&input_map_event->input_map.name, map_key, HASH_MAX_KEY_LEN); + event_manager_send_event(event_manager, input_map_event); break; } @@ -299,6 +304,10 @@ void input_on_key(const struct Event* event) if(key_binding->key_secondary == key && (key_binding->mods_secondary & mods) == key_binding->mods_secondary) { key_binding->state = event->type == EVT_KEY_PRESSED ? KS_PRESSED : KS_RELEASED; + struct Event* input_map_event = event_manager_create_new_event(event_manager); + input_map_event->type = event->type == EVT_KEY_PRESSED ? EVT_INPUT_MAP_PRESSED : EVT_INPUT_MAP_RELEASED; + strncpy(&input_map_event->input_map.name, map_key, HASH_MAX_KEY_LEN); + event_manager_send_event(event_manager, input_map_event); break; } } diff --git a/src/game/player.c b/src/game/player.c index ca7bc06..09a17a0 100755 --- a/src/game/player.c +++ b/src/game/player.c @@ -21,6 +21,7 @@ #include static void player_on_mousebutton_released(const struct Event* event); +static void player_on_input_map_released(const struct Event* event); void player_init(struct Player* player, struct Scene* scene) { @@ -41,6 +42,7 @@ void player_init(struct Player* player, struct Scene* scene) player->min_downward_distance = hashmap_float_get(config, "player_min_downward_distance"); player->min_forward_distance = hashmap_float_get(config, "player_min_forward_distance"); player->grounded = true; + player->can_jump = true; player->health = 100; player->key_mask = 0; @@ -74,11 +76,11 @@ void player_init(struct Player* player, struct Scene* scene) log_error("player:init", "Could not add grunt entity to player"); // Mark player camera and mesh as transient for now. We don't need to save them to file since we recreate them here anyway - player->camera->base.flags |= EF_TRANSIENT; - player->mesh->base.flags |= EF_TRANSIENT; - player->weapon_sound->base.flags |= EF_TRANSIENT; + player->camera->base.flags |= EF_TRANSIENT; + player->mesh->base.flags |= EF_TRANSIENT; + player->weapon_sound->base.flags |= EF_TRANSIENT; player->footstep_sound->base.flags |= EF_TRANSIENT; - player->grunt_sound->base.flags |= EF_TRANSIENT; + player->grunt_sound->base.flags |= EF_TRANSIENT; transform_parent_set(player_camera, player, true); @@ -89,11 +91,13 @@ void player_init(struct Player* player, struct Scene* scene) sound_listener_update(game_state->sound); event_manager_subscribe(game_state->event_manager, EVT_MOUSEBUTTON_RELEASED, &player_on_mousebutton_released); + event_manager_subscribe(game_state->event_manager, EVT_INPUT_MAP_RELEASED, &player_on_input_map_released); } void player_destroy(struct Player* player) { event_manager_unsubscribe(game_state_get()->event_manager, EVT_MOUSEBUTTON_RELEASED, &player_on_mousebutton_released); + event_manager_unsubscribe(game_state_get()->event_manager, EVT_INPUT_MAP_RELEASED, &player_on_input_map_released); entity_reset(player, player->base.id); scene_entity_base_remove(game_state_get()->scene, &player->base); player->base.flags = EF_NONE; @@ -146,11 +150,11 @@ void player_update_physics(struct Player* player, struct Scene* scene, float fix transform_rotate(player->camera, &rot_axis_pitch, pitch, TS_LOCAL); /* Movement */ - float move_speed = player->move_speed; - vec3 move_direction = { 0.f }; + float move_speed = player->move_speed; + vec3 move_direction = { 0.f }; - static bool jumping = false; - static bool landed = false; + static bool jumping = false; + static bool landed = false; static float move_speed_vertical = 0.f; // If we started jumping last frame, set jumpig to false @@ -165,11 +169,16 @@ void player_update_physics(struct Player* player, struct Scene* scene, float fix if(input_map_state_get("Move_Right", KS_PRESSED)) move_direction.x += 1.f; if(input_map_state_get("Jump", KS_PRESSED)) { - if(player->grounded) + if(player->grounded && player->can_jump) { move_speed_vertical += player->jump_speed; jumping = true; player->grounded = false; + player->can_jump = false; + } + else + { + player->can_jump = false; } } @@ -293,6 +302,17 @@ void player_update_physics(struct Player* player, struct Scene* scene, float fix } } + debug_vars_show_bool("Grounded", player->grounded); +} + +void player_on_input_map_released(const struct Event* event) +{ + struct Game_State* game_state = game_state_get(); + if(strncmp("Jump", event->input_map.name, HASH_MAX_KEY_LEN) == 0) + { + struct Player* player = &game_state->scene->player; + player->can_jump = true; + } } void player_on_mousebutton_released(const struct Event* event) diff --git a/src/system/platform.c b/src/system/platform.c index b0f2fde..522c9ba 100755 --- a/src/system/platform.c +++ b/src/system/platform.c @@ -395,3 +395,16 @@ void* platform_load_function_gl(const char* func_name) if(!func_ptr) log_error("platform:load_function_gl", "Failed to load GL function '%s' from library, SDL : (%s)", func_name, SDL_GetError()); return func_ptr; } + +int platform_timer_add(uint32 interval_ms, Timer_Callback_Func callback, void* param) +{ + SDL_TimerID timer_id = SDL_AddTimer(interval_ms, callback, param); + if(timer_id == 0) + log_error("platform:tiemr_add", "Failed to add timer, SDL : (%s)", SDL_GetError()); + return timer_id; +} + +bool platform_timer_remove(int timer_id) +{ + return (bool)SDL_RemoveTimer(timer_id); +} diff --git a/src/system/platform.h b/src/system/platform.h index 8ed196f..70722c3 100755 --- a/src/system/platform.h +++ b/src/system/platform.h @@ -4,6 +4,8 @@ #include #include "../common/num_types.h" +typedef void (*Timer_Callback_Func) (uint32 interval, void* param); + enum Video_Drivers_Linux { VD_X11 = 0, @@ -52,5 +54,7 @@ void* platform_load_function(void* library_handle, const char* func_name); bool platform_load_gl(const char* name); void platform_unload_gl(void); void* platform_load_function_gl(const char* func_name); +int platform_timer_add(uint32 interval_ms, Timer_Callback_Func callback, void* param); +bool platform_timer_remove(int timer_id); #endif diff --git a/todo.txt b/todo.txt index 3df09dc..51b69f6 100644 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ Todo: - - Implement player footstep sounds for walking, running and jumping - RGB keys to progress to next level + - Visual indicator on doors corresponding to their key masks + - Audio cues when player does not have the right key combination to open a particular door - Player/enemies getting hit by bullets - Win/fail States - Remove excessive repitition in scene and editor code that handles multiple entity types @@ -13,8 +14,8 @@ Todo: - Implement flag for ignoring collisions with certain entities - Implement game gui either with a separate nuklear context or as part of existing context - Fix rotate gizmo's origin not being set to the selected entity + - Ambient/Background music - Player shooting - - Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded - Sky Cube maps - Scrolling textures - Apply the selected entity's transformation when duplicating an entity that has an entity archetype @@ -418,4 +419,6 @@ Done: * Composite door entity made up of static mesh, sound entity and trigger. Door might require 0-3 keys in order to be opened. * Add door properties to property inspector in editor * Switched transformation in property inspector to show/modify local transform values by default and show absolute transform values as read-only. - * Doors that open using the red/green/blue keys only as a way of progressing the level or cordoing off certain sections \ No newline at end of file + * Doors that open using the red/green/blue keys only as a way of progressing the level or cordoing off certain sections + * Implemented player footstep sounds for walking, running and jumping + * Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded \ No newline at end of file