diff options
Diffstat (limited to 'common.h')
-rw-r--r-- | common.h | 416 |
1 files changed, 416 insertions, 0 deletions
diff --git a/common.h b/common.h new file mode 100644 index 0000000..a9261b8 --- /dev/null +++ b/common.h @@ -0,0 +1,416 @@ +/* +======================================================================= +This file is part of Redman's RT. + +Redman's RT is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Redman's RT is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Redman's RT. If not, see <http://www.gnu.org/licenses/>. +======================================================================= +*/ + +#ifndef __COMMON_HEADER +#define __COMMON_HEADER + +#include <stdio.h> +#include <stdlib.h> +#include <stdarg.h> +#include <string.h> +#include <math.h> +#include <ctype.h> +#include <SDL2/SDL.h> +#include <SDL2/SDL_image.h> + +//TODO: figure out the platform here +#define PLATFORM_POSIX +///////////////// + +#define PROGRAM_NAME "RRT" +//#define PROGRAM_VERSION "pre-alpha" +//#define PROGRAM_FULLNAME PROGRAM_NAME " (" PROGRAM_VERSION ")" +#define PROGRAM_FULLNAME PROGRAM_NAME + +typedef enum +{ + false, + true +} bool_t; + +#define Swap(T,a,b) {T ___t;___t=(a);(a)=(b);(b)=___t;} + + /* Scalar utilities */ + +typedef float vec_t; + +#define V1Min(a,b) ((a)<(b)?(a):(b)) +#define V1Max(a,b) ((a)>(b)?(a):(b)) +#define V1Clamp(n,a,b) ((n)<(a)?(a):(n)>(b)?(b):(n)) +#define V1Epscmp(a,b,e) (fabs((a)-(b))<e) +#define V1Lerp(f,a,b) ((a)+((b)-(a))*(f)) + + /* Vector utilities */ + +typedef vec_t vec2_t[2]; +typedef vec_t vec3_t[3]; +typedef vec_t vec4_t[4]; + +#define V2Set(R,x,y) ((R)[0]=(x),\ + (R)[1]=(y)) +#define V3Set(R,x,y,z) ((R)[0]=(x),\ + (R)[1]=(y),\ + (R)[2]=(z)) +#define V4Set(R,x,y,z,w) ((R)[0]=(x),\ + (R)[1]=(y),\ + (R)[2]=(z),\ + (R)[3]=(w)) + +#define V2Copy(R,A) ((R)[0]=(A)[0],\ + (R)[1]=(A)[1]) +#define V3Copy(R,A) ((R)[0]=(A)[0],\ + (R)[1]=(A)[1],\ + (R)[2]=(A)[2]) +#define V4Copy(R,A) ((R)[0]=(A)[0],\ + (R)[1]=(A)[1],\ + (R)[2]=(A)[2],\ + (R)[3]=(A)[3]) + +#define V2Add(R,A,B) ((R)[0]=(A)[0]+(B)[0],\ + (R)[1]=(A)[1]+(B)[1]) +#define V3Add(R,A,B) ((R)[0]=(A)[0]+(B)[0],\ + (R)[1]=(A)[1]+(B)[1],\ + (R)[2]=(A)[2]+(B)[2]) +#define V4Add(R,A,B) ((R)[0]=(A)[0]+(B)[0],\ + (R)[1]=(A)[1]+(B)[1],\ + (R)[2]=(A)[2]+(B)[2],\ + (R)[3]=(A)[3]+(B)[3]) + +#define V2Sub(R,A,B) ((R)[0]=(A)[0]-(B)[0],\ + (R)[1]=(A)[1]-(B)[1]) +#define V3Sub(R,A,B) ((R)[0]=(A)[0]-(B)[0],\ + (R)[1]=(A)[1]-(B)[1],\ + (R)[2]=(A)[2]-(B)[2]) +#define V4Sub(R,A,B) ((R)[0]=(A)[0]-(B)[0],\ + (R)[1]=(A)[1]-(B)[1],\ + (R)[2]=(A)[2]-(B)[2],\ + (R)[3]=(A)[3]-(B)[3]) + +#define V2Mul(R,A,s) ((R)[0]=(A)[0]*(s),\ + (R)[1]=(A)[1]*(s)) +#define V3Mul(R,A,s) ((R)[0]=(A)[0]*(s),\ + (R)[1]=(A)[1]*(s),\ + (R)[2]=(A)[2]*(s)) +#define V4Mul(R,A,s) ((R)[0]=(A)[0]*(s),\ + (R)[1]=(A)[1]*(s),\ + (R)[2]=(A)[2]*(s),\ + (R)[3]=(A)[3]*(s)) + + +#define V2Mul2(R,A,s1,B,s2) ((R)[0]=(A)[0]*(s1)+(B)[0]*(s2),\ + (R)[1]=(A)[1]*(s1)+(B)[1]*(s2)) +#define V3Mul2(R,A,s1,B,s2) ((R)[0]=(A)[0]*(s1)+(B)[0]*(s2),\ + (R)[1]=(A)[1]*(s1)+(B)[1]*(s2),\ + (R)[2]=(A)[2]*(s1)+(B)[2]*(s2)) +#define V4Mul2(R,A,s1,B,s2) ((R)[0]=(A)[0]*(s1)+(B)[0]*(s2),\ + (R)[1]=(A)[1]*(s1)+(B)[1]*(s2),\ + (R)[2]=(A)[2]*(s1)+(B)[2]*(s2),\ + (R)[3]=(A)[3]*(s1)+(B)[3]*(s2)) + +#define V2VMul(R,A,B) ((R)[0]=(A)[0]*(B)[0],\ + (R)[1]=(A)[1]*(B)[1]) +#define V3VMul(R,A,B) ((R)[0]=(A)[0]*(B)[0],\ + (R)[1]=(A)[1]*(B)[1],\ + (R)[2]=(A)[2]*(B)[2]) +#define V4VMul(R,A,B) ((R)[0]=(A)[0]*(B)[0],\ + (R)[1]=(A)[1]*(B)[1],\ + (R)[2]=(A)[2]*(B)[2],\ + (R)[3]=(A)[3]*(B)[3]) + +#define V2MA(R,A,s,B) ((R)[0]=(A)[0]+(s)*(B)[0],\ + (R)[1]=(A)[1]+(s)*(B)[1]) +#define V3MA(R,A,s,B) ((R)[0]=(A)[0]+(s)*(B)[0],\ + (R)[1]=(A)[1]+(s)*(B)[1],\ + (R)[2]=(A)[2]+(s)*(B)[2]) +#define V4MA(R,A,s,B) ((R)[0]=(A)[0]+(s)*(B)[0],\ + (R)[1]=(A)[1]+(s)*(B)[1],\ + (R)[2]=(A)[2]+(s)*(B)[2],\ + (R)[3]=(A)[3]+(s)*(B)[3]) + +#define V2VMA(R,A,S,B) ((R)[0]=(A)[0]+(S)[0]*(B)[0],\ + (R)[1]=(A)[1]+(S)[1]*(B)[1]) +#define V3VMA(R,A,S,B) ((R)[0]=(A)[0]+(S)[0]*(B)[0],\ + (R)[1]=(A)[1]+(S)[1]*(B)[1],\ + (R)[2]=(A)[2]+(S)[2]*(B)[2]) +#define V4VMA(R,A,S,B) ((R)[0]=(A)[0]+(S)[0]*(B)[0],\ + (R)[1]=(A)[1]+(S)[1]*(B)[1],\ + (R)[2]=(A)[2]+(S)[2]*(B)[2],\ + (R)[3]=(A)[3]+(S)[3]*(B)[3]) + +#define V2MA2(R,A,s1,V1,s2,V2) ((R)[0]=(A)[0]+(s1)*(V1)[0]+(s2)*(V2)[0],\ + (R)[1]=(A)[1]+(s1)*(V1)[1]+(s2)*(V2)[1]) +#define V3MA2(R,A,s1,V1,s2,V2) ((R)[0]=(A)[0]+(s1)*(V1)[0]+(s2)*(V2)[0],\ + (R)[1]=(A)[1]+(s1)*(V1)[1]+(s2)*(V2)[1],\ + (R)[2]=(A)[2]+(s1)*(V1)[2]+(s2)*(V2)[2]) +#define V4MA2(R,A,s1,V1,s2,V2) ((R)[0]=(A)[0]+(s1)*(V1)[0]+(s2)*(V2)[0],\ + (R)[1]=(A)[1]+(s1)*(V1)[1]+(s2)*(V2)[1],\ + (R)[2]=(A)[2]+(s1)*(V1)[2]+(s2)*(V2)[2],\ + (R)[3]=(A)[3]+(s1)*(V1)[3]+(s2)*(V2)[3]) + +#define V2Lerp(R,s,A,B) ((R)[0]=V1Lerp(s,(A)[0],(B)[0]),\ + (R)[1]=V1Lerp(s,(A)[1],(B)[1])) +#define V3Lerp(R,s,A,B) ((R)[0]=V1Lerp(s,(A)[0],(B)[0]),\ + (R)[1]=V1Lerp(s,(A)[1],(B)[1]),\ + (R)[2]=V1Lerp(s,(A)[2],(B)[2])) +#define V4Lerp(R,s,A,B) ((R)[0]=V1Lerp(s,(A)[0],(B)[0]),\ + (R)[1]=V1Lerp(s,(A)[1],(B)[1]),\ + (R)[2]=V1Lerp(s,(A)[2],(B)[2]),\ + (R)[3]=V1Lerp(s,(A)[3],(B)[3])) + +#define V2Dot(A,B) ((A)[0]*(B)[0]+\ + (A)[1]*(B)[1]) +#define V3Dot(A,B) ((A)[0]*(B)[0]+\ + (A)[1]*(B)[1]+\ + (A)[2]*(B)[2]) +#define V4Dot(A,B) ((A)[0]*(B)[0]+\ + (A)[1]*(B)[1]+\ + (A)[2]*(B)[2]+\ + (A)[3]*(B)[3]) + +#define V3Cross(R,A,B) ((R)[0]=(A)[1]*(B)[2]-(A)[2]*(B)[1],\ + (R)[1]=(A)[2]*(B)[0]-(A)[0]*(B)[2],\ + (R)[2]=(A)[0]*(B)[1]-(A)[1]*(B)[0]) + +#define V2Length(A) sqrt((A)[0]*(A)[0]+\ + (A)[1]*(A)[1]) +#define V3Length(A) sqrt((A)[0]*(A)[0]+\ + (A)[1]*(A)[1]+\ + (A)[2]*(A)[2]) +#define V4Length(A) sqrt((A)[0]*(A)[0]+\ + (A)[1]*(A)[1]+\ + (A)[2]*(A)[2]+\ + (A)[3]*(A)[3]) + +//note: using the same vector for input and output will produce +// bogus results +#define V2ZSq(R,A) ((R)[0]=(A)[0]*(A)[0]-(A)[1]*(A)[1], \ + (R)[1]=2.0*(A)[0]*(A)[1]); + + /* Matrix utilities */ + +typedef vec_t m3_t[9]; + +#define M3Set(r,a,b,c,d,e,f,g,h,i) \ +((r)[0]=(a),(r)[1]=(b),(r)[2]=(c),\ + (r)[3]=(d),(r)[4]=(e),(r)[5]=(f),\ + (r)[6]=(g),(r)[7]=(h),(r)[8]=(i)) + +#define M3Copy(r,a) \ +((r)[0]=(a)[0],(r)[1]=(a)[1],(r)[2]=(a)[2],\ + (r)[3]=(a)[3],(r)[4]=(a)[4],(r)[5]=(a)[5],\ + (r)[6]=(a)[6],(r)[7]=(a)[7],(r)[8]=(a)[8]) + +#define M3RotX(r,a) \ +M3Set(r,1.0,0.0,0.0,0.0,cos(a),-sin(a),0.0,sin(a),cos(a)) +#define M3RotY(r,a) \ +M3Set(r,cos(a),0.0,sin(a),0.0,1.0,0.0,-sin(a),0.0,cos(a)) +#define M3RotZ(r,a) \ +M3Set(r,cos(a),-sin(a),0.0,sin(a),cos(a),0.0,0.0,0.0,1.0) + +#define M3Product(r,a,b) \ +((r)[0]=(a)[2]*(b)[6]+(a)[1]*(b)[3]+(a)[0]*(b)[0],\ + (r)[1]=(a)[2]*(b)[7]+(a)[1]*(b)[4]+(a)[0]*(b)[1],\ + (r)[2]=(a)[2]*(b)[8]+(a)[1]*(b)[5]+(a)[0]*(b)[2],\ + (r)[3]=(a)[5]*(b)[6]+(a)[4]*(b)[3]+(a)[3]*(b)[0],\ + (r)[4]=(a)[5]*(b)[7]+(a)[4]*(b)[4]+(a)[3]*(b)[1],\ + (r)[5]=(a)[5]*(b)[8]+(a)[4]*(b)[5]+(a)[3]*(b)[2],\ + (r)[6]=(a)[8]*(b)[6]+(a)[7]*(b)[3]+(a)[6]*(b)[0],\ + (r)[7]=(a)[8]*(b)[7]+(a)[7]*(b)[4]+(a)[6]*(b)[1],\ + (r)[8]=(a)[8]*(b)[8]+(a)[7]*(b)[5]+(a)[6]*(b)[2]) + + /* Color utilities */ + +#define C_RED 0 +#define C_GREEN 1 +#define C_BLUE 2 + +#define C_HUE 0 +#define C_SATURATION 1 +#define C_VALUE 2 + +#define C_ALPHA 3 + + /* u_misc */ + +#define VA_MAX 2048 +#define VA_BUFFERS 6 + + /* u_world */ + +typedef uint8_t W_blockdata_t; + +enum +{ + BLOCK_NONE, + BLOCK_GROUND, + BLOCK_CONCRETE, + BLOCK_METAL, + BLOCK_MIRROR, + BLOCK_LIGHT, + BLOCK_BANNER +}; + +typedef struct W_otnode_s W_otnode_t; +struct W_otnode_s +{ + W_blockdata_t data; + vec3_t aabb[ 2 ]; + + int i; + W_otnode_t *p; + W_otnode_t *n[ 8 ]; +}; + +typedef struct +{ + bool_t inuse; + bool_t sun; + bool_t flashlight; + bool_t flashlight_enabled; + + uint64_t timestamp; + + vec3_t origin; + vec3_t direction; + vec3_t velocity; + vec3_t light; +} W_light_t; + +#define MAX_DLIGHTS 16 + +typedef struct +{ + W_otnode_t *otroot; + W_light_t lights[ MAX_DLIGHTS ]; + + vec3_t saved_origin; + vec3_t saved_angles; +} W_world_t; + + /* u_ray */ + + +typedef struct +{ + vec3_t org; + vec_t limit; + vec3_t dir; + + int dsign[ 3 ]; // 0 or 1 + int dsign2[ 3 ]; // -1 or +1 + vec3_t dinv; + int dinvsign[ 3 ]; // 0 or 1 + int otorder[ 8 ]; // octtree tracing order + vec3_t aabb[ 2 ]; +} ray_t; + +typedef struct +{ + bool_t startsolid; + + vec_t dist; + vec3_t hit; + vec3_t normal; + + W_blockdata_t data; + + //used only internally + bool_t exit; +} rtres_t; + + /* player */ + +typedef uint32_t G_time_t; + +typedef struct +{ + vec3_t origin; + vec3_t velocity; + vec3_t angles; + m3_t matrix; + m3_t flatMatrix; + vec3_t aabb[ 2 ]; + + G_time_t lastPhysicsTime; + bool_t onGround; + + vec2_t cmd_move; + bool_t cmd_jump; + bool_t cmd_down; + bool_t cmd_sprint; + bool_t cmd_noclip; +} G_player_t; + +// main.c +extern const size_t _Material_count; + +// u_platform.c +uint64_t U_Clock( void ); +uint64_t U_Microclock( void ); +uint64_t U_Nanoclock( void ); + +// u_math.c +vec_t V2Normalize( vec2_t v ); +vec_t V3Normalize( vec3_t v ); +vec_t V4Normalize( vec4_t v ); +void V3AnglesToMatrix( m3_t out, const vec3_t angles ); +void V3Reflect( vec3_t out, const vec3_t in, const vec3_t normal ); +void V3HSVtoRGB( vec3_t out, const vec3_t in ); +void V3RGBtoHSV( vec3_t out, const vec3_t in ); + +// u_misc.c +const char *va( const char *fmt, ... ); + +// u_world.c +void W_InitWorld( W_world_t *world ); +void W_DeleteWorld( W_world_t *world ); + +W_otnode_t *W_NewOTNode( W_otnode_t *p, int i ); +void W_DeleteOTNode( W_otnode_t *n ); + +W_otnode_t *W_Point( W_otnode_t *node, vec3_t const point ); +W_otnode_t *W_Trace( W_world_t *world, const W_otnode_t *ignore, const ray_t *ray, rtres_t *rt ); + +bool_t W_Optimize( W_otnode_t *node ); + +void W_CreateEmptyWorld( W_world_t *world ); +int W_Load( W_world_t *world, const char *file ); +void W_Save( const W_world_t *world, const char *file ); + +void W_Dump( W_world_t *world ); +void W_Stats( const W_world_t *world, size_t *nodes, size_t *leaves ); + +// u_ray.c +bool_t U_PointInAABB( const vec3_t point, const vec3_t *aabb ); +bool_t U_PointInAABB2( const vec3_t point, const vec3_t *aabb ); +//org and dir can be NULL if ray already has them +void U_BuildRay( const vec3_t org, const vec3_t dir, vec_t limit, ray_t *ray, rtres_t *rt ); +bool_t U_RT_Zplane( vec_t z, const ray_t *ray, rtres_t *rt ); +bool_t U_RT_AABB_Fast( const vec3_t const *aabb, const ray_t *ray, rtres_t *rt ); +bool_t U_RT_AABB( const vec3_t const *aabb, const ray_t *ray, rtres_t *rt ); + +// player.c +W_blockdata_t G_RemoveBlock( W_world_t *world, vec3_t vieworg, vec3_t viewdir, size_t targetDepth ); +bool_t G_PlaceBlock( W_world_t *world, vec3_t vieworg, vec3_t viewdir, W_blockdata_t block, size_t targetDepth ); +void G_RunPlayer( W_world_t *world, G_player_t *p ); +void G_RecolorBlock( W_world_t *world, vec3_t vieworg, vec3_t viewdir ); +W_otnode_t *G_BoxTrace( W_world_t *world, rtres_t *rt_best, const ray_t *ray, const vec3_t *aabb ); +void G_MovePlayer( W_world_t *world, G_player_t *p, vec_t delta ); + +#endif //__COMMON_HEADER |