00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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;
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
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;
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];
00164 geFloat GLMapMulU;
00165 geFloat GLMapMulV;
00166
00167
00168 U16 *ZBuffer;
00169 uint16 *ZBufLine;
00170
00171
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
00201
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
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
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
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
00781 if (!Current)
00782 {
00783 SMinMax[y].First = NewSList();
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
00792 if(x1 >= Current->Min && x2 <= Current->Max)
00793 {
00794 return;
00795 }
00796
00797
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
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
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
00848
00849 if (LineStart != NULL)
00850 if (x2 < Current->Min)
00851 break;
00852
00853
00854
00855
00856
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;
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
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
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
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
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
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)
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
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
01529 PolyVisible = 0;
01530
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
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
01587
01588
01589
01590
01591
01592
01593
01594
01595
01596
01597
01598
01599 {
01600
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
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
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
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
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
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
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
02086
02087
02088 *(((U32 *)Dest) + pLeft->X) =0xffffffff;
02089
02090
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
02161
02162
02163 *(((U32 *)Dest) + pLeft->X) =0xffffffff;
02164
02165
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
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
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
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;
02407 *(((geFloat *)((&GBL)))+1) =(geFloat)GW;
02408
02409
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
02453
02454
02455
02456
02457
02458
02459
02460
02461
02462
02463
02464
02465
02466
02467
02468
02469
02470
02471
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
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591
02592
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
02679
02680
02681
02682
02683
02684
02685
02686
02687
02688
02689
02690
02691
02692
02693
02694
02695
02696
02697
02698
02699
02700
02701
02702
02703
02704
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
02993
02994
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004
03005
03006
03007
03008
03009
03010
03011
03012
03013
03014
03015
03016
03017
03018
03019
03020
03021
03022
03023
03024
03025
03026
03027
03028
03029
03030
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
03134
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
03146
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
03305
03306 S32 ZBSize;
03307
03308
03309
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330
03331
03332
03333
03334
03335
03336
03337
03338
03339
03340
03341
03342
03343
03344
03345
03346
03347
03348
03349
03350
03351
03352
03353
03354
03355
03356
03357
03358
03359
03360
03361
03362
03363
03364
03365
03366
03367
03368
03369
03370
03371
03372
03373
03374 {
03375 ZBSize = (Window->Width*Window->Height)<<1;
03376 memset(ZBuffer, 0, ZBSize);
03377 }
03378 }
03379
03380
03381
03382
03383 BOOL RenderInit(DRV_Window *Window)
03384 {
03385
03386
03387 ZBuffer =(U16 *)malloc(ClientWindow.Width * ClientWindow.Height * 2);
03388
03389
03390
03391
03392
03393
03394
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
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