private void drawsegment_texture8_alpha(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) {
      // see if the precomputation goes well, if so finish the setup
      if (precomputeAccurateTexturing()) { 
        newax *= linearInterpLength;
        newbx *= linearInterpLength;
        newcx *= linearInterpLength;
        screenz = nearPlaneDepth;
        firstSegment = false;
      } else {
        // if the matrix inversion screwed up, 
        // revert to normal rendering (something is degenerate)
        accurateMode = false; 
      }
    }
    ytop*=SCREEN_WIDTH;
    ybottom*=SCREEN_WIDTH;
//    int p = m_index;

    float iuf = iuadd;
    float ivf = ivadd;
    float iaf = iaadd;

    int red = m_fill & 0xFF0000;
    int grn = m_fill & 0xFF00;
    int blu = m_fill & 0xFF;

    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);
      int ia = (int) (iaf * xdiff + aleft);
      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;

              int al0;
              if (m_bilinear) {
                int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16);
                int iui = iu & 0xFFFF;
                al0 = m_texture[ofs] & 0xFF;
                int al1 = m_texture[ofs + 1] & 0xFF;
                if (ofs < lastRowStart) ofs+=TEX_WIDTH;
                int al2 = m_texture[ofs] & 0xFF;
                int al3 = m_texture[ofs + 1] & 0xFF;
                al0 = al0 + (((al1-al0) * iui) >> 16);
                al2 = al2 + (((al3-al2) * iui) >> 16);
                al0 = al0 + (((al2-al0) * (iv & 0xFFFF)) >> 16);
              } else {
                al0 = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)] & 0xFF;
              }
              al0 = (al0 * (ia >> 16)) >> 8;

              int br = m_pixels[xstart];
              int bg = (br & 0xFF00);
              int bb = (br & 0xFF);
              br = (br & 0xFF0000);
              m_pixels[xstart] = 0xFF000000 | 
                ((br + (((red - br) * al0) >> 8)) & 0xFF0000) | 
                ((bg + (((grn - bg) * al0) >> 8)) & 0xFF00) | 
                ((bb + (((blu - bb) * al0) >> 8)) & 0xFF);
//              m_stencil[xstart] = p;
            }
          }
        catch (Exception e) {
        }
        xpixel++;//accurate mode
        if (!accurateMode){
          iu+=iuadd;
          iv+=ivadd;
        }
        iz+=izadd;
        ia+=iaadd;
      }
      ypixel++;//accurate mode
      ytop+=SCREEN_WIDTH;
      xleft+=leftadd;
      xrght+=rghtadd;
      uleft+=uleftadd;
      vleft+=vleftadd;
      zleft+=zleftadd;
      aleft+=aleftadd;
    }
  }