Major update, been neglecting CVS for some time...
authorlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Oct 2001 11:46:20 +0000 (11:46 +0000)
committerlordhavoc <lordhavoc@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 15 Oct 2001 11:46:20 +0000 (11:46 +0000)
clipping engine (r_clip.c) to determine exactly what is visible (this has altered MANY parts of the rendering engine)

fixed visibility bug with multiple players on a listen server

vid_glx.c has been improved/cleaned up greatly and now pays attention to vid_mouse and vid_dga and will not grab the mouse until after the first frame

snd_alsa_0_5.c has been fixed (Qprintf vs fprintf bug)

nehahra works again (was missing svc_skybox support)

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@915 d7cf8633-e32d-0410-b094-e92efae38249

45 files changed:
buildnumber.c
cl_input.c
cl_main.c
cl_parse.c
cmd.h
common.c
common.h
gl_models.c
gl_rmain.c
gl_rmisc.c
gl_rsurf.c
gl_screen.c
gl_textures.c
glquake.h
host.c
host_cmd.c
image.c
mathlib.c
mathlib.h
menu.c
model_brush.c
model_brush.h
progs.h
protocol.h
quakeio.c
quakeio.h
r_clip.c [new file with mode: 0644]
r_clip.h [new file with mode: 0644]
r_light.c
r_part.c
r_sprites.c
render.h
snd_alsa_0_5.c
sv_main.c
sv_user.c
sys_linux.c
sys_win.c
transform.c
transform.h
vid.h
vid_3dfxsvga.c
vid_glx.c
view.c
wad.c
world.c

index 82d779f..5bfe6ad 100644 (file)
@@ -1,4 +1,4 @@
 
-#define BUILDNUMBER 103
+#define BUILDNUMBER 104
 
 int buildnumber = BUILDNUMBER;
index 18ba2fc..d49dd43 100644 (file)
@@ -227,10 +227,10 @@ float CL_KeyState (kbutton_t *key)
 
 //==========================================================================
 
-cvar_t cl_upspeed = {"cl_upspeed","200"};
-cvar_t cl_forwardspeed = {"cl_forwardspeed","200", true};
-cvar_t cl_backspeed = {"cl_backspeed","200", true};
-cvar_t cl_sidespeed = {"cl_sidespeed","350"};
+cvar_t cl_upspeed = {"cl_upspeed","400"};
+cvar_t cl_forwardspeed = {"cl_forwardspeed","400", true};
+cvar_t cl_backspeed = {"cl_backspeed","400", true};
+cvar_t cl_sidespeed = {"cl_sidespeed","350", true};
 
 cvar_t cl_movespeedkey = {"cl_movespeedkey","2.0"};
 
index e44e29e..d0f306b 100644 (file)
--- a/cl_main.c
+++ b/cl_main.c
@@ -667,8 +667,16 @@ void CL_RelinkEntities (void)
                        CL_AllocDlight (ent, ent->render.origin, dlightradius, dlightcolor[0] * d, dlightcolor[1] * d, dlightcolor[2] * d, 0, 0);
                }
 
-               if (!chase_active.value && ((i == cl.viewentity) || (ent->render.flags & RENDER_EXTERIORMODEL)))
-                       continue;
+               if (chase_active.value)
+               {
+                       if (ent->render.flags & RENDER_VIEWMODEL)
+                               continue;
+               }
+               else
+               {
+                       if (i == cl.viewentity || (ent->render.flags & RENDER_EXTERIORMODEL))
+                               continue;
+               }
 
                if (ent->render.model == NULL)
                        continue;
index a548373..7b68dde 100644 (file)
@@ -67,7 +67,7 @@ char *svc_strings[128] =
        "svc_cutscene",
        "svc_showlmp",  // [string] iconlabel [string] lmpfile [short] x [short] y
        "svc_hidelmp",  // [string] iconlabel
-       "", // 37
+       "svc_skybox", // [string] skyname
        "", // 38
        "", // 39
        "", // 40
@@ -246,7 +246,7 @@ void CL_ParseEntityLump(char *entdata)
        char wadname[128];
        int i, j, k;
        FOG_clear(); // LordHavoc: no fog until set
-       R_SetSkyBox(""); // LordHavoc: no enviroment mapped sky until set
+       R_SetSkyBox(""); // LordHavoc: no environment mapped sky until set
        r_farclip.value = 6144; // LordHavoc: default farclip distance
        data = entdata;
        if (!data)
@@ -1196,6 +1196,9 @@ void CL_ParseServerMessage (void)
                case svc_showlmp:
                        SHOWLMP_decodeshow();
                        break;
+               case svc_skybox:
+                       R_SetSkyBox(MSG_ReadString());
+                       break;
                }
        }
 
diff --git a/cmd.h b/cmd.h
index 5583b32..da1daa6 100644 (file)
--- a/cmd.h
+++ b/cmd.h
@@ -91,14 +91,6 @@ char         *Cmd_CompleteCommand (char *partial);
 // attempts to match a partial command for automatic command line completion
 // returns NULL if nothing fits
 
-int            Cmd_CompleteAliasCountPossible (char *partial);
-char   **Cmd_CompleteAliasBuildList (char *partial);
-int            Cmd_CompleteCountPossible (char *partial);
-char   **Cmd_CompleteBuildList (char *partial);
-char   *Cmd_CompleteAlias (char *partial);
-// Enhanced console completion by Fett erich@heintz.com
-// Added by EvilTypeGuy eviltypeguy@qeradiant.com
-
 int            Cmd_Argc (void);
 char   *Cmd_Argv (int arg);
 char   *Cmd_Args (void);
index a39cc5e..8f8464a 100644 (file)
--- a/common.c
+++ b/common.c
@@ -50,10 +50,6 @@ qboolean             msg_suppress_1 = 0;
 
 void COM_InitFilesystem (void);
 
-// if a packfile directory differs from this, it is assumed to be hacked
-#define PAK0_COUNT              339
-#define PAK0_CRC                32981
-
 char   com_token[1024];
 int            com_argc;
 char   **com_argv;
@@ -63,27 +59,6 @@ char com_cmdline[CMDLINE_LENGTH];
 
 qboolean               standard_quake = true, rogue = false, hipnotic = false, nehahra = false;
 
-// this graphic needs to be in the pak file to use registered features
-unsigned short pop[] =
-{
- 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
-,0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000
-,0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000
-,0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600
-,0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563
-,0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564
-,0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564
-,0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563
-,0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500
-,0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200
-,0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000
-,0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000
-,0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000
-,0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000
-,0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000
-,0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000
-};
-
 /*
 
 
@@ -102,39 +77,12 @@ into the cache directory, then opened there.
 
 FIXME:
 The file "parms.txt" will be read out of the game directory and appended to the current command line arguments to allow different games to initialize startup parms differently.  This could be used to add a "-sspeed 22050" for the high quality sound edition.  Because they are added at the end, they will not override an explicit setting on the original command line.
-       
+
 */
 
 //============================================================================
 
 
-// ClearLink is used for new headnodes
-void ClearLink (link_t *l)
-{
-       l->prev = l->next = l;
-}
-
-void RemoveLink (link_t *l)
-{
-       l->next->prev = l->prev;
-       l->prev->next = l->next;
-}
-
-void InsertLinkBefore (link_t *l, link_t *before)
-{
-       l->next = before;
-       l->prev = before->prev;
-       l->prev->next = l;
-       l->next->prev = l;
-}
-void InsertLinkAfter (link_t *l, link_t *after)
-{
-       l->next = after->next;
-       l->prev = after;
-       l->prev->next = l;
-       l->next->prev = l;
-}
-
 /*
 ============================================================================
 
@@ -147,7 +95,7 @@ void InsertLinkAfter (link_t *l, link_t *after)
 void Q_memset (void *dest, int fill, int count)
 {
        int             i;
-       
+
        if ( (((long)dest | count) & 3) == 0)
        {
                count >>= 2;
@@ -266,7 +214,7 @@ int Q_strncmp (char *s1, char *s2, int count)
 int Q_strncasecmp (char *s1, char *s2, int n)
 {
        int             c1, c2;
-       
+
        while (1)
        {
                c1 = *s1++;
@@ -428,7 +376,7 @@ float Q_atof (char *str)
                val /= 10;
                total--;
        }
-       
+
        return val*sign;
 }
 */
@@ -441,7 +389,7 @@ float Q_atof (char *str)
 ============================================================================
 */
 
-#ifndef WIN32
+#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
 short   (*BigShort) (short l);
 short   (*LittleShort) (short l);
 int     (*BigLong) (int l);
@@ -698,7 +646,7 @@ int MSG_ReadLong (void)
                msg_badread = true;
                return -1;
        }
-               
+
        c = net_message.data[msg_readcount]
        + (net_message.data[msg_readcount+1]<<8)
        + (net_message.data[msg_readcount+2]<<16)
@@ -879,11 +827,20 @@ char *COM_SkipPath (char *pathname)
 COM_StripExtension
 ============
 */
+// LordHavoc: replacement for severely broken COM_StripExtension that was used in original quake.
 void COM_StripExtension (char *in, char *out)
 {
-       while (*in && *in != '.')
+       char *last = NULL;
+       while (*in)
+       {
+               if (*in == '.')
+                       last = in;
+               if ((*in == '/') || (*in == '\\') || (*in == ':'))
+                       last = NULL;
                *out++ = *in++;
-       *out = 0;
+       }
+       if (last)
+               *last = 0;
 }
 
 /*
@@ -1079,16 +1036,11 @@ being registered.
 */
 void COM_CheckRegistered (void)
 {
-       QFile           *h;
-       unsigned short  check[128];
-       int                     i;
-
        Cvar_Set ("cmdline", com_cmdline);
 
-       COM_FOpenFile("gfx/pop.lmp", &h, false, true);
        static_registered = 0;
 
-       if (!h)
+       if (!Sys_FileTime("gfx/pop.lmp"))
        {
                if (com_modified)
                        Con_Printf ("Playing shareware version, with modification.\nwarning: most mods require full quake data.\n");
@@ -1102,13 +1054,6 @@ void COM_CheckRegistered (void)
 //                     Sys_Error ("You must have the registered version to use modified games");
                return;
        }
-
-       Qread (h, check, sizeof(check));
-       Qclose (h);
-       
-       for (i=0 ; i<128 ; i++)
-               if (pop[i] != (unsigned short)BigShort (check[i]))
-                       Sys_Error ("Corrupted data file.");
        
 //     Cvar_Set ("cmdline", com_cmdline);
        Cvar_Set ("registered", "1");
@@ -1242,7 +1187,7 @@ COM_Init
 */
 void COM_Init (char *basedir)
 {
-#ifndef WIN32
+#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
        byte    swaptest[2] = {1,0};
 
 // set the byte swapping variables in a portable manner 
@@ -1403,7 +1348,7 @@ LordHavoc: Previously only used for CopyFile, now also used for COM_WriteFile.
 void    COM_CreatePath (char *path)
 {
        char    *ofs, save;
-       
+
        for (ofs = path+1 ; *ofs ; ofs++)
        {
                if (*ofs == '/' || *ofs == '\\' || *ofs == ':')
@@ -1598,12 +1543,7 @@ int COM_FindFile (char *filename, QFile **file, qboolean quiet, qboolean zip)
                        
                        findtime = Sys_FileTime (netpath);
                        if (findtime == -1)
-                       {
-                               sprintf (netpath, "%s/%s",search->filename, gzfilename);
-                               findtime = Sys_FileTime (netpath);
-                               if (findtime == -1)
-                                       continue;
-                       }
+                               continue;
                                
 #if CACHEENABLE
                        // see if the file needs to be updated in the cache
@@ -1754,15 +1694,14 @@ of the list so they override previous pack files.
 */
 pack_t *COM_LoadPackFile (char *packfile)
 {
-       dpackheader_t   header;
-       int                             i;
-       packfile_t              *newfiles;
-       int                             numpackfiles;
-       pack_t                  *pack;
-       int                             packhandle;
+       dpackheader_t   header;
+       int                             i;
+       packfile_t              *newfiles;
+       int                             numpackfiles;
+       pack_t                  *pack;
+       int                             packhandle;
        // LordHavoc: changed from stack array to temporary malloc, allowing huge pack directories
-       dpackfile_t             *info;
-       unsigned short          crc;
+       dpackfile_t             *info;
 
        if (Sys_FileOpenRead (packfile, &packhandle) == -1)
        {
@@ -1781,24 +1720,12 @@ pack_t *COM_LoadPackFile (char *packfile)
        if (numpackfiles > MAX_FILES_IN_PACK)
                Sys_Error ("%s has %i files", packfile, numpackfiles);
 
-       if (numpackfiles != PAK0_COUNT)
-               com_modified = true;    // not the original file
-
        newfiles = Hunk_AllocName (numpackfiles * sizeof(packfile_t), "pack file-table");
 
        info = qmalloc(sizeof(*info)*MAX_FILES_IN_PACK);
        Sys_FileSeek (packhandle, header.dirofs);
        Sys_FileRead (packhandle, (void *)info, header.dirlen);
 
-// crc the directory to check for modifications
-       CRC_Init (&crc);
-       // LordHavoc: speedup
-       CRC_ProcessBytes(&crc, (byte *)info, header.dirlen);
-//     for (i=0 ; i<header.dirlen ; i++)
-//             CRC_ProcessByte (&crc, ((byte *)info)[i]);
-       if (crc != PAK0_CRC)
-               com_modified = true;
-
 // parse the directory
        for (i=0 ; i<numpackfiles ; i++)
        {
index 81de850..2d63548 100644 (file)
--- a/common.h
+++ b/common.h
@@ -56,58 +56,47 @@ void SZ_Print (sizebuf_t *buf, char *data); // strcats onto the sizebuf
 
 //============================================================================
 
-typedef struct link_s
-{
-       struct link_s   *prev, *next;
-} link_t;
-
-
-void ClearLink (link_t *l);
-void RemoveLink (link_t *l);
-void InsertLinkBefore (link_t *l, link_t *before);
-void InsertLinkAfter (link_t *l, link_t *after);
-
-// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
-// ent = STRUCT_FROM_LINK(link,entity_t,order)
-// FIXME: remove this mess!
-#define        STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
-
-//============================================================================
-
 #ifndef NULL
 #define NULL ((void *)0)
 #endif
 
-#define Q_MAXCHAR ((char)0x7f)
-#define Q_MAXSHORT ((short)0x7fff)
-#define Q_MAXINT       ((int)0x7fffffff)
-#define Q_MAXLONG ((int)0x7fffffff)
-#define Q_MAXFLOAT ((int)0x7fffffff)
-
-#define Q_MINCHAR ((char)0x80)
-#define Q_MINSHORT ((short)0x8000)
-#define Q_MININT       ((int)0x80000000)
-#define Q_MINLONG ((int)0x80000000)
-#define Q_MINFLOAT ((int)0x7fffffff)
-
 //============================================================================
-#ifdef WIN32
-short   ShortSwap (short l);
-int    LongSwap (int l);
+#if !defined(ENDIAN_LITTLE) && !defined(ENDIAN_BIG)
+#if  defined(__i386__) || defined(__ia64__) || defined(WIN32) || (defined(__alpha__) || defined(__alpha)) || defined(__arm__) || (defined(__mips__) && defined(__MIPSEL__)) || defined(__LITTLE_ENDIAN__)
+#define ENDIAN_LITTLE
+#else
+#define ENDIAN_BIG
+#endif
+#endif
+
+short ShortSwap (short l);
+int LongSwap (int l);
 float FloatSwap (float f);
+
+#ifdef ENDIAN_LITTLE
+// little endian
 #define BigShort(l) ShortSwap(l)
 #define LittleShort(l) (l)
 #define BigLong(l) LongSwap(l)
 #define LittleLong(l) (l)
 #define BigFloat(l) FloatSwap(l)
 #define LittleFloat(l) (l)
+#elif ENDIAN_BIG
+// big endian
+#define BigShort(l) (l)
+#define LittleShort(l) ShortSwap(l)
+#define BigLong(l) (l)
+#define LittleLong(l) LongSwap(l)
+#define BigFloat(l) (l)
+#define LittleFloat(l) FloatSwap(l)
 #else
-extern short   (*BigShort) (short l);
-extern short   (*LittleShort) (short l);
-extern int     (*BigLong) (int l);
-extern int     (*LittleLong) (int l);
-extern float   (*BigFloat) (float l);
-extern float   (*LittleFloat) (float l);
+// figure it out at runtime
+extern short (*BigShort) (short l);
+extern short (*LittleShort) (short l);
+extern int (*BigLong) (int l);
+extern int (*LittleLong) (int l);
+extern float (*BigFloat) (float l);
+extern float (*LittleFloat) (float l);
 #endif
 
 //============================================================================
index 2829b94..9bf9b72 100644 (file)
@@ -149,16 +149,16 @@ void R_AliasLerpVerts(int vertcount,
        float *av, *avn;
        av = aliasvert;
        avn = aliasvertnorm;
-       VectorScaleQuick(fscale1, lerp1, scale1);
+       VectorScale(fscale1, lerp1, scale1);
        if (lerp2)
        {
-               VectorScaleQuick(fscale2, lerp2, scale2);
+               VectorScale(fscale2, lerp2, scale2);
                if (lerp3)
                {
-                       VectorScaleQuick(fscale3, lerp3, scale3);
+                       VectorScale(fscale3, lerp3, scale3);
                        if (lerp4)
                        {
-                               VectorScaleQuick(fscale4, lerp4, scale4);
+                               VectorScale(fscale4, lerp4, scale4);
                                translate[0] = translate1[0] * lerp1 + translate2[0] * lerp2 + translate3[0] * lerp3 + translate4[0] * lerp4;
                                translate[1] = translate1[1] * lerp1 + translate2[1] * lerp2 + translate3[1] * lerp3 + translate4[1] * lerp4;
                                translate[2] = translate1[2] * lerp1 + translate2[2] * lerp2 + translate3[2] * lerp3 + translate4[2] * lerp4;
@@ -563,7 +563,6 @@ void ZymoticLerpBones(int count, zymbonematrix *bonebase, frameblend_t *blend, z
 {
        float lerp1, lerp2, lerp3, lerp4;
        zymbonematrix *out, rootmatrix, m, *bone1, *bone2, *bone3, *bone4;
-       lerp1 = 1 - lerp2;
        out = zymbonepose;
        AngleVectors(rootangles, rootmatrix.m[0], rootmatrix.m[1], rootmatrix.m[2]);
        VectorScale(rootmatrix.m[0], rootscale, rootmatrix.m[0]);
@@ -753,19 +752,11 @@ void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
        }
 }
 
-float ixtable[4096];
-
 void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
 {
        int a, b, c, d;
        float *out, v1[3], v2[3], normal[3];
        int *u;
-       if (!ixtable[1])
-       {
-               ixtable[0] = 0;
-               for (a = 1;a < 4096;a++)
-                       ixtable[a] = 1.0f / a;
-       }
        // clear normals
        memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
        memset(aliasvertusage, 0, sizeof(int) * vertcount);
@@ -947,8 +938,8 @@ void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, f
        VectorAdd (org, clmodel->mins, mins);
        VectorAdd (org, clmodel->maxs, maxs);
 
-       if (cull && R_VisibleCullBox (mins, maxs))
-               return;
+//     if (cull && R_CullBox (mins, maxs))
+//             return;
 
        c_models++;
 
index b8bd3f9..37052fd 100644 (file)
@@ -21,8 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "quakedef.h"
 
-entity_t       r_worldentity;
-
 qboolean       r_cache_thrash;         // compatability
 
 vec3_t         modelorg, r_entorigin;
@@ -60,6 +58,7 @@ mleaf_t               *r_viewleaf, *r_oldviewleaf;
 
 unsigned short d_lightstylevalue[256]; // 8.8 fraction of base light value
 
+float ixtable[4096];
 
 void R_MarkLeaves (void);
 
@@ -88,21 +87,23 @@ cvar_t      gl_fogstart = {"gl_fogstart", "0"};
 cvar_t gl_fogend = {"gl_fogend","0"};
 cvar_t glfog = {"glfog", "0"};
 
+/*
 int R_VisibleCullBox (vec3_t mins, vec3_t maxs)
 {
        int sides;
        mnode_t *nodestack[8192], *node;
        int stack = 0;
 
-       if (R_CullBox(mins, maxs))
-               return true;
-
        node = cl.worldmodel->nodes;
 loc0:
        if (node->contents < 0)
        {
                if (((mleaf_t *)node)->visframe == r_framecount)
+               {
+                       if (R_CullBox(mins, maxs))
+                               return true;
                        return false;
+               }
                if (!stack)
                        return true;
                node = nodestack[--stack];
@@ -131,6 +132,7 @@ loc0:
        node = node->children[1];
        goto loc0;
 }
+*/
 
 qboolean lighthalf;
 
@@ -263,7 +265,12 @@ void gl_main_newmap(void)
 
 void GL_Main_Init(void)
 {
+       int a;
        FOG_registercvars();
+       // LordHavoc: setup 1.0f / N table for quick recipricols of integers
+       ixtable[0] = 0;
+       for (a = 1;a < 4096;a++)
+               ixtable[a] = 1.0f / a;
        Cvar_RegisterVariable (&r_drawentities);
        Cvar_RegisterVariable (&r_drawviewmodel);
        Cvar_RegisterVariable (&r_speeds);
@@ -296,10 +303,12 @@ extern void R_Light_Init(void);
 extern void R_Particles_Init(void);
 extern void R_Explosion_Init(void);
 extern void CL_Effects_Init(void);
+extern void R_Clip_Init(void);
 
 void Render_Init(void)
 {
        R_Modules_Shutdown();
+       R_Clip_Init();
        GL_Draw_Init();
        GL_Main_Init();
        GL_Models_Init();
@@ -372,9 +381,6 @@ float       modelalpha;
 
 //==================================================================================
 
-void R_DrawBrushModel (entity_t *e);
-void R_DrawSpriteModel (entity_t *e, frameblend_t *blend);
-
 void R_LerpUpdate(entity_t *ent)
 {
        int frame;
@@ -442,12 +448,49 @@ void R_PrepareEntities (void)
        }
 }
 
+void R_Entity_Callback(void *data, void *junk)
+{
+       ((entity_t *)data)->render.visframe = r_framecount;
+}
+
+void R_AddModelEntities (void)
+{
+       int             i;
+       vec3_t  mins, maxs;
+       frameblend_t blend[4];
+
+       if (!r_drawentities.value)
+               return;
+
+       for (i = 0;i < cl_numvisedicts;i++)
+       {
+               currententity = cl_visedicts[i];
+               if (currententity->render.model->type == mod_brush)
+               {
+                       modelalpha = currententity->render.alpha;
+                       R_DrawBrushModel (currententity);
+               }
+               else if (currententity->render.model->type == mod_alias)
+               {
+                       VectorAdd(currententity->render.origin, currententity->render.model->mins, mins);
+                       VectorAdd(currententity->render.origin, currententity->render.model->maxs, maxs);
+                       R_Clip_AddBox(mins, maxs, R_Entity_Callback, currententity, NULL);
+               }
+               else if (currententity->render.model->type == mod_sprite)
+               {
+                       R_LerpUpdate(currententity);
+                       R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
+                       R_ClipSprite(currententity, blend);
+               }
+       }
+}
+
 /*
 =============
 R_DrawEntitiesOnList
 =============
 */
-// LordHavoc: split so bmodels are rendered before any other objects
+/*
 void R_DrawEntitiesOnList1 (void)
 {
        int             i;
@@ -457,6 +500,8 @@ void R_DrawEntitiesOnList1 (void)
 
        for (i = 0;i < cl_numvisedicts;i++)
        {
+               if (cl_visedicts[i]->render.visframe != r_framecount)
+                       continue;
                if (cl_visedicts[i]->render.model->type != mod_brush)
                        continue;
                currententity = cl_visedicts[i];
@@ -465,37 +510,55 @@ void R_DrawEntitiesOnList1 (void)
                R_DrawBrushModel (currententity);
        }
 }
+*/
 
-void R_DrawEntitiesOnList2 (void)
+void R_DrawModels (void)
 {
        int             i;
        frameblend_t blend[4];
+//     vec3_t  mins, maxs;
 
        if (!r_drawentities.value)
                return;
 
        for (i = 0;i < cl_numvisedicts;i++)
        {
+               if (cl_visedicts[i]->render.visframe != r_framecount)
+                       continue;
                currententity = cl_visedicts[i];
+               if (currententity->render.model->type != mod_alias && currententity->render.model->type != mod_sprite)
+                       continue;
+
                modelalpha = currententity->render.alpha;
 
-               switch (currententity->render.model->type)
+               if (currententity->render.model->type == mod_alias)
                {
-               case mod_alias:
+                       // only lerp models here because sprites were already lerped for their clip polygon
                        R_LerpUpdate(currententity);
                        R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
                        R_DrawAliasModel (currententity, true, modelalpha, currententity->render.model, blend, currententity->render.skinnum, currententity->render.origin, currententity->render.angles, currententity->render.scale, currententity->render.effects, currententity->render.model->flags, currententity->render.colormap);
-                       break;
-
-               case mod_sprite:
-                       R_LerpUpdate(currententity);
+               }
+               else //if (currententity->render.model->type == mod_sprite)
+               {
+                       // build blend array
                        R_LerpAnimation(currententity->render.model, currententity->render.frame1, currententity->render.frame2, currententity->render.frame1start, currententity->render.frame2start, currententity->render.framelerp, blend);
                        R_DrawSpriteModel (currententity, blend);
-                       break;
+               }
 
-               default:
+               /*
+               VectorAdd(cl_visedicts[i]->render.origin, cl_visedicts[i]->render.model->mins, mins);
+               VectorAdd(cl_visedicts[i]->render.origin, cl_visedicts[i]->render.model->maxs, maxs);
+
+               switch (cl_visedicts[i]->render.model->type)
+               {
+               case mod_alias:
+                       R_Clip_AddBox(mins, maxs, R_DrawModelCallback, cl_visedicts[i], NULL);
+                       break;
+               case mod_sprite:
+                       R_Clip_AddBox(mins, maxs, R_DrawSpriteCallback, cl_visedicts[i], NULL);
                        break;
                }
+               */
        }
 }
 
@@ -534,7 +597,11 @@ void R_SetFrustum (void)
 {
        int             i;
 
-       if (r_refdef.fov_x == 90) 
+       // LordHavoc: note to all quake engine coders, this code was making the
+       // view frustum taller than it should have been (it assumed the view is
+       // square; it is not square), so I disabled it
+       /*
+       if (r_refdef.fov_x == 90)
        {
                // front side is visible
 
@@ -546,6 +613,7 @@ void R_SetFrustum (void)
        }
        else
        {
+       */
                // rotate VPN right by FOV_X/2 degrees
                RotatePointAroundVector( frustum[0].normal, vup, vpn, -(90-r_refdef.fov_x / 2 ) );
                // rotate VPN left by FOV_X/2 degrees
@@ -554,14 +622,14 @@ void R_SetFrustum (void)
                RotatePointAroundVector( frustum[2].normal, vright, vpn, 90-r_refdef.fov_y / 2 );
                // rotate VPN down by FOV_X/2 degrees
                RotatePointAroundVector( frustum[3].normal, vright, vpn, -( 90 - r_refdef.fov_y / 2 ) );
-       }
+       //}
 
        for (i=0 ; i<4 ; i++)
        {
                frustum[i].type = PLANE_ANYZ;
                frustum[i].dist = DotProduct (r_origin, frustum[i].normal);
 //             frustum[i].signbits = SignbitsForPlane (&frustum[i]);
-               BoxOnPlaneSideClassify(&frustum[i]);
+               PlaneClassify(&frustum[i]);
        }
 }
 
@@ -783,16 +851,6 @@ void GL_BlendView(void)
        glEnable(GL_TEXTURE_2D);
 }
 
-#define TIMEREPORT(VAR) \
-       if (r_speeds2.value)\
-       {\
-               temptime = currtime;\
-               currtime = Sys_DoubleTime();\
-               VAR = (int) ((currtime - temptime) * 1000000.0);\
-       }\
-       else\
-               VAR = 0;
-
 /*
 ================
 R_RenderView
@@ -802,33 +860,88 @@ r_refdef must be set before the first call
 */
 extern void R_Sky(void);
 extern void UploadLightmaps(void);
-char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81], r_speeds2_string7[81];
+extern void R_DrawSurfaces(void);
+extern void R_DrawPortals(void);
+char r_speeds2_string[1024];
+int speedstringcount;
+
+void timestring(int t, char *desc)
+{
+       char tempbuf[256];
+       int length;
+       if (t < 1000000)
+               sprintf(tempbuf, " %6ius %s", t, desc);
+       else
+               sprintf(tempbuf, " %6ims %s", t / 1000, desc);
+       length = strlen(tempbuf);
+//     while (length < 20)
+//             tempbuf[length++] = ' ';
+//     tempbuf[length] = 0;
+       if (speedstringcount + length > 80)
+       {
+               strcat(r_speeds2_string, "\n");
+               speedstringcount = 0;
+       }
+       // skip the space at the beginning if it's the first on the line
+       if (speedstringcount == 0)
+       {
+               strcat(r_speeds2_string, tempbuf + 1);
+               speedstringcount = length - 1;
+       }
+       else
+       {
+               strcat(r_speeds2_string, tempbuf);
+               speedstringcount += length;
+       }
+}
+
+#define TIMEREPORT(NAME) \
+       if (r_speeds2.value)\
+       {\
+               temptime = currtime;\
+               currtime = Sys_DoubleTime();\
+               timestring((int) ((currtime - temptime) * 1000000.0), NAME);\
+       }
+
 void R_RenderView (void)
 {
        double starttime, currtime, temptime;
-       int time_clear, time_setup, time_world, time_bmodels, time_upload, time_sky, time_wall, time_models, time_moveparticles, time_drawparticles, time_moveexplosions, time_drawexplosions, time_drawdecals, time_transpoly, time_blend, time_total;
 //     if (r_norefresh.value)
 //             return;
 
-       if (!r_worldentity.render.model || !cl.worldmodel)
+       if (!cl.worldmodel)
                Host_Error ("R_RenderView: NULL worldmodel");
 
-       lighthalf = gl_lightmode.value;
-
-       FOG_framebegin();
-
        if (r_speeds2.value)
+       {
                starttime = currtime = Sys_DoubleTime();
+
+               speedstringcount = 0;
+               sprintf(r_speeds2_string, "org:'%c%6.2f %c%6.2f %c%6.2f' ang:'%c%3.0f %c%3.0f %c%3.0f' dir:'%c%2.3f %c%2.3f %c%2.3f'\n%6i walls %6i dlitwalls %7i modeltris %7i transpoly\nBSP: %6i faces %6i nodes %6i leafs\n%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n",
+                       r_origin[0] < 0 ? '-' : ' ', fabs(r_origin[0]), r_origin[1] < 0 ? '-' : ' ', fabs(r_origin[1]), r_origin[2] < 0 ? '-' : ' ', fabs(r_origin[2]), r_refdef.viewangles[0] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[0]), r_refdef.viewangles[1] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[1]), r_refdef.viewangles[2] < 0 ? '-' : ' ', fabs(r_refdef.viewangles[2]), vpn[0] < 0 ? '-' : ' ', fabs(vpn[0]), vpn[1] < 0 ? '-' : ' ', fabs(vpn[1]), vpn[2] < 0 ? '-' : ' ', fabs(vpn[2]),
+                       c_brush_polys, c_light_polys, c_alias_polys, currenttranspoly,
+                       c_faces, c_nodes, c_leafs,
+                       c_models, c_bmodels, c_sprites, c_particles, c_dlights);
+       }
        else
                starttime = currtime = 0;
+
+       R_MoveParticles ();
+       R_MoveExplosions();
+
+       lighthalf = gl_lightmode.value;
+
+       FOG_framebegin();
+
        R_Clear();
-       TIMEREPORT(time_clear)
+       TIMEREPORT("clear     ")
 
        // render normal view
 
        R_SetupFrame ();
        R_SetFrustum ();
        R_SetupGL ();
+       R_Clip_StartFrame();
 
        R_PrepareEntities();
 
@@ -836,60 +949,62 @@ void R_RenderView (void)
        wallpolyclear();
        transpolyclear();
 
-       TIMEREPORT(time_setup)
+       TIMEREPORT("setup     ")
 
        R_DrawWorld ();
-       TIMEREPORT(time_world)
-       R_DrawEntitiesOnList1 (); // BSP models
-       TIMEREPORT(time_bmodels)
+       TIMEREPORT("world     ")
+
+       R_AddModelEntities();
+       TIMEREPORT("addmodels")
+
+       R_Clip_EndFrame();
+       TIMEREPORT("scanedge  ")
+
+       // now mark the lit surfaces
+       R_PushDlights ();
+       // yes this does add the world surfaces after the brush models
+       R_DrawSurfaces ();
+       R_DrawPortals ();
+       TIMEREPORT("surfaces  ");
 
        UploadLightmaps();
-       TIMEREPORT(time_upload)
+       TIMEREPORT("uploadlmap")
 
-       skypolyrender(); // fogged sky polys, affects depth
+       // fogged sky polys, affects depth
+       skypolyrender();
 
+       // does not affect depth, draws over the sky polys
        if (currentskypoly)
-               R_Sky(); // does not affect depth, draws over the sky polys
-       TIMEREPORT(time_sky)
+               R_Sky();
+       TIMEREPORT("skypoly   ")
 
        wallpolyrender();
-       TIMEREPORT(time_wall)
+       TIMEREPORT("wallpoly  ")
 
        GL_DrawDecals();
-       TIMEREPORT(time_drawdecals)
+       TIMEREPORT("ddecal    ")
 
+       // don't let sound skip if going slow
        if (!intimerefresh && !r_speeds2.value)
-               S_ExtraUpdate ();       // don't let sound get messed up if going slow
+               S_ExtraUpdate ();
 
-       R_DrawEntitiesOnList2 (); // other models
-//     R_RenderDlights ();
        R_DrawViewModel ();
-       TIMEREPORT(time_models)
-       R_MoveParticles ();
-       TIMEREPORT(time_moveparticles)
+       R_DrawModels ();
+       TIMEREPORT("models    ")
+
        R_DrawParticles ();
-       TIMEREPORT(time_drawparticles)
-       R_MoveExplosions();
-       TIMEREPORT(time_moveexplosions)
+       TIMEREPORT("dparticles")
        R_DrawExplosions();
-       TIMEREPORT(time_drawexplosions)
+       TIMEREPORT("dexplosion")
 
        transpolyrender();
-       TIMEREPORT(time_transpoly)
+       TIMEREPORT("transpoly ")
 
        FOG_frameend();
 
        GL_BlendView();
-       TIMEREPORT(time_blend)
+       TIMEREPORT("blend     ")
+
        if (r_speeds2.value)
-       {
-               time_total = (int) ((Sys_DoubleTime() - starttime) * 1000000.0);
-               sprintf(r_speeds2_string1, "%6i walls %6i dlitwalls %7i modeltris %7i transpoly\n", c_brush_polys, c_light_polys, c_alias_polys, currenttranspoly);
-               sprintf(r_speeds2_string2, "BSP: %6i faces %6i nodes %6i leafs\n", c_faces, c_nodes, c_leafs);
-               sprintf(r_speeds2_string3, "%4i models %4i bmodels %4i sprites %5i particles %3i dlights\n", c_models, c_bmodels, c_sprites, c_particles, c_dlights);
-               sprintf(r_speeds2_string4, "%6ius clear  %6ius setup  %6ius world  %6ius bmodel %6ius upload", time_clear, time_setup, time_world, time_bmodels, time_upload);
-               sprintf(r_speeds2_string5, "%6ius sky    %6ius wall   %6ius models %6ius mpart  %6ius dpart ", time_sky, time_wall, time_models, time_moveparticles, time_drawparticles);
-               sprintf(r_speeds2_string6, "%6ius mexplo %6ius dexplo %6ius decals %6ius trans  %6ius blend ", time_moveexplosions, time_drawexplosions, time_drawdecals, time_transpoly, time_blend);
-               sprintf(r_speeds2_string7, "%6ius permdl %6ius total ", time_models / max(c_models, 1), time_total);
-       }
+               timestring((int) ((Sys_DoubleTime() - starttime) * 1000000.0), "total    ");
 }
index d570e3b..5a8a874 100644 (file)
@@ -48,19 +48,16 @@ void R_Envmap_f (void)
        r_refdef.viewangles[0] = 0;
        r_refdef.viewangles[1] = 0;
        r_refdef.viewangles[2] = 0;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
        R_RenderView ();
        glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        COM_WriteFile ("env0.rgb", buffer, sizeof(buffer));             
 
        r_refdef.viewangles[1] = 90;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
        R_RenderView ();
        glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        COM_WriteFile ("env1.rgb", buffer, sizeof(buffer));             
 
        r_refdef.viewangles[1] = 180;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
        R_RenderView ();
        glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        COM_WriteFile ("env2.rgb", buffer, sizeof(buffer));             
@@ -73,14 +70,12 @@ void R_Envmap_f (void)
 
        r_refdef.viewangles[0] = -90;
        r_refdef.viewangles[1] = 0;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
        R_RenderView ();
        glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        COM_WriteFile ("env4.rgb", buffer, sizeof(buffer));             
 
        r_refdef.viewangles[0] = 90;
        r_refdef.viewangles[1] = 0;
-       GL_BeginRendering (&glx, &gly, &glwidth, &glheight);
        R_RenderView ();
        glReadPixels (0, 0, 256, 256, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
        COM_WriteFile ("env5.rgb", buffer, sizeof(buffer));             
@@ -133,10 +128,6 @@ void R_NewMap (void)
        for (i=0 ; i<256 ; i++)
                d_lightstylevalue[i] = 264;             // normal light value
 
-       memset (&r_worldentity, 0, sizeof(r_worldentity));
-       r_worldentity.render.model = cl.worldmodel;
-       currententity = &r_worldentity;
-
        r_viewleaf = NULL;
        R_Modules_NewMap();
 
index 8029f02..7479d5e 100644 (file)
@@ -8,7 +8,7 @@ of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 
 See the GNU General Public License for more details.
 
@@ -23,7 +23,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 int            lightmap_textures;
 
-// LordHavoc: skinny but tall lightmaps for quicker subimage uploads
 #define        BLOCK_WIDTH             256
 #define        BLOCK_HEIGHT    256
 // LordHavoc: increased lightmap limit from 64 to 1024
@@ -48,6 +47,8 @@ cvar_t r_ambient = {"r_ambient", "0"};
 cvar_t gl_vertex = {"gl_vertex", "0"};
 cvar_t r_dlightmap = {"r_dlightmap", "1"};
 cvar_t r_drawportals = {"r_drawportals", "0"};
+cvar_t r_testvis = {"r_testvis", "0"};
+cvar_t r_solidworldnode = {"r_solidworldnode", "1"};
 
 qboolean lightmaprgba, nosubimagefragments, nosubimage;
 int lightmapbytes;
@@ -79,11 +80,13 @@ void GL_Surf_Init(void)
        Cvar_RegisterVariable(&gl_vertex);
        Cvar_RegisterVariable(&r_dlightmap);
        Cvar_RegisterVariable(&r_drawportals);
+       Cvar_RegisterVariable(&r_testvis);
+       Cvar_RegisterVariable(&r_solidworldnode);
 
        R_RegisterModule("GL_Surf", gl_surf_start, gl_surf_shutdown, gl_surf_newmap);
 }
 
-int         dlightdivtable[32768];
+int dlightdivtable[32768];
 
 /*
        R_AddDynamicLights
@@ -260,12 +263,12 @@ Combine and scale multiple lightmaps into the 8.8 format in blocklights
 */
 void R_BuildLightMap (msurface_t *surf, byte *dest, int stride)
 {
-       int                     smax, tmax;
-       int                     i, j, size, size3;
-       byte            *lightmap;
-       int                     scale;
-       int                     maps;
-       int                     *bl;
+       int             smax, tmax;
+       int             i, j, size, size3;
+       byte    *lightmap;
+       int             scale;
+       int             maps;
+       int             *bl;
 
        surf->cached_dlight = 0;
        surf->cached_lighthalf = lighthalf;
@@ -660,7 +663,7 @@ void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
         || (s->styles[2] != 255 && d_lightstylevalue[s->styles[2]] != s->cached_light[2])
         || (s->styles[3] != 255 && d_lightstylevalue[s->styles[3]] != s->cached_light[3]))))
                R_UpdateLightmap(s, s->lightmaptexturenum);
-       if (r_dlightmap.value || s->dlightframe != r_framecount)
+       if (s->dlightframe != r_framecount || r_dlightmap.value)
        {
                // LordHavoc: fast path version for no vertex lighting cases
                wp = &wallpoly[currentwallpoly];
@@ -674,7 +677,7 @@ void RSurf_DrawWall(msurface_t *s, texture_t *t, int transform)
                        wp->glowtexnum = (unsigned short) R_GetTexture(t->glowtexture);
                        wp->firstvert = currentwallvert;
                        wp->numverts = p->numverts;
-                       wp->lit = lit;
+                       wp->lit = false;
                        wp++;
                        currentwallpoly++;
                        currentwallvert += p->numverts;
@@ -844,6 +847,67 @@ void RSurf_DrawWallVertex(msurface_t *s, texture_t *t, int transform, int isbmod
 
 void R_NoVisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model);
 
+float bmverts[256*3];
+
+int vertexworld;
+
+/*
+void RBrushModelSurf_DoVisible(msurface_t *surf)
+{
+//     float *v, *bmv, *endbmv;
+//     glpoly_t *p;
+//     for (p = surf->polys;p;p = p->next)
+//     {
+//             for (v = p->verts[0], bmv = bmpoints, endbmv = bmv + p->numverts * 3;bmv < endbmv;v += VERTEXSIZE, bmv += 3)
+//                     softwaretransform(v, bmv);
+//             if (R_Clip_Polygon(bmpoints, p->numverts, sizeof(float) * 3, surf->flags & SURF_CLIPSOLID))
+                       surf->visframe = r_framecount;
+//     }
+}
+*/
+
+void RBrushModelSurf_Callback(void *data, void *data2)
+{
+       entity_t *ent = data2;
+       msurface_t *surf = data;
+       texture_t *t;
+
+       /*
+       // FIXME: implement better dupe prevention in AddPolygon callback code
+       if (ent->render.model->firstmodelsurface != 0)
+       {
+               // it's not an instanced model, so we already rely on there being only one of it (usually a valid assumption, but QC can break this)
+               if (surf->visframe == r_framecount)
+                       return;
+       }
+       */
+       surf->visframe = r_framecount;
+
+       c_faces++;
+
+       currententity = ent;
+       modelalpha = ent->render.alpha;
+
+       softwaretransformforbrushentity (ent);
+
+       if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
+       {
+               // sky and liquid don't need sorting (skypoly/transpoly)
+               if (surf->flags & SURF_DRAWSKY)
+                       RSurf_DrawSky(surf, true);
+               else
+                       RSurf_DrawWater(surf, R_TextureAnimation(surf->texinfo->texture), true, surf->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+       }
+       else
+       {
+               t = R_TextureAnimation(surf->texinfo->texture);
+               if (surf->texinfo->texture->transparent || vertexworld || ent->render.alpha != 1 || ent->render.model->firstmodelsurface == 0 || (ent->render.effects & EF_FULLBRIGHT) || ent->render.colormod[0] != 1 || ent->render.colormod[2] != 1 || ent->render.colormod[2] != 1)
+                       RSurf_DrawWallVertex(surf, t, true, true);
+               else
+                       RSurf_DrawWall(surf, t, true);
+       }
+}
+
 /*
 =================
 R_DrawBrushModel
@@ -851,12 +915,13 @@ R_DrawBrushModel
 */
 void R_DrawBrushModel (entity_t *e)
 {
-       int                     i;
+       int                     i, j;
        vec3_t          mins, maxs;
        msurface_t      *s;
        model_t         *clmodel;
-       int     rotated, vertexlit = false;
+       int                     rotated;
        vec3_t          org;
+       glpoly_t        *p;
 
        currententity = e;
 
@@ -878,7 +943,7 @@ void R_DrawBrushModel (entity_t *e)
                VectorAdd (e->render.origin, clmodel->maxs, maxs);
        }
 
-       if (R_VisibleCullBox (mins, maxs))
+       if (R_CullBox (mins, maxs))
                return;
 
        c_bmodels++;
@@ -896,16 +961,16 @@ void R_DrawBrushModel (entity_t *e)
                modelorg[2] = DotProduct (temp, up);
        }
 
+       softwaretransformforbrushentity (e);
+
        for (i = 0, s = &clmodel->surfaces[clmodel->firstmodelsurface];i < clmodel->nummodelsurfaces;i++, s++)
        {
+               s->visframe = -1;
                if (((s->flags & SURF_PLANEBACK) == 0) == (PlaneDiff(modelorg, s->plane) >= 0))
                        s->visframe = r_framecount;
-               else
-                       s->visframe = -1;
        }
 
-// calculate dynamic lighting for bmodel if it's not an
-// instanced model
+// calculate dynamic lighting for bmodel if it's not an instanced model
        for (i = 0;i < MAX_DLIGHTS;i++)
        {
                if (!cl_dlights[i].radius)
@@ -914,11 +979,7 @@ void R_DrawBrushModel (entity_t *e)
                VectorSubtract(cl_dlights[i].origin, currententity->render.origin, org);
                R_NoVisMarkLights (org, &cl_dlights[i], 1<<(i&31), i >> 5, clmodel);
        }
-       vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
-
-       e->render.angles[0] = -e->render.angles[0];     // stupid quake bug
-       softwaretransformforentity (e);
-       e->render.angles[0] = -e->render.angles[0];     // stupid quake bug
+//     vertexlit = modelalpha != 1 || clmodel->firstmodelsurface == 0 || (currententity->render.effects & EF_FULLBRIGHT) || currententity->render.colormod[0] != 1 || currententity->render.colormod[2] != 1 || currententity->render.colormod[2] != 1;
 
        // draw texture
        for (i = 0, s = &clmodel->surfaces[clmodel->firstmodelsurface];i < clmodel->nummodelsurfaces;i++, s++)
@@ -926,6 +987,13 @@ void R_DrawBrushModel (entity_t *e)
                if (s->visframe == r_framecount)
                {
 //                     R_DrawSurf(s, true, vertexlit || s->texinfo->texture->transparent);
+                       for (p = s->polys;p;p = p->next)
+                       {
+                               for (j = 0;j < p->numverts;j++)
+                                       softwaretransform(&p->verts[j][0], bmverts + j * 3);
+                               R_Clip_AddPolygon(bmverts, p->numverts, 3 * sizeof(float), (s->flags & SURF_CLIPSOLID) != 0 && modelalpha == 1, RBrushModelSurf_Callback, s, e, NULL);
+                       }
+                       /*
                        if (s->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
                        {
                                // sky and liquid don't need sorting (skypoly/transpoly)
@@ -942,6 +1010,7 @@ void R_DrawBrushModel (entity_t *e)
                                else
                                        RSurf_DrawWall(s, t, true);
                        }
+                       */
                }
        }
        UploadLightmaps();
@@ -955,6 +1024,7 @@ void R_DrawBrushModel (entity_t *e)
 =============================================================
 */
 
+/*
 static byte *worldvis;
 
 void R_MarkLeaves (void)
@@ -968,63 +1038,364 @@ void R_MarkLeaves (void)
 
        worldvis = Mod_LeafPVS (r_viewleaf, cl.worldmodel);
 }
+*/
 
-void R_SolidWorldNode (void)
+void RSurf_Callback(void *data, void *junk)
+{
+       ((msurface_t *)data)->visframe = r_framecount;
+}
+
+/*
+void RSurf_Callback(void *data, void *junk)
+{
+       msurface_t *surf = data;
+       texture_t *t;
+
+//     if (surf->visframe == r_framecount)
+//             return;
+
+       surf->visframe = r_framecount;
+
+       c_faces++;
+
+       if (surf->flags & (SURF_DRAWSKY | SURF_DRAWTURB))
+       {
+               // sky and liquid don't need sorting (skypoly/transpoly)
+               if (surf->flags & SURF_DRAWSKY)
+                       RSurf_DrawSky(surf, false);
+               else
+                       RSurf_DrawWater(surf, R_TextureAnimation(surf->texinfo->texture), false, surf->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+       }
+       else
+       {
+               t = R_TextureAnimation(surf->texinfo->texture);
+               if (vertexworld)
+                       RSurf_DrawWallVertex(surf, t, false, false);
+               else
+                       RSurf_DrawWall(surf, t, false);
+       }
+}
+*/
+
+/*
+mleaf_t *r_oldviewleaf;
+int r_markvisframecount = 0;
+
+void R_MarkLeaves (void)
 {
-       int l;
+       static float noviscache;
+       int i, l, k, c;
        mleaf_t *leaf;
        msurface_t *surf, **mark, **endmark;
+       model_t *model = cl.worldmodel;
+//     mportal_t *portal;
+       glpoly_t *p;
+       byte    *in;
+       int             row;
+
+       // ignore testvis if the map just changed
+       if (r_testvis.value && model->nodes->markvisframe == r_markvisframecount)
+               return;
+
+       if (r_oldviewleaf == r_viewleaf && noviscache == r_novis.value)
+               return;
+
+       r_oldviewleaf = r_viewleaf;
+       noviscache = r_novis.value;
 
-       for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++)
+       if ((in = r_viewleaf->compressed_vis))
        {
-               if (leaf->nummarksurfaces)
+               row = (model->numleafs+7)>>3;
+
+               if (!r_testvis.value)
+                       r_markvisframecount++;
+
+               // LordHavoc: mark the root node as visible, it will terminate all other ascensions
+               model->nodes->markvisframe = r_markvisframecount;
+
+               k = 0;
+               while (k < row)
                {
-                       if (R_CullBox(leaf->mins, leaf->maxs))
-                               continue;
+                       c = *in++;
+                       if (c)
+                       {
+                               l = model->numleafs - (k << 3);
+                               if (l > 8)
+                                       l = 8;
+                               for (i=0 ; i<l ; i++)
+                               {
+                                       if (c & (1<<i))
+                                       {
+                                               leaf = &model->leafs[(k << 3)+i+1];
+                                               node = (mnode_t *)leaf;
+                                               do
+                                               {
+                                                       node->markvisframe = r_markvisframecount;
+                                                       node = node->parent;
+                                               }
+                                               while (node->markvisframecount != r_markvisframecount);
+                                       }
+                               }
+                               k++;
+                       }
+                       else
+                               k += *in++;
+               }
+       }
+       else
+       {
+               // LordHavoc: no vis data, mark everything as visible
+               model->nodes->markvisframe = r_markvisframecount;
 
-                       c_leafs++;
+               for (i = 1;i < model->numleafs;i++)
+               {
+                       node = (mnode_t *)&model->leafs[i];
+                       do
+                       {
+                               node->markvisframe = r_markvisframecount;
+                               node = node->parent;
+                       }
+                       while (node->markvisframecount != r_markvisframecount);
+               }
+       }
+}
+*/
 
-                       leaf->visframe = r_framecount;
+void R_SolidWorldNode (void)
+{
+       if ((int) r_solidworldnode.value == 2)
+       {
+               mnode_t *nodestack[8192], *node = cl.worldmodel->nodes;
+               int nodestackpos = 0;
+               glpoly_t *p;
 
-                       if (leaf->nummarksurfaces)
+loc0:
+               if (node->numsurfaces)
+               {
+                       msurface_t *surf = cl.worldmodel->surfaces + node->firstsurface, *surfend = surf + node->numsurfaces;
+                       tinyplane_t plane;
+                       if (PlaneDiff (r_origin, node->plane) < 0)
                        {
-                               mark = leaf->firstmarksurface;
-                               endmark = mark + leaf->nummarksurfaces;
-                               do
+                               for (;surf < surfend;surf++)
                                {
-                                       surf = *mark++;
-                                       // make sure surfaces are only processed once
-                                       if (surf->worldnodeframe == r_framecount)
-                                               continue;
-                                       surf->worldnodeframe = r_framecount;
-                                       if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                                       if (surf->flags & SURF_PLANEBACK)
                                        {
-                                               if (surf->flags & SURF_PLANEBACK)
-                                                       surf->visframe = r_framecount;
+                                               VectorNegate(surf->plane->normal, plane.normal);
+                                               plane.dist = -surf->plane->dist;
+                                               for (p = surf->polys;p;p = p->next)
+                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, &plane);
                                        }
-                                       else
+                               }
+                       }
+                       else
+                       {
+                               for (;surf < surfend;surf++)
+                               {
+                                       if (!(surf->flags & SURF_PLANEBACK))
+                                               for (p = surf->polys;p;p = p->next)
+                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                               }
+                       }
+               }
+
+               // recurse down the children
+               if (node->children[0]->contents >= 0)
+               {
+                       if (node->children[1]->contents >= 0)
+                       {
+                               if (nodestackpos < 8192)
+                                       nodestack[nodestackpos++] = node->children[1];
+                               node = node->children[0];
+                               goto loc0;
+                       }
+                       node = node->children[0];
+                       goto loc0;
+               }
+               else if (node->children[1]->contents >= 0)
+               {
+                       node = node->children[1];
+                       goto loc0;
+               }
+               else if (nodestackpos > 0)
+               {
+                       node = nodestack[--nodestackpos];
+                       goto loc0;
+               }
+       }
+       else if ((int) r_solidworldnode.value == 1)
+       {
+               glpoly_t *p;
+               msurface_t *surf, *endsurf;
+               tinyplane_t plane;
+
+
+               surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
+               endsurf = surf + cl.worldmodel->nummodelsurfaces;
+               for (;surf < endsurf;surf++)
+               {
+                       if (PlaneDiff(r_origin, surf->plane) < 0)
+                       {
+                               if (surf->flags & SURF_PLANEBACK)
+                               {
+                                       VectorNegate(surf->plane->normal, plane.normal);
+                                       plane.dist = -surf->plane->dist;
+                                       for (p = surf->polys;p;p = p->next)
+                                               R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                               }
+                       }
+                       else
+                       {
+                               if (!(surf->flags & SURF_PLANEBACK))
+                                       for (p = surf->polys;p;p = p->next)
+                                               R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)&surf->plane);
+                       }
+               }
+       }
+       else
+       {
+               int l;
+               mleaf_t *leaf;
+               msurface_t *surf, **mark, **endmark;
+               glpoly_t *p;
+               tinyplane_t plane;
+
+               for (l = 0, leaf = cl.worldmodel->leafs;l < cl.worldmodel->numleafs;l++, leaf++)
+               {
+                       if (R_CullBox(leaf->mins, leaf->maxs))
+                               continue;
+//                     leaf->visframe = r_framecount;
+                       c_leafs++;
+                       if (leaf->nummarksurfaces)
+                       {
+//                             if (R_CullBox(leaf->mins, leaf->maxs))
+//                                     continue;
+
+                               if (leaf->nummarksurfaces)
+                               {
+                                       mark = leaf->firstmarksurface;
+                                       endmark = mark + leaf->nummarksurfaces;
+                                       do
                                        {
-                                               if (!(surf->flags & SURF_PLANEBACK))
-                                                       surf->visframe = r_framecount;
+                                               surf = *mark++;
+                                               // make sure surfaces are only processed once
+                                               if (surf->worldnodeframe == r_framecount)
+                                                       continue;
+                                               surf->worldnodeframe = r_framecount;
+                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                               {
+                                                       if (surf->flags & SURF_PLANEBACK)
+                                                       {
+                                                               VectorNegate(surf->plane->normal, plane.normal);
+                                                               plane.dist = -surf->plane->dist;
+                                                               for (p = surf->polys;p;p = p->next)
+                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                       }
+                                               }
+                                               else
+                                               {
+                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                               for (p = surf->polys;p;p = p->next)
+                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                               }
                                        }
+                                       while (mark < endmark);
+                               }
+                       }
+               }
+       }
+}
+
+/*
+void RSurf_Callback(void *data, void *junk)
+{
+       ((msurface_t *)data)->visframe = r_framecount;
+}
+
+int R_FrustumTestPolygon(float *points, int numpoints, int stride);
+
+void RSurf_DoVisible(msurface_t *surf)
+{
+       glpoly_t *p;
+       for (p = surf->polys;p;p = p->next)
+               if (R_FrustumTestPolygon((float *) p->verts, p->numverts, VERTEXSIZE * sizeof(float)) >= 3)
+//             R_Clip_Polygon((float *) p->verts, p->numverts, VERTEXSIZE * sizeof(float), true, RSurf_Callback, surf, 1);
+//             if (R_Clip_Polygon((float *) p->verts, p->numverts, VERTEXSIZE * sizeof(float), surf->flags & SURF_CLIPSOLID))
+                       surf->visframe = r_framecount;
+}
+*/
+
+//mleaf_t *llistbuffer[32768], *l, **llist;
+
+/*
+void RSurfLeaf_Callback(void *data)
+{
+       int portalstackpos = 0;
+       mleaf_t *leaf;
+       mportal_t *p, *portalstack[32768];
+       msurface_t *surf, **mark, **endmark;
+       do
+       {
+
+               leaf = data;
+               if (leaf->visframe == r_framecount)
+                       return;
+               leaf->visframe = r_framecount;
+
+               c_leafs++;
+
+               if (leaf->nummarksurfaces)
+               {
+                       mark = leaf->firstmarksurface;
+                       endmark = mark + leaf->nummarksurfaces;
+                       do
+                       {
+                               surf = *mark++;
+                               // make sure surfaces are only processed once
+                               if (surf->worldnodeframe == r_framecount)
+                                       continue;
+                               surf->worldnodeframe = r_framecount;
+                               if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                               {
+                                       if (surf->flags & SURF_PLANEBACK)
+                                               RSurf_DoVisible(surf);
+                               }
+                               else
+                               {
+                                       if (!(surf->flags & SURF_PLANEBACK))
+                                               RSurf_DoVisible(surf);
                                }
-                               while (mark < endmark);
+                       }
+                       while (mark < endmark);
+               }
+
+               // follow portals into other leafs
+               for (p = leaf->portals;p;p = p->next)
+               {
+                       if (p->past->visframe != r_framecount && DotProduct(r_origin, p->plane.normal) < p->plane.dist)
+                       {
+       //                      R_Clip_Portal((float *) p->points, p->numpoints, sizeof(float) * 3, RSurfLeaf_Callback, p->past, 1);
+                               if (R_Clip_Portal((float *) p->points, p->numpoints, sizeof(float) * 3))
+                                       portalstack[portalstackpos++] = p;
                        }
                }
        }
+       while(portalstackpos);
+       RSurfLeaf_Callback(p->past);
+       // upon returning, R_ProcessSpans will notice that the spans have changed and restart the line, this is ok because we're not adding any polygons that aren't already behind the portal
 }
+*/
 
 /*
 // experimental and inferior to the other in recursion depth allowances
 void R_PortalWorldNode (void)
 {
-       int i, j;
+//     int i, j;
        mportal_t *p;
        msurface_t *surf, **mark, **endmark;
-       mleaf_t *leaf, *llistbuffer[8192], **l, **llist;
+       mleaf_t *leaf, *llistbuffer[32768], **l, **llist;
 
        leaf = r_viewleaf;
-       leaf->worldnodeframe = r_framecount;
+       leaf->visframe = r_framecount;
        l = llist = &llistbuffer[0];
        *llist++ = r_viewleaf;
        while (l < llist)
@@ -1033,8 +1404,6 @@ void R_PortalWorldNode (void)
 
                c_leafs++;
 
-               leaf->visframe = r_framecount;
-
                if (leaf->nummarksurfaces)
                {
                        mark = leaf->firstmarksurface;
@@ -1049,47 +1418,427 @@ void R_PortalWorldNode (void)
                                if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
                                {
                                        if (surf->flags & SURF_PLANEBACK)
-                                               surf->visframe = r_framecount;
+                                               RSurf_DoVisible(surf);
                                }
                                else
                                {
                                        if (!(surf->flags & SURF_PLANEBACK))
-                                               surf->visframe = r_framecount;
+                                               RSurf_DoVisible(surf);
                                }
                        }
                        while (mark < endmark);
                }
 
                // follow portals into other leafs
-               p = leaf->portals;
-               for (;p;p = p->next)
+               for (p = leaf->portals;p;p = p->next)
                {
-                       leaf = p->past;
-                       if (leaf->worldnodeframe != r_framecount)
+                       if (p->past->visframe != r_framecount)
                        {
-                               leaf->worldnodeframe = r_framecount;
-                               i = (leaf - cl.worldmodel->leafs) - 1;
-                               if ((worldvis[i>>3] & (1<<(i&7))) && R_NotCulledBox(leaf->mins, leaf->maxs))
-                                       *llist++ = leaf;
+                               if (R_Clip_Portal((float *) p->points, p->numpoints, sizeof(float) * 3))
+                               {
+                                       p->past->visframe = r_framecount;
+                                       *llist++ = p->past;
+                               }
                        }
                }
+
+//             for (p = leaf->portals;p;p = p->next)
+//             {
+//                     leaf = p->past;
+//                     if (leaf->worldnodeframe != r_framecount)
+//                     {
+//                             leaf->worldnodeframe = r_framecount;
+//                             i = (leaf - cl.worldmodel->leafs) - 1;
+//                             if ((worldvis[i>>3] & (1<<(i&7))) && R_NotCulledBox(leaf->mins, leaf->maxs))
+//                                     *llist++ = leaf;
+//                     }
+//             }
        }
 
+//     i = 0;
+//     j = 0;
+//     p = r_viewleaf->portals;
+//     for (;p;p = p->next)
+//     {
+//             j++;
+//             if (p->past->worldnodeframe != r_framecount)
+//                     i++;
+//     }
+//     if (i)
+//             Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, j);
+}
+*/
+
+/*
+#define MAXRECURSIVEPORTALPLANES 1024
+#define MAXRECURSIVEPORTALS 256
+
+tinyplane_t portalplanes[MAXRECURSIVEPORTALPLANES];
+int portalplanestack[MAXRECURSIVEPORTALS];
+int portalplanecount;
+int ranoutofportalplanes;
+int ranoutofportals;
+int ranoutofleafs;
+int portalcantseeself;
+int portalrecursion;
+
+int R_ClipPolygonToPlane(float *in, float *out, int inpoints, int maxoutpoints, tinyplane_t *p)
+{
+       int i, outpoints, prevside, side;
+       float *prevpoint, prevdist, dist, dot;
+
+       if (inpoints < 3)
+               return inpoints;
+       // begin with the last point, then enter the loop with the first point as current
+       prevpoint = in + 3 * (inpoints - 1);
+       prevdist = DotProduct(prevpoint, p->normal) - p->dist;
+       prevside = prevdist >= 0 ? SIDE_FRONT : SIDE_BACK;
        i = 0;
-       j = 0;
-       p = r_viewleaf->portals;
-       for (;p;p = p->next)
+       outpoints = 0;
+       goto begin;
+       for (;i < inpoints;i++)
        {
-               j++;
-               if (p->past->worldnodeframe != r_framecount)
-                       i++;
+               prevpoint = in;
+               prevdist = dist;
+               prevside = side;
+               in += 3;
+
+begin:
+               dist = DotProduct(in, p->normal) - p->dist;
+               side = dist >= 0 ? SIDE_FRONT : SIDE_BACK;
+
+               if (prevside == SIDE_FRONT)
+               {
+                       if (outpoints >= maxoutpoints)
+                               return -1;
+                       VectorCopy(prevpoint, out);
+                       out += 3;
+                       outpoints++;
+                       if (side == SIDE_FRONT)
+                               continue;
+               }
+               else if (side == SIDE_BACK)
+                       continue;
+
+               // generate a split point
+               if (outpoints >= maxoutpoints)
+                       return -1;
+               dot = prevdist / (prevdist - dist);
+               out[0] = prevpoint[0] + dot * (in[0] - prevpoint[0]);
+               out[1] = prevpoint[1] + dot * (in[1] - prevpoint[1]);
+               out[2] = prevpoint[2] + dot * (in[2] - prevpoint[2]);
+               out += 3;
+               outpoints++;
+       }
+
+       return outpoints;
+}
+
+float portaltemppoints[2][256][3];
+float portaltemppoints2[256][3];
+
+int R_FrustumTestPolygon(float *points, int numpoints, int stride)
+{
+       int i;
+       float *out;
+       if (numpoints < 3)
+               return numpoints;
+       out = &portaltemppoints[0][0][0];
+       for (i = 0;i < numpoints;i++)
+       {
+               VectorCopy(points, portaltemppoints[0][i]);
+               (byte *)points += stride;
+       }
+       numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, (tinyplane_t *)&frustum[0]);
+       if (numpoints < 3)
+               return numpoints;
+       numpoints = R_ClipPolygonToPlane(&portaltemppoints[1][0][0], &portaltemppoints[0][0][0], numpoints, 256, (tinyplane_t *)&frustum[1]);
+       if (numpoints < 3)
+               return numpoints;
+       numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, (tinyplane_t *)&frustum[2]);
+       if (numpoints < 3)
+               return numpoints;
+       return      R_ClipPolygonToPlane(&portaltemppoints[1][0][0], &portaltemppoints[0][0][0], numpoints, 256, (tinyplane_t *)&frustum[3]);
+}
+
+void R_TriangleToPlane(vec3_t point1, vec3_t point2, vec3_t point3, tinyplane_t *p)
+{
+       vec3_t v1, v2;
+       VectorSubtract(point1, point2, v1);
+       VectorSubtract(point3, point2, v2);
+       CrossProduct(v1, v2, p->normal);
+//     VectorNormalize(p->normal);
+       VectorNormalizeFast(p->normal);
+       p->dist = DotProduct(point1, p->normal);
+}
+
+int R_PortalThroughPortalPlanes(tinyplane_t *clipplanes, int clipnumplanes, float *targpoints, int targnumpoints, float *out, int maxpoints)
+{
+       int numpoints, i;
+       if (targnumpoints < 3)
+               return targnumpoints;
+       if (maxpoints < 3)
+               return -1;
+       numpoints = targnumpoints;
+       memcpy(&portaltemppoints[0][0][0], targpoints, numpoints * 3 * sizeof(float));
+       for (i = 0;i < clipnumplanes;i++)
+       {
+               numpoints = R_ClipPolygonToPlane(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints, 256, clipplanes + i);
+               if (numpoints < 3)
+                       return numpoints;
+               memcpy(&portaltemppoints[0][0][0], &portaltemppoints[1][0][0], numpoints * 3 * sizeof(float));
+       }
+       if (numpoints > maxpoints)
+               return -1;
+       memcpy(out, &portaltemppoints[1][0][0], numpoints * 3 * sizeof(float));
+       return numpoints;
+}
+
+#define MAXRECURSIVEPORTALLEAFS 256
+
+//mleaf_t *leafstack[MAXRECURSIVEPORTALLEAFS];
+//int leafstackpos;
+int r_portalframecount;
+
+void R_RecursivePortalWorldNode (mleaf_t *leaf, int firstclipplane, int numclipplanes)
+{
+       mportal_t *p;
+
+//     if (leafstackpos >= MAXRECURSIVEPORTALLEAFS)
+//     {
+//             ranoutofleafs = true;
+//             return;
+//     }
+
+//     leafstack[leafstackpos++] = leaf;
+
+       if (leaf->visframe != r_framecount)
+       {
+               c_leafs++;
+               leaf->visframe = r_framecount;
+               if (leaf->nummarksurfaces)
+               {
+                       msurface_t *surf, **mark, **endmark;
+                       mark = leaf->firstmarksurface;
+                       endmark = mark + leaf->nummarksurfaces;
+                       do
+                       {
+                               surf = *mark++;
+                               // make sure surfaces are only processed once
+                               if (surf->worldnodeframe == r_framecount)
+                                       continue;
+                               surf->worldnodeframe = r_framecount;
+                               if (PlaneDist(modelorg, surf->plane) < surf->plane->dist)
+                               {
+                                       if (surf->flags & SURF_PLANEBACK)
+                                               RSurf_DoVisible(surf);
+                               }
+                               else
+                               {
+                                       if (!(surf->flags & SURF_PLANEBACK))
+                                               RSurf_DoVisible(surf);
+                               }
+                       }
+                       while (mark < endmark);
+               }
+       }
+
+       // follow portals into other leafs
+       for (p = leaf->portals;p;p = p->next)
+       {
+               int newpoints, i, prev;
+               vec3_t center;
+               vec3_t v1, v2;
+               tinyplane_t *newplanes;
+               // only flow through portals facing away from the viewer
+               if (PlaneDiff(r_origin, (&p->plane)) < 0)
+               {
+*/
+                       /*
+                       for (i = 0;i < leafstackpos;i++)
+                               if (leafstack[i] == p->past)
+                                       break;
+                       if (i < leafstackpos)
+                       {
+                               portalrecursion = true;
+                               continue;
+                       }
+                       */
+/*
+                       newpoints = R_PortalThroughPortalPlanes(&portalplanes[firstclipplane], numclipplanes, (float *) p->points, p->numpoints, &portaltemppoints2[0][0], 256);
+                       if (newpoints < 3)
+                               continue;
+                       else if (firstclipplane + numclipplanes + newpoints > MAXRECURSIVEPORTALPLANES)
+                               ranoutofportalplanes = true;
+                       else
+                       {
+                               // go ahead and mark the leaf early, nothing can abort here
+                               if (!r_testvis.value)
+                                       p->visframe = r_portalframecount;
+
+                               // find the center by averaging
+                               VectorClear(center);
+                               for (i = 0;i < newpoints;i++)
+                                       VectorAdd(center, portaltemppoints2[i], center);
+                               // ixtable is a 1.0f / N table
+                               VectorScale(center, ixtable[newpoints], center);
+                               // calculate the planes, and make sure the polygon can see it's own center
+                               newplanes = &portalplanes[firstclipplane + numclipplanes];
+                               for (prev = newpoints - 1, i = 0;i < newpoints;prev = i, i++)
+                               {
+//                                     R_TriangleToPlane(r_origin, portaltemppoints2[i], portaltemppoints2[prev], newplanes + i);
+                                       VectorSubtract(r_origin, portaltemppoints2[i], v1);
+                                       VectorSubtract(portaltemppoints2[prev], portaltemppoints2[i], v2);
+                                       CrossProduct(v1, v2, newplanes[i].normal);
+                                       VectorNormalizeFast(newplanes[i].normal);
+                                       newplanes[i].dist = DotProduct(r_origin, newplanes[i].normal);
+                                       if (DotProduct(newplanes[i].normal, center) <= newplanes[i].dist)
+                                       {
+                                               // polygon can't see it's own center, discard and use parent portal
+                                               break;
+                                       }
+                               }
+                               if (i == newpoints)
+                                       R_RecursivePortalWorldNode(p->past, firstclipplane + numclipplanes, newpoints);
+                               else
+                                       R_RecursivePortalWorldNode(p->past, firstclipplane, numclipplanes);
+                       }
+               }
+       }
+//     leafstackpos--;
+}
+
+//float viewportalpoints[16*3];
+
+*/
+
+int r_portalframecount = 0;
+
+/*
+void R_Portal_Callback(void *data, void *data2)
+{
+       mleaf_t *leaf = data;
+       if (!r_testvis.value)
+               ((mportal_t *)data2)->visframe = r_portalframecount;
+       if (leaf->visframe != r_framecount)
+       {
+               c_leafs++;
+               leaf->visframe = r_framecount;
        }
-       if (i)
-               Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, j);
 }
 */
 
-void R_PortalWorldNode (void)
+void R_PVSWorldNode()
+{
+       int i/*, l*/, k, c, row, numbits, bit, leafnum, numleafs;
+       mleaf_t *leaf;
+       msurface_t *surf, **mark, **endmark;
+       model_t *model = cl.worldmodel;
+       byte *in;
+//     mportal_t *portal;
+       glpoly_t *p;
+       tinyplane_t plane;
+
+//     c_leafs++;
+//     r_viewleaf->visframe = r_framecount;
+       if (!r_testvis.value)
+               r_portalframecount++;
+
+       numleafs = model->numleafs;
+       numbits = numleafs - 1;
+       k = 0;
+       in = r_viewleaf->compressed_vis;
+       row = (numbits + 7) >> 3;
+       while (k < row)
+       {
+               c = *in++;
+               if (c)
+               {
+                       for (i = 0, bit = 1;c;i++, bit <<= 1)
+                       {
+                               if (c & bit)
+                               {
+                                       leafnum = (k << 3)+i+1;
+                                       if (leafnum >= numleafs)
+                                               return;
+                                       c -= bit;
+                                       leaf = &model->leafs[leafnum];
+                                       if (R_NotCulledBox(leaf->mins, leaf->maxs))
+                                       {
+                                               //for (portal = leaf->portals;portal;portal = portal->next)
+                                               //      if (DotProduct(r_origin, portal->plane.normal) > portal->plane.dist)
+                                               //              R_Clip_AddPolygon((float *)portal->points, portal->numpoints, sizeof(mvertex_t), false, R_Portal_Callback, leaf, portal, portal->plane);
+                                               //leaf->visframe = r_framecount;
+                                               c_leafs++;
+                                               if (leaf->nummarksurfaces)
+                                               {
+                                                       mark = leaf->firstmarksurface;
+                                                       endmark = mark + leaf->nummarksurfaces;
+                                                       do
+                                                       {
+                                                               surf = *mark++;
+                                                               // make sure surfaces are only processed once
+                                                               if (surf->worldnodeframe == r_framecount)
+                                                                       continue;
+                                                               surf->worldnodeframe = r_framecount;
+                                                               if (PlaneDist(r_origin, surf->plane) < surf->plane->dist)
+                                                               {
+                                                                       if (surf->flags & SURF_PLANEBACK)
+                                                                       {
+                                                                               VectorNegate(surf->plane->normal, plane.normal);
+                                                                               plane.dist = -surf->plane->dist;
+                                                                               for (p = surf->polys;p;p = p->next)
+                                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, &plane);
+                                                                       }
+                                                               }
+                                                               else
+                                                               {
+                                                                       if (!(surf->flags & SURF_PLANEBACK))
+                                                                               for (p = surf->polys;p;p = p->next)
+                                                                                       R_Clip_AddPolygon((float *)p->verts, p->numverts, VERTEXSIZE * sizeof(float), (surf->flags & SURF_CLIPSOLID) != 0, RSurf_Callback, surf, NULL, (tinyplane_t *)surf->plane);
+                                                               }
+                                                       }
+                                                       while (mark < endmark);
+                                               }
+                                       }
+                               }
+                       }
+                       k++;
+               }
+               else
+                       k += *in++;
+       }
+}
+
+       /*
+       if (!r_testvis.value)
+               r_portalframecount = r_framecount;
+       portalplanecount = 0;
+//     leafstackpos = 0;
+       ranoutofportalplanes = false;
+       ranoutofportals = false;
+       ranoutofleafs = false;
+       portalcantseeself = 0;
+       portalrecursion = false;
+       memcpy(&portalplanes[0], &frustum[0], sizeof(tinyplane_t));
+       memcpy(&portalplanes[1], &frustum[1], sizeof(tinyplane_t));
+       memcpy(&portalplanes[2], &frustum[2], sizeof(tinyplane_t));
+       memcpy(&portalplanes[3], &frustum[3], sizeof(tinyplane_t));
+       R_RecursivePortalWorldNode(r_viewleaf, 0, 4);
+       if (ranoutofportalplanes)
+               Con_Printf("R_RecursivePortalWorldNode: ran out of %d plane stack when recursing through portals\n", MAXRECURSIVEPORTALPLANES);
+       if (ranoutofportals)
+               Con_Printf("R_RecursivePortalWorldNode: ran out of %d portal stack when recursing through portals\n", MAXRECURSIVEPORTALS);
+       if (ranoutofleafs)
+               Con_Printf("R_RecursivePortalWorldNode: ran out of %d leaf stack when recursing through portals\n", MAXRECURSIVEPORTALLEAFS);
+//     if (portalcantseeself)
+//             Con_Printf("R_RecursivePortalWorldNode: %d portals could not see themself during clipping\n", portalcantseeself);
+       if (portalrecursion)
+               Con_Printf("R_RecursivePortalWorldNode: portal saw into previously encountered leaf??\n");
+       */
+
+/*
+void R_OldPortalWorldNode (void)
 {
        int portalstack, i;
        mportal_t *p, *pstack[8192];
@@ -1170,15 +1919,22 @@ loc1:
        if (i)
                Con_Printf("%i portals of viewleaf (%i portals) were not checked\n", i, portalstack);
 }
+*/
+
+entity_t clworldent;
 
 void R_DrawSurfaces (void)
 {
        msurface_t      *surf, *endsurf;
-       texture_t       *t;
+       texture_t       *t, *currentt;
        int vertex = gl_vertex.value;
 
+       currententity = &clworldent;
+       modelalpha = 1;
+       softwaretransformidentity();
        surf = &cl.worldmodel->surfaces[cl.worldmodel->firstmodelsurface];
        endsurf = surf + cl.worldmodel->nummodelsurfaces;
+       t = currentt = NULL;
        for (;surf < endsurf;surf++)
        {
                if (surf->visframe == r_framecount)
@@ -1190,11 +1946,22 @@ void R_DrawSurfaces (void)
                                if (surf->flags & SURF_DRAWSKY)
                                        RSurf_DrawSky(surf, false);
                                else
-                                       RSurf_DrawWater(surf, R_TextureAnimation(surf->texinfo->texture), false, surf->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+                               {
+                                       if (currentt != surf->texinfo->texture)
+                                       {
+                                               currentt = surf->texinfo->texture;
+                                               t = R_TextureAnimation(surf->texinfo->texture);
+                                       }
+                                       RSurf_DrawWater(surf, t, false, surf->flags & SURF_DRAWNOALPHA ? 255 : wateralpha);
+                               }
                        }
                        else
                        {
-                               t = R_TextureAnimation(surf->texinfo->texture);
+                               if (currentt != surf->texinfo->texture)
+                               {
+                                       currentt = surf->texinfo->texture;
+                                       t = R_TextureAnimation(surf->texinfo->texture);
+                               }
                                if (vertex)
                                        RSurf_DrawWallVertex(surf, t, false, false);
                                else
@@ -1207,12 +1974,13 @@ void R_DrawSurfaces (void)
 void R_DrawPortals(void)
 {
        int drawportals, i, r, g, b;
-       mleaf_t *leaf, *endleaf;
-       mportal_t *portal;
-       mvertex_t *point, *endpoint;
+//     mleaf_t *leaf, *endleaf;
+       mportal_t *portal, *endportal;
+       mvertex_t *point/*, *endpoint*/;
        drawportals = (int)r_drawportals.value;
        if (drawportals < 1)
                return;
+       /*
        leaf = cl.worldmodel->leafs;
        endleaf = leaf + cl.worldmodel->numleafs;
        for (;leaf < endleaf;leaf++)
@@ -1236,6 +2004,32 @@ void R_DrawPortals(void)
                        }
                }
        }
+       */
+       portal = cl.worldmodel->portals;
+       endportal = portal + cl.worldmodel->numportals;
+       for (;portal < endportal;portal++)
+       {
+               if (portal->visframe == r_portalframecount)
+               {
+                       i = portal - cl.worldmodel->portals;
+                       r = (i & 0x0007) << 5;
+                       g = (i & 0x0038) << 2;
+                       b = (i & 0x01C0) >> 1;
+                       transpolybegin(0, 0, 0, TPOLYTYPE_ALPHA);
+                       point = portal->points;
+                       if (PlaneDiff(r_origin, (&portal->plane)) > 0)
+                       {
+                               for (i = portal->numpoints - 1;i >= 0;i--)
+                                       transpolyvertub(point[i].position[0], point[i].position[1], point[i].position[2], 0, 0, r, g, b, 32);
+                       }
+                       else
+                       {
+                               for (i = 0;i < portal->numpoints;i++)
+                                       transpolyvertub(point[i].position[0], point[i].position[1], point[i].position[2], 0, 0, r, g, b, 32);
+                       }
+                       transpolyend();
+               }
+       }
 }
 
 /*
@@ -1245,38 +2039,31 @@ R_DrawWorld
 */
 void R_DrawWorld (void)
 {
-       entity_t        ent;
-
        wateralpha = bound(0, r_wateralpha.value*255.0f, 255);
+       vertexworld = gl_vertex.value;
 
-       memset (&ent, 0, sizeof(ent));
-       ent.render.model = cl.worldmodel;
-       ent.render.colormod[0] = ent.render.colormod[1] = ent.render.colormod[2] = 1;
-       modelalpha = ent.render.alpha = 1;
-       ent.render.scale = 1;
+       memset (&clworldent, 0, sizeof(clworldent));
+       clworldent.render.model = cl.worldmodel;
+       clworldent.render.colormod[0] = clworldent.render.colormod[1] = clworldent.render.colormod[2] = 1;
+       modelalpha = clworldent.render.alpha = 1;
+       clworldent.render.scale = 1;
 
        VectorCopy (r_origin, modelorg);
 
-       currententity = &ent;
+       currententity = &clworldent;
 
        softwaretransformidentity(); // LordHavoc: clear transform
 
        if (cl.worldmodel)
        {
-               if (r_viewleaf->contents == CONTENTS_SOLID)
+               if (r_novis.value || r_viewleaf->compressed_vis == NULL)
                        R_SolidWorldNode ();
                else
                {
-                       R_MarkLeaves ();
-                       R_PortalWorldNode ();
+//                     R_MarkLeaves ();
+                       R_PVSWorldNode ();
                }
        }
-
-       R_PushDlights (); // now mark the lit surfaces
-
-       R_DrawSurfaces ();
-
-       R_DrawPortals ();
 }
 
 /*
@@ -1355,53 +2142,43 @@ int AllocBlock (int w, int h, short *x, short *y)
 }
 
 
-mvertex_t      *r_pcurrentvertbase;
-model_t                *currentmodel;
-
-int    nColinElim;
+//int  nColinElim;
 
 /*
 ================
 BuildSurfaceDisplayList
 ================
 */
-void BuildSurfaceDisplayList (msurface_t *fa)
+void BuildSurfaceDisplayList (model_t *model, mvertex_t *vertices, msurface_t *fa)
 {
        int                     i, j, lindex, lnumverts;
-       medge_t         *pedges, *r_pedge;
-       int                     vertpage;
+       medge_t         *pedges;
        float           *vec;
        float           s, t;
        glpoly_t        *poly;
 
 // reconstruct the polygon
-       pedges = currentmodel->edges;
+       pedges = model->edges;
        lnumverts = fa->numedges;
-       vertpage = 0;
 
        //
        // draw texture
        //
-       poly = Hunk_AllocName (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float), "surfaces");
+       poly = Hunk_AllocName (sizeof(glpolysizeof_t) + lnumverts * sizeof(float[VERTEXSIZE]), "surfaces");
        poly->next = fa->polys;
-       poly->flags = fa->flags;
        fa->polys = poly;
+//     poly->flags = fa->flags;
        poly->numverts = lnumverts;
 
        for (i=0 ; i<lnumverts ; i++)
        {
-               lindex = currentmodel->surfedges[fa->firstedge + i];
+               lindex = model->surfedges[fa->firstedge + i];
 
                if (lindex > 0)
-               {
-                       r_pedge = &pedges[lindex];
-                       vec = r_pcurrentvertbase[r_pedge->v[0]].position;
-               }
+                       vec = vertices[pedges[lindex].v[0]].position;
                else
-               {
-                       r_pedge = &pedges[-lindex];
-                       vec = r_pcurrentvertbase[r_pedge->v[1]].position;
-               }
+                       vec = vertices[pedges[-lindex].v[1]].position;
+
                s = DotProduct (vec, fa->texinfo->vecs[0]) + fa->texinfo->vecs[0][3];
                t = DotProduct (vec, fa->texinfo->vecs[1]) + fa->texinfo->vecs[1][3];
 
@@ -1452,7 +2229,7 @@ void BuildSurfaceDisplayList (msurface_t *fa)
                        // skip co-linear points
                        #define COLINEAR_EPSILON 0.001
                        if ((fabs( v1[0] - v2[0] ) <= COLINEAR_EPSILON) &&
-                               (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) && 
+                               (fabs( v1[1] - v2[1] ) <= COLINEAR_EPSILON) &&
                                (fabs( v1[2] - v2[2] ) <= COLINEAR_EPSILON))
                        {
                                int j;
@@ -1468,9 +2245,9 @@ void BuildSurfaceDisplayList (msurface_t *fa)
                                --i;
                        }
                }
+               poly->numverts = lnumverts;
        }
        */
-       poly->numverts = lnumverts;
 }
 
 /*
@@ -1574,8 +2351,6 @@ void GL_BuildLightmaps (void)
                        break;
                if (m->name[0] == '*')
                        continue;
-               r_pcurrentvertbase = m->vertexes;
-               currentmodel = m;
                for (i=0 ; i<m->numsurfaces ; i++)
                {
                        if ( m->surfaces[i].flags & SURF_DRAWTURB )
@@ -1583,7 +2358,7 @@ void GL_BuildLightmaps (void)
                        if ( m->surfaces[i].flags & SURF_DRAWSKY )
                                continue;
                        GL_CreateSurfaceLightmap (m->surfaces + i);
-                       BuildSurfaceDisplayList (m->surfaces + i);
+                       BuildSurfaceDisplayList (m, m->vertexes, m->surfaces + i);
                }
        }
 
index 07238d4..56ba7f3 100644 (file)
@@ -274,33 +274,30 @@ static void SCR_CalcRefdef (void)
 
 // intermission is always full screen  
        if (cl.intermission)
-               size = 120;
-       else
-               size = scr_viewsize.value;
-
-       if (size >= 120)
-               sb_lines = 0;           // no status bar at all
-       else if (size >= 110)
-               sb_lines = 24;          // no inventory
-       else
-               sb_lines = 24+16+8;
-
-       if (scr_viewsize.value >= 100.0)
        {
                full = true;
-               size = 100.0;
+               size = 1;
+               sb_lines = 0;
        }
        else
-               size = scr_viewsize.value;
-       if (cl.intermission)
        {
-               full = true;
-               size = 100;
-               sb_lines = 0;
+               if (scr_viewsize.value >= 120)
+                       sb_lines = 0;           // no status bar at all
+               else if (scr_viewsize.value >= 110)
+                       sb_lines = 24;          // no inventory
+               else
+                       sb_lines = 24+16+8;
+
+               if (scr_viewsize.value >= 100.0)
+               {
+                       full = true;
+                       size = 1.0f;
+               }
+               else
+                       size = scr_viewsize.value * (1.0f / 100.0f);
        }
-       size /= 100.0;
 
-       // LordHavoc: always fullyscreen rendering
+       // LordHavoc: always fullscreen rendering
        h = vid.height/* - sb_lines*/;
 
        r_refdef.vrect.width = vid.width * size;
@@ -599,7 +596,7 @@ void SCR_ScreenShot_f (void)
                filename[2] = (i/1000)%10 + '0'; 
                filename[3] = (i/ 100)%10 + '0'; 
                filename[4] = (i/  10)%10 + '0'; 
-               filename[5] = (i/   1)%10 + '0'; 
+               filename[5] = (i/   1)%10 + '0';
                sprintf (checkname, "%s/%s", com_gamedir, filename);
                if (Sys_FileTime(checkname) == -1)
                        break;  // file doesn't exist
@@ -691,7 +688,7 @@ void SCR_DrawNotifyString (void)
 //             for (j=0 ; j<l ; j++, x+=8)
 //                     Draw_Character (x, y, start[j]);        
                Draw_String (x, y, start, l);
-                       
+
                y += 8;
 
                while (*start && *start != '\n')
@@ -783,6 +780,7 @@ LordHavoc: due to my rewrite of R_WorldNode, it no longer takes 256k of stack sp
 ==================
 */
 void GL_Finish(void);
+void R_Clip_DisplayBuffer(void);
 void SCR_UpdateScreen (void)
 {
        double  time1 = 0, time2;
@@ -844,6 +842,8 @@ void SCR_UpdateScreen (void)
 
        GL_Set2D();
 
+       R_Clip_DisplayBuffer();
+
        SCR_DrawRam();
        SCR_DrawNet();
        SCR_DrawTurtle();
@@ -879,15 +879,27 @@ void SCR_UpdateScreen (void)
                Draw_String(vid.width - (8*8), vid.height - sb_lines - 8, temp, 9999);
        }
 
-       if (r_speeds2.value)
+       // LordHavoc: only print info if renderer is being used
+       if (r_speeds2.value && cl.worldmodel != NULL)
        {
-               Draw_String(0, vid.height - sb_lines - 56, r_speeds2_string1, 80);
-               Draw_String(0, vid.height - sb_lines - 48, r_speeds2_string2, 80);
-               Draw_String(0, vid.height - sb_lines - 40, r_speeds2_string3, 80);
-               Draw_String(0, vid.height - sb_lines - 32, r_speeds2_string4, 80);
-               Draw_String(0, vid.height - sb_lines - 24, r_speeds2_string5, 80);
-               Draw_String(0, vid.height - sb_lines - 16, r_speeds2_string6, 80);
-               Draw_String(0, vid.height - sb_lines -  8, r_speeds2_string7, 80);
+               int i, j, lines, y;
+               lines = 1;
+               for (i = 0;r_speeds2_string[i];i++)
+                       if (r_speeds2_string[i] == '\n')
+                               lines++;
+               y = vid.height - sb_lines - lines * 8 - 8;
+               i = j = 0;
+               while (r_speeds2_string[i])
+               {
+                       j = i;
+                       while (r_speeds2_string[i] && r_speeds2_string[i] != '\n')
+                               i++;
+                       if (i - j > 0)
+                               Draw_String(0, y, r_speeds2_string + j, i - j);
+                       if (r_speeds2_string[i] == '\n')
+                               i++;
+                       y += 8;
+               }
        }
 
        V_UpdateBlends();
index 3cc49e4..c7b6221 100644 (file)
@@ -364,14 +364,14 @@ void R_ResampleTexture (void *indata, int inwidth, int inheight, void *outdata,
                        inrow = (int *)indata + inwidth*(i*inheight/outheight);
                        frac = fracstep >> 1;
                        j = outwidth - 4;
-                       while(j >= 0)
+                       while (j >= 0)
                        {
                                out[0] = inrow[frac >> 16];frac += fracstep;
                                out[1] = inrow[frac >> 16];frac += fracstep;
                                out[2] = inrow[frac >> 16];frac += fracstep;
                                out[3] = inrow[frac >> 16];frac += fracstep;
                                out += 4;
-                               j--;
+                               j -= 4;
                        }
                        if (j & 2)
                        {
@@ -605,6 +605,8 @@ rtexture_t *R_LoadTexture (char *identifier, int width, int height, byte *data,
 
        if (!identifier[0])
                Host_Error("R_LoadTexture: no identifier\n");
+       if (data == NULL)
+               Host_Error("R_LoadTexture: \"%s\" has no data\n", identifier);
 
        // clear the alpha flag if the texture has no transparent pixels
        if (flags & TEXF_ALPHA)
index 0607c59..7a521f1 100644 (file)
--- a/glquake.h
+++ b/glquake.h
@@ -73,7 +73,6 @@ extern void R_TimeRefresh_f (void);
 //====================================================
 
 
-extern entity_t        r_worldentity;
 extern qboolean        r_cache_thrash;         // compatability
 extern vec3_t          modelorg, r_entorigin;
 extern entity_t        *currententity;
@@ -156,40 +155,3 @@ extern void (GLAPIENTRY *qglUnlockArraysEXT) (void);
 //#endif
 
 #endif
-
-// LordHavoc: vertex transform
-#include "transform.h"
-
-// LordHavoc: transparent polygon system
-#include "gl_poly.h"
-
-#define gl_solid_format 3
-#define gl_alpha_format 4
-
-//#define PARANOID
-
-// LordHavoc: was a major time waster
-#define R_CullBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) == 2 || frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) == 2 || frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) == 2 || frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) == 2)
-#define R_NotCulledBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) != 2 && frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) != 2 && frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) != 2 && frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) != 2)
-
-extern qboolean fogenabled;
-extern vec3_t fogcolor;
-extern vec_t fogdensity;
-//#define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_origin[0]) * vpn[0] + ((v)[1] - r_origin[1]) * vpn[1] + ((v)[2] - r_origin[2]) * vpn[2])*(((v)[0] - r_origin[0]) * vpn[0] + ((v)[1] - r_origin[1]) * vpn[1] + ((v)[2] - r_origin[2]) * vpn[2]))))
-#define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_origin[0])*((v)[0] - r_origin[0])+((v)[1] - r_origin[1])*((v)[1] - r_origin[1])+((v)[2] - r_origin[2])*((v)[2] - r_origin[2])))))
-#define calcfogbyte(v) ((byte) (bound(0, ((int) ((float) (calcfog((v)) * 255.0f))), 255)))
-
-#include "r_modules.h"
-
-extern qboolean lighthalf;
-
-#include "r_lerpanim.h"
-
-void GL_LockArray(int first, int count);
-void GL_UnlockArray(void);
-
-void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, frameblend_t *blend, int skin, vec3_t org, vec3_t angles, vec_t scale, int effects, int flags, int colormap);
-
-extern cvar_t r_render;
-extern cvar_t r_upload;
-#include "image.h"
diff --git a/host.c b/host.c
index b419f8a..2ba18dc 100644 (file)
--- a/host.c
+++ b/host.c
@@ -539,11 +539,16 @@ qboolean Host_FilterTime (double time)
                        return false;
        }
 
-       host_realframetime = host_frametime = realtime - oldrealtime; // LordHavoc: copy into host_realframetime as well
+       // LordHavoc: copy into host_realframetime as well
+       host_realframetime = host_frametime = realtime - oldrealtime;
        oldrealtime = realtime;
 
        if (cls.timedemo)
-               return true; // disable time effects
+       {
+               // disable time effects
+               cl.frametime = host_frametime;
+               return true;
+       }
 
        if (host_framerate.value > 0)
                host_frametime = host_framerate.value;
index b34c09b..7455032 100644 (file)
@@ -573,7 +573,7 @@ void Host_Loadgame_f (void)
        str = Qgetline (f);
        for (i=0 ; i<NUM_SPAWN_PARMS ; i++) {
                str = Qgetline (f);
-               sscanf (str, "%f", &spawn_parms[i]);
+               sscanf (str, "%f\n", &spawn_parms[i]);
        }
 // this silliness is so we can load 1.06 save files, which have float skill values
        str = Qgetline (f);
@@ -582,7 +582,6 @@ void Host_Loadgame_f (void)
        Cvar_SetValue ("skill", (float)current_skill);
 
        strcpy (mapname, Qgetline (f));
-       mapname[strlen (mapname) -1] = 0; // strip trailing \n
 
        str = Qgetline (f);
        sscanf (str, "%f\n",&time);
@@ -603,7 +602,6 @@ void Host_Loadgame_f (void)
        for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
        {
                str = Qgetline (f);
-               str[strlen (str) -1] = 0; // strip trailing \n
                sv.lightstyles[i] = Hunk_AllocName (strlen(str)+1, "lightstyles");
                strcpy (sv.lightstyles[i], str);
        }
diff --git a/image.c b/image.c
index d73e318..acfdf77 100644 (file)
--- a/image.c
+++ b/image.c
@@ -408,10 +408,10 @@ byte* LoadTGA (byte *f, int matchwidth, int matchheight)
                }
        }
 outofdata:;
-       
+
        image_width = columns;
        image_height = rows;
-       free(f);
+       qfree(f);
        return image_rgba;
 }
 
index a1e7939..8a5de30 100644 (file)
--- a/mathlib.c
+++ b/mathlib.c
@@ -60,7 +60,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] =
 {1.000000, 0.000000, 0.000000}, {0.951056, 0.162460, 0.262866}, 
 {0.850651, -0.525731, 0.000000}, {0.955423, -0.295242, 0.000000}, 
 {0.864188, -0.442863, 0.238856}, {0.951056, -0.162460, 0.262866}, 
-{0.809017, -0.309017, 0.500000}, {0.681718, -0.147621, 0.716567}, 
+{0.809017, -0.309017, 0.500000}, {0.681718, -0.147621, 0.716567},
 {0.850651, 0.000000, 0.525731}, {0.864188, 0.442863, -0.238856}, 
 {0.809017, 0.309017, -0.500000}, {0.951056, 0.162460, -0.262866}, 
 {0.525731, 0.000000, -0.850651}, {0.681718, 0.147621, -0.716567}, 
@@ -91,7 +91,7 @@ float m_bytenormals[NUMVERTEXNORMALS][3] =
 {-0.500000, -0.809017, -0.309017}, {-0.262866, -0.951056, -0.162460}, 
 {-0.850651, -0.525731, 0.000000}, {-0.716567, -0.681718, -0.147621}, 
 {-0.716567, -0.681718, 0.147621}, {-0.525731, -0.850651, 0.000000}, 
-{-0.500000, -0.809017, 0.309017}, {-0.238856, -0.864188, 0.442863}, 
+{-0.500000, -0.809017, 0.309017}, {-0.238856, -0.864188, 0.442863},
 {-0.262866, -0.951056, 0.162460}, {-0.864188, -0.442863, 0.238856}, 
 {-0.809017, -0.309017, 0.500000}, {-0.688191, -0.587785, 0.425325}, 
 {-0.681718, -0.147621, 0.716567}, {-0.442863, -0.238856, 0.864188}, 
@@ -142,6 +142,32 @@ void ByteToNormal(byte num, vec3_t n)
                VectorClear(n) // FIXME: complain?
 }
 
+float Q_RSqrt(float number)
+{
+       float y;
+
+       if (number == 0.0f)
+               return 0.0f;
+
+       *((long *)&y) = 0x5f3759df - ((* (long *) &number) >> 1);
+       return y * (1.5f - (number * 0.5f * y * y));
+}
+
+void _VectorNormalizeFast(vec3_t v)
+{
+       float y, number;
+
+       number = DotProduct(v, v);
+
+       if (number != 0.0)
+       {
+               *((long *)&y) = 0x5f3759df - ((* (long *) &number) >> 1);
+               y = y * (1.5f - (number * 0.5f * y * y));
+
+               VectorScale(v, y, v);
+       }
+}
+
 #if 0
 // LordHavoc: no longer used at all
 void ProjectPointOnPlane( vec3_t dst, const vec3_t p, const vec3_t normal )
@@ -538,6 +564,19 @@ void BoxOnPlaneSideClassify(mplane_t *p)
        }
 }
 
+void PlaneClassify(mplane_t *p)
+{
+       if (p->normal[0] == 1)
+               p->type = 0;
+       else if (p->normal[1] == 1)
+               p->type = 1;
+       else if (p->normal[2] == 1)
+               p->type = 2;
+       else
+               p->type = 3;
+       BoxOnPlaneSideClassify(p);
+}
+
 void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up)
 {
        float           angle;
@@ -641,7 +680,7 @@ vec_t Length(vec3_t v)
 {
        int             i;
        float   length;
-       
+
        length = 0;
        for (i=0 ; i< 3 ; i++)
                length += v[i]*v[i];
@@ -691,14 +730,14 @@ float VectorNormalizeLength2 (vec3_t v, vec3_t dest) // LordHavoc: added to allo
 
 }
 
-void VectorInverse (vec3_t v)
+void _VectorInverse (vec3_t v)
 {
        v[0] = -v[0];
        v[1] = -v[1];
        v[2] = -v[2];
 }
 
-void VectorScale (vec3_t in, vec_t scale, vec3_t out)
+void _VectorScale (vec3_t in, vec_t scale, vec3_t out)
 {
        out[0] = in[0]*scale;
        out[1] = in[1]*scale;
index 4b613ba..d3cfe5e 100644 (file)
--- a/mathlib.h
+++ b/mathlib.h
@@ -62,8 +62,19 @@ extern       int nanmask;
 #define VectorDistance2(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]))
 #define VectorDistance(a, b) (sqrt(VectorDistance2(a,b)))
 #define VectorLength(a) sqrt(DotProduct(a, a))
-#define VectorScaleQuick(in, scale, out) {(out)[0] = (in)[0] * (scale);(out)[1] = (in)[1] * (scale);(out)[2] = (in)[2] * (scale);}
+#define VectorScale(in, scale, out) {(out)[0] = (in)[0] * (scale);(out)[1] = (in)[1] * (scale);(out)[2] = (in)[2] * (scale);}
 #define VectorMAQuick(a, scale, b, c) {(c)[0] = (a)[0] + (scale) * (b)[0];(c)[1] = (a)[1] + (scale) * (b)[1];(c)[2] = (a)[2] + (scale) * (b)[2];}
+#define VectorNormalizeFast(_v)\
+{\
+       float _y, _number;\
+       _number = DotProduct(_v, _v);\
+       if (_number != 0.0)\
+       {\
+               *((long *)&_y) = 0x5f3759df - ((* (long *) &_number) >> 1);\
+               _y = _y * (1.5f - (_number * 0.5f * _y * _y));\
+               VectorScale(_v, _y, _v);\
+       }\
+}\
 
 
 void VectorMA (vec3_t veca, float scale, vec3_t vecb, vec3_t vecc);
@@ -77,9 +88,12 @@ int VectorCompare (vec3_t v1, vec3_t v2);
 vec_t Length (vec3_t v);
 float VectorNormalizeLength (vec3_t v);                // returns vector length
 float VectorNormalizeLength2 (vec3_t v, vec3_t dest);          // returns vector length
-void VectorInverse (vec3_t v);
-void VectorScale (vec3_t in, vec_t scale, vec3_t out);
+void _VectorInverse (vec3_t v);
+void _VectorScale (vec3_t in, vec_t scale, vec3_t out);
 int Q_log2(int val);
+void _VectorNormalizeFast (vec3_t v);
+
+float Q_RSqrt(float number);
 
 #define NUMVERTEXNORMALS       162
 extern float m_bytenormals[NUMVERTEXNORMALS][3];
@@ -98,7 +112,7 @@ void AngleVectors (vec3_t angles, vec3_t forward, vec3_t right, vec3_t up);
 // LordHavoc: like AngleVectors, but taking a forward vector instead of angles, useful!
 void VectorVectors(const vec3_t forward, vec3_t right, vec3_t up);
 
-void BoxOnPlaneSideClassify(struct mplane_s *p);
+void PlaneClassify(struct mplane_s *p);
 
 #define BOX_ON_PLANE_SIDE(emins, emaxs, p)     \
        (((p)->type < 3)?                                               \
@@ -118,6 +132,8 @@ void BoxOnPlaneSideClassify(struct mplane_s *p);
 
 #define PlaneDist(point,plane)  ((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal))
 #define PlaneDiff(point,plane) (((plane)->type < 3 ? (point)[(plane)->type] : DotProduct((point), (plane)->normal)) - (plane)->dist)
+//#define PlaneDist(point,plane)  (DotProduct((point), (plane)->normal))
+//#define PlaneDiff(point,plane) (DotProduct((point), (plane)->normal) - (plane)->dist)
 
 #define lhrandom(MIN,MAX) ((rand() & 32767) * (((MAX)-(MIN)) * (1.0f / 32767.0f)) + (MIN))
 
@@ -125,3 +141,14 @@ void BoxOnPlaneSideClassify(struct mplane_s *p);
 #define min(A,B) (A < B ? A : B)
 #define max(A,B) (A > B ? A : B)
 #endif
+
+// LordHavoc: minimal plane structure
+typedef struct
+{
+       float   normal[3], dist;
+} tinyplane_t;
+
+typedef struct
+{
+       double  normal[3], dist;
+} tinydoubleplane_t;
diff --git a/menu.c b/menu.c
index 8e3cfbe..23b6d3d 100644 (file)
--- a/menu.c
+++ b/menu.c
@@ -1236,7 +1236,7 @@ again:
 //=============================================================================
 /* OPTIONS MENU */
 
-#define        OPTIONS_ITEMS   23
+#define        OPTIONS_ITEMS   (vid_menudrawfn ? 23 : 22)
 
 #define        SLIDER_RANGE    10
 
@@ -1410,7 +1410,9 @@ void M_Options_Draw (void)
        M_Print(16, y, "             Use Mouse");M_DrawCheckbox(220, y, vid_mouse.value);y += 8;
        M_Print(16, y, "             Crosshair");M_DrawSlider(220, y, crosshair.value / 5);y += 8;
        M_Print(16, y, "        Show Framerate");M_DrawCheckbox(220, y, showfps.value);y += 8;
-       M_Print(16, y, "         Video Options");y += 8;
+       if (vid_menudrawfn)
+               M_Print(16, y, "         Video Options");
+       y += 8;
 
        // cursor
        M_DrawCharacter(200, 32 + options_cursor*8, 12+((int)(realtime*4)&1));
@@ -1440,7 +1442,8 @@ void M_Options_Key (int k)
                        Cbuf_AddText ("exec default.cfg\n");
                        break;
                case 22:
-                       M_Menu_Video_f ();
+                       if (vid_menudrawfn)
+                               M_Menu_Video_f ();
                        break;
                default:
                        M_AdjustSliders (1);
index b01c1c3..70eae3a 100644 (file)
@@ -817,7 +817,7 @@ void Mod_LoadFaces (lump_t *l)
                 && (out->texinfo->texture->name[2] == 'y' || out->texinfo->texture->name[2] == 'Y'))
                {
                        // LordHavoc: for consistency reasons, mark sky as fullbright and solid as well
-                       out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA);
+                       out->flags |= (SURF_DRAWSKY | SURF_DRAWTILED | SURF_DRAWFULLBRIGHT | SURF_DRAWNOALPHA | SURF_CLIPSOLID);
                        GL_SubdivideSurface (out);      // cut up polygon for warps
                        continue;
                }
@@ -839,7 +839,8 @@ void Mod_LoadFaces (lump_t *l)
                        GL_SubdivideSurface (out);      // cut up polygon for warps
                        continue;
                }
-
+               
+               out->flags |= SURF_CLIPSOLID;
        }
 }
 
@@ -1153,7 +1154,6 @@ void Mod_LoadPlanes (lump_t *l)
        mplane_t        *out;
        dplane_t        *in;
        int                     count;
-       int                     bits;
        
        in = (void *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
@@ -1166,18 +1166,13 @@ void Mod_LoadPlanes (lump_t *l)
 
        for ( i=0 ; i<count ; i++, in++, out++)
        {
-               bits = 0;
                for (j=0 ; j<3 ; j++)
-               {
                        out->normal[j] = LittleFloat (in->normal[j]);
-//                     if (out->normal[j] < 0)
-//                             bits |= 1<<j;
-               }
 
                out->dist = LittleFloat (in->dist);
-               out->type = LittleLong (in->type);
-//             out->signbits = bits;
-               BoxOnPlaneSideClassify(out);
+               // LordHavoc: recalculated by PlaneClassify, FIXME: validate type and report error if type does not match normal?
+//             out->type = LittleLong (in->type);
+               PlaneClassify(out);
        }
 }
 
@@ -1574,6 +1569,7 @@ void Mod_FinalizePortals(void)
                                        VectorCopy(p->winding->points[j], point->position);
                                        point++;
                                }
+                               PlaneClassify(&portal->plane);
 
                                // link into leaf's portal chain
                                portal->next = portal->here->portals;
@@ -1595,6 +1591,7 @@ void Mod_FinalizePortals(void)
                                        VectorCopy(p->winding->points[j], point->position);
                                        point++;
                                }
+                               PlaneClassify(&portal->plane);
 
                                // link into leaf's portal chain
                                portal->next = portal->here->portals;
index cfb371e..24710e2 100644 (file)
@@ -70,11 +70,10 @@ typedef struct texture_s
 #define SURF_DRAWTILED         0x20
 #define SURF_DRAWBACKGROUND    0x40
 //#define SURF_UNDERWATER              0x80
-// LordHavoc: added these for lava and teleport textures
 #define SURF_DRAWNOALPHA       0x100
 #define SURF_DRAWFULLBRIGHT    0x200
-// LordHavoc: light both sides
-#define SURF_LIGHTBOTHSIDES            0x400
+#define SURF_LIGHTBOTHSIDES    0x400
+#define SURF_CLIPSOLID         0x800 // this polygon can obscure other polygons
 
 typedef struct
 {
@@ -89,17 +88,23 @@ typedef struct
 } mtexinfo_t;
 
 // LordHavoc: was 7, I added one more for raw lightmap position
+// (xyz st uv l)
 #define        VERTEXSIZE      8
 
 typedef struct glpoly_s
 {
        struct  glpoly_s        *next;
-       struct  glpoly_s        *chain;
        int             numverts;
-       int             flags;                  // for SURF_UNDERWATER
-       float   verts[4][VERTEXSIZE];   // variable sized (xyz s1t1 s2t2)
+       float   verts[4][VERTEXSIZE];   // variable sized
 } glpoly_t;
 
+typedef struct glpolysizeof_s
+{
+       struct  glpoly_s        *next;
+       int             numverts;
+       int             flags;                  // for SURF_UNDERWATER
+} glpolysizeof_t;
+
 typedef struct msurface_s
 {
        int                     visframe;               // should be drawn when node is crossed
@@ -109,7 +114,7 @@ typedef struct msurface_s
 
        int                     firstedge;      // look up in model->surfedges[], negative numbers
        int                     numedges;       // are backwards edges
-       
+
        short           texturemins[2];
        short           extents[2];
 
@@ -118,7 +123,7 @@ typedef struct msurface_s
        glpoly_t        *polys;                         // multiple if warped
 
        mtexinfo_t      *texinfo;
-       
+
 // lighting info
        int                     dlightframe;
        int                     dlightbits[8];
@@ -146,7 +151,7 @@ typedef struct mnode_s
 
 // node specific
        mplane_t        *plane;
-       struct mnode_s  *children[2];   
+       struct mnode_s  *children[2];
 
        unsigned short          firstsurface;
        unsigned short          numsurfaces;
@@ -163,8 +168,8 @@ typedef struct mleaf_s
        struct mportal_s *portals;
 
 // leaf specific
-       int                     visframe;               // visible if current (r_framecount)
-       int                     worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame
+//     int                     visframe;               // visible if current (r_framecount)
+//     int                     worldnodeframe; // used by certain worldnode variants to avoid processing the same leaf twice in a frame
 
        // for bounding box culling
        vec3_t          mins;
@@ -199,6 +204,7 @@ typedef struct mportal_s
        mvertex_t *points;
        int numpoints;
        mplane_t plane;
+       int visframe; // is this portal visible this frame?
 }
 mportal_t;
 
diff --git a/progs.h b/progs.h
index a6603d5..699d84b 100644 (file)
--- a/progs.h
+++ b/progs.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.
 
@@ -29,21 +29,26 @@ typedef union eval_s
        func_t                  function;
        int                             _int;
        int                             edict;
-} eval_t;      
+} eval_t;
+
+typedef struct link_s
+{
+       struct link_s   *prev, *next;
+} link_t;
 
 // LordHavoc: increased number of leafs per entity limit from 16 to 256
 #define        MAX_ENT_LEAFS   256
 typedef struct edict_s
 {
        qboolean        free;
-       link_t          area;                           // linked to a division node or leaf
-       
+       link_t          area;
+
        int                     num_leafs;
        short           leafnums[MAX_ENT_LEAFS];
 
        entity_state_t  baseline;
        entity_state_t  deltabaseline; // LordHavoc: previous frame
-       
+
        float           freetime;                       // sv.time when the object was freed
        // LordHavoc: for MOVETYPE_STEP interpolation
        vec3_t          steporigin;
@@ -54,7 +59,8 @@ typedef struct edict_s
        entvars_t       v;                                      // C exported fields from progs
 // other fields from progs come immediately after
 } edict_t;
-#define        EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
+//#define      EDICT_FROM_AREA(l) ((edict_t *)((byte *)l - (int)&(((edict_t *)0)->area)))
+//#define      EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,edict_t,area)
 
 // LordHavoc: in an effort to eliminate time wasted on GetEdictFieldValue...  see pr_edict.c for the functions which use these.
 extern int eval_gravity;
index df79dc8..e7b494b 100644 (file)
@@ -199,6 +199,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #define        svc_showlmp                     35              // [string] slotname [string] lmpfilename [short] x [short] y
 #define        svc_hidelmp                     36              // [string] slotname
+#define        svc_skybox                      37              // [string] skyname
 
 #define svc_unusedlh1
 #define svc_fog                                51              // unfinished
index 9c75da1..6e475cc 100644 (file)
--- a/quakeio.c
+++ b/quakeio.c
@@ -377,16 +377,18 @@ Qgetline (QFile *file)
                return 0;
 
        len = strlen (buf);
-       while (buf[len - 1] != '\n') {
+       while (buf[len - 1] != '\n' && buf[len - 1] != '\r') {
                char       *t = realloc (buf, size + 256);
 
                if (!t)
-                       return 0;
+                       Host_Error("Qgetline: realloc failed, out of memory?\n");
                buf = t;
                size += 256;
                if (!Qgets (file, buf + len, size - len))
                        break;
                len = strlen (buf);
        }
+       while ((len = strlen(buf)) && (buf[len - 1] == '\n' || buf[len - 1] == '\r'))
+               buf[len - 1] = 0;
        return buf;
 }
index d8319ba..cf8a9b5 100644 (file)
--- a/quakeio.h
+++ b/quakeio.h
@@ -30,7 +30,7 @@
 #ifndef __quakeio_h
 #define __quakeio_h
 
-#define HAVE_ZLIB
+//#define HAVE_ZLIB
 
 #ifdef HAVE_CONFIG_H
 # include "config.h"
diff --git a/r_clip.c b/r_clip.c
new file mode 100644 (file)
index 0000000..373e1fa
--- /dev/null
+++ b/r_clip.c
@@ -0,0 +1,1029 @@
+
+#include "quakedef.h"
+
+typedef struct clipsurf_s
+{
+       struct clipsurf_s *next, *prev;
+       int state;
+       int visible;
+       int solid;
+       int removed;
+       void (*callback)(void *nativedata, void *nativedata2);
+       void *nativedata;
+       void *nativedata2;
+       float wstepx, wstepy, w00;
+       // wcurrent is a cached copy of w00 + wstepy * y,
+       // updated each time the surface is added to the stack,
+       // for quicker comparisons.
+       float wcurrent;
+       // this is a linked list of all edges belonging to this surface,
+       // used to remove them if this is a non-solid surface that is
+       // marked visible (it can not hide anything, so it is useless)
+//     struct clipedge_s *edgechain;
+}
+clipsurf_t;
+
+typedef struct clipedge_s
+{
+       float x, realx, realxstep;
+       struct clipedge_s *next, *prev, *nextremove;
+       clipsurf_t *psurf;
+       int leading;
+       int pad;
+}
+clipedge_t;
+
+clipsurf_t *pavailsurf, *clipsurfs, *clipsurfsend;
+clipedge_t *pavailedge, *clipedges, *clipedgesend, *newedges, **removeedges;
+
+clipsurf_t surfstack;
+clipedge_t edgehead, edgetail;
+clipedge_t maxedge = {2000000000.0f};
+
+cvar_t r_clipwidth = {"r_clipwidth", "800"};
+cvar_t r_clipheight = {"r_clipheight", "600"};
+cvar_t r_clipedges = {"r_clipedges", "32768", true};
+cvar_t r_clipsurfaces = {"r_clipsurfaces", "8192", true};
+
+int clipwidth = 0, clipheight = 0;
+int maxclipsurfs = 0, maxclipedges = 0;
+int needededges, neededsurfs;
+
+#if CLIPTEST
+typedef struct
+{
+       float w; // inverse depth (1/z)
+}
+clippixel_t;
+
+clippixel_t *clipbuffer;
+#endif
+
+float r_clip_viewmatrix[3][3], r_clip_viewmulx, r_clip_viewmuly, r_clip_viewcenterx, r_clip_viewcentery;
+// REMOVELATER
+//float xscale, yscale, xscaleinv, yscaleinv;
+//float r_clip_nearclipdist, r_clip_nearclipdist2;
+tinyplane_t r_clip_viewplane[5];
+
+void R_Clip_MakeViewMatrix(void)
+{
+       float pixelaspect, screenaspect, horizontalfieldofview, verticalfieldofview;
+       pixelaspect = (float) clipheight / (float) clipwidth * 320 / 240.0;
+       horizontalfieldofview = 2.0 * tan (r_refdef.fov_x/360*M_PI);
+       screenaspect = clipwidth * pixelaspect / clipheight;
+       verticalfieldofview = horizontalfieldofview / screenaspect;
+       r_clip_viewcenterx = clipwidth * 0.5 - 0.5;
+       r_clip_viewcentery = clipheight * 0.5 - 0.5;
+       r_clip_viewmulx = clipwidth / horizontalfieldofview;
+       r_clip_viewmuly = r_clip_viewmulx * pixelaspect;
+       // this constructs a transposed rotation matrix for the view (transposed matrices do the opposite of their normal behavior)
+       VectorCopy (vright, r_clip_viewmatrix[0]);
+       VectorNegate (vup, r_clip_viewmatrix[1]);
+       VectorCopy (vpn, r_clip_viewmatrix[2]);
+//     r_clip_nearclipdist = DotProduct(r_origin, vpn) + 4.0f;
+//     r_clip_nearclipdist2 = r_clip_nearclipdist - 8.0f;
+       VectorCopy (vpn, r_clip_viewplane[0].normal);
+       r_clip_viewplane[0].dist = DotProduct(r_origin, vpn);
+       memcpy(&r_clip_viewplane[1], &frustum[0], sizeof(tinyplane_t));
+       memcpy(&r_clip_viewplane[2], &frustum[1], sizeof(tinyplane_t));
+       memcpy(&r_clip_viewplane[3], &frustum[2], sizeof(tinyplane_t));
+       memcpy(&r_clip_viewplane[4], &frustum[3], sizeof(tinyplane_t));
+// REMOVELATER
+//     maxscreenscaleinv = (1.0f / max(clipwidth, clipheight)) * horizontalfieldofview * 0.5f;
+//     xscale = clipwidth / horizontalfieldofview;
+//     xscaleinv = 1.0 / xscale;
+//     yscale = xscale * pixelaspect;
+//     yscaleinv = 1.0 / yscale;
+}
+
+void R_Clip_StartFrame(void)
+{
+       int i;
+       int newwidth, newheight, newmaxedges, newmaxsurfs;
+       newwidth = bound(80, (int) r_clipwidth.value, vid.width * 2);
+       newheight = bound(60, (int) r_clipheight.value, vid.height * 2);
+       newmaxedges = bound(128, (int) r_clipedges.value, 262144);
+       newmaxsurfs = bound(32, (int) r_clipsurfaces.value, 65536);
+       if (newwidth != clipwidth || newheight != clipheight || maxclipedges != newmaxedges || maxclipsurfs != newmaxsurfs)
+       {
+#if CLIPTEST
+               if (clipbuffer)
+                       qfree(clipbuffer);
+#endif
+               if (clipedges)
+                       qfree(clipedges);
+               if (clipsurfs)
+                       qfree(clipsurfs);
+               if (newedges)
+                       qfree(newedges);
+               if (removeedges)
+                       qfree(removeedges);
+               clipwidth = newwidth;
+               clipheight = newheight;
+               maxclipedges = newmaxedges;
+               maxclipsurfs = newmaxsurfs;
+#if CLIPTEST
+               clipbuffer = qmalloc(clipwidth * clipheight * sizeof(clippixel_t));
+#endif
+               clipedges = qmalloc(maxclipedges * sizeof(clipedge_t));
+               clipsurfs = qmalloc(maxclipsurfs * sizeof(clipsurf_t));
+               newedges = qmalloc(clipheight * sizeof(clipedge_t));
+               removeedges = qmalloc(clipheight * sizeof(clipedge_t *));
+               clipedgesend = clipedges + maxclipedges;
+               clipsurfsend = clipsurfs + maxclipsurfs;
+       }
+#if CLIPTEST
+       memset(clipbuffer, 0, clipwidth * clipheight * sizeof(clippixel_t));
+#endif
+       pavailedge = clipedges;
+       pavailsurf = clipsurfs;
+       // Clear the lists of edges to add and remove on each scan line.
+
+       needededges = 0;
+       neededsurfs = 0;
+       for (i = 0;i < clipheight;i++)
+       {
+               newedges[i].next = &maxedge;
+               removeedges[i] = NULL;
+       }
+
+       R_Clip_MakeViewMatrix();
+}
+
+void ScanEdges (void);
+
+void R_Clip_EndFrame(void)
+{
+       ScanEdges();
+       if (maxclipedges < needededges)
+       {
+               Con_Printf("R_Clip: ran out of edges, increasing limit from %d to %d\n", maxclipedges, needededges);
+               Cvar_SetValue("r_clipedges", needededges);
+       }
+       if (maxclipsurfs < neededsurfs)
+       {
+               Con_Printf("R_Clip: ran out of surfaces, increasing limit from %d to %d\n", maxclipsurfs, neededsurfs);
+               Cvar_SetValue("r_clipsurfaces", neededsurfs);
+       }
+}
+
+void r_clip_start(void)
+{
+}
+
+void r_clip_shutdown(void)
+{
+#if CLIPTEST
+       if (clipbuffer)
+               qfree(clipbuffer);
+       clipbuffer = NULL;
+#endif
+       if (clipsurfs)
+               qfree(clipsurfs);
+       clipsurfs = NULL;
+       if (clipedges)
+               qfree(clipedges);
+       clipedges = NULL;
+       if (newedges)
+               qfree(newedges);
+       newedges = NULL;
+       if (removeedges)
+               qfree(removeedges);
+       removeedges = NULL;
+       clipwidth = -1;
+       clipheight = -1;
+}
+
+void r_clip_newmap(void)
+{
+}
+
+void R_Clip_Init(void)
+{
+       Cvar_RegisterVariable(&r_clipwidth);
+       Cvar_RegisterVariable(&r_clipheight);
+       Cvar_RegisterVariable(&r_clipedges);
+       Cvar_RegisterVariable(&r_clipsurfaces);
+       R_RegisterModule("R_Clip", r_clip_start, r_clip_shutdown, r_clip_newmap);
+}
+
+int R_Clip_TriangleToPlane(vec3_t point1, vec3_t point2, vec3_t point3, tinyplane_t *p)
+{
+       float y, number;
+       vec3_t v1, v2;
+       VectorSubtract(point1, point2, v1);
+       VectorSubtract(point3, point2, v2);
+       CrossProduct(v1, v2, p->normal);
+       number = DotProduct(p->normal, p->normal);
+       if (number >= 0.1f)
+       {
+               *((long *)&y) = 0x5f3759df - ((* (long *) &number) >> 1);
+               y = y * (1.5f - (number * 0.5f * y * y));
+               VectorScale(p->normal, y, p->normal);
+               p->dist = DotProduct(point1, p->normal);
+               return true;
+       }
+       else
+               return false;
+}
+
+/*
+int R_Clip_TriangleToDoublePlane(double *point1, double *point2, double *point3, tinydoubleplane_t *p)
+{
+       double y, number;
+       double v1[3], v2[3];
+       VectorSubtract(point1, point2, v1);
+       VectorSubtract(point3, point2, v2);
+       CrossProduct(v1, v2, p->normal);
+       number = DotProduct(p->normal, p->normal);
+       if (number >= 0.1)
+       {
+               y = 1.0 / sqrt(number);
+               VectorScale(p->normal, y, p->normal);
+               p->dist = DotProduct(point1, p->normal);
+               return true;
+       }
+       else
+               return false;
+}
+*/
+
+int R_Clip_ClipPolygonToPlane(float *in, float *out, int inpoints, int stride, tinyplane_t *plane)
+{
+       int i, outpoints, prevside, side;
+       float *prevpoint, prevdist, dist, dot;
+
+       // begin with the last point, then enter the loop with the first point as current
+       prevpoint = (float *) ((byte *)in + stride * (inpoints - 1));
+       prevdist = DotProduct(prevpoint, plane->normal) - plane->dist;
+       prevside = prevdist >= 0 ? SIDE_FRONT : SIDE_BACK;
+       i = 0;
+       outpoints = 0;
+       goto begin;
+       for (;i < inpoints;i++)
+       {
+               prevpoint = in;
+               prevdist = dist;
+               prevside = side;
+               (byte *)in += stride;
+
+begin:
+               dist = DotProduct(in, plane->normal) - plane->dist;
+               side = dist >= 0 ? SIDE_FRONT : SIDE_BACK;
+
+               if (prevside == SIDE_FRONT)
+               {
+                       VectorCopy(prevpoint, out);
+                       out += 3;
+                       outpoints++;
+                       if (side == SIDE_FRONT)
+                               continue;
+               }
+               else if (side == SIDE_BACK)
+                       continue;
+
+               // generate a split point
+               dot = prevdist / (prevdist - dist);
+               out[0] = prevpoint[0] + dot * (in[0] - prevpoint[0]);
+               out[1] = prevpoint[1] + dot * (in[1] - prevpoint[1]);
+               out[2] = prevpoint[2] + dot * (in[2] - prevpoint[2]);
+               out += 3;
+               outpoints++;
+       }
+
+       return outpoints;
+}
+
+float tempverts[256][3];
+float tempverts2[256][3];
+float screenverts[256][3];
+
+// LordHavoc: this code is based primarily on the ddjzsort code
+
+// Clips polygon to view frustum and nearclip, transforms polygon to viewspace, perspective projects polygon to screenspace,
+// and adds polygon's edges to the global edge table.
+void R_Clip_AddPolygon (vec_t *points, int numverts, int stride, int solid, void (*callback)(void *nativedata, void *nativedata2), void *nativedata, void *nativedata2, tinyplane_t *polyplane)
+{
+       float deltax, deltay, vx, vy, vz, fx;
+       int i, j, k, nextvert, temp, topy, bottomy, height, addededges;
+       clipedge_t *pedge;
+//     tinydoubleplane_t plane;
+       tinyplane_t localplane;
+//     tinyplane_t testplane;
+       float distinv;
+
+//     if (!solid)
+//             return;
+
+       if (polyplane == NULL)
+       {
+               polyplane = &localplane;
+               // calculate the plane for the polygon
+               if (!R_Clip_TriangleToPlane((float *) points, (float *) ((byte *)points + stride), (float *) ((byte *)points + 2 * stride), polyplane))
+               {
+                       for (i = 0;i < numverts;i++)
+                               for (j = i + 1;j < numverts;j++)
+                                       for (k = j + 1;k < numverts;k++)
+                                               if (R_Clip_TriangleToPlane((float *) ((byte *)points + i * stride), (float *) ((byte *)points + j * stride), (float *) ((byte *)points + k * stride), polyplane))
+                                                       goto valid1;
+                       return; // gave up
+                       valid1:;
+               }
+
+               // caller hasn't checked if this polygon faces the view, so we have to check
+               if (DotProduct(r_origin, polyplane->normal) < (polyplane->dist + 0.5f))
+                       return;
+       }
+#if 0 // debugging (validates planes passed in)
+       else
+       {
+               // calculate the plane for the polygon
+               if (!R_Clip_TriangleToPlane((float *) points, (float *) ((byte *)points + stride), (float *) ((byte *)points + 2 * stride), &localplane))
+               {
+                       for (i = 0;i < numverts;i++)
+                               for (j = i + 1;j < numverts;j++)
+                                       for (k = j + 1;k < numverts;k++)
+                                               if (R_Clip_TriangleToPlane((float *) ((byte *)points + i * stride), (float *) ((byte *)points + j * stride), (float *) ((byte *)points + k * stride), &localplane))
+                                                       goto valid4;
+                       return; // gave up
+                       valid4:;
+               }
+
+//             if ((DotProduct(r_origin, polyplane->normal) < (polyplane->dist + 0.5f)) != (DotProduct(r_origin, localplane.normal) < (localplane.dist + 0.5f)))
+               if (DotProduct(polyplane->normal, localplane.normal) < 0.9f)
+               {
+                       Con_Printf("*\n");
+                       return;
+               }
+       }
+#endif
+
+       // for adaptive limits
+       needededges += numverts;
+       neededsurfs++;
+
+       if (pavailsurf >= clipsurfsend)
+               return;
+
+       // clip to view frustum and nearclip
+       if (numverts < 3) return;numverts = R_Clip_ClipPolygonToPlane(points      , tempverts2[0], numverts, stride, &r_clip_viewplane[0]);
+       if (numverts < 3) return;numverts = R_Clip_ClipPolygonToPlane(tempverts2[0], tempverts[0], numverts, sizeof(float) * 3, &r_clip_viewplane[1]);
+       if (numverts < 3) return;numverts = R_Clip_ClipPolygonToPlane(tempverts[0], tempverts2[0], numverts, sizeof(float) * 3, &r_clip_viewplane[2]);
+       if (numverts < 3) return;numverts = R_Clip_ClipPolygonToPlane(tempverts2[0], tempverts[0], numverts, sizeof(float) * 3, &r_clip_viewplane[3]);
+       if (numverts < 3) return;numverts = R_Clip_ClipPolygonToPlane(tempverts[0], tempverts2[0], numverts, sizeof(float) * 3, &r_clip_viewplane[4]);
+       if (numverts < 3)
+               return;
+       if (numverts > 256)
+               Sys_Error("R_Clip_AddPolygon: polygon exceeded 256 vertex buffer\n");
+
+       // it survived the clipping, transform to viewspace and project to screenspace
+
+       if (pavailedge + numverts > clipedgesend)
+               return;
+
+#if 1
+       for (i = 0;i < numverts;i++)
+       {
+               vx = tempverts2[i][0] - r_origin[0];
+               vy = tempverts2[i][1] - r_origin[1];
+               vz = tempverts2[i][2] - r_origin[2];
+               screenverts[i][2] = 1.0f / (r_clip_viewmatrix[2][0] * vx + r_clip_viewmatrix[2][1] * vy + r_clip_viewmatrix[2][2] * vz);
+               screenverts[i][0] = (r_clip_viewmatrix[0][0] * vx + r_clip_viewmatrix[0][1] * vy + r_clip_viewmatrix[0][2] * vz) * r_clip_viewmulx * screenverts[i][2] + r_clip_viewcenterx;
+               screenverts[i][1] = (r_clip_viewmatrix[1][0] * vx + r_clip_viewmatrix[1][1] * vy + r_clip_viewmatrix[1][2] * vz) * r_clip_viewmuly * screenverts[i][2] + r_clip_viewcentery;
+       }
+
+       /*
+       if (polyplane != NULL)
+       {
+       */
+       /*
+               distinv = 1.0f / (polyplane->dist - DotProduct(r_origin, polyplane->normal));
+               pavailsurf->wstepx = DotProduct(r_clip_viewmatrix[0], polyplane->normal) * xscaleinv * distinv;
+               pavailsurf->wstepy = DotProduct(r_clip_viewmatrix[1], polyplane->normal) * yscaleinv * distinv;
+               pavailsurf->w00 = DotProduct(r_clip_viewmatrix[2], polyplane->normal) * distinv - r_clip_viewcenterx * pavailsurf->wstepx - r_clip_viewcentery * pavailsurf->wstepy;
+       */
+       /*
+       }
+       else
+       {
+       */
+               // calculate the plane for the polygon
+               if (!R_Clip_TriangleToPlane(screenverts[0], screenverts[1], screenverts[2], &localplane))
+               {
+                       for (i = 0;i < numverts;i++)
+                               for (j = i + 1;j < numverts;j++)
+                                       for (k = j + 1;k < numverts;k++)
+                                               if (R_Clip_TriangleToPlane(screenverts[i], screenverts[j], screenverts[k], &localplane))
+                                                       goto valid;
+                       return; // gave up
+                       valid:;
+               }
+
+               // Set up the 1/z gradients from the polygon, calculating the
+               // base value at screen coordinate 0,0 so we can use screen
+               // coordinates directly when calculating 1/z from the gradients
+               distinv = 1.0f / localplane.normal[2];
+               pavailsurf->wstepx = -(localplane.normal[0] * distinv);
+               pavailsurf->wstepy = -(localplane.normal[1] * distinv);
+               pavailsurf->w00 = localplane.dist * distinv;
+       /*
+       }
+       */
+       // REMOVELATER
+       /*
+       prevdist = z1 * plane.normal[2] - plane.dist;
+       dist = z2 * plane.normal[2] - plane.dist;
+       d = prevdist / (prevdist - dist);
+       zc = z1 + d * (z2 - z1);
+
+       prevdist = plane.normal[0] + z1 * plane.normal[2] - plane.dist;
+       dist = plane.normal[0] + z2 * plane.normal[2] - plane.dist;
+       d = prevdist / (prevdist - dist);
+       zx = (z1 + d * (z2 - z1)) - zc;
+
+       prevdist = plane.normal[1] + z1 * plane.normal[2] - plane.dist;
+       dist = plane.normal[1] + z2 * plane.normal[2] - plane.dist;
+       d = prevdist / (prevdist - dist);
+       zy = (z1 + d * (z2 - z1)) - zc;
+       */
+
+       /*
+       zc = (-plane.dist) / ((-plane.dist) - (plane.normal[2] - plane.dist));
+       zx = ((plane.normal[0] - plane.dist) / ((plane.normal[0] - plane.dist) - (plane.normal[0] + plane.normal[2] - plane.dist))) - zc;
+       zy = ((plane.normal[1] - plane.dist) / ((plane.normal[1] - plane.dist) - (plane.normal[1] + plane.normal[2] - plane.dist))) - zc;
+       */
+
+//     zc = (plane.dist / plane.normal[2]);
+//     zx = -(plane.normal[0] / plane.normal[2]);
+//     zy = -(plane.normal[1] / plane.normal[2]);
+//     zy = ((plane.normal[1] - plane.dist) / (-plane.normal[2])) + ((plane.dist) / (-plane.normal[2]));
+#else // REMOVELATER
+       for (i = 0;i < numverts;i++)
+       {
+               vx = tempverts2[i][0] - r_origin[0];
+               vy = tempverts2[i][1] - r_origin[1];
+               vz = tempverts2[i][2] - r_origin[2];
+               screenverts[i][0] = r_clip_viewmatrix[0][0] * vx + r_clip_viewmatrix[0][1] * vy + r_clip_viewmatrix[0][2] * vz;
+               screenverts[i][1] = r_clip_viewmatrix[1][0] * vx + r_clip_viewmatrix[1][1] * vy + r_clip_viewmatrix[1][2] * vz;
+               screenverts[i][2] = r_clip_viewmatrix[2][0] * vx + r_clip_viewmatrix[2][1] * vy + r_clip_viewmatrix[2][2] * vz;
+       }
+
+       // REMOVELATER
+       // calculate the plane for the polygon
+       for (i = 0;i < numverts;i++)
+               for (j = i + 1;j < numverts;j++)
+                       for (k = j + 1;k < numverts;k++)
+                               if (R_Clip_TriangleToDoublePlane(screenverts[i], screenverts[j], screenverts[k], &plane))
+                                       goto valid2;
+       return; // gave up
+valid2:;
+
+       distinv = 1.0f / plane.dist;
+       pavailsurf->d_zistepx = plane.normal[0] * xscaleinv * distinv;
+       pavailsurf->d_zistepy = -plane.normal[1] * yscaleinv * distinv;
+       pavailsurf->d_ziorigin = plane.normal[2] * distinv - r_clip_viewcenterx * pavailsurf->wstepx - r_clip_viewcentery * pavailsurf->wstepy;
+
+       for (i = 0;i < numverts;i++)
+       {
+               screenverts[i][2] = 1.0f / (screenverts[i][2]);
+               screenverts[i][0] = screenverts[i][0] * r_clip_viewmulx * screenverts[i][2] + r_clip_viewcenterx;
+               screenverts[i][1] = screenverts[i][1] * r_clip_viewmuly * screenverts[i][2] + r_clip_viewcentery;
+               // REMOVELATER
+//             if (screenverts[i][0] < -0.5)
+//                     screenverts[i][0] = -0.5;
+//             if (screenverts[i][0] > (clipwidth - 0.5))
+//                     screenverts[i][0] = clipwidth - 0.5;
+//             if (screenverts[i][1] < -0.5)
+//                     screenverts[i][1] = -0.5;
+//             if (screenverts[i][1] > (clipheight - 0.5))
+//                     screenverts[i][1] = clipheight - 0.5;
+//             if (screenverts[i][2] <= 0.0)
+//                     Con_Printf("R_Clip_AddPolygon: vertex z <= 0!\n");
+       }
+#endif
+
+       addededges = false;
+
+       // Add each edge in turn
+       for (i = 0;i < numverts;i++)
+       {
+               nextvert = i + 1;
+               if (nextvert >= numverts)
+                       nextvert = 0;
+
+               topy = (int)ceil(screenverts[i][1]);
+               bottomy = (int)ceil(screenverts[nextvert][1]);
+               height = bottomy - topy;
+               if (height == 0)
+                       continue;       // doesn't cross any scan lines
+               if (height < 0)
+               {
+                       // Leading edge
+                       temp = topy;
+                       topy = bottomy;
+                       bottomy = temp;
+                       if (topy < 0)
+                               topy = 0;
+                       if (bottomy > clipheight)
+                               bottomy = clipheight;
+                       if (topy >= bottomy)
+                               continue;
+
+                       pavailedge->leading = 1;
+
+                       deltax = screenverts[i][0] - screenverts[nextvert][0];
+                       deltay = screenverts[i][1] - screenverts[nextvert][1];
+
+                       pavailedge->realxstep = deltax / deltay;
+                       pavailedge->realx = screenverts[nextvert][0] + ((float)topy - screenverts[nextvert][1]) * pavailedge->realxstep;
+               }
+               else
+               {
+                       // Trailing edge
+                       if (topy < 0)
+                               topy = 0;
+                       if (bottomy > clipheight)
+                               bottomy = clipheight;
+                       if (topy >= bottomy)
+                               continue;
+
+                       pavailedge->leading = 0;
+
+                       deltax = screenverts[nextvert][0] - screenverts[i][0];
+                       deltay = screenverts[nextvert][1] - screenverts[i][1];
+
+                       pavailedge->realxstep = deltax / deltay;
+                       pavailedge->realx = screenverts[i][0] + ((float)topy - screenverts[i][1]) * pavailedge->realxstep;
+               }
+
+               // Put the edge on the list to be added on top scan
+               fx = pavailedge->x = bound(0.0f, pavailedge->realx, clipwidth - 0.5f);
+               pedge = &newedges[topy];
+               while (fx > pedge->next->x)
+                       pedge = pedge->next;
+               pavailedge->next = pedge->next;
+               pedge->next = pavailedge;
+
+               // Put the edge on the list to be removed after final scan
+               pavailedge->nextremove = removeedges[bottomy - 1];
+               removeedges[bottomy - 1] = pavailedge;
+
+               // Associate the edge with the surface
+               pavailedge->psurf = pavailsurf;
+
+               pavailedge++;
+
+               addededges = true;
+       }
+
+       if (!addededges)
+               return;
+
+       // Create the surface, so we'll know how to sort and draw from the edges
+       pavailsurf->next = NULL;
+       pavailsurf->prev = NULL;
+       pavailsurf->state = 0;
+       pavailsurf->visible = false;
+       pavailsurf->callback = callback;
+       pavailsurf->nativedata = nativedata;
+       pavailsurf->nativedata2 = nativedata2;
+       pavailsurf->solid = solid;
+       pavailsurf->removed = false;
+       pavailsurf++;
+}
+
+/////////////////////////////////////////////////////////////////////
+// Scan all the edges in the global edge table into spans.
+/////////////////////////////////////////////////////////////////////
+void ScanEdges (void)
+{
+       int y, rescan;
+       float fx, fy, w, w2, clipwidthf = clipwidth - 0.5f;
+       clipedge_t *pedge, *pedge2, *ptemp;
+       clipsurf_t *psurf, *psurf2;
+#if CLIPTEST
+       int x, x2;
+       float zi;
+       clippixel_t *cb;
+#endif
+       float cx;
+
+       // Set up the active edge list as initially empty, containing
+       // only the sentinels (which are also the background fill). Most
+       // of these fields could be set up just once at start-up
+       edgehead.next = &edgetail;
+       edgehead.prev = NULL;
+       edgehead.x = edgehead.realx = -0.9999f; // left edge of screen
+       edgehead.realxstep = 0;
+       edgehead.leading = 1;
+       edgehead.psurf = &surfstack;
+
+       edgetail.next = NULL; // mark end of list
+       edgetail.prev = &edgehead;
+       edgetail.x = edgetail.realx = clipwidth + 0.5f; // right edge of screen
+       edgetail.realxstep = 0;
+       edgetail.leading = 0;
+       edgetail.psurf = &surfstack;
+
+       // The background surface is the entire stack initially, and
+       // is infinitely far away, so everything sorts in front of it.
+       // This could be set just once at start-up
+       surfstack.solid = true;
+       surfstack.visible = true; // no callback
+       surfstack.next = surfstack.prev = &surfstack;
+       surfstack.wcurrent = surfstack.w00 = -999999.0;
+       surfstack.wstepx = surfstack.wstepy = 0.0;
+       surfstack.removed = false;
+
+       // rescan causes the edges to be compared at the span level
+       // it is false if the scanline will be identical to the previous
+       rescan = true;
+       for (y = 0;y < clipheight;y++)
+       {
+               fy = y;
+#if CLIPTEST
+               cb = clipbuffer + y * clipwidth;
+#endif
+
+               // Sort in any edges that start on this scan
+               if (newedges[y].next != &maxedge)
+               {
+                       rescan = true;
+                       pedge = newedges[y].next;
+                       pedge2 = &edgehead;
+                       while (pedge != &maxedge)
+                       {
+                               if (pedge->psurf->removed)
+                               {
+                                       pedge = pedge->next;
+                                       continue;
+                               }
+
+                               while (pedge->x > pedge2->next->x)
+                                       pedge2 = pedge2->next;
+
+                               ptemp = pedge->next;
+                               pedge->next = pedge2->next;
+                               pedge->prev = pedge2;
+                               pedge2->next->prev = pedge;
+                               pedge2->next = pedge;
+
+                               pedge2 = pedge;
+                               pedge = ptemp;
+                       }
+               }
+
+               // Scan out the active edges into spans
+
+               // Start out with the left background edge already inserted, and the surface stack containing only the background
+               surfstack.state = 1;
+               cx = 0;
+
+               // must always rescan if rendering to wbuffer
+#ifndef CLIPTEST
+//             if (rescan)
+#endif
+               {
+                       for (pedge = edgehead.next;pedge;pedge = pedge->next)
+                       {
+                               edgeremoved:
+                               psurf = pedge->psurf;
+                               if (psurf->removed)
+                               {
+                                       pedge2 = pedge->next;
+                                       pedge->prev->next = pedge->next;
+                                       pedge->next->prev = pedge->prev;
+                                       pedge->next = pedge->prev = pedge;
+                                       pedge = pedge2;
+                                       if (pedge)
+                                               goto edgeremoved;
+                                       else
+                                               break;
+                               }
+
+                               if (pedge->leading)
+                               {
+                                       // It's a leading edge. Figure out where it is
+                                       // relative to the current surfaces and insert in
+                                       // the surface stack; if it's on top, emit the span
+                                       // for the current top.
+                                       // First, make sure the edges don't cross
+                                       if (++psurf->state == 1)
+                                       {
+                                               fx = pedge->x;
+                                               // Calculate the surface's 1/z value at this pixel, and cache the y depth for quick compares later
+                                               w = (psurf->wcurrent = psurf->w00 + psurf->wstepy * fy) + psurf->wstepx * fx;
+//                                             if (w < 0)
+//                                                     w = 0;
+
+                                               // See if that makes it a new top surface
+                                               psurf2 = surfstack.next;
+                                               w2 = psurf2->wcurrent + psurf2->wstepx * fx;
+//                                             if (w2 < 0 && psurf2 != &surfstack)
+//                                                     w2 = 0;
+
+                                               if (w >= w2)
+                                               {
+                                                       // It's a new top surface
+                                                       // emit the span for the current top
+                                                       if (fx > cx && !psurf2->visible)
+                                                       {
+                                                               psurf2->visible = true;
+                                                               psurf2->callback(psurf2->nativedata, psurf2->nativedata2);
+                                                       }
+
+#if CLIPTEST
+                                                       for (x = ceil(cx), x2 = ceil(fx) >= clipwidth ? clipwidth : ceil(fx), zi = psurf2->wcurrent + psurf2->wstepx * x;x < x2;x++, zi += psurf2->wstepx)
+                                                               cb[x].w = zi;
+#endif
+
+                                                       cx = fx;
+
+                                                       // Add the edge to the stack
+                                                       psurf->next = psurf2;
+                                                       psurf2->prev = psurf;
+                                                       surfstack.next = psurf;
+                                                       psurf->prev = &surfstack;
+                                               }
+                                               else
+                                               {
+                                                       // Not a new top; sort into the surface stack.
+                                                       // Guaranteed to terminate due to sentinel background surface
+                                                       do
+                                                       {
+                                                               psurf2 = psurf2->next;
+                                                               w2 = psurf2->wcurrent + psurf2->wstepx * fx;
+//                                                             if (w2 < 0 && psurf2 != &surfstack)
+//                                                                     w2 = 0;
+                                                       }
+                                                       while (w < w2);
+
+                                                       // Insert the surface into the stack
+                                                       psurf->next = psurf2;
+                                                       psurf->prev = psurf2->prev;
+                                                       psurf2->prev->next = psurf;
+                                                       psurf2->prev = psurf;
+                                               }
+                                       }
+                               }
+                               else
+                               {
+                                       // It's a trailing edge; if this was the top surface,
+                                       // emit the span and remove it.
+                                       // First, make sure the edges didn't cross
+                                       if (--psurf->state == 0)
+                                       {
+                                               if (surfstack.next == psurf)
+                                               {
+                                                       fx = pedge->x;
+
+                                                       // It's on top, emit the span
+                                                       if (fx > cx && !psurf->visible)
+                                                       {
+                                                               psurf->visible = true;
+                                                               psurf->callback(psurf->nativedata, psurf->nativedata2);
+                                                       }
+
+#if CLIPTEST
+                                                       fx = pedge->x;
+                                                       for (x = ceil(cx), x2 = ceil(fx) >= clipwidth ? clipwidth : ceil(fx), zi = psurf->w00 + psurf->wstepx * x + psurf->wstepy * fy;x < x2;x++, zi += psurf->wstepx)
+                                                               cb[x].w = zi;
+#endif
+
+                                                       cx = fx;
+                                               }
+
+                                               // Remove the surface from the stack
+                                               psurf->next->prev = psurf->prev;
+                                               psurf->prev->next = psurf->next;
+                                       }
+                               }
+
+                               // mark and remove all non-solid surfaces that are ontop
+                               while (!surfstack.next->solid)
+                               {
+                                       psurf = surfstack.next;
+                                       if (!psurf->visible)
+                                       {
+                                               psurf->visible = true;
+                                               psurf->callback(psurf->nativedata, psurf->nativedata2);
+                                       }
+                                       psurf->removed = true;
+                                       psurf->next->prev = psurf->prev;
+                                       psurf->prev->next = psurf->next;
+                                       // isolate the surface
+                                       psurf->next = psurf->prev = psurf;
+                               }
+                       }
+                       rescan = false;
+               }
+
+               // Remove edges that are done
+               pedge = removeedges[y];
+               if (pedge)
+               {
+                       while (pedge)
+                       {
+                               if (!pedge->psurf->removed)
+                               {
+                                       pedge->prev->next = pedge->next;
+                                       pedge->next->prev = pedge->prev;
+                                       if (pedge->psurf->visible)
+                                               rescan = true;
+                               }
+                               pedge = pedge->nextremove;
+                       }
+               }
+
+               // Step the remaining edges one scan line, and re-sort
+               for (pedge = edgehead.next;pedge != &edgetail;)
+               {
+                       ptemp = pedge->next;
+                       if (pedge->psurf->removed)
+                       {
+                               pedge->next->prev = pedge->prev;
+                               pedge->prev->next = pedge->next;
+                               pedge->next = pedge->prev = pedge;
+                               pedge = ptemp;
+                               continue;
+                       }
+
+                       // Step the edge
+                       if (pedge->realxstep)
+                       {
+                               pedge->realx += pedge->realxstep;
+                               pedge->x = bound(0.0f, pedge->realx, clipwidthf);
+                       }
+                       fx = pedge->x;
+
+                       // Move the edge back to the proper sorted location, if necessary
+                       while (fx < pedge->prev->x)
+                       {
+                               if (!rescan && (pedge->psurf->solid || pedge->prev->psurf->solid))
+                                       rescan = true;
+                               pedge2 = pedge->prev;
+                               pedge2->next = pedge->next;
+                               pedge->next->prev = pedge2;
+                               pedge2->prev->next = pedge;
+                               pedge->prev = pedge2->prev;
+                               pedge->next = pedge2;
+                               pedge2->prev = pedge;
+                       }
+
+                       pedge = ptemp;
+               }
+       }
+}
+
+void R_Clip_DisplayBuffer(void)
+{
+#if CLIPTEST
+       int i;
+       static int firstupload = true;
+       byte clipbuffertex[256*256], *b;
+       if (!r_render.value)
+               return;
+       if (clipwidth > 256 || clipheight > 256)
+               return;
+       glBlendFunc(GL_ONE, GL_ONE);
+       glBindTexture(GL_TEXTURE_2D, 8000);
+       if (firstupload)
+       {
+               memset(clipbuffertex, 0, sizeof(clipbuffertex));
+               glTexImage2D(GL_TEXTURE_2D, 0, 1, 256, 256, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, clipbuffertex);
+       }
+       glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+       glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+       if (lighthalf)
+               glColor3f(0.5, 0.5, 0.5);
+       else
+               glColor3f(1, 1, 1);
+       firstupload = false;
+       b = clipbuffertex;
+       for (i = 0;i < clipwidth*clipheight;i++)
+       {
+               if (clipbuffer[i].w > 0)
+                       *b++ = bound(0, (int) (clipbuffer[i].w * 4096.0f), 255);
+               else
+                       *b++ = 0;
+       }
+       glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, clipwidth, clipheight, GL_LUMINANCE, GL_UNSIGNED_BYTE, clipbuffertex);
+       glBegin (GL_QUADS);
+       glTexCoord2f (0                 , 0                  );glVertex2f (0        , 0         );
+       glTexCoord2f (clipwidth / 256.0f, 0                  );glVertex2f (vid.width, 0         );
+       glTexCoord2f (clipwidth / 256.0f, clipheight / 256.0f);glVertex2f (vid.width, vid.height);
+       glTexCoord2f (0                 , clipheight / 256.0f);glVertex2f (0        , vid.height);
+       glEnd ();
+       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+//     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+//     glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+#endif
+}
+
+float boxpoints[4*3];
+
+#define R_Clip_MinsBoxPolygon(axis, axisvalue, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, callback, nativedata, nativedata2, plane) \
+{\
+       if (r_origin[(axis)] < ((axisvalue) - 0.5f))\
+       {\
+               (plane)->dist = -axisvalue;\
+               boxpoints[ 0] = x1;boxpoints[ 1] = y1;boxpoints[ 2] = z1;\
+               boxpoints[ 3] = x2;boxpoints[ 4] = y2;boxpoints[ 5] = z2;\
+               boxpoints[ 6] = x3;boxpoints[ 7] = y3;boxpoints[ 8] = z3;\
+               boxpoints[ 9] = x4;boxpoints[10] = y4;boxpoints[11] = z4;\
+               R_Clip_AddPolygon (boxpoints, 4, sizeof(float[3]), false, callback, nativedata, nativedata2, plane);\
+       }\
+}
+
+#define R_Clip_MaxsBoxPolygon(axis, axisvalue, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, callback, nativedata, nativedata2, plane) \
+{\
+       if (r_origin[(axis)] > ((axisvalue) + 0.5f))\
+       {\
+               (plane)->dist = axisvalue;\
+               boxpoints[ 0] = x1;boxpoints[ 1] = y1;boxpoints[ 2] = z1;\
+               boxpoints[ 3] = x2;boxpoints[ 4] = y2;boxpoints[ 5] = z2;\
+               boxpoints[ 6] = x3;boxpoints[ 7] = y3;boxpoints[ 8] = z3;\
+               boxpoints[ 9] = x4;boxpoints[10] = y4;boxpoints[11] = z4;\
+               R_Clip_AddPolygon (boxpoints, 4, sizeof(float[3]), false, callback, nativedata, nativedata2, plane);\
+       }\
+}
+
+tinyplane_t clipboxplane[6] =
+{
+       {{-1,  0,  0}, 0},
+       {{ 1,  0,  0}, 0},
+       {{ 0, -1,  0}, 0},
+       {{ 0,  1,  0}, 0},
+       {{ 0,  0, -1}, 0},
+       {{ 0,  0,  1}, 0},
+};
+
+void R_Clip_AddBox(float *a, float *b, void (*callback)(void *nativedata, void *nativedata2), void *nativedata, void *nativedata2)
+{
+       if (r_origin[0] >= (a[0] - 5.0f) && r_origin[0] < (b[0] + 5.0f)
+        && r_origin[1] >= (a[1] - 5.0f) && r_origin[1] < (b[1] + 5.0f)
+        && r_origin[2] >= (a[2] - 5.0f) && r_origin[2] < (b[2] + 5.0f))
+       {
+               callback(nativedata, nativedata2);
+               return;
+       }
+
+       if (R_CullBox(a, b))
+               return;
+
+       R_Clip_MinsBoxPolygon
+       (
+               0, a[0],
+               a[0], a[1], a[2],
+               a[0], b[1], a[2],
+               a[0], b[1], b[2],
+               a[0], a[1], b[2],
+               callback, nativedata, nativedata2, &clipboxplane[0]
+       );
+       R_Clip_MaxsBoxPolygon
+       (
+               0, b[0],
+               b[0], b[1], a[2],
+               b[0], a[1], a[2],
+               b[0], a[1], b[2],
+               b[0], b[1], b[2],
+               callback, nativedata, nativedata2, &clipboxplane[1]
+       );
+       R_Clip_MinsBoxPolygon
+       (
+               1, a[1],
+               b[0], a[1], a[2],
+               a[0], a[1], a[2],
+               a[0], a[1], b[2],
+               b[0], a[1], b[2],
+               callback, nativedata, nativedata2, &clipboxplane[2]
+       );
+       R_Clip_MaxsBoxPolygon
+       (
+               1, b[1],
+               a[0], b[1], a[2],
+               b[0], b[1], a[2],
+               b[0], b[1], b[2],
+               a[0], b[1], b[2],
+               callback, nativedata, nativedata2, &clipboxplane[3]
+       );
+       R_Clip_MinsBoxPolygon
+       (
+               2, a[2],
+               a[0], a[1], a[2],
+               b[0], a[1], a[2],
+               b[0], b[1], a[2],
+               a[0], b[1], a[2],
+               callback, nativedata, nativedata2, &clipboxplane[4]
+       );
+       R_Clip_MaxsBoxPolygon
+       (
+               2, b[2],
+               b[0], a[1], b[2],
+               a[0], a[1], b[2],
+               a[0], b[1], b[2],
+               b[0], b[1], b[2],
+               callback, nativedata, nativedata2, &clipboxplane[5]
+       );
+}
diff --git a/r_clip.h b/r_clip.h
new file mode 100644 (file)
index 0000000..6c3c02f
--- /dev/null
+++ b/r_clip.h
@@ -0,0 +1,14 @@
+
+void R_Clip_StartFrame(void);
+void R_Clip_EndFrame(void);
+//int R_Clip_Polygon(float *inv, int numpoints, int stride, int solid);
+//int R_Clip_Portal(float *inv, int numpoints, int stride);
+// This takes a polygon in the form of vec_t triplets, at a caller specified
+// stride (structure size), it can be solid (obscures other geometry) or not,
+// a callback and two parameters must be provided (will be called if it is
+// determined visible), and a plane can be provided (this also indicates that
+// the surface is not a backface, so if a plane is provided, the caller must
+// check that it is not a backface, it is not likely to be fatal if the caller
+// does not, but it is inadvisable)
+void R_Clip_AddPolygon (vec_t *points, int numverts, int stride, int solid, void (*callback)(void *nativedata, void *nativedata2), void *nativedata, void *nativedata2, tinyplane_t *polyplane);
+void R_Clip_AddBox(float *mins, float *maxs, void (*callback)(void *nativedata, void *nativedata2), void *nativedata, void *nativedata2);
index 168efc5..5e05081 100644 (file)
--- a/r_light.c
+++ b/r_light.c
@@ -234,9 +234,9 @@ void R_NoVisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitind
        R_OldMarkLights(lightorigin, light, bit, bitindex, model->nodes + model->hulls[0].firstclipnode);
 }
 
-int lightframe = 0;
 void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex, model_t *model)
 {
+       static int lightframe = 0;
        mleaf_t *pvsleaf = Mod_PointInLeaf (lightorigin, model);
 
        if (!r_dynamic.value)
@@ -258,7 +258,7 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex
 
                lightframe++;
 
-               radius = light->radius * 2;
+               radius = light->radius * 3;
 
                // clamp radius to avoid exceeding 32768 entry division table
                if (radius > 2048)
@@ -284,10 +284,10 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex
                                        if (c & (1<<i))
                                        {
                                                leaf = &model->leafs[(k << 3)+i+1];
-                                               if (leaf->visframe != r_framecount)
-                                                       continue;
-                                               if (leaf->contents == CONTENTS_SOLID)
-                                                       continue;
+//                                             if (leaf->visframe != r_framecount)
+//                                                     continue;
+//                                             if (leaf->contents == CONTENTS_SOLID)
+//                                                     continue;
                                                // if out of the light radius, skip
                                                if (leaf->mins[0] > high[0] || leaf->maxs[0] < low[0]
                                                 || leaf->mins[1] > high[1] || leaf->maxs[1] < low[1]
@@ -305,14 +305,17 @@ void R_VisMarkLights (vec3_t lightorigin, dlight_t *light, int bit, int bitindex
                                                        do
                                                        {
                                                                surf = *mark++;
-                                                               if (surf->visframe != r_framecount || surf->lightframe == lightframe)
+                                                               // if not visible in current frame, or already marked because it was in another leaf we passed, skip
+                                                               if (surf->lightframe == lightframe)
                                                                        continue;
                                                                surf->lightframe = lightframe;
+                                                               if (surf->visframe != r_framecount)
+                                                                       continue;
                                                                dist = PlaneDiff(lightorigin, surf->plane);
                                                                if (surf->flags & SURF_PLANEBACK)
                                                                        dist = -dist;
                                                                // LordHavoc: make sure it is infront of the surface and not too far away
-                                                               if ((dist >= -0.25f || (surf->flags & SURF_LIGHTBOTHSIDES)) && dist < radius)
+                                                               if (dist < radius && (dist > -0.25f || ((surf->flags & SURF_LIGHTBOTHSIDES) && dist > -radius)))
                                                                {
                                                                        int d;
                                                                        float dist2, impact[3];
@@ -405,6 +408,8 @@ void R_PushDlights (void)
 //             R_MarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel->nodes );
                R_VisMarkLights (l->origin, l, 1<<(i&31), i >> 5, cl.worldmodel);
        }
+
+
 }
 
 
@@ -645,6 +650,34 @@ loc0:
                                                lightmap += size3;
                                        }
 
+                                       /*
+                                       // LordHavoc: here's the readable version of the interpolation
+                                       // code, not quite as easy for the compiler to optimize...
+
+                                       // dsfrac is the X position in the lightmap pixel, * 16
+                                       // dtfrac is the Y position in the lightmap pixel, * 16
+                                       // r00 is top left corner, r01 is top right corner
+                                       // r10 is bottom left corner, r11 is bottom right corner
+                                       // g and b are the same layout.
+                                       // r0 and r1 are the top and bottom intermediate results
+
+                                       // first we interpolate the top two points, to get the top
+                                       // edge sample
+                                       r0 = (((r01-r00) * dsfrac) >> 4) + r00;
+                                       g0 = (((g01-g00) * dsfrac) >> 4) + g00;
+                                       b0 = (((b01-b00) * dsfrac) >> 4) + b00;
+                                       // then we interpolate the bottom two points, to get the
+                                       // bottom edge sample
+                                       r1 = (((r11-r10) * dsfrac) >> 4) + r10;
+                                       g1 = (((g11-g10) * dsfrac) >> 4) + g10;
+                                       b1 = (((b11-b10) * dsfrac) >> 4) + b10;
+                                       // then we interpolate the top and bottom samples to get the
+                                       // middle sample (the one which was requested)
+                                       r = (((r1-r0) * dtfrac) >> 4) + r0;
+                                       g = (((g1-g0) * dtfrac) >> 4) + g0;
+                                       b = (((b1-b0) * dtfrac) >> 4) + b0;
+                                       */
+
                                        color[0] += (float) ((((((((r11-r10) * dsfrac) >> 4) + r10)-((((r01-r00) * dsfrac) >> 4) + r00)) * dtfrac) >> 4) + ((((r01-r00) * dsfrac) >> 4) + r00)) * (1.0f / 256.0f);
                                        color[1] += (float) ((((((((g11-g10) * dsfrac) >> 4) + g10)-((((g01-g00) * dsfrac) >> 4) + g00)) * dtfrac) >> 4) + ((((g01-g00) * dsfrac) >> 4) + g00)) * (1.0f / 256.0f);
                                        color[2] += (float) ((((((((b11-b10) * dsfrac) >> 4) + b10)-((((b01-b00) * dsfrac) >> 4) + b00)) * dtfrac) >> 4) + ((((b01-b00) * dsfrac) >> 4) + b00)) * (1.0f / 256.0f);
index b5624af..3256c3b 100644 (file)
--- a/r_part.c
+++ b/r_part.c
@@ -1348,7 +1348,7 @@ void R_DrawParticles (void)
        float                   scale, scale2, minparticledist;
        byte                    *color24;
        vec3_t                  uprightangles, up2, right2, tempcolor, corner;
-       mleaf_t                 *leaf;
+//     mleaf_t                 *leaf;
 
        // LordHavoc: early out condition
        if ((!numparticles) || (!r_drawparticles.value))
@@ -1377,9 +1377,9 @@ void R_DrawParticles (void)
                        continue;
 
                // LordHavoc: check if it's in a visible leaf
-               leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
-               if (leaf->visframe != r_framecount)
-                       continue;
+//             leaf = Mod_PointInLeaf(p->org, cl.worldmodel);
+//             if (leaf->visframe != r_framecount)
+//                     continue;
 
                /*
                if (p->type == pt_decal)
index bdc18f5..27da0a6 100644 (file)
@@ -1,13 +1,82 @@
 #include "quakedef.h"
 
+void R_ClipSpriteImage (entity_t *e, msprite_t *psprite, frameblend_t *blend, vec3_t origin, vec3_t up, vec3_t right)
+{
+       int i;
+       mspriteframe_t *frame;
+       vec3_t points[4];
+       float fleft, fright, fdown, fup;
+       frame = ((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[0].frame;
+       fleft  = frame->left;
+       fdown  = frame->down;
+       fright = frame->right;
+       fup    = frame->up;
+       for (i = 1;i < 4 && blend[i].lerp;i++)
+       {
+               frame = ((mspriteframe_t *)(psprite->ofs_frames + (int) psprite)) + blend[i].frame;
+               fleft  = min(fleft , frame->left );
+               fdown  = min(fdown , frame->down );
+               fright = max(fright, frame->right);
+               fup    = max(fup   , frame->up   );
+       }
+       points[0][0] = origin[0] + fdown * up[0] + fleft  * right[0];points[0][1] = origin[1] + fdown * up[1] + fleft  * right[1];points[0][2] = origin[2] + fdown * up[2] + fleft  * right[2];
+       points[1][0] = origin[0] + fup   * up[0] + fleft  * right[0];points[1][1] = origin[1] + fup   * up[1] + fleft  * right[1];points[1][2] = origin[2] + fup   * up[2] + fleft  * right[2];
+       points[2][0] = origin[0] + fup   * up[0] + fright * right[0];points[2][1] = origin[1] + fup   * up[1] + fright * right[1];points[2][2] = origin[2] + fup   * up[2] + fright * right[2];
+       points[3][0] = origin[0] + fdown * up[0] + fright * right[0];points[3][1] = origin[1] + fdown * up[1] + fright * right[1];points[3][2] = origin[2] + fdown * up[2] + fright * right[2];
+       R_Clip_AddPolygon(&points[0][0], 4, sizeof(float[3]), false, R_Entity_Callback, e, NULL, NULL);
+}
+
+void R_ClipSprite (entity_t *e, frameblend_t *blend)
+{
+       vec3_t right, up, org;
+       msprite_t *psprite;
+
+       if (!blend[0].lerp)
+               return;
+
+       psprite = Mod_Extradata(e->render.model);
+
+       if (psprite->type == SPR_ORIENTED)
+       {
+               // bullet marks on walls
+               vec3_t forward;
+               AngleVectors (e->render.angles, forward, right, up);
+               // nudge it toward the view, so it will be infront of the wall
+               VectorSubtract(e->render.origin, vpn, org);
+               // don't draw if it's a backface
+               if (DotProduct(r_origin, forward) < (DotProduct(org, forward) + 1.0f))
+                       return;
+       }
+       else
+       {
+               // normal sprite
+               VectorCopy(vup, up);
+               VectorCopy(vright, right);
+               VectorCopy(e->render.origin, org);
+               // don't draw if it's a backface
+               if (DotProduct(org, vpn) < (DotProduct(r_origin, vpn) + 1.0f))
+                       return;
+       }
+
+
+       if (e->render.scale != 1)
+       {
+               VectorScale(up, e->render.scale, up);
+               VectorScale(right, e->render.scale, right);
+       }
+
+       // LordHavoc: interpolated sprite rendering
+       R_ClipSpriteImage(e, psprite, blend, org, up, right);
+}
+
 void GL_DrawSpriteImage (mspriteframe_t *frame, vec3_t origin, vec3_t up, vec3_t right, byte red, byte green, byte blue, int alpha)
 {
        byte alphaub;
        alphaub = bound(0, alpha, 255);
        transpolybegin(R_GetTexture(frame->texture), 0, R_GetTexture(frame->fogtexture), currententity->render.effects & EF_ADDITIVE ? TPOLYTYPE_ADD : TPOLYTYPE_ALPHA);
-       transpolyvertub(origin[0] + frame->down * up[0] + frame->left * right[0], origin[1] + frame->down * up[1] + frame->left * right[1], origin[2] + frame->down * up[2] + frame->left * right[2], 0, 1, red, green, blue, alphaub);
-       transpolyvertub(origin[0] + frame->up * up[0] + frame->left * right[0], origin[1] + frame->up * up[1] + frame->left * right[1], origin[2] + frame->up * up[2] + frame->left * right[2], 0, 0, red, green, blue, alphaub);
-       transpolyvertub(origin[0] + frame->up * up[0] + frame->right * right[0], origin[1] + frame->up * up[1] + frame->right * right[1], origin[2] + frame->up * up[2] + frame->right * right[2], 1, 0, red, green, blue, alphaub);
+       transpolyvertub(origin[0] + frame->down * up[0] + frame->left  * right[0], origin[1] + frame->down * up[1] + frame->left  * right[1], origin[2] + frame->down * up[2] + frame->left  * right[2], 0, 1, red, green, blue, alphaub);
+       transpolyvertub(origin[0] + frame->up   * up[0] + frame->left  * right[0], origin[1] + frame->up   * up[1] + frame->left  * right[1], origin[2] + frame->up   * up[2] + frame->left  * right[2], 0, 0, red, green, blue, alphaub);
+       transpolyvertub(origin[0] + frame->up   * up[0] + frame->right * right[0], origin[1] + frame->up   * up[1] + frame->right * right[1], origin[2] + frame->up   * up[2] + frame->right * right[2], 1, 0, red, green, blue, alphaub);
        transpolyvertub(origin[0] + frame->down * up[0] + frame->right * right[0], origin[1] + frame->down * up[1] + frame->right * right[1], origin[2] + frame->down * up[2] + frame->right * right[2], 1, 1, red, green, blue, alphaub);
        transpolyend();
 }
@@ -15,20 +84,22 @@ void GL_DrawSpriteImage (mspriteframe_t *frame, vec3_t origin, vec3_t up, vec3_t
 /*
 =================
 R_DrawSpriteModel
-
 =================
 */
 void R_DrawSpriteModel (entity_t *e, frameblend_t *blend)
 {
-       vec3_t                  right, up, org, color, mins, maxs;
-       byte                    colorub[4];
-       msprite_t               *psprite;
+       vec3_t          right, up, org, color, mins, maxs;
+       byte            colorub[4];
+       msprite_t       *psprite;
+
+       if (!blend[0].lerp)
+               return;
 
        VectorAdd (e->render.origin, e->render.model->mins, mins);
        VectorAdd (e->render.origin, e->render.model->maxs, maxs);
 
-       if (R_VisibleCullBox (mins, maxs))
-               return;
+//     if (R_CullBox (mins, maxs))
+//             return;
 
        c_sprites++;
 
@@ -37,8 +108,11 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend)
 
        if (psprite->type == SPR_ORIENTED)
        {       // bullet marks on walls
-               AngleVectors (e->render.angles, NULL, right, up);
+               vec3_t forward;
+               AngleVectors (e->render.angles, forward, right, up);
                VectorSubtract(e->render.origin, vpn, org);
+               if (DotProduct(r_origin, forward) < DotProduct(e->render.origin, forward))
+                       return; // backface
        }
        else
        {       // normal sprite
@@ -46,6 +120,7 @@ void R_DrawSpriteModel (entity_t *e, frameblend_t *blend)
                VectorCopy(vright, right);
                VectorCopy(e->render.origin, org);
        }
+
        if (e->render.scale != 1)
        {
                VectorScale(up, e->render.scale, up);
index 5d83426..b8f164f 100644 (file)
--- a/render.h
+++ b/render.h
@@ -36,7 +36,7 @@ extern void SHOWLMP_clear(void);
 // render profiling stuff
 extern qboolean intimerefresh;
 extern cvar_t r_speeds2;
-extern char r_speeds2_string1[81], r_speeds2_string2[81], r_speeds2_string3[81], r_speeds2_string4[81], r_speeds2_string5[81], r_speeds2_string6[81], r_speeds2_string7[81];
+extern char r_speeds2_string[1024];
 
 // lighting stuff
 extern vec3_t lightspot;
@@ -54,6 +54,9 @@ extern cvar_t r_novis;
 // model transform stuff
 extern cvar_t gl_transform;
 
+// LordHavoc: 1.0f / N table
+extern float ixtable[4096];
+
 #define        TOP_RANGE               16                      // soldier uniform colors
 #define        BOTTOM_RANGE    96
 
@@ -124,7 +127,7 @@ void R_ViewChanged (vrect_t *pvrect, int lineadj, float aspect); // called whene
 // LordHavoc: changed this for sake of GLQuake
 void R_InitSky (byte *src, int bytesperpixel); // called at level load
 
-int R_VisibleCullBox (vec3_t mins, vec3_t maxs);
+//int R_VisibleCullBox (vec3_t mins, vec3_t maxs);
 
 void R_NewMap (void);
 
@@ -155,3 +158,47 @@ void R_DrawParticles (void);
 void R_MoveParticles (void);
 void R_DrawExplosions (void);
 void R_MoveExplosions (void);
+
+#include "r_clip.h"
+
+// LordHavoc: vertex transform
+#include "transform.h"
+
+// LordHavoc: transparent polygon system
+#include "gl_poly.h"
+
+#define gl_solid_format 3
+#define gl_alpha_format 4
+
+//#define PARANOID
+
+// LordHavoc: was a major time waster
+#define R_CullBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) == 2 || frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) == 2 || frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) == 2 || frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) == 2)
+#define R_NotCulledBox(mins,maxs) (frustum[0].BoxOnPlaneSideFunc(mins, maxs, &frustum[0]) != 2 && frustum[1].BoxOnPlaneSideFunc(mins, maxs, &frustum[1]) != 2 && frustum[2].BoxOnPlaneSideFunc(mins, maxs, &frustum[2]) != 2 && frustum[3].BoxOnPlaneSideFunc(mins, maxs, &frustum[3]) != 2)
+
+extern qboolean fogenabled;
+extern vec3_t fogcolor;
+extern vec_t fogdensity;
+//#define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_origin[0]) * vpn[0] + ((v)[1] - r_origin[1]) * vpn[1] + ((v)[2] - r_origin[2]) * vpn[2])*(((v)[0] - r_origin[0]) * vpn[0] + ((v)[1] - r_origin[1]) * vpn[1] + ((v)[2] - r_origin[2]) * vpn[2]))))
+#define calcfog(v) (exp(-(fogdensity*fogdensity*(((v)[0] - r_origin[0])*((v)[0] - r_origin[0])+((v)[1] - r_origin[1])*((v)[1] - r_origin[1])+((v)[2] - r_origin[2])*((v)[2] - r_origin[2])))))
+#define calcfogbyte(v) ((byte) (bound(0, ((int) ((float) (calcfog((v)) * 255.0f))), 255)))
+
+#include "r_modules.h"
+
+extern qboolean lighthalf;
+
+#include "r_lerpanim.h"
+
+void GL_LockArray(int first, int count);
+void GL_UnlockArray(void);
+
+void R_DrawBrushModel (entity_t *e);
+void R_DrawAliasModel (entity_t *ent, int cull, float alpha, model_t *clmodel, frameblend_t *blend, int skin, vec3_t org, vec3_t angles, vec_t scale, int effects, int flags, int colormap);
+void R_DrawSpriteModel (entity_t *e, frameblend_t *blend);
+
+void R_ClipSprite (entity_t *e, frameblend_t *blend);
+void R_Entity_Callback(void *data, void *junk);
+
+extern cvar_t r_render;
+extern cvar_t r_upload;
+#include "image.h"
index d3551e0..ba04b5b 100644 (file)
@@ -320,7 +320,7 @@ void SNDDMA_Submit(void)
        switch (mmap_control->status.status) {
        case SND_PCM_STATUS_PREPARED:
                if ((rc=snd_pcm_channel_go(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) {
-                       Qprintf(stderr, "unable to start playback. %s\n",
+                       fprintf(stderr, "unable to start playback. %s\n",
                                        snd_strerror(rc));
                        exit(1);
                }
@@ -329,7 +329,7 @@ void SNDDMA_Submit(void)
                break;
        case SND_PCM_STATUS_UNDERRUN:
                if ((rc=snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK))<0) {
-                       Qprintf(stderr, "underrun: playback channel prepare error. %s\n",
+                       fprintf(stderr, "underrun: playback channel prepare error. %s\n",
                                        snd_strerror(rc));
                        exit(1);
                }
index ef29fbf..783e653 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -1392,7 +1392,6 @@ void SV_SpawnServer (char *server)
        ent->v.modelindex = 1;          // world model
        ent->v.solid = SOLID_BSP;
        ent->v.movetype = MOVETYPE_PUSH;
-       ent->v.angles[0] = ent->v.angles[1] = ent->v.angles[2] = 0;
 
        if (coop.value)
                pr_global_struct->coop = coop.value;
@@ -1406,7 +1405,7 @@ void SV_SpawnServer (char *server)
        
        ED_LoadFromFile (sv.worldmodel->entities);
        // LordHavoc: clear world angles (to fix e3m3.bsp)
-       sv.edicts->v.angles[0] = sv.edicts->v.angles[1] = sv.edicts->v.angles[2] = 0;
+       VectorClear(sv.edicts->v.angles);
 
        sv.active = true;
 
index 16405a0..9bf6c21 100644 (file)
--- a/sv_user.c
+++ b/sv_user.c
@@ -260,7 +260,7 @@ void SV_WaterMove (void)
 {
        int             i;
        vec3_t  wishvel;
-       float   speed, newspeed, wishspeed, addspeed, accelspeed;
+       float   speed, newspeed, wishspeed, addspeed, accelspeed, temp;
 
 //
 // user intentions
@@ -278,7 +278,8 @@ void SV_WaterMove (void)
        wishspeed = Length(wishvel);
        if (wishspeed > sv_maxspeed.value)
        {
-               VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
+               temp = sv_maxspeed.value/wishspeed;
+               VectorScale (wishvel, temp, wishvel);
                wishspeed = sv_maxspeed.value;
        }
        wishspeed *= 0.7;
@@ -291,8 +292,9 @@ void SV_WaterMove (void)
        {
                newspeed = speed - sv.frametime * speed * sv_friction.value;
                if (newspeed < 0)
-                       newspeed = 0;   
-               VectorScale (velocity, newspeed/speed, velocity);
+                       newspeed = 0;
+               temp = newspeed/speed;
+               VectorScale (velocity, temp, velocity);
        }
        else
                newspeed = 0;
@@ -339,7 +341,7 @@ void SV_AirMove (void)
 {
        int                     i;
        vec3_t          wishvel;
-       float           fmove, smove;
+       float           fmove, smove, temp;
 
        // LordHavoc: correct quake movement speed bug when looking up/down
        wishvel[0] = wishvel[2] = 0;
@@ -366,7 +368,8 @@ void SV_AirMove (void)
        wishspeed = VectorNormalizeLength(wishdir);
        if (wishspeed > sv_maxspeed.value)
        {
-               VectorScale (wishvel, sv_maxspeed.value/wishspeed, wishvel);
+               temp = sv_maxspeed.value/wishspeed;
+               VectorScale (wishvel, temp, wishvel);
                wishspeed = sv_maxspeed.value;
        }
        
index e886874..6428c17 100644 (file)
@@ -259,11 +259,13 @@ int Sys_FileOpenWrite (char *path)
 
        umask (0);
        
-       handle = open(path,O_RDWR | O_CREAT | O_TRUNC
-       , 0666);
+       handle = open(path,O_RDWR | O_CREAT | O_TRUNC, 0666);
 
        if (handle == -1)
-               Sys_Error ("Error opening %s: %s", path,strerror(errno));
+       {
+               Con_Printf("Sys_FileOpenWrite: Error opening %s: %s", path, strerror(errno));
+               return 0;
+       }
 
        return handle;
 }
index be6021c..1327b35 100644 (file)
--- a/sys_win.c
+++ b/sys_win.c
@@ -152,7 +152,10 @@ int Sys_FileOpenWrite (char *path)
 
        f = Qopen(path, "wb");
        if (!f)
-               Host_Error ("Error opening %s: %s", path,strerror(errno));
+       {
+               Con_Printf("Sys_FileOpenWrite: Error opening %s: %s", path, strerror(errno));
+               return 0;
+       }
        sys_handles[i] = f;
        
        return i;
@@ -338,7 +341,7 @@ double Sys_DoubleTime (void)
        static double oldtime = 0.0, basetime = 0.0, old = 0.0;
        double newtime, now;
 
-       now = (double) timeGetTime () - basetime;
+       now = (double) timeGetTime () + basetime;
 
        if (first)
        {
@@ -350,7 +353,7 @@ double Sys_DoubleTime (void)
        if (now < old)
        {
                // wrapped
-               basetime -= (65536.0 * 65536.0);
+               basetime += (65536.0 * 65536.0);
                now += (65536.0 * 65536.0);
        }
        old = now;
index b4945e1..9396bbe 100644 (file)
@@ -156,3 +156,9 @@ void softwaretransformforentity (entity_t *e)
        angles[2] = e->render.angles[2];
        softwaretransformset(e->render.origin, angles, e->render.scale);
 }
+
+// brush entities are not backwards like models and sprites are
+void softwaretransformforbrushentity (entity_t *e)
+{
+       softwaretransformset(e->render.origin, e->render.angles, e->render.scale);
+}
index 506e5ed..6b0494e 100644 (file)
@@ -11,6 +11,7 @@ extern vec3_t softwaretransform_z;
 extern int softwaretransform_type;
 
 extern void softwaretransformforentity (entity_t *e);
+extern void softwaretransformforbrushentity (entity_t *e);
 extern void softwaretransformidentity (void);
 extern void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale);
 extern void (*softwaretransform) (vec3_t in, vec3_t out);
diff --git a/vid.h b/vid.h
index 174e781..f2757bb 100644 (file)
--- a/vid.h
+++ b/vid.h
@@ -19,12 +19,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
 // vid.h -- video driver defs
 
-#define VID_CBITS      6
-#define VID_GRADES     (1 << VID_CBITS)
-
-// a pixel can be one, two, or four bytes
-typedef byte pixel_t;
-
 typedef struct vrect_s
 {
        int                             x,y,width,height;
@@ -33,12 +27,11 @@ typedef struct vrect_s
 
 typedef struct
 {
-       unsigned                width;          
-       unsigned                height;
-       float                   aspect;         // width / height -- < 0 is taller than wide
-       int                             recalc_refdef;  // if true, recalc vid-based stuff
-       unsigned                conwidth;
-       unsigned                conheight;
+       int             width;          
+       int             height;
+       int             recalc_refdef;  // if true, recalc vid-based stuff
+       int             conwidth;
+       int             conheight;
 } viddef_t;
 
 extern viddef_t        vid;                            // global video state
index 7136f04..6583d37 100644 (file)
@@ -363,8 +363,6 @@ void VID_Init(void)
        vid.width = vid.conwidth;
        vid.height = vid.conheight;
 
-       vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
-
        InitSig(); // trap evil signals
 
        GL_Init();
index 1938a0d..69b8c61 100644 (file)
--- a/vid_glx.c
+++ b/vid_glx.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.
 
@@ -52,16 +52,15 @@ static GLXContext ctx = NULL;
 viddef_t       vid;                            // global video state
 
 static qboolean                mouse_avail = true;
-static qboolean                mouse_active = false;
+static qboolean                mouse_active = false, usingmouse = false;
 // static qboolean             dga_active;
 static float   mouse_x, mouse_y;
 static float   old_mouse_x, old_mouse_y;
 static int p_mouse_x, p_mouse_y;
 
-static cvar_t in_mouse = {"in_mouse", "1", false};
-static cvar_t in_dga = {"in_dga", "1", false};
-static cvar_t in_dga_mouseaccel = {"in_dga_mouseaccel", "1", false};
-static cvar_t m_filter = {"m_filter", "0"};
+cvar_t vid_dga = {"vid_dga", "1", true};
+cvar_t vid_dga_mouseaccel = {"vid_dga_mouseaccel", "1", false};
+cvar_t m_filter = {"m_filter", "0"};
 
 qboolean vidmode_ext = false;
 
@@ -93,7 +92,8 @@ XLateKey(XKeyEvent *ev/*, qboolean modified*/)
 
        keysym = XLookupKeysym(ev, 0);
 
-       switch(keysym) {
+       switch(keysym)
+       {
                case XK_KP_Page_Up:     key = KP_PGUP; break;
                case XK_Page_Up:        key = K_PGUP; break;
 
@@ -176,12 +176,12 @@ XLateKey(XKeyEvent *ev/*, qboolean modified*/)
                case XK_F35:            key = K_PGDN; break;
 
                default:
-                       if (keysym < 128) {
+                       if (keysym < 128)
+                       {
                                /* ASCII keys */
                                key = keysym;
-                               if (/*!modified && */((key >= 'A') && (key <= 'Z'))) {
+                               if (/*!modified && */((key >= 'A') && (key <= 'Z')))
                                        key = key + ('a' - 'A');
-                               }
                        }
                        break;
        }
@@ -191,58 +191,58 @@ XLateKey(XKeyEvent *ev/*, qboolean modified*/)
 
 static Cursor CreateNullCursor(Display *display, Window root)
 {
-    Pixmap cursormask; 
-    XGCValues xgc;
-    GC gc;
-    XColor dummycolour;
-    Cursor cursor;
-
-    cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
-    xgc.function = GXclear;
-    gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
-    XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
-    dummycolour.pixel = 0;
-    dummycolour.red = 0;
-    dummycolour.flags = 04;
-    cursor = XCreatePixmapCursor(display, cursormask, cursormask,
-          &dummycolour,&dummycolour, 0,0);
-    XFreePixmap(display,cursormask);
-    XFreeGC(display,gc);
-    return cursor;
+       Pixmap cursormask;
+       XGCValues xgc;
+       GC gc;
+       XColor dummycolour;
+       Cursor cursor;
+
+       cursormask = XCreatePixmap(display, root, 1, 1, 1/*depth*/);
+       xgc.function = GXclear;
+       gc =  XCreateGC(display, cursormask, GCFunction, &xgc);
+       XFillRectangle(display, cursormask, gc, 0, 0, 1, 1);
+       dummycolour.pixel = 0;
+       dummycolour.red = 0;
+       dummycolour.flags = 04;
+       cursor = XCreatePixmapCursor(display, cursormask, cursormask, &dummycolour,&dummycolour, 0,0);
+       XFreePixmap(display,cursormask);
+       XFreeGC(display,gc);
+       return cursor;
 }
 
 static void install_grabs(void)
 {
-        XWindowAttributes attribs_1;
-        XSetWindowAttributes attribs_2;
+       XWindowAttributes attribs_1;
+       XSetWindowAttributes attribs_2;
 
-        XGetWindowAttributes(dpy, win, &attribs_1);
-        attribs_2.event_mask = attribs_1.your_event_mask | KEY_MASK | MOUSE_MASK;
-        XChangeWindowAttributes(dpy, win, CWEventMask, &attribs_2);
+       XGetWindowAttributes(dpy, win, &attribs_1);
+       attribs_2.event_mask = attribs_1.your_event_mask | KEY_MASK | MOUSE_MASK;
+       XChangeWindowAttributes(dpy, win, CWEventMask, &attribs_2);
 
 // inviso cursor
        XDefineCursor(dpy, win, CreateNullCursor(dpy, win));
 
-       XGrabPointer(dpy, win,  True, 0, GrabModeAsync, GrabModeAsync,
-                    win, None, CurrentTime);
+       XGrabPointer(dpy, win,  True, 0, GrabModeAsync, GrabModeAsync, win, None, CurrentTime);
 
-       if (in_dga.value) {
+       if (vid_dga.value)
+       {
                int MajorVersion, MinorVersion;
 
-               if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 
+               if (!XF86DGAQueryVersion(dpy, &MajorVersion, &MinorVersion))
+               {
                        // unable to query, probalby not supported
                        Con_Printf( "Failed to detect XF86DGA Mouse\n" );
-                       in_dga.value = 0;
-               } else {
-                       in_dga.value = 1;
+                       vid_dga.value = 0;
+               }
+               else
+               {
+                       vid_dga.value = 1;
                        XF86DGADirectVideo(dpy, DefaultScreen(dpy), XF86DGADirectMouse);
                        XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
                }
-       } else {
-               XWarpPointer(dpy, None, win,
-                                        0, 0, 0, 0,
-                                        vid.width / 2, vid.height / 2);
        }
+       else
+               XWarpPointer(dpy, None, win, 0, 0, 0, 0, vid.width / 2, vid.height / 2);
 
        XGrabKeyboard(dpy, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
 
@@ -257,9 +257,8 @@ static void uninstall_grabs(void)
        if (!dpy || !win)
                return;
 
-       if (in_dga.value == 1) {
+       if (vid_dga.value == 1)
                XF86DGADirectVideo(dpy, DefaultScreen(dpy), 0);
-       }
 
        XUngrabPointer(dpy, CurrentTime);
        XUngrabKeyboard(dpy, CurrentTime);
@@ -274,70 +273,108 @@ static void HandleEvents(void)
 {
        XEvent event;
 //     KeySym ks;
-       int b;
        qboolean dowarp = false;
 
        if (!dpy)
                return;
 
-       while (XPending(dpy)) {
+       while (XPending(dpy))
+       {
                XNextEvent(dpy, &event);
 
-               switch (event.type) {
+               switch (event.type)
+               {
                case KeyPress:
                case KeyRelease:
                        Key_Event(XLateKey(&event.xkey), event.type == KeyPress);
                        break;
 
                case MotionNotify:
-                       if (in_dga.value == 1) {
-                               mouse_x += event.xmotion.x_root * in_dga_mouseaccel.value;
-                               mouse_y += event.xmotion.y_root * in_dga_mouseaccel.value;
-                       } else {
-                               if (!p_mouse_x && !p_mouse_y) {
-                                       Con_Printf("event->xmotion.x: %d\n", event.xmotion.x);
-                                       Con_Printf("event->xmotion.y: %d\n", event.xmotion.y);
+                       if (usingmouse)
+                       {
+                               if (vid_dga.value == 1)
+                               {
+                                       mouse_x += event.xmotion.x_root * vid_dga_mouseaccel.value;
+                                       mouse_y += event.xmotion.y_root * vid_dga_mouseaccel.value;
                                }
-                               if (vid_fullscreen.value || vid_mouse.value) {
-                                       if (!event.xmotion.send_event) {
+                               else
+                               {
+                                       /*
+                                       if (!p_mouse_x && !p_mouse_y)
+                                       {
+                                               Con_Printf("event->xmotion.x: %d\n", event.xmotion.x);
+                                               Con_Printf("event->xmotion.y: %d\n", event.xmotion.y);
+                                       }
+                                       */
+                                       //if (usingmouse)
+                                       {
+                                               if (!event.xmotion.send_event)
+                                               {
+                                                       mouse_x += (event.xmotion.x - p_mouse_x);
+                                                       mouse_y += (event.xmotion.y - p_mouse_y);
+                                                       if (abs(vid.width/2 - event.xmotion.x) > vid.width / 4 || abs(vid.height/2 - event.xmotion.y) > vid.height / 4)
+                                                               dowarp = true;
+                                               }
+                                       }
+                                       /*
+                                       else
+                                       {
                                                mouse_x += (event.xmotion.x - p_mouse_x);
                                                mouse_y += (event.xmotion.y - p_mouse_y);
-                                               if (abs(vid.width/2 - event.xmotion.x) > vid.width / 4
-                                               || abs(vid.height/2 - event.xmotion.y) > vid.height / 4) {
-                                                       dowarp = true;
-                                               }
                                        }
-                               } else {
-                                       mouse_x += (event.xmotion.x - p_mouse_x);
-                                       mouse_y += (event.xmotion.y - p_mouse_y);
+                                       */
+                                       p_mouse_x = event.xmotion.x;
+                                       p_mouse_y = event.xmotion.y;
                                }
-                               p_mouse_x = event.xmotion.x;
-                               p_mouse_y = event.xmotion.y;
                        }
                        break;
 
                case ButtonPress:
-                       b=-1;
-                       if (event.xbutton.button == 1)
-                               b = 0;
-                       else if (event.xbutton.button == 2)
-                               b = 2;
-                       else if (event.xbutton.button == 3)
-                               b = 1;
-                       if (b>=0)
-                               Key_Event(K_MOUSE1 + b, true);
+                       switch(event.xbutton.button)
+                       {
+                       case 1:
+                               Key_Event(K_MOUSE1, true);
+                               break;
+                       case 2:
+                               Key_Event(K_MOUSE3, true);
+                               break;
+                       case 3:
+                               Key_Event(K_MOUSE2, true);
+                               break;
+                       case 4:
+                               Key_Event(K_MWHEELUP, true);
+                               break;
+                       case 5:
+                               Key_Event(K_MWHEELDOWN, true);
+                               break;
+               default:
+                               Con_Printf("HandleEvents: ButtonPress gave value %d, 1-5 expected\n", event.xbutton.button);
+                               break;
+                       }
                        break;
 
                case ButtonRelease:
-                       b=-1;
-                       if (event.xbutton.button == 1)
-                               b = 0;
-                       else if (event.xbutton.button == 2)
-                               b = 2;
-                       else if (event.xbutton.button == 3)
-                               b = 1;
-                       if (b>=0)
-                               Key_Event(K_MOUSE1 + b, false);
+                       switch(event.xbutton.button)
+                       {
+                       case 1:
+                               Key_Event(K_MOUSE1, false);
+                               break;
+                       case 2:
+                               Key_Event(K_MOUSE3, false);
+                               break;
+                       case 3:
+                               Key_Event(K_MOUSE2, false);
+                               break;
+                       case 4:
+                               Key_Event(K_MWHEELUP, false);
+                               break;
+                       case 5:
+                               Key_Event(K_MWHEELDOWN, false);
+                               break;
+               default:
+                               Con_Printf("HandleEvents: ButtonRelease gave value %d, 1-5 expected\n", event.xbutton.button);
+                               break;
+                       }
                        break;
 
                case CreateNotify :
@@ -352,7 +389,8 @@ static void HandleEvents(void)
                }
        }
 
-       if (dowarp) {
+       if (dowarp)
+       {
                /* move the mouse to the window center again */
                p_mouse_x = vid.width / 2;
                p_mouse_y = vid.height / 2;
@@ -361,23 +399,25 @@ static void HandleEvents(void)
 
 }
 
-static void IN_DeactivateMouse( void ) 
+static void IN_DeactivateMouse( void )
 {
        if (!mouse_avail || !dpy || !win)
                return;
 
-       if (mouse_active) {
+       if (mouse_active)
+       {
                uninstall_grabs();
                mouse_active = false;
        }
 }
 
-static void IN_ActivateMouse( void ) 
+static void IN_ActivateMouse( void )
 {
        if (!mouse_avail || !dpy || !win)
                return;
 
-       if (!mouse_active) {
+       if (!mouse_active)
+       {
                mouse_x = mouse_y = 0; // don't spazz
                install_grabs();
                mouse_active = true;
@@ -390,7 +430,8 @@ void VID_Shutdown(void)
        if (!ctx || !dpy)
                return;
 
-       if (dpy) {
+       if (dpy)
+       {
                uninstall_grabs();
 
                if (vidmode_active)
@@ -430,7 +471,7 @@ void InitSig(void)
        signal(SIGTERM, signal_handler);
 }
 
-void VID_CheckMultitexture(void) 
+void VID_CheckMultitexture(void)
 {
        void *prjobj;
        qglMTexCoord2f = NULL;
@@ -512,10 +553,34 @@ void GL_BeginRendering (int *x, int *y, int *width, int *height)
 
 void GL_EndRendering (void)
 {
+       int usemouse;
        if (!r_render.value)
                return;
        glFlush();
        glXSwapBuffers(dpy, win);
+
+// handle the mouse state when windowed if that's changed
+       usemouse = false;
+       if (vid_mouse.value && key_dest == key_game)
+               usemouse = true;
+       if (vidmode_active)
+               usemouse = true;
+       if (usemouse)
+       {
+               if (!usingmouse)
+               {
+                       usingmouse = true;
+                       IN_ActivateMouse ();
+               }
+       }
+       else
+       {
+               if (usingmouse)
+               {
+                       usingmouse = false;
+                       IN_DeactivateMouse ();
+               }
+       }
 }
 
 int VID_SetGamma(float prescale, float gamma, float scale, float base)
@@ -526,7 +591,8 @@ int VID_SetGamma(float prescale, float gamma, float scale, float base)
 void VID_Init(void)
 {
        int i;
-       int attrib[] = {
+       int attrib[] =
+       {
                GLX_RGBA,
                GLX_RED_SIZE, 1,
                GLX_GREEN_SIZE, 1,
@@ -545,11 +611,11 @@ void VID_Init(void)
        int MajorVersion, MinorVersion;
        int actualWidth, actualHeight;
 
-       Cvar_RegisterVariable (&in_mouse);
-       Cvar_RegisterVariable (&in_dga);
-       Cvar_RegisterVariable (&in_dga_mouseaccel);
+       Cvar_RegisterVariable (&vid_mouse);
+       Cvar_RegisterVariable (&vid_dga);
+       Cvar_RegisterVariable (&vid_dga_mouseaccel);
        Cvar_RegisterVariable (&m_filter);
-       
+
 // interpret command-line params
 
 // set vid parameters
@@ -580,7 +646,8 @@ void VID_Init(void)
        if (vid.conheight < 200)
                vid.conheight = 200;
 
-       if (!(dpy = XOpenDisplay(NULL))) {
+       if (!(dpy = XOpenDisplay(NULL)))
+       {
                fprintf(stderr, "Error couldn't open the X display\n");
                exit(1);
        }
@@ -590,44 +657,50 @@ void VID_Init(void)
 
        // Get video mode list
        MajorVersion = MinorVersion = 0;
-       if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion)) { 
+       if (!XF86VidModeQueryVersion(dpy, &MajorVersion, &MinorVersion))
                vidmode_ext = false;
-       } else {
+       else
+       {
                Con_Printf("Using XFree86-VidModeExtension Version %d.%d\n", MajorVersion, MinorVersion);
                vidmode_ext = true;
        }
 
        visinfo = glXChooseVisual(dpy, scrnum, attrib);
-       if (!visinfo) {
+       if (!visinfo)
+       {
                fprintf(stderr, "qkHack: Error couldn't get an RGB, Double-buffered, Depth visual\n");
                exit(1);
        }
 
-       if (vidmode_ext) {
+       if (vidmode_ext)
+       {
                int best_fit, best_dist, dist, x, y;
-               
+
                XF86VidModeGetAllModeLines(dpy, scrnum, &num_vidmodes, &vidmodes);
 
                // Are we going fullscreen?  If so, let's change video mode
-               if (fullscreen) {
+               if (fullscreen)
+               {
                        best_dist = 9999999;
                        best_fit = -1;
 
-                       for (i = 0; i < num_vidmodes; i++) {
-                               if (width > vidmodes[i]->hdisplay ||
-                                       height > vidmodes[i]->vdisplay)
+                       for (i = 0; i < num_vidmodes; i++)
+                       {
+                               if (width > vidmodes[i]->hdisplay || height > vidmodes[i]->vdisplay)
                                        continue;
 
                                x = width - vidmodes[i]->hdisplay;
                                y = height - vidmodes[i]->vdisplay;
                                dist = (x * x) + (y * y);
-                               if (dist < best_dist) {
+                               if (dist < best_dist)
+                               {
                                        best_dist = dist;
                                        best_fit = i;
                                }
                        }
 
-                       if (best_fit != -1) {
+                       if (best_fit != -1)
+                       {
                                actualWidth = vidmodes[best_fit]->hdisplay;
                                actualHeight = vidmodes[best_fit]->vdisplay;
 
@@ -637,7 +710,8 @@ void VID_Init(void)
 
                                // Move the viewport to top left
                                XF86VidModeSetViewPort(dpy, scrnum, 0, 0);
-                       } else
+                       }
+                       else
                                fullscreen = 0;
                }
        }
@@ -647,21 +721,22 @@ void VID_Init(void)
        attr.border_pixel = 0;
        attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone);
        attr.event_mask = X_MASK;
-       if (vidmode_active) {
-               mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | 
-                       CWEventMask | CWOverrideRedirect;
+       if (vidmode_active)
+       {
+               mask = CWBackPixel | CWColormap | CWSaveUnder | CWBackingStore | CWEventMask | CWOverrideRedirect;
                attr.override_redirect = True;
                attr.backing_store = NotUseful;
                attr.save_under = False;
-       } else
+       }
+       else
                mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
 
-       win = XCreateWindow(dpy, root, 0, 0, width, height,
-                                               0, visinfo->depth, InputOutput,
-                                               visinfo->visual, mask, &attr);
+       win = XCreateWindow(dpy, root, 0, 0, width, height, 0, visinfo->depth, InputOutput, visinfo->visual, mask, &attr);
+       XStoreName(dpy, win, "DarkPlaces-GLX");
        XMapWindow(dpy, win);
 
-       if (vidmode_active) {
+       if (vidmode_active)
+       {
                XMoveWindow(dpy, win, 0, 0);
                XRaiseWindow(dpy, win);
                XWarpPointer(dpy, None, win, 0, 0, 0, 0, 0, 0);
@@ -686,17 +761,14 @@ void VID_Init(void)
        vid.width = vid.conwidth;
        vid.height = vid.conheight;
 
-       vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
-
        InitSig(); // trap evil signals
 
        GL_Init();
 
        Con_SafePrintf ("Video mode %dx%d initialized.\n", width, height);
 
-       vid.recalc_refdef = 1;                          // force a surface cache flush
-
-       install_grabs();
+       // force a surface cache flush
+       vid.recalc_refdef = 1;
 }
 
 void Sys_SendKeyEvents(void)
@@ -724,13 +796,6 @@ IN_Commands
 */
 void IN_Commands (void)
 {
-       if (!dpy || !win)
-               return;
-
-       if (vidmode_active || key_dest == key_game)
-               IN_ActivateMouse();
-       else
-               IN_DeactivateMouse ();
 }
 
 /*
@@ -743,38 +808,39 @@ void IN_MouseMove (usercmd_t *cmd)
        if (!mouse_avail)
                return;
 
-        if (!mouse_avail)
-                return;
-
-        if (m_filter.value) {
-                mouse_x = (mouse_x + old_mouse_x) * 0.5;
-                mouse_y = (mouse_y + old_mouse_y) * 0.5;
-
-                old_mouse_x = mouse_x;
-                old_mouse_y = mouse_y;
-        }
-
-        mouse_x *= sensitivity.value;
-        mouse_y *= sensitivity.value;
-        
-        if (in_strafe.state & 1)
-                cmd->sidemove += m_side.value * mouse_x;
-        else
-                cl.viewangles[YAW] -= m_yaw.value * mouse_x;
-                
-/*        if (freelook)*/
-                V_StopPitchDrift ();
-
-        if (/*freelook && */!(in_strafe.state & 1)) {
-                cl.viewangles[PITCH] += m_pitch.value * mouse_y;
-                cl.viewangles[PITCH] = bound (-70, cl.viewangles[PITCH], 80);
-        } else {
-                if ((in_strafe.state & 1) && noclip_anglehack)
-                        cmd->upmove -= m_forward.value * mouse_y;
-                else
-                        cmd->forwardmove -= m_forward.value * mouse_y;
-        }
-        mouse_x = mouse_y = 0.0;
+       if (m_filter.value)
+       {
+               mouse_x = (mouse_x + old_mouse_x) * 0.5;
+               mouse_y = (mouse_y + old_mouse_y) * 0.5;
+
+               old_mouse_x = mouse_x;
+               old_mouse_y = mouse_y;
+       }
+
+       mouse_x *= sensitivity.value;
+       mouse_y *= sensitivity.value;
+
+       if (in_strafe.state & 1)
+               cmd->sidemove += m_side.value * mouse_x;
+       else
+               cl.viewangles[YAW] -= m_yaw.value * mouse_x;
+
+       //if (freelook)
+               V_StopPitchDrift ();
+
+       if (/*freelook && */!(in_strafe.state & 1))
+       {
+               cl.viewangles[PITCH] += m_pitch.value * mouse_y;
+               cl.viewangles[PITCH] = bound (-70, cl.viewangles[PITCH], 80);
+       }
+       else
+       {
+               if ((in_strafe.state & 1) && noclip_anglehack)
+                       cmd->upmove -= m_forward.value * mouse_y;
+               else
+                       cmd->forwardmove -= m_forward.value * mouse_y;
+       }
+       mouse_x = mouse_y = 0.0;
 }
 
 void IN_Move (usercmd_t *cmd)
diff --git a/view.c b/view.c
index 5b0da1e..c14f960 100644 (file)
--- a/view.c
+++ b/view.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.
 
@@ -742,99 +742,105 @@ void V_CalcRefdef (void)
        ent = &cl_entities[cl.viewentity];
 // view is the weapon model (only visible from inside body)
        view = &cl.viewent;
-       
 
-// transform the view offset by the model's matrix to get the offset from model origin for the view
-       if (!chase_active.value) // LordHavoc: get rid of angle problems in chase_active mode
+
+       if (chase_active.value)
        {
-               ent->render.angles[YAW] = cl.viewangles[YAW];   // the model should face the view dir
-               ent->render.angles[PITCH] = -cl.viewangles[PITCH];      // the model should face the view dir
+               VectorCopy (ent->render.origin, r_refdef.vieworg);
+               VectorCopy (cl.viewangles, r_refdef.viewangles);
+               Chase_Update ();
+               V_AddIdle ();
        }
-                                                                               
-       
-       bob = V_CalcBob ();
-       
-// refresh position
-       VectorCopy (ent->render.origin, r_refdef.vieworg);
-       r_refdef.vieworg[2] += cl.viewheight + bob;
+       else
+       {
+       // transform the view offset by the model's matrix to get the offset from model origin for the view
+       //      if (!chase_active.value) // LordHavoc: get rid of angle problems in chase_active mode
+       //      {
+       //              ent->render.angles[YAW] = cl.viewangles[YAW];   // the model should face the view dir
+       //              ent->render.angles[PITCH] = -cl.viewangles[PITCH];      // the model should face the view dir
+       //      }
 
-       // LordHavoc: the protocol has changed...  so this is an obsolete approach
-// never let it sit exactly on a node line, because a water plane can
-// dissapear when viewed with the eye exactly on it.
-// the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
-//     r_refdef.vieworg[0] += 1.0/32;
-//     r_refdef.vieworg[1] += 1.0/32;
-//     r_refdef.vieworg[2] += 1.0/32;
+               bob = V_CalcBob ();
 
-       if (!intimerefresh)
-               VectorCopy (cl.viewangles, r_refdef.viewangles);
-       V_CalcViewRoll ();
-       V_AddIdle ();
+       // refresh position
+               VectorCopy (ent->render.origin, r_refdef.vieworg);
+               r_refdef.vieworg[2] += cl.viewheight + bob;
 
-// offsets
-       angles[PITCH] = -ent->render.angles[PITCH];     // because entity pitches are actually backward
-       angles[YAW] = ent->render.angles[YAW];
-       angles[ROLL] = ent->render.angles[ROLL];
+               // LordHavoc: the protocol has changed...  so this is an obsolete approach
+       // never let it sit exactly on a node line, because a water plane can
+       // dissapear when viewed with the eye exactly on it.
+       // the server protocol only specifies to 1/16 pixel, so add 1/32 in each axis
+       //      r_refdef.vieworg[0] += 1.0/32;
+       //      r_refdef.vieworg[1] += 1.0/32;
+       //      r_refdef.vieworg[2] += 1.0/32;
 
-       AngleVectors (angles, forward, NULL, NULL);
+               if (!intimerefresh)
+                       VectorCopy (cl.viewangles, r_refdef.viewangles);
+               V_CalcViewRoll ();
+               V_AddIdle ();
 
-       V_BoundOffsets ();
-               
-// set up gun position
-       VectorCopy (cl.viewangles, view->render.angles);
-       
-       CalcGunAngle ();
+       // offsets
+               angles[PITCH] = -ent->render.angles[PITCH];     // because entity pitches are actually backward
+               angles[YAW] = ent->render.angles[YAW];
+               angles[ROLL] = ent->render.angles[ROLL];
 
-       VectorCopy (ent->render.origin, view->render.origin);
-       view->render.origin[2] += cl.viewheight;
+               AngleVectors (angles, forward, NULL, NULL);
 
-       for (i=0 ; i<3 ; i++)
-       {
-               view->render.origin[i] += forward[i]*bob*0.4;
-//             view->render.origin[i] += right[i]*bob*0.4;
-//             view->render.origin[i] += up[i]*bob*0.8;
-       }
-       view->render.origin[2] += bob;
+               V_BoundOffsets ();
 
-       view->render.model = cl.model_precache[cl.stats[STAT_WEAPON]];
-       view->render.frame = cl.stats[STAT_WEAPONFRAME];
-       view->render.colormap = -1; // no special coloring
+       // set up gun position
+               VectorCopy (cl.viewangles, view->render.angles);
 
-// set up the refresh position
+               CalcGunAngle ();
 
-       // LordHavoc: this never looked all that good to begin with...
-       /*
-// smooth out stair step ups
-if (cl.onground && ent->render.origin[2] - oldz > 0)
-{
-       float steptime;
-       
-       steptime = cl.time - cl.oldtime;
-       if (steptime < 0)
-//FIXME                I_Error ("steptime < 0");
-               steptime = 0;
+               VectorCopy (ent->render.origin, view->render.origin);
+               view->render.origin[2] += cl.viewheight;
 
-       oldz += steptime * 80;
-       if (oldz > ent->render.origin[2])
-               oldz = ent->render.origin[2];
-       if (ent->render.origin[2] - oldz > 12)
-               oldz = ent->render.origin[2] - 12;
-       r_refdef.vieworg[2] += oldz - ent->render.origin[2];
-       view->render.origin[2] += oldz - ent->render.origin[2];
-}
-else
-       oldz = ent->render.origin[2];
-       */
+               for (i=0 ; i<3 ; i++)
+               {
+                       view->render.origin[i] += forward[i]*bob*0.4;
+       //              view->render.origin[i] += right[i]*bob*0.4;
+       //              view->render.origin[i] += up[i]*bob*0.8;
+               }
+               view->render.origin[2] += bob;
+
+               view->render.model = cl.model_precache[cl.stats[STAT_WEAPON]];
+               view->render.frame = cl.stats[STAT_WEAPONFRAME];
+               view->render.colormap = -1; // no special coloring
 
-// LordHavoc: origin view kick added
-       if (!intimerefresh && v_punch.value)
+       // set up the refresh position
+
+               // LordHavoc: this never looked all that good to begin with...
+               /*
+       // smooth out stair step ups
+       if (cl.onground && ent->render.origin[2] - oldz > 0)
        {
-               VectorAdd(r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);
-               VectorAdd(r_refdef.vieworg, cl.punchvector, r_refdef.vieworg);
+               float steptime;
+
+               steptime = cl.time - cl.oldtime;
+               if (steptime < 0)
+       //FIXME         I_Error ("steptime < 0");
+                       steptime = 0;
+
+               oldz += steptime * 80;
+               if (oldz > ent->render.origin[2])
+                       oldz = ent->render.origin[2];
+               if (ent->render.origin[2] - oldz > 12)
+                       oldz = ent->render.origin[2] - 12;
+               r_refdef.vieworg[2] += oldz - ent->render.origin[2];
+               view->render.origin[2] += oldz - ent->render.origin[2];
        }
+       else
+               oldz = ent->render.origin[2];
+               */
 
-       if (chase_active.value)
-               Chase_Update ();
+       // LordHavoc: origin view kick added
+               if (!intimerefresh && v_punch.value)
+               {
+                       VectorAdd(r_refdef.viewangles, cl.punchangle, r_refdef.viewangles);
+                       VectorAdd(r_refdef.vieworg, cl.punchvector, r_refdef.vieworg);
+               }
+       }
 }
 
 /*
diff --git a/wad.c b/wad.c
index 1a5ab0a..241c065 100644 (file)
--- a/wad.c
+++ b/wad.c
@@ -183,7 +183,7 @@ void W_LoadTextureWadFile (char *filename, int complain)
        QFile                   *file;
        int                             numlumps;
        
-       COM_FOpenFile (filename, &file, false, true);
+       COM_FOpenFile (filename, &file, false, false);
        if (!file)
        {
                if (complain)
diff --git a/world.c b/world.c
index 0409d61..dba8fe9 100644 (file)
--- a/world.c
+++ b/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.
 
@@ -29,6 +29,55 @@ line of sight checks trace->crosscontent, but bullets don't
 
 */
 
+/*
+typedef struct link_s
+{
+       struct link_s   *prev, *next;
+} link_t;
+*/
+
+
+void ClearLink (link_t *l);
+void RemoveLink (link_t *l);
+void InsertLinkBefore (link_t *l, link_t *before);
+void InsertLinkAfter (link_t *l, link_t *after);
+
+// (type *)STRUCT_FROM_LINK(link_t *link, type, member)
+// ent = STRUCT_FROM_LINK(link,entity_t,order)
+// FIXME: remove this mess!
+//#define      STRUCT_FROM_LINK(l,t,m) ((t *)((byte *)l - (int)&(((t *)0)->m)))
+
+#define        EDICT_FROM_AREA(l) ((edict_t *)((byte *)l - (int)&(((edict_t *)0)->area)))
+
+//============================================================================
+
+// ClearLink is used for new headnodes
+void ClearLink (link_t *l)
+{
+       l->prev = l->next = l;
+}
+
+void RemoveLink (link_t *l)
+{
+       l->next->prev = l->prev;
+       l->prev->next = l->next;
+}
+
+void InsertLinkBefore (link_t *l, link_t *before)
+{
+       l->next = before;
+       l->prev = before->prev;
+       l->prev->next = l;
+       l->next->prev = l;
+}
+void InsertLinkAfter (link_t *l, link_t *after)
+{
+       l->next = after->next;
+       l->prev = after;
+       l->prev->next = l;
+       l->next->prev = l;
+}
+
 
 typedef struct
 {
@@ -183,7 +232,7 @@ hull_t *SV_HullForEntity (edict_t *ent, vec3_t mins, vec3_t maxs, vec3_t offset)
                VectorSubtract (ent->v.mins, maxs, hullmins);
                VectorSubtract (ent->v.maxs, mins, hullmaxs);
                hull = SV_HullForBox (hullmins, hullmaxs);
-               
+
                VectorCopy (ent->v.origin, offset);
        }
 
@@ -231,28 +280,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);
 
@@ -268,7 +317,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);
@@ -312,11 +361,11 @@ loc0:
                if (!touch->v.touch || touch->v.solid != SOLID_TRIGGER)
                        continue;
                if (ent->v.absmin[0] > touch->v.absmax[0]
-               || ent->v.absmin[1] > touch->v.absmax[1]
-               || ent->v.absmin[2] > touch->v.absmax[2]
-               || ent->v.absmax[0] < touch->v.absmin[0]
-               || ent->v.absmax[1] < touch->v.absmin[1]
-               || ent->v.absmax[2] < touch->v.absmin[2] )
+                || ent->v.absmin[1] > touch->v.absmax[1]
+                || ent->v.absmin[2] > touch->v.absmax[2]
+                || ent->v.absmax[0] < touch->v.absmin[0]
+                || ent->v.absmax[1] < touch->v.absmin[1]
+                || ent->v.absmax[2] < touch->v.absmin[2])
                        continue;
                old_self = pr_global_struct->self;
                old_other = pr_global_struct->other;
@@ -329,11 +378,11 @@ loc0:
                pr_global_struct->self = old_self;
                pr_global_struct->other = old_other;
        }
-       
+
 // recurse down both sides
        if (node->axis == -1)
                return;
-       
+
        // LordHavoc: optimized recursion
 //     if (ent->v.absmax[node->axis] > node->dist) SV_TouchLinks (ent, node->children[0]);
 //     if (ent->v.absmin[node->axis] < node->dist) SV_TouchLinks (ent, node->children[1]);
@@ -363,15 +412,10 @@ SV_FindTouchedLeafs
 */
 void SV_FindTouchedLeafs (edict_t *ent, mnode_t *node)
 {
-       mplane_t        *splitplane;
-       mleaf_t         *leaf;
-       int                     sides;
-       int                     leafnum;
-
 loc0:
        if (node->contents == CONTENTS_SOLID)
                return;
-       
+
 // add an efrag if the node is a leaf
 
        if ( node->contents < 0)
@@ -382,24 +426,18 @@ loc0:
                        return;
                }
 
-               leaf = (mleaf_t *)node;
-               leafnum = leaf - sv.worldmodel->leafs - 1;
-
-               ent->leafnums[ent->num_leafs] = leafnum;
-               ent->num_leafs++;                       
+               ent->leafnums[ent->num_leafs++] = (mleaf_t *)node - sv.worldmodel->leafs - 1;
                return;
        }
-       
-// NODE_MIXED
 
-       splitplane = node->plane;
-       sides = BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, splitplane);
-       
 // recurse down the contacted sides
-       // LordHavoc: optimized recursion
+
+//     sides = BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, node->plane);
 //     if (sides & 1) SV_FindTouchedLeafs (ent, node->children[0]);
 //     if (sides & 2) SV_FindTouchedLeafs (ent, node->children[1]);
-       switch (sides)
+
+       // LordHavoc: optimized recursion
+       switch (BOX_ON_PLANE_SIDE(ent->v.absmin, ent->v.absmax, node->plane))
        {
        case 1:
                node = node->children[0];
@@ -438,7 +476,8 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
 
 // LordHavoc: enabling rotating bmodels
        if (ent->v.solid == SOLID_BSP && (ent->v.angles[0] || ent->v.angles[1] || ent->v.angles[2]))
-       {       // expand for rotation
+       {
+               // expand for rotation
                float           max, v;
                int                     i;
 
@@ -467,7 +506,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
        }
        else
        {
-               VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);  
+               VectorAdd (ent->v.origin, ent->v.mins, ent->v.absmin);
                VectorAdd (ent->v.origin, ent->v.maxs, ent->v.absmax);
        }
 
@@ -483,7 +522,8 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                ent->v.absmax[1] += 15;
        }
        else
-       {       // because movement is clipped an epsilon away from an actual edge,
+       {
+               // because movement is clipped an epsilon away from an actual edge,
                // we must fully check even when bounding boxes don't quite touch
                ent->v.absmin[0] -= 1;
                ent->v.absmin[1] -= 1;
@@ -515,13 +555,13 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers)
                        break;          // crosses the node
        }
 
-// link it in  
+// link it in
 
        if (ent->v.solid == SOLID_TRIGGER)
                InsertLinkBefore (&ent->area, &node->trigger_edicts);
        else
                InsertLinkBefore (&ent->area, &node->solid_edicts);
-       
+
 // if touch_triggers, touch all entities at this node and descend for more
        if (touch_triggers)
                SV_TouchLinks ( ent, sv_areanodes );
@@ -547,7 +587,7 @@ int SV_HullPointContents (hull_t *hull, int num, vec3_t p)
 {
        while (num >= 0)
                num = hull->clipnodes[num].children[(hull->planes[hull->clipnodes[num].planenum].type < 3 ? p[hull->planes[hull->clipnodes[num].planenum].type] : DotProduct (hull->planes[hull->clipnodes[num].planenum].normal, p)) < hull->planes[hull->clipnodes[num].planenum].dist];
-       
+
        return num;
 }
 
@@ -563,7 +603,7 @@ 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;
                
@@ -1031,14 +1071,14 @@ loc0:
                        continue;
 
                if (clip->boxmins[0] > touch->v.absmax[0]
-               || clip->boxmins[1] > touch->v.absmax[1]
-               || clip->boxmins[2] > touch->v.absmax[2]
-               || clip->boxmaxs[0] < touch->v.absmin[0]
-               || clip->boxmaxs[1] < touch->v.absmin[1]
-               || clip->boxmaxs[2] < touch->v.absmin[2] )
+                || clip->boxmins[1] > touch->v.absmax[1]
+                || clip->boxmins[2] > touch->v.absmax[2]
+                || clip->boxmaxs[0] < touch->v.absmin[0]
+                || clip->boxmaxs[1] < touch->v.absmin[1]
+                || clip->boxmaxs[2] < touch->v.absmin[2])
                        continue;
 
-               if (clip->passedict!=0 && clip->passedict->v.size[0] && !touch->v.size[0])
+               if (clip->passedict != NULL && clip->passedict->v.size[0] && !touch->v.size[0])
                        continue;       // points never interact
 
        // might intersect, so do an exact clip
@@ -1075,7 +1115,7 @@ loc0:
                else if (trace.startsolid)
                        clip->trace.startsolid = true;
        }
-       
+
 // recurse down both sides
        if (node->axis == -1)
                return;