From 218ca90543758a20ac326e444ca0643174ca7384 Mon Sep 17 00:00:00 2001 From: Rebellion Developments Date: Thu, 16 Mar 2000 11:25:00 +0100 Subject: 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. --- 3dc/win95/Krender.c | 2830 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2830 insertions(+) create mode 100644 3dc/win95/Krender.c (limited to '3dc/win95/Krender.c') diff --git a/3dc/win95/Krender.c b/3dc/win95/Krender.c new file mode 100644 index 0000000..a52c1d5 --- /dev/null +++ b/3dc/win95/Krender.c @@ -0,0 +1,2830 @@ +/*KJL********************************************************************* +* krender.c - Kevin's scandrawing code. (New render, new danger.) * +* * +* The new scandraws are called by patching the functions below into the * +* jumptables used in item.c. If the KRENDER_ON flag in krender.h is zero * +* then the old scandraws will be used. * +*********************************************************************KJL*/ + +/* this file is a bit messy at the moment, but I'll be back later... */ +#include "3dc.h" +#include "inline.h" +#include "module.h" +#include "gamedef.h" +#include "krender.h" +#include "vision.h" + +#define UseLocalAssert Yes +#include "ourasert.h" + +#define PENTIUM_PROFILING_ON 0 +#if PENTIUM_PROFILING_ON +#include "pentime.h" +#else +#define ProfileStart(); +#define ProfileStop(x); +#endif + +int ReciprocalTable[321]; +#if 1 +#define DIVIDE(a,b) ((a)/(b)) +#else +#define DIVIDE(a,b) (MUL_FIXED((a),ReciprocalTable[(b)])) +#endif + + +int Transparent; + +/* assembler fns */ +extern void ScanDraw2D_Gouraud(void); +extern void ScanDraw2D_GouraudTransparent(void); +extern void ScanDraw2D_VAlignedTransparent(void); +extern void ScanDraw2D_VAlignedOpaque(void); +extern void ScanDraw2D_Transparent(void); +extern void ScanDraw2D_TransparentLit(void); +extern void ScanDraw2D_Opaque(void); +extern void ScanDraw_GouraudScan(void); +extern void ScanDrawF3D_Gouraud(void); + +/* globals accessed by the assembler routines */ +unsigned char *SCASM_Lighting; +unsigned char *SCASM_Destination; +unsigned char *SCASM_Bitmap; +int SCASM_StartU; +int SCASM_StartV; +int SCASM_StartI; +int SCASM_DeltaU; +int SCASM_DeltaV; +int SCASM_DeltaI; +int SCASM_ScanLength; +int SCASM_ShadingTableSize; +int SCASM_TextureDeltaScan; + +/* things from item.c */ +extern int NumScans; +extern int ItemColour; +extern IMAGEHEADER *ImageHeaderPtrs[MaxImages]; +extern SCREENDESCRIPTORBLOCK ScreenDescriptorBlock; +extern unsigned char *TextureLightingTable; +extern int MIP_Index; +extern int ScanData[maxpolys*maxscansize]; +extern unsigned char *ScreenBuffer; +extern long BackBufferPitch; + +void Draw_Gouraud3dTexture_Spans(int *itemptr); + +int KRenderDrawMode = 0; + +/***********/ + +void KR_ScanDraw_Item_Gouraud2dTexturePolygon_VideoModeType_8(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *) itemptr; + I_GOURAUD2DTEXTUREPOLYGON_SCAN *sptr; + + if(NumScans) + { + int y = NumScans; + /* Get the Image Data required for the Draw */ + { + IMAGEHEADER *ImageHdr; + { + int TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + } + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + TEXTURE **TxImagePtr = &ImageHdr->ImagePtr; + SCASM_Bitmap = TxImagePtr[MIP_Index]; + GLOBALASSERT(SCASM_Bitmap); + SCASM_TextureDeltaScan = ImageHdr->ImageWidth >> MIP_Index; + #if MIP_ROUNDUP + if (ImageHdr->ImageWidth & (1<ImageWidth; + SCASM_Bitmap = ImageHdr->ImagePtr; + GLOBALASSERT(SCASM_Bitmap); + } + } + SCASM_Lighting = TextureLightingTable; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_Raw256) SCASM_ShadingTableSize = 256; + else SCASM_ShadingTableSize = 64; + + sptr = (I_GOURAUD2DTEXTUREPOLYGON_SCAN *) ScanData; + do + { + int dx = sptr->ig2s_x2 - sptr->ig2s_x1; + if (dx>0 && !(sptr->ig2s_y & KRenderDrawMode) ) + { + /* Fixed Point U for Interpolation */ + { + int StartU = sptr->ig2s_u1; + SCASM_DeltaU = DIVIDE((sptr->ig2s_u2 - StartU),dx); + SCASM_StartU = StartU; + } + + /* Fixed Point V for Interpolation */ + { + int StartV = sptr->ig2s_v1; + SCASM_DeltaV = DIVIDE((sptr->ig2s_v2 - StartV),dx); + SCASM_StartV = StartV; + } + /* Fixed Point I for Interpolation */ + { + int StartI = sptr->ig2s_c1; + SCASM_DeltaI = DIVIDE((sptr->ig2s_c2 - StartI),dx); + SCASM_StartI = StartI; + } + /* Draw the Gouraud 2d Texture Scan */ + + SCASM_Destination = ScreenBuffer + (sptr->ig2s_y * BackBufferPitch) + sptr->ig2s_x1; + SCASM_ScanLength = dx; + + if(pheader->PolyFlags & iflag_ignore0) + { + ScanDraw2D_GouraudTransparent(); + } + else + { + ScanDraw2D_Gouraud(); + } + } + sptr++; + y--; + } + while(y); + } + +} + +void Draw3DScan(I_GOURAUD3DTEXTUREPOLYGON_SCAN *scanPtr, POLYHEADER *pheader) +{ + int dx = scanPtr->ig3s_x2 - scanPtr->ig3s_x1; + + if(dx > 0) + { + float uf; + float vf; + float uf2; + float vf2; + /* Get start and end UVs */ + { + float ooz1; + ooz1 = 65536.0 / scanPtr->ig3s_z1; + uf = scanPtr->ig3s_u1 * ooz1; + vf = scanPtr->ig3s_v1 * ooz1; + } + { + float ooz2; + ooz2 = 65536.0 / scanPtr->ig3s_z2; + uf2 = scanPtr->ig3s_u2 * ooz2; + vf2 = scanPtr->ig3s_v2 * ooz2; + } + if ( (uf>16700000.0) + ||(uf<0.0) + ||(vf>16700000.0) + ||(vf<0.0) ) + { + textprint("WARNING: UV coords invalid\n"); + // LOCALASSERT(0); + return; + } + if ( (uf2>16700000.0) + ||(uf2<0.0) + ||(vf2>16700000.0) + ||(vf2<0.0) ) + { + textprint("WARNING: UV coords invalid\n"); + // LOCALASSERT(0); + return; + } + /* For UV interpolation */ + f2i(SCASM_StartU,uf); + f2i(SCASM_StartV,vf); + { + int EndU,EndV; + f2i(EndU,uf2); + f2i(EndV,vf2); + SCASM_DeltaU =(EndU-SCASM_StartU)/dx; + SCASM_DeltaV =(EndV-SCASM_StartV)/dx; + } + + /* Fixed Point I for Interpolation */ + { + int StartI = scanPtr->ig3s_c1; + SCASM_DeltaI = (scanPtr->ig3s_c2 - StartI)/dx; + SCASM_StartI = StartI; + } + + /* Draw the 3d Texture Scan */ + SCASM_Destination = ScreenBuffer + (scanPtr->ig3s_y * BackBufferPitch) + scanPtr->ig3s_x1; + SCASM_ScanLength = dx; + + if(pheader->PolyFlags & iflag_ignore0) + { + ScanDraw2D_GouraudTransparent(); + } + else + { + ScanDraw2D_Gouraud(); + } + } +} + + +void KR_ScanDraw_Item_Gouraud3dTexturePolygon_Linear_S_VideoModeType_8(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *) itemptr; + + int num_scans_s; + I_GOURAUD3DTEXTUREPOLYGON_SCAN *sptr_array_ptr; + I_GOURAUD3DTEXTUREPOLYGON_SCAN *next_free_sptr; + I_GOURAUD3DTEXTUREPOLYGON_SCAN sptr_array[lin_s_max + 1]; + int StillSubdividing; + int i; + + + if(NumScans) + { + I_GOURAUD3DTEXTUREPOLYGON_SCAN *sptr; + int y; + /* Get the Image Data required for the Draw */ + { + IMAGEHEADER *ImageHdr; + { + int TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + } + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + TEXTURE **TxImagePtr = &ImageHdr->ImagePtr; + SCASM_Bitmap = TxImagePtr[MIP_Index]; + GLOBALASSERT(SCASM_Bitmap); + SCASM_TextureDeltaScan = ImageHdr->ImageWidth >> MIP_Index; + #if MIP_ROUNDUP + if (ImageHdr->ImageWidth & (1<ImageWidth; + SCASM_Bitmap = ImageHdr->ImagePtr; + GLOBALASSERT(SCASM_Bitmap); + } + } + SCASM_Lighting = TextureLightingTable; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_Raw256) SCASM_ShadingTableSize = 256; + else SCASM_ShadingTableSize = 64; + + + sptr = (I_GOURAUD3DTEXTUREPOLYGON_SCAN *) ScanData; + + for(y = NumScans; y!=0; y--) + { + int dx = sptr->ig3s_x2 - sptr->ig3s_x1; + if (dx>0 && !(sptr->ig3s_y & KRenderDrawMode) ) + { + float zmax, zmin, z_ratio; + + /* Have a look at the z-ratio */ + if(sptr->ig3s_z1 > sptr->ig3s_z2) + { + zmax = sptr->ig3s_z1; + zmin = sptr->ig3s_z2; + } + else + { + zmax = sptr->ig3s_z2; + zmin = sptr->ig3s_z1; + } + z_ratio = (zmax * 256); + + + /* Draw if the z ratio is inside the threshold */ + if(z_ratio < lin_s_zthr*zmin) + { + Draw3DScan(sptr,pheader); + } + /* Else subdivide until scan segments are inside threshold */ + else + { + /* Copy the current scan to the subdivision array */ + sptr_array_ptr = sptr_array; + num_scans_s = 1; + + sptr_array_ptr->ig3s_u1 = sptr->ig3s_u1; + sptr_array_ptr->ig3s_v1 = sptr->ig3s_v1; + sptr_array_ptr->ig3s_z1 = sptr->ig3s_z1; + sptr_array_ptr->ig3s_c1 = sptr->ig3s_c1; + + sptr_array_ptr->ig3s_u2 = sptr->ig3s_u2; + sptr_array_ptr->ig3s_v2 = sptr->ig3s_v2; + sptr_array_ptr->ig3s_z2 = sptr->ig3s_z2; + sptr_array_ptr->ig3s_c2 = sptr->ig3s_c2; + + sptr_array_ptr->ig3s_x1 = sptr->ig3s_x1; + sptr_array_ptr->ig3s_x2 = sptr->ig3s_x2; + + sptr_array_ptr->ig3s_y = sptr->ig3s_y; + + + /* Subdivide until no further divisions are needed */ + + next_free_sptr = sptr_array_ptr + 1; + do + { + sptr_array_ptr = sptr_array; + + StillSubdividing = No; /* Assume not */ + + for(i = num_scans_s; i!=0; i--) + { + #if 0 + /* z ratio of this scan */ + if(sptr_array_ptr->ig3s_z1 > sptr_array_ptr->ig3s_z2) + { + z_ratio = (sptr_array_ptr->ig3s_z1 * 256) / + sptr_array_ptr->ig3s_z2; + } + else + { + z_ratio = (sptr_array_ptr->ig3s_z2 * 256) / + sptr_array_ptr->ig3s_z1; + } + /* Is it within the threshold? */ + if(z_ratio > lin_s_zthr && num_scans_s < lin_s_max) + #endif + int overThreshold=0; + /* z ratio of this scan */ + if(sptr_array_ptr->ig3s_z1 > sptr_array_ptr->ig3s_z2) + { + if ( (sptr_array_ptr->ig3s_z1 * 256) > (lin_s_zthr*sptr_array_ptr->ig3s_z2)) + overThreshold=1; + } + else + { + if ( (sptr_array_ptr->ig3s_z2 * 256) > (lin_s_zthr*sptr_array_ptr->ig3s_z1)) + overThreshold=1; + } + /* Is it within the threshold? */ + if(overThreshold && num_scans_s < lin_s_max) + { + int mid_x, mid_c; + float mid_u, mid_v, mid_z; + /* No - subdivide */ + StillSubdividing = Yes; + + mid_u = (sptr_array_ptr->ig3s_u1 + sptr_array_ptr->ig3s_u2) / 2; + + mid_v = (sptr_array_ptr->ig3s_v1 + sptr_array_ptr->ig3s_v2) / 2; + + mid_z = (sptr_array_ptr->ig3s_z1 + sptr_array_ptr->ig3s_z2) / 2; + + mid_c = (sptr_array_ptr->ig3s_c1 + sptr_array_ptr->ig3s_c2) / 2; + + mid_x = (sptr_array_ptr->ig3s_x1 + sptr_array_ptr->ig3s_x2) / 2; + + /* Create new scan */ + + next_free_sptr->ig3s_u1 = mid_u; + next_free_sptr->ig3s_v1 = mid_v; + next_free_sptr->ig3s_z1 = mid_z; + next_free_sptr->ig3s_c1 = mid_c; + next_free_sptr->ig3s_x1 = mid_x; + next_free_sptr->ig3s_u2 = sptr_array_ptr->ig3s_u2; + next_free_sptr->ig3s_v2 = sptr_array_ptr->ig3s_v2; + next_free_sptr->ig3s_z2 = sptr_array_ptr->ig3s_z2; + next_free_sptr->ig3s_c2 = sptr_array_ptr->ig3s_c2; + next_free_sptr->ig3s_x2 = sptr_array_ptr->ig3s_x2; + next_free_sptr->ig3s_y = sptr_array_ptr->ig3s_y; + /* Redefine old scan */ + + sptr_array_ptr->ig3s_u2 = mid_u; + sptr_array_ptr->ig3s_v2 = mid_v; + sptr_array_ptr->ig3s_z2 = mid_z; + sptr_array_ptr->ig3s_c2 = mid_c; + sptr_array_ptr->ig3s_x2 = mid_x; + + /* Update pointer and counter */ + + next_free_sptr++; + num_scans_s++; + + } + sptr_array_ptr++; + } + + } + while(StillSubdividing); + + /* Draw the scan array */ + sptr_array_ptr = sptr_array; + for(i = num_scans_s; i!=0; i--) + { + Draw3DScan(sptr_array_ptr,pheader); + sptr_array_ptr++; + } + } + } + sptr++; + } + } +} + + + +void KR_ScanDraw_Item_2dTexturePolygon_VideoModeType_8(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *) itemptr; + if(NumScans) + { + if(pheader->PolyFlags & iflag_nolight) + { + int y; + I_2DTEXTUREPOLYGON_SCAN *sptr = (I_2DTEXTUREPOLYGON_SCAN *) ScanData; + + /* Offset in Screen Buffer */ + { + IMAGEHEADER *ImageHdr; + { + int TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + } + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + TEXTURE **TxImagePtr = &ImageHdr->ImagePtr; + SCASM_Bitmap = TxImagePtr[MIP_Index]; + GLOBALASSERT(SCASM_Bitmap); + SCASM_TextureDeltaScan = ImageHdr->ImageWidth >> MIP_Index; + #if MIP_ROUNDUP + if (ImageHdr->ImageWidth & (1<ImageWidth; + SCASM_Bitmap = ImageHdr->ImagePtr; + GLOBALASSERT(SCASM_Bitmap); + } + } + + /* Get the Image Data required for the Draw */ + for(y=NumScans; y!=0; y--) + { + int dx = sptr->i2s_x2 - sptr->i2s_x1; + + if (dx>0 && !(sptr->i2s_y & KRenderDrawMode) ) + { + /* Fixed Point U for Interpolation */ + { + int StartU = sptr->i2s_u1; + SCASM_DeltaU = (sptr->i2s_u2 - StartU)/dx; + SCASM_StartU = StartU; + } + + /* Fixed Point V for Interpolation */ + { + int StartV = sptr->i2s_v1; + SCASM_DeltaV = (sptr->i2s_v2 - StartV)/dx; + SCASM_StartV = StartV; + } + + SCASM_Destination = ScreenBuffer + (sptr->i2s_y * BackBufferPitch) + sptr->i2s_x1; + SCASM_ScanLength = dx; + + + /* Is VDelta = 0? */ + if(SCASM_DeltaV == 0) + { + if(pheader->PolyFlags & iflag_ignore0) + { + ScanDraw2D_VAlignedTransparent(); + } + else + { + ScanDraw2D_VAlignedOpaque(); + } + + } + else + { + if(pheader->PolyFlags & iflag_ignore0) + { + ScanDraw2D_Transparent(); + } + else + { + ScanDraw2D_Opaque(); + } + } + } + sptr++; + } + } + #if 1 + else + { + int y; + I_2DTEXTUREPOLYGON_SCAN *sptr = (I_2DTEXTUREPOLYGON_SCAN *) ScanData; + /* Offset in Screen Buffer */ + { + IMAGEHEADER *ImageHdr; + { + int TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + } + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + TEXTURE **TxImagePtr = &ImageHdr->ImagePtr; + SCASM_Bitmap = TxImagePtr[MIP_Index]; + GLOBALASSERT(SCASM_Bitmap); + SCASM_TextureDeltaScan = ImageHdr->ImageWidth >> MIP_Index; + #if MIP_ROUNDUP + if (ImageHdr->ImageWidth & (1<ImageWidth; + SCASM_Bitmap = ImageHdr->ImagePtr; + GLOBALASSERT(SCASM_Bitmap); + } + } + SCASM_StartI = ItemColour >> TxDefn; + + SCASM_Lighting = TextureLightingTable; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_Raw256) SCASM_ShadingTableSize = 256; + else SCASM_ShadingTableSize = 64; + + + /* Get the Image Data required for the Draw */ + for(y=NumScans; y!=0; y--) + { + int dx = sptr->i2s_x2 - sptr->i2s_x1; + if (dx>0 && !(sptr->i2s_y & KRenderDrawMode) ) + { + /* Fixed Point U for Interpolation */ + { + int StartU = sptr->i2s_u1; + SCASM_DeltaU = (sptr->i2s_u2 - StartU)/dx; + SCASM_StartU = StartU; + } + + /* Fixed Point V for Interpolation */ + { + int StartV = sptr->i2s_v1; + SCASM_DeltaV = (sptr->i2s_v2 - StartV)/dx; + SCASM_StartV = StartV; + } + + SCASM_Destination = ScreenBuffer + (sptr->i2s_y * BackBufferPitch) + sptr->i2s_x1; + SCASM_ScanLength = dx; + + ScanDraw2D_TransparentLit(); + // PredatorScanDraw(); + } + sptr++; + } + + + } + #endif + } + +} +unsigned char LighterTable[255]; +int predatorTimer = 0; +void ScanDraw_CloakedScan(void) +{ + unsigned char *screen = SCASM_Destination; + int x = SCASM_ScanLength; + + unsigned char buffer[1000]; + do + { + buffer[x] = *screen++; + } + while(--x); + + screen = SCASM_Destination; + x = SCASM_ScanLength; + + if (FastRandom()&3==3 && x>2) + { + x--; + screen++; + } + if (FastRandom()&3==3 && x>2) + { + x--; + } + + do + { + { + extern sine[]; + extern cosine[]; + unsigned char colour; + int offset = (GetCos( ((x*2047)/SCASM_ScanLength + predatorTimer)&4095 )+65536)/2; + offset = MUL_FIXED(offset,offset); + colour = (buffer[SCASM_ScanLength-x+1]); + // colour = (buffer[x]); + #if 0 + int i; + for (i=0; i<=255;i++) + { + if (colour==*(TextureLightingTable + 256*200 + i)) break; + } + #endif + colour=*(TextureLightingTable + 256*(60+MUL_FIXED(4,GetCos(predatorTimer&4095)) ) + colour); + *screen++ = colour; + + } + } + while(--x); + +} +#if 0 +void PredatorScanDraw(void) +{ + unsigned char *screen = SCASM_Destination; + unsigned char *source; + + do + { + source = SCASM_Bitmap+ (SCASM_StartU>>16) + (SCASM_StartV>>16)*SCASM_TextureDeltaScan; + + *screen++ = *source++; + + SCASM_StartU += SCASM_DeltaU; + SCASM_StartV += SCASM_DeltaV; + } + while(--SCASM_ScanLength); + +} +#else +void PredatorScanDraw(void) +{ + unsigned char *screen = SCASM_Destination; + unsigned char *source; + int x = SCASM_ScanLength; + do + { + source = SCASM_Bitmap+ (SCASM_StartU>>16) + (SCASM_StartV>>16)*SCASM_TextureDeltaScan; + + if (*source) + { + extern sine[]; + extern cosine[]; + unsigned char colour = *(screen); + *screen = LighterTable[colour]; + } + screen++; + SCASM_StartU += SCASM_DeltaU; + SCASM_StartV += SCASM_DeltaV; + } + while(--x); + +} +#endif + +void Draw_Item_CloakedPolygon(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *)itemptr; + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + + { + I_GOURAUDPOLYGON_PT *vertexPtr = (I_GOURAUDPOLYGON_PT*)&pheader->Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_GOURAUDPOLYGON_PT *vertexPtr = (I_GOURAUDPOLYGON_PT*)&pheader->Poly1stPt; + I_GOURAUDPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion=0; + + NumScans=0; + /* scan out the right edge */ + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + int i,x,y; + int deltaX,deltaI; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_int - vertexPtr[curVertex].i_int; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_int; + + for (y=vertexPtr[curVertex].i_y; yigs_x2 = x>>16; + x+=deltaX; + polyScan->igs_c2 = i; + i+=deltaI; + + polyScan->igs_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + int i,x,y; + int deltaX,deltaI; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_int - vertexPtr[curVertex].i_int; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_int; + + for (y=vertexPtr[curVertex].i_y; yigs_x1 = x>>16; + x+=deltaX; + polyScan->igs_c1 = i; + i+=deltaI; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionPolyColour; + I_GOURAUDPOLYGON_SCAN *polyScan; + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + SCASM_Lighting = TextureLightingTable+colour; + SCASM_ShadingTableSize = 256; + + while(NumScans) + { + int dx = polyScan->igs_x2 - polyScan->igs_x1; + if (dx>0) + { + SCASM_Destination = ScreenBuffer+(polyScan->igs_y * BackBufferPitch) + polyScan->igs_x1; + SCASM_ScanLength = dx; + SCASM_DeltaI = (polyScan->igs_c2-polyScan->igs_c1)/dx; + SCASM_StartI = polyScan->igs_c1; + ScanDraw_CloakedScan(); + } + NumScans--; + polyScan++; + } + } +} +#if 1 +void KDraw_Item_GouraudPolygon(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *)itemptr; + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + + { + I_GOURAUDPOLYGON_PT *vertexPtr = (I_GOURAUDPOLYGON_PT*)&pheader->Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_GOURAUDPOLYGON_PT *vertexPtr = (I_GOURAUDPOLYGON_PT*)&pheader->Poly1stPt; + I_GOURAUDPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion=0; + + NumScans=0; + /* scan out the right edge */ + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + int i,x,y; + int deltaX,deltaI; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_int - vertexPtr[curVertex].i_int; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_int; + + for (y=vertexPtr[curVertex].i_y; yigs_x2 = x>>16; + x+=deltaX; + polyScan->igs_c2 = i; + i+=deltaI; + + polyScan->igs_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + int i,x,y; + int deltaX,deltaI; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_int - vertexPtr[curVertex].i_int; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_int; + + for (y=vertexPtr[curVertex].i_y; yigs_x1 = x>>16; + x+=deltaX; + polyScan->igs_c1 = i; + i+=deltaI; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionPolyColour; + I_GOURAUDPOLYGON_SCAN *polyScan; + polyScan = (I_GOURAUDPOLYGON_SCAN*)ScanData; + SCASM_Lighting = TextureLightingTable+colour; + SCASM_ShadingTableSize = 256; + + while(NumScans) + { + int dx = polyScan->igs_x2 - polyScan->igs_x1; + if (dx>0) + { + SCASM_Destination = ScreenBuffer+(polyScan->igs_y * BackBufferPitch) + polyScan->igs_x1; + SCASM_ScanLength = dx; + SCASM_DeltaI = (polyScan->igs_c2-polyScan->igs_c1)/dx; + SCASM_StartI = polyScan->igs_c1; + ScanDraw_GouraudScan(); + } + NumScans--; + polyScan++; + } + } +} +void KDraw_Item_2dTexturePolygon(int *itemptr) +{ + + POLYHEADER *pheader = (POLYHEADER *) itemptr; + int TxIndex; + IMAGEHEADER *ImageHdr; + ItemColour = pheader->PolyColour; + + TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + + + /* Colour */ + + /* If MIP Mapping, calculate the scale */ + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + I_2DTEXTUREPOLYGON_PT *vector1; + I_2DTEXTUREPOLYGON_PT *vector2; + I_2DTEXTUREPOLYGON_PT *vector3; + int mip1, mip2; + int xyd, uvd; + VECTOR2D s0, s1; + VECTOR2D t0, t1; + + + /* Screen and Texture Space Vectors */ + /* Express the "uvd / xyd" ratio as a binary scale */ + + vector1 = (I_2DTEXTUREPOLYGON_PT *) &pheader->Poly1stPt; + vector2 = &vector1[1]; + vector3 = &vector1[2]; + + + /* Vector 1 */ + + s0.vx = vector1->i_x; + s0.vy = vector1->i_y; + s1.vx = vector2->i_x; + s1.vy = vector2->i_y; + + t0.vx = vector1->i_u >> 16; + t0.vy = vector1->i_v >> 16; + t1.vx = vector2->i_u >> 16; + t1.vy = vector2->i_v >> 16; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip1 = FindShift32(uvd, xyd); + + + /* Vector 2 */ + + s0.vx = vector2->i_x; + s0.vy = vector2->i_y; + s1.vx = vector3->i_x; + s1.vy = vector3->i_y; + + t0.vx = t1.vx; + t0.vy = t1.vy; + t1.vx = vector3->i_u >> 16; + t1.vy = vector3->i_v >> 16; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip2 = FindShift32(uvd, xyd); + + + /* Choose the larger of the two */ + + if(pheader->PolyFlags & iflag_no_mip) { + + MIP_Index = 0; + + } + + else { + + #if UseMIPMax + if(mip1 > mip2) + MIP_Index = mip1; + else + MIP_Index = mip2; + #endif + + #if UseMIPMin + if(mip1 > mip2) + MIP_Index = mip2; + else + MIP_Index = mip1; + #endif + + #if UseMIPAvg + MIP_Index = (mip1 + mip2) >> 1; + #endif + + } + + + /* Clamp "MIP_Index" */ + + #if MIP_INDEX_SUBTRACT + + MIP_Index -= MIP_INDEX_SUBTRACT; + if(MIP_Index < 0) MIP_Index = 0; + else if(MIP_Index > 6) MIP_Index = 6; + + #else + + if(MIP_Index > 6) MIP_Index = 6; + + #endif + + } + + { + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + + { + I_2DTEXTUREPOLYGON_PT *vertexPtr = (I_2DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_u >>= MIP_Index; + vertexPtr->i_v >>= MIP_Index; + } + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_u >>= MIP_Index; + vertexPtr->i_v >>= MIP_Index; + } + + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_2DTEXTUREPOLYGON_PT *vertexPtr = (I_2DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + I_2DTEXTUREPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion = 0; + + NumScans=0; + /* scan out the right edge */ + polyScan = (I_2DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int x,y,u,v; + int deltaX,deltaU,deltaV; + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int widthU = vertexPtr[nextVertex].i_u - vertexPtr[curVertex].i_u; + int widthV = vertexPtr[nextVertex].i_v - vertexPtr[curVertex].i_v; + + deltaX = (width<<16)/height; + deltaU = widthU/height; + deltaV = widthV/height; + + x = vertexPtr[curVertex].i_x<<16; + u = vertexPtr[curVertex].i_u; + v = vertexPtr[curVertex].i_v; + + for (y=vertexPtr[curVertex].i_y; yi2s_x2 = x>>16; + x+=deltaX; + polyScan->i2s_u2 = u; + u+=deltaU; + polyScan->i2s_v2 = v; + v+=deltaV; + + polyScan->i2s_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_2DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int x,y,u,v; + int deltaX,deltaU,deltaV; + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int widthU = vertexPtr[nextVertex].i_u - vertexPtr[curVertex].i_u; + int widthV = vertexPtr[nextVertex].i_v - vertexPtr[curVertex].i_v; + + deltaX = (width<<16)/height; + deltaU = widthU/height; + deltaV = widthV/height; + + x = vertexPtr[curVertex].i_x<<16; + u = vertexPtr[curVertex].i_u; + v = vertexPtr[curVertex].i_v; + + for (y=vertexPtr[curVertex].i_y; yi2s_x1 = x>>16; + x+=deltaX; + polyScan->i2s_u1 = u; + u+=deltaU; + polyScan->i2s_v1 = v; + v+=deltaV; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionPolyColour; + + TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + + + + /* Colour */ + + + /* If MIP Mapping, calculate the scale */ + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + I_GOURAUD2DTEXTUREPOLYGON_PT *vector1; + I_GOURAUD2DTEXTUREPOLYGON_PT *vector2; + I_GOURAUD2DTEXTUREPOLYGON_PT *vector3; + int mip1, mip2; + int xyd, uvd; + VECTOR2D s0, s1; + VECTOR2D t0, t1; + + + /* Screen and Texture Space Vectors */ + /* Express the "uvd / xyd" ratio as a binary scale */ + + vector1 = (I_GOURAUD2DTEXTUREPOLYGON_PT *) &pheader->Poly1stPt; + vector2 = &vector1[1]; + vector3 = &vector1[2]; + + + /* Vector 1 */ + + s0.vx = vector1->i_x; + s0.vy = vector1->i_y; + s1.vx = vector2->i_x; + s1.vy = vector2->i_y; + + t0.vx = vector1->i_u >> 16; + t0.vy = vector1->i_v >> 16; + t1.vx = vector2->i_u >> 16; + t1.vy = vector2->i_v >> 16; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip1 = FindShift32(uvd, xyd); + + + /* Vector 2 */ + + s0.vx = vector2->i_x; + s0.vy = vector2->i_y; + s1.vx = vector3->i_x; + s1.vy = vector3->i_y; + + t0.vx = t1.vx; + t0.vy = t1.vy; + t1.vx = vector3->i_u >> 16; + t1.vy = vector3->i_v >> 16; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip2 = FindShift32(uvd, xyd); + + + /* Choose the larger of the two */ + + if(pheader->PolyFlags & iflag_no_mip) { + + MIP_Index = 0; + + } + + else { + + #if UseMIPMax + if(mip1 > mip2) + MIP_Index = mip1; + else + MIP_Index = mip2; + #endif + + #if UseMIPMin + if(mip1 > mip2) + MIP_Index = mip2; + else + MIP_Index = mip1; + #endif + + #if UseMIPAvg + MIP_Index = (mip1 + mip2) >> 1; + #endif + + } + + + /* Clamp "MIP_Index" */ + + #if MIP_INDEX_SUBTRACT + + MIP_Index -= MIP_INDEX_SUBTRACT; + if(MIP_Index < 0) MIP_Index = 0; + else if(MIP_Index > 6) MIP_Index = 6; + + #else + + if(MIP_Index > 6) MIP_Index = 6; + + #endif + + } + + { + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + + { + I_GOURAUD2DTEXTUREPOLYGON_PT *vertexPtr = (I_GOURAUD2DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_u >>= MIP_Index; + vertexPtr->i_v >>= MIP_Index; + } + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_u >>= MIP_Index; + vertexPtr->i_v >>= MIP_Index; + } + + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_GOURAUD2DTEXTUREPOLYGON_PT *vertexPtr = (I_GOURAUD2DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + I_GOURAUD2DTEXTUREPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion=0; + + NumScans=0; + /* scan out the right edge */ + polyScan = (I_GOURAUD2DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y,u,v; + int deltaX,deltaI,deltaU,deltaV; + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_i - vertexPtr[curVertex].i_i; + int widthU = vertexPtr[nextVertex].i_u - vertexPtr[curVertex].i_u; + int widthV = vertexPtr[nextVertex].i_v - vertexPtr[curVertex].i_v; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_i; + u = vertexPtr[curVertex].i_u; + v = vertexPtr[curVertex].i_v; + + for (y=vertexPtr[curVertex].i_y; yig2s_x2 = x>>16; + x+=deltaX; + polyScan->ig2s_c2 = i; + i+=deltaI; + polyScan->ig2s_u2 = u; + u+=deltaU; + polyScan->ig2s_v2 = v; + v+=deltaV; + + polyScan->ig2s_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_GOURAUD2DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y,u,v; + int deltaX,deltaI,deltaU,deltaV; + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_i - vertexPtr[curVertex].i_i; + int widthU = vertexPtr[nextVertex].i_u - vertexPtr[curVertex].i_u; + int widthV = vertexPtr[nextVertex].i_v - vertexPtr[curVertex].i_v; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_i; + u = vertexPtr[curVertex].i_u; + v = vertexPtr[curVertex].i_v; + + for (y=vertexPtr[curVertex].i_y; yig2s_x1 = x>>16; + x+=deltaX; + polyScan->ig2s_c1 = i; + i+=deltaI; + polyScan->ig2s_u1 = u; + u+=deltaU; + polyScan->ig2s_v1 = v; + v+=deltaV; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionPolyColour; + I_GOURAUD2DTEXTUREPOLYGON_SCAN *polyScan; + polyScan = (I_GOURAUD2DTEXTUREPOLYGON_SCAN*)ScanData; + SCASM_Lighting = TextureLightingTable+colour; + SCASM_ShadingTableSize = 256; + + while(NumScans) + { + int dx = polyScan->ig2s_x2 - polyScan->ig2s_x1; + if (dx>0) + { + SCASM_Destination = ScreenBuffer+(polyScan->ig2s_y * BackBufferPitch) + polyScan->ig2s_x1; + SCASM_ScanLength = dx; + SCASM_DeltaI = (polyScan->ig2s_c2-polyScan->ig2s_c1)/dx; + SCASM_StartI = polyScan->ig2s_c1; + ScanDraw_GouraudScan(); + } + NumScans--; + polyScan++; + } + } + #endif + } +} +#endif +#if 0 +void KDraw_Item_Gouraud3dTexturePolygon(int *itemptr) +{ + POLYHEADER *pheader = (POLYHEADER *) itemptr; + int TxIndex; + IMAGEHEADER *ImageHdr; + ItemColour = pheader->PolyColour; + + TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + + + + /* Colour */ + + + /* If MIP Mapping, calculate the scale */ + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + I_GOURAUD3DTEXTUREPOLYGON_PT *vector1; + I_GOURAUD3DTEXTUREPOLYGON_PT *vector2; + I_GOURAUD3DTEXTUREPOLYGON_PT *vector3; + int mip1, mip2; + int xyd, uvd; + VECTOR2D s0, s1; + VECTOR2D t0, t1; + + + /* Screen and Texture Space Vectors */ + /* Express the "uvd / xyd" ratio as a binary scale */ + + vector1 = (I_GOURAUD3DTEXTUREPOLYGON_PT *) &pheader->Poly1stPt; + vector2 = &vector1[1]; + vector3 = &vector1[2]; + + + /* Vector 1 */ + + s0.vx = vector1->i_x; + s0.vy = vector1->i_y; + s1.vx = vector2->i_x; + s1.vy = vector2->i_y; + + t0.vx = vector1->i_gtx3d_u / vector1->i_gtx3d_z; + t0.vy = vector1->i_gtx3d_v / vector1->i_gtx3d_z; + t1.vx = vector2->i_gtx3d_u / vector2->i_gtx3d_z; + t1.vy = vector2->i_gtx3d_v / vector2->i_gtx3d_z; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip1 = FindShift32(uvd, xyd); + + + /* Vector 2 */ + + s0.vx = vector2->i_x; + s0.vy = vector2->i_y; + s1.vx = vector3->i_x; + s1.vy = vector3->i_y; + + t0.vx = t1.vx; + t0.vy = t1.vy; + t1.vx = vector3->i_gtx3d_u / vector3->i_gtx3d_z; + t1.vy = vector3->i_gtx3d_v / vector3->i_gtx3d_z; + + xyd = FandVD_Distance_2d(&s0, &s1); + uvd = FandVD_Distance_2d(&t0, &t1); + + mip2 = FindShift32(uvd, xyd); + + + /* Choose the larger of the two */ + + if(pheader->PolyFlags & iflag_no_mip) { + + MIP_Index = 0; + + } + + else { + + #if UseMIPMax + if(mip1 > mip2) + MIP_Index = mip1; + else + MIP_Index = mip2; + #endif + + #if UseMIPMin + if(mip1 > mip2) + MIP_Index = mip2; + else + MIP_Index = mip1; + #endif + + #if UseMIPAvg + MIP_Index = (mip1 + mip2) >> 1; + #endif + + } + + + /* Clamp "MIP_Index" */ + + #if MIP_INDEX_SUBTRACT + + MIP_Index -= MIP_INDEX_SUBTRACT; + if(MIP_Index < 0) MIP_Index = 0; + else if(MIP_Index > 6) MIP_Index = 6; + + #else + + if(MIP_Index > 6) MIP_Index = 6; + + #endif + + } + + { + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + float MIP_Divide = 1<Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_gtx3d_u /= MIP_Divide; + vertexPtr->i_gtx3d_v /= MIP_Divide; + } + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + + if(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_MIP && ImageHdr->ImageFlags & ih_flag_mip) + { + vertexPtr->i_gtx3d_u /= MIP_Divide; + vertexPtr->i_gtx3d_v /= MIP_Divide; + } + + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_GOURAUD3DTEXTUREPOLYGON_PT *vertexPtr = (I_GOURAUD3DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + I_GOURAUD3DTEXTUREPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion=0; + + NumScans=0; + + /* scan out the right edge */ + polyScan = (I_GOURAUD3DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y; + float u,v,z; + int deltaX,deltaI; + float deltaU,deltaV,deltaZ; + + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_gtx3d_i - vertexPtr[curVertex].i_gtx3d_i; + float widthU = vertexPtr[nextVertex].i_gtx3d_u - vertexPtr[curVertex].i_gtx3d_u; + float widthV = vertexPtr[nextVertex].i_gtx3d_v - vertexPtr[curVertex].i_gtx3d_v; + float widthZ = vertexPtr[nextVertex].i_gtx3d_z - vertexPtr[curVertex].i_gtx3d_z; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + deltaZ = widthZ/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_gtx3d_i; + u = vertexPtr[curVertex].i_gtx3d_u; + v = vertexPtr[curVertex].i_gtx3d_v; + z = vertexPtr[curVertex].i_gtx3d_z; + + for (y=vertexPtr[curVertex].i_y; yig3s_x2 = x>>16; + x+=deltaX; + polyScan->ig3s_c2 = i; + i+=deltaI; + polyScan->ig3s_u2 = u; + u+=deltaU; + polyScan->ig3s_v2 = v; + v+=deltaV; + polyScan->ig3s_z2 = z; + z+=deltaZ; + + polyScan->ig3s_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_GOURAUD3DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y; + float u,v,z; + int deltaX,deltaI; + float deltaU,deltaV,deltaZ; + + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_gtx3d_i - vertexPtr[curVertex].i_gtx3d_i; + float widthU = vertexPtr[nextVertex].i_gtx3d_u - vertexPtr[curVertex].i_gtx3d_u; + float widthV = vertexPtr[nextVertex].i_gtx3d_v - vertexPtr[curVertex].i_gtx3d_v; + float widthZ = vertexPtr[nextVertex].i_gtx3d_z - vertexPtr[curVertex].i_gtx3d_z; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + deltaZ = widthZ/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_gtx3d_i; + u = vertexPtr[curVertex].i_gtx3d_u; + v = vertexPtr[curVertex].i_gtx3d_v; + z = vertexPtr[curVertex].i_gtx3d_z; + + for (y=vertexPtr[curVertex].i_y; yig3s_x1 = x>>16; + x+=deltaX; + polyScan->ig3s_c1 = i; + i+=deltaI; + polyScan->ig3s_u1 = u; + u+=deltaU; + polyScan->ig3s_v1 = v; + v+=deltaV; + polyScan->ig3s_z1 = z; + z+=deltaZ; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionPolyColour; + + TxIndex = ItemColour & ClrTxDefn; + ImageHdr = ImageHeaderPtrs[TxIndex]; + + + + { + int minYVertex = 0; + int maxYVertex = 0; + int maxVertexNum = 0; + + + { + I_GOURAUD3DTEXTUREPOLYGON_PT *vertexPtr = (I_GOURAUD3DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + int minY = vertexPtr->i_y; + int maxY = vertexPtr->i_y; + + vertexPtr++; + + do + { + maxVertexNum++; + + if (minY > vertexPtr->i_y) + { + minY = vertexPtr->i_y; + minYVertex = maxVertexNum; + } + else if (maxY < vertexPtr->i_y) + { + maxY = vertexPtr->i_y; + maxYVertex = maxVertexNum; + } + + vertexPtr++; + } + while(vertexPtr->i_x != Term); + + } + + + /* Initialise the Scan Data Buffer */ + { + I_GOURAUD3DTEXTUREPOLYGON_PT *vertexPtr = (I_GOURAUD3DTEXTUREPOLYGON_PT*)&pheader->Poly1stPt; + I_GOURAUD3DTEXTUREPOLYGON_SCAN *polyScan; + int curVertex; + int SecondOpinion=0; + + NumScans=0; + + /* scan out the right edge */ + polyScan = (I_GOURAUD3DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex-1; + if (nextVertex<0) nextVertex = maxVertexNum; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y; + float u,v,z; + int deltaX,deltaI; + float deltaU,deltaV,deltaZ; + + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_gtx3d_i - vertexPtr[curVertex].i_gtx3d_i; + float widthU = vertexPtr[nextVertex].i_gtx3d_u - vertexPtr[curVertex].i_gtx3d_u; + float widthV = vertexPtr[nextVertex].i_gtx3d_v - vertexPtr[curVertex].i_gtx3d_v; + float widthZ = vertexPtr[nextVertex].i_gtx3d_z - vertexPtr[curVertex].i_gtx3d_z; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + deltaZ = widthZ/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_gtx3d_i; + u = vertexPtr[curVertex].i_gtx3d_u; + v = vertexPtr[curVertex].i_gtx3d_v; + z = vertexPtr[curVertex].i_gtx3d_z; + + for (y=vertexPtr[curVertex].i_y; yig3s_x2 = x>>16; + x+=deltaX; + polyScan->ig3s_c2 = i; + i+=deltaI; + polyScan->ig3s_u2 = u; + u+=deltaU; + polyScan->ig3s_v2 = v; + v+=deltaV; + polyScan->ig3s_z2 = z; + z+=deltaZ; + + polyScan->ig3s_y = y; + NumScans++; + polyScan++; + } + } + curVertex--; + if (curVertex<0) curVertex = maxVertexNum; + + } + while(curVertex!=maxYVertex); + + /* scan out the left edge */ + polyScan = (I_GOURAUD3DTEXTUREPOLYGON_SCAN*)ScanData; + curVertex = minYVertex; + do + { + int height; + + int nextVertex = curVertex+1; + if (nextVertex>maxVertexNum) nextVertex = 0; + + height = vertexPtr[nextVertex].i_y - vertexPtr[curVertex].i_y; + if (height!=0) + { + int i,x,y; + float u,v,z; + int deltaX,deltaI; + float deltaU,deltaV,deltaZ; + + int width = vertexPtr[nextVertex].i_x - vertexPtr[curVertex].i_x; + int contrast = vertexPtr[nextVertex].i_gtx3d_i - vertexPtr[curVertex].i_gtx3d_i; + float widthU = vertexPtr[nextVertex].i_gtx3d_u - vertexPtr[curVertex].i_gtx3d_u; + float widthV = vertexPtr[nextVertex].i_gtx3d_v - vertexPtr[curVertex].i_gtx3d_v; + float widthZ = vertexPtr[nextVertex].i_gtx3d_z - vertexPtr[curVertex].i_gtx3d_z; + + deltaX = (width<<16)/height; + deltaI = contrast/height; + deltaU = widthU/height; + deltaV = widthV/height; + deltaZ = widthZ/height; + + x = vertexPtr[curVertex].i_x<<16; + i = vertexPtr[curVertex].i_gtx3d_i; + u = vertexPtr[curVertex].i_gtx3d_u; + v = vertexPtr[curVertex].i_gtx3d_v; + z = vertexPtr[curVertex].i_gtx3d_z; + + for (y=vertexPtr[curVertex].i_y; yig3s_x1 = x>>16; + x+=deltaX; + polyScan->ig3s_c1 = i; + i+=deltaI; + polyScan->ig3s_u1 = u; + u+=deltaU; + polyScan->ig3s_v1 = v; + v+=deltaV; + polyScan->ig3s_z1 = z; + z+=deltaZ; + + SecondOpinion++; + polyScan++; + } + } + curVertex++; + if (curVertex>maxVertexNum) curVertex = 0; + + } + while(curVertex!=maxYVertex); + + if (SecondOpinionImageWidth; + SCASM_Bitmap = ImageHdr->ImagePtr; + GLOBALASSERT(SCASM_Bitmap); + } + } + SCASM_Lighting = TextureLightingTable; + + sptr = (I_GOURAUD3DTEXTUREPOLYGON_SCAN *) ScanData; + do + { + int length = sptr->ig3s_x2 - sptr->ig3s_x1; + int dx=length; + + if (dx>0 && !(sptr->ig3s_y & KRenderDrawMode) ) + { + float deltaZ; + float endZ; + + float endU,endV; + float deltaU,deltaV; + + { + int StartI = sptr->ig3s_c1; + SCASM_DeltaI = (sptr->ig3s_c2 - StartI)/dx; + SCASM_StartI = StartI; + } + + SCASM_Destination = ScreenBuffer + (sptr->ig3s_y * BackBufferPitch) + sptr->ig3s_x1; + SCASM_ScanLength = PERS_STEP; + + { + float oneOverdx = 1.0/dx; + + endZ = sptr->ig3s_z1; + deltaZ = (sptr->ig3s_z2 - endZ)*oneOverdx; + + endU = sptr->ig3s_u1; + deltaU = (sptr->ig3s_u2 - endU)*oneOverdx; + + endV = sptr->ig3s_v1; + deltaV = (sptr->ig3s_v2 - endV)*oneOverdx; + } + { + float z = 65536.0/endZ; + SCASM_StartU = endU*z; + SCASM_StartV = endV*z; + } + while(dx>PERS_STEP) + { + /* subdivide! */ + int u,v; + + dx -= PERS_STEP; + + endZ += PERS_STEP*deltaZ; + endU += PERS_STEP*deltaU; + endV += PERS_STEP*deltaV; + + { + float z = 65536.0/endZ; + u = endU*z; + v = endV*z; + } + SCASM_DeltaU = (u-SCASM_StartU)/PERS_STEP; + SCASM_DeltaV = (v-SCASM_StartV)/PERS_STEP; + + /* draw PERS_STEP pixels */ + ScanDraw2D_Gouraud(); + + SCASM_StartU = u; + SCASM_StartV = v; + + SCASM_Destination +=PERS_STEP; + SCASM_StartI += PERS_STEP*SCASM_DeltaI; + } + if (dx>0) + { + int u,v; + SCASM_ScanLength = dx; + { + float z = 65536.0/sptr->ig3s_z2; + u = sptr->ig3s_u2*z; + v = sptr->ig3s_v2*z; + } + SCASM_DeltaU = (u-SCASM_StartU)/dx; + SCASM_DeltaV = (v-SCASM_StartV)/dx; + + /* draw 8 pixels */ + ScanDraw2D_Gouraud(); + } + + + + + + } + sptr++; + y--; + } + while(y); + } + +} +#endif + + + + + + + + + + + +#if 0 +void MakeInverseLightingTable(void) +{ + int lookingForColour; + + for(lookingForColour=1; lookingForColour<=255; lookingForColour++) + { + int exit =0; + int table; + for (table=128; (table>0 && (!exit)); table--) + { + int entry; + for(entry=1; (entry<=255 && (!exit)); entry++) + { + if(lookingForColour == *(TextureLightingTable + 256*(table) + entry)) + { + LighterTable[lookingForColour] = entry; + exit=1; + } + } + } + if (exit==0) LighterTable[lookingForColour] = 255; + } +} +#endif +struct ColourVector +{ + VECTORCH Direction; + int Magnitude; +}; + +struct ColourVector ColourTable[256]; + +void MakeInverseLightingTable(void) +{ + extern unsigned char TestPalette[]; + unsigned char *palPtr = TestPalette; + int i; + + for(i = 0; i < 256; i++) + { + VECTORCH colour; + int mag; + + colour.vx = *palPtr++; + colour.vy = *palPtr++; + colour.vz = *palPtr++; + mag = Magnitude(&colour); + + if (mag!=0) + { + colour.vx = (colour.vx*32)/mag; + colour.vy = (colour.vy*32)/mag; + colour.vz = (colour.vz*32)/mag; + } + ColourTable[i].Magnitude = mag; + ColourTable[i].Direction = colour; + } + + for(i = 0; i < 256; i++) + { + int entry; + int brightest=0; + + for(entry = 0; entry < 256; entry++) + { + VECTORCH v1 = ColourTable[i].Direction; + VECTORCH v2 = ColourTable[entry].Direction; + + if ((v1.vx == v2.vx) + &&(v1.vy == v2.vy) + &&(v1.vz == v2.vz) + &&(ColourTable[i].Magnitude < ColourTable[entry].Magnitude) + &&(ColourTable[brightest].Magnitude > ColourTable[entry].Magnitude ||(!brightest))) + brightest = entry; + } + if (brightest==0) + { + for(entry = 0; entry < 256; entry++) + { + VECTORCH v1 = ColourTable[i].Direction; + VECTORCH v2 = ColourTable[entry].Direction; + + if ((v1.vx>>2 == v2.vx>>1) + &&(v1.vy>>2 == v2.vy>>1) + &&(v1.vz>>2 == v2.vz>>1) + &&(ColourTable[i].Magnitude < ColourTable[entry].Magnitude) + &&(ColourTable[brightest].Magnitude > ColourTable[entry].Magnitude ||(!brightest))) + + brightest = entry; + } + } + + if (brightest==0) + { + for(entry = 0; entry < 256; entry++) + { + VECTORCH v1 = ColourTable[i].Direction; + VECTORCH v2 = ColourTable[entry].Direction; + + if ((v1.vx>>2 == v2.vx>>2) + &&(v1.vy>>2 == v2.vy>>2) + &&(v1.vz>>2 == v2.vz>>2) + &&(ColourTable[i].Magnitude < ColourTable[entry].Magnitude) + &&(ColourTable[brightest].Magnitude > ColourTable[entry].Magnitude ||(!brightest))) + brightest = entry; + } + } + #if 0 + if (brightest==0) + { + for(entry = 0; entry < 256; entry++) + { + VECTORCH v1 = ColourTable[i].Direction; + VECTORCH v2 = ColourTable[entry].Direction; + + if ((v1.vx>>3 == v2.vx>>3) + &&(v1.vy>>3 == v2.vy>>3) + &&(v1.vz>>3 == v2.vz>>3) + &&(ColourTable[i].Magnitude < ColourTable[entry].Magnitude) + &&(ColourTable[brightest].Magnitude > ColourTable[entry].Magnitude ||(!brightest))) + brightest = entry; + } + } + + #endif + if (brightest==0) brightest = i; + + LighterTable[i] = brightest; + } + + +} + + +void DrawPaletteScreen(void) +{ + int sortedColours[256]; + { + extern unsigned char TestPalette[]; + unsigned char *palPtr = TestPalette; + int i; + + for(i = 0; i < 256; i++) + { + VECTORCH colour; + int mag; + + colour.vx = *palPtr++; + colour.vy = *palPtr++; + colour.vz = *palPtr++; + mag = Magnitude(&colour); + + if (mag!=0) + { + colour.vx = (colour.vx*7)/mag; + colour.vy = (colour.vy*7)/mag; + colour.vz = (colour.vz*7)/mag; + } + ColourTable[i].Magnitude = mag; + ColourTable[i].Direction = colour; + } + + for(i = 0; i<256; i++) + { + int e; + int maxKey=-1; + int selectedEntry=0; + + for (e=0; e<256; e++) + { + int key = ColourTable[e].Direction.vx + ColourTable[e].Direction.vy*64+ColourTable[e].Direction.vz*64*64; + if (key>maxKey) + { + maxKey = key; + selectedEntry = e; + } + else if (key==maxKey) + { + if (ColourTable[e].MagnitudemaxKey) + { + maxKey = key; + selectedEntry = e; + } + else if (key==maxKey) + { + int key2 = ColourTable[e].Direction.vx + ColourTable[e].Direction.vy*64+ColourTable[e].Direction.vz*64*64; + int key3 = ColourTable[selectedEntry].Direction.vx + + ColourTable[selectedEntry].Direction.vy*64 + + ColourTable[selectedEntry].Direction.vz*64*64; + + if (key2>16; + } + } + ChangePalette(TestPalette2); + } + else + { + d3d_light_ctrl.ctrl = LCCM_CONSTCOLOUR; + d3d_light_ctrl.r = fadeLevel; + d3d_light_ctrl.g = fadeLevel; + d3d_light_ctrl.b = fadeLevel; + } +} + +void FadeBetweenPalettes(unsigned char *palPtr, int fadeLevel) +{ + extern unsigned char TestPalette[]; + unsigned char TestPalette3[768]; + { + int x; + for (x=0; x<768; x++) + { + TestPalette3[x] = ( (unsigned int)TestPalette[x]*fadeLevel + (unsigned int)(palPtr[x])*(65536-fadeLevel) )>>16; + } + } + ChangePalette(TestPalette3); +} +void FadePaletteToWhite(unsigned char *palPtr,int fadeLevel) +{ + unsigned char TestPalette3[768]; + { + int x; + for (x=0; x<768; x++) + { + TestPalette3[x] = ( (unsigned int)(palPtr[x])*fadeLevel + 63*(65536-fadeLevel) )>>16; + } + } + ChangePalette(TestPalette3); +} + + +void BlankScreen(void) +{ + extern int ScanDrawMode; + + if (ScanDrawDirectDraw==ScanDrawMode) + { + extern unsigned char *ScreenBuffer; + extern unsigned char TestPalette[]; + unsigned int *screenPtr; + int i; + + screenPtr = (unsigned int *)ScreenBuffer; + i = ScreenDescriptorBlock.SDB_Width * ScreenDescriptorBlock.SDB_Height /4; + do + { + *screenPtr++=0; + } + while(--i); + } + else + { + ColourFillBackBuffer(0); + } + + // FlipBuffers(); +} + + + + +void GenerateReciprocalTable(void) +{ + int i=320; + + do + { + ReciprocalTable[i] = 65536/i; + } + while(--i); +} + + + + +#if 0 +#define NO_OF_STARS 500 +typedef struct +{ + VECTORCH Position; + int Colour; + +} STARDESC; +static STARDESC StarArray[NO_OF_STARS]; +#endif +void CreateStarArray(void) +{ + #if 0 + int i; + extern int sine[],cosine[]; + for(i=0; iVDB_Mat)); + + /* is star within alien (wide) view frustrum ? */ + if((-rotatedPosition.vx <= rotatedPosition.vz*2) + &&(rotatedPosition.vx <= rotatedPosition.vz*2) + &&(-rotatedPosition.vy*2 <= rotatedPosition.vz*3) + &&(rotatedPosition.vy*2 <= rotatedPosition.vz*3)) + { + /* project into screen space */ + int y = (rotatedPosition.vy*(Global_VDB_Ptr->VDB_ProjY))/rotatedPosition.vz+Global_VDB_Ptr->VDB_CentreY; + int x = (rotatedPosition.vx*(Global_VDB_Ptr->VDB_ProjX))/rotatedPosition.vz+Global_VDB_Ptr->VDB_CentreX; + + /* draw pixel of required bit depth */ + if (ScanDrawMode == ScanDrawDirectDraw) + { + /* 8 bit mode */ + *(ScreenBuffer + x + y*BackBufferPitch) = StarArray[i].Colour&255; + } + else + { + /* 16 bit mode */ + *(unsigned short*)(ScreenBuffer + (x*2 + y*BackBufferPitch)) = StarArray[i].Colour; + } + } + } + } + else /* normal frustrum */ + { + for(i=0; iVDB_Mat)); + + /* is star within normal view frustrum ? */ + if((-rotatedPosition.vx <= rotatedPosition.vz) + &&(rotatedPosition.vx <= rotatedPosition.vz) + &&(-rotatedPosition.vy*4 <= rotatedPosition.vz*3) + &&(rotatedPosition.vy*4 <= rotatedPosition.vz*3)) + { + /* project into screen space */ + int y = (rotatedPosition.vy*(Global_VDB_Ptr->VDB_ProjY))/rotatedPosition.vz+Global_VDB_Ptr->VDB_CentreY; + int x = (rotatedPosition.vx*(Global_VDB_Ptr->VDB_ProjX))/rotatedPosition.vz+Global_VDB_Ptr->VDB_CentreX; + + /* draw pixel of required bit depth */ + if (ScanDrawMode == ScanDrawDirectDraw) + { + /* 8 bit mode */ + *(ScreenBuffer + x + y*BackBufferPitch) = StarArray[i].Colour&255; + } + else + { + /* 16 bit mode */ + *(unsigned short*)(ScreenBuffer + (x*2 + y*BackBufferPitch)) = StarArray[i].Colour; + } + } + } + } + + UnlockSurface(); + #endif +} \ No newline at end of file -- cgit v1.3