Adding linked lists and texture management
This commit is contained in:
parent
e2b5044bc5
commit
57192d8b0e
|
@ -1,30 +1,46 @@
|
||||||
|
#include <gint/kmalloc.h>
|
||||||
|
#include <stdarg.h>
|
||||||
#include "linked_list.h"
|
#include "linked_list.h"
|
||||||
#include "malloc.h"
|
|
||||||
|
|
||||||
void linked_list_init(linked_list_t *linked_list, const size_t data_size)
|
elem_t *elem_create(const linked_list_t *linked_list)
|
||||||
{
|
{
|
||||||
linked_list->data_size = data_size;
|
elem_t *tmp;
|
||||||
linked_list->first = NULL;
|
tmp = kmalloc(sizeof(elem_t), NULL);
|
||||||
linked_list->last = NULL;
|
if(!tmp) return NULL;
|
||||||
}
|
|
||||||
|
|
||||||
elem_t *elem_create(linked_list_t *linked_list)
|
tmp->data = kmalloc(linked_list->data_size, NULL);
|
||||||
{
|
if(!tmp->data)
|
||||||
elem_t *elem;
|
|
||||||
elem = malloc(sizeof(elem_t));
|
|
||||||
if(!elem) return NULL;
|
|
||||||
|
|
||||||
elem->data = malloc(linked_list->data_size);
|
|
||||||
if(!elem->data)
|
|
||||||
{
|
{
|
||||||
free(elem);
|
kfree(tmp);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return elem;
|
return tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void linked_list_push_back(linked_list_t *linked_list, elem_t *elem)
|
inline void destroy_elem(elem_t *elem, const deleter_t elem_deleter)
|
||||||
|
{
|
||||||
|
if(!elem) return;
|
||||||
|
|
||||||
|
if(elem_deleter)
|
||||||
|
elem_deleter(elem->data);
|
||||||
|
else
|
||||||
|
kfree(elem->data);
|
||||||
|
|
||||||
|
kfree(elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_init(linked_list_t *linked_list, const size_t data_size, deleter_t elem_deleter)
|
||||||
|
{
|
||||||
|
linked_list->first = NULL;
|
||||||
|
linked_list->last = NULL;
|
||||||
|
linked_list->size = 0;
|
||||||
|
|
||||||
|
linked_list->data_size = data_size;
|
||||||
|
linked_list->elem_deleter = elem_deleter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_push_back_elem(linked_list_t *linked_list, elem_t *elem)
|
||||||
{
|
{
|
||||||
if(!elem) return;
|
if(!elem) return;
|
||||||
|
|
||||||
|
@ -37,9 +53,11 @@ void linked_list_push_back(linked_list_t *linked_list, elem_t *elem)
|
||||||
linked_list->first = elem;
|
linked_list->first = elem;
|
||||||
|
|
||||||
linked_list->last = elem;
|
linked_list->last = elem;
|
||||||
|
|
||||||
|
linked_list->size++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void linked_list_push_front(linked_list_t *linked_list, elem_t *elem)
|
void linked_list_push_front_elem(linked_list_t *linked_list, elem_t *elem)
|
||||||
{
|
{
|
||||||
if(!elem) return;
|
if(!elem) return;
|
||||||
|
|
||||||
|
@ -52,6 +70,26 @@ void linked_list_push_front(linked_list_t *linked_list, elem_t *elem)
|
||||||
linked_list->last = elem;
|
linked_list->last = elem;
|
||||||
|
|
||||||
linked_list->first = elem;
|
linked_list->first = elem;
|
||||||
|
|
||||||
|
linked_list->size++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_push_back(linked_list_t *linked_list, void *data)
|
||||||
|
{
|
||||||
|
elem_t *tmp = kmalloc(sizeof(elem_t), NULL);
|
||||||
|
if(!tmp) return;
|
||||||
|
tmp->data = data;
|
||||||
|
|
||||||
|
linked_list_push_back_elem(linked_list, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_push_front(linked_list_t *linked_list, void *data)
|
||||||
|
{
|
||||||
|
elem_t *tmp = kmalloc(sizeof(elem_t), NULL);
|
||||||
|
if(!tmp) return;
|
||||||
|
tmp->data = data;
|
||||||
|
|
||||||
|
linked_list_push_front_elem(linked_list, tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void linked_list_pop_back(linked_list_t *linked_list)
|
void linked_list_pop_back(linked_list_t *linked_list)
|
||||||
|
@ -66,8 +104,9 @@ void linked_list_pop_back(linked_list_t *linked_list)
|
||||||
else
|
else
|
||||||
linked_list->first = NULL;
|
linked_list->first = NULL;
|
||||||
|
|
||||||
free(tmp->data);
|
destroy_elem(tmp, linked_list->elem_deleter);
|
||||||
free(tmp);
|
|
||||||
|
linked_list->size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void linked_list_pop_front(linked_list_t *linked_list)
|
void linked_list_pop_front(linked_list_t *linked_list)
|
||||||
|
@ -82,38 +121,50 @@ void linked_list_pop_front(linked_list_t *linked_list)
|
||||||
else
|
else
|
||||||
linked_list->last = NULL;
|
linked_list->last = NULL;
|
||||||
|
|
||||||
free(tmp->data);
|
destroy_elem(tmp, linked_list->elem_deleter);
|
||||||
free(tmp);
|
|
||||||
|
linked_list->size--;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t linked_list_get_size(linked_list_t *linked_list)
|
void linked_list_clear(linked_list_t *linked_list)
|
||||||
{
|
{
|
||||||
elem_t *actual_elem = linked_list->first;
|
elem_t *actual_elem = linked_list->first;
|
||||||
if(!actual_elem) return 0;
|
elem_t *tmp;
|
||||||
|
|
||||||
size_t size = 0;
|
|
||||||
while(actual_elem)
|
while(actual_elem)
|
||||||
{
|
{
|
||||||
|
tmp = actual_elem;
|
||||||
|
|
||||||
|
destroy_elem(tmp, linked_list->elem_deleter);
|
||||||
|
|
||||||
actual_elem = actual_elem->next;
|
actual_elem = actual_elem->next;
|
||||||
size++;
|
|
||||||
}
|
}
|
||||||
return size;
|
|
||||||
|
linked_list->first = NULL;
|
||||||
|
linked_list->last = NULL;
|
||||||
|
|
||||||
|
linked_list->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool linked_list_is_empty(linked_list_t *linked_list)
|
inline bool linked_list_is_empty(const linked_list_t *linked_list)
|
||||||
{
|
{
|
||||||
return !linked_list->first;
|
return !linked_list->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool linked_list_is_in_bound(linked_list_t *linked_list, size_t index)
|
inline bool linked_list_is_in_bound(const linked_list_t *linked_list, const size_t index)
|
||||||
{
|
{
|
||||||
return index < linked_list_get_size(linked_list);
|
return index < linked_list->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
elem_t *linked_list_get_elem(linked_list_t *linked_list, size_t index)
|
elem_t *linked_list_get_elem(const linked_list_t *linked_list, const size_t index)
|
||||||
{
|
{
|
||||||
if(!linked_list_is_in_bound(linked_list, index)) return NULL;
|
if(!linked_list_is_in_bound(linked_list, index)) return NULL;
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
return linked_list->first;
|
||||||
|
if(index == linked_list->size - 1)
|
||||||
|
return linked_list->last;
|
||||||
|
|
||||||
elem_t *actual_elem = linked_list->first;
|
elem_t *actual_elem = linked_list->first;
|
||||||
if(!actual_elem) return NULL;
|
if(!actual_elem) return NULL;
|
||||||
|
|
||||||
|
@ -124,8 +175,202 @@ elem_t *linked_list_get_elem(linked_list_t *linked_list, size_t index)
|
||||||
|
|
||||||
return actual_elem;
|
return actual_elem;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
void linked_list_insert(linked_list_t *linked_list, elem_t *elem, size_t index)
|
void *linked_list_get(const linked_list_t *linked_list, const size_t index)
|
||||||
{
|
{
|
||||||
|
elem_t *tmp = linked_list_get_elem(linked_list, index);
|
||||||
}*/
|
if(!tmp) return NULL;
|
||||||
|
return tmp->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_insert_elem(linked_list_t *linked_list, elem_t *elem, const size_t index)
|
||||||
|
{
|
||||||
|
if(!elem) return;
|
||||||
|
if(!linked_list_is_in_bound(linked_list, index)) return;
|
||||||
|
|
||||||
|
if(index == 0)
|
||||||
|
{
|
||||||
|
linked_list_push_front(linked_list, elem);
|
||||||
|
}
|
||||||
|
else if(index == (linked_list->size - 1))
|
||||||
|
{
|
||||||
|
linked_list_push_back(linked_list, elem);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elem_t *next_insert_elem = linked_list_get_elem(linked_list, index);
|
||||||
|
elem_t *prev_insert_elem = next_insert_elem->prev;
|
||||||
|
|
||||||
|
elem->prev = prev_insert_elem;
|
||||||
|
elem->next = next_insert_elem;
|
||||||
|
|
||||||
|
prev_insert_elem->next = elem;
|
||||||
|
next_insert_elem->prev = elem;
|
||||||
|
|
||||||
|
linked_list->size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_insert(linked_list_t *linked_list, void *data, const size_t index)
|
||||||
|
{
|
||||||
|
elem_t *tmp = kmalloc(sizeof(elem_t), NULL);
|
||||||
|
if(!tmp) return;
|
||||||
|
tmp->data = data;
|
||||||
|
|
||||||
|
linked_list_insert_elem(linked_list, tmp, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_remove_elem(linked_list_t *linked_list, elem_t *elem)
|
||||||
|
{
|
||||||
|
if(!elem) return;
|
||||||
|
if(!elem->prev && !elem->next) return;
|
||||||
|
|
||||||
|
if(elem == linked_list->first)
|
||||||
|
{
|
||||||
|
linked_list_pop_front(linked_list);
|
||||||
|
}
|
||||||
|
else if(elem == linked_list->last)
|
||||||
|
{
|
||||||
|
linked_list_pop_back(linked_list);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
elem_t *prev_insert_elem = elem->prev;
|
||||||
|
elem_t *next_insert_elem = elem->next;
|
||||||
|
|
||||||
|
prev_insert_elem->next = next_insert_elem;
|
||||||
|
next_insert_elem->prev = prev_insert_elem;
|
||||||
|
|
||||||
|
destroy_elem(elem, linked_list->elem_deleter);
|
||||||
|
|
||||||
|
linked_list->size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_remove(linked_list_t *linked_list, const size_t index)
|
||||||
|
{
|
||||||
|
if(!linked_list_is_in_bound(linked_list, index)) return;
|
||||||
|
|
||||||
|
elem_t *tmp = linked_list_get_elem(linked_list, index);
|
||||||
|
if(tmp) linked_list_remove_elem(linked_list, tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
elem_t *linked_list_get_elem_if(const linked_list_t *linked_list, const condition_t condition, ...)
|
||||||
|
{
|
||||||
|
if(!condition) return NULL;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, condition);
|
||||||
|
|
||||||
|
elem_t *actual_elem = linked_list->first;
|
||||||
|
elem_t *next_elem;
|
||||||
|
|
||||||
|
while(actual_elem)
|
||||||
|
{
|
||||||
|
next_elem = actual_elem->next;
|
||||||
|
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
if(condition(actual_elem, args_copy))
|
||||||
|
{
|
||||||
|
va_end(args_copy);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return actual_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
|
||||||
|
actual_elem = next_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *linked_list_get_if(const linked_list_t *linked_list, const condition_t condition, ...)
|
||||||
|
{
|
||||||
|
if(!condition) return NULL;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, condition);
|
||||||
|
|
||||||
|
elem_t *actual_elem = linked_list->first;
|
||||||
|
elem_t *next_elem;
|
||||||
|
|
||||||
|
while(actual_elem)
|
||||||
|
{
|
||||||
|
next_elem = actual_elem->next;
|
||||||
|
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
if(condition(actual_elem, args_copy))
|
||||||
|
{
|
||||||
|
va_end(args_copy);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return actual_elem->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
|
||||||
|
actual_elem = next_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_remove_if(linked_list_t *linked_list, const condition_t condition, ...)
|
||||||
|
{
|
||||||
|
if(!condition) return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, condition);
|
||||||
|
|
||||||
|
elem_t *actual_elem = linked_list->first;
|
||||||
|
elem_t *next_elem;
|
||||||
|
|
||||||
|
while(actual_elem)
|
||||||
|
{
|
||||||
|
next_elem = actual_elem->next;
|
||||||
|
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
if(condition(actual_elem, args_copy))
|
||||||
|
{
|
||||||
|
linked_list_remove_elem(linked_list, actual_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
|
||||||
|
actual_elem = next_elem;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void linked_list_for_each(const linked_list_t *linked_list, const action_t action, ...)
|
||||||
|
{
|
||||||
|
if(!action) return;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, action);
|
||||||
|
|
||||||
|
for(elem_t *actual_elem = linked_list->first; actual_elem; actual_elem = actual_elem->next)
|
||||||
|
{
|
||||||
|
va_list args_copy;
|
||||||
|
va_copy(args_copy, args);
|
||||||
|
|
||||||
|
action(actual_elem, args_copy);
|
||||||
|
|
||||||
|
va_end(args_copy);
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
|
@ -15,16 +15,59 @@ typedef struct elem_t {
|
||||||
struct elem_t *next;
|
struct elem_t *next;
|
||||||
} elem_t;
|
} elem_t;
|
||||||
|
|
||||||
|
/* deleter_t: A type for deleters used during the destruction of elements
|
||||||
|
|
||||||
|
During the initialisation of linked lists you can pass in argument a deleter.
|
||||||
|
It is used during the destruction of an element.
|
||||||
|
You can pass NULL to the initialisation to use the default deleter (kfree(elem->data)).
|
||||||
|
Your deleter_t function declaration must look like this :
|
||||||
|
|
||||||
|
void name_of_your_deleter(void *data);
|
||||||
|
|
||||||
|
Then do what you need to destroy your data (don't forget to kfree the data itself...).
|
||||||
|
You can define your function with "inline" if the deleting is short. */
|
||||||
|
typedef void (*deleter_t)(void *);
|
||||||
|
|
||||||
|
/* condition_t: A type for condition used for conditionned function like linked_list_remove_if
|
||||||
|
|
||||||
|
For function like linked_list_remove_if you need a condition.
|
||||||
|
It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
|
||||||
|
and the args passed to the function.
|
||||||
|
Your condition_t function declaration must look like this :
|
||||||
|
|
||||||
|
bool name_of_your_condition(elem_t *elem, va_list);
|
||||||
|
|
||||||
|
Then return true if you want the element to be removed from the list or false if not.
|
||||||
|
You can define your function with "static inline" if the condition is short. */
|
||||||
|
typedef bool (*condition_t)(elem_t *, va_list);
|
||||||
|
|
||||||
|
/* action_t: A type for action used for function like linked_list_for_each
|
||||||
|
|
||||||
|
For function like linked_list_for_each you need an action to do.
|
||||||
|
It have two argument which are "elem_t *" and "va_list", that is because it passes the element on the actual index
|
||||||
|
and the args passed to the function.
|
||||||
|
Your condition_t function declaration must look like this :
|
||||||
|
|
||||||
|
void name_of_your_condition(elem_t *elem, va_list);
|
||||||
|
|
||||||
|
Then do whatever you want with the element data, just don't remove it XD.
|
||||||
|
You can define your function with "static inline" if the condition is short. */
|
||||||
|
typedef void (*action_t)(elem_t *, va_list);
|
||||||
|
|
||||||
/* linked_list_t: Base of linked lists
|
/* linked_list_t: Base of linked lists
|
||||||
This struct is the base for creating linked lists.
|
This struct is the base for creating linked lists.
|
||||||
|
|
||||||
@data_size Size of the data stored in the linked list
|
@data_size Size of the data stored in the linked list
|
||||||
@first Pointer to the first element in the linked list
|
@first Pointer to the first element in the linked list
|
||||||
@last Pointer to the last element in the linked list */
|
@last Pointer to the last element in the linked list
|
||||||
typedef struct {
|
@size Size of the linked list
|
||||||
|
@deleter Deleter of the data when removing an element*/
|
||||||
|
typedef struct linked_list_t {
|
||||||
size_t data_size;
|
size_t data_size;
|
||||||
elem_t *first;
|
elem_t *first;
|
||||||
elem_t *last;
|
elem_t *last;
|
||||||
|
size_t size;
|
||||||
|
deleter_t elem_deleter;
|
||||||
} linked_list_t;
|
} linked_list_t;
|
||||||
|
|
||||||
/* linked_list_init(): Init a linked_list_t
|
/* linked_list_init(): Init a linked_list_t
|
||||||
|
@ -32,64 +75,159 @@ typedef struct {
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
@data_size Data size for the linked list */
|
@data_size Data size for the linked list */
|
||||||
void linked_list_init(linked_list_t *linked_list, const size_t data_size);
|
void linked_list_init(linked_list_t *, const size_t, deleter_t deleter);
|
||||||
|
|
||||||
/* elem_create(): Create an elem to fill with data and insert in a linked list.
|
/* elem_create(): Create an elem to fill with data and insert in a linked list.
|
||||||
This function is usefull when you want to initialise an elem with the proper data_size.
|
This function is usefull when you want to initialise an elem with the proper data_size.
|
||||||
|
WARNING : Don't change the "data" ptr after calling this function or it will lead to memory leaks !
|
||||||
|
Instead do something like this :
|
||||||
|
*(int *)elem->data = 42;
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Return adress of initialised elem, NULL on error. */
|
Return adress of initialised elem, NULL on error. */
|
||||||
elem_t *elem_create(linked_list_t *linked_list);
|
elem_t *elem_create(const linked_list_t *);
|
||||||
|
|
||||||
/* linked_list_push_back(): Insert an elem_t from the back in a linked_list_t.
|
/* destroy_elem(): Destroy the given element and its data.
|
||||||
|
This function is usefull when you want to free an element.
|
||||||
|
The deleter is used for the data only.
|
||||||
|
|
||||||
|
@elem Pointer to an elem_t
|
||||||
|
Free the given elem. */
|
||||||
|
void destroy_elem(elem_t *, const deleter_t);
|
||||||
|
|
||||||
|
/* linked_list_push_back_elem(): Insert an elem_t from the back in a linked_list_t.
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
@elem Pointer to an elem_t
|
@elem Pointer to an elem_t
|
||||||
Insert elem in the back of the linked list, do nothing on error. */
|
Insert elem in the back of the linked list, do nothing on error. */
|
||||||
void linked_list_push_back(linked_list_t *linked_list, elem_t *elem);
|
void linked_list_push_back_elem(linked_list_t *, elem_t *);
|
||||||
|
|
||||||
/* linked_list_push_front(): Insert an elem_t from the front in a linked_list_t.
|
/* linked_list_push_front_elem(): Insert an elem_t from the front in a linked_list_t.
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
@elem Pointer to an elem_t
|
@elem Pointer to an elem_t
|
||||||
Insert elem in the front of the linked list, do nothing on error. */
|
Insert elem in the front of the linked list, do nothing on error. */
|
||||||
void linked_list_push_front(linked_list_t *linked_list, elem_t *elem);
|
void linked_list_push_front_elem(linked_list_t *, elem_t *);
|
||||||
|
|
||||||
|
/* linked_list_push_back_elem(): Insert an elem_t filled with data from the back in a linked_list_t.
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@data Pointer to any data
|
||||||
|
Insert elem filled with data in the back of the linked list, do nothing on error. */
|
||||||
|
void linked_list_push_back(linked_list_t *, void *);
|
||||||
|
|
||||||
|
/* linked_list_push_front_elem(): Insert an elem_t filled with data from the front in a linked_list_t.
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@data Pointer to any data
|
||||||
|
Insert elem filled with data in the front of the linked list, do nothing on error. */
|
||||||
|
void linked_list_push_front(linked_list_t *, void *);
|
||||||
|
|
||||||
/* linked_list_pop_back(): Delete the last elem in the given linked list
|
/* linked_list_pop_back(): Delete the last elem in the given linked list
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Delete last elem of the linked list, do nothing on error. */
|
Delete last elem of the linked list, do nothing on error. */
|
||||||
void linked_list_pop_back(linked_list_t *linked_list);
|
void linked_list_pop_back(linked_list_t *);
|
||||||
|
|
||||||
/* linked_list_pop_front(): Delete the first elem in the given linked list
|
/* linked_list_pop_front(): Delete the first elem in the given linked list
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Delete first elem of the linked list, do nothing on error. */
|
Delete first elem of the linked list, do nothing on error. */
|
||||||
void linked_list_pop_front(linked_list_t *linked_list);
|
void linked_list_pop_front(linked_list_t *);
|
||||||
|
|
||||||
/* linked_list_get_size(): Get the size of the given linked list
|
/* linked_list_clear(): Clear the given linked list
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Return size of the given linked list, 0 if it's empty. */
|
Clear linked list. */
|
||||||
size_t linked_list_get_size(linked_list_t *linked_list);
|
void linked_list_clear(linked_list_t *);
|
||||||
|
|
||||||
/* linked_list_is_empty(): Check if the given linked list is empty
|
/* linked_list_is_empty(): Check if the given linked list is empty
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Return true if the given linked list is empty else false. */
|
Return true if the given linked list is empty else false. */
|
||||||
bool linked_list_is_empty(linked_list_t *linked_list);
|
bool linked_list_is_empty(const linked_list_t *);
|
||||||
|
|
||||||
/* linked_list_is_in_bound(): Check if the given index is whithin the range of the linked list
|
/* linked_list_is_in_bound(): Check if the given index is whithin the range of the linked list
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
Return true if the given linked list is empty else false. */
|
Return true if the given linked list is empty else false. */
|
||||||
bool linked_list_is_in_bound(linked_list_t *linked_list, size_t index);
|
bool linked_list_is_in_bound(const linked_list_t *, const size_t);
|
||||||
|
|
||||||
/* linked_list_get_elem(): Get element at the given index in the linked list
|
/* linked_list_get_elem(): Get element at the given index in the linked list
|
||||||
|
|
||||||
@linked_list Pointer to an linked_list_t
|
@linked_list Pointer to an linked_list_t
|
||||||
@index Index of the wanted element
|
@index Index of the wanted element
|
||||||
Return the element, NULL on error. */
|
Return the element, NULL on error. */
|
||||||
elem_t *linked_list_get_elem(linked_list_t *linked_list, size_t index);
|
elem_t *linked_list_get_elem(const linked_list_t *, const size_t);
|
||||||
|
|
||||||
|
/* linked_list_get(): Get data in the element at the given index in the linked list
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@index Index of the wanted element
|
||||||
|
Return the data, NULL on error. */
|
||||||
|
void *linked_list_get(const linked_list_t *, const size_t);
|
||||||
|
|
||||||
|
/* linked_list_insert_elem(): Insert element at the given index in the linked list
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@elem Pointer to an element
|
||||||
|
@index Index of the wanted element
|
||||||
|
Insert the element, do nothing on error. */
|
||||||
|
void linked_list_insert_elem(linked_list_t *, elem_t *, const size_t);
|
||||||
|
|
||||||
|
/* linked_list_insert(): Insert element with data at the given index in the linked list
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@data Data to put in the new element
|
||||||
|
@index Index of the wanted element
|
||||||
|
Return the element, do nothing on error. */
|
||||||
|
void linked_list_insert(linked_list_t *, void *, const size_t);
|
||||||
|
|
||||||
|
/* linked_list_remove_elem(): Remove the given elem in the linked list
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@elem Element to remove
|
||||||
|
Remove the element, do nothing on error. */
|
||||||
|
void linked_list_remove_elem(linked_list_t *, elem_t *);
|
||||||
|
|
||||||
|
/* linked_list_remove(): Remove element at the given index in the linked list
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@index Index of the element
|
||||||
|
Remove the element, do nothing on error. */
|
||||||
|
void linked_list_remove(linked_list_t *, const size_t);
|
||||||
|
|
||||||
|
/* linked_list_get_elem_if(): Return first element that the condition verify
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@condition Condition to verify
|
||||||
|
@... Argument to pass to the condition
|
||||||
|
Return the element, NULL on error. */
|
||||||
|
elem_t *linked_list_get_elem_if(const linked_list_t *, const condition_t, ...);
|
||||||
|
|
||||||
|
/* linked_list_get_if(): Return data in the first element that the condition verify
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@condition Condition to verify
|
||||||
|
@... Argument to pass to the condition
|
||||||
|
Return the element data, NULL on error. */
|
||||||
|
void *linked_list_get_if(const linked_list_t *, const condition_t, ...);
|
||||||
|
|
||||||
|
/* linked_list_remove_if(): Remove element(s) that the condition verify
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@condition Condition to verify
|
||||||
|
@... Argument to pass to the condition
|
||||||
|
Remove the element(s), do nothing on error. */
|
||||||
|
void linked_list_remove_if(linked_list_t *, const condition_t, ...);
|
||||||
|
|
||||||
|
/* linked_list_for_each(): Apply the condition to every elements in the list
|
||||||
|
Useful for changing a value in every single element data.
|
||||||
|
The condition can be anything that dont destroy the element.
|
||||||
|
|
||||||
|
@linked_list Pointer to an linked_list_t
|
||||||
|
@condition Condition to apply
|
||||||
|
@... Argument to pass to the condition */
|
||||||
|
void linked_list_for_each(const linked_list_t *, const action_t, ...);
|
||||||
|
|
||||||
#endif // LINKED_LIST_H
|
#endif // LINKED_LIST_H
|
271
src/main.c
271
src/main.c
|
@ -15,43 +15,262 @@ int main(void)
|
||||||
|
|
||||||
return game_exit(game);
|
return game_exit(game);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#include <gint/display.h>
|
|
||||||
#include <gint/keyboard.h>
|
// Texture Unit Tests
|
||||||
#include "malloc.h"
|
#ifdef TEXTURE_TEST
|
||||||
#include "linked_list.h"
|
|
||||||
|
#include "texture_manager.h"
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
dclear(C_RGB(1, 70, 34));
|
dclear(C_WHITE);
|
||||||
|
|
||||||
linked_list_t linked_list;
|
texture_manager_t texture_manager;
|
||||||
linked_list_init(&linked_list, sizeof(int));
|
texture_manager_init(&texture_manager);
|
||||||
|
texture_manager_load_builtin_textures(&texture_manager);
|
||||||
|
|
||||||
elem_t *elem1 = elem_create(&linked_list);
|
texture_t *texture = texture_manager_get_texture(&texture_manager, "player_run_sheet");
|
||||||
if(!elem1)
|
|
||||||
{
|
|
||||||
dtext(1, 1, C_RED, "elem1 is not initialised correctly");
|
|
||||||
goto Exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
linked_list_push_back(&linked_list, elem1);
|
rect_t srcR = {0,0,32,32};
|
||||||
if( linked_list.first == linked_list.last &&
|
rect_t dstR = srcR;
|
||||||
linked_list.first &&
|
|
||||||
linked_list.first->prev == NULL &&
|
|
||||||
linked_list.last->prev == NULL)
|
|
||||||
{
|
|
||||||
dtext(1, 1, C_BLACK, "elem1 is correctly inserted in linked list");
|
|
||||||
}
|
|
||||||
|
|
||||||
Exit:
|
draw_texture(texture, &src, &dst);
|
||||||
|
|
||||||
|
src.x = 33;
|
||||||
|
dst.x = 33;
|
||||||
|
|
||||||
|
draw_texture(texture, &src, &dst);
|
||||||
|
|
||||||
|
texture_manager_remove_texture(&texture_manager, "player_run_sheet");
|
||||||
|
|
||||||
|
src.w = 128;
|
||||||
|
dst.x = 0;
|
||||||
|
dst.y = 33;
|
||||||
|
|
||||||
|
texture_manager_draw_texture(&texture_manager, "player_idle_sheet", &src, &dst);
|
||||||
|
|
||||||
|
texture_manager_clear(&texture_manager);
|
||||||
|
|
||||||
dupdate();
|
dupdate();
|
||||||
getkey();
|
getkey();
|
||||||
|
|
||||||
if(elem1) free(elem1->data);
|
return 1;
|
||||||
if(elem1) free(elem1);
|
}
|
||||||
|
|
||||||
|
#endif // TEXTURE_TEST
|
||||||
|
|
||||||
|
// Linked List Unit Tests
|
||||||
|
#ifdef LINKED_LIST_TEST
|
||||||
|
|
||||||
|
#include "linked_list.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
dclear(C_WHITE);
|
||||||
|
|
||||||
|
linked_list_t linked_list;
|
||||||
|
linked_list_init(&linked_list, sizeof(int));
|
||||||
|
if(linked_list.first == linked_list.last &&
|
||||||
|
linked_list.first == NULL)
|
||||||
|
{
|
||||||
|
dtext(1, 0, C_BLACK, "linked_list is initialised correctly");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem_t *elem1 = NULL;
|
||||||
|
elem_t *elem2 = NULL;
|
||||||
|
elem_t *elem3 = NULL;
|
||||||
|
elem_t *elem4 = NULL;
|
||||||
|
|
||||||
|
elem1 = elem_create(&linked_list);
|
||||||
|
if(elem1 && elem1->data)
|
||||||
|
{
|
||||||
|
dtext(1, 10, C_BLACK, "elem1 is initalised correctly");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_push_back_elem(&linked_list, elem1);
|
||||||
|
if(linked_list.first == linked_list.last &&
|
||||||
|
linked_list.first == elem1 &&
|
||||||
|
!linked_list.first->prev &&
|
||||||
|
!linked_list.first->next &&
|
||||||
|
!linked_list.last->prev &&
|
||||||
|
!linked_list.last->next)
|
||||||
|
{
|
||||||
|
dtext(1, 20, C_BLACK, "elem1 is correctly pushed back");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_pop_back(&linked_list);
|
||||||
|
if(linked_list.first == linked_list.last &&
|
||||||
|
linked_list.first == NULL)
|
||||||
|
{
|
||||||
|
dtext(1, 30, C_BLACK, "elem1 is correctly poped back");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem1 = elem_create(&linked_list);
|
||||||
|
elem2 = elem_create(&linked_list);
|
||||||
|
elem3 = elem_create(&linked_list);
|
||||||
|
elem4 = elem_create(&linked_list);
|
||||||
|
|
||||||
|
linked_list_push_back_elem(&linked_list, elem1);
|
||||||
|
linked_list_push_back_elem(&linked_list, elem2);
|
||||||
|
if(linked_list.first == elem1 &&
|
||||||
|
linked_list.last == elem2 &&
|
||||||
|
!linked_list.first->prev &&
|
||||||
|
linked_list.first->next &&
|
||||||
|
linked_list.last->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first->next == elem2 &&
|
||||||
|
linked_list.last->prev == elem1)
|
||||||
|
{
|
||||||
|
dtext(1, 40, C_BLACK, "elem1 and elem2 are correctly pushed back");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_push_front_elem(&linked_list, elem3);
|
||||||
|
linked_list_push_front_elem(&linked_list, elem4);
|
||||||
|
if(!linked_list.first->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first == elem4 &&
|
||||||
|
linked_list.first->next == elem3 &&
|
||||||
|
linked_list.first->next->next == elem1 &&
|
||||||
|
linked_list.first->next->next->next == elem2 &&
|
||||||
|
linked_list.last == elem2 &&
|
||||||
|
linked_list.last->prev == elem1 &&
|
||||||
|
linked_list.last->prev->prev == elem3 &&
|
||||||
|
linked_list.last->prev->prev->prev == elem4)
|
||||||
|
{
|
||||||
|
dtext(1, 50, C_BLACK, "elem3 and elem4 are correctly pushed front");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(linked_list_get_elem(&linked_list, 2) == elem1)
|
||||||
|
{
|
||||||
|
dtext(1, 60, C_BLACK, "elem4 is got correctly");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_pop_back(&linked_list);
|
||||||
|
if(!linked_list.first->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first == elem4 &&
|
||||||
|
linked_list.first->next == elem3 &&
|
||||||
|
linked_list.first->next->next == elem1 &&
|
||||||
|
linked_list.last == elem1 &&
|
||||||
|
linked_list.last->prev == elem3 &&
|
||||||
|
linked_list.last->prev->prev == elem4)
|
||||||
|
{
|
||||||
|
dtext(1, 70, C_BLACK, "elem2 is correctly poped back");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_remove(&linked_list, 1);
|
||||||
|
if(!linked_list.first->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first == elem4 &&
|
||||||
|
linked_list.first->next == elem1 &&
|
||||||
|
linked_list.last == elem1 &&
|
||||||
|
linked_list.last->prev == elem4)
|
||||||
|
{
|
||||||
|
dtext(1, 80, C_BLACK, "elem3 is correctly removed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_clear(&linked_list);
|
||||||
|
if(linked_list.first == linked_list.last &&
|
||||||
|
linked_list.first == NULL)
|
||||||
|
{
|
||||||
|
dtext(1, 90, C_BLACK, "linked list is correctly cleared");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
elem1 = elem_create(&linked_list);
|
||||||
|
elem2 = elem_create(&linked_list);
|
||||||
|
elem3 = elem_create(&linked_list);
|
||||||
|
elem4 = elem_create(&linked_list);
|
||||||
|
|
||||||
|
linked_list_push_back_elem(&linked_list, elem1);
|
||||||
|
linked_list_push_back_elem(&linked_list, elem2);
|
||||||
|
linked_list_push_front_elem(&linked_list, elem3);
|
||||||
|
if(linked_list.first == elem3 &&
|
||||||
|
linked_list.last == elem2 &&
|
||||||
|
!linked_list.first->prev &&
|
||||||
|
linked_list.first->next &&
|
||||||
|
linked_list.last->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first->next == elem1 &&
|
||||||
|
linked_list.first->next->next == elem2 &&
|
||||||
|
linked_list.last->prev == elem1 &&
|
||||||
|
linked_list.last->prev->prev == elem3)
|
||||||
|
{
|
||||||
|
dtext(1, 100, C_BLACK, "elem1, elem2 and elem3 are correctly pushed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_insert_elem(&linked_list, elem4, 1);
|
||||||
|
if(linked_list.first == elem3 &&
|
||||||
|
linked_list.last == elem2 &&
|
||||||
|
!linked_list.first->prev &&
|
||||||
|
linked_list.first->next &&
|
||||||
|
linked_list.last->prev &&
|
||||||
|
!linked_list.last->next &&
|
||||||
|
linked_list.first->next == elem4 &&
|
||||||
|
linked_list.first->next->next == elem1 &&
|
||||||
|
linked_list.first->next->next->next == elem2 &&
|
||||||
|
linked_list.last->prev == elem1 &&
|
||||||
|
linked_list.last->prev->prev == elem4 &&
|
||||||
|
linked_list.last->prev->prev->prev == elem3)
|
||||||
|
{
|
||||||
|
dtext(1, 110, C_BLACK, "elem3 is correctly inserted");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto Exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
linked_list_clear(&linked_list);
|
||||||
|
|
||||||
|
Exit:
|
||||||
|
dupdate();
|
||||||
|
getkey();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // LINKED_LIST_TEST
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
#include <gint/kmalloc.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "texture_manager.h"
|
||||||
|
#include "textures.h"
|
||||||
|
|
||||||
|
texture_t *create_texture(image_t *image, const char *name)
|
||||||
|
{
|
||||||
|
if(!image) return NULL;
|
||||||
|
|
||||||
|
texture_t *texture = kmalloc(sizeof(texture_t), NULL);
|
||||||
|
if (!texture) return NULL;
|
||||||
|
|
||||||
|
texture->name = name;
|
||||||
|
texture->image = image;
|
||||||
|
|
||||||
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void destroy_texture(texture_t *texture)
|
||||||
|
{
|
||||||
|
kfree(texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void draw_texture(const texture_t *texture, const rect_t *src, const rect_t *dst, bool flip)
|
||||||
|
{
|
||||||
|
dsubimage_rgb16_effect((int)dst->x, (int)dst->y, texture->image, (int)src->x, (int)src->y, (int)src->w, (int)src->h, flip ? IMAGE_HFLIP : DIMAGE_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void texture_manager_init(texture_manager_t *texture_manager)
|
||||||
|
{
|
||||||
|
linked_list_init(&texture_manager->textures, sizeof(texture_t), NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void texture_manager_load_builtin_textures(texture_manager_t *texture_manager)
|
||||||
|
{
|
||||||
|
for(size_t i = 0; i < BUILTIN_TEXTURE_COUNT; i++)
|
||||||
|
{
|
||||||
|
texture_t *texture = create_texture((image_t *)builtin_textures[i].image, builtin_textures[i].name);
|
||||||
|
texture_manager_add_texture(texture_manager, texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void texture_manager_add_texture(texture_manager_t *texture_manager, texture_t *texture)
|
||||||
|
{
|
||||||
|
linked_list_push_back(&texture_manager->textures, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only for this file
|
||||||
|
// Arg : const char *name
|
||||||
|
static inline bool is_texture_name(elem_t *elem, va_list args)
|
||||||
|
{
|
||||||
|
return !strcmp(((texture_t *)elem->data)->name, va_arg(args, const char*));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline texture_t *texture_manager_get_texture(const texture_manager_t *texture_manager, const char *name)
|
||||||
|
{
|
||||||
|
return linked_list_get_if(&texture_manager->textures, is_texture_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void texture_manager_remove_texture(texture_manager_t *texture_manager, const char *name)
|
||||||
|
{
|
||||||
|
linked_list_remove_if(&texture_manager->textures, is_texture_name, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void texture_manager_clear(texture_manager_t *texture_manager)
|
||||||
|
{
|
||||||
|
linked_list_clear(&texture_manager->textures);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void texture_manager_draw_texture(const texture_manager_t *texture_manager, const char *name, const rect_t *src, const rect_t *dst, bool flip)
|
||||||
|
{
|
||||||
|
draw_texture(texture_manager_get_texture(texture_manager, name), src, dst, flip);
|
||||||
|
}
|
|
@ -1,8 +1,86 @@
|
||||||
#ifndef TEXTURE_MANAGER_H
|
#ifndef TEXTURE_MANAGER_H
|
||||||
#define TEXTURE_MANAGER_H
|
#define TEXTURE_MANAGER_H
|
||||||
|
|
||||||
typedef struct {
|
#include <gint/image.h>
|
||||||
|
#include "vector2d.h"
|
||||||
|
#include "linked_list.h"
|
||||||
|
|
||||||
|
/* texture_t: Texture definition
|
||||||
|
This struct is the base for textures
|
||||||
|
|
||||||
|
@name Name of the texture
|
||||||
|
@image Texture of type bopti_image_t */
|
||||||
|
typedef struct texture_t {
|
||||||
|
const char *name;
|
||||||
|
image_t *image;
|
||||||
|
} texture_t;
|
||||||
|
|
||||||
|
/* create_texture(): Create a texture with the given image and name
|
||||||
|
|
||||||
|
@name Name of the texture
|
||||||
|
@image Texture of type bopti_image_t
|
||||||
|
Return the created texture, NULL on error. */
|
||||||
|
texture_t *create_texture(image_t *, const char *);
|
||||||
|
|
||||||
|
/* destroy_texture(): Destroy the given texture
|
||||||
|
|
||||||
|
@texture Texture to destroy */
|
||||||
|
void destroy_texture(texture_t *);
|
||||||
|
|
||||||
|
/* draw_texture(): Draw the given texture from given src rect to dst rect
|
||||||
|
|
||||||
|
@texture Texture to draw
|
||||||
|
@src Source rectangle of the texture to draw
|
||||||
|
@dst Destination of the drawing */
|
||||||
|
void draw_texture(const texture_t *, const rect_t *, const rect_t *, bool);
|
||||||
|
|
||||||
|
/* texture_manager_t: Texture manager
|
||||||
|
|
||||||
|
@textures Textures loaded in memory */
|
||||||
|
typedef struct texture_manager_t {
|
||||||
|
linked_list_t textures;
|
||||||
} texture_manager_t;
|
} texture_manager_t;
|
||||||
|
|
||||||
|
/* texture_manager_init(): Initialise the given texture_manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager */
|
||||||
|
void texture_manager_init(texture_manager_t *);
|
||||||
|
|
||||||
|
/* texture_manager_load_builtin_textures(): Load textures declared in "textures.h"
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager */
|
||||||
|
void texture_manager_load_builtin_textures(texture_manager_t *);
|
||||||
|
|
||||||
|
/* texture_manager_add_texture(): Add a texture in the texture manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager
|
||||||
|
@texture Texture to add in the texture manager */
|
||||||
|
void texture_manager_add_texture(texture_manager_t *, texture_t *);
|
||||||
|
|
||||||
|
/* texture_manager_get_texture(): Get a texture in the texture manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager
|
||||||
|
@name Name of the texture to get
|
||||||
|
Return the texture, NULL on error or if the texture is not found. */
|
||||||
|
texture_t *texture_manager_get_texture(const texture_manager_t *, const char *);
|
||||||
|
|
||||||
|
/* texture_manager_remove_texture(): Remove a texture in the texture manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager
|
||||||
|
@name Name of the texture to remove
|
||||||
|
Do nothing if the texture is not found. */
|
||||||
|
void texture_manager_remove_texture(texture_manager_t *, const char *);
|
||||||
|
|
||||||
|
/* texture_manager_clear(): Clear the texture manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager */
|
||||||
|
void texture_manager_clear(texture_manager_t *);
|
||||||
|
|
||||||
|
/* texture_manager_draw_texture(): Draw a texture in the texture manager
|
||||||
|
|
||||||
|
@texture_manager Pointer to a texture manager
|
||||||
|
@name Name of the texture to draw
|
||||||
|
Do nothing if the texture is not found. */
|
||||||
|
void texture_manager_draw_texture(const texture_manager_t *, const char *, const rect_t *, const rect_t *, bool);
|
||||||
|
|
||||||
#endif // TEXTURE_MANAGER_H
|
#endif // TEXTURE_MANAGER_H
|
|
@ -0,0 +1,22 @@
|
||||||
|
#ifndef TEXTURES_H
|
||||||
|
#define TEXTURES_H
|
||||||
|
|
||||||
|
#include <gint/display.h>
|
||||||
|
#include "texture_manager.h"
|
||||||
|
|
||||||
|
typedef struct builtin_texture_t {
|
||||||
|
const char *name;
|
||||||
|
bopti_image_t *image;
|
||||||
|
} builtin_texture_t;
|
||||||
|
|
||||||
|
extern bopti_image_t img_player_idle_sheet;
|
||||||
|
extern bopti_image_t img_player_run_sheet;
|
||||||
|
|
||||||
|
static struct builtin_texture_t builtin_textures[] = {
|
||||||
|
{"player_idle_sheet", &img_player_idle_sheet},
|
||||||
|
{"player_run_sheet", &img_player_run_sheet},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define BUILTIN_TEXTURE_COUNT (sizeof(builtin_textures) / sizeof(builtin_texture_t))
|
||||||
|
|
||||||
|
#endif // TEXTURES_H
|
Loading…
Reference in New Issue