// ------------------------- VSPOLYC.C ------------------------------
// Polygon drawing and handling.
// (C) Copyright 1995 by Javier Ar‚valo Baeza.

#if 0
#include "vspoly.h"

//#include <string.h>

    // --------------------------------
    // Clipping region.

extern sint32 VSPLY_MinX = VSPLY_Pix2Scr(0),
              VSPLY_MaxX = VSPLY_Pix2Scr(320),
              VSPLY_MinY = VSPLY_Pix2Scr(0),
              VSPLY_MaxY = VSPLY_Pix2Scr(200);

extern const VSPLY_TClipScan *VSPLY_ClipScans = NULL;

extern float VSPLY_UMultiply = 1.0,
             VSPLY_VMultiply = 1.0;

extern VSTM_PDumpFunc VSPLY_DumpFunc = NULL;

    // --------------------------------------------------------------------
    // Functions.

    // ----------------------------------------------
    // Dumpers (high level).

extern void VSPLY_DumpGouTex(VSTM_TPixel *dest, dword offs,
                               VSPLY_PPolyPoint poly, int nverts,
                               int minyi, dword flags) {
    struct {
        VSPLY_PPolyPoint pv, pvn;
        int ns;
        VSPCoord x, dx;
        VSPFloat tx, ty, l, dtx, dty, dl;
    } l, r;
    VSPLY_PPolyPoint pv0, pvn;
    int y;
    VSPLY_PPolyPoint pv;
    int i;

    if (VSPLY_DumpFunc == NULL)
        return;

        // Handy macros to save typing.
#ifdef NEXTV
#undef NEXTV
#undef PREVV
#undef INIT
#undef ADD
#endif
#define NEXTV(p) (((p) == pvn)? pv0 : (p)+1)
#define PREVV(p) (((p) == pv0)? pvn : (p)-1)
#define INIT(e)  {VSPFloat dy, fy; VSPCoord y;                                 \
                  do {e.pv = e.pvn; e.pvn = (&e==&l)?NEXTV(e.pv):PREVV(e.pv);  \
                      e.ns = VSPLY_Scr2Pix(e.pvn->py)-VSPLY_Scr2Pix(e.pv->py); \
                  } while (e.ns == 0);                                         \
                  if (e.ns < 0) return;                                        \
                  y = e.pv->py;                                                \
                  dy = (VSPFloat)(1 << 16)/(VSPFloat)(e.pvn->py - y);          \
                  fy = (1.0/(1 << 16))*((~y) & 0xFFFF);                        \
                  e.x  = e.pv->px;                                             \
                  e.tx = e.pv->tx*VSPLY_UMultiply;                             \
                  e.ty = e.pv->ty*VSPLY_VMultiply;                             \
                  e.l  = e.pv->l;                                              \
                  e.dx  = dy*(e.pvn->px - e.x);                                \
                  e.dtx = dy*(e.pvn->tx*VSPLY_UMultiply - e.tx);               \
                  e.dty = dy*(e.pvn->ty*VSPLY_VMultiply - e.ty);               \
                  e.dl  = dy*(e.pvn->l  - e.l);                                \
                  e.x  += fy*e.dx ;                                            \
                  e.tx += fy*e.dtx;                                            \
                  e.ty += fy*e.dty;                                            \
                  e.l  += fy*e.dl ;                                            \
                 }
#define ADD(e)  {e.x+=e.dx;e.tx+=e.dtx;e.ty+=e.dty;e.l+=e.dl;}

    pv0 = poly;
    pvn = poly + nverts - 1;

    l.pvn = r.pvn = poly + minyi;
    y = VSPLY_Scr2Pix(l.pvn->py) - VSPLY_Scr2Pix(VSPLY_MinY);
    dest += y*offs;
    INIT(l);
    INIT(r);

    for (;;) {
        int n;

        if (l.ns < r.ns) n = l.ns;
        else             n = r.ns;
        l.ns -= n;
        r.ns -= n;
        while (n-- > 0) {
            int x, np;
            VSPFloat nn, ll, ltx, lty;

            x = VSPLY_Scr2Pix(l.x);
            np = VSPLY_Scr2Pix(r.x) - x;
            if (np > 0) {
                VSPFloat fx, dtx, dty, dl, mll, mrl;

                nn = 1.0/np;
                VSTM_Dither = (x^y) & 1;
                fx = (1.0/(1 << 16))*((~l.x) & 0xFFFF);
                mll = l.l/65536.0;
                mrl = r.l/65536.0;
                ll  = l.l ;
                dl  = nn*(r.l - ll);
                ll  += fx*dl;
                VSTM_APos = ((sint32)(ll)) << 5;
                VSTM_AInc = ((sint32)dl) << 5;
                ltx = l.tx;
                dtx = nn*(r.tx - ltx);
                ltx += fx*dtx;
                VSTM_UPos = ((sint32)(ltx)) << 8;
                VSTM_UInc = ((sint32)dtx) << 8;
                lty = l.ty;
                dty = nn*(r.ty - lty);
                lty += fx*dty;
                VSTM_VPos = ((sint32)(lty)) << 8;
                VSTM_VInc = ((sint32)dty) << 8;
                VSPLY_DumpFunc(dest + x, np);
            }
            ADD(l);
            ADD(r);
            y++;
            dest += offs;
        }
        if (l.ns <= 0)
            INIT(l);
        if (r.ns <= 0)
            INIT(r);
    }
}
/*
extern void VSPLY_DumpShadeTex(VSTM_TPixel *dest, dword offs,
                               VSPLY_PPolyPoint poly, int nverts,
                               int minyi, dword flags) {
    struct {
        VSPLY_PPolyPoint pv, pvn;
        int ns;
        VSPCoord x, dx;
        VSPFloat tx, ty, l, r, g, b, dtx, dty, dl, dr, dg, db;
    } l, r;
    VSPLY_PPolyPoint pv0, pvn;
    int y;
    VSPLY_PPolyPoint pv;
    int i;

            VSPFloat nn, ll, ltx, lty, lr, lg, lb;
                VSPFloat fx, dtx, dty, dl, dr, dg, db, mll, mrl;

    bool calced = FALSE;

    if (VSPLY_DumpFunc == NULL)
        return;

        // Handy macros to save typing.
#ifdef NEXTV
#undef NEXTV
#undef PREVV
#undef INIT
#undef ADD
#endif
#define NEXTV(p) (((p) == pvn)? pv0 : (p)+1)
#define PREVV(p) (((p) == pv0)? pvn : (p)-1)
#define INIT(e)  {VSPFloat dy, fy; VSPCoord y;                                 \
                  do {e.pv = e.pvn; e.pvn = (&e==&l)?NEXTV(e.pv):PREVV(e.pv);  \
                      e.ns = VSPLY_Scr2Pix(e.pvn->py)-VSPLY_Scr2Pix(e.pv->py); \
                  } while (e.ns == 0);                                         \
                  if (e.ns < 0) return;                                        \
                  y = e.pv->py;                                                \
                  dy = (VSPFloat)(1 << 16)/(VSPFloat)(e.pvn->py - y);          \
                  fy = (1.0/(1 << 16))*((~y) & 0xFFFF);                        \
                  e.x  = e.pv->px;                                             \
                  e.tx = e.pv->tx*VSPLY_UMultiply;                             \
                  e.ty = e.pv->ty*VSPLY_VMultiply;                             \
                  e.l  = e.pv->l;                                              \
                  e.r  = e.pv->r;                                              \
                  e.g  = e.pv->g;                                              \
                  e.b  = e.pv->b;                                              \
                  e.dx  = dy*(e.pvn->px - e.x);                                \
                  e.dtx = dy*(e.pvn->tx*VSPLY_UMultiply - e.tx);               \
                  e.dty = dy*(e.pvn->ty*VSPLY_VMultiply - e.ty);               \
                  e.dl  = dy*(e.pvn->l  - e.l);                                \
                  e.dr  = dy*(e.pvn->r  - e.r);                                \
                  e.dg  = dy*(e.pvn->g  - e.g);                                \
                  e.db  = dy*(e.pvn->b  - e.b);                                \
                  e.x  += fy*e.dx ;                                            \
                  e.tx += fy*e.dtx;                                            \
                  e.ty += fy*e.dty;                                            \
                  e.l  += fy*e.dl ;                                            \
                  e.r  += fy*e.dr ;                                            \
                  e.g  += fy*e.dg ;                                            \
                  e.b  += fy*e.db ;                                            \
                 }
#define ADD(e)  {e.x+=e.dx;e.tx+=e.dtx;e.ty+=e.dty;e.l+=e.dl;e.r+=e.dr;e.g+=e.dg;e.b+=e.db;}

    pv0 = poly;
    pvn = poly + nverts - 1;

    l.pvn = r.pvn = poly + minyi;
    y = VSPLY_Scr2Pix(l.pvn->py) - VSPLY_Scr2Pix(VSPLY_MinY);
    dest += y*offs;
    INIT(l);
    INIT(r);

    for (;;) {
        int n;

        if (l.ns < r.ns) n = l.ns;
        else             n = r.ns;
        l.ns -= n;
        r.ns -= n;
        while (n-- > 0) {
            int x, np;
            float spn;

            x = VSPLY_Scr2Pix(l.x);
            np = VSPLY_Scr2Pix(r.x) - x;
            if (np > 0) {

//                nn = 1.0/np;
                nn = 65536.0/(r.x-l.x);
                VSTM_Dither = (x^y) & 1;
                fx = (1.0/(1 << 16))*((~l.x) & 0xFFFF);
                mll = l.l*(1.0/65536.0);
                mrl = r.l*(1.0/65536.0);

                ll  = l.l ;
                lr  = l.r *mll;
                lg  = l.g *mll;
                lb  = l.b *mll;
                ltx = l.tx;
                lty = l.ty;

                if (calced < 3 || nverts != 3) {
                    dl  = nn*(r.l - ll);
                    VSTM_AInc = ((sint32)dl) << 5;
                    dr  = nn*(r.r *mrl - lr);
                    VSTM_RInc = ((sint32)dr) << 8;
                    dg  = nn*(r.g *mrl - lg);
                    VSTM_GInc = ((sint32)dg) << 8;
                    db  = nn*(r.b *mrl - lb);
                    VSTM_BInc = ((sint32)db) << 8;
                    dtx = nn*(r.tx - ltx);
                    VSTM_UInc = ((sint32)dtx) << 8;
                    dty = nn*(r.ty - lty);
                    VSTM_VInc = ((sint32)dty) << 8;
                    calced++;
                }
                ll  += fx*dl;
                VSTM_APos = ((sint32)(ll)) << 5;
                lr  += fx*dr;
                VSTM_RPos = ((sint32)(lr)) << 8;
                lg  += fx*dg;
                VSTM_GPos = ((sint32)(lg)) << 8;
                lb  += fx*db;
                VSTM_BPos = ((sint32)(lb)) << 8;
                ltx += fx*dtx;
                VSTM_UPos = ((sint32)(ltx)) << 8;
                lty += fx*dty;
                VSTM_VPos = ((sint32)(lty)) << 8;

//                VSPLY_DumpFunc(dest + x, np);
                {
                    uint32 u, v, a, r, g, b;
                    int i;
                    VSTM_TPixel *d;

                    u = VSTM_UPos;
                    v = VSTM_VPos;
                    a = VSTM_APos;
                    r = VSTM_RPos;
                    g = VSTM_GPos;
                    b = VSTM_BPos;
                    d = dest + x;
                    for (i = 0; i < np; i++, d++) {
                        dword k = ((u >> 16) | ((v >> 8) & 0xFF00)) & VSTM_TextureMask;
                        *d = VSTM_AddPixelSafe(
                            VSTM_AlphaTbl[(a >> 16) & 31][VSTM_TexturePtr[k]]
                          , VSTM_MAKEPIX(r >> 16, g >> 16, b >> 16));
                        u += VSTM_UInc;
                        v += VSTM_VInc;
                        a += VSTM_AInc;
                        r += VSTM_RInc;
                        g += VSTM_GInc;
                        b += VSTM_BInc;
                    }

                }

            }
            ADD(l);
            ADD(r);
            y++;
            dest += offs;
        }
        if (l.ns <= 0)
            INIT(l);
        if (r.ns <= 0)
            INIT(r);
    }
}
*/

extern void VSPLY_DumpShadeTex(VSTM_TPixel *dest, dword offs,
                               VSPLY_PPolyPoint poly, int nverts,
                               int minyi, dword flags) {
    struct {
        VSPLY_PPolyPoint pv, pvn;
        int ns;
        VSPCoord x, dx;
        VSPFloat tx, ty, l, r, g, b;
        VSPFloat dtx, dty, dl, dr, dg, db;
    } l, r;

//#define VERT2COORD(c,n) ((sint32)((c)*(1 << (n))))
//#define STORECOORD(c,n) ((sint32)((c)))
#define VERT2COORD(c,n) (((c)))
#define STORECOORD(c,n) ((sint32)((c)*(1 << (n))))
//#define STORECOORD(c,n) (((sint32)(c))*(1 << (n)))

    VSPLY_PPolyPoint pv0, pvn;
    int y;
    VSPLY_PPolyPoint pv;
    int i;

            VSPFloat ll, ltx, lty, lr, lg, lb;
                VSPFloat fx, dtx, dty, dl, dr, dg, db, mll, mrl;

    int calced = 0;

    if (VSPLY_DumpFunc == NULL)
        return;

        // Handy macros to save typing.
#ifdef NEXTV
#undef NEXTV
#undef PREVV
#undef INIT
#undef ADD
#endif
#define NEXTV(p) (((p) == pvn)? pv0 : (p)+1)
#define PREVV(p) (((p) == pv0)? pvn : (p)-1)
#define INIT(e)  {VSPFloat dy, fy; VSPCoord y;                                 \
                  do {e.pv = e.pvn; e.pvn = (&e==&l)?NEXTV(e.pv):PREVV(e.pv);  \
                      e.ns = VSPLY_Scr2Pix(e.pvn->py)-VSPLY_Scr2Pix(e.pv->py); \
                  } while (e.ns == 0);                                         \
                  if (e.ns < 0) return;                                        \
                  y = e.pv->py;                                                \
                  dy = (VSPFloat)(1 << 16)/(VSPFloat)(e.pvn->py - y);          \
                  fy = (1.0/(1 << 16))*((~y) & 0xFFFF);                        \
                  e.x  = e.pv->px;                                             \
                  e.tx = VERT2COORD(e.pv->tx*VSPLY_UMultiply,8);                             \
                  e.ty = VERT2COORD(e.pv->ty*VSPLY_VMultiply,8);                             \
                  e.l  = VERT2COORD(e.pv->l,5);                                              \
                  e.r  = VERT2COORD(e.pv->r,8);                                              \
                  e.g  = VERT2COORD(e.pv->g,8);                                              \
                  e.b  = VERT2COORD(e.pv->b,8);                                              \
                  e.dx  = dy*(e.pvn->px - e.x);                                \
                  e.dtx = dy*(VERT2COORD(e.pvn->tx*VSPLY_UMultiply,8) - e.tx);               \
                  e.dty = dy*(VERT2COORD(e.pvn->ty*VSPLY_VMultiply,8) - e.ty);               \
                  e.dl  = dy*(VERT2COORD(e.pvn->l,5)  - e.l);                                \
                  e.dr  = dy*(VERT2COORD(e.pvn->r,8)  - e.r);                                \
                  e.dg  = dy*(VERT2COORD(e.pvn->g,8)  - e.g);                                \
                  e.db  = dy*(VERT2COORD(e.pvn->b,8)  - e.b);                                \
                  e.x  += fy*e.dx ;                                            \
                  e.tx += fy*e.dtx;                                            \
                  e.ty += fy*e.dty;                                            \
                  e.l  += fy*e.dl ;                                            \
                  e.r  += fy*e.dr ;                                            \
                  e.g  += fy*e.dg ;                                            \
                  e.b  += fy*e.db ;                                            \
                 }
#define ADD(e)  {e.x+=e.dx;e.tx+=e.dtx;e.ty+=e.dty;e.l+=e.dl;e.r+=e.dr;e.g+=e.dg;e.b+=e.db;}

    pv0 = poly;
    pvn = poly + nverts - 1;

    l.pvn = r.pvn = poly + minyi;
    y = VSPLY_Scr2Pix(l.pvn->py) - VSPLY_Scr2Pix(VSPLY_MinY);
    dest += y*offs;
    INIT(l);
    INIT(r);

    for (;;) {
        int n;

        if (l.ns < r.ns) n = l.ns;
        else             n = r.ns;
        l.ns -= n;
        r.ns -= n;
        while (n-- > 0) {
            int x, np;
            float spn;

            x = VSPLY_Scr2Pix(l.x);
            np = VSPLY_Scr2Pix(r.x) - x;
            if (np > 0) {

//                nn = 1.0/np;
                VSTM_Dither = (x^y) & 1;
                fx = (1.0/(1 << 16))*((~l.x) & 0xFFFF);

//                mll = l.l*(1.0 /* /(1 << 5)*/ /65536.0);
//                mrl = r.l*(1.0 /* /(1 << 5)*/ /65536.0);
#define mll 1
#define mrl 1
                ll  = l.l ;
                lr  = l.r *mll;
                lg  = l.g *mll;
                lb  = l.b *mll;
                ltx = l.tx;
                lty = l.ty;

                if (calced < 5 || nverts != 3) {
                    VSPFloat nn = 65536.0/(r.x-l.x);
                    dl  = nn*(r.l - ll);
                    VSTM_AInc = STORECOORD(dl,5);
                    if (VSTM_AInc >= 0x80000000)
                        VSTM_AInc++;
                    dr  = nn*(r.r *mrl - lr);
                    VSTM_RInc = STORECOORD(dr,8);
                    dg  = nn*(r.g *mrl - lg);
                    VSTM_GInc = STORECOORD(dg,8);
                    db  = nn*(r.b *mrl - lb);
                    VSTM_BInc = STORECOORD(db,8);
                    dtx = nn*(r.tx - ltx);
                    VSTM_UInc = STORECOORD(dtx,0);
                    dty = nn*(r.ty - lty);
                    VSTM_VInc = STORECOORD(dty,0);
                    calced++;
                }
#undef mll
#undef mrl
                ll  += fx*dl;
                VSTM_APos = STORECOORD(ll,5);
                lr  += fx*dr;
                VSTM_RPos = STORECOORD(lr,8);
                lg  += fx*dg;
                VSTM_GPos = STORECOORD(lg,8);
                lb  += fx*db;
                VSTM_BPos = STORECOORD(lb,8);
                ltx += fx*dtx;
                VSTM_UPos = STORECOORD(ltx,0);
                lty += fx*dty;
                VSTM_VPos = STORECOORD(lty,0);

//                VSPLY_DumpFunc(dest + x, np);
                {
                    uint32 u, v, a, r, g, b;
                    sint32 da1, da2;
                    int i;
                    VSTM_TPixel *d;

                    VSTM_Dither <<= 15;
                    u = VSTM_UPos;
                    v = VSTM_VPos;
                    a = VSTM_APos + VSTM_Dither;
                    r = VSTM_RPos;
                    g = VSTM_GPos;
                    b = VSTM_BPos;
                    d = dest + x;

                    VSTM_Dither = (VSTM_Dither << 1) - 0xC000;
                    da1 = VSTM_AInc - VSTM_Dither;
                    da2 = (VSTM_AInc + VSTM_Dither) ^ da1;

#define MAKEPIX(r,g,b) ((((r) & 0xFFC000) << 6) | (((g) & 0xFFC000) >> 4) | (((b) & 0xFFC000) >> 14))
                    for (i = 0; i < np; i++, d++) {
                        dword k = ((u >> 16) | ((v >> 8) & 0xFF00)) & VSTM_TextureMask;
                        *d = VSTM_AddPixelSafe(
                            VSTM_AlphaTbl[(a >> 16)/* & 31*/][VSTM_TexturePtr[k]]
                          , MAKEPIX(r, g, b));
                        u += VSTM_UInc;
                        v += VSTM_VInc;
                        a += da1;
                        da1 ^= da2;
                        r += VSTM_RInc;
                        g += VSTM_GInc;
                        b += VSTM_BInc;
                    }

                }

            }
            ADD(l);
            ADD(r);
            y++;
            dest += offs;
        }
        if (l.ns <= 0)
            INIT(l);
        if (r.ns <= 0)
            INIT(r);
    }
}

extern void VSPLY_DumpZShadeTex(VSTM_TPixel *dest, dword offs,
                                VSPLY_PPolyPoint poly, int nverts,
                                int minyi, dword flags) {
    struct {
        VSPLY_PPolyPoint pv, pvn;
        int ns;
        VSPCoord x, dx;
        VSPFloat z, dz;
        VSPFloat tx, ty, l, r, g, b, dtx, dty, dl, dr, dg, db;
    } l, r;
    VSPLY_PPolyPoint pv0, pvn;
    int y;
    VSPLY_PPolyPoint pv;
    int i;

    if (VSPLY_DumpFunc == NULL)
        return;

        // Adjust vertices' data
    pv = poly;
    for (i = 0; i < nverts; i++) {
        VSPFloat z;

        if (pv->z <= 1.0) z = 1.0;
        else              z = 1.0/pv->z;

        pv->z   = z;
        pv->tx *= z;
        pv->ty *= z;
/*
        pv->l  *= z;
        pv->r  *= z;
        pv->g  *= z;
        pv->b  *= z;
*/
        pv++;
    }


        // Handy macros to save typing.
#ifdef NEXTV
#undef NEXTV
#undef PREVV
#undef INIT
#undef ADD
#endif
#define NEXTV(p) (((p) == pvn)? pv0 : (p)+1)
#define PREVV(p) (((p) == pv0)? pvn : (p)-1)
#define INIT(e)  {VSPFloat dy, fy; VSPCoord y;                                 \
                  do {e.pv = e.pvn; e.pvn = (&e==&l)?NEXTV(e.pv):PREVV(e.pv);  \
                      e.ns = VSPLY_Scr2Pix(e.pvn->py)-VSPLY_Scr2Pix(e.pv->py); \
                  } while (e.ns == 0);                                         \
                  if (e.ns < 0) return;                                        \
                  y = e.pv->py;                                                \
                  dy = (VSPFloat)(1 << 16)/(VSPFloat)(e.pvn->py - y);          \
                  fy = (1.0/(1 << 16))*((~y) & 0xFFFF);                        \
                  e.x  = e.pv->px;                                             \
                  e.z  = e.pv->z;                                              \
                  e.tx = e.pv->tx*VSPLY_UMultiply;                             \
                  e.ty = e.pv->ty*VSPLY_VMultiply;                             \
                  e.l  = e.pv->l;                                              \
                  e.r  = e.pv->r;                                              \
                  e.g  = e.pv->g;                                              \
                  e.b  = e.pv->b;                                              \
                  e.dx  = dy*(e.pvn->px - e.x);                                \
                  e.dz  = dy*(e.pvn->z  - e.z);                                \
                  e.dtx = dy*(e.pvn->tx*VSPLY_UMultiply - e.tx);               \
                  e.dty = dy*(e.pvn->ty*VSPLY_VMultiply - e.ty);               \
                  e.dl  = dy*(e.pvn->l  - e.l);                                \
                  e.dr  = dy*(e.pvn->r  - e.r);                                \
                  e.dg  = dy*(e.pvn->g  - e.g);                                \
                  e.db  = dy*(e.pvn->b  - e.b);                                \
                  e.x  += fy*e.dx ;                                            \
                  e.z  += fy*e.dz ;                                            \
                  e.tx += fy*e.dtx;                                            \
                  e.ty += fy*e.dty;                                            \
                  e.l  += fy*e.dl ;                                            \
                  e.r  += fy*e.dr ;                                            \
                  e.g  += fy*e.dg ;                                            \
                  e.b  += fy*e.db ;                                            \
                 }
#define ADD(e)  {e.x+=e.dx;e.z+=e.dz;e.tx+=e.dtx;e.ty+=e.dty;e.l+=e.dl;e.r+=e.dr;e.g+=e.dg;e.b+=e.db;}

    pv0 = poly;
    pvn = poly + nverts - 1;

    l.pvn = r.pvn = poly + minyi;
    y = VSPLY_Scr2Pix(l.pvn->py) - VSPLY_Scr2Pix(VSPLY_MinY);
    dest += y*offs;
    INIT(l);
    INIT(r);

    for (;;) {
        int n;

        if (l.ns < r.ns) n = l.ns;
        else             n = r.ns;
        l.ns -= n;
        r.ns -= n;
        while (n-- > 0) {
            int x, np;
            VSPFloat nn, ll, ltx, lty, lr, lg, lb;

            x = VSPLY_Scr2Pix(l.x);
            np = VSPLY_Scr2Pix(r.x) - x;
            if (np > 0) {
                VSPFloat fx, dtx, dty, dl, dr, dg, db;

                nn = 1.0/np;
                VSTM_Dither = (x^y) & 1;
                fx = (1.0/(1 << 16))*((~l.x) & 0xFFFF);
                ll  = l.l ;//*l.z;
                lr  = l.r *l.l/65536;
                lg  = l.g *l.l/65536;
                lb  = l.b *l.l/65536;
                ltx = l.tx*l.z;
                lty = l.ty*l.z;
                dl  = nn*(r.l/* *r.z*/ - ll);
                dr  = nn*(r.r *r.l/65536 - lr);
                dg  = nn*(r.g *r.l/65536 - lg);
                db  = nn*(r.b *r.l/65536 - lb);
                dtx = nn*(r.tx*r.z - ltx);
                dty = nn*(r.ty*r.z - lty);
                ll  += fx*dl;
                lr  += fx*dr;
                lg  += fx*dg;
                lb  += fx*db;
                ltx += fx*dtx;
                lty += fx*dty;
                VSTM_APos = ((sint32)(ll)) << 5;
                VSTM_RPos = ((sint32)(lr)) << 8;
                VSTM_GPos = ((sint32)(lg)) << 8;
                VSTM_BPos = ((sint32)(lb)) << 8;
                VSTM_UPos = ((sint32)(ltx)) << 8;
                VSTM_VPos = ((sint32)(lty)) << 8;
                VSTM_AInc = ((sint32)dl) << 5;
                VSTM_RInc = ((sint32)dr) << 8;
                VSTM_GInc = ((sint32)dg) << 8;
                VSTM_BInc = ((sint32)db) << 8;
                VSTM_UInc = ((sint32)dtx) << 8;
                VSTM_VInc = ((sint32)dty) << 8;
                VSPLY_DumpFunc(dest + x, np);
            }
            ADD(l);
            ADD(r);
            y++;
            dest += offs;
        }
        if (l.ns <= 0)
            INIT(l);
        if (r.ns <= 0)
            INIT(r);
    }
}

    // ----------- High level thing.

    // TRUE -> something was "most probably" drawn.
extern bool VSPLY_DrawPoly(VSTM_TPixel *dest, dword offs,
                           VSPLY_PPolyPoint poly, int nverts,
                           VSPLY_PMaterial mat, dword flags) {
    VSPCoord minx, miny, maxx, maxy;//, minz, maxz;
    int i, minyi;
    VSPLY_PPolyPoint pv;
    float matr, matg, matb;

    if (dest == NULL || poly == NULL || mat == NULL) {
        return FALSE;
    }

    flags |= mat->flags;

        // Find rectangle enclosing the polygon.
        // Also, minyi will have the index of the highest (< y) vertex.
    pv = poly;
    minx = maxx = poly->px;
    miny = maxy = poly->py;
    minyi = 0;
//    minz = poly->z;
//    maxz = poly->z;
    for (i = 1; i < nverts; i++) {
        pv++;
        if (pv->px > maxx) maxx = pv->px;
        if (pv->px < minx) minx = pv->px;
        if (pv->py > maxy) maxy = pv->py;
        if (pv->py < miny) {
            miny = pv->py;
            minyi = i;
        }
//        if (pv->z < minz) minz = pv->z;
//        if (pv->z > maxz) maxz = pv->z;
    }

        // If polygon is completely out of the screen, forget it.
    if (maxx <= VSPLY_MinX || minx >= VSPLY_MaxX
     || maxy <= VSPLY_MinY || miny >= VSPLY_MaxY)
        return FALSE;   // Not drawn.

        // Bring values into range (temporary).
    if (minx < VSPLY_MinX) minx = VSPLY_MinX;
    if (maxx > VSPLY_MaxX) maxx = VSPLY_MaxX;

    if (miny < VSPLY_MinY) miny = VSPLY_MinY;
    if (maxy > VSPLY_MaxY) maxy = VSPLY_MaxY;

    if (VSPLY_Scr2Pix(maxx) <= VSPLY_Scr2Pix(minx)
     || VSPLY_Scr2Pix(maxy) <= VSPLY_Scr2Pix(miny))
        return FALSE;   // Not drawn.

        // Material color adjustment.
    matr = ((mat->c & 0x3FC00000) >> (22-8));
    matg = ((mat->c & 0x000FF000) >> (12-8));
    matb = ((mat->c & 0x000003FC) << (8- 2));

        // Adjust vertices' data
    pv = poly;
    for (i = 0; i < nverts; i++) {
            // Bring values into range (temporary).
        if (pv->px < VSPLY_MinX) pv->px = VSPLY_MinX;
        else if (pv->px > VSPLY_MaxX) pv->px = VSPLY_MaxX;

        if (pv->py < VSPLY_MinY) pv->py = VSPLY_MinY;
        else if (pv->py > VSPLY_MaxY) pv->py = VSPLY_MaxY;

        pv->l = pv->l*(1.0-mat->selflit);

        if (!(flags & VSPLYMF_TEX)) {
                // Material color adjustment.
            pv->l /= 65536.0;
            pv->r = (pv->l*pv->r + ((1.0-pv->l)*matr));
            pv->g = (pv->l*pv->g + ((1.0-pv->l)*matg));
            pv->b = (pv->l*pv->b + ((1.0-pv->l)*matb));
            pv->l = 65536.0;
        }

        pv++;
    }

    if (mat->tex != NULL) {
        VSPLY_PTexture pt;

        pt = mat->tex;
        VSTM_TexturePtr = pt->pix;
        VSTM_TextureMask = pt->mask;
        VSPLY_UMultiply = pt->w / 256.0;
        VSPLY_VMultiply = pt->h / 256.0;
    }

    VSPLY_SelectDumper((flags & VSPLYMF_TEX) != 0, 2, (flags & VSPLYMF_BLEND50) != 0);

//    VSPLY_DumpGouTex(dest, offs, poly, nverts, minyi, flags);
    VSPLY_DumpShadeTex(dest, offs, poly, nverts, minyi, flags);
//    VSPLY_DumpZShadeTex(dest, offs, poly, nverts, minyi, flags);

    return TRUE;
}

// ----------------------

extern void VSPLY_SelectDumper(int tex, int rgb, int blend) {
    static VSTM_PDumpFunc tbl[2][3][2] = {
        {
            {
                VSTM_DumpScan0000, VSTM_DumpScan0004,
            },
            {
                VSTM_DumpScan0000, VSTM_DumpScan0004,
            },
            {
                VSTM_DumpScan0000, VSTM_DumpScan0004,
            },
        },
        {
            {
                VSTM_DumpScan1000, VSTM_DumpScan1004,
            },
            {
                VSTM_DumpScan1000, VSTM_DumpScan1004,
            },
            {
                VSTM_DumpScan2000, VSTM_DumpScan2004,
            },
        },
    };

    VSPLY_DumpFunc = tbl[tex != 0][rgb%3][blend != 0];
}

// ------------------------- VSPOLYC.C ------------------------------
#endif