diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/btree.c | 1192 | ||||
| -rw-r--r-- | src/dltools.c | 66 | ||||
| -rw-r--r-- | src/engine.c | 1182 | ||||
| -rw-r--r-- | src/fov.c | 147 | ||||
| -rw-r--r-- | src/hashmap.c | 4 | ||||
| -rw-r--r-- | src/input.c | 501 | ||||
| -rw-r--r-- | src/logging.c | 119 | ||||
| -rw-r--r-- | src/memory.c | 38 | ||||
| -rw-r--r-- | src/rendering.c | 185 | ||||
| -rw-r--r-- | src/stack.c | 98 | ||||
| -rw-r--r-- | src/state.c | 212 | ||||
| -rw-r--r-- | src/ui_positioning.c | 1380 | ||||
| -rw-r--r-- | src/ui_rendering.c | 391 | ||||
| -rw-r--r-- | src/utils.c | 87 | ||||
| -rw-r--r-- | src/vector.c | 50 |
15 files changed, 2807 insertions, 2845 deletions
diff --git a/src/btree.c b/src/btree.c index 63c2513..c125564 100644 --- a/src/btree.c +++ b/src/btree.c @@ -11,116 +11,111 @@ typedef unsigned char byte; struct node { - ssize_t n; /* number of items/keys/elements */ - ssize_t c; /* number of children */ - byte *items; - struct node **children; + ssize_t n; /* number of items/keys/elements */ + ssize_t c; /* number of children */ + byte* items; + struct node** children; }; struct btree { - /* Memory stuffs */ - void *(*alloc)(size_t); - void (*dealloc)(void*); + /* Memory stuffs */ + void* (*alloc)(size_t); + void (*dealloc)(void*); - /* Size stuffs */ - size_t elem_size; - ssize_t degree; + /* Size stuffs */ + size_t elem_size; + ssize_t degree; - struct node *root; + struct node* root; - /* comparison */ - int (*cmp)(const void *a, const void *b); + /* comparison */ + int (*cmp)(const void* a, const void* b); }; struct btree_iter_t { - size_t head; - struct stack { - int pos; - struct node* node; - } stack[512]; - /* This heavily relies on the assumption that a tree never grows deeper than - * 512 nodes */ + size_t head; + struct stack { + int pos; + struct node* node; + } stack[512]; + /* This heavily relies on the assumption that a tree never grows deeper than + * 512 nodes */ }; /**********************/ /* Node functionality */ /**********************/ -#define \ -node_leaf(node) (node->children == NULL) +#define node_leaf(node) (node->children == NULL) -#define \ -node_maxdegree(t) (2 * t - 1) +#define node_maxdegree(t) (2 * t - 1) -#define \ -node_mindegree(t) (t - 1) +#define node_mindegree(t) (t - 1) -#define \ -node_full(degree, t) (t->n >= 2 * degree - 1) +#define node_full(degree, t) (t->n >= 2 * degree - 1) /* Node memory */ /* `node_new` allocates a new leaf node, children should be added and allocated * when the node is no longer a leaf node */ struct node* node_new(const ssize_t degree, const size_t elem_size) { - const size_t max_items = 2 * degree; - struct node *retval = calloc(1, sizeof(struct node)); + const size_t max_items = 2 * degree; + struct node* retval = calloc(1, sizeof(struct node)); - retval->n = 0; - retval->c = 0; - retval->items = calloc(max_items, elem_size); - retval->children = NULL; + retval->n = 0; + retval->c = 0; + retval->items = calloc(max_items, elem_size); + retval->children = NULL; - return retval; + return retval; } /* `node_transition` turns a leaf node into a non-leaf. Children are not * allocated. * returnvalue: `false` if we we're unable to allocate space for the new * children. */ -bool node_transition(struct node *node, const ssize_t degree) { - const int max_children = 2 * degree + 1; - int c; +bool node_transition(struct node* node, const ssize_t degree) { + const int max_children = 2 * degree + 1; + int c; - if (!node_leaf(node)) { - perror("node_transition was called on an already non-leaf node?"); - return false; - } + if (!node_leaf(node)) { + perror("node_transition was called on an already non-leaf node?"); + return false; + } - /* Allocate pointers for children */ - node->children = calloc(max_children, sizeof(struct node*)); + /* Allocate pointers for children */ + node->children = calloc(max_children, sizeof(struct node*)); - if (node->children == NULL) { - perror("could not allocate space for children pointers"); - return false; - } + if (node->children == NULL) { + perror("could not allocate space for children pointers"); + return false; + } - /* Allocate children */ - for (c = 0; c < max_children; c++) { - node->children[c] = NULL; - } + /* Allocate children */ + for (c = 0; c < max_children; c++) { + node->children[c] = NULL; + } - return true; + return true; } -void node_free(struct node **node, size_t elem_size, void (*dealloc)(void*)) { - if (*node == NULL) return; +void node_free(struct node** node, size_t elem_size, void (*dealloc)(void*)) { + if (*node == NULL) return; - if (!node_leaf((*node))) { - ssize_t i; - for (i = 0; i < (*node)->c; i++) { - node_free(&((*node)->children[i]), elem_size, dealloc); - } - dealloc((*node)->children); - } + if (!node_leaf((*node))) { + ssize_t i; + for (i = 0; i < (*node)->c; i++) { + node_free(&((*node)->children[i]), elem_size, dealloc); + } + dealloc((*node)->children); + } - dealloc((*node)->items); - (*node)->items = NULL; + dealloc((*node)->items); + (*node)->items = NULL; - dealloc(*node); - *node = NULL; + dealloc(*node); + *node = NULL; } - /* `node_tree_split_child` splits a _full_ node (c = 2t-1 items) into two nodes * with t-1 items each. * The median key/item/element moves up to the original nodes parent, to signify @@ -131,66 +126,61 @@ void node_free(struct node **node, size_t elem_size, void (*dealloc)(void*)) { * full nodes we encounter on the way down, including the leafs themselves. * By doing this, we are assured that whenever we split a node, its parent has * room for the median key. */ -void node_tree_split_child( - const ssize_t t, - const size_t elem_size, - struct node *nonfull, - ssize_t i) { - struct node *z = node_new(t, elem_size); - struct node *y = nonfull->children[i]; - ssize_t j; +void node_tree_split_child(const ssize_t t, const size_t elem_size, + struct node* nonfull, ssize_t i) { + struct node* z = node_new(t, elem_size); + struct node* y = nonfull->children[i]; + ssize_t j; - /* `z` should be a branching node if `y` is */ - if (!node_leaf(y)) { - node_transition(z, t); - } + /* `z` should be a branching node if `y` is */ + if (!node_leaf(y)) { + node_transition(z, t); + } - z->n = t - 1; + z->n = t - 1; - /* Move last `t-1` items to new node `z` */ - /* TODO This can be done with one memcpy */ - for (j = 0; j < t-1; j++) { - const size_t offset_dst = elem_size * j; - const size_t offset_src = elem_size * (t+j); - memcpy((z->items) + offset_dst, (y->items) + offset_src, elem_size); - } - /* Set unused item-memory to zero? */ + /* Move last `t-1` items to new node `z` */ + /* TODO This can be done with one memcpy */ + for (j = 0; j < t - 1; j++) { + const size_t offset_dst = elem_size * j; + const size_t offset_src = elem_size * (t + j); + memcpy((z->items) + offset_dst, (y->items) + offset_src, elem_size); + } + /* Set unused item-memory to zero? */ - /* Move children t..2t, if applicable*/ - if (!node_leaf(y)) { - for (j = 0; j < t+1; j++) { - z->children[j] = y->children[j + t]; - } - y->c = t; - z->c = t; - } + /* Move children t..2t, if applicable*/ + if (!node_leaf(y)) { + for (j = 0; j < t + 1; j++) { + z->children[j] = y->children[j + t]; + } + y->c = t; + z->c = t; + } - y->n = t - 1; + y->n = t - 1; - /* Move children +1 */ - for (j = nonfull->n; j > i; j--) { - nonfull->children[j+1] = nonfull->children[j]; - } + /* Move children +1 */ + for (j = nonfull->n; j > i; j--) { + nonfull->children[j + 1] = nonfull->children[j]; + } - /* new child */ - nonfull->children[i+1] = z; - nonfull->c++; + /* new child */ + nonfull->children[i + 1] = z; + nonfull->c++; - /* moving keys i..n + 1*/ - /* TODO This can be done with one memcpy */ - for (j = nonfull->n; j >= i; j--) { - const size_t offset = j * elem_size; - memcpy((nonfull->items) + offset + elem_size, - (nonfull->items) + offset, - elem_size); - } + /* moving keys i..n + 1*/ + /* TODO This can be done with one memcpy */ + for (j = nonfull->n; j >= i; j--) { + const size_t offset = j * elem_size; + memcpy((nonfull->items) + offset + elem_size, (nonfull->items) + offset, + elem_size); + } - /* Lastly, copy the median element to nonfull-parent*/ - memcpy((nonfull->items) + i * elem_size, - (y->items) + (t-1) * elem_size, - elem_size); + /* Lastly, copy the median element to nonfull-parent*/ + memcpy((nonfull->items) + i * elem_size, (y->items) + (t - 1) * elem_size, + elem_size); - nonfull->n++; + nonfull->n++; } /* `node_child_merge`: Merges two children around the key at index `i` (k) @@ -202,649 +192,609 @@ void node_tree_split_child( * * WARNING: THIS FUNCTION ASSUMES THAT `i` IS A VALID INDEX */ -void node_child_merge( - struct node *x, - ssize_t i, - const size_t elem_size, void (*dealloc)(void*)) { - struct node* y = x->children[i ]; - struct node* z = x->children[i+1]; - int j = 0; +void node_child_merge(struct node* x, ssize_t i, const size_t elem_size, + void (*dealloc)(void*)) { + struct node* y = x->children[i]; + struct node* z = x->children[i + 1]; + int j = 0; - /* append k to y */ - memcpy(y->items + (elem_size * y->n++), - x->items + (elem_size * i), - elem_size); + /* append k to y */ + memcpy(y->items + (elem_size * y->n++), x->items + (elem_size * i), + elem_size); - /* append keys in z to y */ - memcpy(y->items + (elem_size * y->n), - z->items, - elem_size * z->n); - y->n += z->n; + /* append keys in z to y */ + memcpy(y->items + (elem_size * y->n), z->items, elem_size * z->n); + y->n += z->n; - /* Move children from z to y */ - for (j = 0; j < z->c; j++) { - y->children[y->c + j] = z->children[j]; - } - y->c += z->c; + /* Move children from z to y */ + for (j = 0; j < z->c; j++) { + y->children[y->c + j] = z->children[j]; + } + y->c += z->c; - /* Remove z from x */ - for (j = i+1; j < x->c; j++) { - x->children[j] = x->children[j+1]; - } - x->c--; + /* Remove z from x */ + for (j = i + 1; j < x->c; j++) { + x->children[j] = x->children[j + 1]; + } + x->c--; - /* remove k from x */ - /* TODO check if we need to use (x->n - 1 - i) instead */ - memmove(x->items + (elem_size * i), - x->items + (elem_size * (i+1)), - elem_size * (x->n - i)); - x->n--; + /* remove k from x */ + /* TODO check if we need to use (x->n - 1 - i) instead */ + memmove(x->items + (elem_size * i), x->items + (elem_size * (i + 1)), + elem_size * (x->n - i)); + x->n--; - dealloc(z); /* DO NOT USE THE RECURSIVE ONE AS CHILDREN WILL BE LOST!!! */ + dealloc(z); /* DO NOT USE THE RECURSIVE ONE AS CHILDREN WILL BE LOST!!! */ } /* ASSUME i < x->c */ -void node_shift_left( - struct node *x, - ssize_t i, - const size_t elem_size) { - struct node* y = x->children[i ]; - struct node* z = x->children[i+1]; - byte *x_k = x->items + (elem_size * i); +void node_shift_left(struct node* x, ssize_t i, const size_t elem_size) { + struct node* y = x->children[i]; + struct node* z = x->children[i + 1]; + byte* x_k = x->items + (elem_size * i); - /* Append x.k[i] to y */ - memcpy(y->items + (elem_size * y->n++), - x_k, - elem_size); + /* Append x.k[i] to y */ + memcpy(y->items + (elem_size * y->n++), x_k, elem_size); - /* Move first element of z to x.k[i] */ - memcpy(x_k, - z->items, - elem_size); + /* Move first element of z to x.k[i] */ + memcpy(x_k, z->items, elem_size); - /* Shift z's items left */ - memmove(z->items, - z->items + elem_size, - elem_size * (z->n - 1)); + /* Shift z's items left */ + memmove(z->items, z->items + elem_size, elem_size * (z->n - 1)); - if (!node_leaf(z)) { - ssize_t j; - /* append first child of z to y */ - y->children[y->c++] = z->children[0]; + if (!node_leaf(z)) { + ssize_t j; + /* append first child of z to y */ + y->children[y->c++] = z->children[0]; - /* Shift z's children left */ - for (j = 0; j < z->c; j++) { - z->children[j] = z->children[j+1]; - } - z->c--; - } + /* Shift z's children left */ + for (j = 0; j < z->c; j++) { + z->children[j] = z->children[j + 1]; + } + z->c--; + } - z->n--; + z->n--; } -void node_shift_right( - struct node *x, - ssize_t i, - const size_t elem_size) { - struct node* y = x->children[i ]; - struct node* z = x->children[i+1]; - byte *x_k = x->items + (elem_size * i); +void node_shift_right(struct node* x, ssize_t i, const size_t elem_size) { + struct node* y = x->children[i]; + struct node* z = x->children[i + 1]; + byte* x_k = x->items + (elem_size * i); - /* Shift z's items right */ - memmove(z->items + elem_size, - z->items, - elem_size * z->n); + /* Shift z's items right */ + memmove(z->items + elem_size, z->items, elem_size * z->n); - /* Prepend x.k[i] to z */ - memcpy(z->items, - x_k, - elem_size); + /* Prepend x.k[i] to z */ + memcpy(z->items, x_k, elem_size); - /* Move last element of y to x.k[i] */ - memcpy(x_k, - y->items + (elem_size * --(y->n)), - elem_size); + /* Move last element of y to x.k[i] */ + memcpy(x_k, y->items + (elem_size * --(y->n)), elem_size); - if (!node_leaf(z)) { - size_t j; - /* Shift z's children right */ - for (j = z->c; j > 0; j--) { - z->children[j] = z->children[j-1]; - } - z->c++; + if (!node_leaf(z)) { + size_t j; + /* Shift z's children right */ + for (j = z->c; j > 0; j--) { + z->children[j] = z->children[j - 1]; + } + z->c++; - /* prepend last child of y to z */ - z->children[0] = y->children[--(y->c)]; - } + /* prepend last child of y to z */ + z->children[0] = y->children[--(y->c)]; + } - z->n++; + z->n++; } /* return: Returns the new root, if a split happens */ -void node_insert_nonfull( - struct node *root, - void *elem, - const ssize_t degree, - const size_t elem_size, - int (*cmp)(const void *a, const void *b)) { +void node_insert_nonfull(struct node* root, void* elem, const ssize_t degree, + const size_t elem_size, + int (*cmp)(const void* a, const void* b)) { - /* TODO check correctness */ - ssize_t i = root->n - 1; + /* TODO check correctness */ + ssize_t i = root->n - 1; - if (node_leaf(root)) { - size_t offset = elem_size * i; - while (i >= 0 && cmp(elem, root->items + offset) < 0) { - /* TODO This can be done with one memcpy */ - memcpy(root->items + offset + elem_size, - root->items + offset, - elem_size); + if (node_leaf(root)) { + size_t offset = elem_size * i; + while (i >= 0 && cmp(elem, root->items + offset) < 0) { + /* TODO This can be done with one memcpy */ + memcpy(root->items + offset + elem_size, root->items + offset, elem_size); - i--; - offset = elem_size * i; - } - offset = elem_size * (++i); - memcpy(root->items + offset, elem, elem_size); - root->n++; + i--; + offset = elem_size * i; + } + offset = elem_size * (++i); + memcpy(root->items + offset, elem, elem_size); + root->n++; - } else { - size_t offset = elem_size * i; - struct node *nextchild = NULL; - while (i >= 0 && cmp(elem, root->items + offset) < 0) { - i--; - offset = elem_size * i; - } - i++; - nextchild = root->children[i]; - if (node_full(degree, nextchild)) { - /* TODO Check if the root has changed */ - node_tree_split_child(degree, elem_size, root, i); - if (cmp(elem, root->items + elem_size * i) > 0) { - nextchild = root->children[++i]; - } - } - node_insert_nonfull(nextchild, elem, degree, elem_size, cmp); - } + } else { + size_t offset = elem_size * i; + struct node* nextchild = NULL; + while (i >= 0 && cmp(elem, root->items + offset) < 0) { + i--; + offset = elem_size * i; + } + i++; + nextchild = root->children[i]; + if (node_full(degree, nextchild)) { + /* TODO Check if the root has changed */ + node_tree_split_child(degree, elem_size, root, i); + if (cmp(elem, root->items + elem_size * i) > 0) { + nextchild = root->children[++i]; + } + } + node_insert_nonfull(nextchild, elem, degree, elem_size, cmp); + } } /* Returns the new root, if a split occurs */ -struct node* node_insert( - struct node *root, - void *elem, - const ssize_t degree, - const size_t elem_size, - int (*cmp)(const void *a, const void *b)) { +struct node* node_insert(struct node* root, void* elem, const ssize_t degree, + const size_t elem_size, + int (*cmp)(const void* a, const void* b)) { - struct node *s = root; + struct node* s = root; - if (node_full(degree, root)) { - s = node_new(degree, elem_size); - if (s == NULL) { - fputs("BTree error: Failed to allocate new node for insertion!\n", stderr); - return NULL; - } - node_transition(s, degree); - s->children[s->c++] = root; - /* TODO Check if the root has changed */ - node_tree_split_child(degree, elem_size, s, 0); - node_insert_nonfull(s, elem, degree, elem_size, cmp); - } - else { - node_insert_nonfull(s, elem, degree, elem_size, cmp); - } - return s; + if (node_full(degree, root)) { + s = node_new(degree, elem_size); + if (s == NULL) { + fputs("BTree error: Failed to allocate new node for insertion!\n", + stderr); + return NULL; + } + node_transition(s, degree); + s->children[s->c++] = root; + /* TODO Check if the root has changed */ + node_tree_split_child(degree, elem_size, s, 0); + node_insert_nonfull(s, elem, degree, elem_size, cmp); + } else { + node_insert_nonfull(s, elem, degree, elem_size, cmp); + } + return s; } -void* node_search(struct node *x, - void *key, - int(*cmp)(const void *a, const void *b), +void* node_search(struct node* x, void* key, + int (*cmp)(const void* a, const void* b), const size_t elem_size) { - /* We set to one, since we pre-emptively do a comparison with the assumption - * that there's already one in the items */ - ssize_t i = 0; - int last_cmp_res = 0; + /* We set to one, since we pre-emptively do a comparison with the assumption + * that there's already one in the items */ + ssize_t i = 0; + int last_cmp_res = 0; - while (i < x->n - && (last_cmp_res = cmp(key, (const void*)(x->items + (i * elem_size)))) - > 0) { - i++; - } + while (i < x->n && + (last_cmp_res = cmp(key, (const void*)(x->items + (i * elem_size)))) > + 0) { + i++; + } - if ((ssize_t)i < x->n && last_cmp_res == 0) { - return (void*)(x->items + (i * elem_size)); - } else if (node_leaf(x)) { - return NULL; - } + if ((ssize_t)i < x->n && last_cmp_res == 0) { + return (void*)(x->items + (i * elem_size)); + } else if (node_leaf(x)) { + return NULL; + } - /* Assumption: ¬node_leaf(x) → x.children is allocated */ - return node_search(x->children[i], key, cmp, elem_size); + /* Assumption: ¬node_leaf(x) → x.children is allocated */ + return node_search(x->children[i], key, cmp, elem_size); } -int node_delete(struct node *x, - void *key, - int(*cmp)(const void *a, const void *b), - const ssize_t degree, - const size_t elem_size, void *(*alloc)(size_t), void (*dealloc)(void*)) { - /* Determine wether the key is in the node */ - int i = 0; /* Index of `k`, if found */ - int last_cmp_res = 0; - - while (i < x->n - && (last_cmp_res = cmp(key, (const void*)(x->items + (i * elem_size)))) - > 0) { - i++; - } +int node_delete(struct node* x, void* key, + int (*cmp)(const void* a, const void* b), const ssize_t degree, + const size_t elem_size, void* (*alloc)(size_t), + void (*dealloc)(void*)) { + /* Determine wether the key is in the node */ + int i = 0; /* Index of `k`, if found */ + int last_cmp_res = 0; - if (last_cmp_res == 0) { + while (i < x->n && + (last_cmp_res = cmp(key, (const void*)(x->items + (i * elem_size)))) > + 0) { + i++; + } - if (node_leaf(x)) { - /* 1. k ϵ x && node_leaf(x) */ - /* Delete k from x */ - int j = i; - while (j + 1 < x->n) { - const size_t offset_dst = elem_size * j; - const size_t offset_src = elem_size * (j+1); - memcpy((x->items) + offset_dst, - (x->items) + offset_src, - elem_size); - j++; - } - x->n--; - return 1; - } else { - /* 2. k ϵ x && !node_leaf(x) */ - /* let i be the index of k in x */ - /* 2a: if size(child[i]) >= t; find the largest k' in child[i] */ - /* replace k with k' */ - if (x->children[i]->n >= degree) { - struct node* y = x->children[i]; - byte *kk = alloc(elem_size); + if (last_cmp_res == 0) { - /* Find the predecessor, k' of k in y */ - { - struct node* tmp = y; - while (!node_leaf(tmp)) { - tmp = tmp->children[tmp->n-1]; - } + if (node_leaf(x)) { + /* 1. k ϵ x && node_leaf(x) */ + /* Delete k from x */ + int j = i; + while (j + 1 < x->n) { + const size_t offset_dst = elem_size * j; + const size_t offset_src = elem_size * (j + 1); + memcpy((x->items) + offset_dst, (x->items) + offset_src, elem_size); + j++; + } + x->n--; + return 1; + } else { + /* 2. k ϵ x && !node_leaf(x) */ + /* let i be the index of k in x */ + /* 2a: if size(child[i]) >= t; find the largest k' in child[i] */ + /* replace k with k' */ + if (x->children[i]->n >= degree) { + struct node* y = x->children[i]; + byte* kk = alloc(elem_size); - /* copy kk */ - memcpy(kk, tmp->items + elem_size * (tmp->n - 1), elem_size); - } + /* Find the predecessor, k' of k in y */ + { + struct node* tmp = y; + while (!node_leaf(tmp)) { + tmp = tmp->children[tmp->n - 1]; + } - /* Recursively delete kk from y */ - return node_delete(y, kk, cmp, degree, elem_size, alloc, dealloc); + /* copy kk */ + memcpy(kk, tmp->items + elem_size * (tmp->n - 1), elem_size); + } - /* replace k with kk */ - memcpy(x->items + (elem_size * i), - kk, - elem_size); + /* Recursively delete kk from y */ + return node_delete(y, kk, cmp, degree, elem_size, alloc, dealloc); - dealloc(kk); + /* replace k with kk */ + memcpy(x->items + (elem_size * i), kk, elem_size); - return 1; + dealloc(kk); - } else if (x->children[i+1]->n >= degree) { - struct node* z = x->children[i+1]; - byte *kk = alloc(elem_size); + return 1; - /* Find the successor, k' of k in z */ - { - struct node* tmp = z->children[0]; - while (!node_leaf(tmp)) { - tmp = tmp->children[0]; - } + } else if (x->children[i + 1]->n >= degree) { + struct node* z = x->children[i + 1]; + byte* kk = alloc(elem_size); - /* copy kk */ - memcpy(kk, tmp->items + elem_size * (tmp->n - 1), elem_size); - } + /* Find the successor, k' of k in z */ + { + struct node* tmp = z->children[0]; + while (!node_leaf(tmp)) { + tmp = tmp->children[0]; + } - /* Recursively delete kk from y */ - return node_delete(z, kk, cmp, degree, elem_size, alloc, dealloc); + /* copy kk */ + memcpy(kk, tmp->items + elem_size * (tmp->n - 1), elem_size); + } - /* replace k with kk */ - memcpy(x->items + (elem_size * i), - kk, - elem_size); + /* Recursively delete kk from y */ + return node_delete(z, kk, cmp, degree, elem_size, alloc, dealloc); - dealloc(kk); + /* replace k with kk */ + memcpy(x->items + (elem_size * i), kk, elem_size); - return 1; - } else { - /* Merge k and z into y */ - node_child_merge(x, i, elem_size, dealloc); + dealloc(kk); - /* recurse */ - return node_delete(x->children[i], key, cmp, degree, elem_size, alloc, dealloc); - } - } - } else if (node_leaf(x)) { - return 0; - } else { - /* 3. !(k ϵ x) */ + return 1; + } else { + /* Merge k and z into y */ + node_child_merge(x, i, elem_size, dealloc); - /* if x is a leaf, then it is not in the tree */ + /* recurse */ + return node_delete(x->children[i], key, cmp, degree, elem_size, alloc, + dealloc); + } + } + } else if (node_leaf(x)) { + return 0; + } else { + /* 3. !(k ϵ x) */ - struct node* y; - int ii; /* index of x.c[i] */ + /* if x is a leaf, then it is not in the tree */ - /* Determine x.c[i] that must contain k */ - /* if last cmp < 0, then the child must be in the left child of x.items[i]*/ - if (last_cmp_res < 0) ii = i; - /* Otherwise, it must be the very last child */ - else if (i < x->n) ii = i+1; - else ii = i; + struct node* y; + int ii; /* index of x.c[i] */ - y = x->children[ii]; + /* Determine x.c[i] that must contain k */ + /* if last cmp < 0, then the child must be in the left child of x.items[i]*/ + if (last_cmp_res < 0) ii = i; + /* Otherwise, it must be the very last child */ + else if (i < x->n) + ii = i + 1; + else + ii = i; - if (y->n < degree) { - /* we are left biased */ - if (ii > 0 && x->children[ii-1]->n >= degree) { - node_shift_right(x, ii-1, elem_size); + y = x->children[ii]; - } else if (ii < x->c - 1 && x->children[ii+1]->n >= degree) { - node_shift_left (x, ii, elem_size); + if (y->n < degree) { + /* we are left biased */ + if (ii > 0 && x->children[ii - 1]->n >= degree) { + node_shift_right(x, ii - 1, elem_size); - } else { - /* We need to determine wether we merge left or right, if possible */ - if (ii > 0) { - node_child_merge(x, ii - 1, elem_size, dealloc); - y = x->children[ii - 1]; - } - else if (ii < x->c - 1) { - node_child_merge(x, ii, elem_size, dealloc); - } - else { - perror("Cannot merge!"); - } - } + } else if (ii < x->c - 1 && x->children[ii + 1]->n >= degree) { + node_shift_left(x, ii, elem_size); - } + } else { + /* We need to determine wether we merge left or right, if possible */ + if (ii > 0) { + node_child_merge(x, ii - 1, elem_size, dealloc); + y = x->children[ii - 1]; + } else if (ii < x->c - 1) { + node_child_merge(x, ii, elem_size, dealloc); + } else { + perror("Cannot merge!"); + } + } + } - return node_delete(y, key, cmp, degree, elem_size, alloc, dealloc); - } - return 0; + return node_delete(y, key, cmp, degree, elem_size, alloc, dealloc); + } + return 0; } - /***********************/ /* Btree functionality */ /***********************/ -struct btree* btree_new(size_t elem_size, - size_t t, - int(*cmp)(const void *a, const void *b)) { - return btree_new_with_allocator(elem_size, t, cmp, malloc, free); +struct btree* btree_new(size_t elem_size, size_t t, + int (*cmp)(const void* a, const void* b)) { + return btree_new_with_allocator(elem_size, t, cmp, malloc, free); } -struct btree* btree_new_with_allocator(size_t elem_size, - size_t t, - int(*cmp)(const void *a, const void *b), - void *(*alloc)(size_t), - void (*dealloc)(void*)) { - struct btree *new_tree = alloc(sizeof(struct btree)); +struct btree* btree_new_with_allocator(size_t elem_size, size_t t, + int (*cmp)(const void* a, const void* b), + void* (*alloc)(size_t), + void (*dealloc)(void*)) { + struct btree* new_tree = alloc(sizeof(struct btree)); - new_tree->alloc = alloc; - new_tree->dealloc = dealloc; + new_tree->alloc = alloc; + new_tree->dealloc = dealloc; - new_tree->elem_size = elem_size; - new_tree->degree = t; + new_tree->elem_size = elem_size; + new_tree->degree = t; - new_tree->root = NULL; + new_tree->root = NULL; - new_tree->cmp = cmp; + new_tree->cmp = cmp; - return new_tree; + return new_tree; } -void btree_free(struct btree **btree) { - node_free(&((*btree)->root), (*btree)->elem_size, (*btree)->dealloc); - (*btree)->dealloc(*btree); - *btree = NULL; +void btree_free(struct btree** btree) { + node_free(&((*btree)->root), (*btree)->elem_size, (*btree)->dealloc); + (*btree)->dealloc(*btree); + *btree = NULL; } -void btree_insert(struct btree *btree, void *elem) { - if (btree == NULL) { - fputs("BTree error: Inserting into a NULL ptr!\n", stderr); - return; - } - if (elem == NULL) { - fputs("BTree error: Inserting NULL into a tree!\n", stderr); - return; - } - if (btree->root == NULL) { - btree->root = node_new(btree->degree, btree->elem_size); - if (btree->root == NULL) { - fputs("BTree error: Failed to create new root node!\n", stderr); - return; - } - node_insert(btree->root, - elem, - btree->degree, - btree->elem_size, - btree->cmp); - } - else { - btree->root = node_insert(btree->root, - elem, - btree->degree, - btree->elem_size, - btree->cmp); - } +void btree_insert(struct btree* btree, void* elem) { + if (btree == NULL) { + fputs("BTree error: Inserting into a NULL ptr!\n", stderr); + return; + } + if (elem == NULL) { + fputs("BTree error: Inserting NULL into a tree!\n", stderr); + return; + } + if (btree->root == NULL) { + btree->root = node_new(btree->degree, btree->elem_size); + if (btree->root == NULL) { + fputs("BTree error: Failed to create new root node!\n", stderr); + return; + } + node_insert(btree->root, elem, btree->degree, btree->elem_size, btree->cmp); + } else { + btree->root = node_insert(btree->root, elem, btree->degree, + btree->elem_size, btree->cmp); + } } -void* btree_search(struct btree *btree, void *elem) { - return node_search(btree->root, elem, btree->cmp, btree->elem_size); +void* btree_search(struct btree* btree, void* elem) { + return node_search(btree->root, elem, btree->cmp, btree->elem_size); } -int btree_delete(struct btree *btree, void *elem) { - struct node *newroot = btree->root; - int res = node_delete(btree->root, elem, btree->cmp, btree->degree, btree->elem_size, btree->alloc, btree->dealloc); - if (newroot->n == 0) { - if (node_leaf(newroot)) return res; - /* shrink the tree */ - struct node *newroot_p = newroot->children[0]; - btree->dealloc(newroot); - btree->root = newroot_p; - } - return res; +int btree_delete(struct btree* btree, void* elem) { + struct node* newroot = btree->root; + int res = node_delete(btree->root, elem, btree->cmp, btree->degree, + btree->elem_size, btree->alloc, btree->dealloc); + if (newroot->n == 0) { + if (node_leaf(newroot)) return res; + /* shrink the tree */ + struct node* newroot_p = newroot->children[0]; + btree->dealloc(newroot); + btree->root = newroot_p; + } + return res; } -void node_print(struct node *root, const size_t elem_size, const int indent, void (*print_elem)(const void*)) { - ssize_t i; - int t; +void node_print(struct node* root, const size_t elem_size, const int indent, + void (*print_elem)(const void*)) { + ssize_t i; + int t; - for (t = 0; t < indent - 1; t++) { fputs(" ┃ ", stdout); } - if (indent > 0) { fputs(" ┣┯", stdout); } - printf("printing node \x1b[33m%0lx\x1b[0m," - " c:%ld n:%ld\t\t" - "\x1b[30m%p\x1b[0m\n", - (unsigned long)((size_t)root % 0x10000), - root->c, - root->n, - (void*)root); - - if (node_leaf(root)) { - for (i = 0; i < root->n - 1; i++) { - const size_t ofst = i * elem_size; - for (t = 0; t < indent; t++) { fputs(" ┃├", stdout); } - print_elem(root->items + ofst); - } - for (t = 0; t < indent; t++) { fputs(" ┃└", stdout); } - print_elem(root->items + i * elem_size); - } else { - size_t ofst = 0; - for (i = 0; i < root->c - 1; i++) { - node_print(root->children[i], elem_size, indent + 1, print_elem); - for (t = 0; t < indent; t++) { fputs(" ┃ ", stdout); } - print_elem(root->items + ofst); - ofst += elem_size; - } - node_print(root->children[i], elem_size, indent + 1, print_elem); - } + for (t = 0; t < indent - 1; t++) { + fputs(" ┃ ", stdout); + } + if (indent > 0) { + fputs(" ┣┯", stdout); + } + printf("printing node \x1b[33m%0lx\x1b[0m," + " c:%ld n:%ld\t\t" + "\x1b[30m%p\x1b[0m\n", + (unsigned long)((size_t)root % 0x10000), root->c, root->n, + (void*)root); + if (node_leaf(root)) { + for (i = 0; i < root->n - 1; i++) { + const size_t ofst = i * elem_size; + for (t = 0; t < indent; t++) { + fputs(" ┃├", stdout); + } + print_elem(root->items + ofst); + } + for (t = 0; t < indent; t++) { + fputs(" ┃└", stdout); + } + print_elem(root->items + i * elem_size); + } else { + size_t ofst = 0; + for (i = 0; i < root->c - 1; i++) { + node_print(root->children[i], elem_size, indent + 1, print_elem); + for (t = 0; t < indent; t++) { + fputs(" ┃ ", stdout); + } + print_elem(root->items + ofst); + ofst += elem_size; + } + node_print(root->children[i], elem_size, indent + 1, print_elem); + } } -void btree_print(struct btree *btree, void (*print_elem)(const void*)) { - printf("BTRee: degree:%ld\n", btree->degree); - if (btree->root == NULL) return; - node_print(btree->root, btree->elem_size, 0, print_elem); +void btree_print(struct btree* btree, void (*print_elem)(const void*)) { + printf("BTRee: degree:%ld\n", btree->degree); + if (btree->root == NULL) return; + node_print(btree->root, btree->elem_size, 0, print_elem); } -void* btree_first(struct btree *btree) { - struct node *root; - if (btree == NULL) return NULL; - root = btree->root; +void* btree_first(struct btree* btree) { + struct node* root; + if (btree == NULL) return NULL; + root = btree->root; - if (root == NULL) return NULL; + if (root == NULL) return NULL; - while (!node_leaf(root)) root = root->children[0]; + while (!node_leaf(root)) root = root->children[0]; - if (root->n == 0) return NULL; - return root->items; /* Return first element */ + if (root->n == 0) return NULL; + return root->items; /* Return first element */ } -void* btree_last(struct btree *btree) { - struct node *root; +void* btree_last(struct btree* btree) { + struct node* root; - if (btree == NULL) return NULL; - root = btree->root; + if (btree == NULL) return NULL; + root = btree->root; - if (root == NULL) return NULL; + if (root == NULL) return NULL; - while (!node_leaf(root)) root = root->children[root->c]; + while (!node_leaf(root)) root = root->children[root->c]; - if (root->n == 0) return NULL; - return root->items + btree->elem_size * (root->n - 1); /* Return first element */ + if (root->n == 0) return NULL; + return root->items + + btree->elem_size * (root->n - 1); /* Return first element */ } -size_t btree_height(struct btree *btree) { - struct node *root; - size_t height = 0; +size_t btree_height(struct btree* btree) { + struct node* root; + size_t height = 0; - if (btree == NULL) return 0; - root = btree->root; + if (btree == NULL) return 0; + root = btree->root; - if (root == NULL) return 0; + if (root == NULL) return 0; - while (!node_leaf(root)) { - root = root->children[0]; - height++; - } + while (!node_leaf(root)) { + root = root->children[0]; + height++; + } - return height; + return height; } size_t u32_pow(size_t base, size_t exponent) { - size_t res = 1; - while (exponent > 0) { - res *= base; - exponent--; - } - return res; + size_t res = 1; + while (exponent > 0) { + res *= base; + exponent--; + } + return res; } - -size_t btree_size(struct btree *btree) { - return u32_pow(2 * btree->degree, btree_height(btree)) - 1; +size_t btree_size(struct btree* btree) { + return u32_pow(2 * btree->degree, btree_height(btree)) - 1; } +struct btree_iter_t* btree_iter_t_new(struct btree* tree) { + struct btree_iter_t* iter = NULL; -struct btree_iter_t* btree_iter_t_new(struct btree *tree) { - struct btree_iter_t *iter = NULL; + if (tree == NULL) return NULL; - if (tree == NULL) return NULL; + iter = (struct btree_iter_t*)tree->alloc(sizeof(struct btree_iter_t)); - iter = (struct btree_iter_t*)tree->alloc(sizeof(struct btree_iter_t)); + if (tree != NULL) { + iter->head = 0; + memset(iter->stack, 0, 512 * sizeof(struct node*)); - if (tree != NULL) { - iter->head = 0; - memset(iter->stack, 0, 512 * sizeof(struct node*)); - - iter->stack[iter->head].pos = 0; - iter->stack[iter->head].node = tree->root; - } else { - perror("Cannot instantiate iterator from null-pointer tree"); - } - return iter; + iter->stack[iter->head].pos = 0; + iter->stack[iter->head].node = tree->root; + } else { + perror("Cannot instantiate iterator from null-pointer tree"); + } + return iter; } +void btree_iter_t_reset(struct btree* tree, struct btree_iter_t** it) { + (*it)->head = 0; -void btree_iter_t_reset(struct btree *tree, struct btree_iter_t** it) { - (*it)->head = 0; - - (*it)->stack[0].pos = 0; - (*it)->stack[0].node = tree->root; + (*it)->stack[0].pos = 0; + (*it)->stack[0].node = tree->root; } +void* btree_iter(struct btree* tree, struct btree_iter_t* iter) { + register int pos = 0; + register ssize_t head = 0; + register ssize_t n = 0; -void* btree_iter(struct btree *tree, struct btree_iter_t *iter) { - register int pos = 0; - register ssize_t head = 0; - register ssize_t n = 0; + if (iter->stack[head].node == NULL) return NULL; - if (iter->stack[head].node == NULL) return NULL; + head = iter->head; + pos = iter->stack[head].pos; + n = iter->stack[head].node->n; - head = iter->head; - pos = iter->stack[head].pos; - n = iter->stack[head].node->n; - -#define BTREE_ITER_POP(it) { \ - iter->stack[head].pos = 0; \ - iter->stack[head].node = NULL; \ - iter->head--; head--; \ - iter->stack[head].pos++; \ - \ - pos = iter->stack[head].pos; \ - n = iter->stack[head].node->n; \ -} +#define BTREE_ITER_POP(it) \ + { \ + iter->stack[head].pos = 0; \ + iter->stack[head].node = NULL; \ + iter->head--; \ + head--; \ + iter->stack[head].pos++; \ + \ + pos = iter->stack[head].pos; \ + n = iter->stack[head].node->n; \ + } - /* Check if we have reached the end of a node. - * Take note of the difference of inequality in the if statement and - * following while */ + /* Check if we have reached the end of a node. + * Take note of the difference of inequality in the if statement and + * following while */ - /* Leafs are a special case, as, if the only node is the root node, we might - * want to exit */ - if (node_leaf(iter->stack[iter->head].node) && pos >= 2 * n) { - if (head == 0) return NULL; + /* Leafs are a special case, as, if the only node is the root node, we might + * want to exit */ + if (node_leaf(iter->stack[iter->head].node) && pos >= 2 * n) { + if (head == 0) return NULL; - /* Pop, if so */ - else BTREE_ITER_POP(iter); - } + /* Pop, if so */ + else + BTREE_ITER_POP(iter); + } - /* Otherwise, pop while we have reached the end of a node */ - while (pos > 2 * n) { - if (head == 0) return NULL; + /* Otherwise, pop while we have reached the end of a node */ + while (pos > 2 * n) { + if (head == 0) return NULL; - /* Pop, if so */ - else BTREE_ITER_POP(iter); - } + /* Pop, if so */ + else + BTREE_ITER_POP(iter); + } #undef BTREE_ITER_POP - /* On evens, we decent into children */ - if (!node_leaf(iter->stack[head].node)) { - if (pos % 2 == 0) { - /* push child node onto iter->stack */ - iter->stack[head + 1].pos = 0; - iter->stack[head + 1].node = iter->stack[head].node->children[pos / 2]; - iter->head++; head++; + /* On evens, we decent into children */ + if (!node_leaf(iter->stack[head].node)) { + if (pos % 2 == 0) { + /* push child node onto iter->stack */ + iter->stack[head + 1].pos = 0; + iter->stack[head + 1].node = iter->stack[head].node->children[pos / 2]; + iter->head++; + head++; - /* Decent all the way to the left, if pos == 0 */ - while (!node_leaf(iter->stack[iter->head].node)) { - iter->stack[head + 1].pos = 0; - iter->stack[head + 1].node = iter->stack[head].node->children[0]; - iter->head++; head++; - } - } - } + /* Decent all the way to the left, if pos == 0 */ + while (!node_leaf(iter->stack[iter->head].node)) { + iter->stack[head + 1].pos = 0; + iter->stack[head + 1].node = iter->stack[head].node->children[0]; + iter->head++; + head++; + } + } + } - /* Finally, update index and return a value */ - if (node_leaf(iter->stack[head].node)) { - iter->stack[head].pos += 2; - pos = iter->stack[head].pos; - } - else { - iter->stack[head].pos++; - pos = iter->stack[head].pos; - } + /* Finally, update index and return a value */ + if (node_leaf(iter->stack[head].node)) { + iter->stack[head].pos += 2; + pos = iter->stack[head].pos; + } else { + iter->stack[head].pos++; + pos = iter->stack[head].pos; + } - return iter->stack[head].node->items + tree->elem_size * ( (pos - 1) / 2 ); + return iter->stack[head].node->items + tree->elem_size * ((pos - 1) / 2); } diff --git a/src/dltools.c b/src/dltools.c index de7c83b..2a52f53 100644 --- a/src/dltools.c +++ b/src/dltools.c @@ -1,62 +1,58 @@ #include <stdbool.h> #include <stdlib.h> -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - /* include winapi */ +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +/* include winapi */ #else #include <dlfcn.h> #endif -#include <engine/logging.h> #include <engine/dltools.h> +#include <engine/logging.h> -bool -dynamic_library_close(void* shared_library) { -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - return true; +bool dynamic_library_close(void* shared_library) { +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + return true; #else - return dlclose(shared_library) == 0; + return dlclose(shared_library) == 0; #endif } -void* -dynamic_library_open(const char *library_path) { -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - return NULL; +void* dynamic_library_open(const char* library_path) { +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + return NULL; #else - return dlopen(library_path, RTLD_NOW); + return dlopen(library_path, RTLD_NOW); #endif } char* dynamic_library_get_error(void) { -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - return "unsupported on windows"; +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + return "unsupported on windows"; #else - return dlerror(); + return dlerror(); #endif } -void* -dynamic_library_reload(void* shared_library, const char *library_path) { - void* library_address = NULL; - if (!dynamic_library_close(shared_library)) { - ERROR("Failed to close shared library: %s", dynamic_library_get_error()); - ERROR("Reloading dynamic library failed."); - return library_address; - } - if ((library_address = dynamic_library_open(library_path)) == NULL) { - ERROR("Failed to open shared library: %s", dynamic_library_get_error()); - ERROR("Reloading dynamic library %s failed.", library_path); - } - return library_address; +void* dynamic_library_reload(void* shared_library, const char* library_path) { + void* library_address = NULL; + if (!dynamic_library_close(shared_library)) { + ERROR("Failed to close shared library: %s", dynamic_library_get_error()); + ERROR("Reloading dynamic library failed."); + return library_address; + } + if ((library_address = dynamic_library_open(library_path)) == NULL) { + ERROR("Failed to open shared library: %s", dynamic_library_get_error()); + ERROR("Reloading dynamic library %s failed.", library_path); + } + return library_address; } - -void* -dynamic_library_get_symbol(void *restrict shared_library, const char *symbol) { -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - return NULL; +void* dynamic_library_get_symbol(void* restrict shared_library, + const char* symbol) { +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) + return NULL; #else - return dlsym(shared_library, symbol); + return dlsym(shared_library, symbol); #endif } diff --git a/src/engine.c b/src/engine.c index ecc6ec1..0bcb8da 100644 --- a/src/engine.c +++ b/src/engine.c @@ -1,40 +1,39 @@ -#include <stdlib.h> #include <errno.h> +#include <stdlib.h> #include <string.h> #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> #include <SDL2/SDL_ttf.h> -#if defined (_WIN32) || defined (__WIN32__) || defined (WIN32) - /* include winapi */ -#elif defined (__APPLE__) - /* mac includes */ -#elif defined (__linux) || defined (__linux__) || defined (linux) +#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) +/* include winapi */ +#elif defined(__APPLE__) +/* mac includes */ +#elif defined(__linux) || defined(__linux__) || defined(linux) #include <unistd.h> #endif - #define ENGINE_INTERNALS -#include <engine/engine.h> #include <engine/btree.h> +#include <engine/engine.h> #include <engine/hashmap.h> #include <engine/list.h> #include <engine/state.h> -//#include <states/titlescreen.h> -//#include <states/gameover.h> +// #include <states/titlescreen.h> +// #include <states/gameover.h> #define DEFAULT_NUM_PROCS 8 #ifdef BENCHMARK -#define BENCHEXPR(timevar, expr) { \ - u32 t = SDL_GetTicks(); \ - expr \ - timevar += SDL_GetTicks() - t; \ -} +#define BENCHEXPR(timevar, expr) \ + { \ + u32 t = SDL_GetTicks(); \ + expr timevar += SDL_GetTicks() - t; \ + } extern i32 drawcall_len; @@ -42,24 +41,22 @@ extern i32 drawcall_len; #define BENCHEXPR(timevar, expr) expr #endif -static u64 FPS_CAP = 50; -Platform *GLOBAL_PLATFORM = NULL; +static u64 FPS_CAP = 50; +Platform* GLOBAL_PLATFORM = NULL; -input_callback_t *callbacks[128]; +input_callback_t* callbacks[128]; usize callbacks_len; -i32 nproc(void) { - return SDL_GetCPUCount(); -} +i32 nproc(void) { return SDL_GetCPUCount(); } -i32 cmp_int(const void *a, const void *b) { - const i32 *x = a; - const i32 *y = b; +i32 cmp_int(const void* a, const void* b) { + const i32* x = a; + const i32* y = b; - return *x - *y; + return *x - *y; } -v2_i32 get_canvas_size(SDL_Renderer *renderer) { +v2_i32 get_canvas_size(SDL_Renderer* renderer) { v2_i32 realsize; SDL_GetRendererOutputSize(renderer, &(realsize.x), &(realsize.y)); @@ -67,707 +64,712 @@ v2_i32 get_canvas_size(SDL_Renderer *renderer) { return realsize; } -Texture *load_texture(SDL_Renderer *render, const TextureSpec *ts) { - SDL_Texture* new_texture = NULL; - SDL_Surface* loaded_surface = NULL; - Texture *t = NULL; +Texture* load_texture(SDL_Renderer* render, const TextureSpec* ts) { + SDL_Texture* new_texture = NULL; + SDL_Surface* loaded_surface = NULL; + Texture* t = NULL; - if (ts == NULL) { - ERROR("Invalid TextureSpec\n"); - return NULL; - } + if (ts == NULL) { + ERROR("Invalid TextureSpec\n"); + return NULL; + } - loaded_surface = IMG_Load(ts->path); - if (loaded_surface == NULL) { - ERROR("Unable to load image \"%s\"!\n", ts->path); - ERROR("SDL_image Error: %s\n", IMG_GetError()); - return NULL; - } + loaded_surface = IMG_Load(ts->path); + if (loaded_surface == NULL) { + ERROR("Unable to load image \"%s\"!\n", ts->path); + ERROR("SDL_image Error: %s\n", IMG_GetError()); + return NULL; + } - const i32 tw = loaded_surface->w / ts->width; + const i32 tw = loaded_surface->w / ts->width; - SDL_SetColorKey(loaded_surface, SDL_TRUE, - SDL_MapRGB(loaded_surface->format, 0xFF, 0x00, 0xFF)); + SDL_SetColorKey(loaded_surface, SDL_TRUE, + SDL_MapRGB(loaded_surface->format, 0xFF, 0x00, 0xFF)); - /*Create texture from surface pixels */ - new_texture = SDL_CreateTextureFromSurface(render, loaded_surface); - if (new_texture == NULL) { - ERROR("Unable to create texture from \"%s\"!\n", ts->path); - ERROR("SDL Error: %s\n", SDL_GetError()); - } + /*Create texture from surface pixels */ + new_texture = SDL_CreateTextureFromSurface(render, loaded_surface); + if (new_texture == NULL) { + ERROR("Unable to create texture from \"%s\"!\n", ts->path); + ERROR("SDL Error: %s\n", SDL_GetError()); + } - /*Get rid of old loaded surface */ - SDL_FreeSurface(loaded_surface); + /*Get rid of old loaded surface */ + SDL_FreeSurface(loaded_surface); - t = (Texture*)malloc(sizeof(Texture)); - t->texture = new_texture; - /* Assigning const value */ - *(i32*)&t->tilesize = tw; - *(i32*)&t->width = ts->width; - *(i32*)&t->height = ts->height; + t = (Texture*)malloc(sizeof(Texture)); + t->texture = new_texture; + /* Assigning const value */ + *(i32*)&t->tilesize = tw; + *(i32*)&t->width = ts->width; + *(i32*)&t->height = ts->height; - return t; + return t; } -void engine_update_window(Window *w, SDL_WindowEvent *e) { - switch (e->event) { - case SDL_WINDOWEVENT_NONE: - case SDL_WINDOWEVENT_SHOWN: - case SDL_WINDOWEVENT_HIDDEN: - case SDL_WINDOWEVENT_EXPOSED: - case SDL_WINDOWEVENT_MOVED: - break; - case SDL_WINDOWEVENT_RESIZED: - w->windowsize = get_canvas_size(w->renderer); - LOG("Resized window to %dx%d", w->windowsize.x, w->windowsize.y); - ui_resolve_constraints(); - if (w->game_w != NULL && w->game_h != NULL) { - *w->game_h = w->windowsize.x; - *w->game_w = w->windowsize.y; - } - break; - case SDL_WINDOWEVENT_SIZE_CHANGED: - case SDL_WINDOWEVENT_MINIMIZED: - case SDL_WINDOWEVENT_MAXIMIZED: - case SDL_WINDOWEVENT_RESTORED: - case SDL_WINDOWEVENT_ENTER: - case SDL_WINDOWEVENT_LEAVE: - case SDL_WINDOWEVENT_FOCUS_GAINED: - case SDL_WINDOWEVENT_FOCUS_LOST: - case SDL_WINDOWEVENT_CLOSE: - case SDL_WINDOWEVENT_TAKE_FOCUS: - case SDL_WINDOWEVENT_HIT_TEST: - break; - default: - WARN("Unhandled window event 0x%04x", (i32)e->event); - break; - } - return; +void engine_update_window(Window* w, SDL_WindowEvent* e) { + switch (e->event) { + case SDL_WINDOWEVENT_NONE: + case SDL_WINDOWEVENT_SHOWN: + case SDL_WINDOWEVENT_HIDDEN: + case SDL_WINDOWEVENT_EXPOSED: + case SDL_WINDOWEVENT_MOVED: + break; + case SDL_WINDOWEVENT_RESIZED: + w->windowsize = get_canvas_size(w->renderer); + LOG("Resized window to %dx%d", w->windowsize.x, w->windowsize.y); + ui_resolve_constraints(); + if (w->game_w != NULL && w->game_h != NULL) { + *w->game_h = w->windowsize.x; + *w->game_w = w->windowsize.y; + } + break; + case SDL_WINDOWEVENT_SIZE_CHANGED: + case SDL_WINDOWEVENT_MINIMIZED: + case SDL_WINDOWEVENT_MAXIMIZED: + case SDL_WINDOWEVENT_RESTORED: + case SDL_WINDOWEVENT_ENTER: + case SDL_WINDOWEVENT_LEAVE: + case SDL_WINDOWEVENT_FOCUS_GAINED: + case SDL_WINDOWEVENT_FOCUS_LOST: + case SDL_WINDOWEVENT_CLOSE: + case SDL_WINDOWEVENT_TAKE_FOCUS: + case SDL_WINDOWEVENT_HIT_TEST: + break; + default: + WARN("Unhandled window event 0x%04x", (i32)e->event); + break; + } + return; } -Platform *engine_init( - const char *windowtitle, - v2_i32 windowsize, - const f32 render_scale, - const u32 flags, - const usize initial_memory, - const FontSpec *fonts[], - const TextureSpec *textures[]) { +Platform* engine_init(const char* windowtitle, v2_i32 windowsize, + const f32 render_scale, const u32 flags, + const usize initial_memory, const FontSpec* fonts[], + const TextureSpec* textures[]) { #ifdef BENCHMARK - u32 init_start = SDL_GetTicks(); + u32 init_start = SDL_GetTicks(); #endif -#if defined (__linux) || defined (__linux__) || defined (linux) - { - pid_t pid = getpid(); - INFO("Starting with pid %lu", pid); - } +#if defined(__linux) || defined(__linux__) || defined(linux) + { + pid_t pid = getpid(); + INFO("Starting with pid %lu", pid); + } #endif - Platform *p = (Platform*)malloc(sizeof(Platform)); - Window *w = (Window*)malloc(sizeof(Window)); - SDL_Window *window = NULL; - SDL_Renderer *renderer = NULL; - - /* initialize resources */ - struct Resources *resources = (struct Resources*)malloc(sizeof(struct Resources)); - resources->textures_len = 0; - resources->fonts_len = 0; - resources->texturepaths_len = 0; - resources->fontpaths_len = 0; - resources->texture_paths = NULL; - resources->font_paths = NULL; - resources->textures = NULL; - resources->fonts = NULL; - + Platform* p = (Platform*)malloc(sizeof(Platform)); + Window* w = (Window*)malloc(sizeof(Window)); + SDL_Window* window = NULL; + SDL_Renderer* renderer = NULL; - { /* Init subsystems */ - INFO_("initializing sdl..."); - if (SDL_Init(SDL_INIT_VIDEO) < 0) { - ERROR("failed to initialize sdl: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else printf("ok\n"); + /* initialize resources */ + struct Resources* resources = + (struct Resources*)malloc(sizeof(struct Resources)); + resources->textures_len = 0; + resources->fonts_len = 0; + resources->texturepaths_len = 0; + resources->fontpaths_len = 0; + resources->texture_paths = NULL; + resources->font_paths = NULL; + resources->textures = NULL; + resources->fonts = NULL; - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); - SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); + { /* Init subsystems */ + INFO_("initializing sdl..."); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + ERROR("failed to initialize sdl: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } else + printf("ok\n"); - INFO_("creating window..."); - window = SDL_CreateWindow(windowtitle, - SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, - windowsize.x, windowsize.y, - SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS | SDL_WINDOW_MOUSE_FOCUS | flags); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); - if (window == NULL) { - ERROR("failed to create window: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else printf("ok\n"); + INFO_("creating window..."); + window = SDL_CreateWindow( + windowtitle, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, + windowsize.x, windowsize.y, + SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_INPUT_FOCUS | + SDL_WINDOW_MOUSE_FOCUS | flags); - INFO_("creating renderer..."); - renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); - if (renderer == NULL) { - ERROR("failed to create renderer: %s\n", SDL_GetError()); - exit(EXIT_FAILURE); - } else printf("ok\n"); + if (window == NULL) { + ERROR("failed to create window: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } else + printf("ok\n"); - INFO_("initializing sdl_image..."); - if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) { - ERROR("failed to initialize sdl_image png support\n"); - exit(EXIT_FAILURE); - } else printf("ok\n"); + INFO_("creating renderer..."); + renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED); + if (renderer == NULL) { + ERROR("failed to create renderer: %s\n", SDL_GetError()); + exit(EXIT_FAILURE); + } else + printf("ok\n"); - INFO_("initializing sdl_ttf..."); - if (TTF_Init() == -1) { - ERROR("failed to initialize sdl_ttf: %s\n", TTF_GetError()); - exit(EXIT_FAILURE); - } else printf("ok\n"); - } + INFO_("initializing sdl_image..."); + if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) { + ERROR("failed to initialize sdl_image png support\n"); + exit(EXIT_FAILURE); + } else + printf("ok\n"); + INFO_("initializing sdl_ttf..."); + if (TTF_Init() == -1) { + ERROR("failed to initialize sdl_ttf: %s\n", TTF_GetError()); + exit(EXIT_FAILURE); + } else + printf("ok\n"); + } - { /* Resource loading */ + { /* Resource loading */ - /* Count resources */ - usize n_textures = 0; - usize n_fonts = 0; + /* Count resources */ + usize n_textures = 0; + usize n_fonts = 0; - if (textures != NULL) while (textures[n_textures] != NULL) n_textures++; - if (fonts != NULL) while (fonts[n_fonts] != NULL) n_fonts++; + if (textures != NULL) + while (textures[n_textures] != NULL) n_textures++; + if (fonts != NULL) + while (fonts[n_fonts] != NULL) n_fonts++; - INFO("Number of textures: "TERM_COLOR_YELLOW"%d"TERM_COLOR_RESET, n_textures); - INFO("Number of fonts: "TERM_COLOR_YELLOW"%d"TERM_COLOR_RESET, n_fonts); + INFO("Number of textures: " TERM_COLOR_YELLOW "%d" TERM_COLOR_RESET, + n_textures); + INFO("Number of fonts: " TERM_COLOR_YELLOW "%d" TERM_COLOR_RESET, n_fonts); + /* Save the textures and fonts, if we should need to reload them later */ + resources->texture_paths = (TextureSpec**)textures; + resources->font_paths = (FontSpec**)fonts; - /* Save the textures and fonts, if we should need to reload them later */ - resources->texture_paths = (TextureSpec**)textures; - resources->font_paths = (FontSpec**)fonts; + /* Allocate memory for textures and fonts */ + resources->textures = (Texture**)malloc(sizeof(Texture*) * n_textures); + resources->fonts = (TTF_Font**)malloc(sizeof(TTF_Font*) * n_fonts); + resources->textures_size = n_textures; - /* Allocate memory for textures and fonts */ - resources->textures = (Texture**)malloc(sizeof(Texture*) * n_textures); - resources->fonts = (TTF_Font**)malloc(sizeof(TTF_Font*) * n_fonts); - resources->textures_size = n_textures; + for (usize i = 0; i < n_textures; i++) resources->textures[i] = NULL; + for (usize i = 0; i < n_fonts; i++) resources->fonts[i] = NULL; - for (usize i = 0; i < n_textures; i++) resources->textures[i] = NULL; - for (usize i = 0; i < n_fonts; i++) resources->fonts[i] = NULL; + /* Load textures */ + for (usize i = 0; i < n_textures; i++) { + Texture* t = NULL; + INFO_("loading texture \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET + "\"...", + textures[i]->path); - /* Load textures */ - for (usize i = 0; i < n_textures; i++) { - Texture *t = NULL; - INFO_("loading texture \"" - TERM_COLOR_YELLOW"%s"TERM_COLOR_RESET - "\"...", textures[i]->path); + t = load_texture(renderer, textures[i]); + if (t == NULL) { + puts(""); + ERROR("failed to load texture\n"); + exit(EXIT_FAILURE); + } - t = load_texture(renderer, textures[i]); - if (t == NULL) { - puts(""); - ERROR("failed to load texture\n"); - exit(EXIT_FAILURE); - } + if (t->tilesize < 8) { + puts(""); + ERROR("texture too small!\n"); + exit(EXIT_FAILURE); + } - if (t->tilesize < 8) { - puts(""); - ERROR("texture too small!\n"); - exit(EXIT_FAILURE); - } + if (t->texture == NULL) { + puts(""); + ERROR("failed to load texture\n"); + } else { + printf("ok\n"); + resources->textures[i] = t; + resources->textures_len++; + } + } - if (t->texture == NULL) { - puts(""); - ERROR("failed to load texture\n"); - } else { - printf("ok\n"); - resources->textures[i] = t; - resources->textures_len++; - } - } + /* Load fonts */ + for (usize i = 0; i < n_fonts; i++) { + INFO_("loading font \"" TERM_COLOR_YELLOW "%s" TERM_COLOR_RESET "\"...", + fonts[i]->font_path); - /* Load fonts */ - for (usize i = 0; i < n_fonts; i++) { - INFO_("loading font \"" - TERM_COLOR_YELLOW"%s"TERM_COLOR_RESET - "\"...", fonts[i]->font_path); + TTF_Font* font = TTF_OpenFont(fonts[i]->font_path, fonts[i]->ptsize); + if (!font) { + ERROR("failed to load font: %s\n", TTF_GetError()); + } else { + printf("ok\n"); + resources->fonts[i] = font; + resources->fonts_len++; + } + } - TTF_Font *font = TTF_OpenFont(fonts[i]->font_path - , fonts[i]->ptsize); - if (!font) { - ERROR("failed to load font: %s\n", TTF_GetError()); - } else { - printf("ok\n"); - resources->fonts[i] = font; - resources->fonts_len++; - } - } + if (resources->textures_len != n_textures) { + WARN("Done. %d/%d textures loaded.", resources->textures_len, n_textures); + } else { + INFO("Done. All %d textures loaded.", n_textures); + } - if (resources->textures_len != n_textures) { - WARN("Done. %d/%d textures loaded.", resources->textures_len, n_textures); - } else { - INFO("Done. All %d textures loaded.", n_textures); - } + if (resources->fonts_len != n_fonts) { + WARN("Done. %d/%d fonts loaded.", resources->fonts_len, n_fonts); + } else { + INFO("Done. All %d fonts loaded.", n_fonts); + } - if (resources->fonts_len != n_fonts) { - WARN("Done. %d/%d fonts loaded.", resources->fonts_len, n_fonts); - } else { - INFO("Done. All %d fonts loaded.", n_fonts); - } + resources->texturepaths_len = resources->textures_len; + resources->fontpaths_len = resources->fonts_len; + } - resources->texturepaths_len = resources->textures_len; - resources->fontpaths_len = resources->fonts_len; + { /* Adjust window and such */ + /* Set actual windowsize, which might be forced by OS */ + SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); + INFO("Adjusting window size..."); + windowsize = get_canvas_size(renderer); - } + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + INFO("Windowsize: <%d,%d>", windowsize.x, windowsize.y); + } - { /* Adjust window and such */ - /* Set actual windowsize, which might be forced by OS */ - SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); - INFO("Adjusting window size..."); - windowsize = get_canvas_size(renderer); + w->renderer = renderer; + w->window = window; + w->render_scale = render_scale; + w->windowsize = windowsize; + w->game_w = NULL; + w->game_h = NULL; - SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND); + p->data = (void*)resources; + p->data_len = sizeof(struct Resources); + p->window = w; + p->quit = false; - INFO("Windowsize: <%d,%d>", windowsize.x, windowsize.y); - } + p->frame = 0; + p->fps_target = 60; - w->renderer = renderer; - w->window = window; - w->render_scale = render_scale; - w->windowsize = windowsize; - w->game_w = NULL; - w->game_h = NULL; + p->mem = memory_new(initial_memory); - p->data = (void*)resources; - p->data_len = sizeof(struct Resources); - p->window = w; - p->quit = false; + /* Getting the mouse coords now resolves the issue where a click "isn't + * registered" when the mouse isn't moved before the user clicks */ + SDL_GetMouseState(&p->mouse_pos.x, &p->mouse_pos.y); - p->frame = 0; - p->fps_target = 60; + p->mousedown = (v2_i32){-1, -1}; + p->mouseup = (v2_i32){-1, -1}; - p->mem = memory_new(initial_memory); + p->mouse_lclick = false; + p->mouse_rclick = false; - /* Getting the mouse coords now resolves the issue where a click "isn't - * registered" when the mouse isn't moved before the user clicks */ - SDL_GetMouseState(&p->mouse_pos.x, &p->mouse_pos.y); + p->camera_x = 0; + p->camera_y = 0; - p->mousedown = (v2_i32){-1, -1}; - p->mouseup = (v2_i32){-1, -1}; + p->edit_text = NULL; + p->edit_pos = 0; - p->mouse_lclick = false; - p->mouse_rclick = false; + p->bindings = NULL; + p->bindings_sz = 0; + p->bindings_len = 0; - p->camera_x = 0; - p->camera_y = 0; - - p->edit_text = NULL; - p->edit_pos = 0; - - p->bindings = NULL; - p->bindings_sz = 0; - p->bindings_len = 0; - - // TODO: Add global bindings + // TODO: Add global bindings #ifdef BENCHMARK - u32 init_stop = SDL_GetTicks(); - INFO("Initialization took %dms", init_stop - init_start); + u32 init_stop = SDL_GetTicks(); + INFO("Initialization took %dms", init_stop - init_start); #endif - INFO("Available cores: %d", nproc()); - - GLOBAL_PLATFORM = p; + INFO("Available cores: %d", nproc()); + GLOBAL_PLATFORM = p; #ifdef DAW_BUILD_HOTRELOAD -#define State(name) \ -if (!State_reload(STATE_##name, p->bindings, p->bindings_len)) { \ - ERROR("Failed to reload shared object file for state %s", #name ); \ -}; +#define State(name) \ + if (!State_reload(STATE_##name, p->bindings, p->bindings_len)) { \ + ERROR("Failed to reload shared object file for state %s", #name); \ + }; #include <states/list_of_states.h> #undef State #endif - return p; + return p; } -i32 engine_run(Platform *p, StateType initial_state) { - if (p == NULL) { - ERROR("Platform is uninitialized.\n"); - INFO("initialize with `engine_init`"); - return -1; - } +i32 engine_run(Platform* p, StateType initial_state) { + if (p == NULL) { + ERROR("Platform is uninitialized.\n"); + INFO("initialize with `engine_init`"); + return -1; + } - memory* mem = p->mem; + memory* mem = p->mem; - StateType state = initial_state; + StateType state = initial_state; - { - u32 state_init_time = SDL_GetTicks(); - State_init(state, mem); - INFO("Initializing state \"%s\" took %ldms", StateTypeStr[state], SDL_GetTicks() - state_init_time); - } + { + u32 state_init_time = SDL_GetTicks(); + State_init(state, mem); + INFO("Initializing state \"%s\" took %ldms", StateTypeStr[state], + SDL_GetTicks() - state_init_time); + } - u32 time = SDL_GetTicks(); + u32 time = SDL_GetTicks(); - // Update ticks - u64 ticks = 0; + // Update ticks + u64 ticks = 0; - /* Profiling values */ + /* Profiling values */ #ifdef BENCHMARK - u64 profile_tick_counter = 0; - //u64 profile_slack = 0; - u64 profile_rendering = 0; - u64 profile_gameloop = 0; - u64 profile_input = 0; - u64 profile_input_handling = 0; - u64 profile_num_drawcalls = 0; - u32 profile_interval_timer = time; - const u32 profile_interval_ms = 5000; - const f32 profile_interval_scale = (f32)(profile_interval_ms) / 100.0f; + u64 profile_tick_counter = 0; + // u64 profile_slack = 0; + u64 profile_rendering = 0; + u64 profile_gameloop = 0; + u64 profile_input = 0; + u64 profile_input_handling = 0; + u64 profile_num_drawcalls = 0; + u32 profile_interval_timer = time; + const u32 profile_interval_ms = 5000; + const f32 profile_interval_scale = (f32)(profile_interval_ms) / 100.0f; #endif - const f64 frame_interval = 1000.0 / FPS_CAP; + const f64 frame_interval = 1000.0 / FPS_CAP; - StateType (*update_func)(void*) = State_updateFunc(state); + StateType (*update_func)(void*) = State_updateFunc(state); - /* Main loop */ - do { - const u32 now = SDL_GetTicks(); - const u64 dt = now - time; - time = now; - /* Wait frame_interval */ - if (dt < frame_interval) { + /* Main loop */ + do { + const u32 now = SDL_GetTicks(); + const u64 dt = now - time; + time = now; + /* Wait frame_interval */ + if (dt < frame_interval) { #ifndef BENCHMARK - SDL_Delay(frame_interval - dt); + SDL_Delay(frame_interval - dt); #else - /* We want to know how much time is spend sleeping */ - //profile_slack += frame_interval - dt; + /* We want to know how much time is spend sleeping */ + // profile_slack += frame_interval - dt; #endif - } + } #ifdef BENCHMARK - if (time - profile_interval_timer > profile_interval_ms) { - /* Ticks/frames since last measurement */ - u32 fps = (ticks - profile_tick_counter) / profile_interval_scale; - u64 drawcalls = profile_num_drawcalls / profile_interval_scale / fps; + if (time - profile_interval_timer > profile_interval_ms) { + /* Ticks/frames since last measurement */ + u32 fps = (ticks - profile_tick_counter) / profile_interval_scale; + u64 drawcalls = profile_num_drawcalls / profile_interval_scale / fps; - u32 sum = - + profile_rendering - //+ profile_slack - + profile_input - + profile_input_handling - + profile_gameloop - ; + u32 sum = +profile_rendering + //+ profile_slack + + profile_input + profile_input_handling + profile_gameloop; - - /* Log fps and slack percentage */ - LOG("fps:%d\t" - "rendering:%.2f%%\t" - //"slack:%.2f%%\t" - "input:%.2f%% (%.2f%%)\t" - "gameloop:%.2f%%\t" - "unaccounted:%llu / %llu ms\t" - "avg drawcalls:%llu", - fps, - 100.0f * (f32)profile_rendering / (f32)sum, - //100.0f * (f32)profile_slack / (f32)sum, - 100.0f * (f32)profile_input / (f32)sum, - 100.0f * (f32)profile_input_handling / (f32)sum, - 100.0f * (f32)profile_gameloop / (f32)sum, - time - profile_interval_timer - sum, sum, - drawcalls); - /* Reset values */ - profile_tick_counter = ticks; - profile_interval_timer = time; - //profile_slack = 0; - profile_rendering = 0; - profile_gameloop = 0; - profile_input = 0; - profile_input_handling = 0; - profile_num_drawcalls = 0; - } + /* Log fps and slack percentage */ + LOG("fps:%d\t" + "rendering:%.2f%%\t" + //"slack:%.2f%%\t" + "input:%.2f%% (%.2f%%)\t" + "gameloop:%.2f%%\t" + "unaccounted:%llu / %llu ms\t" + "avg drawcalls:%llu", + fps, 100.0f * (f32)profile_rendering / (f32)sum, + // 100.0f * (f32)profile_slack / (f32)sum, + 100.0f * (f32)profile_input / (f32)sum, + 100.0f * (f32)profile_input_handling / (f32)sum, + 100.0f * (f32)profile_gameloop / (f32)sum, + time - profile_interval_timer - sum, sum, drawcalls); + /* Reset values */ + profile_tick_counter = ticks; + profile_interval_timer = time; + // profile_slack = 0; + profile_rendering = 0; + profile_gameloop = 0; + profile_input = 0; + profile_input_handling = 0; + profile_num_drawcalls = 0; + } #endif - /* Events */ - BENCHEXPR(profile_input, { - - if (p->mouse_lclick) { - p->mouseup.x = -1; - p->mouseup.y = -1; - p->mousedown.x = -1; - p->mousedown.y = -1; - p->mouse_lclick = false; - } - if (p->mouse_rclick) { - p->mouse_rclick = false; - } + /* Events */ + BENCHEXPR(profile_input, { + if (p->mouse_lclick) { + p->mouseup.x = -1; + p->mouseup.y = -1; + p->mousedown.x = -1; + p->mousedown.y = -1; + p->mouse_lclick = false; + } + if (p->mouse_rclick) { + p->mouse_rclick = false; + } - /* Window events */ - SDL_Event e[8]; - i32 num_events; - SDL_PumpEvents(); - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_SYSWMEVENT)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_QUIT: - state = STATE_quit; - break; - case SDL_WINDOWEVENT: - engine_update_window(p->window, &e[i].window); - break; - default: - WARN("Unhandled event 0x%04x", (i32)e[i].type); - } - } - } + /* Window events */ + SDL_Event e[8]; + i32 num_events; + SDL_PumpEvents(); + while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_FIRSTEVENT, + SDL_SYSWMEVENT)) > 0) { + for (i32 i = 0; i < num_events; i++) { + switch (e[i].type) { + case SDL_QUIT: + state = STATE_quit; + break; + case SDL_WINDOWEVENT: + engine_update_window(p->window, &e[i].window); + break; + default: + WARN("Unhandled event 0x%04x", (i32)e[i].type); + } + } + } - /* Mouse events */ - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEWHEEL)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_MOUSEWHEEL: break; - case SDL_MOUSEMOTION: - { - SDL_MouseMotionEvent m = e[i].motion; - /* In case of a first-person game, use xrel and yrel */ - p->mouse_pos.x = m.x; - p->mouse_pos.y = m.y; - } - break; - case SDL_MOUSEBUTTONUP: - { - switch (e[i].button.button) { - case SDL_BUTTON_LEFT: - p->mouseup = p->mouse_pos; + /* Mouse events */ + while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_MOUSEMOTION, + SDL_MOUSEWHEEL)) > 0) { + for (i32 i = 0; i < num_events; i++) { + switch (e[i].type) { + case SDL_MOUSEWHEEL: + break; + case SDL_MOUSEMOTION: { + SDL_MouseMotionEvent m = e[i].motion; + /* In case of a first-person game, use xrel and yrel */ + p->mouse_pos.x = m.x; + p->mouse_pos.y = m.y; + } break; + case SDL_MOUSEBUTTONUP: { + switch (e[i].button.button) { + case SDL_BUTTON_LEFT: + p->mouseup = p->mouse_pos; - p->mouse_lclick = true; - case SDL_BUTTON_RIGHT: - break; - default: - break; - } - } - break; - case SDL_MOUSEBUTTONDOWN: - switch (e[i].button.button) { - case SDL_BUTTON_LEFT: - p->mousedown = p->mouse_pos; - break; - case SDL_BUTTON_RIGHT: - break; - default: - break; - } - break; - default: - WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); - break; - } - } - } + p->mouse_lclick = true; + case SDL_BUTTON_RIGHT: + break; + default: + break; + } + } break; + case SDL_MOUSEBUTTONDOWN: + switch (e[i].button.button) { + case SDL_BUTTON_LEFT: + p->mousedown = p->mouse_pos; + break; + case SDL_BUTTON_RIGHT: + break; + default: + break; + } + break; + default: + WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); + break; + } + } + } - BENCHEXPR(profile_input_handling, { - if (p->bindings != NULL) { - const i_ctx *bindings = *p->bindings; - const usize bindings_len = p->bindings_len; + BENCHEXPR(profile_input_handling, { + if (p->bindings != NULL) { + const i_ctx* bindings = *p->bindings; + const usize bindings_len = p->bindings_len; - while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_KEYDOWN, SDL_KEYUP)) > 0) { - for (i32 i = 0; i < num_events; i++) { - switch (e[i].type) { - case SDL_KEYDOWN: - if (e[i].key.keysym.sym == SDLK_F7) { - INFO("Reloading %s", StateTypeStr[state]); - if (! State_reload(state, p->bindings, p->bindings_len) ) { - ERROR("Failed to reload state library!"); - } else { - update_func = State_updateFunc(state); - } - break; - } - for (usize b = 0; b < bindings_len; b++) { - const action_t a = i_get_action(&bindings[b], e[i].key.timestamp, e[i].key.keysym.scancode); + while ((num_events = SDL_PeepEvents(e, 8, SDL_GETEVENT, SDL_KEYDOWN, + SDL_KEYUP)) > 0) { + for (i32 i = 0; i < num_events; i++) { + switch (e[i].type) { + case SDL_KEYDOWN: + if (e[i].key.keysym.sym == SDLK_F7) { + INFO("Reloading %s", StateTypeStr[state]); + if (!State_reload(state, p->bindings, p->bindings_len)) { + ERROR("Failed to reload state library!"); + } else { + update_func = State_updateFunc(state); + } + break; + } + for (usize b = 0; b < bindings_len; b++) { + const action_t a = + i_get_action(&bindings[b], e[i].key.timestamp, + e[i].key.keysym.scancode); - switch (a.type) { - case InputType_action: - if (a.action.callback != NULL) { - callbacks[callbacks_len++] = a.action.callback; - } - break; + switch (a.type) { + case InputType_action: + if (a.action.callback != NULL) { + callbacks[callbacks_len++] = a.action.callback; + } + break; - case InputType_state: - if (!e[i].key.repeat && a.state.activate != NULL) { - callbacks[callbacks_len++] = a.state.activate; - } - break; + case InputType_state: + if (!e[i].key.repeat && a.state.activate != NULL) { + callbacks[callbacks_len++] = a.state.activate; + } + break; - case InputType_range: - WARN("Range inputs not supported yet!"); - break; - case InputType_error: - WARN("Unhandled scancode: %lu", e[i].key.keysym.scancode); + case InputType_range: + WARN("Range inputs not supported yet!"); + break; + case InputType_error: + WARN("Unhandled scancode: %lu", e[i].key.keysym.scancode); - default: - break; - } - } - break; + default: + break; + } + } + break; - case SDL_KEYUP: - for (usize b = 0; b < bindings_len; b++) { - const action_t a = i_get_action(&bindings[b], e[i].key.timestamp, e[i].key.keysym.scancode); - if (a.type == InputType_state && a.state.deactivate != NULL && !e[i].key.repeat) { - callbacks[callbacks_len++] = a.state.deactivate; - } - } - break; - default: - WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); - break; - } - } - } - } - }); - }); + case SDL_KEYUP: + for (usize b = 0; b < bindings_len; b++) { + const action_t a = + i_get_action(&bindings[b], e[i].key.timestamp, + e[i].key.keysym.scancode); + if (a.type == InputType_state && a.state.deactivate != NULL && + !e[i].key.repeat) { + callbacks[callbacks_len++] = a.state.deactivate; + } + } + break; + default: + WARN("Unhandled mouse event 0x%04x", (i32)e[i].type); + break; + } + } + } + } + }); + }); - i_flush_bindings(callbacks_len, mem->data, callbacks); - callbacks_len = 0; + i_flush_bindings(callbacks_len, mem->data, callbacks); + callbacks_len = 0; - /* update */ - StateType next_state; - BENCHEXPR(profile_gameloop, {next_state = update_func((void*)(mem->data));} );//State_update(state, mem);}); + /* update */ + StateType next_state; + BENCHEXPR(profile_gameloop, { + next_state = update_func((void*)(mem->data)); + }); // State_update(state, mem);}); - if (next_state != STATE_null) { - if (next_state == STATE_quit) break; + if (next_state != STATE_null) { + if (next_state == STATE_quit) break; - drawcall_reset(); + drawcall_reset(); - engine_window_resize_pointers_reset(); - State_free(state, mem); - memory_clear(mem); + engine_window_resize_pointers_reset(); + State_free(state, mem); + memory_clear(mem); - engine_input_ctx_reset(); + engine_input_ctx_reset(); - state = next_state; - update_func = State_updateFunc(state); + state = next_state; + update_func = State_updateFunc(state); #ifdef BENCHMARK - { - u32 t = SDL_GetTicks(); - State_init(state, mem); - LOG("Initializing %s took %dms", StateTypeStr[state], SDL_GetTicks() - t); - } + { + u32 t = SDL_GetTicks(); + State_init(state, mem); + LOG("Initializing %s took %dms", StateTypeStr[state], + SDL_GetTicks() - t); + } #else - State_init(state, mem); + State_init(state, mem); #endif - } else { + } else { #ifdef BENCHMARK - profile_num_drawcalls += drawcall_len; + profile_num_drawcalls += drawcall_len; #endif - render_begin(p->window); - BENCHEXPR(profile_rendering, {render_present(p->window);}) - } + render_begin(p->window); + BENCHEXPR(profile_rendering, { render_present(p->window); }) + } + ticks++; + } while (state != STATE_quit); - ticks++; - } while (state != STATE_quit); - - return 0; + return 0; } +void stop(Platform* p) { + if (p == NULL) return; -void stop(Platform *p) { - if (p == NULL) return; - - { /* Deallocate resources */ - struct Resources *r = (struct Resources*)p->data; - if (r != NULL) { - /* Destroy textures */ - for (usize i = 0; i < r->textures_len; i++) { - if (r->textures[i] != NULL) { - SDL_DestroyTexture(r->textures[i]->texture); - r->textures[i] = NULL; - } - } - free(r->textures); + { /* Deallocate resources */ + struct Resources* r = (struct Resources*)p->data; + if (r != NULL) { + /* Destroy textures */ + for (usize i = 0; i < r->textures_len; i++) { + if (r->textures[i] != NULL) { + SDL_DestroyTexture(r->textures[i]->texture); + r->textures[i] = NULL; + } + } + free(r->textures); - /* Destroy Fonts */ - for (usize i = 0; i < r->fonts_len; i++) { - if (r->fonts[i] != NULL) { - TTF_CloseFont(r->fonts[i]); - r->fonts[i] = NULL; - } - } - free(r->fonts); - } - } + /* Destroy Fonts */ + for (usize i = 0; i < r->fonts_len; i++) { + if (r->fonts[i] != NULL) { + TTF_CloseFont(r->fonts[i]); + r->fonts[i] = NULL; + } + } + free(r->fonts); + } + } - { /* Deallocate window */ - Window *w = p->window; - if (w != NULL) { - if (w->window != NULL) { SDL_DestroyWindow(w->window); w->window = NULL; } - if (w->renderer != NULL) { SDL_DestroyRenderer(w->renderer); w->renderer = NULL; } - } - } + { /* Deallocate window */ + Window* w = p->window; + if (w != NULL) { + if (w->window != NULL) { + SDL_DestroyWindow(w->window); + w->window = NULL; + } + if (w->renderer != NULL) { + SDL_DestroyRenderer(w->renderer); + w->renderer = NULL; + } + } + } - TTF_Quit(); - IMG_Quit(); - SDL_Quit(); + TTF_Quit(); + IMG_Quit(); + SDL_Quit(); } void engine_fps_max(u64 cap) { FPS_CAP = cap; } -void engine_input_ctx_push(i_ctx *ctx) { - if (GLOBAL_PLATFORM->bindings == NULL) { - GLOBAL_PLATFORM->bindings = calloc(8, sizeof(i_ctx*)); - GLOBAL_PLATFORM->bindings_sz = 8; - } +void engine_input_ctx_push(i_ctx* ctx) { + if (GLOBAL_PLATFORM->bindings == NULL) { + GLOBAL_PLATFORM->bindings = calloc(8, sizeof(i_ctx*)); + GLOBAL_PLATFORM->bindings_sz = 8; + } - if (GLOBAL_PLATFORM->bindings_len + 1 >= GLOBAL_PLATFORM->bindings_sz) { - void* m = realloc(GLOBAL_PLATFORM->bindings, GLOBAL_PLATFORM->bindings_sz + 8); - if (m == NULL) { - ERROR("Failed to allocate 8 bytes (%d): %s", errno, strerror(errno)); - exit(EXIT_FAILURE); - } - GLOBAL_PLATFORM->bindings_sz += 8; - } + if (GLOBAL_PLATFORM->bindings_len + 1 >= GLOBAL_PLATFORM->bindings_sz) { + void* m = + realloc(GLOBAL_PLATFORM->bindings, GLOBAL_PLATFORM->bindings_sz + 8); + if (m == NULL) { + ERROR("Failed to allocate 8 bytes (%d): %s", errno, strerror(errno)); + exit(EXIT_FAILURE); + } + GLOBAL_PLATFORM->bindings_sz += 8; + } - LOG("Bindings in ctx[%d]:", GLOBAL_PLATFORM->bindings_len); - for (isize i = 0; i < ctx->len; i++) { - switch (ctx->bindings[i].action.type) { - case InputType_error: - LOG("(error)"); - break; + LOG("Bindings in ctx[%d]:", GLOBAL_PLATFORM->bindings_len); + for (isize i = 0; i < ctx->len; i++) { + switch (ctx->bindings[i].action.type) { + case InputType_error: + LOG("(error)"); + break; - case InputType_action: - LOG("(action) %s", ctx->bindings[i].action.action.callback_str); - break; + case InputType_action: + LOG("(action) %s", ctx->bindings[i].action.action.callback_str); + break; - case InputType_state: - LOG("(+state) %s", ctx->bindings[i].action.state.activate_str); - LOG("(-state) %s", ctx->bindings[i].action.state.deactivate_str); - break; - case InputType_range: - LOG("(range) --unhandled--"); - break; - } - } + case InputType_state: + LOG("(+state) %s", ctx->bindings[i].action.state.activate_str); + LOG("(-state) %s", ctx->bindings[i].action.state.deactivate_str); + break; + case InputType_range: + LOG("(range) --unhandled--"); + break; + } + } - GLOBAL_PLATFORM->bindings[GLOBAL_PLATFORM->bindings_len++] = ctx; + GLOBAL_PLATFORM->bindings[GLOBAL_PLATFORM->bindings_len++] = ctx; } void engine_input_ctx_pop(void) { - if (GLOBAL_PLATFORM->bindings == NULL || GLOBAL_PLATFORM->bindings_sz == 0) return; - i_ctx_t_free(GLOBAL_PLATFORM->bindings[--GLOBAL_PLATFORM->bindings_len]); + if (GLOBAL_PLATFORM->bindings == NULL || GLOBAL_PLATFORM->bindings_sz == 0) + return; + i_ctx_t_free(GLOBAL_PLATFORM->bindings[--GLOBAL_PLATFORM->bindings_len]); } void engine_input_ctx_reset(void) { - while (GLOBAL_PLATFORM->bindings_len > 0) { - i_ctx_t_free(GLOBAL_PLATFORM->bindings[--GLOBAL_PLATFORM->bindings_len]); - } + while (GLOBAL_PLATFORM->bindings_len > 0) { + i_ctx_t_free(GLOBAL_PLATFORM->bindings[--GLOBAL_PLATFORM->bindings_len]); + } } -u32 get_time(void) {return SDL_GetTicks();} -v2_i32 get_windowsize(void) {return GLOBAL_PLATFORM->window->windowsize;} -v2_i32 *get_mousepos(void) { return &GLOBAL_PLATFORM->mouse_pos; } +u32 get_time(void) { return SDL_GetTicks(); } +v2_i32 get_windowsize(void) { return GLOBAL_PLATFORM->window->windowsize; } +v2_i32* get_mousepos(void) { return &GLOBAL_PLATFORM->mouse_pos; } @@ -1,97 +1,94 @@ -#include <stdint.h> -#include <math.h> #include <engine/fov.h> #include <engine/utils.h> +#include <math.h> +#include <stdint.h> -void fov_shadowcast_rec(const void *map, const v2_i32 mapsize, - bool (*visblocking)(const void*), i32 *lightmap, - const i32 range, v2_i32 src, - const i32 row, - f32 start, const f32 end, - const i8 xx, const i8 xy, const i8 yx, const i8 yy) { +void fov_shadowcast_rec(const void* map, const v2_i32 mapsize, + bool (*visblocking)(const void*), i32* lightmap, + const i32 range, v2_i32 src, const i32 row, f32 start, + const f32 end, const i8 xx, const i8 xy, const i8 yx, + const i8 yy) { - if (start < end) return; + if (start < end) return; - const i32 range_2 = range * range; - f32 new_start = start; + const i32 range_2 = range * range; + f32 new_start = start; - for (i32 i = row; i <= range; i++) { - i32 dx = (-1 * i) - 1; - i32 dy = -1 * i; + for (i32 i = row; i <= range; i++) { + i32 dx = (-1 * i) - 1; + i32 dy = -1 * i; - bool blocked = false; + bool blocked = false; - while (dx <= 0) { - dx += 1; + while (dx <= 0) { + dx += 1; - const i32 mapx = src.x + dx * xx + dy * xy; - const i32 mapy = src.y + dx * yx + dy * yy; + const i32 mapx = src.x + dx * xx + dy * xy; + const i32 mapy = src.y + dx * yx + dy * yy; - const f32 slope_l = (((f32)dx) - 0.5f) / (((f32)dy) + 0.5f); - const f32 slope_r = (((f32)dx) + 0.5f) / (((f32)dy) - 0.5f); + const f32 slope_l = (((f32)dx) - 0.5f) / (((f32)dy) + 0.5f); + const f32 slope_r = (((f32)dx) + 0.5f) / (((f32)dy) - 0.5f); - if (start < slope_r) continue; - if (end > slope_l) break; + if (start < slope_r) continue; + if (end > slope_l) break; - if (dx * dx + dy * dy < range_2) { - /* set as visible */ - if (mapx >= 0 && mapx < (long)mapsize.x - && mapy >= 0 && mapy < (long)mapsize.y) { - // TODO: Calculate proper dist from source - f32 x_2 = (src.x - mapx) * (src.x - mapx); - f32 y_2 = (src.y - mapy) * (src.y - mapy); - lightmap[mapy*mapsize.x + mapx] = MAX(lightmap[mapy*mapsize.x + mapx], range - sqrt((f32)(x_2 + y_2))); - } - } + if (dx * dx + dy * dy < range_2) { + /* set as visible */ + if (mapx >= 0 && mapx < (long)mapsize.x && mapy >= 0 && + mapy < (long)mapsize.y) { + // TODO: Calculate proper dist from source + f32 x_2 = (src.x - mapx) * (src.x - mapx); + f32 y_2 = (src.y - mapy) * (src.y - mapy); + lightmap[mapy * mapsize.x + mapx] = + MAX(lightmap[mapy * mapsize.x + mapx], + range - sqrt((f32)(x_2 + y_2))); + } + } - /* sizeof(i32) is the size of enums */ - /* -- unless the compiler doesn't follow standard behaviour */ - const bool is_blocked = visblocking( - (void*)((u64)map - + sizeof(i32) /* ~ enum size */ - * (mapsize.x * mapy + mapx) /* index */ - )); + /* sizeof(i32) is the size of enums */ + /* -- unless the compiler doesn't follow standard behaviour */ + const bool is_blocked = visblocking( + (void*)((u64)map + sizeof(i32) /* ~ enum size */ + * (mapsize.x * mapy + mapx) /* index */ + )); - if (blocked) { - if (!is_blocked) { - new_start = slope_r; - } else { - blocked = false; - start = new_start; - } - } else if (!is_blocked && i < range) { - blocked = true; - fov_shadowcast_rec(map, mapsize, visblocking, lightmap, range, src, i+1, start, slope_l, xx, xy, yx, yy); - new_start = slope_r; - } - } + if (blocked) { + if (!is_blocked) { + new_start = slope_r; + } else { + blocked = false; + start = new_start; + } + } else if (!is_blocked && i < range) { + blocked = true; + fov_shadowcast_rec(map, mapsize, visblocking, lightmap, range, src, + i + 1, start, slope_l, xx, xy, yx, yy); + new_start = slope_r; + } + } - if (blocked) break; - } + if (blocked) break; + } } -/* http://www.roguebasin.com/index.php?title=FOV_using_recursive_shadowcasting */ -void fov_shadowcast(const void *map, const v2_i32 mapsize, - bool (*visblocking)(const void*), i32 *lightmap, +/* http://www.roguebasin.com/index.php?title=FOV_using_recursive_shadowcasting + */ +void fov_shadowcast(const void* map, const v2_i32 mapsize, + bool (*visblocking)(const void*), i32* lightmap, const i32 range, const v2_i32 src) { - const i8 m[4][8] = { - {1, 0, 0, -1, -1, 0, 0, 1}, - {0, 1, -1, 0, 0, -1, 1, 0}, - {0, 1, 1, 0, 0, -1, -1, 0}, - {1, 0, 0, 1, -1, 0, 0, -1}, - }; + const i8 m[4][8] = { + {1, 0, 0, -1, -1, 0, 0, 1}, + {0, 1, -1, 0, 0, -1, 1, 0}, + {0, 1, 1, 0, 0, -1, -1, 0}, + {1, 0, 0, 1, -1, 0, 0, -1}, + }; - for (i32 oct = 0; oct < 8; oct++) { - fov_shadowcast_rec( - map, mapsize, visblocking, lightmap, range, src, - 1, 1.0, 0.0, - m[0][oct], - m[1][oct], - m[2][oct], - m[3][oct]); - } + for (i32 oct = 0; oct < 8; oct++) { + fov_shadowcast_rec(map, mapsize, visblocking, lightmap, range, src, 1, 1.0, + 0.0, m[0][oct], m[1][oct], m[2][oct], m[3][oct]); + } - /* The center is the most lit square */ - lightmap[src.y * mapsize.x + src.x] = range; + /* The center is the most lit square */ + lightmap[src.y * mapsize.x + src.x] = range; } diff --git a/src/hashmap.c b/src/hashmap.c index edcf9cb..1652bb6 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -1,5 +1,3 @@ #include <engine/hashmap.h> -i32 lolhash(const usize s, i32 v) { - return v % s; -} +i32 lolhash(const usize s, i32 v) { return v % s; } diff --git a/src/input.c b/src/input.c index 633145a..f026260 100644 --- a/src/input.c +++ b/src/input.c @@ -1,332 +1,339 @@ -#include <string.h> -#include <engine/input.h> #include <engine/dltools.h> +#include <engine/input.h> #include <engine/logging.h> +#include <string.h> /* Lazy binds, used internally. They are similar to BindAction and friends. * The only difference is that we set callbacks and such to NULL, but populate * the function name strings such that can be reloaded. */ -#define BindActionLazy(key, altkey, action_str) \ - (binding_t){\ - .action = (action_t){.action = {\ - .type = InputType_action,\ - .callback = NULL,\ - .callback_str = strdup( action_str ),\ - }},\ - .scancode = key,\ - .scancode_alt = altkey,\ - .since_last_activation = 0\ -} +#define BindActionLazy(key, altkey, action_str) \ + (binding_t) { \ + .action = (action_t){.action = \ + { \ + .type = InputType_action, \ + .callback = NULL, \ + .callback_str = strdup(action_str), \ + }}, \ + .scancode = key, .scancode_alt = altkey, .since_last_activation = 0 \ + } -#define BindStateLazy(key, altkey, _activate_str , _deactivate_str) \ - (binding_t){\ - .action = (action_t){.state = {\ - .type = InputType_state,\ - .activate = NULL,\ - .deactivate = NULL,\ - .activate_str = strdup( _activate_str ),\ - .deactivate_str = strdup( _deactivate_str ),\ - }},\ - .scancode = key,\ - .scancode_alt = altkey,\ - .since_last_activation = 0\ -} +#define BindStateLazy(key, altkey, _activate_str, _deactivate_str) \ + (binding_t) { \ + .action = (action_t){.state = \ + { \ + .type = InputType_state, \ + .activate = NULL, \ + .deactivate = NULL, \ + .activate_str = strdup(_activate_str), \ + .deactivate_str = strdup(_deactivate_str), \ + }}, \ + .scancode = key, .scancode_alt = altkey, .since_last_activation = 0 \ + } void binding_t_free(binding_t* b) { - switch (b->action.type) { - case InputType_error: - ERROR("Cannot free binding of type InputType_error"); - break; - case InputType_action: - free(b->action.action.callback_str); - return; + switch (b->action.type) { + case InputType_error: + ERROR("Cannot free binding of type InputType_error"); + break; + case InputType_action: + free(b->action.action.callback_str); + return; - case InputType_state: - free(b->action.state.activate_str); - free(b->action.state.deactivate_str); - break; + case InputType_state: + free(b->action.state.activate_str); + free(b->action.state.deactivate_str); + break; - case InputType_range: - ERROR("Cannot free binding of type InputType_rage"); - break; + case InputType_range: + ERROR("Cannot free binding of type InputType_rage"); + break; - default: - ERROR("Unknown bindings type"); - break; - } - exit(EXIT_FAILURE); + default: + ERROR("Unknown bindings type"); + break; + } + exit(EXIT_FAILURE); } void i_ctx_t_free(i_ctx* c) { - for (isize i = 0; i < c->len; i++) { - binding_t_free(&c->bindings[i]); - } + for (isize i = 0; i < c->len; i++) { + binding_t_free(&c->bindings[i]); + } } -bool binding_action_cmp(binding_t *restrict a, binding_t *restrict b) { - InputType t = a->action.type; - if (t != b->action.type) return false; - switch (t) { - case InputType_action: - return !strcmp(a->action.action.callback_str, b->action.action.callback_str); +bool binding_action_cmp(binding_t* restrict a, binding_t* restrict b) { + InputType t = a->action.type; + if (t != b->action.type) return false; + switch (t) { + case InputType_action: + return !strcmp(a->action.action.callback_str, + b->action.action.callback_str); - case InputType_state: - return (!strcmp(a->action.state.activate_str, b->action.state.activate_str)) - && (!strcmp(a->action.state.deactivate_str, b->action.state.deactivate_str)); + case InputType_state: + return (!strcmp(a->action.state.activate_str, + b->action.state.activate_str)) && + (!strcmp(a->action.state.deactivate_str, + b->action.state.deactivate_str)); - case InputType_range: // fallthrough - default: - return false; // not implemented - } - return false; + case InputType_range: // fallthrough + default: + return false; // not implemented + } + return false; } -bool binding_scancode_cmp(binding_t *restrict a, binding_t *restrict b) { - return a->scancode == b->scancode - || a->scancode_alt == b->scancode_alt; +bool binding_scancode_cmp(binding_t* restrict a, binding_t* restrict b) { + return a->scancode == b->scancode || a->scancode_alt == b->scancode_alt; } -bool binding_scancode_cmp_i(binding_t *restrict a, scancode_t scancode) { - return a->scancode == scancode - || a->scancode_alt == scancode; +bool binding_scancode_cmp_i(binding_t* restrict a, scancode_t scancode) { + return a->scancode == scancode || a->scancode_alt == scancode; } // If any binding in ctx contains action, replace that entry. -bool i_update_binding(i_ctx *ctx, binding_t* binding) { - isize idx = 0; - if (ctx == NULL || binding == NULL) { - ERROR("i_update_binding received nullptr!"); - return false; - } +bool i_update_binding(i_ctx* ctx, binding_t* binding) { + isize idx = 0; + if (ctx == NULL || binding == NULL) { + ERROR("i_update_binding received nullptr!"); + return false; + } - while (idx < ctx->len && !binding_action_cmp(&ctx->bindings[idx], binding)) idx++; + while (idx < ctx->len && !binding_action_cmp(&ctx->bindings[idx], binding)) + idx++; - if (idx < ctx->len && binding_action_cmp(&ctx->bindings[idx], binding)) { - ctx->bindings[idx].scancode = binding->scancode; - ctx->bindings[idx].scancode_alt = binding->scancode_alt; - return true; - } + if (idx < ctx->len && binding_action_cmp(&ctx->bindings[idx], binding)) { + ctx->bindings[idx].scancode = binding->scancode; + ctx->bindings[idx].scancode_alt = binding->scancode_alt; + return true; + } - return false; + return false; } // If any binding in ctx contains scancode, replace that action. -bool i_update_unique_binding(i_ctx *ctx, binding_t* binding) { - isize idx = 0; - if (ctx == NULL || binding == NULL) { - ERROR("i_update_unique_binding received nullptr!"); - return false; - } +bool i_update_unique_binding(i_ctx* ctx, binding_t* binding) { + isize idx = 0; + if (ctx == NULL || binding == NULL) { + ERROR("i_update_unique_binding received nullptr!"); + return false; + } - while (idx < ctx->len && !binding_scancode_cmp(&ctx->bindings[idx], binding)) idx++; + while (idx < ctx->len && !binding_scancode_cmp(&ctx->bindings[idx], binding)) + idx++; - if (idx < ctx->len && binding_scancode_cmp(&ctx->bindings[idx], binding)) { - ctx->bindings[idx].action = binding->action; - return true; - } + if (idx < ctx->len && binding_scancode_cmp(&ctx->bindings[idx], binding)) { + ctx->bindings[idx].action = binding->action; + return true; + } - return false; + return false; } void i_flush_bindings(usize numcalls, void* state_mem, input_callback_t* c[]) { - for (usize i = 0; i < numcalls; i++) { - (c[i])(state_mem); - } + for (usize i = 0; i < numcalls; i++) { + (c[i])(state_mem); + } } -action_t i_get_action(const i_ctx *restrict ctx, u32 time, scancode_t scancode) { - isize idx = 0; +action_t i_get_action(const i_ctx* restrict ctx, u32 time, + scancode_t scancode) { + isize idx = 0; - if (ctx == NULL) { - ERROR("%s received nullptr!", __func__); - return (action_t){.type = InputType_error}; - } + if (ctx == NULL) { + ERROR("%s received nullptr!", __func__); + return (action_t){.type = InputType_error}; + } - while (idx < ctx->len && !binding_scancode_cmp_i(&ctx->bindings[idx], scancode)) idx++; + while (idx < ctx->len && + !binding_scancode_cmp_i(&ctx->bindings[idx], scancode)) + idx++; - if (idx < ctx->len - && binding_scancode_cmp_i(&ctx->bindings[idx], scancode)) { - ctx->bindings[idx].since_last_activation = time; - return ctx->bindings[idx].action; - } + if (idx < ctx->len && binding_scancode_cmp_i(&ctx->bindings[idx], scancode)) { + ctx->bindings[idx].since_last_activation = time; + return ctx->bindings[idx].action; + } - return (action_t){.type = InputType_error}; + return (action_t){.type = InputType_error}; } -bool state_refresh_input_ctx(void *lib, i_ctx **ctx, usize ctx_len) { - if (ctx == NULL) return true; - if (ctx_len > 0 && ctx[0] == NULL) return false; - if (lib == NULL) return false; +bool state_refresh_input_ctx(void* lib, i_ctx** ctx, usize ctx_len) { + if (ctx == NULL) return true; + if (ctx_len > 0 && ctx[0] == NULL) return false; + if (lib == NULL) return false; - for (usize c = 0; c < ctx_len; c++) { - LOG("ctx[%d]->len = %d", c, ctx[c]->len); - for (isize b = 0; b < ctx[c]->len; b++) { - switch (ctx[c]->bindings[b].action.type) { - case InputType_error: - break; - case InputType_action: - if (strcmp("NULL", ctx[c]->bindings[b].action.action.callback_str) != 0) { + for (usize c = 0; c < ctx_len; c++) { + LOG("ctx[%d]->len = %d", c, ctx[c]->len); + for (isize b = 0; b < ctx[c]->len; b++) { + switch (ctx[c]->bindings[b].action.type) { + case InputType_error: + break; + case InputType_action: + if (strcmp("NULL", ctx[c]->bindings[b].action.action.callback_str) != + 0) { - ctx[c]->bindings[b].action.action.callback = - (input_callback_t*)dynamic_library_get_symbol(lib, ctx[c]->bindings[b].action.action.callback_str); + ctx[c]->bindings[b].action.action.callback = + (input_callback_t*)dynamic_library_get_symbol( + lib, ctx[c]->bindings[b].action.action.callback_str); - if (ctx[c]->bindings[b].action.action.callback == NULL) { - ERROR("Failed to get binding for %s: %s", - ctx[c]->bindings[b].action.action.callback_str, - dynamic_library_get_error()); - return false; - } - } - break; - case InputType_state: - if (strcmp("NULL", ctx[c]->bindings[b].action.state.activate_str) != 0) { + if (ctx[c]->bindings[b].action.action.callback == NULL) { + ERROR("Failed to get binding for %s: %s", + ctx[c]->bindings[b].action.action.callback_str, + dynamic_library_get_error()); + return false; + } + } + break; + case InputType_state: + if (strcmp("NULL", ctx[c]->bindings[b].action.state.activate_str) != + 0) { - ctx[c]->bindings[b].action.state.activate = - (input_callback_t*)dynamic_library_get_symbol(lib, ctx[c]->bindings[b].action.state.activate_str); + ctx[c]->bindings[b].action.state.activate = + (input_callback_t*)dynamic_library_get_symbol( + lib, ctx[c]->bindings[b].action.state.activate_str); - if (ctx[c]->bindings[b].action.state.activate == NULL) { - ERROR("Failed to get binding for %s: %s", - ctx[c]->bindings[b].action.state.activate_str, - dynamic_library_get_error()); - return false; - } - } + if (ctx[c]->bindings[b].action.state.activate == NULL) { + ERROR("Failed to get binding for %s: %s", + ctx[c]->bindings[b].action.state.activate_str, + dynamic_library_get_error()); + return false; + } + } - if (strcmp("NULL", ctx[c]->bindings[b].action.state.deactivate_str) != 0) { + if (strcmp("NULL", ctx[c]->bindings[b].action.state.deactivate_str) != + 0) { - ctx[c]->bindings[b].action.state.deactivate = - (input_callback_t*)dynamic_library_get_symbol(lib, ctx[c]->bindings[b].action.state.deactivate_str); + ctx[c]->bindings[b].action.state.deactivate = + (input_callback_t*)dynamic_library_get_symbol( + lib, ctx[c]->bindings[b].action.state.deactivate_str); - if (ctx[c]->bindings[b].action.state.deactivate == NULL) { - ERROR("Failed to get binding for %s: %s", - ctx[c]->bindings[b].action.state.deactivate_str, - dynamic_library_get_error()); - return false; - } - } - break; - case InputType_range: - default: - break; - } - } - } + if (ctx[c]->bindings[b].action.state.deactivate == NULL) { + ERROR("Failed to get binding for %s: %s", + ctx[c]->bindings[b].action.state.deactivate_str, + dynamic_library_get_error()); + return false; + } + } + break; + case InputType_range: + default: + break; + } + } + } - return true; + return true; } - /* Make a lazy duplication of a binding. See comments on BindActionLazy and * friends above. */ -i_ctx* i_ctx_dup(i_ctx **ctx, usize ctx_len) { - usize num_binds = 0; - for (usize c = 0; c < ctx_len; c++) { - num_binds += ctx[c]->len; - } +i_ctx* i_ctx_dup(i_ctx** ctx, usize ctx_len) { + usize num_binds = 0; + for (usize c = 0; c < ctx_len; c++) { + num_binds += ctx[c]->len; + } - binding_t *bb = calloc(num_binds, sizeof(binding_t)); - i_ctx *ret = calloc(ctx_len, sizeof(i_ctx)); + binding_t* bb = calloc(num_binds, sizeof(binding_t)); + i_ctx* ret = calloc(ctx_len, sizeof(i_ctx)); - usize cumsum = 0; - for (usize c = 0; c < ctx_len; c++) { - binding_t *b = ctx[c]->bindings; - ret[c].len = ctx[c]->len; - ret[c].bindings = &bb[cumsum]; + usize cumsum = 0; + for (usize c = 0; c < ctx_len; c++) { + binding_t* b = ctx[c]->bindings; + ret[c].len = ctx[c]->len; + ret[c].bindings = &bb[cumsum]; - for (isize i = 0; i < ctx[c]->len; i++) { - switch (b[i].action.type) { - case InputType_error: - break; - case InputType_action: - bb[cumsum] = BindActionLazy( - b[i].scancode, - b[i].scancode_alt, - strdup(b[i].action.action.callback_str)); - break; - case InputType_state: - bb[cumsum] = BindStateLazy( - b[i].scancode, - b[i].scancode_alt, - strdup(b[i].action.state.activate_str), - strdup(b[i].action.state.deactivate_str)); - break; - case InputType_range: - default: - break; - } - cumsum++; - } - } - return ret; + for (isize i = 0; i < ctx[c]->len; i++) { + switch (b[i].action.type) { + case InputType_error: + break; + case InputType_action: + bb[cumsum] = BindActionLazy(b[i].scancode, b[i].scancode_alt, + strdup(b[i].action.action.callback_str)); + break; + case InputType_state: + bb[cumsum] = BindStateLazy(b[i].scancode, b[i].scancode_alt, + strdup(b[i].action.state.activate_str), + strdup(b[i].action.state.deactivate_str)); + break; + case InputType_range: + default: + break; + } + cumsum++; + } + } + return ret; } /* Returns a pointer to a binding in c with .action == a. * Returns NULL if not found. */ -binding_t *get_action(i_ctx *c, action_t *a) { - for (isize i = 0; i < c->len; i++) { - if (c->bindings[i].action.type != a->type) continue; +binding_t* get_action(i_ctx* c, action_t* a) { + for (isize i = 0; i < c->len; i++) { + if (c->bindings[i].action.type != a->type) continue; - switch (c->bindings[i].action) { - case InputType_error: - return NULL; + switch (c->bindings[i].action) { + case InputType_error: + return NULL; - case InputType_action: - if (!strcmp(c->bindings[i].action.action.callback_str, a->action.callback_str)) { - return &c->bindings[i]; - } - break; + case InputType_action: + if (!strcmp(c->bindings[i].action.action.callback_str, + a->action.callback_str)) { + return &c->bindings[i]; + } + break; - case InputType_state: - if (!strcmp(c->bindings[i].action.state.activate_str, a->state.activate_str) - && !strcmp(c->bindings[i].action.state.deactivate_str, a->state.deactivate_str)) { - return &c->bindings[i]; - } - break; + case InputType_state: + if (!strcmp(c->bindings[i].action.state.activate_str, + a->state.activate_str) && + !strcmp(c->bindings[i].action.state.deactivate_str, + a->state.deactivate_str)) { + return &c->bindings[i]; + } + break; - case InputType_range: - default: - return NULL; - } - } - return NULL; + case InputType_range: + default: + return NULL; + } + } + return NULL; } -void i_bind_ctx(i_ctx *c, scancode_t s, action_t *a) { - binding_t* b = get_action(c, a); +void i_bind_ctx(i_ctx* c, scancode_t s, action_t* a) { + binding_t* b = get_action(c, a); - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } + if (b == NULL) { + WARN("Failed to update keybinding"); + return; + } - b->scancode = s; + b->scancode = s; } -void i_bind_ctx_alt(i_ctx *c, scancode_t s, action_t *a) { - binding_t* b = get_action(c, a); +void i_bind_ctx_alt(i_ctx* c, scancode_t s, action_t* a) { + binding_t* b = get_action(c, a); - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } + if (b == NULL) { + WARN("Failed to update keybinding"); + return; + } - b->scancode_alt = s; + b->scancode_alt = s; } -void i_bind(binding_t *b, scancode_t s) { - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } +void i_bind(binding_t* b, scancode_t s) { + if (b == NULL) { + WARN("Failed to update keybinding"); + return; + } - b->scancode = s; + b->scancode = s; } -void i_bind_alt(binding_t *b, scancode_t s) { - if (b == NULL) { - WARN("Failed to update keybinding"); - return; - } +void i_bind_alt(binding_t* b, scancode_t s) { + if (b == NULL) { + WARN("Failed to update keybinding"); + return; + } - b->scancode_alt = s; + b->scancode_alt = s; } diff --git a/src/logging.c b/src/logging.c index e8c2199..7870258 100644 --- a/src/logging.c +++ b/src/logging.c @@ -1,81 +1,82 @@ -#include <stdlib.h> -#include <engine/types.h> #include <engine/logging.h> +#include <engine/types.h> +#include <stdlib.h> -char *itoa(i32 x) { - const i32 size = (((i32)ceil(log10((f64)x)))+1) * sizeof(char); - char *retval = (char*)malloc(size); - if (retval == NULL) { - perror("Failed to allocate memory for itoa"); - exit(EXIT_FAILURE); - } - sprintf(retval, "%d", x); - return retval; +char* itoa(i32 x) { + const i32 size = (((i32)ceil(log10((f64)x))) + 1) * sizeof(char); + char* retval = (char*)malloc(size); + if (retval == NULL) { + perror("Failed to allocate memory for itoa"); + exit(EXIT_FAILURE); + } + sprintf(retval, "%d", x); + return retval; } -void _log(FILE *stream, const char *prefix, const char *fmt, va_list ap) { - if (stream == NULL) { - fprintf(stderr, "_log got NULL in stream argument\n"); - exit(EXIT_FAILURE); - } - fputs(prefix, stream); - vfprintf(stream, fmt, ap); +void _log(FILE* stream, const char* prefix, const char* fmt, va_list ap) { + if (stream == NULL) { + fprintf(stderr, "_log got NULL in stream argument\n"); + exit(EXIT_FAILURE); + } + fputs(prefix, stream); + vfprintf(stream, fmt, ap); } -void LOG(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - _log(stdout, "[" TERM_COLOR_BLUE "LOG" TERM_COLOR_RESET "] ", fmt, ap); - va_end(ap); - puts(""); +void LOG(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + _log(stdout, "[" TERM_COLOR_BLUE "LOG" TERM_COLOR_RESET "] ", fmt, ap); + va_end(ap); + puts(""); } -void INFO_(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - _log(stdout, "[" TERM_COLOR_GREEN "INFO" TERM_COLOR_RESET "] ", fmt, ap); - va_end(ap); +void INFO_(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + _log(stdout, "[" TERM_COLOR_GREEN "INFO" TERM_COLOR_RESET "] ", fmt, ap); + va_end(ap); } -void INFO(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - _log(stdout, "[" TERM_COLOR_GREEN "INFO" TERM_COLOR_RESET "] ", fmt, ap); - va_end(ap); - puts(""); +void INFO(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + _log(stdout, "[" TERM_COLOR_GREEN "INFO" TERM_COLOR_RESET "] ", fmt, ap); + va_end(ap); + puts(""); } -void __DEBUG(const char* file, const i32 line, const char* func, const char *fmt, ...) { - va_list ap; +void __DEBUG(const char* file, const i32 line, const char* func, + const char* fmt, ...) { + va_list ap; - const usize prefix_len = 1024; + const usize prefix_len = 1024; - char *prefix = malloc(sizeof(char) * 1024); + char* prefix = malloc(sizeof(char) * 1024); - snprintf(prefix, - prefix_len, - "["TERM_COLOR_YELLOW"DEBUG"TERM_COLOR_RESET"] " - "%s:%d <%s> ", file, line, func); + snprintf(prefix, prefix_len, + "[" TERM_COLOR_YELLOW "DEBUG" TERM_COLOR_RESET "] " + "%s:%d <%s> ", + file, line, func); - va_start(ap, fmt); - _log(stdout, prefix, fmt, ap); - va_end(ap); + va_start(ap, fmt); + _log(stdout, prefix, fmt, ap); + va_end(ap); - free(prefix); + free(prefix); } -void WARN(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - _log(stderr, "[" TERM_COLOR_PURPLE "WARN" TERM_COLOR_RESET "] ", fmt, ap); - va_end(ap); - puts(""); +void WARN(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + _log(stderr, "[" TERM_COLOR_PURPLE "WARN" TERM_COLOR_RESET "] ", fmt, ap); + va_end(ap); + puts(""); } -void ERROR(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - _log(stderr, "[" TERM_COLOR_RED "ERROR" TERM_COLOR_RESET "] ", fmt, ap); - va_end(ap); - puts(""); +void ERROR(const char* fmt, ...) { + va_list ap; + va_start(ap, fmt); + _log(stderr, "[" TERM_COLOR_RED "ERROR" TERM_COLOR_RESET "] ", fmt, ap); + va_end(ap); + puts(""); } diff --git a/src/memory.c b/src/memory.c index 6ef63ce..f19803e 100644 --- a/src/memory.c +++ b/src/memory.c @@ -1,18 +1,17 @@ -#include <string.h> -#include <stdlib.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <engine/logging.h> #include <engine/memory.h> -memory *memory_new(usize max_size) { - memory *m = malloc(sizeof(memory)); - m->data = malloc(max_size); - m->size = max_size; - m->pos = 0; - m->free = max_size; +memory* memory_new(usize max_size) { + memory* m = malloc(sizeof(memory)); + m->data = malloc(max_size); + m->size = max_size; + m->pos = 0; + m->free = max_size; memset(m->data, 0, max_size); @@ -20,15 +19,16 @@ memory *memory_new(usize max_size) { } /* Returns a pointer to the allocated data */ -void *memory_allocate(memory* mem, usize size) { +void* memory_allocate(memory* mem, usize size) { void* data = NULL; if (mem->pos + size <= mem->size) { data = (void*)((usize)mem->data + mem->pos); - mem->pos += size; + mem->pos += size; mem->free -= size; } else { - ERROR("Trying to allocate %lu in a %lu sized memory block", size, mem->size); + ERROR("Trying to allocate %lu in a %lu sized memory block", size, + mem->size); ERROR("No more room!"); exit(EXIT_FAILURE); } @@ -36,7 +36,7 @@ void *memory_allocate(memory* mem, usize size) { return data; } -memory memory_init(void *data, usize size) { +memory memory_init(void* data, usize size) { memory m = {0}; m.data = data; m.size = size; @@ -44,19 +44,19 @@ memory memory_init(void *data, usize size) { return m; } -void memory_free(memory *mem, usize size) { +void memory_free(memory* mem, usize size) { if (size > mem->pos) { perror("Freeing too much memory!"); exit(EXIT_FAILURE); } else { - mem->pos -= size; + mem->pos -= size; mem->free += size; } } -void memory_clear(memory *mem) { - mem->pos = 0; - mem->free = mem->size; - /* Reset the memory? */ - memset(mem->data, 0, mem->size); +void memory_clear(memory* mem) { + mem->pos = 0; + mem->free = mem->size; + /* Reset the memory? */ + memset(mem->data, 0, mem->size); } diff --git a/src/rendering.c b/src/rendering.c index e62e746..100a19b 100644 --- a/src/rendering.c +++ b/src/rendering.c @@ -10,7 +10,7 @@ #include <engine/rendering.h> /* Extern globals */ -extern Platform *GLOBAL_PLATFORM; +extern Platform* GLOBAL_PLATFORM; /* Globals */ #define drawcall_limit (64 * 1024) @@ -21,132 +21,119 @@ i32 drawcall_len = 0; /* Clear the screen, * To be used inbetween draw calls */ -void render_begin(Window *w) { +void render_begin(Window* w) { #ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, 0x10, 0x0a, 0x33, 0x00); + SDL_SetRenderDrawColor(w->renderer, 0x10, 0x0a, 0x33, 0x00); #else - SDL_SetRenderDrawColor(w->renderer, 0x00, 0x00, 0x00, 0x00); + SDL_SetRenderDrawColor(w->renderer, 0x00, 0x00, 0x00, 0x00); #endif - SDL_RenderClear(w->renderer); + SDL_RenderClear(w->renderer); } -void render_present(Window *w) { - for (i32 i = 0; i < drawcall_len; i++) { - RenderDrawCall dc = drawcalls[i]; - switch (dc.type) { - case RenderDrawCallType_UITree: - render_uitree(w, dc.data.data); - break; - case RenderDrawCallType_Text: - LOG("RenderDrawCallType_Text rendering not implemented!"); - break; - case RenderDrawCallType_Sprite: - { +void render_present(Window* w) { + for (i32 i = 0; i < drawcall_len; i++) { + RenderDrawCall dc = drawcalls[i]; + switch (dc.type) { + case RenderDrawCallType_UITree: + render_uitree(w, dc.data.data); + break; + case RenderDrawCallType_Text: + LOG("RenderDrawCallType_Text rendering not implemented!"); + break; + case RenderDrawCallType_Sprite: { #ifdef _DEBUG - if (dc.data.sprite.sprite == NULL) { - __asm__("int3;"); - WARN("Sprite %lx in drawcall %d/%d had NULL reference", dc.data.sprite.sprite, i, drawcall_len); + if (dc.data.sprite.sprite == NULL) { + __asm__("int3;"); + WARN("Sprite %lx in drawcall %d/%d had NULL reference", + dc.data.sprite.sprite, i, drawcall_len); - drawcall_len = 0; - SDL_RenderPresent(w->renderer); - exit(EXIT_FAILURE); - } + drawcall_len = 0; + SDL_RenderPresent(w->renderer); + exit(EXIT_FAILURE); + } #endif - Sprite s = *dc.data.sprite.sprite; - Texture *t = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[s.texture_id]; - i32 ts = t->tilesize; - SDL_Rect src = { - s.coord.x, - s.coord.y, - ts,ts - }; - SDL_Rect dst = { - dc.data.sprite.x, - dc.data.sprite.y, - ts * dc.data.sprite.scale, - ts * dc.data.sprite.scale, - }; - SDL_SetTextureColorMod(t->texture, - dc.data.sprite.mod.r, - dc.data.sprite.mod.g, - dc.data.sprite.mod.b); - SDL_RenderCopy( - w->renderer, - t->texture, - &src, &dst); - } - break; - default: - break; - } - } + Sprite s = *dc.data.sprite.sprite; + Texture* t = + ((struct Resources*)GLOBAL_PLATFORM->data)->textures[s.texture_id]; + i32 ts = t->tilesize; + SDL_Rect src = {s.coord.x, s.coord.y, ts, ts}; + SDL_Rect dst = { + dc.data.sprite.x, + dc.data.sprite.y, + ts * dc.data.sprite.scale, + ts * dc.data.sprite.scale, + }; + SDL_SetTextureColorMod(t->texture, dc.data.sprite.mod.r, + dc.data.sprite.mod.g, dc.data.sprite.mod.b); + SDL_RenderCopy(w->renderer, t->texture, &src, &dst); + } break; + default: + break; + } + } - drawcall_len = 0; + drawcall_len = 0; - SDL_RenderPresent(w->renderer); + SDL_RenderPresent(w->renderer); } -void drawcall_reset(void) { - drawcall_len = 0; -} +void drawcall_reset(void) { drawcall_len = 0; } void engine_window_resize_pointers(i32* w, i32* h) { - GLOBAL_PLATFORM->window->game_w = w; - GLOBAL_PLATFORM->window->game_h = h; + GLOBAL_PLATFORM->window->game_w = w; + GLOBAL_PLATFORM->window->game_h = h; } void engine_window_resize_pointers_reset(void) { - GLOBAL_PLATFORM->window->game_w = NULL; - GLOBAL_PLATFORM->window->game_h = NULL; + GLOBAL_PLATFORM->window->game_w = NULL; + GLOBAL_PLATFORM->window->game_h = NULL; } -void engine_draw_uitree(UITree *t) { - if (drawcall_len + 1 >= drawcall_limit) return; - drawcalls[drawcall_len++] = (RenderDrawCall){ - .type = RenderDrawCallType_UITree, - .data.data = (void*)t - }; +void engine_draw_uitree(UITree* t) { + if (drawcall_len + 1 >= drawcall_limit) return; + drawcalls[drawcall_len++] = (RenderDrawCall){ + .type = RenderDrawCallType_UITree, .data.data = (void*)t}; } -void engine_draw_sprite(Sprite *s, v2_i32 *pos, f32 scale) { - if (drawcall_len + 1 >= drawcall_limit) return; +void engine_draw_sprite(Sprite* s, v2_i32* pos, f32 scale) { + if (drawcall_len + 1 >= drawcall_limit) return; #ifdef _DEBUG - if (s == NULL) __asm__("int3;"); + if (s == NULL) __asm__("int3;"); #endif - drawcalls[drawcall_len++] = (RenderDrawCall){ - .type = RenderDrawCallType_Sprite, - .data.sprite = { - .sprite = s, - .x = pos->x, - .y = pos->y, - .scale = scale, - .mod = {0xFF, 0xFF, 0xFF, 0xFF}, - } - }; + drawcalls[drawcall_len++] = + (RenderDrawCall){.type = RenderDrawCallType_Sprite, + .data.sprite = { + .sprite = s, + .x = pos->x, + .y = pos->y, + .scale = scale, + .mod = {0xFF, 0xFF, 0xFF, 0xFF}, + }}; } -void engine_draw_sprite_ex(Sprite *s, v2_i32 *pos, f32 scale, Engine_color colormod) { - if (drawcall_len + 1 >= drawcall_limit) return; +void engine_draw_sprite_ex(Sprite* s, v2_i32* pos, f32 scale, + Engine_color colormod) { + if (drawcall_len + 1 >= drawcall_limit) return; #ifdef _DEBUG - if (s == NULL) __asm__("int3;"); + if (s == NULL) __asm__("int3;"); #endif - drawcalls[drawcall_len++] = (RenderDrawCall){ - .type = RenderDrawCallType_Sprite, - .data.sprite = { - .sprite = s, - .x = pos->x, - .y = pos->y, - .scale = scale, - .mod = {colormod.r, colormod.g, colormod.b, colormod.a}, - } - }; + drawcalls[drawcall_len++] = (RenderDrawCall){ + .type = RenderDrawCallType_Sprite, + .data.sprite = { + .sprite = s, + .x = pos->x, + .y = pos->y, + .scale = scale, + .mod = {colormod.r, colormod.g, colormod.b, colormod.a}, + }}; } - Sprite sprite_new(u64 tid, u8 coord) { - const i32 ts = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[tid]->tilesize; - return (Sprite){.texture_id = tid, (v2_i32){ - .x = ts * (coord & 0x0F), - .y = ts * ((coord & 0xF0) >> 4), - }}; + const i32 ts = + ((struct Resources*)GLOBAL_PLATFORM->data)->textures[tid]->tilesize; + return (Sprite){.texture_id = tid, + (v2_i32){ + .x = ts * (coord & 0x0F), + .y = ts * ((coord & 0xF0) >> 4), + }}; } diff --git a/src/stack.c b/src/stack.c index edc2d9f..ff195ba 100644 --- a/src/stack.c +++ b/src/stack.c @@ -1,88 +1,82 @@ -#include <stdlib.h> #include <engine/logging.h> #include <engine/stack.h> - +#include <stdlib.h> Stack stack_new_ex(const usize element_size, const usize size) { Stack s = { - .head = 0, - .elem_size = element_size, - .size = element_size * size, - .chunk_size = element_size * size, - .data = NULL, + .head = 0, + .elem_size = element_size, + .size = element_size * size, + .chunk_size = element_size * size, + .data = NULL, }; s.data = (void*)calloc(element_size, size); return s; } - Stack stack_new(const usize element_size) { return stack_new_ex(element_size, 512); } - -void stack_free(Stack *s) { - if (s->data == NULL) return; - free(s->data); - s->data = NULL; +void stack_free(Stack* s) { + if (s->data == NULL) return; + free(s->data); + s->data = NULL; } - -void *stack_pop(Stack *s) { +void* stack_pop(Stack* s) { if (s->head == 0) return NULL; /* Empty stack */ return (u8*)s->data + (--(s->head) * s->elem_size); } - -void stack_push(Stack *s, void *elem) { - if (elem == NULL) {WARN("%s received a nullptr", __func__); return;} +void stack_push(Stack* s, void* elem) { + if (elem == NULL) { + WARN("%s received a nullptr", __func__); + return; + } if (s->head > 0 && s->head * s->elem_size >= s->size) { - WARN("Allocating more stack memory"); - /* Reallocate more memory and update size */ - void* ptr = realloc(s->data, s->size + s->chunk_size); - if (ptr == NULL) { - ERROR("Failed to resize memory for stack"); - exit(EXIT_FAILURE); - } - s->data = ptr; - //memset((void*)((u64)s->data + (s->size - s->elem_size)), 0, s->chunk_size); + WARN("Allocating more stack memory"); + /* Reallocate more memory and update size */ + void* ptr = realloc(s->data, s->size + s->chunk_size); + if (ptr == NULL) { + ERROR("Failed to resize memory for stack"); + exit(EXIT_FAILURE); + } + s->data = ptr; + // memset((void*)((u64)s->data + (s->size - s->elem_size)), 0, + // s->chunk_size); s->size += s->chunk_size; } memcpy((u8*)s->data + s->head * s->elem_size, elem, s->elem_size); s->head++; } - -void *stack_peek(Stack *s) { +void* stack_peek(Stack* s) { if (s->head <= 0) return NULL; /* Empty stack */ return (u8*)s->data + ((s->head - 1) * s->elem_size); } +isize stack_size(const Stack* s) { return s->head; } -isize stack_size(const Stack *s) { - return s->head; -} - - -void stack_swap(Stack *s, Stack *t) { - if (s->size > t->size) { - t->data = realloc(t->data, s->size); - } else if (t->size > s->size) { - s->data = realloc(s->data, t->size); - } - void* tmp = malloc(s->size); - if (tmp == NULL) { - ERROR("Failed to allocate memory for stack swapping!"); - exit(EXIT_FAILURE); - } - isize shead = s->head; +void stack_swap(Stack* s, Stack* t) { + if (s->size > t->size) { + t->data = realloc(t->data, s->size); + } else if (t->size > s->size) { + s->data = realloc(s->data, t->size); + } + void* tmp = malloc(s->size); + if (tmp == NULL) { + ERROR("Failed to allocate memory for stack swapping!"); + exit(EXIT_FAILURE); + } + isize shead = s->head; - memcpy(tmp, s->data, s->size); - memcpy(s->data, t->data, t->size); - memcpy(t->data, tmp, s->size); + memcpy(tmp, s->data, s->size); + memcpy(s->data, t->data, t->size); + memcpy(t->data, tmp, s->size); - s->head = t->head; - t->head = shead; - free(tmp); + s->head = t->head; + t->head = shead; + free(tmp); } diff --git a/src/state.c b/src/state.c index f963c4e..55f2a12 100644 --- a/src/state.c +++ b/src/state.c @@ -1,26 +1,26 @@ #include <string.h> -#include <engine/state.h> -#include <engine/logging.h> #include <engine/dltools.h> #include <engine/input.h> +#include <engine/logging.h> +#include <engine/state.h> typedef StateType state_update_t(void*); -const char *StateTypeStr[] = { - "null", +const char* StateTypeStr[] = { + "null", #define State(name) #name, #include <states/list_of_states.h> #undef State - "quit", + "quit", }; // Setup API for states -#define State(name) \ -typedef struct name##_state name##_state; \ -typedef void (state_##name##_init_t)(name##_state*); \ -typedef void (state_##name##_free_t)(name##_state*); \ -typedef StateType (state_##name##_update_t)(name##_state*); +#define State(name) \ + typedef struct name##_state name##_state; \ + typedef void(state_##name##_init_t)(name##_state*); \ + typedef void(state_##name##_free_t)(name##_state*); \ + typedef StateType(state_##name##_update_t)(name##_state*); #include <states/list_of_states.h> #undef State @@ -28,20 +28,20 @@ typedef StateType (state_##name##_update_t)(name##_state*); // When hotreloading is enabled, we want to assign state function pointers // dynamically. -#define State(name) \ -state_##name##_init_t *name##_init = NULL; \ -state_##name##_free_t *name##_free = NULL; \ -state_##name##_update_t *name##_update = NULL; \ - \ -void* libstate_##name = NULL; \ -const char* libstate_##name##_str = "lib" #name ".so"; +#define State(name) \ + state_##name##_init_t* name##_init = NULL; \ + state_##name##_free_t* name##_free = NULL; \ + state_##name##_update_t* name##_update = NULL; \ + \ + void* libstate_##name = NULL; \ + const char* libstate_##name##_str = "lib" #name ".so"; #else // Otherwise we just declare them. -#define State(name) \ -extern state_##name##_init_t name##_init; \ -extern state_##name##_free_t name##_free; \ -extern state_##name##_update_t name##_update; +#define State(name) \ + extern state_##name##_init_t name##_init; \ + extern state_##name##_free_t name##_free; \ + extern state_##name##_update_t name##_update; #endif #include <states/list_of_states.h> @@ -51,128 +51,128 @@ extern state_##name##_update_t name##_update; void binding_t_free(binding_t* b); -void State_init(StateType type, memory *mem) { +void State_init(StateType type, memory* mem) { switch (type) { -#define State(name) \ - case (STATE_##name): { \ - name##_init(memory_allocate(mem, sizeof(name##_state))); \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + name##_init(memory_allocate(mem, sizeof(name##_state))); \ + break; \ + } #include <states/list_of_states.h> #undef State - case STATE_null: - case STATE_quit: - DEBUG("Got %s state.\n", StateTypeStr[type]); - break; - default: - exit(EXIT_FAILURE); + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); } } - -void State_free(StateType type, memory *mem) { +void State_free(StateType type, memory* mem) { switch (type) { -#define State(name) \ - case (STATE_##name): { \ - name##_free(mem->data); \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + name##_free(mem->data); \ + break; \ + } #include <states/list_of_states.h> #undef State - case STATE_null: - case STATE_quit: - DEBUG("Got %s state.\n", StateTypeStr[type]); - break; - default: - exit(EXIT_FAILURE); + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); } memory_clear(mem); } - StateType (*State_updateFunc(StateType type))(void*) { switch (type) { #ifdef DAW_BUILD_HOTRELOAD -#define State(name) \ - case (STATE_##name): { \ - return (state_update_t*)name##_update; \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + return (state_update_t*)name##_update; \ + break; \ + } #else -#define State(name) \ - case (STATE_##name): { \ - return (state_update_t*)&name##_update; \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + return (state_update_t*)&name##_update; \ + break; \ + } #endif #include <states/list_of_states.h> #undef State - case STATE_null: - case STATE_quit: - return NULL; //DEBUG("Got %s state.\n", StateTypeStr[type]); - break; - default: - exit(EXIT_FAILURE); + case STATE_null: + case STATE_quit: + return NULL; // DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); } return NULL; } -StateType State_update(StateType type, memory *mem) { +StateType State_update(StateType type, memory* mem) { StateType next_state = STATE_null; switch (type) { -#define State(name) \ - case (STATE_##name): { \ - next_state = name##_update(mem->data); \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + next_state = name##_update(mem->data); \ + break; \ + } #include <states/list_of_states.h> #undef State - case STATE_null: - case STATE_quit: - DEBUG("Got %s state.\n", StateTypeStr[type]); - break; - default: - exit(EXIT_FAILURE); + case STATE_null: + case STATE_quit: + DEBUG("Got %s state.\n", StateTypeStr[type]); + break; + default: + exit(EXIT_FAILURE); } return next_state; } #ifdef DAW_BUILD_HOTRELOAD -bool State_reload(StateType type, i_ctx **ctx, usize ctx_len) { - void* libptr = NULL; +bool State_reload(StateType type, i_ctx** ctx, usize ctx_len) { + void* libptr = NULL; switch (type) { -#define State(name) \ - case (STATE_##name): { \ - if (libstate_##name == NULL) { \ - libstate_##name = dynamic_library_open(libstate_##name##_str); \ - } else { \ - libstate_##name = \ - dynamic_library_reload(libstate_##name, libstate_##name##_str); \ - } \ - if (libstate_##name == NULL) { \ - ERROR("Failed loading shared object: %s (%s)", \ - libstate_##name##_str, \ - dynamic_library_get_error()); \ - return false; \ - } \ - \ - name##_init = (state_##name##_init_t*)dynamic_library_get_symbol(libstate_##name, STR( name##_init ) ); \ - name##_free = (state_##name##_free_t*)dynamic_library_get_symbol(libstate_##name, STR( name##_free ) ); \ - name##_update = (state_##name##_update_t*)dynamic_library_get_symbol(libstate_##name, STR( name##_update ) ); \ - libptr = libstate_##name; \ - break; \ - } +#define State(name) \ + case (STATE_##name): { \ + if (libstate_##name == NULL) { \ + libstate_##name = dynamic_library_open(libstate_##name##_str); \ + } else { \ + libstate_##name = \ + dynamic_library_reload(libstate_##name, libstate_##name##_str); \ + } \ + if (libstate_##name == NULL) { \ + ERROR("Failed loading shared object: %s (%s)", libstate_##name##_str, \ + dynamic_library_get_error()); \ + return false; \ + } \ + \ + name##_init = (state_##name##_init_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_init)); \ + name##_free = (state_##name##_free_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_free)); \ + name##_update = (state_##name##_update_t*)dynamic_library_get_symbol( \ + libstate_##name, STR(name##_update)); \ + libptr = libstate_##name; \ + break; \ + } #include <states/list_of_states.h> #undef State - case STATE_null: - case STATE_quit: - ERROR("Invalid state"); - DEBUG("Got %s state.\n", StateTypeStr[type]); - return false; - default: - exit(EXIT_FAILURE); + case STATE_null: + case STATE_quit: + ERROR("Invalid state"); + DEBUG("Got %s state.\n", StateTypeStr[type]); + return false; + default: + exit(EXIT_FAILURE); } - return state_refresh_input_ctx(libptr, ctx, ctx_len); + return state_refresh_input_ctx(libptr, ctx, ctx_len); } #endif diff --git a/src/ui_positioning.c b/src/ui_positioning.c index fc8ab0a..07d53a3 100644 --- a/src/ui_positioning.c +++ b/src/ui_positioning.c @@ -5,813 +5,889 @@ #include <stdint.h> #define ENGINE_INTERNALS -#include <engine/engine.h> #include <engine/btree.h> +#include <engine/engine.h> static Engine_color DEFAULT_FG = {0xFF, 0xFF, 0xFF, 0xFF}; static Engine_color DEFAULT_BG = {0x00, 0x00, 0x00, 0xFF}; -static i32 DEFAULT_PADDING = 8; -static i32 DEFAULT_MARGIN = 0; +static i32 DEFAULT_PADDING = 8; +static i32 DEFAULT_MARGIN = 0; /* We want to keep track of the roots of the UI elements, s.t. we can resize and * reposition the elements if needed be. */ -struct btree *GLOBAL_UIROOTS = NULL; +struct btree* GLOBAL_UIROOTS = NULL; -extern Platform *GLOBAL_PLATFORM; +extern Platform* GLOBAL_PLATFORM; -const char *uitype_str[] = { - [uitype_container] = "uitype_container", - [uitype_button] = "uitype_button", - [uitype_title] = "uitype_title", - [uitype_text] = "uitype_text", - [uitype_MAX] = "uitype_MAX", - NULL, +const char* uitype_str[] = { + [uitype_container] = "uitype_container", + [uitype_button] = "uitype_button", + [uitype_title] = "uitype_title", + [uitype_text] = "uitype_text", + [uitype_MAX] = "uitype_MAX", + NULL, }; -const char *constraint_str[] = { - [ui_constraint_width] = "ui_constraint_width", - [ui_constraint_height] = "ui_constraint_height", +const char* constraint_str[] = { + [ui_constraint_width] = "ui_constraint_width", + [ui_constraint_height] = "ui_constraint_height", - [ui_constraint_horizontal_align] = "ui_constraint_horizontal_align", - [ui_constraint_vertical_align] = "ui_constraint_vertical_align", + [ui_constraint_horizontal_align] = "ui_constraint_horizontal_align", + [ui_constraint_vertical_align] = "ui_constraint_vertical_align", - [ui_constraint_left] = "ui_constraint_left", - [ui_constraint_right] = "ui_constraint_right", - [ui_constraint_top] = "ui_constraint_top", - [ui_constraint_bottom] = "ui_constraint_bottom", + [ui_constraint_left] = "ui_constraint_left", + [ui_constraint_right] = "ui_constraint_right", + [ui_constraint_top] = "ui_constraint_top", + [ui_constraint_bottom] = "ui_constraint_bottom", }; -static i32 pointer_cmp(const void *a, const void *b) { - const u64 *x = a; - const u64 *y = b; - /* We just use the address as index */ - return *x - *y; +static i32 pointer_cmp(const void* a, const void* b) { + const u64* x = a; + const u64* y = b; + /* We just use the address as index */ + return *x - *y; } -static void pointer_print(const void *a) { - const u64 *t = a; - printf("%lx\n", *t); +static void pointer_print(const void* a) { + const u64* t = a; + printf("%lx\n", *t); } -void ui_rearrange(UITree *root, v2_i32 ppos, v2_i32 psize); -i32 get_padding(UITree *t); -i32 get_margin(UITree *t); -v2_i32 get_pos(UITree *t); -v2_i32 get_size(UITree *t); +void ui_rearrange(UITree* root, v2_i32 ppos, v2_i32 psize); +i32 get_padding(UITree* t); +i32 get_margin(UITree* t); +v2_i32 get_pos(UITree* t); +v2_i32 get_size(UITree* t); f32 ui_size_pixel_to_percent_width(i32 pixels) { - return (f32)pixels / (f32)GLOBAL_PLATFORM->window->windowsize.x; + return (f32)pixels / (f32)GLOBAL_PLATFORM->window->windowsize.x; } f32 ui_size_pixel_to_percent_height(i32 pixels) { - return (f32)pixels / (f32)GLOBAL_PLATFORM->window->windowsize.y; + return (f32)pixels / (f32)GLOBAL_PLATFORM->window->windowsize.y; } -f32 ui_size_pixel_to_percent(i32 pixels) { return ui_size_percent_height_to_pixel(pixels); } +f32 ui_size_pixel_to_percent(i32 pixels) { + return ui_size_percent_height_to_pixel(pixels); +} i32 ui_size_percent_width_to_pixel(f32 percent) { - return (i32)(percent * GLOBAL_PLATFORM->window->windowsize.x); + return (i32)(percent * GLOBAL_PLATFORM->window->windowsize.x); } i32 ui_size_percent_height_to_pixel(f32 percent) { - return (i32)(percent * GLOBAL_PLATFORM->window->windowsize.y); + return (i32)(percent * GLOBAL_PLATFORM->window->windowsize.y); } -i32 ui_size_percent_to_pixel(f32 percent) {return ui_size_percent_height_to_pixel(percent); } +i32 ui_size_percent_to_pixel(f32 percent) { + return ui_size_percent_height_to_pixel(percent); +} i32 ui_size_to_pixel_ex(ui_size s, bool vertical, v2_i32 psize) { - if (s.type == ui_size_pixel) { - return s.pixel.value; - } else { - psize.x = MAX(1, psize.x); - psize.y = MAX(1, psize.y); - if (vertical) { - return psize.y * s.percent.value; - } - return psize.x * s.percent.value; - } + if (s.type == ui_size_pixel) { + return s.pixel.value; + } else { + psize.x = MAX(1, psize.x); + psize.y = MAX(1, psize.y); + if (vertical) { + return psize.y * s.percent.value; + } + return psize.x * s.percent.value; + } } i32 ui_size_to_pixel(ui_size s) { - if (s.type == ui_size_pixel) { - return s.pixel.value; - } else { - return ui_size_percent_height_to_pixel(s.percent.value); - } + if (s.type == ui_size_pixel) { + return s.pixel.value; + } else { + return ui_size_percent_height_to_pixel(s.percent.value); + } } -void ui_add(UITree *t) { +void ui_add(UITree* t) { - if (GLOBAL_UIROOTS == NULL) { - GLOBAL_UIROOTS = btree_new(sizeof(void*), 16, &pointer_cmp); - } + if (GLOBAL_UIROOTS == NULL) { + GLOBAL_UIROOTS = btree_new(sizeof(void*), 16, &pointer_cmp); + } - u64 tmp = (u64)t; - btree_insert(GLOBAL_UIROOTS, &tmp); + u64 tmp = (u64)t; + btree_insert(GLOBAL_UIROOTS, &tmp); } void clear_ui(void) { - UITree *t = NULL; - while((t = btree_first(GLOBAL_UIROOTS)) != NULL) { - uitree_free(t); - if (!btree_delete(GLOBAL_UIROOTS, t)) { - WARN("Failed deletion"); - UITree *elem = (UITree*)t; - WARN("Failed to remove %s from global ui-table", uitype_str[elem->type]); - } - } + UITree* t = NULL; + while ((t = btree_first(GLOBAL_UIROOTS)) != NULL) { + uitree_free(t); + if (!btree_delete(GLOBAL_UIROOTS, t)) { + WARN("Failed deletion"); + UITree* elem = (UITree*)t; + WARN("Failed to remove %s from global ui-table", uitype_str[elem->type]); + } + } } - /* Unwraps the size to a v2_i32 */ -v2_i32 uitree_get_size(UITree *t) { - if (t == NULL) return (v2_i32){.x=-1, .y=-1}; - switch (t->type) { - case uitype_container: return (v2_i32){.x=t->container.w, .y=t->container.h}; - case uitype_button: return (v2_i32){.x=t->button.w, .y=t->button.h}; - case uitype_title: return (v2_i32){.x=t->title.w, .y=t->title.h}; - case uitype_text: return (v2_i32){.x=t->text.w, .y=t->text.h}; - default: return (v2_i32){.x=-1, .y=-1}; - } +v2_i32 uitree_get_size(UITree* t) { + if (t == NULL) return (v2_i32){.x = -1, .y = -1}; + switch (t->type) { + case uitype_container: + return (v2_i32){.x = t->container.w, .y = t->container.h}; + case uitype_button: + return (v2_i32){.x = t->button.w, .y = t->button.h}; + case uitype_title: + return (v2_i32){.x = t->title.w, .y = t->title.h}; + case uitype_text: + return (v2_i32){.x = t->text.w, .y = t->text.h}; + default: + return (v2_i32){.x = -1, .y = -1}; + } } - /* elem_size also takes into account the padding and other stuffs */ -v2_i32 elem_size(UITree *root) { - if (root == NULL) return (v2_i32){0,0}; +v2_i32 elem_size(UITree* root) { + if (root == NULL) return (v2_i32){0, 0}; - const i32 total_padding = 2 * get_padding(root); - return v2_i32_add_i(uitree_get_size(root), total_padding); + const i32 total_padding = 2 * get_padding(root); + return v2_i32_add_i(uitree_get_size(root), total_padding); } -v2_i32 elem_size_spacing(UITree *root) { - if (root == NULL) return (v2_i32){0,0}; +v2_i32 elem_size_spacing(UITree* root) { + if (root == NULL) return (v2_i32){0, 0}; - const i32 total_margin = 2 * get_padding(root) + 2 * get_margin(root); - return v2_i32_add_i(uitree_get_size(root), total_margin); + const i32 total_margin = 2 * get_padding(root) + 2 * get_margin(root); + return v2_i32_add_i(uitree_get_size(root), total_margin); } -UITree *ui_container_new_ex( - Engine_color fg, - Engine_color bg, - Engine_color border, - bool direction, - struct List_ui_constraint *constraints) { +UITree* ui_container_new_ex(Engine_color fg, Engine_color bg, + Engine_color border, bool direction, + struct List_ui_constraint* constraints) { - UITree *t = malloc(sizeof(UITree)); + UITree* t = malloc(sizeof(UITree)); - t->container.type = uitype_container; - t->container.visible = true; - t->container.direction = direction; + t->container.type = uitype_container; + t->container.visible = true; + t->container.direction = direction; - /* -1 == unsolved constraint */ - t->container.x = -1; - t->container.y = -1; - t->container.w = -1; - t->container.h = -1; - t->container.padding = 0; - t->container.margin = 0; + /* -1 == unsolved constraint */ + t->container.x = -1; + t->container.y = -1; + t->container.w = -1; + t->container.h = -1; + t->container.padding = 0; + t->container.margin = 0; - t->container.fg = fg; - t->container.bg = bg; - t->container.bordercolor = border; + t->container.fg = fg; + t->container.bg = bg; + t->container.bordercolor = border; + t->container.children = NULL; + t->container.children_len = 0; + t->container.children_size = 0; - t->container.children = NULL; - t->container.children_len = 0; - t->container.children_size = 0; + t->container.constraints = constraints; - t->container.constraints = constraints; + ui_rearrange(t, (v2_i32){0, 0}, (v2_i32){0, 0}); - ui_rearrange(t, (v2_i32){0,0}, (v2_i32){0,0}); + ui_add(t); - ui_add(t); - - return t; + return t; } -UITree *ui_container(bool direction, struct List_ui_constraint *constraints) { - return ui_container_new_ex( - /* We set border color to fg by default */ - DEFAULT_FG, DEFAULT_BG, DEFAULT_FG, direction, - constraints); +UITree* ui_container(bool direction, struct List_ui_constraint* constraints) { + return ui_container_new_ex( + /* We set border color to fg by default */ + DEFAULT_FG, DEFAULT_BG, DEFAULT_FG, direction, constraints); } -UITree *ui_title(i32 font_id, const char *text, struct List_ui_constraint *constraints) { - UITree_title *t = malloc(sizeof(UITree)); - t->type = uitype_title; +UITree* ui_title(i32 font_id, const char* text, + struct List_ui_constraint* constraints) { + UITree_title* t = malloc(sizeof(UITree)); + t->type = uitype_title; - t->x = -1; - t->y = -1; + t->x = -1; + t->y = -1; - t->padding = DEFAULT_PADDING; - t->margin = DEFAULT_MARGIN; + t->padding = DEFAULT_PADDING; + t->margin = DEFAULT_MARGIN; - t->fg = DEFAULT_FG; + t->fg = DEFAULT_FG; - t->font_id = font_id; - t->text_original = text; - t->text_texture_index = - engine_render_text(font_id, t->fg, (char*)text, &t->texture_size, false); + t->font_id = font_id; + t->text_original = text; + t->text_texture_index = + engine_render_text(font_id, t->fg, (char*)text, &t->texture_size, false); - t->w = t->texture_size.x; - t->h = t->texture_size.y; + t->w = t->texture_size.x; + t->h = t->texture_size.y; - t->constraints = constraints; + t->constraints = constraints; - ui_rearrange((UITree*)t, (v2_i32){0,0}, (v2_i32){0,0}); + ui_rearrange((UITree*)t, (v2_i32){0, 0}, (v2_i32){0, 0}); - ui_add((UITree*)t); + ui_add((UITree*)t); - return (UITree*)t; + return (UITree*)t; } -UITree *ui_text(i32 font_id, const char *text, struct List_ui_constraint *constraints) { - UITree *t = malloc(sizeof(UITree)); - t->text.type = uitype_text; +UITree* ui_text(i32 font_id, const char* text, + struct List_ui_constraint* constraints) { + UITree* t = malloc(sizeof(UITree)); + t->text.type = uitype_text; - t->text.x = -1; - t->text.y = -1; + t->text.x = -1; + t->text.y = -1; - t->text.padding = 0; - t->text.margin = DEFAULT_MARGIN / 2; + t->text.padding = 0; + t->text.margin = DEFAULT_MARGIN / 2; - t->text.fg = DEFAULT_FG; + t->text.fg = DEFAULT_FG; - t->text.font_id = font_id; - t->text.text_original = text; + t->text.font_id = font_id; + t->text.text_original = text; - /* Postpone rendering until we have a clear set of size-constraints */ + /* Postpone rendering until we have a clear set of size-constraints */ - //t->text.text_texture_index = - // engine_render_text(font_id, DEFAULT_FG, (char*)text, &t->text.texture_size, true); + // t->text.text_texture_index = + // engine_render_text(font_id, DEFAULT_FG, (char*)text, + //&t->text.texture_size, true); - //t->text.w = t->text.texture_size.x; - //t->text.h = t->text.texture_size.y; + // t->text.w = t->text.texture_size.x; + // t->text.h = t->text.texture_size.y; - t->text.constraints = constraints; + t->text.constraints = constraints; - ui_rearrange(t, (v2_i32){0,0}, (v2_i32){0,0}); + ui_rearrange(t, (v2_i32){0, 0}, (v2_i32){0, 0}); - ui_add(t); + ui_add(t); - return t; + return t; } -UITree *ui_button(u64 id, i32 font_id, char *text, struct List_ui_constraint *constraints) { - UITree_button *t = malloc(sizeof(UITree)); - t->type = uitype_button; +UITree* ui_button(u64 id, i32 font_id, char* text, + struct List_ui_constraint* constraints) { + UITree_button* t = malloc(sizeof(UITree)); + t->type = uitype_button; - t->enabled = true; - t->id = id; - t->x = -1; - t->y = -1; - t->padding = DEFAULT_PADDING; - t->margin = DEFAULT_MARGIN; + t->enabled = true; + t->id = id; + t->x = -1; + t->y = -1; + t->padding = DEFAULT_PADDING; + t->margin = DEFAULT_MARGIN; - t->fg = DEFAULT_FG; - t->bg = DEFAULT_BG; + t->fg = DEFAULT_FG; + t->bg = DEFAULT_BG; - t->font_id = font_id; - t->text_original = text; - t->text_texture_index = - engine_render_text(font_id, t->fg, (char*)text, &t->texture_size, false); + t->font_id = font_id; + t->text_original = text; + t->text_texture_index = + engine_render_text(font_id, t->fg, (char*)text, &t->texture_size, false); - t->w = t->texture_size.x; - t->h = t->texture_size.y; + t->w = t->texture_size.x; + t->h = t->texture_size.y; - t->constraints = constraints; + t->constraints = constraints; - ui_rearrange((UITree*)t, (v2_i32){0,0}, (v2_i32){0,0}); + ui_rearrange((UITree*)t, (v2_i32){0, 0}, (v2_i32){0, 0}); - ui_add((UITree*)t); + ui_add((UITree*)t); - return (UITree*)t; + return (UITree*)t; } -void uitree_free(UITree *t) { - switch (t->type) { - case uitype_container: - if (t->container.children != NULL && t->container.children_len > 0) { - for (usize i = 0; i < t->container.children_len; i++) { - uitree_free(t->container.children[i]); - } - free(t->container.children); - } - break; - case uitype_button: - case uitype_title: - case uitype_text: - free(t); - break; - default: break; - } +void uitree_free(UITree* t) { + switch (t->type) { + case uitype_container: + if (t->container.children != NULL && t->container.children_len > 0) { + for (usize i = 0; i < t->container.children_len; i++) { + uitree_free(t->container.children[i]); + } + free(t->container.children); + } + break; + case uitype_button: + case uitype_title: + case uitype_text: + free(t); + break; + default: + break; + } } - -struct List_ui_constraint* get_constraints(UITree *t) { - switch (t->type) { - case uitype_container: return t->container.constraints; - case uitype_button: return t->button.constraints; - case uitype_title: return t->title.constraints; - case uitype_text: return t->text.constraints; - default: return NULL; - } +struct List_ui_constraint* get_constraints(UITree* t) { + switch (t->type) { + case uitype_container: + return t->container.constraints; + case uitype_button: + return t->button.constraints; + case uitype_title: + return t->title.constraints; + case uitype_text: + return t->text.constraints; + default: + return NULL; + } } - -i32 get_padding(UITree *t) { - switch (t->type) { - case uitype_container: return t->container.padding; - case uitype_button: return t->button.padding; - case uitype_title: return t->title.padding; - case uitype_text: return t->text.padding; - default: return 0; - } +i32 get_padding(UITree* t) { + switch (t->type) { + case uitype_container: + return t->container.padding; + case uitype_button: + return t->button.padding; + case uitype_title: + return t->title.padding; + case uitype_text: + return t->text.padding; + default: + return 0; + } } - -i32 get_margin(UITree *t) { - switch (t->type) { - case uitype_container: return t->container.margin; - case uitype_button: return t->button.margin; - case uitype_title: return t->title.margin; - case uitype_text: return t->text.margin; - default: return 0; - } +i32 get_margin(UITree* t) { + switch (t->type) { + case uitype_container: + return t->container.margin; + case uitype_button: + return t->button.margin; + case uitype_title: + return t->title.margin; + case uitype_text: + return t->text.margin; + default: + return 0; + } } -v2_i32 get_pos(UITree *t) { - switch (t->type) { - case uitype_container: return (v2_i32){t->container.x, t->container.y}; - case uitype_button: return (v2_i32){t->button.x, t->button.y}; - case uitype_title: return (v2_i32){t->title.x, t->title.y}; - case uitype_text: return (v2_i32){t->text.x, t->text.y}; - default: return (v2_i32){0, 0}; - } +v2_i32 get_pos(UITree* t) { + switch (t->type) { + case uitype_container: + return (v2_i32){t->container.x, t->container.y}; + case uitype_button: + return (v2_i32){t->button.x, t->button.y}; + case uitype_title: + return (v2_i32){t->title.x, t->title.y}; + case uitype_text: + return (v2_i32){t->text.x, t->text.y}; + default: + return (v2_i32){0, 0}; + } } -v2_i32 get_size(UITree *t) { - switch (t->type) { - case uitype_container: return (v2_i32){t->container.w, t->container.h}; - case uitype_button: return (v2_i32){t->button.w, t->button.h}; - case uitype_title: return (v2_i32){t->title.w, t->title.h}; - case uitype_text: return (v2_i32){t->text.w, t->text.h}; - default: return (v2_i32){0, 0}; - } +v2_i32 get_size(UITree* t) { + switch (t->type) { + case uitype_container: + return (v2_i32){t->container.w, t->container.h}; + case uitype_button: + return (v2_i32){t->button.w, t->button.h}; + case uitype_title: + return (v2_i32){t->title.w, t->title.h}; + case uitype_text: + return (v2_i32){t->text.w, t->text.h}; + default: + return (v2_i32){0, 0}; + } } -#define SETVAL(VAL, tt) { if ((VAL) > 0) t->tt = VAL; } -void uitree_set_pos(UITree *t, v2_i32 newpos) { - switch (t->type) { - case uitype_container: SETVAL( newpos.x, container.x); SETVAL( newpos.y, container.y); break; - case uitype_button: SETVAL( newpos.x, button.x ); SETVAL( newpos.y, button.y ); break; - case uitype_title: SETVAL( newpos.x, title.x ); SETVAL( newpos.y, title.y ); break; - case uitype_text: SETVAL( newpos.x, text.x ); SETVAL( newpos.y, text.y ); break; - default: return; - } +#define SETVAL(VAL, tt) \ + { \ + if ((VAL) > 0) t->tt = VAL; \ + } +void uitree_set_pos(UITree* t, v2_i32 newpos) { + switch (t->type) { + case uitype_container: + SETVAL(newpos.x, container.x); + SETVAL(newpos.y, container.y); + break; + case uitype_button: + SETVAL(newpos.x, button.x); + SETVAL(newpos.y, button.y); + break; + case uitype_title: + SETVAL(newpos.x, title.x); + SETVAL(newpos.y, title.y); + break; + case uitype_text: + SETVAL(newpos.x, text.x); + SETVAL(newpos.y, text.y); + break; + default: + return; + } } - -void uitree_set_size(UITree *t, v2_i32 size) { - switch (t->type) { - case uitype_container: SETVAL( size.x, container.w); SETVAL( size.y, container.h); break; - case uitype_button: SETVAL( size.x, button.w ); SETVAL( size.y, button.h ); break; - case uitype_title: SETVAL( size.x, title.w ); SETVAL( size.y, title.h ); break; - case uitype_text: SETVAL( size.x, text.w ); SETVAL( size.y, text.h ); break; - default: return; - } +void uitree_set_size(UITree* t, v2_i32 size) { + switch (t->type) { + case uitype_container: + SETVAL(size.x, container.w); + SETVAL(size.y, container.h); + break; + case uitype_button: + SETVAL(size.x, button.w); + SETVAL(size.y, button.h); + break; + case uitype_title: + SETVAL(size.x, title.w); + SETVAL(size.y, title.h); + break; + case uitype_text: + SETVAL(size.x, text.w); + SETVAL(size.y, text.h); + break; + default: + return; + } } +bool uitree_has_constraint(UITree* t, const ui_constraint_t constraint) { + struct List_ui_constraint* c = NULL; + struct List_ui_constraint* first_constraint; + if (t == NULL) { + ERROR("%s got nullptr argument!", __func__); + exit(EXIT_FAILURE); + } -bool uitree_has_constraint(UITree *t, const ui_constraint_t constraint) { - struct List_ui_constraint* c = NULL; - struct List_ui_constraint* first_constraint; - if (t == NULL) {ERROR("%s got nullptr argument!", __func__); exit(EXIT_FAILURE);} - - switch (t->type) { - case uitype_container: c = t->container.constraints; break; - case uitype_button: c = t->button.constraints; break; - case uitype_title: c = t->title.constraints; break; - case uitype_text: c = t->text.constraints; break; - default: break; - } + switch (t->type) { + case uitype_container: + c = t->container.constraints; + break; + case uitype_button: + c = t->button.constraints; + break; + case uitype_title: + c = t->title.constraints; + break; + case uitype_text: + c = t->text.constraints; + break; + default: + break; + } - first_constraint = c; + first_constraint = c; - while (c != NULL) { - if ((void*)c->next == (void*)first_constraint) { - ERROR("Infinite constraint loop detected!"); - exit(EXIT_FAILURE); - } - if (constraint == c->value.type) return true; + while (c != NULL) { + if ((void*)c->next == (void*)first_constraint) { + ERROR("Infinite constraint loop detected!"); + exit(EXIT_FAILURE); + } + if (constraint == c->value.type) return true; - c = c->next; - } - return false; + c = c->next; + } + return false; } +void ui_constraints_apply(UITree* t, v2_i32 ppos, v2_i32 psize) { + struct List_ui_constraint* constraints = get_constraints(t); + struct List_ui_constraint* first_constraint = constraints; + v2_i32 tsize = uitree_get_size(t); -void ui_constraints_apply(UITree *t, v2_i32 ppos, v2_i32 psize) { - struct List_ui_constraint* constraints = get_constraints(t); - struct List_ui_constraint* first_constraint = constraints; - v2_i32 tsize = uitree_get_size(t); + if (constraints == NULL) return; - if (constraints == NULL) return; + while (constraints != NULL) { + if ((void*)constraints->next == (void*)first_constraint) { + ERROR("Infinite constraint loop detected!"); + ERROR(" Type: %s", constraint_str[constraints->value.type]); + exit(EXIT_FAILURE); + } - while (constraints != NULL) { - if ((void*)constraints->next == (void*)first_constraint) { - ERROR("Infinite constraint loop detected!"); - ERROR(" Type: %s", constraint_str[constraints->value.type]); - exit(EXIT_FAILURE); - } + const constraintval_t con = constraints->value.constraint; - const constraintval_t con = constraints->value.constraint; + switch (constraints->value.type) { + case ui_constraint_width: { + i32 ww = ui_size_to_pixel_ex(con.width.size, false, psize); + if (con.width.size.type == ui_size_percent) ww -= 2 * get_padding(t); + /* FIXME: Resizing the window makes some elements retain their + * size on window resize. + * This is fixed by replacing MAX(...) with just `ww`, + * This in turn makes elements that are supposed to have some + * relative width not take up the full width. */ + uitree_set_size(t, (v2_i32){.x = MAX(tsize.x, ww), .y = 0}); + tsize = uitree_get_size(t); + } break; - switch(constraints->value.type) { - case ui_constraint_width: - { - i32 ww = ui_size_to_pixel_ex(con.width.size, false, psize); - if (con.width.size.type == ui_size_percent) ww -= 2 * get_padding(t); - /* FIXME: Resizing the window makes some elements retain their - * size on window resize. - * This is fixed by replacing MAX(...) with just `ww`, - * This in turn makes elements that are supposed to have some - * relative width not take up the full width. */ - uitree_set_size(t, (v2_i32){.x=MAX(tsize.x, ww), .y=0}); - tsize = uitree_get_size(t); - } - break; + case ui_constraint_height: { + i32 ww = ui_size_to_pixel_ex(con.height.size, true, psize); + if (con.height.size.type == ui_size_percent) ww -= 2 * get_padding(t); + /* FIXME: Same as above */ + uitree_set_size(t, (v2_i32){.y = MAX(tsize.y, ww), .x = 0}); + tsize = uitree_get_size(t); + } break; - case ui_constraint_height: - { - i32 ww = ui_size_to_pixel_ex(con.height.size, true, psize); - if (con.height.size.type == ui_size_percent) ww -= 2 * get_padding(t); - /* FIXME: Same as above */ - uitree_set_size(t, (v2_i32){.y=MAX(tsize.y, ww), .x=0}); - tsize = uitree_get_size(t); - } - break; + case ui_constraint_horizontal_align: { + const i32 size = + ui_size_to_pixel_ex(con.horizontal_align.spacing, false, psize); + i32 new_x = ppos.x; + switch (con.horizontal_align.align) { + case ui_constraint_horizontal_align_left: + new_x += size + get_margin(t); + break; + case ui_constraint_horizontal_align_center: + new_x += (psize.x / 2) - (tsize.x / 2); + break; + case ui_constraint_horizontal_align_right: + new_x += psize.x - size - tsize.x - get_margin(t); + break; + } + uitree_set_pos(t, (v2_i32){.x = new_x, .y = 0}); + } break; + case ui_constraint_vertical_align: { + i32 size = ui_size_to_pixel_ex(con.horizontal_align.spacing, true, psize); + i32 new_y = ppos.y; + switch (con.vertical_align.align) { + case ui_constraint_vertical_align_top: + new_y += size + get_margin(t); + break; + case ui_constraint_vertical_align_center: + new_y += ((psize.y) / 2) - (tsize.y / 2); + break; + case ui_constraint_vertical_align_bottom: + new_y += psize.y - size - tsize.y - get_margin(t); + break; + } + uitree_set_pos(t, (v2_i32){.x = 0, .y = new_y}); + } break; - case ui_constraint_horizontal_align: - { - const i32 size = ui_size_to_pixel_ex(con.horizontal_align.spacing, false, psize); - i32 new_x = ppos.x; - switch (con.horizontal_align.align) { - case ui_constraint_horizontal_align_left: - new_x += size + get_margin(t); - break; - case ui_constraint_horizontal_align_center: - new_x += (psize.x / 2) - (tsize.x / 2); - break; - case ui_constraint_horizontal_align_right: - new_x += psize.x - size - tsize.x - get_margin(t); - break; - } - uitree_set_pos(t, (v2_i32){.x = new_x, .y = 0}); - } - break; + case ui_constraint_left: + uitree_set_pos(t, (v2_i32){.x = ppos.x + ui_size_to_pixel_ex( + con.left.pos, false, psize), + .y = 0}); + break; - case ui_constraint_vertical_align: - { - i32 size = ui_size_to_pixel_ex(con.horizontal_align.spacing, true, psize); - i32 new_y = ppos.y; - switch (con.vertical_align.align) { - case ui_constraint_vertical_align_top: - new_y += size + get_margin(t); - break; - case ui_constraint_vertical_align_center: - new_y += ((psize.y) / 2) - (tsize.y / 2); - break; - case ui_constraint_vertical_align_bottom: - new_y += psize.y - size - tsize.y - get_margin(t); - break; - } - uitree_set_pos(t, (v2_i32){.x = 0, .y = new_y}); - } - break; + case ui_constraint_top: + uitree_set_pos(t, (v2_i32){.y = ppos.y + ui_size_to_pixel_ex(con.top.pos, + true, psize), + .x = 0}); + break; - case ui_constraint_left: - uitree_set_pos(t, (v2_i32){ - .x = ppos.x + ui_size_to_pixel_ex(con.left.pos, false, psize), - .y=0 - }); - break; + case ui_constraint_right: + if (tsize.x > 0) + uitree_set_pos( + t, (v2_i32){.x = ppos.x + psize.x - + ui_size_to_pixel_ex(con.right.pos, false, psize) - + tsize.x, + .y = 0}); + break; - case ui_constraint_top: - uitree_set_pos(t, (v2_i32){ - .y = ppos.y + ui_size_to_pixel_ex(con.top.pos, true, psize), - .x=0 - }); - break; + case ui_constraint_bottom: + if (tsize.y > 0) + uitree_set_pos( + t, (v2_i32){.y = ppos.y + psize.y - + ui_size_to_pixel_ex(con.bottom.pos, true, psize) - + tsize.y, + .x = 0}); + break; - case ui_constraint_right: - if (tsize.x > 0) - uitree_set_pos(t, (v2_i32){ - .x = ppos.x + psize.x - ui_size_to_pixel_ex(con.right.pos, false, psize) - tsize.x, - .y=0 - }); - break; + default: + ERROR("Unknown constraint: %d", constraints->value.type); + exit(EXIT_FAILURE); + break; + } - case ui_constraint_bottom: - if (tsize.y > 0) - uitree_set_pos(t, (v2_i32){ - .y = ppos.y + psize.y - ui_size_to_pixel_ex(con.bottom.pos, true, psize) - tsize.y, - .x = 0 - }); - break; - - default: - ERROR("Unknown constraint: %d", constraints->value.type); - exit(EXIT_FAILURE); - break; - } - - constraints = constraints->next; - } + constraints = constraints->next; + } } -void ui_rearrange_container(UITree_container *c, v2_i32 ppos, v2_i32 psize) { - struct List_ui_constraint* constraints = c->constraints; - struct List_ui_constraint* first_constraint = constraints; - bool fitwidth = !uitree_has_constraint((UITree*)c, ui_constraint_width); - bool fitheight = !uitree_has_constraint((UITree*)c, ui_constraint_height); +void ui_rearrange_container(UITree_container* c, v2_i32 ppos, v2_i32 psize) { + struct List_ui_constraint* constraints = c->constraints; + struct List_ui_constraint* first_constraint = constraints; + bool fitwidth = !uitree_has_constraint((UITree*)c, ui_constraint_width); + bool fitheight = !uitree_has_constraint((UITree*)c, ui_constraint_height); - if (fitwidth) c->w = 0; - if (fitheight) c->h = 0; + if (fitwidth) c->w = 0; + if (fitheight) c->h = 0; - ui_constraints_apply((UITree*)c, ppos, psize); - /* Apply constraints to children here? */ - { - const v2_i32 pos = v2_i32_sub_i((v2_i32){.x=c->x, .y=c->y}, 0);//c->margin); - const v2_i32 size = v2_i32_sub_i((v2_i32){.x=c->w, .y=c->h}, (2+MAX(c->children_len-1, 0)) * c->padding); - for (usize cc = 0; cc < c->children_len; cc++) { - ui_rearrange(c->children[cc], pos, size); - } - } + ui_constraints_apply((UITree*)c, ppos, psize); + /* Apply constraints to children here? */ + { + const v2_i32 pos = + v2_i32_sub_i((v2_i32){.x = c->x, .y = c->y}, 0); // c->margin); + const v2_i32 size = + v2_i32_sub_i((v2_i32){.x = c->w, .y = c->h}, + (2 + MAX(c->children_len - 1, 0)) * c->padding); + for (usize cc = 0; cc < c->children_len; cc++) { + ui_rearrange(c->children[cc], pos, size); + } + } - /* TODO: We want to update children regardless of whether we are doing a fit - * on the size of children. Switch the conditions (fitwidth||fitheight) and - * (children_len > 0); the size-fit doesn't matter if there's no children, - * the childrens size only matters if we do a size-fit. */ + /* TODO: We want to update children regardless of whether we are doing a fit + * on the size of children. Switch the conditions (fitwidth||fitheight) and + * (children_len > 0); the size-fit doesn't matter if there's no children, + * the childrens size only matters if we do a size-fit. */ - /* If we do not have a size > -1 we need to adapt the size to all children - * and add a size constraint on the largest of one of them */ - if (fitwidth || fitheight) { + /* If we do not have a size > -1 we need to adapt the size to all children + * and add a size constraint on the largest of one of them */ + if (fitwidth || fitheight) { - i32 maxwidth = 2 * c->padding; - i32 maxheight = maxwidth; + i32 maxwidth = 2 * c->padding; + i32 maxheight = maxwidth; - if (c->children_len > 0) { - if (c->children == NULL) { - ERROR("Container has children_len(%d) > 0 but children pointer is NULL!", c->children_len); - exit(EXIT_FAILURE); - } + if (c->children_len > 0) { + if (c->children == NULL) { + ERROR( + "Container has children_len(%d) > 0 but children pointer is NULL!", + c->children_len); + exit(EXIT_FAILURE); + } - /* Calculate new posisitions and save the largest one */ - v2_i32 startpos = (v2_i32){.x=c->x + c->margin, .y=c->y + c->margin}; - v2_i32 startsize = (v2_i32){.x=c->w - (2 * c->padding), .y=c->h - (2 * c->padding)}; + /* Calculate new posisitions and save the largest one */ + v2_i32 startpos = (v2_i32){.x = c->x + c->margin, .y = c->y + c->margin}; + v2_i32 startsize = + (v2_i32){.x = c->w - (2 * c->padding), .y = c->h - (2 * c->padding)}; - for (usize cc = 0; cc < c->children_len; cc++) { - const v2_i32 childsize = elem_size(c->children[cc]); - i32 margin = (cc + 1 == c->children_len) ? 0 : MAX(c->padding, get_margin(c->children[cc])); + for (usize cc = 0; cc < c->children_len; cc++) { + const v2_i32 childsize = elem_size(c->children[cc]); + i32 margin = (cc + 1 == c->children_len) + ? 0 + : MAX(c->padding, get_margin(c->children[cc])); - /* We just sum up in the direction we are going */ - if (c->direction == DIRECTION_HORIZONTAL) { - maxwidth += childsize.x + margin; - maxheight = MAX(childsize.y + 2 * c->padding, maxheight); + /* We just sum up in the direction we are going */ + if (c->direction == DIRECTION_HORIZONTAL) { + maxwidth += childsize.x + margin; + maxheight = MAX(childsize.y + 2 * c->padding, maxheight); - startpos.x += childsize.x + margin; - startsize.x -= childsize.x + margin; - } else { - maxwidth = MAX(childsize.x + 2 * c->padding, maxwidth); - maxheight += childsize.y + margin; + startpos.x += childsize.x + margin; + startsize.x -= childsize.x + margin; + } else { + maxwidth = MAX(childsize.x + 2 * c->padding, maxwidth); + maxheight += childsize.y + margin; - startpos.y += childsize.y + margin; - startsize.y -= childsize.y + margin; - } - } + startpos.y += childsize.y + margin; + startsize.y -= childsize.y + margin; + } + } - struct List_ui_constraint* constraint_head = c->constraints; - struct List_ui_constraint constraint_width; - struct List_ui_constraint constraint_height; + struct List_ui_constraint* constraint_head = c->constraints; + struct List_ui_constraint constraint_width; + struct List_ui_constraint constraint_height; - if (fitwidth) { - /* Create new size constraint */ - constraint_width = (struct List_ui_constraint){ - .value = { - .type = ui_constraint_width, - .constraint.width = { - .size = ui_size_pixel_new(maxwidth), - }, - }, - .next = constraint_head, - }; + if (fitwidth) { + /* Create new size constraint */ + constraint_width = (struct List_ui_constraint){ + .value = + { + .type = ui_constraint_width, + .constraint.width = + { + .size = ui_size_pixel_new(maxwidth), + }, + }, + .next = constraint_head, + }; - /* Prepend it to the list of constraints */ - c->constraints = &constraint_width; - constraint_head = c->constraints; - } - if (fitheight) { - constraint_height = (struct List_ui_constraint){ - .value = { - .type = ui_constraint_height, - .constraint.height = { - .size = ui_size_pixel_new(maxheight), - }, - }, - .next = constraint_head, - }; - /* Prepend it to the list of constraints */ - c->constraints = &constraint_height; - //constraint_head = c->constraints; - /* TODO: Convert to scrollable container if the height is - * greater than some constant relative to the screen height */ - } + /* Prepend it to the list of constraints */ + c->constraints = &constraint_width; + constraint_head = c->constraints; + } + if (fitheight) { + constraint_height = (struct List_ui_constraint){ + .value = + { + .type = ui_constraint_height, + .constraint.height = + { + .size = ui_size_pixel_new(maxheight), + }, + }, + .next = constraint_head, + }; + /* Prepend it to the list of constraints */ + c->constraints = &constraint_height; + // constraint_head = c->constraints; + /* TODO: Convert to scrollable container if the height is + * greater than some constant relative to the screen height */ + } - /* Recurse with new constraints */ - ui_rearrange_container(c, ppos, psize); + /* Recurse with new constraints */ + ui_rearrange_container(c, ppos, psize); - /* Replace the original set of constraints, as the new ones will be - * out of scope once we return from the current call frame */ - c->constraints = first_constraint; + /* Replace the original set of constraints, as the new ones will be + * out of scope once we return from the current call frame */ + c->constraints = first_constraint; - /* Update child elements */ - /* This is 1:1 (almost) to the previous iteration of children */ - startpos = (v2_i32){c->x + c->padding, c->y + c->padding}; - startsize = (v2_i32){c->w - 2 * c->padding, c->h - 2 * c->padding}; + /* Update child elements */ + /* This is 1:1 (almost) to the previous iteration of children */ + startpos = (v2_i32){c->x + c->padding, c->y + c->padding}; + startsize = (v2_i32){c->w - 2 * c->padding, c->h - 2 * c->padding}; - for (usize cc = 0; cc < c->children_len; cc++) { - v2_i32 childsize = elem_size(c->children[cc]); - i32 margin = MAX(c->padding, get_margin(c->children[cc])); + for (usize cc = 0; cc < c->children_len; cc++) { + v2_i32 childsize = elem_size(c->children[cc]); + i32 margin = MAX(c->padding, get_margin(c->children[cc])); - v2_i32 startsize_2; - if (c->direction == DIRECTION_HORIZONTAL) { - startsize_2 = (v2_i32){childsize.x, startsize.y}; - } else { - startsize_2 = (v2_i32){startsize.x, childsize.y}; - } - ui_rearrange(c->children[cc], startpos, startsize_2); + v2_i32 startsize_2; + if (c->direction == DIRECTION_HORIZONTAL) { + startsize_2 = (v2_i32){childsize.x, startsize.y}; + } else { + startsize_2 = (v2_i32){startsize.x, childsize.y}; + } + ui_rearrange(c->children[cc], startpos, startsize_2); - if (c->direction == DIRECTION_HORIZONTAL) { - maxwidth += childsize.x + margin; - maxheight = MAX(childsize.y, maxheight); + if (c->direction == DIRECTION_HORIZONTAL) { + maxwidth += childsize.x + margin; + maxheight = MAX(childsize.y, maxheight); - startpos.x += childsize.x + margin; - startsize.x -= childsize.x + margin; + startpos.x += childsize.x + margin; + startsize.x -= childsize.x + margin; - } else { - maxwidth = MAX(childsize.x + 2 * c->padding, maxwidth); - maxheight += childsize.y + margin; + } else { + maxwidth = MAX(childsize.x + 2 * c->padding, maxwidth); + maxheight += childsize.y + margin; - startpos.y += childsize.y + margin; - startsize.y -= childsize.y + margin; - } - } - } - } + startpos.y += childsize.y + margin; + startsize.y -= childsize.y + margin; + } + } + } + } } -void ui_rearrange_button(UITree_button *t, v2_i32 ppos, v2_i32 psize) { - t->x = ppos.x; - t->y = ppos.y; +void ui_rearrange_button(UITree_button* t, v2_i32 ppos, v2_i32 psize) { + t->x = ppos.x; + t->y = ppos.y; - ui_constraints_apply((UITree*)t, ppos, psize); + ui_constraints_apply((UITree*)t, ppos, psize); } -void ui_rearrange_title(UITree_title *t, v2_i32 ppos, v2_i32 psize) { - /*Defaults to just sit in the top-left corner of the parent*/ - t->x = ppos.x; - t->y = ppos.y; +void ui_rearrange_title(UITree_title* t, v2_i32 ppos, v2_i32 psize) { + /*Defaults to just sit in the top-left corner of the parent*/ + t->x = ppos.x; + t->y = ppos.y; - ui_constraints_apply((UITree*)t, ppos, psize); + ui_constraints_apply((UITree*)t, ppos, psize); } -void ui_rearrange_text(UITree_text *t, v2_i32 ppos, v2_i32 psize) { - t->x = ppos.x; - t->y = ppos.y; - t->w = psize.x; - t->h = psize.y; +void ui_rearrange_text(UITree_text* t, v2_i32 ppos, v2_i32 psize) { + t->x = ppos.x; + t->y = ppos.y; + t->w = psize.x; + t->h = psize.y; - t->texture_size.x = psize.x; - t->texture_size.y = psize.y; + t->texture_size.x = psize.x; + t->texture_size.y = psize.y; - /* Free the old texture */ - /* Re-render the text */ - t->text_texture_index = - engine_render_text(t->font_id, t->fg, (char*)t->text_original, &t->texture_size, true); + /* Free the old texture */ + /* Re-render the text */ + t->text_texture_index = engine_render_text( + t->font_id, t->fg, (char*)t->text_original, &t->texture_size, true); - t->w = t->texture_size.x; - t->h = t->texture_size.y; + t->w = t->texture_size.x; + t->h = t->texture_size.y; - ui_constraints_apply((UITree*)t, ppos, psize); + ui_constraints_apply((UITree*)t, ppos, psize); } +void ui_rearrange(UITree* root, v2_i32 ppos, v2_i32 psize) { + if (root == NULL) { + WARN("%s received a null pointer, ignoring", __func__); + return; + } -void ui_rearrange(UITree *root, v2_i32 ppos, v2_i32 psize) { - if (root == NULL) { - WARN("%s received a null pointer, ignoring", __func__); - return; - } - - switch (root->type) { - case uitype_container: - ui_rearrange_container(&root->container, ppos, psize); - break; - case uitype_button: - ui_rearrange_button(&root->button, ppos, psize); - break; - case uitype_title: - ui_rearrange_title(&root->title, ppos, psize); - break; - case uitype_text: - ui_rearrange_text(&root->text, ppos, psize); - break; - default: - if (root->type >= uitype_MAX) { - ERROR("Unknown uitype: %d", root->type); - exit(EXIT_FAILURE); - } else { - WARN("Rendering not implemented for %s", uitype_str[root->type]); - } - break; - } + switch (root->type) { + case uitype_container: + ui_rearrange_container(&root->container, ppos, psize); + break; + case uitype_button: + ui_rearrange_button(&root->button, ppos, psize); + break; + case uitype_title: + ui_rearrange_title(&root->title, ppos, psize); + break; + case uitype_text: + ui_rearrange_text(&root->text, ppos, psize); + break; + default: + if (root->type >= uitype_MAX) { + ERROR("Unknown uitype: %d", root->type); + exit(EXIT_FAILURE); + } else { + WARN("Rendering not implemented for %s", uitype_str[root->type]); + } + break; + } } void ui_resolve_constraints(void) { - u64 *i = NULL; - struct btree_iter_t *it = NULL; + u64* i = NULL; + struct btree_iter_t* it = NULL; - /*absolutely bonkers way to do this*/ - if (GLOBAL_UIROOTS == NULL) { - WARN("UIROOTS not initialized"); - } + /*absolutely bonkers way to do this*/ + if (GLOBAL_UIROOTS == NULL) { + WARN("UIROOTS not initialized"); + } - it = btree_iter_t_new(GLOBAL_UIROOTS); + it = btree_iter_t_new(GLOBAL_UIROOTS); - while ((i = btree_iter(GLOBAL_UIROOTS, it)) != NULL) { - ui_rearrange((UITree*)*i, (v2_i32){0,0}, GLOBAL_PLATFORM->window->windowsize); - } - free(it); + while ((i = btree_iter(GLOBAL_UIROOTS, it)) != NULL) { + ui_rearrange((UITree*)*i, (v2_i32){0, 0}, + GLOBAL_PLATFORM->window->windowsize); + } + free(it); } -void ui_container_attach(UITree *root, UITree *child) { - if (root == NULL) { - WARN("%s received a null pointer", __func__); - return; - } - if (root->type != uitype_container) { - WARN("Trying to attach a child to a non-container UI element"); - return; - } +void ui_container_attach(UITree* root, UITree* child) { + if (root == NULL) { + WARN("%s received a null pointer", __func__); + return; + } + if (root->type != uitype_container) { + WARN("Trying to attach a child to a non-container UI element"); + return; + } - UITree_container *c = &(root->container); + UITree_container* c = &(root->container); - static const usize size_increment = 32; - static const usize uitree_sz = sizeof(UITree*); + static const usize size_increment = 32; + static const usize uitree_sz = sizeof(UITree*); - if (c->children == NULL) { - /* Allocate space for children */ - c->children = malloc(uitree_sz * size_increment); + if (c->children == NULL) { + /* Allocate space for children */ + c->children = malloc(uitree_sz * size_increment); - } else if ((c->children_len + 1) * uitree_sz >= c->children_size) { - /* If there's not enough room for more children we will need to - * reallocate some more memory */ - c->children = realloc(c->children, (c->children_len + size_increment) * uitree_sz); - c->children_size += size_increment * uitree_sz; - } + } else if ((c->children_len + 1) * uitree_sz >= c->children_size) { + /* If there's not enough room for more children we will need to + * reallocate some more memory */ + c->children = + realloc(c->children, (c->children_len + size_increment) * uitree_sz); + c->children_size += size_increment * uitree_sz; + } - /* Finally: attach the new element */ - c->children[c->children_len++] = child; + /* Finally: attach the new element */ + c->children[c->children_len++] = child; - /* Since the child is no longer a part of the root-ui we can delete it from - * the btree-mapping */ - { - u64 tmp = (u64)child; - if (!btree_delete(GLOBAL_UIROOTS, &tmp)) { - WARN("Could not find child %p in global lookup table", child); - btree_print(GLOBAL_UIROOTS, &pointer_print); - } - } + /* Since the child is no longer a part of the root-ui we can delete it from + * the btree-mapping */ + { + u64 tmp = (u64)child; + if (!btree_delete(GLOBAL_UIROOTS, &tmp)) { + WARN("Could not find child %p in global lookup table", child); + btree_print(GLOBAL_UIROOTS, &pointer_print); + } + } } -void ui_button_enable(UITree_button *b) { - b->enabled = true; - SDL_Texture *t = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[b->text_texture_index]->texture; - SDL_SetTextureColorMod(t, 0xff, 0xff, 0xff); +void ui_button_enable(UITree_button* b) { + b->enabled = true; + SDL_Texture* t = ((struct Resources*)GLOBAL_PLATFORM->data) + ->textures[b->text_texture_index] + ->texture; + SDL_SetTextureColorMod(t, 0xff, 0xff, 0xff); } -void ui_button_disable(UITree_button *b) { - b->enabled = false; +void ui_button_disable(UITree_button* b) { + b->enabled = false; - SDL_Texture *t = ((struct Resources*)GLOBAL_PLATFORM->data)->textures[b->text_texture_index]->texture; - SDL_SetTextureColorMod(t, 0x7f, 0x7f, 0x7f); + SDL_Texture* t = ((struct Resources*)GLOBAL_PLATFORM->data) + ->textures[b->text_texture_index] + ->texture; + SDL_SetTextureColorMod(t, 0x7f, 0x7f, 0x7f); } void ui_set_default_colors(Engine_color fg, Engine_color bg) { - DEFAULT_FG = fg; - DEFAULT_BG = bg; + DEFAULT_FG = fg; + DEFAULT_BG = bg; } void ui_set_default_padding(i32 padding) { DEFAULT_PADDING = padding; } @@ -819,59 +895,59 @@ void ui_set_default_padding(i32 padding) { DEFAULT_PADDING = padding; } Engine_color ui_get_default_fg(void) { return DEFAULT_FG; } Engine_color ui_get_default_bg(void) { return DEFAULT_BG; } -bool check_point_in_rect(const v2_i32 *p, const SDL_Rect *r) { - if (p->x > r->x && p->x < r->x + r->w - && p->y > r->y && p->y < r->y + r->h) return true; - return false; +bool check_point_in_rect(const v2_i32* p, const SDL_Rect* r) { + if (p->x > r->x && p->x < r->x + r->w && p->y > r->y && p->y < r->y + r->h) + return true; + return false; } -u64 ui_check_click_internal(UITree *root, v2_i32 pos) { - v2_i32 ps = get_pos(root); - v2_i32 sz = get_size(root); - SDL_Rect elem_rect = {.x=ps.x, .y=ps.y - ,.w=sz.x, .h=sz.y}; - /* */ - switch (root->type) { - case uitype_container: - if (root->container.children != NULL && root->container.children_len > 0) { - const UITree_container *container = &root->container; +u64 ui_check_click_internal(UITree* root, v2_i32 pos) { + v2_i32 ps = get_pos(root); + v2_i32 sz = get_size(root); + SDL_Rect elem_rect = {.x = ps.x, .y = ps.y, .w = sz.x, .h = sz.y}; + /* */ + switch (root->type) { + case uitype_container: + if (root->container.children != NULL && root->container.children_len > 0) { + const UITree_container* container = &root->container; - if (check_point_in_rect(&pos, &elem_rect)) { + if (check_point_in_rect(&pos, &elem_rect)) { - for (usize i = 0; i < container->children_len; i++) { - u64 res = ui_check_click_internal(container->children[i], pos); - if (res != (u64)ELEM_NOT_FOUND) { - return res; - } - } - } - } - break; - case uitype_button: - if (root->button.enabled) { - WARN("Checking button"); - elem_rect.h += root->button.padding * 2; - elem_rect.w += root->button.padding * 2; - WARN("Button specs: <%d,%d>+%d,%d", elem_rect.w, elem_rect.h, elem_rect.x, elem_rect.y); - if (check_point_in_rect(&pos, &elem_rect)) { - return root->button.id; - } - } - break; - case uitype_title: - case uitype_text: - default: - break; - } - return ELEM_NOT_FOUND; + for (usize i = 0; i < container->children_len; i++) { + u64 res = ui_check_click_internal(container->children[i], pos); + if (res != (u64)ELEM_NOT_FOUND) { + return res; + } + } + } + } + break; + case uitype_button: + if (root->button.enabled) { + WARN("Checking button"); + elem_rect.h += root->button.padding * 2; + elem_rect.w += root->button.padding * 2; + WARN("Button specs: <%d,%d>+%d,%d", elem_rect.w, elem_rect.h, + elem_rect.x, elem_rect.y); + if (check_point_in_rect(&pos, &elem_rect)) { + return root->button.id; + } + } + break; + case uitype_title: + case uitype_text: + default: + break; + } + return ELEM_NOT_FOUND; } -u64 ui_check_click(UITree *root) { - if (!GLOBAL_PLATFORM->mouse_lclick) return NO_CLICK; +u64 ui_check_click(UITree* root) { + if (!GLOBAL_PLATFORM->mouse_lclick) return NO_CLICK; - v2_i32 pos = GLOBAL_PLATFORM->mouse_pos; + v2_i32 pos = GLOBAL_PLATFORM->mouse_pos; - INFO("Mousepos: <%d,%d>", pos.x, pos.y); + INFO("Mousepos: <%d,%d>", pos.x, pos.y); - return ui_check_click_internal(root, pos); + return ui_check_click_internal(root, pos); } diff --git a/src/ui_rendering.c b/src/ui_rendering.c index 196d6ef..8055db8 100644 --- a/src/ui_rendering.c +++ b/src/ui_rendering.c @@ -1,6 +1,6 @@ +#include <stdbool.h> #include <stdio.h> #include <string.h> -#include <stdbool.h> #include <SDL2/SDL.h> #include <SDL2/SDL_image.h> @@ -11,285 +11,236 @@ #include <engine/engine.h> #include <engine/rendering.h> +extern Platform* GLOBAL_PLATFORM; -extern Platform *GLOBAL_PLATFORM; - -extern const char *uitype_str[]; +extern const char* uitype_str[]; -void render_uitree(Window *w, UITree *t) { - switch (t->type) { - case uitype_container: - render_container(w, &t->container); - break; - case uitype_button: - render_button(w, &t->button); - break; - case uitype_title: - render_title(w, &t->title); - break; - case uitype_text: - render_text(w, &t->text); - break; - default: - if (t->type >= uitype_MAX) { - ERROR("Unknown uitype: %d", t->type); - } else { - WARN("Rendering not implemented for %s", uitype_str[t->type]); - } - break; - } +void render_uitree(Window* w, UITree* t) { + switch (t->type) { + case uitype_container: + render_container(w, &t->container); + break; + case uitype_button: + render_button(w, &t->button); + break; + case uitype_title: + render_title(w, &t->title); + break; + case uitype_text: + render_text(w, &t->text); + break; + default: + if (t->type >= uitype_MAX) { + ERROR("Unknown uitype: %d", t->type); + } else { + WARN("Rendering not implemented for %s", uitype_str[t->type]); + } + break; + } } -void render_container(Window *w, UITree_container *t) { - SDL_Rect r = { - .x = t->x, - .y = t->y, - .w = t->w, - .h = t->h - }; +void render_container(Window* w, UITree_container* t) { + SDL_Rect r = {.x = t->x, .y = t->y, .w = t->w, .h = t->h}; - SDL_SetRenderDrawColor(w->renderer, - t->bg.r, - t->bg.g, - t->bg.b, - t->bg.a); + SDL_SetRenderDrawColor(w->renderer, t->bg.r, t->bg.g, t->bg.b, t->bg.a); - SDL_RenderFillRect(w->renderer, &r); + SDL_RenderFillRect(w->renderer, &r); - SDL_SetRenderDrawColor(w->renderer, - t->fg.r, - t->fg.g, - t->fg.b, - t->fg.a); + SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - SDL_RenderDrawRect(w->renderer, &r); + SDL_RenderDrawRect(w->renderer, &r); #ifdef _DEBUG - r.x += t->padding; - r.y += t->padding; - r.w -= t->padding * 2; - r.h -= t->padding * 2; - SDL_SetRenderDrawColor(w->renderer, - 0xFF, - 0xFF, - 0xFF, - 0x7A); - SDL_RenderDrawRect(w->renderer, &r); + r.x += t->padding; + r.y += t->padding; + r.w -= t->padding * 2; + r.h -= t->padding * 2; + SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); + SDL_RenderDrawRect(w->renderer, &r); #endif - if (t->children != NULL && t->children_len > 0) { - for (usize i = 0; i < t->children_len; i++) { - render_uitree(w, t->children[i]); - } - } + if (t->children != NULL && t->children_len > 0) { + for (usize i = 0; i < t->children_len; i++) { + render_uitree(w, t->children[i]); + } + } } -void render_button(Window *w, UITree_button *t) { +void render_button(Window* w, UITree_button* t) { - SDL_Rect inner_r = { - .x = t->x + t->padding + (( t->w - t->texture_size.x) / 2), - .y = t->y + t->padding + (( t->h - t->texture_size.y) / 2), - .w = t->texture_size.x, - .h = t->texture_size.y, - }; + SDL_Rect inner_r = { + .x = t->x + t->padding + ((t->w - t->texture_size.x) / 2), + .y = t->y + t->padding + ((t->h - t->texture_size.y) / 2), + .w = t->texture_size.x, + .h = t->texture_size.y, + }; - SDL_Rect outer_r = { - .x = t->x, - .y = t->y, - .w = t->w + t->padding * 2, - .h = t->h + t->padding * 2, - }; + SDL_Rect outer_r = { + .x = t->x, + .y = t->y, + .w = t->w + t->padding * 2, + .h = t->h + t->padding * 2, + }; - SDL_Color fg = { - t->fg.r, - t->fg.g, - t->fg.b, - t->fg.a, - }; + SDL_Color fg = { + t->fg.r, + t->fg.g, + t->fg.b, + t->fg.a, + }; - if (t->enabled == false) { - fg.r /= 2; - fg.g /= 2; - fg.b /= 2; - } + if (t->enabled == false) { + fg.r /= 2; + fg.g /= 2; + fg.b /= 2; + } - SDL_SetRenderDrawColor(w->renderer, - t->bg.r, - t->bg.g, - t->bg.b, - t->bg.a); + SDL_SetRenderDrawColor(w->renderer, t->bg.r, t->bg.g, t->bg.b, t->bg.a); - SDL_RenderFillRect(w->renderer, &outer_r); + SDL_RenderFillRect(w->renderer, &outer_r); - SDL_SetRenderDrawColor(w->renderer, - fg.r, - fg.g, - fg.b, - fg.a); - - SDL_RenderDrawRect(w->renderer, &outer_r); - SDL_Texture *texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index]->texture; - SDL_RenderCopy( - w->renderer, - texture, - NULL, - &inner_r); + SDL_SetRenderDrawColor(w->renderer, fg.r, fg.g, fg.b, fg.a); + SDL_RenderDrawRect(w->renderer, &outer_r); + SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) + ->textures[t->text_texture_index] + ->texture; + SDL_RenderCopy(w->renderer, texture, NULL, &inner_r); } +void render_title(Window* w, UITree_title* t) { + SDL_Rect r = { + .x = t->x, + .y = t->y, + .w = t->texture_size.x, + .h = t->texture_size.y, + }; -void render_title(Window *w, UITree_title *t) { - SDL_Rect r = { - .x = t->x, - .y = t->y, - .w = t->texture_size.x, - .h = t->texture_size.y, - }; - - SDL_SetRenderDrawColor(w->renderer, - t->fg.r, - t->fg.g, - t->fg.b, - t->fg.a); + SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - SDL_Texture *texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index]->texture; + SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) + ->textures[t->text_texture_index] + ->texture; - SDL_RenderCopy( - w->renderer, - texture, - NULL, - &r); + SDL_RenderCopy(w->renderer, texture, NULL, &r); #ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, - 0xFF, - 0xFF, - 0xFF, - 0x7A); + SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); - SDL_RenderDrawRect(w->renderer, &r); + SDL_RenderDrawRect(w->renderer, &r); #endif } -void render_text(Window *w, UITree_text *t) { - SDL_Rect r = { - .x = t->x, - .y = t->y, - .w = t->texture_size.x, - .h = t->texture_size.y, - }; +void render_text(Window* w, UITree_text* t) { + SDL_Rect r = { + .x = t->x, + .y = t->y, + .w = t->texture_size.x, + .h = t->texture_size.y, + }; - SDL_SetRenderDrawColor(w->renderer, - t->fg.r, - t->fg.g, - t->fg.b, - t->fg.a); + SDL_SetRenderDrawColor(w->renderer, t->fg.r, t->fg.g, t->fg.b, t->fg.a); - SDL_Texture *texture = ((struct Resources*)GLOBAL_PLATFORM->data) - ->textures[t->text_texture_index]->texture; + SDL_Texture* texture = ((struct Resources*)GLOBAL_PLATFORM->data) + ->textures[t->text_texture_index] + ->texture; - SDL_RenderCopy( - w->renderer, - texture, - NULL, - &r); + SDL_RenderCopy(w->renderer, texture, NULL, &r); #ifdef _DEBUG - SDL_SetRenderDrawColor(w->renderer, - 0xFF, - 0xFF, - 0xFF, - 0x7A); + SDL_SetRenderDrawColor(w->renderer, 0xFF, 0xFF, 0xFF, 0x7A); - SDL_RenderDrawRect(w->renderer, &r); + SDL_RenderDrawRect(w->renderer, &r); #endif - } -i64 add_texture(struct Resources *resptr, Texture *t) { - if (NULL == resptr - || NULL == t) return -1; +i64 add_texture(struct Resources* resptr, Texture* t) { + if (NULL == resptr || NULL == t) return -1; - if (resptr->textures == NULL) { - resptr->textures = malloc(sizeof(Texture*) * TEXTURES_INCREMENT); - } else if (resptr->textures_len + 1 >= resptr->textures_size) { - resptr->textures_size += TEXTURES_INCREMENT; - resptr->textures = realloc(resptr->textures, sizeof(Texture*) * resptr->textures_size); - memset(resptr->textures + resptr->textures_size - TEXTURES_INCREMENT, 0, TEXTURES_INCREMENT); - } + if (resptr->textures == NULL) { + resptr->textures = malloc(sizeof(Texture*) * TEXTURES_INCREMENT); + } else if (resptr->textures_len + 1 >= resptr->textures_size) { + resptr->textures_size += TEXTURES_INCREMENT; + resptr->textures = + realloc(resptr->textures, sizeof(Texture*) * resptr->textures_size); + memset(resptr->textures + resptr->textures_size - TEXTURES_INCREMENT, 0, + TEXTURES_INCREMENT); + } - resptr->textures[resptr->textures_len] = t; - return resptr->textures_len++; + resptr->textures[resptr->textures_len] = t; + return resptr->textures_len++; } -i64 engine_render_text(i32 font_id, Engine_color fg, char *text, v2_i32 *size_out, bool wrapped) { - const SDL_Color sdl_fg = {.r = fg.r, .g = fg.g, .b = fg.b, .a = fg.a}; - Texture *t = malloc(sizeof(Texture)); - struct Resources *r; +i64 engine_render_text(i32 font_id, Engine_color fg, char* text, + v2_i32* size_out, bool wrapped) { + const SDL_Color sdl_fg = {.r = fg.r, .g = fg.g, .b = fg.b, .a = fg.a}; + Texture* t = malloc(sizeof(Texture)); + struct Resources* r; - if (t == NULL) { - ERROR("Failed to allocate memory for texture!\n"); - exit(EXIT_FAILURE); - } + if (t == NULL) { + ERROR("Failed to allocate memory for texture!\n"); + exit(EXIT_FAILURE); + } - if (GLOBAL_PLATFORM == NULL) { - ERROR("Platform is uninitialized.\n"); - exit(EXIT_FAILURE); - } + if (GLOBAL_PLATFORM == NULL) { + ERROR("Platform is uninitialized.\n"); + exit(EXIT_FAILURE); + } - r = (struct Resources*)GLOBAL_PLATFORM->data; + r = (struct Resources*)GLOBAL_PLATFORM->data; - if (r == NULL) { - ERROR("Resources not loaded!\n"); - exit(EXIT_FAILURE); - } + if (r == NULL) { + ERROR("Resources not loaded!\n"); + exit(EXIT_FAILURE); + } - if (r->fonts == NULL) { - ERROR("No fonts are initialized!\n"); - exit(EXIT_FAILURE); - } + if (r->fonts == NULL) { + ERROR("No fonts are initialized!\n"); + exit(EXIT_FAILURE); + } - if ((usize)font_id >= r->fonts_len) { - ERROR("font-id \"%d\" is out of bounds!\n", font_id); - ERROR("Couldn't render text \"%s\"\n", text); - } + if ((usize)font_id >= r->fonts_len) { + ERROR("font-id \"%d\" is out of bounds!\n", font_id); + ERROR("Couldn't render text \"%s\"\n", text); + } - SDL_Surface *s = NULL; + SDL_Surface* s = NULL; - if (wrapped) { - s = TTF_RenderUTF8_Solid_Wrapped(r->fonts[font_id], text, sdl_fg, size_out->x); + if (wrapped) { + s = TTF_RenderUTF8_Solid_Wrapped(r->fonts[font_id], text, sdl_fg, + size_out->x); - if (s == NULL) { - ERROR("Failed call to TTF_RenderUTF8_Solid_Wrapped: %s\n", TTF_GetError()); - exit(EXIT_FAILURE); - } - } else { - s = TTF_RenderUTF8_Solid(r->fonts[font_id], text, sdl_fg); + if (s == NULL) { + ERROR("Failed call to TTF_RenderUTF8_Solid_Wrapped: %s\n", + TTF_GetError()); + exit(EXIT_FAILURE); + } + } else { + s = TTF_RenderUTF8_Solid(r->fonts[font_id], text, sdl_fg); - if (s == NULL) { - ERROR("Failed call to TTF_RenderUTF8_Solid: %s\n", TTF_GetError()); - exit(EXIT_FAILURE); - } - } + if (s == NULL) { + ERROR("Failed call to TTF_RenderUTF8_Solid: %s\n", TTF_GetError()); + exit(EXIT_FAILURE); + } + } - t->texture = SDL_CreateTextureFromSurface(GLOBAL_PLATFORM->window->renderer, s); + t->texture = + SDL_CreateTextureFromSurface(GLOBAL_PLATFORM->window->renderer, s); - if (t->texture == NULL) { - ERROR("Failed call to SDL_CreateTextureFromSurface: %s\n", SDL_GetError()); - INFO("FontID: %d", font_id); - INFO("Text: \"%s\" [%lu]", text, strlen(text)); - exit(EXIT_FAILURE); - } + if (t->texture == NULL) { + ERROR("Failed call to SDL_CreateTextureFromSurface: %s\n", SDL_GetError()); + INFO("FontID: %d", font_id); + INFO("Text: \"%s\" [%lu]", text, strlen(text)); + exit(EXIT_FAILURE); + } - *(i32*)&t->width = s->w; - *(i32*)&t->height = s->h; + *(i32*)&t->width = s->w; + *(i32*)&t->height = s->h; - size_out->x = s->w; - size_out->y = s->h; + size_out->x = s->w; + size_out->y = s->h; - SDL_FreeSurface(s); + SDL_FreeSurface(s); - return add_texture(r, t); + return add_texture(r, t); } diff --git a/src/utils.c b/src/utils.c index cd6d0b0..f91ef4d 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,70 +1,69 @@ -#include <stdlib.h> #include <stdint.h> +#include <stdlib.h> #include <string.h> -#include <engine/utils.h> #include <engine/logging.h> +#include <engine/utils.h> -f32 lerp(f32 dt, f32 a, f32 b) { - return (a * (1.0f - dt)) + (b * dt); -} +f32 lerp(f32 dt, f32 a, f32 b) { return (a * (1.0f - dt)) + (b * dt); } i32 int_lerp(f32 dt, i32 a, i32 b) { - return ((f32)a * (1.0f - dt)) + ((f32)b * dt); + return ((f32)a * (1.0f - dt)) + ((f32)b * dt); } -u32 hash(char *str) { - u32 sum = 0; - while (*str != '\0') { - sum ^= (*str) * 0xdeece66d + 0xb; - str++; - } - return sum; +u32 hash(char* str) { + u32 sum = 0; + while (*str != '\0') { + sum ^= (*str) * 0xdeece66d + 0xb; + str++; + } + return sum; } /* Populates dstmap * on success: return pointer to dstmap * on failure: return NULL */ -i32* kernmap(const void *map, i32 *dstmap, const v2_i32 mapsize, predicate_t *predicate) { - const i32 w = mapsize.x; - const i32 h = mapsize.y; - i32 mask[w*h]; +i32* kernmap(const void* map, i32* dstmap, const v2_i32 mapsize, + predicate_t* predicate) { + const i32 w = mapsize.x; + const i32 h = mapsize.y; + i32 mask[w * h]; - if (w * h < 1) return NULL; + if (w * h < 1) return NULL; - for (i32 i = 0; i < w * h; i++) { - mask[i] = predicate((void*)((u64)map + sizeof(i32) * i)) ? 1 : 0; - } + for (i32 i = 0; i < w * h; i++) { + mask[i] = predicate((void*)((u64)map + sizeof(i32) * i)) ? 1 : 0; + } - for (i32 y = 1; y < h - 1; y++) { - for (i32 x = 1; x < w - 1; x++) { - const i32 global_idx = (y * w) + x; - const i32 offs = global_idx - w - 1; - i32 _sum = 0; + for (i32 y = 1; y < h - 1; y++) { + for (i32 x = 1; x < w - 1; x++) { + const i32 global_idx = (y * w) + x; + const i32 offs = global_idx - w - 1; + i32 _sum = 0; - i32 shift = 0; + i32 shift = 0; - /* We go in the following order */ - /* ....|0|1|2|....*/ - /* ....|3|4|5|....*/ - /* ....|6|7|8|....*/ - /* Where `4` is in the center, MASK_C */ - for (i32 yy = offs; yy <= offs + w + w; yy += w) { - for (i32 xx = yy; xx < yy + 3; xx++) { - _sum = _sum | (mask[xx] << shift++); - } - } + /* We go in the following order */ + /* ....|0|1|2|....*/ + /* ....|3|4|5|....*/ + /* ....|6|7|8|....*/ + /* Where `4` is in the center, MASK_C */ + for (i32 yy = offs; yy <= offs + w + w; yy += w) { + for (i32 xx = yy; xx < yy + 3; xx++) { + _sum = _sum | (mask[xx] << shift++); + } + } - dstmap[global_idx] = _sum; - } - } - return dstmap; + dstmap[global_idx] = _sum; + } + } + return dstmap; } /* Returns an index from the given weights. */ -i32 pick_from_sample(const i32 *weights, i32 len) { - if (len <= 0) return 0; +i32 pick_from_sample(const i32* weights, i32 len) { + if (len <= 0) return 0; /* Cumulative sum */ i32 cumweights[len]; @@ -74,7 +73,7 @@ i32 pick_from_sample(const i32 *weights, i32 len) { cumweights[i] = sum; } - if (sum == 0) return 0; + if (sum == 0) return 0; i32 pick = rand() % sum; diff --git a/src/vector.c b/src/vector.c index 1a4cc61..3465df7 100644 --- a/src/vector.c +++ b/src/vector.c @@ -1,28 +1,32 @@ -#include <engine/vector.h> #include <engine/utils.h> +#include <engine/vector.h> -bool v2_i32_eq (const v2_i32 a, - const v2_i32 b) { return (a.x == b.x) && (a.y == b.y); } -v2_i32 v2_i32_add (v2_i32 a, v2_i32 b) { return (v2_i32){a.x + b.x, a.y + b.y}; } -v2_i32 v2_i32_add_i(v2_i32 a, i32 b) { return (v2_i32){a.x + b , a.y + b }; } -v2_i32 v2_i32_sub (v2_i32 a, v2_i32 b) { return (v2_i32){a.x - b.x, a.y - b.y}; } -v2_i32 v2_i32_sub_i(v2_i32 a, i32 b) { return (v2_i32){a.x - b , a.y - b }; } -v2_i32 v2_i32_div (v2_i32 a, v2_i32 b) { return (v2_i32){a.x / b.x, a.y / b.y}; } -v2_i32 v2_i32_div_i(v2_i32 a, i32 b) { return (v2_i32){a.x / b , a.y / b }; } -v2_i32 v2_i32_mul (v2_i32 a, v2_i32 b) { return (v2_i32){a.x * b.x, a.y * b.y}; } -v2_i32 v2_i32_mul_i(v2_i32 a, i32 b) { return (v2_i32){a.x * b , a.y * b }; } -v2_i32 v2_i32_mod (v2_i32 a, v2_i32 b) { return (v2_i32){a.x % b.x, a.y % b.y}; } -v2_i32 v2_i32_mod_i(v2_i32 a, i32 b) { return (v2_i32){a.x % b , a.y % b }; } -v2_i32 v2_i32_max (v2_i32 a, v2_i32 b) { return (v2_i32){MAX(a.x, b.x), MAX(a.y, b.y)}; } -v2_i32 v2_i32_min (v2_i32 a, v2_i32 b) { return (v2_i32){MIN(a.x, b.x), MIN(a.y, b.y)}; } -v2_i32 v2_i32_lerp (f32 dt, v2_i32 a, v2_i32 b) { - return (v2_i32){ - .x = lerp(dt, (f32)a.x, (f32)b.x), - .y = lerp(dt, (f32)a.y, (f32)b.y), - }; +bool v2_i32_eq(const v2_i32 a, const v2_i32 b) { + return (a.x == b.x) && (a.y == b.y); +} +v2_i32 v2_i32_add(v2_i32 a, v2_i32 b) { return (v2_i32){a.x + b.x, a.y + b.y}; } +v2_i32 v2_i32_add_i(v2_i32 a, i32 b) { return (v2_i32){a.x + b, a.y + b}; } +v2_i32 v2_i32_sub(v2_i32 a, v2_i32 b) { return (v2_i32){a.x - b.x, a.y - b.y}; } +v2_i32 v2_i32_sub_i(v2_i32 a, i32 b) { return (v2_i32){a.x - b, a.y - b}; } +v2_i32 v2_i32_div(v2_i32 a, v2_i32 b) { return (v2_i32){a.x / b.x, a.y / b.y}; } +v2_i32 v2_i32_div_i(v2_i32 a, i32 b) { return (v2_i32){a.x / b, a.y / b}; } +v2_i32 v2_i32_mul(v2_i32 a, v2_i32 b) { return (v2_i32){a.x * b.x, a.y * b.y}; } +v2_i32 v2_i32_mul_i(v2_i32 a, i32 b) { return (v2_i32){a.x * b, a.y * b}; } +v2_i32 v2_i32_mod(v2_i32 a, v2_i32 b) { return (v2_i32){a.x % b.x, a.y % b.y}; } +v2_i32 v2_i32_mod_i(v2_i32 a, i32 b) { return (v2_i32){a.x % b, a.y % b}; } +v2_i32 v2_i32_max(v2_i32 a, v2_i32 b) { + return (v2_i32){MAX(a.x, b.x), MAX(a.y, b.y)}; +} +v2_i32 v2_i32_min(v2_i32 a, v2_i32 b) { + return (v2_i32){MIN(a.x, b.x), MIN(a.y, b.y)}; +} +v2_i32 v2_i32_lerp(f32 dt, v2_i32 a, v2_i32 b) { + return (v2_i32){ + .x = lerp(dt, (f32)a.x, (f32)b.x), + .y = lerp(dt, (f32)a.y, (f32)b.y), + }; } - -void v2_i32_fprintf(FILE *stream, v2_i32 a) { - fprintf(stream, "<%d,%d>", a.x, a.y); +void v2_i32_fprintf(FILE* stream, v2_i32 a) { + fprintf(stream, "<%d,%d>", a.x, a.y); } |
