Input is more responsive. Fixed bug with creating session-players.

This commit is contained in:
2025-12-11 17:29:42 +01:00
parent cdbd0b2c43
commit 1d414cc392
10 changed files with 302 additions and 77 deletions

View File

@@ -6,7 +6,9 @@
#include <stdio.h>
#include <string.h>
#include "raylib.h"
#include "shared/squeue.h"
#define INPUT_QUEUE_CAPACITY 8
Game_Session *g_current_session = NULL;
@@ -28,11 +30,23 @@ void game_session_create(bool is_singleplayer, bool is_host, Game_Session_Settin
session->players = (Game_Session_Player *)calloc(session->settings.max_players, sizeof(Game_Session_Player));
session->players_prev = (Game_Session_Player *)calloc(session->settings.max_players, sizeof(Game_Session_Player));
for(uint16_t i = 0; i < session->settings.max_players; i++) {
assert(squeue_init(
&session->players[i].input_queue,
INPUT_QUEUE_CAPACITY,
sizeof(Simulation_Game_Input)
));
// Intentionally not initializing players_prev's input_queue.
}
{ // TEMP
session->local_player_index = 0;
assert(game_session_create_player(session, &session->local_player_index));
}
session->simulation_accumulator = 0.0f;
g_current_session = session;
printf("New Game_Session created.\n");
@@ -47,6 +61,12 @@ void game_session_destroy() {
simulation_destroy_world(&session->simulation_world);
for(uint16_t i = 0; i < session->settings.max_players; i++) {
squeue_free(&session->players[i].input_queue);
// Intentionally not freeing players_prev's input_queue.
}
free(session->players);
session->players = NULL;
free(session->players_prev);
@@ -58,30 +78,23 @@ void game_session_destroy() {
void game_session_init_default_settings(bool is_singleplayer, Game_Session_Settings *out_settings) {
out_settings->seed = 1337; // TODO: SS - Randomize.
out_settings->tickrate = 10.0;
out_settings->level_width = 32;
out_settings->level_height = 32;
out_settings->max_players = is_singleplayer ? 1 : 8;
}
void game_session_tick(Game_Session *session) {
Game_Session_Player *local_session_player = game_session_get_local_player(session);
assert(local_session_player != NULL);
local_session_player->input = (Simulation_Game_Input) { // TODO: SS - Move this somewhere else, maybe.
.up = IsKeyDown(KEY_UP) || IsKeyDown(KEY_W),
.down = IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S),
.right = IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D),
.left = IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)
};
static void game_session_tick(Game_Session *session) {
// Update input.
for(uint16_t i = 0; i < session->settings.max_players; i++) {
Game_Session_Player *session_player = &session->players[i];
{ // TODO: SS - Use delta-time to accumulate time. Tick the simulation in a constant tick-rate.
// Update input.
for(uint16_t i = 0; i < session->settings.max_players; i++) {
{ // Check if any players have joined/disconnected by comparing against the previous session_player.
Game_Session_Player *session_player_prev = &session->players_prev[i];
Game_Session_Player *session_player = &session->players[i];
bool was_active = session_player_prev->active;
bool is_active = session_player->active;
if (!was_active && is_active) {
simulation_world_enqueue_command(&session->simulation_world, (Simulation_Command) {
.type = Simulation_Command_Type_Add_Player,
@@ -93,31 +106,57 @@ void game_session_tick(Game_Session *session) {
.player_id = i
});
}
}
if(!session_player->active) {
continue;
}
if(!session_player->active) {
continue;
}
Simulation_Game_Input input = {0};
if(squeue_pop(&session_player->input_queue, &input)) {
// We got an input.
simulation_world_enqueue_command(&session->simulation_world, (Simulation_Command) {
.type = Simulation_Command_Type_Set_Player_Input,
.player_id = i,
.player_input = session_player->input,
.player_input = input,
});
}
// Tick.
simulation_world_tick(&session->simulation_world);
// Copy 'players' from session to 'players_prev'.
memcpy(session->players_prev, session->players, sizeof(Game_Session_Player) * session->settings.max_players);
}
// Tick.
simulation_world_tick(&session->simulation_world);
// Copy 'players' from session to 'players_prev'.
memcpy(session->players_prev, session->players, sizeof(Game_Session_Player) * session->settings.max_players);
}
void game_session_update(Game_Session *session, const double delta_time) {
session->simulation_accumulator += delta_time;
const double sim_dt = 1.0 / session->settings.tickrate;
while (session->simulation_accumulator >= sim_dt) {
game_session_tick(session);
session->simulation_accumulator -= sim_dt;
}
}
static Game_Session_Player *game_session_get_player_from_id(Game_Session *session, uint16_t player_index) {
assert(session != NULL);
if(player_index >= session->settings.max_players) {
return NULL;
}
return &session->players[player_index];
}
Game_Session_Player *game_session_get_local_player(Game_Session *session) {
assert(session != NULL);
return &session->players[session->local_player_index];
return game_session_get_player_from_id(session, session->local_player_index);
}
bool game_session_create_player(Game_Session *session, uint16_t *out_player_index) {
assert(session != NULL);
@@ -126,8 +165,10 @@ bool game_session_create_player(Game_Session *session, uint16_t *out_player_inde
Game_Session_Player *session_player = &session->players[i];
assert(session_player != NULL);
if(!session_player->active) {
session_player->active = true;
found_index = i;
session_player->active = true;
break;
}
}
@@ -148,4 +189,20 @@ void game_session_destroy_player(Game_Session *session, uint16_t player_index) {
assert(player->active);
memset(player, 0, sizeof(Game_Session_Player));
}
bool game_session_enqueue_player_input(Game_Session *session, uint16_t player_index, Simulation_Game_Input input) {
Game_Session_Player *player = game_session_get_player_from_id(session, player_index);
assert(player != NULL);
if(simulation_input_equal(player->most_recent_input, input)) {
return false;
}
if(!squeue_push(&player->input_queue, (void *)&input)) {
return false;
}
player->most_recent_input = input;
return true;
}