branches/n64-angrylion/src/mame/video/n64.c
| r248605 | r248606 | |
| 361 | 361 | |
| 362 | 362 | void n64_rdp::set_suba_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata) |
| 363 | 363 | { |
| 364 | userdata->m_noise_used = false; |
| 364 | 365 | switch (code & 0xf) |
| 365 | 366 | { |
| 366 | 367 | case 0: *input = &userdata->m_combined_color; break; |
| r248605 | r248606 | |
| 370 | 371 | case 4: *input = &userdata->m_shade_color; break; |
| 371 | 372 | case 5: *input = &userdata->m_env_color; break; |
| 372 | 373 | 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; |
| 374 | 375 | case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: |
| 375 | 376 | { |
| 376 | 377 | *input = &m_zero; break; |
| r248605 | r248606 | |
| 706 | 707 | const UINT8 yarray[16] = {0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; |
| 707 | 708 | const UINT8 xarray[16] = {0, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; |
| 708 | 709 | |
| 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 | | |
| 715 | 710 | for (INT32 i = 0; i < 0x100; i++) |
| 716 | 711 | { |
| 717 | 712 | UINT16 mask = decompress_cvmask_frombyte(i); |
| r248605 | r248606 | |
| 739 | 734 | |
| 740 | 735 | UINT16 n64_rdp::decompress_cvmask_frombyte(UINT8 x) |
| 741 | 736 | { |
| 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); |
| 745 | 738 | } |
| 746 | 739 | |
| 747 | 740 | void n64_rdp::lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy, rdp_span_aux* userdata) |
| 748 | 741 | { |
| 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; |
| 754 | 746 | } |
| 755 | 747 | |
| 756 | | void n64_rdp::z_store(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc) |
| 748 | void n64_rdp::z_store(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 dzpix_enc) |
| 757 | 749 | { |
| 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); |
| 767 | 752 | } |
| 768 | 753 | |
| 769 | 754 | INT32 n64_rdp::normalize_dzpix(INT32 sum) |
| r248605 | r248606 | |
| 776 | 761 | { |
| 777 | 762 | return 1; |
| 778 | 763 | } |
| 764 | if (sum == 1) |
| 765 | { |
| 766 | return 3; |
| 767 | } |
| 779 | 768 | for(INT32 count = 0x2000; count > 0; count >>= 1) |
| 780 | 769 | { |
| 781 | 770 | if (sum & count) |
| r248605 | r248606 | |
| 791 | 780 | return m_z_complete_dec_table[(RREADIDX16(zcurpixel) >> 2) & 0x3fff]; |
| 792 | 781 | } |
| 793 | 782 | |
| 794 | | UINT32 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 | | |
| 802 | 783 | UINT32 n64_rdp::dz_compress(UINT32 value) |
| 803 | 784 | { |
| 804 | 785 | 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 | } |
| 806 | 802 | return j; |
| 807 | 803 | } |
| 808 | 804 | |
| r248605 | r248606 | |
| 895 | 891 | if (object.m_other_modes.z_compare_en) |
| 896 | 892 | { |
| 897 | 893 | oz = z_decompress(zcurpixel); |
| 898 | | dzmem = dz_decompress(zcurpixel, dzcurpixel); |
| 899 | 894 | 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; |
| 909 | 898 | |
| 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); |
| 913 | 901 | |
| 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) |
| 919 | 903 | { |
| 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); |
| 921 | 906 | } |
| 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) |
| 924 | 911 | { |
| 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 | } |
| 926 | 926 | } |
| 927 | | if (!dzmem) |
| 928 | | { |
| 929 | | dzmem = 0xffff; |
| 930 | | } |
| 931 | | } |
| 932 | | if (dzmem > 0x8000) |
| 933 | | { |
| 934 | | dzmem = 0xffff; |
| 935 | | } |
| 936 | 927 | |
| 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; |
| 940 | 931 | |
| 941 | | bool farther = (sz + dznew) >= oz; |
| 942 | | bool infront = sz < oz; |
| 932 | bool farther = force_coplanar || (sz + dznew) >= oz; |
| 943 | 933 | |
| 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; |
| 948 | 937 | |
| 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 | } |
| 961 | 979 | } |
| 962 | | |
| 963 | | if (!object.m_other_modes.z_compare_en) |
| 980 | else |
| 964 | 981 | { |
| 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); |
| 967 | 984 | |
| 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; |
| 975 | 991 | |
| 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; |
| 986 | 995 | } |
| 987 | 996 | |
| 988 | | return false; |
| 997 | return true; |
| 989 | 998 | } |
| 990 | 999 | |
| 991 | 1000 | UINT32 n64_rdp::get_log2(UINT32 lod_clamp) |
| r248605 | r248606 | |
| 1603 | 1612 | |
| 1604 | 1613 | static UINT32 rightcvghex(UINT32 x, UINT32 fmask) |
| 1605 | 1614 | { |
| 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; |
| 1610 | 1616 | } |
| 1611 | 1617 | |
| 1612 | 1618 | static UINT32 leftcvghex(UINT32 x, UINT32 fmask) |
| 1613 | 1619 | { |
| 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; |
| 1618 | 1621 | } |
| 1619 | 1622 | |
| 1620 | | static INT32 CLIP(INT32 value,INT32 min,INT32 max) |
| 1623 | void n64_rdp::compute_cvg_noflip(rdp_span_aux* data, UINT32 lx, UINT32 rx) |
| 1621 | 1624 | { |
| 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; |
| 1635 | 1629 | |
| 1636 | | void 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) |
| 1646 | 1631 | { |
| 1647 | | if (minorxint[i] < purgestart) |
| 1648 | | { |
| 1649 | | purgestart = minorxint[i]; |
| 1650 | | } |
| 1651 | | if (majorxint[i] > purgeend) |
| 1652 | | { |
| 1653 | | purgeend = majorxint[i]; |
| 1654 | | } |
| 1632 | return; |
| 1655 | 1633 | } |
| 1656 | 1634 | |
| 1657 | | purgestart = CLIP(purgestart, 0, 1023); |
| 1658 | | purgeend = CLIP(purgeend, 0, 1023); |
| 1659 | | INT32 length = purgeend - purgestart; |
| 1635 | memset(&cvgbuf[purgestart], 0xff, length + 1); |
| 1660 | 1636 | |
| 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 | | |
| 1666 | 1637 | for(INT32 i = 0; i < 4; i++) |
| 1667 | 1638 | { |
| 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; |
| 1673 | 1642 | |
| 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]) |
| 1681 | 1644 | { |
| 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++) |
| 1683 | 1651 | { |
| 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; |
| 1692 | 1653 | } |
| 1693 | | else |
| 1654 | for (INT32 k = majorcurint; k <= purgeend; k++) |
| 1694 | 1655 | { |
| 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; |
| 1700 | 1657 | } |
| 1701 | | for (; fleft <= fright; fleft++) |
| 1658 | |
| 1659 | if (majorcurint > minorcurint) |
| 1702 | 1660 | { |
| 1703 | | userdata->m_cvg[fleft] |= fmaskshifted; |
| 1661 | cvgbuf[minorcurint] |= leftcvghex(minorcur, fmask) << maskshift; |
| 1662 | cvgbuf[majorcurint] |= rightcvghex(majorcur, fmask) << maskshift; |
| 1704 | 1663 | } |
| 1664 | else if (majorcurint == minorcurint) |
| 1665 | { |
| 1666 | INT32 samecvg = leftcvghex(minorcur, fmask) & rightcvghex(majorcur, fmask); |
| 1667 | cvgbuf[majorcurint] |= samecvg << maskshift; |
| 1668 | } |
| 1705 | 1669 | } |
| 1670 | else |
| 1671 | { |
| 1672 | for (INT32 k = purgestart; k <= purgeend; k++) |
| 1673 | { |
| 1674 | cvgbuf[k] &= ~fmaskshifted; |
| 1675 | } |
| 1676 | } |
| 1706 | 1677 | } |
| 1707 | 1678 | } |
| 1708 | 1679 | |
| 1709 | | void n64_rdp::compute_cvg_flip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base) |
| 1680 | void n64_rdp::compute_cvg_flip(rdp_span_aux* data, UINT32 lx, UINT32 rx) |
| 1710 | 1681 | { |
| 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; |
| 1715 | 1686 | |
| 1716 | | if(!writablescanline) return; |
| 1717 | | |
| 1718 | | for(INT32 i = 0; i < 4; i++) |
| 1687 | if (length < 0) |
| 1719 | 1688 | { |
| 1720 | | if (majorxint[i] < purgestart) |
| 1721 | | { |
| 1722 | | purgestart = majorxint[i]; |
| 1723 | | } |
| 1724 | | if (minorxint[i] > purgeend) |
| 1725 | | { |
| 1726 | | purgeend = minorxint[i]; |
| 1727 | | } |
| 1689 | return; |
| 1728 | 1690 | } |
| 1729 | 1691 | |
| 1730 | | purgestart = CLIP(purgestart, 0, 1023); |
| 1731 | | purgeend = CLIP(purgeend, 0, 1023); |
| 1692 | memset(&cvgbuf[purgestart], 0xff, length + 1); |
| 1732 | 1693 | |
| 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 | | |
| 1740 | 1694 | for(INT32 i = 0; i < 4; i++) |
| 1741 | 1695 | { |
| 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; |
| 1747 | 1699 | |
| 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]) |
| 1755 | 1701 | { |
| 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++) |
| 1757 | 1708 | { |
| 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; |
| 1766 | 1710 | } |
| 1767 | | else |
| 1711 | for (INT32 k = minorcurint; k <= purgeend; k++) |
| 1768 | 1712 | { |
| 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; |
| 1774 | 1714 | } |
| 1775 | | for (; fleft <= fright; fleft++) |
| 1715 | |
| 1716 | if (minorcurint > majorcurint) |
| 1776 | 1717 | { |
| 1777 | | userdata->m_cvg[fleft] |= fmaskshifted; |
| 1718 | cvgbuf[minorcurint] |= rightcvghex(minorcur, fmask) << maskshift; |
| 1719 | cvgbuf[majorcurint] |= leftcvghex(majorcur, fmask) << maskshift; |
| 1778 | 1720 | } |
| 1721 | else if (minorcurint == majorcurint) |
| 1722 | { |
| 1723 | INT32 samecvg = rightcvghex(minorcur, fmask) & leftcvghex(majorcur, fmask); |
| 1724 | cvgbuf[majorcurint] |= samecvg << maskshift; |
| 1725 | } |
| 1779 | 1726 | } |
| 1727 | else |
| 1728 | { |
| 1729 | for (INT32 k = purgestart; k <= purgeend; k++) |
| 1730 | { |
| 1731 | cvgbuf[k] &= ~fmaskshifted; |
| 1732 | } |
| 1733 | } |
| 1780 | 1734 | } |
| 1781 | 1735 | } |
| 1782 | 1736 | |
| 1737 | void 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 | |
| 1745 | void 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 | |
| 1783 | 1761 | void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect) |
| 1784 | 1762 | { |
| 1785 | 1763 | const UINT32* cmd_data = rect ? m_temp_rect_data : m_cmd_data; |
| r248605 | r248606 | |
| 1796 | 1774 | INT32 dsdxh = 0, dtdxh = 0, dwdxh = 0, drdxh = 0, dgdxh = 0, dbdxh = 0, dadxh = 0, dzdxh = 0; |
| 1797 | 1775 | INT32 dsdyh = 0, dtdyh = 0, dwdyh = 0, drdyh = 0, dgdyh = 0, dbdyh = 0, dadyh = 0, dzdyh = 0; |
| 1798 | 1776 | |
| 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 | | |
| 1804 | 1777 | INT32 shade_base = fifo_index + 8; |
| 1805 | 1778 | INT32 texture_base = fifo_index + 8; |
| 1806 | 1779 | INT32 zbuffer_base = fifo_index + 8; |
| r248605 | r248606 | |
| 1821 | 1794 | UINT32 w7 = cmd_data[fifo_index + 6]; |
| 1822 | 1795 | UINT32 w8 = cmd_data[fifo_index + 7]; |
| 1823 | 1796 | |
| 1824 | | INT32 yl = (w1 & 0x3fff); |
| 1797 | INT32 yl = w1 & 0x3fff; |
| 1825 | 1798 | 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; |
| 1830 | 1803 | // Inverse slopes in 16.16 format |
| 1831 | 1804 | INT32 dxldy = (INT32)(w4); |
| 1832 | 1805 | INT32 dxhdy = (INT32)(w6); |
| r248605 | r248606 | |
| 1873 | 1846 | const INT32 dzde = cmd_data[zbuffer_base+2]; |
| 1874 | 1847 | const INT32 dzdy = cmd_data[zbuffer_base+3]; |
| 1875 | 1848 | |
| 1876 | | const INT32 dzdy_dz = (dzdy >> 16) & 0xffff; |
| 1877 | | const INT32 dzdx_dz = (dzdx >> 16) & 0xffff; |
| 1878 | | |
| 1879 | 1849 | extent_t spans[2048]; |
| 1880 | 1850 | #ifdef MAME_DEBUG |
| 1881 | 1851 | memset(spans, 0xcc, sizeof(spans)); |
| 1882 | 1852 | #endif |
| 1883 | 1853 | |
| 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; |
| 1891 | 1857 | m_span_base.m_span_dr = drdx & ~0x1f; |
| 1892 | 1858 | m_span_base.m_span_dg = dgdx & ~0x1f; |
| 1893 | 1859 | m_span_base.m_span_db = dbdx & ~0x1f; |
| 1894 | 1860 | 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); |
| 1900 | 1882 | m_span_base.m_span_dzpix = m_dzpix_normalize[temp_dzpix & 0xffff]; |
| 1901 | 1883 | |
| 1902 | 1884 | INT32 xleft_inc = (dxmdy >> 2) & ~1; |
| r248605 | r248606 | |
| 1906 | 1888 | INT32 xleft = xm & ~1; |
| 1907 | 1889 | |
| 1908 | 1890 | const INT32 sign_dxhdy = (dxhdy & 0x80000000) ? 1 : 0; |
| 1909 | | const INT32 do_offset = !(sign_dxhdy ^ (flip)); |
| 1891 | const INT32 do_offset = !(sign_dxhdy ^ flip); |
| 1910 | 1892 | |
| 1911 | 1893 | if (do_offset) |
| 1912 | 1894 | { |
| 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; |
| 1921 | 1903 | |
| 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); |
| 1930 | 1921 | } |
| 1931 | 1922 | else |
| 1932 | 1923 | { |
| 1933 | 1924 | dsdiff = dtdiff = dwdiff = drdiff = dgdiff = dbdiff = dadiff = dzdiff = 0; |
| 1934 | 1925 | } |
| 1935 | 1926 | |
| 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 | } |
| 1944 | 1942 | |
| 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 | |
| 1945 | 1951 | const INT32 ycur = yh & ~3; |
| 1946 | | const INT32 ylfar = yl | 3; |
| 1947 | 1952 | const INT32 ldflag = (sign_dxhdy ^ flip) ? 0 : 3; |
| 1948 | | INT32 majorx[4]; |
| 1949 | | INT32 minorx[4]; |
| 1950 | | INT32 majorxint[4]; |
| 1951 | | INT32 minorxint[4]; |
| 1952 | 1953 | |
| 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; |
| 1954 | 1970 | |
| 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 | } |
| 1957 | 1984 | |
| 1958 | | // Trivial reject |
| 1959 | | if((ycur >> 2) >= clipy2 && (ylfar >> 2) >= clipy2) |
| 1985 | bool limited_yh = false; |
| 1986 | INT32 yhlimit = 0; |
| 1987 | if (yh & 0x2000) |
| 1960 | 1988 | { |
| 1961 | | return; |
| 1989 | limited_yh = false; |
| 1962 | 1990 | } |
| 1963 | | if((ycur >> 2) < clipy1 && (ylfar >> 2) < clipy1) |
| 1991 | else if (yh & 0x1000) |
| 1964 | 1992 | { |
| 1965 | | return; |
| 1993 | limited_yh = true; |
| 1966 | 1994 | } |
| 1995 | else |
| 1996 | { |
| 1997 | limited_yh = (yh >= m_scissor.m_yh); |
| 1998 | } |
| 1999 | yhlimit = limited_yh ? yh : m_scissor.m_yh; |
| 1967 | 2000 | |
| 1968 | | bool new_object = true; |
| 1969 | | rdp_poly_state* object = NULL; |
| 1970 | | bool valid = false; |
| 2001 | INT32 yhclose = yhlimit & ~3; |
| 1971 | 2002 | |
| 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; |
| 1976 | 2005 | |
| 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 |
| 1977 | 2333 | for (INT32 k = ycur; k <= ylfar; k++) |
| 1978 | 2334 | { |
| 1979 | 2335 | if (k == ym) |
| r248605 | r248606 | |
| 2018 | 2374 | |
| 2019 | 2375 | if (spix == 0) |
| 2020 | 2376 | { |
| 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); |
| 2029 | 2377 | valid = true; |
| 2030 | | m_aux_buf_ptr += sizeof(rdp_span_aux); |
| 2031 | 2378 | |
| 2032 | 2379 | if(m_aux_buf_ptr >= EXTENT_AUX_COUNT) |
| 2033 | 2380 | { |
| r248605 | r248606 | |
| 2077 | 2424 | { |
| 2078 | 2425 | spans[spanidx].startx = *startx; |
| 2079 | 2426 | 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))); |
| 2081 | 2429 | } |
| 2082 | 2430 | |
| 2083 | 2431 | if (spix == ldflag) |
| r248605 | r248606 | |
| 2109 | 2457 | xleft += xleft_inc; |
| 2110 | 2458 | xright += xright_inc; |
| 2111 | 2459 | } |
| 2460 | #endif |
| 2112 | 2461 | |
| 2113 | | if(!new_object && valid) |
| 2462 | if(anyvalid) |
| 2114 | 2463 | { |
| 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); |
| 2116 | 2465 | } |
| 2117 | 2466 | |
| 2118 | 2467 | //wait("draw_triangle"); |
| r248605 | r248606 | |
| 2337 | 2686 | k2 = (SIGN9(k2) << 1) + 1; |
| 2338 | 2687 | k3 = (SIGN9(k3) << 1) + 1; |
| 2339 | 2688 | |
| 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)); |
| 2341 | 2690 | } |
| 2342 | 2691 | |
| 2343 | 2692 | void n64_rdp::cmd_set_scissor(UINT32 w1, UINT32 w2) |
| 2344 | 2693 | { |
| 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; |
| 2349 | 2698 | |
| 2350 | | // TODO: handle f & o? |
| 2699 | m_scissor.m_field = (w2 >> 25) & 1; |
| 2700 | m_scissor.m_keep_odd = (w2 >> 24) & 1; |
| 2351 | 2701 | } |
| 2352 | 2702 | |
| 2353 | 2703 | void n64_rdp::cmd_set_prim_depth(UINT32 w1, UINT32 w2) |
| r248605 | r248606 | |
| 2827 | 3177 | ewdata[0] = (0x3680 << 16) | yl;//command, flipped, tile, yl |
| 2828 | 3178 | ewdata[1] = (yl << 16) | yh;//ym, yh |
| 2829 | 3179 | ewdata[2] = (xlint << 16) | ((xl & 3) << 14);//xl, xl frac |
| 2830 | | ewdata[3] = 0;//dxldy, dxldy frac |
| 2831 | 3180 | ewdata[4] = (xhint << 16) | ((xh & 3) << 14);//xh, xh frac |
| 2832 | | ewdata[5] = 0;//dxhdy, dxhdy frac |
| 2833 | 3181 | ewdata[6] = (xlint << 16) | ((xl & 3) << 14);//xm, xm frac |
| 2834 | | ewdata[7] = 0;//dxmdy, dxmdy frac |
| 2835 | 3182 | memset(&ewdata[8], 0, 36 * sizeof(UINT32));//shade, texture, depth |
| 2836 | 3183 | |
| 2837 | 3184 | draw_triangle(false, false, false, true); |
| r248605 | r248606 | |
| 3211 | 3558 | |
| 3212 | 3559 | void n64_rdp::render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object) |
| 3213 | 3560 | { |
| 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; |
| 3216 | 3563 | INT32 offset = 0; |
| 3217 | 3564 | |
| 3218 | 3565 | if (clipy2 <= 0) |
| r248605 | r248606 | |
| 3244 | 3591 | memcpy(&object->m_other_modes, &m_other_modes, sizeof(other_modes_t)); |
| 3245 | 3592 | memcpy(&object->m_span_base, &m_span_base, sizeof(span_base_t)); |
| 3246 | 3593 | memcpy(&object->m_scissor, &m_scissor, sizeof(rectangle_t)); |
| 3594 | memcpy(&object->m_mode_derivs, &m_mode_derivs, sizeof(mode_derivs_t)); |
| 3247 | 3595 | memcpy(&object->m_tiles, &m_tiles, 8 * sizeof(n64_tile_t)); |
| 3248 | 3596 | object->tilenum = tilenum; |
| 3249 | 3597 | object->flip = flip; |
| 3250 | 3598 | object->m_fill_color = m_fill_color; |
| 3251 | 3599 | object->rect = rect; |
| 3252 | 3600 | |
| 3601 | //printf("%d", m_other_modes.cycle_type); |
| 3253 | 3602 | switch(m_other_modes.cycle_type) |
| 3254 | 3603 | { |
| 3255 | 3604 | case CYCLE_TYPE_1: |
| 3605 | //printf("%d, %d\n", start, end); |
| 3256 | 3606 | render_triangle_custom(m_visarea, render_delegate(FUNC(n64_rdp::span_draw_1cycle), this), start, (end - start) + 1, spans + offset); |
| 3257 | 3607 | break; |
| 3258 | 3608 | |
| r248605 | r248606 | |
| 3271 | 3621 | //wait(); |
| 3272 | 3622 | } |
| 3273 | 3623 | |
| 3274 | | void n64_rdp::rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata) |
| 3624 | void 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) |
| 3275 | 3625 | { |
| 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 | | |
| 3293 | | void 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 | | { |
| 3295 | 3626 | if (userdata->m_current_pix_cvg == 8) |
| 3296 | 3627 | { |
| 3297 | 3628 | *r >>= 2; |
| 3298 | 3629 | *g >>= 2; |
| 3299 | 3630 | *b >>= 2; |
| 3300 | 3631 | *a >>= 2; |
| 3301 | | *z = (*z >> 3) & 0x7ffff; |
| 3632 | *z >>= 3; |
| 3302 | 3633 | } |
| 3303 | 3634 | else |
| 3304 | 3635 | { |
| 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; |
| 3313 | 3641 | |
| 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 | } |
| 3316 | 3648 | |
| 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; |
| 3322 | 3661 | } |
| 3323 | 3662 | } |
| 3324 | 3663 | |
| r248605 | r248606 | |
| 3502 | 3841 | { |
| 3503 | 3842 | assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4); |
| 3504 | 3843 | |
| 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 | | |
| 3510 | 3844 | span_param_t r; r.w = extent.param[SPAN_R].start; |
| 3511 | 3845 | span_param_t g; g.w = extent.param[SPAN_G].start; |
| 3512 | 3846 | span_param_t b; b.w = extent.param[SPAN_B].start; |
| r248605 | r248606 | |
| 3526 | 3860 | #endif |
| 3527 | 3861 | rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata; |
| 3528 | 3862 | |
| 3529 | | m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object); |
| 3863 | if (!userdata->m_valid_line) |
| 3864 | { |
| 3865 | return; |
| 3866 | } |
| 3530 | 3867 | |
| 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; |
| 3533 | 3872 | |
| 3873 | const bool flip = object.flip; |
| 3874 | |
| 3534 | 3875 | INT32 drinc, dginc, dbinc, dainc; |
| 3535 | 3876 | INT32 dzinc, dzpix; |
| 3536 | 3877 | INT32 dsinc, dtinc, dwinc; |
| r248605 | r248606 | |
| 3561 | 3902 | xinc = 1; |
| 3562 | 3903 | } |
| 3563 | 3904 | |
| 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 | |
| 3564 | 3922 | const INT32 fb_index = object.m_misc_state.m_fb_width * scanline; |
| 3565 | 3923 | |
| 3566 | 3924 | const INT32 xstart = extent.startx; |
| 3567 | 3925 | const INT32 xend = userdata->m_unscissored_rx; |
| 3568 | 3926 | const INT32 xend_scissored = extent.stopx; |
| 3569 | 3927 | |
| 3570 | | INT32 x = xend; |
| 3928 | INT32 x = xend_scissored; |
| 3571 | 3929 | |
| 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) |
| 3575 | 3932 | { |
| 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; |
| 3579 | 3936 | } |
| 3580 | 3937 | else |
| 3581 | 3938 | { |
| 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; |
| 3583 | 3942 | } |
| 3584 | 3943 | |
| 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 | |
| 3585 | 3956 | if (object.m_misc_state.m_fb_size < 2 || object.m_misc_state.m_fb_size > 4) |
| 3586 | 3957 | fatalerror("unsupported m_fb_size %d\n", object.m_misc_state.m_fb_size); |
| 3587 | 3958 | |
| r248605 | r248606 | |
| 3591 | 3962 | INT32 sss = 0; |
| 3592 | 3963 | INT32 sst = 0; |
| 3593 | 3964 | |
| 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; |
| 3602 | 3967 | |
| 3603 | 3968 | 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 | |
| 3604 | 3975 | for (INT32 j = 0; j <= length; j++) |
| 3605 | 3976 | { |
| 3606 | 3977 | INT32 sr = r.w >> 14; |
| 3607 | 3978 | INT32 sg = g.w >> 14; |
| 3608 | 3979 | INT32 sb = b.w >> 14; |
| 3609 | 3980 | INT32 sa = a.w >> 14; |
| 3981 | INT32 ss = s.w >> 16; |
| 3982 | INT32 st = t.w >> 16; |
| 3983 | INT32 sw = w.w >> 16; |
| 3610 | 3984 | INT32 sz = (z.w >> 10) & 0x3fffff; |
| 3611 | | const bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored); |
| 3612 | 3985 | |
| 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) |
| 3614 | 3993 | { |
| 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 | } |
| 3617 | 4004 | |
| 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 | } |
| 3619 | 4013 | |
| 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 | } |
| 3622 | 4030 | |
| 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 | |
| 3623 | 4033 | ((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); |
| 3626 | 4034 | |
| 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 | { |
| 3627 | 4057 | const UINT8 noise = rand() << 3; // Not accurate |
| 3628 | 4058 | userdata->m_noise_color.set(0, noise, noise, noise); |
| 4059 | } |
| 3629 | 4060 | |
| 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]); |
| 3634 | 4065 | |
| 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]); |
| 3639 | 4070 | |
| 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); |
| 3643 | 4074 | |
| 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); |
| 3651 | 4082 | |
| 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)); |
| 3653 | 4085 | |
| 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; |
| 3656 | 4089 | |
| 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); |
| 3660 | 4092 | |
| 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); |
| 3662 | 4098 | |
| 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) |
| 3664 | 4103 | { |
| 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) |
| 3673 | 4106 | { |
| 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); |
| 3679 | 4108 | } |
| 3680 | 4109 | } |
| 3681 | | |
| 3682 | | sss = userdata->m_precomp_s; |
| 3683 | | sst = userdata->m_precomp_t; |
| 3684 | 4110 | } |
| 3685 | 4111 | |
| 4112 | sss = userdata->m_precomp_s; |
| 4113 | sst = userdata->m_precomp_t; |
| 4114 | |
| 3686 | 4115 | r.w += drinc; |
| 3687 | 4116 | g.w += dginc; |
| 3688 | 4117 | b.w += dbinc; |
| 3689 | 4118 | a.w += dainc; |
| 3690 | | s.w += dsinc; |
| 3691 | | t.w += dtinc; |
| 3692 | | w.w += dwinc; |
| 3693 | 4119 | z.w += dzinc; |
| 3694 | 4120 | |
| 3695 | 4121 | x += xinc; |
| r248605 | r248606 | |
| 3700 | 4126 | { |
| 3701 | 4127 | assert(object.m_misc_state.m_fb_size >= 2 && object.m_misc_state.m_fb_size < 4); |
| 3702 | 4128 | |
| 3703 | | const INT32 clipx1 = object.m_scissor.m_xh; |
| 3704 | | const INT32 clipx2 = object.m_scissor.m_xl; |
| 3705 | 4129 | const INT32 tilenum = object.tilenum; |
| 3706 | 4130 | const bool flip = object.flip; |
| 3707 | 4131 | |
| r248605 | r248606 | |
| 3722 | 4146 | const UINT32 prim_tile = tilenum; |
| 3723 | 4147 | |
| 3724 | 4148 | INT32 newtile1 = tile1; |
| 3725 | | INT32 news = 0; |
| 3726 | | INT32 newt = 0; |
| 4149 | INT32 newtile2 = tile2; |
| 3727 | 4150 | |
| 3728 | 4151 | #ifdef PTR64 |
| 3729 | 4152 | assert(extent.userdata != (const void *)0xcccccccccccccccc); |
| r248605 | r248606 | |
| 3779 | 4202 | |
| 3780 | 4203 | INT32 x = xend; |
| 3781 | 4204 | |
| 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 | } |
| 3783 | 4218 | |
| 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 | |
| 3784 | 4231 | if(object.m_other_modes.z_source_sel) |
| 3785 | 4232 | { |
| 3786 | 4233 | z.w = object.m_misc_state.m_primitive_z; |
| r248605 | r248606 | |
| 3802 | 4249 | INT32 sss = 0; |
| 3803 | 4250 | INT32 sst = 0; |
| 3804 | 4251 | |
| 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; |
| 3813 | 4254 | |
| 3814 | 4255 | 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 | |
| 3815 | 4264 | for (INT32 j = 0; j <= length; j++) |
| 3816 | 4265 | { |
| 3817 | 4266 | INT32 sr = r.w >> 14; |
| 3818 | 4267 | INT32 sg = g.w >> 14; |
| 3819 | 4268 | INT32 sb = b.w >> 14; |
| 3820 | 4269 | INT32 sa = a.w >> 14; |
| 4270 | INT32 ss = s.w >> 16; |
| 4271 | INT32 st = t.w >> 16; |
| 4272 | INT32 sw = w.w >> 16; |
| 3821 | 4273 | INT32 sz = (z.w >> 10) & 0x3fffff; |
| 3822 | | color_t c1; |
| 3823 | | color_t c2; |
| 3824 | 4274 | |
| 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)); |
| 3826 | 4277 | |
| 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) |
| 3828 | 4286 | { |
| 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 | } |
| 3835 | 4293 | |
| 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 | } |
| 3837 | 4312 | |
| 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); |
| 3841 | 4314 | |
| 3842 | | rgbaz_correct_triangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object); |
| 3843 | | rgbaz_clip(sr, sg, sb, sa, &sz, userdata); |
| 3844 | | |
| 3845 | 4315 | ((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tile1, 0, userdata, object); |
| 3846 | 4316 | ((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); |
| 3848 | 4317 | |
| 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 | } |
| 3855 | 4320 | |
| 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 | { |
| 3856 | 4334 | const UINT8 noise = rand() << 3; // Not accurate |
| 3857 | 4335 | userdata->m_noise_color.set(0, noise, noise, noise); |
| 4336 | } |
| 3858 | 4337 | |
| 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]); |
| 3863 | 4342 | |
| 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]); |
| 3868 | 4347 | |
| 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); |
| 3872 | 4351 | |
| 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); |
| 3876 | 4355 | |
| 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); |
| 3881 | 4360 | |
| 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); |
| 3885 | 4364 | |
| 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); |
| 3890 | 4369 | |
| 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]); |
| 3895 | 4374 | |
| 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]); |
| 3900 | 4379 | |
| 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); |
| 3904 | 4383 | |
| 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); |
| 3912 | 4391 | |
| 3913 | | userdata->m_pixel_color.set(rgbsub_a); |
| 4392 | userdata->m_pixel_color.set(rgbsub_a); |
| 3914 | 4393 | |
| 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)); |
| 3917 | 4396 | |
| 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; |
| 3921 | 4400 | |
| 3922 | | read_pixel(curpixel, userdata, object); |
| 4401 | read_pixel(curpixel, userdata, object); |
| 3923 | 4402 | |
| 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); |
| 3927 | 4406 | |
| 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); |
| 3930 | 4409 | |
| 3931 | | if (rendered) |
| 4410 | if (rendered) |
| 4411 | { |
| 4412 | write_pixel(curpixel, blended_pixel, userdata, object); |
| 4413 | if (object.m_other_modes.z_update_en) |
| 3932 | 4414 | { |
| 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); |
| 3938 | 4416 | } |
| 3939 | 4417 | } |
| 3940 | | sss = userdata->m_precomp_s; |
| 3941 | | sst = userdata->m_precomp_t; |
| 3942 | 4418 | } |
| 4419 | sss = userdata->m_precomp_s; |
| 4420 | sst = userdata->m_precomp_t; |
| 3943 | 4421 | |
| 3944 | 4422 | r.w += drinc; |
| 3945 | 4423 | g.w += dginc; |
| r248605 | r248606 | |
| 3956 | 4434 | |
| 3957 | 4435 | void n64_rdp::span_draw_copy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid) |
| 3958 | 4436 | { |
| 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; |
| 3961 | 4439 | const INT32 tilenum = object.tilenum; |
| 3962 | 4440 | const bool flip = object.flip; |
| 3963 | 4441 | |
| 3964 | 4442 | rdp_span_aux* userdata = (rdp_span_aux*)extent.userdata; |
| 4443 | |
| 3965 | 4444 | const INT32 xstart = extent.startx; |
| 3966 | 4445 | const INT32 xend = userdata->m_unscissored_rx; |
| 3967 | 4446 | const INT32 xend_scissored = extent.stopx; |
| r248605 | r248606 | |
| 4009 | 4488 | |
| 4010 | 4489 | const bool flip = object.flip; |
| 4011 | 4490 | |
| 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; |
| 4014 | 4493 | |
| 4015 | 4494 | const INT32 xinc = flip ? 1 : -1; |
| 4016 | 4495 | |
branches/n64-angrylion/src/mame/video/rdptpipe.c
| r248605 | r248606 | |
| 59 | 59 | } |
| 60 | 60 | } |
| 61 | 61 | |
| 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 | |
| 62 | 75 | m_st2_add.set(1, 0, 1, 0); |
| 63 | 76 | m_v1.set(1, 1, 1, 1); |
| 77 | m_yuv1.set(1, 0, 0, 0); |
| 64 | 78 | } |
| 65 | 79 | |
| 80 | void 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 | |
| 148 | void 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 | |
| 223 | void 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 | |
| 299 | void 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 | |
| 450 | void 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 | |
| 561 | void 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 | |
| 601 | void 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 | |
| 66 | 623 | void n64_texture_pipe_t::mask(rgbaint_t& sstt, const n64_tile_t& tile) |
| 67 | 624 | { |
| 68 | 625 | UINT32 s_mask_bits = m_maskbits_table[tile.mask_s]; |
| r248605 | r248606 | |
| 197 | 754 | t0.set(*prev); |
| 198 | 755 | } |
| 199 | 756 | |
| 200 | | t0.sign_extend(0x00000100, 0xffffff00); |
| 757 | if (tile.format == FORMAT_YUV) |
| 758 | { |
| 759 | t0.sign_extend(0x00000100, 0xffffff00); |
| 760 | } |
| 201 | 761 | |
| 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()); |
| 204 | 764 | |
| 205 | | TEX->set(m_rdp->get_k023()); |
| 765 | TEX->set(m_rdp->get_k02()); |
| 206 | 766 | TEX->mul_imm(t0.get_g32()); |
| 207 | | TEX->add(k1r); |
| 767 | TEX->add(k13r); |
| 208 | 768 | TEX->add_imm(0x80); |
| 209 | 769 | TEX->shr_imm(8); |
| 210 | 770 | TEX->add_imm(t0.get_b32()); |
| r248605 | r248606 | |
| 224 | 784 | UINT32 tbase = tile.tmem + ((tile.line * st.get_b32()) & 0x1ff); |
| 225 | 785 | |
| 226 | 786 | ((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 | } |
| 227 | 793 | } |
| 228 | 794 | |
| 229 | 795 | void 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) |
| r248605 | r248606 | |
| 242 | 808 | |
| 243 | 809 | const UINT32 tbase = tile.tmem + ((tile.line * st.get_b32()) & 0x1ff); |
| 244 | 810 | |
| 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 | | |
| 261 | 811 | rgbaint_t t0; |
| 262 | 812 | ((this)->*(m_texel_fetch[index]))(t0, st.get_r32(), st.get_b32(), tbase, tile.palette, userdata); |
| 263 | 813 | if (object.m_other_modes.convert_one && cycle) |
| r248605 | r248606 | |
| 267 | 817 | |
| 268 | 818 | t0.sign_extend(0x00000100, 0xffffff00); |
| 269 | 819 | |
| 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()); |
| 272 | 822 | |
| 273 | | TEX->set(m_rdp->get_k023()); |
| 823 | TEX->set(m_rdp->get_k02()); |
| 274 | 824 | TEX->mul_imm(t0.get_g32()); |
| 275 | | TEX->add(k1r); |
| 825 | TEX->add(k13r); |
| 276 | 826 | TEX->add_imm(0x80); |
| 277 | 827 | TEX->shr_imm(8); |
| 278 | 828 | TEX->add_imm(t0.get_b32()); |
| r248605 | r248606 | |
| 300 | 850 | const UINT32 tbase1 = tile.tmem + ((tile.line * sstt.get_b32()) & 0x1ff); |
| 301 | 851 | const UINT32 tbase2 = tile.tmem + ((tile.line * sstt.get_g32()) & 0x1ff); |
| 302 | 852 | |
| 303 | | bool upper = ((stfrac.get_r32() + stfrac.get_b32()) >= 0x20); |
| 853 | const UINT32 sfrac = stfrac.get_r32(); |
| 854 | const UINT32 tfrac = stfrac.get_b32(); |
| 304 | 855 | |
| 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 | | |
| 317 | 856 | rgbaint_t t2; |
| 318 | 857 | ((this)->*(m_texel_fetch[index]))(*TEX, sstt.get_a32(), sstt.get_b32(), tbase1, tpal, userdata); |
| 319 | 858 | ((this)->*(m_texel_fetch[index]))(t2, sstt.get_r32(), sstt.get_g32(), tbase2, tpal, userdata); |
| 320 | 859 | |
| 321 | | if (!center) |
| 860 | if ((sfrac != 0x10) || (tfrac != 0x10) || !object.m_other_modes.mid_texel) |
| 322 | 861 | { |
| 323 | | if (upper) |
| 862 | if ((sfrac + tfrac) >= 0x20) |
| 324 | 863 | { |
| 864 | rgbaint_t invstf(stfrac); |
| 865 | invstf.set(stfrac); |
| 866 | invstf.subr_imm(0x20); |
| 867 | invstf.shl_imm(3); |
| 868 | |
| 325 | 869 | rgbaint_t t3; |
| 326 | 870 | ((this)->*(m_texel_fetch[index]))(t3, sstt.get_a32(), sstt.get_g32(), tbase2, tpal, userdata); |
| 327 | 871 | |
| r248605 | r248606 | |
| 338 | 882 | } |
| 339 | 883 | else |
| 340 | 884 | { |
| 885 | stfrac.shl_imm(3); |
| 886 | |
| 341 | 887 | rgbaint_t t0; |
| 342 | 888 | ((this)->*(m_texel_fetch[index]))(t0, sstt.get_r32(), sstt.get_b32(), tbase1, tpal, userdata); |
| 343 | 889 | |
| r248605 | r248606 | |
| 647 | 1193 | |
| 648 | 1194 | void n64_texture_pipe_t::calculate_clamp_diffs(UINT32 prim_tile, rdp_span_aux* userdata, const rdp_poly_state& object) |
| 649 | 1195 | { |
| 1196 | if (userdata == NULL) |
| 1197 | { |
| 1198 | printf("Whoa, userdata is NULL!\n"); fflush(stdout); |
| 1199 | } |
| 650 | 1200 | const n64_tile_t* tiles = object.m_tiles; |
| 651 | 1201 | if (object.m_other_modes.cycle_type == CYCLE_TYPE_2) |
| 652 | 1202 | { |