mirror of
https://github.com/UberGames/rpgxEF.git
synced 2024-11-10 07:11:34 +00:00
Modified list module and sublicensed it
This commit is contained in:
parent
e757da99ff
commit
86fb3565c4
6 changed files with 229 additions and 94 deletions
|
@ -71,7 +71,57 @@ creators is not allowed. Feel free to use the source code included
|
|||
in this file and/or git repository for your own mod as long as you
|
||||
give full credit to UberGamesi for our modification/code and as long
|
||||
as this does not conflict with the original license of the STVEF HM
|
||||
gamecode.. The Ubergames and other conributers to the RPG-X Mod cannot
|
||||
gamecode. The Ubergames and other conributers to the RPG-X Mod cannot
|
||||
be held accountable for any damage that may have been caused by playing
|
||||
the game.
|
||||
|
||||
Lua License:
|
||||
------------
|
||||
/****************************************************************************
|
||||
* Copyright (C) 1994-2013 Lua.org, PUC-Rio. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
******************************************************************************/
|
||||
|
||||
Original List Module License (list.h, list.c):
|
||||
----------------------------------------------
|
||||
/*
|
||||
Copyright (c) 2011 Zhehao Mao
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
||||
of the Software, and to permit persons to whom the Software is furnished to do
|
||||
so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -519,13 +519,13 @@ static char *TimedMessage( void ){
|
|||
}
|
||||
|
||||
if(iterTimedMessages == NULL) {
|
||||
iterTimedMessages = list_iterator(level.timedMessages, FRONT);
|
||||
iterTimedMessages = list_iterator(level.timedMessages, LIST_FRONT);
|
||||
if(iterTimedMessages == NULL) { // something went wrong
|
||||
return "^1RPG-X ERROR: No messages to display";
|
||||
}
|
||||
}
|
||||
|
||||
msg = (timedMessage_t *)list_cycl_next(iterTimedMessages);
|
||||
msg = (timedMessage_t *)list_cycl_next(iterTimedMessages)->data;
|
||||
message = msg->message;
|
||||
|
||||
return message;
|
||||
|
|
|
@ -7450,20 +7450,20 @@ void addShaderToList(list_p list, char *shader) {
|
|||
return;
|
||||
}
|
||||
|
||||
i = list_iterator(list, FRONT);
|
||||
i = list_iterator(list, LIST_FRONT);
|
||||
if(i == NULL) {
|
||||
free(s->s);
|
||||
free(s);
|
||||
return;
|
||||
}
|
||||
|
||||
for(t = (rShader_s *)list_next(i); t != NULL; t = (rShader_s *)list_next(i)) {
|
||||
for(t = (rShader_s *)list_next(i)->data; t != NULL; t = (rShader_s *)list_next(i)->data) {
|
||||
if(!strcmp(shader, t->s)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
list_add(list, s, sizeof(rShader_s));
|
||||
list_add(list, s, LT_DATA, sizeof(rShader_s));
|
||||
}
|
||||
|
||||
extern target_alert_Shaders_s alertShaders;
|
||||
|
@ -7519,14 +7519,14 @@ void Cmd_GeneratePrecacheFile(gentity_t *ent) {
|
|||
}
|
||||
}
|
||||
|
||||
iter = list_iterator(shaders, FRONT);
|
||||
iter = list_iterator(shaders, LIST_FRONT);
|
||||
if(iter == NULL) {
|
||||
trap_FS_FCloseFile(f);
|
||||
destroy_list(shaders);
|
||||
return;
|
||||
}
|
||||
|
||||
for(s = (rShader_s *)list_next(iter); s != NULL; s = (rShader_s *)list_next(iter)) {
|
||||
for(s = (rShader_s *)list_next(iter)->data; s != NULL; s = (rShader_s *)list_next(iter)->data) {
|
||||
G_Printf("\t%s\n", s->s);
|
||||
if(first) {
|
||||
trap_FS_Write("\"", 1, f);
|
||||
|
|
|
@ -968,7 +968,7 @@ static void G_LoadTimedMessages(void) {
|
|||
}
|
||||
|
||||
msg->message = strdup(token);
|
||||
list_add(level.timedMessages, msg, sizeof(timedMessage_s));
|
||||
list_add(level.timedMessages, msg, LT_DATA, sizeof(timedMessage_s));
|
||||
} else {
|
||||
if(token[0] == '}') {
|
||||
break;
|
||||
|
|
154
code/game/list.c
154
code/game/list.c
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2011 Zhehao Mao
|
||||
Copyright (c) 2013 Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -20,78 +20,100 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
*/
|
||||
|
||||
#include "list.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
list_p create_list() {
|
||||
list_p list = (list_p)malloc(sizeof(struct list));
|
||||
|
||||
if(list == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->length = 0;
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->destructor = free;
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
list_iter_p list_iterator(list_p list, char init) {
|
||||
list_iter_p iter = (list_iter_p)malloc(sizeof(struct list_iter));
|
||||
if(init==FRONT){
|
||||
iter->current = list->first;
|
||||
}
|
||||
else if(init==BACK){
|
||||
iter->current = list->last;
|
||||
}
|
||||
else {
|
||||
if(iter != NULL)
|
||||
free(iter);
|
||||
|
||||
if(iter == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(init == LIST_FRONT) {
|
||||
iter->current = list->first;
|
||||
} else if(init == LIST_BACK) {
|
||||
iter->current = list->last;
|
||||
} else { // asume front
|
||||
iter->current = list->first;
|
||||
}
|
||||
|
||||
iter->list = list;
|
||||
iter->started = 0;
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
void list_add(list_p list, void* data, int size){
|
||||
int list_add(list_p list, void* data, dataType_t type, int size) {
|
||||
lnode_p node = (lnode_p)malloc(sizeof(struct linked_node));
|
||||
node->data = malloc(size);
|
||||
memcpy(node->data, data, size);
|
||||
|
||||
node->cont = (container_p)(sizeof(container));
|
||||
if(node->cont == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
node->cont->data = malloc(size);
|
||||
if(node->cont->data == NULL) {
|
||||
return 0;
|
||||
}
|
||||
memcpy(node->cont->data, data, size);
|
||||
|
||||
if(list->first == NULL) {
|
||||
node->prev = NULL;
|
||||
node->next = NULL;
|
||||
list->first = node;
|
||||
list->last = node;
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
list->last->next = node;
|
||||
node->prev = list->last;
|
||||
node->next = NULL;
|
||||
list->last = node;
|
||||
}
|
||||
list->length++;
|
||||
|
||||
return list->length;
|
||||
}
|
||||
|
||||
container_p list_current(list_iter_p iter){
|
||||
if(iter->started && iter->current != NULL) {
|
||||
return iter->current->cont;
|
||||
}
|
||||
|
||||
void* list_current(list_iter_p iter){
|
||||
if(iter->started&&iter->current!=NULL)
|
||||
return iter->current->data;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* list_next(list_iter_p iter){
|
||||
container_p list_next(list_iter_p iter) {
|
||||
if(!iter->started && iter->current != NULL) {
|
||||
iter->started = 1;
|
||||
return iter->current->data;
|
||||
return iter->current->cont;
|
||||
}
|
||||
|
||||
if(iter->current != NULL) {
|
||||
iter->current = iter->current->next;
|
||||
return list_current(iter);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* list_cycl_next(list_iter_p iter){
|
||||
container_p list_cycl_next(list_iter_p iter) {
|
||||
if(!iter->started && iter->current != NULL) {
|
||||
iter->started = 1;
|
||||
return iter->current->data;
|
||||
return iter->current->cont;
|
||||
}
|
||||
if(iter->current != NULL) {
|
||||
iter->current = iter->current->next;
|
||||
|
@ -103,10 +125,10 @@ void* list_cycl_next(list_iter_p iter){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void* list_prev(list_iter_p iter){
|
||||
container_p list_prev(list_iter_p iter) {
|
||||
if(!iter->started&&iter->current!=NULL) {
|
||||
iter->started = 1;
|
||||
return iter->current->data;
|
||||
return iter->current->cont;
|
||||
}
|
||||
if(iter->current!=NULL) {
|
||||
iter->current = iter->current->prev;
|
||||
|
@ -115,11 +137,12 @@ void* list_prev(list_iter_p iter){
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void* list_cycl_prev(list_iter_p iter){
|
||||
container_p list_cycl_prev(list_iter_p iter){
|
||||
if(!iter->started && iter->current != NULL) {
|
||||
iter->started =1 ;
|
||||
return iter->current->data;
|
||||
return iter->current->cont;
|
||||
}
|
||||
|
||||
if(iter->current!=NULL) {
|
||||
iter->current = iter->current->prev;
|
||||
if(iter->current == NULL) {
|
||||
|
@ -127,66 +150,98 @@ void* list_cycl_prev(list_iter_p iter){
|
|||
}
|
||||
return list_current(iter);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void* list_first(list_p list){
|
||||
return list->first->data;
|
||||
container_p list_first(list_p list) {
|
||||
return list->first->cont;
|
||||
}
|
||||
|
||||
void* list_last(list_p list){
|
||||
return list->last->data;
|
||||
container_p list_last(list_p list) {
|
||||
return list->last->cont;
|
||||
}
|
||||
|
||||
void* list_pop(list_p list){
|
||||
container_p list_pop(list_p list) {
|
||||
container_p cont;
|
||||
lnode_p last = list->last;
|
||||
if(last == NULL) return NULL;
|
||||
|
||||
if(last == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->last = last->prev;
|
||||
void* data = last->data;
|
||||
cont = last->cont;
|
||||
|
||||
if(last->prev != NULL) {
|
||||
last->prev->next = NULL;
|
||||
}
|
||||
|
||||
free(last);
|
||||
list->length--;
|
||||
|
||||
if(list->length == 0) {
|
||||
list->last = list->first = NULL;
|
||||
}
|
||||
return data;
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
void* list_poll(list_p list){
|
||||
container_p list_poll(list_p list){
|
||||
container_p cont;
|
||||
lnode_p first = list->first;
|
||||
if(first == NULL) return NULL;
|
||||
|
||||
if(first == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->first = first->next;
|
||||
void* data = first->data;
|
||||
cont = first->cont;
|
||||
|
||||
if(first->next != NULL) {
|
||||
first->next->prev = NULL;
|
||||
}
|
||||
|
||||
free(first);
|
||||
list->length--;
|
||||
|
||||
if(list->length == 0) {
|
||||
list->last = list->first = NULL;
|
||||
}
|
||||
return data;
|
||||
|
||||
return cont;
|
||||
}
|
||||
|
||||
void list_remove(list_p list, char end) {
|
||||
void * data;
|
||||
if(end == FRONT)
|
||||
data = list_poll(list);
|
||||
else if (end == BACK)
|
||||
data = list_pop(list);
|
||||
else return;
|
||||
list->destructor(data);
|
||||
container_p cont;
|
||||
void (*destructor)(void*) = list->destructor;
|
||||
|
||||
if(end == LIST_FRONT) {
|
||||
cont = list_poll(list);
|
||||
} else if (end == LIST_BACK) {
|
||||
cont = list_pop(list);
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if(cont != NULL) {
|
||||
if(cont->data != NULL) {
|
||||
destructor(cont->data);
|
||||
}
|
||||
|
||||
free(cont);
|
||||
}
|
||||
}
|
||||
|
||||
void destroy_list(list_p list) {
|
||||
lnode_p cur = list->first;
|
||||
lnode_p next;
|
||||
|
||||
while(cur!=NULL){
|
||||
next = cur->next;
|
||||
if(list->destructor != NULL) { // only destroy data if there is a destructor set
|
||||
list->destructor(cur->data);
|
||||
list->destructor(cur->cont->data);
|
||||
free(cur->cont);
|
||||
}
|
||||
free(cur);
|
||||
cur = next;
|
||||
|
@ -195,7 +250,10 @@ void destroy_list(list_p list){
|
|||
}
|
||||
|
||||
void destroy_iterator(list_iter_p iter) {
|
||||
if(iter == NULL) return;
|
||||
if(iter == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
free(iter);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
Copyright (c) 2011 Zhehao Mao
|
||||
Copyright (c) 2013 Ubergames
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
|
@ -25,11 +25,37 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
/* A C implementation of a doubly-linked list. Contains void pointer values.
|
||||
Can be used as a LIFO stack of FIFO queue. */
|
||||
|
||||
#define FRONT 0
|
||||
#define BACK 1
|
||||
#include <stdlib.h>
|
||||
|
||||
#define LIST_FRONT 0
|
||||
#define LIST_BACK 1
|
||||
|
||||
typedef enum {
|
||||
LT_BOOLEAN,
|
||||
LT_CHAR,
|
||||
LT_UNSIGNED_CHAR,
|
||||
LT_SHORT,
|
||||
LT_UNSIGNED_SHORT,
|
||||
LT_INT,
|
||||
LT_UNSIGNED_INT,
|
||||
LT_LONG,
|
||||
LT_UNSIGNED_LONG,
|
||||
LT_DOUBLE,
|
||||
LT_STRING,
|
||||
LT_DATA,
|
||||
LT_MAX
|
||||
} dataType_t;
|
||||
|
||||
struct container {
|
||||
void* data;
|
||||
size_t size;
|
||||
dataType_t type;
|
||||
} container;
|
||||
|
||||
typedef struct container* container_p;
|
||||
|
||||
struct linked_node {
|
||||
void* data;
|
||||
container_p cont;
|
||||
struct linked_node* next;
|
||||
struct linked_node* prev;
|
||||
};
|
||||
|
@ -61,41 +87,42 @@ list_p create_list(void);
|
|||
|
||||
/**
|
||||
* Create a list_iter object for the linked_list list. The flag init can be
|
||||
* either FRONT or BACK and indicates whether to start the iterator from the first
|
||||
* either LIST_FRONT or LIST_BACK and indicates whether to start the iterator from the first
|
||||
* or last item in the list
|
||||
*/
|
||||
list_iter_p list_iterator(list_p list, char init);
|
||||
|
||||
/**
|
||||
* Add an item with the given value and size to the back of the list.
|
||||
* Add an item with the given value, type, and size to the back of the list.
|
||||
* The data is copied by value, so the original pointer must be freed if it
|
||||
* was allocated on the heap.
|
||||
* Returns the length of the list if succesfull else returns 0.
|
||||
*/
|
||||
void list_add(list_p list, void* data, int size);
|
||||
int list_add(list_p list, void* data, dataType_t type, int size);
|
||||
|
||||
/**
|
||||
* Gets the data stored in the first item of the list or NULL if the list is empty
|
||||
*/
|
||||
void* list_first(list_p list);
|
||||
container_p list_first(list_p list);
|
||||
/**
|
||||
* Gets the data stored in the last item of the list or NULL if the list is empty
|
||||
*/
|
||||
void* list_last(list_p list);
|
||||
container_p list_last(list_p list);
|
||||
|
||||
/**
|
||||
* Removes the last item in the list (LIFO order) and returns the data stored
|
||||
* there. The data returned must be freed later in order to remain memory safe.
|
||||
*/
|
||||
void* list_pop(list_p list);
|
||||
container_p list_pop(list_p list);
|
||||
/**
|
||||
* Removes the first item in the list (FIFO order) and returns the data stored
|
||||
* there. The data return must be freed later in order to remain memory safe.
|
||||
*/
|
||||
void* list_poll(list_p list);
|
||||
container_p list_poll(list_p list);
|
||||
/**
|
||||
* Convenience function for completely destroying an item in the list. If the end
|
||||
* flag is FRONT, an item will be polled from the front of the list and its data
|
||||
* freed. If the end flag is set to BACK, an item will be popped off the end of
|
||||
* flag is LIST_FRONT, an item will be polled from the front of the list and its data
|
||||
* freed. If the end flag is set to LIST_BACK, an item will be popped off the end of
|
||||
* the list and the data freed.
|
||||
*/
|
||||
void list_remove(list_p list, char end);
|
||||
|
@ -113,28 +140,28 @@ void destroy_iterator(list_iter_p iter);
|
|||
/**
|
||||
* Return the data held by the current item pointed to by the iterator
|
||||
*/
|
||||
void* list_current(list_iter_p list);
|
||||
container_p list_current(list_iter_p list);
|
||||
/**
|
||||
* Advances the iterator to the next item in the list and returns the data
|
||||
* stored there.
|
||||
*/
|
||||
void* list_next(list_iter_p list);
|
||||
container_p list_next(list_iter_p list);
|
||||
/**
|
||||
* Advances the iterator to the previous item in the list and returns the data
|
||||
* stored there.
|
||||
*/
|
||||
void* list_prev(list_iter_p list);
|
||||
container_p list_prev(list_iter_p list);
|
||||
/**
|
||||
* Advances the iterator to the next item in the list and returns the data
|
||||
* stored there. If the end of the list is reached it continues with the first
|
||||
* element of the list.
|
||||
*/
|
||||
void* list_cycl_next(list_iter_p list);
|
||||
container_p list_cycl_next(list_iter_p list);
|
||||
/**
|
||||
* Advances the iterator to the previous item in the list and returns the data
|
||||
* stored there. If the start of the list is reached it continues with the last
|
||||
* element of the list.
|
||||
*/
|
||||
void* list_cycl_prev(list_iter_p list);
|
||||
container_p list_cycl_prev(list_iter_p list);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue