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
++ ) {
194 /* push an int onto an array */
195 int array_push_int(array_t
*a
, uint32_t v
)
198 if (a
->type
== ARRAY_TYPE_STRING
) {
201 return array_push_string(a
,sv
);
202 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
203 return array_push_float(a
,(float)v
);
204 }else if (a
->type
!= ARRAY_TYPE_INT
) {
212 if (a
->size
< a
->length
) {
213 p
= realloc(a
->data
,sizeof(uint32_t)*a
->length
);
227 /* push a float onto an array */
228 int array_push_float(array_t
*a
, float v
)
231 if (a
->type
== ARRAY_TYPE_STRING
) {
234 return array_push_string(a
,sv
);
235 }else if (a
->type
== ARRAY_TYPE_INT
) {
236 return array_push_int(a
,(int)v
);
237 }else if (a
->type
!= ARRAY_TYPE_FLOAT
) {
245 if (a
->size
< a
->length
) {
246 p
= realloc(a
->data
,sizeof(float)*a
->length
);
260 /* push a string onto an array */
261 int array_push_string(array_t
*a
, char* v
)
264 if (a
->type
!= ARRAY_TYPE_STRING
)
271 if (a
->size
< a
->length
) {
272 p
= realloc(a
->data
,sizeof(char*)*a
->length
);
281 p
[a
->length
-1] = strdup(v
);
283 p
[a
->length
-1] = NULL
;
290 /* push a pointer onto an array */
291 int array_push_ptr(array_t
*a
, void *v
)
294 if (a
->type
!= ARRAY_TYPE_PTR
)
301 if (a
->size
< a
->length
) {
302 p
= realloc(a
->data
,sizeof(char*)*a
->length
);
315 /* push a colour onto an array */
316 int array_push_colour(array_t
*a
, colour_t
*c
)
319 r
+= array_push_float(a
,((float)c
->r
)/255.0);
320 r
+= array_push_float(a
,((float)c
->g
)/255.0);
321 r
+= array_push_float(a
,((float)c
->b
)/255.0);
322 r
+= array_push_float(a
,((float)c
->a
)/255.0);
326 /* push a v3_t onto an array */
327 int array_push_v3t(array_t
*a
, v3_t
*v
)
330 r
+= array_push_float(a
,v
->x
);
331 r
+= array_push_float(a
,v
->y
);
332 r
+= array_push_float(a
,v
->z
);
336 /* push a v2_t onto an array */
337 int array_push_v2t(array_t
*a
, v2_t
*v
)
340 r
+= array_push_float(a
,v
->x
);
341 r
+= array_push_float(a
,v
->y
);
345 /* set the value of array index i to an int value */
346 int array_set_int(array_t
*a
, uint32_t v
, int i
)
348 uint32_t *p
= a
->data
;
349 if (a
->type
== ARRAY_TYPE_STRING
) {
352 return array_set_string(a
,sv
,i
);
353 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
354 return array_set_float(a
,(float)v
,i
);
355 }else if (a
->type
!= ARRAY_TYPE_INT
) {
363 p
= realloc(a
->data
,sizeof(uint32_t)*l
);
366 for (k
=a
->length
; k
<l
; k
++) {
381 /* set the value of array index i to a float value */
382 int array_set_float(array_t
*a
, float v
, int i
)
385 if (a
->type
== ARRAY_TYPE_STRING
) {
388 return array_set_string(a
,sv
,i
);
389 }else if (a
->type
== ARRAY_TYPE_INT
) {
390 return array_set_float(a
,(uint32_t)v
,i
);
391 }else if (a
->type
!= ARRAY_TYPE_FLOAT
) {
399 p
= realloc(a
->data
,sizeof(float)*l
);
402 for (k
=a
->length
; k
<l
; k
++) {
416 /* set the value of array index i to a string value */
417 int array_set_string(array_t
*a
, char* v
, int i
)
420 if (a
->type
!= ARRAY_TYPE_STRING
)
427 p
= realloc(a
->data
,sizeof(char*)*l
);
430 for (k
=a
->length
; k
<l
; k
++) {
448 /* set the value of array index i to a ponter value */
449 int array_set_ptr(array_t
*a
, void* v
, int i
)
452 if (a
->type
!= ARRAY_TYPE_PTR
)
459 p
= realloc(a
->data
,sizeof(char*)*l
);
462 for (k
=a
->length
; k
<l
; k
++) {
476 /* pop an int off the top of an array */
477 uint32_t array_pop_int(array_t
*a
)
479 if (a
->type
== ARRAY_TYPE_INT
) {
483 return ((uint32_t*)(a
->data
))[a
->length
];
484 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
485 float v
= array_pop_float(a
);
487 }else if (a
->type
== ARRAY_TYPE_STRING
) {
489 char* s
= array_pop_string(a
);
490 v
= strtol(s
,NULL
,10);
497 /* pop a float off the top of an array */
498 float array_pop_float(array_t
*a
)
500 if (a
->type
== ARRAY_TYPE_FLOAT
) {
504 return ((float*)(a
->data
))[a
->length
];
505 }else if (a
->type
== ARRAY_TYPE_INT
) {
506 uint32_t v
= array_pop_int(a
);
508 }else if (a
->type
== ARRAY_TYPE_STRING
) {
510 char* s
= array_pop_string(a
);
518 /* pop a string off the top of an array */
519 char* array_pop_string(array_t
*a
)
521 if (a
->type
== ARRAY_TYPE_FLOAT
) {
522 float v
= array_pop_float(a
);
528 }else if (a
->type
== ARRAY_TYPE_INT
) {
529 uint32_t v
= array_pop_int(a
);
535 }else if (a
->type
== ARRAY_TYPE_STRING
) {
539 return ((char**)(a
->data
))[a
->length
];
544 /* pop a pointer off the top of an array */
545 void *array_pop_ptr(array_t
*a
)
547 if (a
->type
== ARRAY_TYPE_PTR
&& a
->length
) {
549 return ((char**)(a
->data
))[a
->length
];
554 /* get an int value from an array */
555 uint32_t array_get_int(array_t
*a
, int i
)
557 if (a
->type
== ARRAY_TYPE_INT
) {
560 return ((uint32_t*)(a
->data
))[i
];
561 }else if (a
->type
== ARRAY_TYPE_FLOAT
) {
562 float v
= array_get_float(a
,i
);
564 }else if (a
->type
== ARRAY_TYPE_STRING
) {
566 char* s
= array_get_string(a
,i
);
567 v
= strtol(s
,NULL
,10);
574 /* get a float value from an array */
575 float array_get_float(array_t
*a
, int i
)
577 if (a
->type
== ARRAY_TYPE_FLOAT
) {
580 return ((float*)(a
->data
))[i
];
581 }else if (a
->type
== ARRAY_TYPE_INT
) {
582 uint32_t v
= array_get_int(a
,i
);
584 }else if (a
->type
== ARRAY_TYPE_STRING
) {
586 char* s
= array_get_string(a
,i
);
594 /* get a string value from an array */
595 char* array_get_string(array_t
*a
, int i
)
597 if (a
->type
== ARRAY_TYPE_FLOAT
) {
598 float v
= array_get_float(a
,i
);
602 }else if (a
->type
== ARRAY_TYPE_INT
) {
603 uint32_t v
= array_get_int(a
,i
);
607 }else if (a
->type
== ARRAY_TYPE_STRING
) {
610 return ((char**)(a
->data
))[i
];
615 /* get a pointer from an array */
616 void *array_get_ptr(array_t
*a
, int i
)
618 if (a
->type
== ARRAY_TYPE_PTR
&& a
->length
> i
) {
619 return ((char**)(a
->data
))[i
];
624 /* find the index of an int value in an array */
625 int array_find_int(array_t
*a
, uint32_t v
)
627 if (a
->type
== ARRAY_TYPE_INT
) {
629 uint32_t *p
= a
->data
;
630 for (i
=0; i
<a
->length
; i
++) {
638 /* find the index of a float value in an array */
639 int array_find_float(array_t
*a
, float v
)
641 if (a
->type
== ARRAY_TYPE_FLOAT
) {
644 for (i
=0; i
<a
->length
; i
++) {
652 /* find the index of a string value in an array */
653 int array_find_string(array_t
*a
, char* v
)
655 if (a
->type
== ARRAY_TYPE_STRING
) {
658 for (i
=0; i
<a
->length
; i
++) {
666 /* find the index of a pointer in an array */
667 int array_find_ptr(array_t
*a
, void *v
)
669 if (a
->type
== ARRAY_TYPE_PTR
) {
671 unsigned char* cv
= v
;
672 unsigned char** p
= a
->data
;
673 for (i
=0; i
<a
->length
; i
++) {
681 /* remove a string value from an array */
682 int array_remove_string(array_t
*a
, char* v
)
684 if (a
->type
== ARRAY_TYPE_STRING
) {
687 for (i
=0; i
<a
->length
; i
++) {
688 if (!strcmp(p
[i
],v
)) {
694 for (; i
<a
->length
; i
++) {
702 /* split a string into an array, at a separator character */
703 /* TODO: if strings is non-zero, then don't split within "" or '' */
704 /* TODO: utf8 support */
705 array_t
*array_split(char* str
, char* s
, int strings
)
716 r
= array_create(ARRAY_TYPE_STRING
);
720 for (i
=0; str
[i
]; i
++) {
721 if (!strncmp(str
+i
,s
,l
)) {
723 array_push_string(r
,buff
);
731 array_push_string(r
,buff
);
736 /* join an array into a string, using a glue character */
737 char* array_join(array_t
*a
, char* glue
, int start
)
743 if (a
->type
== ARRAY_TYPE_STRING
) {
745 int gl
= strlen(glue
);
746 for (i
=start
; i
<a
->length
; i
++) {
747 l
+= strlen(((char**)(a
->data
))[i
])+gl
;
752 for (i
=start
; i
<a
->length
; i
++) {
755 strcat(str
,((char**)(a
->data
))[i
]);