private void drawsegment_texture32(float leftadd,
                                     float rghtadd,
                                     int ytop,
                                     int ybottom) {
    //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details
    int ypixel = ytop;
    int lastRowStart = m_texture.length - TEX_WIDTH - 2;
    boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES];
    float screenx = 0; float screeny = 0; float screenz = 0;
    float a = 0; float b = 0; float c = 0;
    int linearInterpPower = TEX_INTERP_POWER;
    int linearInterpLength = 1 << linearInterpPower;
    if (accurateMode){
      if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup
        newax *= linearInterpLength;
        newbx *= linearInterpLength;
        newcx *= linearInterpLength;
        screenz = nearPlaneDepth;
        firstSegment = false;
      } else{
        accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate)
      }
    }

    ytop*=SCREEN_WIDTH;
    ybottom*=SCREEN_WIDTH;
//    int p = m_index;

    boolean tint = m_fill != 0xFFFFFFFF;
    int rtint = (m_fill >> 16) & 0xff;
    int gtint = (m_fill >> 8) & 0xff;
    int btint = m_fill & 0xFF;
    
    float iuf = iuadd;
    float ivf = ivadd;

    while (ytop < ybottom) {
      int xstart = (int) (xleft + PIXEL_CENTER);
      if (xstart < 0)
        xstart = 0;

      int xpixel = xstart;//accurate mode

      int xend = (int) (xrght + PIXEL_CENTER);
      if (xend > SCREEN_WIDTH)
        xend = SCREEN_WIDTH;

      float xdiff = (xstart + PIXEL_CENTER) - xleft;
      int iu = (int) (iuf * xdiff + uleft);
      int iv = (int) (ivf * xdiff + vleft);
      float iz = izadd * xdiff + zleft;

      xstart+=ytop;
      xend+=ytop;

      if (accurateMode){
        screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f));
        screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f));
        a = screenx*ax+screeny*ay+screenz*az;
        b = screenx*bx+screeny*by+screenz*bz;
        c = screenx*cx+screeny*cy+screenz*cz;
      }
      boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true;
      int interpCounter = 0;
      int deltaU = 0; int deltaV = 0;
      float fu = 0; float fv = 0;
      float oldfu = 0; float oldfv = 0;

      if (accurateMode&&goingIn){
        int rightOffset = (xend-xstart-1)%linearInterpLength;
        int leftOffset = linearInterpLength-rightOffset;
        float rightOffset2 = rightOffset / ((float)linearInterpLength);
        float leftOffset2 = leftOffset / ((float)linearInterpLength);
        interpCounter = leftOffset;
        float ao = a-leftOffset2*newax;
        float bo = b-leftOffset2*newbx;
        float co = c-leftOffset2*newcx;
        float oneoverc = 65536.0f/co;
        oldfu = (ao*oneoverc); oldfv = (bo*oneoverc);
        a += rightOffset2*newax;
        b += rightOffset2*newbx;
        c += rightOffset2*newcx;
        oneoverc = 65536.0f/c;
        fu = a*oneoverc; fv = b*oneoverc;
        deltaU = ((int)(fu - oldfu)) >> linearInterpPower;
        deltaV = ((int)(fv - oldfv)) >> linearInterpPower;
        iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack
      } else{
        float preoneoverc = 65536.0f/c;
        fu = (a*preoneoverc);
        fv = (b*preoneoverc);
      }


      for ( ; xstart < xend; xstart++ ) {
        if(accurateMode){
          if (interpCounter == linearInterpLength) interpCounter = 0;
          if (interpCounter == 0){
            a += newax;
            b += newbx;
            c += newcx;
            float oneoverc = 65536.0f/c;
            oldfu = fu; oldfv = fv;
            fu = (a*oneoverc); fv = (b*oneoverc);
            iu = (int)oldfu; iv = (int)oldfv;
            deltaU = ((int)(fu - oldfu)) >> linearInterpPower;
            deltaV = ((int)(fv - oldfv)) >> linearInterpPower;
          } else{
            iu += deltaU;
            iv += deltaV;
          }
          interpCounter++;
        }

        // try-catch just in case pixel offset it out of range
        try {
          if (noDepthTest || (iz <= m_zbuffer[xstart])) {
            //m_zbuffer[xstart] = iz;

            if (m_bilinear) {
              int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16);
              int iui = (iu & 0xFFFF) >> 9;
              int ivi = (iv & 0xFFFF) >> 9;

              // get texture pixels
              int pix0 = m_texture[ofs];
              int pix1 = m_texture[ofs + 1];
              if (ofs < lastRowStart) ofs+=TEX_WIDTH;
              int pix2 = m_texture[ofs];
              int pix3 = m_texture[ofs + 1];

              // red
              int red0 = (pix0 & 0xFF0000);
              int red2 = (pix2 & 0xFF0000);
              int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7);
              int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7);
              int red = up + (((dn-up) * ivi) >> 7);
              if (tint) red = ((red * rtint) >> 8) & 0xFF0000;

              // grn
              red0 = (pix0 & 0xFF00);
              red2 = (pix2 & 0xFF00);
              up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7);
              dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7);
              int grn = up + (((dn-up) * ivi) >> 7);
              if (tint) grn = ((grn * gtint) >> 8) & 0xFF00;

              // blu
              red0 = (pix0 & 0xFF);
              red2 = (pix2 & 0xFF);
              up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7);
              dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7);
              int blu = up + (((dn-up) * ivi) >> 7);
              if (tint) blu = ((blu * btint) >> 8) & 0xFF;

              // alpha
              pix0>>>=24;
              pix2>>>=24;
              up = pix0 + ((((pix1 >>> 24) - pix0) * iui) >> 7);
              dn = pix2 + ((((pix3 >>> 24) - pix2) * iui) >> 7);
              int al = up + (((dn-up) * ivi) >> 7);

              // get buffer pixels
              int bb = m_pixels[xstart];
              int br = (bb & 0xFF0000);  // 0x00FF0000
              int bg = (bb & 0xFF00);    // 0x0000FF00
              bb = (bb & 0xFF);          // 0x000000FF
              m_pixels[xstart] = 0xFF000000 | 
                ((br + (((red - br) * al) >> 8)) & 0xFF0000) |
                ((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | 
                ((bb + (((blu - bb) * al) >> 8)) & 0xFF);
            } else {
              int red = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)];
              int al = red >>> 24;
              int grn = red & 0xFF00;
              int blu = red & 0xFF;
              red&=0xFF0000;

              // get buffer pixels
              int bb = m_pixels[xstart];
              int br = (bb & 0xFF0000);  // 0x00FF0000
              int bg = (bb & 0xFF00);    // 0x0000FF00
              bb = (bb & 0xFF);          // 0x000000FF
              m_pixels[xstart] = 0xFF000000 | 
              ((br + (((red - br) * al) >> 8)) & 0xFF0000) |
              ((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | 
              ((bb + (((blu - bb) * al) >> 8)) & 0xFF);
            }
//            m_stencil[xstart] = p;
          }
        } catch (Exception e) { }
        xpixel++;//accurate mode
        if (!accurateMode){
          iu+=iuadd;
          iv+=ivadd;
        }
        iz+=izadd;
      }
      ypixel++;//accurate mode

      ytop+=SCREEN_WIDTH;

      xleft+=leftadd;
      xrght+=rghtadd;
      uleft+=uleftadd;
      vleft+=vleftadd;
      zleft+=zleftadd;
      aleft+=aleftadd;
    }


  }