Checkpoint

This commit is contained in:
therealmogminer@gmail.com 2015-06-17 22:49:07 +02:00
parent ac5a98e8f3
commit 70a4871beb
11 changed files with 724 additions and 748 deletions

View File

@ -84,11 +84,6 @@ void rgbint_t::set_rgb(INT32 r, INT32 g, INT32 b)
m_value = _mm_set_epi32(0, r, g, b);
}
void rgbaint_t::set_rgba(INT32 a, INT32 r, INT32 g, INT32 b)
{
m_value = _mm_set_epi32(a, r, g, b);
}
/***************************************************************************
OPERATORS
***************************************************************************/
@ -142,7 +137,7 @@ rgbint_t& rgbint_t::operator>>=(const INT32 shift)
rgb_t rgbint_t::to_rgb()
{
__m128i anded = _mm_and_si128(m_value, _mm_set_epi32(0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff));
__m128i anded = _mm_and_si128(m_value, _mm_set1_epi32(0x000000ff));
return _mm_cvtsi128_si32(_mm_packus_epi16(_mm_packs_epi32(anded, anded), _mm_setzero_si128()));
}
@ -165,17 +160,6 @@ rgb_t rgbint_t::to_rgba_clamp()
CORE MATH
***************************************************************************/
void rgbint_t::add(const rgbint_t& color2)
{
m_value = _mm_add_epi32(m_value, color2.m_value);
}
void rgbint_t::add_imm(const INT32 imm)
{
__m128i temp = _mm_set_epi32(imm, imm, imm, imm);
m_value = _mm_add_epi32(m_value, temp);
}
void rgbint_t::add_imm_rgb(const INT32 r, const INT32 g, const INT32 b)
{
__m128i temp = _mm_set_epi32(0, r, g, b);
@ -188,11 +172,6 @@ void rgbaint_t::add_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const
m_value = _mm_add_epi32(m_value, temp);
}
inline void rgbint_t::sub(const rgbint_t& color2)
{
m_value = _mm_sub_epi32(m_value, color2.m_value);
}
void rgbint_t::sub_imm(const INT32 imm)
{
__m128i temp = _mm_set_epi32(imm, imm, imm, imm);
@ -234,31 +213,16 @@ void rgbaint_t::subr_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const
m_value = _mm_sub_epi32(temp, m_value);
}
void rgbint_t::mul(rgbint_t& color)
{
__m128i tmp1 = _mm_mul_epu32(m_value, color.m_value);
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(m_value, 4), _mm_srli_si128(color.m_value, 4));
m_value = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0)));
}
void rgbint_t::print()
{
printf("%04x ", _mm_extract_epi16(m_value, 0));
printf("%04x ", _mm_extract_epi16(m_value, 1));
printf("%04x ", _mm_extract_epi16(m_value, 2));
printf("%04x ", _mm_extract_epi16(m_value, 3));
printf("%04x ", _mm_extract_epi16(m_value, 4));
printf("%04x ", _mm_extract_epi16(m_value, 5));
printf("%04x ", _mm_extract_epi16(m_value, 7));
printf("%04x ", _mm_extract_epi16(m_value, 6));
printf("%04x\n", _mm_extract_epi16(m_value, 7));
}
void rgbint_t::mul_imm(const INT32 imm)
{
__m128i immv = _mm_set1_epi32(imm);
__m128i tmp1 = _mm_mul_epu32(m_value, immv);
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(m_value, 4), _mm_srli_si128(immv, 4));
m_value = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0)));
printf("%04x ", _mm_extract_epi16(m_value, 5));
printf("%04x ", _mm_extract_epi16(m_value, 4));
printf("%04x ", _mm_extract_epi16(m_value, 3));
printf("%04x ", _mm_extract_epi16(m_value, 2));
printf("%04x ", _mm_extract_epi16(m_value, 1));
printf("%04x\n", _mm_extract_epi16(m_value, 0));
}
void rgbint_t::mul_imm_rgb(const INT32 r, const INT32 g, const INT32 b)
@ -277,28 +241,6 @@ void rgbaint_t::mul_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const
m_value = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0)));
}
void rgbint_t::shl(UINT8 shift)
{
m_value = _mm_slli_epi32(m_value, shift);
}
void rgbint_t::shr(UINT8 shift)
{
m_value = _mm_srli_epi32(m_value, shift);
}
void rgbint_t::sra(UINT8 shift)
{
m_value = _mm_srai_epi32(m_value, shift);
}
void rgbint_t::sign_extend(const INT32 compare, const INT32 sign)
{
__m128i compare_vec = _mm_set1_epi32(compare);
__m128i compare_mask = _mm_cmpeq_epi32(_mm_and_si128(m_value, compare_vec), compare_vec);
m_value = _mm_or_si128(m_value, _mm_and_si128(_mm_set1_epi32(sign), compare_mask));
}
/***************************************************************************
HIGHER LEVEL OPERATIONS
***************************************************************************/

View File

@ -15,6 +15,21 @@
#include <emmintrin.h>
/***************************************************************************
TABLES
***************************************************************************/
extern const struct _rgbsse_statics
{
__m128 dummy_for_alignment;
INT16 maxbyte[8];
INT16 alpha_mask[8];
INT16 red_mask[8];
INT16 green_mask[8];
INT16 blue_mask[8];
INT16 scale_table[256][8];
} rgbsse_statics;
/***************************************************************************
TYPE DEFINITIONS
***************************************************************************/
@ -34,17 +49,33 @@ public:
void set_rgb(INT32 r, INT32 g, INT32 b);
void set_rgb(rgb_t& rgb);
inline void set(rgbint_t& other)
{
m_value = other.m_value;
}
rgb_t to_rgb();
rgb_t to_rgb_clamp();
rgb_t to_rgba();
rgb_t to_rgba_clamp();
void add(const rgbint_t& color2);
void add_imm(const INT32 imm);
inline void add(const rgbint_t& color2)
{
m_value = _mm_add_epi32(m_value, color2.m_value);
}
inline void add_imm(const INT32 imm)
{
__m128i temp = _mm_set_epi32(imm, imm, imm, imm);
m_value = _mm_add_epi32(m_value, temp);
}
void add_imm_rgb(const INT32 r, const INT32 g, const INT32 b);
void sub(const rgbint_t& color2);
inline void sub(const rgbint_t& color2)
{
m_value = _mm_sub_epi32(m_value, color2.m_value);
}
void sub_imm(const INT32 imm);
void sub_imm_rgb(const INT32 r, const INT32 g, const INT32 b);
@ -52,13 +83,124 @@ public:
void subr_imm(const INT32 imm);
void subr_imm_rgb(const INT32 r, const INT32 g, const INT32 b);
void mul(rgbint_t& color);
void mul_imm(const INT32 imm);
inline void set_r(const INT32 value)
{
m_value = _mm_or_si128(_mm_and_si128(m_value, *(__m128i *)&rgbsse_statics.red_mask), _mm_set_epi32(0, value, 0, 0));
}
inline void set_g(const INT32 value)
{
m_value = _mm_or_si128(_mm_and_si128(m_value, *(__m128i *)&rgbsse_statics.green_mask), _mm_set_epi32(0, 0, value, 0));
}
inline void set_b(const INT32 value)
{
m_value = _mm_or_si128(_mm_and_si128(m_value, *(__m128i *)&rgbsse_statics.blue_mask), _mm_set_epi32(0, 0, 0, value));
}
inline UINT8 get_r()
{
return _mm_extract_epi16(m_value, 4) & 0xff;
}
inline UINT8 get_g()
{
return _mm_extract_epi16(m_value, 2) & 0xff;
}
inline UINT8 get_b()
{
return _mm_extract_epi16(m_value, 0) & 0xff;
}
inline UINT16 get_r32()
{
return _mm_extract_epi16(m_value, 4);
}
inline UINT16 get_g32()
{
return _mm_extract_epi16(m_value, 2);
}
inline UINT16 get_b32()
{
return _mm_extract_epi16(m_value, 0);
}
inline void mul(rgbint_t& color)
{
__m128i tmp1 = _mm_mul_epu32(m_value, color.m_value);
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(m_value, 4), _mm_srli_si128(color.m_value, 4));
m_value = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0)));
}
inline void mul_imm(const INT32 imm)
{
__m128i immv = _mm_set1_epi32(imm);
__m128i tmp1 = _mm_mul_epu32(m_value, immv);
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(m_value, 4), _mm_srli_si128(immv, 4));
m_value = _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE(0, 0, 2, 0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE(0, 0, 2, 0)));
}
void mul_imm_rgb(const INT32 r, const INT32 g, const INT32 b);
void shl(const UINT8 shift);
void shr(const UINT8 shift);
void sra(const UINT8 shift);
inline void shl(const UINT8 shift)
{
m_value = _mm_slli_epi32(m_value, shift);
}
inline void shr(const UINT8 shift)
{
m_value = _mm_srli_epi32(m_value, shift);
}
inline void sra(const UINT8 shift)
{
m_value = _mm_srai_epi32(m_value, shift);
}
inline void or_reg(const rgbint_t& color2)
{
m_value = _mm_or_si128(m_value, color2.m_value);
}
inline void or_imm(const INT32 value)
{
m_value = _mm_or_si128(m_value, _mm_set1_epi32(value));
}
inline void and_reg(const rgbint_t& color)
{
m_value = _mm_and_si128(m_value, color.m_value);
}
inline void and_imm(const INT32 value)
{
m_value = _mm_and_si128(m_value, _mm_set1_epi32(value));
}
inline void and_imm_rgb(const INT32 r, const INT32 g, const INT32 b)
{
m_value = _mm_and_si128(m_value, _mm_set_epi32(0xffffffff, r, g, b));
}
inline void clamp_and_clear(const rgbint_t& color, const INT32 sign)
{
__m128i vsign = _mm_set1_epi32(sign);
m_value = _mm_and_si128(color.m_value, _mm_cmpeq_epi32(_mm_and_si128(color.m_value, vsign), _mm_setzero_si128()));
vsign = _mm_srai_epi32(vsign, 1);
vsign = _mm_xor_si128(vsign, _mm_set1_epi32(0xffffffff));
__m128i mask = _mm_cmpgt_epi32(m_value, vsign); // m_value > vsign ? 0xffffffff : 0
m_value = _mm_or_si128(_mm_and_si128(vsign, mask), _mm_and_si128(m_value, _mm_xor_si128(mask, _mm_set1_epi32(0xffffffff))));
}
inline void min(const INT32 value)
{
__m128i val = _mm_set1_epi32(value);
__m128i mask = _mm_cmpgt_epi32(m_value, val); // m_value > value ? 0xffffffff : 0
m_value = _mm_or_si128(_mm_and_si128(val, mask), _mm_and_si128(m_value, _mm_xor_si128(mask, _mm_set1_epi32(0xffffffff))));
}
void blend(const rgbint_t& other, UINT8 factor);
@ -68,7 +210,14 @@ public:
void scale_add_and_clamp(const rgbint_t& scale, const rgbint_t& other);
void scale_imm_add_and_clamp(const INT16 scale, const rgbint_t& other);
void sign_extend(const INT32 compare, const INT32 sign);
void max(const rgbint_t& max);
inline void sign_extend(const INT32 compare, const INT32 sign)
{
__m128i compare_vec = _mm_set1_epi32(compare);
__m128i compare_mask = _mm_cmpeq_epi32(_mm_and_si128(m_value, compare_vec), compare_vec);
m_value = _mm_or_si128(m_value, _mm_and_si128(_mm_set1_epi32(sign), compare_mask));
}
void print();
@ -97,7 +246,25 @@ public:
rgbaint_t(INT32 a, INT32 r, INT32 g, INT32 b);
rgbaint_t(rgb_t& rgb);
void set_rgba(INT32 a, INT32 r, INT32 g, INT32 b);
inline void set_rgba(INT32 a, INT32 r, INT32 g, INT32 b)
{
m_value = _mm_set_epi32(a, r, g, b);
}
inline void set_a(const INT32 value)
{
m_value = _mm_or_si128(_mm_and_si128(m_value, *(__m128i *)&rgbsse_statics.alpha_mask), _mm_set_epi32(value, 0, 0, 0));
}
inline UINT8 get_a()
{
return _mm_extract_epi16(m_value, 6) & 0xff;
}
inline void and_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const INT32 b)
{
m_value = _mm_and_si128(m_value, _mm_set_epi32(a, r, g, b));
}
void add_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const INT32 b);
void sub_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const INT32 b);
@ -105,15 +272,4 @@ public:
void mul_imm_rgba(const INT32 a, const INT32 r, const INT32 g, const INT32 b);
};
/***************************************************************************
TABLES
***************************************************************************/
extern const struct _rgbsse_statics
{
__m128 dummy_for_alignment;
INT16 maxbyte[8];
INT16 scale_table[256][8];
} rgbsse_statics;
#endif /* __RGBSSE__ */

View File

@ -22,6 +22,10 @@ const struct _rgbsse_statics rgbsse_statics =
{
{ 0 },
{ 255, 255, 255, 255, 255, 255, 255, 255 },
{ 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000},
{ 0xffff, 0xffff, 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff },
{ 0xffff, 0xffff, 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff },
{ 0x0000, 0x0000, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff, 0xffff },
{
{ 0, 256, 0, 256, 0, 256, 0, 256 }, { 1, 255, 1, 255, 1, 255, 1, 255 },
{ 2, 254, 2, 254, 2, 254, 2, 254 }, { 3, 253, 3, 253, 3, 253, 3, 253 },

View File

@ -65,9 +65,9 @@ bool n64_rdp::rdp_range_check(UINT32 addr)
// The functions in this file should be moved into the parent Processor class.
#include "rdpfiltr.inc"
void n64_rdp::get_alpha_cvg(UINT8* comb_alpha, rdp_span_aux* userdata, const rdp_poly_state &object)
INT32 n64_rdp::get_alpha_cvg(INT32 comb_alpha, rdp_span_aux* userdata, const rdp_poly_state &object)
{
INT32 temp = *comb_alpha;
INT32 temp = comb_alpha;
INT32 temp2 = userdata->m_current_pix_cvg;
INT32 temp3 = 0;
@ -84,7 +84,7 @@ void n64_rdp::get_alpha_cvg(UINT8* comb_alpha, rdp_span_aux* userdata, const rdp
{
temp = 0xff;
}
*comb_alpha = temp;
return temp;
}
/*****************************************************************************/
@ -156,90 +156,13 @@ void n64_rdp::video_update16(n64_periphs* n64, bitmap_rgb32 &bitmap)
for(INT32 i = 0; i < hres; i++)
{
color_t c;
//INT32 r, g, b;
UINT16 pix = frame_buffer[pixels ^ WORD_ADDR_XOR];
//m_misc_state.m_current_pix_cvg = ((pix & 1) << 2) | (hidden_buffer[pixels ^ BYTE_ADDR_XOR] & 3);
//if(divot)
//{
// if(i > 0 && i < (hres - 1))
// {
// prev_cvg = ((frame_buffer[(pixels - 1)^WORD_ADDR_XOR] & 1) << 2) | (hidden_buffer[(pixels - 1)^BYTE_ADDR_XOR] & 3);
// next_cvg = ((frame_buffer[(pixels + 1)^WORD_ADDR_XOR] & 1) << 2) | (hidden_buffer[(pixels + 1)^BYTE_ADDR_XOR] & 3);
// }
//}
c.i.r = ((pix >> 8) & 0xf8) | (pix >> 13);
c.i.g = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07);
c.i.b = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07);
//if(fsaa)
//{
//if (/*!vibuffering &&*/ state->m_rdp.m_misc_state.m_current_pix_cvg < 7 && i > 1 && j > 1 && i < (hres - 2) && j < (vres - 2))
//{
//video_filter16(&c.i.r, &c.i.g, &c.i.b, &frame_buffer[pixels ^ WORD_ADDR_XOR],&hidden_buffer[pixels ^ BYTE_ADDR_XOR], n64->vi_width);
//}
//}
//else if (dither_filter && state->m_rdp.m_misc_state.m_current_pix_cvg == 7 && i > 0 && j > 0 && i < (hres - 1) && j < (vres - 1))
//{
//if (vibuffering)
//{
// restore_filter16_buffer(&r, &g, &b, &ViBuffer[i][j], n64->vi_width);
//}
//else
//{
//restore_filter16(&c.i.r, &c.i.g, &c.i.b, &frame_buffer[pixels ^ WORD_ADDR_XOR], pixels ^ WORD_ADDR_XOR, n64->vi_width);
//}
//}
//if(divot)
//{
//if (i > 0 && i < (hres - 1) && (m_misc_state.m_current_pix_cvg != 7 || prev_cvg != 7 || next_cvg != 7))
//{
//if (vibuffering)
//{
// divot_filter16_buffer(&r, &g, &b, &ViBuffer[i][j]);
//}
//else
//{
//divot_filter16(&c.i.r, &c.i.g, &c.i.b, &frame_buffer[pixels ^ WORD_ADDR_XOR], pixels ^ WORD_ADDR_XOR);
//}
//}
//}
/*
if (gamma_dither)
{
dith = screen.machine().rand() & 0x3f;
}
if (gamma)
{
if (gamma_dither)
{
r = m_gamma_dither_table[(r << 6)|dith];
g = m_gamma_dither_table[(g << 6)|dith];
b = m_gamma_dither_table[(b << 6)|dith];
}
else
{
r = m_gamma_table[r];
g = m_gamma_table[g];
b = m_gamma_table[b];
}
}
else if (gamma_dither)
{
if (r < 255)
r += (dith & 1);
if (g < 255)
g += (dith & 1);
if (b < 255)
b += (dith & 1);
}
*/
const UINT8 r = ((pix >> 8) & 0xf8) | (pix >> 13);
const UINT8 g = ((pix >> 3) & 0xf8) | ((pix >> 8) & 0x07);
const UINT8 b = ((pix << 2) & 0xf8) | ((pix >> 3) & 0x07);
d[i] = (r << 16) | (g << 8) | b;
pixels++;
d[i] = c.c >> 8;//(r << 16) | (g << 8) | b; // Fix me for endianness
}
pixels +=invisiblewidth;
}
@ -436,118 +359,118 @@ INT32 n64_rdp::alpha_combiner_equation(INT32 a, INT32 b, INT32 c, INT32 d)
return a;
}
void n64_rdp::set_suba_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_suba_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0xf)
{
case 0: *input_r = &userdata->m_combined_color.i.r; *input_g = &userdata->m_combined_color.i.g; *input_b = &userdata->m_combined_color.i.b; break;
case 1: *input_r = &userdata->m_texel0_color.i.r; *input_g = &userdata->m_texel0_color.i.g; *input_b = &userdata->m_texel0_color.i.b; break;
case 2: *input_r = &userdata->m_texel1_color.i.r; *input_g = &userdata->m_texel1_color.i.g; *input_b = &userdata->m_texel1_color.i.b; break;
case 3: *input_r = &userdata->m_prim_color.i.r; *input_g = &userdata->m_prim_color.i.g; *input_b = &userdata->m_prim_color.i.b; break;
case 4: *input_r = &userdata->m_shade_color.i.r; *input_g = &userdata->m_shade_color.i.g; *input_b = &userdata->m_shade_color.i.b; break;
case 5: *input_r = &userdata->m_env_color.i.r; *input_g = &userdata->m_env_color.i.g; *input_b = &userdata->m_env_color.i.b; break;
case 6: *input_r = &m_one.i.r; *input_g = &m_one.i.g; *input_b = &m_one.i.b; break;
case 7: *input_r = &userdata->m_noise_color.i.r; *input_g = &userdata->m_noise_color.i.g; *input_b = &userdata->m_noise_color.i.b; break;
case 0: *input = &userdata->m_combined_color; break;
case 1: *input = &userdata->m_texel0_color; break;
case 2: *input = &userdata->m_texel1_color; break;
case 3: *input = &userdata->m_prim_color; break;
case 4: *input = &userdata->m_shade_color; break;
case 5: *input = &userdata->m_env_color; break;
case 6: *input = &m_one; break;
case 7: *input = &userdata->m_noise_color; break;
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
{
*input_r = &m_zero.i.r; *input_g = &m_zero.i.g; *input_b = &m_zero.i.b; break;
*input = &m_zero; break;
}
}
}
void n64_rdp::set_subb_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_subb_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0xf)
{
case 0: *input_r = &userdata->m_combined_color.i.r; *input_g = &userdata->m_combined_color.i.g; *input_b = &userdata->m_combined_color.i.b; break;
case 1: *input_r = &userdata->m_texel0_color.i.r; *input_g = &userdata->m_texel0_color.i.g; *input_b = &userdata->m_texel0_color.i.b; break;
case 2: *input_r = &userdata->m_texel1_color.i.r; *input_g = &userdata->m_texel1_color.i.g; *input_b = &userdata->m_texel1_color.i.b; break;
case 3: *input_r = &userdata->m_prim_color.i.r; *input_g = &userdata->m_prim_color.i.g; *input_b = &userdata->m_prim_color.i.b; break;
case 4: *input_r = &userdata->m_shade_color.i.r; *input_g = &userdata->m_shade_color.i.g; *input_b = &userdata->m_shade_color.i.b; break;
case 5: *input_r = &userdata->m_env_color.i.r; *input_g = &userdata->m_env_color.i.g; *input_b = &userdata->m_env_color.i.b; break;
case 0: *input = &userdata->m_combined_color; break;
case 1: *input = &userdata->m_texel0_color; break;
case 2: *input = &userdata->m_texel1_color; break;
case 3: *input = &userdata->m_prim_color; break;
case 4: *input = &userdata->m_shade_color; break;
case 5: *input = &userdata->m_env_color; break;
case 6: fatalerror("SET_SUBB_RGB_INPUT: key_center\n");
case 7: *input_r = &userdata->m_k4.i.r; *input_g = &userdata->m_k4.i.g; *input_b = &userdata->m_k4.i.b; break;
case 7: *input = &userdata->m_k4; break;
case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
{
*input_r = &m_zero.i.r; *input_g = &m_zero.i.g; *input_b = &m_zero.i.b; break;
*input = &m_zero; break;
}
}
}
void n64_rdp::set_mul_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_mul_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0x1f)
{
case 0: *input_r = &userdata->m_combined_color.i.r; *input_g = &userdata->m_combined_color.i.g; *input_b = &userdata->m_combined_color.i.b; break;
case 1: *input_r = &userdata->m_texel0_color.i.r; *input_g = &userdata->m_texel0_color.i.g; *input_b = &userdata->m_texel0_color.i.b; break;
case 2: *input_r = &userdata->m_texel1_color.i.r; *input_g = &userdata->m_texel1_color.i.g; *input_b = &userdata->m_texel1_color.i.b; break;
case 3: *input_r = &userdata->m_prim_color.i.r; *input_g = &userdata->m_prim_color.i.g; *input_b = &userdata->m_prim_color.i.b; break;
case 4: *input_r = &userdata->m_shade_color.i.r; *input_g = &userdata->m_shade_color.i.g; *input_b = &userdata->m_shade_color.i.b; break;
case 5: *input_r = &userdata->m_env_color.i.r; *input_g = &userdata->m_env_color.i.g; *input_b = &userdata->m_env_color.i.b; break;
case 6: *input_r = &userdata->m_key_scale.i.r; *input_g = &userdata->m_key_scale.i.g; *input_b = &userdata->m_key_scale.i.b; break;
case 7: *input_r = &userdata->m_combined_alpha.i.r; *input_g = &userdata->m_combined_alpha.i.g; *input_b = &userdata->m_combined_alpha.i.b; break;
case 8: *input_r = &userdata->m_texel0_alpha.i.r; *input_g = &userdata->m_texel0_alpha.i.g; *input_b = &userdata->m_texel0_alpha.i.b; break;
case 9: *input_r = &userdata->m_texel1_alpha.i.r; *input_g = &userdata->m_texel1_alpha.i.g; *input_b = &userdata->m_texel1_alpha.i.b; break;
case 10: *input_r = &userdata->m_prim_alpha.i.r; *input_g = &userdata->m_prim_alpha.i.g; *input_b = &userdata->m_prim_alpha.i.b; break;
case 11: *input_r = &userdata->m_shade_alpha.i.r; *input_g = &userdata->m_shade_alpha.i.g; *input_b = &userdata->m_shade_alpha.i.b; break;
case 12: *input_r = &userdata->m_env_alpha.i.r; *input_g = &userdata->m_env_alpha.i.g; *input_b = &userdata->m_env_alpha.i.b; break;
case 13: *input_r = &userdata->m_lod_fraction.i.r; *input_g = &userdata->m_lod_fraction.i.g; *input_b = &userdata->m_lod_fraction.i.b; break;
case 14: *input_r = &userdata->m_prim_lod_fraction.i.r; *input_g = &userdata->m_prim_lod_fraction.i.g; *input_b = &userdata->m_prim_lod_fraction.i.b; break;
case 15: *input_r = &userdata->m_k5.i.r; *input_g = &userdata->m_k5.i.g; *input_b = &userdata->m_k5.i.b; break;
case 0: *input = &userdata->m_combined_color; break;
case 1: *input = &userdata->m_texel0_color; break;
case 2: *input = &userdata->m_texel1_color; break;
case 3: *input = &userdata->m_prim_color; break;
case 4: *input = &userdata->m_shade_color; break;
case 5: *input = &userdata->m_env_color; break;
case 6: *input = &userdata->m_key_scale; break;
case 7: *input = &userdata->m_combined_alpha; break;
case 8: *input = &userdata->m_texel0_alpha; break;
case 9: *input = &userdata->m_texel1_alpha; break;
case 10: *input = &userdata->m_prim_alpha; break;
case 11: *input = &userdata->m_shade_alpha; break;
case 12: *input = &userdata->m_env_alpha; break;
case 13: *input = &userdata->m_lod_fraction; break;
case 14: *input = &userdata->m_prim_lod_fraction; break;
case 15: *input = &userdata->m_k5; break;
case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23:
case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
{
*input_r = &m_zero.i.r; *input_g = &m_zero.i.g; *input_b = &m_zero.i.b; break;
*input = &m_zero; break;
}
}
}
void n64_rdp::set_add_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_add_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0x7)
{
case 0: *input_r = &userdata->m_combined_color.i.r; *input_g = &userdata->m_combined_color.i.g; *input_b = &userdata->m_combined_color.i.b; break;
case 1: *input_r = &userdata->m_texel0_color.i.r; *input_g = &userdata->m_texel0_color.i.g; *input_b = &userdata->m_texel0_color.i.b; break;
case 2: *input_r = &userdata->m_texel1_color.i.r; *input_g = &userdata->m_texel1_color.i.g; *input_b = &userdata->m_texel1_color.i.b; break;
case 3: *input_r = &userdata->m_prim_color.i.r; *input_g = &userdata->m_prim_color.i.g; *input_b = &userdata->m_prim_color.i.b; break;
case 4: *input_r = &userdata->m_shade_color.i.r; *input_g = &userdata->m_shade_color.i.g; *input_b = &userdata->m_shade_color.i.b; break;
case 5: *input_r = &userdata->m_env_color.i.r; *input_g = &userdata->m_env_color.i.g; *input_b = &userdata->m_env_color.i.b; break;
case 6: *input_r = &m_one.i.r; *input_g = &m_one.i.g; *input_b = &m_one.i.b; break;
case 7: *input_r = &m_zero.i.r; *input_g = &m_zero.i.g; *input_b = &m_zero.i.b; break;
case 0: *input = &userdata->m_combined_alpha; break;
case 1: *input = &userdata->m_texel0_alpha; break;
case 2: *input = &userdata->m_texel1_alpha; break;
case 3: *input = &userdata->m_prim_alpha; break;
case 4: *input = &userdata->m_shade_alpha; break;
case 5: *input = &userdata->m_env_alpha; break;
case 6: *input = &m_one; break;
case 7: *input = &m_zero; break;
}
}
void n64_rdp::set_sub_input_alpha(UINT8** input, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_sub_input_alpha(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0x7)
{
case 0: *input = &userdata->m_combined_color.i.a; break;
case 1: *input = &userdata->m_texel0_color.i.a; break;
case 2: *input = &userdata->m_texel1_color.i.a; break;
case 3: *input = &userdata->m_prim_color.i.a; break;
case 4: *input = &userdata->m_shade_color.i.a; break;
case 5: *input = &userdata->m_env_color.i.a; break;
case 6: *input = &m_one.i.a; break;
case 7: *input = &m_zero.i.a; break;
case 0: *input = &userdata->m_combined_alpha; break;
case 1: *input = &userdata->m_texel0_alpha; break;
case 2: *input = &userdata->m_texel1_alpha; break;
case 3: *input = &userdata->m_prim_alpha; break;
case 4: *input = &userdata->m_shade_alpha; break;
case 5: *input = &userdata->m_env_alpha; break;
case 6: *input = &m_one; break;
case 7: *input = &m_zero; break;
}
}
void n64_rdp::set_mul_input_alpha(UINT8** input, INT32 code, rdp_span_aux* userdata)
void n64_rdp::set_mul_input_alpha(color_t** input, INT32 code, rdp_span_aux* userdata)
{
switch (code & 0x7)
{
case 0: *input = &userdata->m_lod_fraction.i.a; break;
case 1: *input = &userdata->m_texel0_color.i.a; break;
case 2: *input = &userdata->m_texel1_color.i.a; break;
case 3: *input = &userdata->m_prim_color.i.a; break;
case 4: *input = &userdata->m_shade_color.i.a; break;
case 5: *input = &userdata->m_env_color.i.a; break;
case 6: *input = &userdata->m_prim_lod_fraction.i.a; break;
case 7: *input = &m_zero.i.a; break;
case 0: *input = &userdata->m_lod_fraction; break;
case 1: *input = &userdata->m_texel0_alpha; break;
case 2: *input = &userdata->m_texel1_alpha; break;
case 3: *input = &userdata->m_prim_alpha; break;
case 4: *input = &userdata->m_shade_alpha; break;
case 5: *input = &userdata->m_env_alpha; break;
case 6: *input = &userdata->m_prim_lod_fraction; break;
case 7: *input = &m_zero; break;
}
}
void n64_rdp::set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, UINT8** input_a, INT32 a, INT32 b, rdp_span_aux* userdata)
void n64_rdp::set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, color_t** input_a, INT32 a, INT32 b, rdp_span_aux* userdata)
{
switch (a & 0x3)
{
@ -572,20 +495,20 @@ void n64_rdp::set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, U
{
switch (b & 0x3)
{
case 0: *input_a = &userdata->m_pixel_color.i.a; break;
case 1: *input_a = &userdata->m_fog_color.i.a; break;
case 2: *input_a = &userdata->m_shade_color.i.a; break;
case 3: *input_a = &m_zero.i.a; break;
case 0: *input_a = &userdata->m_pixel_color; break;
case 1: *input_a = &userdata->m_fog_alpha; break;
case 2: *input_a = &userdata->m_shade_alpha; break;
case 3: *input_a = &m_zero; break;
}
}
else
{
switch (b & 0x3)
{
case 0: *input_a = &userdata->m_inv_pixel_color.i.a; break;
case 1: *input_a = &userdata->m_memory_color.i.a; break;
case 2: *input_a = &m_one.i.a; break;
case 3: *input_a = &m_zero.i.a; break;
case 0: *input_a = &userdata->m_inv_pixel_color; break;
case 1: *input_a = &userdata->m_memory_color; break;
case 2: *input_a = &m_one; break;
case 3: *input_a = &m_zero; break;
}
}
}
@ -2133,19 +2056,19 @@ void n64_rdp::draw_triangle(bool shade, bool texture, bool zbuffer, bool rect)
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);
// Setup color combiner data for this scanline
set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a_r[0], &userdata->m_color_inputs.combiner_rgbsub_a_g[0], &userdata->m_color_inputs.combiner_rgbsub_a_b[0], m_combine.sub_a_rgb0, userdata);
set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b_r[0], &userdata->m_color_inputs.combiner_rgbsub_b_g[0], &userdata->m_color_inputs.combiner_rgbsub_b_b[0], m_combine.sub_b_rgb0, userdata);
set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul_r[0], &userdata->m_color_inputs.combiner_rgbmul_g[0], &userdata->m_color_inputs.combiner_rgbmul_b[0], m_combine.mul_rgb0, userdata);
set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd_r[0], &userdata->m_color_inputs.combiner_rgbadd_g[0], &userdata->m_color_inputs.combiner_rgbadd_b[0], m_combine.add_rgb0, userdata);
set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[0], m_combine.sub_a_rgb0, userdata);
set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[0], m_combine.sub_b_rgb0, userdata);
set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[0], m_combine.mul_rgb0, userdata);
set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[0], m_combine.add_rgb0, userdata);
set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[0], m_combine.sub_a_a0, userdata);
set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[0], m_combine.sub_b_a0, userdata);
set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[0], m_combine.mul_a0, userdata);
set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphaadd[0], m_combine.add_a0, userdata);
set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a_r[1], &userdata->m_color_inputs.combiner_rgbsub_a_g[1], &userdata->m_color_inputs.combiner_rgbsub_a_b[1], m_combine.sub_a_rgb1, userdata);
set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b_r[1], &userdata->m_color_inputs.combiner_rgbsub_b_g[1], &userdata->m_color_inputs.combiner_rgbsub_b_b[1], m_combine.sub_b_rgb1, userdata);
set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul_r[1], &userdata->m_color_inputs.combiner_rgbmul_g[1], &userdata->m_color_inputs.combiner_rgbmul_b[1], m_combine.mul_rgb1, userdata);
set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd_r[1], &userdata->m_color_inputs.combiner_rgbadd_g[1], &userdata->m_color_inputs.combiner_rgbadd_b[1], m_combine.add_rgb1, userdata);
set_suba_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_a[1], m_combine.sub_a_rgb1, userdata);
set_subb_input_rgb(&userdata->m_color_inputs.combiner_rgbsub_b[1], m_combine.sub_b_rgb1, userdata);
set_mul_input_rgb(&userdata->m_color_inputs.combiner_rgbmul[1], m_combine.mul_rgb1, userdata);
set_add_input_rgb(&userdata->m_color_inputs.combiner_rgbadd[1], m_combine.add_rgb1, userdata);
set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_a[1], m_combine.sub_a_a1, userdata);
set_sub_input_alpha(&userdata->m_color_inputs.combiner_alphasub_b[1], m_combine.sub_b_a1, userdata);
set_mul_input_alpha(&userdata->m_color_inputs.combiner_alphamul[1], m_combine.mul_a1, userdata);
@ -2386,13 +2309,13 @@ void n64_rdp::cmd_sync_full(UINT32 w1, UINT32 w2)
void n64_rdp::cmd_set_key_gb(UINT32 w1, UINT32 w2)
{
m_key_scale.i.b = w2 & 0xff;
m_key_scale.i.g = (w2 >> 16) & 0xff;
m_key_scale.set_b(w2 & 0xff);
m_key_scale.set_g((w2 >> 16) & 0xff);
}
void n64_rdp::cmd_set_key_r(UINT32 w1, UINT32 w2)
{
m_key_scale.i.r = w2 & 0xff;
m_key_scale.set_r(w2 & 0xff);
}
void n64_rdp::cmd_set_fill_color32(UINT32 w1, UINT32 w2)
@ -2417,9 +2340,9 @@ void n64_rdp::cmd_set_convert(UINT32 w1, UINT32 w2)
k4 = ((w2 >> 17) & 1) ? (-(0x100 - k4)) : k4;
k5 = ((w2 >> 8) & 1) ? (-(0x100 - k5)) : k5;
UINT32 repl_k4 = (k4 & 0xff) * 0x01010101;
UINT32 repl_k5 = (k5 & 0xff) * 0x01010101;
set_yuv_factors(k0, k1, k2, k3, repl_k4, repl_k5);
const UINT32 k4val = k4 & 0xff;
const UINT32 k5val = k5 & 0xff;
set_yuv_factors(k0, k1, k2, k3, rgbaint_t(k4val, k4val, k4val, k4val), rgbaint_t(k5val, k5val, k5val, k5val));
}
void n64_rdp::cmd_set_scissor(UINT32 w1, UINT32 w2)
@ -2902,28 +2825,30 @@ void n64_rdp::cmd_fill_rect(UINT32 w1, UINT32 w2)
void n64_rdp::cmd_set_fog_color(UINT32 w1, UINT32 w2)
{
m_fog_color.c = w2;
m_fog_alpha.c = m_fog_color.i.a * 0x01010101;
m_fog_color.set_rgba(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff);
m_fog_alpha.set(m_fog_color);
}
void n64_rdp::cmd_set_blend_color(UINT32 w1, UINT32 w2)
{
m_blend_color.c = w2;
m_blend_alpha.c = m_blend_color.i.a * 0x01010101;
m_blend_color.set_rgba(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff);
m_blend_alpha.set(m_blend_color);
}
void n64_rdp::cmd_set_prim_color(UINT32 w1, UINT32 w2)
{
m_misc_state.m_min_level = (w1 >> 8) & 0x1f;
m_prim_lod_fraction.c = (w1 & 0xff) * 0x01010101;
m_prim_color.c = w2;
m_prim_alpha.c = m_prim_color.i.a * 0x01010101;
const UINT8 prim_lod_fraction = w1 & 0xff;
m_prim_lod_fraction.set_rgba(prim_lod_fraction, prim_lod_fraction, prim_lod_fraction, prim_lod_fraction);
m_prim_color.set_rgba(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff);
m_prim_alpha.set(m_prim_color);
}
void n64_rdp::cmd_set_env_color(UINT32 w1, UINT32 w2)
{
m_env_color.c = w2;
m_env_alpha.c = m_env_color.i.a * 0x01010101;
m_env_color.set_rgba(w2 & 0xff, (w2 >> 24) & 0xff, (w2 >> 16) & 0xff, (w2 >> 8) & 0xff);
m_env_alpha.set(m_env_color);
}
void n64_rdp::cmd_set_combine(UINT32 w1, UINT32 w2)
@ -3123,8 +3048,8 @@ n64_rdp::n64_rdp(n64_state &state) : poly_manager<UINT32, rdp_poly_state, 8, 320
m_tiles[i].num = i;
}
m_one.c = 0xffffffff;
m_zero.c = 0x00000000;
m_one.set_rgba(0xff, 0xff, 0xff, 0xff);
m_zero.set_rgba(0, 0, 0, 0);
m_tmem = NULL;
@ -3132,7 +3057,7 @@ n64_rdp::n64_rdp(n64_state &state) : poly_manager<UINT32, rdp_poly_state, 8, 320
//memset(m_hidden_bits, 3, 8388608);
m_prim_lod_fraction.c = 0;
m_prim_lod_fraction.set_rgba(0, 0, 0, 0);
for (INT32 i = 0; i < 256; i++)
{

View File

@ -177,12 +177,12 @@ public:
// Color Combiner
INT32 color_combiner_equation(INT32 a, INT32 b, INT32 c, INT32 d);
INT32 alpha_combiner_equation(INT32 a, INT32 b, INT32 c, INT32 d);
void set_suba_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata);
void set_subb_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata);
void set_mul_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata);
void set_add_input_rgb(UINT8** input_r, UINT8** input_g, UINT8** input_b, INT32 code, rdp_span_aux* userdata);
void set_sub_input_alpha(UINT8** input, INT32 code, rdp_span_aux* userdata);
void set_mul_input_alpha(UINT8** input, INT32 code, rdp_span_aux* userdata);
void set_suba_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata);
void set_subb_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata);
void set_mul_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata);
void set_add_input_rgb(color_t** input, INT32 code, rdp_span_aux* userdata);
void set_sub_input_alpha(color_t** input, INT32 code, rdp_span_aux* userdata);
void set_mul_input_alpha(color_t** input, INT32 code, rdp_span_aux* userdata);
// Texture memory
UINT8* get_tmem8() { return m_tmem; }
@ -192,14 +192,14 @@ public:
UINT8 get_random() { return m_misc_state.m_random_seed += 0x13; }
// YUV Factors
void set_yuv_factors(INT32 k0, INT32 k1, INT32 k2, INT32 k3, INT32 k4, INT32 k5) { m_k0 = k0; m_k1 = k1; m_k2 = k2; m_k3 = k3; m_k4.c = k4; m_k5.c = k5; }
void set_yuv_factors(INT32 k0, INT32 k1, INT32 k2, INT32 k3, color_t k4, color_t k5) { m_k0 = k0; m_k1 = k1; m_k2 = k2; m_k3 = k3; m_k4 = k4; m_k5 = k5; }
INT32 get_k0() const { return m_k0; }
INT32 get_k1() const { return m_k1; }
INT32 get_k2() const { return m_k2; }
INT32 get_k3() const { return m_k3; }
// Blender-related (move into RDP::Blender)
void set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, UINT8** input_a, INT32 a, INT32 b, rdp_span_aux* userdata);
void set_blender_input(INT32 cycle, INT32 which, color_t** input_rgb, color_t** input_a, INT32 a, INT32 b, rdp_span_aux* userdata);
// Span rasterization
void span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, INT32 threadid);
@ -212,7 +212,7 @@ public:
void tc_div_no_perspective(INT32 ss, INT32 st, INT32 sw, INT32* sss, INT32* sst);
UINT32 get_log2(UINT32 lod_clamp);
void render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, extent_t* spans, bool rect, rdp_poly_state* object);
void get_alpha_cvg(UINT8* comb_alpha, rdp_span_aux* userdata, const rdp_poly_state &object);
INT32 get_alpha_cvg(INT32 comb_alpha, rdp_span_aux* userdata, const rdp_poly_state &object);
void z_store(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
UINT32 z_decompress(UINT32 zcurpixel);
@ -324,9 +324,9 @@ private:
void compute_cvg_noflip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
void compute_cvg_flip(extent_t* spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
void write_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, rdp_span_aux* userdata, const rdp_poly_state &object);
void write_pixel(UINT32 curpixel, color_t& color, rdp_span_aux* userdata, const rdp_poly_state &object);
void read_pixel(UINT32 curpixel, rdp_span_aux* userdata, const rdp_poly_state &object);
void copy_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, INT32 m_current_pix_cvg, const rdp_poly_state &object);
void copy_pixel(UINT32 curpixel, color_t& color, const rdp_poly_state &object);
void fill_pixel(UINT32 curpixel, const rdp_poly_state &object);
void precalc_cvmask_derivatives(void);

View File

@ -4,6 +4,8 @@
#ifndef _VIDEO_N64TYPES_H_
#define _VIDEO_N64TYPES_H_
#include "video/rgbutil.h"
struct misc_state_t
{
misc_state_t()
@ -34,6 +36,7 @@ struct misc_state_t
UINT16 m_primitive_dz; // Forced Delta-Z value for current primitive, if applicable
};
#if 0
class color_t
{
public:
@ -52,7 +55,12 @@ class color_t
set(a, r, g, b);
}
void set(UINT32 color)
inline void set(color_t& other)
{
c = other.c;
}
inline void set(UINT32 color)
{
i.a = (color >> 24) & 0xff;
i.r = (color >> 16) & 0xff;
@ -68,6 +76,11 @@ class color_t
i.b = b;
}
inline void set_direct(UINT32 color)
{
c = color;
}
UINT32 get()
{
return i.a << 24 | i.r << 16 | i.g << 8 | i.b;
@ -83,6 +96,9 @@ class color_t
#endif
};
};
#else
#define color_t rgbaint_t
#endif
enum
{
@ -151,29 +167,21 @@ struct combine_modes_t
struct color_inputs_t
{
// combiner inputs
UINT8* combiner_rgbsub_a_r[2];
UINT8* combiner_rgbsub_a_g[2];
UINT8* combiner_rgbsub_a_b[2];
UINT8* combiner_rgbsub_b_r[2];
UINT8* combiner_rgbsub_b_g[2];
UINT8* combiner_rgbsub_b_b[2];
UINT8* combiner_rgbmul_r[2];
UINT8* combiner_rgbmul_g[2];
UINT8* combiner_rgbmul_b[2];
UINT8* combiner_rgbadd_r[2];
UINT8* combiner_rgbadd_g[2];
UINT8* combiner_rgbadd_b[2];
color_t* combiner_rgbsub_a[2];
color_t* combiner_rgbsub_b[2];
color_t* combiner_rgbmul[2];
color_t* combiner_rgbadd[2];
UINT8* combiner_alphasub_a[2];
UINT8* combiner_alphasub_b[2];
UINT8* combiner_alphamul[2];
UINT8* combiner_alphaadd[2];
color_t* combiner_alphasub_a[2];
color_t* combiner_alphasub_b[2];
color_t* combiner_alphamul[2];
color_t* combiner_alphaadd[2];
// blender input
color_t* blender1a_rgb[2];
UINT8* blender1b_a[2];
color_t* blender1b_a[2];
color_t* blender2a_rgb[2];
UINT8* blender2b_a[2];
color_t* blender2b_a[2];
};
struct other_modes_t

View File

@ -88,428 +88,375 @@ bool n64_blender_t::alpha_reject(rdp_span_aux* userdata, const rdp_poly_state& o
return false;
case 2:
return userdata->m_pixel_color.i.a < userdata->m_blend_color.i.a;
return userdata->m_pixel_color.get_a() < userdata->m_blend_color.get_a();
case 3:
return userdata->m_pixel_color.i.a < (rand() & 0xff);
return userdata->m_pixel_color.get_a() < (rand() & 0xff);
default:
return false;
}
}
bool n64_blender_t::cycle1_noblend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_noblend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
*fr = (*userdata->m_color_inputs.blender1a_rgb[0]).i.r;
*fg = (*userdata->m_color_inputs.blender1a_rgb[0]).i.g;
*fb = (*userdata->m_color_inputs.blender1a_rgb[0]).i.b;
blended_pixel.set(*userdata->m_color_inputs.blender1a_rgb[0]);
return true;
}
bool n64_blender_t::cycle1_noblend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_noblend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
*fr = m_color_dither[(((*userdata->m_color_inputs.blender1a_rgb[0]).i.r & 0xff) << 3) | dith];
*fg = m_color_dither[(((*userdata->m_color_inputs.blender1a_rgb[0]).i.g & 0xff) << 3) | dith];
*fb = m_color_dither[(((*userdata->m_color_inputs.blender1a_rgb[0]).i.b & 0xff) << 3) | dith];
rgbaint_t index(*userdata->m_color_inputs.blender1a_rgb[0]);
index.shl(3);
index.or_imm(dith);
index.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[index.get_r32()], m_color_dither[index.get_g32()], m_color_dither[index.get_b32()]);
return true;
}
bool n64_blender_t::cycle1_noblend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_noblend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
*fr = (*userdata->m_color_inputs.blender1a_rgb[0]).i.r;
*fg = (*userdata->m_color_inputs.blender1a_rgb[0]).i.g;
*fb = (*userdata->m_color_inputs.blender1a_rgb[0]).i.b;
blended_pixel.set(*userdata->m_color_inputs.blender1a_rgb[0]);
return true;
}
bool n64_blender_t::cycle1_noblend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_noblend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
if (test_for_reject(userdata, object))
{
return false;
}
*fr = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[0]).i.r << 3) | dith];
*fg = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[0]).i.g << 3) | dith];
*fb = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[0]).i.b << 3) | dith];
return true;
}
bool n64_blender_t::cycle1_blend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
blend_with_partial_reject(&r, &g, &b, 0, partialreject, sel0, userdata, object);
*fr = r;
*fg = g;
*fb = b;
rgbaint_t index(*userdata->m_color_inputs.blender1a_rgb[0]);
index.shl(3);
index.or_imm(dith);
index.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[index.get_r32()], m_color_dither[index.get_g32()], m_color_dither[index.get_b32()]);
return true;
}
bool n64_blender_t::cycle1_blend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_blend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
blend_with_partial_reject(&r, &g, &b, 0, partialreject, sel0, userdata, object);
*fr = m_color_dither[((r & 0xff) << 3) | dith];
*fg = m_color_dither[((g & 0xff) << 3) | dith];
*fb = m_color_dither[((b & 0xff) << 3) | dith];
blend_with_partial_reject(blended_pixel, 0, partialreject, sel0, userdata, object);
return true;
}
bool n64_blender_t::cycle1_blend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_blend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
blend_with_partial_reject(&r, &g, &b, 0, partialreject, sel0, userdata, object);
color_t rgb;
blend_with_partial_reject(rgb, 0, partialreject, sel0, userdata, object);
*fr = r;
*fg = g;
*fb = b;
rgb.shl(3);
rgb.or_imm(dith);
rgb.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[rgb.get_r32()], m_color_dither[rgb.get_g32()], m_color_dither[rgb.get_b32()]);
return true;
}
bool n64_blender_t::cycle1_blend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_blend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
blend_with_partial_reject(&r, &g, &b, 0, partialreject, sel0, userdata, object);
*fr = m_color_dither[((r & 0xff) << 3) | dith];
*fg = m_color_dither[((g & 0xff) << 3) | dith];
*fb = m_color_dither[((b & 0xff) << 3) | dith];
blend_with_partial_reject(blended_pixel, 0, partialreject, sel0, userdata, object);
return true;
}
bool n64_blender_t::cycle2_noblend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle1_blend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
color_t rgb;
blend_with_partial_reject(rgb, 0, partialreject, sel0, userdata, object);
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
*fr = (*userdata->m_color_inputs.blender1a_rgb[1]).i.r;
*fg = (*userdata->m_color_inputs.blender1a_rgb[1]).i.g;
*fb = (*userdata->m_color_inputs.blender1a_rgb[1]).i.b;
rgb.shl(3);
rgb.or_imm(dith);
rgb.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[rgb.get_r32()], m_color_dither[rgb.get_g32()], m_color_dither[rgb.get_b32()]);
return true;
}
bool n64_blender_t::cycle2_noblend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_noblend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
*fr = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.r << 3) | dith];
*fg = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.g << 3) | dith];
*fb = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.b << 3) | dith];
userdata->m_blended_pixel_color.set_a(userdata->m_pixel_color.get_a());
blended_pixel.set(*userdata->m_color_inputs.blender1a_rgb[1]);
return true;
}
bool n64_blender_t::cycle2_noblend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_noblend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
*fr = (*userdata->m_color_inputs.blender1a_rgb[1]).i.r;
*fg = (*userdata->m_color_inputs.blender1a_rgb[1]).i.g;
*fb = (*userdata->m_color_inputs.blender1a_rgb[1]).i.b;
rgbaint_t index(*userdata->m_color_inputs.blender1a_rgb[1]);
index.shl(3);
index.or_imm(dith);
index.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[index.get_r32()], m_color_dither[index.get_g32()], m_color_dither[index.get_b32()]);
return true;
}
bool n64_blender_t::cycle2_noblend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_noblend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
*fr = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.r << 3) | dith];
*fg = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.g << 3) | dith];
*fb = m_color_dither[((*userdata->m_color_inputs.blender1a_rgb[1]).i.b << 3) | dith];
blended_pixel.set(*userdata->m_color_inputs.blender1a_rgb[1]);
return true;
}
bool n64_blender_t::cycle2_blend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_noblend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
blend_with_partial_reject(&r, &g, &b, 1, partialreject, sel1, userdata, object);
*fr = r;
*fg = g;
*fb = b;
rgbaint_t index(*userdata->m_color_inputs.blender1a_rgb[1]);
index.shl(3);
index.or_imm(dith);
index.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[index.get_r32()], m_color_dither[index.get_g32()], m_color_dither[index.get_b32()]);
if (blended_pixel.get_r() == 0 && blended_pixel.get_g() == 0 && blended_pixel.get_b() == 0)
{
rgbaint_t other_index(*userdata->m_color_inputs.blender1a_rgb[1]);
//other_index.shl(3);
//other_index.or_imm(dith);
//other_index.and_imm(0x7ff);
printf("%08x%08x%08x\n", userdata->m_blended_pixel_color.get_r32(), userdata->m_blended_pixel_color.get_g32(), userdata->m_blended_pixel_color.get_b32());
}
return true;
}
bool n64_blender_t::cycle2_blend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_blend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_pixel_color.i.a = m_alpha_dither[(userdata->m_pixel_color.i.a << 3) | adseed];
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
blend_with_partial_reject(&r, &g, &b, 1, partialreject, sel1, userdata, object);
*fr = m_color_dither[((r & 0xff) << 3) | dith];
*fg = m_color_dither[((g & 0xff) << 3) | dith];
*fb = m_color_dither[((b & 0xff) << 3) | dith];
blend_with_partial_reject(blended_pixel, 1, partialreject, sel1, userdata, object);
return true;
}
bool n64_blender_t::cycle2_blend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_blend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_pixel_color.set_a(m_alpha_dither[((UINT8)userdata->m_pixel_color.get_a() << 3) | adseed]);
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a(userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
color_t rgb;
blend_with_partial_reject(rgb, 1, partialreject, sel1, userdata, object);
blend_with_partial_reject(&r, &g, &b, 1, partialreject, sel1, userdata, object);
*fr = r;
*fg = g;
*fb = b;
rgb.shl(3);
rgb.or_imm(dith);
rgb.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[rgb.get_r32()], m_color_dither[rgb.get_g32()], m_color_dither[rgb.get_b32()]);
return true;
}
bool n64_blender_t::cycle2_blend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_blend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
userdata->m_shade_color.i.a = m_alpha_dither[(userdata->m_shade_color.i.a << 3) | adseed];
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
return false;
}
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[0];
blend_pipe(0, sel0, &r, &g, &b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
userdata->m_blended_pixel_color.i.r = r;
userdata->m_blended_pixel_color.i.g = g;
userdata->m_blended_pixel_color.i.b = b;
userdata->m_blended_pixel_color.i.a = userdata->m_pixel_color.i.a;
blend_with_partial_reject(&r, &g, &b, 1, partialreject, sel1, userdata, object);
*fr = m_color_dither[((r & 0xff) << 3) | dith];
*fg = m_color_dither[((g & 0xff) << 3) | dith];
*fb = m_color_dither[((b & 0xff) << 3) | dith];
blend_with_partial_reject(blended_pixel, 1, partialreject, sel1, userdata, object);
return true;
}
void n64_blender_t::blend_with_partial_reject(INT32* r, INT32* g, INT32* b, INT32 cycle, INT32 partialreject, INT32 select, rdp_span_aux* userdata, const rdp_poly_state& object)
bool n64_blender_t::cycle2_blend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object)
{
if (partialreject && userdata->m_pixel_color.i.a >= 0xff)
userdata->m_shade_color.set_a(m_alpha_dither[((UINT8)userdata->m_shade_alpha.get_a() << 3) | adseed]);
if (test_for_reject(userdata, object))
{
*r = (*userdata->m_color_inputs.blender1a_rgb[cycle]).i.r;
*g = (*userdata->m_color_inputs.blender1a_rgb[cycle]).i.g;
*b = (*userdata->m_color_inputs.blender1a_rgb[cycle]).i.b;
return false;
}
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[0]->get_a());
blend_pipe(0, sel0, userdata->m_blended_pixel_color, userdata, object);
userdata->m_blended_pixel_color.set_a((UINT8)userdata->m_pixel_color.get_a());
color_t rgb;
blend_with_partial_reject(rgb, 1, partialreject, sel1, userdata, object);
rgb.shl(3);
rgb.or_imm(dith);
rgb.and_imm(0x7ff);
blended_pixel.set_rgba(0, m_color_dither[rgb.get_r32()], m_color_dither[rgb.get_g32()], m_color_dither[rgb.get_b32()]);
return true;
}
void n64_blender_t::blend_with_partial_reject(color_t& out, INT32 cycle, INT32 partialreject, INT32 select, rdp_span_aux* userdata, const rdp_poly_state& object)
{
if (partialreject && (UINT8)userdata->m_pixel_color.get_a() >= 0xff)
{
out.set(*userdata->m_color_inputs.blender1a_rgb[cycle]);
}
else
{
userdata->m_inv_pixel_color.i.a = 0xff - *userdata->m_color_inputs.blender1b_a[cycle];
blend_pipe(cycle, select, r, g, b, userdata, object);
userdata->m_inv_pixel_color.set_a(0xff - (UINT8)userdata->m_color_inputs.blender1b_a[cycle]->get_a());
blend_pipe(cycle, select, out, userdata, object);
}
}
void n64_blender_t::blend_pipe(const int cycle, const int special, int* r_out, int* g_out, int* b_out, rdp_span_aux* userdata, const rdp_poly_state& object)
void n64_blender_t::blend_pipe(const int cycle, const int special, color_t& out, rdp_span_aux* userdata, const rdp_poly_state& object)
{
const INT32 mask = 0xff &~ (0x73 * special);
const INT32 shift_a = 3 + userdata->m_shift_a * special;
const INT32 shift_b = 3 + userdata->m_shift_b * special;
const INT32 blend1a = (*userdata->m_color_inputs.blender1b_a[cycle] >> shift_a) & mask;
const INT32 blend2a = (*userdata->m_color_inputs.blender2b_a[cycle] >> shift_b) & mask;
const INT32 blend1a = (userdata->m_color_inputs.blender1b_a[cycle]->get_a() >> shift_a) & mask;
const INT32 blend2a = (userdata->m_color_inputs.blender2b_a[cycle]->get_a() >> shift_b) & mask;
const INT32 special_shift = special << 1;
INT32 r = (((int)(*userdata->m_color_inputs.blender1a_rgb[cycle]).i.r * (int)(blend1a))) + (((int)(*userdata->m_color_inputs.blender2a_rgb[cycle]).i.r * (int)(blend2a)));
INT32 g = (((int)(*userdata->m_color_inputs.blender1a_rgb[cycle]).i.g * (int)(blend1a))) + (((int)(*userdata->m_color_inputs.blender2a_rgb[cycle]).i.g * (int)(blend2a)));
INT32 b = (((int)(*userdata->m_color_inputs.blender1a_rgb[cycle]).i.b * (int)(blend1a))) + (((int)(*userdata->m_color_inputs.blender2a_rgb[cycle]).i.b * (int)(blend2a)));
rgbaint_t temp(*userdata->m_color_inputs.blender1a_rgb[cycle]);
temp.mul_imm(blend1a);
r += (*userdata->m_color_inputs.blender2a_rgb[cycle]).i.r << special_shift;
g += (*userdata->m_color_inputs.blender2a_rgb[cycle]).i.g << special_shift;
b += (*userdata->m_color_inputs.blender2a_rgb[cycle]).i.b << special_shift;
rgbaint_t secondary(*userdata->m_color_inputs.blender2a_rgb[cycle]);
rgbaint_t other(*userdata->m_color_inputs.blender2a_rgb[cycle]);
other.mul_imm(blend2a);
r >>= object.m_other_modes.blend_shift;
g >>= object.m_other_modes.blend_shift;
b >>= object.m_other_modes.blend_shift;
temp.add(other);
secondary.shl(special_shift);
temp.add(secondary);
temp.shr(object.m_other_modes.blend_shift);
if (!object.m_other_modes.force_blend)
{
INT32 factor_sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
if (factor_sum)
{
r /= factor_sum;
g /= factor_sum;
b /= factor_sum;
temp.set_r(temp.get_r() / factor_sum);
temp.set_g(temp.get_g() / factor_sum);
temp.set_b(temp.get_b() / factor_sum);
}
else
{
r = g = b = 0xff;
temp.set_rgba(0, 0xff, 0xff, 0xff);
}
}
*r_out = min(r, 255);
*g_out = min(g, 255);
*b_out = min(b, 255);
temp.min(255);
out.set(temp);
}
inline INT32 n64_blender_t::min(const INT32 x, const INT32 min)

View File

@ -22,8 +22,8 @@
class n64_blender_t
{
public:
typedef bool (n64_blender_t::*blender1)(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
typedef bool (n64_blender_t::*blender2)(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
typedef bool (n64_blender_t::*blender1)(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
typedef bool (n64_blender_t::*blender2)(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
n64_blender_t();
@ -42,26 +42,26 @@ class n64_blender_t
INT32 min(const INT32 x, const INT32 min);
bool alpha_reject(rdp_span_aux* userdata, const rdp_poly_state& object);
bool test_for_reject(rdp_span_aux* userdata, const rdp_poly_state& object);
void blend_pipe(const int cycle, const int special, int* r_out, int* g_out, int* b_out, rdp_span_aux* userdata, const rdp_poly_state& object);
void blend_with_partial_reject(INT32* r, INT32* g, INT32* b, INT32 cycle, INT32 partialreject, INT32 select, rdp_span_aux* userdata, const rdp_poly_state& object);
void blend_pipe(const int cycle, const int special, color_t& out, rdp_span_aux* userdata, const rdp_poly_state& object);
void blend_with_partial_reject(color_t& out, INT32 cycle, INT32 partialreject, INT32 select, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_noblend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle1_blend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_noacvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_noacvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_acvg_nodither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_acvg_dither(INT32* fr, INT32* fg, INT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_noblend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_noacvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_noacvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_acvg_nodither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
bool cycle2_blend_acvg_dither(color_t& blended_pixel, int dith, int adseed, int partialreject, int sel0, int sel1, rdp_span_aux* userdata, const rdp_poly_state& object);
INT32 dither_alpha(INT32 alpha, INT32 dither);
INT32 dither_color(INT32 color, INT32 dither);

View File

@ -1,5 +1,6 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
#if 0
INLINE void video_filter16(int *out_r, int *out_g, int *out_b, UINT16* vbuff, UINT8* hbuff, const UINT32 hres);
INLINE void divot_filter16(UINT8* r, UINT8* g, UINT8* b, UINT16* fbuff, UINT32 fbuff_index);
INLINE void restore_filter16(INT32* r, INT32* g, INT32* b, UINT16* fbuff, UINT32 fbuff_index, UINT32 hres);
@ -613,3 +614,4 @@ INLINE UINT32 ge_two(UINT32 enb)
}
return 0;
}
#endif

View File

@ -82,10 +82,8 @@ void n64_rdp::render_spans(INT32 start, INT32 end, INT32 tilenum, bool flip, ext
void n64_rdp::rgbaz_clip(INT32 sr, INT32 sg, INT32 sb, INT32 sa, INT32* sz, rdp_span_aux* userdata)
{
userdata->m_shade_color.i.r = s_special_9bit_clamptable[sr & 0x1ff];
userdata->m_shade_color.i.g = s_special_9bit_clamptable[sg & 0x1ff];
userdata->m_shade_color.i.b = s_special_9bit_clamptable[sb & 0x1ff];
userdata->m_shade_color.i.a = s_special_9bit_clamptable[sa & 0x1ff];
userdata->m_shade_color.clamp_and_clear(rgbaint_t((UINT8)sa, (UINT8)sr, (UINT8)sg, (UINT8)sb), 0xfffffe00);
userdata->m_shade_alpha = userdata->m_shade_color;
INT32 zanded = (*sz) & 0x60000;
@ -131,7 +129,7 @@ void n64_rdp::rgbaz_correct_triangle(INT32 offx, INT32 offy, INT32* r, INT32* g,
}
}
inline void n64_rdp::write_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, rdp_span_aux* userdata, const rdp_poly_state &object)
inline void n64_rdp::write_pixel(UINT32 curpixel, color_t& color, rdp_span_aux* userdata, const rdp_poly_state &object)
{
if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
{
@ -144,7 +142,8 @@ inline void n64_rdp::write_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, rdp
}
else
{
finalcolor = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1);
color.shr(3);
finalcolor = (color.get_r() << 11) | (color.get_g() << 6) | (color.get_b() << 1);
}
switch (object.m_other_modes.cvg_dest)
@ -195,7 +194,7 @@ inline void n64_rdp::write_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, rdp
}
else
{
finalcolor = (r << 24) | (g << 16) | (b << 8);
finalcolor = (color.get_r() << 24) | (color.get_g() << 16) | (color.get_b() << 8);
}
switch (object.m_other_modes.cvg_dest)
@ -233,59 +232,52 @@ inline void n64_rdp::read_pixel(UINT32 curpixel, rdp_span_aux* userdata, const r
{
if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
{
UINT16 fword;
const UINT16 fword = RREADIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel);
userdata->m_memory_color.set_rgba(0, GETHICOL(fword), GETMEDCOL(fword), GETLOWCOL(fword));
if (object.m_other_modes.image_read_en)
{
fword = RREADIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel);
UINT8 hbyte = HREADADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel);
userdata->m_memory_color.i.a = userdata->m_current_mem_cvg << 5;
userdata->m_memory_color.set_a(userdata->m_current_mem_cvg << 5);
userdata->m_current_mem_cvg = ((fword & 1) << 2) | (hbyte & 3);
}
else
{
fword = RREADIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel);
userdata->m_memory_color.i.a = 0xff;
userdata->m_memory_color.set_a(0xff);
userdata->m_current_mem_cvg = 7;
}
userdata->m_memory_color.i.r = GETHICOL(fword);
userdata->m_memory_color.i.g = GETMEDCOL(fword);
userdata->m_memory_color.i.b = GETLOWCOL(fword);
}
else // 32-bit framebuffer
{
UINT32 mem;
const UINT32 mem = RREADIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel);
userdata->m_memory_color.set_rgba(0, (mem >> 24) & 0xff, (mem >> 16) & 0xff, (mem >> 8) & 0xff);
if (object.m_other_modes.image_read_en)
{
mem = RREADIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel);
userdata->m_memory_color.i.a = (mem) & 0xff;
userdata->m_memory_color.set_a(mem & 0xff);
userdata->m_current_mem_cvg = (mem >> 5) & 7;
}
else
{
mem = RREADIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel);
userdata->m_memory_color.i.a = 0xff;
userdata->m_memory_color.set_a(0xff);
userdata->m_current_mem_cvg = 7;
}
userdata->m_memory_color.i.r = (mem >> 24) & 0xff;
userdata->m_memory_color.i.g = (mem >> 16) & 0xff;
userdata->m_memory_color.i.b = (mem >> 8) & 0xff;
}
}
inline void n64_rdp::copy_pixel(UINT32 curpixel, INT32 r, INT32 g, INT32 b, INT32 m_current_pix_cvg, const rdp_poly_state &object)
inline void n64_rdp::copy_pixel(UINT32 curpixel, color_t& color, const rdp_poly_state &object)
{
const UINT32 current_pix_cvg = color.get_a() ? 7 : 0;
const UINT8 r = color.get_r(); // Vectorize me
const UINT8 g = color.get_g();
const UINT8 b = color.get_b();
if (object.m_misc_state.m_fb_size == 2) // 16-bit framebuffer
{
RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((m_current_pix_cvg >> 2) & 1));
HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, m_current_pix_cvg & 3);
RWRITEIDX16((object.m_misc_state.m_fb_address >> 1) + curpixel, ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((current_pix_cvg >> 2) & 1));
HWRITEADDR8((object.m_misc_state.m_fb_address >> 1) + curpixel, current_pix_cvg & 3);
}
else // 32-bit framebuffer
{
RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, (r << 24) | (g << 16) | (b << 8) | (m_current_pix_cvg << 5));
RWRITEIDX32((object.m_misc_state.m_fb_address >> 2) + curpixel, (r << 24) | (g << 16) | (b << 8) | (current_pix_cvg << 5));
}
}
@ -343,8 +335,8 @@ void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp
m_tex_pipe.calculate_clamp_diffs(tilenum, userdata, object);
const bool partialreject = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_inv_pixel_color.i.a && userdata->m_color_inputs.blender1b_a[0] == &userdata->m_pixel_color.i.a);
const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color.i.a) ? 1 : 0;
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);
const INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
INT32 drinc, dginc, dbinc, dainc;
INT32 dzinc, dzpix;
@ -385,7 +377,6 @@ void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp
INT32 x = xend;
const INT32 length = flip ? (xstart - xend) : (xend - xstart);
INT32 fir, fig, fib;
if(object.m_other_modes.z_source_sel)
{
@ -439,37 +430,52 @@ void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp
((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle0]))(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tilenum, 0, userdata, object);
//m_tex_pipe.Cycle(&userdata->m_texel0_color, &userdata->m_texel0_color, sss, sst, tilenum, 0, userdata, object);
userdata->m_noise_color.i.r = userdata->m_noise_color.i.g = userdata->m_noise_color.i.b = rand() << 3; // Not accurate
userdata->m_texel0_alpha.set(userdata->m_texel0_color);
rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_alphasub_a[1], *userdata->m_color_inputs.combiner_rgbsub_a_r[1], *userdata->m_color_inputs.combiner_rgbsub_a_g[1], *userdata->m_color_inputs.combiner_rgbsub_a_b[1]);
rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_alphasub_b[1], *userdata->m_color_inputs.combiner_rgbsub_b_r[1], *userdata->m_color_inputs.combiner_rgbsub_b_g[1], *userdata->m_color_inputs.combiner_rgbsub_b_b[1]);
rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_alphamul[1], *userdata->m_color_inputs.combiner_rgbmul_r[1], *userdata->m_color_inputs.combiner_rgbmul_g[1], *userdata->m_color_inputs.combiner_rgbmul_b[1]);
rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_alphaadd[1], *userdata->m_color_inputs.combiner_rgbadd_r[1], *userdata->m_color_inputs.combiner_rgbadd_g[1], *userdata->m_color_inputs.combiner_rgbadd_b[1]);
const UINT8 noise = rand() << 3; // Not accurate
userdata->m_noise_color.set_rgba(0, noise, noise, noise);
rgbsub_a.sign_extend(0x180, 0xfe00);
rgbsub_b.sign_extend(0x180, 0xfe00);
rgbadd.sign_extend(0x180, 0xfe00);
rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
rgbaint_t alphasub_a(*userdata->m_color_inputs.combiner_alphasub_a[0]);
rgbaint_t alphasub_b(*userdata->m_color_inputs.combiner_alphasub_b[0]);
rgbaint_t alphamul(*userdata->m_color_inputs.combiner_alphamul[0]);
rgbaint_t alphaadd(*userdata->m_color_inputs.combiner_alphaadd[0]);
rgbsub_a.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbsub_b.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbmul.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbadd.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
alphasub_a.and_imm_rgba(0xffffffff, 0, 0, 0);
alphasub_b.and_imm_rgba(0xffffffff, 0, 0, 0);
alphamul.and_imm_rgba(0xffffffff, 0, 0, 0);
alphaadd.and_imm_rgba(0xffffffff, 0, 0, 0);
rgbsub_a.or_reg(alphasub_a);
rgbsub_b.or_reg(alphasub_b);
rgbmul.or_reg(alphamul);
rgbadd.or_reg(alphaadd);
rgbsub_a.sign_extend(0x180, 0xfffffe00);
rgbsub_b.sign_extend(0x180, 0xfffffe00);
rgbadd.sign_extend(0x180, 0xfffffe00);
rgbadd.shl(8);
rgbsub_a.sub(rgbsub_b);
rgbsub_a.mul(rgbmul);
rgbsub_a.add(rgbadd);
rgbsub_a.add_imm(0x0080);
rgbsub_a.shr(8);
rgbsub_a.sign_extend(0x100, 0xff00);
rgbsub_a.sra(8);
rgbsub_a.clamp_and_clear(rgbsub_a, 0xfffffe00);
const UINT32 unclamped = rgbsub_a.to_rgba();
userdata->m_pixel_color.i.a = s_special_9bit_clamptable[(unclamped >> 24) & 0xff];
userdata->m_pixel_color.i.r = s_special_9bit_clamptable[(unclamped >> 16) & 0xff];
userdata->m_pixel_color.i.g = s_special_9bit_clamptable[(unclamped >> 8) & 0xff];
userdata->m_pixel_color.i.b = s_special_9bit_clamptable[unclamped & 0xff];
//userdata->m_pixel_color.i.r = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_r[1],*userdata->m_color_inputs.combiner_rgbsub_b_r[1],*userdata->m_color_inputs.combiner_rgbmul_r[1],*userdata->m_color_inputs.combiner_rgbadd_r[1]);
//userdata->m_pixel_color.i.g = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_g[1],*userdata->m_color_inputs.combiner_rgbsub_b_g[1],*userdata->m_color_inputs.combiner_rgbmul_g[1],*userdata->m_color_inputs.combiner_rgbadd_g[1]);
//userdata->m_pixel_color.i.b = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_b[1],*userdata->m_color_inputs.combiner_rgbsub_b_b[1],*userdata->m_color_inputs.combiner_rgbmul_b[1],*userdata->m_color_inputs.combiner_rgbadd_b[1]);
//userdata->m_pixel_color.i.a = alpha_combiner_equation(*userdata->m_color_inputs.combiner_alphasub_a[1],*userdata->m_color_inputs.combiner_alphasub_b[1],*userdata->m_color_inputs.combiner_alphamul[1],*userdata->m_color_inputs.combiner_alphaadd[1]);
userdata->m_pixel_color = rgbsub_a;
//Alpha coverage combiner
get_alpha_cvg(&userdata->m_pixel_color.i.a, userdata, object);
userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
const UINT32 curpixel = fb_index + x;
const UINT32 zbcur = zb + curpixel;
@ -483,15 +489,16 @@ void n64_rdp::span_draw_1cycle(INT32 scanline, const extent_t &extent, const rdp
INT32 adith = 0;
get_dither_values(scanline, j, &cdith, &adith, object);
if (((userdata->m_blend_enable << 2) | blend_index) != 5 && machine().input().code_pressed(KEYCODE_B))
color_t blended_pixel;
bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, userdata, object);
if (machine().input().code_pressed(KEYCODE_S) && blended_pixel.get_r() == 0 && blended_pixel.get_g() == 0 && blended_pixel.get_b() == 0)
{
printf("1:%d\n", (userdata->m_blend_enable << 2) | blend_index);
printf("1:%d ", (userdata->m_blend_enable << 2) | blend_index);
}
bool rendered = ((&m_blender)->*(m_blender.blend1[(userdata->m_blend_enable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, userdata, object);
if (rendered)
{
write_pixel(curpixel, fir, fig, fib, userdata, object);
write_pixel(curpixel, blended_pixel, userdata, object);
if (object.m_other_modes.z_update_en)
{
z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
@ -554,9 +561,9 @@ void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp
m_tex_pipe.calculate_clamp_diffs(tile1, userdata, object);
bool partialreject = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_inv_pixel_color.i.a && userdata->m_color_inputs.blender1b_a[1] == &userdata->m_pixel_color.i.a);
INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color.i.a) ? 1 : 0;
INT32 sel1 = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_memory_color.i.a) ? 1 : 0;
bool partialreject = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_inv_pixel_color && userdata->m_color_inputs.blender1b_a[1] == &userdata->m_pixel_color);
INT32 sel0 = (userdata->m_color_inputs.blender2b_a[0] == &userdata->m_memory_color) ? 1 : 0;
INT32 sel1 = (userdata->m_color_inputs.blender2b_a[1] == &userdata->m_memory_color) ? 1 : 0;
INT32 drinc, dginc, dbinc, dainc;
INT32 dzinc, dzpix;
@ -600,7 +607,6 @@ void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp
INT32 x = xend;
const INT32 length = flip ? (xstart - xend) : (xend - xstart);
INT32 fir, fig, fib;
if(object.m_other_modes.z_source_sel)
{
@ -667,67 +673,99 @@ void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp
((m_tex_pipe).*(m_tex_pipe.m_cycle[cycle1]))(&userdata->m_texel1_color, &userdata->m_texel0_color, sss, sst, tile2, 1, userdata, object);
((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);
userdata->m_noise_color.i.r = userdata->m_noise_color.i.g = userdata->m_noise_color.i.b = rand() << 3; // Not accurate
userdata->m_texel0_alpha.set(userdata->m_texel0_color);
userdata->m_texel1_alpha.set(userdata->m_texel1_color);
userdata->m_next_texel_alpha.set(userdata->m_next_texel_color);
/*rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_alphasub_a[0], *userdata->m_color_inputs.combiner_rgbsub_a_r[0], *userdata->m_color_inputs.combiner_rgbsub_a_g[0], *userdata->m_color_inputs.combiner_rgbsub_a_b[0]);
rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_alphasub_b[0], *userdata->m_color_inputs.combiner_rgbsub_b_r[0], *userdata->m_color_inputs.combiner_rgbsub_b_g[0], *userdata->m_color_inputs.combiner_rgbsub_b_b[0]);
rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_alphamul[0], *userdata->m_color_inputs.combiner_rgbmul_r[0], *userdata->m_color_inputs.combiner_rgbmul_g[0], *userdata->m_color_inputs.combiner_rgbmul_b[0]);
rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_alphaadd[0], *userdata->m_color_inputs.combiner_rgbadd_r[0], *userdata->m_color_inputs.combiner_rgbadd_g[0], *userdata->m_color_inputs.combiner_rgbadd_b[0]);
const UINT8 noise = rand() << 3; // Not accurate
userdata->m_noise_color.set_rgba(0, noise, noise, noise);
rgbsub_a.sign_extend(0x180, 0xfe00);
rgbsub_b.sign_extend(0x180, 0xfe00);
rgbadd.sign_extend(0x180, 0xfe00);
rgbaint_t rgbsub_a(*userdata->m_color_inputs.combiner_rgbsub_a[0]);
rgbaint_t rgbsub_b(*userdata->m_color_inputs.combiner_rgbsub_b[0]);
rgbaint_t rgbmul(*userdata->m_color_inputs.combiner_rgbmul[0]);
rgbaint_t rgbadd(*userdata->m_color_inputs.combiner_rgbadd[0]);
rgbaint_t alphasub_a(*userdata->m_color_inputs.combiner_alphasub_a[0]);
rgbaint_t alphasub_b(*userdata->m_color_inputs.combiner_alphasub_b[0]);
rgbaint_t alphamul(*userdata->m_color_inputs.combiner_alphamul[0]);
rgbaint_t alphaadd(*userdata->m_color_inputs.combiner_alphaadd[0]);
rgbsub_a.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbsub_b.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbmul.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbadd.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
alphasub_a.and_imm_rgba(0xffffffff, 0, 0, 0);
alphasub_b.and_imm_rgba(0xffffffff, 0, 0, 0);
alphamul.and_imm_rgba(0xffffffff, 0, 0, 0);
alphaadd.and_imm_rgba(0xffffffff, 0, 0, 0);
rgbsub_a.or_reg(alphasub_a);
rgbsub_b.or_reg(alphasub_b);
rgbmul.or_reg(alphamul);
rgbadd.or_reg(alphaadd);
rgbsub_a.sign_extend(0x180, 0xfffffe00);
rgbsub_b.sign_extend(0x180, 0xfffffe00);
rgbadd.sign_extend(0x180, 0xfffffe00);
rgbadd.shl(8);
rgbsub_a.sub(rgbsub_b);
rgbsub_a.mul(rgbmul);
rgbsub_a.add(rgbadd);
rgbsub_a.add_imm(0x0080);
rgbsub_a.shr(8);
rgbsub_a.sign_extend(0x100, 0xff00);
rgbsub_a.sra(8);
rgbsub_a.clamp_and_clear(rgbsub_a, 0xfffffe00);
const UINT32 unclamped0 = rgbsub_a.to_rgba();
userdata->m_combined_color.i.a = s_special_9bit_clamptable[(unclamped0 >> 24) & 0xff];
userdata->m_combined_color.i.r = s_special_9bit_clamptable[(unclamped0 >> 16) & 0xff];
userdata->m_combined_color.i.g = s_special_9bit_clamptable[(unclamped0 >> 8) & 0xff];
userdata->m_combined_color.i.b = s_special_9bit_clamptable[unclamped0 & 0xff];*/
userdata->m_combined_color.set(rgbsub_a);
userdata->m_combined_alpha.set(rgbsub_a);
userdata->m_texel0_color.set(userdata->m_texel1_color);
userdata->m_texel0_alpha.set(userdata->m_texel1_alpha);
userdata->m_texel1_color.set(userdata->m_next_texel_color);
userdata->m_texel1_alpha.set(userdata->m_next_texel_alpha);
userdata->m_combined_color.i.r = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_r[0], *userdata->m_color_inputs.combiner_rgbsub_b_r[0], *userdata->m_color_inputs.combiner_rgbmul_r[0], *userdata->m_color_inputs.combiner_rgbadd_r[0]);
userdata->m_combined_color.i.g = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_g[0], *userdata->m_color_inputs.combiner_rgbsub_b_g[0], *userdata->m_color_inputs.combiner_rgbmul_g[0], *userdata->m_color_inputs.combiner_rgbadd_g[0]);
userdata->m_combined_color.i.b = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_b[0], *userdata->m_color_inputs.combiner_rgbsub_b_b[0], *userdata->m_color_inputs.combiner_rgbmul_b[0], *userdata->m_color_inputs.combiner_rgbadd_b[0]);
userdata->m_combined_color.i.a = alpha_combiner_equation(*userdata->m_color_inputs.combiner_alphasub_a[0], *userdata->m_color_inputs.combiner_alphasub_b[0], *userdata->m_color_inputs.combiner_alphamul[0], *userdata->m_color_inputs.combiner_alphaadd[0]);
rgbsub_a = *userdata->m_color_inputs.combiner_rgbsub_a[1];
rgbsub_b = *userdata->m_color_inputs.combiner_rgbsub_b[1];
rgbmul = *userdata->m_color_inputs.combiner_rgbmul[1];
rgbadd = *userdata->m_color_inputs.combiner_rgbadd[1];
/*userdata->m_texel0_color = userdata->m_texel1_color;
userdata->m_texel1_color = userdata->m_next_texel_color;
alphasub_a = *userdata->m_color_inputs.combiner_alphasub_a[1];
alphasub_b = *userdata->m_color_inputs.combiner_alphasub_b[1];
alphamul = *userdata->m_color_inputs.combiner_alphamul[1];
alphaadd = *userdata->m_color_inputs.combiner_alphaadd[1];
rgbsub_a.set_rgba(*userdata->m_color_inputs.combiner_alphasub_a[1], *userdata->m_color_inputs.combiner_rgbsub_a_r[1], *userdata->m_color_inputs.combiner_rgbsub_a_g[1], *userdata->m_color_inputs.combiner_rgbsub_a_b[1]);
rgbsub_b.set_rgba(*userdata->m_color_inputs.combiner_alphasub_b[1], *userdata->m_color_inputs.combiner_rgbsub_b_r[1], *userdata->m_color_inputs.combiner_rgbsub_b_g[1], *userdata->m_color_inputs.combiner_rgbsub_b_b[1]);
rgbmul.set_rgba(*userdata->m_color_inputs.combiner_alphamul[1], *userdata->m_color_inputs.combiner_rgbmul_r[1], *userdata->m_color_inputs.combiner_rgbmul_g[1], *userdata->m_color_inputs.combiner_rgbmul_b[1]);
rgbadd.set(*userdata->m_color_inputs.combiner_alphaadd[1], *userdata->m_color_inputs.combiner_rgbadd_r[1], *userdata->m_color_inputs.combiner_rgbadd_g[1], *userdata->m_color_inputs.combiner_rgbadd_b[1]);
rgbsub_a.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbsub_b.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbmul.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbadd.and_imm_rgba(0, 0xffffffff, 0xffffffff, 0xffffffff);
rgbsub_a.sign_extend(0x180, 0xfe00);
rgbsub_b.sign_extend(0x180, 0xfe00);
rgbadd.sign_extend(0x180, 0xfe00);
alphasub_a.and_imm_rgba(0xffffffff, 0, 0, 0);
alphasub_b.and_imm_rgba(0xffffffff, 0, 0, 0);
alphamul.and_imm_rgba(0xffffffff, 0, 0, 0);
alphaadd.and_imm_rgba(0xffffffff, 0, 0, 0);
rgbsub_a.or_reg(alphasub_a);
rgbsub_b.or_reg(alphasub_b);
rgbmul.or_reg(alphamul);
rgbadd.or_reg(alphaadd);
rgbsub_a.sign_extend(0x180, 0xfffffe00);
rgbsub_b.sign_extend(0x180, 0xfffffe00);
rgbadd.sign_extend(0x180, 0xfffffe00);
rgbadd.shl(8);
rgbsub_a.sub(rgbsub_b);
rgbsub_a.mul(rgbmul);
rgbsub_a.add(rgbadd);
rgbsub_a.add_imm(0x0080);
rgbsub_a.shr(8);
rgbsub_a.sign_extend(0x100, 0xff00);
rgbsub_a.sra(8);
rgbsub_a.clamp_and_clear(rgbsub_a, 0xfffffe00);
const UINT32 unclamped = rgbsub_a.to_rgba();
userdata->m_pixel_color.i.a = s_special_9bit_clamptable[(unclamped >> 24) & 0xff];
userdata->m_pixel_color.i.r = s_special_9bit_clamptable[(unclamped >> 16) & 0xff];
userdata->m_pixel_color.i.g = s_special_9bit_clamptable[(unclamped >> 8) & 0xff];
userdata->m_pixel_color.i.b = s_special_9bit_clamptable[unclamped & 0xff];*/
userdata->m_pixel_color.i.r = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_r[1], *userdata->m_color_inputs.combiner_rgbsub_b_r[1], *userdata->m_color_inputs.combiner_rgbmul_r[1], *userdata->m_color_inputs.combiner_rgbadd_r[1]);
userdata->m_pixel_color.i.g = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_g[1], *userdata->m_color_inputs.combiner_rgbsub_b_g[1], *userdata->m_color_inputs.combiner_rgbmul_g[1], *userdata->m_color_inputs.combiner_rgbadd_g[1]);
userdata->m_pixel_color.i.b = color_combiner_equation(*userdata->m_color_inputs.combiner_rgbsub_a_b[1], *userdata->m_color_inputs.combiner_rgbsub_b_b[1], *userdata->m_color_inputs.combiner_rgbmul_b[1], *userdata->m_color_inputs.combiner_rgbadd_b[1]);
userdata->m_pixel_color.i.a = alpha_combiner_equation(*userdata->m_color_inputs.combiner_alphasub_a[1], *userdata->m_color_inputs.combiner_alphasub_b[1], *userdata->m_color_inputs.combiner_alphamul[1], *userdata->m_color_inputs.combiner_alphaadd[1]);
userdata->m_pixel_color = rgbsub_a;
//Alpha coverage combiner
get_alpha_cvg(&userdata->m_pixel_color.i.a, userdata, object);
userdata->m_pixel_color.set_a(get_alpha_cvg(userdata->m_pixel_color.get_a(), userdata, object));
const UINT32 curpixel = fb_index + x;
const UINT32 zbcur = zb + curpixel;
@ -739,15 +777,16 @@ void n64_rdp::span_draw_2cycle(INT32 scanline, const extent_t &extent, const rdp
{
get_dither_values(scanline, j, &cdith, &adith, object);
if (((userdata->m_blend_enable << 2) | blend_index) != 5 && machine().input().code_pressed(KEYCODE_B))
color_t blended_pixel;
bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(blended_pixel, cdith, adith, partialreject, sel0, sel1, userdata, object);
if (machine().input().code_pressed(KEYCODE_S) && blended_pixel.get_r() == 0 && blended_pixel.get_g() == 0 && blended_pixel.get_b() == 0)
{
printf("2:%d\n", (userdata->m_blend_enable << 2) | blend_index);
printf("2:%d ", (userdata->m_blend_enable << 2) | blend_index);
}
bool rendered = ((&m_blender)->*(m_blender.blend2[(userdata->m_blend_enable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, sel1, userdata, object);
if (rendered)
{
write_pixel(curpixel, fir, fig, fib, userdata, object);
write_pixel(curpixel, blended_pixel, userdata, object);
if (object.m_other_modes.z_update_en)
{
z_store(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
@ -808,9 +847,9 @@ void n64_rdp::span_draw_copy(INT32 scanline, const extent_t &extent, const rdp_p
m_tex_pipe.copy(&userdata->m_texel0_color, sss, sst, tilenum, object, userdata);
UINT32 curpixel = fb_index + x;
if ((userdata->m_texel0_color.i.a != 0) || (!object.m_other_modes.alpha_compare_en))
if ((userdata->m_texel0_color.get_a() != 0) || (!object.m_other_modes.alpha_compare_en))
{
copy_pixel(curpixel, userdata->m_texel0_color.i.r, userdata->m_texel0_color.i.g, userdata->m_texel0_color.i.b, userdata->m_texel0_color.i.a ? 7 : 0, object);
copy_pixel(curpixel, userdata->m_texel0_color, object);
}
}

View File

@ -283,17 +283,15 @@ void n64_texture_pipe_t::cycle_nearest(color_t* TEX, color_t* prev, INT32 SSS, I
{
t0 = *prev;
}
t0.i.r = SIGN9(t0.i.r);
t0.i.g = SIGN9(t0.i.g);
t0.i.b = SIGN9(t0.i.b);
TEX->i.r = t0.i.b + (((newk0 - invk0) * t0.i.g + 0x80) >> 8);
TEX->i.g = t0.i.b + (((newk1 - invk1) * t0.i.r + (newk2 - invk2) * t0.i.g + 0x80) >> 8);
TEX->i.b = t0.i.b + (((newk3 - invk3) * t0.i.r + 0x80) >> 8);
TEX->i.a = t0.i.b;
TEX->i.r &= 0x1ff;
TEX->i.g &= 0x1ff;
TEX->i.b &= 0x1ff;
TEX->i.a &= 0x1ff;
t0.sign_extend(0x00000100, 0xffffff00);
const UINT32 r = t0.get_r();
const UINT32 g = t0.get_g();
TEX->set_rgba(0, (newk0 - invk0) * g + 0x80, (newk1 - invk1) * r + (newk2 - invk2) * g + 0x80, (newk3 - invk3) * g + 0x80);
TEX->shr(8);
TEX->add_imm(t0.get_b());
TEX->and_imm(0x1ff);
}
void n64_texture_pipe_t::cycle_nearest_lerp(color_t* TEX, color_t* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux* userdata, const rdp_poly_state& object)
@ -315,7 +313,7 @@ void n64_texture_pipe_t::cycle_nearest_lerp(color_t* TEX, color_t* prev, INT32 S
UINT32 tbase = tile.tmem + ((tile.line * sst1) & 0x1ff);
TEX->set(((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase, tpal, userdata).get());
*TEX = ((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase, tpal, userdata);
}
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)
@ -371,15 +369,15 @@ void n64_texture_pipe_t::cycle_linear(color_t* TEX, color_t* prev, INT32 SSS, IN
{
t0 = *prev;
}
t0.i.r = SIGN9(t0.i.r); t0.i.g = SIGN9(t0.i.g); t0.i.b = SIGN9(t0.i.b);
TEX->i.r = t0.i.b + (((newk0 - invk0) * t0.i.g + 0x80) >> 8);
TEX->i.g = t0.i.b + (((newk1 - invk1) * t0.i.r + (newk2 - invk2) * t0.i.g + 0x80) >> 8);
TEX->i.b = t0.i.b + (((newk3 - invk3) * t0.i.r + 0x80) >> 8);
TEX->i.a = t0.i.b;
TEX->i.r &= 0x1ff;
TEX->i.g &= 0x1ff;
TEX->i.b &= 0x1ff;
TEX->i.a &= 0x1ff;
t0.sign_extend(0x00000100, 0xffffff00);
const UINT32 r = t0.get_r();
const UINT32 g = t0.get_g();
TEX->set_rgba(0, (newk0 - invk0) * g + 0x80, (newk1 - invk1) * r + (newk2 - invk2) * g + 0x80, (newk3 - invk3) * g + 0x80);
TEX->shr(8);
TEX->add_imm(t0.get_b());
TEX->and_imm(0x1ff);
}
void n64_texture_pipe_t::cycle_linear_lerp(color_t* TEX, color_t* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux* userdata, const rdp_poly_state& object)
@ -429,87 +427,53 @@ void n64_texture_pipe_t::cycle_linear_lerp(color_t* TEX, color_t* prev, INT32 SS
{
if (upper)
{
#if USE_SIMD
rgbaint_t v1_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata).get());
rgbaint_t v2_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata).get());
rgbaint_t v3_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata).get());
rgbaint_t v1_vec = ((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata);
rgbaint_t v2_vec = ((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata);
rgbaint_t v3_vec = ((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata);
v1_vec -= v3_vec;
v2_vec -= v3_vec;
v1_vec.sub(v3_vec);
v2_vec.sub(v3_vec);
v1_vec *= invtf;
v2_vec *= invsf;
v1_vec.mul_imm(invtf);
v2_vec.mul_imm(invsf);
v1_vec += v2_vec;
v1_vec += 0x0080;
v1_vec >>= 8;
v1_vec += v3_vec;
v1_vec.add(v2_vec);
v1_vec.add_imm(0x0080);
v1_vec.sra(8);
v1_vec.add(v3_vec);
TEX->set((UINT32)v1_vec.to_rgba());
#else
color_t t1 = ((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata);
color_t t2 = ((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata);
color_t t3 = ((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata);
TEX->i.r = t3.i.r + (((invsf * (t2.i.r - t3.i.r)) + (invtf * (t1.i.r - t3.i.r)) + 0x80) >> 8);
TEX->i.g = t3.i.g + (((invsf * (t2.i.g - t3.i.g)) + (invtf * (t1.i.g - t3.i.g)) + 0x80) >> 8);
TEX->i.b = t3.i.b + (((invsf * (t2.i.b - t3.i.b)) + (invtf * (t1.i.b - t3.i.b)) + 0x80) >> 8);
TEX->i.a = t3.i.a + (((invsf * (t2.i.a - t3.i.a)) + (invtf * (t1.i.a - t3.i.a)) + 0x80) >> 8);
#endif
*TEX = v1_vec;
}
else
{
#if USE_SIMD
rgbaint_t v0_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata).get());
rgbaint_t v1_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata).get());
rgbaint_t v2_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata).get());
rgbaint_t v0_vec = ((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata);
rgbaint_t v1_vec = ((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata);
rgbaint_t v2_vec = ((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata);
v1_vec -= v0_vec;
v2_vec -= v0_vec;
v1_vec.sub(v0_vec);
v2_vec.sub(v0_vec);
v1_vec *= sfrac;
v2_vec *= tfrac;
v1_vec.mul_imm(sfrac);
v2_vec.mul_imm(tfrac);
v1_vec += v2_vec;
v1_vec += 0x0080;
v1_vec >>= 8;
v1_vec += v0_vec;
v1_vec.add(v2_vec);
v1_vec.add_imm(0x0080);
v1_vec.sra(8);
v1_vec.add(v0_vec);
TEX->set((UINT32)v1_vec.to_rgba());
#else
color_t t0 = ((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata);
color_t t1 = ((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata);
color_t t2 = ((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata);
TEX->i.r = t0.i.r + (((tfrac * (t2.i.r - t0.i.r)) + (sfrac * (t1.i.r - t0.i.r)) + 0x80) >> 8);
TEX->i.g = t0.i.g + (((tfrac * (t2.i.g - t0.i.g)) + (sfrac * (t1.i.g - t0.i.g)) + 0x80) >> 8);
TEX->i.b = t0.i.b + (((tfrac * (t2.i.b - t0.i.b)) + (sfrac * (t1.i.b - t0.i.b)) + 0x80) >> 8);
TEX->i.a = t0.i.a + (((tfrac * (t2.i.a - t0.i.a)) + (sfrac * (t1.i.a - t0.i.a)) + 0x80) >> 8);
#endif
*TEX = v1_vec;
}
}
else
{
#if USE_SIMD
rgbaint_t t0_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata).get());
rgbaint_t t0_vec((rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata));
t0_vec += (rgbaint_t)((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata).get();
t0_vec += (rgbaint_t)((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata).get();
t0_vec += (rgbaint_t)((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata).get();
t0_vec >>= 2;
t0_vec.add(((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata));
t0_vec.add(((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata));
t0_vec.add(((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata));
t0_vec.sra(2);
TEX->set((UINT32)t0_vec.to_rgba());
#else
color_t t0 = ((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase1, tpal, userdata);
color_t t1 = ((this)->*(m_texel_fetch[index]))(sss2, sst1, tbase1, tpal, userdata);
color_t t3 = ((this)->*(m_texel_fetch[index]))(sss2, sst2, tbase2, tpal, userdata);
color_t t2 = ((this)->*(m_texel_fetch[index]))(sss1, sst2, tbase2, tpal, userdata);
TEX->i.r = (t0.i.r + t1.i.r + t2.i.r + t3.i.r) >> 2;
TEX->i.g = (t0.i.g + t1.i.g + t2.i.g + t3.i.r) >> 2;
TEX->i.b = (t0.i.b + t1.i.b + t2.i.b + t3.i.r) >> 2;
TEX->i.a = (t0.i.a + t1.i.a + t2.i.a + t3.i.r) >> 2;
#endif
*TEX = t0_vec;
}
}
@ -530,7 +494,7 @@ void n64_texture_pipe_t::copy(color_t* TEX, INT32 SSS, INT32 SST, UINT32 tilenum
const UINT32 index = (tile.format << 4) | (tile.size << 2) | ((UINT32) object.m_other_modes.en_tlut << 1) | (UINT32) object.m_other_modes.tlut_type;
const UINT32 tbase = tile.tmem + ((tile.line * sst1) & 0x1ff);
TEX->set(((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase, tile.palette, userdata).get());
*TEX = ((this)->*(m_texel_fetch[index]))(sss1, sst1, tbase, tile.palette, userdata);
}
void n64_texture_pipe_t::lod_1cycle(INT32* sss, INT32* sst, const INT32 s, const INT32 t, const INT32 w, const INT32 dsinc, const INT32 dtinc, const INT32 dwinc, rdp_span_aux* userdata, const rdp_poly_state& object)
@ -597,7 +561,7 @@ void n64_texture_pipe_t::lod_1cycle(INT32* sss, INT32* sst, const INT32 s, const
}
}
userdata->m_lod_fraction.i.r = userdata->m_lod_fraction.i.g = userdata->m_lod_fraction.i.b = userdata->m_lod_fraction.i.a = lod_fraction;
userdata->m_lod_fraction.set_rgba(lod_fraction, lod_fraction, lod_fraction, lod_fraction);
/* FIXME: ???
if(object.m_other_modes.sharpen_tex_en && magnify)
{
@ -670,7 +634,7 @@ void n64_texture_pipe_t::lod_2cycle(INT32* sss, INT32* sst, const INT32 s, const
}
}
userdata->m_lod_fraction.i.r = userdata->m_lod_fraction.i.g = userdata->m_lod_fraction.i.b = userdata->m_lod_fraction.i.a = lod_fraction;
userdata->m_lod_fraction.set_rgba(lod_fraction, lod_fraction, lod_fraction, lod_fraction);
/* FIXME: ???
if(object.m_other_modes.sharpen_tex_en && magnify)
@ -893,10 +857,11 @@ color_t n64_texture_pipe_t::fetch_rgba32_raw(INT32 s, INT32 t, INT32 tbase, INT3
{
const INT32 taddr = (((tbase << 2) + s) ^ sTexAddrSwap16[t & 1]) & 0x3ff;
const UINT32 cl = ((UINT16*)userdata->m_tmem)[taddr];
const UINT32 ch = ((UINT16*)userdata->m_tmem)[taddr | 0x400];
const UINT16 cl = ((UINT16*)userdata->m_tmem)[taddr];
const UINT16 ch = ((UINT16*)userdata->m_tmem)[taddr | 0x400];
return color_t(ch, cl >> 8, cl, ch >> 8);
color_t val = color_t(ch & 0xff, cl >> 8, cl & 0xff, ch >> 8);
return val;
}
color_t n64_texture_pipe_t::fetch_nop(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux* userdata) { return 0; }
@ -1031,12 +996,6 @@ color_t n64_texture_pipe_t::fetch_ia4_raw(INT32 s, INT32 t, INT32 tbase, INT32 t
UINT8 i = p & 0xe;
i = (i << 4) | (i << 1) | (i >> 2);
color_t color;
color.i.r = i;
color.i.g = i;
color.i.b = i;
color.i.a = (p & 1) * 0xff;
return color_t((p & 1) * 0xff, i, i, i);
}
@ -1076,12 +1035,6 @@ color_t n64_texture_pipe_t::fetch_ia8_raw(INT32 s, INT32 t, INT32 tbase, INT32 t
UINT8 i = p & 0xf0;
i |= (i >> 4);
color_t color;
color.i.r = i;
color.i.g = i;
color.i.b = i;
color.i.a = (p << 4) | (p & 0xf);
return color_t((p << 4) | (p & 0xf), i, i, i);
}