diff --git a/src/common/version.h b/src/common/version.h index 5ccd18e..1db6d7f 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 318 +#define SYMMETRY_VERSION_REVISION 319 #define SYMMETRY_VERSION_BRANCH "dev" #endif \ No newline at end of file diff --git a/src/game/enemy.c b/src/game/enemy.c index e363386..dedbf00 100644 --- a/src/game/enemy.c +++ b/src/game/enemy.c @@ -8,11 +8,15 @@ #include "../common/hashmap.h" #include "../common/parser.h" #include "event.h" +#include "../system/platform.h" +#include "debug_vars.h" #include +#include static void enemy_on_scene_loaded(struct Event* event, void* enemy_ptr); -static void enemy_update_turret(struct Enemy* enemy, struct Game_State* game_state, float dt); +static void enemy_update_physics_turret(struct Enemy* enemy, struct Game_State* game_state, float fixed_dt); +static void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state, float dt); void enemy_init(struct Enemy* enemy, int type) { @@ -77,7 +81,17 @@ void enemy_update(struct Enemy* enemy, struct Scene* scene, float dt) switch(enemy->type) { - case ENEMY_TURRET: enemy_update_turret(enemy, game_state, dt); break; + case ENEMY_TURRET: enemy_update_ai_turret(enemy, game_state, dt); break; + } + +} + +void enemy_update_physics(struct Enemy* enemy, struct Scene* scene, float fixed_dt) +{ + struct Game_State* game_state = game_state_get(); + switch(enemy->type) + { + case ENEMY_TURRET: enemy_update_physics_turret(enemy, game_state, fixed_dt); break; } } @@ -160,8 +174,9 @@ void enemy_on_scene_loaded(struct Event* event, void* enemy_ptr) // Do other post-scene-load initialization stuff per enemy type here } -void enemy_update_turret(struct Enemy* enemy, struct Game_State* game_state, float dt) +void enemy_update_physics_turret(struct Enemy* enemy, struct Game_State* game_state, float dt) { + /* Turning/Rotation */ static vec3 turn_axis = { 0.f, 1.f, 0.f }; float current_yaw = quat_get_yaw(&enemy->base.transform.rotation); @@ -183,4 +198,19 @@ void enemy_update_turret(struct Enemy* enemy, struct Game_State* game_state, flo if(yaw != 0.f) transform_rotate(enemy, &turn_axis, yaw, TS_LOCAL); + + /* Movement */ + float ticks = (float)platform_ticks_get(); + float pulsate_speed = 50.f; + vec3 translation = { 0.f }; + transform_get_absolute_position(enemy, &translation); + translation.y += sinf(TO_RADIANS(ticks)) * dt * pulsate_speed; + debug_vars_show_float("T", sinf(TO_RADIANS(ticks * dt * pulsate_speed))); + transform_set_position(enemy, &translation); + //transform_translate(enemy, &translation, TS_LOCAL); +} + +void enemy_update_ai_turret(struct Enemy* enemy, struct Game_State* game_state, float dt) +{ + } diff --git a/src/game/enemy.h b/src/game/enemy.h index 725ff92..c8cd081 100644 --- a/src/game/enemy.h +++ b/src/game/enemy.h @@ -8,6 +8,7 @@ struct Entity; struct Hashmap; void enemy_init(struct Enemy* enemy, int type); +void enemy_update_physics(struct Enemy* enemy, struct Scene* scene, float dt); void enemy_update(struct Enemy* enemy, struct Scene* scene, float dt); void enemy_reset(struct Enemy* enemy); struct Enemy* enemy_read(struct Parser_Object* object, const char* name, struct Entity* parent_entity); diff --git a/src/game/game.c b/src/game/game.c index 2125d3d..9e445e5 100755 --- a/src/game/game.c +++ b/src/game/game.c @@ -43,6 +43,7 @@ #define LEN(a) (sizeof(a)/sizeof(a)[0]) static void game_update(float dt, bool* window_should_close); +static void game_update_physics(float fixed_dt); static void game_post_update(float dt); static void game_render(void); static void game_debug(float dt); @@ -66,18 +67,19 @@ bool game_init(struct Window* window, struct Hashmap* cvars) } else { - game_state->window = window; - game_state->cvars = cvars; - game_state->is_initialized = false; - game_state->game_mode = GAME_MODE_GAME; - game_state->renderer = calloc(1, sizeof(*game_state->renderer)); - game_state->scene = calloc(1, sizeof(*game_state->scene)); - game_state->console = calloc(1, sizeof(*game_state->console)); - game_state->editor = calloc(1, sizeof(*game_state->editor)); - game_state->gui = calloc(1, sizeof(*game_state->gui)); - game_state->event_manager = calloc(1, sizeof(*game_state->event_manager)); - game_state->sound = calloc(1, sizeof(*game_state->sound)); - game_state->debug_vars = calloc(1, sizeof(*game_state->debug_vars)); + game_state->window = window; + game_state->cvars = cvars; + game_state->is_initialized = false; + game_state->fixed_delta_time = 1.f / 60.f; + game_state->game_mode = GAME_MODE_GAME; + game_state->renderer = calloc(1, sizeof(*game_state->renderer)); + game_state->scene = calloc(1, sizeof(*game_state->scene)); + game_state->console = calloc(1, sizeof(*game_state->console)); + game_state->editor = calloc(1, sizeof(*game_state->editor)); + game_state->gui = calloc(1, sizeof(*game_state->gui)); + game_state->event_manager = calloc(1, sizeof(*game_state->event_manager)); + game_state->sound = calloc(1, sizeof(*game_state->sound)); + game_state->debug_vars = calloc(1, sizeof(*game_state->debug_vars)); log_message_callback_set(game_on_log_message); log_warning_callback_set(game_on_log_warning); @@ -512,21 +514,31 @@ void game_debug(float dt) bool game_run(void) { - uint32 last_time = platform_ticks_get(); + uint32 previous_time = platform_ticks_get(); + float accumulator = 0.f; bool should_window_close = false; + while(!should_window_close) { - 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 */ + uint32 current_time = platform_ticks_get(); + float frame_time = (float)(current_time - previous_time) / 1000.f; + previous_time = current_time; + if(frame_time > MAX_FRAME_TIME) frame_time = (1.f / 60.f); /* To deal with resuming from breakpoint we artificially set delta time */ + accumulator += frame_time; gui_input_begin(game_state->gui); event_manager_poll_events(game_state->event_manager, &should_window_close); gui_input_end(game_state->gui); + + struct Game_State* game_state = game_state_get(); + while(accumulator >= game_state->fixed_delta_time) + { + game_update_physics(game_state->fixed_delta_time); + accumulator -= game_state->fixed_delta_time; + } - game_update(delta_time, &should_window_close); - game_post_update(delta_time); + game_update(frame_time, &should_window_close); + game_post_update(frame_time); game_render(); window_swap_buffers(game_state->window); } @@ -1983,3 +1995,9 @@ void game_on_log_error(const char* context, const char* error_message, va_list a { console_on_log_error(game_state->console, context, error_message, args); } + +void game_update_physics(float fixed_dt) +{ + struct Game_State* game_state = game_state_get(); + scene_update_physics(game_state->scene, fixed_dt); +} diff --git a/src/game/game.h b/src/game/game.h index 7592b22..ab148a1 100755 --- a/src/game/game.h +++ b/src/game/game.h @@ -25,6 +25,7 @@ struct Game_State { bool is_initialized; int game_mode; + float fixed_delta_time; struct Window* window; struct Renderer* renderer; struct Scene* scene; diff --git a/src/game/player.c b/src/game/player.c index 75afff9..51c750a 100755 --- a/src/game/player.c +++ b/src/game/player.c @@ -80,7 +80,7 @@ void player_destroy(struct Player* player) player->base.flags = EF_NONE; } -void player_update(struct Player* player, struct Scene* scene, float dt) +void player_update_physics(struct Player* player, struct Scene* scene, float fixed_dt) { /* Look around */ float total_pitch = quat_get_pitch(&player->camera->base.transform.rotation); @@ -103,8 +103,8 @@ void player_update(struct Player* player, struct Scene* scene, float dt) cursor_yaw = cursor_pitch = 0; } - pitch = -cursor_pitch * player->turn_speed * dt; - yaw = cursor_yaw * player->turn_speed * dt; + pitch = -cursor_pitch * player->turn_speed * fixed_dt; + yaw = cursor_yaw * player->turn_speed * fixed_dt; total_pitch += pitch; if(total_pitch >= max_pitch) @@ -221,9 +221,9 @@ void player_update(struct Player* player, struct Scene* scene, float dt) vec3 translation = {0.f, 0.f, 0.f}; vec3_assign(&translation, &move_direction); - translation.x *= move_speed * dt; - translation.z *= move_speed * dt; - translation.y = move_speed_vertical * dt; + translation.x *= move_speed * fixed_dt; + translation.z *= move_speed * fixed_dt; + translation.y = move_speed_vertical * fixed_dt; transform_translate(player, &translation, TS_WORLD); debug_vars_show_bool("Grounded", player->grounded); diff --git a/src/game/player.h b/src/game/player.h index e51746e..19a0b14 100755 --- a/src/game/player.h +++ b/src/game/player.h @@ -6,6 +6,6 @@ struct Scene; void player_init(struct Player* player, struct Scene* scene); void player_destroy(struct Player* player); -void player_update(struct Player* player, struct Scene* scene, float dt); +void player_update_physics(struct Player* player, struct Scene* scene, float dt); #endif diff --git a/src/game/scene.c b/src/game/scene.c index 0c89825..694f147 100755 --- a/src/game/scene.c +++ b/src/game/scene.c @@ -366,7 +366,6 @@ void scene_update(struct Scene* scene, float dt) { if(game_state_get()->game_mode == GAME_MODE_GAME) { - player_update(&scene->player, scene, dt); for(int i = 0; i < MAX_SCENE_ENEMIES; i++) { if(scene->enemies[i].base.flags & EF_ACTIVE) @@ -375,6 +374,19 @@ void scene_update(struct Scene* scene, float dt) } } +void scene_update_physics(struct Scene* scene, float fixed_dt) +{ + if(game_state_get()->game_mode == GAME_MODE_GAME) + { + player_update_physics(&scene->player, scene, fixed_dt); + for(int i = 0; i < MAX_SCENE_ENEMIES; i++) + { + if(scene->enemies[i].base.flags & EF_ACTIVE) + enemy_update_physics(&scene->enemies[i], scene, fixed_dt); + } + } +} + void scene_post_update(struct Scene* scene) { assert(scene); diff --git a/src/game/scene.h b/src/game/scene.h index 435b337..725250d 100755 --- a/src/game/scene.h +++ b/src/game/scene.h @@ -10,17 +10,17 @@ struct Raycast_Result; struct Scene { - char filename[MAX_FILENAME_LEN]; - struct Entity root_entity; - struct Player player; - struct Entity entities[MAX_SCENE_ENTITIES]; - struct Static_Mesh static_meshes[MAX_SCENE_STATIC_MESHES]; - struct Camera cameras[MAX_SCENE_CAMERAS]; - struct Light lights[MAX_SCENE_LIGHTS]; - struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES]; - struct Enemy enemies[MAX_SCENE_ENEMIES]; - char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN]; - int active_camera_index; + char filename[MAX_FILENAME_LEN]; + struct Entity root_entity; + struct Player player; + struct Entity entities[MAX_SCENE_ENTITIES]; + struct Static_Mesh static_meshes[MAX_SCENE_STATIC_MESHES]; + struct Camera cameras[MAX_SCENE_CAMERAS]; + struct Light lights[MAX_SCENE_LIGHTS]; + struct Sound_Source sound_sources[MAX_SCENE_SOUND_SOURCES]; + struct Enemy enemies[MAX_SCENE_ENEMIES]; + char entity_archetypes[MAX_SCENE_ENTITY_ARCHETYPES][MAX_FILENAME_LEN]; + int active_camera_index; }; void scene_init(struct Scene* scene); @@ -28,6 +28,7 @@ bool scene_load(struct Scene* scene, const char* filename, int directory_type); bool scene_save(struct Scene* scene, const char* filename, int directory_type); void scene_destroy(struct Scene* scene); void scene_update(struct Scene* scene, float dt); +void scene_update_physics(struct Scene* scene, float fixed_dt); void scene_post_update(struct Scene* scene); struct Entity* scene_entity_duplicate(struct Scene* scene, struct Entity* entity); diff --git a/src/system/config_vars.c b/src/system/config_vars.c index d9c97a1..c262224 100755 --- a/src/system/config_vars.c +++ b/src/system/config_vars.c @@ -31,9 +31,9 @@ void config_vars_init(struct Hashmap* cvars) hashmap_vec4_setf(cvars, "debug_draw_color", 0.8f, 0.4f, 0.1f, 1.f); hashmap_float_set(cvars, "player_move_speed", 20.f); hashmap_float_set(cvars, "player_move_speed_multiplier", 1.75f); - hashmap_float_set(cvars, "player_turn_speed", 45.f); + hashmap_float_set(cvars, "player_turn_speed", 25.f); hashmap_float_set(cvars, "player_jump_speed", 50.f); - hashmap_float_set(cvars, "player_gravity", -0.25f); + hashmap_float_set(cvars, "player_gravity", -2.5f); hashmap_float_set(cvars, "player_min_forward_distance", 5.f); hashmap_float_set(cvars, "player_min_downward_distance", 2.f); } diff --git a/todo.txt b/todo.txt index 07beca6..07df487 100644 --- a/todo.txt +++ b/todo.txt @@ -1,4 +1,6 @@ Todo: + - Make movement framerate independent + - Implement displaying bounding boxes as a command which should work in game mode - Enemy ray casting and shooting - Player shooting - Player jump cooldown, don't allow jump until a certian time interval has passed, even if we're grounded @@ -13,6 +15,7 @@ Todo: - Main Menu Scene ? Split this todo into gameplay/engine todos - Check if running in a lower frame rate affects movement + - Remove ODE completely ? Write entity flags to scene file or when saving entity to file? ? Add scene init/de-init function hashmap that maps a function that should be called when scene is loaded and unloaded. Save this to file for every scene or map functions based on the name of the scene? - Release mouse when window loses focus and limit fps @@ -405,4 +408,5 @@ Done: * 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. - * Added Scene reload command \ No newline at end of file + * Added Scene reload command + * Introduced fixed time step interval which can be configured and be used for movement and other physics related updates \ No newline at end of file