summaryrefslogtreecommitdiff
path: root/3dc/VDB.C
diff options
context:
space:
mode:
authorRebellion Developments <rebellion@nomail>2000-03-16 11:25:00 +0100
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-19 05:45:17 +0200
commit218ca90543758a20ac326e444ca0643174ca7384 (patch)
tree16bfe3e5307f9f515489000f28728224291a0e3b /3dc/VDB.C
Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
Diffstat (limited to '3dc/VDB.C')
-rw-r--r--3dc/VDB.C779
1 files changed, 779 insertions, 0 deletions
diff --git a/3dc/VDB.C b/3dc/VDB.C
new file mode 100644
index 0000000..983497f
--- /dev/null
+++ b/3dc/VDB.C
@@ -0,0 +1,779 @@
+
+#include "3dc.h"
+#include "inline.h"
+
+
+
+/*
+
+ externs for commonly used global variables and arrays
+
+*/
+
+ #if platform_pc
+ extern int sine[];
+ extern int cosine[];
+ #endif
+
+ #if SupportWindows95
+ extern int ScanDrawMode;
+ #endif
+
+
+/*
+
+ General System Globals
+
+*/
+
+SCENE Global_Scene = 0;
+
+
+
+
+/*
+
+ Screen Descriptor Block
+
+*/
+
+SCREENDESCRIPTORBLOCK ScreenDescriptorBlock;
+
+
+/*
+
+ View Descriptor Blocks
+
+*/
+
+ int NumFreeVDBs;
+ VIEWDESCRIPTORBLOCK *FreeVDBList[maxvdbs];
+ static VIEWDESCRIPTORBLOCK **FreeVDBListPtr = &FreeVDBList[maxvdbs-1];
+
+ int NumActiveVDBs;
+ VIEWDESCRIPTORBLOCK *ActiveVDBList[maxvdbs];
+ static VIEWDESCRIPTORBLOCK **ActiveVDBListPtr = &ActiveVDBList[0];
+
+ static VIEWDESCRIPTORBLOCK FreeVDBData[maxvdbs];
+
+
+/* Clip Plane Block */
+
+ static CLIPPLANEPOINTS ClipPlanePoints;
+
+
+
+extern int GlobalAmbience;
+
+/*
+
+ Support Functions
+
+*/
+
+
+/*
+
+ Calculate View Volume Planes from the Clip Boundaries for a VDB
+
+ Before doing this, check that the requested boundaries are within those of
+ the physical sceen. If any boundary transgresses, truncate it and set the
+ appropriate flag bit.
+
+*/
+
+void VDBClipPlanes(VIEWDESCRIPTORBLOCK *vdb)
+
+{
+
+
+/* Check Clip Boundaries against the Physical Screen */
+
+
+ /* Check Left Boundary */
+
+ if(vdb->VDB_ClipLeft < ScreenDescriptorBlock.SDB_ClipLeft) {
+
+ vdb->VDB_ClipLeft = ScreenDescriptorBlock.SDB_ClipLeft;
+ vdb->VDB_Flags |= ViewDB_Flag_LTrunc;
+
+ }
+
+ /* Check Right Boundary */
+
+ if(vdb->VDB_ClipRight > ScreenDescriptorBlock.SDB_ClipRight) {
+
+ vdb->VDB_ClipRight = ScreenDescriptorBlock.SDB_ClipRight;
+ vdb->VDB_Flags |= ViewDB_Flag_RTrunc;
+
+ }
+
+ /* Check Up boundary */
+
+ if(vdb->VDB_ClipUp < ScreenDescriptorBlock.SDB_ClipUp) {
+
+ vdb->VDB_ClipUp = ScreenDescriptorBlock.SDB_ClipUp;
+ vdb->VDB_Flags |= ViewDB_Flag_UTrunc;
+
+ }
+
+ /* Check Down boundary */
+
+ if(vdb->VDB_ClipDown > ScreenDescriptorBlock.SDB_ClipDown) {
+
+ vdb->VDB_ClipDown = ScreenDescriptorBlock.SDB_ClipDown;
+ vdb->VDB_Flags |= ViewDB_Flag_DTrunc;
+
+ }
+
+
+/* Calculate Width and Height */
+
+ /* textprint("current wh = %d, %d\n", vdb->VDB_Width, vdb->VDB_Height); */
+
+ /* Width */
+
+ vdb->VDB_Width = vdb->VDB_ClipRight - vdb->VDB_ClipLeft;
+
+ /* Height */
+
+ vdb->VDB_Height = vdb->VDB_ClipDown - vdb->VDB_ClipUp;
+
+ #if 0
+ textprint("new wh = %d, %d\n", vdb->VDB_Width, vdb->VDB_Height);
+ WaitForReturn();
+ #endif
+
+
+/* Set up the Clip Planes */
+
+
+ /* Clip Left */
+
+ ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
+ ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
+ ClipPlanePoints.cpp1.vz = NearZ;
+
+ ClipPlanePoints.cpp2.vx = vdb->VDB_ClipLeft;
+ ClipPlanePoints.cpp2.vy = (vdb->VDB_ClipUp + vdb->VDB_ClipDown) / 2;
+ ClipPlanePoints.cpp2.vz = FarZ;
+
+ ClipPlanePoints.cpp3.vx = vdb->VDB_ClipLeft;
+ ClipPlanePoints.cpp3.vy = vdb->VDB_ClipDown;
+ ClipPlanePoints.cpp3.vz = NearZ;
+
+ MakeClipPlane(vdb, &vdb->VDB_ClipLeftPlane, &ClipPlanePoints);
+
+
+ /* Clip Right */
+
+ ClipPlanePoints.cpp1.vx = vdb->VDB_ClipRight;
+ ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
+ ClipPlanePoints.cpp1.vz = NearZ;
+
+ ClipPlanePoints.cpp2.vx = vdb->VDB_ClipRight;
+ ClipPlanePoints.cpp2.vy = vdb->VDB_ClipDown;
+ ClipPlanePoints.cpp2.vz = NearZ;
+
+ ClipPlanePoints.cpp3.vx = vdb->VDB_ClipRight;
+ ClipPlanePoints.cpp3.vy = (vdb->VDB_ClipUp + vdb->VDB_ClipDown) / 2;
+ ClipPlanePoints.cpp3.vz = FarZ;
+
+ MakeClipPlane(vdb, &vdb->VDB_ClipRightPlane, &ClipPlanePoints);
+
+
+ /* Clip Up */
+
+ ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
+ ClipPlanePoints.cpp1.vy = vdb->VDB_ClipUp;
+ ClipPlanePoints.cpp1.vz = NearZ;
+
+ ClipPlanePoints.cpp2.vx = vdb->VDB_ClipRight;
+ ClipPlanePoints.cpp2.vy = vdb->VDB_ClipUp;
+ ClipPlanePoints.cpp2.vz = NearZ;
+
+ ClipPlanePoints.cpp3.vx = (vdb->VDB_ClipLeft + vdb->VDB_ClipRight) / 2;
+ ClipPlanePoints.cpp3.vy = vdb->VDB_ClipUp;
+ ClipPlanePoints.cpp3.vz = FarZ;
+
+ MakeClipPlane(vdb, &vdb->VDB_ClipUpPlane, &ClipPlanePoints);
+
+
+ /* Clip Down */
+
+ ClipPlanePoints.cpp1.vx = vdb->VDB_ClipLeft;
+ ClipPlanePoints.cpp1.vy = vdb->VDB_ClipDown;
+ ClipPlanePoints.cpp1.vz = NearZ;
+
+ ClipPlanePoints.cpp2.vx = (vdb->VDB_ClipLeft + vdb->VDB_ClipRight) / 2;
+ ClipPlanePoints.cpp2.vy = vdb->VDB_ClipDown;
+ ClipPlanePoints.cpp2.vz = FarZ;
+
+ ClipPlanePoints.cpp3.vx = vdb->VDB_ClipRight;
+ ClipPlanePoints.cpp3.vy = vdb->VDB_ClipDown;
+ ClipPlanePoints.cpp3.vz = NearZ;
+
+ MakeClipPlane(vdb, &vdb->VDB_ClipDownPlane, &ClipPlanePoints);
+
+
+/* Clip Z */
+
+ vdb->VDB_ClipZPlane.CPB_Normal.vx = 0;
+ vdb->VDB_ClipZPlane.CPB_Normal.vy = 0;
+ vdb->VDB_ClipZPlane.CPB_Normal.vz = -ONE_FIXED;
+
+ vdb->VDB_ClipZPlane.CPB_POP.vx = 0;
+ vdb->VDB_ClipZPlane.CPB_POP.vy = 0;
+ vdb->VDB_ClipZPlane.CPB_POP.vz = vdb->VDB_ClipZ;
+
+}
+
+
+/*
+
+ Make a Clip Plane.
+
+ Reverse Project the three Clip Points (overwrite their struct).
+
+ Use the first Clip Point as the POP, writing this to the CPB.
+
+ Pass the three Clip Points to MakeNormal() specifying the CPB Normal as
+ the destination.
+
+ NOTES
+
+ The vdb is passed for the reverse projection.
+
+*/
+
+void MakeClipPlane(
+
+VIEWDESCRIPTORBLOCK *vdb,
+CLIPPLANEBLOCK *cpb,
+CLIPPLANEPOINTS *cpp)
+
+{
+
+ int x, y;
+
+/* Reverse Project the Clip Points */
+
+
+/* cpp1 */
+
+/* x */
+
+ x=cpp->cpp1.vx;
+ x-=vdb->VDB_CentreX;
+ x*=cpp->cpp1.vz;
+ x/=vdb->VDB_ProjX;
+ cpp->cpp1.vx=x;
+
+/* y */
+
+ y=cpp->cpp1.vy;
+ y-=vdb->VDB_CentreY;
+ y*=cpp->cpp1.vz;
+ y/=vdb->VDB_ProjY;
+ cpp->cpp1.vy=y;
+
+
+/* cpp2 */
+
+/* x */
+
+ x=cpp->cpp2.vx;
+ x-=vdb->VDB_CentreX;
+ x*=cpp->cpp2.vz;
+ x/=vdb->VDB_ProjX;
+ cpp->cpp2.vx=x;
+
+/* y */
+
+ y=cpp->cpp2.vy;
+ y-=vdb->VDB_CentreY;
+ y*=cpp->cpp2.vz;
+ y/=vdb->VDB_ProjY;
+ cpp->cpp2.vy=y;
+
+
+/* cpp3 */
+
+/* x */
+
+ x=cpp->cpp3.vx;
+ x-=vdb->VDB_CentreX;
+ x*=cpp->cpp3.vz;
+ x/=vdb->VDB_ProjX;
+ cpp->cpp3.vx=x;
+
+/* y */
+
+ y=cpp->cpp3.vy;
+ y-=vdb->VDB_CentreY;
+ y*=cpp->cpp3.vz;
+ y/=vdb->VDB_ProjY;
+ cpp->cpp3.vy=y;
+
+/* The 1st Clip Point can be the POP */
+
+ cpb->CPB_POP.vx=cpp->cpp1.vx;
+ cpb->CPB_POP.vy=cpp->cpp1.vy;
+ cpb->CPB_POP.vz=cpp->cpp1.vz;
+
+/* Make CPB_Normal */
+
+ MakeNormal(&cpp->cpp1, &cpp->cpp2, &cpp->cpp3, &cpb->CPB_Normal);
+
+}
+
+
+#if pc_backdrops
+
+/*
+
+ Create the projector array used for cylindrically projected backdrops
+
+ The array looks like this
+
+ unsigned short VDB_ProjectorXOffsets[MaxScreenWidth];
+
+ For each centre relative x there is a projector. Using just the x and z
+ components of the projector an angular offset from the centre (0) can be
+ calculated using ArcTan().
+
+ To calculate a projector one must reverse project each x value at a given
+ z value. Rather than go on to create the normalised projector vector we can
+ go straight to the ArcTan() to find the angular offset.
+
+*/
+
+static void CreateProjectorArray(VIEWDESCRIPTORBLOCK *vdb)
+
+{
+
+ int sx, x, vx, vz, i, ao;
+
+
+ vz = ONE_FIXED;
+
+ sx = vdb->VDB_ClipLeft;
+
+ i = 0;
+
+ while(sx < vdb->VDB_ClipRight) {
+
+ x = sx - vdb->VDB_CentreX;
+
+ vx = (x * vz) / vdb->VDB_ProjX;
+
+ ao = ArcTan(vx, vz);
+
+ vdb->VDB_ProjectorXOffsets[i] = ao;
+
+ #if 0
+ textprint("Pr. Offset %d = %u\n", i, vdb->VDB_ProjectorXOffsets[i]);
+ WaitForReturn();
+ #endif
+
+ sx++; i++;
+
+ }
+
+}
+
+#endif
+
+
+
+
+
+
+/*
+
+ SetVDB requires a VIEWDESCRIPTORBLOCK
+
+ See the actual function code for what each parameter is
+
+*/
+
+void SetVDB(vdb, fl, ty, d, cx,cy, prx,pry, mxp, cl,cr,cu,cd, h1,h2,hc, amb)
+
+ VIEWDESCRIPTORBLOCK *vdb;
+
+ int fl;
+ int ty;
+
+ int d;
+
+ int cx;
+ int cy;
+
+ int prx;
+ int pry;
+ int mxp;
+
+ int cl;
+ int cr;
+ int cu;
+ int cd;
+
+ int h1;
+ int h2;
+ int hc;
+
+ int amb;
+
+{
+
+
+
+ /* Initial setup */
+
+ vdb->VDB_Flags = fl;
+ vdb->VDB_ViewType = ty;
+
+
+ /* Ambience */
+
+ vdb->VDB_Ambience = amb;
+ /* KJL 14:30:57 05/14/97 - set globalAmbience here as well */
+ GlobalAmbience = amb;
+
+ /* Width and Height are set by the Clip Boundaries */
+
+ if(vdb->VDB_Flags & ViewDB_Flag_FullSize) {
+
+ vdb->VDB_Depth = ScreenDescriptorBlock.SDB_Depth;
+
+ #if SupportWindows95
+ vdb->VDB_ScreenDepth = ScreenDescriptorBlock.SDB_ScreenDepth;
+ #endif
+
+ vdb->VDB_CentreX = ScreenDescriptorBlock.SDB_CentreX;
+ vdb->VDB_CentreY = ScreenDescriptorBlock.SDB_CentreY;
+
+ vdb->VDB_ProjX = ScreenDescriptorBlock.SDB_ProjX;
+ vdb->VDB_ProjY = ScreenDescriptorBlock.SDB_ProjY;
+ vdb->VDB_MaxProj = ScreenDescriptorBlock.SDB_MaxProj;
+
+ vdb->VDB_ClipLeft = ScreenDescriptorBlock.SDB_ClipLeft;
+ vdb->VDB_ClipRight = ScreenDescriptorBlock.SDB_ClipRight;
+ vdb->VDB_ClipUp = ScreenDescriptorBlock.SDB_ClipUp;
+ vdb->VDB_ClipDown = ScreenDescriptorBlock.SDB_ClipDown;
+
+ }
+
+ else {
+
+ #if SupportWindows95
+ if (ScanDrawMode == ScanDrawDirectDraw)
+ vdb->VDB_Depth = d;
+ else
+ vdb->VDB_Depth = VideoModeType_24;
+
+ vdb->VDB_ScreenDepth = ScreenDescriptorBlock.SDB_ScreenDepth;
+ #else
+ vdb->VDB_Depth = d;
+ #endif
+
+ vdb->VDB_CentreX = cx;
+ vdb->VDB_CentreY = cy;
+
+ vdb->VDB_ProjX = prx;
+ vdb->VDB_ProjY = pry;
+ vdb->VDB_MaxProj = mxp;
+
+ vdb->VDB_ClipLeft = cl;
+ vdb->VDB_ClipRight = cr;
+ vdb->VDB_ClipUp = cu;
+ vdb->VDB_ClipDown = cd;
+
+ if(vdb->VDB_Flags & ViewDB_Flag_AdjustScale) {
+
+ vdb->VDB_CentreX =
+ WideMulNarrowDiv(
+ vdb->VDB_CentreX,
+ ScreenDescriptorBlock.SDB_Width,
+ 320);
+
+ vdb->VDB_CentreY =
+ WideMulNarrowDiv(
+ vdb->VDB_CentreY,
+ ScreenDescriptorBlock.SDB_Height,
+ 200);
+
+
+ vdb->VDB_ProjX =
+ WideMulNarrowDiv(
+ vdb->VDB_ProjX,
+ ScreenDescriptorBlock.SDB_Width,
+ 320);
+
+ vdb->VDB_ProjY =
+ WideMulNarrowDiv(
+ vdb->VDB_ProjY,
+ ScreenDescriptorBlock.SDB_Height,
+ 200);
+
+ vdb->VDB_MaxProj =
+ WideMulNarrowDiv(
+ vdb->VDB_MaxProj,
+ ScreenDescriptorBlock.SDB_Width,
+ 320);
+
+
+ vdb->VDB_ClipLeft =
+ WideMulNarrowDiv(
+ vdb->VDB_ClipLeft,
+ ScreenDescriptorBlock.SDB_Width,
+ 320);
+
+ vdb->VDB_ClipRight =
+ WideMulNarrowDiv(
+ vdb->VDB_ClipRight,
+ ScreenDescriptorBlock.SDB_Width,
+ 320);
+
+ vdb->VDB_ClipUp =
+ WideMulNarrowDiv(
+ vdb->VDB_ClipUp,
+ ScreenDescriptorBlock.SDB_Height,
+ 200);
+
+ vdb->VDB_ClipDown =
+ WideMulNarrowDiv(
+ vdb->VDB_ClipDown,
+ ScreenDescriptorBlock.SDB_Height,
+ 200);
+
+ }
+
+ }
+
+
+ /* Create the clip planes */
+
+ /* KJL 10:41:13 04/09/97 - set to constant so the same for all screen sizes! */
+ vdb->VDB_ClipZ = 64;//vdb->VDB_MaxProj; /* Safe */
+
+ VDBClipPlanes(vdb);
+
+ #if 0
+ /* View Angle */
+
+ if(vdb->VDB_CentreX > vdb->VDB_CentreY) s = vdb->VDB_CentreX;
+ else s = vdb->VDB_CentreY;
+
+ z = vdb->VDB_MaxProj * 100;
+
+ x = (s * z) / vdb->VDB_MaxProj;
+
+ vdb->VDB_ViewAngle = ArcTan(x, z);
+
+ vdb->VDB_ViewAngleCos = GetCos(vdb->VDB_ViewAngle);
+
+
+ #if 0
+ textprint("View Angle = %d\n", vdb->VDB_ViewAngle);
+ WaitForReturn();
+ #endif
+
+
+ #if pc_backdrops
+
+ /* Projector Array */
+
+ CreateProjectorArray(vdb);
+
+ #endif
+
+
+ /* Hazing & Background Colour */
+
+ vdb->VDB_H1 = h1;
+ vdb->VDB_H2 = h2;
+ vdb->VDB_HInterval = h2 - h1;
+ vdb->VDB_HColour = hc;
+ #endif
+}
+
+
+
+
+/*
+
+ Initialise the Free VDB List
+
+*/
+
+void InitialiseVDBs(void)
+
+{
+
+ VIEWDESCRIPTORBLOCK *FreeVDBPtr = &FreeVDBData[0];
+
+ NumActiveVDBs = 0;
+
+ for(NumFreeVDBs = 0; NumFreeVDBs < maxvdbs; NumFreeVDBs++) {
+
+ FreeVDBList[NumFreeVDBs] = FreeVDBPtr;
+
+ FreeVDBPtr++;
+
+ }
+
+ FreeVDBListPtr = &FreeVDBList[maxvdbs-1];
+ ActiveVDBListPtr = &ActiveVDBList[0];
+
+}
+
+
+/*
+
+ Get a VDB from the Free VDB list
+
+*/
+
+VIEWDESCRIPTORBLOCK* AllocateVDB(void)
+
+{
+
+ VIEWDESCRIPTORBLOCK *FreeVDBPtr = 0; /* Default to null ptr */
+ int *i_src;
+ int i;
+
+
+ if(NumFreeVDBs) {
+
+ FreeVDBPtr = *FreeVDBListPtr--;
+
+ NumFreeVDBs -= 1; /* One less free block */
+
+ /* Clear the block */
+
+ i_src = (int *) FreeVDBPtr;
+ for(i = sizeof(VIEWDESCRIPTORBLOCK)/4; i!=0; i--)
+ *i_src++ = 0;
+
+ }
+
+ return(FreeVDBPtr);
+
+}
+
+
+/*
+
+ Return a VDB to the Free VDB list
+
+*/
+
+void DeallocateVDB(VIEWDESCRIPTORBLOCK *vdb)
+
+{
+
+ FreeVDBListPtr++;
+ *FreeVDBListPtr = vdb;
+
+ NumFreeVDBs++; /* One more free block */
+
+}
+
+
+/*
+
+ Allocate a VDB and make it active
+
+*/
+
+VIEWDESCRIPTORBLOCK* CreateActiveVDB(void)
+
+{
+
+ VIEWDESCRIPTORBLOCK *vdb;
+ VIEWDESCRIPTORBLOCK *vdb_tmp;
+ VIEWDESCRIPTORBLOCK **v_src;
+
+ int v;
+ int p = -1;
+
+
+ vdb = AllocateVDB();
+
+ if(vdb) {
+
+ /* Find the next "VDB_Priority" */
+
+ if(NumActiveVDBs) {
+
+ v_src = &ActiveVDBList[0];
+
+ for(v = NumActiveVDBs; v!=0; v--) {
+
+ vdb_tmp = *v_src++;
+
+ if(vdb_tmp->VDB_Priority > p) p = vdb_tmp->VDB_Priority;
+
+ }
+
+ }
+
+ /* Set the VDB priority */
+
+ vdb->VDB_Priority = (p + 1);
+
+ /* Update the active VDB list */
+
+ *ActiveVDBListPtr++ = vdb;
+
+ NumActiveVDBs++;
+
+ }
+
+ return vdb;
+
+}
+
+
+/*
+
+ Deallocate an active VDB
+
+*/
+
+int DestroyActiveVDB(dblockptr)
+
+ VIEWDESCRIPTORBLOCK *dblockptr;
+
+{
+
+ int j = -1;
+ int i;
+
+
+ /* If the VDB ptr is OK, search the Active VDB List */
+
+ if(dblockptr) {
+
+ for(i = 0; i < NumActiveVDBs && j!=0; i++) {
+
+ if(ActiveVDBList[i] == dblockptr) {
+
+ #if ProjectSpecificVDBs
+ ProjectSpecificVDBDestroy(dblockptr);
+ #endif
+
+ ActiveVDBList[i] = ActiveVDBList[NumActiveVDBs - 1];
+ NumActiveVDBs--;
+ ActiveVDBListPtr--;
+ DeallocateVDB(dblockptr); /* Return VDB to Free List */
+ j = 0; /* Flag OK */
+
+ }
+ }
+ }
+
+ return(j);
+
+}