Initial commit

This is working repository now. I had to clean this up due to
my f_ups, that made this simple repo around 200MB large.

Signed-off-by: Piotr Krygier <piotrkrygier@everyonecancode@xyz>
This commit is contained in:
Piotr Krygier
2022-06-28 09:54:41 +02:00
committed by Piotr Krygier
commit 493afb05e6
56 changed files with 5574 additions and 0 deletions
+48
View File
@@ -0,0 +1,48 @@
/**
* @file commons.h
* @author Piotr Krygier (everyonecancode@gmail.com)
* @brief Common functionality for all modules
* @version 0.1
* @date 2023-10-05
*
* @copyright Copyright (c) 2023
*
*/
#ifndef COMMONS_H
#define COMMONS_H
#include <SDL3/SDL_log.h>
#include <stdint.h>
#include <stdlib.h>
/**
* @brief Macro for allocating memory and checking it on the same line
*
*/
#ifndef RSE_TEST
#define rse_malloc(ptr, size) \
ptr = malloc(size); \
if (ptr == NULL) { \
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Memory allocation failure"); \
exit(1); \
}
#define rse_free(ptr) free(ptr);
#define rse_memcpy(dst, src, size) memcpy(dst, src, size);
#define rse_memset(ptr, value, size) memset(ptr, value, size);
#else
#define rse_malloc(ptr, size) ptr = NULL;
#define rse_free(ptr)
#define rse_memcpy(dst, src, size)
#define rse_memset
#endif
/**
* @brief Error type for RSE
*
*/
typedef uint32_t rse_err_t;
#endif /* COMMONS_H */
+26
View File
@@ -0,0 +1,26 @@
/**
* @file entity.h
* @author Piotr Krygier (piotrkrygier@everyonencancode.xyz)
* @brief Entity from ECS
* @version 0.1
* @date 2025-09-25
*
* @copyright Copyright (c) 2025
*
*/
#ifndef ENTITY_H
#define ENTITY_H
#include <stdint.h>
#define ENTITY_MAX_COUNT 65535
#define COMPONENT_MAX_COUNT 65535
typedef uint32_t entity_t;
entity_t entity_create(void);
void entity_free(entity_t entity);
#endif // !ENTITY_H
+34
View File
@@ -0,0 +1,34 @@
/**
* @file errors_common.h
* @author Piotr Krygier (everyonecancode@gmail.com)
* @brief Common error messages, that can appear in any module
* @version 0.1
* @date 2023-10-05
*
* @copyright Copyright (c) 2023
*
*/
#ifndef ERRORS_COMMON_H
/* Macro for checking status of function execution in initVulkan. Created to avoid writing boilerplate code */
#define STATUS_CHECK(FUNC) \
status = FUNC; \
if (RSE_ERROR_NO_ERROR != status) { \
return status; \
}
#define RSE_COMMON_MODULE_ID 0x0100U
enum common_error_t
{
RSE_ERROR_NO_ERROR = RSE_COMMON_MODULE_ID,
RSE_ERROR_NULL_POINTER,
RSE_ERROR_ALREADY_INITIALIZED,
RSE_COMMON_ERROR_MALLLOC_FAILED,
RSE_ERROR_INVALID_PARAM,
RSE_ERROR_INTERNAL_ERROR,
};
#define ERRORS_COMMON_H
#endif /* ERRORS_COMMON_H */
+26
View File
@@ -0,0 +1,26 @@
#ifndef FILE_UTILS_H
#define FILE_UTILS_H
#include <stddef.h>
#include "commons.h"
#define MAX_PATH_LENGTH (4096U)
/**
* @brief Reads file and puts its content into char buffer. If NULL is provided as buffer, than just bytes_count
* is set
*
* @param file_path Path to file
* @param bytes_count Returned bytes count
* @param buffer Returned filled buffer
*/
rse_err_t file_read(const char* file_path, size_t* bytes_count, char* buffer);
rse_err_t file_write(const char* file_name, size_t bytes_count, char* buffer);
rse_err_t file_load_pixels(const char* file_name, unsigned char* buffer, size_t* buffer_size, int* width, int* height);
rse_err_t file_append_full_path(char* file_path, size_t max_buffer_size);
#endif /* FILE_UTILS_H */
+23
View File
@@ -0,0 +1,23 @@
rse_utilities_srcs = [
'src/file_utils.c'
]
cc = meson.get_compiler('c')
sdl3_dep = dependency('sdl3',
version : '>=3.4.0')
stb_dep = dependency('stb',
version : '>=2.30.0')
m_dep = cc.find_library('m')
rse_utilities_lib = shared_library(
'rse_utilities',
rse_utilities_srcs,
include_directories : ['.'],
dependencies : [
sdl3_dep,
stb_dep,
m_dep,
],
install : true
)
+34
View File
@@ -0,0 +1,34 @@
/**
* @file entity.c
* @author Piotr Krygier (piotrkrygier@everyonencancode.xyz)
* @brief Entity from ECS
* @version 0.1
* @date 2025-09-25
*
* @copyright Copyright (c) 2025
*
*/
#include "utilities/entity.h"
#include <stdint.h>
static entity_t g_free_list[ENTITY_MAX_COUNT];
static uint32_t g_free_count = 0U;
static uint32_t g_living_count = 0U;
entity_t entity_create(void)
{
entity_t e = 0U;
if (g_free_count > 0) {
e = g_free_list[g_free_count--];
} else {
e = g_living_count++;
}
return e;
}
void entity_free(entity_t entity)
{
g_free_list[g_free_count++] = entity;
}
+242
View File
@@ -0,0 +1,242 @@
#include "file_utils.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "SDL3/SDL_log.h"
#include "commons.h"
#include "errors_common.h"
#define STB_IMAGE_IMPLEMENTATION
#include "stb/stb_image.h"
#ifdef __linux__
#include <limits.h>
#include <unistd.h>
#endif /* ifndef __linux */
static rse_err_t get_curr_path(char* path)
{
char* last_sep = NULL;
char* tmp_path = NULL;
size_t path_length = 0U;
ssize_t binary_path_length = 0U;
size_t directory_path_length = 0U;
if (NULL == path) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to get path. Provided pointer is NULL");
return RSE_ERROR_NULL_POINTER;
}
path_length = strlen(path);
if (path_length > MAX_PATH_LENGTH) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Max path length cannot be 0");
return RSE_ERROR_INVALID_PARAM;
}
rse_memset(path, '\0', path_length);
rse_malloc(tmp_path, MAX_PATH_LENGTH);
#ifdef __linux__
binary_path_length = readlink("/proc/self/exe", tmp_path, MAX_PATH_LENGTH - 1);
if (binary_path_length == -1) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to read current binary path");
return RSE_ERROR_NULL_POINTER;
}
tmp_path[binary_path_length] = '\0';
#endif /* ifdef __linux__ */
last_sep = strrchr(tmp_path, '/') + 1;
if (NULL == last_sep) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to get last separator in path");
return RSE_ERROR_INTERNAL_ERROR;
}
directory_path_length = last_sep - tmp_path;
if (directory_path_length > MAX_PATH_LENGTH) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Provided path buffer is too small");
return RSE_ERROR_INTERNAL_ERROR;
}
strncpy(path, tmp_path, directory_path_length);
free(tmp_path);
return RSE_ERROR_NO_ERROR;
}
rse_err_t file_append_full_path(char* file_path, size_t max_buffer_size)
{
rse_err_t ret = RSE_ERROR_NO_ERROR;
size_t curr_path_length = 0U;
size_t file_path_length = 0U;
char curr_path[MAX_PATH_LENGTH] = {0};
char temp_path[MAX_PATH_LENGTH] = {0};
file_path_length = strlen(file_path);
if (file_path_length > max_buffer_size) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided max_buffer_size is smaller than the file path itself");
return RSE_ERROR_INVALID_PARAM;
}
if ((ret = get_curr_path(curr_path)) != RSE_ERROR_NO_ERROR) {
return ret;
}
curr_path_length = strlen(curr_path);
if ((curr_path_length + file_path_length) > max_buffer_size) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Provided max_buffer_size is to small to hold concatenated file path. %ld vs %ld",
(curr_path_length + file_path_length),
max_buffer_size);
}
strncpy(temp_path, file_path, MAX_PATH_LENGTH);
memset(file_path, 0, max_buffer_size);
strncat(file_path, curr_path, max_buffer_size);
strncat(file_path, temp_path, max_buffer_size);
return ret;
}
rse_err_t file_load_pixels(const char* file_name, unsigned char* buffer, size_t* buffer_size, int* width, int* height)
{
int channels = 0;
stbi_uc* pixel_buffer = NULL;
size_t image_buffer_size = 0U;
rse_err_t ret = RSE_ERROR_NO_ERROR;
char real_path[MAX_PATH_LENGTH] = {0};
if (buffer_size == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL buffer_size");
return RSE_ERROR_INVALID_PARAM;
}
if (width == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL width");
return RSE_ERROR_INVALID_PARAM;
}
if (height == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Provided NULL height");
return RSE_ERROR_INVALID_PARAM;
}
strncpy(real_path, file_name, MAX_PATH_LENGTH);
if ((ret = file_append_full_path(real_path, MAX_PATH_LENGTH)) != RSE_ERROR_NO_ERROR) {
return ret;
}
pixel_buffer = stbi_load(real_path, width, height, &channels, STBI_rgb_alpha);
if (pixel_buffer == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to load texture from file: %s", file_name);
return RSE_ERROR_INTERNAL_ERROR;
}
image_buffer_size = *width * *height * 4; // TODO: "4" is very hardcoded value. Change this
if ((buffer != NULL) && (image_buffer_size > *buffer_size)) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION,
"Provided buffer is to small to hold pixel data. %ld vs %ld",
*buffer_size,
image_buffer_size);
ret = RSE_ERROR_INTERNAL_ERROR;
goto image_free;
}
*buffer_size = image_buffer_size;
if (buffer != NULL) {
memset(buffer, 0, *buffer_size);
memcpy(buffer, pixel_buffer, *buffer_size);
}
image_free:
stbi_image_free(pixel_buffer);
return ret;
}
rse_err_t file_read(const char* file_name, size_t* bytes_count, char* buffer)
{
rse_err_t ret = RSE_ERROR_NO_ERROR;
FILE* file = NULL;
char real_path[MAX_PATH_LENGTH] = {0};
strncpy(real_path, file_name, MAX_PATH_LENGTH);
if ((ret = file_append_full_path(real_path, MAX_PATH_LENGTH)) != RSE_ERROR_NO_ERROR) {
return ret;
}
file = fopen(real_path, "rb");
if (file == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Failed to open file for read: %s", real_path);
ret = RSE_ERROR_INTERNAL_ERROR;
goto file_close;
}
fseek(file, 0, SEEK_END);
*bytes_count = ftell(file);
fseek(file, 0, SEEK_SET);
if (buffer == NULL) {
goto file_close;
}
fread(buffer, *bytes_count, 1, file);
if (ferror(file) != 0) {
perror("Error reading file");
ret = RSE_ERROR_INTERNAL_ERROR;
}
file_close:
fclose(file);
return ret;
}
rse_err_t file_write(const char* file_name, size_t bytes_count, char* buffer)
{
FILE* file = NULL;
char real_path[MAX_PATH_LENGTH] = {0};
rse_err_t ret = RSE_ERROR_NO_ERROR;
strncpy(real_path, file_name, MAX_PATH_LENGTH);
if ((ret = file_append_full_path(real_path, MAX_PATH_LENGTH)) != RSE_ERROR_NO_ERROR) {
return ret;
}
file = fopen(real_path, "wb");
if (file == NULL) {
SDL_LogCritical(SDL_LOG_CATEGORY_GPU, "Failed to open file for write: %s", file_name);
return RSE_ERROR_INTERNAL_ERROR;
}
fwrite(buffer, bytes_count, 1, file);
fclose(file);
return RSE_ERROR_NO_ERROR;
}
+45
View File
@@ -0,0 +1,45 @@
/**
* @file stack.h
* @author Piotr Krygier (everyonecancode@gmail.com)
* @brief
* @version 0.1
* @date 2024-05-01
*
* @copyright Copyright (c) 2024
*
*/
#ifndef STACK_H
#define STACK_H
#define RSE_STACK_DEFINE(name, type, size) \
struct name { \
type data[size]; \
int top; \
}
#define RSE_STACK_PUSH(stack, value) \
stack.data[++stack.top] = value
#define RSE_STACK_POP(stack) \
stack.data[stack.top--]
#define RSE_STACK_TOP(stack) \
stack.data[stack.top]
#define RSE_STACK_IS_EMPTY(stack) \
(stack.top == -1)
#define RSE_STACK_IS_FULL(stack, size) \
(stack.top == size - 1)
#define RSE_STACK_INIT(stack) \
(stack.top = -1)
#define RSE_STACK_SIZE(stack) \
(stack.top + 1)
#define RSE_STACK_CLEAR(stack) \
(stack.top = -1)
#endif // STACK_H
+94
View File
@@ -0,0 +1,94 @@
/**
* @file vector.h
* @author Piotr Krygier (piotrkrygier@everyonecancode.xyz)
* @brief C implementation of a vector, dynamic array
* @version 0.1
* @date 2024-09-18
*
* @copyright Copyright (c) 2025
*
*/
#ifndef VECTOR_H
#define VECTOR_H
#include <stddef.h>
#include <stdlib.h>
#include "SDL3/SDL_log.h"
#include "utilities/commons.h"
#include "utilities/errors_common.h"
#define VECTOR_CHUNK_SIZE (64U)
#define RSE_VECTOR_DEFINE(name, type) \
struct name \
{ \
type* data; \
size_t size; \
size_t _allocated_size; \
}
#define RSE_VECTOR_PUSH_BACK(vector, value) \
{ \
if (vector.data == NULL) { \
vector.size = 0; \
vector._allocated_size = VECTOR_CHUNK_SIZE; \
rse_malloc(vector.data, sizeof(*vector.data) * VECTOR_CHUNK_SIZE); \
} \
if (vector._allocated_size == vector.size) { \
__typeof__((vector.data)) tmp_buffer = NULL; \
rse_malloc(tmp_buffer, sizeof(*vector.data) * vector.size); \
rse_memcpy(tmp_buffer, vector.data, sizeof(*vector.data) * vector.size); \
rse_free(vector.data); \
vector._allocated_size += VECTOR_CHUNK_SIZE; \
rse_malloc(vector.data, vector._allocated_size * vector.size); \
rse_memcpy(vector.data, tmp_buffer, sizeof(*vector.data) * vector.size); \
rse_free(tmp_buffer); \
} \
vector.data[vector.size] = value; \
vector.size++; \
}
#define RSE_VECTOR_INSERT_INTO(vector, idx, data) \
{ \
if (vector._allocated_size == vector.size) { \
__typeof__((vector.data)) tmp_buffer = NULL; \
rse_malloc(tmp_buffer, sizeof(*vector.data) * vector.size); \
rse_memcpy(tmp_buffer, vector.data, sizeof(*vector.data) * vector.size); \
if (vector.data != NULL) { \
rse_free(vector.data); \
} \
vector._allocated_size += VECTOR_CHUNK_SIZE; \
rse_malloc(vector.data, vector._allocated_size * vector.size); \
rse_memcpy(vector.data, tmp_buffer, sizeof(*vector.data) * vector.size); \
rse_free(tmp_buffer); \
} \
vector->size++; \
rse_memcpy(&vector->data[idx + 1], &vector->data[idx], sizeof(*vector->data) * (vector->size - idx)); \
vector->data[idx] = data; \
}
#define RSE_VECTOR_REMOVE_ELEMENT(vector, idx) \
{ \
if (vector->size <= idx) { \
SDL_LogCritical(SDL_LOG_CATEGORY_APPLICATION, "Vector index out of bounds"); \
exit(EXIT_FAILURE); \
} \
if (vector->size == 1) { \
rse_free(vector->data); \
vector->_allocated_size = 0; \
} else { \
rse_memcpy(&vector->data[idx], &vector->data[idx + 1], sizeof(vector->data) * (vector->size - idx - 1)); \
} \
vector->size--; \
}
struct vector_t
{
void* data;
size_t size;
size_t _data_size;
size_t _allocated_size;
};
#endif // !VECTOR_H