Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

140 lines
4.6 KiB

  1. //-----------------------------------------------------------------------------
  2. //
  3. // This file contains C span loops.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1997.
  6. //
  7. //-----------------------------------------------------------------------------
  8. include(`ctexaddr.mh')dnl
  9. #include "rgb_pch.h"
  10. #pragma hdrstop
  11. #include "cloop.h"
  12. #include "cspnutil.h"
  13. //-----------------------------------------------------------------------------
  14. //
  15. // C_LoopAny
  16. //
  17. // Loops over the pixels of a span, calling processing routines at each one.
  18. // Handles any pixel-to-pixel step.
  19. //
  20. //-----------------------------------------------------------------------------
  21. void C_LoopAny(PD3DI_RASTCTX pCtx, PD3DI_RASTPRIM pP, PD3DI_RASTSPAN pS)
  22. {
  23. // get values to iterate
  24. UINT16 uPix = pS->uPix;
  25. // Keep dither pattern up to date directly, so keeping SI.uX up
  26. // to date is not necessary, except for debug
  27. pCtx->SI.uDitherOffset = (pS->uY & 3) | ((pS->uX & 3)<<2);
  28. if (pCtx->pdwRenderState[D3DRS_FOGENABLE]) {
  29. D3DCOLOR FogColor = pCtx->pdwRenderState[D3DRS_FOGCOLOR];
  30. UINT16 uMFog = 0xff - (pS->uFog>>8);
  31. UINT16 FR = (UINT16)RGBA_GETRED(FogColor);
  32. UINT16 FG = (UINT16)RGBA_GETGREEN(FogColor);
  33. UINT16 FB = (UINT16)RGBA_GETBLUE(FogColor);
  34. pCtx->SI.uFogR = uMFog * FR; // 0.8 * 8.0 = 8.8
  35. pCtx->SI.uFogG = uMFog * FG;
  36. pCtx->SI.uFogB = uMFog * FB;
  37. INT32 iMDFog = -pS->iDFog;
  38. // 1.7.8 * 8.0 >> 8 = 1.7.8 (ATTENTION this could overflow, but it is naturally aligned for
  39. // doing the walking. Can fix by changing precision of uFogR values, or by clamping
  40. // range of iDFog.
  41. pCtx->SI.iFogRDX = (INT16)((iMDFog * FR) >> 8);
  42. pCtx->SI.iFogGDX = (INT16)((iMDFog * FG) >> 8);
  43. pCtx->SI.iFogBDX = (INT16)((iMDFog * FB) >> 8);
  44. // if iFog*DX is positive, iFog*DX will always be too small, hence no overflow
  45. // but if iFog*DX is negative, add some to make sure overflow does not
  46. // occur
  47. if (pCtx->SI.iFogRDX < 0)
  48. {
  49. pCtx->SI.iFogRDX = min< UINT16>(pCtx->SI.iFogRDX+4, 0);
  50. }
  51. if (pCtx->SI.iFogGDX < 0)
  52. {
  53. pCtx->SI.iFogGDX = min< UINT16>(pCtx->SI.iFogGDX+4, 0);
  54. }
  55. if (pCtx->SI.iFogBDX < 0)
  56. {
  57. pCtx->SI.iFogBDX = min< UINT16>(pCtx->SI.iFogBDX+4, 0);
  58. }
  59. }
  60. // don't need to do this if not texture mapping
  61. if (true || pCtx->pdwRenderState[D3DRENDERSTATE_TEXTUREPERSPECTIVE])
  62. {
  63. for (INT32 i = 0; i < (INT32)pCtx->cActTex; i ++)
  64. {
  65. pCtx->SI.TexUV[i].iU = d_WTimesUVoW(pS->iW,pS->UVoW[i].iUoW);
  66. pCtx->SI.TexUV[i].iV = d_WTimesUVoW(pS->iW,pS->UVoW[i].iVoW);
  67. }
  68. pCtx->SI.iDW = 0x0;
  69. if (pP->iDOoWDX > 0)
  70. {
  71. // iSpecialW should be negative for the first 3 pixels of span
  72. pCtx->SI.iSpecialW = -3;
  73. }
  74. else
  75. {
  76. // iSpecialW should be negative for the last 3 pixels of span
  77. pCtx->SI.iSpecialW = 0x7fff - uPix;
  78. pCtx->SI.iSpecialW += 5; // this may wrap, but it should
  79. }
  80. }
  81. else
  82. {
  83. for (INT32 i = 0; i < (INT32)pCtx->cActTex; i ++)
  84. {
  85. pCtx->SI.TexUV[i].iU = pS->UVoW[i].iUoW>>TEX_TO_FINAL_SHIFT; // 1.11.20 >> 4 == 1.15.16
  86. pCtx->SI.TexUV[i].iV = pS->UVoW[i].iVoW>>TEX_TO_FINAL_SHIFT;
  87. }
  88. pCtx->SI.iDW = 0x0;
  89. pCtx->SI.iSpecialW = 0;
  90. }
  91. INT iSurfaceStep;
  92. INT iZStep;
  93. if (pP->uFlags & D3DI_RASTPRIM_X_DEC)
  94. {
  95. iZStep = -pCtx->iZStep;
  96. iSurfaceStep = -pCtx->iSurfaceStep;
  97. pCtx->SI.iXStep = -1; // for dithering
  98. }
  99. else
  100. {
  101. iZStep = pCtx->iZStep;
  102. iSurfaceStep = pCtx->iSurfaceStep;
  103. pCtx->SI.iXStep = 1;
  104. }
  105. while (1)
  106. {
  107. #if 0
  108. // for debug, since breakpoints with conditions are really really slow
  109. if ((pS->uX == 104) && (pS->uY == 146))
  110. {
  111. DPF(0, "Look at this");
  112. }
  113. #endif
  114. pCtx->pfnLoopEnd(pCtx, pP, pS);
  115. if (--uPix <= 0)
  116. break;
  117. pS->pZ += iZStep;
  118. pS->pSurface += iSurfaceStep;
  119. // don't update this in dithered write functions because of alpha test
  120. // ATTENTION could specialize loop routines based on things like dither and Z buffer
  121. pCtx->SI.uDitherOffset = (pCtx->SI.uDitherOffset + (pCtx->SI.iXStep<<2)) & 0xf;
  122. #ifdef DBG
  123. // handy for debug to see where we are
  124. pS->uX += (INT16)pCtx->SI.iXStep;
  125. #endif
  126. }
  127. }