Skip to content

Commit

Permalink
First implementation of a ring buffer (FIFO, queue-like) DS
Browse files Browse the repository at this point in the history
  • Loading branch information
iWas-Coder committed Apr 26, 2024
1 parent 6f8d62e commit 73df131
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 2 deletions.
43 changes: 43 additions & 0 deletions include/sk_rngbuf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* GNU Sparky --- A 5v5 character-based libre tactical shooter
* Copyright (C) 2024 Wasym A. Alonso
*
* This file is part of Sparky.
*
* Sparky is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sparky is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sparky. If not, see <http://www.gnu.org/licenses/>.
*/


#pragma once

#include <sk_defines.h>

typedef struct {
u32 capacity;
u32 element_size;
u32 curr_len;
i32 head;
i32 tail;
void *data;
} sk_rngbuf;

sk_rngbuf sk_rngbuf_create(u32 capacity, u32 element_size);

void sk_rngbuf_destroy(sk_rngbuf *rb);

u8 sk_rngbuf_push(sk_rngbuf *rb, void *value);

u8 sk_rngbuf_pop(sk_rngbuf *rb, void *out_value);

u8 sk_rngbuf_peek(const sk_rngbuf *rb, void *out_value);
2 changes: 2 additions & 0 deletions include/sk_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <sk_scene.h>
#include <sk_lobby.h>
#include <sk_config.h>
#include <sk_rngbuf.h>

#define SK_STATE_MAX_LOBBIES 256

Expand All @@ -44,6 +45,7 @@ typedef struct sk_state {
struct {
sk_map map;
sk_player player;
sk_rngbuf shots_rb;
};
};
} sk_state;
Expand Down
88 changes: 88 additions & 0 deletions src/sk_rngbuf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* GNU Sparky --- A 5v5 character-based libre tactical shooter
* Copyright (C) 2024 Wasym A. Alonso
*
* This file is part of Sparky.
*
* Sparky is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Sparky is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Sparky. If not, see <http://www.gnu.org/licenses/>.
*/


#include <stdlib.h>
#include <string.h>
#include <sk_log.h>
#include <sk_rngbuf.h>

sk_rngbuf sk_rngbuf_create(u32 capacity, u32 element_size) {
return (sk_rngbuf) {
.capacity = capacity,
.element_size = element_size,
.curr_len = 0,
.head = 0,
.tail = -1,
.data = malloc(capacity * element_size)
};
}

void sk_rngbuf_destroy(sk_rngbuf *rb) {
if (!rb) {
SK_LOG_WARN("sk_rngbuf_destroy :: `rb` is not a valid pointer, skipping destruction");
return;
}
*rb = (sk_rngbuf) {0};
rb = 0;
}

u8 sk_rngbuf_push(sk_rngbuf *rb, void *value) {
if (!rb || !value) {
SK_LOG_ERROR("sk_rngbuf_push :: `rb` and `value` need to be valid pointers");
return 0;
}
if (rb->curr_len == rb->capacity) {
SK_LOG_ERROR("sk_rngbuf_push :: ring buffer is full (%p)", rb);
return 0;
}
rb->tail = (rb->tail + 1) % rb->capacity;
memcpy((void *) ((i32 *) rb->data + (rb->tail * rb->element_size)), value, rb->element_size);
++rb->curr_len;
return 1;
}

u8 sk_rngbuf_pop(sk_rngbuf *rb, void *out_value) {
if (!rb || !out_value) {
SK_LOG_ERROR("sk_rngbuf_pop :: `rb` and `out_value` need to be valid pointers");
return 0;
}
if (rb->curr_len == 0) {
SK_LOG_ERROR("sk_rngbuf_pop :: ring buffer is empty (%p)", rb);
return 0;
}
memcpy(out_value, (void *) ((i32 *) rb->data + (rb->head * rb->element_size)), rb->element_size);
rb->head = (rb->head + 1) % rb->capacity;
--rb->curr_len;
return 1;
}

u8 sk_rngbuf_peek(const sk_rngbuf *rb, void *out_value) {
if (!rb || !out_value) {
SK_LOG_ERROR("sk_rngbuf_peek :: `rb` and `out_value` need to be valid pointers");
return 0;
}
if (rb->curr_len == 0) {
SK_LOG_ERROR("sk_rngbuf_peek :: ring buffer is empty (%p)", rb);
return 0;
}
memcpy(out_value, (void *) ((i32 *) rb->data + (rb->head * rb->element_size)), rb->element_size);
return 1;
}
3 changes: 2 additions & 1 deletion src/sk_scene_gameplay.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@ void sk_scene_gameplay_update(sk_state *s) {
if (IsMouseButtonPressed(s->config.controls.shoot)) {
sk_shot shot = {0};
if (!sk_weapon_shoot(&s->player.weapon, s->player.id, &s->player.camera, &shot)) return;
SK_LOG_DEBUG("sk_shot :: {");
SK_LOG_DEBUG("sk_shot = {");
SK_LOG_DEBUG(" .bullet = {");
SK_LOG_DEBUG(" .position = (%f, %f, %f),", shot.bullet.position.x, shot.bullet.position.y, shot.bullet.position.z);
SK_LOG_DEBUG(" .direction = (%f, %f, %f)", shot.bullet.direction.x, shot.bullet.direction.y, shot.bullet.direction.z);
SK_LOG_DEBUG(" },");
SK_LOG_DEBUG(" .shooter_id = %s,", shot.shooter_id.value);
SK_LOG_DEBUG(" .weapon_kind = %d", shot.weapon_kind);
SK_LOG_DEBUG("};");
sk_rngbuf_push(&s->shots_rb, &shot);
}
if (IsKeyPressed(s->config.controls.reload)) sk_weapon_reload(&s->player.weapon);
sk_player_jump(&s->player, &s->config);
Expand Down
4 changes: 3 additions & 1 deletion src/sk_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,15 @@ sk_state sk_state_create_offline(void) {
.curr_scene = sk_scene_create(SK_SCENE_KIND_INTRO),
.menu_music = LoadMusicStream(TextFormat(MUSIC_PATH_PLACEHOLDER, "menu")),
.map = sk_map_create(SK_MAP_CAMPING),
.player = sk_player_create(0, 0, SK_PLAYER_KIND_AGENT69, &config)
.player = sk_player_create(0, 0, SK_PLAYER_KIND_AGENT69, &config),
.shots_rb = sk_rngbuf_create(2 << 14, sizeof(sk_shot))
};
SetWindowIcon(s.win_icon);
return s;
}

void sk_state_destroy_offline(sk_state *s) {
sk_rngbuf_destroy(&s->shots_rb);
sk_player_destroy(&s->player);
sk_map_destroy(&s->map);
UnloadMusicStream(s->menu_music);
Expand Down

0 comments on commit 73df131

Please sign in to comment.