diff --git a/Makefile b/Makefile index 8dac669..3baa1b8 100644 --- a/Makefile +++ b/Makefile @@ -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 \ diff --git a/source/cl_parse.c b/source/cl_parse.c index 3487294..4232100 100644 --- a/source/cl_parse.c +++ b/source/cl_parse.c @@ -1173,7 +1173,7 @@ void CL_ParseServerMessage (void) for (j=0; j 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 (); diff --git a/source/cvar.c b/source/cvar.c index ed0fbc9..fe8d2d0 100644 --- a/source/cvar.c +++ b/source/cvar.c @@ -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; diff --git a/source/cvar.h b/source/cvar.h index 495be2e..dc5d6f1 100644 --- a/source/cvar.h +++ b/source/cvar.h @@ -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 diff --git a/source/gl_fog.c b/source/gl_fog.c index 745a243..d7abdd4 100644 --- a/source/gl_fog.c +++ b/source/gl_fog.c @@ -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; diff --git a/source/host.c b/source/host.c index d20171b..b128948 100644 --- a/source/host.c +++ b/source/host.c @@ -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; diff --git a/source/host_cmd.c b/source/host_cmd.c index 109cfaa..e45b93f 100644 --- a/source/host_cmd.c +++ b/source/host_cmd.c @@ -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); diff --git a/source/mathlib.c b/source/mathlib.c index 5925cc3..5ddc9a0 100644 --- a/source/mathlib.c +++ b/source/mathlib.c @@ -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 #include "quakedef.h" +#ifdef PSP_VFPU +#include +#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]; + } } -} \ No newline at end of file + + 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]; + } + } +} diff --git a/source/mathlib.h b/source/mathlib.h index c1a5472..bf4c621 100644 --- a/source/mathlib.h +++ b/source/mathlib.h @@ -18,13 +18,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ // mathlib.h +#ifdef PSP_VFPU +#include +#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] 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; diff --git a/source/matrixlib.c b/source/matrixlib.c index 47cbb2f..ce517a5 100644 --- a/source/matrixlib.c +++ b/source/matrixlib.c @@ -14,7 +14,6 @@ GNU General Public License for more details. */ #include "quakedef.h" -#include 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; -} \ No newline at end of file +} diff --git a/source/menu.c b/source/menu.c index 4dc0382..a67cb72 100644 --- a/source/menu.c +++ b/source/menu.c @@ -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; } diff --git a/source/pr_cmds.c b/source/pr_cmds.c index d106b9d..7072956 100644 --- a/source/pr_cmds.c +++ b/source/pr_cmds.c @@ -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,19 +20,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "quakedef.h" +#ifdef _3DS +extern bool new3ds_flag; +#endif // _3DS + #define PR_MAX_TEMPSTRING 2048 // 2001-10-25 Enhanced temp string handling by Maddes #define RETURN_EDICT(e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(e)) -extern bool new3ds_flag; - /* =============================================================================== - BUILT-IN FUNCTIONS - =============================================================================== */ - char pr_varstring_temp[PR_MAX_TEMPSTRING]; // 2001-10-25 Enhanced temp string handling by Maddes char *PF_VarString (int first) { @@ -76,7 +75,7 @@ void PF_error (void) { char *s; edict_t *ed; - + s = PF_VarString(0); Con_Printf ("======SERVER ERROR in %s:\n%s\n" ,pr_strings + pr_xfunction->s_name,s); @@ -100,14 +99,14 @@ void PF_objerror (void) { char *s; edict_t *ed; - + s = PF_VarString(0); Con_Printf ("======OBJECT ERROR in %s:\n%s\n" ,pr_strings + pr_xfunction->s_name,s); ed = PROG_TO_EDICT(pr_global_struct->self); ED_Print (ed); ED_Free (ed); - + Host_Error ("Program error"); } @@ -139,7 +138,7 @@ void PF_setorigin (void) { edict_t *e; float *org; - + e = G_EDICT(OFS_PARM0); org = G_VECTOR(OFS_PARM1); VectorCopy (org, e->v.origin); @@ -156,7 +155,7 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) float a; vec3_t base, transformed; int i, j, k, l; - + for (i=0 ; i<3 ; i++) if (min[i] > max[i]) PR_RunError ("backwards mins/maxs"); @@ -172,20 +171,20 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) { // find min / max for rotations angles = e->v.angles; - + a = angles[1]/180 * M_PI; - - xvector[0] = cos(a); - xvector[1] = sin(a); - yvector[0] = -sin(a); - yvector[1] = cos(a); - + + xvector[0] = cosf(a); + xvector[1] = sinf(a); + yvector[0] = -sinf(a); + yvector[1] = cosf(a); + VectorCopy (min, bounds[0]); VectorCopy (max, bounds[1]); - + rmin[0] = rmin[1] = rmin[2] = 9999; rmax[0] = rmax[1] = rmax[2] = -9999; - + for (i=0 ; i<= 1 ; i++) { base[0] = bounds[i][0]; @@ -195,12 +194,12 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) for (k=0 ; k<= 1 ; k++) { base[2] = bounds[k][2]; - + // transform the point transformed[0] = xvector[0]*base[0] + yvector[0]*base[1]; transformed[1] = xvector[1]*base[0] + yvector[1]*base[1]; transformed[2] = base[2]; - + for (l=0 ; l<3 ; l++) { if (transformed[l] < rmin[l]) @@ -212,12 +211,12 @@ void SetMinMaxSize (edict_t *e, float *min, float *max, qboolean rotate) } } } - + // set derived values VectorCopy (rmin, e->v.mins); VectorCopy (rmax, e->v.maxs); VectorSubtract (max, min, e->v.size); - + SV_LinkEdict (e, false); } @@ -234,7 +233,7 @@ void PF_setsize (void) { edict_t *e; float *min, *max; - + e = G_EDICT(OFS_PARM0); min = G_VECTOR(OFS_PARM1); max = G_VECTOR(OFS_PARM2); @@ -263,16 +262,16 @@ void PF_setmodel (void) for (i=0, check = sv.model_precache ; *check ; i++, check++) if (!strcmp(*check, m)) break; - + if (!*check) PR_RunError ("no precache: %s\n", m); - + e->v.model = m - pr_strings; e->v.modelindex = i; //SV_ModelIndex (m); mod = sv.models[ (int)e->v.modelindex]; // Mod_ForName (m, true); - + if (mod) SetMinMaxSize (e, mod->mins, mod->maxs, true); else @@ -282,9 +281,7 @@ void PF_setmodel (void) /* ================= PF_bprint - broadcast print to everyone on server - bprint(style, value) ================= */ @@ -310,18 +307,18 @@ void PF_sprint (void) char *s; client_t *client; int entnum; - + entnum = G_EDICTNUM(OFS_PARM0); s = PF_VarString(1); - + if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); return; } - + client = &svs.clients[entnum-1]; - + MSG_WriteChar (&client->message,svc_print); MSG_WriteString (&client->message, s ); } @@ -341,18 +338,18 @@ void PF_centerprint (void) char *s; client_t *client; int entnum; - + entnum = G_EDICTNUM(OFS_PARM0); s = PF_VarString(1); - + if (entnum < 1 || entnum > svs.maxclients) { Con_Printf ("tried to sprint to a non-client\n"); return; } - + client = &svs.clients[entnum-1]; - + MSG_WriteChar (&client->message,svc_centerprint); MSG_WriteString (&client->message, s ); } @@ -392,6 +389,7 @@ void PF_useprint (void) //MSG_WriteString (&client->message, s ); } + /* ================= PF_normalize @@ -404,12 +402,12 @@ void PF_normalize (void) float *value1; vec3_t newvalue; float new; - + value1 = G_VECTOR(OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; - new = sqrt(new); - + new = sqrtf(new); + if (new == 0) newvalue[0] = newvalue[1] = newvalue[2] = 0; else @@ -419,8 +417,8 @@ void PF_normalize (void) newvalue[1] = value1[1] * new; newvalue[2] = value1[2] * new; } - - VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); + + VectorCopy (newvalue, G_VECTOR(OFS_RETURN)); } /* @@ -434,12 +432,12 @@ void PF_vlen (void) { float *value1; float new; - + value1 = G_VECTOR(OFS_PARM0); new = value1[0] * value1[0] + value1[1] * value1[1] + value1[2]*value1[2]; - new = sqrt(new); - + new = sqrtf(new); + G_FLOAT(OFS_RETURN) = new; } @@ -454,14 +452,14 @@ void PF_vectoyaw (void) { float *value1; float yaw; - + value1 = G_VECTOR(OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) yaw = 0; else { - yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); + yaw = (int) (atan2f(value1[1], value1[0]) * 180 / M_PI); if (yaw < 0) yaw += 360; } @@ -482,7 +480,7 @@ void PF_vectoangles (void) float *value1; float forward; float yaw, pitch; - + value1 = G_VECTOR(OFS_PARM0); if (value1[1] == 0 && value1[0] == 0) @@ -495,12 +493,12 @@ void PF_vectoangles (void) } else { - yaw = (int) (atan2(value1[1], value1[0]) * 180 / M_PI); + yaw = (int) (atan2f(value1[1], value1[0]) * 180 / M_PI); if (yaw < 0) yaw += 360; - forward = sqrt (value1[0]*value1[0] + value1[1]*value1[1]); - pitch = (int) (atan2(value1[2], forward) * 180 / M_PI); + forward = sqrtf (value1[0]*value1[0] + value1[1]*value1[1]); + pitch = (int) (atan2f(value1[2], forward) * 180 / M_PI); if (pitch < 0) pitch += 360; } @@ -522,9 +520,9 @@ random() void PF_random (void) { float num; - + num = (rand ()&0x7fff) / ((float)0x7fff); - + G_FLOAT(OFS_RETURN) = num; } @@ -540,7 +538,7 @@ void PF_particle (void) float *org, *dir; float color; float count; - + org = G_VECTOR(OFS_PARM0); dir = G_VECTOR(OFS_PARM1); color = G_FLOAT(OFS_PARM2); @@ -563,16 +561,16 @@ void PF_ambientsound (void) float vol, attenuation; int i, soundnum; - pos = G_VECTOR (OFS_PARM0); + pos = G_VECTOR (OFS_PARM0); samp = G_STRING(OFS_PARM1); vol = G_FLOAT(OFS_PARM2); attenuation = G_FLOAT(OFS_PARM3); - + // check to see if samp was properly precached for (soundnum=0, check = sv.sound_precache ; *check ; check++, soundnum++) if (!strcmp(*check,samp)) break; - + if (!*check) { Con_Printf ("no precache: %s\n", samp); @@ -614,13 +612,36 @@ void PF_sound (void) edict_t *entity; int volume; float attenuation; - + entity = G_EDICT(OFS_PARM0); channel = G_FLOAT(OFS_PARM1); sample = G_STRING(OFS_PARM2); volume = G_FLOAT(OFS_PARM3) * 255; attenuation = G_FLOAT(OFS_PARM4); - + + // AWFUL AWFUL HACK for limiting zombie sound variations +#ifndef SLIM + char* s = sample; + + if (s[strlen(s) - 6] == 'r' || s[strlen(s) - 6] == 'd' || s[strlen(s) - 6] == 'a' || + s[strlen(s) - 6] == 't' || s[strlen(s) - 6] == 'w') { + if (s[strlen(s) - 5] == '1' || s[strlen(s) - 5] == '2' || + s[strlen(s) - 5] == '3' || s[strlen(s) - 5] == '4' || + s[strlen(s) - 5] == '5' || s[strlen(s) - 5] == '6' || + s[strlen(s) - 5] == '7' || s[strlen(s) - 5] == '8' || + s[strlen(s) - 5] == '9') { + + if (s[strlen(s) - 6] == 'r') { + sample[strlen(sample) - 6] = 'w'; + sample[strlen(sample) - 5] = '1'; + } else { + sample[strlen(sample) - 5] = '0'; + } + } + } + +#endif // SLIM + if (volume < 0 || volume > 255) Sys_Error ("SV_StartSound: volume = %i", volume); @@ -679,7 +700,7 @@ void PF_traceline (void) pr_global_struct->trace_inopen = trace.inopen; VectorCopy (trace.endpos, pr_global_struct->trace_endpos); VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + pr_global_struct->trace_plane_dist = trace.plane.dist; if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); else @@ -687,14 +708,12 @@ void PF_traceline (void) } -#ifdef QUAKE2 extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore); void PF_TraceToss (void) { trace_t trace; - edict_t *ent; - edict_t *ignore; + edict_t *ent, *ignore; ent = G_EDICT(OFS_PARM0); ignore = G_EDICT(OFS_PARM1); @@ -708,13 +727,12 @@ void PF_TraceToss (void) pr_global_struct->trace_inopen = trace.inopen; VectorCopy (trace.endpos, pr_global_struct->trace_endpos); VectorCopy (trace.plane.normal, pr_global_struct->trace_plane_normal); - pr_global_struct->trace_plane_dist = trace.plane.dist; + pr_global_struct->trace_plane_dist = trace.plane.dist; if (trace.ent) pr_global_struct->trace_ent = EDICT_TO_PROG(trace.ent); else pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); } -#endif int TraceMove(vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *ent)//engine-sides { @@ -849,9 +867,9 @@ void PF_tracemove(void)//progs side nomonsters = G_FLOAT(OFS_PARM4); ent = G_EDICT(OFS_PARM5); - //Con_DPrintf ("TraceMove start, "); + // Con_DPrintf ("TraceMove start, "); G_INT(OFS_RETURN) = TraceMove(start, mins, maxs, end,nomonsters,ent); - //Con_DPrintf ("TM end\n"); + // Con_DPrintf ("TM end\n"); return; } @@ -884,7 +902,6 @@ void PF_tracebox (void) else pr_global_struct->trace_ent = EDICT_TO_PROG(sv.edicts); } - /* ================= PF_checkpos @@ -948,7 +965,12 @@ int PF_newcheckclient (int check) VectorAdd (ent->v.origin, ent->v.view_ofs, org); leaf = Mod_PointInLeaf (org, sv.worldmodel); pvs = Mod_LeafPVS (leaf, sv.worldmodel); - memcpy (checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 ); + +#ifdef __PSP__ + memcpy_vfpu(checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 ); +#else + memcpy(checkpvs, pvs, (sv.worldmodel->numleafs+7)>>3 ); +#endif // __PSP__ return i; } @@ -976,7 +998,7 @@ void PF_checkclient (void) mleaf_t *leaf; int l; vec3_t view; - + // find a new check if on a new frame if (sv.time - sv.lastchecktime >= 0.1) { @@ -984,7 +1006,7 @@ void PF_checkclient (void) sv.lastchecktime = sv.time; } -// return check if it might be visible +// return check if it might be visible ent = EDICT_NUM(sv.lastcheck); if (ent->free || ent->v.health <= 0) { @@ -1026,12 +1048,12 @@ void PF_stuffcmd (void) int entnum; char *str; client_t *old; - + entnum = G_EDICTNUM(OFS_PARM0); if (entnum < 1 || entnum > svs.maxclients) PR_RunError ("Parm 0 not a client"); - str = G_STRING(OFS_PARM1); - + str = G_STRING(OFS_PARM1); + old = host_client; host_client = &svs.clients[entnum-1]; Host_ClientCommands ("%s", str); @@ -1050,8 +1072,8 @@ localcmd (string) void PF_localcmd (void) { char *str; - - str = G_STRING(OFS_PARM0); + + str = G_STRING(OFS_PARM0); Cbuf_AddText (str); } @@ -1065,9 +1087,9 @@ float cvar (string) void PF_cvar (void) { char *str; - + str = G_STRING(OFS_PARM0); - + G_FLOAT(OFS_RETURN) = Cvar_VariableValue (str); } @@ -1081,10 +1103,10 @@ float cvar (string) void PF_cvar_set (void) { char *var, *val; - + var = G_STRING(OFS_PARM0); val = G_STRING(OFS_PARM1); - + Cvar_Set (var, val); } @@ -1106,9 +1128,9 @@ void PF_findradius (void) int i, j; chain = (edict_t *)sv.edicts; - - org = G_VECTOR(OFS_PARM0); + org = G_VECTOR(OFS_PARM0); + rad = G_FLOAT(OFS_PARM1); rad *= rad; @@ -1120,11 +1142,11 @@ void PF_findradius (void) if (ent->v.solid == SOLID_NOT) continue; for (j=0 ; j<3 ; j++) - eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5); + eorg[j] = org[j] - (ent->v.origin[j] + (ent->v.mins[j] + ent->v.maxs[j])*0.5); if (DotProduct(eorg, eorg) > rad) continue; - + ent->v.chain = EDICT_TO_PROG(chain); chain = ent; } @@ -1143,13 +1165,13 @@ void PF_dprint (void) Con_DPrintf ("%s",PF_VarString(0)); } -char pr_string_temp[128]; +char pr_string_temp[PR_MAX_TEMPSTRING]; // 2001-10-25 Enhanced temp string handling by Maddes void PF_ftos (void) { float v; v = G_FLOAT(OFS_PARM0); - + if (v == (int)v) sprintf (pr_string_temp, "%d",(int)v); else @@ -1161,7 +1183,7 @@ void PF_fabs (void) { float v; v = G_FLOAT(OFS_PARM0); - G_FLOAT(OFS_RETURN) = fabs(v); + G_FLOAT(OFS_RETURN) = fabsf(v); } void PF_vtos (void) @@ -1176,6 +1198,7 @@ void PF_etos (void) G_INT(OFS_RETURN) = pr_string_temp - pr_strings; } + void PF_Spawn (void) { edict_t *ed; @@ -1186,7 +1209,7 @@ void PF_Spawn (void) void PF_Remove (void) { edict_t *ed; - + ed = G_EDICT(OFS_PARM0); ED_Free (ed); } @@ -1231,7 +1254,7 @@ string strtrim (string) */ void PF_strtrim (void) { - int offset, length; + int offset, length; int maxoffset; // 2001-10-25 Enhanced temp string handling by Maddes char *str; char *end; @@ -1326,51 +1349,6 @@ void PF_strcat (void) G_INT(OFS_RETURN) = pr_string_temp - pr_strings; } -/* -================= -PF_strtolower - -string strtolower (string) -================= -*/ -void PF_strtolower(void) -{ - char *s; - - s = G_STRING(OFS_PARM0); - - pr_string_temp[0] = 0; - if (strlen(s) < PR_MAX_TEMPSTRING) - { - strcpy(pr_string_temp, s); - } - else - { - strncpy(pr_string_temp, s, PR_MAX_TEMPSTRING); - pr_string_temp[PR_MAX_TEMPSTRING-1] = 0; - } - - for(int i = 0; i < strlen(s); i++) - pr_string_temp[i] = tolower(pr_string_temp[i]); - - G_INT(OFS_RETURN) = pr_string_temp - pr_strings; -} - -/* -================= -PF_crc16 - -float crc16 (float, string) -================= -*/ -void PF_crc16(void) -{ - int insens = G_FLOAT(OFS_PARM0); - char *s = G_STRING(OFS_PARM1); - - G_FLOAT(OFS_RETURN) = (unsigned short) ((insens ? CRC_Block_CaseInsensitive : CRC_Block) ((unsigned char *) s, strlen(s))); -} - /* ================= PF_substring @@ -1426,6 +1404,51 @@ void PF_stof (void) G_FLOAT(OFS_RETURN) = atof(s); } +/* +================= +PF_strtolower + +string strtolower (string) +================= +*/ +void PF_strtolower(void) +{ + char *s; + + s = G_STRING(OFS_PARM0); + + pr_string_temp[0] = 0; + if (strlen(s) < PR_MAX_TEMPSTRING) + { + strcpy(pr_string_temp, s); + } + else + { + strncpy(pr_string_temp, s, PR_MAX_TEMPSTRING); + pr_string_temp[PR_MAX_TEMPSTRING-1] = 0; + } + + for(int i = 0; i < strlen(s); i++) + pr_string_temp[i] = tolower(pr_string_temp[i]); + + G_INT(OFS_RETURN) = pr_string_temp - pr_strings; +} + +/* +================= +PF_crc16 + +float crc16 (float, string) +================= +*/ +void PF_crc16(void) +{ + int insens = G_FLOAT(OFS_PARM0); + char *s = G_STRING(OFS_PARM1); + + G_FLOAT(OFS_RETURN) = (unsigned short) ((insens ? CRC_Block_CaseInsensitive : CRC_Block) ((unsigned char *) s, strlen(s))); +} + /* ================= PF_stov @@ -1464,6 +1487,7 @@ void PF_Set_Zombie (void) //int entitynum = G_EDICT(OFS_PARM0); } + /* ================= Main_Waypoint functin @@ -1472,8 +1496,11 @@ This is where the magic happens ================= */ - -#define MaxZombies 18 // 18 for N3DS and 12 for O3DS +#ifdef __PSP__ +#define MaxZombies 12 +#else +#define MaxZombies 18 +#endif #define WAYPOINT_SET_NONE 0 @@ -1524,6 +1551,7 @@ void sv_way_remove_way_from_set(char set, int waypoint_idx) { waypoint_set[waypoint_idx] = WAYPOINT_SET_NONE; } + // // Debug method to verify that `openset` and `opensetRef` remain synchronized // @@ -1638,6 +1666,7 @@ float sv_way_heuristic_cost_estimate(int waypoint_idx_a, int waypoint_idx_b) { return VectorDistanceSquared(waypoints[waypoint_idx_a].origin, waypoints[waypoint_idx_b].origin); } + // Global array in which to store pathfinding results int process_list[MAX_WAYPOINTS]; int process_list_length; @@ -1842,6 +1871,7 @@ void Close_Waypoint (void) { } } } + /* ================= Do_Pathfind @@ -2434,6 +2464,7 @@ void Get_First_Waypoint (void) { Get_Next_Waypoint(); } + // 2001-09-20 QuakeC file access by FrikaC/Maddes start /* ================= @@ -2559,57 +2590,8 @@ void PF_fputs (void) // entity (entity start, .string field, string match) find = #5; void PF_Find (void) -#ifdef QUAKE2 { - int e; - int f; - char *s, *t; - edict_t *ed; - edict_t *first; - edict_t *second; - edict_t *last; - - first = second = last = (edict_t *)sv.edicts; - e = G_EDICTNUM(OFS_PARM0); - f = G_INT(OFS_PARM1); - s = G_STRING(OFS_PARM2); - if (!s) - PR_RunError ("PF_Find: bad search string"); - - for (e++ ; e < sv.num_edicts ; e++) - { - ed = EDICT_NUM(e); - if (ed->free) - continue; - t = E_STRING(ed,f); - if (!t) - continue; - if (!strcmp(t,s)) - { - if (first == (edict_t *)sv.edicts) - first = ed; - else if (second == (edict_t *)sv.edicts) - second = ed; - ed->v.chain = EDICT_TO_PROG(last); - last = ed; - } - } - - if (first != last) - { - if (last != second) - first->v.chain = last->v.chain; - else - first->v.chain = EDICT_TO_PROG(last); - last->v.chain = EDICT_TO_PROG((edict_t *)sv.edicts); - if (second && second != last) - second->v.chain = EDICT_TO_PROG(last); - } - RETURN_EDICT(first); -} -#else -{ - int e; + int e; int f; char *s, *t; edict_t *ed; @@ -2619,7 +2601,7 @@ void PF_Find (void) s = G_STRING(OFS_PARM2); if (!s) PR_RunError ("PF_Find: bad search string"); - + for (e++ ; e < sv.num_edicts ; e++) { ed = EDICT_NUM(e); @@ -2637,7 +2619,6 @@ void PF_Find (void) RETURN_EDICT(sv.edicts); } -#endif // entity (entity start, .float field, float match) findfloat = #98; void PF_FindFloat (void) @@ -2686,14 +2667,38 @@ void PF_precache_sound (void) { char *s; int i; - + if (sv.state != ss_loading) PR_RunError ("PF_Precache_*: Precache can only be done in spawn functions"); - + s = G_STRING(OFS_PARM0); G_INT(OFS_RETURN) = G_INT(OFS_PARM0); PR_CheckEmptyString (s); + + // AWFUL AWFUL HACK for limiting zombie sound variations +#ifndef SLIM + + if (s[strlen(s) - 6] == 'r' || s[strlen(s) - 6] == 'd' || s[strlen(s) - 6] == 'a' || + s[strlen(s) - 6] == 't' || s[strlen(s) - 6] == 'w') { + if (s[strlen(s) - 5] == '1' || s[strlen(s) - 5] == '2' || + s[strlen(s) - 5] == '3' || s[strlen(s) - 5] == '4' || + s[strlen(s) - 5] == '5' || s[strlen(s) - 5] == '6' || + s[strlen(s) - 5] == '7' || s[strlen(s) - 5] == '8' || + s[strlen(s) - 5] == '9') { + + if (s[strlen(s) - 6] == 'r') { + s[strlen(s) - 6] = 'w'; + s[strlen(s) - 5] = '1'; + } else + s[strlen(s) - 5] = '0'; + } + } + + +#endif // SLIM + + for (i=0 ; iself); yaw = G_FLOAT(OFS_PARM0); dist = G_FLOAT(OFS_PARM1); - + if ( !( (int)ent->v.flags & (FL_ONGROUND|FL_FLY|FL_SWIM) ) ) { G_FLOAT(OFS_RETURN) = 0; @@ -2780,18 +2785,24 @@ void PF_walkmove (void) } yaw = yaw*M_PI*2 / 360; - - move[0] = cos(yaw)*dist; - move[1] = sin(yaw)*dist; + + move[0] = cosf(yaw)*dist; + move[1] = sinf(yaw)*dist; move[2] = 0; // save program state, because SV_movestep may call other progs oldf = pr_xfunction; oldself = pr_global_struct->self; - + G_FLOAT(OFS_RETURN) = SV_movestep(ent, move, true); - - + + //if(!strcmp(pr_strings + ent->v.classname, "ai_zombie")) + //{ + // VectorCopy(ent->v.origin,PROG_TO_EDICT(ent->v.head)->v.origin); + // VectorCopy(ent->v.origin,PROG_TO_EDICT(ent->v.rarm)->v.origin); + // VectorCopy(ent->v.origin,PROG_TO_EDICT(ent->v.larm)->v.origin); + //} + // restore program state pr_xfunction = oldf; pr_global_struct->self = oldself; @@ -2809,12 +2820,12 @@ void PF_droptofloor (void) edict_t *ent; vec3_t end; trace_t trace; - + ent = PROG_TO_EDICT(pr_global_struct->self); VectorCopy (ent->v.origin, end); end[2] -= 256; - + trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, false, ent); if (trace.fraction == 1 || trace.allsolid) @@ -2842,17 +2853,17 @@ void PF_lightstyle (void) char *val; client_t *client; int j; - + style = G_FLOAT(OFS_PARM0); val = G_STRING(OFS_PARM1); // change the string in sv sv.lightstyles[style] = val; - + // send message to all clients on this server if (sv.state != ss_active) return; - + for (j=0, client = svs.clients ; jactive || client->spawned) { @@ -2873,11 +2884,11 @@ void PF_rint (void) } void PF_floor (void) { - G_FLOAT(OFS_RETURN) = floor(G_FLOAT(OFS_PARM0)); + G_FLOAT(OFS_RETURN) = floorf(G_FLOAT(OFS_PARM0)); } void PF_ceil (void) { - G_FLOAT(OFS_RETURN) = ceil(G_FLOAT(OFS_PARM0)); + G_FLOAT(OFS_RETURN) = ceilf(G_FLOAT(OFS_PARM0)); } @@ -2889,7 +2900,7 @@ PF_checkbottom void PF_checkbottom (void) { edict_t *ent; - + ent = G_EDICT(OFS_PARM0); G_FLOAT(OFS_RETURN) = SV_CheckBottom (ent); @@ -2903,10 +2914,10 @@ PF_pointcontents void PF_pointcontents (void) { float *v; - + v = G_VECTOR(OFS_PARM0); - G_FLOAT(OFS_RETURN) = SV_PointContents (v); + G_FLOAT(OFS_RETURN) = SV_PointContents (v); } /* @@ -2920,7 +2931,7 @@ void PF_nextent (void) { int i; edict_t *ent; - + i = G_EDICTNUM(OFS_PARM0); while (1) { @@ -2951,16 +2962,16 @@ cvar_t sv_aim = {"sv_aim", "0.93"}; void PF_aim (void) { edict_t *ent, *check, *bestent; - vec3_t start, dir, end, bestdir; + vec3_t start, dir, end, bestdir, tempv; int i, j; trace_t tr; float dist, bestdist; float speed; - + ent = G_EDICT(OFS_PARM0); speed = G_FLOAT(OFS_PARM1); - - VectorCopy (ent->v.origin, start); + VectorAdd(ent->v.origin, ent->v.view_ofs, tempv); + VectorCopy (tempv, start); start[2] += 20; // try sending a trace straight @@ -2978,8 +2989,9 @@ void PF_aim (void) // try all possible entities VectorCopy (dir, bestdir); bestdist = sv_aim.value; + // dr_mabuse1981: PSP controls sucks ass bestent = NULL; - + check = NEXT_EDICT(sv.edicts); for (i=1 ; iv.origin, ent->v.origin, dir); - dist = DotProduct (dir, pr_global_struct->v_forward); - VectorScale (pr_global_struct->v_forward, dist, end); +// dr_mabuse1981: bullets shouldnt go offset anymore (fix from Quartal engine) +// dist = DotProduct (dir, pr_global_struct->v_forward); +// VectorScale (pr_global_struct->v_forward, dist, end); +// end[2] = dir[2]; + end[0] = dir[0]; + end[1] = dir[1]; end[2] = dir[2]; VectorNormalize (end); - VectorCopy (end, G_VECTOR(OFS_RETURN)); + VectorCopy (end, G_VECTOR(OFS_RETURN)); } else { @@ -3031,12 +3047,12 @@ void PF_changeyaw (void) { edict_t *ent; float ideal, current, move, speed; - + ent = PROG_TO_EDICT(pr_global_struct->self); current = anglemod( ent->v.angles[1] ); ideal = ent->v.ideal_yaw; speed = ent->v.yaw_speed; - + if (current == ideal) return; move = ideal - current; @@ -3060,7 +3076,7 @@ void PF_changeyaw (void) if (move < -speed) move = -speed; } - + ent->v.angles[1] = anglemod (current + move); } @@ -3108,7 +3124,6 @@ void PF_GetSoundLen (void) G_FLOAT(OFS_RETURN) = (float)info.samples/(float)info.rate; } -#ifdef QUAKE2 /* ============== PF_changepitch @@ -3116,16 +3131,35 @@ PF_changepitch */ void PF_changepitch (void) { - edict_t *ent; - float ideal, current, move, speed; - + float ideal, current, move, speed; + edict_t *ent; + eval_t *val; + ent = G_EDICT(OFS_PARM0); - current = anglemod( ent->v.angles[0] ); - ideal = ent->v.idealpitch; - speed = ent->v.pitch_speed; - + current = anglemod(ent->v.angles[0]); + if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch))) + { + ideal = val->_float; + } + else + { + PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch"); + return; + } + + if ((val = GETEDICTFIELDVALUE(ent, eval_pitch_speed))) + { + speed = val->_float; + } + else + { + PR_RunError ("PF_changepitch: .float idealpitch and .float pitch_speed must be defined to use changepitch"); + return; + } + if (current == ideal) return; + move = ideal - current; if (ideal > current) { @@ -3137,6 +3171,7 @@ void PF_changepitch (void) if (move <= -180) move = move + 360; } + if (move > 0) { if (move > speed) @@ -3147,10 +3182,9 @@ void PF_changepitch (void) if (move < -speed) move = -speed; } - + ent->v.angles[0] = anglemod (current + move); } -#endif /* =============================================================================== @@ -3176,17 +3210,17 @@ sizebuf_t *WriteDest (void) { case MSG_BROADCAST: return &sv.datagram; - + case MSG_ONE: ent = PROG_TO_EDICT(pr_global_struct->msg_entity); entnum = NUM_FOR_EDICT(ent); if (entnum < 1 || entnum > svs.maxclients) PR_RunError ("WriteDest: not a client"); return &svs.clients[entnum-1].message; - + case MSG_ALL: return &sv.reliable_datagram; - + case MSG_INIT: return &sv.signon; @@ -3194,7 +3228,7 @@ sizebuf_t *WriteDest (void) PR_RunError ("WriteDest: bad destination"); break; } - + return NULL; } @@ -3247,7 +3281,7 @@ void PF_makestatic (void) { edict_t *ent; int i; - + ent = G_EDICT(OFS_PARM0); MSG_WriteByte (&sv.signon,svc_spawnstatic); @@ -3299,54 +3333,38 @@ PF_changelevel */ void PF_changelevel (void) { -#ifdef QUAKE2 - char *s1, *s2; - - if (svs.changelevel_issued) - return; - svs.changelevel_issued = true; - - s1 = G_STRING(OFS_PARM0); - s2 = G_STRING(OFS_PARM1); - - if ((int)pr_global_struct->serverflags & (SFL_NEW_UNIT | SFL_NEW_EPISODE)) - Cbuf_AddText (va("changelevel %s %s\n",s1, s2)); - else - Cbuf_AddText (va("changelevel2 %s %s\n",s1, s2)); -#else char *s; // make sure we don't issue two changelevels if (svs.changelevel_issued) return; svs.changelevel_issued = true; - + s = G_STRING(OFS_PARM0); Cbuf_AddText (va("changelevel %s\n",s)); -#endif } - void PF_sin (void) { - G_FLOAT(OFS_RETURN) = sin(G_FLOAT(OFS_PARM0)); + G_FLOAT(OFS_RETURN) = sinf(G_FLOAT(OFS_PARM0)); } void PF_cos (void) { - G_FLOAT(OFS_RETURN) = cos(G_FLOAT(OFS_PARM0)); + G_FLOAT(OFS_RETURN) = cosf(G_FLOAT(OFS_PARM0)); } void PF_sqrt (void) { - G_FLOAT(OFS_RETURN) = sqrt(G_FLOAT(OFS_PARM0)); + G_FLOAT(OFS_RETURN) = sqrtf(G_FLOAT(OFS_PARM0)); } void PF_Fixme (void) { - PR_RunError ("unimplemented bulitin"); + //PR_RunError ("unimplemented bulitin"); + Con_DPrintf("unimplemented bulitin"); } /* @@ -3360,12 +3378,10 @@ songegg(trackname) */ void PF_SongEgg (void) { - char trackname; + char *s; - trackname = G_STRING(OFS_PARM0); - - //MSG_WriteByte (&sv.reliable_datagram, svc_songegg); - //MSG_WriteString (&sv.reliable_datagram, trackname); + s = G_STRING(OFS_PARM0); + Cbuf_AddText (va("cd playstring %s 0\n",s)); } /* @@ -3386,7 +3402,7 @@ void PF_MaxAmmo(void) ================= PF_GrenadePulse -pulses crosshair for grenades +pulses grenade crosshair grenade_pulse() ================= @@ -3402,7 +3418,7 @@ void PF_GrenadePulse(void) return; client = &svs.clients[entnum-1]; - MSG_WriteByte (&client->message,svc_pulse); + MSG_WriteByte (&client->message, svc_pulse); } /* @@ -3433,6 +3449,44 @@ void PF_SetDoubleTapVersion(void) MSG_WriteByte (&client->message, state); } +/* +================= +PF_ScreenFlash + +Server tells client to flash on screen +for a short (but specified) moment. + +nzp_screenflash(target, color, duration, type) +================= +*/ +void PF_ScreenFlash(void) +{ + client_t *client; + int entnum; + int color, duration, type; + + entnum = G_EDICTNUM(OFS_PARM0); + color = G_FLOAT(OFS_PARM1); + duration = G_FLOAT(OFS_PARM2); + type = G_FLOAT(OFS_PARM3); + + // Specified world, or something. Send to everyone. + if (entnum < 1 || entnum > svs.maxclients) { + MSG_WriteByte(&sv.reliable_datagram, svc_screenflash); + MSG_WriteByte(&sv.reliable_datagram, color); + MSG_WriteByte(&sv.reliable_datagram, duration); + MSG_WriteByte(&sv.reliable_datagram, type); + } + // Send to specific user + else { + client = &svs.clients[entnum-1]; + MSG_WriteByte (&client->message, svc_screenflash); + MSG_WriteByte (&client->message, color); + MSG_WriteByte (&client->message, duration); + MSG_WriteByte (&client->message, type); + } +} + /* ================= PF_LockViewmodel @@ -3493,44 +3547,6 @@ void PF_Rumble(void) MSG_WriteShort (&client->message, duration); } -/* -================= -PF_ScreenFlash - -Server tells client to flash on screen -for a short (but specified) moment. - -nzp_screenflash(target, color, duration, type) -================= -*/ -void PF_ScreenFlash(void) -{ - client_t *client; - int entnum; - int color, duration, type; - - entnum = G_EDICTNUM(OFS_PARM0); - color = G_FLOAT(OFS_PARM1); - duration = G_FLOAT(OFS_PARM2); - type = G_FLOAT(OFS_PARM3); - - // Specified world, or something. Send to everyone. - if (entnum < 1 || entnum > svs.maxclients) { - MSG_WriteByte(&sv.reliable_datagram, svc_screenflash); - MSG_WriteByte(&sv.reliable_datagram, color); - MSG_WriteByte(&sv.reliable_datagram, duration); - MSG_WriteByte(&sv.reliable_datagram, type); - } - // Send to specific user - else { - client = &svs.clients[entnum-1]; - MSG_WriteByte (&client->message, svc_screenflash); - MSG_WriteByte (&client->message, color); - MSG_WriteByte (&client->message, duration); - MSG_WriteByte (&client->message, type); - } -} - /* ================= PF_BettyPrompt @@ -3597,10 +3613,14 @@ nzp_maxai() */ void PF_MaxZombies(void) { +#ifdef __PSP__ + G_FLOAT(OFS_RETURN) = MaxZombies; +#else if (new3ds_flag) G_FLOAT(OFS_RETURN) = MaxZombies; else G_FLOAT(OFS_RETURN) = 12; +#endif // __PSP__ } /* @@ -3634,6 +3654,7 @@ void PF_achievement (void) MSG_WriteByte (&client->message, ach); } + /* ================= PF_updateLimb @@ -3657,6 +3678,40 @@ void PF_updateLimb (void) MSG_WriteShort (&sv.reliable_datagram, limbent); } +// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start +/* +================= +PF_builtin_find + +float builtin_find (string) +================= +*/ +void PF_builtin_find (void) +{ + int j; + float funcno; + char *funcname; + + funcno = 0; + funcname = G_STRING(OFS_PARM0); + + // search function name + for ( j=1 ; j < pr_ebfs_numbuiltins ; j++) + { + if ((pr_ebfs_builtins[j].funcname) && (!(Q_strcasecmp(funcname,pr_ebfs_builtins[j].funcname)))) + { + break; // found + } + } + + if (j < pr_ebfs_numbuiltins) + { + funcno = pr_ebfs_builtins[j].funcno; + } + + G_FLOAT(OFS_RETURN) = funcno; +} + /* ================= PF_tokenize @@ -3688,529 +3743,236 @@ void PF_ArgV (void) } -builtin_t pr_builtin[] = +// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end +builtin_t *pr_builtins; +int pr_numbuiltins; +// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes start +// for builtin function definitions see Quake Standards Group at http://www.quakesrc.org/ +ebfs_builtin_t pr_ebfs_builtins[] = { -PF_Fixme, -PF_makevectors, // void(entity e) makevectors = #1; -PF_setorigin, // void(entity e, vector o) setorigin = #2; -PF_setmodel, // void(entity e, string m) setmodel = #3; -PF_setsize, // void(entity e, vector min, vector max) setsize = #4; -PF_Fixme, // void(entity e, vector min, vector max) setabssize = #5; -PF_break, // void() break = #6; -PF_random, // float() random = #7; -PF_sound, // void(entity e, float chan, string samp) sound = #8; -PF_normalize, // vector(vector v) normalize = #9; -PF_error, // void(string e) error = #10; -PF_objerror, // void(string e) objerror = #11; -PF_vlen, // float(vector v) vlen = #12; -PF_vectoyaw, // float(vector v) vectoyaw = #13; -PF_Spawn, // entity() spawn = #14; -PF_Remove, // void(entity e) remove = #15; -PF_traceline, // float(vector v1, vector v2, float tryents) traceline = #16; -PF_checkclient, // entity() clientlist = #17; -PF_Find, // entity(entity start, .string fld, string match) find = #18; -PF_precache_sound, // void(string s) precache_sound = #19; -PF_precache_model, // void(string s) precache_model = #20; -PF_stuffcmd, // void(entity client, string s)stuffcmd = #21; -PF_findradius, // entity(vector org, float rad) findradius = #22; -PF_bprint, // void(string s) bprint = #23; -PF_sprint, // void(entity client, string s) sprint = #24; -PF_dprint, // void(string s) dprint = #25; -PF_ftos, // void(string s) ftos = #26; -PF_vtos, // void(string s) vtos = #27; -PF_coredump, -PF_traceon, -PF_traceoff, -PF_eprint, // void(entity e) debug print an entire entity -PF_walkmove, // float(float yaw, float dist) walkmove -PF_updateLimb, // #33 -PF_droptofloor, -PF_lightstyle, -PF_rint, -PF_floor, -PF_ceil, -PF_Fixme, -PF_checkbottom, -PF_pointcontents, -PF_Fixme, -PF_fabs, -PF_aim, -PF_cvar, -PF_localcmd, -PF_nextent, -PF_particle, -PF_changeyaw, -PF_GetSoundLen, -PF_vectoangles, + { 0, NULL, PF_Fixme }, // has to be first entry as it is needed for initialization in PR_LoadProgs() + { 1, "makevectors", PF_makevectors }, // void(entity e) makevectors = #1; + { 2, "setorigin", PF_setorigin }, // void(entity e, vector o) setorigin = #2; + { 3, "setmodel", PF_setmodel }, // void(entity e, string m) setmodel = #3; + { 4, "setsize", PF_setsize }, // void(entity e, vector min, vector max) setsize = #4; +// { 5, "fixme", PF_Fixme }, // void(entity e, vector min, vector max) setabssize = #5; + { 6, "break", PF_break }, // void() break = #6; + { 7, "random", PF_random }, // float() random = #7; + { 8, "sound", PF_sound }, // void(entity e, float chan, string samp) sound = #8; + { 9, "normalize", PF_normalize }, // vector(vector v) normalize = #9; + { 10, "error", PF_error }, // void(string e) error = #10; + { 11, "objerror", PF_objerror }, // void(string e) objerror = #11; + { 12, "vlen", PF_vlen }, // float(vector v) vlen = #12; + { 13, "vectoyaw", PF_vectoyaw }, // float(vector v) vectoyaw = #13; + { 14, "spawn", PF_Spawn }, // entity() spawn = #14; + { 15, "remove", PF_Remove }, // void(entity e) remove = #15; + { 16, "traceline", PF_traceline }, // float(vector v1, vector v2, float tryents) traceline = #16; + { 17, "checkclient", PF_checkclient }, // entity() clientlist = #17; + { 18, "find", PF_Find }, // entity(entity start, .string fld, string match) find = #18; + { 19, "precache_sound", PF_precache_sound }, // void(string s) precache_sound = #19; + { 20, "precache_model", PF_precache_model }, // void(string s) precache_model = #20; + { 21, "stuffcmd", PF_stuffcmd }, // void(entity client, string s)stuffcmd = #21; + { 22, "findradius", PF_findradius }, // entity(vector org, float rad) findradius = #22; + { 23, "bprint", PF_bprint }, // void(string s) bprint = #23; + { 24, "sprint", PF_sprint }, // void(entity client, string s) sprint = #24; + { 25, "dprint", PF_dprint }, // void(string s) dprint = #25; + { 26, "ftos", PF_ftos }, // void(string s) ftos = #26; + { 27, "vtos", PF_vtos }, // void(string s) vtos = #27; + { 28, "coredump", PF_coredump }, + { 29, "traceon", PF_traceon }, + { 30, "traceoff", PF_traceoff }, + { 31, "eprint", PF_eprint }, // void(entity e) debug print an entire entity + { 32, "walkmove", PF_walkmove }, // float(float yaw, float dist) walkmove + { 33, "updateLimb", PF_updateLimb }, + { 34, "droptofloor", PF_droptofloor }, + { 35, "lightstyle", PF_lightstyle }, + { 36, "rint", PF_rint }, + { 37, "floor", PF_floor }, + { 38, "ceil", PF_ceil }, +// { 39, "fixme", PF_Fixme }, + { 40, "checkbottom", PF_checkbottom }, + { 41, "pointcontents", PF_pointcontents }, +// { 42, "fixme", PF_Fixme }, + { 43, "fabs", PF_fabs }, + { 44, "aim", PF_aim }, + { 45, "cvar", PF_cvar }, + { 46, "localcmd", PF_localcmd }, + { 47, "nextent", PF_nextent }, + { 48, "particle", PF_particle }, + { 49, "ChangeYaw", PF_changeyaw }, + { 50, "getSoundLen", PF_GetSoundLen }, + { 51, "vectoangles", PF_vectoangles }, -PF_WriteByte, -PF_WriteChar, -PF_WriteShort, -PF_WriteLong, -PF_WriteCoord, -PF_WriteAngle, -PF_WriteString, -PF_WriteEntity, + { 52, "WriteByte", PF_WriteByte }, + { 53, "WriteChar", PF_WriteChar }, + { 54, "WriteShort", PF_WriteShort }, + { 55, "WriteLong", PF_WriteLong }, + { 56, "WriteCoord", PF_WriteCoord }, + { 57, "WriteAngle", PF_WriteAngle }, + { 58, "WriteString", PF_WriteString }, + { 59, "WriteEntity", PF_WriteEntity }, -PF_sin, -PF_cos, -PF_sqrt, -PF_Fixme,//PF_changepitch, -PF_Fixme,//PF_TraceToss, -PF_etos, -PF_Fixme,//PF_WaterMove, + { 60, "sin", PF_sin }, + { 61, "cos", PF_cos }, + { 62, "sqrt", PF_sqrt }, + { 65, "etos", PF_etos }, -SV_MoveToGoal, -PF_precache_file, -PF_makestatic, + { 67, "movetogoal", SV_MoveToGoal }, + { 68, "precache_file", PF_precache_file }, + { 69, "makestatic", PF_makestatic }, -PF_changelevel, -SV_MoveToOrigin, // #71 + { 70, "changelevel", PF_changelevel }, + { 71, "movetoorigin", SV_MoveToOrigin }, -PF_cvar_set, -PF_centerprint, + { 72, "cvar_set", PF_cvar_set }, + { 73, "centerprint", PF_centerprint }, -PF_ambientsound, + { 74, "ambientsound", PF_ambientsound }, -PF_precache_model, -PF_precache_sound, // precache_sound2 is different only for qcc -PF_precache_file, + { 75, "precache_model2", PF_precache_model }, + { 76, "precache_sound2", PF_precache_sound }, // precache_sound2 is different only for qcc + { 77, "precache_file2", PF_precache_file }, + + { 78, "setspawnparms", PF_setspawnparms }, + { 79, "achievement", PF_achievement }, + + { 81, "stof", PF_stof }, // 2001-09-20 QuakeC string manipulation by FrikaC/Maddes + + { 82, "Set_Zombie", PF_Set_Zombie }, //set zombies stats + { 83, "Get_Waypoint_Near", Get_Waypoint_Near }, //returns the cords for closest waypoint + { 84, "Do_Pathfind", Do_Pathfind }, //starts the magic + { 85, "Open_Waypoint", Open_Waypoint }, //Opens a waypoint + { 86, "Get_Next_Waypoint", Get_Next_Waypoint }, //Get next waypoint + { 87, "useprint", PF_useprint }, //Print with button + { 88, "Get_First_Waypoint", Get_First_Waypoint },//Get the first waypoint in the list + { 89, "Close_Waypoint", Close_Waypoint }, //Closes a waypoint + +// 2001-11-15 DarkPlaces general builtin functions by Lord Havoc start +// not implemented yet + + + { 90, "tracebox", PF_tracebox }, + { 99, "tracemove", PF_tracemove },//blubs improved tracebox +/* { 91, "randomvec", PF_randomvec }, + { 92, "getlight", PF_GetLight }, // not implemented yet + { 93, "cvar_create", PF_cvar_create }, // 2001-09-18 New BuiltIn Function: cvar_create() by Maddes + { 94, "fmin", PF_fmin }, + { 95, "fmax", PF_fmax }, + { 96, "fbound", PF_fbound }, + { 97, "fpow", PF_fpow }, + */{ 98, "findfloat", PF_FindFloat },/* + { PR_DEFAULT_FUNCNO_EXTENSION_FIND, "extension_find", PF_extension_find }, // 2001-10-20 Extension System by Lord Havoc/Maddes + { 0, "registercvar", PF_cvar_create }, // 0 indicates that this entry is just for remapping (because of name change) + { 0, "checkextension", PF_extension_find }, +*/ +// 2001-11-15 DarkPlaces general builtin functions by Lord Havoc end + + { PR_DEFAULT_FUNCNO_BUILTIN_FIND, "builtin_find", PF_builtin_find }, // 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes + +// not implemented yet +/* + { 101, "cmd_find", PF_cmd_find }, // 2001-09-16 New BuiltIn Function: cmd_find() by Maddes + + { 102, "cvar_find", PF_cvar_find }, // 2001-09-16 New BuiltIn Function: cvar_find() by Maddes + + { 103, "cvar_string", PF_cvar_string }, // 2001-09-16 New BuiltIn Function: cvar_string() by Maddes + + { 105, "cvar_free", PF_cvar_free }, // 2001-09-18 New BuiltIn Function: cvar_free() by Maddes + + { 106, "NVS_InitSVCMsg", PF_NVS_InitSVCMsg }, // 2000-05-02 NVS SVC by Maddes + + { 107, "WriteFloat", PF_WriteFloat }, // 2001-09-16 New BuiltIn Function: WriteFloat() by Maddes + + { 108, "etof", PF_etof }, // 2001-09-25 New BuiltIn Function: etof() by Maddes + + { 109, "ftoe", PF_ftoe }, // 2001-09-25 New BuiltIn Function: ftoe() by Maddes +*/ + +// 2001-09-20 QuakeC file access by FrikaC/Maddes start +// not implemented yet + + { 110, "fopen", PF_fopen }, + { 111, "fclose", PF_fclose }, + { 112, "fgets", PF_fgets }, + { 113, "fputs", PF_fputs }, + { 0, "open", PF_fopen }, // 0 indicates that this entry is just for remapping (because of name and number change) + { 0, "close", PF_fclose }, + { 0, "read", PF_fgets }, + { 0, "write", PF_fputs }, + +// 2001-09-20 QuakeC file access by FrikaC/Maddes end + +// 2001-09-20 QuakeC string manipulation by FrikaC/Maddes start +// not implemented yet + + { 114, "strlen", PF_strlen }, + { 115, "strcat", PF_strcat }, + { 116, "substring", PF_substring }, + { 117, "stov", PF_stov }, + { 118, "strzone", PF_strzone }, + { 119, "strunzone", PF_strunzone }, + { 120, "strtrim", PF_strtrim }, + { 0, "zone", PF_strzone }, // 0 indicates that this entry is just for remapping (because of name and number change) + { 0, "unzone", PF_strunzone }, + +// 2001-09-20 QuakeC string manipulation by FrikaC/Maddes end + +// 2001-11-15 DarkPlaces general builtin functions by Lord Havoc start +// not implemented yet +/* + { 400, "copyentity", PF_... }, + { 401, "setcolor", PF_... }, + { 402, "findchain", PF_... }, + { 403, "findchainfloat", PF_... }, + { 404, "effect", PF_... }, + { 405, "te_blood", PF_... }, + { 406, "te_bloodshower", PF_... }, + { 407, "te_explosionrgb", PF_... }, + { 408, "te_particlecube", PF_... }, + { 409, "te_particlerain", PF_... }, + { 410, "te_particlesnow", PF_... }, + { 411, "te_spark", PF_... }, + { 412, "te_gunshotquad", PF_... }, + { 413, "te_spikequad", PF_... }, + { 414, "te_superspikequad", PF_... }, + { 415, "te_explosionquad", PF_... }, + { 416, "te_smallflash", PF_... } + { 417, "te_customflash", PF_... }, + { 418, "te_gunshot", PF_... }, + { 419, "te_spike", PF_... }, + { 420, "te_superspike", PF_... }, + { 421, "te_explosion", PF_... }, + { 422, "te_tarexplosion", PF_... }, + { 423, "te_wizspike", PF_... }, + { 424, "te_knightspike", PF_... }, + { 425, "te_lavasplash", PF_... } + { 426, "te_teleport", PF_... }, + { 427, "te_explosion2", PF_... }, + { 428, "te_lightning1", PF_... }, + { 429, "te_lightning2", PF_... }, + { 430, "te_lightning3", PF_... }, + { 431, "te_beam", PF_... }, + { 432, "vectorvectors", PF_... },*/ + { 441, "tokenize", PF_tokenize }, + { 442, "argv", PF_ArgV }, + { 480, "strtolower", PF_strtolower }, + { 494, "crc16", PF_crc16 }, + + { 500, "songegg", PF_SongEgg }, + { 501, "nzp_maxammo", PF_MaxAmmo }, + { 502, "grenade_pulse", PF_GrenadePulse }, + { 503, "nzp_maxai", PF_MaxZombies }, + { 504, "nzp_bettyprompt", PF_BettyPrompt }, + { 505, "nzp_setplayername", PF_SetPlayerName }, + { 506, "nzp_setdoubletapver", PF_SetDoubleTapVersion }, + { 507, "nzp_screenflash", PF_ScreenFlash }, + { 508, "nzp_lockviewmodel", PF_LockViewmodel }, + { 509, "nzp_rumble", PF_Rumble } + +// 2001-11-15 DarkPlaces general builtin functions by Lord Havoc end -PF_setspawnparms, -PF_achievement, // #79 -PF_Fixme, // #80 -PF_stof, // #81 -PF_Fixme, // #82 -Get_Waypoint_Near, // #83 -Do_Pathfind, // #84 -Open_Waypoint, // #85 -Get_Next_Waypoint, // #86 -PF_useprint, // #87 -Get_First_Waypoint, // #88 -Close_Waypoint, // #89 -PF_tracebox, // #90 -PF_Fixme, // #91 -PF_Fixme, // #92 -PF_Fixme, // #93 -PF_Fixme, // #94 -PF_Fixme, // #95 -PF_Fixme, // #96 -PF_Fixme, // #97 -PF_FindFloat, // #98 -PF_tracemove, // #99 -PF_Fixme, // #100 -PF_Fixme, // #101 -PF_Fixme, // #102 -PF_Fixme, // #103 -PF_Fixme, // #104 -PF_Fixme, // #105 -PF_Fixme, // #106 -PF_Fixme, // #107 -PF_Fixme, // #108 -PF_Fixme, // #109 -PF_fopen, // #110 -PF_fclose, // #111 -PF_fgets, // #112 -PF_fputs, // #113 -PF_strlen, // #114 -PF_strcat, // #115 -PF_substring, // #116 -PF_stov, // #117 -PF_strzone, // #118 -PF_strunzone, // #119 -PF_strtrim, // #120 -PF_Fixme, // #121 -PF_Fixme, // #122 -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_tokenize, // #441 -PF_ArgV, // #442 -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_strtolower, // #480 -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_crc16, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_Fixme, -PF_SongEgg, // #500 -PF_MaxAmmo, // #501 -PF_GrenadePulse, // #502 -PF_MaxZombies, // #503 -PF_BettyPrompt, // #504 -PF_SetPlayerName, // #505 -PF_SetDoubleTapVersion, // #506 -PF_ScreenFlash, // #507 -PF_LockViewmodel, // #508 -PF_Rumble, // #509 -PF_Fixme, }; -builtin_t *pr_builtins = pr_builtin; -int pr_numbuiltins = sizeof(pr_builtin)/sizeof(pr_builtin[0]); +int pr_ebfs_numbuiltins = sizeof(pr_ebfs_builtins)/sizeof(pr_ebfs_builtins[0]); +// 2001-09-14 Enhanced BuiltIn Function System (EBFS) by Maddes end diff --git a/source/pr_edict.c b/source/pr_edict.c index 3bff77a..a07fc98 100644 --- a/source/pr_edict.c +++ b/source/pr_edict.c @@ -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 ; inumglobaldefs ; i++) { def = &pr_globaldefs[i]; @@ -201,7 +206,7 @@ ddef_t *ED_FieldAtOfs (int ofs) { ddef_t *def; int i; - + for (i=0 ; inumfielddefs ; i++) { def = &pr_fielddefs[i]; @@ -220,7 +225,7 @@ ddef_t *ED_FindField (char *name) { ddef_t *def; int i; - + for (i=0 ; inumfielddefs ; i++) { def = &pr_fielddefs[i]; @@ -240,7 +245,7 @@ ddef_t *ED_FindGlobal (char *name) { ddef_t *def; int i; - + for (i=0 ; inumglobaldefs ; i++) { def = &pr_globaldefs[i]; @@ -260,7 +265,7 @@ dfunction_t *ED_FindFunction (char *name) { dfunction_t *func; int i; - + for (i=0 ; inumfunctions ; 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 ; jtype, (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 ; inumfielddefs ; 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) { @@ -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 ; iofs_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 ; inumstatements ; 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 ; inumfunctions; 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 ; inumglobaldefs ; 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; diff --git a/source/pr_exec.c b/source/pr_exec.c index f369692..d6a1a37 100644 --- a/source/pr_exec.c +++ b/source/pr_exec.c @@ -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 ("\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 ("\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); } diff --git a/source/progs.h b/source/progs.h index 8490cb0..6985511 100644 --- a/source/progs.h +++ b/source/progs.h @@ -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) \ No newline at end of file +//eval_t *GetEdictFieldValue(edict_t *ed, char *field); +#define GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (eval_t *)((byte *)&ed->v + fieldoffset) : NULL) diff --git a/source/protocol.h b/source/protocol.h index ea52ec4..607484d 100644 --- a/source/protocol.h +++ b/source/protocol.h @@ -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 // #define svc_stopsound 16 // -#define svc_updatecolors 17 // [byte] [byte] #define svc_particle 18 // [vec3] #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 \ No newline at end of file +#define TE_RAYSPLASHRED 15 diff --git a/source/world.c b/source/world.c index f17dd3d..f2c8545 100644 --- a/source/world.c +++ b/source/world.c @@ -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 +#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 ); diff --git a/source/world.h b/source/world.h index 3514829..e33672e 100644 --- a/source/world.h +++ b/source/world.h @@ -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