aboutsummaryrefslogtreecommitdiff
path: root/src/basic
diff options
context:
space:
mode:
Diffstat (limited to 'src/basic')
-rw-r--r--src/basic/arena.c76
-rw-r--r--src/basic/arena.h36
-rw-r--r--src/basic/basic.h75
-rw-r--r--src/basic/math.c84
-rw-r--r--src/basic/math.h42
-rw-r--r--src/basic/string32.c324
-rw-r--r--src/basic/string32.h60
-rw-r--r--src/basic/time.h42
8 files changed, 739 insertions, 0 deletions
diff --git a/src/basic/arena.c b/src/basic/arena.c
new file mode 100644
index 0000000..8f2e17e
--- /dev/null
+++ b/src/basic/arena.c
@@ -0,0 +1,76 @@
+#include <basic/arena.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+void
+arena_init(Arena *arena, u64 size)
+{
+ arena->size_used = 0;
+ arena->size_max = size;
+ arena->memory = malloc(size);
+}
+
+void
+arena_deinit(Arena *arena)
+{
+ arena->size_used = 0;
+ arena->size_max = 0;
+ free(arena->memory);
+}
+
+void
+arena_align(Arena *arena, u64 alignment)
+{
+ // @Incomplete
+}
+
+void*
+arena_push(Arena *arena, u64 size)
+{
+ void *result = arena->memory + arena->size_used;
+ arena->size_used += size;
+ assert(arena->size_used <= arena->size_max);
+ return result;
+}
+
+void
+arena_pop_to(Arena *arena, u64 pos)
+{
+ arena->size_used = pos;
+}
+
+void
+arena_pop_size(Arena *arena, u64 size)
+{
+ arena->size_used -= size;
+}
+
+void
+arena_zero(Arena *arena)
+{
+ memset(arena->memory, 0, arena->size_used);
+}
+
+void
+arena_clear(Arena *arena)
+{
+ arena->size_used = 0;
+}
+
+
+ArenaTmp
+arena_tmp_begin(Arena *arena)
+{
+ ArenaTmp tmp;
+ tmp.arena = arena;
+ tmp.pos = arena->size_used;
+ return tmp;
+}
+
+void
+arena_tmp_end(ArenaTmp tmp)
+{
+ tmp.arena->size_used = tmp.pos;
+}
+
diff --git a/src/basic/arena.h b/src/basic/arena.h
new file mode 100644
index 0000000..f13ccfa
--- /dev/null
+++ b/src/basic/arena.h
@@ -0,0 +1,36 @@
+#ifndef ARENA_H
+#define ARENA_H
+
+
+#include <basic/basic.h>
+
+typedef struct {
+ size_t size_used;
+ size_t size_max;
+ u8 *memory;
+} Arena;
+
+
+typedef struct {
+ Arena *arena;
+ u64 pos;
+} ArenaTmp;
+
+
+void arena_init(Arena *arena, u64 size);
+void arena_deinit(Arena *arena);
+
+void arena_align(Arena *arena, u64 alignment);
+void* arena_push(Arena *arena, u64 size);
+void arena_pop_to(Arena *arena, u64 pos);
+void arena_pop_size(Arena *arena, u64 size);
+
+void arena_zero(Arena *arena);
+void arena_clear(Arena *arena);
+
+
+ArenaTmp arena_tmp_begin(Arena *arena);
+void arena_tmp_end(ArenaTmp tmp);
+
+
+#endif // MEM_ARENA_H
diff --git a/src/basic/basic.h b/src/basic/basic.h
new file mode 100644
index 0000000..46bf77c
--- /dev/null
+++ b/src/basic/basic.h
@@ -0,0 +1,75 @@
+#ifndef BASIC_H
+#define BASIC_H
+
+#include <stdint.h>
+#include <limits.h>
+#include <stdbool.h>
+#include <stddef.h>
+#include <assert.h>
+#include <sys/param.h>
+
+typedef int8_t i8;
+typedef int16_t i16;
+typedef int32_t i32;
+typedef int64_t i64;
+
+typedef uint8_t u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+typedef uint8_t b8;
+typedef uint16_t b16;
+typedef uint32_t b32;
+typedef uint64_t b64;
+
+typedef float f32;
+typedef double f64;
+
+#define ARRAY_COUNT(x) (sizeof(x) / sizeof(x[0]))
+
+#define KIBIBYTES(x) ((x)*1024)
+#define MEBIBYTES(x) ((x)*KIBIBYTES(1024))
+#define GIBIBYTES(x) ((x)*MEBIBYTES(1024))
+
+#define I8_MAX INT8_MAX
+#define I16_MAX INT16_MAX
+#define I32_MAX INT32_MAX
+#define I64_MAX INT64_MAX
+
+#define U8_MAX UINT8_MAX
+#define U16_MAX UINT16_MAX
+#define U32_MAX UINT32_MAX
+#define U64_MAX UINT64_MAX
+
+#define F32_MAX FLT_MAX
+#define F64_MAX DBL_MAX
+#define F32_MIN FLT_MIN
+#define F64_MIN DBL_MIN
+
+#define likely(expr) __builtin_expect(!!(expr), 1)
+#define unlikely(expr) __builtin_expect(!!(expr), 0)
+
+#define InvalidCodePath assert(!"InvalidCodePath")
+#define InvalidDefaultCase default: {InvalidCodePath;} break
+
+#define internal_var static
+#define internal_fn static
+#define persist_var static
+
+// Todo: use __FILE__ and __LINE__ macros for debug prints
+#ifdef NDEBUG
+#define debug_printf()
+#else
+#define debug_printf(...) printf(__VA_ARGS__)
+#endif
+
+
+#if defined(__linux__)
+#include <alloca.h>
+#elif defined(_WIN64)
+#define alloca(size) _alloca(size)
+#endif
+
+
+#endif // BASIC_H
diff --git a/src/basic/math.c b/src/basic/math.c
new file mode 100644
index 0000000..3521821
--- /dev/null
+++ b/src/basic/math.c
@@ -0,0 +1,84 @@
+#include <basic/basic.h>
+#include <basic/math.h>
+
+i32
+f32_round_to_i32(f32 value)
+{
+ i32 result;
+ if (value >= 0) {
+ result = (i32)(value + 0.5f);
+ } else {
+ result = (i32)(value - 0.5f);
+ }
+ return result;
+}
+
+f32
+f32_center(f32 dim, f32 dim_total)
+{
+ f32 result = (dim_total - dim) / 2;
+ return result;
+}
+
+V2F32
+v2f32(f32 x, f32 y)
+{
+ V2F32 result = {x, y};
+ return result;
+}
+
+V2F32
+v2f32_add(V2F32 v1, V2F32 v2)
+{
+ V2F32 result = {v1.x + v2.x, v1.y + v2.y};
+ return result;
+}
+
+V2F32
+v2f32_sub(V2F32 v1, V2F32 v2)
+{
+ V2F32 result = {v1.x - v2.x, v1.y - v2.y};
+ return result;
+}
+
+V2F32
+v2f32_center(V2F32 dim_inner, V2F32 dim_outer)
+{
+ V2F32 pos;
+ pos.x = f32_center(dim_inner.x, dim_outer.x);
+ pos.y = f32_center(dim_inner.y, dim_outer.y);
+ return pos;
+}
+
+V3F32
+v3f32(f32 x, f32 y, f32 z)
+{
+ V3F32 result = {x, y, z};
+ return result;
+}
+
+V4F32
+v4f32(f32 x, f32 y, f32 z, f32 w)
+{
+ V4F32 result = {x, y, z, w};
+ return result;
+}
+
+RectF32
+rectf32(float x0, float y0, float x1, float y1)
+{
+ RectF32 result = {x0, y0, x1, y1};
+ return result;
+}
+
+b32
+rectf32_contains_v2f32(RectF32 rect, V2F32 pos)
+{
+ b32 result = pos.x >= rect.x0 &&
+ pos.x <= rect.x1 &&
+ pos.y >= rect.y0 &&
+ pos.y <= rect.y1;
+ return result;
+}
+
+
diff --git a/src/basic/math.h b/src/basic/math.h
new file mode 100644
index 0000000..d0863c1
--- /dev/null
+++ b/src/basic/math.h
@@ -0,0 +1,42 @@
+#ifndef MATH_H
+#define MATH_H
+
+#include <basic/basic.h>
+
+typedef struct {
+ f32 x, y;
+} V2F32;
+
+typedef struct {
+ f32 x, y, z;
+} V3F32;
+
+typedef struct {
+ f32 x, y, z, w;
+} V4F32;
+
+typedef struct {
+ f32 x0;
+ f32 y0;
+ f32 x1;
+ f32 y1;
+} RectF32;
+
+V2F32 v2f32(f32 x, f32 y);
+V2F32 v2f32_add(V2F32 v1, V2F32 v2);
+V2F32 v2f32_sub(V2F32 v1, V2F32 v2);
+V2F32 v2f32_center(V2F32 dim, V2F32 dim_total);
+
+V3F32 v3f32(f32 x, f32 y, f32 z);
+
+V4F32 v4f32(f32 x, f32 y, f32 z, f32 w);
+
+i32 f32_round_to_i32(f32 value);
+f32 f32_center(f32 dim, f32 dim_total);
+
+RectF32 rectf32(f32 x0, f32 y0, f32 x1, f32 y1);
+b32 rectf32_contains_v2f32(RectF32 rect, V2F32 pos);
+
+
+
+#endif // MATH_H
diff --git a/src/basic/string32.c b/src/basic/string32.c
new file mode 100644
index 0000000..c88a1a8
--- /dev/null
+++ b/src/basic/string32.c
@@ -0,0 +1,324 @@
+#include "basic/arena.h"
+#include <SDL2/SDL_keycode.h>
+#include <os/os.h>
+#include <string.h>
+
+#include <basic/basic.h>
+#include <basic/string32.h>
+
+
+
+void
+string32_buffer_move_cursor_left(String32Buffer *buffer)
+{
+ if (buffer->cursor > 0) {
+ buffer->cursor -= 1;
+ }
+}
+
+
+void
+string32_buffer_move_cursor_right(String32Buffer *buffer)
+{
+ if (buffer->cursor < buffer->len) {
+ buffer->cursor += 1;
+ }
+}
+
+
+b32
+string32_buffer_del_left(String32Buffer *buffer)
+{
+ if (buffer->cursor > 0){
+ u32 *dest = &buffer->codepoints[buffer->cursor - 1];
+ u32 *src = &buffer->codepoints[buffer->cursor];
+ size_t move_size = (buffer->len - buffer->cursor) * sizeof(u32);
+ memmove(dest, src, move_size);
+
+ buffer->len -= 1;
+ buffer->cursor -= 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+b32
+string32_buffer_del_right(String32Buffer *buffer)
+{
+ if (buffer->cursor < buffer->len) {
+ u32 *dest = &buffer->codepoints[buffer->cursor];
+ u32 *src = &buffer->codepoints[buffer->cursor + 1];
+ size_t move_size = (buffer->len - buffer->cursor) * sizeof(u32);
+ memmove(dest, src, move_size);
+
+ buffer->len -= 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+b32
+string32_buffer_insert(String32Buffer *buffer, u32 codepoint)
+{
+ if (buffer->len < buffer->max_len &&
+ buffer->cursor <= buffer->len)
+ {
+ u32 *dest = &buffer->codepoints[buffer->cursor + 1];
+ u32 *src = &buffer->codepoints[buffer->cursor];
+ size_t move_size = (buffer->len - buffer->cursor) * sizeof(u32);
+ memmove(dest, src, move_size);
+
+ buffer->codepoints[buffer->cursor] = codepoint;
+ buffer->len += 1;
+ buffer->cursor += 1;
+
+ return true;
+ }
+
+ return false;
+}
+
+
+void
+string32_buffer_edit(String32Buffer *buffer, OSEventKeyPress key_press)
+{
+ if (key_press.is_unicode) {
+ switch (key_press.code) {
+ case '\b': {
+ string32_buffer_del_left(buffer);
+ } break;
+
+ case 127: {
+ string32_buffer_del_right(buffer);
+ } break;
+
+ default: {
+ string32_buffer_insert(buffer, key_press.code);
+ }
+ }
+ }
+ else {
+ if (key_press.code == OS_KEYCODE_LEFT) {
+ string32_buffer_move_cursor_left(buffer);
+ }
+ else if (key_press.code == OS_KEYCODE_RIGHT) {
+ string32_buffer_move_cursor_right(buffer);
+ }
+ }
+}
+
+
+void
+string32_buffer_append_string32_buffer(String32Buffer *buffer, String32Buffer *src_buffer)
+{
+ size_t len_avail = buffer->max_len - buffer->len;
+ size_t copy_count = len_avail >= src_buffer->len ? src_buffer->len : len_avail;
+ u32 *dest = buffer->codepoints + buffer->len;
+ u32 *src = src_buffer->codepoints;
+ for (size_t i = 0; i < copy_count; i++) {
+ *dest++ = *src++;
+ }
+ buffer->len += copy_count;
+}
+
+
+void
+string32_buffer_append_string32(String32Buffer *buffer, String32 *str)
+{
+ size_t len_avail = buffer->max_len - buffer->len;
+ size_t copy_count = str->len >= len_avail ? len_avail : str->len;
+ u32 *dest = buffer->codepoints + buffer->len;
+ u32 *src = str->codepoints;
+ for (size_t i = 0; i < copy_count; i++) {
+ *dest++ = *src++;
+ }
+ buffer->len += copy_count;
+}
+
+
+void
+string32_buffer_append_ascii_cstr(String32Buffer *buffer, char *ascii)
+{
+ while (*ascii) {
+ if (buffer->len >= buffer->max_len) {
+ break;
+ }
+
+ buffer->codepoints[buffer->len] = *ascii;
+ buffer->len += 1;
+ ascii++;
+ }
+}
+
+
+void
+string32_buffer_copy_string32_buffer(String32Buffer *dest, String32Buffer *src)
+{
+ string32_buffer_reset(dest);
+ string32_buffer_append_string32_buffer(dest, src);
+}
+
+
+void
+string32_buffer_copy_string32(String32Buffer *buffer, String32 *str)
+{
+ string32_buffer_reset(buffer);
+ string32_buffer_append_string32(buffer, str);
+}
+
+
+b32 string32_buffer_equal_string32(String32Buffer *buffer, String32 *str)
+{
+ if (buffer->len != str->len) {
+ return false;
+ }
+ for (size_t i = 0; i < buffer->len; i++) {
+ if (buffer->codepoints[i] != str->codepoints[i]) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
+String32 *
+string32_buffer_to_string32_with_len(Arena *arena, String32Buffer *buffer, size_t len)
+{
+ size_t push_size = sizeof(String32) + len * sizeof(u32);
+ String32 *result = arena_push(arena, push_size);
+
+ memcpy(result->codepoints, buffer->codepoints, len * sizeof(u32));
+ result->len = len;
+
+ return result;
+}
+
+
+String32 *
+string32_buffer_to_string32(Arena *arena, String32Buffer *buffer)
+{
+ size_t push_size = sizeof(String32) + buffer->len * sizeof(u32);
+ String32 *result = arena_push(arena, push_size);
+
+ memcpy(result->codepoints, buffer->codepoints, buffer->len * sizeof(u32));
+ result->len = buffer->len;
+
+ return result;
+}
+
+
+void
+string32_buffer_print(String32Buffer *buffer)
+{
+ for (size_t i = 0; i < buffer->len; i++) {
+ putchar(buffer->codepoints[i]);
+ }
+}
+
+
+void
+string32_buffer_reset(String32Buffer *buffer)
+{
+ buffer->len = 0;
+ buffer->cursor = 0;
+}
+
+void
+string32_buffer_init_in_place(String32Buffer *buffer, size_t max_len)
+{
+ buffer->cursor = 0;
+ buffer->len = 0;
+ buffer->max_len = max_len;
+}
+
+
+String32Buffer *
+string32_buffer_create(Arena *arena, size_t max_len)
+{
+ size_t push_size = sizeof(String32Buffer) + max_len * sizeof(u32);
+ String32Buffer *buffer = arena_push(arena, push_size);
+
+ buffer->cursor = 0;
+ buffer->len = 0;
+ buffer->max_len = max_len;
+
+ return buffer;
+}
+
+
+void
+string32_print(String32 *str)
+{
+ for (size_t i = 0; i < str->len; i++) {
+ putchar(str->codepoints[i]);
+ }
+}
+
+
+b32
+string32_equal(String32 *str1, String32 *str2) { if (str1->len != str2->len) {
+ return false;
+ }
+
+ for (size_t i = 0; i < str1->len; i++) {
+ if (str1->codepoints[i] != str2->codepoints[i]) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+
+String32 *
+string32_create_from_u32_array(Arena *arena, u32 *buffer, size_t len)
+{
+ size_t push_size = sizeof(String32) + len * sizeof(u32);
+ String32 *result = arena_push(arena, push_size);
+
+ memcpy(result->codepoints, buffer, len);
+ result->len = len;
+
+ return result;
+}
+
+
+
+String32 *
+string32_create_from_string32(Arena *arena, String32 *src)
+{
+ size_t push_size = sizeof(String32) + src->len * sizeof(u32);
+ String32 *result = arena_push(arena, push_size);
+
+ for (size_t i = 0; i < src->len; i++) {
+ result->codepoints[i] = src->codepoints[i];
+ }
+ result->len = src->len;
+
+ return result;
+}
+
+
+String32 *
+string32_create_from_ascii(Arena *arena, char *ascii)
+{
+ size_t len = strlen(ascii);
+
+ size_t push_size = sizeof(String32) + strlen(ascii) * sizeof(u32);
+ String32 *result = arena_push(arena, push_size);
+
+ u32 *dest = result->codepoints;
+ while (*ascii) {
+ *dest++ = *ascii++;
+ }
+ result->len = len;
+
+ return result;
+}
+
diff --git a/src/basic/string32.h b/src/basic/string32.h
new file mode 100644
index 0000000..3af5fb3
--- /dev/null
+++ b/src/basic/string32.h
@@ -0,0 +1,60 @@
+#ifndef STRING32_H
+#define STRING32_H
+
+#include <basic/basic.h>
+#include <basic/arena.h>
+#include <os/os.h>
+
+
+
+typedef struct {
+ u32 len;
+ u32 codepoints[];
+} String32;
+
+
+typedef struct {
+ u32 cursor;
+ u32 len;
+ u32 max_len;
+ u32 codepoints[];
+} String32Buffer;
+
+
+
+String32 *string32_create_from_ascii(Arena *arena, char *ascii);
+String32 *string32_create_from_string32(Arena *arena, String32 *src);
+String32 *string32_create_from_string32_with_len(Arena *arena, String32 *src, size_t len);
+String32 *string32_create_from_u32_array(Arena *arena, u32 *buffer, size_t len);
+
+b32 string32_equal(String32 *str1, String32 *str2);
+void string32_print(String32 *str);
+
+
+
+String32Buffer* string32_buffer_create(Arena *arena, size_t max_len);
+void string32_buffer_init_in_place(String32Buffer *buffer, size_t max_len);
+
+String32 *string32_buffer_to_string32(Arena *arena, String32Buffer *buffer);
+String32 *string32_buffer_to_string32_with_len(Arena *arena, String32Buffer *buffer, size_t len);
+
+void string32_buffer_reset(String32Buffer *buffer);
+void string32_buffer_print(String32Buffer *buffer);
+
+void string32_buffer_append_ascii_cstr(String32Buffer *buffer, char *ascii);
+void string32_buffer_append_string32(String32Buffer *buffer, String32 *str);
+void string32_buffer_append_string32_buffer(String32Buffer *buffer, String32Buffer *src);
+
+b32 string32_buffer_equal_string32(String32Buffer *buffer, String32 *str);
+void string32_buffer_copy_string32(String32Buffer *buffer, String32 *str);
+void string32_buffer_copy_string32_buffer(String32Buffer *dest, String32Buffer *src);
+
+void string32_buffer_edit(String32Buffer *buffer, OSEventKeyPress key_press);
+b32 string32_buffer_insert(String32Buffer *buffer, u32 codepoint);
+b32 string32_buffer_delete_right(String32Buffer *buffer);
+b32 string32_buffer_delete_left(String32Buffer *buffer);
+void string32_buffer_move_cursor_left(String32Buffer *buffer);
+void string32_buffer_move_cursor_right(String32Buffer *buffer);
+
+
+#endif // STRING32_H
diff --git a/src/basic/time.h b/src/basic/time.h
new file mode 100644
index 0000000..8d739b2
--- /dev/null
+++ b/src/basic/time.h
@@ -0,0 +1,42 @@
+#ifndef BASIC_TIME_H
+#define BASIC_TIME_H
+
+#include <os/os.h>
+
+typedef OSTime Time;
+
+
+typedef struct {
+ Time t0;
+ Time t1;
+} Timer;
+
+#define TIMER_START(name) \
+ static Timer timer_##name; \
+ timer_##name.t0 = os_time_get_now();
+
+// Todo: On windows this %ld should be %lld
+#define TIMER_END(name) \
+ timer_##name.t1 = os_time_get_now(); \
+ i64 sec_diff = timer_##name.t1.seconds - timer_##name.t0.seconds; \
+ i64 nsec0 = timer_##name.t0.nanoseconds; \
+ i64 nsec1 = timer_##name.t1.nanoseconds; \
+ i64 nsec_total = sec_diff*1000*1000*1000; \
+ if (nsec1 >= nsec0) nsec_total += nsec1 - nsec0; \
+ else nsec_total -= nsec1 + nsec0; \
+ i64 ms_part = nsec_total / (1000*1000); \
+ i64 ns_part = nsec_total % (1000*1000); \
+ printf("%-24s: %3ld,%06ld ms\n", #name, ms_part, ns_part);
+
+
+#define CYCLER_START(name) \
+ u64 cycler_##name_t0 = __rdtsc();
+
+// Todo: On windows this %lu should be %llu
+#define CYCLER_END(name) \
+ u64 cycler_##name_t1 = __rdtsc(); \
+ u64 cycles_counted_##name = cycler_##name_t1 - cycler_##name_t0; \
+ printf("cycles elapsed (%s): %lu\n", #name, cycles_counted_##name);
+
+
+#endif // BASIC_TIME_H