1 /************************************************************************
3 * voxelands - 3d voxel world sandbox game
4 * Copyright (C) Lisa 'darkrose' Milne 2016 <lisa@ltmnet.com>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>
18 ************************************************************************/
27 /* initialises an array - useful for those created on the stack */
28 void array_init(array_t
*a
, uint32_t type
)
36 /* create a new array of type */
37 array_t
*array_create(uint32_t type
)
41 a
= malloc(sizeof(array_t
));
50 /* create a new array as a copy of a */
51 array_t
*array_copy(array_t
*a
)
53 array_t
*r
= array_create(ARRAY_TYPE_STRING
);
59 case ARRAY_TYPE_STRING
:
60 for (i
=0; i
<a
->length
; i
++) {
61 array_push_string(r
,((char**)(a
->data
))[i
]);
64 case ARRAY_TYPE_FLOAT
:
65 for (i
=0; i
<a
->length
; i
++) {
66 array_push_float(r
,((float*)(a
->data
))[i
]);
70 for (i
=0; i
<a
->length
; i
++) {
71 array_push_int(r
,((uint32_t*)(a
->data
))[i
]);
75 for (i
=0; i
<a
->length
; i
++) {
76 array_push_ptr(r
,((unsigned char**)(a
->data
))[i
]);
86 /* compare two arrays */
87 int array_cmp(array_t
*a1
, array_t
*a2
)
98 if (a1
->length
!= a2
->length
)
101 if (a1
->type
== ARRAY_TYPE_STRING
&& a2
->type
== ARRAY_TYPE_STRING
) {
104 for (i
=0; i
<a1
->length
; i
++) {
105 if (!c1
[i
] || !c2
[i
] || strcmp(c1
[i
],c2
[i
]))
108 }else if (a1
->type
== ARRAY_TYPE_STRING
&& a2
->type
== ARRAY_TYPE_INT
) {
111 for (i
=0; i
<a1
->length
; i
++) {
112 if (!c1
[i
] || i2
[i
] != strtol(c1
[i
],NULL
,10))
115 }else if (a1
->type
== ARRAY_TYPE_STRING
&& a2
->type
== ARRAY_TYPE_FLOAT
) {
118 for (i
=0; i
<a1
->length
; i
++) {
119 if (!c1
[i
] || f2
[i
] != strtof(c1
[i
],NULL
))
122 }else if (a1
->type
== ARRAY_TYPE_INT
&& a2
->type
== ARRAY_TYPE_STRING
) {
125 for (i
=0; i
<a1
->length
; i
++) {
126 if (!c2
[i
] || i1
[i
] != strtol(c2
[i
],NULL
,10))
129 }else if (a1
->type
== ARRAY_TYPE_FLOAT
&& a2
->type
== ARRAY_TYPE_STRING
) {
132 for (i
=0; i
<a1
->length
; i
++) {
133 if (!c2
[i
] || f1
[i
] != strtof(c2
[i
],NULL
))
136 }else if (a1
->type
== ARRAY_TYPE_INT
&& a2
->type
== ARRAY_TYPE_INT
) {
139 for (i
=0; i
<a1
->length
; i
++) {
143 }else if (a1
->type
== ARRAY_TYPE_FLOAT
&& a2
->type
== ARRAY_TYPE_FLOAT
) {
146 for (i
=0; i
<a1
->length
; i
++) {
150 }else if (a1
->type
== ARRAY_TYPE_INT
&& a2
->type
== ARRAY_TYPE_FLOAT
) {
153 for (i
=0; i
<a1
->length
; i
++) {
154 if (i1
[i
] != (int)f2
[i
])
157 }else if (a1
->type
== ARRAY_TYPE_FLOAT
&& a2
->type
== ARRAY_TYPE_INT
) {
160 for (i
=0; i
<a1
->length
; i
++) {
161 if ((int)f1
[i
] != i2
[i
])
164 }else if (a1
->type
== ARRAY_TYPE_PTR
&& a2
->type
== ARRAY_TYPE_PTR
) {
167 for (i
=0; i
<a1
->length
; i
++) {
176 /* destroy an array */
177 void array_free(array_t
*a
, int freestruct
)
182 if (a
->type
== ARRAY_TYPE_STRING
) {
184 for (i
=0; i
<a
->length
; i
++ ) {
200 /* push an int onto an array */
201 int array_push_int(array_t
*a
, uint32_t v
)
204 if (a
->type
== ARRAY_TYPE_STRING
) {
207 return array_push_string(a
,sv
);
208 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
209 return array_push_float(a
,(float)v
);
210 }else if (a
->type
!= ARRAY_TYPE_INT
) {
218 if (a
->size
< a
->length
) {
219 p
= realloc(a
->data
,sizeof(uint32_t)*a
->length
);
233 /* push a float onto an array */
234 int array_push_float(array_t
*a
, float v
)
237 if (a
->type
== ARRAY_TYPE_STRING
) {
240 return array_push_string(a
,sv
);
241 }else if (a
->type
== ARRAY_TYPE_INT
) {
242 return array_push_int(a
,(int)v
);
243 }else if (a
->type
!= ARRAY_TYPE_FLOAT
) {
251 if (a
->size
< a
->length
) {
252 p
= realloc(a
->data
,sizeof(float)*a
->length
);
266 /* push a string onto an array */
267 int array_push_string(array_t
*a
, char* v
)
270 if (a
->type
!= ARRAY_TYPE_STRING
)
277 if (a
->size
< a
->length
) {
278 p
= realloc(a
->data
,sizeof(char*)*a
->length
);
287 p
[a
->length
-1] = strdup(v
);
289 p
[a
->length
-1] = NULL
;
296 /* push a pointer onto an array */
297 int array_push_ptr(array_t
*a
, void *v
)
300 if (a
->type
!= ARRAY_TYPE_PTR
)
307 if (a
->size
< a
->length
) {
308 p
= realloc(a
->data
,sizeof(char*)*a
->length
);
323 /* push a colour onto an array */
324 int array_push_colour(array_t
*a
, colour_t
*c
)
327 r
+= array_push_float(a
,((float)c
->r
)/255.0);
328 r
+= array_push_float(a
,((float)c
->g
)/255.0);
329 r
+= array_push_float(a
,((float)c
->b
)/255.0);
330 r
+= array_push_float(a
,((float)c
->a
)/255.0);
334 /* push a v3_t onto an array */
335 int array_push_v3t(array_t
*a
, v3_t
*v
)
338 r
+= array_push_float(a
,v
->x
);
339 r
+= array_push_float(a
,v
->y
);
340 r
+= array_push_float(a
,v
->z
);
344 /* push a v2_t onto an array */
345 int array_push_v2t(array_t
*a
, v2_t
*v
)
348 r
+= array_push_float(a
,v
->x
);
349 r
+= array_push_float(a
,v
->y
);
353 /* set the value of array index i to an int value */
354 int array_set_int(array_t
*a
, uint32_t v
, int i
)
356 uint32_t *p
= a
->data
;
357 if (a
->type
== ARRAY_TYPE_STRING
) {
360 return array_set_string(a
,sv
,i
);
361 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
362 return array_set_float(a
,(float)v
,i
);
363 }else if (a
->type
!= ARRAY_TYPE_INT
) {
371 p
= realloc(a
->data
,sizeof(uint32_t)*l
);
374 for (k
=a
->length
; k
<l
; k
++) {
389 /* set the value of array index i to a float value */
390 int array_set_float(array_t
*a
, float v
, int i
)
393 if (a
->type
== ARRAY_TYPE_STRING
) {
396 return array_set_string(a
,sv
,i
);
397 }else if (a
->type
== ARRAY_TYPE_INT
) {
398 return array_set_float(a
,(uint32_t)v
,i
);
399 }else if (a
->type
!= ARRAY_TYPE_FLOAT
) {
407 p
= realloc(a
->data
,sizeof(float)*l
);
410 for (k
=a
->length
; k
<l
; k
++) {
424 /* set the value of array index i to a string value */
425 int array_set_string(array_t
*a
, char* v
, int i
)
428 if (a
->type
!= ARRAY_TYPE_STRING
)
435 p
= realloc(a
->data
,sizeof(char*)*l
);
438 for (k
=a
->length
; k
<l
; k
++) {
456 /* set the value of array index i to a ponter value */
457 int array_set_ptr(array_t
*a
, void* v
, int i
)
460 if (a
->type
!= ARRAY_TYPE_PTR
)
467 p
= realloc(a
->data
,sizeof(char*)*l
);
470 for (k
=a
->length
; k
<l
; k
++) {
484 /* pop an int off the top of an array */
485 uint32_t array_pop_int(array_t
*a
)
487 if (a
->type
== ARRAY_TYPE_INT
) {
491 return ((uint32_t*)(a
->data
))[a
->length
];
492 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
493 float v
= array_pop_float(a
);
495 }else if (a
->type
== ARRAY_TYPE_STRING
) {
497 char* s
= array_pop_string(a
);
498 v
= strtol(s
,NULL
,10);
505 /* pop a float off the top of an array */
506 float array_pop_float(array_t
*a
)
508 if (a
->type
== ARRAY_TYPE_FLOAT
) {
512 return ((float*)(a
->data
))[a
->length
];
513 }else if (a
->type
== ARRAY_TYPE_INT
) {
514 uint32_t v
= array_pop_int(a
);
516 }else if (a
->type
== ARRAY_TYPE_STRING
) {
518 char* s
= array_pop_string(a
);
526 /* pop a string off the top of an array */
527 char* array_pop_string(array_t
*a
)
529 if (a
->type
== ARRAY_TYPE_FLOAT
) {
530 float v
= array_pop_float(a
);
536 }else if (a
->type
== ARRAY_TYPE_INT
) {
537 uint32_t v
= array_pop_int(a
);
543 }else if (a
->type
== ARRAY_TYPE_STRING
) {
547 return ((char**)(a
->data
))[a
->length
];
552 /* pop a pointer off the top of an array */
553 void *array_pop_ptr(array_t
*a
)
555 if (a
->type
== ARRAY_TYPE_PTR
&& a
->length
) {
557 return ((char**)(a
->data
))[a
->length
];
562 /* get an int value from an array */
563 uint32_t array_get_int(array_t
*a
, int i
)
565 if (a
->type
== ARRAY_TYPE_INT
) {
568 return ((uint32_t*)(a
->data
))[i
];
569 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
570 float v
= array_get_float(a
,i
);
572 }else if (a
->type
== ARRAY_TYPE_STRING
) {
574 char* s
= array_get_string(a
,i
);
575 v
= strtol(s
,NULL
,10);
582 /* get a float value from an array */
583 float array_get_float(array_t
*a
, int i
)
585 if (a
->type
== ARRAY_TYPE_FLOAT
) {
588 return ((float*)(a
->data
))[i
];
589 }else if (a
->type
== ARRAY_TYPE_INT
) {
590 uint32_t v
= array_get_int(a
,i
);
592 }else if (a
->type
== ARRAY_TYPE_STRING
) {
594 char* s
= array_get_string(a
,i
);
602 /* get a string value from an array */
603 char* array_get_string(array_t
*a
, int i
)
605 if (a
->type
== ARRAY_TYPE_FLOAT
) {
606 float v
= array_get_float(a
,i
);
610 }else if (a
->type
== ARRAY_TYPE_INT
) {
611 uint32_t v
= array_get_int(a
,i
);
615 }else if (a
->type
== ARRAY_TYPE_STRING
) {
618 return ((char**)(a
->data
))[i
];
623 /* get a pointer from an array */
624 void *array_get_ptr(array_t
*a
, int i
)
626 if (a
->type
== ARRAY_TYPE_PTR
&& a
->length
> i
) {
627 return ((char**)(a
->data
))[i
];
632 /* find the index of an int value in an array */
633 int array_find_int(array_t
*a
, uint32_t v
)
635 if (a
->type
== ARRAY_TYPE_INT
) {
637 uint32_t *p
= a
->data
;
638 for (i
=0; i
<a
->length
; i
++) {
646 /* find the index of a float value in an array */
647 int array_find_float(array_t
*a
, float v
)
649 if (a
->type
== ARRAY_TYPE_FLOAT
) {
652 for (i
=0; i
<a
->length
; i
++) {
660 /* find the index of a string value in an array */
661 int array_find_string(array_t
*a
, char* v
)
663 if (a
->type
== ARRAY_TYPE_STRING
) {
666 for (i
=0; i
<a
->length
; i
++) {
674 /* find the index of a pointer in an array */
675 int array_find_ptr(array_t
*a
, void *v
)
677 if (a
->type
== ARRAY_TYPE_PTR
) {
679 unsigned char* cv
= v
;
680 unsigned char** p
= a
->data
;
681 for (i
=0; i
<a
->length
; i
++) {
689 /* remove a string value from an array */
690 int array_remove_string(array_t
*a
, char* v
)
692 if (a
->type
== ARRAY_TYPE_STRING
) {
695 for (i
=0; i
<a
->length
; i
++) {
696 if (!strcmp(p
[i
],v
)) {
702 for (; i
<a
->length
; i
++) {
710 /* split a string into an array, at a separator character */
711 /* TODO: if strings is non-zero, then don't split within "" or '' */
712 /* TODO: utf8 support */
713 array_t
*array_split(char* str
, char* s
, int strings
)
724 r
= array_create(ARRAY_TYPE_STRING
);
728 for (i
=0; str
[i
]; i
++) {
729 if (!strncmp(str
+i
,s
,l
)) {
731 array_push_string(r
,buff
);
739 array_push_string(r
,buff
);
744 /* join an array into a string, using a glue character */
745 char* array_join(array_t
*a
, char* glue
, int start
)
751 if (a
->type
== ARRAY_TYPE_STRING
) {
753 int gl
= strlen(glue
);
754 for (i
=start
; i
<a
->length
; i
++) {
755 l
+= strlen(((char**)(a
->data
))[i
])+gl
;
760 for (i
=start
; i
<a
->length
; i
++) {
763 strcat(str
,((char**)(a
->data
))[i
]);