[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:
parent
2809e5323f
commit
a17b7792f3
15
bin/Makefile
15
bin/Makefile
@ -3,6 +3,7 @@ DEBUG := 1
|
|||||||
#DEBUG_PARANOID := 1
|
#DEBUG_PARANOID := 1
|
||||||
|
|
||||||
OS := LINUX
|
OS := LINUX
|
||||||
|
#OS := FREEBSD
|
||||||
#OS := WIN32
|
#OS := WIN32
|
||||||
#OS := MACOS
|
#OS := MACOS
|
||||||
export OS
|
export OS
|
||||||
@ -36,10 +37,17 @@ CFLAGS += -DDATA_DEF=$(DATA_DEF)
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# OS Stuff.
|
# OS Stuff.
|
||||||
|
|
||||||
|
# Linux Stuff.
|
||||||
ifeq ($(OS),LINUX)
|
ifeq ($(OS),LINUX)
|
||||||
CFLAGS += -D_POSIX_SOURCE
|
CFLAGS += -D_POSIX_SOURCE
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# FreeBSD stuff.
|
||||||
|
ifeq ($(OS),FREEBSD)
|
||||||
|
CFLAGS += -D_POSIX_SOURCE -D__BSD_VISIBLE
|
||||||
|
endif
|
||||||
|
|
||||||
# Debug stuff.
|
# Debug stuff.
|
||||||
ifdef DEBUG
|
ifdef DEBUG
|
||||||
CFLAGS += -W -Wall -Wextra -Wunused -Wshadow -Wpointer-arith -Wmissing-prototypes \
|
CFLAGS += -W -Wall -Wextra -Wunused -Wshadow -Wpointer-arith -Wmissing-prototypes \
|
||||||
@ -51,10 +59,17 @@ CFLAGS += -DDEBUG_PARANOID
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
# Handle OS Debug stuff here.
|
# Handle OS Debug stuff here.
|
||||||
|
|
||||||
|
# Linux Stuff.
|
||||||
ifeq ($(OS), LINUX)
|
ifeq ($(OS), LINUX)
|
||||||
LDFLAGS += -rdynamic
|
LDFLAGS += -rdynamic
|
||||||
endif # Linux.
|
endif # Linux.
|
||||||
|
|
||||||
|
# FreeBSD stuff.
|
||||||
|
ifeq ($(OS), FREEBSD)
|
||||||
|
LDFLAGS += -rdynamic
|
||||||
|
endif
|
||||||
|
|
||||||
else # DEBUG
|
else # DEBUG
|
||||||
CFLAGS += -O2 -funroll-loops -pipe -std=c99
|
CFLAGS += -O2 -funroll-loops -pipe -std=c99
|
||||||
endif
|
endif
|
||||||
|
@ -729,12 +729,10 @@ static const char* debug_sigCodeToStr(int sig, int sig_code) {
|
|||||||
case SEGV_ACCERR: return "SIGEGV (invalid permissions for mapped object)";
|
case SEGV_ACCERR: return "SIGEGV (invalid permissions for mapped object)";
|
||||||
default: return "SIGSEGV";
|
default: return "SIGSEGV";
|
||||||
}
|
}
|
||||||
else if(sig == SIGTRAP)
|
else if(sig == SIGABRT)
|
||||||
switch(sig_code) {
|
switch(sig_code) {
|
||||||
case SI_USER: return "SIGTRAP (raised by program)";
|
case SI_USER: return "SIGABRT (raised by program)";
|
||||||
case TRAP_BRKPT: return "SIGTRAP (process breakpoint)";
|
default: return "SIGABRT";
|
||||||
case TRAP_TRACE: return "SIGTRAP (process trace trap)";
|
|
||||||
default: return "SIGTRAP";
|
|
||||||
}
|
}
|
||||||
/* No suitable code found. */
|
/* No suitable code found. */
|
||||||
return strsignal(sig);
|
return strsignal(sig);
|
||||||
@ -786,9 +784,9 @@ static void debug_sigInit(void) {
|
|||||||
sigaction(SIGFPE, &sa, &so);
|
sigaction(SIGFPE, &sa, &so);
|
||||||
if(so.sa_handler == SIG_IGN)
|
if(so.sa_handler == SIG_IGN)
|
||||||
DEBUG("Unable to set up SIGFPE signal handler.");
|
DEBUG("Unable to set up SIGFPE signal handler.");
|
||||||
sigaction(SIGTRAP, &sa, &so);
|
sigaction(SIGABRT, &sa, &so);
|
||||||
if(so.sa_handler == SIG_IGN)
|
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) */
|
#endif /* #if defined(LINUX) && !defined(NODEBUG) */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
src/lfile.c
10
src/lfile.c
@ -9,7 +9,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#ifdef LINUX
|
#if defined(LINUX) || defined(FREEBSD)
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -33,7 +33,7 @@ char* lfile_basePath(void) {
|
|||||||
char* home;
|
char* home;
|
||||||
|
|
||||||
if(lephisto_base[0] == '\0') {
|
if(lephisto_base[0] == '\0') {
|
||||||
#ifdef LINUX
|
#if defined(LINUX) || defined(FREEBSD)
|
||||||
home = getenv("HOME");
|
home = getenv("HOME");
|
||||||
snprintf(lephisto_base, PATH_MAX, "%s/.lephisto/", home);
|
snprintf(lephisto_base, PATH_MAX, "%s/.lephisto/", home);
|
||||||
#else
|
#else
|
||||||
@ -71,7 +71,7 @@ int lfile_dirMakeExist(const char* path, ...) {
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LINUX
|
#if defined(LINUX) || defined(FREEBSD)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
stat(file, &buf);
|
stat(file, &buf);
|
||||||
@ -105,7 +105,7 @@ int lfile_fileExists(const char* path, ...) {
|
|||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LINUX
|
#if defined(LINUX) || defined(FREEBSD)
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
|
|
||||||
if(stat(file, &buf)==0) /* Stat worked, file must exist. */
|
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);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LINUX
|
#if defined(LINUX) || defined(FREEBSD)
|
||||||
int i, j, k, n;
|
int i, j, k, n;
|
||||||
DIR* d;
|
DIR* d;
|
||||||
struct dirent *dir;
|
struct dirent *dir;
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
|
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
|
||||||
#ifdef DEBUG_PARANOID /* Will cause WARN's to blow up. */
|
#ifdef DEBUG_PARANOID /* Will cause WARN's to blow up. */
|
||||||
#define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args), \
|
#define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args), \
|
||||||
raise(SIGRAP))
|
abort())
|
||||||
#else
|
#else
|
||||||
#define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args))
|
#define WARN(str, args...)(fprintf(stderr, "Warning: [%s] "str"\n", __func__, ## args))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: [%s] "str"\n", \
|
#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
|
#ifdef DEBUG
|
||||||
# undef DEBUG
|
# undef DEBUG
|
||||||
|
123
src/physics.c
123
src/physics.c
@ -96,37 +96,46 @@ double vect_dot(Vec2* a, Vec2* b) {
|
|||||||
return a->x * b->x + a->y * b->y;
|
return a->x * b->x + a->y * b->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ================ */
|
/* ================
|
||||||
/* SOLID! */
|
* SOLID!
|
||||||
/* ================ */
|
* ================
|
||||||
|
*/
|
||||||
|
|
||||||
/* ==Update method.======================================== */
|
/* ==Update method.========================================
|
||||||
/* d^2 x(t) / d t^2 = a, a = constant (acceleration) */
|
* @fn static void simple_update(Solid* obj, const double dt)
|
||||||
/* x'(0) = v, x(0) = p */
|
*
|
||||||
/* */
|
* @brief Update the solids position using a euler integration.
|
||||||
/* d x(t) / d t = a*t + v, v = constant (initial velocity) */
|
*
|
||||||
/* x(t) = a/2*t + v*t + p, p = constant (initial position) */
|
* Simple method.
|
||||||
/* */
|
*
|
||||||
/* Since dt isn't actually differential this gives us an */
|
* d^2 x(t) / d t^2 = a, a = constant (acceleration)
|
||||||
/* error, so watch out with big values for dt. */
|
* x'(0) = v, x(0) = p
|
||||||
/* ======================================================== */
|
*
|
||||||
#if 0 /* Simply commenting this out to avoid silly warnings. */
|
* 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) {
|
static void simple_update(Solid* obj, const double dt) {
|
||||||
|
double px, py, vx, vy, ax, ay;
|
||||||
|
|
||||||
/* Make sure angle doesn't flip. */
|
/* 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 > 2*M_PI) obj->dir -= 2*M_PI;
|
||||||
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
if(obj->dir < 0.) obj->dir += 2*M_PI;
|
||||||
|
|
||||||
double px, py, vx, vy;
|
/* Initial positions. */
|
||||||
px = obj->pos->x;
|
px = obj->pos.x;
|
||||||
py = obj->pos->y;
|
py = obj->pos.y;
|
||||||
vx = obj->vel->x;
|
vx = obj->vel.x;
|
||||||
vy = obj->vel->y;
|
vy = obj->vel.y;
|
||||||
|
|
||||||
if(obj->force.mod) { /* Force applied on an object. */
|
if(obj->force.mod) { /* Force applied on an object. */
|
||||||
double ax, ay;
|
ax = obj->force.x /obj->mass;
|
||||||
ax = obj->force->x/obj->mass;
|
ay = obj->force.y /obj->mass;
|
||||||
ay = obj->force->y/obj->mass;
|
|
||||||
|
|
||||||
vx += ax*dt;
|
vx += ax*dt;
|
||||||
vy += ay*dt;
|
vy += ay*dt;
|
||||||
@ -140,26 +149,39 @@ static void simple_update(Solid* obj, const double dt) {
|
|||||||
px += vx*dt;
|
px += vx*dt;
|
||||||
py += vy*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.=============================== */
|
/* ==Runge-Kutta 4th method.===============================
|
||||||
/* d^2 x(t) / d t^2 = a, a = constant(acceleration) */
|
*
|
||||||
/* x'(0) = v, x(0) = p */
|
* @brief Runge-Kutta method of updating a solid based on it's
|
||||||
/* x'' = f(t, x, x') = (x', a) */
|
* acceleration.
|
||||||
/* */
|
*
|
||||||
/* x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4) */
|
* d^2 x(t) / d t^2 = a, a = constant(acceleration)
|
||||||
/* h = (b-a)/2 */
|
* x'(0) = v, x(0) = p
|
||||||
/* k1 = f(t_n, X_n), X_n = (x_n, x'_n) */
|
* x'' = f(t, x, x') = (x', a)
|
||||||
/* k2 = f(t_n + h/2, X_n + h/2*k1) */
|
*
|
||||||
/* k3 = f(t_n + h/2, X_n + h/2*k2) */
|
* x_ {n+1} = x_n + h/6 (k1 + 2*k2 + 3*k3 + k4)
|
||||||
/* k4 = f(t_n + h, X_n + h*k3) */
|
* h = (b-a)/2
|
||||||
/* */
|
* k1 = f(t_n, X_n), X_n = (x_n, x'_n)
|
||||||
/* x_{n+1} = x_n + h/6x'_n + 3*h*a, 4*a) */
|
* 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. */
|
#define RK4_MIN_H 0.01 /* Minimal pass we want. */
|
||||||
static void rk4_update(Solid* obj, const double dt) {
|
static void rk4_update(Solid* obj, const double dt) {
|
||||||
int i, N; /* For iteration and pass calculation. */
|
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;
|
if(obj->dir >= 2.*M_PI) obj->dir -= 2*M_PI;
|
||||||
else if(obj->dir < 0.) 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;
|
N = (dt > RK4_MIN_H) ? (int)(dt/RK4_MIN_H) : 1;
|
||||||
h = dt / (double)N; /* Step. */
|
h = dt / (double)N; /* Step. */
|
||||||
|
|
||||||
|
/* Initial positions and velocity. */
|
||||||
px = obj->pos.x;
|
px = obj->pos.x;
|
||||||
py = obj->pos.y;
|
py = obj->pos.y;
|
||||||
vx = obj->vel.x;
|
vx = obj->vel.x;
|
||||||
@ -212,26 +236,41 @@ static void rk4_update(Solid* obj, const double dt) {
|
|||||||
}
|
}
|
||||||
vect_cset(&obj->pos, px, py);
|
vect_cset(&obj->pos, px, py);
|
||||||
}
|
}
|
||||||
|
#endif /* !defined(FREEBSD) */
|
||||||
|
|
||||||
/* Initialize a new solid. */
|
/* Initialize a new solid. */
|
||||||
void solid_init(Solid* dest, const double mass, const double dir,
|
void solid_init(Solid* dest, const double mass, const double dir,
|
||||||
const Vec2* pos, const Vec2* vel) {
|
const Vec2* pos, const Vec2* vel) {
|
||||||
dest->mass = mass;
|
dest->mass = mass;
|
||||||
|
|
||||||
|
/* Set direction velocity. */
|
||||||
dest->dir_vel = 0.;
|
dest->dir_vel = 0.;
|
||||||
|
|
||||||
vect_cset(&dest->force, 0., 0.);
|
/* Set force. */
|
||||||
|
vectnull(&dest->force);
|
||||||
|
|
||||||
|
/* Set direction. */
|
||||||
dest->dir = dir;
|
dest->dir = dir;
|
||||||
if((dest->dir > 2.*M_PI) || (dest->dir < 0.))
|
if((dest->dir > 2.*M_PI) || (dest->dir < 0.))
|
||||||
dest->dir = fmod(dest->dir, 2*M_PI);
|
dest->dir = fmod(dest->dir, 2*M_PI);
|
||||||
|
|
||||||
|
/* Set velocity. */
|
||||||
if(vel == NULL) vectnull(&dest->vel);
|
if(vel == NULL) vectnull(&dest->vel);
|
||||||
else vectcpy(&dest->vel, vel);
|
else vectcpy(&dest->vel, vel);
|
||||||
|
|
||||||
|
/* Set position. */
|
||||||
if(pos == NULL) vectnull(&dest->pos);
|
if(pos == NULL) vectnull(&dest->pos);
|
||||||
else vectcpy(&dest->pos, 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;
|
dest->update = rk4_update;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create a new solid. */
|
/* Create a new solid. */
|
||||||
|
Loading…
Reference in New Issue
Block a user