mirror of
https://github.com/holub/mame
synced 2025-10-05 08:41:31 +03:00
-N64 optimizations: [MooglyGuy]
* Converted PIF RAM from 8-bit array to 32-bit array * Inlined color and alpha combiner equations * Moved a number of calculations in span rendering to outer loops * Flattened branch structure of texel fetching somewhat
This commit is contained in:
parent
419b6f0158
commit
975435ad75
@ -221,7 +221,7 @@ private:
|
||||
void handle_pif();
|
||||
int pif_channel_handle_command(int channel, int slength, UINT8 *sdata, int rlength, UINT8 *rdata);
|
||||
UINT8 calc_mempak_crc(UINT8 *buffer, int length);
|
||||
UINT8 pif_ram[0x40];
|
||||
UINT32 pif_ram[0x10];
|
||||
UINT8 pif_cmd[0x40];
|
||||
UINT32 si_dram_addr;
|
||||
UINT32 si_pif_addr;
|
||||
|
@ -45,40 +45,22 @@ void n64_periphs::reset_tick()
|
||||
switch(cic_type)
|
||||
{
|
||||
case 1:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x06;
|
||||
pif_ram[0x26] = 0x3f;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x00063f3f;
|
||||
break;
|
||||
case 3:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x02;
|
||||
pif_ram[0x26] = 0x78;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0002783f;
|
||||
break;
|
||||
case 5:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x02;
|
||||
pif_ram[0x26] = 0x91;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0002913f;
|
||||
break;
|
||||
case 6:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x02;
|
||||
pif_ram[0x26] = 0x85;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0002853f;
|
||||
break;
|
||||
case 0xd:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x0a;
|
||||
pif_ram[0x26] = 0xdd;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x000add3f;
|
||||
break;
|
||||
default:
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x02;
|
||||
pif_ram[0x26] = 0x3f;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x00023f3f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -213,63 +195,40 @@ void n64_periphs::device_reset()
|
||||
}
|
||||
|
||||
// CIC-NUS-6102 (default)
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x00;
|
||||
pif_ram[0x26] = 0x3f;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x00003f3f;
|
||||
dd_present = false;
|
||||
cic_type=2;
|
||||
mem_map->write_dword(0x00000318, 0x800000);
|
||||
|
||||
if (boot_checksum == U64(0x00000000001ff230))
|
||||
{
|
||||
//printf("64DD detected\n");
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x08;
|
||||
pif_ram[0x26] = 0xdd; // How utterly predictable
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x3fdd0800;
|
||||
dd_present = true;
|
||||
cic_type=0xd;
|
||||
}
|
||||
else if (boot_checksum == U64(0x000000cffb830843) || boot_checksum == U64(0x000000d0027fdf31))
|
||||
{
|
||||
// CIC-NUS-6101
|
||||
//printf("CIC-NUS-6101 detected\n");
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x04;
|
||||
pif_ram[0x26] = 0x3f;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x00043f3f;
|
||||
cic_type=1;
|
||||
}
|
||||
else if (boot_checksum == U64(0x000000d6499e376b))
|
||||
{
|
||||
// CIC-NUS-6103
|
||||
//printf("CIC-NUS-6103 detected\n");
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x00;
|
||||
pif_ram[0x26] = 0x78;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0000783f;
|
||||
cic_type=3;
|
||||
}
|
||||
else if (boot_checksum == U64(0x0000011a4a1604b6))
|
||||
{
|
||||
// CIC-NUS-6105
|
||||
//printf("CIC-NUS-6105 detected\n");
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x00;
|
||||
pif_ram[0x26] = 0x91;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0000913f;
|
||||
cic_type=5;
|
||||
mem_map->write_dword(0x000003f0, 0x800000);
|
||||
}
|
||||
else if (boot_checksum == U64(0x000000d6d5de4ba0))
|
||||
{
|
||||
// CIC-NUS-6106
|
||||
//printf("CIC-NUS-6106 detected\n");
|
||||
pif_ram[0x24] = 0x00;
|
||||
pif_ram[0x25] = 0x00;
|
||||
pif_ram[0x26] = 0x85;
|
||||
pif_ram[0x27] = 0x3f;
|
||||
pif_ram[0x09] = 0x0000853f;
|
||||
cic_type=6;
|
||||
}
|
||||
else
|
||||
@ -2002,15 +1961,7 @@ int n64_periphs::pif_channel_handle_command(int channel, int slength, UINT8 *sda
|
||||
|
||||
void n64_periphs::handle_pif()
|
||||
{
|
||||
/*printf("Before:\n"); fflush(stdout);
|
||||
for(int i = 0; i < 0x40; i++)
|
||||
{
|
||||
printf("%02x ", pif_cmd[i]);
|
||||
if((i & 0xf) == 0xf)
|
||||
{
|
||||
printf("\n"); fflush(stdout);
|
||||
}
|
||||
}*/
|
||||
UINT8 *ram = (UINT8*)pif_ram;
|
||||
if(pif_cmd[0x3f] == 0x1) // only handle the command if the last byte is 1
|
||||
{
|
||||
int channel = 0;
|
||||
@ -2064,13 +2015,14 @@ void n64_periphs::handle_pif()
|
||||
}
|
||||
for(int j = 0; j < bytes_to_recv; j++)
|
||||
{
|
||||
pif_ram[cmd_ptr++] = recv_buffer[j];
|
||||
ram[cmd_ptr ^ BYTE4_XOR_BE(0)] = recv_buffer[j];
|
||||
cmd_ptr++;
|
||||
}
|
||||
}
|
||||
else if (res == 1)
|
||||
{
|
||||
int offset = 0;//bytes_to_send;
|
||||
pif_ram[cmd_ptr-offset-2] |= 0x80;
|
||||
ram[(cmd_ptr - offset - 2) ^ BYTE4_XOR_BE(0)] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2078,7 +2030,7 @@ void n64_periphs::handle_pif()
|
||||
}
|
||||
}
|
||||
|
||||
pif_ram[0x3f] = 0;
|
||||
ram[0x3f ^ BYTE4_XOR_BE(0)] = 0;
|
||||
}
|
||||
|
||||
/*printf("After:\n"); fflush(stdout);
|
||||
@ -2094,7 +2046,7 @@ void n64_periphs::handle_pif()
|
||||
|
||||
void n64_periphs::pif_dma(int direction)
|
||||
{
|
||||
UINT32 *src, *dst;
|
||||
UINT8 *ram = (UINT8*)pif_ram;
|
||||
|
||||
if (si_dram_addr & 0x3)
|
||||
{
|
||||
@ -2103,15 +2055,12 @@ void n64_periphs::pif_dma(int direction)
|
||||
|
||||
if (direction) // RDRAM -> PIF RAM
|
||||
{
|
||||
src = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4];
|
||||
UINT32 *src = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4];
|
||||
|
||||
for(int i = 0; i < 64; i+=4)
|
||||
{
|
||||
UINT32 d = *src++;
|
||||
pif_ram[i+0] = (d >> 24) & 0xff;
|
||||
pif_ram[i+1] = (d >> 16) & 0xff;
|
||||
pif_ram[i+2] = (d >> 8) & 0xff;
|
||||
pif_ram[i+3] = (d >> 0) & 0xff;
|
||||
ram[i >> 2] = *src;
|
||||
src++;
|
||||
}
|
||||
|
||||
memcpy(pif_cmd, pif_ram, 0x40);
|
||||
@ -2120,17 +2069,12 @@ void n64_periphs::pif_dma(int direction)
|
||||
{
|
||||
handle_pif();
|
||||
|
||||
dst = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4];
|
||||
UINT32 *dst = (UINT32*)&rdram[(si_dram_addr & 0x1fffffff) / 4];
|
||||
|
||||
for(int i = 0; i < 64; i+=4)
|
||||
{
|
||||
UINT32 d = 0;
|
||||
d |= pif_ram[i+0] << 24;
|
||||
d |= pif_ram[i+1] << 16;
|
||||
d |= pif_ram[i+2] << 8;
|
||||
d |= pif_ram[i+3] << 0;
|
||||
|
||||
*dst++ = d;
|
||||
*dst = ram[i >> 2];
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2403,28 +2347,12 @@ READ32_MEMBER( n64_periphs::pif_ram_r )
|
||||
return cic_status;
|
||||
}
|
||||
}
|
||||
return ( ( pif_ram[offset*4+0] << 24 ) | ( pif_ram[offset*4+1] << 16 ) | ( pif_ram[offset*4+2] << 8 ) | ( pif_ram[offset*4+3] << 0 ) ) & mem_mask;
|
||||
return pif_ram[offset] & mem_mask;
|
||||
}
|
||||
|
||||
WRITE32_MEMBER( n64_periphs::pif_ram_w )
|
||||
{
|
||||
if( mem_mask & 0xff000000 )
|
||||
{
|
||||
pif_ram[offset*4+0] = ( data >> 24 ) & 0x000000ff;
|
||||
}
|
||||
if( mem_mask & 0x00ff0000 )
|
||||
{
|
||||
pif_ram[offset*4+1] = ( data >> 16 ) & 0x000000ff;
|
||||
}
|
||||
if( mem_mask & 0x0000ff00 )
|
||||
{
|
||||
pif_ram[offset*4+2] = ( data >> 8 ) & 0x000000ff;
|
||||
}
|
||||
if( mem_mask & 0x000000ff )
|
||||
{
|
||||
pif_ram[offset*4+3] = ( data >> 0 ) & 0x000000ff;
|
||||
}
|
||||
|
||||
COMBINE_DATA(&pif_ram[offset]);
|
||||
signal_rcp_interrupt(SI_INTERRUPT);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,8 @@ TODO:
|
||||
|
||||
static FILE *rdp_exec;
|
||||
|
||||
UINT32 n64_rdp::s_special_9bit_clamptable[512];
|
||||
|
||||
bool n64_rdp::rdp_range_check(UINT32 addr)
|
||||
{
|
||||
if(MiscState.FBSize == 0) return false;
|
||||
@ -413,7 +415,7 @@ INT32 n64_rdp::ColorCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d)
|
||||
d = KURT_AKELEY_SIGN9(d);
|
||||
a = (((a - b) * c) + (d << 8) + 0x80);
|
||||
a = SIGN17(a) >> 8;
|
||||
a = m_special_9bit_clamptable[a & 0x1ff];
|
||||
a = s_special_9bit_clamptable[a & 0x1ff];
|
||||
return a;
|
||||
}
|
||||
|
||||
@ -425,61 +427,10 @@ INT32 n64_rdp::AlphaCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d)
|
||||
d = KURT_AKELEY_SIGN9(d);
|
||||
a = (((a - b) * c) + (d << 8) + 0x80) >> 8;
|
||||
a = SIGN9(a);
|
||||
a = m_special_9bit_clamptable[a & 0x1ff];
|
||||
a = s_special_9bit_clamptable[a & 0x1ff];
|
||||
return a;
|
||||
}
|
||||
|
||||
void n64_rdp::ColorCombiner1Cycle(rdp_span_aux *userdata)
|
||||
{
|
||||
userdata->NoiseColor.i.r = userdata->NoiseColor.i.g = userdata->NoiseColor.i.b = GetRandom() << 3; // Not accurate
|
||||
|
||||
userdata->PixelColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[1],*userdata->ColorInputs.combiner_rgbsub_b_r[1],*userdata->ColorInputs.combiner_rgbmul_r[1],*userdata->ColorInputs.combiner_rgbadd_r[1]);
|
||||
userdata->PixelColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[1],*userdata->ColorInputs.combiner_rgbsub_b_g[1],*userdata->ColorInputs.combiner_rgbmul_g[1],*userdata->ColorInputs.combiner_rgbadd_g[1]);
|
||||
userdata->PixelColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[1],*userdata->ColorInputs.combiner_rgbsub_b_b[1],*userdata->ColorInputs.combiner_rgbmul_b[1],*userdata->ColorInputs.combiner_rgbadd_b[1]);
|
||||
userdata->PixelColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[1],*userdata->ColorInputs.combiner_alphasub_b[1],*userdata->ColorInputs.combiner_alphamul[1],*userdata->ColorInputs.combiner_alphaadd[1]);
|
||||
}
|
||||
|
||||
void n64_rdp::ColorCombiner2Cycle(rdp_span_aux *userdata)
|
||||
{
|
||||
userdata->NoiseColor.i.r = userdata->NoiseColor.i.g = userdata->NoiseColor.i.b = GetRandom() << 3; // Not accurate
|
||||
userdata->CombinedColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_r[0]);
|
||||
userdata->CombinedColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_g[0]);
|
||||
userdata->CombinedColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_b[0]);
|
||||
userdata->CombinedColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[0],
|
||||
*userdata->ColorInputs.combiner_alphasub_b[0],
|
||||
*userdata->ColorInputs.combiner_alphamul[0],
|
||||
*userdata->ColorInputs.combiner_alphaadd[0]);
|
||||
|
||||
userdata->Texel0Color = userdata->Texel1Color;
|
||||
userdata->Texel1Color = userdata->NextTexelColor;
|
||||
|
||||
userdata->PixelColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_r[1]);
|
||||
userdata->PixelColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_g[1]);
|
||||
userdata->PixelColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_b[1]);
|
||||
userdata->PixelColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[1],
|
||||
*userdata->ColorInputs.combiner_alphasub_b[1],
|
||||
*userdata->ColorInputs.combiner_alphamul[1],
|
||||
*userdata->ColorInputs.combiner_alphaadd[1]);
|
||||
}
|
||||
|
||||
void n64_rdp::SetSubAInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata)
|
||||
{
|
||||
switch (code & 0xf)
|
||||
@ -3782,13 +3733,13 @@ n64_rdp::n64_rdp(n64_state &state) : poly_manager<UINT32, rdp_poly_state, 8, 320
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
m_special_9bit_clamptable[i] = i & 0xff;
|
||||
s_special_9bit_clamptable[i] = i & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
m_special_9bit_clamptable[i] = 0xff;
|
||||
s_special_9bit_clamptable[i] = 0xff;
|
||||
break;
|
||||
case 3:
|
||||
m_special_9bit_clamptable[i] = 0;
|
||||
s_special_9bit_clamptable[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -56,7 +56,7 @@
|
||||
#define MEM16_LIMIT 0x3fffff
|
||||
#define MEM32_LIMIT 0x1fffff
|
||||
|
||||
#define RDP_RANGE_CHECK (1)
|
||||
#define RDP_RANGE_CHECK (0)
|
||||
|
||||
#if RDP_RANGE_CHECK
|
||||
#define CHECK8(in) if(rdp_range_check((in))) { printf("Check8: Address %08x out of range!\n", (in)); fflush(stdout); fatalerror("Address %08x out of range!\n", (in)); }
|
||||
@ -458,8 +458,6 @@ class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
|
||||
// Color Combiner
|
||||
INT32 ColorCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d);
|
||||
INT32 AlphaCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d);
|
||||
void ColorCombiner2Cycle(rdp_span_aux *userdata);
|
||||
void ColorCombiner1Cycle(rdp_span_aux *userdata);
|
||||
void SetSubAInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
|
||||
void SetSubBInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
|
||||
void SetMulInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
|
||||
@ -562,8 +560,6 @@ class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
|
||||
|
||||
void GetDitherValues(int x, int y, int* cdith, int* adith, const rdp_poly_state &object);
|
||||
|
||||
UINT32* GetSpecial9BitClampTable() { return m_special_9bit_clamptable; }
|
||||
|
||||
UINT16 decompress_cvmask_frombyte(UINT8 x);
|
||||
void lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy, rdp_span_aux *userdata);
|
||||
|
||||
@ -665,7 +661,7 @@ class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
|
||||
INT32 m_gamma_table[256];
|
||||
INT32 m_gamma_dither_table[0x4000];
|
||||
|
||||
UINT32 m_special_9bit_clamptable[512];
|
||||
static UINT32 s_special_9bit_clamptable[512];
|
||||
|
||||
Writer _Write[16];
|
||||
Reader _Read[4];
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include "includes/n64.h"
|
||||
#include "video/n64.h"
|
||||
|
||||
#define LookUpCC(A, B, C, D) m_rdp->GetCCLUT2()[(m_rdp->GetCCLUT1()[(A << 16) | (B << 8) | C] << 8) | D]
|
||||
#define LookUpCC(A, B, C, D) GetCCLUT2()[(GetCCLUT1()[(A << 16) | (B << 8) | C] << 8) | D]
|
||||
|
||||
void n64_rdp::RenderSpans(int start, int end, int tilenum, bool flip, extent_t *Spans, bool rect, rdp_poly_state *object)
|
||||
{
|
||||
@ -81,10 +81,10 @@ void n64_rdp::RenderSpans(int start, int end, int tilenum, bool flip, extent_t *
|
||||
|
||||
void n64_rdp::RGBAZClip(int sr, int sg, int sb, int sa, int *sz, rdp_span_aux *userdata)
|
||||
{
|
||||
userdata->ShadeColor.i.r = m_special_9bit_clamptable[sr & 0x1ff];
|
||||
userdata->ShadeColor.i.g = m_special_9bit_clamptable[sg & 0x1ff];
|
||||
userdata->ShadeColor.i.b = m_special_9bit_clamptable[sb & 0x1ff];
|
||||
userdata->ShadeColor.i.a = m_special_9bit_clamptable[sa & 0x1ff];
|
||||
userdata->ShadeColor.i.r = s_special_9bit_clamptable[sr & 0x1ff];
|
||||
userdata->ShadeColor.i.g = s_special_9bit_clamptable[sg & 0x1ff];
|
||||
userdata->ShadeColor.i.b = s_special_9bit_clamptable[sb & 0x1ff];
|
||||
userdata->ShadeColor.i.a = s_special_9bit_clamptable[sa & 0x1ff];
|
||||
|
||||
INT32 zanded = (*sz) & 0x60000;
|
||||
|
||||
@ -134,7 +134,6 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
{
|
||||
int clipx1 = object.Scissor.m_xh;
|
||||
int clipx2 = object.Scissor.m_xl;
|
||||
n64_rdp *m_rdp = object.m_rdp;
|
||||
int tilenum = object.tilenum;
|
||||
bool flip = object.flip;
|
||||
|
||||
@ -157,7 +156,7 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
INT32 m_clamp_s_diff[8];
|
||||
INT32 m_clamp_t_diff[8];
|
||||
m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
bool partialreject = (userdata->ColorInputs.blender2b_a[0] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[0] == &userdata->PixelColor.i.a);
|
||||
int sel0 = (OtherModes.force_blend ? 2 : 0) | ((userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a) ? 1 : 0);
|
||||
@ -209,8 +208,21 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
|
||||
int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
|
||||
int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
|
||||
int cycle0 = ((object.OtherModes.sample_type & 1) << 1) | (object.OtherModes.bi_lerp0 & 1);
|
||||
int acmode = (object.OtherModes.alpha_compare_en ? 2 : 0) | (object.OtherModes.dither_alpha_en ? 1 : 0);
|
||||
|
||||
INT32 sss = 0;
|
||||
INT32 sst = 0;
|
||||
|
||||
if (object.OtherModes.persp_tex_en)
|
||||
{
|
||||
TCDiv(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
TCDivNoPersp(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
|
||||
}
|
||||
|
||||
userdata->m_start_span = true;
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
@ -218,44 +230,27 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
int sg = g.w >> 14;
|
||||
int sb = b.w >> 14;
|
||||
int sa = a.w >> 14;
|
||||
int ss = s.w >> 16;
|
||||
int st = t.w >> 16;
|
||||
int sw = w.w >> 16;
|
||||
int sz = (z.w >> 10) & 0x3fffff;
|
||||
INT32 sss = 0;
|
||||
INT32 sst = 0;
|
||||
|
||||
bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
|
||||
|
||||
if (x >= clipx1 && x < clipx2 && valid_x)
|
||||
{
|
||||
m_rdp->lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
|
||||
lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
|
||||
|
||||
if (userdata->m_start_span)
|
||||
{
|
||||
if (object.OtherModes.persp_tex_en)
|
||||
{
|
||||
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->TCDivNoPersp(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sss = userdata->m_precomp_s;
|
||||
sst = userdata->m_precomp_t;
|
||||
}
|
||||
|
||||
m_rdp->TexPipe.LOD1Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
|
||||
TexPipe.LOD1Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
|
||||
|
||||
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
|
||||
RGBAZClip(sr, sg, sb, sa, &sz, userdata);
|
||||
|
||||
m_rdp->TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tilenum, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
((TexPipe).*(TexPipe.cycle[cycle0]))(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tilenum, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
//TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tilenum, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
m_rdp->ColorCombiner1Cycle(userdata);
|
||||
userdata->NoiseColor.i.r = userdata->NoiseColor.i.g = userdata->NoiseColor.i.b = rand() << 3; // Not accurate
|
||||
|
||||
userdata->PixelColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[1],*userdata->ColorInputs.combiner_rgbsub_b_r[1],*userdata->ColorInputs.combiner_rgbmul_r[1],*userdata->ColorInputs.combiner_rgbadd_r[1]);
|
||||
userdata->PixelColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[1],*userdata->ColorInputs.combiner_rgbsub_b_g[1],*userdata->ColorInputs.combiner_rgbmul_g[1],*userdata->ColorInputs.combiner_rgbadd_g[1]);
|
||||
userdata->PixelColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[1],*userdata->ColorInputs.combiner_rgbsub_b_b[1],*userdata->ColorInputs.combiner_rgbmul_b[1],*userdata->ColorInputs.combiner_rgbadd_b[1]);
|
||||
userdata->PixelColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[1],*userdata->ColorInputs.combiner_alphasub_b[1],*userdata->ColorInputs.combiner_alphamul[1],*userdata->ColorInputs.combiner_alphaadd[1]);
|
||||
|
||||
//Alpha coverage combiner
|
||||
GetAlphaCvg(&userdata->PixelColor.i.a, userdata, object);
|
||||
@ -266,11 +261,11 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
((this)->*(_Read[read_index]))(curpixel, userdata, object);
|
||||
|
||||
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
|
||||
if(ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
|
||||
{
|
||||
m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
|
||||
GetDitherValues(scanline, j, &cdith, &adith, object);
|
||||
|
||||
bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, acmode, userdata, object);
|
||||
bool rendered = ((&Blender)->*(Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, acmode, userdata, object);
|
||||
|
||||
if (rendered)
|
||||
{
|
||||
@ -278,10 +273,13 @@ void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
if (object.OtherModes.z_update_en)
|
||||
{
|
||||
m_rdp->ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
|
||||
ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sss = userdata->m_precomp_s;
|
||||
sst = userdata->m_precomp_t;
|
||||
}
|
||||
|
||||
r.w += drinc;
|
||||
@ -301,7 +299,6 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
{
|
||||
int clipx1 = object.Scissor.m_xh;
|
||||
int clipx2 = object.Scissor.m_xl;
|
||||
n64_rdp *m_rdp = object.m_rdp;
|
||||
int tilenum = object.tilenum;
|
||||
bool flip = object.flip;
|
||||
|
||||
@ -316,7 +313,6 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
UINT32 zb = object.MiscState.ZBAddress >> 1;
|
||||
UINT32 zhb = object.MiscState.ZBAddress;
|
||||
UINT8 offx = 0, offy = 0;
|
||||
|
||||
INT32 tile2 = (tilenum + 1) & 7;
|
||||
INT32 tile1 = tilenum;
|
||||
@ -330,7 +326,7 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
INT32 m_clamp_s_diff[8];
|
||||
INT32 m_clamp_t_diff[8];
|
||||
m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
bool partialreject = (userdata->ColorInputs.blender2b_a[1] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[1] == &userdata->PixelColor.i.a);
|
||||
int sel0 = (OtherModes.force_blend ? 2 : 0) | ((userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a) ? 1 : 0);
|
||||
@ -371,8 +367,22 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
|
||||
int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
|
||||
int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
|
||||
int cycle0 = ((object.OtherModes.sample_type & 1) << 1) | (object.OtherModes.bi_lerp0 & 1);
|
||||
int cycle1 = ((object.OtherModes.sample_type & 1) << 1) | (object.OtherModes.bi_lerp1 & 1);
|
||||
int acmode = (object.OtherModes.alpha_compare_en ? 2 : 0) | (object.OtherModes.dither_alpha_en ? 1 : 0);
|
||||
|
||||
INT32 sss = 0;
|
||||
INT32 sst = 0;
|
||||
|
||||
if (object.OtherModes.persp_tex_en)
|
||||
{
|
||||
TCDiv(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
TCDivNoPersp(s.w >> 16, t.w >> 16, w.w >> 16, &sss, &sst);
|
||||
}
|
||||
|
||||
userdata->m_start_span = true;
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
@ -380,12 +390,7 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
int sg = g.w >> 14;
|
||||
int sb = b.w >> 14;
|
||||
int sa = a.w >> 14;
|
||||
int ss = s.h.h;
|
||||
int st = t.h.h;
|
||||
int sw = w.h.h;
|
||||
int sz = (z.w >> 10) & 0x3fffff;
|
||||
INT32 sss = 0;
|
||||
INT32 sst = 0;
|
||||
Color c1;
|
||||
Color c2;
|
||||
|
||||
@ -393,40 +398,66 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
if (x >= clipx1 && x < clipx2 && valid_x)
|
||||
{
|
||||
m_rdp->lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
|
||||
UINT32 compidx = compressed_cvmasks[userdata->m_cvg[x]];
|
||||
userdata->CurrentPixCvg = cvarray[compidx].cvg;
|
||||
userdata->CurrentCvgBit = cvarray[compidx].cvbit;
|
||||
UINT8 offx = cvarray[compidx].xoff;
|
||||
UINT8 offy = cvarray[compidx].yoff;
|
||||
//lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
|
||||
|
||||
if (userdata->m_start_span)
|
||||
{
|
||||
if (object.OtherModes.persp_tex_en)
|
||||
{
|
||||
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->TCDivNoPersp(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sss = userdata->m_precomp_s;
|
||||
sst = userdata->m_precomp_t;
|
||||
}
|
||||
|
||||
m_rdp->TexPipe.LOD2Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
|
||||
TexPipe.LOD2Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
|
||||
|
||||
news = userdata->m_precomp_s;
|
||||
newt = userdata->m_precomp_t;
|
||||
m_rdp->TexPipe.LOD2CycleLimited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
|
||||
TexPipe.LOD2CycleLimited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
|
||||
|
||||
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
|
||||
RGBAZClip(sr, sg, sb, sa, &sz, userdata);
|
||||
|
||||
m_rdp->TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tile1, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
m_rdp->TexPipe.Cycle(&userdata->Texel1Color, &userdata->Texel0Color, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
((TexPipe).*(TexPipe.cycle[cycle0]))(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tile1, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
((TexPipe).*(TexPipe.cycle[cycle1]))(&userdata->Texel1Color, &userdata->Texel0Color, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
((TexPipe).*(TexPipe.cycle[cycle1]))(&userdata->NextTexelColor, &userdata->NextTexelColor, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
//TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tile1, 0, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
//TexPipe.Cycle(&userdata->Texel1Color, &userdata->Texel0Color, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
//TexPipe.Cycle(&userdata->NextTexelColor, &userdata->NextTexelColor, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
m_rdp->TexPipe.Cycle(&userdata->NextTexelColor, &userdata->NextTexelColor, sss, sst, tile2, 1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
userdata->NoiseColor.i.r = userdata->NoiseColor.i.g = userdata->NoiseColor.i.b = rand() << 3; // Not accurate
|
||||
userdata->CombinedColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_r[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_r[0]);
|
||||
userdata->CombinedColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_g[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_g[0]);
|
||||
userdata->CombinedColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbmul_b[0],
|
||||
*userdata->ColorInputs.combiner_rgbadd_b[0]);
|
||||
userdata->CombinedColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[0],
|
||||
*userdata->ColorInputs.combiner_alphasub_b[0],
|
||||
*userdata->ColorInputs.combiner_alphamul[0],
|
||||
*userdata->ColorInputs.combiner_alphaadd[0]);
|
||||
|
||||
m_rdp->ColorCombiner2Cycle(userdata);
|
||||
userdata->Texel0Color = userdata->Texel1Color;
|
||||
userdata->Texel1Color = userdata->NextTexelColor;
|
||||
|
||||
userdata->PixelColor.i.r = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_r[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_r[1]);
|
||||
userdata->PixelColor.i.g = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_g[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_g[1]);
|
||||
userdata->PixelColor.i.b = ColorCombinerEquation(*userdata->ColorInputs.combiner_rgbsub_a_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbsub_b_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbmul_b[1],
|
||||
*userdata->ColorInputs.combiner_rgbadd_b[1]);
|
||||
userdata->PixelColor.i.a = AlphaCombinerEquation(*userdata->ColorInputs.combiner_alphasub_a[1],
|
||||
*userdata->ColorInputs.combiner_alphasub_b[1],
|
||||
*userdata->ColorInputs.combiner_alphamul[1],
|
||||
*userdata->ColorInputs.combiner_alphaadd[1]);
|
||||
|
||||
//Alpha coverage combiner
|
||||
GetAlphaCvg(&userdata->PixelColor.i.a, userdata, object);
|
||||
@ -437,21 +468,23 @@ void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_p
|
||||
|
||||
((this)->*(_Read[read_index]))(curpixel, userdata, object);
|
||||
|
||||
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
|
||||
if(ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
|
||||
{
|
||||
m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
|
||||
GetDitherValues(scanline, j, &cdith, &adith, object);
|
||||
|
||||
bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, sel1, acmode, userdata, object);
|
||||
bool rendered = ((&Blender)->*(Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, sel1, acmode, userdata, object);
|
||||
|
||||
if (rendered)
|
||||
{
|
||||
((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
|
||||
if (object.OtherModes.z_update_en)
|
||||
{
|
||||
m_rdp->ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
|
||||
ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
|
||||
}
|
||||
}
|
||||
}
|
||||
sss = userdata->m_precomp_s;
|
||||
sst = userdata->m_precomp_t;
|
||||
}
|
||||
|
||||
r.w += drinc;
|
||||
@ -471,7 +504,6 @@ void n64_rdp::SpanDrawCopy(INT32 scanline, const extent_t &extent, const rdp_pol
|
||||
{
|
||||
int clipx1 = object.Scissor.m_xh;
|
||||
int clipx2 = object.Scissor.m_xl;
|
||||
n64_rdp *m_rdp = object.m_rdp;
|
||||
int tilenum = object.tilenum;
|
||||
bool flip = object.flip;
|
||||
|
||||
@ -503,7 +535,7 @@ void n64_rdp::SpanDrawCopy(INT32 scanline, const extent_t &extent, const rdp_pol
|
||||
{
|
||||
INT32 sss = s.h.h;
|
||||
INT32 sst = t.h.h;
|
||||
m_rdp->TexPipe.Copy(&userdata->Texel0Color, sss, sst, tilenum, object, userdata);
|
||||
TexPipe.Copy(&userdata->Texel0Color, sss, sst, tilenum, object, userdata);
|
||||
|
||||
UINT32 curpixel = fb_index + x;
|
||||
if ((userdata->Texel0Color.i.a != 0) || (!object.OtherModes.alpha_compare_en))
|
||||
|
@ -36,41 +36,61 @@ void N64TexturePipeT::SetMachine(running_machine &machine)
|
||||
|
||||
void N64TexturePipeT::Mask(INT32* S, INT32* T, INT32 num, const rdp_poly_state& object)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
|
||||
if (tile[num].mask_s)
|
||||
if (tiles[num].mask_s)
|
||||
{
|
||||
INT32 wrap = *S >> (tile[num].mask_s > 10 ? 10 : tile[num].mask_s);
|
||||
INT32 wrap = *S >> (tiles[num].mask_s > 10 ? 10 : tiles[num].mask_s);
|
||||
wrap &= 1;
|
||||
if (tile[num].ms && wrap)
|
||||
if (tiles[num].ms && wrap)
|
||||
{
|
||||
*S = (~(*S));
|
||||
}
|
||||
*S &= m_maskbits_table[tile[num].mask_s];
|
||||
*S &= m_maskbits_table[tiles[num].mask_s];
|
||||
}
|
||||
|
||||
if (tile[num].mask_t)
|
||||
if (tiles[num].mask_t)
|
||||
{
|
||||
INT32 wrap = *T >> (tile[num].mask_t > 10 ? 10 : tile[num].mask_t);
|
||||
INT32 wrap = *T >> (tiles[num].mask_t > 10 ? 10 : tiles[num].mask_t);
|
||||
wrap &= 1;
|
||||
if (tile[num].mt && wrap)
|
||||
if (tiles[num].mt && wrap)
|
||||
{
|
||||
*T = (~(*T));
|
||||
}
|
||||
*T &= m_maskbits_table[tile[num].mask_t];
|
||||
*T &= m_maskbits_table[tiles[num].mask_t];
|
||||
}
|
||||
}
|
||||
|
||||
#define MASK_COUPLED(param, param1, num, coord) \
|
||||
if (tiles[num].mask_##coord) \
|
||||
{ \
|
||||
INT32 maskbits_##coord = m_maskbits_table[tiles[num].mask_##coord]; \
|
||||
if (tiles[num].m##coord) \
|
||||
{ \
|
||||
INT32 wrapthreshold = tiles[num].mask_##coord > 10 ? 10 : tiles[num].mask_##coord; \
|
||||
if ((param >> wrapthreshold) & 1) \
|
||||
{ \
|
||||
param = ~param; \
|
||||
} \
|
||||
if ((param1 >> wrapthreshold) & 1) \
|
||||
{ \
|
||||
param1 = ~param1; \
|
||||
} \
|
||||
} \
|
||||
param &= maskbits_##coord; \
|
||||
param1 &= maskbits_##coord; \
|
||||
}
|
||||
|
||||
void N64TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num, const rdp_poly_state& object)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
|
||||
if (tile[num].mask_s)
|
||||
if (tiles[num].mask_s)
|
||||
{
|
||||
INT32 maskbits_s = m_maskbits_table[tile[num].mask_s];
|
||||
if (tile[num].ms)
|
||||
INT32 maskbits_s = m_maskbits_table[tiles[num].mask_s];
|
||||
if (tiles[num].ms)
|
||||
{
|
||||
INT32 swrapthreshold = tile[num].mask_s > 10 ? 10 : tile[num].mask_s;
|
||||
INT32 swrapthreshold = tiles[num].mask_s > 10 ? 10 : tiles[num].mask_s;
|
||||
INT32 wrap = (*S >> swrapthreshold) & 1;
|
||||
INT32 wrap1 = (*S1 >> swrapthreshold) & 1;
|
||||
if (wrap)
|
||||
@ -86,12 +106,12 @@ void N64TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT3
|
||||
*S1 &= maskbits_s;
|
||||
}
|
||||
|
||||
if (tile[num].mask_t)
|
||||
if (tiles[num].mask_t)
|
||||
{
|
||||
INT32 maskbits_t = m_maskbits_table[tile[num].mask_t];
|
||||
if (tile[num].mt)
|
||||
INT32 maskbits_t = m_maskbits_table[tiles[num].mask_t];
|
||||
if (tiles[num].mt)
|
||||
{
|
||||
INT32 twrapthreshold = tile[num].mask_t > 10 ? 10 : tile[num].mask_t;
|
||||
INT32 twrapthreshold = tiles[num].mask_t > 10 ? 10 : tiles[num].mask_t;
|
||||
INT32 wrap = (*T >> twrapthreshold) & 1;
|
||||
INT32 wrap1 = (*T1 >> twrapthreshold) & 1;
|
||||
if (wrap)
|
||||
@ -108,66 +128,100 @@ void N64TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT3
|
||||
}
|
||||
}
|
||||
|
||||
#define SHIFT_CYCLE(param, max, num, coord) \
|
||||
param = SIGN16(param); \
|
||||
if (tiles[num].shift_##coord < 11) \
|
||||
{ \
|
||||
param >>= tiles[num].shift_##coord; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
param <<= (16 - tiles[num].shift_##coord); \
|
||||
} \
|
||||
param = SIGN16(param); \
|
||||
max = ((param >> 3) >= tiles[num].coord##h);
|
||||
|
||||
void N64TexturePipeT::ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num, const rdp_poly_state& object)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
*S = SIGN16(*S);
|
||||
*T = SIGN16(*T);
|
||||
if (tile[num].shift_s < 11)
|
||||
if (tiles[num].shift_s < 11)
|
||||
{
|
||||
*S >>= tile[num].shift_s;
|
||||
*S >>= tiles[num].shift_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
*S <<= (16 - tile[num].shift_s);
|
||||
*S <<= (16 - tiles[num].shift_s);
|
||||
}
|
||||
*S = SIGN16(*S);
|
||||
if (tile[num].shift_t < 11)
|
||||
{
|
||||
*T >>= tile[num].shift_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
*T <<= (16 - tile[num].shift_t);
|
||||
}
|
||||
*T = SIGN16(*T);
|
||||
*maxs = ((*S >> 3) >= tiles[num].sh);
|
||||
|
||||
*maxs = ((*S >> 3) >= tile[num].sh);
|
||||
*maxt = ((*T >> 3) >= tile[num].th);
|
||||
*T = SIGN16(*T);
|
||||
if (tiles[num].shift_t < 11)
|
||||
{
|
||||
*T >>= tiles[num].shift_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
*T <<= (16 - tiles[num].shift_t);
|
||||
}
|
||||
*T = SIGN16(*T);
|
||||
*maxt = ((*T >> 3) >= tiles[num].th);
|
||||
}
|
||||
|
||||
void N64TexturePipeT::ShiftCopy(INT32* S, INT32* T, UINT32 num, const rdp_poly_state& object)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
*S = SIGN16(*S);
|
||||
*T = SIGN16(*T);
|
||||
if (tile[num].shift_s < 11)//?-? tcu_tile
|
||||
if (tiles[num].shift_s < 11)//?-? tcu_tile
|
||||
{
|
||||
*S >>= tile[num].shift_s;
|
||||
*S >>= tiles[num].shift_s;
|
||||
}
|
||||
else
|
||||
{
|
||||
*S <<= (16 - tile[num].shift_s);
|
||||
*S <<= (16 - tiles[num].shift_s);
|
||||
}
|
||||
*S = SIGN16(*S);
|
||||
if (tile[num].shift_t < 11)
|
||||
if (tiles[num].shift_t < 11)
|
||||
{
|
||||
*T >>= tile[num].shift_t;
|
||||
*T >>= tiles[num].shift_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
*T <<= (16 - tile[num].shift_t);
|
||||
*T <<= (16 - tiles[num].shift_t);
|
||||
}
|
||||
*T = SIGN16(*T);
|
||||
}
|
||||
|
||||
#define CLAMP_CYCLE(param, frac, max, num, coord) \
|
||||
if (tiles[num].c##coord || !tiles[num].mask_##coord) \
|
||||
{ \
|
||||
if (param & 0x10000) \
|
||||
{ \
|
||||
param = 0; \
|
||||
frac = 0; \
|
||||
} \
|
||||
else if (max) \
|
||||
{ \
|
||||
param = m_clamp_##coord##_diff[num]; \
|
||||
frac = 0; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
param = (SIGN17(param) >> 5) & 0x1fff; \
|
||||
} \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
param = (SIGN17(param) >> 5) & 0x1fff; \
|
||||
}
|
||||
|
||||
void N64TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, INT32 maxs, INT32 maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
int dos = tile[num].cs || !tile[num].mask_s;
|
||||
int dot = tile[num].ct || !tile[num].mask_t;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
|
||||
if (dos)
|
||||
if (tiles[num].cs || !tiles[num].mask_s)
|
||||
{
|
||||
if (*S & 0x10000)
|
||||
{
|
||||
@ -189,7 +243,7 @@ void N64TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC,
|
||||
*S = (SIGN17(*S) >> 5) & 0x1fff;
|
||||
}
|
||||
|
||||
if (dot)
|
||||
if (tiles[num].ct || !tiles[num].mask_t)
|
||||
{
|
||||
if (*T & 0x10000)
|
||||
{
|
||||
@ -214,9 +268,9 @@ void N64TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC,
|
||||
|
||||
void N64TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
int dos = tile[num].cs || !tile[num].mask_s;
|
||||
int dot = tile[num].ct || !tile[num].mask_t;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
int dos = tiles[num].cs || !tiles[num].mask_s;
|
||||
int dot = tiles[num].ct || !tiles[num].mask_t;
|
||||
|
||||
if (dos)
|
||||
{
|
||||
@ -259,180 +313,263 @@ void N64TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt,
|
||||
}
|
||||
}
|
||||
|
||||
void N64TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
void N64TexturePipeT::CycleNearest(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
UINT32 tformat = tile.format;
|
||||
UINT32 tsize = tile.size;
|
||||
UINT32 tpal = tile.palette;
|
||||
UINT32 index = (tformat << 4) | (tsize << 2) | ((UINT32) object.OtherModes.en_tlut << 1) | (UINT32) object.OtherModes.tlut_type;
|
||||
|
||||
#define TRELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
|
||||
INT32 bilerp = cycle ? object.OtherModes.bi_lerp1 : object.OtherModes.bi_lerp0;
|
||||
int convert = object.OtherModes.convert_one && cycle;
|
||||
Color t0;
|
||||
|
||||
INT32 sss1 = SSS;
|
||||
INT32 maxs;
|
||||
SHIFT_CYCLE(sss1, maxs, tilenum, s);
|
||||
sss1 = TRELATIVE(sss1, tile.sl);
|
||||
|
||||
INT32 sst1 = SST;
|
||||
INT32 maxt;
|
||||
SHIFT_CYCLE(sst1, maxt, tilenum, t);
|
||||
sst1 = TRELATIVE(sst1, tile.tl);
|
||||
|
||||
ClampCycleLight(&sss1, &sst1, maxs, maxt, tilenum, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
Mask(&sss1, &sst1, tilenum, object);
|
||||
|
||||
UINT32 tbase = tile.tmem + ((tile.line * sst1) & 0x1ff);
|
||||
|
||||
t0.c = ((this)->*(TexelFetch[index]))(sss1, sst1, tbase, tpal, userdata);
|
||||
|
||||
INT32 newk0 = SIGN9(m_rdp->GetK0());
|
||||
INT32 newk1 = SIGN9(m_rdp->GetK1());
|
||||
INT32 newk2 = SIGN9(m_rdp->GetK2());
|
||||
INT32 newk3 = SIGN9(m_rdp->GetK3());
|
||||
INT32 invk0 = ~newk0;
|
||||
INT32 invk1 = ~newk1;
|
||||
INT32 invk2 = ~newk2;
|
||||
INT32 invk3 = ~newk3;
|
||||
if (convert)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void N64TexturePipeT::CycleNearestLerp(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
UINT32 tformat = tile.format;
|
||||
UINT32 tsize = tile.size;
|
||||
UINT32 tpal = tile.palette;
|
||||
UINT32 index = (tformat << 4) | (tsize << 2) | ((UINT32) object.OtherModes.en_tlut << 1) | (UINT32) object.OtherModes.tlut_type;
|
||||
|
||||
#define TRELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
|
||||
Color t0;
|
||||
|
||||
INT32 sss1 = SSS;
|
||||
INT32 maxs;
|
||||
SHIFT_CYCLE(sss1, maxs, tilenum, s);
|
||||
sss1 = TRELATIVE(sss1, tile.sl);
|
||||
|
||||
INT32 sst1 = SST;
|
||||
INT32 maxt;
|
||||
SHIFT_CYCLE(sst1, maxt, tilenum, t);
|
||||
sst1 = TRELATIVE(sst1, tile.tl);
|
||||
|
||||
ClampCycleLight(&sss1, &sst1, maxs, maxt, tilenum, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
Mask(&sss1, &sst1, tilenum, object);
|
||||
|
||||
UINT32 tbase = tile.tmem + ((tile.line * sst1) & 0x1ff);
|
||||
|
||||
(*TEX).c = ((this)->*(TexelFetch[index]))(sss1, sst1, tbase, tpal, userdata);
|
||||
}
|
||||
|
||||
void N64TexturePipeT::CycleLinear(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
|
||||
#define TRELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
|
||||
int convert = object.OtherModes.convert_one && cycle;
|
||||
UINT32 tpal = tile.palette;
|
||||
UINT32 index = (tile.format << 4) | (tile.size << 2) | ((UINT32) object.OtherModes.en_tlut << 1) | (UINT32) object.OtherModes.tlut_type;
|
||||
|
||||
INT32 invsf = 0;
|
||||
INT32 sss1 = SSS;
|
||||
INT32 maxs;
|
||||
SHIFT_CYCLE(sss1, maxs, tilenum, s);
|
||||
sss1 = TRELATIVE(sss1, tile.sl);
|
||||
INT32 sfrac = sss1 & 0x1f;
|
||||
CLAMP_CYCLE(sss1, sfrac, maxs, tilenum, s);
|
||||
INT32 sss2 = sss1 + 1;
|
||||
MASK_COUPLED(sss1, sss2, tilenum, s);
|
||||
|
||||
INT32 invtf = 0;
|
||||
INT32 sst1 = SST;
|
||||
INT32 maxt;
|
||||
SHIFT_CYCLE(sst1, maxt, tilenum, t);
|
||||
sst1 = TRELATIVE(sst1, tile.tl);
|
||||
INT32 tfrac = sst1 & 0x1f;
|
||||
CLAMP_CYCLE(sst1, tfrac, maxt, tilenum, t);
|
||||
INT32 sst2 = sst1 + 1;
|
||||
MASK_COUPLED(sst1, sst2, tilenum, t);
|
||||
|
||||
UINT32 tbase = tile.tmem + ((tile.line * sst1) & 0x1ff);
|
||||
|
||||
bool upper = ((sfrac + tfrac) >= 0x20);
|
||||
|
||||
if (upper)
|
||||
{
|
||||
invsf = 0x20 - sfrac;
|
||||
invsf <<= 3;
|
||||
|
||||
invtf = 0x20 - tfrac;
|
||||
invtf <<= 3;
|
||||
}
|
||||
|
||||
sfrac <<= 3;
|
||||
tfrac <<= 3;
|
||||
|
||||
Color t0;
|
||||
t0.c = ((this)->*(TexelFetch[index]))(sss1, sst1, tbase, tpal, userdata);
|
||||
INT32 newk0 = SIGN9(m_rdp->GetK0());
|
||||
INT32 newk1 = SIGN9(m_rdp->GetK1());
|
||||
INT32 newk2 = SIGN9(m_rdp->GetK2());
|
||||
INT32 newk3 = SIGN9(m_rdp->GetK3());
|
||||
INT32 invk0 = ~newk0;
|
||||
INT32 invk1 = ~newk1;
|
||||
INT32 invk2 = ~newk2;
|
||||
INT32 invk3 = ~newk3;
|
||||
if (convert)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void N64TexturePipeT::CycleLinearLerp(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
|
||||
#define TRELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
|
||||
UINT32 tpal = tile.palette;
|
||||
UINT32 index = (tile.format << 4) | (tile.size << 2) | ((UINT32) object.OtherModes.en_tlut << 1) | (UINT32) object.OtherModes.tlut_type;
|
||||
|
||||
int center = 0;
|
||||
|
||||
INT32 invsf = 0;
|
||||
INT32 sss1 = SSS;
|
||||
INT32 maxs;
|
||||
SHIFT_CYCLE(sss1, maxs, tilenum, s);
|
||||
sss1 = TRELATIVE(sss1, tile.sl);
|
||||
INT32 sfrac = sss1 & 0x1f;
|
||||
CLAMP_CYCLE(sss1, sfrac, maxs, tilenum, s);
|
||||
INT32 sss2 = sss1 + 1;
|
||||
MASK_COUPLED(sss1, sss2, tilenum, s);
|
||||
|
||||
INT32 invtf = 0;
|
||||
INT32 sst1 = SST;
|
||||
INT32 maxt;
|
||||
SHIFT_CYCLE(sst1, maxt, tilenum, t);
|
||||
sst1 = TRELATIVE(sst1, tile.tl);
|
||||
INT32 tfrac = sst1 & 0x1f;
|
||||
CLAMP_CYCLE(sst1, tfrac, maxt, tilenum, t);
|
||||
INT32 sst2 = sst1 + 1;
|
||||
MASK_COUPLED(sst1, sst2, tilenum, t);
|
||||
|
||||
UINT32 tbase1 = tile.tmem + ((tile.line * sst1) & 0x1ff);
|
||||
UINT32 tbase2 = tile.tmem + ((tile.line * sst2) & 0x1ff);
|
||||
|
||||
bool upper = ((sfrac + tfrac) >= 0x20);
|
||||
|
||||
if (upper)
|
||||
{
|
||||
invsf = 0x20 - sfrac;
|
||||
invsf <<= 3;
|
||||
|
||||
invtf = 0x20 - tfrac;
|
||||
invtf <<= 3;
|
||||
}
|
||||
|
||||
center = (sfrac == 0x10) && (tfrac == 0x10) && object.OtherModes.mid_texel;
|
||||
|
||||
sfrac <<= 3;
|
||||
tfrac <<= 3;
|
||||
|
||||
Color t1;
|
||||
Color t2;
|
||||
Color t3;
|
||||
if (object.OtherModes.sample_type)
|
||||
t1.c = ((this)->*(TexelFetch[index]))(sss2, sst1, tbase1, tpal, userdata);
|
||||
t2.c = ((this)->*(TexelFetch[index]))(sss1, sst2, tbase2, tpal, userdata);
|
||||
if (!center)
|
||||
{
|
||||
int sss1, sst1, sss2, sst2;
|
||||
|
||||
INT32 invsf = 0;
|
||||
INT32 invtf = 0;
|
||||
int center = 0;
|
||||
|
||||
sss1 = SSS;
|
||||
sst1 = SST;
|
||||
|
||||
INT32 maxs;
|
||||
INT32 maxt;
|
||||
|
||||
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum, object);
|
||||
|
||||
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
|
||||
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
|
||||
|
||||
INT32 sfrac = sss1 & 0x1f;
|
||||
INT32 tfrac = sst1 & 0x1f;
|
||||
|
||||
ClampCycle(&sss1, &sst1, &sfrac, &tfrac, maxs, maxt, tilenum, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
sss2 = sss1 + 1;
|
||||
sst2 = sst1 + 1;
|
||||
|
||||
MaskCoupled(&sss1, &sss2, &sst1, &sst2, tilenum, object);
|
||||
|
||||
bool upper = ((sfrac + tfrac) >= 0x20);
|
||||
|
||||
if (upper)
|
||||
{
|
||||
invsf = 0x20 - sfrac;
|
||||
invtf = 0x20 - tfrac;
|
||||
}
|
||||
|
||||
center = (sfrac == 0x10) && (tfrac == 0x10) && object.OtherModes.mid_texel;
|
||||
|
||||
invsf <<= 3;
|
||||
invtf <<= 3;
|
||||
sfrac <<= 3;
|
||||
tfrac <<= 3;
|
||||
|
||||
t0.c = Fetch(sss1, sst1, tilenum, object, userdata);
|
||||
|
||||
if (bilerp)
|
||||
{
|
||||
t1.c = Fetch(sss2, sst1, tilenum, object, userdata);
|
||||
t2.c = Fetch(sss1, sst2, tilenum, object, userdata);
|
||||
t3.c = Fetch(sss2, sst2, tilenum, object, userdata);
|
||||
if (!center)
|
||||
{
|
||||
if (upper)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
TEX->i.r = t0.i.r + (((sfrac * (t1.i.r - t0.i.r)) + (tfrac * (t2.i.r - t0.i.r)) + 0x80) >> 8);
|
||||
TEX->i.g = t0.i.g + (((sfrac * (t1.i.g - t0.i.g)) + (tfrac * (t2.i.g - t0.i.g)) + 0x80) >> 8);
|
||||
TEX->i.b = t0.i.b + (((sfrac * (t1.i.b - t0.i.b)) + (tfrac * (t2.i.b - t0.i.b)) + 0x80) >> 8);
|
||||
TEX->i.a = t0.i.a + (((sfrac * (t1.i.a - t0.i.a)) + (tfrac * (t2.i.a - t0.i.a)) + 0x80) >> 8);
|
||||
}
|
||||
TEX->i.r &= 0x1ff;
|
||||
TEX->i.g &= 0x1ff;
|
||||
TEX->i.b &= 0x1ff;
|
||||
TEX->i.a &= 0x1ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
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.g) >> 2;
|
||||
TEX->i.b = (t0.i.b + t1.i.b + t2.i.b + t3.i.b) >> 2;
|
||||
TEX->i.a = (t0.i.a + t1.i.a + t2.i.a + t3.i.a) >> 2;
|
||||
}
|
||||
Color t3;
|
||||
t3.c = ((this)->*(TexelFetch[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);
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 newk0 = SIGN9(m_rdp->GetK0());
|
||||
INT32 newk1 = SIGN9(m_rdp->GetK1());
|
||||
INT32 newk2 = SIGN9(m_rdp->GetK2());
|
||||
INT32 newk3 = SIGN9(m_rdp->GetK3());
|
||||
INT32 invk0 = ~newk0;
|
||||
INT32 invk1 = ~newk1;
|
||||
INT32 invk2 = ~newk2;
|
||||
INT32 invk3 = ~newk3;
|
||||
if (convert)
|
||||
{
|
||||
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;
|
||||
Color t0;
|
||||
t0.c = ((this)->*(TexelFetch[index]))(sss1, sst1, tbase1, tpal, userdata);
|
||||
TEX->i.r = t0.i.r + (((sfrac * (t1.i.r - t0.i.r)) + (tfrac * (t2.i.r - t0.i.r)) + 0x80) >> 8);
|
||||
TEX->i.g = t0.i.g + (((sfrac * (t1.i.g - t0.i.g)) + (tfrac * (t2.i.g - t0.i.g)) + 0x80) >> 8);
|
||||
TEX->i.b = t0.i.b + (((sfrac * (t1.i.b - t0.i.b)) + (tfrac * (t2.i.b - t0.i.b)) + 0x80) >> 8);
|
||||
TEX->i.a = t0.i.a + (((sfrac * (t1.i.a - t0.i.a)) + (tfrac * (t2.i.a - t0.i.a)) + 0x80) >> 8);
|
||||
}
|
||||
TEX->i.r &= 0x1ff;
|
||||
TEX->i.g &= 0x1ff;
|
||||
TEX->i.b &= 0x1ff;
|
||||
TEX->i.a &= 0x1ff;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 sss1 = SSS;
|
||||
INT32 sst1 = SST;
|
||||
|
||||
INT32 maxs;
|
||||
INT32 maxt;
|
||||
|
||||
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum, object);
|
||||
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
|
||||
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
|
||||
|
||||
ClampCycleLight(&sss1, &sst1, maxs, maxt, tilenum, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
|
||||
|
||||
Mask(&sss1, &sst1, tilenum, object);
|
||||
|
||||
t0.c = Fetch(sss1, sst1, tilenum, object, userdata);
|
||||
if (bilerp)
|
||||
{
|
||||
*TEX = t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 newk0 = SIGN9(m_rdp->GetK0());
|
||||
INT32 newk1 = SIGN9(m_rdp->GetK1());
|
||||
INT32 newk2 = SIGN9(m_rdp->GetK2());
|
||||
INT32 newk3 = SIGN9(m_rdp->GetK3());
|
||||
INT32 invk0 = ~newk0;
|
||||
INT32 invk1 = ~newk1;
|
||||
INT32 invk2 = ~newk2;
|
||||
INT32 invk3 = ~newk3;
|
||||
if (convert)
|
||||
{
|
||||
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;
|
||||
}
|
||||
Color t0;
|
||||
Color t3;
|
||||
t0.c = ((this)->*(TexelFetch[index]))(sss1, sst1, 1, tpal, userdata);
|
||||
t3.c = ((this)->*(TexelFetch[index]))(sss2, 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.g) >> 2;
|
||||
TEX->i.b = (t0.i.b + t1.i.b + t2.i.b + t3.i.b) >> 2;
|
||||
TEX->i.a = (t0.i.a + t1.i.a + t2.i.a + t3.i.a) >> 2;
|
||||
}
|
||||
}
|
||||
|
||||
void N64TexturePipeT::Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
INT32 sss1 = SSS;
|
||||
INT32 sst1 = SST;
|
||||
ShiftCopy(&sss1, &sst1, tilenum, object);
|
||||
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
|
||||
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
|
||||
sss1 = TRELATIVE(sss1, tile.sl);
|
||||
sst1 = TRELATIVE(sst1, tile.tl);
|
||||
sss1 = (SIGN17(sss1) >> 5) & 0x1fff;
|
||||
sst1 = (SIGN17(sst1) >> 5) & 0x1fff;
|
||||
Mask(&sss1, &sst1, tilenum, object);
|
||||
@ -789,7 +926,7 @@ void N64TexturePipeT::LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t,
|
||||
|
||||
void N64TexturePipeT::CalculateClampDiffs(UINT32 prim_tile, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
if (object.OtherModes.cycle_type == CYCLE_TYPE_2)
|
||||
{
|
||||
if (object.OtherModes.tex_lod_en)
|
||||
@ -798,24 +935,24 @@ void N64TexturePipeT::CalculateClampDiffs(UINT32 prim_tile, rdp_span_aux *userda
|
||||
int end = 7;
|
||||
for (; start <= end; start++)
|
||||
{
|
||||
m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
|
||||
m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
|
||||
m_clamp_s_diff[start] = (tiles[start].sh >> 2) - (tiles[start].sl >> 2);
|
||||
m_clamp_t_diff[start] = (tiles[start].th >> 2) - (tiles[start].tl >> 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int start = prim_tile;
|
||||
int end = (prim_tile + 1) & 7;
|
||||
m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
|
||||
m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
|
||||
m_clamp_s_diff[end] = (tile[end].sh >> 2) - (tile[end].sl >> 2);
|
||||
m_clamp_t_diff[end] = (tile[end].th >> 2) - (tile[end].tl >> 2);
|
||||
m_clamp_s_diff[start] = (tiles[start].sh >> 2) - (tiles[start].sl >> 2);
|
||||
m_clamp_t_diff[start] = (tiles[start].th >> 2) - (tiles[start].tl >> 2);
|
||||
m_clamp_s_diff[end] = (tiles[end].sh >> 2) - (tiles[end].sl >> 2);
|
||||
m_clamp_t_diff[end] = (tiles[end].th >> 2) - (tiles[end].tl >> 2);
|
||||
}
|
||||
}
|
||||
else//1-cycle or copy
|
||||
{
|
||||
m_clamp_s_diff[prim_tile] = (tile[prim_tile].sh >> 2) - (tile[prim_tile].sl >> 2);
|
||||
m_clamp_t_diff[prim_tile] = (tile[prim_tile].th >> 2) - (tile[prim_tile].tl >> 2);
|
||||
m_clamp_s_diff[prim_tile] = (tiles[prim_tile].sh >> 2) - (tiles[prim_tile].sl >> 2);
|
||||
m_clamp_t_diff[prim_tile] = (tiles[prim_tile].th >> 2) - (tiles[prim_tile].tl >> 2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1377,15 +1514,14 @@ UINT32 N64TexturePipeT::_FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal,
|
||||
|
||||
UINT32 N64TexturePipeT::Fetch(INT32 s, INT32 t, INT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata)
|
||||
{
|
||||
const N64Tile* tile = object.m_tiles;
|
||||
UINT32 tformat = tile[tilenum].format;
|
||||
UINT32 tsize = tile[tilenum].size;
|
||||
|
||||
UINT32 tbase = (tile[tilenum].line * t) & 0x1ff;
|
||||
tbase += tile[tilenum].tmem;
|
||||
UINT32 tpal = tile[tilenum].palette;
|
||||
|
||||
const N64Tile* tiles = object.m_tiles;
|
||||
const N64Tile& tile = tiles[tilenum];
|
||||
UINT32 tformat = tile.format;
|
||||
UINT32 tsize = tile.size;
|
||||
UINT32 tpal = tile.palette;
|
||||
UINT32 index = (tformat << 4) | (tsize << 2) | ((UINT32) object.OtherModes.en_tlut << 1) | (UINT32) object.OtherModes.tlut_type;
|
||||
|
||||
UINT32 tbase = tile.tmem + ((tile.line * t) & 0x1ff);
|
||||
|
||||
return ((this)->*(TexelFetch[index]))(s, t, tbase, tpal, userdata);
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ class N64TexturePipeT
|
||||
{
|
||||
public:
|
||||
typedef UINT32 (N64TexturePipeT::*TexelFetcher) (INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
|
||||
typedef void (N64TexturePipeT::*Cycler) (Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
|
||||
N64TexturePipeT()
|
||||
{
|
||||
@ -85,9 +86,20 @@ class N64TexturePipeT
|
||||
TexelFetch[69] = &N64TexturePipeT::_FetchI_8_RAW;
|
||||
TexelFetch[70] = &N64TexturePipeT::_FetchI_8_TLUT0;
|
||||
TexelFetch[71] = &N64TexturePipeT::_FetchI_8_TLUT1;
|
||||
|
||||
cycle[0] = &N64TexturePipeT::CycleNearest;
|
||||
cycle[1] = &N64TexturePipeT::CycleNearestLerp;
|
||||
cycle[2] = &N64TexturePipeT::CycleLinear;
|
||||
cycle[3] = &N64TexturePipeT::CycleLinearLerp;
|
||||
}
|
||||
|
||||
void Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
void CycleNearest(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
void CycleNearestLerp(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
void CycleLinear(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
void CycleLinearLerp(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
|
||||
Cycler cycle[4];
|
||||
|
||||
void Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata);
|
||||
UINT32 Fetch(INT32 SSS, INT32 SST, INT32 tile, const rdp_poly_state& object, rdp_span_aux *userdata);
|
||||
void CalculateClampDiffs(UINT32 prim_tile, rdp_span_aux *userdata, const rdp_poly_state& object, INT32 *m_clamp_s_diff, INT32 *m_clamp_t_diff);
|
||||
|
Loading…
Reference in New Issue
Block a user