Match a bunch more stuff with dquakeplus

This commit is contained in:
cypress 2024-09-04 20:26:54 -07:00
parent 19bd2f273d
commit 664cfe3b99
18 changed files with 1822 additions and 1544 deletions

View file

@ -77,6 +77,7 @@ COMMON_OBJS = chase.c \
host_cmd.c \
keys.c \
mathlib.c \
matrixlib.c \
menu.c \
net_dgrm.c \
net_udpctr.c \

View file

@ -1173,7 +1173,7 @@ void CL_ParseServerMessage (void)
for (j=0; j<cl_lightstyle[i].length; j++)
{
total += cl_lightstyle[i].map[j] - 'a';
cl_lightstyle[i].peak = max(cl_lightstyle[i].peak, cl_lightstyle[i].map[j]);
cl_lightstyle[i].peak = fmax(cl_lightstyle[i].peak, cl_lightstyle[i].map[j]);
}
cl_lightstyle[i].average = total / cl_lightstyle[i].length + 'a';
}
@ -1198,14 +1198,6 @@ void CL_ParseServerMessage (void)
Host_Error ("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD");
strcpy (cl.scores[i].name, MSG_ReadString ());
break;
case svc_updatecolors:
Sbar_Changed ();
i = MSG_ReadByte ();
if (i >= cl.maxclients)
Host_Error ("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD");
MSG_ReadByte ();
break;
case svc_particle:
R_ParseParticleEffect ();

View file

@ -424,8 +424,8 @@ void Cvar_SetQuick (cvar_t *var, const char *value)
}
//johnfitz
if (var->callback)
var->callback (var);
//if (var->callback)
// var->callback (var);
}
void Cvar_SetValueQuick (cvar_t *var, const float value)
@ -433,10 +433,10 @@ void Cvar_SetValueQuick (cvar_t *var, const float value)
char val[32], *ptr = val;
if (value == (float)((int)value))
q_snprintf (val, sizeof(val), "%i", (int)value);
snprintf (val, sizeof(val), "%i", (int)value);
else
{
q_snprintf (val, sizeof(val), "%f", value);
snprintf (val, sizeof(val), "%f", value);
// kill trailing zeroes
while (*ptr)
ptr++;
@ -476,10 +476,10 @@ void Cvar_SetValue (const char *var_name, const float value)
char val[32], *ptr = val;
if (value == (float)((int)value))
q_snprintf (val, sizeof(val), "%i", (int)value);
snprintf (val, sizeof(val), "%i", (int)value);
else
{
q_snprintf (val, sizeof(val), "%f", value);
snprintf (val, sizeof(val), "%f", value);
// kill trailing zeroes
while (*ptr)
ptr++;
@ -573,7 +573,7 @@ void Cvar_RegisterVariable (cvar_t *variable)
variable->flags |= CVAR_REGISTERED;
// copy the value off, because future sets will Z_Free it
q_strlcpy (value, variable->string, sizeof(value));
strlcpy (value, variable->string, sizeof(value));
variable->string = NULL;
variable->default_string = NULL;

View file

@ -63,14 +63,14 @@ interface from being ambiguous.
*/
#define CVAR_NONE 0
#define CVAR_NONE 0
#define CVAR_ARCHIVE (1U << 0) // if set, causes it to be saved to config
#define CVAR_NOTIFY (1U << 1) // changes will be broadcasted to all players (q1)
#define CVAR_NOTIFY (1U << 1) // changes will be broadcasted to all players (q1)
#define CVAR_SERVERINFO (1U << 2) // added to serverinfo will be sent to clients (q1/net_dgrm.c and qwsv)
#define CVAR_USERINFO (1U << 3) // added to userinfo, will be sent to server (qwcl)
#define CVAR_CHANGED (1U << 4)
#define CVAR_ROM (1U << 6)
#define CVAR_LOCKED (1U << 8) // locked temporarily
#define CVAR_ROM (1U << 6)
#define CVAR_LOCKED (1U << 8) // locked temporarily
#define CVAR_REGISTERED (1U << 10) // the var is added to the list of variables
#define CVAR_CALLBACK (1U << 16) // var has a callback

View file

@ -277,7 +277,7 @@ float *Fog_GetColor (void)
//find closest 24-bit RGB value, so solid-colored sky can match the fog perfectly
for (i=0;i<3;i++)
c[i] = (float)(Q_rint(c[i] * 255)) / 255.0f;
c[i] = (float)(rint(c[i] * 255)) / 255.0f;
for (i = 0; i < 3; i++)
c[i] /= 64.0;

View file

@ -881,11 +881,7 @@ Host_Init
*/
void Host_Init (quakeparms_t *parms)
{
if (standard_quake)
minimum_memory = MINIMUM_MEMORY;
else
minimum_memory = MINIMUM_MEMORY_LEVELPAK;
minimum_memory = MINIMUM_MEMORY_LEVELPAK;
if (COM_CheckParm ("-minmemory"))
parms->memsize = minimum_memory;

View file

@ -1120,58 +1120,6 @@ void Host_Tell_f(void)
host_client = save;
}
/*
==================
Host_Color_f
==================
*/
void Host_Color_f(void)
{
int top, bottom;
int playercolor;
if (Cmd_Argc() == 1)
{
Con_Printf ("\"color\" is \"%i %i\"\n", ((int)cl_color.value) >> 4, ((int)cl_color.value) & 0x0f);
Con_Printf ("color <0-13> [0-13]\n");
return;
}
if (Cmd_Argc() == 2)
top = bottom = atoi(Cmd_Argv(1));
else
{
top = atoi(Cmd_Argv(1));
bottom = atoi(Cmd_Argv(2));
}
top &= 15;
if (top > 13)
top = 13;
bottom &= 15;
if (bottom > 13)
bottom = 13;
playercolor = top*16 + bottom;
if (cmd_source == src_command)
{
Cvar_SetValue ("_cl_color", playercolor);
if (cls.state == ca_connected)
Cmd_ForwardToServer ();
return;
}
host_client->colors = playercolor;
host_client->edict->v.team = bottom + 1;
// send notification to all clients
MSG_WriteByte (&sv.reliable_datagram, svc_updatecolors);
MSG_WriteByte (&sv.reliable_datagram, host_client - svs.clients);
MSG_WriteByte (&sv.reliable_datagram, host_client->colors);
}
/*
==================
Host_Kill_f
@ -1753,7 +1701,6 @@ void Host_InitCommands (void)
Cmd_AddCommand ("say", Host_Say_f);
Cmd_AddCommand ("say_team", Host_Say_Team_f);
Cmd_AddCommand ("tell", Host_Tell_f);
Cmd_AddCommand ("color", Host_Color_f);
Cmd_AddCommand ("kill", Host_Kill_f);
Cmd_AddCommand ("pause", Host_Pause_f);
Cmd_AddCommand ("spawn", Host_Spawn_f);

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -22,19 +22,38 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <math.h>
#include "quakedef.h"
#ifdef PSP_VFPU
#include <pspmath.h>
#endif
void Sys_Error (char *error, ...);
vec3_t vec3_origin = {0,0,0};
int nanmask = 255<<23;
int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
/*-----------------------------------------------------------------*/
float rsqrt( float number )
{
#ifdef PSP_VFPU
float d;
__asm__ (
".set push\n" // save assember option
".set noreorder\n" // suppress reordering
"lv.s s000, %1\n" // s000 = s
"vrsq.s s000, s000\n" // s000 = 1 / sqrt(s000)
"sv.s s000, %0\n" // d = s000
".set pop\n" // restore assember option
: "=m"(d)
: "m"(number)
);
return d;
#else
int i;
float x, y;
@ -48,10 +67,35 @@ float rsqrt( float number )
y = y * (1.5f - (x * y * y)); // first iteration
return y;
#endif
}
/*
=================
SinCos
=================
*/
void SinCos( float radians, float *sine, float *cosine )
{
#ifndef __PSP__
sincos(radians, sine, cosine);
#else
/*-----------------------------------------------------------------*/
#ifdef PSP_VFPU
vfpu_sincos(radians,sine,cosine);
#else
__asm__ volatile (
"mtv %2, S002\n"
"vcst.s S003, VFPU_2_PI\n"
"vmul.s S002, S002, S003\n"
"vrot.p C000, S002, [s, c]\n"
"mfv %0, S000\n"
"mfv %1, S001\n"
: "=r"(*sine), "=r"(*cosine): "r"(radians));
#endif // PSP_VFPU
#endif // __PSP__
}
void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
{
@ -87,10 +131,10 @@ void PerpendicularVector( vec3_t dst, const vec3_t src )
*/
for ( pos = 0, i = 0; i < 3; i++ )
{
if ( fabs( src[i] ) < minelem )
if ( fabsf( src[i] ) < minelem )
{
pos = i;
minelem = fabs( src[i] );
minelem = fabsf( src[i] );
}
}
tempvec[0] = tempvec[1] = tempvec[2] = 0.0F;
@ -107,10 +151,6 @@ void PerpendicularVector( vec3_t dst, const vec3_t src )
VectorNormalize( dst );
}
#ifdef _WIN32
#pragma optimize( "", off )
#endif
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees )
{
@ -141,8 +181,16 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
m[1][2] = vf[1];
m[2][2] = vf[2];
#ifdef PSP_VFPU
memcpy_vfpu( im, m, sizeof( im ) );
#else
memcpy( im, m, sizeof( im ) );
#endif // PSP_VFPU
im[0][1] = m[1][0];
im[0][2] = m[2][0];
im[1][0] = m[0][1];
@ -153,10 +201,17 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
memset( zrot, 0, sizeof( zrot ) );
zrot[0][0] = zrot[1][1] = zrot[2][2] = 1.0F;
#ifdef PSP_VFPU
zrot[0][0] = vfpu_cosf( DEG2RAD( degrees ) );
zrot[0][1] = vfpu_sinf( DEG2RAD( degrees ) );
zrot[1][0] = -vfpu_sinf( DEG2RAD( degrees ) );
zrot[1][1] = vfpu_cosf( DEG2RAD( degrees ) );
#else
zrot[0][0] = cosf( DEG2RAD( degrees ) );
zrot[0][1] = sinf( DEG2RAD( degrees ) );
zrot[1][0] = -sinf( DEG2RAD( degrees ) );
zrot[1][1] = cosf( DEG2RAD( degrees ) );
#endif
R_ConcatRotations( m, zrot, tmpmat );
R_ConcatRotations( tmpmat, im, rot );
@ -167,25 +222,8 @@ void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point,
}
}
#ifdef _WIN32
#pragma optimize( "", on )
#endif
/*-----------------------------------------------------------------*/
float anglemod(float a)
{
#if 0
if (a >= 0)
a -= 360*(int)(a/360);
else
a += 360*( 1 + (int)(-a/360) );
#endif
a = (360.0/65536) * ((int)(a*(65536/360.0)) & 65535);
return a;
}
/*
==================
BOPS_Error
@ -198,9 +236,6 @@ void BOPS_Error (void)
Sys_Error ("BoxOnPlaneSide: Bad signbits");
}
#if !id386
/*
==================
BoxOnPlaneSide
@ -208,107 +243,244 @@ BoxOnPlaneSide
Returns 1, 2, or 1 + 2
==================
*/
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, mplane_t *p)
// crow_bar's enhanced boxonplaneside
int BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, mplane_t *p)
{
float dist1, dist2;
int sides;
int sides;
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.s S000, 0 + %[normal]\n" // S000 = p->normal[0]
"lv.s S001, 4 + %[normal]\n" // S001 = p->normal[1]
"lv.s S002, 8 + %[normal]\n" // S002 = p->normal[2]
"vzero.p C030\n" // C030 = [0.0f, 0.0f]
"lv.s S032, %[dist]\n" // S032 = p->dist
"move $8, $0\n" // $8 = 0
"beq %[signbits], $8, 0f\n" // jump to 0
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 1f\n" // jump to 1
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 2f\n" // jump to 2
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 3f\n" // jump to 3
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 4f\n" // jump to 4
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 5f\n" // jump to 5
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 6f\n" // jump to 6
"addiu $8, $8, 1\n" // $8 = $8 + 1 ( delay slot )
"beq %[signbits], $8, 7f\n" // jump to 7
"nop\n" // ( delay slot )
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"0:\n"
/*
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
*/
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"1:\n"
/*
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
*/
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"2:\n"
/*
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
*/
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"3:\n"
/*
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
*/
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
"lv.s S012, 8 + %[emaxs]\n" // S012 = emaxs[2]
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
"lv.s S022, 8 + %[emins]\n" // S022 = emins[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"4:\n"
/*
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
*/
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"5:\n"
/*
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
*/
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
"lv.s S011, 4 + %[emaxs]\n" // S011 = emaxs[1]
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
"lv.s S021, 4 + %[emins]\n" // S021 = emins[1]
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"6:\n"
/*
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
*/
"lv.s S010, 0 + %[emaxs]\n" // S010 = emaxs[0]
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
"lv.s S020, 0 + %[emins]\n" // S020 = emins[0]
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"j 8f\n" // jump to SetSides
"nop\n" // ( delay slot )
"7:\n"
/*
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
*/
"lv.s S010, 0 + %[emins]\n" // S010 = emins[0]
"lv.s S011, 4 + %[emins]\n" // S011 = emins[1]
"lv.s S012, 8 + %[emins]\n" // S012 = emins[2]
"lv.s S020, 0 + %[emaxs]\n" // S020 = emaxs[0]
"lv.s S021, 4 + %[emaxs]\n" // S021 = emaxs[1]
"lv.s S022, 8 + %[emaxs]\n" // S022 = emaxs[2]
"vdot.t S030, C000, C010\n" // S030 = C000 * C010
"vdot.t S031, C000, C020\n" // S030 = C000 * C020
"8:\n" // SetSides
/*
if( dist1 >= p->dist )
sides = 1;
if( dist2 < p->dist )
sides |= 2;
*/
"addiu %[sides], $0, 0\n" // sides = 0
"vcmp.s LT, S030, S032\n" // S030 < S032
"bvt 0, 9f\n" // if ( CC[0] == 1 ) jump to 9
"nop\n" // ( delay slot )
"addiu %[sides], %[sides], 1\n"// sides = 1
"9:\n"
"vcmp.s GE, S031, S032\n" // S031 >= S032
"bvt 0, 10f\n" // if ( CC[0] == 1 ) jump to 10
"nop\n" // ( delay slot )
"addiu %[sides], %[sides], 2\n"// sides = sides + 2
"10:\n"
".set pop\n" // restore assembler option
: [sides] "=r" ( sides )
: [normal] "m" (*(p->normal)),
[emaxs] "m" ( *emaxs ),
[emins] "m" ( *emins ),
[signbits] "r" ( p->signbits ),
[dist] "m" ( p->dist )
: "$8"
);
#else
float dist1, dist2;
#if 0 // this is done by the BOX_ON_PLANE_SIDE macro before calling this
// function
// fast axial cases
if (p->type < 3)
{
if (p->dist <= emins[p->type])
return 1;
if (p->dist >= emaxs[p->type])
return 2;
return 3;
}
#endif
// general case
switch (p->signbits)
{
case 0:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
break;
case 1:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
break;
case 2:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
break;
case 3:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
break;
case 4:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
break;
case 5:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
dist1 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emaxs[2];
break;
case 6:
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist1 = p->normal[0]*emaxs[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emins[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
break;
case 7:
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
dist1 = p->normal[0]*emins[0] + p->normal[1]*emins[1] + p->normal[2]*emins[2];
dist2 = p->normal[0]*emaxs[0] + p->normal[1]*emaxs[1] + p->normal[2]*emaxs[2];
break;
default:
dist1 = dist2 = 0; // shut up compiler
BOPS_Error ();
Sys_Error ("BoxOnPlaneSide: Bad signbits");
break;
}
#if 0
int i;
vec3_t corners[2];
for (i=0 ; i<3 ; i++)
{
if (plane->normal[i] < 0)
{
corners[0][i] = emins[i];
corners[1][i] = emaxs[i];
}
else
{
corners[1][i] = emins[i];
corners[0][i] = emaxs[i];
}
}
dist = DotProduct (plane->normal, corners[0]) - plane->dist;
dist2 = DotProduct (plane->normal, corners[1]) - plane->dist;
sides = 0;
if (dist1 >= 0)
sides = 1;
if (dist2 < 0)
sides |= 2;
#endif
sides = 0;
if (dist1 >= p->dist)
sides = 1;
if (dist2 < p->dist)
sides |= 2;
#ifdef PARANOID
if (sides == 0)
Sys_Error ("BoxOnPlaneSide: sides==0");
#endif
return sides;
#endif // __PSP__
return sides;
}
#endif
void vectoangles (vec3_t vec, vec3_t ang)
{
@ -329,11 +501,10 @@ void vectoangles (vec3_t vec, vec3_t ang)
if (yaw < 0)
yaw += 360;
forward = sqrt (vec[0] * vec[0] + vec[1] * vec[1]);
#ifdef PSP_VFPU
forward = vfpu_sqrtf (vec[0] * vec[0] + vec[1] * vec[1]);
pitch = vfpu_atan2f (vec[2], forward) * 180 / M_PI;
#else
forward = sqrt (vec[0] * vec[0] + vec[1] * vec[1]);
pitch = atan2 (vec[2], forward) * 180 / M_PI;
#endif
if (pitch < 0)
@ -351,14 +522,29 @@ void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
float sr, sp, sy, cr, cp, cy;
angle = angles[YAW] * (M_PI*2 / 360);
sy = sin(angle);
cy = cos(angle);
#ifdef PSP_VFPU
sy = vfpu_sinf(angle);
cy = vfpu_cosf(angle);
#else
sy = sinf(angle);
cy = cosf(angle);
#endif
angle = angles[PITCH] * (M_PI*2 / 360);
sp = sin(angle);
cp = cos(angle);
#ifdef PSP_VFPU
sp = vfpu_sinf(angle);
cp = vfpu_cosf(angle);
#else
sp = sinf(angle);
cp = cosf(angle);
#endif
angle = angles[ROLL] * (M_PI*2 / 360);
sr = sin(angle);
cr = cos(angle);
#ifdef PSP_VFPU
sr = vfpu_sinf(angle);
cr = vfpu_cosf(angle);
#else
sr = sinf(angle);
cr = cosf(angle);
#endif
forward[0] = cp*cy;
forward[1] = cp*sy;
@ -376,17 +562,6 @@ float VectorLength (vec3_t v)
return sqrtf(DotProduct(v, v));
}
int VectorCompare (vec3_t v1, vec3_t v2)
{
int i;
for (i=0 ; i<3 ; i++)
if (v1[i] != v2[i])
return 0;
return 1;
}
void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc)
{
vecc[0] = veca[0] + scale*vecb[0];
@ -428,8 +603,6 @@ void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
}
double sqrt(double x);
float VecLength2(vec3_t v1, vec3_t v2)
{
vec3_t k;
@ -439,14 +612,11 @@ float VecLength2(vec3_t v1, vec3_t v2)
float VectorNormalize (vec3_t v)
{
float length, ilength;
length = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
length = sqrt (length); // FIXME
float length = sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
if (length)
{
ilength = 1/length;
const float ilength = 1.0f / length;
v[0] *= ilength;
v[1] *= ilength;
v[2] *= ilength;
@ -552,36 +722,30 @@ quotient must fit in 32 bits.
====================
*/
void FloorDivMod (double numer, double denom, int *quotient,
void FloorDivMod (float numer, float denom, int *quotient,
int *rem)
{
int q, r;
double x;
float x;
#ifndef PARANOID
if (denom <= 0.0)
Sys_Error ("FloorDivMod: bad denominator %d\n", denom);
// if ((floor(numer) != numer) || (floor(denom) != denom))
// Sys_Error ("FloorDivMod: non-integer numer or denom %f %f\n",
// numer, denom);
#endif
if (numer >= 0.0)
{
x = floor(numer / denom);
x = floorf(numer / denom);
q = (int)x;
r = (int)floor(numer - (x * denom));
r = (int)floorf(numer - (x * denom));
}
else
{
//
// perform operations with positive values, and fix mod to make floor-based
//
x = floor(-numer / denom);
x = floorf(-numer / denom);
q = -(int)x;
r = (int)floor(-numer - (x * denom));
r = (int)floorf(-numer - (x * denom));
if (r != 0)
{
q--;
@ -634,131 +798,126 @@ fixed16_t Invert24To16(fixed16_t val)
return (0xFFFFFFFF);
return (fixed16_t)
(((double)0x10000 * (double)0x1000000 / (double)val) + 0.5);
(((float)0x10000 * (float)0x1000000 / (float)val) + 0.5);
}
#endif
/*
========================================================================
Matrix4x4 operations
========================================================================
*/
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] )
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out)
{
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
}
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] )
void AngleQuaternion( const vec3_t angles, vec4_t quaternion )
{
vec3_t dir;
float angle;
float sr, sp, sy, cr, cp, cy;
dir[0] = v[0] - in[0][3];
dir[1] = v[1] - in[1][3];
dir[2] = v[2] - in[2][3];
// FIXME: rescale the inputs to 1/2 angle
angle = angles[2] * 0.5;
#ifdef PSP_VFPU
sy = vfpu_sinf(angle);
cy = vfpu_cosf(angle);
#else
sy = sin(angle);
cy = cos(angle);
#endif
angle = angles[1] * 0.5;
#ifdef PSP_VFPU
sp = vfpu_sinf(angle);
cp = vfpu_cosf(angle);
#else
sp = sin(angle);
cp = cos(angle);
#endif
angle = angles[0] * 0.5;
#ifdef PSP_VFPU
sr = vfpu_sinf(angle);
cr = vfpu_cosf(angle);
#else
sr = sin(angle);
cr = cos(angle);
#endif
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
quaternion[0] = sr*cp*cy-cr*sp*sy; // X
quaternion[1] = cr*sp*cy+sr*cp*sy; // Y
quaternion[2] = cr*cp*sy-sr*sp*cy; // Z
quaternion[3] = cr*cp*cy+sr*sp*sy; // W
}
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale )
void QuaternionMatrix( const vec4_t quaternion, float (*matrix)[4] )
{
float angle, sr, sp, sy, cr, cp, cy;
if( angles[ROLL] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
angle = angles[ROLL] * (M_PI*2 / 360);
sincos( angle, &sr, &cr );
matrix[0][0] = 1.0 - 2.0 * quaternion[1] * quaternion[1] - 2.0 * quaternion[2] * quaternion[2];
matrix[1][0] = 2.0 * quaternion[0] * quaternion[1] + 2.0 * quaternion[3] * quaternion[2];
matrix[2][0] = 2.0 * quaternion[0] * quaternion[2] - 2.0 * quaternion[3] * quaternion[1];
out[0][0] = (cp*cy) * scale;
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
out[0][2] = (cr*sp*cy+-sr*-sy) * scale;
out[0][3] = origin[0];
out[1][0] = (cp*sy) * scale;
out[1][1] = (sr*sp*sy+cr*cy) * scale;
out[1][2] = (cr*sp*sy+-sr*cy) * scale;
out[1][3] = origin[1];
out[2][0] = (-sp) * scale;
out[2][1] = (sr*cp) * scale;
out[2][2] = (cr*cp) * scale;
out[2][3] = origin[2];
out[3][0] = 0;
out[3][1] = 0;
out[3][2] = 0;
out[3][3] = 1;
}
else if( angles[PITCH] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
matrix[0][1] = 2.0 * quaternion[0] * quaternion[1] - 2.0 * quaternion[3] * quaternion[2];
matrix[1][1] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[2] * quaternion[2];
matrix[2][1] = 2.0 * quaternion[1] * quaternion[2] + 2.0 * quaternion[3] * quaternion[0];
out[0][0] = (cp*cy) * scale;
out[0][1] = (-sy) * scale;
out[0][2] = (sp*cy) * scale;
out[0][3] = origin[0];
out[1][0] = (cp*sy) * scale;
out[1][1] = (cy) * scale;
out[1][2] = (sp*sy) * scale;
out[1][3] = origin[1];
out[2][0] = (-sp) * scale;
out[2][1] = 0;
out[2][2] = (cp) * scale;
out[2][3] = origin[2];
out[3][0] = 0;
out[3][1] = 0;
out[3][2] = 0;
out[3][3] = 1;
}
else if( angles[YAW] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
matrix[0][2] = 2.0 * quaternion[0] * quaternion[2] + 2.0 * quaternion[3] * quaternion[1];
matrix[1][2] = 2.0 * quaternion[1] * quaternion[2] - 2.0 * quaternion[3] * quaternion[0];
matrix[2][2] = 1.0 - 2.0 * quaternion[0] * quaternion[0] - 2.0 * quaternion[1] * quaternion[1];
}
out[0][0] = (cy) * scale;
out[0][1] = (-sy) * scale;
out[0][2] = 0;
out[0][3] = origin[0];
out[1][0] = (sy) * scale;
out[1][1] = (cy) * scale;
out[1][2] = 0;
out[1][3] = origin[1];
out[2][0] = 0;
out[2][1] = 0;
out[2][2] = scale;
out[2][3] = origin[2];
out[3][0] = 0;
out[3][1] = 0;
out[3][2] = 0;
out[3][3] = 1;
void QuaternionSlerp( const vec4_t p, vec4_t q, float t, vec4_t qt )
{
int i;
float omega, cosom, sinom, sclp, sclq;
// decide if one of the quaternions is backwards
float a = 0;
float b = 0;
for (i = 0; i < 4; i++) {
a += (p[i]-q[i])*(p[i]-q[i]);
b += (p[i]+q[i])*(p[i]+q[i]);
}
else
{
out[0][0] = scale;
out[0][1] = 0;
out[0][2] = 0;
out[0][3] = origin[0];
out[1][0] = 0;
out[1][1] = scale;
out[1][2] = 0;
out[1][3] = origin[1];
out[2][0] = 0;
out[2][1] = 0;
out[2][2] = scale;
out[2][3] = origin[2];
out[3][0] = 0;
out[3][1] = 0;
out[3][2] = 0;
out[3][3] = 1;
if (a > b) {
for (i = 0; i < 4; i++) {
q[i] = -q[i];
}
}
}
cosom = p[0]*q[0] + p[1]*q[1] + p[2]*q[2] + p[3]*q[3];
if ((1.0 + cosom) > 0.00000001) {
if ((1.0 - cosom) > 0.00000001) {
omega = acos( cosom );
#ifdef PSP_VFPU
sinom = vfpu_sinf( omega );
sclp = vfpu_sinf( (1.0 - t)*omega) / sinom;
sclq = vfpu_sinf( t*omega ) / sinom;
#else
sinom = sin( omega );
sclp = sin( (1.0 - t)*omega) / sinom;
sclq = sin( t*omega ) / sinom;
#endif
}
else {
sclp = 1.0 - t;
sclq = t;
}
for (i = 0; i < 4; i++) {
qt[i] = sclp * p[i] + sclq * q[i];
}
}
else {
qt[0] = -p[1];
qt[1] = p[0];
qt[2] = -p[3];
qt[3] = p[2];
#ifdef PSP_VFPU
sclp = vfpu_sinf( (1.0 - t) * 0.5 * M_PI);
sclq = vfpu_sinf( t * 0.5 * M_PI);
#else
sclp = sin( (1.0 - t) * 0.5 * M_PI);
sclq = sin( t * 0.5 * M_PI);
#endif
for (i = 0; i < 3; i++) {
qt[i] = sclp * p[i] + sclq * qt[i];
}
}
}

View file

@ -18,13 +18,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
// mathlib.h
#ifdef PSP_VFPU
#include <pspmath.h>
#endif
typedef float vec_t;
typedef vec_t vec3_t[3];
typedef vec_t vec5_t[5];
typedef vec_t vec2_t[2];
typedef vec_t vec3_t[3];
typedef vec_t vec4_t[4];
typedef vec_t vec5_t[5];
typedef vec_t matrix4x4[4][4];
typedef byte byte_vec4_t[4];
typedef int fixed4_t;
typedef int fixed8_t;
typedef int fixed16_t;
@ -33,31 +39,43 @@ typedef int fixed16_t;
#define M_PI 3.14159265358979323846 // matches value in gcc v2 math.h
#endif
#define RAD2DEG( x ) ((float)(x) * (float)(180.f / M_PI))
#define DEG2RAD( x ) ((float)(x) * (float)(M_PI / 180.f))
struct mplane_s;
extern vec3_t vec3_origin;
extern int nanmask;
#define CLAMP(min, x, max) ((x) < (min) ? (min) : (x) > (max) ? (max) : (x)) //johnfitz
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))
#define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN))
#define IS_NAN(x) (((*(int *)&x)&nanmask)==nanmask)
#define Q_rint(x) ((x) > 0 ? (int)((x) + 0.5) : (int)((x) - 0.5)) //johnfitz -- from joequake
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define DoublePrecisionDotProduct(x,y) ((double)x[0]*y[0]+(double)x[1]*y[1]+(double)x[2]*y[2])
#define VectorLerp( v1, lerp, v2, c ) ((c)[0] = (v1)[0] + (lerp) * ((v2)[0] - (v1)[0]), (c)[1] = (v1)[1] + (lerp) * ((v2)[1] - (v1)[1]), (c)[2] = (v1)[2] + (lerp) * ((v2)[2] - (v1)[2]))
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
#define VectorSubtract(a,b,c) {(c)[0]=(a)[0]-(b)[0];(c)[1]=(a)[1]-(b)[1];(c)[2]=(a)[2]-(b)[2];}
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0)
#define VectorSet(v, x, y, z) ((v)[0] = (x), (v)[1] = (y), (v)[2] = (z))
#define VectorNegate(a, b) ((b)[0] = -(a)[0], (b)[1] = -(a)[1], (b)[2] = -(a)[2])
#define VectorMax(a,b,out) {out[0]=a[0]>b[0]?a[0]:b[0]; out[1]=a[1]>b[1]?a[1]:b[1]; out[2]=a[2]>b[2]?a[2]:b[2];}
#define VectorMin(a,b,out) {out[0]=a[0]<b[0]?a[0]:b[0]; out[1]=a[1]<b[1]?a[1]:b[1]; out[2]=a[2]<b[2]?a[2]:b[2];}
#define DEG2RAD( a ) ( a * M_PI ) / 180.0F
#define VectorClear(a) ((a)[0] = (a)[1] = (a)[2] = 0)
#define VectorNegate(a, b) ((b)[0] = -(a)[0], (b)[1] = -(a)[1], (b)[2] = -(a)[2])
#define VectorSet(v, x, y, z) ((v)[0] = (x), (v)[1] = (y), (v)[2] = (z))
#define VectorRandom(v) {do{(v)[0] = lhrandom(-1, 1);(v)[1] = lhrandom(-1, 1);(v)[2] = lhrandom(-1, 1);}while(DotProduct(v, v) > 1);}
#define DoublePrecisionDotProduct(x,y) ((double)(x)[0]*(y)[0]+(double)(x)[1]*(y)[1]+(double)(x)[2]*(y)[2])
#define VSM(a,b,c) {c[0]=a[0]*b;c[1]=a[1]*b;c[2]=a[2]*b;}
#define VectorNormalizeFast( v ){float ilength = (float)rsqrt(DotProduct(v,v));v[0] *= ilength;v[1] *= ilength;v[2] *= ilength; }
#define VectorDistanceSquared(a,b)((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])+(a[2]-b[2])*(a[2]-b[2]))
typedef float matrix3x4[3][4];
typedef float matrix3x3[3][3];
void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
vec_t _DotProduct (vec3_t v1, vec3_t v2);
@ -67,17 +85,9 @@ void _VectorCopy (vec3_t in, vec3_t out);
void vectoangles (vec3_t vec, vec3_t ang);
#define VectorInterpolate(v1, _frac, v2, v) \
do { \
_mathlib_temp_float1 = _frac; \
\
(v)[0] = (v1)[0] + _mathlib_temp_float1 * ((v2)[0] - (v1)[0]);\
(v)[1] = (v1)[1] + _mathlib_temp_float1 * ((v2)[1] - (v1)[1]);\
(v)[2] = (v1)[2] + _mathlib_temp_float1 * ((v2)[2] - (v1)[2]);\
} while(0)
int VectorCompare (vec3_t v1, vec3_t v2);
#define VectorCompare(v1,v2) ((v1)[0]==(v2)[0] && (v1)[1]==(v2)[1] && (v1)[2]==(v2)[2])
#define Length(v) (sqrtf(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]))
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
float VectorLength (vec3_t v);
float VecLength2(vec3_t v1, vec3_t v2);
@ -89,22 +99,16 @@ int Q_log2(int val);
void R_ConcatRotations (float in1[3][3], float in2[3][3], float out[3][3]);
void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4]);
void FloorDivMod (double numer, double denom, int *quotient,
void FloorDivMod (float numer, float denom, int *quotient,
int *rem);
fixed16_t Invert24To16(fixed16_t val);
int GreatestCommonDivisor (int i1, int i2);
void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
int BoxOnPlaneSide (vec3_t emins, vec3_t emaxs, struct mplane_s *plane);
float anglemod(float a);
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] );
extern int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
extern float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
#define anglemod(a) ((360.0/65536) * ((int)((a)*(65536/360.0)) & 65535))
#define VectorL2Compare(v, w, m) \
(_mathlib_temp_float1 = (m) * (m), \
@ -113,6 +117,7 @@ extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
_mathlib_temp_vec1[1] * _mathlib_temp_vec1[1] + \
_mathlib_temp_vec1[2] * _mathlib_temp_vec1[2] < _mathlib_temp_float1)
#define VectorSupCompare(v, w, m) \
(_mathlib_temp_float1 = m, \
(v)[0] - (w)[0] > -_mathlib_temp_float1 && (v)[0] - (w)[0] < _mathlib_temp_float1 && \
@ -135,5 +140,72 @@ extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;
: \
BoxOnPlaneSide( (emins), (emaxs), (p)))
#define VectorInterpolate(v1, _frac, v2, v) \
do { \
_mathlib_temp_float1 = _frac; \
\
(v)[0] = (v1)[0] + _mathlib_temp_float1 * ((v2)[0] - (v1)[0]);\
(v)[1] = (v1)[1] + _mathlib_temp_float1 * ((v2)[1] - (v1)[1]);\
(v)[2] = (v1)[2] + _mathlib_temp_float1 * ((v2)[2] - (v1)[2]);\
} while(0)
#define FloatInterpolate(f1, _frac, f2) \
(_mathlib_temp_float1 = _frac, \
(f1) + _mathlib_temp_float1 * ((f2) - (f1)))
#define PlaneDist(point, plane) ( \
(plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal) \
)
#define PlaneDiff(point, plane) ( \
(((plane)->type < 3) ? (point)[(plane)->type] - (plane)->dist : DotProduct((point), (plane)->normal) - (plane)->dist) \
)
void SinCos( float radians, float *sine, float *cosine );
float rsqrt( float number );
//
// matrixlib.c
//
#define Matrix3x4_LoadIdentity( mat ) Matrix3x4_Copy( mat, matrix3x4_identity )
#define Matrix3x4_Copy( out, in ) memcpy( out, in, sizeof( matrix3x4 ))
void Matrix3x4_VectorTransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorITransform( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_VectorIRotate( const matrix3x4 in, const float v[3], float out[3] );
void Matrix3x4_ConcatTransforms( matrix3x4 out, const matrix3x4 in1, const matrix3x4 in2 );
void Matrix3x4_FromOriginQuat( matrix3x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix3x4_TransformPositivePlane( const matrix3x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix3x4_SetOrigin( matrix3x4 out, float x, float y, float z );
void Matrix3x4_Invert_Simple( matrix3x4 out, const matrix3x4 in1 );
void Matrix3x4_OriginFromMatrix( const matrix3x4 in, float *out );
#define Matrix4x4_LoadIdentity( mat ) Matrix4x4_Copy( mat, matrix4x4_identity )
#define Matrix4x4_Copy( out, in ) memcpy( out, in, sizeof( matrix4x4 ))
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3] );
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 );
void Matrix4x4_FromOriginQuat( matrix4x4 out, const vec4_t quaternion, const vec3_t origin );
void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_t origin, float scale );
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist );
void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin );
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z );
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 );
void Matrix4x4_OriginFromMatrix( const matrix4x4 in, float *out );
extern const matrix3x4 matrix3x4_identity;
extern const matrix4x4 matrix4x4_identity;
void VectorTransform (const vec3_t in1, matrix3x4 in2, vec3_t out);
// Prototypes added by PM.
void RotatePointAroundVector( vec3_t dst, const vec3_t dir, const vec3_t point, float degrees );
extern int _mathlib_temp_int1, _mathlib_temp_int2, _mathlib_temp_int3;
extern float _mathlib_temp_float1, _mathlib_temp_float2, _mathlib_temp_float3;
extern vec3_t _mathlib_temp_vec1, _mathlib_temp_vec2, _mathlib_temp_vec3;

View file

@ -14,7 +14,6 @@ GNU General Public License for more details.
*/
#include "quakedef.h"
#include <math.h>
const matrix3x4 matrix3x4_identity =
@ -121,11 +120,11 @@ void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_
if( angles[ROLL] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
SinCos( angle, &sp, &cp );
angle = angles[ROLL] * (M_PI*2 / 360);
sincos( angle, &sr, &cr );
SinCos( angle, &sr, &cr );
out[0][0] = (cp*cy) * scale;
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
@ -143,9 +142,9 @@ void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_
else if( angles[PITCH] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
SinCos( angle, &sp, &cp );
out[0][0] = (cp*cy) * scale;
out[0][1] = (-sy) * scale;
@ -163,7 +162,7 @@ void Matrix3x4_CreateFromEntity( matrix3x4 out, const vec3_t angles, const vec3_
else if( angles[YAW] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
out[0][0] = (cy) * scale;
out[0][1] = (-sy) * scale;
@ -249,13 +248,61 @@ const matrix4x4 matrix4x4_identity =
*/
void Matrix4x4_VectorTransform( const matrix4x4 in, const float v[3], float out[3] )
{
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in[0]
"lv.q C110, 16 + %1\n" // C110 = in[1]
"lv.q C120, 32 + %1\n" // C120 = in[2]
"lv.s S130, 0 + %2\n" // S130 = v[0]
"lv.s S131, 4 + %2\n" // S131 = v[1]
"lv.s S132, 8 + %2\n" // S132 = v[2]
"vhdp.q S000, C130, C100\n" // S000 = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3]
"vhdp.q S001, C130, C110\n" // S001 = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3]
"vhdp.q S002, C130, C120\n" // S002 = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3]
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in ), "m"( *v )
);
#else
out[0] = v[0] * in[0][0] + v[1] * in[0][1] + v[2] * in[0][2] + in[0][3];
out[1] = v[0] * in[1][0] + v[1] * in[1][1] + v[2] * in[1][2] + in[1][3];
out[2] = v[0] * in[2][0] + v[1] * in[2][1] + v[2] * in[2][2] + in[2][3];
#endif // __PSP__
}
void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out[3] )
{
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in[0]
"lv.q C110, 16 + %1\n" // C110 = in[1]
"lv.q C120, 32 + %1\n" // C120 = in[2]
"lv.s S130, 0 + %2\n" // S130 = v[0]
"lv.s S131, 4 + %2\n" // S131 = v[1]
"lv.s S132, 8 + %2\n" // S132 = v[2]
"vsub.t C130, C130, R103\n" // C130 = v - in[][3]
#if 1
"vtfm3.t C000, E100, C130\n" // C000 = E100 * C130
#else
"vdot.t S000, C130, R100\n" // S000 = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0]
"vdot.t S001, C130, R101\n" // S001 = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1]
"vdot.t S002, C130, R102\n" // S002 = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2]
#endif
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in ), "m"( *v )
);
#else
vec3_t dir;
dir[0] = v[0] - in[0][3];
@ -265,6 +312,7 @@ void Matrix4x4_VectorITransform( const matrix4x4 in, const float v[3], float out
out[0] = dir[0] * in[0][0] + dir[1] * in[1][0] + dir[2] * in[2][0];
out[1] = dir[0] * in[0][1] + dir[1] * in[1][1] + dir[2] * in[2][1];
out[2] = dir[0] * in[0][2] + dir[1] * in[1][2] + dir[2] * in[2][2];
#endif // __PSP__
}
void Matrix4x4_VectorRotate( const matrix4x4 in, const float v[3], float out[3] )
@ -283,6 +331,27 @@ void Matrix4x4_VectorIRotate( const matrix4x4 in, const float v[3], float out[3]
void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matrix4x4 in2 )
{
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %1\n" // C100 = in1[0]
"lv.q C110, 16 + %1\n" // C110 = in1[1]
"lv.q C120, 32 + %1\n" // C120 = in1[2]
"vzero.q C130\n" // C130 = [0, 0, 0, 0]
"lv.q C200, 0 + %2\n" // C100 = in2[0]
"lv.q C210, 16 + %2\n" // C110 = in2[1]
"lv.q C220, 32 + %2\n" // C120 = in2[2]
"vidt.q C230\n" // C230 = [0, 0, 0, 1]
"vmmul.q E000, E100, E200\n" // E000 = E100 * E200
"sv.q C000, 0 + %0\n" // out[0] = C000
"sv.q C010, 16 + %0\n" // out[1] = C010
"sv.q C020, 32 + %0\n" // out[2] = C020
".set pop\n" // restore assembler option
: "=m"( *out )
: "m"( *in1 ), "m"( *in2 )
);
#else
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] + in1[0][2] * in2[2][0];
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] + in1[0][2] * in2[2][1];
out[0][2] = in1[0][0] * in2[0][2] + in1[0][1] * in2[1][2] + in1[0][2] * in2[2][2];
@ -295,6 +364,7 @@ void Matrix4x4_ConcatTransforms( matrix4x4 out, const matrix4x4 in1, const matri
out[2][1] = in1[2][0] * in2[0][1] + in1[2][1] * in2[1][1] + in1[2][2] * in2[2][1];
out[2][2] = in1[2][0] * in2[0][2] + in1[2][1] * in2[1][2] + in1[2][2] * in2[2][2];
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] + in1[2][2] * in2[2][3] + in1[2][3];
#endif // __PSP__
}
void Matrix4x4_SetOrigin( matrix4x4 out, float x, float y, float z )
@ -338,11 +408,11 @@ void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_
if( angles[ROLL] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
SinCos( angle, &sp, &cp );
angle = angles[ROLL] * (M_PI*2 / 360);
sincos( angle, &sr, &cr );
SinCos( angle, &sr, &cr );
out[0][0] = (cp*cy) * scale;
out[0][1] = (sr*sp*cy+cr*-sy) * scale;
@ -364,9 +434,9 @@ void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_
else if( angles[PITCH] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
angle = angles[PITCH] * (M_PI*2 / 360);
sincos( angle, &sp, &cp );
SinCos( angle, &sp, &cp );
out[0][0] = (cp*cy) * scale;
out[0][1] = (-sy) * scale;
@ -388,7 +458,7 @@ void Matrix4x4_CreateFromEntity( matrix4x4 out, const vec3_t angles, const vec3_
else if( angles[YAW] )
{
angle = angles[YAW] * (M_PI*2 / 360);
sincos( angle, &sy, &cy );
SinCos( angle, &sy, &cy );
out[0][0] = (cy) * scale;
out[0][1] = (-sy) * scale;
@ -453,6 +523,34 @@ void Matrix4x4_ConvertToEntity( const matrix4x4 in, vec3_t angles, vec3_t origin
void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
{
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %2\n" // C100 = in[0]
"lv.q C110, 16 + %2\n" // C110 = in[1]
"lv.q C120, 32 + %2\n" // C120 = in[2]
"lv.s S200, 0 + %3\n" // S200 = normal[0]
"lv.s S201, 4 + %3\n" // S201 = normal[1]
"lv.s S202, 8 + %3\n" // S202 = normal[2]
"lv.s S210, %4\n" // S210 = d
"vdot.t S211, C100, C100\n" // S211 = C100 * C100
"vsqrt.s S211, S211\n" // S211 = sqrt( S211 )
"vrcp.s S212, S211\n" // S212 = 1 / S211
"vtfm3.t C000, M100, C200\n" // C000 = M100 * C200
"vscl.t C000, C000, S212\n" // C000 = C000 * S211
"vmul.s S003, S210, S211\n" // S003 = S210 * S211
"vdot.t S010, R103, C000\n" // S010 = R103 * C000
"vadd.s S003, S003, S010\n" // S003 = S003 + S010
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
"sv.s S003, %1\n" // dist = S003
".set pop\n" // restore assembler option
: "=m"( *out ), "=m"( *dist )
: "m"( *in ), "m"( *normal ), "m"( d )
);
#else
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
float iscale = 1.0f / scale;
@ -460,10 +558,39 @@ void Matrix4x4_TransformPositivePlane( const matrix4x4 in, const vec3_t normal,
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
*dist = d * scale + ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
#endif // __PSP__
}
void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal, float d, vec3_t out, float *dist )
{
#ifdef __PSP__
__asm__ (
".set push\n" // save assembler option
".set noreorder\n" // suppress reordering
"lv.q C100, 0 + %2\n" // C100 = in[0]
"lv.q C110, 16 + %2\n" // C110 = in[1]
"lv.q C120, 32 + %2\n" // C120 = in[2]
"lv.s S200, 0 + %3\n" // S200 = normal[0]
"lv.s S201, 4 + %3\n" // S201 = normal[1]
"lv.s S202, 8 + %3\n" // S202 = normal[2]
"lv.s S210, %4\n" // S210 = d
"vdot.t S211, C100, C100\n" // S211 = C100 * C100
"vsqrt.s S211, S211\n" // S211 = sqrt( S211 )
"vrcp.s S212, S211\n" // S212 = 1 / S211
"vtfm3.t C000, M100, C200\n" // C000 = M100 * C200
"vscl.t C000, C000, S212\n" // C000 = C000 * S211
"vmul.s S003, S210, S211\n" // S003 = S210 * S211
"vdot.t S010, R103, C000\n" // S010 = R103 * C000
"vsub.s S003, S003, S010\n" // S003 = S003 - S010
"sv.s S000, 0 + %0\n" // out[0] = S000
"sv.s S001, 4 + %0\n" // out[1] = S001
"sv.s S002, 8 + %0\n" // out[2] = S002
"sv.s S003, %1\n" // dist = S003
".set pop\n" // restore assembler option
: "=m"( *out ), "=m"( *dist )
: "m"( *in ), "m"( *normal ), "m"( d )
);
#else
float scale = sqrt( in[0][0] * in[0][0] + in[0][1] * in[0][1] + in[0][2] * in[0][2] );
float iscale = 1.0f / scale;
@ -471,6 +598,7 @@ void Matrix4x4_TransformStandardPlane( const matrix4x4 in, const vec3_t normal,
out[1] = (normal[0] * in[1][0] + normal[1] * in[1][1] + normal[2] * in[1][2]) * iscale;
out[2] = (normal[0] * in[2][0] + normal[1] * in[2][1] + normal[2] * in[2][2]) * iscale;
*dist = d * scale - ( out[0] * in[0][3] + out[1] * in[1][3] + out[2] * in[2][3] );
#endif // __PSP__
}
void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 )
@ -503,4 +631,4 @@ void Matrix4x4_Invert_Simple( matrix4x4 out, const matrix4x4 in1 )
out[3][1] = 0;
out[3][2] = 0;
out[3][3] = 1;
}
}

View file

@ -1980,23 +1980,6 @@ void M_GameOptions_Draw (void)
M_Print (160, 64, "Deathmatch");
M_Print (0, 72, " Teamplay");
if (rogue)
{
char *msg;
switch((int)teamplay.value)
{
case 1: msg = "No Friendly Fire"; break;
case 2: msg = "Friendly Fire"; break;
case 3: msg = "Tag"; break;
case 4: msg = "Capture the Flag"; break;
case 5: msg = "One Flag CTF"; break;
case 6: msg = "Three Team CTF"; break;
default: msg = "Off"; break;
}
M_Print (160, 72, msg);
}
else
{
char *msg;
@ -2032,33 +2015,11 @@ void M_GameOptions_Draw (void)
M_Print (160, 96, va("%i minutes", (int)timelimit.value));
M_Print (0, 112, " Episode");
//MED 01/06/97 added hipnotic episodes
if (hipnotic)
M_Print (160, 112, hipnoticepisodes[startepisode].description);
//PGM 01/07/97 added rogue episodes
else if (rogue)
M_Print (160, 112, rogueepisodes[startepisode].description);
else
M_Print (160, 112, episodes[startepisode].description);
M_Print (160, 112, episodes[startepisode].description);
M_Print (0, 120, " Level");
//MED 01/06/97 added hipnotic episodes
if (hipnotic)
{
M_Print (160, 120, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].description);
M_Print (160, 128, hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name);
}
//PGM 01/07/97 added rogue episodes
else if (rogue)
{
M_Print (160, 120, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].description);
M_Print (160, 128, roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name);
}
else
{
M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description);
M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name);
}
M_Print (160, 120, levels[episodes[startepisode].firstLevel + startlevel].description);
M_Print (160, 128, levels[episodes[startepisode].firstLevel + startlevel].name);
// line cursor
M_DrawCharacter (144, gameoptions_cursor_table[gameoptions_cursor], 12+((int)(realtime*4)&1));
@ -2106,10 +2067,7 @@ void M_NetStart_Change (int dir)
break;
case 3:
if (rogue)
count = 6;
else
count = 2;
count = 2;
Cvar_SetValue ("teamplay", teamplay.value + dir);
if (teamplay.value > count)
@ -2144,15 +2102,7 @@ void M_NetStart_Change (int dir)
case 7:
startepisode += dir;
//MED 01/06/97 added hipnotic count
if (hipnotic)
count = 6;
//PGM 01/07/97 added rogue count
//PGM 03/02/97 added 1 for dmatch episode
else if (rogue)
count = 4;
else
count = 2;
count = 2;
if (startepisode < 0)
startepisode = count - 1;
@ -2165,14 +2115,7 @@ void M_NetStart_Change (int dir)
case 8:
startlevel += dir;
//MED 01/06/97 added hipnotic episodes
if (hipnotic)
count = hipnoticepisodes[startepisode].levels;
//PGM 01/06/97 added hipnotic episodes
else if (rogue)
count = rogueepisodes[startepisode].levels;
else
count = episodes[startepisode].levels;
count = episodes[startepisode].levels;
if (startlevel < 0)
startlevel = count - 1;
@ -2226,13 +2169,7 @@ void M_GameOptions_Key (int key)
Cbuf_AddText ("listen 0\n"); // so host_netport will be re-examined
Cbuf_AddText ( va ("maxplayers %u\n", maxplayers) );
SCR_BeginLoadingPlaque ();
if (hipnotic)
Cbuf_AddText ( va ("map %s\n", hipnoticlevels[hipnoticepisodes[startepisode].firstLevel + startlevel].name) );
else if (rogue)
Cbuf_AddText ( va ("map %s\n", roguelevels[rogueepisodes[startepisode].firstLevel + startlevel].name) );
else
Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) );
Cbuf_AddText ( va ("map %s\n", levels[episodes[startepisode].firstLevel + startlevel].name) );
return;
}

File diff suppressed because it is too large Load diff

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -31,6 +31,11 @@ globalvars_t *pr_global_struct;
float *pr_globals; // same as pr_global_struct
int pr_edict_size; // in bytes
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
cvar_t pr_builtin_find = {"pr_builtin_find", "0", false, false};
cvar_t pr_builtin_remap = {"pr_builtin_remap", "0", false, false};
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
unsigned short pr_crc;
int type_size[8] = {1,sizeof(string_t)/4,1,3,1,1,sizeof(func_t)/4,sizeof(void *)/4};
@ -130,10 +135,10 @@ edict_t *ED_Alloc (void)
return e;
}
}
if (i == MAX_EDICTS)
Sys_Error ("ED_Alloc: no free edicts");
sv.num_edicts++;
e = EDICT_NUM(i);
ED_ClearEdict (e);
@ -153,7 +158,7 @@ void ED_Free (edict_t *ed)
{
// pathfind optimization:
closest_waypoints[NUM_FOR_EDICT(ed)] = -1;
SV_UnlinkEdict (ed); // unlink from world bsp
ed->free = true;
@ -167,7 +172,7 @@ void ED_Free (edict_t *ed)
VectorCopy (vec3_origin, ed->v.angles);
ed->v.nextthink = -1;
ed->v.solid = 0;
ed->freetime = sv.time;
}
@ -182,7 +187,7 @@ ddef_t *ED_GlobalAtOfs (int ofs)
{
ddef_t *def;
int i;
for (i=0 ; i<progs->numglobaldefs ; i++)
{
def = &pr_globaldefs[i];
@ -201,7 +206,7 @@ ddef_t *ED_FieldAtOfs (int ofs)
{
ddef_t *def;
int i;
for (i=0 ; i<progs->numfielddefs ; i++)
{
def = &pr_fielddefs[i];
@ -220,7 +225,7 @@ ddef_t *ED_FindField (char *name)
{
ddef_t *def;
int i;
for (i=0 ; i<progs->numfielddefs ; i++)
{
def = &pr_fielddefs[i];
@ -240,7 +245,7 @@ ddef_t *ED_FindGlobal (char *name)
{
ddef_t *def;
int i;
for (i=0 ; i<progs->numglobaldefs ; i++)
{
def = &pr_globaldefs[i];
@ -260,7 +265,7 @@ dfunction_t *ED_FindFunction (char *name)
{
dfunction_t *func;
int i;
for (i=0 ; i<progs->numfunctions ; i++)
{
func = &pr_functions[i];
@ -270,7 +275,7 @@ dfunction_t *ED_FindFunction (char *name)
return NULL;
}
/*
eval_t *GetEdictFieldValue(edict_t *ed, char *field)
{
ddef_t *def = NULL;
@ -301,7 +306,7 @@ Done:
return (eval_t *)((char *)&ed->v + def->ofs*4);
}
*/
/*
============
@ -315,7 +320,7 @@ char *PR_ValueString (etype_t type, eval_t *val)
static char line[256];
ddef_t *def;
dfunction_t *f;
type &= ~DEF_SAVEGLOBAL;
switch (type)
@ -323,7 +328,7 @@ char *PR_ValueString (etype_t type, eval_t *val)
case ev_string:
sprintf (line, "%s", pr_strings + val->string);
break;
case ev_entity:
case ev_entity:
sprintf (line, "entity %i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)) );
break;
case ev_function:
@ -350,7 +355,7 @@ char *PR_ValueString (etype_t type, eval_t *val)
sprintf (line, "bad type %i", type);
break;
}
return line;
}
@ -367,7 +372,7 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
static char line[256];
ddef_t *def;
dfunction_t *f;
type &= ~DEF_SAVEGLOBAL;
switch (type)
@ -375,7 +380,7 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
case ev_string:
sprintf (line, "%s", pr_strings + val->string);
break;
case ev_entity:
case ev_entity:
sprintf (line, "%i", NUM_FOR_EDICT(PROG_TO_EDICT(val->edict)));
break;
case ev_function:
@ -399,7 +404,7 @@ char *PR_UglyValueString (etype_t type, eval_t *val)
sprintf (line, "bad type %i", type);
break;
}
return line;
}
@ -418,22 +423,22 @@ char *PR_GlobalString (int ofs)
ddef_t *def;
void *val;
static char line[128];
val = (void *)&pr_globals[ofs];
def = ED_GlobalAtOfs(ofs);
if (!def)
sprintf (line,"%i(???)", ofs);
sprintf (line,"%i(?\?\?)", ofs);
else
{
s = PR_ValueString (def->type, val);
sprintf (line,"%i(%s)%s", ofs, pr_strings + def->s_name, s);
}
i = strlen(line);
for ( ; i<20 ; i++)
strcat (line," ");
strcat (line," ");
return line;
}
@ -442,18 +447,18 @@ char *PR_GlobalStringNoContents (int ofs)
int i;
ddef_t *def;
static char line[128];
def = ED_GlobalAtOfs(ofs);
if (!def)
sprintf (line,"%i(???)", ofs);
sprintf (line,"%i(?\?\?)", ofs);
else
sprintf (line,"%i(%s)", ofs, pr_strings + def->s_name);
i = strlen(line);
for ( ; i<20 ; i++)
strcat (line," ");
strcat (line," ");
return line;
}
@ -487,24 +492,24 @@ void ED_Print (edict_t *ed)
name = pr_strings + d->s_name;
if (name[strlen(name)-2] == '_')
continue; // skip _x, _y, _z vars
v = (int *)((char *)&ed->v + d->ofs*4);
// if the value is still all 0, skip the field
type = d->type & ~DEF_SAVEGLOBAL;
for (j=0 ; j<type_size[type] ; j++)
if (v[j])
break;
if (j == type_size[type])
continue;
Con_Printf ("%s",name);
l = strlen (name);
while (l++ < 15)
Con_Printf (" ");
Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v));
Con_Printf ("%s\n", PR_ValueString(d->type, (eval_t *)v));
}
}
@ -530,14 +535,14 @@ void ED_Write (FILE *f, edict_t *ed)
fprintf (f, "}\n");
return;
}
for (i=1 ; i<progs->numfielddefs ; i++)
{
d = &pr_fielddefs[i];
name = pr_strings + d->s_name;
if (name[strlen(name)-2] == '_')
continue; // skip _x, _y, _z vars
v = (int *)((char *)&ed->v + d->ofs*4);
// if the value is still all 0, skip the field
@ -547,9 +552,9 @@ void ED_Write (FILE *f, edict_t *ed)
break;
if (j == type_size[type])
continue;
fprintf (f,"\"%s\" ",name);
fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
fprintf (f,"\"%s\"\n", PR_UglyValueString(d->type, (eval_t *)v));
}
fprintf (f, "}\n");
@ -570,7 +575,7 @@ For debugging, prints all the entities in the current server
void ED_PrintEdicts (void)
{
int i;
Con_Printf ("%i entities\n", sv.num_edicts);
for (i=0 ; i<sv.num_edicts ; i++)
ED_PrintNum (i);
@ -586,7 +591,7 @@ For debugging, prints a single edicy
void ED_PrintEdict_f (void)
{
int i;
i = Q_atoi (Cmd_Argv(1));
if (i >= sv.num_edicts)
{
@ -667,9 +672,9 @@ void ED_WriteGlobals (FILE *f)
&& type != ev_entity)
continue;
name = pr_strings + def->s_name;
name = pr_strings + def->s_name;
fprintf (f,"\"%s\" ", name);
fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
fprintf (f,"\"%s\"\n", PR_UglyValueString(type, (eval_t *)&pr_globals[def->ofs]));
}
fprintf (f,"}\n");
}
@ -685,7 +690,7 @@ void ED_ParseGlobals (char *data)
ddef_t *key;
while (1)
{
{
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
@ -695,7 +700,7 @@ void ED_ParseGlobals (char *data)
strcpy (keyname, com_token);
// parse value
// parse value
data = COM_Parse (data);
if (!data)
Sys_Error ("ED_ParseEntity: EOF without closing brace");
@ -727,7 +732,7 @@ char *ED_NewString (char *string)
{
char *new, *new_p;
int i,l;
l = strlen(string) + 1;
new = Hunk_Alloc (l);
new_p = new;
@ -745,7 +750,7 @@ char *ED_NewString (char *string)
else
*new_p++ = string[i];
}
return new;
}
@ -766,19 +771,19 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
char *v, *w;
void *d;
dfunction_t *func;
d = (void *)((int *)base + key->ofs);
switch (key->type & ~DEF_SAVEGLOBAL)
{
case ev_string:
*(string_t *)d = ED_NewString (s) - pr_strings;
break;
case ev_float:
*(float *)d = atof (s);
break;
case ev_vector:
strcpy (string, s);
v = string;
@ -792,11 +797,11 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
w = v = v+1;
}
break;
case ev_entity:
*(int *)d = EDICT_TO_PROG(EDICT_NUM(atoi (s)));
break;
case ev_field:
def = ED_FindField (s);
if (!def)
@ -806,7 +811,7 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
}
*(int *)d = G_INT(def->ofs);
break;
case ev_function:
func = ED_FindFunction (s);
if (!func)
@ -816,7 +821,7 @@ qboolean ED_ParseEpair (void *base, ddef_t *key, char *s)
}
*(func_t *)d = func - pr_functions;
break;
default:
break;
}
@ -848,14 +853,14 @@ char *ED_ParseEdict (char *data, edict_t *ent)
// go through all the dictionary pairs
while (1)
{
{
// parse key
data = COM_Parse (data);
if (com_token[0] == '}')
break;
if (!data)
Sys_Error ("ED_ParseEntity: EOF without closing brace");
// anglehack is to allow QuakeEd to write single scalar angles
// and allow them to be turned into vectors. (FIXME...)
if (!strcmp(com_token, "angle"))
@ -880,7 +885,7 @@ if (!strcmp(com_token, "light"))
n--;
}
// parse value
// parse value
data = COM_Parse (data);
if (!data)
Sys_Error ("ED_ParseEntity: EOF without closing brace");
@ -888,17 +893,25 @@ if (!strcmp(com_token, "light"))
if (com_token[0] == '}')
Sys_Error ("ED_ParseEntity: closing brace without data");
init = true;
init = true;
// keynames with a leading underscore are used for utility comments,
// and are immediately discarded by quake
if (keyname[0] == '_')
continue;
key = ED_FindField (keyname);
if (!key)
{
Con_Printf ("'%s' is not a field\n", keyname);
if (strcmp (keyname, "compiler") &&
strcmp (keyname, "r_skycolor") &&
strcmp (keyname, "sequence") &&
strcmp (keyname, "message2") && //dirty hack to keep the console clean. Dem lazy mappers
strcmp (keyname, "mangle") &&
strcmp (keyname, "Maxrange") &&
strcmp (keyname, "light_lev") &&
strcmp (keyname, "fog"))
Con_Printf ("'%s' is not a field\n", keyname);
continue;
}
@ -936,19 +949,19 @@ to call ED_CallSpawnFunctions () to let the objects initialize themselves.
================
*/
void ED_LoadFromFile (char *data)
{
{
edict_t *ent;
int inhibit;
dfunction_t *func;
ent = NULL;
inhibit = 0;
pr_global_struct->time = sv.time;
// parse ents
while (1)
{
// parse the opening brace
// parse the opening brace
data = COM_Parse (data);
if (!data)
break;
@ -985,14 +998,12 @@ void ED_LoadFromFile (char *data)
pr_global_struct->self = EDICT_TO_PROG(ent);
PR_ExecuteProgram (func - pr_functions);
}
}
Con_DPrintf ("%i entities inhibited\n", inhibit);
}
func_t EndFrame;
/*
===============
PR_LoadProgs
@ -1002,6 +1013,11 @@ void PR_LoadProgs (void)
{
dfunction_t *f;
int i;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
int j;
int funcno;
char *funcname;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
// flush the non-C variable lookup cache
for (i=0 ; i<GEFV_CACHESIZE ; i++)
@ -1010,8 +1026,12 @@ void PR_LoadProgs (void)
CRC_Init (&pr_crc);
progs = (dprograms_t *)COM_LoadHunkFile ("progs.dat");
if (!progs)
Sys_Error ("PR_LoadProgs: couldn't load progs.dat");
if (!progs) {
Sys_Error("PR_LoadProgs: couldn't load progs.dat");
Host_Error ("PR_LoadProgs: couldn't load progs.dat");
}
Con_DPrintf ("Programs occupy %iK.\n", com_filesize/1024);
for (i=0 ; i<com_filesize ; i++)
@ -1019,7 +1039,7 @@ void PR_LoadProgs (void)
// byte swap the header
for (i=0 ; i<sizeof(*progs)/4 ; i++)
((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
((int *)progs)[i] = LittleLong ( ((int *)progs)[i] );
pr_functions = (dfunction_t *)((byte *)progs + progs->ofs_functions);
pr_strings = (char *)progs + progs->ofs_strings;
@ -1029,9 +1049,9 @@ void PR_LoadProgs (void)
pr_global_struct = (globalvars_t *)((byte *)progs + progs->ofs_globals);
pr_globals = (float *)pr_global_struct;
pr_edict_size = progs->entityfields * 4 + sizeof (edict_t) - sizeof(entvars_t);
// byte swap the lumps
for (i=0 ; i<progs->numstatements ; i++)
{
@ -1041,6 +1061,33 @@ void PR_LoadProgs (void)
pr_statements[i].c = LittleShort(pr_statements[i].c);
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
// initialize function numbers for PROGS.DAT
pr_numbuiltins = 0;
pr_builtins = NULL;
if (pr_builtin_remap.value)
{
// remove all previous assigned function numbers
for ( j=1 ; j < pr_ebfs_numbuiltins; j++)
{
pr_ebfs_builtins[j].funcno = 0;
}
}
else
{
// use default function numbers
for ( j=1 ; j < pr_ebfs_numbuiltins; j++)
{
pr_ebfs_builtins[j].funcno = pr_ebfs_builtins[j].default_funcno;
// determine highest builtin number (when NOT remapped)
if (pr_ebfs_builtins[j].funcno > pr_numbuiltins)
{
pr_numbuiltins = pr_ebfs_builtins[j].funcno;
}
}
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
for (i=0 ; i<progs->numfunctions; i++)
{
pr_functions[i].first_statement = LittleLong (pr_functions[i].first_statement);
@ -1049,7 +1096,104 @@ void PR_LoadProgs (void)
pr_functions[i].s_file = LittleLong (pr_functions[i].s_file);
pr_functions[i].numparms = LittleLong (pr_functions[i].numparms);
pr_functions[i].locals = LittleLong (pr_functions[i].locals);
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
if (pr_builtin_remap.value)
{
if (pr_functions[i].first_statement < 0) // builtin function
{
funcno = -pr_functions[i].first_statement;
funcname = pr_strings + pr_functions[i].s_name;
// search function name
for ( j=1 ; j < pr_ebfs_numbuiltins ; j++)
{
if (!(Q_strcasecmp(funcname, pr_ebfs_builtins[j].funcname)))
{
break; // found
}
}
if (j < pr_ebfs_numbuiltins) // found
{
pr_ebfs_builtins[j].funcno = funcno;
}
else
{
Con_DPrintf("Can not assign builtin number #%i to %s - function unknown\n", funcno, funcname);
}
}
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm start
if (pr_builtin_remap.value)
{
// check for unassigned functions and try to assign their default function number
for ( i=1 ; i < pr_ebfs_numbuiltins; i++)
{
if ((!pr_ebfs_builtins[i].funcno) && (pr_ebfs_builtins[i].default_funcno)) // unassigned and has a default number
{
// check if default number is already assigned to another function
for ( j=1 ; j < pr_ebfs_numbuiltins; j++)
{
if (pr_ebfs_builtins[j].funcno == pr_ebfs_builtins[i].default_funcno)
{
break; // number already assigned to another builtin function
}
}
if (j < pr_ebfs_numbuiltins) // already assigned
{
Con_DPrintf("Can not assign default builtin number #%i to %s - number is already assigned to %s\n",
pr_ebfs_builtins[i].default_funcno, pr_ebfs_builtins[i].funcname, pr_ebfs_builtins[j].funcname);
}
else
{
pr_ebfs_builtins[i].funcno = pr_ebfs_builtins[i].default_funcno;
}
}
// determine highest builtin number (when remapped)
if (pr_ebfs_builtins[i].funcno > pr_numbuiltins)
{
pr_numbuiltins = pr_ebfs_builtins[i].funcno;
}
}
}
pr_numbuiltins++;
// allocate and initialize builtin list for execution time
pr_builtins = Hunk_AllocName (pr_numbuiltins*sizeof(builtin_t), "builtins");
for ( i=0 ; i < pr_numbuiltins ; i++)
{
pr_builtins[i] = pr_ebfs_builtins[0].function;
}
// create builtin list for execution time and set cvars accordingly
Cvar_Set("pr_builtin_find", "0");
// Cvar_Set("pr_checkextension", "0"); // 2001-10-20 Extension System by Lord Havoc/Maddes (DP compatibility)
for ( j=1 ; j < pr_ebfs_numbuiltins ; j++)
{
if (pr_ebfs_builtins[j].funcno) // only put assigned functions into builtin list
{
pr_builtins[pr_ebfs_builtins[j].funcno] = pr_ebfs_builtins[j].function;
}
if (pr_ebfs_builtins[j].default_funcno == PR_DEFAULT_FUNCNO_BUILTIN_FIND)
{
Cvar_SetValue("pr_builtin_find", pr_ebfs_builtins[j].funcno);
}
// 2001-10-20 Extension System by Lord Havoc/Maddes (DP compatibility) start
// not implemented yet
/*
if (pr_ebfs_builtins[j].default_funcno == PR_DEFAULT_FUNCNO_EXTENSION_FIND)
{
Cvar_SetValue("pr_checkextension", pr_ebfs_builtins[j].funcno);
}
*/
// 2001-10-20 Extension System by Lord Havoc/Maddes (DP compatibility) end
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes/Firestorm end
for (i=0 ; i<progs->numglobaldefs ; i++)
{
@ -1077,6 +1221,51 @@ void PR_LoadProgs (void)
EndFrame = (func_t)(f - pr_functions);
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
/*
=============
PR_BuiltInList_f
For debugging, prints all builtin functions with assigned and default number
=============
*/
void PR_BuiltInList_f (void)
{
int i;
char *partial;
int len;
int count;
if (Cmd_Argc() > 1)
{
partial = Cmd_Argv (1);
len = strlen(partial);
}
else
{
partial = NULL;
len = 0;
}
count=0;
for (i=1; i < pr_ebfs_numbuiltins; i++)
{
if (partial && Q_strncasecmp (partial, pr_ebfs_builtins[i].funcname, len))
{
continue;
}
count++;
Con_Printf ("%i(%i): %s\n", pr_ebfs_builtins[i].funcno, pr_ebfs_builtins[i].default_funcno, pr_ebfs_builtins[i].funcname);
}
Con_Printf ("------------\n");
if (partial)
{
Con_Printf ("%i beginning with \"%s\" out of ", count, partial);
}
Con_Printf ("%i builtin functions\n", i);
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
/*
===============
@ -1100,11 +1289,16 @@ void PR_Init (void)
Cvar_RegisterVariable (&saved2);
Cvar_RegisterVariable (&saved3);
Cvar_RegisterVariable (&saved4);
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
Cvar_RegisterVariable (&pr_builtin_find);
Cvar_RegisterVariable (&pr_builtin_remap);
Cmd_AddCommand ("builtinlist", PR_BuiltInList_f); // 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
}
edict_t *EDICT_NUM(int n)
inline edict_t *EDICT_NUM(int n)
{
if (n < 0 || n >= sv.max_edicts)
Sys_Error ("EDICT_NUM: bad number %i", n);
@ -1114,10 +1308,10 @@ edict_t *EDICT_NUM(int n)
int NUM_FOR_EDICT(edict_t *e)
{
int b;
b = (byte *)e - (byte *)sv.edicts;
b = b / pr_edict_size;
if (b < 0 || b >= sv.num_edicts)
Sys_Error ("NUM_FOR_EDICT: bad pointer");
return b;

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
/*
*/
@ -52,43 +51,43 @@ char *pr_opnames[] =
"DONE",
"MUL_F",
"MUL_V",
"MUL_V",
"MUL_FV",
"MUL_VF",
"DIV",
"ADD_F",
"ADD_V",
"ADD_V",
"SUB_F",
"SUB_V",
"EQ_F",
"EQ_V",
"EQ_S",
"EQ_S",
"EQ_E",
"EQ_FNC",
"NE_F",
"NE_V",
"NE_V",
"NE_S",
"NE_E",
"NE_E",
"NE_FNC",
"LE",
"GE",
"LT",
"GT",
"GT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"INDIRECT",
"ADDRESS",
"ADDRESS",
"STORE_F",
"STORE_V",
@ -105,16 +104,16 @@ char *pr_opnames[] =
"STOREP_FNC",
"RETURN",
"NOT_F",
"NOT_V",
"NOT_S",
"NOT_ENT",
"NOT_FNC",
"NOT_S",
"NOT_ENT",
"NOT_FNC",
"IF",
"IFNOT",
"CALL0",
"CALL1",
"CALL2",
@ -124,13 +123,13 @@ char *pr_opnames[] =
"CALL6",
"CALL7",
"CALL8",
"STATE",
"GOTO",
"GOTO",
"AND",
"OR",
"OR",
"BITAND",
"BITOR"
@ -150,7 +149,7 @@ PR_PrintStatement
void PR_PrintStatement (dstatement_t *s)
{
int i;
if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
{
Con_Printf ("%s ", pr_opnames[s->op]);
@ -158,7 +157,7 @@ void PR_PrintStatement (dstatement_t *s)
for ( ; i<10 ; i++)
Con_Printf (" ");
}
if (s->op == OP_IF || s->op == OP_IFNOT)
Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
else if (s->op == OP_GOTO)
@ -191,24 +190,24 @@ void PR_StackTrace (void)
{
dfunction_t *f;
int i;
if (pr_depth == 0)
{
Con_Printf ("<NO STACK>\n");
return;
}
pr_stack[pr_depth].f = pr_xfunction;
for (i=pr_depth ; i>=0 ; i--)
{
f = pr_stack[i].f;
if (!f)
{
Con_Printf ("<NO FUNCTION>\n");
}
else
Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);
Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);
}
}
@ -225,8 +224,8 @@ void PR_Profile_f (void)
int max;
int num;
int i;
num = 0;
num = 0;
do
{
max = 0;
@ -270,7 +269,7 @@ void PR_RunError (char *error, ...)
PR_PrintStatement (pr_statements + pr_xstatement);
PR_StackTrace ();
Con_Printf ("%s\n", string);
pr_depth = 0; // dump the stack so host_error can shutdown functions
Host_Error ("Program error");
@ -296,7 +295,7 @@ int PR_EnterFunction (dfunction_t *f)
int i, j, c, o;
pr_stack[pr_depth].s = pr_xstatement;
pr_stack[pr_depth].f = pr_xfunction;
pr_stack[pr_depth].f = pr_xfunction;
pr_depth++;
if (pr_depth >= MAX_STACK_DEPTH)
PR_RunError ("stack overflow");
@ -369,6 +368,10 @@ void PR_ExecuteProgram (func_t fnum)
edict_t *ed;
int exitdepth;
eval_t *ptr;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
char *funcname;
char *remaphint;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
if (!fnum || fnum >= progs->numfunctions)
{
@ -376,7 +379,7 @@ void PR_ExecuteProgram (func_t fnum)
ED_Print (PROG_TO_EDICT(pr_global_struct->self));
Host_Error ("PR_ExecuteProgram: NULL function");
}
f = &pr_functions[fnum];
runaway = 400000;
@ -386,7 +389,7 @@ void PR_ExecuteProgram (func_t fnum)
exitdepth = pr_depth;
s = PR_EnterFunction (f);
while (1)
{
s++; // next statement
@ -395,16 +398,16 @@ while (1)
a = (eval_t *)&pr_globals[st->a];
b = (eval_t *)&pr_globals[st->b];
c = (eval_t *)&pr_globals[st->c];
if (!--runaway)
PR_RunError ("runaway loop error");
pr_xfunction->profile++;
pr_xstatement = s;
if (pr_trace)
PR_PrintStatement (st);
switch (st->op)
{
case OP_ADD_F:
@ -415,7 +418,7 @@ while (1)
c->vector[1] = a->vector[1] + b->vector[1];
c->vector[2] = a->vector[2] + b->vector[2];
break;
case OP_SUB_F:
c->_float = a->_float - b->_float;
break;
@ -447,16 +450,16 @@ while (1)
case OP_DIV_F:
c->_float = a->_float / b->_float;
break;
case OP_BITAND:
c->_float = (int)a->_float & (int)b->_float;
break;
case OP_BITOR:
c->_float = (int)a->_float | (int)b->_float;
break;
case OP_GE:
c->_float = a->_float >= b->_float;
break;
@ -475,7 +478,7 @@ while (1)
case OP_OR:
c->_float = a->_float || b->_float;
break;
case OP_NOT_F:
c->_float = !a->_float;
break;
@ -542,7 +545,7 @@ while (1)
b->vector[1] = a->vector[1];
b->vector[2] = a->vector[2];
break;
case OP_STOREP_F:
case OP_STOREP_ENT:
case OP_STOREP_FLD: // integers
@ -557,57 +560,49 @@ while (1)
ptr->vector[1] = a->vector[1];
ptr->vector[2] = a->vector[2];
break;
case OP_ADDRESS:
ed = PROG_TO_EDICT(a->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
if (ed == (edict_t *)sv.edicts && sv.state == ss_active)
PR_RunError ("assignment to world entity");
c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
break;
case OP_LOAD_F:
case OP_LOAD_FLD:
case OP_LOAD_ENT:
case OP_LOAD_S:
case OP_LOAD_FNC:
ed = PROG_TO_EDICT(a->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
a = (eval_t *)((int *)&ed->v + b->_int);
c->_int = a->_int;
break;
case OP_LOAD_V:
ed = PROG_TO_EDICT(a->edict);
#ifdef PARANOID
NUM_FOR_EDICT(ed); // make sure it's in range
#endif
a = (eval_t *)((int *)&ed->v + b->_int);
c->vector[0] = a->vector[0];
c->vector[1] = a->vector[1];
c->vector[2] = a->vector[2];
break;
//==================
case OP_IFNOT:
if (!a->_int)
s += st->b - 1; // offset the s++
break;
case OP_IF:
if (a->_int)
s += st->b - 1; // offset the s++
break;
case OP_GOTO:
s += st->a - 1; // offset the s++
break;
case OP_CALL0:
case OP_CALL1:
case OP_CALL2:
@ -620,14 +615,26 @@ while (1)
pr_argc = st->op - OP_CALL0;
if (!a->function)
PR_RunError ("NULL function");
newf = &pr_functions[a->function];
if (newf->first_statement < 0)
{ // negative statements are built in functions
i = -newf->first_statement;
if (i >= pr_numbuiltins)
PR_RunError ("Bad builtin call number");
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
if ( (i >= pr_numbuiltins)
|| (pr_builtins[i] == pr_ebfs_builtins[0].function) )
{
funcname = pr_strings + newf->s_name;
if (pr_builtin_remap.value)
{
remaphint = NULL;
}
else
{
remaphint = "Try \"builtin remapping\" by setting PR_BUILTIN_REMAP to 1\n";
}
PR_RunError ("Bad builtin call number %i for %s\nPlease contact the PROGS.DAT author\nUse BUILTINLIST to see all assigned builtin functions\n%s", i, funcname, remaphint);
}
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
pr_builtins[i] ();
break;
}
@ -640,26 +647,22 @@ while (1)
pr_globals[OFS_RETURN] = pr_globals[st->a];
pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
s = PR_LeaveFunction ();
if (pr_depth == exitdepth)
return; // all done
break;
case OP_STATE:
ed = PROG_TO_EDICT(pr_global_struct->self);
#ifdef FPS_20
ed->v.nextthink = pr_global_struct->time + 0.05;
#else
ed->v.nextthink = pr_global_struct->time + 0.1;
#endif
if (a->_float != ed->v.frame)
{
ed->v.frame = a->_float;
}
ed->v.think = b->function;
break;
default:
PR_RunError ("Bad opcode %i", st->op);
}

View file

@ -121,6 +121,26 @@ typedef void (*builtin_t) (void);
extern builtin_t *pr_builtins;
extern int pr_numbuiltins;
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start
typedef struct ebfs_builtin_s
{
int default_funcno;
char *funcname;
builtin_t function;
int funcno;
} ebfs_builtin_t;
extern ebfs_builtin_t pr_ebfs_builtins[];
extern int pr_ebfs_numbuiltins;
#define PR_DEFAULT_FUNCNO_BUILTIN_FIND 100
extern cvar_t pr_builtin_find;
extern cvar_t pr_builtin_remap;
#define PR_DEFAULT_FUNCNO_EXTENSION_FIND 99 // 2001-10-20 Extension System by Lord Havoc/Maddes
// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end
extern int pr_argc;
extern qboolean pr_trace;
@ -134,5 +154,5 @@ void PR_RunError (char *error, ...);
void ED_PrintEdicts (void);
void ED_PrintNum (int ent);
eval_t *GetEdictFieldValue(edict_t *ed, char *field);
#define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((byte *)&ed->v + fieldoffset) : NULL)
//eval_t *GetEdictFieldValue(edict_t *ed, char *field);
#define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((byte *)&ed->v + fieldoffset) : NULL)

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -40,6 +40,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define U_SKIN (1<<13)
#define U_EFFECTS (1<<14)
// Tomaz - QC Alpha Scale Glow Control Begin
#define U_LONGENTITY (1<<15)//blubs here, U_EXTEND1 used to be here, but it needs to be in the byte above, so moved it to the 1<<8 position, and moved the rest down
#define U_RENDERMODE (1<<16)
@ -48,10 +49,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define U_RENDERCOLOR2 (1<<19)
#define U_RENDERCOLOR3 (1<<20)
#define U_EXTEND2 (1<<21) // another byte to follow
#define U_FRAMETIME (1<<22) // another byte to follow
// Tomaz - QC Alpha Scale Glow Control End
#define U_SCALE (1<<23)
#define SU_VIEWHEIGHT (1<<0)
#define SU_IDEALPITCH (1<<1)
#define SU_PUNCH1 (1<<2)
@ -79,6 +80,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define ENTSCALE_ENCODE(a) ((a) ? ((a) * ENTSCALE_DEFAULT) : ENTSCALE_DEFAULT) // Convert to byte
#define ENTSCALE_DECODE(a) ((float)(a) / ENTSCALE_DEFAULT) // Convert to float for rendering
// defaults for clientinfo messages
#define DEFAULT_VIEWHEIGHT 22
@ -108,7 +110,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_stufftext 9 // [string] stuffed into client's console buffer
// the string should be \n terminated
#define svc_setangle 10 // [angle3] set the view angle to this absolute value
#define svc_serverinfo 11 // [long] version
// [string] signon string
// [string]..[0]model cache
@ -116,17 +118,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define svc_lightstyle 12 // [byte] [string]
#define svc_updatename 13 // [byte] [string]
#define svc_updatepoints 14 // [byte] [short]
#define svc_clientdata 15 // <shortbits + data>
#define svc_stopsound 16 // <see code>
#define svc_updatecolors 17 // [byte] [byte]
#define svc_particle 18 // [vec3] <variable>
#define svc_damage 19
#define svc_spawnstatic 20
// svc_spawnbinary 21
#define svc_spawnbaseline 22
#define svc_temp_entity 23
#define svc_setpause 24 // [byte] on / off
@ -188,10 +188,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define TE_LAVASPLASH 10
#define TE_TELEPORT 11
#define TE_EXPLOSION2 12
// PGM 01/21/97
// PGM 01/21/97
#define TE_BEAM 13
// PGM 01/21/97
// PGM 01/21/97
#define TE_RAYSPLASHGREEN 14
#define TE_RAYSPLASHRED 15
#define TE_RAYSPLASHRED 15

View file

@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
This program 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.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
@ -21,6 +21,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "quakedef.h"
/*#ifdef PSP_VFPU
#include <pspmath.h>
#endif*/
/*
entities never clip against themselves, or their owner
@ -78,19 +82,19 @@ void SV_InitBoxHull (void)
for (i=0 ; i<6 ; i++)
{
box_clipnodes[i].planenum = i;
side = i&1;
box_clipnodes[i].children[side] = CONTENTS_EMPTY;
if (i != 5)
box_clipnodes[i].children[side^1] = i + 1;
else
box_clipnodes[i].children[side^1] = CONTENTS_SOLID;
box_planes[i].type = i>>1;
box_planes[i].normal[i>>1] = 1;
}
}
@ -114,8 +118,6 @@ hull_t *SV_HullForBox (vec3_t mins, vec3_t maxs)
return &box_hull;
}
/*
================
SV_HullForEntity
@ -126,64 +128,72 @@ Offset is filled in to contain the adjustment that must be added to the
testing object's origin to get a point to use with the returned hull.
================
*/
hull_t *SV_HullForEntity(edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset, edict_t *move_ent)
{
model_t *model;
vec3_t size, hullmins, hullmaxs;
vec3_t size;
vec3_t hullmins, hullmaxs;
hull_t *hull;
// decide which clipping hull to use, based on the size
// decide which clipping hull to use, based on the size
if (ent->v.solid == SOLID_BSP)
{ // explicit hulls in the BSP model
{ // explicit hulls in the BSP model
if (ent->v.movetype != MOVETYPE_PUSH)
Sys_Error("SOLID_BSP without MOVETYPE_PUSH");
Sys_Error ("SOLID_BSP without MOVETYPE_PUSH");
model = sv.models[(int)ent->v.modelindex];
model = sv.models[ (int)ent->v.modelindex ];
if (!model || model->type != mod_brush)
Sys_Error("MOVETYPE_PUSH with a non-bsp model");
Sys_Error ("MOVETYPE_PUSH with a non bsp model");
VectorSubtract (maxs, mins, size);
VectorSubtract(maxs, mins, size);
if (model->bspversion == HL_BSPVERSION)
{
if (size[0] < 3)
if (model->bspversion == HL_BSPVERSION)
{
hull = &model->hulls[0]; // 0x0x0
}
else if (size[0] <= 32)
{
if (size[2] < 54) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1]; // 32x32x72
if (size[0] < 3)
{
hull = &model->hulls[0]; // 0x0x0
}
else if (size[0] <= 32)
{
if (size[2] < 54) // pick the nearest of 36 or 72
hull = &model->hulls[3]; // 32x32x36
else
hull = &model->hulls[1]; // 32x32x72
}
else
{
hull = &model->hulls[2]; // 64x64x64
}
}
else
{
hull = &model->hulls[2]; // 64x64x64
}
}
else
{
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else
hull = &model->hulls[2];
}
// calculate an offset value to center the origin
VectorSubtract(hull->clip_mins, mins, offset);
VectorAdd(offset, ent->v.origin, offset);
{
if (size[0] < 3)
hull = &model->hulls[0];
else if (size[0] <= 32)
hull = &model->hulls[1];
else if (size[0] <= 32 && size[2] <= 28) // Crouch
hull = &model->hulls[3];
else
hull = &model->hulls[2];
}
}
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorAdd (offset, ent->v.origin, offset);
}
else
{ // create a temp hull from bounding box sizes
VectorSubtract(ent->v.mins, maxs, hullmins);
VectorSubtract(ent->v.maxs, mins, hullmaxs);
hull = SV_HullForBox(hullmins, hullmaxs);
VectorCopy(ent->v.origin, offset);
VectorSubtract (ent->v.mins, maxs, hullmins);
VectorSubtract (ent->v.maxs, mins, hullmaxs);
hull = SV_HullForBox (hullmins, hullmaxs);
VectorCopy (ent->v.origin, offset);
}
return hull;
}
@ -227,28 +237,28 @@ areanode_t *SV_CreateAreaNode (int depth, vec3_t mins, vec3_t maxs)
ClearLink (&anode->trigger_edicts);
ClearLink (&anode->solid_edicts);
if (depth == AREA_DEPTH)
{
anode->axis = -1;
anode->children[0] = anode->children[1] = NULL;
return anode;
}
VectorSubtract (maxs, mins, size);
if (size[0] > size[1])
anode->axis = 0;
else
anode->axis = 1;
anode->dist = 0.5 * (maxs[anode->axis] + mins[anode->axis]);
VectorCopy (mins, mins1);
VectorCopy (mins, mins2);
VectorCopy (maxs, maxs1);
VectorCopy (maxs, maxs2);
VectorCopy (mins, mins1);
VectorCopy (mins, mins2);
VectorCopy (maxs, maxs1);
VectorCopy (maxs, maxs2);
maxs1[anode->axis] = mins2[anode->axis] = anode->dist;
anode->children[0] = SV_CreateAreaNode (depth+1, mins2, maxs2);
anode->children[1] = SV_CreateAreaNode (depth+1, mins1, maxs1);
@ -264,7 +274,7 @@ SV_ClearWorld
void SV_ClearWorld (void)
{
SV_InitBoxHull ();
memset (sv_areanodes, 0, sizeof(sv_areanodes));
sv_numareanodes = 0;
SV_CreateAreaNode (0, sv.worldmodel->mins, sv.worldmodel->maxs);
@ -389,6 +399,7 @@ void SV_TouchLinks (edict_t *ent)
Hunk_FreeToLowMark (mark);
}
/*
===============
SV_FindTouchedLeafs
@ -404,7 +415,7 @@ void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
if (node->contents == CONTENTS_SOLID)
return;
// add an efrag if the node is a leaf
if ( node->contents < 0)
@ -416,19 +427,19 @@ void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
leafnum = leaf - sv.worldmodel->leafs - 1;
ent->leafnums[ent->num_leafs] = leafnum;
ent->num_leafs++;
ent->num_leafs++;
return;
}
// NODE_MIXED
splitplane = node->plane;
sides = BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, splitplane);
// recurse down the contacted sides
if (sides & 1)
SV_FindTouchedLeafs (ent, node->children[0]);
if (sides & 2)
SV_FindTouchedLeafs (ent, node->children[1]);
}
@ -540,10 +551,10 @@ int SV_HullPointContents (hull_t *hull, int num, vec3_t p)
{
if (num < hull->firstclipnode || num > hull->lastclipnode)
Sys_Error ("SV_HullPointContents: bad node number");
node = hull->clipnodes + num;
plane = hull->planes + node->planenum;
if (plane->type < 3)
d = p[plane->type] - plane->dist;
else
@ -553,7 +564,7 @@ int SV_HullPointContents (hull_t *hull, int num, vec3_t p)
else
num = node->children[0];
}
return num;
}
@ -595,10 +606,10 @@ edict_t *SV_TestEntityPosition (edict_t *ent)
trace_t trace;
trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, 0, ent);
if (trace.startsolid)
return sv.edicts;
return NULL;
}
@ -792,6 +803,56 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, vec3_t p1, vec3_t p2, tra
}
}
/*
==================
SV_WorldTransformAABB
==================
*/
void SV_WorldTransformAABB( matrix4x4 transform, const vec3_t mins, const vec3_t maxs, vec3_t outmins, vec3_t outmaxs )
{
vec3_t p1, p2;
matrix4x4 itransform;
int i;
if( !outmins || !outmaxs ) return;
Matrix4x4_Invert_Simple( itransform, transform );
outmins[0] = outmins[1] = outmins[2] = 999999;
outmaxs[0] = outmaxs[1] = outmaxs[2] = -999999;
// compute a full bounding box
for( i = 0; i < 8; i++ )
{
p1[0] = ( i & 1 ) ? mins[0] : maxs[0];
p1[1] = ( i & 2 ) ? mins[1] : maxs[1];
p1[2] = ( i & 4 ) ? mins[2] : maxs[2];
p2[0] = DotProduct( p1, itransform[0] );
p2[1] = DotProduct( p1, itransform[1] );
p2[2] = DotProduct( p1, itransform[2] );
if( p2[0] < outmins[0] ) outmins[0] = p2[0];
if( p2[0] > outmaxs[0] ) outmaxs[0] = p2[0];
if( p2[1] < outmins[1] ) outmins[1] = p2[1];
if( p2[1] > outmaxs[1] ) outmaxs[1] = p2[1];
if( p2[2] < outmins[2] ) outmins[2] = p2[2];
if( p2[2] > outmaxs[2] ) outmaxs[2] = p2[2];
}
// sanity check
for( i = 0; i < 3; i++ )
{
if( outmins[i] > outmaxs[i] )
{
Sys_Error("World_TransformAABB: backwards mins/maxs\n");
outmins[0] = outmins[1] = outmins[2] = 0;
outmaxs[0] = outmaxs[1] = outmaxs[2] = 0;
return;
}
}
}
/*
==================
@ -801,84 +862,90 @@ Handles selection or creation of a clipping hull, and offseting (and
eventually rotation) of the end points
==================
*/
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end)
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, edict_t *move_ent )
{
trace_t trace;
vec3_t offset;
matrix4x4 matrix;
vec3_t offset, temp;
vec3_t start_l, end_l;
hull_t *hull;
int j;
qboolean transform_bbox = true;
// fill in a default trace
memset (&trace, 0, sizeof(trace_t));
VectorCopy (end, trace.endpos);
trace.fraction = 1;
trace.allsolid = true;
VectorCopy (end, trace.endpos);
// get the clipping hull
hull = SV_HullForEntity (ent, mins, maxs, offset);
hull = SV_HullForEntity (ent, mins, maxs, offset, move_ent);
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
// keep untransformed bbox less than 45 degress or train on subtransit.bsp will stop working
if(( check_angles( ent->v.angles[0] ) || check_angles( ent->v.angles[2] )) && (mins[0] || mins[1] || mins[2]))
transform_bbox = true;
else
transform_bbox = false;
#ifdef QUAKE2
// rotate start and end into the models frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) )
if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
vec3_t out_mins, out_maxs;
AngleVectors (ent->v.angles, forward, right, up);
if( transform_bbox )
Matrix4x4_CreateFromEntity( matrix, ent->v.angles, ent->v.origin, 1.0f );
else
Matrix4x4_CreateFromEntity( matrix, ent->v.angles, offset, 1.0f );
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
Matrix4x4_VectorITransform( matrix, start, start_l );
Matrix4x4_VectorITransform( matrix, end, end_l );
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
}
#endif
// trace a line through the apropriate clipping hull
SV_RecursiveHullCheck (hull, hull->firstclipnode, start_l, end_l, &trace);
#ifdef QUAKE2
// rotate endpos back to world frame of reference
if (ent->v.solid == SOLID_BSP &&
(ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]) )
{
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
if (trace.fraction != 1)
if( transform_bbox )
{
VectorSubtract (vec3_origin, ent->v.angles, a);
AngleVectors (a, forward, right, up);
SV_WorldTransformAABB( matrix, mins, maxs, out_mins, out_maxs );
VectorSubtract( hull->clip_mins, out_mins, offset ); // calc new local offset
VectorCopy (trace.endpos, temp);
trace.endpos[0] = DotProduct (temp, forward);
trace.endpos[1] = -DotProduct (temp, right);
trace.endpos[2] = DotProduct (temp, up);
VectorCopy (trace.plane.normal, temp);
trace.plane.normal[0] = DotProduct (temp, forward);
trace.plane.normal[1] = -DotProduct (temp, right);
trace.plane.normal[2] = DotProduct (temp, up);
for( j = 0; j < 3; j++ )
{
if( start_l[j] >= 0.0f )
start_l[j] -= offset[j];
else start_l[j] += offset[j];
if( end_l[j] >= 0.0f )
end_l[j] -= offset[j];
else end_l[j] += offset[j];
}
}
}
#endif
else
{
VectorSubtract (start, offset, start_l);
VectorSubtract (end, offset, end_l);
}
// fix trace up by the offset
if (trace.fraction != 1)
VectorAdd (trace.endpos, offset, trace.endpos);
// did we clip the move?
if (trace.fraction < 1 || trace.startsolid )
// trace a line through the apropriate clipping hull
//(hull_t *hull, int num, vec3_t p1, vec3_t p2, trace_t *trace)
SV_RecursiveHullCheck (hull, hull->firstclipnode, start_l, end_l, &trace);
if( trace.fraction != 1.0f )
{
// compute endpos (generic case)
VectorLerp( start, trace.fraction, end, trace.endpos );
if(ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
{
// transform plane
VectorCopy( trace.plane.normal, temp );
Matrix4x4_TransformPositivePlane( matrix, temp, trace.plane.dist, trace.plane.normal, &trace.plane.dist );
}
else
{
trace.plane.dist = DotProduct( trace.endpos, trace.plane.normal );
}
}
if( trace.fraction < 1.0f || trace.startsolid )
trace.ent = ent;
return trace;
@ -937,9 +1004,10 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
}
if ((int)touch->v.flags & FL_MONSTER)
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end, touch);
else
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end, touch);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
@ -955,7 +1023,7 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
else if (trace.startsolid)
clip->trace.startsolid = true;
}
// recurse down both sides
if (node->axis == -1)
return;
@ -980,7 +1048,7 @@ boxmins[0] = boxmins[1] = boxmins[2] = -9999;
boxmaxs[0] = boxmaxs[1] = boxmaxs[2] = 9999;
#else
int i;
for (i=0 ; i<3 ; i++)
{
if (end[i] > start[i])
@ -1009,9 +1077,6 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
memset ( &clip, 0, sizeof ( moveclip_t ) );
// clip to world
clip.trace = SV_ClipMoveToEntity ( sv.edicts, start, mins, maxs, end );
clip.start = start;
clip.end = end;
clip.mins = mins;
@ -1019,6 +1084,9 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
clip.type = type;
clip.passedict = passedict;
// clip to world
clip.trace = SV_ClipMoveToEntity( sv.edicts, start, mins, maxs, end, passedict);
if (type == MOVE_MISSILE)
{
for (i=0 ; i<3 ; i++)
@ -1032,7 +1100,7 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
VectorCopy (mins, clip.mins2);
VectorCopy (maxs, clip.maxs2);
}
// create the bounding box of the entire move
SV_MoveBounds ( start, clip.mins2, clip.maxs2, end, clip.boxmins, clip.boxmaxs );

View file

@ -62,10 +62,11 @@ int SV_TruePointContents (vec3_t p);
// does not check any entities at all
// the non-true version remaps the water current contents to content_water
#define check_angles( x ) ( (int)x == 90 || (int)x == 180 || (int)x == 270 || (int)x == -90 || (int)x == -180 || (int)x == -270 )
edict_t *SV_TestEntityPosition (edict_t *ent);
qboolean SV_RecursiveHullCheck (hull_t *hull, int num, vec3_t p1, vec3_t p2, trace_t *trace);
int SV_HullPointContents (hull_t *hull, int num, vec3_t p);
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict);
// mins and maxs are reletive