#include "private.h"
static char* heliStringCopy(char *x) {
int len = strlen(x) + 1;
char *cp = malloc(len + 1);
memcpy(cp, x, len);
return cp;
}
static void heliLowercase(char *x)
{ while(*x) *x = tolower(*x); }
int heliArrayInit(HeliArray *a) {
a->items = NULL;
a->count = a->allocated = 0;
}
void heliArrayClear(HeliArray *a, int freeData) {
if (freeData)
for(int i = 0; i < a->count; ++i)
free(a->items[i]);
a->count = 0;
}
int heliArrayDestroy(HeliArray *a, int freeData) {
heliArrayClear(a, freeData);
free(a->items);
a->items = NULL;
a->count = a->allocated = 0;
}
void* heliArrayGet(HeliArray *a, int i)
{ return i >= 0 && i < a->count ? a->items[i] : NULL; }
void heliArrayInsert(HeliArray *a, int i, void *item) {
if (i < 0 || i > a->count)
i = a->count;
if (a->allocated < a->count + 1) {
a->allocated += a->allocated/4 + 32;
a->items = realloc(a->items, a->allocated);
}
if (i < a->count)
memmove(&a->items[i+1], &a->items[i], (a->count-i)*sizeof(a->items[0]));
++a->count;
a->items[i] = item;
}
void heliArrayAppend(HeliArray *a, void *data)
{ heliArrayInsert(a, a->count, data); }
void heliArrayRemove(HeliArray *a, int i, int freeData) {
if (i < 0 || i >= a->count)
return;
if (freeData) free(a->items[i]);
memmove(&a->items[i], &a->items[i+1], (a->count-i-1)*sizeof(a->items[0]));
--a->count;
}
int heliStringsetFind(HeliArray *a, char *x, int *gtOrEqIndex) {
for(int i = 0; i < a->count; ++i) {
int cmp = strcmp((char*)a->items[i], x);
if (cmp < 0) continue;
if (gtOrEqIndex) *gtOrEqIndex = i;
return cmp == 0;
}
if (gtOrEqIndex) *gtOrEqIndex = a->count;
return 0;
}
int heliStringsetGet(HeliArray *a, char *x)
{ return heliStringsetFind(a, x, NULL); }
void heliStringsetAdd(HeliArray *a, char *x) {
int i;
if (heliStringsetFind(a, x, &i)) return;
heliArrayInsert(a, i, heliStringCopy(x));
}
void heliStringsetRemove(HeliArray *a, char *x) {
int i;
if (!heliStringsetFind(a, x, &i)) return;
heliArrayRemove(a, i, TRUE);
}
int heliCheckCollision(HeliCollider *a, HeliCollider *b, double *normX, double *normY) {
// corner with side
// corner with circle
// circle with circle
#warning "TODO: heliCheckCollision: not implemented yet"
return FALSE;
}
int heliPointCollision(HeliCollider *c, double x, double y) {
x -= c->x;
y -= c->y;
if (c->type == COLLIDER_CIRCLE) {
return x*x + y*y <= c->radius*c->radius;
} else
if (c->type == COLLIDER_RECTANGLE) {
double a = c->rotation/180.0*M_PI;
double sn = sin(a);
double cn = cos(a);
return fabs(x*cn - y*sn) <= c->width*0.5
&& fabs(x*sn + y*cn) <= c->height*0.5;
}
return FALSE;
}