mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +03:00
Updated the RSP and RDP implementations to be largely bit-perfect and pixel-accurate. [angrylion, Harmony]
This commit is contained in:
parent
de94242bcc
commit
0ea11333c6
7
.gitattributes
vendored
7
.gitattributes
vendored
@ -365,6 +365,7 @@ src/emu/cpu/powerpc/ppcfe.h svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rsp.c svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rsp.h svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rsp_dasm.c svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rspdiv.h svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rspdrc.c svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rspfe.c svneol=native#text/plain
|
||||
src/emu/cpu/rsp/rspfe.h svneol=native#text/plain
|
||||
@ -3984,17 +3985,11 @@ src/mame/video/rdpblend.c svneol=native#text/plain
|
||||
src/mame/video/rdpblend.h svneol=native#text/plain
|
||||
src/mame/video/rdpfb.c svneol=native#text/plain
|
||||
src/mame/video/rdpfb.h svneol=native#text/plain
|
||||
src/mame/video/rdpfetch.c svneol=native#text/plain
|
||||
src/mame/video/rdpfetch.h svneol=native#text/plain
|
||||
src/mame/video/rdpfiltr.c svneol=native#text/plain
|
||||
src/mame/video/rdpfrect.c svneol=native#text/plain
|
||||
src/mame/video/rdpfrect.h svneol=native#text/plain
|
||||
src/mame/video/rdpspn16.c svneol=native#text/plain
|
||||
src/mame/video/rdpspn16.h svneol=native#text/plain
|
||||
src/mame/video/rdptpipe.c svneol=native#text/plain
|
||||
src/mame/video/rdptpipe.h svneol=native#text/plain
|
||||
src/mame/video/rdptrect.c svneol=native#text/plain
|
||||
src/mame/video/rdptrect.h svneol=native#text/plain
|
||||
src/mame/video/rdptri.h svneol=native#text/plain
|
||||
src/mame/video/realbrk.c svneol=native#text/plain
|
||||
src/mame/video/redalert.c svneol=native#text/plain
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -139,51 +139,20 @@ void rspdrc_add_dmem(running_device *device, void *base);
|
||||
|
||||
#define RSPDRC_STRICT_VERIFY 0x0001 /* verify all instructions */
|
||||
|
||||
typedef struct
|
||||
typedef union
|
||||
{
|
||||
union
|
||||
{
|
||||
UINT8 b[16];
|
||||
UINT16 s[8];
|
||||
UINT32 l[4];
|
||||
UINT64 d[2];
|
||||
};
|
||||
UINT64 d[2];
|
||||
UINT32 l[4];
|
||||
INT16 s[8];
|
||||
UINT8 b[16];
|
||||
} VECTOR_REG;
|
||||
|
||||
typedef struct
|
||||
typedef union
|
||||
{
|
||||
union
|
||||
{
|
||||
INT64 l;
|
||||
#ifdef LSB_FIRST
|
||||
struct
|
||||
{
|
||||
INT16 z;
|
||||
INT16 low;
|
||||
INT16 mid;
|
||||
INT16 high;
|
||||
} h;
|
||||
struct
|
||||
{
|
||||
INT32 zl;
|
||||
INT32 mh;
|
||||
} w;
|
||||
#else
|
||||
struct
|
||||
{
|
||||
INT16 high;
|
||||
INT16 mid;
|
||||
INT16 low;
|
||||
INT16 z;
|
||||
} h;
|
||||
struct
|
||||
{
|
||||
INT32 mh;
|
||||
INT32 zl;
|
||||
} w;
|
||||
#endif
|
||||
};
|
||||
} ACCUMULATOR;
|
||||
INT64 q;
|
||||
INT32 l[2];
|
||||
INT16 w[4];
|
||||
} ACCUMULATOR_REG;
|
||||
|
||||
typedef struct _rspimp_state rspimp_state;
|
||||
typedef struct _rsp_state rsp_state;
|
||||
@ -199,11 +168,12 @@ struct _rsp_state
|
||||
UINT32 sr;
|
||||
UINT32 step_count;
|
||||
|
||||
ACCUMULATOR accum[8];
|
||||
ACCUMULATOR_REG accum[8];
|
||||
INT32 square_root_res;
|
||||
INT32 square_root_high;
|
||||
INT32 reciprocal_res;
|
||||
INT32 reciprocal_high;
|
||||
INT32 dp_allowed;
|
||||
|
||||
UINT32 ppc;
|
||||
UINT32 nextpc;
|
||||
|
1027
src/emu/cpu/rsp/rspdiv.h
Normal file
1027
src/emu/cpu/rsp/rspdiv.h
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -390,10 +390,13 @@ static void sp_dma(int direction)
|
||||
src = (UINT8*)&rdram[sp_dram_addr / 4];
|
||||
dst = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4];
|
||||
|
||||
//printf("CPU %08x -> RSP %08x\n", sp_dram_addr, 0x04000000 | sp_mem_addr);
|
||||
for (i=0; i < sp_dma_length; i++)
|
||||
{
|
||||
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
|
||||
//printf("%02x ", src[i]);
|
||||
dst[i] = src[i];
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
sp_mem_addr += sp_dma_length;
|
||||
sp_dram_addr += sp_dma_length;
|
||||
@ -408,10 +411,13 @@ static void sp_dma(int direction)
|
||||
src = (sp_mem_addr & 0x1000) ? (UINT8*)&rsp_imem[(sp_mem_addr & 0xfff) / 4] : (UINT8*)&rsp_dmem[(sp_mem_addr & 0xfff) / 4];
|
||||
dst = (UINT8*)&rdram[sp_dram_addr / 4];
|
||||
|
||||
//printf("RSP %08x -> CPU %08x\n", 0x04000000 | sp_mem_addr, sp_dram_addr);
|
||||
for (i=0; i < sp_dma_length; i++)
|
||||
{
|
||||
dst[BYTE4_XOR_BE(i)] = src[BYTE4_XOR_BE(i)];
|
||||
//printf("%02x ", src[i]);
|
||||
dst[i] = src[i];
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
sp_mem_addr += sp_dma_length;
|
||||
sp_dram_addr += sp_dma_length;
|
||||
@ -729,6 +735,7 @@ READ32_DEVICE_HANDLER( n64_dp_reg_r )
|
||||
{
|
||||
_n64_state *state = device->machine->driver_data<_n64_state>();
|
||||
|
||||
//printf("%08x\n", offset);
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4: // DP_START_REG
|
||||
@ -755,6 +762,7 @@ WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
|
||||
{
|
||||
_n64_state *state = device->machine->driver_data<_n64_state>();
|
||||
|
||||
//printf("%08x: %08x\n", offset, data);
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00/4: // DP_START_REG
|
||||
@ -1091,6 +1099,8 @@ static AUDIO_DMA *audio_fifo_get_top(void)
|
||||
}
|
||||
}
|
||||
|
||||
#define N64_ATTOTIME_NORMALIZE(a) do { while ((a).attoseconds >= ATTOSECONDS_PER_SECOND) { (a).seconds++; (a).attoseconds -= ATTOSECONDS_PER_SECOND; } } while (0)
|
||||
|
||||
static void start_audio_dma(running_machine *machine)
|
||||
{
|
||||
INT16 *ram = (INT16*)rdram;
|
||||
@ -2011,7 +2021,7 @@ MACHINE_START( n64 )
|
||||
/* configure fast RAM regions for DRC */
|
||||
mips3drc_add_fastram(machine->device("maincpu"), 0x00000000, 0x007fffff, FALSE, rdram);
|
||||
|
||||
rspdrc_set_options(machine->device("rsp"), 0);
|
||||
rspdrc_set_options(machine->device("rsp"), RSPDRC_STRICT_VERIFY);
|
||||
rspdrc_add_imem(machine->device("rsp"), rsp_imem);
|
||||
rspdrc_add_dmem(machine->device("rsp"), rsp_dmem);
|
||||
rspdrc_flush_drc_cache(machine->device("rsp"));
|
||||
|
@ -1206,7 +1206,7 @@ $(MAMEOBJ)/seibu.a: \
|
||||
$(DRIVERS)/feversoc.o \
|
||||
|
||||
$(MAMEOBJ)/seta.a: \
|
||||
$(DRIVERS)/aleck64.o $(MACHINE)/n64.o $(VIDEO)/n64.o $(VIDEO)/rdpblend.o $(VIDEO)/rdpfb.o $(VIDEO)/rdpspn16.o $(VIDEO)/rdptrect.o $(VIDEO)/rdpfrect.o $(VIDEO)/rdpfetch.o $(VIDEO)/rdptpipe.o \
|
||||
$(DRIVERS)/aleck64.o $(MACHINE)/n64.o $(VIDEO)/n64.o $(VIDEO)/rdpblend.o $(VIDEO)/rdpfb.o $(VIDEO)/rdpspn16.o $(VIDEO)/rdptpipe.o \
|
||||
$(DRIVERS)/darkhors.o \
|
||||
$(DRIVERS)/hanaawas.o $(VIDEO)/hanaawas.o \
|
||||
$(DRIVERS)/macs.o \
|
||||
|
2215
src/mame/video/n64.c
2215
src/mame/video/n64.c
File diff suppressed because it is too large
Load Diff
@ -5,11 +5,8 @@
|
||||
#include "video/rdpblend.h"
|
||||
#include "video/rdptri.h"
|
||||
#include "video/rdpfb.h"
|
||||
#include "video/rdpfrect.h"
|
||||
#include "video/rdptrect.h"
|
||||
#include "video/rdptpipe.h"
|
||||
#include "video/rdpspn16.h"
|
||||
#include "video/rdpfetch.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -37,10 +34,54 @@
|
||||
#define XOR_SWAP_WORD 2
|
||||
#define XOR_SWAP_DWORD 1
|
||||
|
||||
#define FORMAT_RGBA 0
|
||||
#define FORMAT_YUV 1
|
||||
#define FORMAT_CI 2
|
||||
#define FORMAT_IA 3
|
||||
#define FORMAT_I 4
|
||||
|
||||
#if LSB_FIRST
|
||||
#define BYTE_XOR_DWORD_SWAP 7
|
||||
#define WORD_XOR_DWORD_SWAP 3
|
||||
#else
|
||||
#define BYTE_XOR_DWORD_SWAP 4
|
||||
#define WORD_XOR_DWORD_SWAP 2
|
||||
#endif
|
||||
#define DWORD_XOR_DWORD_SWAP 1
|
||||
|
||||
#define GET_LOW_RGBA16_TMEM(x) (m_rdp->ReplicatedRGBA()[((x) >> 1) & 0x1f])
|
||||
#define GET_MED_RGBA16_TMEM(x) (m_rdp->ReplicatedRGBA()[((x) >> 6) & 0x1f])
|
||||
#define GET_HI_RGBA16_TMEM(x) (m_rdp->ReplicatedRGBA()[((x) >> 11) & 0x1f])
|
||||
|
||||
#define MEM8_LIMIT 0x7fffff
|
||||
#define MEM16_LIMIT 0x3fffff
|
||||
#define MEM32_LIMIT 0x1fffff
|
||||
|
||||
#define RREADADDR8(in) (((in) <= MEM8_LIMIT) ? (((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR]) : 0)
|
||||
#define RREADIDX16(in) (((in) <= MEM16_LIMIT) ? (((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR]) : 0)
|
||||
#define RREADIDX32(in) (((in) <= MEM32_LIMIT) ? (rdram[(in)]) : 0)
|
||||
|
||||
#define RWRITEADDR8(in, val) {if ((in) <= MEM8_LIMIT) ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;}
|
||||
#define RWRITEIDX16(in, val) {if ((in) <= MEM16_LIMIT) ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;}
|
||||
#define RWRITEIDX32(in, val) {if ((in) <= MEM32_LIMIT) rdram[(in)] = val;}
|
||||
|
||||
#define GETLOWCOL(x) (((x) & 0x3e) << 2)
|
||||
#define GETMEDCOL(x) (((x) & 0x7c0) >> 3)
|
||||
#define GETHICOL(x) (((x) & 0xf800) >> 8)
|
||||
|
||||
#define HREADADDR8(in) (((in) <= MEM8_LIMIT) ? (m_rdp->GetHiddenBits()[(in) ^ BYTE_ADDR_XOR]) : 0)
|
||||
#define HWRITEADDR8(in, val) {if ((in) <= MEM8_LIMIT) m_rdp->GetHiddenBits()[(in) ^ BYTE_ADDR_XOR] = val;}
|
||||
|
||||
//sign-extension macros
|
||||
#define SIGN22(x) (((x) & 0x200000) ? ((x) | ~0x3fffff) : ((x) & 0x3fffff))
|
||||
#define SIGN17(x) (((x) & 0x10000) ? ((x) | ~0x1ffff) : ((x) & 0x1ffff))
|
||||
#define SIGN16(x) (((x) & 0x8000) ? ((x) | ~0xffff) : ((x) & 0xffff))
|
||||
#define SIGN13(x) (((x) & 0x1000) ? ((x) | ~0x1fff) : ((x) & 0x1fff))
|
||||
#define SIGN11(x) (((x) & 0x400) ? ((x) | ~0x7ff) : ((x) & 0x7ff))
|
||||
#define SIGN9(x) (((x) & 0x100) ? ((x) | ~0x1ff) : ((x) & 0x1ff))
|
||||
#define SIGN8(x) (((x) & 0x80) ? ((x) | ~0xff) : ((x) & 0xff))
|
||||
|
||||
#define KURT_AKELEY_SIGN9(x) ((((x) & 0x180) == 0x180) ? ((x) | ~0x1ff) : ((x) & 0x1ff))
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
@ -86,8 +127,8 @@ class Tile
|
||||
public:
|
||||
int format; // Image data format: RGBA, YUV, CI, IA, I
|
||||
int size; // Size of texel element: 4b, 8b, 16b, 32b
|
||||
UINT32 line; // Size of tile line in bytes
|
||||
UINT32 tmem; // Starting tmem address for this tile in bytes
|
||||
int line; // Size of tile line in bytes
|
||||
int tmem; // Starting tmem address for this tile in bytes
|
||||
int palette; // Palette number for 4b CI texels
|
||||
int ct, mt, cs, ms; // Clamp / mirror enable bits for S / T direction
|
||||
int mask_t, shift_t, mask_s, shift_s; // Mask values / LOD shifts
|
||||
@ -101,6 +142,8 @@ class MiscState
|
||||
MiscState()
|
||||
{
|
||||
m_curpixel_cvg = 0;
|
||||
m_curpixel_memcvg = 0;
|
||||
m_curpixel_cvbit = 0;
|
||||
m_curpixel_overlap = 0;
|
||||
|
||||
m_max_level = 0;
|
||||
@ -121,6 +164,8 @@ class MiscState
|
||||
UINT32 m_ti_address;
|
||||
|
||||
UINT32 m_curpixel_cvg;
|
||||
UINT32 m_curpixel_memcvg;
|
||||
UINT32 m_curpixel_cvbit;
|
||||
UINT32 m_curpixel_overlap;
|
||||
|
||||
UINT8 m_random_seed;
|
||||
@ -232,6 +277,14 @@ class ColorInputs
|
||||
UINT8 *blender2b_a[2];
|
||||
};
|
||||
|
||||
struct Rectangle
|
||||
{
|
||||
UINT16 m_xl; // 10.2 fixed-point
|
||||
UINT16 m_yl; // 10.2 fixed-point
|
||||
UINT16 m_xh; // 10.2 fixed-point
|
||||
UINT16 m_yh; // 10.2 fixed-point
|
||||
};
|
||||
|
||||
class Processor
|
||||
{
|
||||
public:
|
||||
@ -245,47 +298,6 @@ class Processor
|
||||
m_current = 0;
|
||||
m_status = 0x88;
|
||||
|
||||
for(int i = 0; i < (1 << 16); i++)
|
||||
{
|
||||
UINT8 r = ((i >> 8) & 0xf8) | (i >> 13);
|
||||
UINT8 g = ((i >> 3) & 0xf8) | ((i >> 8) & 0x07);
|
||||
UINT8 b = ((i << 2) & 0xf8) | ((i >> 3) & 0x07);
|
||||
UINT8 a = (i & 1) ? 0xff : 0;
|
||||
m_rgb16_to_rgb32_lut[i] = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
|
||||
r = g = b = (i >> 8) & 0xff;
|
||||
a = i & 0xff;
|
||||
m_ia8_to_rgb32_lut[i] = (r << 24) | (g << 16) | (b << 8) | a;
|
||||
}
|
||||
|
||||
for(int i = 0; i < (1 << 24); i++)
|
||||
{
|
||||
UINT8 A = (i >> 16) & 0x000000ff;
|
||||
UINT8 B = (i >> 8) & 0x000000ff;
|
||||
UINT8 C = i & 0x000000ff;
|
||||
m_cc_lut1[i] = (INT16)((((((INT32)A - (INT32)B) * (INT32)C) + 0x80) >> 8) & 0x0000ffff);
|
||||
}
|
||||
|
||||
for(int i = 0; i < (1 << 16); i++)
|
||||
{
|
||||
for(int j = 0; j < (1 << 8); j++)
|
||||
{
|
||||
INT32 temp = (INT32)((INT16)i) + j;
|
||||
if(temp > 255)
|
||||
{
|
||||
m_cc_lut2[(i << 8) | j] = 255;
|
||||
}
|
||||
else if(temp < 0)
|
||||
{
|
||||
m_cc_lut2[(i << 8) | j] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cc_lut2[(i << 8) | j] = (UINT8)temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
m_tiles[i].num = i;
|
||||
@ -325,7 +337,7 @@ class Processor
|
||||
|
||||
m_machine = NULL;
|
||||
|
||||
memset(m_hidden_bits, 3, 4194304); // Hack / fix for letters in Rayman 2
|
||||
//memset(m_hidden_bits, 3, 8388608);
|
||||
|
||||
m_prim_lod_frac = 0;
|
||||
m_lod_frac = 0;
|
||||
@ -342,16 +354,72 @@ class Processor
|
||||
m_gamma_dither_table[i] <<= 1;
|
||||
}
|
||||
|
||||
BuildCompressedZTable();
|
||||
z_build_com_table();
|
||||
|
||||
for (int i = 0; i < 0x4000; i++)
|
||||
{
|
||||
UINT32 exponent = (i >> 11) & 7;
|
||||
UINT32 mantissa = i & 0x7ff;
|
||||
z_complete_dec_table[i] = ((mantissa << z_dec_table[exponent].shift) + z_dec_table[exponent].add) & 0x3fffff;
|
||||
}
|
||||
|
||||
precalc_cvmask_derivatives();
|
||||
|
||||
for(int i = 0; i < 0x200; i++)
|
||||
{
|
||||
switch((i >> 7) & 3)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
m_special_9bit_clamptable[i] = i & 0xff;
|
||||
break;
|
||||
case 2:
|
||||
m_special_9bit_clamptable[i] = 0xff;
|
||||
break;
|
||||
case 3:
|
||||
m_special_9bit_clamptable[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
m_replicated_rgba[i] = (i << 3) | ((i >> 2) & 7);
|
||||
}
|
||||
}
|
||||
|
||||
~Processor() { }
|
||||
|
||||
UINT8* ReplicatedRGBA() { return m_replicated_rgba; }
|
||||
|
||||
void Dasm(char *buffer);
|
||||
|
||||
void ProcessList();
|
||||
UINT32 ReadData(UINT32 address);
|
||||
|
||||
void set_span_base(int dr, int dg, int db, int da, int ds, int dt, int dw, int dz, int dymax, int dzpix)
|
||||
{
|
||||
m_span_dr = dr;
|
||||
m_span_dg = dg;
|
||||
m_span_db = db;
|
||||
m_span_da = da;
|
||||
m_span_ds = ds;
|
||||
m_span_dt = dt;
|
||||
m_span_dw = dw;
|
||||
m_span_dz = dz;
|
||||
m_span_dymax = dymax;
|
||||
m_span_dzpix = dzpix;
|
||||
}
|
||||
|
||||
void set_span_base_y(int dr, int dg, int db, int da, int dz)
|
||||
{
|
||||
m_span_drdy = dr;
|
||||
m_span_dgdy = dg;
|
||||
m_span_dbdy = db;
|
||||
m_span_dady = da;
|
||||
m_span_dzdy = dz;
|
||||
}
|
||||
|
||||
void InitInternalState()
|
||||
{
|
||||
if(m_machine)
|
||||
@ -362,7 +430,7 @@ class Processor
|
||||
UINT8 *normpoint = memory_region(m_machine, "normpoint");
|
||||
UINT8 *normslope = memory_region(m_machine, "normslope");
|
||||
|
||||
for(int i = 0; i < 64; i++)
|
||||
for(INT32 i = 0; i < 64; i++)
|
||||
{
|
||||
m_norm_point_rom[i] = (normpoint[(i << 1) + 1] << 8) | normpoint[i << 1];
|
||||
m_norm_slope_rom[i] = (normslope[(i << 1) + 1] << 8) | normslope[i << 1];
|
||||
@ -430,6 +498,9 @@ class Processor
|
||||
Color* GetTexel1Color() { return &m_texel1_color; }
|
||||
void SetTexel1Color(UINT32 color) { m_texel1_color.c = color; }
|
||||
|
||||
Color* GetNextTexelColor() { return &m_next_texel_color; }
|
||||
void SetNextTexelColor(UINT32 color) { m_next_texel_color.c = color; }
|
||||
|
||||
Color* GetShadeColor() { return &m_shade_color; }
|
||||
void SetShadeColor(UINT32 color) { m_shade_color.c = color; }
|
||||
|
||||
@ -442,13 +513,17 @@ class Processor
|
||||
Color* GetOne() { return &m_one_color; }
|
||||
Color* GetZero() { return &m_zero_color; }
|
||||
|
||||
UINT8* GetLODFrac() { return &m_lod_frac; }
|
||||
UINT8 GetLODFrac() { return m_lod_frac; }
|
||||
void SetLODFrac(UINT8 lod_frac) { m_lod_frac = lod_frac; }
|
||||
|
||||
UINT8* GetPrimLODFrac() { return &m_prim_lod_frac; }
|
||||
UINT8 GetPrimLODFrac() { return m_prim_lod_frac; }
|
||||
void SetPrimLODFrac(UINT8 prim_lod_frac) { m_prim_lod_frac = prim_lod_frac; }
|
||||
|
||||
// Color Combiner
|
||||
INT32 ColorCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d);
|
||||
INT32 AlphaCombinerEquation(INT32 a, INT32 b, INT32 c, INT32 d);
|
||||
void ColorCombiner2Cycle(bool noisecompute);
|
||||
void ColorCombiner1Cycle(bool noisecompute);
|
||||
void SetSubAInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code);
|
||||
void SetSubBInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code);
|
||||
void SetMulInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code);
|
||||
@ -464,10 +539,6 @@ class Processor
|
||||
Tile* GetTiles(){ return m_tiles; }
|
||||
|
||||
// Emulation Accelerators
|
||||
UINT32 LookUp16To32(UINT16 in) const { return m_rgb16_to_rgb32_lut[in]; }
|
||||
UINT32 LookUpIA8To32(UINT16 in) const { return m_ia8_to_rgb32_lut[in]; }
|
||||
UINT16* GetCCLUT1() { return m_cc_lut1; }
|
||||
UINT8* GetCCLUT2() { return m_cc_lut2; }
|
||||
UINT8 GetRandom() { return m_misc_state.m_random_seed += 0x13; }
|
||||
|
||||
// YUV Factors
|
||||
@ -485,8 +556,9 @@ class Processor
|
||||
// Render-related (move into eventual drawing-related classes?)
|
||||
Rectangle* GetScissor() { return &m_scissor; }
|
||||
void TCDiv(INT32 ss, INT32 st, INT32 sw, INT32* sss, INT32* sst);
|
||||
void TCDivNoPersp(INT32 ss, INT32 st, INT32 sw, INT32* sss, INT32* sst);
|
||||
UINT32 GetLog2(UINT32 lod_clamp);
|
||||
void RenderSpans(int start, int end, int tilenum, bool shade, bool texture, bool zbuffer, bool flip);
|
||||
void RenderSpans(int start, int end, int tilenum, bool flip);
|
||||
UINT8* GetHiddenBits() { return m_hidden_bits; }
|
||||
void GetAlphaCvg(UINT8 *comb_alpha);
|
||||
const UINT8* GetBayerMatrix() const { return s_bayer_matrix; }
|
||||
@ -495,11 +567,12 @@ class Processor
|
||||
int GetCurrFIFOIndex() const { return m_cmd_cur; }
|
||||
UINT32 GetFillColor32() const { return m_fill_color; }
|
||||
|
||||
void ZStore(UINT16* zb, UINT8* zhb, UINT32 z, UINT32 deltaz);
|
||||
UINT32 DecompressZ(UINT16 *zb);
|
||||
UINT16 DecompressDZ(UINT16* zb, UINT8* zhb);
|
||||
void ZStore(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z);
|
||||
UINT32 ZDecompress(UINT32 zcurpixel);
|
||||
UINT32 DZDecompress(UINT32 zcurpixel, UINT32 dzcurpixel);
|
||||
UINT32 DZCompress(UINT32 value);
|
||||
INT32 NormalizeDZPix(INT32 sum);
|
||||
bool ZCompare(void* fb, UINT8* hb, UINT16* zb, UINT8* zhb, UINT32 sz, UINT16 dzpix);
|
||||
bool ZCompare(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 sz, UINT16 dzpix);
|
||||
|
||||
// Fullscreen update-related
|
||||
void VideoUpdate(bitmap_t *bitmap);
|
||||
@ -548,6 +621,31 @@ class Processor
|
||||
UINT32 AddLeftCvg(UINT32 x, UINT32 k);
|
||||
|
||||
UINT32* GetCommandData() { return m_cmd_data; }
|
||||
UINT32* GetTempRectData() { return m_temp_rect_data; }
|
||||
|
||||
void GetDitherValues(int x, int y, int* cdith, int* adith);
|
||||
|
||||
|
||||
int m_span_dr;
|
||||
int m_span_drdy;
|
||||
int m_span_dg;
|
||||
int m_span_dgdy;
|
||||
int m_span_db;
|
||||
int m_span_dbdy;
|
||||
int m_span_da;
|
||||
int m_span_dady;
|
||||
int m_span_ds;
|
||||
int m_span_dt;
|
||||
int m_span_dw;
|
||||
int m_span_dz;
|
||||
int m_span_dzdy;
|
||||
int m_span_dymax;
|
||||
int m_span_dzpix;
|
||||
|
||||
UINT32* GetSpecial9BitClampTable() { return m_special_9bit_clamptable; }
|
||||
|
||||
UINT16 decompress_cvmask_frombyte(UINT8 x);
|
||||
void lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy);
|
||||
|
||||
protected:
|
||||
Blender m_blender;
|
||||
@ -571,6 +669,7 @@ class Processor
|
||||
Color m_combined_color;
|
||||
Color m_texel0_color;
|
||||
Color m_texel1_color;
|
||||
Color m_next_texel_color;
|
||||
Color m_shade_color;
|
||||
Color m_key_scale;
|
||||
Color m_noise_color;
|
||||
@ -582,12 +681,22 @@ class Processor
|
||||
|
||||
UINT32 m_fill_color;
|
||||
|
||||
UINT16 m_cc_lut1[(1<<24)];
|
||||
UINT8 m_cc_lut2[(1<<24)];
|
||||
UINT32 m_rgb16_to_rgb32_lut[(1 << 16)];
|
||||
UINT32 m_ia8_to_rgb32_lut[(1 << 16)];
|
||||
typedef struct
|
||||
{
|
||||
UINT8 cvg;
|
||||
UINT8 cvbit;
|
||||
UINT8 xoff;
|
||||
UINT8 yoff;
|
||||
} CVMASKDERIVATIVE;
|
||||
CVMASKDERIVATIVE cvarray[(1 << 8)];
|
||||
|
||||
UINT16 z_com_table[0x40000]; //precalced table of compressed z values, 18b: 512 KB array!
|
||||
UINT32 z_complete_dec_table[0x4000]; //the same for decompressed z values, 14b
|
||||
UINT8 compressed_cvmasks[0x10000]; //16bit cvmask -> to byte
|
||||
|
||||
UINT32 m_cmd_data[0x1000];
|
||||
UINT32 m_temp_rect_data[0x1000];
|
||||
|
||||
int m_cmd_ptr;
|
||||
int m_cmd_cur;
|
||||
|
||||
@ -627,6 +736,13 @@ class Processor
|
||||
INT32 m_gamma_table[256];
|
||||
INT32 m_gamma_dither_table[0x4000];
|
||||
|
||||
UINT32 m_special_9bit_clamptable[512];
|
||||
|
||||
UINT8 m_replicated_rgba[32];
|
||||
|
||||
INT32 m_dzpix_enc;
|
||||
INT32 m_dz_enc;
|
||||
|
||||
class ZDecompressEntry
|
||||
{
|
||||
public:
|
||||
@ -634,9 +750,9 @@ class Processor
|
||||
UINT32 add;
|
||||
};
|
||||
|
||||
void BuildCompressedZTable();
|
||||
UINT16 m_z_compress_table[0x40000];
|
||||
static const ZDecompressEntry m_z_decompress_table[8];
|
||||
void precalc_cvmask_derivatives(void);
|
||||
void z_build_com_table(void);
|
||||
static const ZDecompressEntry z_dec_table[8];
|
||||
|
||||
// Internal screen-update functions
|
||||
void VideoUpdate16(bitmap_t *bitmap);
|
||||
|
@ -5,537 +5,265 @@
|
||||
namespace N64
|
||||
{
|
||||
|
||||
bool RDP::Blender::Blend(void* in_fb, UINT8* hb, RDP::Color c1, RDP::Color c2, int dith)
|
||||
namespace RDP
|
||||
{
|
||||
switch(m_misc_state->m_fb_size)
|
||||
|
||||
bool Blender::Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel)
|
||||
{
|
||||
ColorInputs* ci = m_rdp->GetColorInputs();
|
||||
INT32 r, g, b;
|
||||
|
||||
if (!m_other_modes->alpha_cvg_select)
|
||||
{
|
||||
case PIXEL_SIZE_16BIT:
|
||||
return Blend16Bit((UINT16*)in_fb, hb, c1, c2, dith);
|
||||
|
||||
case PIXEL_SIZE_32BIT:
|
||||
return Blend32Bit((UINT32*)in_fb, c1, c2);
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size);
|
||||
break;
|
||||
DitherA(&m_rdp->GetPixelColor()->i.a, adseed);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
DitherA(&m_rdp->GetShadeColor()->i.a, adseed);
|
||||
|
||||
bool RDP::Blender::Blend16Bit(UINT16* fb, UINT8* hb, RDP::Color c1, RDP::Color c2, int dith)
|
||||
{
|
||||
switch(m_other_modes->cycle_type)
|
||||
if (!AlphaCompare(m_rdp->GetPixelColor()->i.a))
|
||||
{
|
||||
case CYCLE_TYPE_1:
|
||||
return Blend16Bit1Cycle(fb, hb, c1, dith);
|
||||
|
||||
case CYCLE_TYPE_2:
|
||||
return Blend16Bit2Cycle(fb, hb, c1, c2, dith);
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported cycle type for Blend16Bit: %d\n", m_other_modes->cycle_type);
|
||||
break;
|
||||
//return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RDP::Blender::Blend16Bit1Cycle(UINT16* fb, UINT8* hb, RDP::Color c, int dith)
|
||||
{
|
||||
UINT16 mem = *fb;
|
||||
UINT32 memory_cvg = 7;
|
||||
if(m_other_modes->image_read_en)
|
||||
{
|
||||
memory_cvg = ((mem & 1) << 2) + (*hb & 3);
|
||||
}
|
||||
|
||||
// Alpha compare
|
||||
if (!AlphaCompare(c.i.a))
|
||||
if (m_other_modes->antialias_en ? (!m_misc_state->m_curpixel_cvg) : (!m_misc_state->m_curpixel_cvbit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_misc_state->m_curpixel_cvg) // New coverage is zero, so abort
|
||||
bool dontblend = (partialreject && m_rdp->GetPixelColor()->i.a >= 0xff);
|
||||
if (!m_blend_enable || dontblend)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int special_bsel = 0;
|
||||
if (m_rdp->GetColorInputs()->blender2b_a[0] == &m_rdp->GetMemoryColor()->i.a)
|
||||
{
|
||||
special_bsel = 1;
|
||||
}
|
||||
|
||||
m_rdp->GetPixelColor()->c = c.c;
|
||||
|
||||
if(!m_other_modes->z_compare_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_overlap = 0;
|
||||
}
|
||||
|
||||
m_rdp->GetMemoryColor()->c = m_rdp->LookUp16To32(mem);
|
||||
m_rdp->GetMemoryColor()->i.a = (memory_cvg << 5) & 0xe0;
|
||||
|
||||
int r;
|
||||
int g;
|
||||
int b;
|
||||
|
||||
if(m_other_modes->z_compare_en)
|
||||
{
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
BlendEquation0Force(&r, &g, &b, special_bsel);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_misc_state->m_curpixel_overlap)
|
||||
{
|
||||
r = *m_rdp->GetColorInputs()->blender1a_r[0];
|
||||
g = *m_rdp->GetColorInputs()->blender1a_g[0];
|
||||
b = *m_rdp->GetColorInputs()->blender1a_b[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
|
||||
BlendEquation0NoForce(&r, &g, &b, special_bsel);
|
||||
}
|
||||
}
|
||||
r = *ci->blender1a_r[0];
|
||||
g = *ci->blender1a_g[0];
|
||||
b = *ci->blender1a_b[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
|
||||
BlendEquation0Force(&r, &g, &b, special_bsel);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = *m_rdp->GetColorInputs()->blender1a_r[0];
|
||||
g = *m_rdp->GetColorInputs()->blender1a_g[0];
|
||||
b = *m_rdp->GetColorInputs()->blender1a_b[0];
|
||||
}
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *ci->blender1b_a[0];
|
||||
BlendEquationCycle0(&r, &g, &b, special_bsel);
|
||||
}
|
||||
|
||||
if(!(m_other_modes->rgb_dither_sel & 2))
|
||||
if (m_other_modes->rgb_dither_sel < 3)
|
||||
{
|
||||
// Hack to prevent "double-dithering" artifacts
|
||||
if (!(((r & 0xf8)==(m_rdp->GetMemoryColor()->i.r&0xf8) && (g & 0xf8) == (m_rdp->GetMemoryColor()->i.g & 0xf8) &&(b&0xf8)==(m_rdp->GetMemoryColor()->i.b&0xf8))))
|
||||
{
|
||||
DitherRGB(&r, &g, &b, dith);
|
||||
}
|
||||
DitherRGB(&r, &g, &b, dith);
|
||||
}
|
||||
|
||||
return m_rdp->GetFramebuffer()->Write(fb, hb, r, g, b);
|
||||
*fr = r;
|
||||
*fg = g;
|
||||
*fb = b;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RDP::Blender::Blend16Bit2Cycle(UINT16* fb, UINT8* hb, RDP::Color c1, RDP::Color c2, int dith)
|
||||
bool Blender::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1)
|
||||
{
|
||||
UINT16 mem = *fb;
|
||||
UINT32 memory_cvg = 7;
|
||||
if(m_other_modes->image_read_en)
|
||||
ColorInputs* ci = m_rdp->GetColorInputs();
|
||||
if (!m_other_modes->alpha_cvg_select)
|
||||
{
|
||||
memory_cvg = ((mem & 1) << 2) + (*hb & 3);
|
||||
DitherA(&m_rdp->GetPixelColor()->i.a, adseed);
|
||||
}
|
||||
|
||||
// Alpha compare
|
||||
if (!AlphaCompare(c2.i.a))
|
||||
DitherA(&m_rdp->GetShadeColor()->i.a, adseed);
|
||||
|
||||
if (!AlphaCompare(m_rdp->GetPixelColor()->i.a))
|
||||
{
|
||||
//return false;
|
||||
}
|
||||
|
||||
if (m_other_modes->antialias_en ? (!m_misc_state->m_curpixel_cvg) : (!m_misc_state->m_curpixel_cvbit))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_misc_state->m_curpixel_cvg)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *ci->blender1b_a[0];
|
||||
|
||||
int special_bsel = 0;
|
||||
if (m_rdp->GetColorInputs()->blender2b_a[0] == &m_rdp->GetMemoryColor()->i.a)
|
||||
{
|
||||
special_bsel = 1;
|
||||
}
|
||||
|
||||
m_rdp->GetPixelColor()->c = c2.c;
|
||||
|
||||
if(m_other_modes->z_compare_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_overlap = 0;
|
||||
}
|
||||
|
||||
m_rdp->GetMemoryColor()->c = m_rdp->LookUp16To32(mem);
|
||||
m_rdp->GetMemoryColor()->i.a = (memory_cvg << 5) & 0xe0;
|
||||
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
|
||||
int r, g, b;
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
BlendEquation0Force(&r, &g, &b, special_bsel);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendEquation0NoForce(&r, &g, &b, special_bsel);
|
||||
}
|
||||
INT32 r, g, b;
|
||||
BlendEquationCycle0(&r, &g, &b, special_bsel0);
|
||||
|
||||
m_rdp->GetBlendedColor()->i.r = r;
|
||||
m_rdp->GetBlendedColor()->i.g = g;
|
||||
m_rdp->GetBlendedColor()->i.b = b;
|
||||
m_rdp->GetBlendedColor()->i.a = m_rdp->GetPixelColor()->i.a;
|
||||
|
||||
m_rdp->GetPixelColor()->i.r = r;
|
||||
m_rdp->GetPixelColor()->i.g = g;
|
||||
m_rdp->GetPixelColor()->i.b = b;
|
||||
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[1];
|
||||
|
||||
if(m_other_modes->force_blend)
|
||||
bool dontblend = (partialreject && m_rdp->GetPixelColor()->i.a >= 0xff);
|
||||
if (!m_blend_enable || dontblend)
|
||||
{
|
||||
if (m_rdp->GetColorInputs()->blender2b_a[1] == &m_rdp->GetMemoryColor()->i.a)
|
||||
{
|
||||
special_bsel = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
special_bsel = 0;
|
||||
}
|
||||
|
||||
BlendEquation1Force(&r, &g, &b, special_bsel);
|
||||
r = *ci->blender1a_r[1];
|
||||
g = *ci->blender1a_g[1];
|
||||
b = *ci->blender1a_b[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_misc_state->m_curpixel_overlap)
|
||||
{
|
||||
r = *m_rdp->GetColorInputs()->blender1a_r[1];
|
||||
g = *m_rdp->GetColorInputs()->blender1a_g[1];
|
||||
b = *m_rdp->GetColorInputs()->blender1a_b[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_rdp->GetColorInputs()->blender2b_a[1] == &m_rdp->GetMemoryColor()->i.a)
|
||||
{
|
||||
special_bsel = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
special_bsel = 0;
|
||||
}
|
||||
|
||||
BlendEquation1NoForce(&r, &g, &b, special_bsel);
|
||||
}
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *ci->blender1b_a[1];
|
||||
BlendEquationCycle1(&r, &g, &b, special_bsel1);
|
||||
}
|
||||
|
||||
if(!(m_other_modes->rgb_dither_sel & 2))
|
||||
if (m_other_modes->rgb_dither_sel < 3)
|
||||
{
|
||||
// Hack to prevent "double-dithering" artifacts
|
||||
if (!(((r & 0xf8)==(m_rdp->GetMemoryColor()->i.r&0xf8) && (g & 0xf8) == (m_rdp->GetMemoryColor()->i.g & 0xf8) &&(b&0xf8)==(m_rdp->GetMemoryColor()->i.b&0xf8))))
|
||||
{
|
||||
DitherRGB(&r, &g, &b, dith);
|
||||
}
|
||||
DitherRGB(&r, &g, &b, dith);
|
||||
}
|
||||
|
||||
return m_rdp->GetFramebuffer()->Write(fb, hb, r, g, b);
|
||||
*fr = r;
|
||||
*fg = g;
|
||||
*fb = b;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RDP::Blender::Blend32Bit(UINT32* fb, RDP::Color c1, RDP::Color c2)
|
||||
void Blender::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special)
|
||||
{
|
||||
switch(m_other_modes->cycle_type)
|
||||
{
|
||||
case CYCLE_TYPE_1:
|
||||
return Blend32Bit1Cycle(fb, c1);
|
||||
ColorInputs* ci = m_rdp->GetColorInputs();
|
||||
UINT8 blend1a = *ci->blender1b_a[0] >> 3;
|
||||
UINT8 blend2a = *ci->blender2b_a[0] >> 3;
|
||||
|
||||
case CYCLE_TYPE_2:
|
||||
return Blend32Bit2Cycle(fb, c1, c2);
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported cycle type for Blend16Bit: %d\n", m_other_modes->cycle_type);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RDP::Blender::Blend32Bit1Cycle(UINT32* fb, RDP::Color c)
|
||||
{
|
||||
UINT32 mem = *fb;
|
||||
int r, g, b;
|
||||
|
||||
// Alpha compare
|
||||
if (!AlphaCompare(c.i.a))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_misc_state->m_curpixel_cvg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_rdp->GetPixelColor()->c = c.c;
|
||||
if (!m_other_modes->z_compare_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_overlap = 0;
|
||||
}
|
||||
|
||||
m_rdp->GetMemoryColor()->i.r = (mem >> 24) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.g = (mem >> 16) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.b = (mem >> 8) & 0xff;
|
||||
|
||||
if (m_other_modes->image_read_en)
|
||||
{
|
||||
m_rdp->GetMemoryColor()->i.a = mem & 0xe0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetMemoryColor()->i.a = 0xe0;
|
||||
}
|
||||
|
||||
if (!m_misc_state->m_curpixel_overlap && !m_other_modes->force_blend)
|
||||
{
|
||||
r = *m_rdp->GetColorInputs()->blender1a_r[0];
|
||||
g = *m_rdp->GetColorInputs()->blender1a_g[0];
|
||||
b = *m_rdp->GetColorInputs()->blender1a_b[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
BlendEquation0Force(&r, &g, &b, m_misc_state->m_special_bsel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendEquation0NoForce(&r, &g, &b, m_misc_state->m_special_bsel0);
|
||||
}
|
||||
}
|
||||
|
||||
return m_rdp->GetFramebuffer()->Write(fb, NULL, r, g, b);
|
||||
}
|
||||
|
||||
bool RDP::Blender::Blend32Bit2Cycle(UINT32* fb, RDP::Color c1, RDP::Color c2)
|
||||
{
|
||||
UINT32 mem = *fb;
|
||||
int r, g, b;
|
||||
|
||||
// Alpha compare
|
||||
if (!AlphaCompare(c2.i.a))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!m_misc_state->m_curpixel_cvg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
m_rdp->GetPixelColor()->c = c2.c;
|
||||
if (!m_other_modes->z_compare_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_overlap = 0;
|
||||
}
|
||||
|
||||
m_rdp->GetMemoryColor()->i.r = (mem >>24) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.g = (mem >> 16) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.b = (mem >> 8) & 0xff;
|
||||
|
||||
if (m_other_modes->image_read_en)
|
||||
{
|
||||
m_rdp->GetMemoryColor()->i.a = (mem & 0xe0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetMemoryColor()->i.a = 0xe0;
|
||||
}
|
||||
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
BlendEquation0Force(&r, &g, &b, m_misc_state->m_special_bsel0);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendEquation0NoForce(&r, &g, &b, m_misc_state->m_special_bsel0);
|
||||
}
|
||||
|
||||
m_rdp->GetBlendedColor()->i.r = r;
|
||||
m_rdp->GetBlendedColor()->i.g = g;
|
||||
m_rdp->GetBlendedColor()->i.b = b;
|
||||
|
||||
m_rdp->GetPixelColor()->i.r = r;
|
||||
m_rdp->GetPixelColor()->i.g = g;
|
||||
m_rdp->GetPixelColor()->i.b = b;
|
||||
|
||||
if (!m_misc_state->m_curpixel_overlap && !m_other_modes->force_blend)
|
||||
{
|
||||
r = *m_rdp->GetColorInputs()->blender1a_r[1];
|
||||
g = *m_rdp->GetColorInputs()->blender1a_g[1];
|
||||
b = *m_rdp->GetColorInputs()->blender1a_b[1];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetInvPixelColor()->i.a = 0xff - *m_rdp->GetColorInputs()->blender1b_a[1];
|
||||
|
||||
if(m_other_modes->force_blend)
|
||||
{
|
||||
BlendEquation1Force(&r, &g, &b, m_misc_state->m_special_bsel1);
|
||||
}
|
||||
else
|
||||
{
|
||||
BlendEquation1NoForce(&r, &g, &b, m_misc_state->m_special_bsel1);
|
||||
}
|
||||
}
|
||||
|
||||
return m_rdp->GetFramebuffer()->Write(fb, NULL, r, g, b);
|
||||
}
|
||||
|
||||
void RDP::Blender::BlendEquation0Force(INT32* r, INT32* g, INT32* b, int bsel_special)
|
||||
{
|
||||
int blend1a = *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
if (bsel_special)
|
||||
{
|
||||
blend1a &= 0xe0;
|
||||
blend1a = (blend1a >> m_shift_a) & 0x1C;
|
||||
blend2a = (blend2a >> m_shift_b) & 0x1C;
|
||||
}
|
||||
|
||||
INT32 tr = ((int)(*m_rdp->GetColorInputs()->blender1a_r[0]) * blend1a + (int)(*m_rdp->GetColorInputs()->blender2a_r[0]) * *m_rdp->GetColorInputs()->blender2b_a[0] + ((int)(*m_rdp->GetColorInputs()->blender2a_r[0]) << (3 + bsel_special))) >> 8;
|
||||
INT32 tg = ((int)(*m_rdp->GetColorInputs()->blender1a_g[0]) * blend1a + (int)(*m_rdp->GetColorInputs()->blender2a_g[0]) * *m_rdp->GetColorInputs()->blender2b_a[0] + ((int)(*m_rdp->GetColorInputs()->blender2a_g[0]) << (3 + bsel_special))) >> 8;
|
||||
INT32 tb = ((int)(*m_rdp->GetColorInputs()->blender1a_b[0]) * blend1a + (int)(*m_rdp->GetColorInputs()->blender2a_b[0]) * *m_rdp->GetColorInputs()->blender2b_a[0] + ((int)(*m_rdp->GetColorInputs()->blender2a_b[0]) << (3 + bsel_special))) >> 8;
|
||||
UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
|
||||
|
||||
if (tr > 255) *r = 255; else *r = tr;
|
||||
if (tg > 255) *g = 255; else *g = tg;
|
||||
if (tb > 255) *b = 255; else *b = tb;
|
||||
}
|
||||
*r = (((int)(*ci->blender1a_r[0]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_r[0]) * (int)(blend2a)));
|
||||
|
||||
*g = (((int)(*ci->blender1a_g[0]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_g[0]) * (int)(blend2a)));
|
||||
|
||||
*b = (((int)(*ci->blender1a_b[0]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_b[0]) * (int)(blend2a)));
|
||||
|
||||
void RDP::Blender::BlendEquation0NoForce(INT32* r, INT32* g, INT32* b, int bsel_special)
|
||||
{
|
||||
UINT8 blend1a = *m_rdp->GetColorInputs()->blender1b_a[0];
|
||||
UINT8 blend2a = *m_rdp->GetColorInputs()->blender2b_a[0];
|
||||
if (bsel_special)
|
||||
{
|
||||
blend1a &= 0xe0;
|
||||
}
|
||||
|
||||
UINT32 sum = (((blend1a >> 5) + (blend2a >> 5) + 1) & 0xf) << 5;
|
||||
|
||||
INT32 tr = (((int)(*m_rdp->GetColorInputs()->blender1a_r[0]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_r[0]) * (int)(blend2a)));
|
||||
tr += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_r[0])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_r[0])) << 3);
|
||||
|
||||
INT32 tg = (((int)(*m_rdp->GetColorInputs()->blender1a_g[0]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_g[0]) * (int)(blend2a)));
|
||||
tg += (bsel_special) ? ((int)((*m_rdp->GetColorInputs()->blender2a_g[0])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_g[0])) << 3);
|
||||
|
||||
INT32 tb = (((int)(*m_rdp->GetColorInputs()->blender1a_b[0]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_b[0]) * (int)(blend2a)));
|
||||
tb += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_b[0])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_b[0])) << 3);
|
||||
|
||||
if (sum)
|
||||
{
|
||||
tr /= sum;
|
||||
tg /= sum;
|
||||
tb /= sum;
|
||||
*r += (((int)*ci->blender2a_r[0]) << 2);
|
||||
*g += (((int)*ci->blender2a_g[0]) << 2);
|
||||
*b += (((int)*ci->blender2a_b[0]) << 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = *g = *b = 0xff;
|
||||
return;
|
||||
*r += (int)*ci->blender2a_r[0];
|
||||
*g += (int)*ci->blender2a_g[0];
|
||||
*b += (int)*ci->blender2a_b[0];
|
||||
}
|
||||
|
||||
if (tr > 255) *r = 255; else *r = tr;
|
||||
if (tg > 255) *g = 255; else *g = tg;
|
||||
if (tb > 255) *b = 255; else *b = tb;
|
||||
}
|
||||
*r >>= 2;
|
||||
*g >>= 2;
|
||||
*b >>= 2;
|
||||
|
||||
void RDP::Blender::BlendEquation1Force(INT32* r, INT32* g, INT32* b, int bsel_special)
|
||||
{
|
||||
UINT8 blend1a = *m_rdp->GetColorInputs()->blender1b_a[1];
|
||||
UINT8 blend2a = *m_rdp->GetColorInputs()->blender2b_a[1];
|
||||
if (bsel_special)
|
||||
if (m_other_modes->force_blend)
|
||||
{
|
||||
blend1a &= 0xe0;
|
||||
}
|
||||
|
||||
INT32 tr = (((int)(*m_rdp->GetColorInputs()->blender1a_r[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_r[1]) * (int)(blend2a)));
|
||||
tr += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_r[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_r[1])) << 3);
|
||||
|
||||
INT32 tg = (((int)(*m_rdp->GetColorInputs()->blender1a_g[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_g[1]) * (int)(blend2a)));
|
||||
tg += (bsel_special) ? ((int)((*m_rdp->GetColorInputs()->blender2a_g[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_g[1])) << 3);
|
||||
|
||||
INT32 tb = (((int)(*m_rdp->GetColorInputs()->blender1a_b[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_b[1]) * (int)(blend2a)));
|
||||
tb += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_b[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_b[1])) << 3);
|
||||
|
||||
tr >>= 8;
|
||||
tg >>= 8;
|
||||
tb >>= 8;
|
||||
|
||||
if (tr > 255) *r = 255; else *r = tr;
|
||||
if (tg > 255) *g = 255; else *g = tg;
|
||||
if (tb > 255) *b = 255; else *b = tb;
|
||||
}
|
||||
|
||||
void RDP::Blender::BlendEquation1NoForce(INT32* r, INT32* g, INT32* b, int bsel_special)
|
||||
{
|
||||
UINT8 blend1a = *m_rdp->GetColorInputs()->blender1b_a[1];
|
||||
UINT8 blend2a = *m_rdp->GetColorInputs()->blender2b_a[1];
|
||||
if (bsel_special)
|
||||
{
|
||||
blend1a &= 0xe0;
|
||||
}
|
||||
|
||||
UINT32 sum = (((blend1a >> 5) + (blend2a >> 5) + 1) & 0xf) << 5;
|
||||
|
||||
INT32 tr = (((int)(*m_rdp->GetColorInputs()->blender1a_r[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_r[1]) * (int)(blend2a)));
|
||||
tr += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_r[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_r[1])) << 3);
|
||||
|
||||
INT32 tg = (((int)(*m_rdp->GetColorInputs()->blender1a_g[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_g[1]) * (int)(blend2a)));
|
||||
tg += (bsel_special) ? ((int)((*m_rdp->GetColorInputs()->blender2a_g[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_g[1])) << 3);
|
||||
|
||||
INT32 tb = (((int)(*m_rdp->GetColorInputs()->blender1a_b[1]) * (int)(blend1a))) +
|
||||
(((int)(*m_rdp->GetColorInputs()->blender2a_b[1]) * (int)(blend2a)));
|
||||
tb += (bsel_special) ? (((int)(*m_rdp->GetColorInputs()->blender2a_b[1])) << 5) : (((int)(*m_rdp->GetColorInputs()->blender2a_b[1])) << 3);
|
||||
|
||||
if (sum)
|
||||
{
|
||||
tr /= sum;
|
||||
tg /= sum;
|
||||
tb /= sum;
|
||||
*r >>= 3;
|
||||
*g >>= 3;
|
||||
*b >>= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = *g = *b = 0xff;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tr > 255) *r = 255; else *r = tr;
|
||||
if (tg > 255) *g = 255; else *g = tg;
|
||||
if (tb > 255) *b = 255; else *b = tb;
|
||||
}
|
||||
|
||||
bool RDP::Blender::AlphaCompare(UINT8 alpha)
|
||||
{
|
||||
if(m_other_modes->alpha_compare_en)
|
||||
{
|
||||
if(m_other_modes->dither_alpha_en)
|
||||
if (sum)
|
||||
{
|
||||
return (alpha > m_rdp->GetRandom());
|
||||
*r /= sum;
|
||||
*g /= sum;
|
||||
*b /= sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (alpha > m_rdp->GetBlendColor()->i.a);
|
||||
*r = *g = *b = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if (*r > 255) *r = 255;
|
||||
if (*g > 255) *g = 255;
|
||||
if (*b > 255) *b = 255;
|
||||
}
|
||||
|
||||
void Blender::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special)
|
||||
{
|
||||
ColorInputs* ci = m_rdp->GetColorInputs();
|
||||
UINT8 blend1a = *ci->blender1b_a[1] >> 3;
|
||||
UINT8 blend2a = *ci->blender2b_a[1] >> 3;
|
||||
|
||||
if (bsel_special)
|
||||
{
|
||||
blend1a = (blend1a >> m_shift_a) & 0x1C;
|
||||
blend2a = (blend2a >> m_shift_b) & 0x1C;
|
||||
}
|
||||
|
||||
UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
|
||||
|
||||
*r = (((int)(*ci->blender1a_r[1]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_r[1]) * (int)(blend2a)));
|
||||
|
||||
*g = (((int)(*ci->blender1a_g[1]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_g[1]) * (int)(blend2a)));
|
||||
|
||||
*b = (((int)(*ci->blender1a_b[1]) * (int)(blend1a))) +
|
||||
(((int)(*ci->blender2a_b[1]) * (int)(blend2a)));
|
||||
|
||||
if (bsel_special)
|
||||
{
|
||||
*r += (((int)*ci->blender2a_r[1]) << 2);
|
||||
*g += (((int)*ci->blender2a_g[1]) << 2);
|
||||
*b += (((int)*ci->blender2a_b[1]) << 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
*r += (int)*ci->blender2a_r[1];
|
||||
*g += (int)*ci->blender2a_g[1];
|
||||
*b += (int)*ci->blender2a_b[1];
|
||||
}
|
||||
|
||||
*r >>= 2;
|
||||
*g >>= 2;
|
||||
*b >>= 2;
|
||||
|
||||
if (m_other_modes->force_blend)
|
||||
{
|
||||
*r >>= 3;
|
||||
*g >>= 3;
|
||||
*b >>= 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sum)
|
||||
{
|
||||
*r /= sum;
|
||||
*g /= sum;
|
||||
*b /= sum;
|
||||
}
|
||||
else
|
||||
{
|
||||
*r = *g = *b = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
if (*r > 255) *r = 255;
|
||||
if (*g > 255) *g = 255;
|
||||
if (*b > 255) *b = 255;
|
||||
}
|
||||
|
||||
bool Blender::AlphaCompare(UINT8 alpha)
|
||||
{
|
||||
INT32 threshold;
|
||||
if (m_other_modes->alpha_compare_en)
|
||||
{
|
||||
threshold = (m_other_modes->dither_alpha_en) ? (mame_rand(m_machine) & 0xff) : m_rdp->GetBlendColor()->i.a;
|
||||
if (alpha < threshold)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RDP::Blender::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
|
||||
void Blender::DitherA(UINT8 *a, int dith)
|
||||
{
|
||||
INT32 new_a = *a + dith;
|
||||
if(new_a & 0x100)
|
||||
{
|
||||
new_a = 0xff;
|
||||
}
|
||||
*a = (UINT8)new_a;
|
||||
}
|
||||
|
||||
void Blender::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
|
||||
{
|
||||
if ((*r & 7) > dith)
|
||||
{
|
||||
@ -563,4 +291,6 @@ void RDP::Blender::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
||||
|
@ -17,35 +17,42 @@ class Color;
|
||||
class Blender
|
||||
{
|
||||
public:
|
||||
Blender() { }
|
||||
Blender()
|
||||
{
|
||||
m_blend_enable = false;
|
||||
}
|
||||
|
||||
bool Blend(void* in_fb, UINT8* hb, Color c1, Color c2, int dith);
|
||||
bool Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1);
|
||||
bool Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel);
|
||||
|
||||
void SetOtherModes(OtherModes* other_modes) { m_other_modes = other_modes; }
|
||||
void SetMiscState(MiscState* misc_state) { m_misc_state = misc_state; }
|
||||
void SetMachine(running_machine* machine) { m_machine = machine; }
|
||||
void SetProcessor(Processor* rdp) { m_rdp = rdp; }
|
||||
|
||||
void SetBlendEnable(bool enable) { m_blend_enable = enable; }
|
||||
bool GetBlendEnable() { return m_blend_enable; }
|
||||
|
||||
void SetShiftA(INT32 shift) { m_shift_a = shift; }
|
||||
void SetShiftB(INT32 shift) { m_shift_b = shift; }
|
||||
|
||||
private:
|
||||
running_machine* m_machine;
|
||||
OtherModes* m_other_modes;
|
||||
MiscState* m_misc_state;
|
||||
Processor* m_rdp;
|
||||
|
||||
bool Blend16Bit(UINT16* fb, UINT8* hb, RDP::Color c1, RDP::Color c2, int dith);
|
||||
bool Blend16Bit1Cycle(UINT16* fb, UINT8* hb, RDP::Color c, int dith);
|
||||
bool Blend16Bit2Cycle(UINT16* fb, UINT8* hb, RDP::Color c1, RDP::Color c2, int dith);
|
||||
bool Blend32Bit(UINT32* fb, RDP::Color c1, RDP::Color c2);
|
||||
bool Blend32Bit1Cycle(UINT32* fb, RDP::Color c);
|
||||
bool Blend32Bit2Cycle(UINT32* fb, RDP::Color c1, RDP::Color c2);
|
||||
bool m_blend_enable;
|
||||
INT32 m_shift_a;
|
||||
INT32 m_shift_b;
|
||||
|
||||
void BlendEquationCycle0(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
void BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
|
||||
bool AlphaCompare(UINT8 alpha);
|
||||
|
||||
void BlendEquation0Force(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
void BlendEquation0NoForce(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
void BlendEquation1Force(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
void BlendEquation1NoForce(INT32* r, INT32* g, INT32* b, int bsel_special);
|
||||
|
||||
void DitherRGB(INT32* r, INT32* g, INT32* b, int dith);
|
||||
void DitherA(UINT8* a, int dith);
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
@ -5,161 +5,271 @@
|
||||
namespace N64
|
||||
{
|
||||
|
||||
bool RDP::Framebuffer::Write(void *fb, UINT8* hb, UINT32 r, UINT32 g, UINT32 b)
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
void Framebuffer::Write(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
switch(m_misc_state->m_fb_size)
|
||||
{
|
||||
case PIXEL_SIZE_16BIT:
|
||||
return Write16Bit((UINT16*)fb, hb, r, g, b);
|
||||
Write16Bit(curpixel, r, g, b);
|
||||
break;
|
||||
|
||||
case PIXEL_SIZE_32BIT:
|
||||
return Write32Bit((UINT32*)fb, r, g, b);
|
||||
Write32Bit(curpixel, r, g, b);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RDP::Framebuffer::Write16Bit(UINT16 *fb, UINT8* hb, UINT32 r, UINT32 g, UINT32 b)
|
||||
void Framebuffer::Write16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
#undef CVG_DRAW
|
||||
//#define CVG_DRAW
|
||||
#ifdef CVG_DRAW
|
||||
int covdraw;
|
||||
if (m_misc_state->m_curpixel_cvg == 8)
|
||||
{
|
||||
covdraw = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
covdraw = m_misc_state->m_curpixel_cvg << 5;
|
||||
}
|
||||
int covdraw = (curpixel_cvg - 1) << 5;
|
||||
r = covdraw;
|
||||
g = covdraw;
|
||||
b = covdraw;
|
||||
#endif
|
||||
|
||||
if (!m_other_modes->z_compare_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_overlap = 0;
|
||||
}
|
||||
UINT32 fb = (m_misc_state->m_fb_address >> 1) + curpixel;
|
||||
UINT32 hb = fb;
|
||||
|
||||
UINT32 memory_cvg = 8;
|
||||
if (m_other_modes->image_read_en)
|
||||
#if 0
|
||||
if (m_misc_state->m_curpixel_cvg > 8 && m_other_modes->z_mode != 1)
|
||||
{
|
||||
memory_cvg = ((*fb & 1) << 2) + (*hb & 3) + 1;
|
||||
stricterror("FBWRITE_16: curpixel_cvg %d", m_misc_state->m_curpixel_cvg);
|
||||
}
|
||||
|
||||
UINT32 newcvg = m_misc_state->m_curpixel_cvg + memory_cvg;
|
||||
bool wrapped = newcvg > 8;
|
||||
#endif
|
||||
|
||||
UINT16 finalcolor = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1);
|
||||
UINT32 finalcvg = 0;
|
||||
|
||||
UINT32 clamped_cvg = wrapped ? 8 : newcvg;
|
||||
newcvg = wrapped ? (newcvg - 8) : newcvg;
|
||||
|
||||
m_misc_state->m_curpixel_cvg--;
|
||||
newcvg--;
|
||||
memory_cvg--;
|
||||
clamped_cvg--;
|
||||
|
||||
if (m_other_modes->color_on_cvg && !wrapped)
|
||||
if (m_other_modes->color_on_cvg && !m_pre_wrap)
|
||||
{
|
||||
*fb &= 0xfffe;
|
||||
*fb |= ((newcvg >> 2) & 1);
|
||||
*hb = (newcvg & 3);
|
||||
return false;
|
||||
finalcolor = RREADIDX16(fb) & 0xfffe;
|
||||
}
|
||||
|
||||
switch(m_other_modes->cvg_dest)
|
||||
{
|
||||
case 0:
|
||||
if (!m_other_modes->force_blend && !m_misc_state->m_curpixel_overlap)
|
||||
case 0:
|
||||
if (!m_rdp->GetBlender()->GetBlendEnable())
|
||||
{
|
||||
finalcvg = (m_misc_state->m_curpixel_cvg - 1) & 7;
|
||||
RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1));
|
||||
HWRITEADDR8(hb, finalcvg & 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalcvg = m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg;
|
||||
if (finalcvg & 8)
|
||||
{
|
||||
*fb = finalcolor | ((m_misc_state->m_curpixel_cvg >> 2) & 1);
|
||||
*hb = (m_misc_state->m_curpixel_cvg & 3);
|
||||
finalcvg = 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fb = finalcolor | ((clamped_cvg >> 2) & 1);
|
||||
*hb = (clamped_cvg & 3);
|
||||
}
|
||||
break;
|
||||
|
||||
case 1:
|
||||
*fb = finalcolor | ((newcvg >> 2) & 1);
|
||||
*hb = (newcvg & 3);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
*fb = finalcolor | 1;
|
||||
*hb = 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
*fb = finalcolor | ((memory_cvg >> 2) & 1);
|
||||
*hb = (memory_cvg & 3);
|
||||
break;
|
||||
RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1));
|
||||
HWRITEADDR8(hb, finalcvg & 3);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
finalcvg = (m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg) & 7;
|
||||
RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1));
|
||||
HWRITEADDR8(hb, finalcvg & 3);
|
||||
break;
|
||||
case 2:
|
||||
RWRITEIDX16(fb, finalcolor | 1);
|
||||
HWRITEADDR8(hb, 3);
|
||||
break;
|
||||
case 3:
|
||||
RWRITEIDX16(fb, finalcolor | ((m_misc_state->m_curpixel_memcvg >> 2) & 1));
|
||||
HWRITEADDR8(hb, m_misc_state->m_curpixel_memcvg & 3);
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool RDP::Framebuffer::Write32Bit(UINT32 *fb, UINT32 r, UINT32 g, UINT32 b)
|
||||
void Framebuffer::Write32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
UINT32 finalcolor = (r << 24) | (g << 16) | (b << 8);
|
||||
UINT32 memory_alphachannel = *fb & 0xff;
|
||||
UINT32 fb = (m_misc_state->m_fb_address >> 2) + curpixel;
|
||||
UINT32 finalcolor = (r << 24) | (g << 16) | (b << 8);//cvg as 3 MSBs of alpha channel;
|
||||
UINT32 finalcvg = 0;
|
||||
|
||||
UINT32 memory_cvg = 8;
|
||||
#if 0
|
||||
if (curpixel_cvg > 8 && m_other_modes->z_mode != 1)
|
||||
{
|
||||
stricterror("FBWRITE_16: curpixel_cvg %d", curpixel_cvg);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_other_modes->color_on_cvg && !m_pre_wrap)
|
||||
{
|
||||
finalcolor = RREADIDX32(fb) & 0xffffff00;
|
||||
}
|
||||
|
||||
switch(m_other_modes->cvg_dest)
|
||||
{
|
||||
case 0: //normal
|
||||
if (!m_rdp->GetBlender()->GetBlendEnable())
|
||||
{
|
||||
finalcvg = (m_misc_state->m_curpixel_cvg - 1) & 7;
|
||||
finalcolor |= (finalcvg << 5);
|
||||
RWRITEIDX32(fb, finalcolor);
|
||||
}
|
||||
else
|
||||
{
|
||||
finalcvg = m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg;
|
||||
if (finalcvg & 8)
|
||||
{
|
||||
finalcvg = 7;
|
||||
}
|
||||
finalcolor |= (finalcvg << 5);
|
||||
RWRITEIDX32(fb, finalcolor);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
finalcvg = (m_misc_state->m_curpixel_cvg + m_misc_state->m_curpixel_memcvg) & 7;
|
||||
finalcolor |= (finalcvg << 5);
|
||||
RWRITEIDX32(fb, finalcolor);
|
||||
break;
|
||||
case 2:
|
||||
RWRITEIDX32(fb, finalcolor | 0xE0);
|
||||
break;
|
||||
case 3:
|
||||
finalcolor |= (m_misc_state->m_curpixel_memcvg << 5);
|
||||
RWRITEIDX32(fb, finalcolor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Read(UINT32 curpixel)
|
||||
{
|
||||
switch(m_misc_state->m_fb_size)
|
||||
{
|
||||
case PIXEL_SIZE_16BIT:
|
||||
Read16Bit(curpixel);
|
||||
break;
|
||||
|
||||
case PIXEL_SIZE_32BIT:
|
||||
Read32Bit(curpixel);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Read16Bit(UINT32 curpixel)
|
||||
{
|
||||
UINT16 fword = RREADIDX16((m_misc_state->m_fb_address >> 1) + curpixel);
|
||||
UINT8 hbyte = HREADADDR8((m_misc_state->m_fb_address >> 1) + curpixel);
|
||||
m_rdp->GetMemoryColor()->i.r = GETHICOL(fword);
|
||||
m_rdp->GetMemoryColor()->i.g = GETMEDCOL(fword);
|
||||
m_rdp->GetMemoryColor()->i.b = GETLOWCOL(fword);
|
||||
if (m_other_modes->image_read_en)
|
||||
{
|
||||
memory_cvg = ((*fb >>5) & 7) + 1;
|
||||
m_misc_state->m_curpixel_memcvg = ((fword & 1) << 2) | (hbyte & 3);
|
||||
m_rdp->GetMemoryColor()->i.a = m_misc_state->m_curpixel_memcvg << 5;
|
||||
}
|
||||
|
||||
UINT32 newcvg = m_misc_state->m_curpixel_cvg + memory_cvg;
|
||||
bool wrapped = (newcvg > 8);
|
||||
UINT32 clamped_cvg = wrapped ? 8 : newcvg;
|
||||
newcvg = (wrapped) ? (newcvg - 8) : newcvg;
|
||||
|
||||
m_misc_state->m_curpixel_cvg--;
|
||||
newcvg--;
|
||||
memory_cvg--;
|
||||
clamped_cvg--;
|
||||
|
||||
if (m_other_modes->color_on_cvg && !wrapped)
|
||||
else
|
||||
{
|
||||
*fb &= 0xffffff00;
|
||||
*fb |= ((newcvg << 5) & 0xff);
|
||||
return 0;
|
||||
m_misc_state->m_curpixel_memcvg = 7;
|
||||
m_rdp->GetMemoryColor()->i.a = 0xff;
|
||||
}
|
||||
|
||||
switch(m_other_modes->cvg_dest)
|
||||
{
|
||||
case 0:
|
||||
if (!m_other_modes->force_blend && !m_misc_state->m_curpixel_overlap)
|
||||
{
|
||||
*fb = finalcolor|(m_misc_state->m_curpixel_cvg << 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
*fb = finalcolor|(clamped_cvg << 5);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
*fb = finalcolor | (newcvg << 5);
|
||||
break;
|
||||
case 2:
|
||||
*fb = finalcolor | 0xE0;
|
||||
break;
|
||||
case 3:
|
||||
*fb = finalcolor | memory_alphachannel;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Framebuffer::Read32Bit(UINT32 curpixel)
|
||||
{
|
||||
UINT32 mem = RREADIDX32((m_misc_state->m_fb_address >> 2) + curpixel);
|
||||
m_rdp->GetMemoryColor()->i.r = (mem >> 24) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.g = (mem >> 16) & 0xff;
|
||||
m_rdp->GetMemoryColor()->i.b = (mem >> 8) & 0xff;
|
||||
if (m_other_modes->image_read_en)
|
||||
{
|
||||
m_misc_state->m_curpixel_memcvg = (mem >> 5) & 7;
|
||||
m_rdp->GetMemoryColor()->i.a = (mem) & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_misc_state->m_curpixel_memcvg = 7;
|
||||
m_rdp->GetMemoryColor()->i.a = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Copy(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
switch(m_misc_state->m_fb_size)
|
||||
{
|
||||
case PIXEL_SIZE_16BIT:
|
||||
Copy16Bit(curpixel, r, g, b);
|
||||
break;
|
||||
|
||||
case PIXEL_SIZE_32BIT:
|
||||
Copy32Bit(curpixel, r, g, b);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
UINT16 val = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((m_misc_state->m_curpixel_cvg >> 2) & 1);
|
||||
RWRITEIDX16((m_misc_state->m_fb_address >> 1) + curpixel, val);
|
||||
HWRITEADDR8((m_misc_state->m_fb_address >> 1) + curpixel, m_misc_state->m_curpixel_cvg & 3);
|
||||
}
|
||||
|
||||
void Framebuffer::Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
|
||||
{
|
||||
UINT32 val = (r << 24) | (g << 16) | (b << 8) | (m_misc_state->m_curpixel_cvg << 5);
|
||||
RWRITEIDX32((m_misc_state->m_fb_address >> 2) + curpixel, val);
|
||||
}
|
||||
|
||||
void Framebuffer::Fill(UINT32 curpixel)
|
||||
{
|
||||
switch(m_misc_state->m_fb_size)
|
||||
{
|
||||
case PIXEL_SIZE_16BIT:
|
||||
Fill16Bit(curpixel);
|
||||
break;
|
||||
|
||||
case PIXEL_SIZE_32BIT:
|
||||
Fill32Bit(curpixel);
|
||||
break;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported bit depth: %d\n", m_misc_state->m_fb_size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Framebuffer::Fill16Bit(UINT32 curpixel)
|
||||
{
|
||||
UINT16 val;
|
||||
if (curpixel & 1)
|
||||
{
|
||||
val = m_rdp->GetFillColor32() & 0xffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
val = (m_rdp->GetFillColor32() >> 16) & 0xffff;
|
||||
}
|
||||
RWRITEIDX16((m_misc_state->m_fb_address >> 1) + curpixel, val);
|
||||
HWRITEADDR8((m_misc_state->m_fb_address >> 1) + curpixel, ((val & 1) << 1) | (val & 1));
|
||||
}
|
||||
|
||||
void Framebuffer::Fill32Bit(UINT32 curpixel)
|
||||
{
|
||||
UINT32 fill_color = m_rdp->GetFillColor32();
|
||||
RWRITEIDX32((m_misc_state->m_fb_address >> 2) + curpixel, fill_color);
|
||||
HWRITEADDR8((m_misc_state->m_fb_address >> 1) + (curpixel << 1), (fill_color & 0x10000) ? 3 : 0);
|
||||
HWRITEADDR8((m_misc_state->m_fb_address >> 1) + (curpixel << 1) + 1, (fill_color & 0x1) ? 3 : 0);
|
||||
}
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
||||
|
@ -15,19 +15,35 @@ class MiscState;
|
||||
class Framebuffer
|
||||
{
|
||||
public:
|
||||
Framebuffer() { }
|
||||
Framebuffer()
|
||||
{
|
||||
m_pre_wrap = false;
|
||||
}
|
||||
|
||||
bool Write(void* fb, UINT8* hb, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Write(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Read(UINT32 index);
|
||||
void Copy(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Fill(UINT32 curpixel);
|
||||
|
||||
void SetProcessor(Processor* rdp) { m_rdp = rdp; }
|
||||
void SetOtherModes(OtherModes* other_modes) { m_other_modes = other_modes; }
|
||||
void SetMiscState(MiscState* misc_state) { m_misc_state = misc_state; }
|
||||
void SetPreWrap(bool prewrap) { m_pre_wrap = prewrap; }
|
||||
|
||||
private:
|
||||
Processor* m_rdp;
|
||||
OtherModes* m_other_modes;
|
||||
MiscState* m_misc_state;
|
||||
bool m_pre_wrap;
|
||||
|
||||
bool Write16Bit(UINT16* fb, UINT8* hb, UINT32 r, UINT32 g, UINT32 b);
|
||||
bool Write32Bit(UINT32* fb, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Write16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Write32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Read16Bit(UINT32 curpixel);
|
||||
void Read32Bit(UINT32 curpixel);
|
||||
void Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b);
|
||||
void Fill16Bit(UINT32 curpixel);
|
||||
void Fill32Bit(UINT32 curpixel);
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
@ -1,465 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "includes/n64.h"
|
||||
#include "video/n64.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
void TexFetch::SetMachine(running_machine *machine)
|
||||
{
|
||||
_n64_state *state = machine->driver_data<_n64_state>();
|
||||
|
||||
m_machine = machine;
|
||||
m_rdp = &state->m_rdp;
|
||||
m_other_modes = m_rdp->GetOtherModes();
|
||||
m_misc_state = m_rdp->GetMiscState();
|
||||
m_tiles = m_rdp->GetTiles();
|
||||
}
|
||||
|
||||
UINT32 TexFetch::Fetch(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 tformat = tile->format;
|
||||
|
||||
if (t < 0) t = 0;
|
||||
if (s < 0) s = 0;
|
||||
|
||||
switch (tformat)
|
||||
{
|
||||
case 0: // RGBA
|
||||
return FetchRGBA(s, t, tile);
|
||||
|
||||
case 1: // YUV: Bottom of the 9th, Pokemon Stadium, Ogre Battle 64
|
||||
return FetchYUV(s, t, tile);
|
||||
|
||||
case 2: // Color Index
|
||||
return FetchCI(s, t, tile);
|
||||
|
||||
case 3: // Intensity + Alpha
|
||||
return FetchIA(s, t, tile);
|
||||
|
||||
case 4: // Intensity
|
||||
return FetchI(s, t, tile);
|
||||
|
||||
default:
|
||||
fatalerror("FETCH_TEXEL: unknown texture format %d\n", tformat);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 TexFetch::FetchRGBA(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 twidth = tile->line;
|
||||
UINT32 tbase = tile->tmem;
|
||||
UINT32 tpal = tile->palette & 0xf;
|
||||
|
||||
switch (tile->size)
|
||||
{
|
||||
case PIXEL_SIZE_4BIT:
|
||||
{
|
||||
UINT8 *tc = (UINT8*)m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s) / 2)) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0x7ff;
|
||||
UINT8 p = ((s) & 1) ? (tc[taddr ^ BYTE_ADDR_XOR] & 0xf) : (tc[taddr ^ BYTE_ADDR_XOR] >> 4);
|
||||
UINT16 c = m_rdp->GetTLUT()[(((tpal << 4) | p) ^ WORD_ADDR_XOR) << 2];
|
||||
|
||||
if (m_other_modes->en_tlut)
|
||||
{
|
||||
if (m_other_modes->tlut_type == 0)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((tpal << 4) | p) * 0x01010101;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_8BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s))) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0x7ff;
|
||||
UINT8 p = tc[taddr ^ BYTE_ADDR_XOR];
|
||||
UINT16 c = m_rdp->GetTLUT()[(p ^ WORD_ADDR_XOR) << 2];
|
||||
|
||||
if (m_other_modes->en_tlut)
|
||||
{
|
||||
if (m_other_modes->tlut_type == 0)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return p * 0x01010101;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_16BIT:
|
||||
{
|
||||
UINT16 *tc = m_rdp->GetTMEM16();
|
||||
int taddr = ((tbase>>1) + ((t) * (twidth>>1)) + (s)) ^ ((t & 1) ? XOR_SWAP_WORD : 0);
|
||||
UINT16 c = tc[(taddr & 0x7ff) ^ WORD_ADDR_XOR]; // PGA European Tour (U)
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_other_modes->tlut_type == 0) //Golden Eye 007, sea, "frigate" level
|
||||
{
|
||||
return m_rdp->LookUp16To32(m_rdp->GetTLUT()[(c >> 8) << 2]);
|
||||
}
|
||||
else // Beetle Adventure Racing, Mount Mayhem
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(m_rdp->GetTLUT()[(c >> 8) << 2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_32BIT:
|
||||
{
|
||||
UINT32 *tc = m_rdp->GetTMEM32();
|
||||
int xorval = (m_misc_state->m_fb_size == PIXEL_SIZE_16BIT) ? XOR_SWAP_WORD : XOR_SWAP_DWORD; // Conker's Bad Fur Day, Jet Force Gemini, Super Smash Bros., Mickey's Speedway USA, Ogre Battle, Wave Race, Gex 3, South Park Rally
|
||||
int taddr = (((tbase >> 2) + ((t) * (twidth >> 1)) + (s)) ^ ((t & 1) ? xorval : 0)) & 0x3ff;
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return tc[taddr];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_other_modes->tlut_type)
|
||||
{
|
||||
return m_rdp->LookUp16To32(m_rdp->GetTLUT()[(tc[taddr] >> 24) << 2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(m_rdp->GetTLUT()[(tc[taddr] >> 24) << 2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
fatalerror("FETCH_TEXEL: unknown RGBA texture size %d\n", tile->size);
|
||||
return 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 TexFetch::FetchYUV(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 twidth = tile->line;
|
||||
UINT32 tsize = tile->size;
|
||||
UINT32 tbase = tile->tmem;
|
||||
Color out;
|
||||
|
||||
out.c = 0;
|
||||
|
||||
if(tsize == PIXEL_SIZE_16BIT)
|
||||
{
|
||||
INT32 newr = 0;
|
||||
INT32 newg = 0;
|
||||
INT32 newb = 0;
|
||||
UINT16 *tc = m_rdp->GetTMEM16();
|
||||
int taddr = ((tbase >> 1) + ((t) * (twidth)) + (s)) ^ ((t & 1) ? XOR_SWAP_WORD : 0);
|
||||
UINT16 c1, c2;
|
||||
INT32 y;
|
||||
INT32 u, v;
|
||||
c1 = tc[taddr ^ WORD_ADDR_XOR];
|
||||
c2 = tc[taddr]; // other word
|
||||
|
||||
if (!(taddr & 1))
|
||||
{
|
||||
v = c2 >> 8;
|
||||
u = c1 >> 8;
|
||||
y = c1 & 0xff;
|
||||
}
|
||||
else
|
||||
{
|
||||
v = c1 >> 8;
|
||||
u = c2 >> 8;
|
||||
y = c1 & 0xff;
|
||||
}
|
||||
v -= 128;
|
||||
u -= 128;
|
||||
|
||||
if (!m_other_modes->bi_lerp0)
|
||||
{
|
||||
newr = y + ((m_rdp->GetK0() * v) >> 8);
|
||||
newg = y + ((m_rdp->GetK1() * u) >> 8) + ((m_rdp->GetK2() * v) >> 8);
|
||||
newb = y + ((m_rdp->GetK2() * u) >> 8);
|
||||
}
|
||||
out.i.r = (newr < 0) ? 0 : ((newr > 0xff) ? 0xff : newr);
|
||||
out.i.g = (newg < 0) ? 0 : ((newg > 0xff) ? 0xff : newg);
|
||||
out.i.b = (newb < 0) ? 0 : ((newb > 0xff) ? 0xff : newb);
|
||||
out.i.a = 0xff;
|
||||
}
|
||||
|
||||
return out.c;
|
||||
}
|
||||
|
||||
UINT32 TexFetch::FetchCI(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 twidth = tile->line;
|
||||
UINT32 tsize = tile->size;
|
||||
UINT32 tbase = tile->tmem;
|
||||
UINT32 tpal = tile->palette & 0xf;
|
||||
|
||||
switch (tsize)
|
||||
{
|
||||
case PIXEL_SIZE_4BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s) / 2)) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0x7ff;
|
||||
UINT8 p = ((s) & 1) ? (tc[taddr ^ BYTE_ADDR_XOR] & 0xf) : (tc[taddr ^ BYTE_ADDR_XOR] >> 4);
|
||||
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
|
||||
|
||||
if (m_other_modes->en_tlut)
|
||||
{
|
||||
if (m_other_modes->tlut_type == 0)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return ((tpal << 4) | p) * 0x01010101;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_8BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s))) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0x7ff;
|
||||
UINT8 p = tc[taddr ^ BYTE_ADDR_XOR];
|
||||
UINT16 c = m_rdp->GetTLUT()[p << 2];
|
||||
|
||||
if (m_other_modes->en_tlut)
|
||||
{
|
||||
if (m_other_modes->tlut_type == 0)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return p * 0x01010101;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_16BIT:
|
||||
{
|
||||
// 16-bit CI is a "valid" mode; some games use it, it behaves the same as 16-bit RGBA
|
||||
UINT16 *tc = m_rdp->GetTMEM16();
|
||||
int taddr = ((tbase>>1) + ((t) * (twidth>>1)) + (s)) ^ ((t & 1) ? XOR_SWAP_WORD : 0);
|
||||
UINT16 c = tc[(taddr & 0x7ff) ^ WORD_ADDR_XOR]; // PGA European Tour (U)
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_other_modes->tlut_type) // GoldenEye 007, sea, "frigate" level
|
||||
{
|
||||
return m_rdp->LookUp16To32(m_rdp->GetTLUT()[(c >> 8) << 2]);
|
||||
}
|
||||
else // Beetle Adventure Racing, Mount Mayhem
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(m_rdp->GetTLUT()[(c >> 8) << 2]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
fatalerror("FETCH_TEXEL: unknown CI texture size %d\n", tsize);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 TexFetch::FetchIA(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 twidth = tile->line;
|
||||
UINT32 tsize = tile->size;
|
||||
UINT32 tbase = tile->tmem;
|
||||
UINT32 tpal = tile->palette & 0xf;
|
||||
|
||||
switch (tsize)
|
||||
{
|
||||
case PIXEL_SIZE_4BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = (tbase + ((t) * twidth) + (s >> 1)) ^ ((t & 1) ? XOR_SWAP_BYTE : 0);
|
||||
UINT8 p = ((s) & 1) ? (tc[taddr ^ BYTE_ADDR_XOR] & 0xf) : (tc[taddr ^ BYTE_ADDR_XOR] >> 4);
|
||||
UINT8 i = ((p & 0xe) << 4) | ((p & 0xe) << 1) | (p & 0xe >> 2);
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return (i * 0x01010100) | ((p & 0x1) ? 0xff : 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
|
||||
if (!m_other_modes->tlut_type)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_8BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s))) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0xfff;
|
||||
UINT8 p = tc[taddr ^ BYTE_ADDR_XOR];
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
UINT8 i = (p >> 4) | (p & 0xf0);
|
||||
return (i * 0x01010100) | ((p & 0xf) | ((p << 4) & 0xf0));
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 c = m_rdp->GetTLUT()[p << 2];
|
||||
if (!m_other_modes->tlut_type)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_16BIT:
|
||||
{
|
||||
UINT16 *tc = m_rdp->GetTMEM16();
|
||||
int taddr = ((tbase >> 1) + ((t) * (twidth >> 1)) + (s)) ^ ((t & 1) ? XOR_SWAP_WORD : 0);
|
||||
UINT16 c = tc[taddr ^ WORD_ADDR_XOR];
|
||||
|
||||
if (m_other_modes->en_tlut)
|
||||
{
|
||||
c = m_rdp->GetTLUT()[(c >> 8) << 2];
|
||||
if (m_other_modes->tlut_type == 0)
|
||||
{
|
||||
return m_rdp->LookUp16To32(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(c);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return 0xffffffff;
|
||||
fatalerror("FETCH_TEXEL: unknown IA texture size %d\n", tsize);
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 TexFetch::FetchI(UINT32 s, UINT32 t, Tile* tile)
|
||||
{
|
||||
UINT32 twidth = tile->line;
|
||||
UINT32 tsize = tile->size;
|
||||
UINT32 tbase = tile->tmem;
|
||||
UINT32 tpal = tile->palette & 0xf;
|
||||
|
||||
switch (tsize)
|
||||
{
|
||||
case PIXEL_SIZE_4BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s) / 2)) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0xfff;
|
||||
UINT8 c = ((s) & 1) ? (tc[taddr ^ BYTE_ADDR_XOR] & 0xf) : (tc[taddr ^ BYTE_ADDR_XOR] >> 4);
|
||||
c |= (c << 4);
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return c * 0x01010101;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 k = m_rdp->GetTLUT()[((tpal << 4) | c) << 2];
|
||||
if (!m_other_modes->tlut_type)
|
||||
{
|
||||
return m_rdp->LookUp16To32(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(k);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PIXEL_SIZE_8BIT:
|
||||
{
|
||||
UINT8 *tc = m_rdp->GetTMEM();
|
||||
int taddr = ((tbase + ((t) * twidth) + ((s))) ^ ((t & 1) ? XOR_SWAP_BYTE : 0)) & 0xfff;
|
||||
UINT8 c = tc[taddr ^ BYTE_ADDR_XOR];
|
||||
|
||||
if (!m_other_modes->en_tlut)
|
||||
{
|
||||
return c * 0x01010101;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT16 k = m_rdp->GetTLUT()[ c << 2];
|
||||
if (!m_other_modes->tlut_type)
|
||||
{
|
||||
return m_rdp->LookUp16To32(k);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_rdp->LookUpIA8To32(k);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
//fatalerror("FETCH_TEXEL: unknown I texture size %d\n", tsize);
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
@ -1,44 +0,0 @@
|
||||
#ifndef _VIDEO_RDPFETCH_H_
|
||||
#define _VIDEO_RDPFETCH_H_
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
class Processor;
|
||||
class OtherModes;
|
||||
class MiscState;
|
||||
class Tile;
|
||||
|
||||
class TexFetch
|
||||
{
|
||||
public:
|
||||
TexFetch() { }
|
||||
|
||||
UINT32 Fetch(UINT32 s, UINT32 t, Tile* tile);
|
||||
|
||||
void SetMachine(running_machine* machine);
|
||||
|
||||
private:
|
||||
running_machine* m_machine;
|
||||
Processor* m_rdp;
|
||||
OtherModes* m_other_modes;
|
||||
MiscState* m_misc_state;
|
||||
Tile* m_tiles;
|
||||
|
||||
UINT32 FetchRGBA(UINT32 s, UINT32 t, Tile* tile);
|
||||
UINT32 FetchYUV(UINT32 s, UINT32 t, Tile* tile);
|
||||
UINT32 FetchCI(UINT32 s, UINT32 t, Tile* tile);
|
||||
UINT32 FetchIA(UINT32 s, UINT32 t, Tile* tile);
|
||||
UINT32 FetchI(UINT32 s, UINT32 t, Tile* tile);
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
||||
|
||||
#endif // _VIDEO_RDPFETCH_H_
|
@ -1,510 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "includes/n64.h"
|
||||
#include "video/n64.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
#define LookUpCC(A, B, C, D) m_rdp->GetCCLUT2()[(m_rdp->GetCCLUT1()[(A << 16) | (B << 8) | C] << 8) | D]
|
||||
|
||||
void Rectangle::SetMachine(running_machine* machine)
|
||||
{
|
||||
_n64_state *state = machine->driver_data<_n64_state>();
|
||||
|
||||
m_machine = machine;
|
||||
m_rdp = &state->m_rdp;
|
||||
m_misc_state = m_rdp->GetMiscState();
|
||||
m_other_modes = m_rdp->GetOtherModes();
|
||||
m_blender = m_rdp->GetBlender();
|
||||
}
|
||||
|
||||
void Rectangle::Draw()
|
||||
{
|
||||
switch(m_other_modes->cycle_type)
|
||||
{
|
||||
case CYCLE_TYPE_1:
|
||||
Draw1Cycle();
|
||||
return;
|
||||
|
||||
case CYCLE_TYPE_2:
|
||||
Draw2Cycle();
|
||||
return;
|
||||
|
||||
case CYCLE_TYPE_FILL:
|
||||
DrawFill();
|
||||
return;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported cycle type for Textured Rectangle: %d\n", m_other_modes->cycle_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void Rectangle::Draw1Cycle()
|
||||
{
|
||||
UINT16 *fb = (UINT16*)&rdram[(m_misc_state->m_fb_address / 4)];
|
||||
UINT8* hb = &m_rdp->GetHiddenBits()[m_misc_state->m_fb_address >> 1];
|
||||
|
||||
int index, i, j;
|
||||
int x1 = m_xh >> 2;
|
||||
int x2 = m_xl >> 2;
|
||||
int y1 = m_yh >> 2;
|
||||
int y2 = m_yl >> 2;
|
||||
UINT16 fill_color1 = (m_rdp->GetFillColor32() >> 16) & 0xffff;
|
||||
UINT16 fill_color2 = (m_rdp->GetFillColor32() >> 0) & 0xffff;
|
||||
int fill_cvg1 = (fill_color1 & 1) ? 8 : 1;
|
||||
int fill_cvg2 = (fill_color2 & 1) ? 8 : 1;
|
||||
|
||||
if (x2 <= x1)
|
||||
{
|
||||
x2=x1+1; // SCARS (E)
|
||||
}
|
||||
if (y2 == y1)
|
||||
{
|
||||
y2=y1+1; // Goldeneye
|
||||
}
|
||||
|
||||
// clip
|
||||
if (x1 < m_rdp->GetScissor()->m_xh)
|
||||
{
|
||||
x1 = m_rdp->GetScissor()->m_xh;
|
||||
}
|
||||
if (y1 < m_rdp->GetScissor()->m_yh)
|
||||
{
|
||||
y1 = m_rdp->GetScissor()->m_yh;
|
||||
}
|
||||
if (x2 >= m_rdp->GetScissor()->m_xl)
|
||||
{
|
||||
x2 = m_rdp->GetScissor()->m_xl - 1;
|
||||
}
|
||||
if (y2 >= m_rdp->GetScissor()->m_yl)
|
||||
{
|
||||
y2 = m_rdp->GetScissor()->m_yl - 1;
|
||||
}
|
||||
|
||||
m_rdp->GetShadeColor()->c = 0; // Needed by Command & Conquer menus
|
||||
|
||||
if(m_other_modes->rgb_dither_sel == 0)
|
||||
{
|
||||
for (int j = y1; j <= y2; j++)
|
||||
{
|
||||
Color c1;
|
||||
int dith = 0;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i = x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
|
||||
dith = m_rdp->GetMagicMatrix()[(((j) & 3) << 2) + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, *m_rdp->GetZero(), dith);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_other_modes->rgb_dither_sel == 1)
|
||||
{
|
||||
for (j = y1; j <= y2; j++)
|
||||
{
|
||||
Color c1;
|
||||
int dith = 0;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i = x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
|
||||
dith = m_rdp->GetBayerMatrix()[(((j) & 3) << 2) + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, *m_rdp->GetZero(), dith);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j = y1; j <= y2; j++)
|
||||
{
|
||||
Color c1;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i = x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, *m_rdp->GetZero(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rectangle::Draw2Cycle()
|
||||
{
|
||||
UINT16 *fb = (UINT16*)&rdram[(m_misc_state->m_fb_address / 4)];
|
||||
UINT8* hb = &m_rdp->GetHiddenBits()[m_misc_state->m_fb_address >> 1];
|
||||
|
||||
int index, i, j;
|
||||
int x1 = m_xh >> 2;
|
||||
int x2 = m_xl >> 2;
|
||||
int y1 = m_yh >> 2;
|
||||
int y2 = m_yl >> 2;
|
||||
UINT16 fill_color1;
|
||||
UINT16 fill_color2;
|
||||
int fill_cvg1;
|
||||
int fill_cvg2;
|
||||
|
||||
if (x2 <= x1)
|
||||
{
|
||||
x2=x1+1; // SCARS (E)
|
||||
}
|
||||
if (y2 == y1)
|
||||
{
|
||||
y2=y1+1; // Goldeneye
|
||||
}
|
||||
|
||||
|
||||
fill_color1 = (m_rdp->GetFillColor32() >> 16) & 0xffff;
|
||||
fill_color2 = (m_rdp->GetFillColor32() >> 0) & 0xffff;
|
||||
fill_cvg1 = (fill_color1 & 1) ? 8 : 1;
|
||||
fill_cvg2 = (fill_color2 & 1) ? 8 : 1;
|
||||
|
||||
// clip
|
||||
if (x1 < m_rdp->GetScissor()->m_xh)
|
||||
{
|
||||
x1 = m_rdp->GetScissor()->m_xh;
|
||||
}
|
||||
if (y1 < m_rdp->GetScissor()->m_yh)
|
||||
{
|
||||
y1 = m_rdp->GetScissor()->m_yh;
|
||||
}
|
||||
if (x2 >= m_rdp->GetScissor()->m_xl)
|
||||
{
|
||||
x2 = m_rdp->GetScissor()->m_xl - 1;
|
||||
}
|
||||
if (y2 >= m_rdp->GetScissor()->m_yl)
|
||||
{
|
||||
y2 = m_rdp->GetScissor()->m_yl - 1;
|
||||
}
|
||||
|
||||
m_rdp->GetShadeColor()->c = 0; // Needed by Command & Conquer menus
|
||||
|
||||
if(m_other_modes->rgb_dither_sel == 0)
|
||||
{
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
Color c1;
|
||||
Color c2;
|
||||
int dith = 0;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
|
||||
dith = m_rdp->GetMagicMatrix()[(((j) & 3) << 2) + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, c2, dith);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m_other_modes->rgb_dither_sel == 1)
|
||||
{
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
Color c1;
|
||||
Color c2;
|
||||
int dith = 0;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
|
||||
dith = m_rdp->GetBayerMatrix()[(((j) & 3) << 2) + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, c2, dith);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
Color c1, c2;
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1; i <= x2; i++)
|
||||
{
|
||||
m_misc_state->m_curpixel_cvg = (i & 1) ? fill_cvg1 : fill_cvg2;
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
|
||||
m_blender->Blend(&fb[(index + i) ^ WORD_ADDR_XOR], &hb[(index + i) ^ BYTE_ADDR_XOR], c1, c2, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Rectangle::DrawFill()
|
||||
{
|
||||
UINT16 *fb = (UINT16*)&rdram[(m_misc_state->m_fb_address / 4)];
|
||||
UINT8* hb = &m_rdp->GetHiddenBits()[m_misc_state->m_fb_address >> 1];
|
||||
|
||||
int index, i, j;
|
||||
int x1 = m_xh >> 2;
|
||||
int x2 = m_xl >> 2;
|
||||
int y1 = m_yh >> 2;
|
||||
int y2 = m_yl >> 2;
|
||||
UINT16 fill_color1;
|
||||
UINT16 fill_color2;
|
||||
int fill_cvg1;
|
||||
int fill_cvg2;
|
||||
|
||||
if (x2 <= x1)
|
||||
{
|
||||
x2=x1+1; // SCARS (E)
|
||||
}
|
||||
if (y2 == y1)
|
||||
{
|
||||
y2=y1+1; // Goldeneye
|
||||
}
|
||||
|
||||
|
||||
fill_color1 = (m_rdp->GetFillColor32() >> 16) & 0xffff;
|
||||
fill_color2 = (m_rdp->GetFillColor32() >> 0) & 0xffff;
|
||||
fill_cvg1 = (fill_color1 & 1) ? 8 : 1;
|
||||
fill_cvg2 = (fill_color2 & 1) ? 8 : 1;
|
||||
|
||||
// clip
|
||||
if (x1 < m_rdp->GetScissor()->m_xh)
|
||||
{
|
||||
x1 = m_rdp->GetScissor()->m_xh;
|
||||
}
|
||||
if (y1 < m_rdp->GetScissor()->m_yh)
|
||||
{
|
||||
y1 = m_rdp->GetScissor()->m_yh;
|
||||
}
|
||||
if (x2 >= m_rdp->GetScissor()->m_xl)
|
||||
{
|
||||
x2 = m_rdp->GetScissor()->m_xl - 1;
|
||||
}
|
||||
if (y2 >= m_rdp->GetScissor()->m_yl)
|
||||
{
|
||||
y2 = m_rdp->GetScissor()->m_yl - 1;
|
||||
}
|
||||
|
||||
m_rdp->GetShadeColor()->c = 0; // Needed by Command & Conquer menus
|
||||
|
||||
fill_cvg1 = (fill_color1 & 1) ? 3 : 0;
|
||||
fill_cvg2 = (fill_color2 & 1) ? 3 : 0;
|
||||
|
||||
if(x1 & 1)
|
||||
{
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1; i <= x2; i += 2)
|
||||
{
|
||||
int curpixel = index + i;
|
||||
fb[curpixel ^ WORD_ADDR_XOR] = fill_color2;
|
||||
hb[curpixel ^ BYTE_ADDR_XOR] = fill_cvg2;
|
||||
}
|
||||
}
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1+1; i <= x2; i += 2)
|
||||
{
|
||||
int curpixel = index + i;
|
||||
fb[curpixel ^ WORD_ADDR_XOR] = fill_color1;
|
||||
hb[curpixel ^ BYTE_ADDR_XOR] = fill_cvg1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1; i <= x2; i += 2)
|
||||
{
|
||||
int curpixel = index + i;
|
||||
fb[curpixel ^ WORD_ADDR_XOR] = fill_color1;
|
||||
hb[curpixel ^ BYTE_ADDR_XOR] = fill_cvg1;
|
||||
}
|
||||
}
|
||||
for (j=y1; j <= y2; j++)
|
||||
{
|
||||
index = j * m_misc_state->m_fb_width;
|
||||
for (i=x1+1; i <= x2; i += 2)
|
||||
{
|
||||
int curpixel = index + i;
|
||||
fb[curpixel ^ WORD_ADDR_XOR] = fill_color2;
|
||||
hb[curpixel ^ BYTE_ADDR_XOR] = fill_cvg2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
@ -1,54 +0,0 @@
|
||||
#ifndef _VIDEO_RDPFILLRECT_H_
|
||||
#define _VIDEO_RDPFILLRECT_H_
|
||||
|
||||
#include "emu.h"
|
||||
#include "video/rdpblend.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
class OtherModes;
|
||||
class MiscState;
|
||||
class Processor;
|
||||
class Blender;
|
||||
class Color;
|
||||
|
||||
class Rectangle
|
||||
{
|
||||
public:
|
||||
Rectangle() {}
|
||||
Rectangle(running_machine *machine, UINT32 *data)
|
||||
{
|
||||
SetMachine(machine);
|
||||
InitFromBuffer(data);
|
||||
}
|
||||
|
||||
void Draw();
|
||||
void SetMachine(running_machine *machine);
|
||||
void InitFromBuffer(UINT32 *data);
|
||||
|
||||
UINT16 m_xl; // 10.2 fixed-point
|
||||
UINT16 m_yl; // 10.2 fixed-point
|
||||
UINT16 m_xh; // 10.2 fixed-point
|
||||
UINT16 m_yh; // 10.2 fixed-point
|
||||
|
||||
private:
|
||||
void Draw1Cycle();
|
||||
void Draw2Cycle();
|
||||
void DrawFill();
|
||||
|
||||
running_machine* m_machine;
|
||||
Processor* m_rdp;
|
||||
MiscState* m_misc_state;
|
||||
OtherModes* m_other_modes;
|
||||
Blender* m_blender;
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
||||
|
||||
#endif // _VIDEO_RDPFILLRECT_H_
|
@ -10,10 +10,8 @@ namespace RDP
|
||||
|
||||
#define LookUpCC(A, B, C, D) m_rdp->GetCCLUT2()[(m_rdp->GetCCLUT1()[(A << 16) | (B << 8) | C] << 8) | D]
|
||||
|
||||
void Processor::RenderSpans(int start, int end, int tilenum, bool shade, bool texture, bool zbuffer, bool flip)
|
||||
void Processor::RenderSpans(int start, int end, int tilenum, bool flip)
|
||||
{
|
||||
m_tex_pipe.CalculateClampDiffs(tilenum);
|
||||
|
||||
int clipy1 = GetScissor()->m_yh;
|
||||
int clipy2 = GetScissor()->m_yl;
|
||||
|
||||
@ -37,7 +35,14 @@ void Processor::RenderSpans(int start, int end, int tilenum, bool shade, bool te
|
||||
for(int i = start; i <= end; i++)
|
||||
{
|
||||
m_span[i].SetMachine(m_machine);
|
||||
m_span[i].Draw(i, tilenum, shade, texture, zbuffer, flip);
|
||||
switch(m_other_modes.cycle_type)
|
||||
{
|
||||
case CYCLE_TYPE_1: m_span[i].Draw1Cycle(i, tilenum, flip); break;
|
||||
case CYCLE_TYPE_2: m_span[i].Draw2Cycle(i, tilenum, flip); break;
|
||||
case CYCLE_TYPE_COPY: m_span[i].DrawCopy(i, tilenum, flip); break;
|
||||
case CYCLE_TYPE_FILL: m_span[i].DrawFill(i, tilenum, flip); break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -60,17 +65,6 @@ void Span::Dump()
|
||||
printf("%d", m_cvg[index]);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf(" m_dymax = %08x\n", m_dymax);
|
||||
printf(" m_ds.w = %08x\n", m_ds.w);
|
||||
printf(" m_dt.w = %08x\n", m_dt.w);
|
||||
printf(" m_dw.w = %08x\n", m_dw.w);
|
||||
printf(" m_dr.w = %08x\n", m_dr.w);
|
||||
printf(" m_dg.w = %08x\n", m_dg.w);
|
||||
printf(" m_db.w = %08x\n", m_db.w);
|
||||
printf(" m_da.w = %08x\n", m_da.w);
|
||||
printf(" m_dz.w = %08x\n", m_dz.w);
|
||||
printf(" m_dzpix = %08x\n", m_dzpix);
|
||||
}
|
||||
|
||||
void Span::SetMachine(running_machine *machine)
|
||||
@ -83,7 +77,58 @@ void Span::SetMachine(running_machine *machine)
|
||||
m_misc_state = m_rdp->GetMiscState();
|
||||
}
|
||||
|
||||
void Span::Draw(int index, int tilenum, bool shade, bool texture, bool zbuffer, bool flip)
|
||||
void Span::RGBAZClip(int sr, int sg, int sb, int sa, int *sz)
|
||||
{
|
||||
m_rdp->GetShadeColor()->i.r = m_rdp->GetSpecial9BitClampTable()[sr & 0x1ff];
|
||||
m_rdp->GetShadeColor()->i.g = m_rdp->GetSpecial9BitClampTable()[sg & 0x1ff];
|
||||
m_rdp->GetShadeColor()->i.b = m_rdp->GetSpecial9BitClampTable()[sb & 0x1ff];
|
||||
m_rdp->GetShadeColor()->i.a = m_rdp->GetSpecial9BitClampTable()[sa & 0x1ff];
|
||||
|
||||
INT32 zanded = (*sz) & 0x60000;
|
||||
|
||||
zanded >>= 17;
|
||||
switch(zanded)
|
||||
{
|
||||
case 0: *sz &= 0x3ffff; break;
|
||||
case 1: *sz &= 0x3ffff; break;
|
||||
case 2: *sz = 0x3ffff; break;
|
||||
case 3: *sz = 0x3ffff; break;
|
||||
}
|
||||
}
|
||||
|
||||
void Span::RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z)
|
||||
{
|
||||
if (m_rdp->GetMiscState()->m_curpixel_cvg == 8)
|
||||
{
|
||||
*r >>= 2;
|
||||
*g >>= 2;
|
||||
*b >>= 2;
|
||||
*a >>= 2;
|
||||
*z = (*z >> 3) & 0x7ffff;
|
||||
}
|
||||
else
|
||||
{
|
||||
INT32 summand_xr = offx * SIGN13(m_rdp->m_span_dr >> 14);
|
||||
INT32 summand_yr = offy * SIGN13(m_rdp->m_span_drdy >> 14);
|
||||
INT32 summand_xb = offx * SIGN13(m_rdp->m_span_db >> 14);
|
||||
INT32 summand_yb = offy * SIGN13(m_rdp->m_span_dbdy >> 14);
|
||||
INT32 summand_xg = offx * SIGN13(m_rdp->m_span_dg >> 14);
|
||||
INT32 summand_yg = offy * SIGN13(m_rdp->m_span_dgdy >> 14);
|
||||
INT32 summand_xa = offx * SIGN13(m_rdp->m_span_da >> 14);
|
||||
INT32 summand_ya = offy * SIGN13(m_rdp->m_span_dady >> 14);
|
||||
|
||||
INT32 summand_xz = offx * SIGN22(m_rdp->m_span_dz >> 10);
|
||||
INT32 summand_yz = offy * SIGN22(m_rdp->m_span_dzdy >> 10);
|
||||
|
||||
*r = ((*r << 2) + summand_xr + summand_yr) >> 4;
|
||||
*g = ((*g << 2) + summand_xg + summand_yg) >> 4;
|
||||
*b = ((*b << 2) + summand_xb + summand_yb) >> 4;
|
||||
*a = ((*a << 2) + summand_xa + summand_ya) >> 4;
|
||||
*z = (((*z << 2) + summand_xz + summand_yz) >> 5) & 0x7ffff;
|
||||
}
|
||||
}
|
||||
|
||||
void Span::Draw1Cycle(int index, int tilenum, bool flip)
|
||||
{
|
||||
int clipx1 = m_rdp->GetScissor()->m_xh;
|
||||
int clipx2 = m_rdp->GetScissor()->m_xl;
|
||||
@ -97,356 +142,360 @@ void Span::Draw(int index, int tilenum, bool shade, bool texture, bool zbuffer,
|
||||
SpanParam t = m_t;
|
||||
SpanParam w = m_w;
|
||||
|
||||
UINT16 *fb = (UINT16*)&rdram[m_misc_state->m_fb_address / 4];
|
||||
UINT16 *zb = (UINT16*)&rdram[m_misc_state->m_zb_address / 4];
|
||||
UINT8 *hb = &m_rdp->GetHiddenBits()[m_misc_state->m_fb_address >> 1];
|
||||
UINT8 *zhb = &m_rdp->GetHiddenBits()[m_misc_state->m_zb_address >> 1];
|
||||
UINT32 zb = m_misc_state->m_zb_address >> 1;
|
||||
UINT32 zhb = zb;
|
||||
UINT8 offx = 0, offy = 0;
|
||||
|
||||
UINT32 prim_tile = tilenum;
|
||||
UINT32 tilenum2 = 0;
|
||||
INT32 tile1 = tilenum;
|
||||
|
||||
int dzpix = m_dzpix;
|
||||
int drinc = flip ? (m_dr.w) : -m_dr.w;
|
||||
int dginc = flip ? (m_dg.w) : -m_dg.w;
|
||||
int dbinc = flip ? (m_db.w) : -m_db.w;
|
||||
int dainc = flip ? (m_da.w) : -m_da.w;
|
||||
int dzinc = flip ? (m_dz.w) : -m_dz.w;
|
||||
int dsinc = flip ? (m_ds.w) : -m_ds.w;
|
||||
int dtinc = flip ? (m_dt.w) : -m_dt.w;
|
||||
int dwinc = flip ? (m_dw.w) : -m_dw.w;
|
||||
m_rdp->GetTexPipe()->CalculateClampDiffs(tile1);
|
||||
|
||||
bool noisecompute = m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1] == &m_rdp->GetNoiseColor()->i.r;
|
||||
bool partialreject = (m_rdp->GetColorInputs()->blender2b_a[0] == &m_rdp->GetInvPixelColor()->i.a && m_rdp->GetColorInputs()->blender1b_a[0] == &m_rdp->GetPixelColor()->i.a);
|
||||
bool bsel0 = (m_rdp->GetColorInputs()->blender2b_a[0] == &m_rdp->GetMemoryColor()->i.a);
|
||||
|
||||
int drinc = flip ? (m_rdp->m_span_dr) : -m_rdp->m_span_dr;
|
||||
int dginc = flip ? (m_rdp->m_span_dg) : -m_rdp->m_span_dg;
|
||||
int dbinc = flip ? (m_rdp->m_span_db) : -m_rdp->m_span_db;
|
||||
int dainc = flip ? (m_rdp->m_span_da) : -m_rdp->m_span_da;
|
||||
int dzinc = flip ? (m_rdp->m_span_dz) : -m_rdp->m_span_dz;
|
||||
int dsinc = flip ? (m_rdp->m_span_ds) : -m_rdp->m_span_ds;
|
||||
int dtinc = flip ? (m_rdp->m_span_dt) : -m_rdp->m_span_dt;
|
||||
int dwinc = flip ? (m_rdp->m_span_dw) : -m_rdp->m_span_dw;
|
||||
int dzpix = m_rdp->m_span_dzpix;
|
||||
int xinc = flip ? 1 : -1;
|
||||
|
||||
int nexts;
|
||||
int nextt;
|
||||
int nextsw;
|
||||
|
||||
int fb_index = m_misc_state->m_fb_width * index;
|
||||
|
||||
int x = m_rx;
|
||||
int cdith = 0;
|
||||
int adith = 0;
|
||||
|
||||
int length = flip ? (m_lx - m_rx) : (m_rx - m_lx);
|
||||
int xstart = m_lx;
|
||||
int xend = m_unscissored_rx;
|
||||
int xend_scissored = m_rx;
|
||||
|
||||
bool disable_lod = false;
|
||||
if (m_other_modes->cycle_type != CYCLE_TYPE_2) // Used by World Driver Championship
|
||||
{
|
||||
disable_lod = true;
|
||||
}
|
||||
int x = xend;
|
||||
|
||||
if (m_other_modes->cycle_type == CYCLE_TYPE_2 && texture && !m_other_modes->tex_lod_en)
|
||||
{
|
||||
tilenum2 = (prim_tile + 1) & 7;
|
||||
}
|
||||
|
||||
if (texture && !m_other_modes->tex_lod_en)
|
||||
{
|
||||
tilenum = prim_tile;
|
||||
}
|
||||
|
||||
if(!shade)
|
||||
{
|
||||
m_rdp->GetShadeColor()->c = m_rdp->GetPrimColor()->c;
|
||||
}
|
||||
int length = flip ? (xstart - xend) : (xend - xstart);
|
||||
m_rdp->GetTexPipe()->m_start_span = true;
|
||||
UINT32 fir, fig, fib;
|
||||
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
int sr = 0;
|
||||
int sg = 0;
|
||||
int sb = 0;
|
||||
int sa = 0;
|
||||
int ss = 0;
|
||||
int st = 0;
|
||||
int sw = 0;
|
||||
int sz = 0;
|
||||
int sss = 0;
|
||||
int sst = 0;
|
||||
int sr = r.w >> 14;
|
||||
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;
|
||||
|
||||
if (m_other_modes->z_source_sel)
|
||||
{
|
||||
sz = (((UINT32)m_misc_state->m_primitive_z) << 6) & 0x3fffff;
|
||||
dzpix = m_misc_state->m_primitive_delta_z;
|
||||
dzinc = m_rdp->m_span_dz = m_rdp->m_span_dzdy = 0;
|
||||
}
|
||||
|
||||
bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
|
||||
|
||||
if (x >= clipx1 && x < clipx2 && valid_x)
|
||||
{
|
||||
m_rdp->lookup_cvmask_derivatives(m_cvg[x], &offx, &offy);
|
||||
|
||||
if (m_rdp->GetTexPipe()->m_start_span)
|
||||
{
|
||||
if (m_other_modes->persp_tex_en)
|
||||
{
|
||||
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->TCDivNoPersp(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sss = m_rdp->GetTexPipe()->m_precomp_s;
|
||||
sst = m_rdp->GetTexPipe()->m_precomp_t;
|
||||
}
|
||||
|
||||
m_rdp->GetTexPipe()->LOD1Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc);
|
||||
|
||||
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz);
|
||||
RGBAZClip(sr, sg, sb, sa, &sz);
|
||||
|
||||
m_rdp->GetTexPipe()->Cycle(m_rdp->GetTexel0Color(), m_rdp->GetTexel0Color(), sss, sst, tilenum, 0);
|
||||
|
||||
m_rdp->ColorCombiner1Cycle(noisecompute);
|
||||
|
||||
UINT32 curpixel = fb_index + x;
|
||||
UINT32 zbcur = zb + curpixel;
|
||||
UINT32 zhbcur = zhb + curpixel;
|
||||
|
||||
m_rdp->GetFramebuffer()->Read(curpixel);
|
||||
|
||||
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix))
|
||||
{
|
||||
m_rdp->GetDitherValues(index, j, &cdith, &adith);
|
||||
|
||||
bool rendered = m_rdp->GetBlender()->Blend1Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0);
|
||||
|
||||
if (rendered)
|
||||
{
|
||||
m_rdp->GetFramebuffer()->Write(curpixel, fir, fig, fib);
|
||||
if (m_other_modes->z_update_en)
|
||||
{
|
||||
m_rdp->ZStore(zbcur, zhbcur, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.w += drinc;
|
||||
g.w += dginc;
|
||||
b.w += dbinc;
|
||||
a.w += dainc;
|
||||
s.w += dsinc;
|
||||
t.w += dtinc;
|
||||
w.w += dwinc;
|
||||
z.w += dzinc;
|
||||
|
||||
x += xinc;
|
||||
}
|
||||
}
|
||||
|
||||
void Span::Draw2Cycle(int index, int tilenum, bool flip)
|
||||
{
|
||||
int clipx1 = m_rdp->GetScissor()->m_xh;
|
||||
int clipx2 = m_rdp->GetScissor()->m_xl;
|
||||
|
||||
SpanParam r = m_r;
|
||||
SpanParam g = m_g;
|
||||
SpanParam b = m_b;
|
||||
SpanParam a = m_a;
|
||||
SpanParam z = m_z;
|
||||
SpanParam s = m_s;
|
||||
SpanParam t = m_t;
|
||||
SpanParam w = m_w;
|
||||
|
||||
UINT32 zb = m_misc_state->m_zb_address >> 1;
|
||||
UINT32 zhb = zb;
|
||||
UINT8 offx = 0, offy = 0;
|
||||
|
||||
INT32 tile2 = (tilenum + 1) & 7;
|
||||
INT32 tile1 = tilenum;
|
||||
UINT32 prim_tile = tilenum;
|
||||
|
||||
int newtile1 = tile1;
|
||||
INT32 news = 0;
|
||||
INT32 newt = 0;
|
||||
|
||||
m_rdp->GetTexPipe()->CalculateClampDiffs(tile1);
|
||||
|
||||
bool noisecompute = (m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0] == &m_rdp->GetNoiseColor()->i.r || m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1] == &m_rdp->GetPixelColor()->i.r);
|
||||
bool partialreject = (m_rdp->GetColorInputs()->blender2b_a[1] == &m_rdp->GetInvPixelColor()->i.a && m_rdp->GetColorInputs()->blender1b_a[1] == &m_rdp->GetPixelColor()->i.a);
|
||||
bool bsel0 = (m_rdp->GetColorInputs()->blender2b_a[0] == &m_rdp->GetMemoryColor()->i.a);
|
||||
bool bsel1 = (m_rdp->GetColorInputs()->blender2b_a[1] == &m_rdp->GetMemoryColor()->i.a);
|
||||
|
||||
int dzpix = m_rdp->m_span_dzpix;
|
||||
int drinc = flip ? (m_rdp->m_span_dr) : -m_rdp->m_span_dr;
|
||||
int dginc = flip ? (m_rdp->m_span_dg) : -m_rdp->m_span_dg;
|
||||
int dbinc = flip ? (m_rdp->m_span_db) : -m_rdp->m_span_db;
|
||||
int dainc = flip ? (m_rdp->m_span_da) : -m_rdp->m_span_da;
|
||||
int dzinc = flip ? (m_rdp->m_span_dz) : -m_rdp->m_span_dz;
|
||||
int dsinc = flip ? (m_rdp->m_span_ds) : -m_rdp->m_span_ds;
|
||||
int dtinc = flip ? (m_rdp->m_span_dt) : -m_rdp->m_span_dt;
|
||||
int dwinc = flip ? (m_rdp->m_span_dw) : -m_rdp->m_span_dw;
|
||||
int xinc = flip ? 1 : -1;
|
||||
|
||||
int fb_index = m_misc_state->m_fb_width * index;
|
||||
|
||||
int cdith = 0;
|
||||
int adith = 0;
|
||||
|
||||
int xstart = m_lx;
|
||||
int xend = m_unscissored_rx;
|
||||
int xend_scissored = m_rx;
|
||||
|
||||
int x = xend;
|
||||
|
||||
int length = flip ? (xstart - xend) : (xend - xstart);
|
||||
m_rdp->GetTexPipe()->m_start_span = true;
|
||||
UINT32 fir, fig, fib;
|
||||
|
||||
//printf( "Span length: %d\n", length);
|
||||
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
int sr = r.w >> 14;
|
||||
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;
|
||||
|
||||
if(shade)
|
||||
if (m_other_modes->z_source_sel)
|
||||
{
|
||||
sr = r.h.h;
|
||||
sg = g.h.h;
|
||||
sb = b.h.h;
|
||||
sa = a.h.h;
|
||||
sz = (((UINT32)m_misc_state->m_primitive_z) << 6) & 0x3fffff;
|
||||
dzpix = m_misc_state->m_primitive_delta_z;
|
||||
dzinc = m_rdp->m_span_dz = m_rdp->m_span_dzdy = 0;
|
||||
}
|
||||
|
||||
if(texture)
|
||||
{
|
||||
ss = s.h.h;
|
||||
st = t.h.h;
|
||||
sw = w.h.h;
|
||||
}
|
||||
bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
|
||||
|
||||
if(zbuffer)
|
||||
if (x >= clipx1 && x < clipx2 && valid_x)
|
||||
{
|
||||
sz = z.w >> 13;
|
||||
m_rdp->lookup_cvmask_derivatives(m_cvg[x], &offx, &offy);
|
||||
|
||||
if (m_other_modes->z_source_sel)
|
||||
if (m_rdp->GetTexPipe()->m_start_span)
|
||||
{
|
||||
sz = (((UINT32)m_misc_state->m_primitive_z) << 3) & 0x3ffff;
|
||||
dzpix = m_misc_state->m_primitive_delta_z;
|
||||
if (m_other_modes->persp_tex_en)
|
||||
{
|
||||
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->TCDivNoPersp(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sss = m_rdp->GetTexPipe()->m_precomp_s;
|
||||
sst = m_rdp->GetTexPipe()->m_precomp_t;
|
||||
}
|
||||
|
||||
m_rdp->GetTexPipe()->LOD2Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2);
|
||||
|
||||
news = m_rdp->GetTexPipe()->m_precomp_s;
|
||||
newt = m_rdp->GetTexPipe()->m_precomp_t;
|
||||
m_rdp->GetTexPipe()->LOD2CycleLimited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1);
|
||||
|
||||
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz);
|
||||
RGBAZClip(sr, sg, sb, sa, &sz);
|
||||
|
||||
m_rdp->GetTexPipe()->Cycle(m_rdp->GetTexel0Color(), m_rdp->GetTexel0Color(), sss, sst, tile1, 0);
|
||||
m_rdp->GetTexPipe()->Cycle(m_rdp->GetTexel1Color(), m_rdp->GetTexel0Color(), sss, sst, tile2, 1);
|
||||
|
||||
m_rdp->GetTexPipe()->Cycle(m_rdp->GetNextTexelColor(), m_rdp->GetNextTexelColor(), sss, sst, tile2, 1);
|
||||
|
||||
m_rdp->ColorCombiner2Cycle(noisecompute);
|
||||
|
||||
UINT32 curpixel = fb_index + x;
|
||||
UINT32 zbcur = zb + curpixel;
|
||||
UINT32 zhbcur = zhb + curpixel;
|
||||
|
||||
m_rdp->GetFramebuffer()->Read(curpixel);
|
||||
|
||||
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix))
|
||||
{
|
||||
m_rdp->GetDitherValues(index, j, &cdith, &adith);
|
||||
|
||||
bool rendered = m_rdp->GetBlender()->Blend2Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1);
|
||||
|
||||
if (rendered)
|
||||
{
|
||||
m_rdp->GetFramebuffer()->Write(curpixel, fir, fig, fib);
|
||||
if (m_other_modes->z_update_en)
|
||||
{
|
||||
m_rdp->ZStore(zbcur, zhbcur, sz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
r.w += drinc;
|
||||
g.w += dginc;
|
||||
b.w += dbinc;
|
||||
a.w += dainc;
|
||||
s.w += dsinc;
|
||||
t.w += dtinc;
|
||||
w.w += dwinc;
|
||||
z.w += dzinc;
|
||||
|
||||
x += xinc;
|
||||
}
|
||||
}
|
||||
|
||||
void Span::DrawCopy(int index, int tilenum, bool flip)
|
||||
{
|
||||
int clipx1 = m_rdp->GetScissor()->m_xh;
|
||||
int clipx2 = m_rdp->GetScissor()->m_xl;
|
||||
|
||||
SpanParam s = m_s;
|
||||
SpanParam t = m_t;
|
||||
|
||||
int ds = m_rdp->m_span_ds / 4;
|
||||
int dt = m_rdp->m_span_dt / 4;
|
||||
int dsinc = flip ? (ds) : -ds;
|
||||
int dtinc = flip ? (dt) : -dt;
|
||||
int xinc = flip ? 1 : -1;
|
||||
|
||||
int fb_index = m_misc_state->m_fb_width * index;
|
||||
|
||||
int xstart = m_lx;
|
||||
int xend = m_unscissored_rx;
|
||||
int xend_scissored = m_rx;
|
||||
|
||||
int x = xend;
|
||||
|
||||
int length = flip ? (xstart - xend) : (xend - xstart);
|
||||
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
bool valid_x = (flip) ? (x >= xend_scissored) : (x <= xend_scissored);
|
||||
|
||||
if (x >= clipx1 && x < clipx2 && valid_x)
|
||||
{
|
||||
INT32 sss = s.h.h;
|
||||
INT32 sst = t.h.h;
|
||||
m_rdp->GetTexPipe()->Copy(m_rdp->GetTexel0Color(), sss, sst, tilenum);
|
||||
|
||||
UINT32 curpixel = fb_index + x;
|
||||
m_misc_state->m_curpixel_cvg = m_rdp->GetTexel0Color()->i.a ? 7 : 0;
|
||||
if ((m_rdp->GetTexel0Color()->i.a != 0) || (!m_other_modes->alpha_compare_en))
|
||||
{
|
||||
m_rdp->GetFramebuffer()->Copy(curpixel, m_rdp->GetTexel0Color()->i.r, m_rdp->GetTexel0Color()->i.g, m_rdp->GetTexel0Color()->i.b);
|
||||
}
|
||||
}
|
||||
|
||||
s.w += dsinc;
|
||||
t.w += dtinc;
|
||||
x += xinc;
|
||||
}
|
||||
}
|
||||
|
||||
void Span::DrawFill(int index, int tilenum, bool flip)
|
||||
{
|
||||
int clipx1 = m_rdp->GetScissor()->m_xh;
|
||||
int clipx2 = m_rdp->GetScissor()->m_xl;
|
||||
|
||||
int xinc = flip ? 1 : -1;
|
||||
|
||||
int fb_index = m_misc_state->m_fb_width * index;
|
||||
|
||||
int xstart = m_lx;
|
||||
int xend_scissored = m_rx;
|
||||
|
||||
int x = xend_scissored;
|
||||
|
||||
int length = flip ? (xstart - xend_scissored) : (xend_scissored - xstart);
|
||||
|
||||
for (int j = 0; j <= length; j++)
|
||||
{
|
||||
if (x >= clipx1 && x < clipx2)
|
||||
{
|
||||
bool z_compare_result = true;
|
||||
|
||||
m_misc_state->m_curpixel_cvg = m_cvg[x];
|
||||
|
||||
if (m_misc_state->m_curpixel_cvg)
|
||||
{
|
||||
int curpixel = fb_index + x;
|
||||
UINT16* fbcur = &fb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT16* zbcur = &zb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT8* hbcur = &hb[curpixel ^ BYTE_ADDR_XOR];
|
||||
UINT8* zhbcur = &zhb[curpixel ^ BYTE_ADDR_XOR];
|
||||
|
||||
if(texture)
|
||||
{
|
||||
if (m_other_modes->persp_tex_en)
|
||||
{
|
||||
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
|
||||
}
|
||||
else // Hack for Bust-a-Move 2
|
||||
{
|
||||
sss = ss;
|
||||
sst = st;
|
||||
}
|
||||
|
||||
if (m_other_modes->tex_lod_en && !disable_lod)
|
||||
{
|
||||
if (m_other_modes->persp_tex_en)
|
||||
{
|
||||
nextsw = (w.w + dwinc) >> 16;
|
||||
nexts = (s.w + dsinc) >> 16;
|
||||
nextt = (t.w + dtinc) >> 16;
|
||||
m_rdp->TCDiv(nexts, nextt, nextsw, &nexts, &nextt);
|
||||
}
|
||||
else
|
||||
{
|
||||
nexts = (s.w + dsinc)>>16;
|
||||
nextt = (t.w + dtinc)>>16;
|
||||
}
|
||||
|
||||
INT32 horstep = SIGN17(nexts & 0x1ffff) - SIGN17(sss & 0x1ffff);
|
||||
INT32 vertstep = SIGN17(nextt & 0x1ffff) - SIGN17(sst & 0x1ffff);
|
||||
if (horstep & 0x20000)
|
||||
{
|
||||
horstep = ~horstep & 0x1ffff;
|
||||
}
|
||||
if (vertstep & 0x20000)
|
||||
{
|
||||
vertstep = ~vertstep & 0x1ffff;
|
||||
}
|
||||
|
||||
int LOD = (horstep >= vertstep) ? horstep : vertstep;
|
||||
LOD = (LOD >= m_dymax) ? LOD : m_dymax;
|
||||
|
||||
if (LOD & 0x1c000)
|
||||
{
|
||||
LOD = 0x7fff;
|
||||
}
|
||||
if (LOD < m_misc_state->m_min_level)
|
||||
{
|
||||
LOD = m_misc_state->m_min_level;
|
||||
}
|
||||
|
||||
bool magnify = (LOD < 32);
|
||||
INT32 l_tile = m_rdp->GetLog2((LOD >> 5) & 0xff);
|
||||
bool distant = ((LOD & 0x6000) || (l_tile >= m_misc_state->m_max_level));
|
||||
|
||||
m_rdp->SetLODFrac(((LOD << 3) >> l_tile) & 0xff);
|
||||
|
||||
if (distant)
|
||||
{
|
||||
l_tile = m_misc_state->m_max_level;
|
||||
}
|
||||
if(!m_other_modes->sharpen_tex_en && !m_other_modes->detail_tex_en && magnify)
|
||||
{
|
||||
m_rdp->SetLODFrac(0);
|
||||
}
|
||||
if(!m_other_modes->sharpen_tex_en && !m_other_modes->detail_tex_en && distant)
|
||||
{
|
||||
m_rdp->SetLODFrac(0xff);
|
||||
}
|
||||
if(m_other_modes->sharpen_tex_en && magnify)
|
||||
{
|
||||
m_rdp->SetLODFrac(*(m_rdp->GetLODFrac()) | 0x100);
|
||||
}
|
||||
|
||||
if (!m_other_modes->detail_tex_en)
|
||||
{
|
||||
tilenum = (prim_tile + l_tile);
|
||||
tilenum &= 7;
|
||||
if (m_other_modes->sharpen_tex_en)
|
||||
{
|
||||
tilenum2 = (tilenum + 1) & 7;
|
||||
}
|
||||
else if (!distant)
|
||||
{
|
||||
tilenum2 = (tilenum + 1) & 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
tilenum2 = tilenum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!magnify)
|
||||
{
|
||||
tilenum = (prim_tile + l_tile + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
tilenum = (prim_tile + l_tile);
|
||||
}
|
||||
tilenum &= 7;
|
||||
|
||||
if (!distant && !magnify)
|
||||
{
|
||||
tilenum2 = (prim_tile + l_tile + 2) & 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
tilenum2 = (prim_tile + l_tile + 1) & 7;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_other_modes->cycle_type == CYCLE_TYPE_1)
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(sss, sst, &m_rdp->GetTiles()[tilenum]);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(sss, sst, &m_rdp->GetTiles()[tilenum]);
|
||||
m_rdp->GetTexel1Color()->c = m_rdp->GetTexPipe()->Fetch(sss, sst, &m_rdp->GetTiles()[tilenum2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (shade)
|
||||
{
|
||||
if (sr > 0xff) sr = 0xff;
|
||||
if (sg > 0xff) sg = 0xff;
|
||||
if (sb > 0xff) sb = 0xff;
|
||||
if (sa > 0xff) sa = 0xff;
|
||||
if (sr < 0) sr = 0;
|
||||
if (sg < 0) sg = 0;
|
||||
if (sb < 0) sb = 0;
|
||||
if (sa < 0) sa = 0;
|
||||
m_rdp->GetShadeColor()->i.r = sr;
|
||||
m_rdp->GetShadeColor()->i.g = sg;
|
||||
m_rdp->GetShadeColor()->i.b = sb;
|
||||
m_rdp->GetShadeColor()->i.a = sa;
|
||||
}
|
||||
|
||||
if (m_other_modes->cycle_type == CYCLE_TYPE_1)
|
||||
{
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
}
|
||||
else if (m_other_modes->cycle_type == CYCLE_TYPE_2)
|
||||
{
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
}
|
||||
|
||||
if ((zbuffer || m_other_modes->z_source_sel) && m_other_modes->z_compare_en)
|
||||
{
|
||||
z_compare_result = m_rdp->ZCompare(fbcur, hbcur, zbcur, zhbcur, sz, dzpix);
|
||||
}
|
||||
|
||||
if(z_compare_result)
|
||||
{
|
||||
bool rendered = false;
|
||||
int dith = 0;
|
||||
if (!m_other_modes->rgb_dither_sel)
|
||||
{
|
||||
dith = m_rdp->GetMagicMatrix()[(((index) & 3) << 2) + ((x ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
else if (m_other_modes->rgb_dither_sel == 1)
|
||||
{
|
||||
dith = m_rdp->GetBayerMatrix()[(((index) & 3) << 2) + ((x ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
|
||||
rendered = m_rdp->GetBlender()->Blend(fbcur, hbcur, c1, c2, dith);
|
||||
|
||||
if (m_other_modes->z_update_en && rendered)
|
||||
{
|
||||
m_rdp->ZStore(zbcur, zhbcur, sz, dzpix);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shade)
|
||||
{
|
||||
r.w += drinc;
|
||||
g.w += dginc;
|
||||
b.w += dbinc;
|
||||
a.w += dainc;
|
||||
}
|
||||
if (texture)
|
||||
{
|
||||
s.w += dsinc;
|
||||
t.w += dtinc;
|
||||
w.w += dwinc;
|
||||
}
|
||||
if (zbuffer)
|
||||
{
|
||||
z.w += dzinc;
|
||||
UINT32 curpixel = fb_index + x;
|
||||
m_rdp->GetFramebuffer()->Fill(curpixel);
|
||||
}
|
||||
|
||||
x += xinc;
|
||||
|
@ -34,13 +34,18 @@ class Span
|
||||
public:
|
||||
Span() { }
|
||||
|
||||
void Draw(int index, int tilenum, bool shade, bool texture, bool zbuffer, bool flip);
|
||||
void Dump();
|
||||
void SetMachine(running_machine* machine);
|
||||
|
||||
void Draw1Cycle(int index, int tilenum, bool flip);
|
||||
void Draw2Cycle(int index, int tilenum, bool flip);
|
||||
void DrawCopy(int index, int tilenum, bool flip);
|
||||
void DrawFill(int index, int tilenum, bool flip);
|
||||
|
||||
public:
|
||||
int m_lx;
|
||||
int m_rx;
|
||||
int m_unscissored_rx;
|
||||
|
||||
SpanParam m_s;
|
||||
SpanParam m_t;
|
||||
@ -51,22 +56,12 @@ class Span
|
||||
SpanParam m_a;
|
||||
SpanParam m_z;
|
||||
|
||||
UINT8 m_cvg[RDP_CVG_SPAN_MAX];
|
||||
|
||||
int m_dymax;
|
||||
|
||||
SpanParam m_ds;
|
||||
SpanParam m_dt;
|
||||
SpanParam m_dw;
|
||||
SpanParam m_dr;
|
||||
SpanParam m_dg;
|
||||
SpanParam m_db;
|
||||
SpanParam m_da;
|
||||
SpanParam m_dz;
|
||||
|
||||
int m_dzpix;
|
||||
UINT16 m_cvg[RDP_CVG_SPAN_MAX];
|
||||
|
||||
private:
|
||||
void RGBAZClip(int sr, int sg, int sb, int sa, int *sz);
|
||||
void RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z);
|
||||
|
||||
running_machine* m_machine;
|
||||
Processor* m_rdp;
|
||||
MiscState* m_misc_state;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -2,7 +2,6 @@
|
||||
#define _VIDEO_RDPTEXPIPE_H_
|
||||
|
||||
#include "emu.h"
|
||||
#include "video/rdpfetch.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
@ -25,23 +24,39 @@ class TexturePipe
|
||||
{
|
||||
m_maskbits_table[i] = ((UINT16)(0xffff) >> (16 - i)) & 0x3ff;
|
||||
}
|
||||
m_start_span = false;
|
||||
m_precomp_s = 0;
|
||||
m_precomp_t = 0;
|
||||
}
|
||||
|
||||
UINT32 Fetch(INT32 SSS, INT32 SST, Tile* tile);
|
||||
void Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle);
|
||||
void Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum);
|
||||
UINT32 Fetch(INT32 SSS, INT32 SST, INT32 tile);
|
||||
void CalculateClampDiffs(UINT32 prim_tile);
|
||||
void LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc);
|
||||
void LOD2Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2);
|
||||
void LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1);
|
||||
|
||||
void SetMachine(running_machine* machine);
|
||||
|
||||
bool m_start_span;
|
||||
INT32 m_precomp_s;
|
||||
INT32 m_precomp_t;
|
||||
|
||||
private:
|
||||
void Mask(INT32* S, INT32* T, Tile* tile);
|
||||
void TexShift(INT32* S, INT32* T, bool* maxs, bool* maxt, Tile *tile);
|
||||
void Clamp(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, bool maxs, bool maxt, Tile* tile);
|
||||
void ClampLight(INT32* S, INT32* T, bool maxs, bool maxt, Tile* tile);
|
||||
void Mask(INT32* S, INT32* T, INT32 num);
|
||||
void MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num);
|
||||
|
||||
void ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num);
|
||||
void ShiftCopy(INT32* S, INT32* T, UINT32 num);
|
||||
|
||||
void ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, INT32 maxs, INT32 maxt, INT32 num);
|
||||
void ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT32 num);
|
||||
|
||||
running_machine* m_machine;
|
||||
OtherModes* m_other_modes;
|
||||
MiscState* m_misc_state;
|
||||
Processor* m_rdp;
|
||||
TexFetch m_tex_fetch;
|
||||
|
||||
INT32 m_maskbits_table[16];
|
||||
INT32 m_clamp_t_diff[8];
|
||||
|
@ -1,460 +0,0 @@
|
||||
#include "emu.h"
|
||||
#include "includes/n64.h"
|
||||
#include "video/n64.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
#define LookUpCC(A, B, C, D) m_rdp->GetCCLUT2()[(m_rdp->GetCCLUT1()[(A << 16) | (B << 8) | C] << 8) | D]
|
||||
|
||||
void TexRectangle::SetMachine(running_machine* machine)
|
||||
{
|
||||
_n64_state *state = machine->driver_data<_n64_state>();
|
||||
|
||||
m_machine = machine;
|
||||
m_rdp = &state->m_rdp;
|
||||
m_other_modes = m_rdp->GetOtherModes();
|
||||
m_misc_state = m_rdp->GetMiscState();
|
||||
}
|
||||
|
||||
void TexRectangle::Draw()
|
||||
{
|
||||
switch(m_other_modes->cycle_type)
|
||||
{
|
||||
case CYCLE_TYPE_1:
|
||||
case CYCLE_TYPE_2:
|
||||
DrawDefault();
|
||||
return;
|
||||
|
||||
case CYCLE_TYPE_COPY:
|
||||
DrawCopy();
|
||||
return;
|
||||
|
||||
default:
|
||||
fatalerror("Unsupported cycle type for Textured Rectangle: %d\n", m_other_modes->cycle_type);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TexRectangle::DrawDefault()
|
||||
{
|
||||
UINT16 *fb = (UINT16*)&rdram[(m_misc_state->m_fb_address / 4)];
|
||||
UINT8 *hb = &m_rdp->GetHiddenBits()[m_misc_state->m_fb_address >> 1];
|
||||
UINT16 *zb = (UINT16*)&rdram[m_misc_state->m_zb_address / 4];
|
||||
UINT8 *zhb = &m_rdp->GetHiddenBits()[m_misc_state->m_zb_address >> 1];
|
||||
|
||||
UINT32 tilenum = m_tilenum;
|
||||
N64::RDP::Tile *tex_tile = &m_rdp->GetTiles()[m_tilenum];
|
||||
UINT32 tilenum2 = 0;
|
||||
N64::RDP::Tile *tex_tile2 = NULL;
|
||||
|
||||
int x1 = m_xh >> 2;
|
||||
int x2 = m_xl >> 2;
|
||||
int y1 = m_yh >> 2;
|
||||
int y2 = m_yl >> 2;
|
||||
|
||||
if (x2 <= x1)
|
||||
{
|
||||
x2 = x1 + 1;
|
||||
}
|
||||
if (y1 == y2)
|
||||
{
|
||||
y2 = y1 + 1; // Needed by Goldeneye
|
||||
}
|
||||
|
||||
if ((m_xl & 3) == 3) // Needed by Mega Man 64
|
||||
{
|
||||
x2++;
|
||||
}
|
||||
if ((m_yl & 3) == 3)
|
||||
{
|
||||
y2++;
|
||||
}
|
||||
|
||||
m_rdp->GetTexPipe()->CalculateClampDiffs(tilenum);
|
||||
|
||||
if(m_other_modes->cycle_type == CYCLE_TYPE_2)
|
||||
{
|
||||
if (!m_other_modes->tex_lod_en)
|
||||
{
|
||||
tilenum2 = (tilenum + 1) & 7;
|
||||
tex_tile2 = &m_rdp->GetTiles()[tilenum2];
|
||||
}
|
||||
else
|
||||
{
|
||||
tilenum2 = (tilenum + 1) & 7;
|
||||
tex_tile2 = &m_rdp->GetTiles()[tilenum2];
|
||||
}
|
||||
}
|
||||
|
||||
m_rdp->GetShadeColor()->c = 0; // Needed by Pilotwings 64
|
||||
|
||||
if(y1 < m_rdp->GetScissor()->m_yh)
|
||||
{
|
||||
m_t += m_dtdy * (m_rdp->GetScissor()->m_yh - y1);
|
||||
y1 = m_rdp->GetScissor()->m_yh;
|
||||
}
|
||||
if(y2 > m_rdp->GetScissor()->m_yl)
|
||||
{
|
||||
y2 = m_rdp->GetScissor()->m_yl;
|
||||
}
|
||||
if(x1 < m_rdp->GetScissor()->m_xh)
|
||||
{
|
||||
m_s += m_dsdx * (m_rdp->GetScissor()->m_xh - x1);
|
||||
x1 = m_rdp->GetScissor()->m_xh;
|
||||
}
|
||||
if(x2 > m_rdp->GetScissor()->m_xl)
|
||||
{
|
||||
x2 = m_rdp->GetScissor()->m_xl;
|
||||
}
|
||||
m_dsdx >>= 5;
|
||||
m_dtdy >>= 5;
|
||||
|
||||
int t = ((int)(m_t));
|
||||
|
||||
if(m_flip)
|
||||
{
|
||||
for (int j = y1; j < y2; j++)
|
||||
{
|
||||
int fb_index = j * m_misc_state->m_fb_width;
|
||||
int mline = 0;
|
||||
if(!(m_other_modes->rgb_dither_sel & 2))
|
||||
{
|
||||
mline = (j & 3) << 2;
|
||||
}
|
||||
int s = ((int)(m_s));
|
||||
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
N64::RDP::Color c1;
|
||||
N64::RDP::Color c2;
|
||||
int dith = 0;
|
||||
int curpixel = fb_index + i;
|
||||
UINT16* fbcur = &fb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT8* hbcur = &hb[curpixel ^ BYTE_ADDR_XOR];
|
||||
UINT16* zbcur = &zb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT8* zhbcur = &zhb[curpixel ^ BYTE_ADDR_XOR];
|
||||
|
||||
m_misc_state->m_curpixel_cvg = 8;
|
||||
|
||||
if(m_other_modes->cycle_type == CYCLE_TYPE_1)
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(t, s, tex_tile);
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(t, s, tex_tile);
|
||||
m_rdp->GetTexel1Color()->c = m_rdp->GetTexPipe()->Fetch(t, s, tex_tile2);
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
}
|
||||
|
||||
if(m_other_modes->rgb_dither_sel == 0)
|
||||
{
|
||||
dith = m_rdp->GetMagicMatrix()[mline + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
else if(m_other_modes->rgb_dither_sel == 1)
|
||||
{
|
||||
dith = m_rdp->GetBayerMatrix()[mline + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
|
||||
bool z_compare_result = true;
|
||||
if(m_other_modes->z_compare_en)
|
||||
{
|
||||
z_compare_result = m_rdp->ZCompare(fbcur, hbcur, zbcur, zhbcur, ((UINT32)m_misc_state->m_primitive_z)<<3, m_misc_state->m_primitive_delta_z);
|
||||
}
|
||||
|
||||
if(z_compare_result)
|
||||
{
|
||||
bool rendered = m_rdp->GetBlender()->Blend(fbcur, hbcur, c1, c2, dith);
|
||||
|
||||
if(m_other_modes->z_update_en && rendered)
|
||||
{
|
||||
m_rdp->ZStore(zbcur, zhbcur, ((UINT32)m_misc_state->m_primitive_z) << 3, m_misc_state->m_primitive_delta_z);
|
||||
}
|
||||
}
|
||||
|
||||
s += (int)(m_dsdx);
|
||||
}
|
||||
t += (int)(m_dtdy);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = y1; j < y2; j++)
|
||||
{
|
||||
int fb_index = j * m_misc_state->m_fb_width;
|
||||
int mline = 0;
|
||||
if(!(m_other_modes->rgb_dither_sel & 2))
|
||||
{
|
||||
mline = (j & 3) << 2;
|
||||
}
|
||||
|
||||
int s = ((int)(m_s));
|
||||
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
N64::RDP::Color c1;
|
||||
N64::RDP::Color c2;
|
||||
int dith = 0;
|
||||
int curpixel = fb_index + i;
|
||||
UINT16* fbcur = &fb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT8* hbcur = &hb[curpixel ^ BYTE_ADDR_XOR];
|
||||
UINT16* zbcur = &zb[curpixel ^ WORD_ADDR_XOR];
|
||||
UINT8* zhbcur = &zhb[curpixel ^ BYTE_ADDR_XOR];
|
||||
|
||||
m_misc_state->m_curpixel_cvg = 8;
|
||||
|
||||
if(m_other_modes->cycle_type == CYCLE_TYPE_1)
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(s, t, tex_tile);
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c1.i.a);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(s, t, tex_tile);
|
||||
m_rdp->GetTexel1Color()->c = m_rdp->GetTexPipe()->Fetch(s, t, tex_tile2);
|
||||
|
||||
c1.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[0]);
|
||||
c1.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[0]);
|
||||
c1.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[0]);
|
||||
c1.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[0],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[0]);
|
||||
m_rdp->GetCombinedColor()->c = c1.c;
|
||||
c2.c = m_rdp->GetTexel0Color()->c;
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexel1Color()->c;
|
||||
m_rdp->GetTexel1Color()->c = c2.c;
|
||||
c2.i.r = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_r[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_r[1]);
|
||||
c2.i.g = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_g[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_g[1]);
|
||||
c2.i.b = LookUpCC(*m_rdp->GetColorInputs()->combiner_rgbsub_a_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbsub_b_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbmul_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_rgbadd_b[1]);
|
||||
c2.i.a = LookUpCC(*m_rdp->GetColorInputs()->combiner_alphasub_a[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphasub_b[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphamul[1],
|
||||
*m_rdp->GetColorInputs()->combiner_alphaadd[1]);
|
||||
m_rdp->GetAlphaCvg(&c2.i.a);
|
||||
}
|
||||
|
||||
if(m_other_modes->rgb_dither_sel == 0)
|
||||
{
|
||||
dith = m_rdp->GetMagicMatrix()[mline + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
else if(m_other_modes->rgb_dither_sel == 1)
|
||||
{
|
||||
dith = m_rdp->GetBayerMatrix()[mline + ((i ^ WORD_ADDR_XOR) & 3)];
|
||||
}
|
||||
|
||||
bool z_compare_result = true;
|
||||
if(m_other_modes->z_compare_en)
|
||||
{
|
||||
z_compare_result = m_rdp->ZCompare(fbcur, hbcur, zbcur, zhbcur, ((UINT32)m_misc_state->m_primitive_z)<<3, m_misc_state->m_primitive_delta_z);
|
||||
}
|
||||
|
||||
if(z_compare_result)
|
||||
{
|
||||
bool rendered = m_rdp->GetBlender()->Blend(fbcur, hbcur, c1, c2, dith);
|
||||
|
||||
if(m_other_modes->z_update_en && rendered)
|
||||
{
|
||||
m_rdp->ZStore(zbcur, zhbcur, ((UINT32)m_misc_state->m_primitive_z) << 3, m_misc_state->m_primitive_delta_z);
|
||||
}
|
||||
}
|
||||
|
||||
s += (int)(m_dsdx);
|
||||
}
|
||||
t += (int)(m_dtdy);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TexRectangle::DrawCopy()
|
||||
{
|
||||
UINT16 *fb = (UINT16*)&rdram[(m_misc_state->m_fb_address / 4)];
|
||||
|
||||
N64::RDP::Tile *tex_tile = &m_rdp->GetTiles()[m_tilenum];
|
||||
|
||||
int x1 = m_xh >> 2;
|
||||
int x2 = m_xl >> 2;
|
||||
int y1 = m_yh >> 2;
|
||||
int y2 = m_yl >> 2;
|
||||
|
||||
if (x2 <= x1)
|
||||
{
|
||||
x2 = x1 + 1;
|
||||
}
|
||||
if (y1 == y2)
|
||||
{
|
||||
y2 = y1 + 1; // Needed by Goldeneye
|
||||
}
|
||||
|
||||
m_dsdx /= 4;
|
||||
x2 += 1;
|
||||
y2 += 1;
|
||||
|
||||
m_rdp->GetShadeColor()->c = 0; // Needed by Pilotwings 64
|
||||
|
||||
if(y1 < m_rdp->GetScissor()->m_yh)
|
||||
{
|
||||
m_t += m_dtdy * (m_rdp->GetScissor()->m_yh - y1);
|
||||
y1 = m_rdp->GetScissor()->m_yh;
|
||||
}
|
||||
if(y2 > m_rdp->GetScissor()->m_yl)
|
||||
{
|
||||
y2 = m_rdp->GetScissor()->m_yl;
|
||||
}
|
||||
if(x1 < m_rdp->GetScissor()->m_xh)
|
||||
{
|
||||
m_s += m_dsdx * (m_rdp->GetScissor()->m_xh - x1);
|
||||
x1 = m_rdp->GetScissor()->m_xh;
|
||||
}
|
||||
if(x2 > m_rdp->GetScissor()->m_xl)
|
||||
{
|
||||
x2 = m_rdp->GetScissor()->m_xl;
|
||||
}
|
||||
m_dsdx >>= 5;
|
||||
m_dtdy >>= 5;
|
||||
|
||||
int t = (int)m_t;
|
||||
|
||||
if(m_flip)
|
||||
{
|
||||
for (int j = y1; j < y2; j++)
|
||||
{
|
||||
int fb_index = j * m_misc_state->m_fb_width;
|
||||
int s = (int)(m_s);
|
||||
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(t, s, tex_tile);
|
||||
|
||||
m_misc_state->m_curpixel_cvg = 8;
|
||||
|
||||
if ((m_rdp->GetTexel0Color()->i.a != 0)||(!m_other_modes->alpha_compare_en))
|
||||
{
|
||||
fb[(fb_index + i) ^ WORD_ADDR_XOR] = ((m_rdp->GetTexel0Color()->i.r >> 3) << 11) | ((m_rdp->GetTexel0Color()->i.g >> 3) << 6) | ((m_rdp->GetTexel0Color()->i.b >> 3) << 1)|1;
|
||||
}
|
||||
s += m_dsdx;
|
||||
}
|
||||
t += m_dtdy;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int j = y1; j < y2; j++)
|
||||
{
|
||||
int fb_index = j * m_misc_state->m_fb_width;
|
||||
int s = (int)(m_s);
|
||||
|
||||
for (int i = x1; i < x2; i++)
|
||||
{
|
||||
m_rdp->GetTexel0Color()->c = m_rdp->GetTexPipe()->Fetch(s, t, tex_tile);
|
||||
|
||||
m_misc_state->m_curpixel_cvg = 8;
|
||||
|
||||
if ((m_rdp->GetTexel0Color()->i.a != 0)||(!m_other_modes->alpha_compare_en))
|
||||
{
|
||||
fb[(fb_index + i) ^ WORD_ADDR_XOR] = ((m_rdp->GetTexel0Color()->i.r >> 3) << 11) | ((m_rdp->GetTexel0Color()->i.g >> 3) << 6) | ((m_rdp->GetTexel0Color()->i.b >> 3) << 1)|1;
|
||||
}
|
||||
s += m_dsdx;
|
||||
}
|
||||
t += m_dtdy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
@ -1,57 +0,0 @@
|
||||
#ifndef _VIDEO_RDPTEXRECT_H_
|
||||
#define _VIDEO_RDPTEXRECT_H_
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
namespace N64
|
||||
{
|
||||
|
||||
namespace RDP
|
||||
{
|
||||
|
||||
class OtherModes;
|
||||
class MiscState;
|
||||
class Processor;
|
||||
class Color;
|
||||
|
||||
class TexRectangle
|
||||
{
|
||||
public:
|
||||
TexRectangle() {}
|
||||
TexRectangle(running_machine *machine, UINT32 *data, int flip)
|
||||
{
|
||||
SetMachine(machine);
|
||||
InitFromBuffer(data);
|
||||
m_flip = flip;
|
||||
}
|
||||
|
||||
void Draw();
|
||||
void SetMachine(running_machine *machine);
|
||||
void InitFromBuffer(UINT32 *data);
|
||||
|
||||
int m_tilenum;
|
||||
UINT16 m_xl; // 10.2 fixed-point
|
||||
UINT16 m_yl; // 10.2 fixed-point
|
||||
UINT16 m_xh; // 10.2 fixed-point
|
||||
UINT16 m_yh; // 10.2 fixed-point
|
||||
INT16 m_s; // 10.5 fixed-point
|
||||
INT16 m_t; // 10.5 fixed-point
|
||||
INT16 m_dsdx; // 5.10 fixed-point
|
||||
INT16 m_dtdy; // 5.10 fixed-point
|
||||
int m_flip;
|
||||
|
||||
private:
|
||||
void DrawDefault();
|
||||
void DrawCopy();
|
||||
|
||||
running_machine* m_machine;
|
||||
Processor* m_rdp;
|
||||
MiscState* m_misc_state;
|
||||
OtherModes* m_other_modes;
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
||||
} // namespace N64
|
||||
|
||||
#endif // _VIDEO_RDPTEXRECT_H_
|
@ -16,12 +16,15 @@ class Triangle
|
||||
{
|
||||
public:
|
||||
Triangle() { fatalerror("Please don't use the default constructor for N64::RDP::Triangle\n"); }
|
||||
Triangle(running_machine* machine, bool shade, bool texture, bool zbuffer);
|
||||
Triangle(running_machine *machine, bool shade, bool texture, bool zbuffer, bool rect, bool flip);
|
||||
|
||||
void InitFromData(running_machine* machine, bool shade, bool texture, bool zbuffer);
|
||||
void InitFromData(running_machine* machine, bool shade, bool texture, bool zbuffer, bool rect, bool flip);
|
||||
void Draw();
|
||||
|
||||
private:
|
||||
void compute_cvg_noflip(INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl);
|
||||
void compute_cvg_flip(INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl);
|
||||
|
||||
running_machine* m_machine;
|
||||
UINT32* m_cmd_data;
|
||||
MiscState* m_misc_state;
|
||||
@ -29,6 +32,7 @@ class Triangle
|
||||
bool m_shade;
|
||||
bool m_texture;
|
||||
bool m_zbuffer;
|
||||
bool m_rect;
|
||||
};
|
||||
|
||||
} // namespace RDP
|
||||
|
Loading…
Reference in New Issue
Block a user