Main Page | Alphabetical List | Compound List | File List | Compound Members | File Members

render.c

Go to the documentation of this file.
00001 /****************************************************************************************/
00002 /*  render.c                                                                            */
00003 /*                                                                                      */
00004 /*  Author:       John Pollard, Ken Baird                                               */
00005 /*  Description:  Poly raster calls and data structures                                 */
00006 /*                                                                                      */
00007 /*  The contents of this file are subject to the Genesis3D Public License               */
00008 /*  Version 1.01 (the "License"); you may not use this file except in                   */
00009 /*  compliance with the License. You may obtain a copy of the License at                */
00010 /*  http://www.genesis3d.com                                                            */
00011 /*                                                                                      */
00012 /*  Software distributed under the License is distributed on an "AS IS"                 */
00013 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */
00014 /*  the License for the specific language governing rights and limitations              */
00015 /*  under the License.                                                                  */
00016 /*                                                                                      */
00017 /*  The Original Code is Genesis3D, released March 25, 1999.                            */
00018 /*Genesis3D Version 1.1 released November 15, 1999                            */
00019 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */
00020 /*                                                                                      */
00021 /****************************************************************************************/
00022 
00023 /*
00024 Code fragments from Chris Hecker's texture mapping articles used with
00025 permission.  http://www.d6.com/users/checker 
00026 */
00027 
00028 #include <Windows.h>
00029 #include <Stdio.h>
00030 #include <Assert.h>
00031 #include <Math.h>
00032 
00033 #include "SoftDrv.h"
00034 #include "DCommon.h"
00035 #include "Render.h"
00036 #include "Span.h"
00037 #include "Scene.h"
00038 #include "Sal.h"
00039 #include "Register.h"
00040 #include "3dnowspan.h"
00041 #include "x86span565.h"
00042 #include "x86span555.h"
00043 #include "XForm3d.h"
00044 #include "Vec3d.h"
00045 #include "dmodes.h"
00046 
00047 
00048 
00049 
00050 extern          CPUInfo                 ProcessorInfo;
00051 
00052 typedef struct EdgeAsmWorldTag
00053 {
00054         int             X, y, Height;
00055         geFloat x, r, g, b;
00056         geFloat xstep, rstep, gstep, bstep;
00057         U32             R, G, B, X2, pad;       //x2 for clip check
00058 } EdgeAsmWorld;
00059 
00060 typedef struct EdgeAsmTag
00061 {
00062         int             X, y, Height;
00063         geFloat x, u, v, z, r, g, b;
00064         geFloat xstep, ustep, vstep, zstep;
00065         geFloat rstep, gstep, bstep;
00066 } EdgeAsm;
00067 
00068 typedef struct EdgeAsmFPUTag
00069 {
00070         int             X, y, Height;
00071         geFloat x, u, v, z, r, g, b;
00072         geFloat xstep, ustep, vstep, zstep;
00073         geFloat rstep, gstep, bstep;
00074         U32             R, G, B;
00075 } EdgeAsmFPU;
00076 
00077 //globals used in span rendering routines
00078 __int64         Bucket, Bucket2, Bucket3, Magic, Red, Green;
00079 uint32          Blue, UMask, VShift, VMask, widTemp, TDest, TempPix;
00080 
00081 geFloat         BlueMask        =0x001f001f;
00082 geFloat         GreenMask       =0x07e007e0;
00083 geFloat         MiniRedMask     =0xf800f800;
00084 double          RedMask         =0xf800f800;
00085 geFloat         GreenMask2      =0x03e003e0;
00086 geFloat         MiniRedMask2=0x7c007c00;
00087 double          RedMask2        =0x7c007c00;
00088 
00089 
00090 S32                             SpanMode;
00091 S32                             PolyMode;
00092 BOOL                    PolyIsTrans;
00093 BOOL                    bStipple;
00094 
00095 BOOL                    PolyVisible;
00096 S32                             ActuallVisible;
00097 S32                             NumPixels;
00098 
00099 S32                             SMIN, SMAX;
00100 U8                              GMipLevel;                              // Miplevel passed by the latest rendering routine
00101 int32                   GMipLevel4, GMipLevel20, GMipLevel4_8;
00102 S32                             GLMapAdd;
00103 
00104 DRV_LInfo                       *GLInfo;
00105 DRV_Bitmap                      *GBitmap;
00106 geRDriver_THandle       *GTexture;
00107 
00108 U16                             *pScrPtr16bpp;
00109 U32                             *pScrPtr32bpp;
00110 extern                  U16     *pZBufferPtr=0;
00111 
00112 int32                   GLightWidth;
00113 uint8                   *GLightData;
00114 
00115 int32                   DeltaX, Remaining, N_Runs, PixelCount;
00116 uint16                  *Source, *Dest;
00117 int32                   U2, V2, StepU, StepV;
00118 geFloat                 UDivZ, VDivZ, Zi, Z, Dx, Dy, PixelEnd;
00119 int32                   TxWhole, TyWhole, TxFract, TyFract;
00120 geFloat                 UDivZnStepX, VDivZnStepX, ZinStepX;
00121 int32                   Junk[2];
00122 
00123 geFloat                 Real16 = 16.0f; 
00124 geFloat                 Real65536 = (geFloat)65536;
00125 
00126 int32                   U, V;
00127 
00128 S32                             GW, GWMask, GWMaskShifted;
00129 S32                             GH, GHMask, GHMaskShifted, GHMaskShifted16;
00130 __int64                 QNegAlpha       =0x00ff00ff00ff00ff;
00131 U32                             SolidColor      =0xffffffff;
00132 U8                              *GBitPtr;
00133 U8                              *GBitPtrHalf;
00134 U8                              *ABitPtr;
00135 U16                             *GBitPtr16;
00136 U8                              *TexPal;
00137 U8                              *ATexPal;
00138 __int64                 UV16=0, UVLeft=0, UVLeftW=0;
00139 __int64                 UVDivZ16StepX=0, ARL=0, GBL=0;
00140 __int64                 WrapMask=0;
00141 __int64                 UVLeft2=0;
00142 __int64                 UVDivZOrigin=0, UVR=0;
00143 __int64                 ZIR=0, RGBADelta=0;
00144 __int64                 UVDivZStepX=0, UVDivZStepY;
00145 __int64                 Zero=0, UVZ=0, UVAdjustL=0;
00146 __int64                 GLMapMulUV=0, UVL16=0, UV162=0;
00147 __int64                 LMapMask8=0x000000ff000000ff;
00148 __int64                 UVAdjust=0, UVAdjust2=0;
00149 __int64                 QGMip20=0, QGMip4_8=0;
00150 __int64                 QDibCan=0, QZCan=0, VertAlpha=0;
00151 __int64                 QDibOrCan=0, QZOrCan=0;
00152 __int64                 QZVal=0, QZDelta=0, UV16V=0;
00153 __int64                 QZOut=0, QDibOut=0, QShiftV=0;
00154 __int64                 QZVal32_0=0, QZVal32_1=0;
00155 geFloat                 QFixedScaleLUT[34]={ 0.0f, 0.0f, 65536.0f, 65536.0f, 32768.0f, 32768.0f,
00156                                                                         21845.3333f, 21845.3333f, 16384.0f, 16384.0f,
00157                                                                         13107.2f, 13107.2f, 10922.6666f, 10922.6666f,
00158                                                                         9362.2857f, 9362.2857f, 8192.0f, 8192.0f,
00159                                                                         7281.7777f, 7281.7777f, 6553.6f, 6553.6f, 
00160                                                                         5957.8181f, 5957.8181f, 5461.3333f, 5461.3333f,
00161                                                                         5041.2307f, 5041.2307f, 4681.1428f, 4681.1428f,
00162                                                                         4369.0666f, 4369.0666f, 4096.0f, 4096.0f };
00163 int                             SCan[16];       //for zbuffer fake ptr
00164 geFloat                 GLMapMulU;      //lightscale
00165 geFloat                 GLMapMulV;      //lightscale
00166 
00167 // 16bit zbuffer
00168 U16                             *ZBuffer;
00169 uint16                  *ZBufLine;
00170 
00171 // Gradients info
00172 geFloat UDivZStepX;
00173 geFloat UDivZStepY;
00174 geFloat VDivZStepX;
00175 geFloat VDivZStepY;
00176 
00177 geFloat UDivZOrigin;
00178 geFloat VDivZOrigin;
00179 geFloat UDivZ16StepX, VDivZ16StepX, Zi16StepX;
00180 geFloat UDivZ32StepX, VDivZ32StepX, Zi32StepX;
00181 
00182 geFloat ZiStepX;
00183 geFloat ZiStepY;
00184 geFloat ZiOrigin;
00185 
00186 GInfo *GlobalInfo;
00187 
00188 Fixed16 UAdjust;
00189 Fixed16 VAdjust;
00190 Fixed16 UAdjustL;
00191 Fixed16 VAdjustL;
00192 Fixed16 UAdjust1;
00193 Fixed16 VAdjust1;
00194 Fixed16 UAdjust2;
00195 Fixed16 VAdjust2;
00196 
00197 Fixed16 MaxU;
00198 Fixed16 MaxV;
00199 
00200 //magic numbers for geFloat to int conversion
00201 //only works on values between -4194304 and 4194303
00202 geFloat FistMagic=12582912.0f;
00203 geFloat FistTruncate=0.5f;
00204 
00205 
00206 void TmapTriangle_32(DRV_TLVertex *verts);
00207 void TmapTriangle_16(DRV_TLVertex *verts);
00208 
00209 typedef void (* MapperPtr) (EdgeAsm *, EdgeAsm *);
00210 
00211 static MapperPtr        CurMapper;
00212 
00213 typedef void (* MapperPtrFPU) (EdgeAsmFPU *, EdgeAsmFPU *);
00214 
00215 static MapperPtrFPU     CurMapperFPU;
00216 
00217 typedef void (* MapperPtrWorld) (int32 x1, int32 x2, int32 y, geFloat r1, geFloat g1, geFloat b1, geFloat r2, geFloat g2, geFloat b2);
00218 
00219 static MapperPtrWorld   CurMapperWorld;
00220 
00221 typedef void (* MapperPtrWorldFPU) (int32 x1, int32 x2, int32 y, int32 r1, int32 g1, int32 b1, int32 r2, int32 g2, int32 b2);
00222 
00223 static MapperPtrWorldFPU        CurMapperWorldFPU;
00224 
00225 static  geVec3d         TVectU, TVectV;
00226 static  geVec3d         TVectUL, TVectVL;
00227 
00228 static void     CalcGradients(S32 MipLevel, geFloat DrawScaleU, geFloat DrawScaleV)
00229 {
00230         geFloat         MipScale;
00231         geVec3d         SOrigin;
00232         geFloat         t, dsui, dsvi;
00233         Fixed16         UAdjust1L, VAdjust1L;
00234         int                     GW_log2;
00235         geVec3d         Temp    =GlobalInfo->Pov;
00236         geFloat         distinv, ZScaleInv;
00237 
00238         distinv         =1.0f / (GlobalInfo->ZScale * (GlobalInfo->PlaneDist - geVec3d_DotProduct(&Temp, &GlobalInfo->PlaneNormal)));
00239         ZScaleInv       =1.0f / GlobalInfo->ZScale;
00240         dsui            =1.0f / DrawScaleU;
00241         dsvi            =1.0f / DrawScaleV;
00242 
00243         MipScale        =(1.0f / (geFloat)(1 << MipLevel));
00244 
00245         geXForm3d_Rotate(&GlobalInfo->CXForm, &GlobalInfo->VecU, &TVectUL);
00246         geXForm3d_Rotate(&GlobalInfo->CXForm, &GlobalInfo->VecV, &TVectVL);
00247         geVec3d_Scale(&TVectUL, dsui, &TVectU);
00248         geVec3d_Scale(&TVectVL, dsvi, &TVectV);
00249 
00250         t                       =GlobalInfo->XScaleInv * ZScaleInv * MipScale;
00251 
00252         UDivZStepX      =TVectU.X * t;
00253         VDivZStepX      =TVectV.X * t;
00254 
00255         t                       =GlobalInfo->YScaleInv * ZScaleInv * MipScale;
00256 
00257         UDivZStepY      =-TVectU.Y * t;
00258         VDivZStepY      =-TVectV.Y * t;
00259 
00260         GLMapMulU       =DrawScaleU;
00261         GLMapMulV       =DrawScaleV;
00262 
00263         *((geFloat *)(&GLMapMulUV))             =DrawScaleV;
00264         *(((geFloat *)((&GLMapMulUV)))+1)       =DrawScaleU;
00265 
00266         UDivZOrigin     =TVectU.Z * ZScaleInv * MipScale
00267                 - GlobalInfo->XCenter * UDivZStepX
00268                 - GlobalInfo->YCenter * UDivZStepY;
00269 
00270         VDivZOrigin     =TVectV.Z * ZScaleInv * MipScale
00271                 - GlobalInfo->XCenter * VDivZStepX
00272                 - GlobalInfo->YCenter * VDivZStepY;
00273 
00274         geVec3d_Scale(&GlobalInfo->CPov, MipScale, &SOrigin);
00275 
00276         t                       =65536.0f * MipScale;
00277         UAdjust1        =((Fixed16)(geVec3d_DotProduct(&SOrigin, &TVectU) * 65536.0f + 0.5f));
00278         UAdjust1L       =((Fixed16)(geVec3d_DotProduct(&SOrigin, &TVectUL) * 65536.0f + 0.5f));
00279         UAdjust2        =((GlobalInfo->TexMinsX << 16) >> MipLevel);
00280 
00281         VAdjust1        =((Fixed16)(geVec3d_DotProduct(&SOrigin, &TVectV) * 65536.0f + 0.5f));
00282         VAdjust1L       =((Fixed16)(geVec3d_DotProduct(&SOrigin, &TVectVL) * 65536.0f + 0.5f));
00283         VAdjust2        =((GlobalInfo->TexMinsY << 16) >> MipLevel);
00284 
00285         UAdjustL        =UAdjust1L - UAdjust2;
00286         VAdjustL        =VAdjust1L - VAdjust2;
00287 
00288         UAdjust2        =(int)(((geFloat)UAdjust2) * dsui);
00289         VAdjust2        =(int)(((geFloat)VAdjust2) * dsvi);
00290 
00291         *((int *)(&UVAdjustL))          =VAdjustL;
00292         *(((int *)((&UVAdjustL)))+1)=UAdjustL;
00293 
00294         UAdjust         =UAdjust1 - UAdjust2;
00295         VAdjust         =VAdjust1 - VAdjust2;
00296 
00297         *((int *)(&UVAdjust))           =VAdjust;
00298         *(((int *)((&UVAdjust)))+1)     =UAdjust;
00299 
00300         UAdjust1        +=(Fixed16)(GlobalInfo->TexShiftX * t);
00301         VAdjust1        +=(Fixed16)(GlobalInfo->TexShiftY * t);
00302         UAdjust2        +=(Fixed16)(GlobalInfo->TexShiftX * t);
00303         VAdjust2        +=(Fixed16)(GlobalInfo->TexShiftY * t);
00304 
00305         *((int *)(&UVAdjust2))          =VAdjust2;
00306         *(((int *)((&UVAdjust2)))+1)=UAdjust2;
00307 
00308         MaxU            =(((int)((GlobalInfo->TexWidth << 16) * dsui)) >> MipLevel);
00309         MaxV            =(((int)((GlobalInfo->TexHeight << 16) * dsvi)) >> MipLevel);
00310 
00311         *((int *)(&WrapMask))           =GWMask<<16;
00312         *(((int *)((&WrapMask)))+1)     =GWMask<<16;
00313 
00314         //find log2 of the texture width
00315         for(GW_log2=1;((1<<GW_log2) < GW); GW_log2++);
00316 
00317         VShift                  =GW_log2;
00318         GHMaskShifted   =GHMask << (GW_log2);
00319         GHMaskShifted16 =GHMaskShifted << 16;
00320 
00321         QShiftV =(__int64)(16 - GW_log2);
00322 
00323 
00324         ZiStepX         =GlobalInfo->RPlaneNormal.X * GlobalInfo->XScaleInv * distinv;
00325         ZiStepY         =-GlobalInfo->RPlaneNormal.Y * GlobalInfo->YScaleInv * distinv;
00326         ZiOrigin        =GlobalInfo->RPlaneNormal.Z * distinv -
00327                                         GlobalInfo->XCenter * ZiStepX - GlobalInfo->YCenter * ZiStepY;
00328 
00329         // Get 16 step Gradients
00330         UDivZ16StepX    =UDivZStepX * 16.0f;
00331         VDivZ16StepX    =VDivZStepX * 16.0f;
00332         Zi16StepX               =ZiStepX * 16.0f;
00333 
00334         *((U32 *)(&QZDelta))            =(U32)(ZiStepX * -ZBUFFER_PREC);
00335         *(((U32 *)((&QZDelta)))+1)      =(U32)(ZiStepX * -ZBUFFER_PREC);
00336 
00337         *(((geFloat *)((&UVDivZ16StepX)))+1)    =UDivZ16StepX;
00338         *((geFloat *)(&UVDivZ16StepX))          =VDivZ16StepX;
00339 
00340         *(((geFloat *)((&UVDivZStepX)))+1)      =UDivZStepX;
00341         *((geFloat *)(&UVDivZStepX))                    =VDivZStepX;
00342 
00343         *(((geFloat *)((&UVDivZStepY)))+1)      =UDivZStepY;
00344         *((geFloat *)(&UVDivZStepY))                    =VDivZStepY;
00345 
00346         *(((geFloat *)((&UVDivZOrigin)))+1)     =UDivZOrigin;
00347         *((geFloat *)(&UVDivZOrigin))                   =VDivZOrigin;
00348 }
00349 
00350 
00351 BOOL DRIVERCC RenderGouraudPoly(DRV_TLVertex *Pnts, S32 NumPoints, U32 Flags)
00352 {
00353         S32                             i;
00354         DRV_TLVertex    TriVerts[3];
00355 
00356         assert(NumPoints > 2);
00357 
00358         if(!bActive)
00359         {
00360                 return  GE_TRUE;
00361         }
00362 
00363         if(ProcessorInfo.Has3DNow)
00364         {
00365                 if(Flags & DRV_RENDER_NO_ZMASK)
00366                 {
00367                         if(Flags & DRV_RENDER_NO_ZWRITE)
00368                         {
00369                                 CurMapper       =DrawScanLineGouraudNoZSolid_Asm3DNow;
00370                         }
00371                         else
00372                         {
00373                                 CurMapper       =DrawScanLineGouraudNoZBufferZWriteSolid_Asm3DNow;
00374                         }
00375                 }
00376                 else
00377                 {
00378                         if(Flags & DRV_RENDER_NO_ZWRITE)
00379                         {
00380                                 CurMapper       =DrawScanLineGouraudZBufferNoZWriteSolid_Asm3DNow;
00381                         }
00382                         else
00383                         {
00384                                 CurMapper       =DrawScanLineGouraudZBufferSolid_Asm3DNow;
00385                         }
00386                 }
00387 
00388                 if(NumPoints==3)
00389                 {
00390                         TriVerts[2]     =Pnts[0];
00391                         TriVerts[1]     =Pnts[1];
00392                         TriVerts[0]     =Pnts[2];
00393 
00394                         TmapTriangle_32(TriVerts);
00395                 }
00396                 else
00397                 {
00398                         for(i=0;i < NumPoints-2;i++)
00399                         {
00400                                 TriVerts[0]     =Pnts[0];
00401                                 TriVerts[1]     =Pnts[1+i];
00402                                 TriVerts[2]     =Pnts[2+i];
00403 
00404                                 TmapTriangle_32(TriVerts);
00405                         }
00406                 }
00407                 return GE_TRUE;
00408         }
00409         else
00410         {
00411                 if(ClientWindow.G_mask == 0x03e0)
00412                 {
00413                         if(Flags & DRV_RENDER_NO_ZMASK)
00414                         {
00415                                 if(Flags & DRV_RENDER_NO_ZWRITE)
00416                                 {
00417                                         CurMapperFPU    =DrawScanLineGouraudNoZSolid_Asm555X86FPU;
00418                                 }
00419                                 else
00420                                 {
00421                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteSolid_Asm555X86FPU;
00422                                 }
00423                         }
00424                         else
00425                         {
00426                                 if(Flags & DRV_RENDER_NO_ZWRITE)
00427                                 {
00428                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteSolid_Asm555X86FPU;
00429                                 }
00430                                 else
00431                                 {
00432                                         CurMapperFPU    =DrawScanLineGouraudZBufferSolid_Asm555X86FPU;
00433                                 }
00434                         }
00435                 }
00436                 else
00437                 {
00438                         if(Flags & DRV_RENDER_NO_ZMASK)
00439                         {
00440                                 if(Flags & DRV_RENDER_NO_ZWRITE)
00441                                 {
00442                                         CurMapperFPU    =DrawScanLineGouraudNoZSolid_AsmX86FPU;
00443                                 }
00444                                 else
00445                                 {
00446                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteSolid_AsmX86FPU;
00447                                 }
00448                         }
00449                         else
00450                         {
00451                                 if(Flags & DRV_RENDER_NO_ZWRITE)
00452                                 {
00453                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteSolid_AsmX86FPU;
00454                                 }
00455                                 else
00456                                 {
00457                                         CurMapperFPU    =DrawScanLineGouraudZBufferSolid_AsmX86FPU;
00458                                 }
00459                         }
00460                 }
00461                 if(NumPoints==3)
00462                 {
00463                         TriVerts[2]     =Pnts[0];
00464                         TriVerts[1]     =Pnts[1];
00465                         TriVerts[0]     =Pnts[2];
00466 
00467                         TmapTriangle_16(TriVerts);
00468                 }
00469                 else
00470                 {
00471                         for(i=0;i < NumPoints-2;i++)
00472                         {
00473                                 TriVerts[0]     =Pnts[0];
00474                                 TriVerts[1]     =Pnts[1+i];
00475                                 TriVerts[2]     =Pnts[2+i];
00476 
00477                                 TmapTriangle_16(TriVerts);
00478                         }
00479                 }
00480                 return GE_TRUE;
00481         }
00482 }
00483 
00484 void StepWorld(EdgeAsmWorld *edge)
00485 {
00486         int     r,g,b;
00487         _asm
00488         {
00489                 push    ecx
00490                 push    ebx
00491                 push    esi
00492                 push    edi
00493                 push    edx
00494 
00495                 mov     eax,edge
00496                 fld             [eax]EdgeAsmWorld.x             ; x
00497                 fadd    [eax]EdgeAsmWorld.xstep ; xd
00498                 fld             [eax]EdgeAsmWorld.r             ; r   xd
00499                 fadd    [eax]EdgeAsmWorld.rstep ; rd  xd
00500                 fld             [eax]EdgeAsmWorld.g             ; g   rd  xd
00501                 fadd    [eax]EdgeAsmWorld.gstep ; gd  rd  xd
00502                 fld             [eax]EdgeAsmWorld.b             ; b   gd  rd  xd
00503                 fadd    [eax]EdgeAsmWorld.bstep ; bd  gd  rd  xd
00504                 fxch    st(2)                                   ; rd  gd  bd  xd
00505                 fst             [eax]EdgeAsmWorld.r
00506                 fadd    [FistMagic]                     ; rdk gd  bd  xd
00507                 fxch    st(2)                           ; bd  gd  rdk xd
00508                 fst             [eax]EdgeAsmWorld.b
00509                 fadd    [FistMagic]                     ; bdk gd  rdk xd
00510                 fxch    st(1)                           ; gd  bdk rdk xd
00511                 fst             [eax]EdgeAsmWorld.g
00512                 fadd    [FistMagic]                     ; gdk bdk rdk xd
00513                 fxch    st(2)                           ; rdk bdk gdk xd
00514                 fstp    [r]                                     ; bdk gdk xd
00515                 fstp    [b]                                     ; gdk xd
00516                 fstp    [g]                                     ; xd
00517 
00518                 mov             edx,[FistMagic]
00519                 mov             ebx,[r]
00520 
00521                 mov             ecx,[g]
00522                 sub             ebx,edx
00523                 
00524                 mov             esi,[b]
00525                 sub             ecx,edx
00526 
00527                 sub             esi,edx
00528                 and             ebx,0fch
00529 
00530                 fst             [eax]EdgeAsmWorld.x             ; xd
00531 
00532                 and             ecx,0fch
00533                 and             esi,0fch
00534 
00535                 fsub    [FistTruncate]      ; xdt
00536 
00537                 mov             [eax]EdgeAsmWorld.R,ebx
00538                 mov             [eax]EdgeAsmWorld.G,ecx
00539 
00540                 fadd    [FistMagic]         ; xnt
00541 
00542                 mov             [eax]EdgeAsmWorld.B,esi
00543 
00544                 fstp    [eax]EdgeAsmWorld.X
00545 
00546                 sub     [eax]EdgeAsmWorld.X,edx
00547 
00548                 pop             edx
00549                 pop             edi
00550                 pop             esi
00551                 pop             ebx
00552                 pop             ecx
00553         }
00554         edge->y++;
00555         edge->Height--;
00556 }
00557 
00558 void setup_edgeWorld(EdgeAsmWorld *edge, DRV_TLVertex *verts, int top, int end)
00559 {
00560         int             ey,ty;
00561         geFloat yd;
00562 
00563         _asm
00564         {
00565                 push    ebx
00566                 mov             eax,end
00567                 mov     edx,top
00568 
00569                 shl     eax,2
00570                 mov     ebx,verts
00571 
00572                 shl     edx,2
00573                 lea             eax,[8*eax+eax]
00574                 lea             edx,[8*edx+edx]
00575 
00576                 fld             [ebx+eax]DRV_TLVertex.y         ; endy
00577                 fld     [ebx+edx]DRV_TLVertex.y         ; topy endy
00578                 fsub    st(1),st                        ; topy yd
00579                 fld     [ebx+eax]DRV_TLVertex.y         ; endy topy yd
00580                 fadd    [FistTruncate]
00581                 fadd    [FistMagic]                                     ; eyi  topy yd
00582                 fxch    st(2)                       ; yd   topy eyi
00583                 fstp    [yd]                                            ; topy eyi
00584                 fadd    [FistTruncate]
00585                 fadd    [FistMagic]                     ; tyi  eyi
00586                 fxch    st(1)                       ; eyi  tyi
00587                 fstp    [ey]                        ; tyi
00588                 fld     [ebx+edx]DRV_TLVertex.x     ; x    tyi
00589                 fxch    st(1)                       ; tyi  x
00590                 fstp    [ty]                        ; x
00591                 fadd    [FistMagic]                 ; xi
00592 
00593                 mov     ebx,[FistMagic]
00594                 mov     eax,edge
00595 
00596                 sub     [ey],ebx
00597 
00598                 fstp    [eax]EdgeAsm.X
00599 
00600                 sub     [ty],ebx
00601 
00602                 sub     [eax]EdgeAsm.X, ebx
00603                 pop             ebx
00604         }
00605 
00606         edge->Height    =ey-ty;
00607 
00608 //      yd              =(edge->Height >0)? 1.0f/edge->Height : 1;
00609         yd              =(edge->Height >0)? 1.0f/(verts[end].y - verts[top].y) : 1;
00610         edge->y =ty;
00611 
00612         edge->x         =verts[top].x;
00613         edge->xstep     =(verts[end].x-edge->x)*yd;
00614 
00615         edge->r         =verts[top].r;
00616         edge->rstep     =(verts[end].r-edge->r)*yd;
00617         edge->R         =(int)(verts[top].r)&0xfc;
00618 
00619         edge->g         =verts[top].g;
00620         edge->gstep     =(verts[end].g-edge->g)*yd;
00621         edge->G         =(int)(verts[top].g)&0xfc;
00622 
00623         edge->b         =verts[top].b;
00624         edge->bstep     =(verts[end].b-edge->b)*yd;
00625         edge->B         =(int)(verts[top].b)&0xfc;
00626 }
00627 
00628 void AddSpanDraw(EdgeAsmWorld *pLeft, EdgeAsmWorld *pRight)
00629 {
00630         int             x1, x2, y;
00631         BOOL    Dynamic;
00632 
00633         x1      =pLeft->X2;
00634         x2      =pRight->X2;
00635         y       =pLeft->y;
00636 
00637     if (!PolyVisible)
00638         {
00639                 PolyVisible = 1;
00640                 ActuallVisible++;
00641                 
00642                 if (GLInfo)
00643                 {
00644                         if(ProcessorInfo.Has3DNow)
00645                         {
00646                                 Femms3DNow();
00647 
00648                                 SOFTDRV.SetupLightmap(GLInfo, &Dynamic);
00649 
00650                                 Femms3DNow();
00651                         }
00652                         else
00653                         {
00654                                 SOFTDRV.SetupLightmap(GLInfo, &Dynamic);
00655                         }
00656 
00657                         GLightData = (uint8*)GLInfo->RGBLight[0];
00658                 }
00659                 else
00660                 {
00661                         GLightData      =NULL;
00662                 }
00663         }
00664         if(PolyIsTrans)
00665         {
00666                 if(!(y & 1))
00667                 {
00668                         return;
00669                 }
00670         }
00671 
00672     NumPixels += x2 - x1 + 1;
00673 
00674         if(ProcessorInfo.Has3DNow)
00675         {
00676                 switch(SpanMode)
00677                 {
00678                         case 0:
00679                         {
00680                                 DrawSpan32_AsmLitZWrite3DNow(x1, x2, y);
00681                                 break;
00682                         }
00683                         case 1:
00684                         {
00685                                 DrawSpan32_AsmGouraudZWrite3DNow(x1, x2, y, pLeft->r, pLeft->g, pLeft->b, pRight->r, pRight->g, pRight->b);
00686                                 break;
00687                         }
00688                         case 2:
00689                         {
00690                                 DrawSpan32_AsmLitZBuffer3DNow(x1, x2, y);
00691                                 break;
00692                         }
00693                         case 3:
00694                         {
00695                                 DrawSpan32_AsmGouraudZBuffer3DNow(x1, x2, y, pLeft->r, pLeft->g, pLeft->b, pRight->r, pRight->g, pRight->b);
00696                                 break;
00697                         }
00698                 }
00699         }
00700         else
00701         {
00702                 pZBufferPtr     =ZBufLine;
00703                 if(ClientWindow.G_mask == 0x03e0)
00704                 {
00705                         switch(SpanMode)
00706                         {
00707                                 case 0:
00708                                 {
00709                                         DrawSpan16_AsmLitZWrite555X86FPU(x1, x2, y);
00710                                         break;
00711                                 }
00712                                 case 1:
00713                                 {
00714                                         DrawSpan16_AsmGouraudZWrite555X86FPU(x1, x2, y, pLeft->R, pLeft->G, pLeft->B, pRight->R, pRight->G, pRight->B);
00715                                         break;
00716                                 }
00717                                 case 2:
00718                                 {
00719                                         DrawSpan16_AsmLitZBuffer555X86FPU(x1, x2, y);
00720                                         break;
00721                                 }
00722                                 case 3:
00723                                 {
00724                                         DrawSpan16_AsmGouraudZBuffer555X86FPU(x1, x2, y, pLeft->R, pLeft->G, pLeft->B, pRight->R, pRight->G, pRight->B);
00725                                         break;
00726                                 }
00727                         }
00728                 }
00729                 else
00730                 {
00731                         switch(SpanMode)
00732                         {
00733                                 case 0:
00734                                 {
00735                                         DrawSpan16_AsmLitZWriteX86FPU(x1, x2, y);
00736                                         break;
00737                                 }
00738                                 case 1:
00739                                 {
00740                                         DrawSpan16_AsmGouraudZWriteX86FPU(x1, x2, y, pLeft->R, pLeft->G, pLeft->B, pRight->R, pRight->G, pRight->B);
00741                                         break;
00742                                 }
00743                                 case 2:
00744                                 {
00745                                         DrawSpan16_AsmLitZBufferX86FPU(x1, x2, y);
00746                                         break;
00747                                 }
00748                                 case 3:
00749                                 {
00750                                         DrawSpan16_AsmGouraudZBufferX86FPU(x1, x2, y, pLeft->R, pLeft->G, pLeft->B, pRight->R, pRight->G, pRight->B);
00751                                         break;
00752                                 }
00753                         }
00754                 }
00755         }
00756 }
00757 
00758 void AddSpan(EdgeAsmWorld *pLeft, EdgeAsmWorld *pRight)
00759 {
00760         S32             y, x1, x2;
00761     SList       *LineStart      =NULL;
00762     SList       *Current;
00763 
00764         y       =pLeft->y;
00765         x1      =pLeft->X;
00766         pLeft->X2       =x1;
00767         x2      =pRight->X;
00768         pRight->X2      =x2;
00769 
00770         assert(y >=0 && y < MAXSCANLINES);
00771 
00772         if(RenderMode == RENDER_MODELS)
00773         {
00774                 AddSpanDraw(pLeft, pRight);
00775                 return;
00776         }
00777 
00778     Current = SMinMax[y].First;
00779 
00780         // Check to see if there are spans
00781     if (!Current) 
00782         {        
00783                 SMinMax[y].First = NewSList();     // in the list yet...
00784         (SMinMax[y].First)->Last = NULL;
00785         (SMinMax[y].First)->Next = NULL;
00786         (SMinMax[y].First)->Min = x1;
00787         (SMinMax[y].First)->Max = x2;
00788     }
00789         else while (Current)
00790     {
00791                 // See if this line is totally hidden...
00792         if(x1 >= Current->Min && x2 <= Current->Max)
00793                 {
00794                         return; // Yep
00795                 }
00796 
00797                 //if falls before the entire min, max
00798                 if(!LineStart)
00799                 {
00800                         if(Current == SMinMax[y].First)
00801                         {
00802                                 if(x2 < Current->Min)
00803                                 {
00804                                         SList   *NewMinMax      =NewSList();
00805                                         NewMinMax->Next         =Current;
00806                                         NewMinMax->Last         =NULL;
00807                                         Current->Last           =NewMinMax;
00808                                         SMinMax[y].First        =NewMinMax;
00809                                         NewMinMax->Min          =x1;
00810                                         NewMinMax->Max          =x2;
00811                                         break;
00812                                 }
00813                         }
00814 
00815             //if falls in the middle (but not touching)
00816             if(Current->Next)
00817                         {
00818                                 if(x1 > Current->Max && x2 < (Current->Next)->Min)
00819                                 {
00820                                         SList   *NewMinMax              =NewSList();
00821                                         NewMinMax->Next                 =Current->Next;
00822                                         NewMinMax->Last                 =Current;
00823                                         (Current->Next)->Last   =NewMinMax;
00824                                         Current->Next                   =NewMinMax;
00825                                         NewMinMax->Min                  =x1;
00826                                         NewMinMax->Max                  =x2;
00827                                         break;
00828                                 }
00829                         }
00830 
00831             //if it falls to the right of all spans
00832             if(!Current->Next)
00833                         {
00834                                 if(x1 > Current->Max)
00835                                 {
00836                                         SList   *NewMinMax      =NewSList();
00837                                         Current->Next           =NewMinMax;
00838                                         NewMinMax->Next         =NULL;
00839                                         NewMinMax->Last         =Current;
00840                                         NewMinMax->Min          =x1;
00841                                         NewMinMax->Max          =x2;
00842                                         break;
00843                                 }
00844                         }
00845                 }
00846 
00847         //if we have already started crossing spans, and we find out
00848         // that we are in front of a span, then we can bail out...
00849                 if (LineStart != NULL)
00850                         if (x2 < Current->Min)
00851                                 break;
00852                 
00853         // We now know that we have not fallen into any empty holes.
00854         // We must now check to see what spans, we've crossed...
00855 
00856         // if split by a min/max
00857         if (x1 < Current->Min && x2 > Current->Max) 
00858                 {
00859             pRight->X2          =Current->Min;
00860             Current->Min        =pLeft->X2      =x1;
00861 
00862                         AddSpanDraw(pLeft, pRight);
00863 
00864             pLeft->X2           =x1                     =Current->Max;
00865                         Current->Max    =pRight->X2     =x2;
00866 
00867                         if (LineStart!=NULL) 
00868                                 LineStart->Max  =x2;
00869             else
00870                                 LineStart = Current;
00871 
00872             Current = Current->Next;
00873                         continue;
00874                 }
00875 
00876                 if (x1 <= Current->Max && x2 > Current->Max) 
00877                 {
00878             pLeft->X2           =x1                     =Current->Max;//+1;
00879                         Current->Max    =pRight->X2     =x2;
00880             LineStart = Current;
00881 
00882                         Current = Current->Next;
00883 
00884                         continue;
00885                 }
00886                 if (x1 < Current->Min && x2 >= Current->Min) 
00887                 {
00888             pRight->X2  =x2                             =Current->Min;
00889             pLeft->X2   =Current->Min   =x1;
00890             if (LineStart!=NULL) 
00891                                 LineStart->Max = Current->Max;
00892                         break;
00893                 }
00894                 Current = Current->Next;
00895     }
00896 
00897         AddSpanDraw(pLeft, pRight);
00898 }
00899 
00900 void SpanOutWorldTri(DRV_TLVertex *verts)
00901 {
00902         int                     Top, Middle, Bottom, MiddleForCompare;
00903         int                     MiddleIsLeft, BottomForCompare, Height;
00904         geFloat         Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
00905         EdgeAsmWorld    TopToBottom, TopToMiddle, MiddleToBottom;
00906         EdgeAsmWorld    *pLeft, *pRight;
00907 
00908         // sort vertices in y
00909         if(Y0 < Y1)
00910         {
00911                 if(Y2 < Y0)
00912                 {
00913                         Top             =2;
00914                         Middle  =MiddleForCompare       =0;
00915                         Bottom  =BottomForCompare       =1;
00916                 }
00917                 else
00918                 {
00919                         Top     =0;
00920                         if(Y1 < Y2)
00921                         {
00922                                 Middle  =MiddleForCompare       =1;
00923                                 Bottom  =BottomForCompare       =2;
00924                         }
00925                         else
00926                         {
00927                                 Middle  =MiddleForCompare       =2;
00928                                 Bottom  =BottomForCompare       =1;
00929                         }
00930                 }
00931         }
00932         else
00933         {
00934                 if(Y2 < Y1)
00935                 {
00936                         Top             =2;
00937                         Middle  =MiddleForCompare       =1;
00938                         Bottom  =BottomForCompare       =0;
00939                 }
00940                 else
00941                 {
00942                         Top     =1;
00943                         if(Y0 < Y2)
00944                         {
00945                                 Middle  =0;
00946                                 Bottom  =BottomForCompare       =2;
00947                                 MiddleForCompare                        =3;
00948                         }
00949                         else
00950                         {
00951                                 BottomForCompare                        =3;
00952                                 Middle  =MiddleForCompare       =2;
00953                                 Bottom  =0;
00954                         }
00955                 }
00956         }
00957 
00958         setup_edgeWorld(&TopToBottom, verts, Top, Bottom);
00959         setup_edgeWorld(&TopToMiddle, verts, Top, Middle);
00960         setup_edgeWorld(&MiddleToBottom, verts, Middle, Bottom);
00961 
00962         if(BottomForCompare > MiddleForCompare)
00963         {
00964                 MiddleIsLeft = 0;
00965                 pLeft = &TopToBottom; pRight = &TopToMiddle;
00966         }
00967         else
00968         {
00969                 MiddleIsLeft = 1;
00970                 pLeft = &TopToMiddle; pRight = &TopToBottom;
00971         }
00972 
00973         Height  =TopToMiddle.Height;
00974 
00975         Dest            =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
00976         ZBufLine        =ZBuffer + (pLeft->y * ClientWindow.Width);
00977         
00978         pZBufferPtr     =ZBufLine;
00979         while(Height--)
00980         {
00981                 if(bStipple)
00982                 {
00983                         if(pLeft->y & 1)
00984                         {
00985                                 AddSpan(pLeft, pRight);
00986                         }
00987                 }
00988                 else
00989                 {
00990                         AddSpan(pLeft, pRight);
00991                 }
00992                 StepWorld(pLeft);
00993                 StepWorld(pRight);
00994 
00995                 Dest            +=ClientWindow.PixelPitch / 2;
00996                 ZBufLine        +=ClientWindow.Width;
00997                 pZBufferPtr     =ZBufLine;
00998         }
00999 
01000         Height  =MiddleToBottom.Height;
01001 
01002         if(MiddleIsLeft)
01003         {
01004                 pLeft   =&MiddleToBottom;
01005                 pRight  =&TopToBottom;
01006         }
01007         else
01008         {
01009                 pLeft   =&TopToBottom;
01010                 pRight  =&MiddleToBottom;
01011         }
01012         
01013         while(Height--)
01014         {
01015                 if(bStipple)
01016                 {
01017                         if(pLeft->y & 1)
01018                         {
01019                                 AddSpan(pLeft, pRight);
01020                         }
01021                 }
01022                 else
01023                 {
01024                         AddSpan(pLeft, pRight);
01025                 }
01026                 StepWorld(pLeft);
01027                 StepWorld(pRight);
01028 
01029                 Dest            +=ClientWindow.PixelPitch / 2;
01030                 ZBufLine        +=ClientWindow.Width;
01031                 pZBufferPtr     =ZBufLine;
01032         }
01033 }
01034 
01035 void SpanOutWorldTri3DNow(DRV_TLVertex *verts)
01036 {
01037         int                     Top, Middle, Bottom, MiddleForCompare;
01038         int                     MiddleIsLeft, BottomForCompare, Height;
01039         geFloat         Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
01040         EdgeAsmWorld    TopToBottom, TopToMiddle, MiddleToBottom;
01041         EdgeAsmWorld    *pLeft, *pRight;
01042 
01043         // sort vertices in y
01044         if(Y0 < Y1)
01045         {
01046                 if(Y2 < Y0)
01047                 {
01048                         Top             =2;
01049                         Middle  =MiddleForCompare       =0;
01050                         Bottom  =BottomForCompare       =1;
01051                 }
01052                 else
01053                 {
01054                         Top     =0;
01055                         if(Y1 < Y2)
01056                         {
01057                                 Middle  =MiddleForCompare       =1;
01058                                 Bottom  =BottomForCompare       =2;
01059                         }
01060                         else
01061                         {
01062                                 Middle  =MiddleForCompare       =2;
01063                                 Bottom  =BottomForCompare       =1;
01064                         }
01065                 }
01066         }
01067         else
01068         {
01069                 if(Y2 < Y1)
01070                 {
01071                         Top             =2;
01072                         Middle  =MiddleForCompare       =1;
01073                         Bottom  =BottomForCompare       =0;
01074                 }
01075                 else
01076                 {
01077                         Top     =1;
01078                         if(Y0 < Y2)
01079                         {
01080                                 Middle  =0;
01081                                 Bottom  =BottomForCompare       =2;
01082                                 MiddleForCompare                        =3;
01083                         }
01084                         else
01085                         {
01086                                 BottomForCompare                        =3;
01087                                 Middle  =MiddleForCompare       =2;
01088                                 Bottom  =0;
01089                         }
01090                 }
01091         }
01092 
01093         setup_edgeWorld(&TopToBottom, verts, Top, Bottom);
01094         setup_edgeWorld(&TopToMiddle, verts, Top, Middle);
01095         setup_edgeWorld(&MiddleToBottom, verts, Middle, Bottom);
01096 
01097         Femms3DNow();
01098 
01099         if(BottomForCompare > MiddleForCompare)
01100         {
01101                 MiddleIsLeft = 0;
01102                 pLeft = &TopToBottom; pRight = &TopToMiddle;
01103         }
01104         else
01105         {
01106                 MiddleIsLeft = 1;
01107                 pLeft = &TopToMiddle; pRight = &TopToBottom;
01108         }
01109 
01110         Height  =TopToMiddle.Height;
01111 
01112         Dest            =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
01113         
01114         while(Height--)
01115         {
01116                 AddSpan(pLeft, pRight);
01117 
01118                 StepWorld3DNow(pLeft);
01119                 StepWorld3DNow(pRight);
01120 
01121                 Dest            +=ClientWindow.PixelPitch / 2;
01122         }
01123 
01124         Height  =MiddleToBottom.Height;
01125 
01126         if(MiddleIsLeft)
01127         {
01128                 pLeft   =&MiddleToBottom;
01129                 pRight  =&TopToBottom;
01130         }
01131         else
01132         {
01133                 pLeft   =&TopToBottom;
01134                 pRight  =&MiddleToBottom;
01135         }
01136         
01137         while(Height--)
01138         {
01139                 AddSpan(pLeft, pRight);
01140 
01141                 StepWorld3DNow(pLeft);
01142                 StepWorld3DNow(pRight);
01143 
01144                 Dest            +=ClientWindow.PixelPitch / 2;
01145         }
01146         Femms3DNow();
01147 }
01148 
01149 void SpanOutWorldTriAlpha(DRV_TLVertex *verts)
01150 {
01151         int                     Top, Middle, Bottom, MiddleForCompare;
01152         int                     MiddleIsLeft, BottomForCompare, Height;
01153         geFloat         Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
01154         EdgeAsmWorld    TopToBottom, TopToMiddle, MiddleToBottom;
01155         EdgeAsmWorld    *pLeft, *pRight;
01156 
01157         // sort vertices in y
01158         if(Y0 < Y1)
01159         {
01160                 if(Y2 < Y0)
01161                 {
01162                         Top             =2;
01163                         Middle  =MiddleForCompare       =0;
01164                         Bottom  =BottomForCompare       =1;
01165                 }
01166                 else
01167                 {
01168                         Top     =0;
01169                         if(Y1 < Y2)
01170                         {
01171                                 Middle  =MiddleForCompare       =1;
01172                                 Bottom  =BottomForCompare       =2;
01173                         }
01174                         else
01175                         {
01176                                 Middle  =MiddleForCompare       =2;
01177                                 Bottom  =BottomForCompare       =1;
01178                         }
01179                 }
01180         }
01181         else
01182         {
01183                 if(Y2 < Y1)
01184                 {
01185                         Top             =2;
01186                         Middle  =MiddleForCompare       =1;
01187                         Bottom  =BottomForCompare       =0;
01188                 }
01189                 else
01190                 {
01191                         Top     =1;
01192                         if(Y0 < Y2)
01193                         {
01194                                 Middle  =0;
01195                                 Bottom  =BottomForCompare       =2;
01196                                 MiddleForCompare                        =3;
01197                         }
01198                         else
01199                         {
01200                                 BottomForCompare                        =3;
01201                                 Middle  =MiddleForCompare       =2;
01202                                 Bottom  =0;
01203                         }
01204                 }
01205         }
01206 
01207         setup_edgeWorld(&TopToBottom, verts, Top, Bottom);
01208         setup_edgeWorld(&TopToMiddle, verts, Top, Middle);
01209         setup_edgeWorld(&MiddleToBottom, verts, Middle, Bottom);
01210 
01211         if(BottomForCompare > MiddleForCompare)
01212         {
01213                 MiddleIsLeft = 0;
01214                 pLeft = &TopToBottom; pRight = &TopToMiddle;
01215         }
01216         else
01217         {
01218                 MiddleIsLeft = 1;
01219                 pLeft = &TopToMiddle; pRight = &TopToBottom;
01220         }
01221 
01222         Height  =TopToMiddle.Height;
01223 
01224         Dest            =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
01225         ZBufLine        =ZBuffer + (pLeft->y * ClientWindow.Width);
01226         
01227         pZBufferPtr     =ZBufLine;
01228         while(Height--)
01229         {
01230                 if(bStipple)
01231                 {
01232                         if(pLeft->y & 1)
01233                         {
01234                                 CurMapperWorldFPU(pLeft->X, pRight->X, pLeft->y
01235                                         , pLeft->R, pLeft->G, pLeft->B,
01236                                         pRight->R, pRight->G, pRight->B);
01237                         }
01238                 }
01239                 else
01240                 {
01241                         CurMapperWorldFPU(pLeft->X, pRight->X, pLeft->y
01242                                 , pLeft->R, pLeft->G, pLeft->B,
01243                                 pRight->R, pRight->G, pRight->B);
01244                 }
01245                 StepWorld(pLeft);
01246                 StepWorld(pRight);
01247 
01248                 Dest            +=ClientWindow.PixelPitch / 2;
01249                 ZBufLine        +=ClientWindow.Width;
01250                 pZBufferPtr     =ZBufLine;
01251         }
01252 
01253         Height  =MiddleToBottom.Height;
01254 
01255         if(MiddleIsLeft)
01256         {
01257                 pLeft   =&MiddleToBottom;
01258                 pRight  =&TopToBottom;
01259         }
01260         else
01261         {
01262                 pLeft   =&TopToBottom;
01263                 pRight  =&MiddleToBottom;
01264         }
01265         
01266         while(Height--)
01267         {
01268                 if(bStipple)
01269                 {
01270                         if(pLeft->y & 1)
01271                         {
01272                                 CurMapperWorldFPU(pLeft->X, pRight->X, pLeft->y
01273                                         , pLeft->R, pLeft->G, pLeft->B,
01274                                         pRight->R, pRight->G, pRight->B);
01275                         }
01276                 }
01277                 else
01278                 {
01279                         CurMapperWorldFPU(pLeft->X, pRight->X, pLeft->y
01280                                 , pLeft->R, pLeft->G, pLeft->B,
01281                                 pRight->R, pRight->G, pRight->B);
01282                 }
01283                 StepWorld(pLeft);
01284                 StepWorld(pRight);
01285 
01286                 Dest            +=ClientWindow.PixelPitch / 2;
01287                 ZBufLine        +=ClientWindow.Width;
01288                 pZBufferPtr     =ZBufLine;
01289         }
01290 }
01291 
01292 void SpanOutWorldTriAlpha3DNow(DRV_TLVertex *verts)
01293 {
01294         int                     Top, Middle, Bottom, MiddleForCompare;
01295         int                     MiddleIsLeft, BottomForCompare, Height;
01296         geFloat         Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
01297         EdgeAsmWorld    TopToBottom, TopToMiddle, MiddleToBottom;
01298         EdgeAsmWorld    *pLeft, *pRight;
01299 
01300         // sort vertices in y
01301         if(Y0 < Y1)
01302         {
01303                 if(Y2 < Y0)
01304                 {
01305                         Top             =2;
01306                         Middle  =MiddleForCompare       =0;
01307                         Bottom  =BottomForCompare       =1;
01308                 }
01309                 else
01310                 {
01311                         Top     =0;
01312                         if(Y1 < Y2)
01313                         {
01314                                 Middle  =MiddleForCompare       =1;
01315                                 Bottom  =BottomForCompare       =2;
01316                         }
01317                         else
01318                         {
01319                                 Middle  =MiddleForCompare       =2;
01320                                 Bottom  =BottomForCompare       =1;
01321                         }
01322                 }
01323         }
01324         else
01325         {
01326                 if(Y2 < Y1)
01327                 {
01328                         Top             =2;
01329                         Middle  =MiddleForCompare       =1;
01330                         Bottom  =BottomForCompare       =0;
01331                 }
01332                 else
01333                 {
01334                         Top     =1;
01335                         if(Y0 < Y2)
01336                         {
01337                                 Middle  =0;
01338                                 Bottom  =BottomForCompare       =2;
01339                                 MiddleForCompare                        =3;
01340                         }
01341                         else
01342                         {
01343                                 BottomForCompare                        =3;
01344                                 Middle  =MiddleForCompare       =2;
01345                                 Bottom  =0;
01346                         }
01347                 }
01348         }
01349 
01350         setup_edgeWorld(&TopToBottom, verts, Top, Bottom);
01351         setup_edgeWorld(&TopToMiddle, verts, Top, Middle);
01352         setup_edgeWorld(&MiddleToBottom, verts, Middle, Bottom);
01353 
01354         Femms3DNow();
01355 
01356         if(BottomForCompare > MiddleForCompare)
01357         {
01358                 MiddleIsLeft = 0;
01359                 pLeft = &TopToBottom; pRight = &TopToMiddle;
01360         }
01361         else
01362         {
01363                 MiddleIsLeft = 1;
01364                 pLeft = &TopToMiddle; pRight = &TopToBottom;
01365         }
01366 
01367         Height  =TopToMiddle.Height;
01368 
01369         Dest            =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
01370         
01371         while(Height--)
01372         {
01373                 CurMapperWorld(pLeft->X, pRight->X, pLeft->y
01374                         , pLeft->r, pLeft->g, pLeft->b,
01375                         pRight->r, pRight->g, pRight->b);
01376 
01377                 StepWorld3DNow(pLeft);
01378                 StepWorld3DNow(pRight);
01379 
01380                 Dest            +=ClientWindow.PixelPitch / 2;
01381         }
01382 
01383         Height  =MiddleToBottom.Height;
01384 
01385         if(MiddleIsLeft)
01386         {
01387                 pLeft   =&MiddleToBottom;
01388                 pRight  =&TopToBottom;
01389         }
01390         else
01391         {
01392                 pLeft   =&TopToBottom;
01393                 pRight  =&MiddleToBottom;
01394         }
01395         
01396         while(Height--)
01397         {
01398                 CurMapperWorld(pLeft->X, pRight->X, pLeft->y
01399                         , pLeft->r, pLeft->g, pLeft->b,
01400                         pRight->r, pRight->g, pRight->b);
01401 
01402                 StepWorld3DNow(pLeft);
01403                 StepWorld3DNow(pRight);
01404 
01405                 Dest            +=ClientWindow.PixelPitch / 2;
01406         }
01407         Femms3DNow();
01408 }
01409 
01410 BOOL DRIVERCC RenderWorldPoly(DRV_TLVertex *Pnts, S32 NumPoints, geRDriver_THandle *THandle, DRV_TexInfo *TexInfo, DRV_LInfo *LInfo, U32 Flags)
01411 {
01412         U8                              MipLevel = 0;
01413         int32                   i;
01414         DRV_TLVertex    TriVerts[3];
01415 
01416         if(!bActive)
01417         {
01418                 return  GE_TRUE;
01419         }
01420 
01421         assert(THandle != NULL);
01422         assert(Pnts != NULL);
01423         assert(NumPoints > 2);
01424         
01425         GlobalInfo = SOFTDRV.GlobalInfo;
01426         assert(GlobalInfo);
01427 
01428         //
01429         //      Get the mip level
01430         //
01431         {
01432                 geFloat du, dv, dx, dy, MipScale;
01433 
01434                 du      =Pnts[1].u - Pnts[0].u;
01435                 dv      =Pnts[1].v - Pnts[0].v;
01436                 dx      =Pnts[1].x - Pnts[0].x;
01437                 dy      =Pnts[1].y - Pnts[0].y;
01438 
01439                 du      /=TexInfo->DrawScaleU;
01440                 dv      /=TexInfo->DrawScaleV;
01441 
01442                 MipScale        =((du*du)+(dv*dv)) / ((dx*dx)+(dy*dy));
01443 
01444                 if(MipScale <= 5)               // 2, 6, 12
01445                 {
01446                         MipLevel        =0;
01447                 }
01448                 else if(MipScale <= 20)
01449                 {
01450                         MipLevel        =1;
01451                 }
01452                 else if(MipScale <= 45)
01453                 {
01454                         MipLevel        =2;
01455                 }
01456                 else
01457                 {
01458                         MipLevel        =3;
01459                 }
01460         }
01461 
01462         if(MipLevel >= THandle->MipLevels)
01463         {
01464                 MipLevel        =THandle->MipLevels-1;
01465         }
01466 
01467         assert(THandle->BitPtr[MipLevel] != NULL);
01468 
01469         GW = THandle->Width >> MipLevel;
01470         GH = THandle->Height >> MipLevel;
01471         GWMask = GW-1;
01472         GHMask = GH-1;
01473 
01474         CalcGradients(MipLevel, TexInfo->DrawScaleU, TexInfo->DrawScaleV);
01475 
01476         // Assign some global variables...
01477         GTexture        =THandle;
01478         GLInfo          =LInfo;
01479 
01480         if(ProcessorInfo.Has3DNow)
01481         {
01482                 GBitPtr         =(U8 *)THandle->BitPtr[MipLevel];
01483                 TexPal          =(U8 *)THandle->PalHandle->BitPtr[0];
01484         }
01485         else
01486         {
01487                 GBitPtr16       =THandle->BitPtr[MipLevel];
01488                 GWMaskShifted=(GWMask<<16) |0xffff;
01489         }
01490 
01491         GMipLevel = (U8)MipLevel;
01492         GMipLevel4 = 4-MipLevel;
01493         GMipLevel4_8 = GMipLevel4+8;
01494         GMipLevel20 = 20-MipLevel;
01495 
01496         QGMip20 =GMipLevel20;
01497         QGMip4_8=GMipLevel4_8;
01498 
01499         if(LInfo)
01500         {
01501                 GLMapAdd = LInfo->Width*3 - 6;
01502                 GLightWidth = LInfo->Width;
01503 
01504                 GLightData = (uint8*)LInfo->RGBLight[0];
01505 
01506                 if(RenderMode == RENDER_MODELS)
01507                         SpanMode = 2;
01508                 else
01509                         SpanMode = 0;
01510         }
01511         else
01512         {
01513                 if(RenderMode == RENDER_MODELS)
01514                         SpanMode = 3;
01515                 else
01516                         SpanMode = 1;
01517         }
01518         
01519         if(Flags & DRV_RENDER_ALPHA)
01520         {
01521                 PolyIsTrans     =GE_TRUE;
01522         }
01523         else
01524         {
01525                 PolyIsTrans     =FALSE;
01526         }
01527 
01528         // Reset the polyvisible flag
01529         PolyVisible = 0;
01530 
01531 /*      if(THandle->PixelFormat.Flags & RDRIVER_PF_HAS_ALPHA)
01532         {
01533                 PolyIsTrans     =GE_TRUE;
01534         }
01535         else if(THandle->PalHandle)
01536         {
01537                 PolyIsTrans     =gePixelFormat_HasAlpha(THandle->PalHandle->PixelFormat.PixelFormat);
01538         }
01539         else
01540         {
01541                 PolyIsTrans     =GE_FALSE;
01542         }
01543 */
01544         if(RenderMode == RENDER_WORLD || RenderMode == RENDER_MODELS)
01545         {
01546                 assert(!(Flags & DRV_RENDER_ALPHA));
01547                 if(NumPoints==3)
01548                 {
01549                         TriVerts[0]     =Pnts[0];
01550                         TriVerts[1]     =Pnts[1];
01551                         TriVerts[2]     =Pnts[2];
01552 
01553                         if(ProcessorInfo.Has3DNow)
01554                         {
01555                                 SpanOutWorldTri3DNow(TriVerts);
01556                         }
01557                         else
01558                         {
01559                                 SpanOutWorldTri(TriVerts);
01560                         }
01561                 }
01562                 else
01563                 {
01564                         for(i=0;i < NumPoints-2;i++)
01565                         {
01566                                 TriVerts[0]     =Pnts[0];
01567                                 TriVerts[1]     =Pnts[1+i];
01568                                 TriVerts[2]     =Pnts[2+i];
01569                                 
01570                                 if(ProcessorInfo.Has3DNow)
01571                                 {
01572                                         SpanOutWorldTri3DNow(TriVerts);
01573                                 }
01574                                 else
01575                                 {
01576                                         SpanOutWorldTri(TriVerts);
01577                                 }
01578                         }
01579                 }
01580         }
01581         else
01582         {
01583                 bStipple        =GE_FALSE;
01584                 if(ProcessorInfo.Has3DNow)
01585                 {
01586 /*                      if(LInfo)       //lit alpha not done yet
01587                         {
01588                                 //check for argb alpha faces (no seperate right now)
01589                                 if(GTexture->PixelFormat.PixelFormat==GE_PIXELFORMAT_32BIT_ARGB)
01590                                 {
01591                                         CurMapperWorld  =DrawSpan32_AsmGouraudZBufferAlphaARGB3DNow;
01592                                 }
01593                                 else
01594                                 {
01595                                         CurMapperWorld  =DrawSpan32_AsmLitZBuffer3DNow;
01596                                 }
01597                         }
01598                         else
01599 */                      {
01600                                 //vertex alpha overrides argb 
01601                                 if(Pnts[0].a < 255.0f)
01602                                 {
01603                                         i       =(int)Pnts[0].a;
01604                                         *((U32 *)(&VertAlpha))          =(i << 16) | i;
01605                                         *(((U32 *)((&VertAlpha)))+1)=(i << 16) | i;
01606                                         CurMapperWorld  =DrawSpan32_AsmGouraudZBufferVertexAlpha3DNow;
01607                                 }
01608                                 else
01609                                 {
01610                                         //check for argb alpha faces (no seperate right now)
01611                                         if(GTexture->PalHandle->PixelFormat.PixelFormat==GE_PIXELFORMAT_32BIT_ARGB)
01612                                         {
01613                                                 CurMapperWorld  =DrawSpan32_AsmGouraudZBufferAlphaARGB3DNow;
01614                                         }
01615                                         else
01616                                         {
01617                                                 CurMapperWorld  =DrawSpan32_AsmGouraudZBuffer3DNow;
01618                                         }
01619                                 }
01620                         }
01621                         if(NumPoints==3)
01622                         {
01623                                 TriVerts[0]     =Pnts[0];
01624                                 TriVerts[1]     =Pnts[1];
01625                                 TriVerts[2]     =Pnts[2];
01626 
01627                                 SpanOutWorldTriAlpha3DNow(TriVerts);
01628                         }
01629                         else
01630                         {
01631                                 for(i=0;i < NumPoints-2;i++)
01632                                 {
01633                                         TriVerts[0]     =Pnts[0];
01634                                         TriVerts[1]     =Pnts[1+i];
01635                                         TriVerts[2]     =Pnts[2+i];
01636                                         
01637                                         SpanOutWorldTriAlpha3DNow(TriVerts);
01638                                 }
01639                         }
01640                 }
01641                 else
01642                 {
01643 /*                      if(LInfo)       //lit alpha not done yet
01644                         {
01645                                 //check for argb alpha faces (no seperate right now)
01646                                 if(GTexture->PixelFormat.PixelFormat==GE_PIXELFORMAT_32BIT_ARGB)
01647                                 {
01648                                         CurMapperWorld  =DrawSpan32_AsmGouraudZBufferAlphaARGB3DNow;
01649                                 }
01650                                 else
01651                                 {
01652                                         CurMapperWorld  =DrawSpan32_AsmLitZBuffer3DNow;
01653                                 }
01654                         }
01655                         else
01656 */
01657                         if(ClientWindow.G_mask == 0x03e0)
01658                         {
01659                                 if(Pnts[0].a > 254.0f)
01660                                 {
01661                                         CurMapperWorldFPU       =DrawSpan16_AsmGouraudZBufferTrans555X86FPU;
01662                                 }
01663                                 else
01664                                 {
01665                                         CurMapperWorldFPU       =DrawSpan16_AsmGouraudZBuffer555X86FPU;
01666                                 }
01667                                 bStipple                        =GE_TRUE;
01668                         }
01669                         else
01670                         {
01671                                 if(Pnts[0].a > 254.0f)
01672                                 {
01673                                         CurMapperWorldFPU       =DrawSpan16_AsmGouraudZBufferTransX86FPU;
01674                                 }
01675                                 else
01676                                 {
01677                                         CurMapperWorldFPU       =DrawSpan16_AsmGouraudZBufferX86FPU;
01678                                 }
01679                                 bStipple                        =GE_TRUE;
01680                         }
01681                         if(NumPoints==3)
01682                         {
01683                                 TriVerts[0]     =Pnts[0];
01684                                 TriVerts[1]     =Pnts[1];
01685                                 TriVerts[2]     =Pnts[2];
01686 
01687                                 SpanOutWorldTriAlpha(TriVerts);
01688                         }
01689                         else
01690                         {
01691                                 for(i=0;i < NumPoints-2;i++)
01692                                 {
01693                                         TriVerts[0]     =Pnts[0];
01694                                         TriVerts[1]     =Pnts[1+i];
01695                                         TriVerts[2]     =Pnts[2+i];
01696                                         
01697                                         SpanOutWorldTriAlpha(TriVerts);
01698                                 }
01699                         }
01700                 }
01701 
01702                 bStipple        =GE_FALSE;
01703         }
01704 
01705         return GE_TRUE;
01706 }
01707 
01708 void Step(EdgeAsm *edge)
01709 {
01710         _asm
01711         {
01712                 mov     eax,edge
01713                 fld             [eax]EdgeAsm.x          ; x
01714                 fadd    [eax]EdgeAsm.xstep      ; xd
01715                 fld     [eax]EdgeAsm.u          ; u   xd
01716                 fadd    [eax]EdgeAsm.ustep      ; ud  xd
01717                 fld     [eax]EdgeAsm.v          ; v   ud  xd
01718                 fadd    [eax]EdgeAsm.vstep  ; vd  ud  xd
01719                 fld     [eax]EdgeAsm.z      ; z   vd  ud  xd
01720                 fadd    [eax]EdgeAsm.zstep  ; zd  vd  ud  xd
01721                 fld             [eax]EdgeAsm.r          ; r   zd  vd  ud  xd
01722                 fadd    [eax]EdgeAsm.rstep      ; rd  zd  vd  ud  xd
01723                 fld             [eax]EdgeAsm.g          ; g   rd  zd  vd  ud  xd
01724                 fadd    [eax]EdgeAsm.gstep      ; gd  rd  zd  vd  ud  xd
01725                 fld             [eax]EdgeAsm.b          ; b   gd  rd  zd  vd  ud  xd
01726                 fadd    [eax]EdgeAsm.bstep      ; bd  gd  rd  zd  vd  ud  xd
01727                 fxch    st(2)                           ; rd  gd  bd  zd  vd  ud  xd
01728                 fstp    [eax]EdgeAsm.r          ; gd  bd  zd  vd  ud  xd
01729                 fstp    [eax]EdgeAsm.g          ; bd  zd  vd  ud  xd
01730                 fstp    [eax]EdgeAsm.b          ; zd  vd  ud  xd
01731                 fstp    [eax]EdgeAsm.z          ; vd  ud  xd
01732                 fstp    [eax]EdgeAsm.v          ; ud  xd
01733                 fstp    [eax]EdgeAsm.u          ; xd
01734                 fst             [eax]EdgeAsm.x          ; xd
01735                 fsub    [FistTruncate]      ; xdt
01736                 fadd    [FistMagic]         ; xnt
01737                 fstp    [eax]EdgeAsm.X
01738 
01739                 mov     edx,[FistMagic]
01740                 sub     [eax]EdgeAsm.X,edx
01741         }
01742         edge->y++;
01743         edge->Height--;
01744 }
01745 
01746 //special handling of colors for fpu blend
01747 void StepFPU(EdgeAsmFPU *edge)
01748 {
01749         int     r,g,b;
01750         _asm
01751         {
01752                 push    ecx
01753                 push    ebx
01754                 push    esi
01755 
01756                 mov     eax,edge
01757                 fld             [eax]EdgeAsmFPU.x               ; x
01758                 fadd    [eax]EdgeAsmFPU.xstep   ; xd
01759                 fld     [eax]EdgeAsmFPU.u               ; u   xd
01760                 fadd    [eax]EdgeAsmFPU.ustep   ; ud  xd
01761                 fld     [eax]EdgeAsmFPU.v               ; v   ud  xd
01762                 fadd    [eax]EdgeAsmFPU.vstep  ; vd  ud  xd
01763                 fld     [eax]EdgeAsmFPU.z           ; z   vd  ud  xd
01764                 fadd    [eax]EdgeAsmFPU.zstep  ; zd  vd  ud  xd
01765                 fld             [eax]EdgeAsmFPU.r               ; r   zd  vd  ud  xd
01766                 fadd    [eax]EdgeAsmFPU.rstep   ; rd  zd  vd  ud  xd
01767                 fld             [eax]EdgeAsmFPU.g               ; g   rd  zd  vd  ud  xd
01768                 fadd    [eax]EdgeAsmFPU.gstep   ; gd  rd  zd  vd  ud  xd
01769                 fld             [eax]EdgeAsmFPU.b               ; b   gd  rd  zd  vd  ud  xd
01770                 fadd    [eax]EdgeAsmFPU.bstep   ; bd  gd  rd  zd  vd  ud  xd
01771                 fxch    st(2)                           ; rd  gd  bd  zd  vd  ud  xd
01772                 fst             [eax]EdgeAsmFPU.r
01773                 fadd    [FistMagic]                     ; rdk gd  bd  zd  vd  ud  xd
01774                 fxch    st(2)                           ; bd  gd  rdk zd  vd  ud  xd
01775                 fst             [eax]EdgeAsmFPU.b
01776                 fadd    [FistMagic]                     ; bdk gd  rdk zd  vd  ud  xd
01777                 fxch    st(1)                           ; gd  bdk rdk zd  vd  ud  xd
01778                 fst             [eax]EdgeAsmFPU.g
01779                 fadd    [FistMagic]                     ; gdk bdk rdk zd  vd  ud  xd
01780                 fxch    st(2)                           ; rdk bdk gdk zd  vd  ud  xd
01781                 fstp    [r]                                     ; bdk gdk zd  vd  ud  xd
01782                 fstp    [b]                                     ; gdk zd  vd  ud  xd
01783                 fstp    [g]                                     ; zd  vd  ud  xd
01784 
01785                 mov             edx,[FistMagic]
01786                 mov             ebx,[r]
01787 
01788                 fstp    [eax]EdgeAsmFPU.z               ; vd  ud  xd
01789 
01790                 mov             ecx,[g]
01791                 sub             ebx,edx
01792                 
01793                 fstp    [eax]EdgeAsmFPU.v               ; ud  xd
01794 
01795                 mov             esi,[b]
01796                 sub             ecx,edx
01797 
01798                 fstp    [eax]EdgeAsmFPU.u               ; xd
01799 
01800                 sub             esi,edx
01801                 and             ebx,0fch
01802 
01803                 fst             [eax]EdgeAsmFPU.x               ; xd
01804 
01805                 and             ecx,0fch
01806                 and             esi,0fch
01807 
01808                 fsub    [FistTruncate]      ; xdt
01809 
01810                 mov             [eax]EdgeAsmFPU.R,ebx
01811                 mov             [eax]EdgeAsmFPU.G,ecx
01812 
01813                 fadd    [FistMagic]         ; xnt
01814 
01815                 mov             [eax]EdgeAsmFPU.B,esi
01816 
01817                 fstp    [eax]EdgeAsmFPU.X
01818 
01819                 sub     [eax]EdgeAsmFPU.X,edx
01820 
01821                 pop             esi
01822                 pop             ebx
01823                 pop             ecx
01824         }
01825         edge->y++;
01826         edge->Height--;
01827 }
01828 
01829 void setup_edge(EdgeAsm *edge, DRV_TLVertex *verts, int top, int end)
01830 {
01831         int             ey,ty;
01832         geFloat yd;
01833 
01834         _asm
01835         {
01836                 push    ebx
01837                 mov             eax,end
01838                 mov     edx,top
01839 
01840                 shl     eax,2
01841                 mov     ebx,verts
01842 
01843                 shl     edx,2
01844                 lea             eax,[8*eax+eax]
01845                 lea             edx,[8*edx+edx]
01846 
01847                 fld             [ebx+eax]DRV_TLVertex.y         ; endy
01848                 fld     [ebx+edx]DRV_TLVertex.y         ; topy endy
01849                 fsub    st(1),st                        ; topy yd
01850                 fld     [ebx+eax]DRV_TLVertex.y         ; endy topy yd
01851                 fsub    [FistTruncate]
01852                 fadd    [FistMagic]                                     ; eyi  topy yd
01853                 fxch    st(2)                       ; yd   topy eyi
01854                 fstp    [yd]                                            ; topy eyi
01855                 fsub    [FistTruncate]
01856                 fadd    [FistMagic]                     ; tyi  eyi
01857                 fxch    st(1)                       ; eyi  tyi
01858                 fstp    [ey]                        ; tyi
01859                 fld     [ebx+edx]DRV_TLVertex.x     ; x    tyi
01860                 fxch    st(1)                       ; tyi  x
01861                 fstp    [ty]                        ; x
01862                 fsub    [FistTruncate]
01863                 fadd    [FistMagic]                 ; xi
01864 
01865                 mov     ebx,[FistMagic]
01866                 mov     eax,edge
01867 
01868                 sub     [ey],ebx
01869 
01870                 fstp    [eax]EdgeAsm.X
01871 
01872                 sub     [ty],ebx
01873 
01874                 sub     [eax]EdgeAsm.X, ebx
01875                 pop             ebx
01876         }
01877 
01878         edge->Height    =ey-ty;
01879 
01880         yd              =(edge->Height >0)? 1.0f/edge->Height : 1;
01881         edge->y =ty;
01882 
01883         edge->x         =verts[top].x;
01884         edge->xstep     =(verts[end].x-edge->x)*yd;
01885 
01886         edge->u         =verts[top].u;
01887         edge->ustep     =(verts[end].u-edge->u)*yd;
01888 
01889         edge->v         =verts[top].v;
01890         edge->vstep     =(verts[end].v-edge->v)*yd;
01891 
01892         edge->z         =(1.0f / verts[top].z) * (geFloat)ZBUFFER_PREC;
01893         edge->zstep     =(((1.0f / verts[end].z) * (geFloat)ZBUFFER_PREC)-edge->z)*yd;
01894 
01895         edge->r         =verts[top].r;
01896         edge->rstep     =(verts[end].r-edge->r)*yd;
01897 
01898         edge->g         =verts[top].g;
01899         edge->gstep     =(verts[end].g-edge->g)*yd;
01900 
01901         edge->b         =verts[top].b;
01902         edge->bstep     =(verts[end].b-edge->b)*yd;
01903 }
01904 
01905 void setup_edgeFPU(EdgeAsmFPU *edge, DRV_TLVertex *verts, int top, int end)
01906 {
01907         int             ey,ty;
01908         geFloat yd;
01909 
01910         _asm
01911         {
01912                 push    ebx
01913                 mov             eax,end
01914                 mov     edx,top
01915 
01916                 shl     eax,2
01917                 mov     ebx,verts
01918 
01919                 shl     edx,2
01920                 lea             eax,[8*eax+eax]
01921                 lea             edx,[8*edx+edx]
01922 
01923                 fld             [ebx+eax]DRV_TLVertex.y         ; endy
01924                 fld     [ebx+edx]DRV_TLVertex.y         ; topy endy
01925                 fsub    st(1),st                        ; topy yd
01926                 fld     [ebx+eax]DRV_TLVertex.y         ; endy topy yd
01927                 fsub    [FistTruncate]
01928                 fadd    [FistMagic]                                     ; eyi  topy yd
01929                 fxch    st(2)                       ; yd   topy eyi
01930                 fstp    [yd]                                            ; topy eyi
01931                 fsub    [FistTruncate]
01932                 fadd    [FistMagic]                     ; tyi  eyi
01933                 fxch    st(1)                       ; eyi  tyi
01934                 fstp    [ey]                        ; tyi
01935                 fld     [ebx+edx]DRV_TLVertex.x     ; x    tyi
01936                 fxch    st(1)                       ; tyi  x
01937                 fstp    [ty]                        ; x
01938                 fsub    [FistTruncate]
01939                 fadd    [FistMagic]                 ; xi
01940 
01941                 mov     ebx,[FistMagic]
01942                 mov     eax,edge
01943 
01944                 sub     [ey],ebx
01945 
01946                 fstp    [eax]EdgeAsm.X
01947 
01948                 sub     [ty],ebx
01949 
01950                 sub     [eax]EdgeAsm.X, ebx
01951                 pop             ebx
01952         }
01953 
01954         edge->Height    =ey-ty;
01955 
01956         yd              =(edge->Height >0)? 1.0f/edge->Height : 1;
01957         edge->y =ty;
01958 
01959         edge->x         =verts[top].x;
01960         edge->xstep     =(verts[end].x-edge->x)*yd;
01961 
01962         edge->u         =verts[top].u;
01963         edge->ustep     =(verts[end].u-edge->u)*yd;
01964 
01965         edge->v         =verts[top].v;
01966         edge->vstep     =(verts[end].v-edge->v)*yd;
01967 
01968         edge->z         =(1.0f / verts[top].z) * (geFloat)ZBUFFER_PREC;
01969         edge->zstep     =(((1.0f / verts[end].z) * (geFloat)ZBUFFER_PREC)-edge->z)*yd;
01970 
01971         edge->r         =verts[top].r;
01972         edge->rstep     =(verts[end].r-edge->r)*yd;
01973         edge->R         =(int)(verts[top].r)&0xfc;
01974 
01975         edge->g         =verts[top].g;
01976         edge->gstep     =(verts[end].g-edge->g)*yd;
01977         edge->G         =(int)(verts[top].g)&0xfc;
01978 
01979         edge->b         =verts[top].b;
01980         edge->bstep     =(verts[end].b-edge->b)*yd;
01981         edge->B         =(int)(verts[top].b)&0xfc;
01982 }
01983 
01984 //#define       WIREFRAMEHACK
01985 
01986 void TmapTriangle_32(DRV_TLVertex *verts)
01987 {
01988         int             Top, Middle, Bottom, MiddleForCompare;
01989         int             MiddleIsLeft, BottomForCompare, Height;
01990         EdgeAsm TopToBottom, TopToMiddle, MiddleToBottom;
01991         EdgeAsm *pLeft, *pRight;
01992         geFloat Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
01993 
01994         // sort vertices in y
01995         if(Y0 < Y1)
01996         {
01997                 if(Y2 < Y0)
01998                 {
01999                         Top             =2;
02000                         Middle  =MiddleForCompare       =0;
02001                         Bottom  =BottomForCompare       =1;
02002                 }
02003                 else
02004                 {
02005                         Top     =0;
02006                         if(Y1 < Y2)
02007                         {
02008                                 Middle  =MiddleForCompare       =1;
02009                                 Bottom  =BottomForCompare       =2;
02010                         }
02011                         else
02012                         {
02013                                 Middle  =MiddleForCompare       =2;
02014                                 Bottom  =BottomForCompare       =1;
02015                         }
02016                 }
02017         }
02018         else
02019         {
02020                 if(Y2 < Y1)
02021                 {
02022                         Top             =2;
02023                         Middle  =MiddleForCompare       =1;
02024                         Bottom  =BottomForCompare       =0;
02025                 }
02026                 else
02027                 {
02028                         Top     =1;
02029                         if(Y0 < Y2)
02030                         {
02031                                 Middle  =0;
02032                                 Bottom  =BottomForCompare       =2;
02033                                 MiddleForCompare                        =3;
02034                         }
02035                         else
02036                         {
02037                                 BottomForCompare                        =3;
02038                                 Middle  =MiddleForCompare       =2;
02039                                 Bottom  =0;
02040                         }
02041                 }
02042         }
02043 
02044         setup_edge((EdgeAsm *)&TopToBottom, verts, Top, Bottom);
02045         setup_edge((EdgeAsm *)&TopToMiddle, verts, Top, Middle);
02046         setup_edge((EdgeAsm *)&MiddleToBottom, verts, Middle, Bottom);
02047 
02048         if(BottomForCompare > MiddleForCompare)
02049         {
02050                 MiddleIsLeft = 0;
02051                 pLeft = &TopToBottom; pRight = &TopToMiddle;
02052         }
02053         else
02054         {
02055                 MiddleIsLeft = 1;
02056                 pLeft = &TopToMiddle; pRight = &TopToBottom;
02057         }
02058 
02059         Height          =TopToMiddle.Height;
02060         Dest                    =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
02061         ZBufLine        =ZBuffer + (pLeft->y * ClientWindow.Width);
02062         pZBufferPtr             =ZBufLine;
02063 
02064 #ifdef WIREFRAMEHACK
02065         Top=1;
02066 #endif
02067 
02068         while(Height--)
02069         {
02070 #ifdef WIREFRAMEHACK
02071                 if(!Height || Top)
02072                 {
02073                         Top     =0;
02074                         if(pLeft->X <= pRight->X)
02075                         {
02076                                 memset(((U32 *)Dest)+pLeft->X, 0xff, (pRight->X - pLeft->X)<<2);
02077                         }
02078                         else
02079                         {
02080                                 memset(((U32 *)Dest)+pRight->X, 0xff, (pLeft->X - pRight->X)<<2);
02081                         }
02082                 }
02083                 else
02084                 {
02085                         //uncomment for zbuffered wire
02086 //              if(*(ZBufLine + pLeft->X) > ((U16)pLeft->z))
02087 //              {
02088                         *(((U32 *)Dest) + pLeft->X)     =0xffffffff;
02089 //              }
02090 //              if(*(ZBufLine + pRight->X) > ((U16)pRight->z))
02091 //              {
02092                         *(((U32 *)Dest) + pRight->X)=0xffffffff;
02093 //              }
02094                 }
02095 #else
02096                 if(bStipple)
02097                 {
02098                         if(pLeft->y & 1)
02099                         {
02100                                 if(pLeft->X <= pRight->X)
02101                                 {
02102                                         CurMapper(pLeft, pRight);
02103                                 }
02104                                 else
02105                                 {
02106                                         CurMapper(pRight, pLeft);
02107                                 }
02108                         }
02109                 }
02110                 else
02111                 {
02112                         if(pLeft->X <= pRight->X)
02113                         {
02114                                 CurMapper(pLeft, pRight);
02115                         }
02116                         else
02117                         {
02118                                 CurMapper(pRight, pLeft);
02119                         }
02120                 }
02121 #endif
02122                 Step(pLeft);
02123                 Step(pRight);
02124 
02125                 Dest            +=ClientWindow.PixelPitch / 2;
02126                 ZBufLine        +=ClientWindow.Width;
02127                 pZBufferPtr     =ZBufLine;
02128         }
02129 
02130         Height  =MiddleToBottom.Height;
02131 
02132         if(MiddleIsLeft)
02133         {
02134                 pLeft   =&MiddleToBottom;
02135                 pRight  =&TopToBottom;
02136         }
02137         else
02138         {
02139                 pLeft   =&TopToBottom;
02140                 pRight  =&MiddleToBottom;
02141         }
02142         
02143         while(Height--)
02144         {
02145 #ifdef WIREFRAMEHACK
02146                 if(!Height || Top)
02147                 {
02148                         Top     =0;
02149                         if(pLeft->X <= pRight->X)
02150                         {
02151                                 memset(((U32 *)Dest)+pLeft->X, 0xff, (pRight->X - pLeft->X)<<2);
02152                         }
02153                         else
02154                         {
02155                                 memset(((U32 *)Dest)+pRight->X, 0xff, (pLeft->X - pRight->X)<<2);
02156                         }
02157                 }
02158                 else
02159                 {
02160                         //uncomment for zbuffered wire
02161 //              if(*(ZBufLine + pLeft->X) > ((U16)pLeft->z))
02162 //              {
02163                         *(((U32 *)Dest) + pLeft->X)     =0xffffffff;
02164 //              }
02165 //              if(*(ZBufLine + pRight->X) > ((U16)pRight->z))
02166 //              {
02167                         *(((U32 *)Dest) + pRight->X)=0xffffffff;
02168 //              }
02169                 }
02170 #else
02171                 if(bStipple)
02172                 {
02173                         if(pLeft->y & 1)
02174                         {
02175                                 if(pLeft->X <= pRight->X)
02176                                 {
02177                                         CurMapper(pLeft, pRight);
02178                                 }
02179                                 else
02180                                 {
02181                                         CurMapper(pRight, pLeft);
02182                                 }
02183                         }
02184                 }
02185                 else
02186                 {
02187                         if(pLeft->X <= pRight->X)
02188                         {
02189                                 CurMapper(pLeft, pRight);
02190                         }
02191                         else
02192                         {
02193                                 CurMapper(pRight, pLeft);
02194                         }
02195                 }
02196 #endif
02197                 Step(pLeft);
02198                 Step(pRight);
02199 
02200                 Dest            +=ClientWindow.PixelPitch / 2;
02201                 ZBufLine        +=ClientWindow.Width;
02202                 pZBufferPtr     =ZBufLine;
02203         }
02204 }
02205 
02206 //16 bit fpu version
02207 void TmapTriangle_16(DRV_TLVertex *verts)
02208 {
02209         int                     Top, Middle, Bottom, MiddleForCompare;
02210         int                     MiddleIsLeft, BottomForCompare, Height;
02211         EdgeAsmFPU      TopToBottom, TopToMiddle, MiddleToBottom;
02212         EdgeAsmFPU      *pLeft, *pRight;
02213         geFloat         Y0=verts[0].y, Y1=verts[1].y, Y2=verts[2].y;
02214 
02215         // sort vertices in y
02216         if(Y0 < Y1)
02217         {
02218                 if(Y2 < Y0)
02219                 {
02220                         Top             =2;
02221                         Middle  =MiddleForCompare       =0;
02222                         Bottom  =BottomForCompare       =1;
02223                 }
02224                 else
02225                 {
02226                         Top     =0;
02227                         if(Y1 < Y2)
02228                         {
02229                                 Middle  =MiddleForCompare       =1;
02230                                 Bottom  =BottomForCompare       =2;
02231                         }
02232                         else
02233                         {
02234                                 Middle  =MiddleForCompare       =2;
02235                                 Bottom  =BottomForCompare       =1;
02236                         }
02237                 }
02238         }
02239         else
02240         {
02241                 if(Y2 < Y1)
02242                 {
02243                         Top             =2;
02244                         Middle  =MiddleForCompare       =1;
02245                         Bottom  =BottomForCompare       =0;
02246                 }
02247                 else
02248                 {
02249                         Top     =1;
02250                         if(Y0 < Y2)
02251                         {
02252                                 Middle  =0;
02253                                 Bottom  =BottomForCompare       =2;
02254                                 MiddleForCompare                        =3;
02255                         }
02256                         else
02257                         {
02258                                 BottomForCompare                        =3;
02259                                 Middle  =MiddleForCompare       =2;
02260                                 Bottom  =0;
02261                         }
02262                 }
02263         }
02264 
02265         setup_edgeFPU(&TopToBottom, verts, Top, Bottom);
02266         setup_edgeFPU(&TopToMiddle, verts, Top, Middle);
02267         setup_edgeFPU(&MiddleToBottom, verts, Middle, Bottom);
02268 
02269         if(BottomForCompare > MiddleForCompare)
02270         {
02271                 MiddleIsLeft = 0;
02272                 pLeft = &TopToBottom; pRight = &TopToMiddle;
02273         }
02274         else
02275         {
02276                 MiddleIsLeft = 1;
02277                 pLeft = &TopToMiddle; pRight = &TopToBottom;
02278         }
02279 
02280         Height  =TopToMiddle.Height;
02281 
02282         Dest                    =(U16 *)(ClientWindow.Buffer + (pLeft->y * ClientWindow.PixelPitch));
02283         ZBufLine        =ZBuffer + (pLeft->y * ClientWindow.Width);
02284         
02285         pZBufferPtr             =ZBufLine;
02286         while(Height--)
02287         {
02288                 if(bStipple)
02289                 {
02290                         if(pLeft->y & 1)
02291                         {
02292                                 if(pLeft->X <= pRight->X)
02293                                 {
02294                                         CurMapperFPU(pLeft, pRight);
02295                                 }
02296                                 else
02297                                 {
02298                                         CurMapperFPU(pRight, pLeft);
02299                                 }
02300                         }
02301                 }
02302                 else
02303                 {
02304                         if(pLeft->X <= pRight->X)
02305                         {
02306                                 CurMapperFPU(pLeft, pRight);
02307                         }
02308                         else
02309                         {
02310                                 CurMapperFPU(pRight, pLeft);
02311                         }
02312                 }
02313                 StepFPU(pLeft);
02314                 StepFPU(pRight);
02315 
02316                 Dest            +=ClientWindow.PixelPitch / 2;
02317                 ZBufLine        +=ClientWindow.Width;
02318                 pZBufferPtr     =ZBufLine;
02319         }
02320 
02321         Height  =MiddleToBottom.Height;
02322 
02323         if(MiddleIsLeft)
02324         {
02325                 pLeft   =&MiddleToBottom;
02326                 pRight  =&TopToBottom;
02327         }
02328         else
02329         {
02330                 pLeft   =&TopToBottom;
02331                 pRight  =&MiddleToBottom;
02332         }
02333         
02334         while(Height--)
02335         {
02336                 if(bStipple)
02337                 {
02338                         if(pLeft->y & 1)
02339                         {
02340                                 if(pLeft->X <= pRight->X)
02341                                 {
02342                                         CurMapperFPU(pLeft, pRight);
02343                                 }
02344                                 else
02345                                 {
02346                                         CurMapperFPU(pRight, pLeft);
02347                                 }
02348                         }
02349                 }
02350                 else
02351                 {
02352                         if(pLeft->X <= pRight->X)
02353                         {
02354                                 CurMapperFPU(pLeft, pRight);
02355                         }
02356                         else
02357                         {
02358                                 CurMapperFPU(pRight, pLeft);
02359                         }
02360                 }
02361                 StepFPU(pLeft);
02362                 StepFPU(pRight);
02363 
02364                 Dest            +=ClientWindow.PixelPitch / 2;
02365                 ZBufLine        +=ClientWindow.Width;
02366                 pZBufferPtr     =ZBufLine;
02367         }
02368 }
02369 
02370 BOOL DRIVERCC RenderMiscTexturePoly(DRV_TLVertex *Pnts, S32 NumPoints, geRDriver_THandle *THandle, U32 Flags)
02371 {
02372         int                                     i, GW_log2, MipLevel=0;
02373         DRV_TLVertex            TriVerts[3];
02374 
02375         if(!bActive)
02376         {
02377                 return  GE_TRUE;
02378         }
02379 
02380         assert(Pnts != NULL);
02381         assert(NumPoints > 2);
02382 
02383         assert(THandle->BitPtr[MipLevel] != NULL);
02384 
02385         // Assign some global variables...
02386         GMipLevel       =(U8)MipLevel;
02387         GW                      =THandle->Width >> MipLevel;
02388         GH                      =THandle->Height >> MipLevel;
02389         GWMask          =GW-1;
02390         GHMask          =GH-1;
02391         
02392         if(THandle->Flags & THANDLE_TRANS)
02393         {
02394                 PolyMode        =1;
02395         }
02396         else
02397         {
02398                 PolyMode        =0;
02399         }
02400 
02401         if(ProcessorInfo.Has3DNow)
02402         {
02403                 *((int *)(&WrapMask))           =GHMask<<16;
02404                 *(((int *)((&WrapMask)))+1)     =GWMask<<16;
02405 
02406                 *((geFloat *)(&GBL))                    =(geFloat)GH;//Mask;
02407                 *(((geFloat *)((&GBL)))+1)      =(geFloat)GW;//Mask;
02408 
02409                 //find log2 of the texture width
02410                 for(GW_log2=1;((1<<GW_log2) < GW); GW_log2++);
02411 
02412                 QShiftV =(__int64)(16 - GW_log2);
02413                 TexPal  =(U8 *)THandle->PalHandle->BitPtr[0];
02414                 GBitPtr = (U8 *)THandle->BitPtr[MipLevel];
02415 
02416                 bStipple        =FALSE;
02417                 if(THandle->PixelFormat.Flags & RDRIVER_PF_HAS_ALPHA)
02418                 {
02419                         if(THandle->AlphaHandle)
02420                         {
02421                                 ABitPtr =(U8 *)THandle->AlphaHandle->BitPtr[0];
02422                                 ATexPal =(U8 *)THandle->AlphaHandle->PalHandle->BitPtr[0];
02423 
02424                                 CurMapper       =DrawScanLineGouraudNoZAlphaTex_Asm3DNow;
02425                                 if(Flags & DRV_RENDER_NO_ZMASK)
02426                                 {
02427                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02428                                         {
02429                                                 CurMapper       =DrawScanLineGouraudNoZAlphaTex_Asm3DNow;
02430                                         }
02431                                         else
02432                                         {
02433                                                 CurMapper       =DrawScanLineGouraudNoZBufferZWriteAlphaTex_Asm3DNow;
02434                                         }
02435                                 }
02436                                 else
02437                                 {
02438                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02439                                         {
02440                                                 CurMapper       =DrawScanLineGouraudZBufferNoZWriteAlphaTex_Asm3DNow;
02441                                         }
02442                                         else
02443                                         {
02444                                                 CurMapper       =DrawScanLineGouraudZBufferAlphaTex_Asm3DNow;
02445                                         }
02446                                 }
02447                         }
02448                         else
02449                         {
02450                                 assert(THandle->PixelFormat.PixelFormat==GE_PIXELFORMAT_32BIT_ARGB);
02451                                 CurMapper       =DrawScanLineGouraudNoZAlphaARGB_Asm3DNow;
02452 /*                              if(Flags & DRV_RENDER_NO_ZMASK)
02453                                 {
02454                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02455                                         {
02456                                                 CurMapper       =DrawScanLineGouraudNoZAlphaTex_Asm3DNow;
02457                                         }
02458                                         else
02459                                         {
02460                                                 CurMapper       =DrawScanLineGouraudNoZBufferZWriteAlphaTex_Asm3DNow;
02461                                         }
02462                                 }
02463                                 else
02464                                 {
02465                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02466                                         {
02467                                                 CurMapper       =DrawScanLineGouraudZBufferNoZWriteAlphaTex_Asm3DNow;
02468                                         }
02469                                         else
02470                                         {
02471                                                 CurMapper       =DrawScanLineGouraudZBufferAlphaTex_Asm3DNow;
02472                                         }
02473                                 }*/
02474                         }
02475                 }
02476                 else
02477                 {
02478                         if(Flags & DRV_RENDER_NO_ZMASK)
02479                         {
02480                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02481                                 {
02482                                         if(PolyMode)
02483                                         {
02484                                                 CurMapper       =DrawScanLineGouraudNoZTrans_Asm3DNow;
02485                                         }
02486                                         else
02487                                         {
02488                                                 CurMapper       =DrawScanLineGouraudNoZ_Asm3DNow;
02489                                         }
02490                                 }
02491                                 else
02492                                 {
02493                                         if(PolyMode)
02494                                         {
02495                                                 CurMapper       =DrawScanLineGouraudNoZBufferZWriteTrans_Asm3DNow;
02496                                         }
02497                                         else
02498                                         {
02499                                                 CurMapper       =DrawScanLineGouraudNoZBufferZWrite_Asm3DNow;
02500                                         }
02501                                 }
02502                         }
02503                         else
02504                         {
02505                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02506                                 {
02507                                         if(PolyMode)
02508                                         {
02509                                                 CurMapper       =DrawScanLineGouraudZBufferNoZWriteTrans_Asm3DNow;
02510                                         }
02511                                         else
02512                                         {
02513                                                 CurMapper       =DrawScanLineGouraudZBufferNoZWrite_Asm3DNow;
02514                                         }
02515                                 }
02516                                 else
02517                                 {
02518                                         if(PolyMode)
02519                                         {
02520                                                 CurMapper       =DrawScanLineGouraudZBufferTrans_Asm3DNow;
02521                                         }
02522                                         else
02523                                         {
02524                                                 CurMapper       =DrawScanLineGouraudZBuffer_Asm3DNow;
02525                                         }
02526                                 }
02527                         }
02528                 }
02529                 if(NumPoints==3)
02530                 {
02531                         TriVerts[2]     =Pnts[0];
02532                         TriVerts[1]     =Pnts[1];
02533                         TriVerts[0]     =Pnts[2];
02534 
02535                         TmapTriangle_32(TriVerts);
02536                 }
02537                 else
02538                 {
02539                         for(i=0;i < NumPoints-2;i++)
02540                         {
02541                                 TriVerts[0]     =Pnts[0];
02542                                 TriVerts[1]     =Pnts[1+i];
02543                                 TriVerts[2]     =Pnts[2+i];
02544 
02545                                 TmapTriangle_32(TriVerts);
02546                         }
02547                 }
02548                 bStipple        =FALSE;
02549                 return GE_TRUE;
02550         }
02551         else
02552         {
02553                 for(GW_log2=1;((1<<GW_log2) < GW); GW_log2++);
02554 
02555                 GHMaskShifted   =GHMask << GW_log2;
02556                 VShift                  =(16 - GW_log2);
02557                 GBitPtrHalf             =(U8 *)THandle->BitPtr[MipLevel];
02558                 GBitPtrHalf             =(U8 *)((U32)(GBitPtrHalf)>>1);
02559                 bStipple                =FALSE;
02560 
02561                 if(ClientWindow.G_mask == 0x03e0)
02562                 {
02563                         if(THandle->AlphaHandle)
02564                         {
02565                                 bStipple        =GE_TRUE;
02566         /*                              if(bWindowed)
02567                                 {
02568                                         CurMapperFPU    =DrawScanLineGouraudNoZAlphaTex_AsmX86FPU;
02569                                         if(Flags & DRV_RENDER_NO_ZMASK)
02570                                         {
02571                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02572                                                 {
02573                                                         CurMapperFPU    =DrawScanLineGouraudNoZAlphaTex_AsmX86FPU;
02574                                                 }
02575                                                 else
02576                                                 {
02577                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteAlphaTex_AsmX86FPU;
02578                                                 }
02579                                         }
02580                                         else
02581                                         {
02582                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02583                                                 {
02584                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteAlphaTex_AsmX86FPU;
02585                                                 }
02586                                                 else
02587                                                 {
02588                                                         CurMapperFPU    =DrawScanLineGouraudZBufferAlphaTex_AsmX86FPU;
02589                                                 }
02590                                         }
02591                                 }
02592                                 else
02593                                 {*/
02594                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_Asm555X86FPU;
02595                                         if(Flags & DRV_RENDER_NO_ZMASK)
02596                                         {
02597                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02598                                                 {
02599                                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_Asm555X86FPU;
02600                                                 }
02601                                                 else
02602                                                 {
02603                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteTrans_Asm555X86FPU;
02604                                                 }
02605                                         }
02606                                         else
02607                                         {
02608                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02609                                                 {
02610                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteTrans_Asm555X86FPU;
02611                                                 }
02612                                                 else
02613                                                 {
02614                                                         CurMapperFPU    =DrawScanLineGouraudZBufferTrans_Asm555X86FPU;
02615                                                 }
02616                                         }
02617         //                      }
02618                         }
02619                         else
02620                         {
02621                                 if(Flags & DRV_RENDER_NO_ZMASK)
02622                                 {
02623                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02624                                         {
02625                                                 if(PolyMode)
02626                                                 {
02627                                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_Asm555X86FPU;
02628                                                 }
02629                                                 else
02630                                                 {
02631                                                         CurMapperFPU    =DrawScanLineGouraudNoZ_Asm555X86FPU;
02632                                                 }
02633                                         }
02634                                         else
02635                                         {
02636                                                 if(PolyMode)
02637                                                 {
02638                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteTrans_Asm555X86FPU;
02639                                                 }
02640                                                 else
02641                                                 {
02642                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWrite_Asm555X86FPU;
02643                                                 }
02644                                         }
02645                                 }
02646                                 else
02647                                 {
02648                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02649                                         {
02650                                                 if(PolyMode)
02651                                                 {
02652                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteTrans_Asm555X86FPU;
02653                                                 }
02654                                                 else
02655                                                 {
02656                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWrite_Asm555X86FPU;
02657                                                 }
02658                                         }
02659                                         else
02660                                         {
02661                                                 if(PolyMode)
02662                                                 {
02663                                                         CurMapperFPU    =DrawScanLineGouraudZBufferTrans_Asm555X86FPU;
02664                                                 }
02665                                                 else
02666                                                 {
02667                                                         CurMapperFPU    =DrawScanLineGouraudZBuffer_Asm555X86FPU;
02668                                                 }
02669                                         }
02670                                 }
02671                         }
02672                 }
02673                 else
02674                 {
02675                         if(THandle->AlphaHandle)
02676                         {
02677                                 bStipple        =GE_TRUE;
02678         /*                              if(bWindowed)
02679                                 {
02680                                         CurMapperFPU    =DrawScanLineGouraudNoZAlphaTex_AsmX86FPU;
02681                                         if(Flags & DRV_RENDER_NO_ZMASK)
02682                                         {
02683                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02684                                                 {
02685                                                         CurMapperFPU    =DrawScanLineGouraudNoZAlphaTex_AsmX86FPU;
02686                                                 }
02687                                                 else
02688                                                 {
02689                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteAlphaTex_AsmX86FPU;
02690                                                 }
02691                                         }
02692                                         else
02693                                         {
02694                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02695                                                 {
02696                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteAlphaTex_AsmX86FPU;
02697                                                 }
02698                                                 else
02699                                                 {
02700                                                         CurMapperFPU    =DrawScanLineGouraudZBufferAlphaTex_AsmX86FPU;
02701                                                 }
02702                                         }
02703                                 }
02704                                 else
02705                                 {*/
02706                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_AsmX86FPU;
02707                                         if(Flags & DRV_RENDER_NO_ZMASK)
02708                                         {
02709                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02710                                                 {
02711                                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_AsmX86FPU;
02712                                                 }
02713                                                 else
02714                                                 {
02715                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteTrans_AsmX86FPU;
02716                                                 }
02717                                         }
02718                                         else
02719                                         {
02720                                                 if(Flags & DRV_RENDER_NO_ZWRITE)
02721                                                 {
02722                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteTrans_AsmX86FPU;
02723                                                 }
02724                                                 else
02725                                                 {
02726                                                         CurMapperFPU    =DrawScanLineGouraudZBufferTrans_AsmX86FPU;
02727                                                 }
02728                                         }
02729         //                      }
02730                         }
02731                         else
02732                         {
02733                                 if(Flags & DRV_RENDER_NO_ZMASK)
02734                                 {
02735                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02736                                         {
02737                                                 if(PolyMode)
02738                                                 {
02739                                                         CurMapperFPU    =DrawScanLineGouraudNoZTrans_AsmX86FPU;
02740                                                 }
02741                                                 else
02742                                                 {
02743                                                         CurMapperFPU    =DrawScanLineGouraudNoZ_AsmX86FPU;
02744                                                 }
02745                                         }
02746                                         else
02747                                         {
02748                                                 if(PolyMode)
02749                                                 {
02750                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWriteTrans_AsmX86FPU;
02751                                                 }
02752                                                 else
02753                                                 {
02754                                                         CurMapperFPU    =DrawScanLineGouraudNoZBufferZWrite_AsmX86FPU;
02755                                                 }
02756                                         }
02757                                 }
02758                                 else
02759                                 {
02760                                         if(Flags & DRV_RENDER_NO_ZWRITE)
02761                                         {
02762                                                 if(PolyMode)
02763                                                 {
02764                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWriteTrans_AsmX86FPU;
02765                                                 }
02766                                                 else
02767                                                 {
02768                                                         CurMapperFPU    =DrawScanLineGouraudZBufferNoZWrite_AsmX86FPU;
02769                                                 }
02770                                         }
02771                                         else
02772                                         {
02773                                                 if(PolyMode)
02774                                                 {
02775                                                         CurMapperFPU    =DrawScanLineGouraudZBufferTrans_AsmX86FPU;
02776                                                 }
02777                                                 else
02778                                                 {
02779                                                         CurMapperFPU    =DrawScanLineGouraudZBuffer_AsmX86FPU;
02780                                                 }
02781                                         }
02782                                 }
02783                         }
02784                 }
02785                 if(NumPoints==3)
02786                 {
02787                         TriVerts[0]     =Pnts[0];
02788                         TriVerts[1]     =Pnts[1];
02789                         TriVerts[2]     =Pnts[2];
02790                         TriVerts[0].u   *=GWMask;
02791                         TriVerts[0].v   *=GHMask;
02792                         TriVerts[1].u   *=GWMask;
02793                         TriVerts[1].v   *=GHMask;
02794                         TriVerts[2].u   *=GWMask;
02795                         TriVerts[2].v   *=GHMask;
02796 
02797                         TmapTriangle_16(TriVerts);
02798                 }
02799                 else
02800                 {
02801                         for(i=0;i < NumPoints-2;i++)
02802                         {
02803                                 TriVerts[0]     =Pnts[0];
02804                                 TriVerts[1]     =Pnts[1+i];
02805                                 TriVerts[2]     =Pnts[2+i];
02806 
02807                                 TriVerts[0].u   *=GWMask;
02808                                 TriVerts[0].v   *=GHMask;
02809                                 TriVerts[1].u   *=GWMask;
02810                                 TriVerts[1].v   *=GHMask;
02811                                 TriVerts[2].u   *=GWMask;
02812                                 TriVerts[2].v   *=GHMask;
02813 
02814                                 TmapTriangle_16(TriVerts);
02815                         }
02816                 }
02817                 bStipple        =FALSE;
02818                 return  GE_TRUE;
02819         }
02820 
02821 }
02822 
02823 
02824 #if 0
02825 BOOL DRIVERCC BlitDecal(geRDriver_THandle *THandle, RECT *SRect, int32 x, int32 y)
02826 {
02827         S32             w, h, Width, Height, Stride;
02828 
02829         return GE_TRUE;
02830 
02831         if(x >= ClientWindow.PixelPitch)
02832                 return GE_TRUE;
02833         if(y >= ClientWindow.Height)
02834                 return GE_TRUE;
02835 
02836         if(!THandle)
02837         {
02838                 SetLastDrvError(DRV_ERROR_INVALID_PARMS, "SOFT_DrawDecal:  NULL THandle parm.");
02839                 return FALSE;
02840         }
02841         
02842         if(THandle->Id < 0 || THandle->Id > MAX_DECALS || !Decals[THandle->Id].Used)
02843         {
02844                 SetLastDrvError(DRV_ERROR_GENERIC, "SOFT_DrawDecal:  Invalid decal.");
02845                 return FALSE;
02846         }
02847 
02848         if(ProcessorInfo.Has3DNow)
02849         {
02850                 U8              *BitPtr;
02851                 U32             *pScrPtr2;
02852                 DRV_RGB *PalPtr =THandle->Palette;
02853 
02854                 BitPtr  =(U8 *)Decals[THandle->Id].BitPtr;
02855                 Width   =Stride =Decals[THandle->Id].Width;
02856                 Height  =Decals[THandle->Id].Height;
02857                 
02858                 if(SRect)
02859                 {
02860                         BitPtr += SRect->top*Width + SRect->left;
02861                         Height = SRect->bottom - SRect->top;
02862                         Width = SRect->right - SRect->left;
02863                 }
02864 
02865                 if(x < 0)
02866                 {
02867                         if(x+Width <= 0)
02868                                 return GE_TRUE;
02869                         BitPtr -= x;
02870                         Width += x;
02871                         x=0;
02872                 }
02873 
02874                 if(y < 0)
02875                 {
02876                         if(y+Height <= 0)
02877                                 return GE_TRUE;
02878                         BitPtr -= (y*Stride);
02879                         Height += y;
02880                         y=0;
02881                 }
02882                 
02883                 if(x + Width >= (ClientWindow.PixelPitch-1))
02884                         Width -= (x+Width) - (ClientWindow.PixelPitch-1);
02885 
02886                 if(y + Height >= (ClientWindow.Height-1))
02887                         Height -=  (y+Height) - (ClientWindow.Height-1);
02888 
02889                 pScrPtr32bpp    =(U32*)(ClientWindow.Buffer);
02890                 pScrPtr32bpp    =&pScrPtr32bpp[y *ClientWindow.PixelPitch + x];
02891                 pScrPtr2                =pScrPtr32bpp;
02892 
02893                 Stride -= Width;
02894 
02895                 for (h=0; h< Height; h++)
02896                 {
02897                         for (w=0; w< Width; w++)
02898                         {
02899                                 U8      idx     =*BitPtr++;
02900                                 if(idx != 0xff)
02901                                         *pScrPtr32bpp   =*((U32 *)&PalPtr[idx]);
02902                                 
02903                                 pScrPtr32bpp++;
02904                         }
02905                         BitPtr  +=Stride;
02906                         pScrPtr2+=ClientWindow.PixelPitch;
02907                         pScrPtr32bpp    =pScrPtr2;
02908                 }
02909         }
02910         else
02911         {
02912                 U16             *BitPtr;
02913                 U16             *pScrPtr2;
02914 
02915                 BitPtr = Decals[THandle->Id].BitPtr;
02916                 Width = Stride = Decals[THandle->Id].Width;
02917                 Height = Decals[THandle->Id].Height;
02918                 
02919                 if(SRect)
02920                 {
02921                         BitPtr += SRect->top*Width + SRect->left;
02922                         Height = SRect->bottom - SRect->top;
02923                         Width = SRect->right - SRect->left;
02924                 }
02925 
02926                 if(x < 0)
02927                 {
02928                         if(x+Width <= 0)
02929                                 return GE_TRUE;
02930                         BitPtr -= x;
02931                         Width += x;
02932                         x=0;
02933                 }
02934 
02935                 if(y < 0)
02936                 {
02937                         if(y+Height <= 0)
02938                                 return GE_TRUE;
02939                         BitPtr -= (y*Stride);
02940                         Height += y;
02941                         y=0;
02942                 }
02943                 
02944                 if(x + Width >= (ClientWindow.PixelPitch-1))
02945                         Width -= (x+Width) - (ClientWindow.PixelPitch-1);
02946 
02947                 if(y + Height >= (ClientWindow.Height-1))
02948                         Height -=  (y+Height) - (ClientWindow.Height-1);
02949 
02950                 pScrPtr16bpp = (U16*)(ClientWindow.Buffer);
02951                 pScrPtr16bpp = &pScrPtr16bpp[y *ClientWindow.PixelPitch + x];
02952                 pScrPtr2 = pScrPtr16bpp;
02953 
02954                 Stride -= Width;
02955 
02956                 for (h=0; h< Height; h++)
02957                 {
02958                         for (w=0; w< Width; w++)
02959                         {
02960                                 U16 Color = *BitPtr++;
02961                                 if(Color != 0xffff)
02962                                         *pScrPtr16bpp = Color;
02963                                 
02964                                 pScrPtr16bpp++;
02965                         }
02966                         BitPtr += Stride;
02967                         pScrPtr2 += ClientWindow.PixelPitch;
02968                         pScrPtr16bpp = pScrPtr2;
02969                 }
02970         }
02971         return GE_TRUE;
02972 }
02973 #endif
02974 
02975 static S32              BWidth, BHeight, BStride;
02976 static S32              DrawWidth, DrawHeight;
02977 static S32              EbpAdd, EdiAdd;
02978 static U16              *BBitPtr16;
02979 static U8               *BBitPtr;
02980 extern VidModeList      *cmode;
02981 extern RECT                     FrontRect;
02982 
02983 BOOL DRIVERCC DrawDecal(geRDriver_THandle *THandle, RECT *SRect, int32 x, int32 y)
02984 {
02985         U32     *PalPtr;
02986 
02987         if(!bActive)
02988         {
02989                 return  GE_TRUE;
02990         }
02991         /*
02992         if(SRect)
02993         {
02994                 OutputDebugString("What the !?!?!\n");
02995                 return  DDrawBlitDecal(Decals[Bitmap->Id].Surface, SRect, x, y);
02996         }
02997         else
02998         {
02999                 RECT    SrcRect;
03000                 SrcRect.left=0;
03001                 SrcRect.top=0;
03002                 SrcRect.right=Bitmap->Width-1;
03003                 SrcRect.bottom=Bitmap->Height-1;
03004                 OutputDebugString("NULL rect2\n");
03005 //              return  DDrawBlitDecal(Decals[Bitmap->Id].Surface, &SrcRect, x, y);
03006                 DDrawBlitDecal(Decals[Bitmap->Id].Surface, &SrcRect, x, y);
03007 
03008         }
03009         */
03010 //      POINT   uleft;
03011 //      uleft.x =x;
03012 //      uleft.y =y;
03013 
03014 /*      if(!bWindowed)
03015         {
03016                 if(cmode->flags & STRETCHMODE)
03017                 {
03018                         if(!PtInRect(&FrontRect, uleft))
03019                         {
03020                                 DDrawBlitDecalToFront(Decals[Bitmap->Id].Surface, SRect, x, y);
03021                                 return  GE_TRUE;
03022                         }
03023                 }
03024                 else if((!bBackLocked && !bWindowed))
03025                 {
03026                         DDrawBlitDecalDelayed(Decals[Bitmap->Id].Surface, SRect, x, y);
03027                         return  GE_TRUE;
03028 //              }
03029         }
03030 //      return GE_TRUE;
03031 */
03032         
03033         BWidth          =THandle->Width;
03034         BHeight         =THandle->Height;
03035         DrawWidth       =THandle->Width;
03036         DrawHeight      =THandle->Height;
03037         
03038         if(ProcessorInfo.Has3DNow )
03039         {
03040                 BBitPtr         =(U8 *)THandle->BitPtr[0];
03041 
03042                 if ( ! THandle->PalHandle )
03043                         return 0;
03044 
03045                 PalPtr  =(U32 *)THandle->PalHandle->BitPtr[0];
03046 
03047                 if(SRect)
03048                 {
03049                         BBitPtr         +=SRect->top * DrawWidth + SRect->left;
03050                         DrawHeight      =(SRect->bottom - SRect->top);
03051                         DrawWidth       =(SRect->right - SRect->left);
03052                 }
03053 
03054                 if(x < 0)
03055                 {
03056                         if(x + DrawWidth <= 0)
03057                         {
03058                                 return  GE_TRUE;
03059                         }
03060                         BBitPtr         -=x;
03061                         DrawWidth       +=x;
03062                         x                       =0;
03063                 }
03064 
03065                 if(y < 0)
03066                 {
03067                         if(y + DrawHeight <= 0)
03068                         {
03069                                 return  GE_TRUE;
03070                         }
03071                         BBitPtr         -=y * BWidth;
03072                         DrawHeight      +=y;
03073                         y                       =0;
03074                 }
03075                 
03076                 if(x >= ClientWindow.Width)
03077                 {
03078                         return  GE_TRUE;
03079                 }
03080                 if(y >= ClientWindow.Height)
03081                 {
03082                         return  GE_TRUE;
03083                 }
03084 
03085                 if(x + DrawWidth >= (ClientWindow.Width-1))
03086                         DrawWidth -= (x+DrawWidth) - (ClientWindow.Width-1);
03087 
03088                 if(y + DrawHeight >= (ClientWindow.Height-1))
03089                         DrawHeight -=  (y+DrawHeight)- (ClientWindow.Height-1);
03090 
03091                 if(DrawWidth <= 0)
03092                         return GE_TRUE;
03093                 
03094                 if(DrawHeight <= 0)
03095                         return GE_TRUE;
03096 
03097                 pScrPtr32bpp    =(U32 *)(ClientWindow.Buffer);
03098                 pScrPtr32bpp    =&pScrPtr32bpp[y * ClientWindow.Width + x];
03099 
03100                 __asm
03101                 {
03102                         push ecx
03103                         push esi
03104                         push edi
03105                         push ebp
03106 
03107                         mov     ebx,PalPtr
03108 
03109                         mov ebp, pScrPtr32bpp
03110                         mov edi, BBitPtr
03111 
03112                         mov ecx, DrawWidth
03113 
03114                         mov edx, ClientWindow.PixelPitch
03115                         shl ecx,2
03116                         sub edx, ecx
03117                         mov EbpAdd, edx
03118 
03119                         mov edx, BWidth
03120                         mov ecx, DrawHeight
03121                         sub edx, DrawWidth
03122                         mov EdiAdd, edx
03123 
03124 
03125                 NextHeight:
03126                 
03127                         push ecx
03128                         mov ecx, DrawWidth
03129 
03130                         lea     ebp,[4*ecx+ebp]
03131 
03132                         add edi, ecx
03133 //                      shl ecx, 2
03134 //                      add ebp, ecx
03135 
03136                         neg ecx
03137 
03138                         NextWidth:
03139                                 xor     eax,eax
03140                                 mov al, [edi+ecx]
03141                                 
03142                                 cmp al,0ffh
03143                                 je Skip
03144 
03145 //                              cmp al,01h
03146 //                              je Skip
03147 
03148                                 mov     eax,[ebx+eax*4]
03149 
03150                                 mov [ebp+ecx*4], eax
03151 
03152                         Skip:
03153                                 inc ecx
03154                                 jnz NextWidth
03155 
03156                         add ebp, EbpAdd
03157                         add edi, EdiAdd
03158 
03159                         pop ecx
03160                         
03161                         sub ecx, 1
03162                         jnz NextHeight
03163 
03164                         pop ebp
03165                         pop edi
03166                         pop esi
03167                         pop ecx
03168                 }
03169         }
03170         else
03171         {
03172                 BBitPtr16       =THandle->BitPtr[0];
03173                 if(SRect)
03174                 {
03175                         BBitPtr16       +=SRect->top * DrawWidth + SRect->left;
03176                         DrawHeight      =(SRect->bottom - SRect->top);
03177                         DrawWidth       =(SRect->right - SRect->left);
03178                 }
03179 
03180                 if(x < 0)
03181                 {
03182                         if(x + DrawWidth <= 0)
03183                         {
03184                                 return  GE_TRUE;
03185                         }
03186                         BBitPtr16       -=x;
03187                         DrawWidth       +=x;
03188                         x                       =0;
03189                 }
03190 
03191                 if(y < 0)
03192                 {
03193                         if(y + DrawHeight <= 0)
03194                         {
03195                                 return  GE_TRUE;
03196                         }
03197                         BBitPtr16       -=y*BWidth;
03198                         DrawHeight      +=y;
03199                         y                       =0;
03200                 }
03201                 
03202                 if(x >= ClientWindow.Width)
03203                 {
03204                         return  GE_TRUE;
03205                 }
03206                 if(y >= ClientWindow.Height)
03207                 {
03208                         return  GE_TRUE;
03209                 }
03210 
03211                 if(x + DrawWidth >= (ClientWindow.Width - 1))
03212                 {
03213                         DrawWidth       -=(x + DrawWidth) - (ClientWindow.Width - 1);
03214                 }
03215                 if(y + DrawHeight >= (ClientWindow.Height - 1))
03216                 {
03217                         DrawHeight      -=(y + DrawHeight) - (ClientWindow.Height - 1);
03218                 }
03219 
03220                 if(DrawWidth <= 0)
03221                 {
03222                         return  GE_TRUE;
03223                 }
03224                 if(DrawHeight <= 0)
03225                 {
03226                         return  GE_TRUE;
03227                 }
03228 
03229                 pScrPtr16bpp    =(U16 *)(ClientWindow.Buffer);
03230                 pScrPtr16bpp    =&pScrPtr16bpp[y * (ClientWindow.PixelPitch >> 1) + x];
03231 
03232                 __asm
03233                 {
03234                         push ecx
03235                         push esi
03236                         push edi
03237                         push ebp
03238 
03239                         mov ebp, pScrPtr16bpp
03240                         mov edi, BBitPtr16
03241 
03242                         mov ecx, DrawWidth
03243 
03244                         mov edx, ClientWindow.PixelPitch
03245                         sub edx, ecx
03246                         sub edx, ecx
03247                         mov EbpAdd, edx
03248 
03249                         mov edx, BWidth
03250                         add edx, BWidth
03251                         sub edx, ecx
03252                         sub edx, ecx
03253                         mov EdiAdd, edx
03254 
03255                         mov ecx, DrawHeight
03256 
03257                 NextHeightA:
03258                 
03259                         push ecx
03260                         mov ecx, DrawWidth
03261 
03262                         shl ecx, 1
03263                         add ebp, ecx
03264                         add edi, ecx
03265 
03266                         neg ecx
03267 
03268                         NextWidthA:
03269                                 mov ax, [edi+ecx]
03270                                 
03271                                 cmp ax, 0x1
03272                                 je SkipA
03273 
03274                                 mov [ebp+ecx], ax
03275 
03276                         SkipA:
03277                                 add ecx, 2
03278                                 jnz NextWidthA
03279 
03280                         add ebp, EbpAdd
03281                         add edi, EdiAdd
03282 
03283                         pop ecx
03284                         
03285                         sub ecx, 1
03286                         jnz NextHeightA
03287 
03288                         pop ebp
03289                         pop edi
03290                         pop esi
03291                         pop ecx
03292                 }
03293         }
03294         return GE_TRUE;
03295 }
03296 
03297 static Fixed16  UStep, VStep, ZStep;
03298 static int32    Length;
03299 static uint16   Color;
03300 static int32    ESPSave;
03301 
03302 void ClearZBuffer(DRV_Window *Window)
03303 {
03304         //hahhah memcpy is faster than anything I can do
03305         //return;
03306         S32     ZBSize;
03307 /*      if(0 && ProcessorInfo.Has3DNow)
03308         {
03309                 ZBSize  =(Window->Width*Window->Height)>>5;
03310 
03311                 _asm    _emit   0x0f    \
03312                 _asm    _emit   0x0e    \
03313                 _asm    mov             eax,[ZBuffer]
03314                 _asm    mov             ebx,[ZBuffer]
03315                 _asm    mov             ecx,dword ptr[ZBSize]
03316 //              _asm    _emit   0x0f                            \
03317 //              _asm    _emit   0x0d                            \
03318 //              _asm    _emit   0x00
03319                 _asm    movq    mm0,[Zero]
03320                 _asm    movq    mm1,[Zero]
03321 //              _asm    movq    mm2,[Zero]
03322 //              _asm    movq    mm3,[Zero]
03323 //              _asm    movq    mm4,[Zero]
03324 //              _asm    movq    mm5,[Zero]
03325 //              _asm    movq    mm6,[Zero]
03326 //              _asm    movq    mm7,[Zero]
03327 //              _asm    _emit   0x0f                            \
03328 //              _asm    _emit   0x0d                            \
03329 //              _asm    _emit   0x40                            \
03330 //              _asm    _emit   0x20                            
03331 ClearLoop3DNow:
03332                 _asm    movq    [eax],mm0
03333                 _asm    movq    [ebx+32],mm1
03334 //              _asm    _emit   0x0f                            \
03335 //              _asm    _emit   0x0d                            \
03336 //              _asm    _emit   0x40                            \
03337 //              _asm    _emit   0x40                            
03338                 _asm    movq    [eax+8],mm0
03339                 _asm    movq    [ebx+40],mm1
03340                 _asm    movq    [eax+16],mm0
03341                 _asm    movq    [ebx+48],mm1
03342                 _asm    movq    [eax+24],mm0
03343                 _asm    movq    [ebx+56],mm1
03344                 _asm    add             eax,64
03345                 _asm    add             ebx,64
03346 //              _asm    _emit   0x0f                            \
03347 //              _asm    _emit   0x0d                            \
03348 //              _asm    _emit   0x40                            \
03349 //              _asm    _emit   0x60                            
03350                 _asm    dec             ecx
03351                 _asm    jnz             ClearLoop3DNow
03352                 _asm    _emit   0x0f    \
03353                 _asm    _emit   0x0e    \
03354         }
03355         else if(0 && ProcessorInfo.HasMMX)
03356         {
03357                 ZBSize  =(Window->Width*Window->Height)>>4;
03358 
03359                 _asm    emms
03360                 _asm    mov             eax,[ZBuffer]
03361                 _asm    mov             ecx,dword ptr[ZBSize]
03362                 _asm    movq    mm0,[Zero]
03363 ClearLoop:
03364                 _asm    movq    [eax],mm0
03365                 _asm    movq    [eax+8],mm0
03366                 _asm    movq    [eax+16],mm0
03367                 _asm    movq    [eax+24],mm0
03368                 _asm    add             eax,32
03369                 _asm    dec             ecx
03370                 _asm    jnz             ClearLoop
03371                 _asm    emms
03372         }
03373         else
03374 */      {
03375                 ZBSize = (Window->Width*Window->Height)<<1;
03376                 memset(ZBuffer, 0, ZBSize);
03377         }
03378 }
03379 
03380 //===========================================================================================
03381 //      Render Sys init, de-init code
03382 //===========================================================================================
03383 BOOL RenderInit(DRV_Window *Window)
03384 {
03385 //      U32     OldFlags        =0;
03386 
03387         ZBuffer =(U16 *)malloc(ClientWindow.Width * ClientWindow.Height * 2);
03388 
03389 /*      if(!VirtualProtect((U8 *)ZBuffer,
03390                 (ClientWindow.Width * ClientWindow.Height)*2,
03391                 PAGE_READWRITE | PAGE_NOCACHE,
03392                 &OldFlags))
03393         {
03394                 ErrorPrintf("Failed to set zbuffer page uncacheable\n");
03395         }
03396 */
03397         if(!ZBuffer)
03398         {
03399                 SetLastDrvError(DRV_ERROR_NO_MEMORY, "SOFT_RenderInit:  Not enough memory for ZBuffer.");
03400                 return FALSE;
03401         }
03402         
03403         #define Mul(a) (uint32)((1.0f/(geFloat)(a))*65536*32768)
03404         //#define Mul(a) ((uint32)((1.0f/(geFloat)(a))*(1<<31)))
03405 
03406         return GE_TRUE;
03407 }
03408 
03409 BOOL RenderShutdown(void)
03410 {
03411         if(ZBuffer)
03412         {
03413                 free(ZBuffer);
03414                 ZBuffer =NULL;
03415         }
03416         return  GE_TRUE;
03417 }
03418 

Generated on Tue Sep 30 12:36:17 2003 for GTestAndEngine by doxygen 1.3.2