home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Jeux / demos / crystalPPC.lha / scan.cpp < prev    next >
C/C++ Source or Header  |  1998-02-05  |  15KB  |  644 lines

  1. #include <math.h>
  2. #include <time.h>
  3. #include "system.h"
  4.  
  5. #ifndef DEF_H
  6. #include "def.h"
  7. #endif
  8.  
  9. #ifndef SCAN_H
  10. #include "scan.h"
  11. #endif
  12.  
  13. #ifndef TEXTURE_H
  14. #include "texture.h"
  15. #endif
  16.  
  17. #ifndef POLYGON_H
  18. #include "polygon.h"
  19. #endif
  20.  
  21. #ifndef LIGHT_H
  22. #include "light.h"
  23. #endif
  24.  
  25. #if defined(PROC_M68K) && defined(COMP_GCC) && !defined(OS_LINUX)
  26. extern void draw_sl_map_m68k_big(void) asm("_draw_sl_map_m68k_big");
  27. #define DRAW_SL_MAP_M68K(XX,TW,TH,SHF_U,D,TMAP,INV_Z,U_DIV_Z,V_DIV_Z,M,J,K)    \
  28. ({                                        \
  29.         {                                    \
  30.                 register int _xx1 __asm("d0") = XX;                \
  31.                 register int _tw1 __asm("d1") = TW;                \
  32.                 register int _th1 __asm("d2") = TH;                \
  33.                 register int _shf_u1 __asm("d3") = SHF_U;            \
  34.                 register unsigned char *_d1 __asm("a0") = D;            \
  35.                 register unsigned char *_tmap2 __asm("a1") = TMAP;        \
  36.                 register float _inv_z1 __asm("fp0") = INV_Z;            \
  37.                 register float _u_div_z1 __asm("fp1") = U_DIV_Z;        \
  38.                 register float _v_div_z1 __asm("fp2") = V_DIV_Z;        \
  39.                 register float _m1 __asm("fp3") = M;                \
  40.                 register float _j1 __asm("fp4") = J;                \
  41.                 register float _k1 __asm("fp5") = K;                \
  42.                 __asm volatile ("jsr _draw_sl_map_m68k_big"            \
  43.                 : /* no output */                        \
  44.                 : "r"(_xx1), "r"(_tw1), "r"(_th1), "r"(_shf_u1), "r"(_d1), "r"(_tmap2), \
  45.                   "r"(_inv_z1), "r"(_u_div_z1), "r"(_v_div_z1), "r"(_m1), "r"(_j1), \
  46.                   "r"(_k1)                            \
  47.                 : "d0", "d1", "a0", "a1", "fp0", "fp1","cc","memory");        \
  48.    }                                        \
  49. })
  50. #endif
  51.  
  52. // The GCC on my Linux/68k box didn't accept more than 10 parameters to
  53. // __asm statement -- amlaukka@cc.helsinki.fi.
  54. #if defined(PROC_M68K) && defined(OS_LINUX)
  55. extern void DRAW_SL_MAP_M68K(   int, int, int, int, unsigned char*,
  56.                                 unsigned char*, float, float, float,
  57.                                 float, float, float)
  58.                                 asm("_draw_sl_map_m68k_big");
  59. #endif
  60.  
  61. Graphics* Scan::g;
  62. Camera* Scan::c;
  63. Texture* Scan::texture;
  64. Textures* Scan::textures;
  65. unsigned char* Scan::tmap;
  66. int Scan::texnr;
  67. int Scan::tw;
  68. int Scan::th;
  69. int Scan::shf_w, Scan::and_w;
  70. int Scan::shf_h, Scan::and_h;
  71. float Scan::t11, Scan::t12, Scan::t13;
  72. float Scan::t21, Scan::t22, Scan::t23;
  73. float Scan::t31, Scan::t32, Scan::t33;
  74. float Scan::tx, Scan::ty, Scan::tz;
  75. SegmentInfo Scan::sinfo;
  76. unsigned long* Scan::z_buffer = NULL;
  77.  
  78. unsigned char* Scan::tmap2;
  79. int Scan::tw2;
  80. int Scan::th2;
  81. float Scan::fdu;
  82. float Scan::fdv;
  83. int Scan::shf_u;
  84.  
  85.  
  86. void Scan::draw_scanline_flat (int xx, unsigned char* d,
  87.                    unsigned long* z_buf,
  88.                    float inv_z, float u_div_z, float v_div_z,
  89.                    float M, float J1, float K1)
  90. {
  91.   (void)z_buf; (void)inv_z; (void)u_div_z; (void)v_div_z;
  92.   (void)M; (void)J1; (void)K1;
  93.   int color = texnr;
  94.   while (xx > 0)
  95.   {
  96.  
  97.     *d++ = color;
  98.     xx--;
  99.   }
  100. }
  101.  
  102. void Scan::draw_scanline (int xx, unsigned char* d,
  103.               unsigned long* z_buf,
  104.               float inv_z, float u_div_z, float v_div_z,
  105.               float M, float J1, float K1)
  106. {
  107.   (void)z_buf;
  108.   float u1, v1, u, v, z, z1;
  109.   int uu1, vv1, duu, dvv, uu, vv;
  110.  
  111.   z = 1 / inv_z;
  112.   u = u_div_z * z;
  113.   v = v_div_z * z;
  114.   uu = QInt16 (u);
  115.   vv = QInt16 (v);
  116.  
  117.   // Some optimizations for processors with many registers (PowerPC, 680x0).
  118.   // Get global variables into registers.
  119.   unsigned long shifter_w = shf_w;
  120.   unsigned long shifter_h = shf_h;
  121.   unsigned long ander_w = and_w;
  122.   unsigned long ander_h = and_h;
  123.   unsigned char* srcTex = tmap;
  124.   unsigned char* lastD;
  125.   unsigned char* dd = d;
  126.  
  127.   while (xx > 0)
  128.   {
  129.     inv_z += M;
  130.     z1 = 1 / inv_z;
  131.  
  132.     u_div_z += J1;
  133.     v_div_z += K1;
  134.  
  135.     if (xx < INTERPOL_STEP) { lastD = dd + xx; xx = 0; }
  136.     else { lastD = dd + INTERPOL_STEP; xx -= INTERPOL_STEP; }
  137.  
  138.     u1 = u_div_z * z1;
  139.     v1 = v_div_z * z1;
  140.     uu1 = QInt16 (u1);
  141.     vv1 = QInt16 (v1);
  142.  
  143.     duu = (uu1-uu)/INTERPOL_STEP;
  144.     dvv = (vv1-vv)/INTERPOL_STEP;
  145.  
  146.     do
  147.     {
  148.       *dd++ = srcTex[((uu>>shifter_w)&ander_w) + ((vv>>shifter_h)&ander_h)];
  149.       uu += duu;
  150.       vv += dvv;
  151.     }
  152.     while (dd < lastD);
  153.   }
  154. }
  155.  
  156. #if defined(PROC_M68K) && defined(COMP_GCC)
  157. void Scan::draw_scanline_map( int xx, unsigned char *d,
  158.                 unsigned long *z_buf,
  159.                 float inv_z, float u_div_z, float v_div_z,
  160.                 float M, float J1, float K1)
  161. {
  162.         (void)z_buf;
  163.         DRAW_SL_MAP_M68K( xx, Scan::tw2, Scan::th2, shf_u, d,Scan::tmap2, inv_z, u_div_z, v_div_z, M, J1, K1);
  164. }
  165. #else
  166. void Scan::draw_scanline_map (int xx, unsigned char* d,
  167.                   unsigned long* z_buf,
  168.                   float inv_z, float u_div_z, float v_div_z,
  169.                   float M, float J1, float K1)
  170. {
  171.   (void)z_buf;
  172.   float u1, v1, u, v, z, z1;
  173.   int uu1, vv1, duu, dvv, uu, vv;
  174.  
  175.   z = 1 / inv_z;
  176.   u = u_div_z * z;
  177.   v = v_div_z * z;
  178.   uu = QInt16 (u);
  179.   vv = QInt16 (v);
  180.   if (uu < 0) uu = 0; else if (uu >= (tw2<<16)) uu = (tw2<<16)-1;
  181.   if (vv < 0) vv = 0; else if (vv >= (th2<<16)) vv = (th2<<16)-1;
  182.  
  183.   // Some optimizations for processors with many registers (PowerPC, 680x0).
  184.   // Get global variables into registers.
  185.   unsigned long shifter = shf_u;
  186.   unsigned char* srcTex = tmap2;
  187.   unsigned char* lastD;
  188.   unsigned char* dd = d;
  189.  
  190.   while (xx > 0)
  191.   {
  192.     inv_z += M;
  193.     z1 = 1 / inv_z;
  194.  
  195.     u_div_z += J1;
  196.     v_div_z += K1;
  197.  
  198.     if (xx < INTERPOL_STEP) { lastD = dd + xx; xx = 0; }
  199.     else { lastD = dd + INTERPOL_STEP; xx -= INTERPOL_STEP; }
  200.  
  201.     u1 = u_div_z * z1;
  202.     v1 = v_div_z * z1;
  203.     uu1 = QInt16 (u1);
  204.     vv1 = QInt16 (v1);
  205.  
  206.     // Slight rounding errors in floating point can cause this error!
  207.     // @@@ Can't we prevent this some way?
  208.     if (uu1 < 0) uu1 = 0; else if (uu1 >= (tw2<<16)) uu1 = (tw2<<16)-1;
  209.     if (vv1 < 0) vv1 = 0; else if (vv1 >= (th2<<16)) vv1 = (th2<<16)-1;
  210.  
  211.     duu = (uu1-uu)/INTERPOL_STEP;
  212.     dvv = (vv1-vv)/INTERPOL_STEP;
  213.  
  214.     do
  215.     {
  216.       *dd++ = srcTex[((vv>>16)<<shifter) + (uu>>16)];
  217.       uu += duu;
  218.       vv += dvv;
  219.     }
  220.     while (dd < lastD);
  221.   }
  222. }
  223. #endif
  224.  
  225. #if 0
  226.     movl i,%ecx
  227.     movl tmap2,%esi
  228.     movl d,%edi
  229.     incl %ecx
  230.     .loop:
  231.         decl %ecx
  232.     jz .end
  233.     movl vv,%edx
  234.     movl %edx,%eax
  235.     sarl $16,%eax
  236.     movl shf_u,%ebx
  237.     sall %bl,%eax
  238.     movl uu,%ebx
  239.     sarl $16,%ebx
  240.     addl %ebx,%eax
  241.     movb (%eax,%esi),%al
  242.     movb %al,(%edi)
  243.     incl %edi
  244.  
  245.     asm ("\
  246.         movl %0,%%ecx /*i*/ \
  247.     movl %0,%%esi /*tmap2*/ \
  248.     movl %0,%%edi /*d*/ \
  249.     .loop: \
  250.         testl %%ecx,%%ecx \
  251.     jz .end \
  252.     decl %%ecx \
  253.     movl %0,%%eax /*vv*/ \
  254.     sarl $16,%%eax \
  255.     movl %0,%%edx /*shf_u*/ \
  256.     sall %%edx,%%eax \
  257.     movl %0,%%edx /*uu*/ \
  258.     sarl $16,%%edx \
  259.     addl %%edx,%%eax \
  260.     movb (%%esi,%%eax),%%al \
  261.     movb %%al,(%%edi) \
  262.     incl %%edi \
  263.     jmp .loop \
  264.     .end: \
  265.         movl %%edi,%w0 \
  266.     "
  267.     : "=g" (d)
  268.     : "g" (i), "g" (tmap2), "0" (d), "g" (vv), "g" (shf_u), "g" (uu)
  269.     : "%ecx", "%edx", "%eax", "%ebx", "%edi", "%esi", "cc");
  270. #endif
  271.  
  272. void Scan::draw_scanline_transp (int xx, unsigned char* d,
  273.                  unsigned long* z_buf,
  274.                  float inv_z, float u_div_z, float v_div_z,
  275.                  float M, float J1, float K1)
  276. {
  277.   (void)z_buf;
  278.   int i;
  279.   float u1, v1, u, v, z, z1;
  280.   int uu1, vv1, duu, dvv, uu, vv;
  281.   unsigned char c;
  282.  
  283.   z = 1 / inv_z;
  284.   u = u_div_z * z;
  285.   v = v_div_z * z;
  286.   uu = QInt16 (u);
  287.   vv = QInt16 (v);
  288.   if (uu < 0) uu = 0; else if (uu >= (tw2<<16)) uu = (tw2<<16)-1;
  289.   if (vv < 0) vv = 0; else if (vv >= (th2<<16)) vv = (th2<<16)-1;
  290.  
  291.   while (xx > 0)
  292.   {
  293.     inv_z += M;
  294.     z1 = 1 / inv_z;
  295.  
  296.     u_div_z += J1;
  297.     v_div_z += K1;
  298.  
  299.     i = INTERPOL_STEP;
  300.     if (xx < i) i = xx;
  301.     xx -= i;
  302.  
  303.     u1 = u_div_z * z1;
  304.     v1 = v_div_z * z1;
  305.     uu1 = QInt16 (u1);
  306.     vv1 = QInt16 (v1);
  307.  
  308.     // Slight rounding errors in floating point can cause this error!
  309.     // @@@ Can't we prevent this some way?
  310.     if (uu1 < 0) uu1 = 0; else if (uu1 >= (tw2<<16)) uu1 = (tw2<<16)-1;
  311.     if (vv1 < 0) vv1 = 0; else if (vv1 >= (th2<<16)) vv1 = (th2<<16)-1;
  312.  
  313.     duu = (uu1-uu)/INTERPOL_STEP;
  314.     dvv = (vv1-vv)/INTERPOL_STEP;
  315.  
  316.     while (i-- > 0)
  317.     {
  318.       c = tmap[((uu>>shf_w)&and_w) + ((vv>>shf_h)&and_h)];
  319.       if (c) *d++ = c;
  320.       else d++;
  321.       uu += duu;
  322.       vv += dvv;
  323.     }
  324.   }
  325. }
  326.  
  327. void Scan::draw_scanline_filtered (int xx, unsigned char* d,
  328.                    unsigned long* z_buf,
  329.                    float inv_z, float u_div_z, float v_div_z,
  330.                    float M, float J1, float K1)
  331. {
  332.   (void)z_buf;
  333.   float u1, v1, u, v, z, z1;
  334.   int uu1, vv1, duu, dvv, uu, vv;
  335.   unsigned char c;
  336.   Filter** filters = texture->get_filters ();
  337.  
  338.   z = 1 / inv_z;
  339.   u = u_div_z * z;
  340.   v = v_div_z * z;
  341.   uu = QInt16 (u);
  342.   vv = QInt16 (v);
  343.   if (uu < 0) uu = 0; else if (uu >= (tw2<<16)) uu = (tw2<<16)-1;
  344.   if (vv < 0) vv = 0; else if (vv >= (th2<<16)) vv = (th2<<16)-1;
  345.  
  346.   // Some optimizations for processors with many registers (PowerPC, 680x0).
  347.   // Get global variables into registers.
  348.   unsigned long shifter_w = shf_w;
  349.   unsigned long shifter_h = shf_h;
  350.   unsigned long ander_w = and_w;
  351.   unsigned long ander_h = and_h;
  352.   unsigned char* srcTex = tmap;
  353.   unsigned char* lastD;
  354.   unsigned char* dd = d;
  355.  
  356.   while (xx > 0)
  357.   {
  358.     inv_z += M;
  359.     z1 = 1 / inv_z;
  360.  
  361.     u_div_z += J1;
  362.     v_div_z += K1;
  363.  
  364.     if (xx < INTERPOL_STEP) { lastD = dd + xx; xx = 0; }
  365.     else { lastD = dd + INTERPOL_STEP; xx -= INTERPOL_STEP; }
  366.  
  367.     u1 = u_div_z * z1;
  368.     v1 = v_div_z * z1;
  369.     uu1 = QInt16 (u1);
  370.     vv1 = QInt16 (v1);
  371.  
  372.     // Slight rounding errors in floating point can cause this error!
  373.     // @@@ Can't we prevent this some way?
  374.     if (uu1 < 0) uu1 = 0; else if (uu1 >= (tw2<<16)) uu1 = (tw2<<16)-1;
  375.     if (vv1 < 0) vv1 = 0; else if (vv1 >= (th2<<16)) vv1 = (th2<<16)-1;
  376.  
  377.     duu = (uu1-uu)/INTERPOL_STEP;
  378.     dvv = (vv1-vv)/INTERPOL_STEP;
  379.  
  380.     do
  381.     {
  382.       c = srcTex[((uu>>shifter_w)&ander_w) + ((vv>>shifter_h)&ander_h)];
  383.       if (filters[c]) *dd++ = filters[c]->translate (*dd);
  384.       else *dd++ = c;
  385.       uu += duu;
  386.       vv += dvv;
  387.     }
  388.     while (dd < lastD);
  389.   }
  390. }
  391.  
  392. void Scan::draw_scanline_z_buf_flat (int xx, unsigned char* d,
  393.                    unsigned long* z_buf,
  394.                    float inv_z, float u_div_z, float v_div_z,
  395.                    float M, float J1, float K1)
  396. {
  397.   (void)u_div_z; (void)v_div_z; (void)J1; (void)K1;
  398.   int i;
  399.   int zz1, dzz, zz;
  400.   int color = texnr;
  401.  
  402.   zz = QInt16 (inv_z);
  403.     
  404.   while (xx > 0)
  405.   {
  406.     inv_z += M;
  407.  
  408.     i = INTERPOL_STEP;
  409.     if (xx < i) i = xx;
  410.     xx -= i;
  411.  
  412.     zz1 = QInt16 (inv_z);
  413.     dzz = (zz1-zz)/INTERPOL_STEP;
  414.  
  415.     while (i-- > 0)
  416.     {
  417.       if (zz > (int)(*z_buf))
  418.       {
  419.     *d++ = color;
  420.     *z_buf = zz;
  421.       }
  422.       else d++;
  423.       z_buf++;
  424.       zz += dzz;
  425.     }
  426.   }
  427. }
  428.  
  429. void Scan::draw_scanline_z_buf (int xx, unsigned char* d,
  430.                 unsigned long* z_buf,
  431.                 float inv_z, float u_div_z, float v_div_z,
  432.                 float M, float J1, float K1)
  433. {
  434.   float u1, v1, z, z1, u, v;
  435.   int uu1, vv1, duu, dvv, uu, vv;
  436.   long zz, zz1, dzz;
  437.  
  438.   z = 1 / inv_z;
  439.   u = u_div_z * z;
  440.   v = v_div_z * z;
  441.   uu = QInt16 (u);
  442.   vv = QInt16 (v);
  443.   zz = QInt16 (inv_z);
  444.  
  445.   // Some optimizations for processors with many registers (PowerPC, 680x0).
  446.   // Get global variables into registers.
  447.   unsigned long shifter_w = shf_w;
  448.   unsigned long shifter_h = shf_h;
  449.   unsigned long ander_w = and_w;
  450.   unsigned long ander_h = and_h;
  451.   unsigned char* srcTex = tmap;
  452.   unsigned char* lastD;
  453.   unsigned long* z_buffer = z_buf;
  454.   unsigned char* dd = d;
  455.  
  456.   while (xx > 0)
  457.   {
  458.     inv_z += M;
  459.     z1 = 1 / inv_z;
  460.     zz1 = QInt16 (inv_z);
  461.     dzz = (zz1-zz)/INTERPOL_STEP;
  462.  
  463.     u_div_z += J1;
  464.     v_div_z += K1;
  465.  
  466.     if (xx < INTERPOL_STEP) { lastD = dd + xx; xx = 0; }
  467.     else { lastD = dd + INTERPOL_STEP; xx -= INTERPOL_STEP; }
  468.  
  469.     u1 = u_div_z * z1;
  470.     v1 = v_div_z * z1;
  471.  
  472.     uu1 = QInt16 (u1);
  473.     vv1 = QInt16 (v1);
  474.     duu = (uu1-uu)/INTERPOL_STEP;
  475.     dvv = (vv1-vv)/INTERPOL_STEP;
  476.  
  477.     do
  478.     {
  479.       if (zz > (int)(*z_buffer))
  480.       {
  481.     *dd++ = srcTex[((uu>>shifter_w)&ander_w) + ((vv>>shifter_h)&ander_h)];
  482.     *z_buffer = zz;
  483.       }
  484.       else dd++;
  485.       z_buffer++;
  486.       uu += duu;
  487.       vv += dvv;
  488.       zz += dzz;
  489.     }
  490.     while (dd < lastD);
  491.   }
  492. }
  493.  
  494. void Scan::draw_scanline_z_buf_map (int xx, unsigned char* d,
  495.                     unsigned long* z_buf,
  496.                     float inv_z, float u_div_z, float v_div_z,
  497.                     float M, float J1, float K1)
  498. {
  499.   float u1, v1, z, z1, u, v;
  500.   int uu1, vv1, duu, dvv, uu, vv;
  501.   long zz, zz1, dzz;
  502.  
  503.   z = 1 / inv_z;
  504.   u = u_div_z * z;
  505.   v = v_div_z * z;
  506.   uu = QInt16 (u);
  507.   vv = QInt16 (v);
  508.  
  509.   zz = QInt16 (inv_z);
  510.   if (uu < 0) uu = 0; else if (uu >= (tw2<<16)) uu = (tw2<<16)-1;
  511.   if (vv < 0) vv = 0; else if (vv >= (th2<<16)) vv = (th2<<16)-1;
  512.  
  513.   // Some optimizations for processors with many registers (PowerPC, 680x0).
  514.   // Get global variables into registers.
  515.   unsigned long shifter = shf_u;
  516.   unsigned char *srcTex = tmap2;
  517.   unsigned long *z_buffer = z_buf;
  518.   unsigned char *lastD;
  519.   unsigned char* dd = d;
  520.  
  521.   while (xx > 0)
  522.   {
  523.     inv_z += M;
  524.     z1 = 1 / inv_z;
  525.     zz1 = QInt16 (inv_z);
  526.  
  527.     u_div_z += J1;
  528.     v_div_z += K1;
  529.  
  530.     if (xx < INTERPOL_STEP) { lastD = dd + xx; xx = 0; }
  531.     else { lastD = dd + INTERPOL_STEP; xx -= INTERPOL_STEP; }
  532.  
  533.     u1 = u_div_z * z1;
  534.     v1 = v_div_z * z1;
  535.  
  536.     uu1 = QInt16 (u1);
  537.     vv1 = QInt16 (v1);
  538.  
  539.     // Slight rounding errors in floating point can cause this error!
  540.     // @@@ Can't we prevent this some way?
  541.     if (uu1 < 0) uu1 = 0; else if (uu1 >= (tw2<<16)) uu1 = (tw2<<16)-1;
  542.     if (vv1 < 0) vv1 = 0; else if (vv1 >= (th2<<16)) vv1 = (th2<<16)-1;
  543.  
  544.     duu = (uu1-uu)/INTERPOL_STEP;
  545.     dvv = (vv1-vv)/INTERPOL_STEP;
  546.     dzz = (zz1-zz)/INTERPOL_STEP;
  547.  
  548.     do
  549.     {
  550.       if (zz > (int)(*z_buffer))
  551.       {
  552.     *dd++ = srcTex[((vv>>16)<<shifter) + (uu>>16)];
  553.     *z_buffer = zz;
  554.       }
  555.       else dd++;
  556.       z_buffer++;
  557.       uu += duu;
  558.       vv += dvv;
  559.       zz += dzz;
  560.     }
  561.     while (dd < lastD);
  562.   }
  563. }
  564.  
  565. #if 0
  566. void Scan::light_scanline (int xx,
  567.                int uu, int vv,
  568.                unsigned char* d,
  569.                float d1, float d2, float dd1, float dd2,
  570.                float dd_u, float da_u, float dd_v, float da_v,
  571.                int lu, int lv, int sq_rad)
  572. {
  573.   int i;
  574.   float r, u1, v1;
  575.   int uu1, vv1, duu, dvv;
  576.   int sqd;
  577.   unsigned char* lt;
  578.  
  579.   while (xx > 0)
  580.   {
  581.     d1 -= dd1;
  582.     d2 += dd2;
  583.     r = d1 / d2;
  584.  
  585.     i = INTERPOL_STEP;
  586.     if (xx < i) i = xx;
  587.     xx -= i;
  588.  
  589.     u1 = r*dd_u + da_u;
  590.     v1 = r*dd_v + da_v;
  591.  
  592.     uu1 = QInt16 (u1);
  593.     vv1 = QInt16 (v1);
  594.  
  595.     duu = (uu1-uu)/INTERPOL_STEP;
  596.     dvv = (vv1-vv)/INTERPOL_STEP;
  597.  
  598.     while (i-- > 0)
  599.     {
  600.       sqd = ((uu>>16)-lu)*((uu>>16)-lu) + ((vv>>16)-lv)*((vv>>16)-lv);
  601.       sqd = sq_rad-sqd;
  602.       if (sqd > 0)
  603.       {
  604.     if (sqd > (255-NORMAL_LIGHT_LEVEL)) sqd = 255-NORMAL_LIGHT_LEVEL;
  605.     lt = textures->get_light_table (NORMAL_LIGHT_LEVEL+sqd);
  606.     *d++ = lt[*d];
  607.       }
  608.       uu += duu;
  609.       vv += dvv;
  610.     }
  611.   }
  612. }
  613. #endif
  614.  
  615. void Scan::init_draw (Polygon3D* p, PolyTexture* tex)
  616. {
  617.   (void)p;
  618.   texnr = tex->get_texnr ();
  619.   texture = textures->get_texture (texnr);
  620.   tmap = texture->get_bitmap ();
  621.   tw = texture->get_width ();
  622.   th = texture->get_height ();
  623.  
  624.   if (textures->do_lighting) tmap2 = tex->get_bitmap ();
  625.   else tmap2 = NULL;
  626.   tw2 = tex->get_width ();
  627.   th2 = tex->get_height ();
  628.   fdu = tex->get_fdu ();
  629.   fdv = tex->get_fdv ();
  630.   shf_u = tex->get_shf_u ();
  631.  
  632.   shf_w = texture->get_w_shift ();
  633.   and_w = texture->get_w_mask ();
  634.   shf_h = texture->get_h_shift ();
  635.   and_h = texture->get_h_mask ();
  636.  
  637.   and_h <<= shf_w;
  638.   shf_h += shf_w;
  639.   shf_w = 16-shf_w;
  640.   shf_h = 16-shf_h;
  641. }
  642.  
  643. //---------------------------------------------------------------------------
  644.