diff --git a/bin/Makefile b/bin/Makefile index 375e60a..ef3679f 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -3,6 +3,7 @@ DEBUG := 1 #DEBUG_PARANOID := 1 OS := LINUX +#OS := FREEBSD #OS := WIN32 #OS := MACOS export OS @@ -36,10 +37,17 @@ CFLAGS += -DDATA_DEF=$(DATA_DEF) endif # OS Stuff. + +# Linux Stuff. ifeq ($(OS),LINUX) CFLAGS += -D_POSIX_SOURCE endif +# FreeBSD stuff. +ifeq ($(OS),FREEBSD) + CFLAGS += -D_POSIX_SOURCE -D__BSD_VISIBLE +endif + # Debug stuff. ifdef DEBUG CFLAGS += -W -Wall -Wextra -Wunused -Wshadow -Wpointer-arith -Wmissing-prototypes \ @@ -51,10 +59,17 @@ CFLAGS += -DDEBUG_PARANOID endif # Handle OS Debug stuff here. + +# Linux Stuff. ifeq ($(OS), LINUX) LDFLAGS += -rdynamic endif # Linux. +# FreeBSD stuff. +ifeq ($(OS), FREEBSD) + LDFLAGS += -rdynamic +endif + else # DEBUG CFLAGS += -O2 -funroll-loops -pipe -std=c99 endif diff --git a/src/lephisto.c b/src/lephisto.c index 8c44848..c74eb10 100644 --- a/src/lephisto.c +++ b/src/lephisto.c @@ -729,12 +729,10 @@ static const char* debug_sigCodeToStr(int sig, int sig_code) { case SEGV_ACCERR: return "SIGEGV (invalid permissions for mapped object)"; default: return "SIGSEGV"; } - else if(sig == SIGTRAP) + else if(sig == SIGABRT) switch(sig_code) { - case SI_USER: return "SIGTRAP (raised by program)"; - case TRAP_BRKPT: return "SIGTRAP (process breakpoint)"; - case TRAP_TRACE: return "SIGTRAP (process trace trap)"; - default: return "SIGTRAP"; + case SI_USER: return "SIGABRT (raised by program)"; + default: return "SIGABRT"; } /* No suitable code found. */ return strsignal(sig); @@ -786,9 +784,9 @@ static void debug_sigInit(void) { sigaction(SIGFPE, &sa, &so); if(so.sa_handler == SIG_IGN) DEBUG("Unable to set up SIGFPE signal handler."); - sigaction(SIGTRAP, &sa, &so); + sigaction(SIGABRT, &sa, &so); if(so.sa_handler == SIG_IGN) - DEBUG("Unable to get set up SIGTRAP signal handler."); + DEBUG("Unable to get set up SIGABRT signal handler."); #endif /* #if defined(LINUX) && !defined(NODEBUG) */ } diff --git a/src/lfile.c b/src/lfile.c index 5c1910e..47ef8f0 100644 --- a/src/lfile.c +++ b/src/lfile.c @@ -9,7 +9,7 @@ #include <stdio.h> #include <string.h> #include <stdarg.h> -#ifdef LINUX +#if defined(LINUX) || defined(FREEBSD) #include <stdlib.h> #include <sys/types.h> #include <sys/stat.h> @@ -33,7 +33,7 @@ char* lfile_basePath(void) { char* home; if(lephisto_base[0] == '\0') { -#ifdef LINUX +#if defined(LINUX) || defined(FREEBSD) home = getenv("HOME"); snprintf(lephisto_base, PATH_MAX, "%s/.lephisto/", home); #else @@ -71,7 +71,7 @@ int lfile_dirMakeExist(const char* path, ...) { va_end(ap); } -#ifdef LINUX +#if defined(LINUX) || defined(FREEBSD) struct stat buf; stat(file, &buf); @@ -105,7 +105,7 @@ int lfile_fileExists(const char* path, ...) { va_end(ap); } -#ifdef LINUX +#if defined(LINUX) || defined(FREEBSD) struct stat buf; if(stat(file, &buf)==0) /* Stat worked, file must exist. */ @@ -140,7 +140,7 @@ char** lfile_readDir(int* lfiles, const char* path, ...) { va_end(ap); } -#ifdef LINUX +#if defined(LINUX) || defined(FREEBSD) int i, j, k, n; DIR* d; struct dirent *dir; diff --git a/src/log.h b/src/log.h index 7fd9b68..265c3a3 100644 --- a/src/log.h +++ b/src/log.h @@ -5,13 +5,13 @@ #define LOG(str, args...)(fprintf(stdout, str"\n", ## args)) #ifdef DEBUG_PARANOID /* Will cause WARN's to blow up. */ #define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args), \ - raise(SIGRAP)) + abort()) #else #define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args)) #endif #define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: [%s] "str"\n", \ - __FILE__, __LINE__, __func__, ## args), raise(SIGTRAP)) + __FILE__, __LINE__, __func__, ## args), abort()) #ifdef DEBUG # undef DEBUG diff --git a/src/physics.c b/src/physics.c index c6ee382..c346438 100644 --- a/src/physics.c +++ b/src/physics.c @@ -96,37 +96,46 @@ double vect_dot(Vec2* a, Vec2* b) { return a->x * b->x + a->y * b->y; } -/* ================ */ -/* SOLID! */ -/* ================ */ +/* ================ + * SOLID! + * ================ + */ -/* ==Update method.======================================== */ -/* d^2 x(t) / d t^2 = a, a = constant (acceleration) */ -/* x'(0) = v, x(0) = p */ -/* */ -/* d x(t) / d t = a*t + v, v = constant (initial velocity) */ -/* x(t) = a/2*t + v*t + p, p = constant (initial position) */ -/* */ -/* Since dt isn't actually differential this gives us an */ -/* error, so watch out with big values for dt. */ -/* ======================================================== */ -#if 0 /* Simply commenting this out to avoid silly warnings. */ +/* ==Update method.======================================== + * @fn static void simple_update(Solid* obj, const double dt) + * + * @brief Update the solids position using a euler integration. + * + * Simple method. + * + * d^2 x(t) / d t^2 = a, a = constant (acceleration) + * x'(0) = v, x(0) = p + * + * d x(t) / d t = a*t + v, v = constant (initial velocity) + * x(t) = a/2*t + v*t + p, p = constant (initial position) + * + * Since dt isn't actually differential this gives us an + * error, so watch out with big values for dt. + * ======================================================== + */ +#if defined(FREEBSD) static void simple_update(Solid* obj, const double dt) { + double px, py, vx, vy, ax, ay; + /* Make sure angle doesn't flip. */ - obj->dir += M_PI/360.*obj->dir_vel*dt; - if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI; + obj->dir += M_PI/180.*obj->dir_vel*dt; + if(obj->dir > 2*M_PI) obj->dir -= 2*M_PI; if(obj->dir < 0.) obj->dir += 2*M_PI; - double px, py, vx, vy; - px = obj->pos->x; - py = obj->pos->y; - vx = obj->vel->x; - vy = obj->vel->y; + /* Initial positions. */ + px = obj->pos.x; + py = obj->pos.y; + vx = obj->vel.x; + vy = obj->vel.y; if(obj->force.mod) { /* Force applied on an object. */ - double ax, ay; - ax = obj->force->x/obj->mass; - ay = obj->force->y/obj->mass; + ax = obj->force.x /obj->mass; + ay = obj->force.y /obj->mass; vx += ax*dt; vy += ay*dt; @@ -140,26 +149,39 @@ static void simple_update(Solid* obj, const double dt) { px += vx*dt; py += vy*dt; } - obj->pos.mod = MOD(px, py); - obj->pos.angle = ANGLE(px, py); + + /* Update position and velocity. */ + vect_cset(&obj->vel, vx, vy); + vect_cset(&obj->pos, px, py); } -#endif +#endif /* defined(FREEBSD) */ -/* ==Runge-Kutta 4th method.=============================== */ -/* d^2 x(t) / d t^2 = a, a = constant(acceleration) */ -/* x'(0) = v, x(0) = p */ -/* x'' = f(t, x, x') = (x', a) */ -/* */ -/* x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4) */ -/* h = (b-a)/2 */ -/* k1 = f(t_n, X_n), X_n = (x_n, x'_n) */ -/* k2 = f(t_n + h/2, X_n + h/2*k1) */ -/* k3 = f(t_n + h/2, X_n + h/2*k2) */ -/* k4 = f(t_n + h, X_n + h*k3) */ -/* */ -/* x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a) */ -/* ======================================================== */ +/* ==Runge-Kutta 4th method.=============================== + * + * @brief Runge-Kutta method of updating a solid based on it's + * acceleration. + * + * d^2 x(t) / d t^2 = a, a = constant(acceleration) + * x'(0) = v, x(0) = p + * x'' = f(t, x, x') = (x', a) + * + * x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4) + * h = (b-a)/2 + * k1 = f(t_n, X_n), X_n = (x_n, x'_n) + * k2 = f(t_n + h/2, X_n + h/2*k1) + * k3 = f(t_n + h/2, X_n + h/2*k2) + * k4 = f(t_n + h, X_n + h*k3) + * + * x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a) + * + * Main advantage comes thanks to the fact that Lephisto is on + * a 2D plane. Therefore RK chops it up in chunks and actually + * creates a tiny curve instead of aproximating the curve for + * a tiny staight line. + * ======================================================== + */ +#if !defined(FREEBSD) #define RK4_MIN_H 0.01 /* Minimal pass we want. */ static void rk4_update(Solid* obj, const double dt) { int i, N; /* For iteration and pass calculation. */ @@ -170,9 +192,11 @@ static void rk4_update(Solid* obj, const double dt) { if(obj->dir >= 2.*M_PI) obj->dir -= 2*M_PI; else if(obj->dir < 0.) obj->dir += 2*M_PI; + /* Initial RK parameters. */ N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1; h = dt / (double)N; /* Step. */ + /* Initial positions and velocity. */ px = obj->pos.x; py = obj->pos.y; vx = obj->vel.x; @@ -212,26 +236,41 @@ static void rk4_update(Solid* obj, const double dt) { } vect_cset(&obj->pos, px, py); } +#endif /* !defined(FREEBSD) */ /* Initialize a new solid. */ void solid_init(Solid* dest, const double mass, const double dir, const Vec2* pos, const Vec2* vel) { dest->mass = mass; + /* Set direction velocity. */ dest->dir_vel = 0.; - vect_cset(&dest->force, 0., 0.); + /* Set force. */ + vectnull(&dest->force); + + /* Set direction. */ dest->dir = dir; if((dest->dir > 2.*M_PI) || (dest->dir < 0.)) dest->dir = fmod(dest->dir, 2*M_PI); + /* Set velocity. */ if(vel == NULL) vectnull(&dest->vel); else vectcpy(&dest->vel, vel); + /* Set position. */ if(pos == NULL) vectnull(&dest->pos); else vectcpy(&dest->pos, pos); +/* + * FreeBSD seems to have a bug with optimizations in rk4_update causing it to + * eventually become NaN. + */ +#if defined(FREEBSD) + dest->update = simple_update; +#else dest->update = rk4_update; +#endif } /* Create a new solid. */ diff --git a/src/rng.c b/src/rng.c index 64dac45..8f3a74a 100644 --- a/src/rng.c +++ b/src/rng.c @@ -11,7 +11,7 @@ #include <unistd.h> #include <time.h> #include <errno.h> -#ifdef LINUX +#if defined _POSIX_SOURCE #include <sys/time.h> #include <fcntl.h> #endif