aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--README.md46
-rwxr-xr-xbuild.sh41
-rw-r--r--src/cyn_log.c73
-rw-r--r--src/cynic.c4
-rw-r--r--src/cynic.h63
-rw-r--r--src/cynic_internal.h31
-rw-r--r--src/un_list.c5
-rw-r--r--src/un_log.c71
-rw-r--r--src/un_memory.c7
-rw-r--r--src/un_strings.c38
-rw-r--r--src/ungrateful.c1
-rw-r--r--src/ungrateful.h33
-rw-r--r--tests/cyn/log.c5
-rw-r--r--tests/hello_world.c7
-rw-r--r--tests/un/allocs.c (renamed from tests/allocs.c)0
-rw-r--r--tests/un/lists.c (renamed from tests/lists.c)0
-rw-r--r--tests/un/memctl.c (renamed from tests/memctl.c)0
-rw-r--r--tests/un/strings.c (renamed from tests/strings.c)0
19 files changed, 284 insertions, 142 deletions
diff --git a/.gitignore b/.gitignore
index cd106a5..6b5f4d5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
bin/
obj/
lib/
+include/
diff --git a/README.md b/README.md
index 49c0470..a4d8a6e 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,7 @@
+# C99 libraries for gamedev and high quality programs.
+
# Ungrateful
-C99 standard libraries for game development.
# Note:
@@ -12,30 +13,51 @@ Only core features of C99 were used:
- long long;
- restrict keyword;
-# TODO:
+# Ungrateful
+
+Types, Strings, basic memory allocators (platform specific), and so on. Features:
+ Memory allocation;
+ Strings;
-- compressing algorithms;
-- Wide strings;
+- easing;
+- splines (qubic);
- vecs/ivec;
- matrix;
-- splines (qubic);
-- easing;
- Quaternions;
-- noise;
-- random;
-- sorting;
- raycasting;
-- sorting;
+- Random;
+- Noises;
+- Compression;
+- Wide strings, u16/u32;
+- Sorting;
+- Memory debugging;
+
+# Cynic
+
+Platform layer for abstracting basic functionality, like loading libraries or threading. Features:
-# Serf
- Library loading;
- Threading;
- non-blocking logging;
- Clocks;
- File IO;
- Configurations;
+- Internal compressable filesystem for speeding up IO work;
+
+# Visage
+
+Plugin based Input-Output layer (Audio, Keyboard, Video):
+
+- Plugin API for audio and video;
+- OpenGL;
+- OpenGLES;
+- DirectX;
+- Vulkan;
+
+# Disgrace
+Networking library:
-- Internal, compressable filesystem for speeding up IO work;
+- TCP;
+- UDP;
+- Packing;
diff --git a/build.sh b/build.sh
index 7984d22..d54c6b9 100755
--- a/build.sh
+++ b/build.sh
@@ -4,19 +4,22 @@ cc="gcc"
ld="gcc"
ar="ar"
+cflags="-std=c99 -fPIC -Wall -Wextra -g -Wno-error -pedantic"
+
proc=$(nproc)
+rm -rf ./include/
rm -rf ./lib/
rm -rf ./bin/
rm -rf ./obj/
+
+mkdir ./include/
mkdir ./lib/
mkdir ./bin/
mkdir ./obj/
echo "[BUILD] ungrateful.c"
-cflags="-std=c99 -fPIC -Wall -Wextra -g -Wno-error -pedantic"
-
$cc $cflags \
-c -o obj/ungrateful.o \
-g src/ungrateful.c
@@ -25,7 +28,21 @@ if [[ $? -ne 0 ]]; then
exit
fi
+echo "[BUILD] cynic.c"
+
+$cc $cflags -Isrc/ \
+ -c -o obj/cynic.o \
+ -g src/cynic.c
+
+if [[ $? -ne 0 ]]; then
+ exit
+fi
+
$ar rcs lib/libungrateful.a obj/ungrateful.o
+$ar rcs lib/libcynic.a obj/cynic.o
+
+cp src/ungrateful.h include/ungrateful.h
+cp src/cynic.h include/cynic.h
# ------------ Tests from here
#
@@ -35,13 +52,28 @@ fi
echo
-for test in tests/*.c; do
+for test in tests/un/*.c; do
+ fname=$(basename -- "$test")
+ fname="${fname%.*}"
+
+ echo "[BUILD] $test"
+
+ $cc $cflags -o bin/$fname $test -Llib/ -Iinclude/ -lungrateful &
+
+ if [[ $(jobs -r -p | wc -l) -ge $proc ]]; then
+ wait
+ fi
+done
+
+wait
+
+for test in tests/cyn/*.c; do
fname=$(basename -- "$test")
fname="${fname%.*}"
echo "[BUILD] $test"
- $cc $cflags -o bin/$fname $test -Llib/ -Isrc/ -lungrateful &
+ $cc $cflags -o bin/$fname $test -Llib/ -Iinclude/ -lungrateful -lcynic &
if [[ $(jobs -r -p | wc -l) -ge $proc ]]; then
wait
@@ -49,6 +81,7 @@ for test in tests/*.c; do
done
wait
+
echo
for case in bin/*; do
diff --git a/src/cyn_log.c b/src/cyn_log.c
new file mode 100644
index 0000000..d2d18f2
--- /dev/null
+++ b/src/cyn_log.c
@@ -0,0 +1,73 @@
+#include <stdio.h>
+
+Log_Level cyn_current_log_level = UN_LOG_INFO;
+
+void cyn_log_write_internal(Log_Level level, String format, va_list vaptr) {
+ Allocator talloc;
+ String output;
+
+ if (level < cyn_current_log_level) return;
+
+
+ talloc = un_allocator_get_temporary();
+
+ switch (level) {
+ case UN_LOG_TRACE:
+ output = UN_STR("[TRACE] ");
+ break;
+ case UN_LOG_DEBUG:
+ output = UN_STR("[DEBUG] ");
+ break;
+ case UN_LOG_INFO:
+ output = UN_STR("[INFO] ");
+ break;
+ case UN_LOG_WARNING:
+ output = UN_STR("[WARNING] ");
+ break;
+ case UN_LOG_ERROR:
+ output = UN_STR("[ERROR] ");
+ break;
+ case UN_LOG_FATAL:
+ output = UN_STR("[FATAL] ");
+ break;
+ default:
+ break;
+ }
+
+ output = un_string_concat(output, un_string_vformat(talloc, format, vaptr), talloc);
+
+ switch (level) {
+ case UN_LOG_RAW:
+ break;
+ case UN_LOG_FATAL: // @todo, logging should be part of Cynic.
+ default:
+ output = un_string_concat(output, UN_STR("\n"), talloc);
+ break;
+ }
+
+ fprintf(stderr, CSTR un_string_to_cstring(output, talloc));
+}
+
+extern void cyn_log_write_cstring(Log_Level level, u8 *format, ...) {
+ va_list vaptr;
+ String temp;
+
+ if (level < cyn_current_log_level) return;
+
+ temp.size = un_string_get_length(format);
+ temp.data = format;
+
+ va_start(vaptr, format);
+ cyn_log_write_internal(level, temp, vaptr);
+ va_end(vaptr);
+}
+
+void cyn_log_write(Log_Level level, String format, ...) {
+ va_list vaptr;
+
+ if (level < cyn_current_log_level) return;
+
+ va_start(vaptr, format);
+ cyn_log_write_internal(level, format, vaptr);
+ va_end(vaptr);
+}
diff --git a/src/cynic.c b/src/cynic.c
new file mode 100644
index 0000000..e0831e7
--- /dev/null
+++ b/src/cynic.c
@@ -0,0 +1,4 @@
+#include "cynic.h"
+#include "cynic_internal.h"
+
+#include "cyn_log.c"
diff --git a/src/cynic.h b/src/cynic.h
new file mode 100644
index 0000000..2aeb6f9
--- /dev/null
+++ b/src/cynic.h
@@ -0,0 +1,63 @@
+#if !defined(CYNIC_H)
+# define CYNIC_H
+/*
+ Cynic - platform layer for games and programs.
+
+ LICENSE:
+
+ Copyright (C) 2025 Bogdan Masyutin (bonmas14)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Bogdan Masyutin - bonmas14@gmail.com
+*/
+
+#include <ungrateful.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* ---- Library loading API ---- */
+/* ------- Threading API ------- */
+/* -------- Logging API -------- */
+
+typedef enum {
+ UN_LOG_TRACE,
+ UN_LOG_DEBUG,
+ UN_LOG_INFO,
+ UN_LOG_WARNING,
+ UN_LOG_ERROR,
+ UN_LOG_FATAL,
+ UN_LOG_RAW
+} Log_Level;
+
+extern Log_Level cyn_current_log_level;
+
+extern void cyn_log_write(Log_Level level, String format, ...);
+extern void cyn_log_write_cstring(Log_Level level, u8 *format, ...);
+
+/* --------- Timer API --------- */
+/* --------- File API ---------- */
+/* ------ Filesystem API ------- */
+/* --------- Config API -------- */
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // CYNIC_H
diff --git a/src/cynic_internal.h b/src/cynic_internal.h
new file mode 100644
index 0000000..1c1e8bb
--- /dev/null
+++ b/src/cynic_internal.h
@@ -0,0 +1,31 @@
+#if !defined(CYNIC_INTERNAL_H)
+# define CYNIC_INTERNAL_H
+/*
+ Internal header for Cynic, do not use as it defines platform specific code
+
+ LICENCE:
+
+ Copyright (C) 2025 Bogdan Masyutin (bonmas14)
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Bogdan Masyutin - bonmas14@gmail.com
+*/
+
+/* Windows threading, loading libraries and so on. */
+
+#endif // CYNIC_INTERNAL_H
diff --git a/src/un_list.c b/src/un_list.c
index a670de0..133dc12 100644
--- a/src/un_list.c
+++ b/src/un_list.c
@@ -47,15 +47,16 @@ static b32 list_grow_if_needed(List *list) {
return true;
}
-void un_list_append(List *list, void *data) {
+b32 un_list_append(List *list, void *data) {
void *addr;
if (list_grow_if_needed(list)) {
addr = (u8*)list->data + list->count * list->element_size;
un_memory_copy(addr, data, list->element_size);
list->count++;
+ return true;
} else {
- un_log_write_cstring(UN_LOG_ERROR, UN_CSTR "Failed to grow list");
+ return false;
}
}
diff --git a/src/un_log.c b/src/un_log.c
deleted file mode 100644
index ef5bb02..0000000
--- a/src/un_log.c
+++ /dev/null
@@ -1,71 +0,0 @@
-#include <stdio.h>
-
-Log_Level un_current_log_level = UN_LOG_INFO;
-
-u8 log_buffer[UN_KB(4)];
-
-void un_log_write_internal(Log_Level level, String format, va_list vaptr) {
- if (level < un_current_log_level) return;
-
- switch (level) {
- case UN_LOG_TRACE:
- fprintf(stderr, "[TRACE] ");
- break;
- case UN_LOG_DEBUG:
- fprintf(stderr, "[DEBUG] ");
- break;
- case UN_LOG_INFO:
- fprintf(stderr, "[INFO] ");
- break;
- case UN_LOG_WARNING:
- fprintf(stderr, "[WARNING] ");
- break;
- case UN_LOG_ERROR:
- fprintf(stderr, "[ERROR] ");
- break;
- case UN_LOG_FATAL:
- fprintf(stderr, "[FATAL] ");
- break;
- default:
- break;
- }
-
- sprintf(CSTR log_buffer, "%.*s", (int)format.size, format.data);
- vfprintf(stderr, CSTR log_buffer, vaptr);
-
- switch (level) {
- case UN_LOG_RAW:
- break;
- case UN_LOG_FATAL:
- fprintf(stderr, "\n");
- assert(false);
- break;
- default:
- fprintf(stderr, "\n");
- break;
- }
-}
-
-extern void un_log_write_cstring(Log_Level level, u8 *format, ...) {
- va_list vaptr;
- String temp;
-
- if (level < un_current_log_level) return;
-
- temp.size = un_string_get_length(format);
- temp.data = format;
-
- va_start(vaptr, format);
- un_log_write_internal(level, temp, vaptr);
- va_end(vaptr);
-}
-
-void un_log_write(Log_Level level, String format, ...) {
- va_list vaptr;
-
- if (level < un_current_log_level) return;
-
- va_start(vaptr, format);
- un_log_write_internal(level, format, vaptr);
- va_end(vaptr);
-}
diff --git a/src/un_memory.c b/src/un_memory.c
index 9ff316b..84f5f14 100644
--- a/src/un_memory.c
+++ b/src/un_memory.c
@@ -111,12 +111,12 @@ static void temp_reset(void) {
static void *temp_alloc(u64 size) {
if ((temp.index + size) > UN_TEMP_SIZE) {
- un_log_write_cstring(UN_LOG_ERROR, UN_CSTR "Temp allocator wrapped!");
+ // @todo: Decice what is the best behaviour for wrapping
+ assert(false);
temp_reset();
}
if ((temp.index + size) > UN_TEMP_SIZE) {
- un_log_write_cstring(UN_LOG_ERROR, UN_CSTR "Too much space requested!");
return NULL;
}
@@ -164,7 +164,6 @@ static Arena *arena_create(u64 size) {
arena = CLITERAL(Arena*)un_memory_alloc(size, alloc);
if (!arena) {
- un_log_write_cstring(UN_LOG_FATAL, UN_CSTR "Buy mem, failed to create arena!");
return NULL;
}
@@ -206,10 +205,8 @@ static ALLOCATOR_PROC_SIGNATURE(un_arena_alloc_proc) {
case UN_ALLOC_MSG_ALLOCATE:
return arena_allocate(size, (Arena*)data);
case UN_ALLOC_MSG_REALLOCATE:
- un_log_write_cstring(UN_LOG_ERROR, UN_CSTR "Arena doesn't reallocate.");
break;
case UN_ALLOC_MSG_FREE:
- un_log_write_cstring(UN_LOG_ERROR, UN_CSTR "Arena doesn't free it's memory, please destroy arena itself.");
break;
case UN_ALLOC_MSG_SELF_DELETE:
arena_delete((Arena*)data);
diff --git a/src/un_strings.c b/src/un_strings.c
index 7d73d0b..ff74c39 100644
--- a/src/un_strings.c
+++ b/src/un_strings.c
@@ -32,8 +32,6 @@ String un_string_copy(String source, Allocator alloc) {
u8 *mem;
String result;
- assert(source.size >= 0);
-
mem = (u8*)un_memory_alloc(source.size, alloc);
un_memory_copy(mem, source.data, (u64)source.size);
@@ -64,8 +62,6 @@ s32 un_string_compare(String left, String right) {
String un_string_concat(String left, String right, Allocator alloc) {
String result = { 0 };
- assert(left.size >= 0 && right.size >= 0);
-
if (left.size == right.size && left.size == 0) {
return result;
}
@@ -89,7 +85,7 @@ String un_string_concat(String left, String right, Allocator alloc) {
}
String un_string_swap(String input, u8 from, u8 to, Allocator alloc) {
- s64 i;
+ u64 i;
String output;
output = un_string_copy(input, alloc);
@@ -107,7 +103,7 @@ String un_string_swap(String input, u8 from, u8 to, Allocator alloc) {
List un_string_split(String input, String pattern, Allocator alloc) {
List splits;
String string;
- s64 i, start;
+ u64 i, start;
u64 matches, size;
u8 *buffer;
@@ -196,18 +192,17 @@ String un_string_join(List string_list, String separator, Allocator alloc) {
return un_string_copy(cont, alloc);
}
-String un_string_substring(String input, s64 start, s64 max_size) {
+String un_string_substring(String input, u64 start, u64 max_size) {
String slice;
- assert(start >= 0);
assert(max_size > 0);
- slice.size = UN_MIN(max_size, (input.size - (s64)max_size));
+ slice.size = UN_MIN(max_size, (input.size - (u64)max_size));
slice.data = input.data + start;
if (start > (input.size - max_size)) {
- slice.size = UN_MIN(max_size, (input.size - (s64)max_size));
+ slice.size = UN_MIN(max_size, (input.size - (u64)max_size));
} else {
slice.size = max_size;
}
@@ -217,7 +212,7 @@ String un_string_substring(String input, s64 start, s64 max_size) {
}
s64 un_string_index_of(String input, u8 value, u64 skip_count) {
- s64 i;
+ u64 i;
for (i = 0; i < input.size; i++) {
if (input.data[i] != value) {
@@ -233,12 +228,12 @@ s64 un_string_index_of(String input, u8 value, u64 skip_count) {
return -1;
}
-extern s64 un_string_index_of_last(String input, u8 value) {
+s64 un_string_index_of_last(String input, u8 value) {
s64 i, index;
index = -1;
- for (i = 0; i < input.size; i++) {
+ for (i = 0; i < (s64)input.size; i++) {
if (input.data[i] == value) index = i;
}
@@ -319,16 +314,23 @@ static String format_s64(s64 value) {
String un_string_format(Allocator alloc, String buffer, ...) {
va_list args;
- String s;
+ String result;
+ va_start(args, buffer);
+ result = un_string_vformat(alloc, buffer, args);
+ va_end(args);
+ return result;
+}
+
+String un_string_vformat(Allocator alloc, String buffer, va_list args) {
List output;
- s64 i, j;
+ String s;
+ u64 i, j;
u32 b;
Allocator talloc = un_allocator_get_temporary();
+ // @todo @bug: this would fail on realloc, because we need to realloc
output = un_list_create(UN_KB(1), sizeof(u8), talloc);
- va_start(args, buffer);
-
for (i = 0; i < buffer.size; i++) {
if (buffer.data[i] != '%') {
un_list_append(&output, buffer.data + i);
@@ -374,8 +376,6 @@ String un_string_format(Allocator alloc, String buffer, ...) {
}
}
- va_end(args);
-
s.size = (s64)output.count;
s.data = output.data;
diff --git a/src/ungrateful.c b/src/ungrateful.c
index 1ceefd6..f0c2346 100644
--- a/src/ungrateful.c
+++ b/src/ungrateful.c
@@ -3,4 +3,3 @@
#include "un_memory.c"
#include "un_strings.c"
#include "un_list.c"
-#include "un_log.c"
diff --git a/src/ungrateful.h b/src/ungrateful.h
index 8d1e70e..e3c52cf 100644
--- a/src/ungrateful.h
+++ b/src/ungrateful.h
@@ -146,14 +146,14 @@ extern List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc
extern void un_list_destroy(List *list);
extern List un_list_clone(List *list, Allocator alloc);
-extern void un_list_append(List *list, void *data);
+extern b32 un_list_append(List *list, void *data); /* Returns true if succeed. */
extern void *un_list_get(List *list, u64 index);
extern void un_list_remove(List *list, u64 index);
/* ---- no-wide string API ---- */
typedef struct {
- s64 size;
+ u64 size;
u8 *data;
} String;
@@ -170,30 +170,21 @@ extern String un_string_swap(String input, u8 from, u8 to, Allocator alloc);
extern List un_string_split(String input, String pattern, Allocator alloc);
extern String un_string_join(List string_list, String separator, Allocator alloc);
-extern String un_string_substring(String input, s64 start, s64 max_size);
+extern String un_string_substring(String input, u64 start, u64 max_size);
extern s64 un_string_index_of(String input, u8 value, u64 skip_count);
extern s64 un_string_index_of_last(String input, u8 value);
+/* Simplest formatter, supports:
+ *
+ * %% - %
+ * %c - char (internally u32)
+ * %u - u64
+ * %d - s64
+ * %s - String
+ * */
extern String un_string_format(Allocator alloc, String buffer, ...);
-extern String un_string_tformat(String buffer, ...);
-
-/* ---- Logging API ---- */
-
-typedef enum {
- UN_LOG_TRACE,
- UN_LOG_DEBUG,
- UN_LOG_INFO,
- UN_LOG_WARNING,
- UN_LOG_ERROR,
- UN_LOG_FATAL,
- UN_LOG_RAW
-} Log_Level;
-
-extern Log_Level un_current_log_level;
-
-extern void un_log_write(Log_Level level, String format, ...);
-extern void un_log_write_cstring(Log_Level level, u8 *format, ...);
+extern String un_string_vformat(Allocator alloc, String buffer, va_list args);
#if defined(__cplusplus)
}
diff --git a/tests/cyn/log.c b/tests/cyn/log.c
new file mode 100644
index 0000000..a6b0643
--- /dev/null
+++ b/tests/cyn/log.c
@@ -0,0 +1,5 @@
+#include <cynic.h>
+
+int main(void) {
+ cyn_log_write(UN_LOG_INFO, UN_STR("Hello %u %d %s!"), (u64)100, (s64)-400, UN_STR("World"));
+}
diff --git a/tests/hello_world.c b/tests/hello_world.c
deleted file mode 100644
index 78f6c29..0000000
--- a/tests/hello_world.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <ungrateful.h>
-
-int main(void) {
- un_log_write(UN_LOG_INFO, un_string_from_cstring(UN_CSTR "Hello world!"));
-
- return 0;
-}
diff --git a/tests/allocs.c b/tests/un/allocs.c
index 608d9f4..608d9f4 100644
--- a/tests/allocs.c
+++ b/tests/un/allocs.c
diff --git a/tests/lists.c b/tests/un/lists.c
index a8627ac..a8627ac 100644
--- a/tests/lists.c
+++ b/tests/un/lists.c
diff --git a/tests/memctl.c b/tests/un/memctl.c
index 1614442..1614442 100644
--- a/tests/memctl.c
+++ b/tests/un/memctl.c
diff --git a/tests/strings.c b/tests/un/strings.c
index d49d525..d49d525 100644
--- a/tests/strings.c
+++ b/tests/un/strings.c