shithub: duke3d

Download patch

ref: e11e7cb42d1762154194fc58eb200dd0fe1c47bd
parent: 99f04725a106190feb2f923ebbc555bfefc277ef
author: Fabien Sanglard <[email protected]>
date: Wed Dec 12 23:47:24 EST 2012

Added comment for Visible Surface Determination

--- a/Engine/src/a.c
+++ b/Engine/src/a.c
@@ -201,7 +201,7 @@
     if (i3 == 0)
     {
 		if (!RENDER_DRAW_TOP_AND_BOTTOM_COLUMN)
-		return;
+		return 0;
 
 	    i1 += i4;
         //FCS
@@ -226,7 +226,7 @@
     unsigned char *dest = (unsigned char *)i6;
 
     if (!RENDER_DRAW_WALL_BORDERS)
-		return;
+		return vplce;
 
     i3++;
     while (i3)
--- a/Engine/src/build.h
+++ b/Engine/src/build.h
@@ -311,14 +311,16 @@
 
 //FCS: In order to see how the engine renders different part of the screen you can set the following macros
 //VISUALIZE RENDERER
-#define RENDER_DRAW_WALL_BORDERS 0
-#define RENDER_DRAW_WALL_INSIDE 0
-#define RENDER_DRAW_CEILING_AND_FLOOR 0
+#define RENDER_DRAW_WALL_BORDERS 1
+#define RENDER_DRAW_WALL_INSIDE 1
+#define RENDER_DRAW_CEILING_AND_FLOOR 1
 #define RENDER_DRAW_TOP_AND_BOTTOM_COLUMN 1
-#define RENDER_SLOPPED_CEILING_AND_FLOOR 0
+#define RENDER_SLOPPED_CEILING_AND_FLOOR 1
 
-#if RENDER_DRAW_WALL_BORDERS || RENDER_DRAW_WALL_INSIDE || RENDER_DRAW_CEILING_AND_FLOOR || RENDER_DRAW_TOP_AND_BOTTOM_COLUMN || RENDER_SLOPPED_CEILING_AND_FLOOR
-#define CLEAR_FRAMEBUFFER 1
+#if RENDER_DRAW_WALL_BORDERS && RENDER_DRAW_WALL_INSIDE && RENDER_DRAW_CEILING_AND_FLOOR  && RENDER_DRAW_TOP_AND_BOTTOM_COLUMN && RENDER_SLOPPED_CEILING_AND_FLOOR
+   #define CLEAR_FRAMEBUFFER 0
+#else
+   #define CLEAR_FRAMEBUFFER 1
 #endif
 //END VISUALIZE RENDERER
 
--- a/Engine/src/engine.c
+++ b/Engine/src/engine.c
@@ -228,7 +228,10 @@
 long globalx1, globaly1, globalx2, globaly2, globalx3, globaly3, globalzx;
 long globalx, globaly, globalz;
 
+//Those two variables are using during portal flooding:
+// sectorBorder is the stack and sectorbordercnt is the stack counter.
 static short sectorborder[256], sectorbordercnt;
+
 static char tablesloaded = 0;
 long pageoffset, ydim16, qsetmode = 0;
 long startposx, startposy, startposz;
@@ -339,7 +342,10 @@
 	return((D<<24)|((D<<8)&0x00FF0000)|((D>>8)&0x0000FF00)|(D>>24));
 }
 
-
+/*
+     FCS: Scan through sectors using portals (a portal is wall with a nextwall attribute != -1).
+          Flood is prevented if a portal does not face the POV.
+ */
 static void scansector (short sectnum)
 {
 	walltype *wal, *wal2;
@@ -357,6 +363,7 @@
 	{
 		sectnum = sectorborder[--sectorbordercnt];
 
+        //Add every script in the current sector as potentially visible.
 		for(z=headspritesect[sectnum];z>=0;z=nextspritesect[z])
 		{
 			spr = &sprite[z];
@@ -373,6 +380,7 @@
 			}
 		}
 
+        //Mark the current sector as "visited"
 		gotsector[sectnum>>3] |= pow2char[sectnum&7];
 
 		bunchfrst = numbunches;
@@ -386,35 +394,53 @@
 			nextsectnum = wal->nextsector;
 
 			wal2 = &wall[wal->point2];
+            
+            // In camera space the center is the player.
+            // Make the camrea the center of the world: Wall coordinates
 			x1 = wal->x-globalposx; y1 = wal->y-globalposy;
 			x2 = wal2->x-globalposx; y2 = wal2->y-globalposy;
 
+            // If this is a portal...
 			if ((nextsectnum >= 0) && ((wal->cstat&32) == 0))
+                //If this portal has not been visited.
 				if ((gotsector[nextsectnum>>3]&pow2char[nextsectnum&7]) == 0)
 				{
 					templong = x1*y2-x2*y1;
+                    
+                    // Using cross product, determine if the portal is facing us or not.
+                    // If it is: Add it to the stack and bump the stack counter.
 					if (((unsigned)templong+262144) < 524288)
 						if (mulscale5(templong,templong) <= (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1))
 							sectorborder[sectorbordercnt++] = nextsectnum;
 				}
 
+            // Rotate the wall endpoint position according to the player orientation.
+            // This is a regular rotation matrix using [29.3] fixed point.
 			if ((z == startwall) || (wall[z-1].point2 != z))
 			{
+                //If this is the first endpoint of the bunch, rotate
 				xp1 = dmulscale6(y1,cosglobalang,-x1,singlobalang);
 				yp1 = dmulscale6(x1,cosviewingrangeglobalang,y1,sinviewingrangeglobalang);
 			}
 			else
 			{
+                //If this is NOT the first endpoint, Save the coordinate for next loop.
 				xp1 = xp2;
 				yp1 = yp2;
 			}
-			xp2 = dmulscale6(y2,cosglobalang,-x2,singlobalang);
-			yp2 = dmulscale6(x2,cosviewingrangeglobalang,y2,sinviewingrangeglobalang);
+			    xp2 = dmulscale6(y2,cosglobalang,-x2,singlobalang);
+			    yp2 = dmulscale6(x2,cosviewingrangeglobalang,y2,sinviewingrangeglobalang);
+            
+            
+            
+            // No idea what this is.
 			if ((yp1 < 256) && (yp2 < 256)) goto skipitaddwall;
 
-				/* If wall's NOT facing you */
+            /* If wall's NOT facing you */
 			if (dmulscale32(xp1,yp2,-xp2,yp1) >= 0) goto skipitaddwall;
 
+            // The wall is still not eligible for rendition: Let's do some more Frustrum culling !!
+            
 			if (xp1 >= -yp1)
 			{
 				if ((xp1 > yp1) || (yp1 == 0)) goto skipitaddwall;
@@ -463,15 +489,18 @@
 				p2[numscans-1] = scanfirst, scanfirst = numscans;
 		}
 
+        //FCS: TODO rename this p2[]. This name is an abomination
 		for(z=numscansbefore;z<numscans;z++)
 			if ((wall[thewall[z]].point2 != thewall[p2[z]]) || (xb2[z] >= xb1[p2[z]]))
 				bunchfirst[numbunches++] = p2[z], p2[z] = -1;
 
+        //For each bunch, cache the last wall of the bunch in bunchlast.
 		for(z=bunchfrst;z<numbunches;z++)
 		{
 			for(zz=bunchfirst[z];p2[zz]>=0;zz=p2[zz]);
 			bunchlast[z] = zz;
 		}
+    
 	} while (sectorbordercnt > 0);
 }
 
@@ -2395,6 +2424,7 @@
 			if (j == 0) tempbuf[closest] = 1, closest = i, i = 0;
 		}
 
+        //Draw every solid walls in the bunch "closest"
 		drawalls(closest);
 
 		if (automapping)
@@ -3917,11 +3947,17 @@
 	i = sector[sectnum].wallnum;
 	do
 	{
-		y1 = wal->y-y; y2 = wall[wal->point2].y-y;
+		y1 = wal->y-y;
+        y2 = wall[wal->point2].y-y;
 		if ((y1^y2) < 0)
 		{
-			x1 = wal->x-x; x2 = wall[wal->point2].x-x;
-			if ((x1^x2) >= 0) cnt ^= x1; else cnt ^= (x1*y2-x2*y1)^y2;
+			x1 = wal->x-x;
+            x2 = wall[wal->point2].x-x;
+            
+			if ((x1^x2) >= 0)
+                cnt ^= x1;
+            else
+                cnt ^= (x1*y2-x2*y1)^y2;
 		}
 		wal++; i--;
 	} while (i);
@@ -6718,7 +6754,18 @@
 	return(bad);
 }
 
-
+/*
+   FCS:  x and y are the new position of the entity.
+         sectnum is an hint (the last known sector number of the entity)
+ 
+   Thanks to the "hint", the algorithm check:
+   1. Is (x,y) inside sectors[sectnum].
+   2. Flood in sectnum portal and check again if (x,y) is inside.
+   3. Do a linear search on sectors[sectnum] from 0 to numSectors.
+  
+   Note: Inside uses cross_product and return as soon as the point switch
+         from one side to the other.
+ */
 void updatesector(long x, long y, short *sectnum)
 {
 	walltype *wal;
--- a/xcode/Duke3D.xcodeproj/project.pbxproj
+++ b/xcode/Duke3D.xcodeproj/project.pbxproj
@@ -99,7 +99,6 @@
 		2D7B621A1678885A00E35E54 /* pragmas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = pragmas.c; path = ../../Engine/src/pragmas.c; sourceTree = "<group>"; };
 		2D7B621B1678885A00E35E54 /* pragmas.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pragmas.h; path = ../../Engine/src/pragmas.h; sourceTree = "<group>"; };
 		2D7B621C1678885A00E35E54 /* sdl_driver.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sdl_driver.c; path = ../../Engine/src/sdl_driver.c; sourceTree = "<group>"; };
-		2D7B622E1678887600E35E54 /* win32_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = win32_compat.h; path = ../../Engine/src/win32_compat.h; sourceTree = "<group>"; };
 		2D7B622F1678895A00E35E54 /* macos_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = macos_compat.h; path = ../../Engine/src/macos_compat.h; sourceTree = "<group>"; };
 		2D7B623016788A9B00E35E54 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
 		2D7B623216788AAB00E35E54 /* SDL_mixer.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL_mixer.framework; path = /Library/Frameworks/SDL_mixer.framework; sourceTree = "<absolute>"; };
@@ -227,7 +226,6 @@
 				2D7B621A1678885A00E35E54 /* pragmas.c */,
 				2D7B621B1678885A00E35E54 /* pragmas.h */,
 				2D7B621C1678885A00E35E54 /* sdl_driver.c */,
-				2D7B622E1678887600E35E54 /* win32_compat.h */,
 				2D7B622F1678895A00E35E54 /* macos_compat.h */,
 				2D7B630016791C0200E35E54 /* dummy_multi.c */,
 			);