Previous 199869 Revisions Next

r40094 Friday 31st July, 2015 at 21:44:38 UTC by Ryan Holtz
nw, initial merge of angrylion's RDP changes.
[/branches/n64-angrylion/src/mame/video]n64.c n64.h n64types.h rdptpipe.c rdptpipe.h

branches/n64-angrylion/src/mame/video/n64.c
r248605r248606
361361
362362void n64_rdp::set_suba_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata)
363363{
364   userdata->m_noise_used = false;
364365   switch (code & 0xf)
365366   {
366367      case 0:     *input = &userdata->m_combined_color; break;
r248605r248606
370371      case 4:     *input = &userdata->m_shade_color; break;
371372      case 5:     *input = &userdata->m_env_color; break;
372373      case 6:     *input = &m_one; break;
373      case 7:     *input = &userdata->m_noise_color; break;
374      case 7:     *input = &userdata->m_noise_color; userdata->m_noise_used = true; break;
374375      case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
375376      {
376377               *input = &m_zero; break;
r248605r248606
706707   const UINT8 yarray[16] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0};
707708   const UINT8 xarray[16] = {0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
708709
709   for (INT32 i = 0; i < 0x10000; i++)
710   {
711      m_compressed_cvmasks[i] = (i & 1) | ((i & 4) >> 1) | ((i & 0x20) >> 3) | ((i & 0x80) >> 4) |
712      ((i & 0x100) >> 4) | ((i & 0x400) >> 5) | ((i & 0x2000) >> 7) | ((i & 0x8000) >> 8);
713   }
714
715710   for (INT32 i = 0; i < 0x100; i++)
716711   {
717712      UINT16 mask = decompress_cvmask_frombyte(i);
r248605r248606
739734
740735UINT16 n64_rdp::decompress_cvmask_frombyte(UINT8 x)
741736{
742   UINT16 y = (x & 1) | ((x & 2) << 1) | ((x & 4) << 3) | ((x & 8) << 4) |
743      ((x & 0x10) << 4) | ((x & 0x20) << 5) | ((x & 0x40) << 7) | ((x & 0x80) << 8);
744   return y;
737   return (x & 1) | ((x & 2) << 4) | (x & 4) | ((x & 8) << 4) | ((x & 0x10) << 4) | ((x & 0x20) << 8) | ((x & 0x40) << 4) | ((x & 0x80) << 8);
745738}
746739
747740void n64_rdp::lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy, rdp_span_aux* userdata)
748741{
749   const UINT32 index = m_compressed_cvmasks[mask];
750   userdata->m_current_pix_cvg = cvarray[index].cvg;
751   userdata->m_current_cvg_bit = cvarray[index].cvbit;
752   *offx = cvarray[index].xoff;
753   *offy = cvarray[index].yoff;
742   userdata->m_current_pix_cvg = cvarray[mask].cvg;
743   userdata->m_current_cvg_bit = cvarray[mask].cvbit;
744   *offx = cvarray[mask].xoff;
745   *offy = cvarray[mask].yoff;
754746}
755747
756void n64_rdp::z_store(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc)
748void n64_rdp::z_store(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 dzpix_enc)
757749{
758   UINT16 zval = m_z_com_table[z & 0x3ffff]|(enc >> 2);
759   if(zcurpixel <= MEM16_LIMIT)
760   {
761      ((UINT16*)rdram)[zcurpixel ^ WORD_ADDR_XOR] = zval;
762   }
763   if(dzcurpixel <= MEM8_LIMIT)
764   {
765      m_hidden_bits[dzcurpixel ^ BYTE_ADDR_XOR] = enc & 3;
766   }
750   RWRITEIDX16(zcurpixel, m_z_com_table[z & 0x3ffff] | (dzpix_enc >> 2));
751   HWRITEADDR8(dzcurpixel, dzpix_enc & 3);
767752}
768753
769754INT32 n64_rdp::normalize_dzpix(INT32 sum)
r248605r248606
776761   {
777762      return 1;
778763   }
764   if (sum == 1)
765   {
766      return 3;
767   }
779768   for(INT32 count = 0x2000; count > 0; count >>= 1)
780769   {
781770      if (sum & count)
r248605r248606
791780   return m_z_complete_dec_table[(RREADIDX16(zcurpixel) >> 2) & 0x3fff];
792781}
793782
794UINT32 n64_rdp::dz_decompress(UINT32 zcurpixel, UINT32 dzcurpixel)
795{
796   const UINT16 zval = RREADIDX16(zcurpixel);
797   const UINT8 dzval = (((dzcurpixel) <= 0x7fffff) ? (m_hidden_bits[(dzcurpixel) ^ BYTE_ADDR_XOR]) : 0);
798   const UINT32 dz_compressed = ((zval & 3) << 2) | (dzval & 3);
799   return (1 << dz_compressed);
800}
801
802783UINT32 n64_rdp::dz_compress(UINT32 value)
803784{
804785   INT32 j = 0;
805   for (; value > 1; j++, value >>= 1);
786   if (value & 0xff00)
787   {
788      j |= 8;
789   }
790   if (value & 0xf0f0)
791   {
792      j |= 4;
793   }
794   if (value & 0xcccc)
795   {
796      j |= 2;
797   }
798   if (value & 0xaaaa)
799   {
800      j |= 1;
801   }
806802   return j;
807803}
808804
r248605r248606
895891   if (object.m_other_modes.z_compare_en)
896892   {
897893      oz = z_decompress(zcurpixel);
898      dzmem = dz_decompress(zcurpixel, dzcurpixel);
899894      zval = RREADIDX16(zcurpixel);
900      rawdzmem = ((zval & 3) << 2) | ((((dzcurpixel) <= 0x3fffff) ? (m_hidden_bits[(dzcurpixel) ^ BYTE_ADDR_XOR]) : 0) & 3);
901   }
902   else
903   {
904      oz = 0;
905      dzmem = 1 << 0xf;
906      zval = 0x3;
907      rawdzmem = 0xf;
908   }
895      UINT32 hval = HREADADDR8(dzcurpixel);
896      rawdzmem = ((zval & 3) << 2) | hval;
897      dzmem = 1 << rawdzmem;
909898
910   userdata->m_dzpix_enc = dz_compress(dzpix & 0xffff);
911   userdata->m_shift_a = CLAMP(userdata->m_dzpix_enc - rawdzmem, 0, 4);
912   userdata->m_shift_b = CLAMP(rawdzmem - userdata->m_dzpix_enc, 0, 4);
899      userdata->m_shift_a = CLAMP(userdata->m_dzpix_enc - rawdzmem, 0, 4);
900      userdata->m_shift_b = CLAMP(rawdzmem - userdata->m_dzpix_enc, 0, 4);
913901
914   INT32 precision_factor = (zval >> 13) & 0xf;
915   if (precision_factor < 3)
916   {
917      INT32 dzmemmodifier = 16 >> precision_factor;
918      if (dzmem == 0x8000)
902      if(object.m_other_modes.cycle_type == CYCLE_TYPE_2)
919903      {
920         force_coplanar = true;
904         userdata->m_prev_shift_a = CLAMP(userdata->m_dzpix_enc - userdata->m_prev_raw_dzmem, 0, 4);
905         userdata->m_prev_shift_b = CLAMP(userdata->m_prev_raw_dzmem - userdata->m_dzpix_enc, 0, 4);
921906      }
922      dzmem <<= 1;
923      if (dzmem <= dzmemmodifier)
907      userdata->m_prev_raw_dzmem = rawdzmem;
908
909      INT32 precision_factor = (zval >> 13) & 0xf;
910      if (precision_factor < 3)
924911      {
925         dzmem = dzmemmodifier;
912         if (dzmem != 0x8000)
913         {
914            UINT32 dzmemmodifier = 16 >> precision_factor;
915            dzmem <<= 1;
916            if (dzmem < dzmemmodifier)
917            {
918               dzmem = dzmemmodifier;
919            }
920         }
921         else
922         {
923            force_coplanar = true;
924            dzmem = 0xffff;
925         }
926926      }
927      if (!dzmem)
928      {
929         dzmem = 0xffff;
930      }
931   }
932   if (dzmem > 0x8000)
933   {
934      dzmem = 0xffff;
935   }
936927
937   UINT32 dznew = (dzmem > dzpix) ? dzmem : (UINT32)dzpix;
938   UINT32 dznotshift = dznew;
939   dznew <<= 3;
928      UINT32 dznew = m_dz_compare_lut[dzpix | dzmem];
929      UINT32 dznotshift = dznew;
930      dznew <<= 3;
940931
941   bool farther = (sz + dznew) >= oz;
942   bool infront = sz < oz;
932      bool farther = force_coplanar || (sz + dznew) >= oz;
943933
944   if (force_coplanar)
945   {
946      farther = true;
947   }
934      bool overflow = ((userdata->m_current_mem_cvg + userdata->m_current_pix_cvg) & 8) > 0;
935      userdata->m_blend_enable = (object.m_other_modes.force_blend || (!overflow && object.m_other_modes.antialias_en && farther)) ? 1 : 0;
936      userdata->m_pre_wrap = overflow;
948937
949   bool overflow = ((userdata->m_current_mem_cvg + userdata->m_current_pix_cvg) & 8) > 0;
950   userdata->m_blend_enable = (object.m_other_modes.force_blend || (!overflow && object.m_other_modes.antialias_en && farther)) ? 1 : 0;
951   userdata->m_pre_wrap = overflow;
952
953   INT32 cvgcoeff = 0;
954   UINT32 dzenc = 0;
955
956   if (object.m_other_modes.z_mode == 1 && infront && farther && overflow)
957   {
958      dzenc = dz_compress(dznotshift & 0xffff);
959      cvgcoeff = ((oz >> dzenc) - (sz >> dzenc)) & 0xf;
960      userdata->m_current_pix_cvg = ((cvgcoeff * userdata->m_current_pix_cvg) >> 3) & 0xf;
938      switch(object.m_other_modes.z_mode)
939      {
940         case ZMODE_OPAQUE:
941         {
942            bool infront = sz < oz;
943            INT32 diff = (INT32)sz - (INT32)dznew;
944            bool nearer = force_coplanar || (diff <= (INT32)oz);
945            bool max = oz == 0x3ffff;
946            return (max || (overflow ? infront : nearer));
947         }
948         case ZMODE_INTERPENETRATING:
949         {
950            bool infront = sz < oz;
951            if (!infront || !farther || !overflow)
952            {
953               INT32 diff = (INT32)sz - (INT32)dznew;
954               bool nearer = force_coplanar || (diff <= (INT32)oz);
955               bool max = oz == 0x3ffff;
956               return (max || (overflow ? infront : nearer));
957            }
958            else
959            {
960               UINT32 dzenc = dz_compress(dznotshift & 0xffff);
961               INT32 cvgcoeff = ((oz >> dzenc) - (sz >> dzenc)) & 0xf;
962               userdata->m_current_pix_cvg = ((cvgcoeff * userdata->m_current_pix_cvg) >> 3) & 0xf;
963               return true;
964            }
965            break;
966         }
967         case ZMODE_TRANSLUCENT:
968         {
969            return (sz < oz || oz == 0x3ffff);
970         }
971         case ZMODE_DECAL:
972         {
973            INT32 diff = (INT32)sz - (INT32)dznew;
974            bool nearer = force_coplanar || (diff <= (INT32)oz);
975            bool max = oz == 0x3ffff;
976            return farther && nearer && !max;
977         }
978      }
961979   }
962
963   if (!object.m_other_modes.z_compare_en)
980   else
964981   {
965      return true;
966   }
982      userdata->m_shift_a = 0;
983      userdata->m_shift_b = (userdata->m_dzpix_enc < 0xb) ? 4 : (0xf - userdata->m_dzpix_enc);
967984
968   INT32 diff = (INT32)sz - (INT32)dznew;
969   bool nearer = diff <= (INT32)oz;
970   bool max = (oz == 0x3ffff);
971   if (force_coplanar)
972   {
973      nearer = true;
974   }
985      if(object.m_other_modes.cycle_type == CYCLE_TYPE_2)
986      {
987         userdata->m_prev_shift_a = 0;
988         userdata->m_prev_shift_b = userdata->m_shift_b;
989      }
990      userdata->m_prev_raw_dzmem = 0xf;
975991
976   switch(object.m_other_modes.z_mode)
977   {
978   case 0:
979      return (max || (overflow ? infront : nearer));
980   case 1:
981      return (max || (overflow ? infront : nearer));
982   case 2:
983      return (infront || max);
984   case 3:
985      return (farther && nearer && !max);
992      bool overflow = ((userdata->m_current_mem_cvg + userdata->m_current_pix_cvg) & 8) > 0;
993      userdata->m_blend_enable = (object.m_other_modes.force_blend || (!overflow && object.m_other_modes.antialias_en)) ? 1 : 0;
994      userdata->m_pre_wrap = overflow;
986995   }
987996
988   return false;
997   return true;
989998}
990999
9911000UINT32 n64_rdp::get_log2(UINT32 lod_clamp)
r248605r248606
16031612
16041613static UINT32 rightcvghex(UINT32 x, UINT32 fmask)
16051614{
1606   UINT32 stickybit = ((x >> 1) & 0x1fff) > 0;
1607   UINT32 covered = ((x >> 14) & 3) + stickybit;
1608   covered = (0xf0 >> covered) & 0xf;
1609   return (covered & fmask);
1615   return (0xf0 >> (((x & 7) + 1) >> 1)) & fmask;
16101616}
16111617
16121618static UINT32 leftcvghex(UINT32 x, UINT32 fmask)
16131619{
1614   UINT32 stickybit = ((x >> 1) & 0x1fff) > 0;
1615   UINT32 covered = ((x >> 14) & 3) + stickybit;
1616   covered = 0xf >> covered;
1617   return (covered & fmask);
1620   return (0xf >> (((x & 7) + 1) >> 1)) & fmask;
16181621}
16191622
1620static INT32 CLIP(INT32 value,INT32 min,INT32 max)
1623void n64_rdp::compute_cvg_noflip(rdp_span_aux* data, UINT32 lx, UINT32 rx)
16211624{
1622   if (value < min)
1623   {
1624      return min;
1625   }
1626   else if (value > max)
1627   {
1628      return max;
1629   }
1630   else
1631   {
1632      return value;
1633   }
1634}
1625   UINT8* cvgbuf = data->m_cvg;
1626   INT32 purgestart = lx;
1627   INT32 purgeend = rx;
1628   INT32 length = purgeend - purgestart;
16351629
1636void n64_rdp::compute_cvg_noflip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base)
1637{
1638   INT32 purgestart = 0xfff;
1639   INT32 purgeend = 0;
1640   const bool writablescanline = !(scanline & ~0x3ff);
1641   const INT32 scanlinespx = scanline << 2;
1642
1643   if (!writablescanline) return;
1644
1645   for(INT32 i = 0; i < 4; i++)
1630   if (length < 0)
16461631   {
1647      if (minorxint[i] < purgestart)
1648      {
1649         purgestart = minorxint[i];
1650      }
1651      if (majorxint[i] > purgeend)
1652      {
1653         purgeend = majorxint[i];
1654      }
1632      return;
16551633   }
16561634
1657   purgestart = CLIP(purgestart, 0, 1023);
1658   purgeend = CLIP(purgeend, 0, 1023);
1659   INT32 length = purgeend - purgestart;
1635   memset(&cvgbuf[purgestart], 0xff, length + 1);
16601636
1661   if (length < 0) return;
1662
1663   rdp_span_aux* userdata = (rdp_span_aux*)spans[scanline - base].userdata;
1664   memset(&userdata->m_cvg[purgestart], 0, (length + 1) << 1);
1665
16661637   for(INT32 i = 0; i < 4; i++)
16671638   {
1668      INT32 minorcur = minorx[i];
1669      INT32 majorcur = majorx[i];
1670      INT32 minorcurint = minorxint[i];
1671      INT32 majorcurint = majorxint[i];
1672      length = majorcurint - minorcurint;
1639      const INT32 fmask = 0xa >> (i & 1);
1640      const INT32 maskshift = (i - 2) & 4;
1641      const INT32 fmaskshifted = fmask << maskshift;
16731642
1674      INT32 fmask = (i & 1) ? 5 : 0xa;
1675      INT32 maskshift = (i ^ 3) << 2;
1676      INT32 fmaskshifted = fmask << maskshift;
1677      INT32 fleft = CLIP(minorcurint + 1, 0, 647);
1678      INT32 fright = CLIP(majorcurint - 1, 0, 647);
1679      bool valid_y = ((scanlinespx + i) >= yh && (scanlinespx + i) < yl);
1680      if (valid_y && length >= 0)
1643      if (!data->m_invalid_y[i])
16811644      {
1682         if (minorcurint != majorcurint)
1645         INT32 minorcur = data->m_minorx[i];
1646         INT32 majorcur = data->m_majorx[i];
1647         INT32 minorcurint = minorcur >> 3;
1648         INT32 majorcurint = majorcur >> 3;
1649
1650         for (INT32 k = purgestart; k <= minorcurint; k++)
16831651         {
1684            if (!(minorcurint & ~0x3ff))
1685            {
1686               userdata->m_cvg[minorcurint] |= (leftcvghex(minorcur, fmask) << maskshift);
1687            }
1688            if (!(majorcurint & ~0x3ff))
1689            {
1690               userdata->m_cvg[majorcurint] |= (rightcvghex(majorcur, fmask) << maskshift);
1691            }
1652            cvgbuf[k] &= ~fmaskshifted;
16921653         }
1693         else
1654         for (INT32 k = majorcurint; k <= purgeend; k++)
16941655         {
1695            if (!(majorcurint & ~0x3ff))
1696            {
1697               INT32 samecvg = leftcvghex(minorcur, fmask) & rightcvghex(majorcur, fmask);
1698               userdata->m_cvg[majorcurint] |= (samecvg << maskshift);
1699            }
1656            cvgbuf[k] &= ~fmaskshifted;
17001657         }
1701         for (; fleft <= fright; fleft++)
1658
1659         if (majorcurint > minorcurint)
17021660         {
1703            userdata->m_cvg[fleft] |= fmaskshifted;
1661            cvgbuf[minorcurint] |= leftcvghex(minorcur, fmask) << maskshift;
1662            cvgbuf[majorcurint] |= rightcvghex(majorcur, fmask) << maskshift;
17041663         }
1664         else if (majorcurint == minorcurint)
1665         {
1666            INT32 samecvg = leftcvghex(minorcur, fmask) & rightcvghex(majorcur, fmask);
1667            cvgbuf[majorcurint] |= samecvg << maskshift;
1668         }
17051669      }
1670      else
1671      {
1672         for (INT32 k = purgestart; k <= purgeend; k++)
1673         {
1674            cvgbuf[k] &= ~fmaskshifted;
1675         }
1676      }
17061677   }
17071678}
17081679
1709void n64_rdp::compute_cvg_flip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base)
1680void n64_rdp::compute_cvg_flip(rdp_span_aux* data, UINT32 lx, UINT32 rx)
17101681{
1711   INT32 purgestart = 0xfff;
1712   INT32 purgeend = 0;
1713   const bool writablescanline = !(scanline & ~0x3ff);
1714   const INT32 scanlinespx = scanline << 2;
1682   UINT8* cvgbuf = data->m_cvg;
1683   INT32 purgestart = rx;
1684   INT32 purgeend = lx;
1685   INT32 length = purgeend - purgestart;
17151686
1716   if(!writablescanline) return;
1717
1718   for(INT32 i = 0; i < 4; i++)
1687   if (length < 0)
17191688   {
1720      if (majorxint[i] < purgestart)
1721      {
1722         purgestart = majorxint[i];
1723      }
1724      if (minorxint[i] > purgeend)
1725      {
1726         purgeend = minorxint[i];
1727      }
1689      return;
17281690   }
17291691
1730   purgestart = CLIP(purgestart, 0, 1023);
1731   purgeend = CLIP(purgeend, 0, 1023);
1692   memset(&cvgbuf[purgestart], 0xff, length + 1);
17321693
1733   INT32 length = purgeend - purgestart;
1734
1735   if (length < 0) return;
1736
1737   rdp_span_aux* userdata = (rdp_span_aux*)spans[scanline - base].userdata;
1738   memset(&userdata->m_cvg[purgestart], 0, (length + 1) << 1);
1739
17401694   for(INT32 i = 0; i < 4; i++)
17411695   {
1742      INT32 minorcur = minorx[i];
1743      INT32 majorcur = majorx[i];
1744      INT32 minorcurint = minorxint[i];
1745      INT32 majorcurint = majorxint[i];
1746      length = minorcurint - majorcurint;
1696      const INT32 fmask = 0xa >> (i & 1);
1697      const INT32 maskshift = (i - 2) & 4;
1698      const INT32 fmaskshifted = fmask << maskshift;
17471699
1748      INT32 fmask = (i & 1) ? 5 : 0xa;
1749      INT32 maskshift = (i ^ 3) << 2;
1750      INT32 fmaskshifted = fmask << maskshift;
1751      INT32 fleft = CLIP(majorcurint + 1, 0, 647);
1752      INT32 fright = CLIP(minorcurint - 1, 0, 647);
1753      bool valid_y = ((scanlinespx + i) >= yh && (scanlinespx + i) < yl);
1754      if (valid_y && length >= 0)
1700      if (!data->m_invalid_y[i])
17551701      {
1756         if (minorcurint != majorcurint)
1702         INT32 minorcur = data->m_minorx[i];
1703         INT32 majorcur = data->m_majorx[i];
1704         INT32 minorcurint = minorcur >> 3;
1705         INT32 majorcurint = majorcur >> 3;
1706
1707         for (INT32 k = purgestart; k <= majorcurint; k++)
17571708         {
1758            if (!(minorcurint & ~0x3ff))
1759            {
1760               userdata->m_cvg[minorcurint] |= (rightcvghex(minorcur, fmask) << maskshift);
1761            }
1762            if (!(majorcurint & ~0x3ff))
1763            {
1764               userdata->m_cvg[majorcurint] |= (leftcvghex(majorcur, fmask) << maskshift);
1765            }
1709            cvgbuf[k] &= ~fmaskshifted;
17661710         }
1767         else
1711         for (INT32 k = minorcurint; k <= purgeend; k++)
17681712         {
1769            if (!(majorcurint & ~0x3ff))
1770            {
1771               INT32 samecvg = rightcvghex(minorcur, fmask) & leftcvghex(majorcur, fmask);
1772               userdata->m_cvg[majorcurint] |= (samecvg << maskshift);
1773            }
1713            cvgbuf[k] &= ~fmaskshifted;
17741714         }
1775         for (; fleft <= fright; fleft++)
1715
1716         if (minorcurint > majorcurint)
17761717         {
1777            userdata->m_cvg[fleft] |= fmaskshifted;
1718            cvgbuf[minorcurint] |= rightcvghex(minorcur, fmask) << maskshift;
1719            cvgbuf[majorcurint] |= leftcvghex(majorcur, fmask) << maskshift;
17781720         }
1721         else if (minorcurint == majorcurint)
1722         {
1723            INT32 samecvg = rightcvghex(minorcur, fmask) & leftcvghex(majorcur, fmask);
1724            cvgbuf[majorcurint] |= samecvg << maskshift;
1725         }
17791726      }
1727      else
1728      {
1729         for (INT32 k = purgestart; k <= purgeend; k++)
1730         {
1731            cvgbuf[k] &= ~fmaskshifted;
1732         }
1733      }
17801734   }
17811735}
17821736
1737void n64_rdp::get_span_userdata(void** userdata)
1738{
1739   *userdata = (void*)((UINT8*)m_aux_buf + m_aux_buf_ptr);
1740   m_aux_buf_ptr += sizeof(rdp_span_aux);
1741   rdp_span_aux* data = (rdp_span_aux*)*userdata;
1742   data->m_valid_line = true;
1743}
1744
1745void n64_rdp::deduce_derivatives(rdp_span_aux *userdata)
1746{
1747   m_mode_derivs.m_partial_reject_1cycle = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color);
1748   m_mode_derivs.m_partial_reject_2cycle = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[1] == &userdata->m_pixel_color);
1749
1750   m_mode_derivs.m_special_bsel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color);
1751   m_mode_derivs.m_special_bsel1 = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_memory_color);
1752
1753   m_mode_derivs.m_rgb_alpha_dither = (m_other_modes.rgb_dither_sel << 2) | m_other_modes.alpha_dither_sel;
1754
1755   const bool lod_frac_used_in_cycle1 = (userdata->m_color_inputs.combiner_rgbmul[0] == &userdata->m_lod_fraction) || (userdata->m_color_inputs.combiner_alphamul[0] == &userdata->m_lod_fraction);
1756   const bool lod_frac_used_in_cycle2 = (userdata->m_color_inputs.combiner_rgbmul[1] == &userdata->m_lod_fraction) || (userdata->m_color_inputs.combiner_alphamul[1] == &userdata->m_lod_fraction);
1757   const bool lod_frac_used = (m_other_modes.cycle_type == CYCLE_TYPE_2 && (lod_frac_used_in_cycle1 || lod_frac_used_in_cycle2)) || (m_other_modes.cycle_type == CYCLE_TYPE_1 && lod_frac_used_in_cycle2);
1758   m_mode_derivs.m_do_lod = m_other_modes.tex_lod_en || lod_frac_used;
1759}
1760
17831761void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect)
17841762{
17851763   const UINT32* cmd_data = rect ? m_temp_rect_data : m_cmd_data;
r248605r248606
17961774   INT32 dsdxh = 0, dtdxh = 0, dwdxh = 0, drdxh = 0, dgdxh = 0, dbdxh = 0, dadxh = 0, dzdxh = 0;
17971775   INT32 dsdyh = 0, dtdyh = 0, dwdyh = 0, drdyh = 0, dgdyh = 0, dbdyh = 0, dadyh = 0, dzdyh = 0;
17981776
1799   INT32 maxxmx = 0; // maxxmx / minxhx very opaque names, consider re-naming
1800   INT32 minxmx = 0;
1801   INT32 maxxhx = 0;
1802   INT32 minxhx = 0;
1803
18041777   INT32 shade_base = fifo_index + 8;
18051778   INT32 texture_base = fifo_index + 8;
18061779   INT32 zbuffer_base = fifo_index + 8;
r248605r248606
18211794   UINT32 w7 = cmd_data[fifo_index + 6];
18221795   UINT32 w8 = cmd_data[fifo_index + 7];
18231796
1824   INT32 yl = (w1 & 0x3fff);
1797   INT32 yl = w1 & 0x3fff;
18251798   INT32 ym = ((w2 >> 16) & 0x3fff);
1826   INT32 yh = ((w2 >>  0) & 0x3fff);
1827   INT32 xl = (INT32)(w3 & 0x3fffffff);
1828   INT32 xh = (INT32)(w5 & 0x3fffffff);
1829   INT32 xm = (INT32)(w7 & 0x3fffffff);
1799   INT32 yh = w2 & 0x3fff;
1800   INT32 xl = w3 & 0x3fffffff;
1801   INT32 xh = w5 & 0x3fffffff;
1802   INT32 xm = w7 & 0x3fffffff;
18301803   // Inverse slopes in 16.16 format
18311804   INT32 dxldy = (INT32)(w4);
18321805   INT32 dxhdy = (INT32)(w6);
r248605r248606
18731846   const INT32 dzde = cmd_data[zbuffer_base+2];
18741847   const INT32 dzdy = cmd_data[zbuffer_base+3];
18751848
1876   const INT32 dzdy_dz = (dzdy >> 16) & 0xffff;
1877   const INT32 dzdx_dz = (dzdx >> 16) & 0xffff;
1878
18791849   extent_t spans[2048];
18801850#ifdef MAME_DEBUG
18811851   memset(spans, 0xcc, sizeof(spans));
18821852#endif
18831853
1884   m_span_base.m_span_drdy = drdy;
1885   m_span_base.m_span_dgdy = dgdy;
1886   m_span_base.m_span_dbdy = dbdy;
1887   m_span_base.m_span_dady = dady;
1888   m_span_base.m_span_dzdy = m_other_modes.z_source_sel ? 0 : dzdy;
1889
1890   UINT32 temp_dzpix = ((dzdy_dz & 0x8000) ? ((~dzdy_dz) & 0x7fff) : dzdy_dz) + ((dzdx_dz & 0x8000) ? ((~dzdx_dz) & 0x7fff) : dzdx_dz);
1854   m_span_base.m_span_ds = dsdx & ~0x1f;
1855   m_span_base.m_span_dt = dtdx & ~0x1f;
1856   m_span_base.m_span_dw = dwdx & ~0x1f;
18911857   m_span_base.m_span_dr = drdx & ~0x1f;
18921858   m_span_base.m_span_dg = dgdx & ~0x1f;
18931859   m_span_base.m_span_db = dbdx & ~0x1f;
18941860   m_span_base.m_span_da = dadx & ~0x1f;
1895   m_span_base.m_span_ds = dsdx;
1896   m_span_base.m_span_dt = dtdx;
1897   m_span_base.m_span_dw = dwdx;
1898   m_span_base.m_span_dz = m_other_modes.z_source_sel ? 0 : dzdx;
1899   m_span_base.m_span_dymax = 0;
1861   m_span_base.m_span_dz = dzdx;
1862
1863   m_span_base.m_span_drdy = SIGN13(drdy >> 14);
1864   m_span_base.m_span_dgdy = SIGN13(dgdy >> 14);
1865   m_span_base.m_span_dbdy = SIGN13(dbdy >> 14);
1866   m_span_base.m_span_dady = SIGN13(dady >> 14);
1867   m_span_base.m_span_dzdy = dzdy >> 10;
1868   m_span_base.m_span_cdr = SIGN13(m_span_base.m_span_dr >> 14);
1869   m_span_base.m_span_cdg = SIGN13(m_span_base.m_span_dg >> 14);
1870   m_span_base.m_span_cdb = SIGN13(m_span_base.m_span_db >> 14);
1871   m_span_base.m_span_cda = SIGN13(m_span_base.m_span_da >> 14);
1872   m_span_base.m_span_cdz = SIGN22(m_span_base.m_span_dz >> 10);
1873
1874   m_span_base.m_span_dsdy = dsdy & ~0x7fff;
1875   m_span_base.m_span_dtdy = dtdy & ~0x7fff;
1876   m_span_base.m_span_dwdy = dwdy & ~0x7fff;
1877
1878   const INT32 dzdy_dz = (dzdy >> 16) & 0xffff;
1879   const INT32 dzdx_dz = (dzdx >> 16) & 0xffff;
1880
1881   const UINT32 temp_dzpix = ((dzdy_dz & 0x8000) ? ((~dzdy_dz) & 0x7fff) : dzdy_dz) + ((dzdx_dz & 0x8000) ? ((~dzdx_dz) & 0x7fff) : dzdx_dz);
19001882   m_span_base.m_span_dzpix = m_dzpix_normalize[temp_dzpix & 0xffff];
19011883
19021884   INT32 xleft_inc = (dxmdy >> 2) & ~1;
r248605r248606
19061888   INT32 xleft = xm & ~1;
19071889
19081890   const INT32 sign_dxhdy = (dxhdy & 0x80000000) ? 1 : 0;
1909   const INT32 do_offset = !(sign_dxhdy ^ (flip));
1891   const INT32 do_offset = !(sign_dxhdy ^ flip);
19101892
19111893   if (do_offset)
19121894   {
1913      dsdeh = dsde >> 9;  dsdyh = dsdy >> 9;
1914      dtdeh = dtde >> 9;  dtdyh = dtdy >> 9;
1915      dwdeh = dwde >> 9;  dwdyh = dwdy >> 9;
1916      drdeh = drde >> 9;  drdyh = drdy >> 9;
1917      dgdeh = dgde >> 9;  dgdyh = dgdy >> 9;
1918      dbdeh = dbde >> 9;  dbdyh = dbdy >> 9;
1919      dadeh = dade >> 9;  dadyh = dady >> 9;
1920      dzdeh = dzde >> 9;  dzdyh = dzdy >> 9;
1895      dsdeh = dsde & ~0x1ff;
1896      dtdeh = dtde & ~0x1ff;
1897      dwdeh = dwde & ~0x1ff;
1898      drdeh = drde & ~0x1ff;
1899      dgdeh = dgde & ~0x1ff;
1900      dbdeh = dbde & ~0x1ff;
1901      dadeh = dade & ~0x1ff;
1902      dzdeh = dzde & ~0x1ff;
19211903
1922      dsdiff = (dsdeh << 8) + (dsdeh << 7) - (dsdyh << 8) - (dsdyh << 7);
1923      dtdiff = (dtdeh << 8) + (dtdeh << 7) - (dtdyh << 8) - (dtdyh << 7);
1924      dwdiff = (dwdeh << 8) + (dwdeh << 7) - (dwdyh << 8) - (dwdyh << 7);
1925      drdiff = (drdeh << 8) + (drdeh << 7) - (drdyh << 8) - (drdyh << 7);
1926      dgdiff = (dgdeh << 8) + (dgdeh << 7) - (dgdyh << 8) - (dgdyh << 7);
1927      dbdiff = (dbdeh << 8) + (dbdeh << 7) - (dbdyh << 8) - (dbdyh << 7);
1928      dadiff = (dadeh << 8) + (dadeh << 7) - (dadyh << 8) - (dadyh << 7);
1929      dzdiff = (dzdeh << 8) + (dzdeh << 7) - (dzdyh << 8) - (dzdyh << 7);
1904      dsdyh = dsdy & ~0x1ff;
1905      dtdyh = dtdy & ~0x1ff;
1906      dwdyh = dwdy & ~0x1ff;
1907      drdyh = drdy & ~0x1ff;
1908      dgdyh = dgdy & ~0x1ff;
1909      dbdyh = dbdy & ~0x1ff;
1910      dadyh = dady & ~0x1ff;
1911      dzdyh = dzdy & ~0x1ff;
1912
1913      dsdiff = (dsdeh - dsdyh) - (dsdiff >> 2);
1914      dtdiff = (dtdeh - dtdyh) - (dtdiff >> 2);
1915      dwdiff = (dwdeh - dwdyh) - (dwdiff >> 2);
1916      drdiff = (drdeh - drdyh) - (drdiff >> 2);
1917      dgdiff = (dgdeh - dgdyh) - (dgdiff >> 2);
1918      dbdiff = (dbdeh - dbdyh) - (dbdiff >> 2);
1919      dadiff = (dadeh - dadyh) - (dadiff >> 2);
1920      dzdiff = (dzdeh - dzdyh) - (dzdiff >> 2);
19301921   }
19311922   else
19321923   {
19331924      dsdiff = dtdiff = dwdiff = drdiff = dgdiff = dbdiff = dadiff = dzdiff = 0;
19341925   }
19351926
1936   dsdxh = dsdx >> 8;
1937   dtdxh = dtdx >> 8;
1938   dwdxh = dwdx >> 8;
1939   drdxh = drdx >> 8;
1940   dgdxh = dgdx >> 8;
1941   dbdxh = dbdx >> 8;
1942   dadxh = dadx >> 8;
1943   dzdxh = dzdx >> 8;
1927   if (m_other_modes.cycle_type != CYCLE_TYPE_COPY)
1928   {
1929      dsdxh = (dsdx >> 8) & ~1;
1930      dtdxh = (dtdx >> 8) & ~1;
1931      dwdxh = (dwdx >> 8) & ~1;
1932      drdxh = (drdx >> 8) & ~1;
1933      dgdxh = (dgdx >> 8) & ~1;
1934      dbdxh = (dbdx >> 8) & ~1;
1935      dadxh = (dadx >> 8) & ~1;
1936      dzdxh = (dzdx >> 8) & ~1;
1937   }
1938   else
1939   {
1940      dsdxh = dtdxh = dwdxh = drdxh = dgdxh = dbdxh = dadxh = dzdxh = 0;
1941   }
19441942
1943   INT32 maxxmx = 0;
1944   INT32 minxmx = 0;
1945   INT32 maxxhx = 0;
1946   INT32 minxhx = 0;
1947
1948   rdp_poly_state* object = &object_data_alloc();
1949   memcpy(object->m_tmem, m_tmem, 0x1000);
1950
19451951   const INT32 ycur = yh & ~3;
1946   const INT32 ylfar = yl | 3;
19471952   const INT32 ldflag = (sign_dxhdy ^ flip) ? 0 : 3;
1948   INT32 majorx[4];
1949   INT32 minorx[4];
1950   INT32 majorxint[4];
1951   INT32 minorxint[4];
19521953
1953   INT32 xfrac = ((xright >> 8) & 0xff);
1954   bool invalid_y = true;
1955   bool limited_yl = false;
1956   INT32 yllimit = 0;
1957   if (yl & 0x2000)
1958   {
1959      limited_yl = true;
1960   }
1961   else if (yl & 0x1000)
1962   {
1963      limited_yl = false;
1964   }
1965   else
1966   {
1967      limited_yl = (yl & 0xfff) < m_scissor.m_yl;
1968   }
1969   yllimit = limited_yl ? yl : m_scissor.m_yl;
19541970
1955   const INT32 clipy1 = m_scissor.m_yh;
1956   const INT32 clipy2 = m_scissor.m_yl;
1971   INT32 invalid_index = -1;
1972   INT32 ylfar = yllimit | 3;
1973   if ((yl >> 2) > (ylfar >> 2))
1974   {
1975      ylfar += 4;
1976   }
1977   else if((yllimit >> 2) >= 0 && (yllimit >> 2) < 0x3ff)
1978   {
1979      INT32 idx = (yllimit >> 2) + 1;
1980      get_span_userdata(&spans[idx].userdata);
1981      ((rdp_span_aux*)spans[idx].userdata)->m_valid_line = false;
1982      invalid_index = idx;
1983   }
19571984
1958   // Trivial reject
1959   if((ycur >> 2) >= clipy2 && (ylfar >> 2) >= clipy2)
1985   bool limited_yh = false;
1986   INT32 yhlimit = 0;
1987   if (yh & 0x2000)
19601988   {
1961      return;
1989      limited_yh = false;
19621990   }
1963   if((ycur >> 2) < clipy1 && (ylfar >> 2) < clipy1)
1991   else if (yh & 0x1000)
19641992   {
1965      return;
1993      limited_yh = true;
19661994   }
1995   else
1996   {
1997      limited_yh = (yh >= m_scissor.m_yh);
1998   }
1999   yhlimit = limited_yh ? yh : m_scissor.m_yh;
19672000
1968   bool new_object = true;
1969   rdp_poly_state* object = NULL;
1970   bool valid = false;
2001   INT32 yhclose = yhlimit & ~3;
19712002
1972   INT32* minx = flip ? &minxhx : &minxmx;
1973   INT32* maxx = flip ? &maxxmx : &maxxhx;
1974   INT32* startx = flip ? maxx : minx;
1975   INT32* endx = flip ? minx : maxx;
2003   INT32 clipxlshift = m_scissor.m_xl << 1;
2004   INT32 clipxhshift = m_scissor.m_xh << 1;
19762005
2006   bool allover = true;
2007   bool allunder = true;
2008   bool bothinvalid = true;
2009   bool anyvalid = false;
2010   bool first_line = true;
2011
2012   INT32 xfrac = ((xright >> 8) & 0xff);
2013
2014   if (flip)
2015   {
2016      for (INT32 k = ycur; k <= ylfar; k++)
2017      {
2018         if (k == ym)
2019         {
2020            xleft = xl & ~1;
2021            xleft_inc = (dxldy >> 2) & ~1;
2022         }
2023
2024         INT32 spix = k & 3;
2025
2026         if (k >= yhclose)
2027         {
2028            invalid_y = k < yhlimit || k >= yllimit;
2029
2030            INT32 j = k >> 2;
2031            const INT32 spanidx = j - (ycur >> 2);
2032
2033            if (spix == 0)
2034            {
2035               maxxmx = 0;
2036               minxhx = 0xfff;
2037               allover = allunder = bothinvalid = true;
2038            }
2039
2040            if (spix == 0 || k == ycur)
2041            {
2042               get_span_userdata(&spans[spanidx].userdata);
2043
2044               rdp_span_aux* userdata = (rdp_span_aux*)spans[spanidx].userdata;
2045               if (j == invalid_index)
2046               {
2047                  userdata->m_valid_line = false;
2048               }
2049               userdata->m_tmem = object->m_tmem;
2050
2051               userdata->m_blend_color = m_blend_color;
2052               userdata->m_prim_color = m_prim_color;
2053               userdata->m_env_color = m_env_color;
2054               userdata->m_fog_color = m_fog_color;
2055               userdata->m_prim_alpha = m_prim_alpha;
2056               userdata->m_env_alpha = m_env_alpha;
2057               userdata->m_key_scale = m_key_scale;
2058               userdata->m_lod_fraction = m_lod_fraction;
2059               userdata->m_prim_lod_fraction = m_prim_lod_fraction;
2060
2061               // Setup blender data for this scanline
2062               set_blender_input(0, 0, &userdata->m_color_inputs.blender1a_rgb[0], &userdata->m_color_inputs.blender1b_a[0], m_other_modes.blend_m1a_0, m_other_modes.blend_m1b_0, userdata);
2063               set_blender_input(0, 1, &userdata->m_color_inputs.blender2a_rgb[0], &userdata->m_color_inputs.blender2b_a[0], m_other_modes.blend_m2a_0, m_other_modes.blend_m2b_0, userdata);
2064               set_blender_input(1, 0, &userdata->m_color_inputs.blender1a_rgb[1], &userdata->m_color_inputs.blender1b_a[1], m_other_modes.blend_m1a_1, m_other_modes.blend_m1b_1, userdata);
2065               set_blender_input(1, 1, &userdata->m_color_inputs.blender2a_rgb[1], &userdata->m_color_inputs.blender2b_a[1], m_other_modes.blend_m2a_1, m_other_modes.blend_m2b_1, userdata);
2066
2067               // Setup color combiner data for this scanline
2068               set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[0], m_combine.sub_a_rgb0, userdata);
2069               set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[0], m_combine.sub_b_rgb0, userdata);
2070               set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[0], m_combine.mul_rgb0, userdata);
2071               set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[0], m_combine.add_rgb0, userdata);
2072               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[0], m_combine.sub_a_a0, userdata);
2073               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[0], m_combine.sub_b_a0, userdata);
2074               set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[0], m_combine.mul_a0, userdata);
2075               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphaadd[0], m_combine.add_a0, userdata);
2076
2077               set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[1], m_combine.sub_a_rgb1, userdata);
2078               set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[1], m_combine.sub_b_rgb1, userdata);
2079               set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[1], m_combine.mul_rgb1, userdata);
2080               set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[1], m_combine.add_rgb1, userdata);
2081               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[1], m_combine.sub_a_a1, userdata);
2082               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[1], m_combine.sub_b_a1, userdata);
2083               set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[1], m_combine.mul_a1, userdata);
2084               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphaadd[1], m_combine.add_a1, userdata);
2085
2086               deduce_derivatives(userdata);
2087            }
2088
2089            rdp_span_aux* userdata = (rdp_span_aux*)spans[spanidx].userdata;
2090            INT32 stickybit = ((xright >> 1) & 0x1fff) > 0 ? 1 : 0;
2091            UINT32 xsrc = ((xright >> 13) & 0x1ffe) | stickybit;
2092            bool curunder = (xright & 0x8000000) || xsrc < clipxhshift;
2093            xsrc = curunder ? clipxhshift : (((xright >> 13) & 0x3ffe) | stickybit);
2094            bool curover = (xsrc & 0x2000) != 0 || (xsrc & 0x1fff) > clipxlshift;
2095            xsrc = curover ? clipxlshift : xsrc;
2096            userdata->m_majorx[spix] = xsrc & 0x1fff;
2097            allover = allover && curover;
2098            allunder = allunder && curunder;
2099
2100            stickybit = ((xleft >> 1) & 0x1fff) > 0 ? 1 : 0;
2101            UINT32 xlsc = ((xleft >> 13) & 0x1ffe) | stickybit;
2102            curunder = (xleft & 0x8000000) || xlsc < clipxhshift;
2103            xlsc = curunder ? clipxhshift : (((xleft >> 13) & 0x3ffe) | stickybit);
2104            curover = (xlsc & 0x2000) != 0 || (xlsc & 0x1fff) > clipxlshift;
2105            xlsc = curover ? clipxlshift : xlsc;
2106            userdata->m_minorx[spix] = xlsc & 0x1fff;
2107            allover = allover && curover;
2108            allunder = allunder && curunder;
2109
2110            bool curcross = ((xleft ^ (1 << 27)) & (0x3fff << 14)) < ((xright ^ (1 << 27)) & (0x3fff << 14));
2111
2112            invalid_y = invalid_y || curcross;
2113            userdata->m_invalid_y[spix] = invalid_y;
2114            bothinvalid = bothinvalid && invalid_y;
2115
2116            if (!invalid_y)
2117            {
2118               maxxmx = (((xlsc >> 3) & 0xfff) > maxxmx) ? (xlsc >> 3) & 0xfff : maxxmx;
2119               minxhx = (((xsrc >> 3) & 0xfff) < minxhx) ? (xsrc >> 3) & 0xfff : minxhx;
2120            }
2121
2122            if (spix == ldflag)
2123            {
2124               userdata->m_unscissored_rx = xright >> 16;
2125               xfrac = (xright >> 8) & 0xff;
2126               spans[spanidx].param[SPAN_R].start = ((r & ~0x1ff) + drdiff - (xfrac * drdxh)) & ~0x3ff;
2127               spans[spanidx].param[SPAN_G].start = ((g & ~0x1ff) + dgdiff - (xfrac * dgdxh)) & ~0x3ff;
2128               spans[spanidx].param[SPAN_B].start = ((b & ~0x1ff) + dbdiff - (xfrac * dbdxh)) & ~0x3ff;
2129               spans[spanidx].param[SPAN_A].start = ((a & ~0x1ff) + dadiff - (xfrac * dadxh)) & ~0x3ff;
2130               spans[spanidx].param[SPAN_S].start = ((s & ~0x1ff) + dsdiff - (xfrac * dsdxh)) & ~0x3ff;
2131               spans[spanidx].param[SPAN_T].start = ((t & ~0x1ff) + dtdiff - (xfrac * dtdxh)) & ~0x3ff;
2132               spans[spanidx].param[SPAN_W].start = ((w & ~0x1ff) + dwdiff - (xfrac * dwdxh)) & ~0x3ff;
2133               spans[spanidx].param[SPAN_Z].start = ((z & ~0x1ff) + dzdiff - (xfrac * dzdxh)) & ~0x3ff;
2134            }
2135
2136            if (spix == 3)
2137            {
2138               spans[spanidx].startx = maxxmx;
2139               spans[spanidx].stopx = minxhx;
2140               bool even_line = j & 1;
2141               userdata->m_valid_line = !bothinvalid && !allover && !allunder && (!m_scissor.m_field || (m_scissor.m_field && !(m_scissor.m_keep_odd ^ even_line)));
2142               if (!first_line && spans[spanidx-1].userdata != NULL)
2143               {
2144                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_valid = true;
2145                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_s = spans[spanidx].param[SPAN_S].start;
2146                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_t = spans[spanidx].param[SPAN_T].start;
2147                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_w = spans[spanidx].param[SPAN_W].start;
2148               }
2149               else
2150               {
2151                  first_line = false;
2152               }
2153               anyvalid = anyvalid || !bothinvalid;
2154            }
2155         }
2156
2157         if (spix == 3)
2158         {
2159            r += drde;
2160            g += dgde;
2161            b += dbde;
2162            a += dade;
2163            s += dsde;
2164            t += dtde;
2165            w += dwde;
2166            z += dzde;
2167         }
2168
2169         xleft += xleft_inc;
2170         xright += xright_inc;
2171      }
2172   }
2173   else
2174   {
2175      for (INT32 k = ycur; k <= ylfar; k++)
2176      {
2177         if (k == ym)
2178         {
2179            xleft = xl & ~1;
2180            xleft_inc = (dxldy >> 2) & ~1;
2181         }
2182
2183         INT32 spix = k & 3;
2184
2185         if (k >= yhclose)
2186         {
2187            bool invalid_y = k < yhlimit || k >= yllimit;
2188
2189            INT32 j = k >> 2;
2190            const INT32 spanidx = j - (ycur >> 2);
2191
2192            if (spix == 0)
2193            {
2194               maxxhx = 0;
2195               minxmx = 0xfff;
2196               allover = allunder = bothinvalid = true;
2197            }
2198
2199            if (spix == 0 || k == ycur)
2200            {
2201               get_span_userdata(&spans[spanidx].userdata);
2202
2203               rdp_span_aux* userdata = (rdp_span_aux*)spans[spanidx].userdata;
2204               if (j == invalid_index)
2205               {
2206                  userdata->m_valid_line = false;
2207               }
2208               userdata->m_tmem = object->m_tmem;
2209
2210               userdata->m_blend_color = m_blend_color;
2211               userdata->m_prim_color = m_prim_color;
2212               userdata->m_env_color = m_env_color;
2213               userdata->m_fog_color = m_fog_color;
2214               userdata->m_prim_alpha = m_prim_alpha;
2215               userdata->m_env_alpha = m_env_alpha;
2216               userdata->m_key_scale = m_key_scale;
2217               userdata->m_lod_fraction = m_lod_fraction;
2218               userdata->m_prim_lod_fraction = m_prim_lod_fraction;
2219
2220               // Setup blender data for this scanline
2221               set_blender_input(0, 0, &userdata->m_color_inputs.blender1a_rgb[0], &userdata->m_color_inputs.blender1b_a[0], m_other_modes.blend_m1a_0, m_other_modes.blend_m1b_0, userdata);
2222               set_blender_input(0, 1, &userdata->m_color_inputs.blender2a_rgb[0], &userdata->m_color_inputs.blender2b_a[0], m_other_modes.blend_m2a_0, m_other_modes.blend_m2b_0, userdata);
2223               set_blender_input(1, 0, &userdata->m_color_inputs.blender1a_rgb[1], &userdata->m_color_inputs.blender1b_a[1], m_other_modes.blend_m1a_1, m_other_modes.blend_m1b_1, userdata);
2224               set_blender_input(1, 1, &userdata->m_color_inputs.blender2a_rgb[1], &userdata->m_color_inputs.blender2b_a[1], m_other_modes.blend_m2a_1, m_other_modes.blend_m2b_1, userdata);
2225
2226               // Setup color combiner data for this scanline
2227               set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[0], m_combine.sub_a_rgb0, userdata);
2228               set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[0], m_combine.sub_b_rgb0, userdata);
2229               set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[0], m_combine.mul_rgb0, userdata);
2230               set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[0], m_combine.add_rgb0, userdata);
2231               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[0], m_combine.sub_a_a0, userdata);
2232               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[0], m_combine.sub_b_a0, userdata);
2233               set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[0], m_combine.mul_a0, userdata);
2234               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphaadd[0], m_combine.add_a0, userdata);
2235
2236               set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[1], m_combine.sub_a_rgb1, userdata);
2237               set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[1], m_combine.sub_b_rgb1, userdata);
2238               set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[1], m_combine.mul_rgb1, userdata);
2239               set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[1], m_combine.add_rgb1, userdata);
2240               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[1], m_combine.sub_a_a1, userdata);
2241               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[1], m_combine.sub_b_a1, userdata);
2242               set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[1], m_combine.mul_a1, userdata);
2243               set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphaadd[1], m_combine.add_a1, userdata);
2244
2245               deduce_derivatives(userdata);
2246            }
2247
2248            rdp_span_aux* userdata = (rdp_span_aux*)spans[spanidx].userdata;
2249            INT32 stickybit = ((xright >> 1) & 0x1fff) > 0 ? 1 : 0;
2250            UINT32 xsrc = ((xright >> 13) & 0x1ffe) | stickybit;
2251            bool curunder = (xright & 0x8000000) || xsrc < clipxhshift;
2252            xsrc = curunder ? clipxhshift : (((xright >> 13) & 0x3ffe) | stickybit);
2253            bool curover = (xsrc & 0x2000) != 0 || (xsrc & 0x1fff) > clipxlshift;
2254            xsrc = curover ? clipxlshift : xsrc;
2255            userdata->m_majorx[spix] = xsrc & 0x1fff;
2256            allover = allover && curover;
2257            allunder = allunder && curunder;
2258
2259            stickybit = ((xleft >> 1) & 0x1fff) > 0 ? 1 : 0;
2260            UINT32 xlsc = ((xleft >> 13) & 0x1ffe) | stickybit;
2261            curunder = (xleft & 0x8000000) || xlsc < clipxhshift;
2262            xlsc = curunder ? clipxhshift : (((xleft >> 13) & 0x3ffe) | stickybit);
2263            curover = (xlsc & 0x2000) != 0 || (xlsc & 0x1fff) > clipxlshift;
2264            xlsc = curover ? clipxlshift : xlsc;
2265            userdata->m_minorx[spix] = xlsc & 0x1fff;
2266            allover = allover && curover;
2267            allunder = allunder && curunder;
2268
2269            bool curcross = ((xright ^ (1 << 27)) & (0x3fff << 14)) < ((xleft ^ (1 << 27)) & (0x3fff << 14));
2270
2271            invalid_y = invalid_y || curcross;
2272            userdata->m_invalid_y[spix] = invalid_y;
2273            bothinvalid = bothinvalid && invalid_y;
2274
2275            if (!invalid_y)
2276            {
2277               minxmx = (((xlsc >> 3) & 0xfff) > minxmx) ? (xlsc >> 3) & 0xfff : minxmx;
2278               maxxhx = (((xsrc >> 3) & 0xfff) < maxxhx) ? (xsrc >> 3) & 0xfff : maxxhx;
2279            }
2280
2281            if (spix == ldflag)
2282            {
2283               userdata->m_unscissored_rx = xright >> 16;
2284               xfrac = (xright >> 8) & 0xff;
2285               spans[spanidx].param[SPAN_R].start = ((r & ~0x1ff) + drdiff - (xfrac * drdxh)) & ~0x3ff;
2286               spans[spanidx].param[SPAN_G].start = ((g & ~0x1ff) + dgdiff - (xfrac * dgdxh)) & ~0x3ff;
2287               spans[spanidx].param[SPAN_B].start = ((b & ~0x1ff) + dbdiff - (xfrac * dbdxh)) & ~0x3ff;
2288               spans[spanidx].param[SPAN_A].start = ((a & ~0x1ff) + dadiff - (xfrac * dadxh)) & ~0x3ff;
2289               spans[spanidx].param[SPAN_S].start = ((s & ~0x1ff) + dsdiff - (xfrac * dsdxh)) & ~0x3ff;
2290               spans[spanidx].param[SPAN_T].start = ((t & ~0x1ff) + dtdiff - (xfrac * dtdxh)) & ~0x3ff;
2291               spans[spanidx].param[SPAN_W].start = ((w & ~0x1ff) + dwdiff - (xfrac * dwdxh)) & ~0x3ff;
2292               spans[spanidx].param[SPAN_Z].start = ((z & ~0x1ff) + dzdiff - (xfrac * dzdxh)) & ~0x3ff;
2293            }
2294
2295            if (spix == 3)
2296            {
2297               spans[spanidx].startx = minxmx;
2298               spans[spanidx].stopx = maxxhx;
2299               bool even_line = j & 1;
2300               userdata->m_valid_line = !bothinvalid && !allover && !allunder && (!m_scissor.m_field || (m_scissor.m_field && !(m_scissor.m_keep_odd ^ even_line)));
2301               if (!first_line && spans[spanidx-1].userdata != NULL)
2302               {
2303                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_valid = true;
2304                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_s = spans[spanidx].param[SPAN_S].start;
2305                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_t = spans[spanidx].param[SPAN_T].start;
2306                  ((rdp_span_aux*)spans[spanidx-1].userdata)->m_next_w = spans[spanidx].param[SPAN_W].start;
2307               }
2308               else
2309               {
2310                  first_line = false;
2311               }
2312               anyvalid = anyvalid || !bothinvalid;
2313            }
2314         }
2315
2316         if (spix == 3)
2317         {
2318            r += drde;
2319            g += dgde;
2320            b += dbde;
2321            a += dade;
2322            s += dsde;
2323            t += dtde;
2324            w += dwde;
2325            z += dzde;
2326         }
2327
2328         xleft += xleft_inc;
2329         xright += xright_inc;
2330      }
2331   }
2332#if 0
19772333   for (INT32 k = ycur; k <= ylfar; k++)
19782334   {
19792335      if (k == ym)
r248605r248606
20182374
20192375         if (spix == 0)
20202376         {
2021            if(new_object)
2022            {
2023               object = &object_data_alloc();
2024               memcpy(object->m_tmem, m_tmem, 0x1000);
2025               new_object = false;
2026            }
2027
2028            spans[spanidx].userdata = (void*)((UINT8*)m_aux_buf + m_aux_buf_ptr);
20292377            valid = true;
2030            m_aux_buf_ptr += sizeof(rdp_span_aux);
20312378
20322379            if(m_aux_buf_ptr >= EXTENT_AUX_COUNT)
20332380            {
r248605r248606
20772424         {
20782425            spans[spanidx].startx = *startx;
20792426            spans[spanidx].stopx = *endx;
2080            ((this)->*(m_compute_cvg[flip]))(spans, majorx, minorx, majorxint, minorxint, j, yh, yl, ycur >> 2);
2427            bool even_line = j & 1;
2428            userdata->m_valid_line = !allinvalid && !allover && !allunder && (!m_scissor.m_field || (m_scissor.m_field && !(m_scissor.m_keep_odd ^ even_line)));
20812429         }
20822430
20832431         if (spix == ldflag)
r248605r248606
21092457      xleft += xleft_inc;
21102458      xright += xright_inc;
21112459   }
2460#endif
21122461
2113   if(!new_object && valid)
2462   if(anyvalid)
21142463   {
2115      render_spans(yh >> 2, yl >> 2, tilenum, flip ? true : false, spans, rect, object);
2464      render_spans(yhlimit >> 2, yllimit >> 2, tilenum, flip ? true : false, spans, rect, object);
21162465   }
21172466
21182467   //wait("draw_triangle");
r248605r248606
23372686   k2 = (SIGN9(k2) << 1) + 1;
23382687   k3 = (SIGN9(k3) << 1) + 1;
23392688
2340   set_yuv_factors(rgbaint_t(0, k0, k2, k3), rgbaint_t(0, 0, k1, 0), rgbaint_t(k4, k4, k4, k4), rgbaint_t(k5, k5, k5, k5));
2689   set_yuv_factors(rgbaint_t(0, k0, k2, 0), rgbaint_t(0, 0, k1, k3), rgbaint_t(k4, k4, k4, k4), rgbaint_t(k5, k5, k5, k5));
23412690}
23422691
23432692void n64_rdp::cmd_set_scissor(UINT32 w1, UINT32 w2)
23442693{
2345   m_scissor.m_xh = ((w1 >> 12) & 0xfff) >> 2;
2346   m_scissor.m_yh = ((w1 >>  0) & 0xfff) >> 2;
2347   m_scissor.m_xl = ((w2 >> 12) & 0xfff) >> 2;
2348   m_scissor.m_yl = ((w2 >>  0) & 0xfff) >> 2;
2694   m_scissor.m_xh = (w1 >> 12) & 0xfff;
2695   m_scissor.m_yh = (w1 >>  0) & 0xfff;
2696   m_scissor.m_xl = (w2 >> 12) & 0xfff;
2697   m_scissor.m_yl = (w2 >>  0) & 0xfff;
23492698
2350   // TODO: handle f & o?
2699   m_scissor.m_field = (w2 >> 25) & 1;
2700   m_scissor.m_keep_odd = (w2 >> 24) & 1;
23512701}
23522702
23532703void n64_rdp::cmd_set_prim_depth(UINT32 w1, UINT32 w2)
r248605r248606
28273177   ewdata[0] = (0x3680 << 16) | yl;//command, flipped, tile, yl
28283178   ewdata[1] = (yl << 16) | yh;//ym, yh
28293179   ewdata[2] = (xlint << 16) | ((xl & 3) << 14);//xl, xl frac
2830   ewdata[3] = 0;//dxldy, dxldy frac
28313180   ewdata[4] = (xhint << 16) | ((xh & 3) << 14);//xh, xh frac
2832   ewdata[5] = 0;//dxhdy, dxhdy frac
28333181   ewdata[6] = (xlint << 16) | ((xl & 3) << 14);//xm, xm frac
2834   ewdata[7] = 0;//dxmdy, dxmdy frac
28353182   memset(&ewdata[8], 0, 36 * sizeof(UINT32));//shade, texture, depth
28363183
28373184   draw_triangle(false, false, false, true);
r248605r248606
32113558
32123559void n64_rdp::render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object)
32133560{
3214   const INT32 clipy1 = m_scissor.m_yh;
3215   const INT32 clipy2 = m_scissor.m_yl;
3561   const INT32 clipy1 = m_scissor.m_yh >> 2;
3562   const INT32 clipy2 = m_scissor.m_yl >> 2;
32163563   INT32 offset = 0;
32173564
32183565   if (clipy2 <= 0)
r248605r248606
32443591   memcpy(&object->m_other_modes, &m_other_modes, sizeof(other_modes_t));
32453592   memcpy(&object->m_span_base, &m_span_base, sizeof(span_base_t));
32463593   memcpy(&object->m_scissor, &m_scissor, sizeof(rectangle_t));
3594   memcpy(&object->m_mode_derivs, &m_mode_derivs, sizeof(mode_derivs_t));
32473595   memcpy(&object->m_tiles, &m_tiles, 8 * sizeof(n64_tile_t));
32483596   object->tilenum = tilenum;
32493597   object->flip = flip;
32503598   object->m_fill_color = m_fill_color;
32513599   object->rect = rect;
32523600
3601   //printf("%d", m_other_modes.cycle_type);
32533602   switch(m_other_modes.cycle_type)
32543603   {
32553604      case CYCLE_TYPE_1:
3605         //printf("%d, %d\n", start, end);
32563606         render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_1cycle), this), start, (end - start) + 1, spans + offset);
32573607         break;
32583608
r248605r248606
32713621   //wait();
32723622}
32733623
3274void n64_rdp::rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata)
3624void n64_rdp::rgbaz_correct_clip(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object)
32753625{
3276   userdata->m_shade_color.set(sa, sr, sg, sb);
3277   userdata->m_shade_color.clamp_and_clear(0xfffffe00);
3278   UINT32 a = userdata->m_shade_color.get_a();
3279   userdata->m_shade_alpha.set(a, a, a, a);
3280
3281   INT32 zanded = (*sz) & 0x60000;
3282
3283   zanded >>= 17;
3284   switch(zanded)
3285   {
3286      case 0: *sz &= 0x3ffff;                                         break;
3287      case 1: *sz &= 0x3ffff;                                         break;
3288      case 2: *sz = 0x3ffff;                                          break;
3289      case 3: *sz = 0x3ffff;                                          break;
3290   }
3291}
3292
3293void n64_rdp::rgbaz_correct_triangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object)
3294{
32953626   if (userdata->m_current_pix_cvg == 8)
32963627   {
32973628      *r >>= 2;
32983629      *g >>= 2;
32993630      *b >>= 2;
33003631      *a >>= 2;
3301      *z = (*z >> 3) & 0x7ffff;
3632      *z >>= 3;
33023633   }
33033634   else
33043635   {
3305      INT32 summand_xr = offx * SIGN13(object.m_span_base.m_span_dr >> 14);
3306      INT32 summand_yr = offy * SIGN13(object.m_span_base.m_span_drdy >> 14);
3307      INT32 summand_xb = offx * SIGN13(object.m_span_base.m_span_db >> 14);
3308      INT32 summand_yb = offy * SIGN13(object.m_span_base.m_span_dbdy >> 14);
3309      INT32 summand_xg = offx * SIGN13(object.m_span_base.m_span_dg >> 14);
3310      INT32 summand_yg = offy * SIGN13(object.m_span_base.m_span_dgdy >> 14);
3311      INT32 summand_xa = offx * SIGN13(object.m_span_base.m_span_da >> 14);
3312      INT32 summand_ya = offy * SIGN13(object.m_span_base.m_span_dady >> 14);
3636      const INT32 summand_r = offx * object.m_span_base.m_span_cdr + offy * object.m_span_base.m_span_drdy;
3637      const INT32 summand_g = offx * object.m_span_base.m_span_cdg + offy * object.m_span_base.m_span_dgdy;
3638      const INT32 summand_b = offx * object.m_span_base.m_span_cdb + offy * object.m_span_base.m_span_dbdy;
3639      const INT32 summand_a = offx * object.m_span_base.m_span_cda + offy * object.m_span_base.m_span_dady;
3640      const INT32 summand_z = offx * object.m_span_base.m_span_cdz + offy * object.m_span_base.m_span_dzdy;
33133641
3314      INT32 summand_xz = offx * SIGN22(object.m_span_base.m_span_dz >> 10);
3315      INT32 summand_yz = offy * SIGN22(object.m_span_base.m_span_dzdy >> 10);
3642      *r = ((*r << 2) + summand_r) >> 4;
3643      *g = ((*g << 2) + summand_g) >> 4;
3644      *b = ((*b << 2) + summand_b) >> 4;
3645      *a = ((*a << 2) + summand_a) >> 4;
3646      *z = ((*z << 2) + summand_z) >> 5;
3647   }
33163648
3317      *r = ((*r << 2) + summand_xr + summand_yr) >> 4;
3318      *g = ((*g << 2) + summand_xg + summand_yg) >> 4;
3319      *b = ((*b << 2) + summand_xb + summand_yb) >> 4;
3320      *a = ((*a << 2) + summand_xa + summand_ya) >> 4;
3321      *z = (((*z << 2) + summand_xz + summand_yz) >> 5) & 0x7ffff;
3649   userdata->m_shade_color.set(*r, *g, *b, *a);
3650   userdata->m_shade_color.clamp_and_clear(0xfffffe00);
3651   userdata->m_shade_alpha.set(*a, *a, *a, *a);
3652
3653   const INT32 zanded = ((*z) & 0x60000) >> 17;
3654
3655   switch(zanded)
3656   {
3657      case 0: *z &= 0x3ffff;   break;
3658      case 1: *z &= 0x3ffff;   break;
3659      case 2: *z = 0x3ffff;   break;
3660      case 3: *z = 0;         break;
33223661   }
33233662}
33243663
r248605r248606
35023841{
35033842   assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
35043843
3505   const INT32 clipx1 = object.m_scissor.m_xh;
3506   const INT32 clipx2 = object.m_scissor.m_xl;
3507   const INT32 tilenum = object.tilenum;
3508   const bool flip = object.flip;
3509
35103844   span_param_t r; r.w = extent.param[SPAN_R].start;
35113845   span_param_t g; g.w = extent.param[SPAN_G].start;
35123846   span_param_t b; b.w = extent.param[SPAN_B].start;
r248605r248606
35263860#endif
35273861   rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
35283862
3529   m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object);
3863   if (!userdata->m_valid_line)
3864   {
3865      return;
3866   }
35303867
3531   const bool partialreject = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color);
3532   const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
3868   const INT32 tilenum = object.tilenum;
3869   const INT32 prim_tile = tilenum;
3870   INT32 tile1 = tilenum;
3871   INT32 newtile = tilenum;
35333872
3873   const bool flip = object.flip;
3874
35343875   INT32 drinc, dginc, dbinc, dainc;
35353876   INT32 dzinc, dzpix;
35363877   INT32 dsinc, dtinc, dwinc;
r248605r248606
35613902      xinc = 1;
35623903   }
35633904
3905   if(object.m_other_modes.z_source_sel)
3906   {
3907      z.w = object.m_misc_state.m_primitive_z;
3908      dzpix = object.m_misc_state.m_primitive_dz;
3909      dzinc = 0;
3910   }
3911   else
3912   {
3913      dzpix = object.m_span_base.m_span_dzpix;
3914   }
3915   userdata->m_dzpix_enc = dz_compress(dzpix);
3916
3917   m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object);
3918
3919   const bool partialreject = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color);
3920   const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
3921
35643922   const INT32 fb_index = object.m_misc_state.m_fb_width * scanline;
35653923
35663924   const INT32 xstart = extent.startx;
35673925   const INT32 xend = userdata->m_unscissored_rx;
35683926   const INT32 xend_scissored = extent.stopx;
35693927
3570   INT32 x = xend;
3928   INT32 x = xend_scissored;
35713929
3572   const INT32 length = flip ? (xstart - xend) : (xend - xstart);
3573
3574   if(object.m_other_modes.z_source_sel)
3930   INT32 length, scdiff;
3931   if (flip)
35753932   {
3576      z.w = object.m_misc_state.m_primitive_z;
3577      dzpix = object.m_misc_state.m_primitive_dz;
3578      dzinc = 0;
3933      compute_cvg_flip(userdata, extent.startx, extent.stopx);
3934      length = xstart - xend_scissored;
3935      scdiff = xend_scissored - xend;
35793936   }
35803937   else
35813938   {
3582      dzpix = object.m_span_base.m_span_dzpix;
3939      compute_cvg_noflip(userdata, extent.startx, extent.stopx);
3940      length = xend_scissored - xstart;
3941      scdiff = xend - xend_scissored;
35833942   }
35843943
3944   if (scdiff)
3945   {
3946      r.w += (drinc * scdiff);
3947      g.w += (dginc * scdiff);
3948      b.w += (dbinc * scdiff);
3949      a.w += (dainc * scdiff);
3950      z.w += (dzinc * scdiff);
3951      s.w += (dsinc * scdiff);
3952      t.w += (dtinc * scdiff);
3953      w.w += (dwinc * scdiff);
3954   }
3955
35853956   if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4)
35863957      fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size);
35873958
r248605r248606
35913962   INT32 sss = 0;
35923963   INT32 sst = 0;
35933964
3594   if (object.m_other_modes.persp_tex_en)
3595   {
3596      tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
3597   }
3598   else
3599   {
3600      tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
3601   }
3965   INT32 news, newt;
3966   INT32 prelodfrac;
36023967
36033968   userdata->m_start_span = true;
3969   userdata->m_long_span = (length > 7);
3970   userdata->m_mid_span = (length == 7);
3971   userdata->m_almost_mid_span = (length == 6);
3972
3973   INT32 nexts, nextt, nextw;
3974
36043975   for (INT32 j = 0; j <= length; j++)
36053976   {
36063977      INT32 sr = r.w >> 14;
36073978      INT32 sg = g.w >> 14;
36083979      INT32 sb = b.w >> 14;
36093980      INT32 sa = a.w >> 14;
3981      INT32 ss = s.w >> 16;
3982      INT32 st = t.w >> 16;
3983      INT32 sw = w.w >> 16;
36103984      INT32 sz = (z.w >> 10) & 0x3fffff;
3611      const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
36123985
3613      if (x >= clipx1 && x < clipx2 && valid_x)
3986      userdata->m_end_span = (j == length);
3987      userdata->m_pre_end_span = (j == (length - 1));
3988
3989      UINT8 offx, offy;
3990      lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
3991
3992      if (!userdata->m_end_span || !userdata->m_long_span || !userdata->m_next_valid)
36143993      {
3615         UINT8 offx, offy;
3616         lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
3994         nexts = (s.w + dsinc) >> 16;
3995         nextt = (t.w + dtinc) >> 16;
3996         nextw = (w.w + dwinc) >> 16;
3997      }
3998      else
3999      {
4000         nexts = userdata->m_next_s >> 16;
4001         nextt = userdata->m_next_t >> 16;
4002         nextw = userdata->m_next_w >> 16;
4003      }
36174004
3618         m_tex_pipe.lod_1cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
4005      if (object.m_other_modes.persp_tex_en)
4006      {
4007         tc_div(nexts, nextt, nextw, &news, &newt);
4008      }
4009      else
4010      {
4011         tc_div_no_perspective(nexts, nextt, nextw, &news, &newt);
4012      }
36194013
3620         rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
3621         rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
4014      if (!userdata->m_start_span)
4015      {
4016         userdata->m_texel0_color.set(userdata->m_texel1_color);
4017         userdata->m_texel1_alpha.set(userdata->m_texel1_alpha);
4018         userdata->m_lod_fraction.set(prelodfrac, prelodfrac, prelodfrac, prelodfrac);
4019      }
4020      else
4021      {
4022         if (object.m_other_modes.persp_tex_en)
4023         {
4024            tc_div(ss, st, sw, &sss, &sst);
4025         }
4026         else
4027         {
4028            tc_div_no_perspective(ss, st, sw, &sss, &sst);
4029         }
36224030
4031         m_tex_pipe.tclod_1cycle_current(&sss, &sst, news, newt, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, userdata, object);
4032
36234033         ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tilenum, 0, userdata, object);
3624         UINT32 t0a = userdata->m_texel0_color.get_a();
3625         userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
36264034
4035         userdata->m_start_span = false;
4036      }
4037
4038      userdata->m_next_span = userdata->m_end_span;
4039      userdata->m_end_span = userdata->m_pre_end_span;
4040      userdata->m_pre_end_span = (j == (length - 2));
4041
4042      s.w += dsinc;
4043      t.w += dtinc;
4044      w.w += dwinc;
4045
4046      m_tex_pipe.tclod_1cycle_next(&news, &newt, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &newtile, &prelodfrac, userdata, object);
4047
4048      ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel1_color, &userdata->m_texel1_color, news, newt, tilenum, 0, userdata, object);
4049
4050      rgbaz_correct_clip(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
4051
4052      UINT32 t0a = userdata->m_texel0_color.get_a();
4053      userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
4054
4055      if (userdata->m_noise_used)
4056      {
36274057         const UINT8 noise = rand() << 3; // Not accurate
36284058         userdata->m_noise_color.set(0, noise, noise, noise);
4059      }
36294060
3630         rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
3631         rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
3632         rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[1]);
3633         rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[1]);
4061      rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
4062      rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
4063      rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[1]);
4064      rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[1]);
36344065
3635         rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
3636         rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
3637         rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
3638         rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
4066      rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
4067      rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
4068      rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
4069      rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
36394070
3640         rgbsub_a.sign_extend(0x180, 0xfffffe00);
3641         rgbsub_b.sign_extend(0x180, 0xfffffe00);
3642         rgbadd.sign_extend(0x180, 0xfffffe00);
4071      rgbsub_a.sign_extend(0x180, 0xfffffe00);
4072      rgbsub_b.sign_extend(0x180, 0xfffffe00);
4073      rgbadd.sign_extend(0x180, 0xfffffe00);
36434074
3644         rgbadd.shl_imm(8);
3645         rgbsub_a.sub(rgbsub_b);
3646         rgbsub_a.mul(rgbmul);
3647         rgbsub_a.add(rgbadd);
3648         rgbsub_a.add_imm(0x0080);
3649         rgbsub_a.sra_imm(8);
3650         rgbsub_a.clamp_and_clear(0xfffffe00);
4075      rgbadd.shl_imm(8);
4076      rgbsub_a.sub(rgbsub_b);
4077      rgbsub_a.mul(rgbmul);
4078      rgbsub_a.add(rgbadd);
4079      rgbsub_a.add_imm(0x0080);
4080      rgbsub_a.sra_imm(8);
4081      rgbsub_a.clamp_and_clear(0xfffffe00);
36514082
3652         userdata->m_pixel_color = rgbsub_a;
4083      userdata->m_pixel_color = rgbsub_a;
4084      userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
36534085
3654         //Alpha coverage combiner
3655         userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
4086      const UINT32 curpixel = fb_index + x;
4087      const UINT32 zbcur = zb + curpixel;
4088      const UINT32 zhbcur = zhb + curpixel;
36564089
3657         const UINT32 curpixel = fb_index + x;
3658         const UINT32 zbcur = zb + curpixel;
3659         const UINT32 zhbcur = zhb + curpixel;
4090      //printf("%d, %d\n", x, scanline);
4091      read_pixel(curpixel, userdata, object);
36604092
3661         read_pixel(curpixel, userdata, object);
4093      if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
4094      {
4095         INT32 cdith = 0;
4096         INT32 adith = 0;
4097         get_dither_values(scanline, j, &cdith, &adith, object);
36624098
3663         if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
4099         color_t blended_pixel;
4100         bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, userdata, object);
4101
4102         if (rendered)
36644103         {
3665            INT32 cdith = 0;
3666            INT32 adith = 0;
3667            get_dither_values(scanline, j, &cdith, &adith, object);
3668
3669            color_t blended_pixel;
3670            bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, userdata, object);
3671
3672            if (rendered)
4104            write_pixel(curpixel, blended_pixel, userdata, object);
4105            if (object.m_other_modes.z_update_en)
36734106            {
3674               write_pixel(curpixel, blended_pixel, userdata, object);
3675               if (object.m_other_modes.z_update_en)
3676               {
3677                  z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
3678               }
4107               z_store(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
36794108            }
36804109         }
3681
3682         sss = userdata->m_precomp_s;
3683         sst = userdata->m_precomp_t;
36844110      }
36854111
4112      sss = userdata->m_precomp_s;
4113      sst = userdata->m_precomp_t;
4114
36864115      r.w += drinc;
36874116      g.w += dginc;
36884117      b.w += dbinc;
36894118      a.w += dainc;
3690      s.w += dsinc;
3691      t.w += dtinc;
3692      w.w += dwinc;
36934119      z.w += dzinc;
36944120
36954121      x += xinc;
r248605r248606
37004126{
37014127   assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4);
37024128
3703   const INT32 clipx1 = object.m_scissor.m_xh;
3704   const INT32 clipx2 = object.m_scissor.m_xl;
37054129   const INT32 tilenum = object.tilenum;
37064130   const bool flip = object.flip;
37074131
r248605r248606
37224146   const UINT32 prim_tile = tilenum;
37234147
37244148   INT32 newtile1 = tile1;
3725   INT32 news = 0;
3726   INT32 newt = 0;
4149   INT32 newtile2 = tile2;
37274150
37284151#ifdef PTR64
37294152   assert(extent.userdata != (const void *)0xcccccccccccccccc);
r248605r248606
37794202
37804203   INT32 x = xend;
37814204
3782   const INT32 length = flip ? (xstart - xend) : (xend - xstart);
4205   INT32 length, scdiff;
4206   if (flip)
4207   {
4208      compute_cvg_flip(userdata, extent.startx, extent.stopx);
4209      length = xstart - xend_scissored;
4210      scdiff = xend_scissored - xend;
4211   }
4212   else
4213   {
4214      compute_cvg_noflip(userdata, extent.startx, extent.stopx);
4215      length = xend_scissored - xstart;
4216      scdiff = xend - xend_scissored;
4217   }
37834218
4219   if (scdiff)
4220   {
4221      r.w += (drinc * scdiff);
4222      g.w += (dginc * scdiff);
4223      b.w += (dbinc * scdiff);
4224      a.w += (dainc * scdiff);
4225      z.w += (dzinc * scdiff);
4226      s.w += (dsinc * scdiff);
4227      t.w += (dtinc * scdiff);
4228      w.w += (dwinc * scdiff);
4229   }
4230
37844231   if(object.m_other_modes.z_source_sel)
37854232   {
37864233      z.w = object.m_misc_state.m_primitive_z;
r248605r248606
38024249   INT32 sss = 0;
38034250   INT32 sst = 0;
38044251
3805   if (object.m_other_modes.persp_tex_en)
3806   {
3807      tc_div(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
3808   }
3809   else
3810   {
3811      tc_div_no_perspective(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
3812   }
4252   INT32 news, newt;
4253   INT32 prelodfrac;
38134254
38144255   userdata->m_start_span = true;
4256   userdata->m_long_span = (length > 7);
4257   userdata->m_mid_span = (length == 7);
4258   userdata->m_almost_mid_span = (length == 6);
4259
4260   INT32 nexts, nextt, nextw;
4261
4262   userdata->m_start_span = true;
4263
38154264   for (INT32 j = 0; j <= length; j++)
38164265   {
38174266      INT32 sr = r.w >> 14;
38184267      INT32 sg = g.w >> 14;
38194268      INT32 sb = b.w >> 14;
38204269      INT32 sa = a.w >> 14;
4270      INT32 ss = s.w >> 16;
4271      INT32 st = t.w >> 16;
4272      INT32 sw = w.w >> 16;
38214273      INT32 sz = (z.w >> 10) & 0x3fffff;
3822      color_t c1;
3823      color_t c2;
38244274
3825      const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
4275      userdata->m_end_span = (j == length);
4276      userdata->m_pre_end_span = (j == (length - 1));
38264277
3827      if (x >= clipx1 && x < clipx2 && valid_x)
4278      UINT8 offx, offy;
4279      lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
4280
4281      nexts = (s.w + dsinc) >> 16;
4282      nextt = (t.w + dtinc) >> 16;
4283      nextw = (w.w + dwinc) >> 16;
4284
4285      if (object.m_other_modes.persp_tex_en)
38284286      {
3829         const UINT32 compidx = m_compressed_cvmasks[userdata->m_cvg[x]];
3830         userdata->m_current_pix_cvg = cvarray[compidx].cvg;
3831         userdata->m_current_cvg_bit = cvarray[compidx].cvbit;
3832         const UINT8 offx = cvarray[compidx].xoff;
3833         const UINT8 offy = cvarray[compidx].yoff;
3834         //lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
4287         tc_div(nexts, nextt, nextw, &news, &newt);
4288      }
4289      else
4290      {
4291         tc_div_no_perspective(nexts, nextt, nextw, &news, &newt);
4292      }
38354293
3836         m_tex_pipe.lod_2cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
4294      if (!userdata->m_start_span)
4295      {
4296         userdata->m_texel0_color.set(userdata->m_next_texel0_color);
4297         userdata->m_texel1_color.set(userdata->m_next_texel1_color);
4298         userdata->m_texel0_alpha.set(userdata->m_next_texel0_alpha);
4299         userdata->m_texel1_alpha.set(userdata->m_next_texel1_alpha);
4300         userdata->m_lod_fraction.set(prelodfrac, prelodfrac, prelodfrac, prelodfrac);
4301      }
4302      else
4303      {
4304         if (object.m_other_modes.persp_tex_en)
4305         {
4306            tc_div(ss, st, sw, &sss, &sst);
4307         }
4308         else
4309         {
4310            tc_div_no_perspective(ss, st, sw, &sss, &sst);
4311         }
38374312
3838         news = userdata->m_precomp_s;
3839         newt = userdata->m_precomp_t;
3840         m_tex_pipe.lod_2cycle_limited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
4313         m_tex_pipe.tclod_2cycle_current(&sss, &sst, news, newt, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
38414314
3842         rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
3843         rgbaz_clip(sr, sg, sb, sa, &sz, userdata);
3844
38454315         ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tile1, 0, userdata, object);
38464316         ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_texel1_color, &userdata->m_texel0_color, sss, sst, tile2, 1, userdata, object);
3847         ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_next_texel_color, &userdata->m_next_texel_color, sss, sst, tile2, 1, userdata, object);
38484317
3849         UINT32 t0a = userdata->m_texel0_color.get_a();
3850         UINT32 t1a = userdata->m_texel1_color.get_a();
3851         UINT32 tna = userdata->m_next_texel_color.get_a();
3852         userdata->m_texel0_alpha.set(t0a, t0a, t0a, t0a);
3853         userdata->m_texel1_alpha.set(t1a, t1a, t1a, t1a);
3854         userdata->m_next_texel_alpha.set(tna, tna, tna, tna);
4318         userdata->m_start_span = false;
4319      }
38554320
4321      s.w += dsinc;
4322      t.w += dtinc;
4323      w.w += dwinc;
4324
4325      m_tex_pipe.tclod_2cycle_next(&news, &newt, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &newtile1, &newtile2, &prelodfrac, userdata, object);
4326
4327      ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_next_texel0_color, &userdata->m_texel0_color, news, newt, newtile1, 0, userdata, object);
4328      ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_next_texel1_color, &userdata->m_texel1_color, news, newt, newtile2, 1, userdata, object);
4329
4330      rgbaz_correct_clip(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
4331
4332      if (userdata->m_noise_used)
4333      {
38564334         const UINT8 noise = rand() << 3; // Not accurate
38574335         userdata->m_noise_color.set(0, noise, noise, noise);
4336      }
38584337
3859         rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
3860         rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
3861         rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
3862         rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
4338      rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
4339      rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
4340      rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
4341      rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
38634342
3864         rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[0]);
3865         rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[0]);
3866         rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[0]);
3867         rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[0]);
4343      rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[0]);
4344      rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[0]);
4345      rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[0]);
4346      rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[0]);
38684347
3869         rgbsub_a.sign_extend(0x180, 0xfffffe00);
3870         rgbsub_b.sign_extend(0x180, 0xfffffe00);
3871         rgbadd.sign_extend(0x180, 0xfffffe00);
4348      rgbsub_a.sign_extend(0x180, 0xfffffe00);
4349      rgbsub_b.sign_extend(0x180, 0xfffffe00);
4350      rgbadd.sign_extend(0x180, 0xfffffe00);
38724351
3873         rgbadd.shl_imm(8);
3874         rgbsub_a.sub(rgbsub_b);
3875         rgbsub_a.mul(rgbmul);
4352      rgbadd.shl_imm(8);
4353      rgbsub_a.sub(rgbsub_b);
4354      rgbsub_a.mul(rgbmul);
38764355
3877         rgbsub_a.add(rgbadd);
3878         rgbsub_a.add_imm(0x0080);
3879         rgbsub_a.sra_imm(8);
3880         rgbsub_a.clamp_and_clear(0xfffffe00);
4356      rgbsub_a.add(rgbadd);
4357      rgbsub_a.add_imm(0x0080);
4358      rgbsub_a.sra_imm(8);
4359      rgbsub_a.clamp_and_clear(0xfffffe00);
38814360
3882         userdata->m_combined_color.set(rgbsub_a);
3883         userdata->m_texel0_color.set(userdata->m_texel1_color);
3884         userdata->m_texel1_color.set(userdata->m_next_texel_color);
4361      userdata->m_combined_color.set(rgbsub_a);
4362      userdata->m_texel0_color.set(userdata->m_texel1_color);
4363      userdata->m_texel1_color.set(userdata->m_next_texel0_color);
38854364
3886         UINT32 ca = userdata->m_combined_color.get_a();
3887         userdata->m_combined_alpha.set(ca, ca, ca, ca);
3888         userdata->m_texel0_alpha.set(userdata->m_texel1_alpha);
3889         userdata->m_texel1_alpha.set(userdata->m_next_texel_alpha);
4365      UINT32 ca = userdata->m_combined_color.get_a();
4366      userdata->m_combined_alpha.set(ca, ca, ca, ca);
4367      userdata->m_texel0_alpha.set(userdata->m_texel1_alpha);
4368      userdata->m_texel1_alpha.set(userdata->m_next_texel0_alpha);
38904369
3891         rgbsub_a.set(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
3892         rgbsub_b.set(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
3893         rgbmul.set(*userdata->m_color_inputs.combiner_rgbmul[1]);
3894         rgbadd.set(*userdata->m_color_inputs.combiner_rgbadd[1]);
4370      rgbsub_a.set(*userdata->m_color_inputs.combiner_rgbsub_a[1]);
4371      rgbsub_b.set(*userdata->m_color_inputs.combiner_rgbsub_b[1]);
4372      rgbmul.set(*userdata->m_color_inputs.combiner_rgbmul[1]);
4373      rgbadd.set(*userdata->m_color_inputs.combiner_rgbadd[1]);
38954374
3896         rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
3897         rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
3898         rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
3899         rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
4375      rgbsub_a.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_a[1]);
4376      rgbsub_b.merge_alpha(*userdata->m_color_inputs.combiner_alphasub_b[1]);
4377      rgbmul.merge_alpha(*userdata->m_color_inputs.combiner_alphamul[1]);
4378      rgbadd.merge_alpha(*userdata->m_color_inputs.combiner_alphaadd[1]);
39004379
3901         rgbsub_a.sign_extend(0x180, 0xfffffe00);
3902         rgbsub_b.sign_extend(0x180, 0xfffffe00);
3903         rgbadd.sign_extend(0x180, 0xfffffe00);
4380      rgbsub_a.sign_extend(0x180, 0xfffffe00);
4381      rgbsub_b.sign_extend(0x180, 0xfffffe00);
4382      rgbadd.sign_extend(0x180, 0xfffffe00);
39044383
3905         rgbadd.shl_imm(8);
3906         rgbsub_a.sub(rgbsub_b);
3907         rgbsub_a.mul(rgbmul);
3908         rgbsub_a.add(rgbadd);
3909         rgbsub_a.add_imm(0x0080);
3910         rgbsub_a.sra_imm(8);
3911         rgbsub_a.clamp_and_clear(0xfffffe00);
4384      rgbadd.shl_imm(8);
4385      rgbsub_a.sub(rgbsub_b);
4386      rgbsub_a.mul(rgbmul);
4387      rgbsub_a.add(rgbadd);
4388      rgbsub_a.add_imm(0x0080);
4389      rgbsub_a.sra_imm(8);
4390      rgbsub_a.clamp_and_clear(0xfffffe00);
39124391
3913         userdata->m_pixel_color.set(rgbsub_a);
4392      userdata->m_pixel_color.set(rgbsub_a);
39144393
3915         //Alpha coverage combiner
3916         userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
4394      //Alpha coverage combiner
4395      userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
39174396
3918         const UINT32 curpixel = fb_index + x;
3919         const UINT32 zbcur = zb + curpixel;
3920         const UINT32 zhbcur = zhb + curpixel;
4397      const UINT32 curpixel = fb_index + x;
4398      const UINT32 zbcur = zb + curpixel;
4399      const UINT32 zhbcur = zhb + curpixel;
39214400
3922         read_pixel(curpixel, userdata, object);
4401      read_pixel(curpixel, userdata, object);
39234402
3924         if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
3925         {
3926            get_dither_values(scanline, j, &cdith, &adith, object);
4403      if(z_compare(zbcur, zhbcur, sz, dzpix, userdata, object))
4404      {
4405         get_dither_values(scanline, j, &cdith, &adith, object);
39274406
3928            color_t blended_pixel;
3929            bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, sel1, userdata, object);
4407         color_t blended_pixel;
4408         bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, sel1, userdata, object);
39304409
3931            if (rendered)
4410         if (rendered)
4411         {
4412            write_pixel(curpixel, blended_pixel, userdata, object);
4413            if (object.m_other_modes.z_update_en)
39324414            {
3933               write_pixel(curpixel, blended_pixel, userdata, object);
3934               if (object.m_other_modes.z_update_en)
3935               {
3936                  z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
3937               }
4415               z_store(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
39384416            }
39394417         }
3940         sss = userdata->m_precomp_s;
3941         sst = userdata->m_precomp_t;
39424418      }
4419      sss = userdata->m_precomp_s;
4420      sst = userdata->m_precomp_t;
39434421
39444422      r.w += drinc;
39454423      g.w += dginc;
r248605r248606
39564434
39574435void n64_rdp::span_draw_copy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid)
39584436{
3959   const INT32 clipx1 = object.m_scissor.m_xh;
3960   const INT32 clipx2 = object.m_scissor.m_xl;
4437   const INT32 clipx1 = object.m_scissor.m_xh >> 2;
4438   const INT32 clipx2 = object.m_scissor.m_xl >> 2;
39614439   const INT32 tilenum = object.tilenum;
39624440   const bool flip = object.flip;
39634441
39644442   rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata;
4443
39654444   const INT32 xstart = extent.startx;
39664445   const INT32 xend = userdata->m_unscissored_rx;
39674446   const INT32 xend_scissored = extent.stopx;
r248605r248606
40094488
40104489   const bool flip = object.flip;
40114490
4012   const INT32 clipx1 = object.m_scissor.m_xh;
4013   const INT32 clipx2 = object.m_scissor.m_xl;
4491   const INT32 clipx1 = object.m_scissor.m_xh >> 2;
4492   const INT32 clipx2 = object.m_scissor.m_xl >> 2;
40144493
40154494   const INT32 xinc = flip ? 1 : -1;
40164495
branches/n64-angrylion/src/mame/video/n64.h
r248605r248606
3939#define FORMAT_IA               3
4040#define FORMAT_I                4
4141
42#define ZMODE_OPAQUE         0
43#define ZMODE_INTERPENETRATING   1
44#define ZMODE_TRANSLUCENT      2
45#define ZMODE_DECAL            3
46
47#define SPAN_UNINITIALIZED      0
48#define SPAN_VALID            1
49#define SPAN_INVALID         2
50
4251#ifdef LSB_FIRST
4352#define BYTE_XOR_DWORD_SWAP 7
4453#define WORD_XOR_DWORD_SWAP 3
r248605r248606
98107#define HWRITEADDR8(in, val)    /*{if ((in) <= MEM8_LIMIT) */m_hidden_bits[(in) ^ BYTE_ADDR_XOR] = val;/*}*/
99108
100109//sign-extension macros
101#define SIGN22(x)   (((x & 0x00200000) * 0x7ff) | (x & 0x1fffff))
102#define SIGN17(x)   (((x & 0x00010000) * 0xffff) | (x & 0xffff))
103#define SIGN16(x)   (((x & 0x00008000) * 0x1ffff) | (x & 0x7fff))
104#define SIGN13(x)   (((x & 0x00001000) * 0xfffff) | (x & 0xfff))
105#define SIGN11(x)   (((x & 0x00000400) * 0x3fffff) | (x & 0x3ff))
106#define SIGN9(x)    (((x & 0x00000100) * 0xffffff) | (x & 0xff))
107#define SIGN8(x)    (((x & 0x00000080) * 0x1ffffff) | (x & 0x7f))
110#define SIGN22(x)   ((((x) & 0x00200000) * 0x7ff) | ((x) & 0x1fffff))
111#define SIGN17(x)   ((((x) & 0x00010000) * 0xffff) | ((x) & 0xffff))
112#define SIGN16(x)   ((((x) & 0x00008000) * 0x1ffff) | ((x) & 0x7fff))
113#define SIGN13(x)   ((((x) & 0x00001000) * 0xfffff) | ((x) & 0xfff))
114#define SIGN11(x)   ((((x) & 0x00000400) * 0x3fffff) | ((x) & 0x3ff))
115#define SIGN9(x)    ((((x) & 0x00000100) * 0xffffff) | ((x) & 0xff))
116#define SIGN8(x)    ((((x) & 0x00000080) * 0x1ffffff) | ((x) & 0x7f))
108117
109118#define KURT_AKELEY_SIGN9(x)    ((((x) & 0x180) == 0x180) ? ((x) | ~0x1ff) : ((x) & 0x1ff))
110119
r248605r248606
117126#define SPAN_W      (6)
118127#define SPAN_Z      (7)
119128
120#define EXTENT_AUX_COUNT            (sizeof(rdp_span_aux)*(480*192)) // Screen coverage *192, more or less
129#define EXTENT_AUX_COUNT            (sizeof(rdp_span_aux)*(480*4096)) // Screen coverage *192, more or less
121130
122131/*****************************************************************************/
123132
r248605r248606
160169         m_tiles[i].invmm = rgbaint_t(~0, ~0, ~0, ~0);
161170         m_tiles[i].invmask = rgbaint_t(~0, ~0, ~0, ~0);
162171      }
172
173      m_dz_compare_lut[0] = 0;
174      for (INT32 i = 1; i < 0x10000; i++)
175      {
176         for (INT32 k = 15; k >= 0; k--)
177         {
178            if (i & (1 << k))
179            {
180               m_dz_compare_lut[i] = 1 << k;
181               break;
182            }
183         }
184      }
163185   }
164186
165187   void        process_command_list();
r248605r248606
199221   UINT8       get_random() { return m_misc_state.m_random_seed += 0x13; }
200222
201223   // YUV Factors
202   void        set_yuv_factors(color_t k023, color_t k1, color_t k4, color_t k5) { m_k023 = k023; m_k1 = k1; m_k4 = k4; m_k5 = k5; }
203   color_t&    get_k023() { return m_k023; }
204   color_t&    get_k1() { return m_k1; }
224   void        set_yuv_factors(color_t k02, color_t k13, color_t k4, color_t k5) { m_k02 = k02; m_k13 = k13; m_k4 = k4; m_k5 = k5; }
225   color_t&    get_k02() { return m_k02; }
226   color_t&    get_k13() { return m_k13; }
205227
206228   // Blender-related (move into RDP::Blender)
207229   void        set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, color_t** input_a, INT32 a, INT32 b, rdp_span_aux* userdata);
r248605r248606
219241   void            render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object);
220242   INT32           get_alpha_cvg(INT32 comb_alpha, rdp_span_aux* userdata, const rdp_poly_state &object);
221243
222   void            z_store(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
244   void            z_store(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
223245   UINT32          z_decompress(UINT32 zcurpixel);
224   UINT32          dz_decompress(UINT32 zcurpixel, UINT32 dzcurpixel);
225246   UINT32          dz_compress(UINT32 value);
226247   INT32           normalize_dzpix(INT32 sum);
227248   bool            z_compare(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 sz, UINT16 dzpix, rdp_span_aux* userdata, const rdp_poly_state &object);
r248605r248606
268289   void        cmd_set_mask_image(UINT32 w1, UINT32 w2);
269290   void        cmd_set_color_image(UINT32 w1, UINT32 w2);
270291
271   void        rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata);
272   void        rgbaz_correct_triangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object);
292   void        rgbaz_correct_clip(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux* userdata, const rdp_poly_state &object);
273293
274294   void        triangle(bool shade, bool texture, bool zbuffer);
275295
r248605r248606
324344   n64_tile_t      m_tiles[8];
325345
326346private:
327   void    compute_cvg_noflip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
328   void    compute_cvg_flip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
347   void   deduce_derivatives(rdp_span_aux *userdata);
348   void   get_span_userdata(void** userdata);
349   void    compute_cvg_noflip(rdp_span_aux* data, UINT32 lx, UINT32 rx);
350   void    compute_cvg_flip(rdp_span_aux* data, UINT32 lx, UINT32 rx);
329351
330352   void    write_pixel(UINT32 curpixel, color_t& color, rdp_span_aux* userdata, const rdp_poly_state &object);
331353   void    read_pixel(UINT32 curpixel, rdp_span_aux* userdata, const rdp_poly_state &object);
r248605r248606
338360   void    video_update16(n64_periphs* n64, bitmap_rgb32 &bitmap);
339361   void    video_update32(n64_periphs* n64, bitmap_rgb32 &bitmap);
340362
341   typedef void (n64_rdp::*compute_cvg_t) (extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
363   typedef void (n64_rdp::*compute_cvg_t) (rdp_span_aux* data, UINT32 lx, UINT32 rx);
342364   compute_cvg_t   m_compute_cvg[2];
343365
344366   running_machine* m_machine;
345367
346368   combine_modes_t m_combine;
369   mode_derivs_t   m_mode_derivs;
347370   bool            m_pending_mode_block;
348371   bool            m_pipe_clean;
349372
r248605r248606
367390   UINT8*  m_tmem;
368391
369392   // YUV factors
370   color_t m_k023;
371   color_t m_k1;
393   color_t m_k02;
394   color_t m_k13;
372395   color_t m_k4;
373396   color_t m_k5;
374397
r248605r248606
378401
379402   INT32 m_gamma_table[256];
380403   INT32 m_gamma_dither_table[0x4000];
404   UINT32 m_dz_compare_lut[0x10000];
381405
382406   static UINT32 s_special_9bit_clamptable[512];
383407   static const z_decompress_entry_t m_z_dec_table[8];
branches/n64-angrylion/src/mame/video/n64types.h
r248605r248606
143143   INT32 m_span_dt;
144144   INT32 m_span_dw;
145145   INT32 m_span_dz;
146   INT32 m_span_dymax;
147   INT32 m_span_dzpix;
148146   INT32 m_span_drdy;
149147   INT32 m_span_dgdy;
150148   INT32 m_span_dbdy;
151149   INT32 m_span_dady;
150   INT32 m_span_dsdy;
151   INT32 m_span_dtdy;
152   INT32 m_span_dwdy;
152153   INT32 m_span_dzdy;
154   INT32 m_span_dzpix;
155   INT32 m_span_cdr;
156   INT32 m_span_cdg;
157   INT32 m_span_cdb;
158   INT32 m_span_cda;
159   INT32 m_span_cdz;
153160};
154161
155162struct combine_modes_t
r248605r248606
242249   UINT16 m_yl;    // 10.2 fixed-point
243250   UINT16 m_xh;    // 10.2 fixed-point
244251   UINT16 m_yh;    // 10.2 fixed-point
252
253   bool m_field;
254   bool m_keep_odd;
245255};
246256
257struct mode_derivs_t
258{
259   bool   m_stale_derivs;
260   bool   m_do_lod;
261   bool   m_partial_reject_1cycle;
262   bool   m_partial_reject_2cycle;
263   bool   m_special_bsel0;
264   bool   m_special_bsel1;
265   INT32   m_rgb_alpha_dither;
266};
267
247268struct rdp_poly_state
248269{
249270   n64_rdp*            m_rdp;                  /* pointer back to the RDP state */
r248605r248606
252273   other_modes_t       m_other_modes;          /* miscellaneous rasterizer bits (2) */
253274   span_base_t         m_span_base;            /* span initial values for triangle rasterization */
254275   rectangle_t         m_scissor;              /* screen-space scissor bounds */
276   mode_derivs_t      m_mode_derivs;
255277   UINT32              m_fill_color;           /* poly fill color */
256278   n64_tile_t          m_tiles[8];             /* texture tile state */
257279   UINT8               m_tmem[0x1000];         /* texture cache */
r248605r248606
266288struct rdp_span_aux
267289{
268290   UINT32              m_unscissored_rx;
269   UINT16              m_cvg[RDP_CVG_SPAN_MAX];
291   UINT8            m_cvg[RDP_CVG_SPAN_MAX];
270292   color_t             m_memory_color;
271293   color_t             m_pixel_color;
272294   color_t             m_inv_pixel_color;
r248605r248606
278300   color_t             m_texel0_alpha;
279301   color_t             m_texel1_color;
280302   color_t             m_texel1_alpha;
281   color_t             m_next_texel_color;
282   color_t             m_next_texel_alpha;
303   color_t             m_next_texel0_color;
304   color_t             m_next_texel0_alpha;
305   color_t             m_next_texel1_color;
306   color_t             m_next_texel1_alpha;
283307   color_t             m_blend_color;          /* constant blend color */
284308   color_t             m_prim_color;           /* flat primitive color */
285309   color_t             m_prim_alpha;           /* flat primitive alpha */
r248605r248606
300324   UINT32              m_current_cvg_bit;
301325   INT32               m_shift_a;
302326   INT32               m_shift_b;
327   INT32            m_prev_shift_a;
328   INT32            m_prev_shift_b;
329   INT32            m_prev_raw_dzmem;
303330   INT32               m_precomp_s;
304331   INT32               m_precomp_t;
305332   INT32               m_blend_enable;
r248605r248606
308335   UINT8*              m_tmem;                /* pointer to texture cache for this polygon */
309336   bool                m_start_span;
310337   rgbaint_t           m_clamp_diff[8];
338   bool            m_noise_used;
339   INT32            m_majorx[4];
340   INT32            m_minorx[4];
341   bool            m_valid_line;
342   bool            m_next_valid;
343   INT32            m_next_s;
344   INT32            m_next_t;
345   INT32            m_next_w;
346   bool            m_invalid_y[4];
347   bool            m_long_span;
348   bool            m_mid_span;
349   bool            m_almost_mid_span;
350   bool            m_end_span;
351   bool            m_pre_end_span;
352   bool            m_next_span;
311353};
312354
313355struct z_decompress_entry_t
branches/n64-angrylion/src/mame/video/rdptpipe.c
r248605r248606
5959      }
6060   }
6161
62   m_log2_table[0] = m_log2_table[1] = 0;
63   for (INT32 i = 2; i < 256; i++)
64   {
65      for (INT32 k = 7; k > 0; k--)
66      {
67         if ((i >> k) & 1)
68         {
69            m_log2_table[i] = k;
70            break;
71         }
72      }
73   }
74
6275   m_st2_add.set(1, 0, 1, 0);
6376   m_v1.set(1, 1, 1, 1);
77   m_yuv1.set(1, 0, 0, 0);
6478}
6579
80void n64_texture_pipe_t::tclod_tcclamp(INT32* sss, INT32* sst)
81{
82   INT32 temps = *sss;
83   INT32 tempt = *sst;
84
85   if (!(temps & 0x40000))
86   {
87      if (!(temps & 0x20000))
88      {
89         const INT32 tempanded = temps & 0x18000;
90         if (tempanded != 0x8000)
91         {
92            if (tempanded != 0x10000)
93            {
94               *sss &= 0xffff;
95            }
96            else
97            {
98               *sss = 0x8000;
99            }
100         }
101         else
102         {
103            *sss = 0x7fff;
104         }
105      }
106      else
107      {
108         *sss = 0x8000;
109      }
110   }
111   else
112   {
113      *sss = 0x7fff;
114   }
115
116   if (!(tempt & 0x40000))
117   {
118      if (!(tempt & 0x20000))
119      {
120         const INT32 tempanded = tempt & 0x18000;
121         if (tempanded != 0x8000)
122         {
123            if (tempanded != 0x10000)
124            {
125               *sst &= 0xffff;
126            }
127            else
128            {
129               *sst = 0x8000;
130            }
131         }
132         else
133         {
134            *sst = 0x7fff;
135         }
136      }
137      else
138      {
139         *sst = 0x8000;
140      }
141   }
142   else
143   {
144      *sst = 0x7fff;
145   }
146}
147
148void n64_texture_pipe_t::tclod_1cycle_current(INT32* sss, INT32* sst, INT32 nexts, INT32 nextt, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, rdp_span_aux* userdata, const rdp_poly_state& object)
149{
150   tclod_tcclamp(sss, sst);
151
152   if (object.m_mode_derivs.m_do_lod)
153   {
154      INT32 fars, fart, farw;
155      if (userdata->m_next_valid)
156      {
157         if (!userdata->m_end_span || !userdata->m_long_span)
158         {
159            if (!(userdata->m_pre_end_span && userdata->m_long_span) && !(userdata->m_end_span && userdata->m_mid_span))
160            {
161               fars = (s + (dsinc << 1)) >> 16;
162               fart = (t + (dtinc << 1)) >> 16;
163               farw = (w + (dwinc << 1)) >> 16;
164            }
165            else
166            {
167               fars = (s - dsinc) >> 16;
168               fart = (t - dtinc) >> 16;
169               farw = (w - dwinc) >> 16;
170            }
171         }
172         else
173         {
174            fars = (userdata->m_next_s + dsinc) >> 16;
175            fart = (userdata->m_next_t + dtinc) >> 16;
176            farw = (userdata->m_next_w + dwinc) >> 16;
177         }
178      }
179      else
180      {
181         fars = (s + (dsinc << 1)) >> 16;
182         fart = (t + (dtinc << 1)) >> 16;
183         farw = (w + (dwinc << 1)) >> 16;
184      }
185
186      if (object.m_other_modes.persp_tex_en)
187      {
188         m_rdp->tc_div(fars, fart, farw, &fars, &fart);
189      }
190      else
191      {
192         m_rdp->tc_div_no_perspective(fars, fart, farw, &fars, &fart);
193      }
194
195      const bool lodclamp = ((fars | nexts | fart | nextt) & 0x60000) ? true : false;
196
197      INT32 lod;
198      tclod_4x17_to_15(nexts, fars, nextt, fart, 0, &lod);
199
200      bool magnify, distant;
201      UINT32 l_tile;
202      lodfrac_lodtile_signals(lodclamp, lod, &l_tile, &magnify, &distant, userdata, object);
203
204      if (object.m_other_modes.tex_lod_en)
205      {
206         if (distant)
207         {
208            l_tile = object.m_misc_state.m_max_level;
209         }
210
211         if (object.m_other_modes.detail_tex_en || magnify)
212         {
213            *t1 = (prim_tile + l_tile) & 7;
214         }
215         else
216         {
217            *t1 = (prim_tile + l_tile + 1) & 7;
218         }
219      }
220   }
221}
222
223void n64_texture_pipe_t::tclod_2cycle_current(INT32* sss, INT32* sst, INT32 nexts, INT32 nextt, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2, rdp_span_aux* userdata, const rdp_poly_state& object)
224{
225   tclod_tcclamp(sss, sst);
226
227   if (object.m_mode_derivs.m_do_lod)
228   {
229      INT32 nextys = (s + object.m_span_base.m_span_dsdy) >> 16;
230      INT32 nextyt = (t + object.m_span_base.m_span_dtdy) >> 16;
231      INT32 nextyw = (w + object.m_span_base.m_span_dwdy) >> 16;
232
233      if (object.m_other_modes.persp_tex_en)
234      {
235         m_rdp->tc_div(nextys, nextyt, nextyw, &nextys, &nextyt);
236      }
237      else
238      {
239         m_rdp->tc_div_no_perspective(nextys, nextyt, nextyw, &nextys, &nextyt);
240      }
241
242      INT32 inits = *sss;
243      INT32 initt = *sst;
244      const bool lodclamp = ((inits | nexts | nextys | initt | nextt | nextyt) & 0x60000) ? true : false;
245
246      INT32 lod;
247      tclod_4x17_to_15(inits, nexts, initt, nextt, 0, &lod);
248      tclod_4x17_to_15(inits, nextys, initt, nextyt, lod, &lod);
249
250      bool magnify, distant;
251      UINT32 l_tile;
252      lodfrac_lodtile_signals(lodclamp, lod, &l_tile, &magnify, &distant, userdata, object);
253
254      if (object.m_other_modes.tex_lod_en)
255      {
256         if (distant)
257         {
258            l_tile = object.m_misc_state.m_max_level;
259         }
260
261         if (!object.m_other_modes.detail_tex_en)
262         {
263            *t1 = (prim_tile + l_tile) & 7;
264            if (!(distant || (!object.m_other_modes.sharpen_tex_en && magnify)))
265            {
266               *t2 = (*t1 + 1) & 7;
267            }
268            else
269            {
270               *t2 = *t1;
271            }
272         }
273         else
274         {
275            if (!magnify)
276            {
277               *t1 = prim_tile + l_tile + 1;
278            }
279            else
280            {
281               *t1 = prim_tile + l_tile;
282            }
283            *t1 &= 7;
284
285            if (!distant && !magnify)
286            {
287               *t2 = prim_tile + l_tile + 2;
288            }
289            else
290            {
291               *t2 = prim_tile + l_tile + 1;
292            }
293            *t2 &= 7;
294         }
295      }
296   }
297}
298
299void n64_texture_pipe_t::tclod_1cycle_next(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* pre_lod_frac, rdp_span_aux* userdata, const rdp_poly_state& object)
300{
301   tclod_tcclamp(sss, sst);
302
303   if (object.m_mode_derivs.m_do_lod)
304   {
305      INT32 nexts, nextt, nextw, fars, fart, farw;
306      if (userdata->m_next_valid)
307      {
308         if (userdata->m_next_span)
309         {
310            if (!userdata->m_end_span || !userdata->m_long_span)
311            {
312               nexts = (s + dsinc)>> 16;
313               nextt = (t + dtinc)>> 16;
314               nextw = (w + dwinc)>> 16;
315
316               if (!(userdata->m_pre_end_span && userdata->m_long_span) && !(userdata->m_end_span && userdata->m_mid_span))
317               {
318                  fars = (s + (dsinc << 1)) >> 16;
319                  fart = (t + (dtinc << 1)) >> 16;
320                  farw = (w + (dwinc << 1)) >> 16;
321               }
322               else
323               {
324                  fars = (s - dsinc) >> 16;
325                  fart = (t - dtinc) >> 16;
326                  farw = (w - dwinc) >> 16;
327               }
328            }
329            else
330            {
331               nexts = userdata->m_next_s;
332               nextt = userdata->m_next_t;
333               nextw = userdata->m_next_w;
334
335               fars = (nexts + dsinc) >> 16;
336               fart = (nextt + dtinc) >> 16;
337               farw = (nextw + dwinc) >> 16;
338
339               nexts >>= 16;
340               nextt >>= 16;
341               nextw >>= 16;
342            }
343         }
344         else
345         {
346            if (!userdata->m_almost_mid_span)
347            {
348               nexts = userdata->m_next_s + dsinc;
349               nextt = userdata->m_next_t + dtinc;
350               nextw = userdata->m_next_w + dwinc;
351
352               fars = (nexts + dsinc) >> 16;
353               fart = (nextt + dtinc) >> 16;
354               farw = (nextw + dwinc) >> 16;
355
356               nexts >>= 16;
357               nextt >>= 16;
358               nextw >>= 16;
359            }
360            else
361            {
362               nexts = (s + dsinc) >> 16;
363               nextt = (t + dtinc) >> 16;
364               nextw = (w + dwinc) >> 16;
365
366               fars = (s - dsinc) >> 16;
367               fart = (t - dtinc) >> 16;
368               farw = (w - dwinc) >> 16;
369            }
370         }
371      }
372      else
373      {
374         nexts = (s + dsinc) >> 16;
375         nextt = (t + dtinc) >> 16;
376         nextw = (w + dwinc) >> 16;
377
378         fars = (s + (dsinc << 1)) >> 16;
379         fart = (t + (dtinc << 1)) >> 16;
380         farw = (w + (dwinc << 1)) >> 16;
381      }
382
383      if (object.m_other_modes.persp_tex_en)
384      {
385         m_rdp->tc_div(fars, fart, farw, &fars, &fart);
386         m_rdp->tc_div(nexts, nextt, nextw, &nexts, &nextt);
387      }
388      else
389      {
390         m_rdp->tc_div_no_perspective(fars, fart, farw, &fars, &fart);
391         m_rdp->tc_div_no_perspective(nexts, nextt, nextw, &nexts, &nextt);
392      }
393
394      const bool lodclamp = ((fars | nexts | fart | nextt) & 0x60000) ? true : false;
395
396      INT32 lod;
397      tclod_4x17_to_15(nexts, fars, nextt, fart, 0, &lod);
398
399      if ((lod & 0x4000) || lodclamp)
400      {
401         lod = 0x7fff;
402      }
403      else if (lod < object.m_misc_state.m_min_level)
404      {
405         lod = object.m_misc_state.m_min_level;
406      }
407
408      const bool magnify = (lod < 32);
409      UINT32 l_tile = m_log2_table[(lod >> 5) & 0xff];
410      const bool distant = (lod & 0x6000) || (l_tile >= object.m_misc_state.m_max_level);
411
412      *pre_lod_frac = ((lod << 3) >> l_tile) & 0xff;
413
414      if (!object.m_other_modes.sharpen_tex_en && !object.m_other_modes.detail_tex_en)
415      {
416         if (distant)
417         {
418            *pre_lod_frac = 0xff;
419         }
420         else
421         {
422            *pre_lod_frac = 0;
423         }
424      }
425
426      if (object.m_other_modes.sharpen_tex_en && magnify)
427      {
428         *pre_lod_frac |= 0x100;
429      }
430
431      if (object.m_other_modes.tex_lod_en)
432      {
433         if (distant)
434         {
435            l_tile = object.m_misc_state.m_max_level;
436         }
437
438         if (!object.m_other_modes.detail_tex_en || magnify)
439         {
440            *t1 = (prim_tile + l_tile) & 7;
441         }
442         else
443         {
444            *t1 = (prim_tile + l_tile + 1) & 7;
445         }
446      }
447   }
448}
449
450void n64_texture_pipe_t::tclod_2cycle_next(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2, INT32* pre_lod_frac, rdp_span_aux* userdata, const rdp_poly_state& object)
451{
452   tclod_tcclamp(sss, sst);
453
454   if (object.m_mode_derivs.m_do_lod)
455   {
456      INT32 inits = *sss;
457      INT32 initt = *sst;
458
459      INT32 nexts = (s + dsinc) >> 16;
460      INT32 nextt = (t + dtinc) >> 16;
461      INT32 nextw = (w + dwinc) >> 16;
462
463      INT32 nextys = (s + object.m_span_base.m_span_dsdy) >> 16;
464      INT32 nextyt = (t + object.m_span_base.m_span_dtdy) >> 16;
465      INT32 nextyw = (w + object.m_span_base.m_span_dwdy) >> 16;
466
467      if (object.m_other_modes.persp_tex_en)
468      {
469         m_rdp->tc_div(nexts, nextt, nextw, &nexts, &nextt);
470         m_rdp->tc_div(nextys, nextyt, nextyw, &nextys, &nextyt);
471      }
472      else
473      {
474         m_rdp->tc_div_no_perspective(nexts, nextt, nextw, &nexts, &nextt);
475         m_rdp->tc_div_no_perspective(nextys, nextyt, nextyw, &nextys, &nextyt);
476      }
477
478      const bool lodclamp = ((inits | nexts | nextys | initt | nextt | nextyt) & 0x60000) ? true : false;
479
480      INT32 lod;
481      tclod_4x17_to_15(inits, nexts, initt, nextt, 0, &lod);
482      tclod_4x17_to_15(inits, nextys, initt, nextyt, lod, &lod);
483
484      if ((lod & 0x4000) || lodclamp)
485      {
486         lod = 0x7fff;
487      }
488      else if (lod < object.m_misc_state.m_min_level)
489      {
490         lod = object.m_misc_state.m_min_level;
491      }
492
493      const bool magnify = (lod < 32);
494      UINT32 l_tile = m_log2_table[(lod >> 5) & 0xff];
495      const bool distant = (lod & 0x6000) || (l_tile >= object.m_misc_state.m_max_level);
496
497      *pre_lod_frac = ((lod << 3) >> l_tile) & 0xff;
498
499      if (!object.m_other_modes.sharpen_tex_en && !object.m_other_modes.detail_tex_en)
500      {
501         if (distant)
502         {
503            *pre_lod_frac = 0xff;
504         }
505         else
506         {
507            *pre_lod_frac = 0;
508         }
509      }
510
511      if (object.m_other_modes.sharpen_tex_en && magnify)
512      {
513         *pre_lod_frac |= 0x100;
514      }
515
516      if (object.m_other_modes.tex_lod_en)
517      {
518         if (distant)
519         {
520            l_tile = object.m_misc_state.m_max_level;
521         }
522
523         if (!object.m_other_modes.detail_tex_en)
524         {
525            *t1 = (prim_tile + l_tile) & 7;
526            if (!(distant || (!object.m_other_modes.sharpen_tex_en && magnify)))
527            {
528               *t2 = (*t1 + 1) & 7;
529            }
530            else
531            {
532               *t2 = *t1;
533            }
534         }
535         else
536         {
537            if (!magnify)
538            {
539               *t1 = prim_tile + l_tile + 1;
540            }
541            else
542            {
543               *t1 = prim_tile + l_tile;
544            }
545            *t1 &= 7;
546
547            if (!distant && !magnify)
548            {
549               *t2 = prim_tile + l_tile + 2;
550            }
551            else
552            {
553               *t2 = prim_tile + l_tile + 1;
554            }
555            *t2 &= 7;
556         }
557      }
558   }
559}
560
561void n64_texture_pipe_t::lodfrac_lodtile_signals(bool lodclamp, INT32 lod, UINT32* l_tile, bool* magnify, bool* distant, rdp_span_aux* userdata, const rdp_poly_state& object)
562{
563   if ((lod & 0x4000) || lodclamp)
564   {
565      lod = 0x7fff;
566   }
567   else if (lod < object.m_misc_state.m_min_level)
568   {
569      lod = object.m_misc_state.m_min_level;
570   }
571
572   const bool mag = (lod < 32);
573   UINT32 ltil = m_log2_table[(lod >> 5) & 0xff];
574   const bool dis = (lod & 0x6000) || (ltil >= object.m_misc_state.m_max_level);
575
576   INT32 lf = ((lod << 3) >> ltil) & 0xff;
577
578   if (object.m_other_modes.sharpen_tex_en && !object.m_other_modes.detail_tex_en)
579   {
580      if (dis)
581      {
582         lf = 0xff;
583      }
584      else
585      {
586         lf = 0;
587      }
588   }
589
590   if (object.m_other_modes.sharpen_tex_en && mag)
591   {
592      lf |= 0x100;
593   }
594
595   *distant = dis;
596   *l_tile = ltil;
597   *magnify = mag;
598   userdata->m_lod_fraction.set(lf, lf, lf, lf);
599}
600
601void n64_texture_pipe_t::tclod_4x17_to_15(INT32 scurr, INT32 snext, INT32 tcurr, INT32 tnext, INT32 previous, INT32* lod)
602{
603   INT32 dels = SIGN17(snext) - SIGN17(scurr);
604   INT32 delt = SIGN17(tnext) - SIGN17(tcurr);
605   if (dels & 0x20000)
606   {
607      dels = ~dels & 0x1ffff;
608   }
609   if (delt & 0x20000)
610   {
611      delt = ~delt & 0x1ffff;
612   }
613
614   dels = (dels > delt) ? dels : delt;
615   dels = (previous > dels) ? previous : dels;
616   *lod = dels & 0x7fff;
617   if (dels & 0x1c000)
618   {
619      *lod |= 0x4000;
620   }
621}
622
66623void n64_texture_pipe_t::mask(rgbaint_t& sstt, const n64_tile_t& tile)
67624{
68625   UINT32 s_mask_bits = m_maskbits_table[tile.mask_s];
r248605r248606
197754      t0.set(*prev);
198755   }
199756
200   t0.sign_extend(0x00000100, 0xffffff00);
757   if (tile.format == FORMAT_YUV)
758   {
759      t0.sign_extend(0x00000100, 0xffffff00);
760   }
201761
202   rgbaint_t k1r(m_rdp->get_k1());
203   k1r.mul_imm(t0.get_r32());
762   rgbaint_t k13r(m_rdp->get_k13());
763   k13r.mul_imm(t0.get_r32());
204764
205   TEX->set(m_rdp->get_k023());
765   TEX->set(m_rdp->get_k02());
206766   TEX->mul_imm(t0.get_g32());
207   TEX->add(k1r);
767   TEX->add(k13r);
208768   TEX->add_imm(0x80);
209769   TEX->shr_imm(8);
210770   TEX->add_imm(t0.get_b32());
r248605r248606
224784   UINT32 tbase = tile.tmem + ((tile.line * st.get_b32()) & 0x1ff);
225785
226786   ((this)->*(m_texel_fetch[index]))(*TEX, st.get_r32(), st.get_b32(), tbase, tile.palette, userdata);
787
788   if (object.m_other_modes.convert_one && cycle)
789   {
790      const UINT32 prev_b = prev->get_b32();
791      TEX->set(prev_b, prev_b, prev_b, prev_b);
792   }
227793}
228794
229795void n64_texture_pipe_t::cycle_linear(color_t* TEX, color_t* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux* userdata, const rdp_poly_state& object)
r248605r248606
242808
243809   const UINT32 tbase = tile.tmem + ((tile.line * st.get_b32()) & 0x1ff);
244810
245   bool upper = ((stfrac.get_r32() + stfrac.get_b32()) >= 0x20);
246
247   rgbaint_t invstf;
248   if (upper)
249   {
250      invstf.set(stfrac);
251      invstf.subr_imm(0x20);
252      invstf.shl_imm(3);
253   }
254   else
255   {
256      invstf.set(0, 0, 0, 0);
257   }
258
259   stfrac.shl_imm(3);
260
261811   rgbaint_t t0;
262812   ((this)->*(m_texel_fetch[index]))(t0, st.get_r32(), st.get_b32(), tbase, tile.palette, userdata);
263813   if (object.m_other_modes.convert_one && cycle)
r248605r248606
267817
268818   t0.sign_extend(0x00000100, 0xffffff00);
269819
270   rgbaint_t k1r(m_rdp->get_k1());
271   k1r.mul_imm(t0.get_r32());
820   rgbaint_t k13r(m_rdp->get_k13());
821   k13r.mul_imm(t0.get_r32());
272822
273   TEX->set(m_rdp->get_k023());
823   TEX->set(m_rdp->get_k02());
274824   TEX->mul_imm(t0.get_g32());
275   TEX->add(k1r);
825   TEX->add(k13r);
276826   TEX->add_imm(0x80);
277827   TEX->shr_imm(8);
278828   TEX->add_imm(t0.get_b32());
r248605r248606
300850   const UINT32 tbase1 = tile.tmem + ((tile.line * sstt.get_b32()) & 0x1ff);
301851   const UINT32 tbase2 = tile.tmem + ((tile.line * sstt.get_g32()) & 0x1ff);
302852
303   bool upper = ((stfrac.get_r32() + stfrac.get_b32()) >= 0x20);
853   const UINT32 sfrac = stfrac.get_r32();
854   const UINT32 tfrac = stfrac.get_b32();
304855
305   rgbaint_t invstf;
306   if (upper)
307   {
308      invstf.set(stfrac);
309      invstf.subr_imm(0x20);
310      invstf.shl_imm(3);
311   }
312
313   stfrac.shl_imm(3);
314
315   bool center = (stfrac.get_r32() == 0x10) && (stfrac.get_b32() == 0x10) && object.m_other_modes.mid_texel;
316
317856   rgbaint_t t2;
318857   ((this)->*(m_texel_fetch[index]))(*TEX, sstt.get_a32(), sstt.get_b32(), tbase1, tpal, userdata);
319858   ((this)->*(m_texel_fetch[index]))(t2, sstt.get_r32(), sstt.get_g32(), tbase2, tpal, userdata);
320859
321   if (!center)
860   if ((sfrac != 0x10) || (tfrac != 0x10) || !object.m_other_modes.mid_texel)
322861   {
323      if (upper)
862      if ((sfrac + tfrac) >= 0x20)
324863      {
864         rgbaint_t invstf(stfrac);
865         invstf.set(stfrac);
866         invstf.subr_imm(0x20);
867         invstf.shl_imm(3);
868
325869         rgbaint_t t3;
326870         ((this)->*(m_texel_fetch[index]))(t3, sstt.get_a32(), sstt.get_g32(), tbase2, tpal, userdata);
327871
r248605r248606
338882      }
339883      else
340884      {
885         stfrac.shl_imm(3);
886
341887         rgbaint_t t0;
342888         ((this)->*(m_texel_fetch[index]))(t0, sstt.get_r32(), sstt.get_b32(), tbase1, tpal, userdata);
343889
r248605r248606
6471193
6481194void n64_texture_pipe_t::calculate_clamp_diffs(UINT32 prim_tile, rdp_span_aux* userdata, const rdp_poly_state& object)
6491195{
1196   if (userdata == NULL)
1197   {
1198      printf("Whoa, userdata is NULL!\n"); fflush(stdout);
1199   }
6501200   const n64_tile_t* tiles = object.m_tiles;
6511201   if (object.m_other_modes.cycle_type == CYCLE_TYPE_2)
6521202   {
branches/n64-angrylion/src/mame/video/rdptpipe.h
r248605r248606
9999
100100      void                copy(color_t* TEX, INT32 SSS, INT32 SST, UINT32 tilenum, const rdp_poly_state& object, rdp_span_aux* userdata);
101101      void                calculate_clamp_diffs(UINT32 prim_tile, rdp_span_aux* userdata, const rdp_poly_state& object);
102      void            tclod_tcclamp(INT32* sss, INT32* sst);
103      void            tclod_1cycle_current(INT32* sss, INT32* sst, INT32 nexts, INT32 nextt, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, rdp_span_aux* userdata, const rdp_poly_state& object);
104      void            tclod_1cycle_next(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* pre_lod_frac, rdp_span_aux* userdata, const rdp_poly_state& object);
105      void            tclod_2cycle_current(INT32* sss, INT32* sst, INT32 nexts, INT32 nextt, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2, rdp_span_aux* userdata, const rdp_poly_state& object);
106      void            tclod_2cycle_next(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2, INT32* pre_lod_frac, rdp_span_aux* userdata, const rdp_poly_state& object);
107      void            lodfrac_lodtile_signals(bool lodclamp, INT32 lod, UINT32* l_tile, bool* magnify, bool* distant, rdp_span_aux* userdata, const rdp_poly_state& object);
102108      void                lod_1cycle(INT32* sss, INT32* sst, const INT32 s, const INT32 t, const INT32 w, const INT32 dsinc, const INT32 dtinc, const INT32 dwinc, rdp_span_aux* userdata, const rdp_poly_state& object);
103109      void                lod_2cycle(INT32* sss, INT32* sst, const INT32 s, const INT32 t, const INT32 w, const INT32 dsinc, const INT32 dtinc, const INT32 dwinc, const INT32 prim_tile, INT32* t1, INT32* t2, rdp_span_aux* userdata, const rdp_poly_state& object);
104110      void                lod_2cycle_limited(INT32* sss, INT32* sst, const INT32 s, const INT32 t, INT32 w, const INT32 dsinc, const INT32 dtinc, const INT32 dwinc, const INT32 prim_tile, INT32* t1, const rdp_poly_state& object);
r248605r248606
108114      bool                m_start_span;
109115
110116   private:
117      void            tclod_4x17_to_15(INT32 scurr, INT32 snext, INT32 tcurr, INT32 tnext, INT32 previous, INT32* lod);
111118      void                mask(rgbaint_t& sstt, const n64_tile_t& tile);
112119
113120      rgbaint_t           shift_cycle(rgbaint_t& st, const n64_tile_t& tile);
r248605r248606
158165      INT32               m_maskbits_table[16];
159166      color_t             m_expand_16to32_table[0x10000];
160167      UINT16              m_lod_lookup[0x80000];
168      INT32            m_log2_table[0x100];
161169
162170      rgbaint_t           m_st2_add;
163171      rgbaint_t           m_v1;
172      rgbaint_t         m_yuv1;
164173};
165174
166175#endif // _VIDEO_RDPTEXPIPE_H_


Previous 199869 Revisions Next


© 1997-2024 The MAME Team