[Add] Support for FreeBSD. Had to play around with the physics slightly

as FreeBSD didn't like the optimizations in Runge-Kuta forcing it to
eventually become NaN.
This commit is contained in:
Allanis 2014-04-10 01:07:20 +01:00
parent 2809e5323f
commit a17b7792f3
6 changed files with 109 additions and 57 deletions

View File

@ -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

View File

@ -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) */
}

View File

@ -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;

View File

@ -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

View File

@ -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;
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. */

View File

@ -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