- Added polynew.h multithreaded-render support to N64 RDP emulation. Speedup ratios of 1.6x to 2.8x observed. [Ryan Holtz]

(nw) If anyone has any suggestions on how better to sync per-scanline state than what I'm currently doing, I'd be all ears. The renderer is now pretty darn fast, but every little bit counts.
This commit is contained in:
Ryan Holtz 2012-02-11 16:05:10 +00:00
parent 24257711dc
commit 5cb480e748
17 changed files with 1889 additions and 1851 deletions

3
.gitattributes vendored
View File

@ -4769,14 +4769,11 @@ src/mame/video/rampart.c svneol=native#text/plain
src/mame/video/rastan.c svneol=native#text/plain
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/rdpfiltr.c 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/rdptri.h svneol=native#text/plain
src/mame/video/realbrk.c svneol=native#text/plain
src/mame/video/redalert.c svneol=native#text/plain
src/mame/video/redclash.c svneol=native#text/plain

View File

@ -44,7 +44,7 @@
#define KEEP_STATISTICS 0
// turn this on to log the reasons for any long waits
#define LOG_WAITS 0
#define LOG_WAITS 1
// number of profiling ticks before we consider a wait "long"
#define LOG_WAIT_THRESHOLD 1000
@ -112,6 +112,7 @@ public:
_BaseType start; // parameter value at start
_BaseType dpdx; // dp/dx relative to start
} param[_MaxParams];
void *userdata; // custom per-span data
};
// delegate type for scanline callbacks
@ -568,6 +569,7 @@ UINT32 poly_manager<_BaseType, _ObjectData, _MaxParams, _MaxPolys>::render_tile(
extent_t &extent = unit.extent[extnum];
extent.startx = istartx;
extent.stopx = istopx;
extent.userdata = NULL;
pixels += istopx - istartx;
// fill in the parameters for the extent
@ -749,6 +751,7 @@ UINT32 poly_manager<_BaseType, _ObjectData, _MaxParams, _MaxPolys>::render_trian
extent_t &extent = unit.extent[extnum];
extent.startx = istartx;
extent.stopx = istopx;
extent.userdata = NULL;
pixels += istopx - istartx;
// fill in the parameters for the extent
@ -847,17 +850,13 @@ UINT32 poly_manager<_BaseType, _ObjectData, _MaxParams, _MaxPolys>::render_trian
const extent_t &srcextent = extents[(curscan + extnum) - startscanline];
INT32 istartx = srcextent.startx, istopx = srcextent.stopx;
// force start < stop
if (istartx > istopx)
{
INT32 temp = istartx;
istartx = istopx;
istopx = temp;
}
// apply left/right clipping
if (istartx < cliprect.min_x)
istartx = cliprect.min_x;
if (istartx > cliprect.max_x)
istartx = cliprect.max_x + 1;
if (istopx < cliprect.min_x)
istopx = cliprect.min_x;
if (istopx > cliprect.max_x)
istopx = cliprect.max_x + 1;
@ -865,8 +864,19 @@ UINT32 poly_manager<_BaseType, _ObjectData, _MaxParams, _MaxPolys>::render_trian
extent_t &extent = unit.extent[extnum];
extent.startx = istartx;
extent.stopx = istopx;
// fill in the parameters for the extent
for (int paramnum = 0; paramnum < _MaxParams; paramnum++)
{
extent.param[paramnum].start = srcextent.param[paramnum].start;
extent.param[paramnum].dpdx = srcextent.param[paramnum].dpdx;
}
extent.userdata = srcextent.userdata;
if (istartx < istopx)
pixels += istopx - istartx;
else if(istopx < istartx)
pixels += istartx - istopx;
}
}
@ -1064,6 +1074,7 @@ UINT32 poly_manager<_BaseType, _ObjectData, _MaxParams, _MaxPolys>::render_polyg
istartx = istopx = 0;
extent.startx = istartx;
extent.stopx = istopx;
extent.userdata = NULL;
pixels += istopx - istartx;
}
}

View File

@ -805,7 +805,7 @@ static INTERRUPT_GEN( n64_vblank )
signal_rcp_interrupt(device->machine(), VI_INTERRUPT);
}
static MACHINE_CONFIG_START( aleck64, _n64_state )
static MACHINE_CONFIG_START( aleck64, n64_state )
/* basic machine hardware */
MCFG_CPU_ADD("maincpu", VR4300BE, 93750000)

View File

@ -2,22 +2,22 @@
#define _INCLUDES_N64_H_
#include "cpu/rsp/rsp.h"
#include "video/n64.h"
#include "sound/dmadac.h"
#include "includes/n64.h"
/*----------- forward decls -----------*/
/*----------- driver state -----------*/
class _n64_state : public driver_device
class n64_rdp;
class n64_state : public driver_device
{
public:
_n64_state(const machine_config &mconfig, device_type type, const char *tag)
n64_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag) { }
/* video-related */
N64::RDP::Processor m_rdp;
n64_rdp *m_rdp;
};
/*----------- devices -----------*/

View File

@ -5,6 +5,8 @@
#include "cpu/mips/mips3.h"
#include "cpu/mips/mips3com.h"
#include "includes/n64.h"
#include "video/n64.h"
#include "profiler.h"
UINT32 *rdram;
UINT32 *rsp_imem;
@ -758,22 +760,22 @@ void dp_full_sync(running_machine &machine)
READ32_DEVICE_HANDLER( n64_dp_reg_r )
{
_n64_state *state = device->machine().driver_data<_n64_state>();
n64_state *state = device->machine().driver_data<n64_state>();
//printf("%08x\n", offset);
//printf("dp_reg_r %08x\n", offset);
switch (offset)
{
case 0x00/4: // DP_START_REG
return state->m_rdp.GetStartReg();
return state->m_rdp->GetStartReg();
case 0x04/4: // DP_END_REG
return state->m_rdp.GetEndReg();
return state->m_rdp->GetEndReg();
case 0x08/4: // DP_CURRENT_REG
return state->m_rdp.GetCurrentReg();
return state->m_rdp->GetCurrentReg();
case 0x0c/4: // DP_STATUS_REG
return state->m_rdp.GetStatusReg();
return state->m_rdp->GetStatusReg();
default:
logerror("dp_reg_r: %08X, %08X at %08X\n", offset, mem_mask, cpu_get_pc(device));
@ -785,33 +787,33 @@ READ32_DEVICE_HANDLER( n64_dp_reg_r )
WRITE32_DEVICE_HANDLER( n64_dp_reg_w )
{
_n64_state *state = device->machine().driver_data<_n64_state>();
n64_state *state = device->machine().driver_data<n64_state>();
//printf("%08x: %08x\n", offset, data);
//printf("dp_reg_w %08x %08x %08x\n", offset, data, mem_mask);
switch (offset)
{
case 0x00/4: // DP_START_REG
state->m_rdp.SetStartReg(data);
state->m_rdp.SetCurrentReg(state->m_rdp.GetStartReg());
state->m_rdp->SetStartReg(data);
state->m_rdp->SetCurrentReg(state->m_rdp->GetStartReg());
break;
case 0x04/4: // DP_END_REG
state->m_rdp.SetEndReg(data);
state->m_rdp->SetEndReg(data);
g_profiler.start(PROFILER_USER1);
state->m_rdp.ProcessList();
state->m_rdp->ProcessList();
g_profiler.stop();
break;
case 0x0c/4: // DP_STATUS_REG
{
UINT32 current_status = state->m_rdp.GetStatusReg();
UINT32 current_status = state->m_rdp->GetStatusReg();
if (data & 0x00000001) current_status &= ~DP_STATUS_XBUS_DMA;
if (data & 0x00000002) current_status |= DP_STATUS_XBUS_DMA;
if (data & 0x00000004) current_status &= ~DP_STATUS_FREEZE;
if (data & 0x00000008) current_status |= DP_STATUS_FREEZE;
if (data & 0x00000010) current_status &= ~DP_STATUS_FLUSH;
if (data & 0x00000020) current_status |= DP_STATUS_FLUSH;
state->m_rdp.SetStatusReg(current_status);
state->m_rdp->SetStatusReg(current_status);
break;
}
@ -835,7 +837,7 @@ const rsp_config n64_rsp_config =
// Video Interface
void n64_periphs::vi_recalculate_resolution()
{
_n64_state *state = machine().driver_data<_n64_state>();
n64_state *state = machine().driver_data<n64_state>();
int x_start = (vi_hstart & 0x03ff0000) >> 16;
int x_end = vi_hstart & 0x000003ff;
@ -866,7 +868,7 @@ void n64_periphs::vi_recalculate_resolution()
if (height > 480)
height = 480;
state->m_rdp.MiscState.FBHeight = height;
state->m_rdp->MiscState.FBHeight = height;
visarea.max_x = width - 1;
visarea.max_y = height - 1;
@ -930,7 +932,7 @@ READ32_MEMBER( n64_periphs::vi_reg_r )
WRITE32_MEMBER( n64_periphs::vi_reg_w )
{
//printf("vi_reg_w %08x %08x %08x\n", offset * 4, data, mem_mask);
_n64_state *state = machine().driver_data<_n64_state>();
n64_state *state = machine().driver_data<n64_state>();
switch (offset)
{
@ -949,7 +951,7 @@ WRITE32_MEMBER( n64_periphs::vi_reg_w )
vi_recalculate_resolution();
}
vi_width = data;
state->m_rdp.MiscState.FBWidth = data;
state->m_rdp->MiscState.FBWidth = data;
break;
case 0x0c/4: // VI_INTR_REG

View File

@ -1278,7 +1278,7 @@ $(MAMEOBJ)/seibu.a: \
$(VIDEO)/sei_crtc.o \
$(MAMEOBJ)/seta.a: \
$(DRIVERS)/aleck64.o $(MACHINE)/n64.o $(VIDEO)/n64.o $(VIDEO)/rdpblend.o $(VIDEO)/rdpfb.o $(VIDEO)/rdpspn16.o $(VIDEO)/rdptpipe.o \
$(DRIVERS)/aleck64.o $(MACHINE)/n64.o $(VIDEO)/n64.o $(VIDEO)/rdpblend.o $(VIDEO)/rdpspn16.o $(VIDEO)/rdptpipe.o \
$(DRIVERS)/darkhors.o \
$(DRIVERS)/hanaawas.o $(VIDEO)/hanaawas.o \
$(DRIVERS)/macs.o \

File diff suppressed because it is too large Load Diff

View File

@ -2,11 +2,10 @@
#define _VIDEO_N64_H_
#include "emu.h"
#include "includes/n64.h"
#include "video/polynew.h"
#include "video/rdpblend.h"
#include "video/rdptri.h"
#include "video/rdpfb.h"
#include "video/rdptpipe.h"
#include "video/rdpspn16.h"
/*****************************************************************************/
@ -57,20 +56,20 @@
#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 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 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->HiddenBits[(in) ^ BYTE_ADDR_XOR]) : 0)
#define HWRITEADDR8(in, val) {if ((in) <= MEM8_LIMIT) m_rdp->HiddenBits[(in) ^ BYTE_ADDR_XOR] = val;}
#define HREADADDR8(in) /*(((in) <= MEM8_LIMIT) ? */(HiddenBits[(in) ^ BYTE_ADDR_XOR])/* : 0)*/
#define HWRITEADDR8(in, val) /*{if ((in) <= MEM8_LIMIT) */HiddenBits[(in) ^ BYTE_ADDR_XOR] = val;/*}*/
//sign-extension macros
#define SIGN22(x) (((x) & 0x200000) ? ((x) | ~0x3fffff) : ((x) & 0x3fffff))
@ -83,19 +82,30 @@
#define KURT_AKELEY_SIGN9(x) ((((x) & 0x180) == 0x180) ? ((x) | ~0x1ff) : ((x) & 0x1ff))
#define SPAN_R (0)
#define SPAN_G (1)
#define SPAN_B (2)
#define SPAN_A (3)
#define SPAN_S (4)
#define SPAN_T (5)
#define SPAN_W (6)
#define SPAN_Z (7)
#define RDP_CVG_SPAN_MAX (1024)
#define EXTENT_AUX_COUNT (sizeof(rdp_span_aux)*(480*128)) // Screen coverage *128, more or less
/*****************************************************************************/
class n64_periphs;
class n64_rdp;
namespace N64
{
namespace RDP
{
class Processor;
class MiscStateT;
class OtherModesT;
struct MiscStateT;
struct OtherModesT;
struct CombineModesT;
struct ColorInputsT;
struct SpanBaseT;
struct Rectangle;
class Color
{
@ -124,159 +134,216 @@ enum
BIT_DEPTH_COUNT
};
class Tile
class SpanParam
{
public:
int format; // Image data format: RGBA, YUV, CI, IA, I
int size; // Size of texel element: 4b, 8b, 16b, 32b
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
UINT16 sl, tl, sh, th; // 10.2 fixed-point, starting and ending texel row / column
int num;
};
class MiscStateT
{
public:
MiscStateT()
union
{
CurrentPixCvg = 0;
CurrentMemCvg = 0;
CurrentCvgBit = 0;
CurrentPixOverlap = 0;
MaxLevel = 0;
MinLevel = 0;
}
int FBFormat; // Framebuffer pixel format index (0 - I, 1 - IA, 2 - CI, 3 - RGBA)
int FBSize; // Framebuffer pixel size index (0 - 4bpp, 1 - 8bpp, 2 - 16bpp, 3 - 32bpp)
int FBWidth; // Framebuffer width, in pixels
int FBHeight; // Framebuffer height, in scanlines
UINT32 FBAddress; // Framebuffer source address offset (in bytes) from start of RDRAM
UINT32 ZBAddress; // Z-buffer source address offset (in bytes) from start of RDRAM
int TIFormat; // Format for Texture Interface (TI) transfers
int TISize; // Size (in bytes) of TI transfers
int TIWidth; // Width (in pixels) of TI transfers
UINT32 TIAddress; // Destination address for TI transfers
UINT32 CurrentPixCvg; // Coverage for the current pixel
UINT32 CurrentMemCvg; // Incoming coverage, in memory, for the current pixel
UINT32 CurrentCvgBit; // Bitfield representation of current coverage value
UINT32 CurrentPixOverlap; // Current overlap value, in coverage indices, for the current pixel
UINT8 RandomSeed; // %HACK%, adds 19 each time it's read and is more or less random
int SpecialBlendSelect0; // Special blend-mode select for cycle 0
int SpecialBlendSelect1; // Special blend-mode select for cycle 1
UINT32 MaxLevel; // Maximum LOD level for texture filtering
UINT32 MinLevel; // Minimum LOD level for texture filtering
UINT16 PrimitiveZ; // Forced Z value for current primitive, if applicable
UINT16 PrimitiveDZ; // Forced Delta-Z value for current primitive, if applicable
UINT32 w;
#ifdef LSB_FIRST
struct { UINT16 l; INT16 h; } h;
#else
struct { INT16 h; UINT16 l; } h;
#endif
};
};
class CombineModes
struct N64Tile
{
public:
int sub_a_rgb0;
int sub_b_rgb0;
int mul_rgb0;
int add_rgb0;
int sub_a_a0;
int sub_b_a0;
int mul_a0;
int add_a0;
int sub_a_rgb1;
int sub_b_rgb1;
int mul_rgb1;
int add_rgb1;
int sub_a_a1;
int sub_b_a1;
int mul_a1;
int add_a1;
int format; // Image data format: RGBA, YUV, CI, IA, I
int size; // Size of texel element: 4b, 8b, 16b, 32b
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
UINT16 sl, tl, sh, th; // 10.2 fixed-point, starting and ending texel row / column
int num;
};
class OtherModesT
struct SpanBaseT
{
public:
int cycle_type;
bool persp_tex_en;
bool detail_tex_en;
bool sharpen_tex_en;
bool tex_lod_en;
bool en_tlut;
bool tlut_type;
bool sample_type;
bool mid_texel;
bool bi_lerp0;
bool bi_lerp1;
bool convert_one;
bool key_en;
int rgb_dither_sel;
int alpha_dither_sel;
int blend_m1a_0;
int blend_m1a_1;
int blend_m1b_0;
int blend_m1b_1;
int blend_m2a_0;
int blend_m2a_1;
int blend_m2b_0;
int blend_m2b_1;
int tex_edge;
bool force_blend;
bool alpha_cvg_select;
bool cvg_times_alpha;
int z_mode;
int cvg_dest;
bool color_on_cvg;
bool image_read_en;
bool z_update_en;
bool z_compare_en;
bool antialias_en;
bool z_source_sel;
bool dither_alpha_en;
bool alpha_compare_en;
int m_span_dr;
int m_span_dg;
int m_span_db;
int m_span_da;
int m_span_ds;
int m_span_dt;
int m_span_dw;
int m_span_dz;
int m_span_dymax;
int m_span_dzpix;
int m_span_drdy;
int m_span_dgdy;
int m_span_dbdy;
int m_span_dady;
int m_span_dzdy;
};
class ColorInputsT
struct MiscStateT
{
public:
// combiner inputs
UINT8 *combiner_rgbsub_a_r[2];
UINT8 *combiner_rgbsub_a_g[2];
UINT8 *combiner_rgbsub_a_b[2];
UINT8 *combiner_rgbsub_b_r[2];
UINT8 *combiner_rgbsub_b_g[2];
UINT8 *combiner_rgbsub_b_b[2];
UINT8 *combiner_rgbmul_r[2];
UINT8 *combiner_rgbmul_g[2];
UINT8 *combiner_rgbmul_b[2];
UINT8 *combiner_rgbadd_r[2];
UINT8 *combiner_rgbadd_g[2];
UINT8 *combiner_rgbadd_b[2];
MiscStateT()
{
MaxLevel = 0;
MinLevel = 0;
}
UINT8 *combiner_alphasub_a[2];
UINT8 *combiner_alphasub_b[2];
UINT8 *combiner_alphamul[2];
UINT8 *combiner_alphaadd[2];
int FBFormat; // Framebuffer pixel format index (0 - I, 1 - IA, 2 - CI, 3 - RGBA)
int FBSize; // Framebuffer pixel size index (0 - 4bpp, 1 - 8bpp, 2 - 16bpp, 3 - 32bpp)
int FBWidth; // Framebuffer width, in pixels
int FBHeight; // Framebuffer height, in scanlines
UINT32 FBAddress; // Framebuffer source address offset (in bytes) from start of RDRAM
// blender input
UINT8 *blender1a_r[2];
UINT8 *blender1a_g[2];
UINT8 *blender1a_b[2];
UINT8 *blender1b_a[2];
UINT8 *blender2a_r[2];
UINT8 *blender2a_g[2];
UINT8 *blender2a_b[2];
UINT8 *blender2b_a[2];
UINT32 ZBAddress; // Z-buffer source address offset (in bytes) from start of RDRAM
int TIFormat; // Format for Texture Interface (TI) transfers
int TISize; // Size (in bytes) of TI transfers
int TIWidth; // Width (in pixels) of TI transfers
UINT32 TIAddress; // Destination address for TI transfers
UINT8 RandomSeed; // %HACK%, adds 19 each time it's read and is more or less random
int SpecialBlendSelect0; // Special blend-mode select for cycle 0
int SpecialBlendSelect1; // Special blend-mode select for cycle 1
UINT32 MaxLevel; // Maximum LOD level for texture filtering
UINT32 MinLevel; // Minimum LOD level for texture filtering
UINT16 PrimitiveZ; // Forced Z value for current primitive, if applicable
UINT16 PrimitiveDZ; // Forced Delta-Z value for current primitive, if applicable
};
struct CombineModesT
{
int sub_a_rgb0;
int sub_b_rgb0;
int mul_rgb0;
int add_rgb0;
int sub_a_a0;
int sub_b_a0;
int mul_a0;
int add_a0;
int sub_a_rgb1;
int sub_b_rgb1;
int mul_rgb1;
int add_rgb1;
int sub_a_a1;
int sub_b_a1;
int mul_a1;
int add_a1;
};
struct OtherModesT
{
int cycle_type;
bool persp_tex_en;
bool detail_tex_en;
bool sharpen_tex_en;
bool tex_lod_en;
bool en_tlut;
bool tlut_type;
bool sample_type;
bool mid_texel;
bool bi_lerp0;
bool bi_lerp1;
bool convert_one;
bool key_en;
int rgb_dither_sel;
int alpha_dither_sel;
int blend_m1a_0;
int blend_m1a_1;
int blend_m1b_0;
int blend_m1b_1;
int blend_m2a_0;
int blend_m2a_1;
int blend_m2b_0;
int blend_m2b_1;
int tex_edge;
bool force_blend;
bool alpha_cvg_select;
bool cvg_times_alpha;
int z_mode;
int cvg_dest;
bool color_on_cvg;
UINT8 image_read_en;
bool z_update_en;
bool z_compare_en;
bool antialias_en;
bool z_source_sel;
bool dither_alpha_en;
bool alpha_compare_en;
};
struct ColorInputsT
{
// combiner inputs
UINT8 *combiner_rgbsub_a_r[2];
UINT8 *combiner_rgbsub_a_g[2];
UINT8 *combiner_rgbsub_a_b[2];
UINT8 *combiner_rgbsub_b_r[2];
UINT8 *combiner_rgbsub_b_g[2];
UINT8 *combiner_rgbsub_b_b[2];
UINT8 *combiner_rgbmul_r[2];
UINT8 *combiner_rgbmul_g[2];
UINT8 *combiner_rgbmul_b[2];
UINT8 *combiner_rgbadd_r[2];
UINT8 *combiner_rgbadd_g[2];
UINT8 *combiner_rgbadd_b[2];
UINT8 *combiner_alphasub_a[2];
UINT8 *combiner_alphasub_b[2];
UINT8 *combiner_alphamul[2];
UINT8 *combiner_alphaadd[2];
// blender input
UINT8 *blender1a_r[2];
UINT8 *blender1a_g[2];
UINT8 *blender1a_b[2];
UINT8 *blender1b_a[2];
UINT8 *blender2a_r[2];
UINT8 *blender2a_g[2];
UINT8 *blender2a_b[2];
UINT8 *blender2b_a[2];
};
struct rdp_span_aux
{
UINT32 m_unscissored_rx;
UINT16 m_cvg[RDP_CVG_SPAN_MAX];
Color MemoryColor;
Color PixelColor;
Color InvPixelColor;
Color BlendedPixelColor;
Color CombinedColor;
Color Texel0Color;
Color Texel1Color;
Color NextTexelColor;
Color BlendColor; /* constant blend color */
Color PrimColor; /* flat primitive color */
Color EnvColor; /* generic color constant ('environment') */
Color FogColor; /* generic color constant ('fog') */
Color ShadeColor; /* gouraud-shaded color */
Color KeyScale; /* color-keying constant */
Color NoiseColor; /* noise */
UINT8 LODFraction; /* Z-based LOD fraction for this poly */
UINT8 PrimLODFraction; /* fixed LOD fraction for this poly */
ColorInputsT ColorInputs;
UINT32 CurrentPixCvg;
UINT32 CurrentMemCvg;
UINT32 CurrentCvgBit;
UINT32 CurrentPixOverlap;
INT32 ShiftA;
INT32 ShiftB;
INT32 m_precomp_s;
INT32 m_precomp_t;
INT32 m_clamp_s_diff[8];
INT32 m_clamp_t_diff[8];
UINT8 BlendEnable;
bool PreWrap;
INT32 m_dzpix_enc;
UINT8 *m_tmem; /* pointer to texture cache for this polygon */
bool m_start_span;
};
struct Rectangle
@ -287,138 +354,33 @@ struct Rectangle
UINT16 m_yh; // 10.2 fixed-point
};
class Processor
struct rdp_poly_state
{
n64_rdp * m_rdp; /* pointer back to the RDP state */
MiscStateT MiscState; /* miscellaneous rasterizer bits */
OtherModesT OtherModes; /* miscellaneous rasterizer bits (2) */
SpanBaseT SpanBase; /* span initial values for triangle rasterization */
Rectangle Scissor; /* screen-space scissor bounds */
UINT32 FillColor; /* poly fill color */
N64Tile m_tiles[8]; /* texture tile state */
UINT8 m_tmem[0x1000]; /* texture cache */
int tilenum; /* texture tile index */
bool flip; /* left-major / right-major flip */
bool rect; /* primitive is rectangle (vs. triangle) */
};
//class n64_state;
class n64_rdp : public poly_manager<UINT32, rdp_poly_state, 8, 32000>
{
public:
Processor()
{
m_cmd_ptr = 0;
m_cmd_cur = 0;
typedef void (n64_rdp::*Writer) (UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
typedef void (n64_rdp::*Reader) (UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object);
typedef void (n64_rdp::*Copier) (UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, int CurrentPixCvg, const rdp_poly_state &object);
typedef void (n64_rdp::*Filler) (UINT32 curpixel, const rdp_poly_state &object);
m_start = 0;
m_end = 0;
m_current = 0;
m_status = 0x88;
for (int i = 0; i < 8; i++)
{
m_tiles[i].num = i;
}
OneColor.c = 0xffffffff;
ZeroColor.c = 0x00000000;
ColorInputs.combiner_rgbsub_a_r[0] = ColorInputs.combiner_rgbsub_a_r[1] = &OneColor.i.r;
ColorInputs.combiner_rgbsub_a_g[0] = ColorInputs.combiner_rgbsub_a_g[1] = &OneColor.i.g;
ColorInputs.combiner_rgbsub_a_b[0] = ColorInputs.combiner_rgbsub_a_b[1] = &OneColor.i.b;
ColorInputs.combiner_rgbsub_b_r[0] = ColorInputs.combiner_rgbsub_b_r[1] = &OneColor.i.r;
ColorInputs.combiner_rgbsub_b_g[0] = ColorInputs.combiner_rgbsub_b_g[1] = &OneColor.i.g;
ColorInputs.combiner_rgbsub_b_b[0] = ColorInputs.combiner_rgbsub_b_b[1] = &OneColor.i.b;
ColorInputs.combiner_rgbmul_r[0] = ColorInputs.combiner_rgbmul_r[1] = &OneColor.i.r;
ColorInputs.combiner_rgbmul_g[0] = ColorInputs.combiner_rgbmul_g[1] = &OneColor.i.g;
ColorInputs.combiner_rgbmul_b[0] = ColorInputs.combiner_rgbmul_b[1] = &OneColor.i.b;
ColorInputs.combiner_rgbadd_r[0] = ColorInputs.combiner_rgbadd_r[1] = &OneColor.i.r;
ColorInputs.combiner_rgbadd_g[0] = ColorInputs.combiner_rgbadd_g[1] = &OneColor.i.g;
ColorInputs.combiner_rgbadd_b[0] = ColorInputs.combiner_rgbadd_b[1] = &OneColor.i.b;
ColorInputs.combiner_alphasub_a[0] = ColorInputs.combiner_alphasub_a[1] = &OneColor.i.a;
ColorInputs.combiner_alphasub_b[0] = ColorInputs.combiner_alphasub_b[1] = &OneColor.i.a;
ColorInputs.combiner_alphamul[0] = ColorInputs.combiner_alphamul[1] = &OneColor.i.a;
ColorInputs.combiner_alphaadd[0] = ColorInputs.combiner_alphaadd[1] = &OneColor.i.a;
ColorInputs.blender1a_r[0] = ColorInputs.blender1a_r[1] = &PixelColor.i.r;
ColorInputs.blender1a_g[0] = ColorInputs.blender1a_g[1] = &PixelColor.i.r;
ColorInputs.blender1a_b[0] = ColorInputs.blender1a_b[1] = &PixelColor.i.r;
ColorInputs.blender1b_a[0] = ColorInputs.blender1b_a[1] = &PixelColor.i.r;
ColorInputs.blender2a_r[0] = ColorInputs.blender2a_r[1] = &PixelColor.i.r;
ColorInputs.blender2a_g[0] = ColorInputs.blender2a_g[1] = &PixelColor.i.r;
ColorInputs.blender2a_b[0] = ColorInputs.blender2a_b[1] = &PixelColor.i.r;
ColorInputs.blender2b_a[0] = ColorInputs.blender2b_a[1] = &PixelColor.i.r;
m_tmem = NULL;
m_machine = NULL;
//memset(m_hidden_bits, 3, 8388608);
PrimLODFraction = 0;
LODFraction = 0;
for (int i = 0; i < 256; i++)
{
m_gamma_table[i] = sqrt((float)(i << 6));
m_gamma_table[i] <<= 1;
}
for (int i = 0; i < 0x4000; i++)
{
m_gamma_dither_table[i] = sqrt((float)i);
m_gamma_dither_table[i] <<= 1;
}
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++)
{
ReplicatedRGBA[i] = (i << 3) | ((i >> 2) & 7);
}
}
~Processor() { }
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;
}
n64_rdp(n64_state &state);
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
@ -437,6 +399,10 @@ class Processor
}
}
void ProcessList();
UINT32 ReadData(UINT32 address);
void Dasm(char *buffer);
void SetMachine(running_machine& machine) { m_machine = &machine; }
// CPU-visible registers
@ -453,26 +419,25 @@ class Processor
UINT32 GetStatusReg() const { return m_status; }
// Internal state
CombineModes* GetCombine() { return &m_combine; }
CombineModesT* GetCombine() { return &m_combine; }
// 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);
void SetAddInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code);
void SetSubInputAlpha(UINT8 **input, int code);
void SetMulInputAlpha(UINT8 **input, int code);
void ColorCombiner2Cycle(rdp_span_aux *userdata);
void ColorCombiner1Cycle(rdp_span_aux *userdata);
void SetSubAInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
void SetSubBInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
void SetMulInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
void SetAddInputRGB(UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, int code, rdp_span_aux *userdata);
void SetSubInputAlpha(UINT8 **input, int code, rdp_span_aux *userdata);
void SetMulInputAlpha(UINT8 **input, int code, rdp_span_aux *userdata);
// Texture memory
UINT8* GetTMEM() { return m_tmem; }
UINT16* GetTMEM16() { return (UINT16*)m_tmem; }
UINT32* GetTMEM32() { return (UINT32*)m_tmem; }
UINT16* GetTLUT() { return (UINT16*)(m_tmem + 0x800); }
Tile* GetTiles(){ return m_tiles; }
// Emulation Accelerators
UINT8 GetRandom() { return MiscState.RandomSeed += 0x13; }
@ -487,25 +452,30 @@ class Processor
INT32* GetK5() { return &m_k5; }
// Blender-related (move into RDP::Blender)
void SetBlenderInput(int cycle, int which, UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, UINT8 **input_a, int a, int b);
void SetBlenderInput(int cycle, int which, UINT8 **input_r, UINT8 **input_g, UINT8 **input_b, UINT8 **input_a, int a, int b, rdp_span_aux *userdata);
// Span rasterization
void SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid);
void SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid);
void SpanDrawCopy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid);
void SpanDrawFill(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid);
// 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 flip);
void GetAlphaCvg(UINT8 *comb_alpha);
void RenderSpans(int start, int end, int tilenum, bool flip, extent_t *Spans, bool rect, rdp_poly_state &object);
void GetAlphaCvg(UINT8 *comb_alpha, rdp_span_aux *userdata, const rdp_poly_state &object);
const UINT8* GetBayerMatrix() const { return s_bayer_matrix; }
const UINT8* GetMagicMatrix() const { return s_magic_matrix; }
int GetCurrFIFOIndex() const { return m_cmd_cur; }
void ZStore(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z);
void ZStore(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
UINT32 ZDecompress(UINT32 zcurpixel);
UINT32 DZDecompress(UINT32 zcurpixel, UINT32 dzcurpixel);
UINT32 DZCompress(UINT32 value);
INT32 NormalizeDZPix(INT32 sum);
bool ZCompare(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 sz, UINT16 dzpix);
bool ZCompare(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 sz, UINT16 dzpix, rdp_span_aux *userdata, const rdp_poly_state &object);
// Fullscreen update-related
void VideoUpdate(n64_periphs *n64, bitmap_rgb32 &bitmap);
@ -549,81 +519,67 @@ class Processor
void CmdSetMaskImage(UINT32 w1, UINT32 w2);
void CmdSetColorImage(UINT32 w1, UINT32 w2);
void RGBAZClip(int sr, int sg, int sb, int sa, int *sz, rdp_span_aux *userdata);
void RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux *userdata, const rdp_poly_state &object);
void Triangle(bool shade, bool texture, bool zbuffer);
UINT32 AddRightCvg(UINT32 x, UINT32 k);
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;
void GetDitherValues(int x, int y, int* cdith, int* adith, const rdp_poly_state &object);
UINT32* GetSpecial9BitClampTable() { return m_special_9bit_clamptable; }
UINT16 decompress_cvmask_frombyte(UINT8 x);
void lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy);
void lookup_cvmask_derivatives(UINT32 mask, UINT8* offx, UINT8* offy, rdp_span_aux *userdata);
MiscStateT MiscState;
// Color constants
Color MemoryColor;
Color PixelColor;
Color InvPixelColor;
Color BlendedPixelColor;
Color BlendColor;
Color PrimColor;
Color EnvColor;
Color FogColor;
Color CombinedColor;
Color Texel0Color;
Color Texel1Color;
Color NextTexelColor;
Color ShadeColor;
Color KeyScale;
Color NoiseColor;
Color BlendColor; /* constant blend color */
Color PrimColor; /* flat primitive color */
Color EnvColor; /* generic color constant ('environment') */
Color FogColor; /* generic color constant ('fog') */
Color KeyScale; /* color-keying constant */
UINT8 LODFraction; /* Z-based LOD fraction for this poly */
UINT8 PrimLODFraction; /* fixed LOD fraction for this poly */
Color OneColor;
Color ZeroColor;
UINT8 LODFraction;
UINT8 PrimLODFraction;
UINT32 FillColor;
OtherModesT OtherModes;
ColorInputsT ColorInputs;
BlenderT Blender;
N64BlenderT Blender;
Span Spans[4096];
FramebufferT Framebuffer;
TexturePipeT TexPipe;
N64TexturePipeT TexPipe;
UINT8 HiddenBits[0x800000];
UINT8 ReplicatedRGBA[32];
Rectangle Scissor;
SpanBaseT SpanBase;
rectangle visarea;
void DrawTriangle(bool shade, bool texture, bool zbuffer, bool rect);
void compute_cvg_noflip(extent_t *Spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
void compute_cvg_flip(extent_t *Spans, INT32* majorx, INT32* minorx, INT32* majorxint, INT32* minorxint, INT32 scanline, INT32 yh, INT32 yl, INT32 base);
void* AuxBuf[2];
UINT32 AuxBufPtr[2];
UINT32 AuxBufIndex;
void* ExtentBuf[2];
UINT32 ExtentBufPtr[2];
UINT32 ExtentBufIndex;
protected:
CombineModes m_combine;
CombineModesT m_combine;
bool m_pending_mode_block;
bool m_pipe_clean;
typedef struct
{
@ -651,7 +607,7 @@ class Processor
UINT8* m_tmem;
Tile m_tiles[8];
N64Tile m_tiles[8];
running_machine* m_machine;
@ -663,9 +619,6 @@ class Processor
INT32 m_k4;
INT32 m_k5;
// Render-related (move into eventual drawing-related classes?)
Rectangle m_scissor;
// Texture perspective division
INT32 m_norm_point_rom[64];
INT32 m_norm_slope_rom[64];
@ -678,8 +631,29 @@ class Processor
UINT32 m_special_9bit_clamptable[512];
INT32 m_dzpix_enc;
INT32 m_dz_enc;
Writer _Write[16];
Reader _Read[4];
Copier _Copy[2];
Filler _Fill[2];
void _Write16Bit_Cvg0_Blend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write16Bit_Cvg0_NoBlend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write16Bit_Cvg1(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write16Bit_Cvg2(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write16Bit_Cvg3(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write32Bit_Cvg0_Blend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write32Bit_Cvg0_NoBlend(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write32Bit_Cvg1(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write32Bit_Cvg2(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Write32Bit_Cvg3(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Read16Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Read16Bit_ImgRead1(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Read32Bit_ImgRead0(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Read32Bit_ImgRead1(UINT32 curpixel, rdp_span_aux *userdata, const rdp_poly_state &object);
void _Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, int CurrentPixCvg, const rdp_poly_state &object);
void _Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b, int CurrentPixCvg, const rdp_poly_state &object);
void _Fill16Bit(UINT32 curpixel, const rdp_poly_state &object);
void _Fill32Bit(UINT32 curpixel, const rdp_poly_state &object);
class ZDecompressEntry
{
@ -701,8 +675,4 @@ class Processor
static const Command m_commands[0x40];
};
} // namespace RDP
} // namespace N64
#endif // _VIDEO_N64_H_

View File

@ -2,100 +2,41 @@
#include "includes/n64.h"
#include "video/n64.h"
namespace N64
{
namespace RDP
{
bool BlenderT::Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel)
bool N64BlenderT::Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object)
{
INT32 r, g, b;
if (!m_rdp->OtherModes.alpha_cvg_select)
if (!object.OtherModes.alpha_cvg_select)
{
DitherA(&m_rdp->PixelColor.i.a, adseed);
DitherA(&userdata->PixelColor.i.a, adseed);
}
DitherA(&m_rdp->ShadeColor.i.a, adseed);
DitherA(&userdata->ShadeColor.i.a, adseed);
if (!AlphaCompare(m_rdp->PixelColor.i.a))
if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))
{
return false;
}
if (m_rdp->OtherModes.antialias_en ? (!m_rdp->MiscState.CurrentPixCvg) : (!m_rdp->MiscState.CurrentCvgBit))
if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))
{
return false;
}
bool dontblend = (partialreject && m_rdp->PixelColor.i.a >= 0xff);
if (!BlendEnable || dontblend)
bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff);
if (!userdata->BlendEnable || dontblend)
{
r = *m_rdp->ColorInputs.blender1a_r[0];
g = *m_rdp->ColorInputs.blender1a_g[0];
b = *m_rdp->ColorInputs.blender1a_b[0];
r = *userdata->ColorInputs.blender1a_r[0];
g = *userdata->ColorInputs.blender1a_g[0];
b = *userdata->ColorInputs.blender1a_b[0];
}
else
{
m_rdp->InvPixelColor.i.a = 0xff - *m_rdp->ColorInputs.blender1b_a[0];
BlendEquationCycle0(&r, &g, &b, special_bsel);
userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
BlendEquationCycle0(&r, &g, &b, special_bsel, userdata, object);
}
if (m_rdp->OtherModes.rgb_dither_sel < 3)
{
DitherRGB(&r, &g, &b, dith);
}
*fr = r;
*fg = g;
*fb = b;
return true;
}
bool BlenderT::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1)
{
if (!m_rdp->OtherModes.alpha_cvg_select)
{
DitherA(&m_rdp->PixelColor.i.a, adseed);
}
DitherA(&m_rdp->ShadeColor.i.a, adseed);
if (!AlphaCompare(m_rdp->PixelColor.i.a))
{
return false;
}
if (m_rdp->OtherModes.antialias_en ? (!m_rdp->MiscState.CurrentPixCvg) : (!m_rdp->MiscState.CurrentCvgBit))
{
return false;
}
m_rdp->InvPixelColor.i.a = 0xff - *m_rdp->ColorInputs.blender1b_a[0];
INT32 r, g, b;
BlendEquationCycle0(&r, &g, &b, special_bsel0);
m_rdp->BlendedPixelColor.i.r = r;
m_rdp->BlendedPixelColor.i.g = g;
m_rdp->BlendedPixelColor.i.b = b;
m_rdp->BlendedPixelColor.i.a = m_rdp->PixelColor.i.a;
bool dontblend = (partialreject && m_rdp->PixelColor.i.a >= 0xff);
if (!BlendEnable || dontblend)
{
r = *m_rdp->ColorInputs.blender1a_r[1];
g = *m_rdp->ColorInputs.blender1a_g[1];
b = *m_rdp->ColorInputs.blender1a_b[1];
}
else
{
m_rdp->InvPixelColor.i.a = 0xff - *m_rdp->ColorInputs.blender1b_a[1];
BlendEquationCycle1(&r, &g, &b, special_bsel1);
}
if (m_rdp->OtherModes.rgb_dither_sel < 3)
if (object.OtherModes.rgb_dither_sel < 3)
{
DitherRGB(&r, &g, &b, dith);
}
@ -107,46 +48,100 @@ bool BlenderT::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int ads
return true;
}
void BlenderT::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special)
bool N64BlenderT::Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, int special_bsel1, rdp_span_aux *userdata, const rdp_poly_state& object)
{
UINT8 blend1a = *m_rdp->ColorInputs.blender1b_a[0] >> 3;
UINT8 blend2a = *m_rdp->ColorInputs.blender2b_a[0] >> 3;
if (!object.OtherModes.alpha_cvg_select)
{
DitherA(&userdata->PixelColor.i.a, adseed);
}
DitherA(&userdata->ShadeColor.i.a, adseed);
if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))
{
return false;
}
if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))
{
return false;
}
userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
INT32 r, g, b;
BlendEquationCycle0(&r, &g, &b, special_bsel0, userdata, object);
userdata->BlendedPixelColor.i.r = r;
userdata->BlendedPixelColor.i.g = g;
userdata->BlendedPixelColor.i.b = b;
userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a;
bool dontblend = (partialreject && userdata->PixelColor.i.a >= 0xff);
if (!userdata->BlendEnable || dontblend)
{
r = *userdata->ColorInputs.blender1a_r[1];
g = *userdata->ColorInputs.blender1a_g[1];
b = *userdata->ColorInputs.blender1a_b[1];
}
else
{
userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[1];
BlendEquationCycle1(&r, &g, &b, special_bsel1, userdata, object);
}
if (object.OtherModes.rgb_dither_sel < 3)
{
DitherRGB(&r, &g, &b, dith);
}
*fr = r;
*fg = g;
*fb = b;
return true;
}
void N64BlenderT::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object)
{
UINT8 blend1a = *userdata->ColorInputs.blender1b_a[0] >> 3;
UINT8 blend2a = *userdata->ColorInputs.blender2b_a[0] >> 3;
if (bsel_special)
{
blend1a = (blend1a >> ShiftA) & 0x1C;
blend2a = (blend2a >> ShiftB) & 0x1C;
blend1a = (blend1a >> userdata->ShiftA) & 0x1C;
blend2a = (blend2a >> userdata->ShiftB) & 0x1C;
}
UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
*r = (((int)(*m_rdp->ColorInputs.blender1a_r[0]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_r[0]) * (int)(blend2a)));
*r = (((int)(*userdata->ColorInputs.blender1a_r[0]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_r[0]) * (int)(blend2a)));
*g = (((int)(*m_rdp->ColorInputs.blender1a_g[0]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_g[0]) * (int)(blend2a)));
*g = (((int)(*userdata->ColorInputs.blender1a_g[0]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_g[0]) * (int)(blend2a)));
*b = (((int)(*m_rdp->ColorInputs.blender1a_b[0]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_b[0]) * (int)(blend2a)));
*b = (((int)(*userdata->ColorInputs.blender1a_b[0]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_b[0]) * (int)(blend2a)));
if (bsel_special)
{
*r += (((int)*m_rdp->ColorInputs.blender2a_r[0]) << 2);
*g += (((int)*m_rdp->ColorInputs.blender2a_g[0]) << 2);
*b += (((int)*m_rdp->ColorInputs.blender2a_b[0]) << 2);
*r += (((int)*userdata->ColorInputs.blender2a_r[0]) << 2);
*g += (((int)*userdata->ColorInputs.blender2a_g[0]) << 2);
*b += (((int)*userdata->ColorInputs.blender2a_b[0]) << 2);
}
else
{
*r += (int)*m_rdp->ColorInputs.blender2a_r[0];
*g += (int)*m_rdp->ColorInputs.blender2a_g[0];
*b += (int)*m_rdp->ColorInputs.blender2a_b[0];
*r += (int)*userdata->ColorInputs.blender2a_r[0];
*g += (int)*userdata->ColorInputs.blender2a_g[0];
*b += (int)*userdata->ColorInputs.blender2a_b[0];
}
*r >>= 2;
*g >>= 2;
*b >>= 2;
if (m_rdp->OtherModes.force_blend)
if (object.OtherModes.force_blend)
{
*r >>= 3;
*g >>= 3;
@ -171,46 +166,46 @@ void BlenderT::BlendEquationCycle0(int* r, int* g, int* b, int bsel_special)
if (*b > 255) *b = 255;
}
void BlenderT::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special)
void N64BlenderT::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object)
{
UINT8 blend1a = *m_rdp->ColorInputs.blender1b_a[1] >> 3;
UINT8 blend2a = *m_rdp->ColorInputs.blender2b_a[1] >> 3;
UINT8 blend1a = *userdata->ColorInputs.blender1b_a[1] >> 3;
UINT8 blend2a = *userdata->ColorInputs.blender2b_a[1] >> 3;
if (bsel_special)
{
blend1a = (blend1a >> ShiftA) & 0x1C;
blend2a = (blend2a >> ShiftB) & 0x1C;
blend1a = (blend1a >> userdata->ShiftA) & 0x1C;
blend2a = (blend2a >> userdata->ShiftB) & 0x1C;
}
UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
*r = (((int)(*m_rdp->ColorInputs.blender1a_r[1]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_r[1]) * (int)(blend2a)));
*r = (((int)(*userdata->ColorInputs.blender1a_r[1]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_r[1]) * (int)(blend2a)));
*g = (((int)(*m_rdp->ColorInputs.blender1a_g[1]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_g[1]) * (int)(blend2a)));
*g = (((int)(*userdata->ColorInputs.blender1a_g[1]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_g[1]) * (int)(blend2a)));
*b = (((int)(*m_rdp->ColorInputs.blender1a_b[1]) * (int)(blend1a))) +
(((int)(*m_rdp->ColorInputs.blender2a_b[1]) * (int)(blend2a)));
*b = (((int)(*userdata->ColorInputs.blender1a_b[1]) * (int)(blend1a))) +
(((int)(*userdata->ColorInputs.blender2a_b[1]) * (int)(blend2a)));
if (bsel_special)
{
*r += (((int)*m_rdp->ColorInputs.blender2a_r[1]) << 2);
*g += (((int)*m_rdp->ColorInputs.blender2a_g[1]) << 2);
*b += (((int)*m_rdp->ColorInputs.blender2a_b[1]) << 2);
*r += (((int)*userdata->ColorInputs.blender2a_r[1]) << 2);
*g += (((int)*userdata->ColorInputs.blender2a_g[1]) << 2);
*b += (((int)*userdata->ColorInputs.blender2a_b[1]) << 2);
}
else
{
*r += (int)*m_rdp->ColorInputs.blender2a_r[1];
*g += (int)*m_rdp->ColorInputs.blender2a_g[1];
*b += (int)*m_rdp->ColorInputs.blender2a_b[1];
*r += (int)*userdata->ColorInputs.blender2a_r[1];
*g += (int)*userdata->ColorInputs.blender2a_g[1];
*b += (int)*userdata->ColorInputs.blender2a_b[1];
}
*r >>= 2;
*g >>= 2;
*b >>= 2;
if (m_rdp->OtherModes.force_blend)
if (object.OtherModes.force_blend)
{
*r >>= 3;
*g >>= 3;
@ -235,12 +230,12 @@ void BlenderT::BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_specia
if (*b > 255) *b = 255;
}
bool BlenderT::AlphaCompare(UINT8 alpha)
bool N64BlenderT::AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
{
INT32 threshold;
if (m_rdp->OtherModes.alpha_compare_en)
if (object.OtherModes.alpha_compare_en)
{
threshold = (m_rdp->OtherModes.dither_alpha_en) ? m_rdp->GetRandom() : m_rdp->BlendColor.i.a;
threshold = (object.OtherModes.dither_alpha_en) ? m_rdp->GetRandom() : userdata->BlendColor.i.a;
if (alpha < threshold)
{
return false;
@ -250,7 +245,7 @@ bool BlenderT::AlphaCompare(UINT8 alpha)
return true;
}
void BlenderT::DitherA(UINT8 *a, int dith)
void N64BlenderT::DitherA(UINT8 *a, int dith)
{
INT32 new_a = *a + dith;
if(new_a & 0x100)
@ -260,7 +255,7 @@ void BlenderT::DitherA(UINT8 *a, int dith)
*a = (UINT8)new_a;
}
void BlenderT::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
void N64BlenderT::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
{
if ((*r & 7) > dith)
{
@ -287,7 +282,3 @@ void BlenderT::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
}
}
}
} // namespace RDP
} // namespace N64

View File

@ -3,52 +3,39 @@
#include "emu.h"
namespace N64
{
namespace RDP
{
class OtherModesT;
class MiscStateT;
class Processor;
class n64_rdp;
class rdp_span_aux;
class Color;
struct rdp_poly_state;
class BlenderT
class N64BlenderT
{
public:
BlenderT()
N64BlenderT()
{
BlendEnable = false;
}
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);
bool Blend2Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int bsel0, int bsel1, rdp_span_aux *userdata, const rdp_poly_state& object);
bool Blend1Cycle(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
void SetMachine(running_machine& machine) { m_machine = &machine; }
void SetProcessor(Processor* rdp) { m_rdp = rdp; }
void SetProcessor(n64_rdp* rdp) { m_rdp = rdp; }
running_machine &machine() const { assert(m_machine != NULL); return *m_machine; }
bool BlendEnable;
INT32 ShiftA;
INT32 ShiftB;
private:
running_machine* m_machine;
Processor* m_rdp;
n64_rdp* m_rdp;
void BlendEquationCycle0(INT32* r, INT32* g, INT32* b, int bsel_special);
void BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special);
void BlendEquationCycle0(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object);
void BlendEquationCycle1(INT32* r, INT32* g, INT32* b, int bsel_special, rdp_span_aux *userdata, const rdp_poly_state& object);
bool AlphaCompare(UINT8 alpha);
bool AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
void DitherRGB(INT32* r, INT32* g, INT32* b, int dith);
void DitherA(UINT8* a, int dith);
};
} // namespace RDP
} // namespace N64
#endif // _VIDEO_RDPBLEND_H_

View File

@ -1,275 +0,0 @@
#include "emu.h"
#include "includes/n64.h"
#include "video/n64.h"
namespace N64
{
namespace RDP
{
void FramebufferT::Write(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
switch(m_rdp->MiscState.FBSize)
{
case PIXEL_SIZE_16BIT:
Write16Bit(curpixel, r, g, b);
break;
case PIXEL_SIZE_32BIT:
Write32Bit(curpixel, r, g, b);
break;
default:
fatalerror("Unsupported bit depth: %d\n", m_rdp->MiscState.FBSize);
break;
}
}
void FramebufferT::Write16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
#undef CVG_DRAW
#ifdef CVG_DRAW
int covdraw = (CurrentPixCvg - 1) << 5;
r = covdraw;
g = covdraw;
b = covdraw;
#endif
UINT32 fb = (m_rdp->MiscState.FBAddress >> 1) + curpixel;
UINT32 hb = fb;
#if 0
if (m_rdp->MiscState.CurrentPixCvg > 8 && m_rdp->OtherModes.z_mode != 1)
{
stricterror("FBWRITE_16: CurrentPixCvg %d", m_rdp->MiscState.CurrentPixCvg);
}
#endif
UINT16 finalcolor = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1);
UINT32 finalcvg = 0;
if (m_rdp->OtherModes.color_on_cvg && !m_pre_wrap)
{
finalcolor = RREADIDX16(fb) & 0xfffe;
}
switch(m_rdp->OtherModes.cvg_dest)
{
case 0:
if (!m_rdp->Blender.BlendEnable)
{
finalcvg = (m_rdp->MiscState.CurrentPixCvg - 1) & 7;
RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1));
HWRITEADDR8(hb, finalcvg & 3);
}
else
{
finalcvg = m_rdp->MiscState.CurrentPixCvg + m_rdp->MiscState.CurrentMemCvg;
if (finalcvg & 8)
{
finalcvg = 7;
}
RWRITEIDX16(fb, finalcolor | ((finalcvg >> 2) & 1));
HWRITEADDR8(hb, finalcvg & 3);
}
break;
case 1:
finalcvg = (m_rdp->MiscState.CurrentPixCvg + m_rdp->MiscState.CurrentMemCvg) & 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_rdp->MiscState.CurrentMemCvg >> 2) & 1));
HWRITEADDR8(hb, m_rdp->MiscState.CurrentMemCvg & 3);
break;
}
}
void FramebufferT::Write32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
UINT32 fb = (m_rdp->MiscState.FBAddress >> 2) + curpixel;
UINT32 finalcolor = (r << 24) | (g << 16) | (b << 8);//cvg as 3 MSBs of alpha channel;
UINT32 finalcvg = 0;
#if 0
if (CurrentPixCvg > 8 && m_rdp->OtherModes.z_mode != 1)
{
stricterror("FBWRITE_16: CurrentPixCvg %d", CurrentPixCvg);
}
#endif
if (m_rdp->OtherModes.color_on_cvg && !m_pre_wrap)
{
finalcolor = RREADIDX32(fb) & 0xffffff00;
}
switch(m_rdp->OtherModes.cvg_dest)
{
case 0: //normal
if (!m_rdp->Blender.BlendEnable)
{
finalcvg = (m_rdp->MiscState.CurrentPixCvg - 1) & 7;
finalcolor |= (finalcvg << 5);
RWRITEIDX32(fb, finalcolor);
}
else
{
finalcvg = m_rdp->MiscState.CurrentPixCvg + m_rdp->MiscState.CurrentMemCvg;
if (finalcvg & 8)
{
finalcvg = 7;
}
finalcolor |= (finalcvg << 5);
RWRITEIDX32(fb, finalcolor);
}
break;
case 1:
finalcvg = (m_rdp->MiscState.CurrentPixCvg + m_rdp->MiscState.CurrentMemCvg) & 7;
finalcolor |= (finalcvg << 5);
RWRITEIDX32(fb, finalcolor);
break;
case 2:
RWRITEIDX32(fb, finalcolor | 0xE0);
break;
case 3:
finalcolor |= (m_rdp->MiscState.CurrentMemCvg << 5);
RWRITEIDX32(fb, finalcolor);
break;
}
}
void FramebufferT::Read(UINT32 curpixel)
{
switch(m_rdp->MiscState.FBSize)
{
case PIXEL_SIZE_16BIT:
Read16Bit(curpixel);
break;
case PIXEL_SIZE_32BIT:
Read32Bit(curpixel);
break;
default:
fatalerror("Unsupported bit depth: %d\n", m_rdp->MiscState.FBSize);
break;
}
}
void FramebufferT::Read16Bit(UINT32 curpixel)
{
UINT16 fword = RREADIDX16((m_rdp->MiscState.FBAddress >> 1) + curpixel);
UINT8 hbyte = HREADADDR8((m_rdp->MiscState.FBAddress >> 1) + curpixel);
m_rdp->MemoryColor.i.r = GETHICOL(fword);
m_rdp->MemoryColor.i.g = GETMEDCOL(fword);
m_rdp->MemoryColor.i.b = GETLOWCOL(fword);
if (m_rdp->OtherModes.image_read_en)
{
m_rdp->MiscState.CurrentMemCvg = ((fword & 1) << 2) | (hbyte & 3);
m_rdp->MemoryColor.i.a = m_rdp->MiscState.CurrentMemCvg << 5;
}
else
{
m_rdp->MiscState.CurrentMemCvg = 7;
m_rdp->MemoryColor.i.a = 0xff;
}
}
void FramebufferT::Read32Bit(UINT32 curpixel)
{
UINT32 mem = RREADIDX32((m_rdp->MiscState.FBAddress >> 2) + curpixel);
m_rdp->MemoryColor.i.r = (mem >> 24) & 0xff;
m_rdp->MemoryColor.i.g = (mem >> 16) & 0xff;
m_rdp->MemoryColor.i.b = (mem >> 8) & 0xff;
if (m_rdp->OtherModes.image_read_en)
{
m_rdp->MiscState.CurrentMemCvg = (mem >> 5) & 7;
m_rdp->MemoryColor.i.a = (mem) & 0xff;
}
else
{
m_rdp->MiscState.CurrentMemCvg = 7;
m_rdp->MemoryColor.i.a = 0xff;
}
}
void FramebufferT::Copy(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
switch(m_rdp->MiscState.FBSize)
{
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_rdp->MiscState.FBSize);
break;
}
}
void FramebufferT::Copy16Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
UINT16 val = ((r >> 3) << 11) | ((g >> 3) << 6) | ((b >> 3) << 1) | ((m_rdp->MiscState.CurrentPixCvg >> 2) & 1);
RWRITEIDX16((m_rdp->MiscState.FBAddress >> 1) + curpixel, val);
HWRITEADDR8((m_rdp->MiscState.FBAddress >> 1) + curpixel, m_rdp->MiscState.CurrentPixCvg & 3);
}
void FramebufferT::Copy32Bit(UINT32 curpixel, UINT32 r, UINT32 g, UINT32 b)
{
UINT32 val = (r << 24) | (g << 16) | (b << 8) | (m_rdp->MiscState.CurrentPixCvg << 5);
RWRITEIDX32((m_rdp->MiscState.FBAddress >> 2) + curpixel, val);
}
void FramebufferT::Fill(UINT32 curpixel)
{
switch(m_rdp->MiscState.FBSize)
{
case PIXEL_SIZE_16BIT:
Fill16Bit(curpixel);
break;
case PIXEL_SIZE_32BIT:
Fill32Bit(curpixel);
break;
default:
fatalerror("Unsupported bit depth: %d\n", m_rdp->MiscState.FBSize);
break;
}
}
void FramebufferT::Fill16Bit(UINT32 curpixel)
{
UINT16 val;
if (curpixel & 1)
{
val = m_rdp->FillColor & 0xffff;
}
else
{
val = (m_rdp->FillColor >> 16) & 0xffff;
}
RWRITEIDX16((m_rdp->MiscState.FBAddress >> 1) + curpixel, val);
HWRITEADDR8((m_rdp->MiscState.FBAddress >> 1) + curpixel, ((val & 1) << 1) | (val & 1));
}
void FramebufferT::Fill32Bit(UINT32 curpixel)
{
UINT32 FillColor = m_rdp->FillColor;
RWRITEIDX32((m_rdp->MiscState.FBAddress >> 2) + curpixel, FillColor);
HWRITEADDR8((m_rdp->MiscState.FBAddress >> 1) + (curpixel << 1), (FillColor & 0x10000) ? 3 : 0);
HWRITEADDR8((m_rdp->MiscState.FBAddress >> 1) + (curpixel << 1) + 1, (FillColor & 0x1) ? 3 : 0);
}
} // namespace RDP
} // namespace N64

View File

@ -1,53 +0,0 @@
#ifndef _VIDEO_RDPFB_H_
#define _VIDEO_RDPFB_H_
#include "emu.h"
namespace N64
{
namespace RDP
{
class OtherModes;
class MiscState;
class FramebufferT
{
public:
FramebufferT()
{
m_pre_wrap = false;
}
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;
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
} // namespace N64
#endif // _VIDEO_RDPFB_H_

View File

@ -1,15 +1,15 @@
INLINE void video_filter16(int *out_r, int *out_g, int *out_b, UINT16* vbuff, UINT8* hbuff, const UINT32 hres);
INLINE void divot_filter16(UINT8* r, UINT8* g, UINT8* b, UINT16* fbuff, UINT32 fbuff_index);
INLINE void restore_filter16(INT32* r, INT32* g, INT32* b, UINT16* fbuff, UINT32 fbuff_index, UINT32 hres);
INLINE void divot_filter16_buffer(INT32* r, INT32* g, INT32* b, N64::RDP::Color* vibuffer);
INLINE void restore_filter16_buffer(INT32* r, INT32* g, INT32* b, N64::RDP::Color* vibuff, UINT32 hres);
INLINE void restore_two(N64::RDP::Color* filtered, N64::RDP::Color* neighbour);
INLINE void divot_filter16_buffer(INT32* r, INT32* g, INT32* b, Color* vibuffer);
INLINE void restore_filter16_buffer(INT32* r, INT32* g, INT32* b, Color* vibuff, UINT32 hres);
INLINE void restore_two(Color* filtered, Color* neighbour);
INLINE void video_max(UINT32* Pixels, UINT8* max, UINT32* enb);
INLINE UINT32 ge_two(UINT32 enb);
INLINE void video_filter16(int *out_r, int *out_g, int *out_b, UINT16* vbuff, UINT8* hbuff, const UINT32 hres)
{
N64::RDP::Color penumax, penumin, max, min;
Color penumax, penumin, max, min;
UINT16 pix = *vbuff;
const UINT8 centercvg = (*hbuff & 3) + ((pix & 1) << 2) + 1;
UINT32 numoffull = 1;
@ -253,11 +253,11 @@ INLINE void divot_filter16(UINT8* r, UINT8* g, UINT8* b, UINT16* fbuff, UINT32 f
}
}
INLINE void divot_filter16_buffer(int* r, int* g, int* b, N64::RDP::Color* vibuffer)
INLINE void divot_filter16_buffer(int* r, int* g, int* b, Color* vibuffer)
{
N64::RDP::Color leftpix = vibuffer[-1];
N64::RDP::Color rightpix = vibuffer[1];
N64::RDP::Color filtered = *vibuffer;
Color leftpix = vibuffer[-1];
Color rightpix = vibuffer[1];
Color filtered = *vibuffer;
*r = filtered.i.r;
*g = filtered.i.g;
@ -427,12 +427,12 @@ INLINE void restore_filter16(int* r, int* g, int* b, UINT16* fbuff, UINT32 fbuff
}
}
INLINE void restore_filter16_buffer(INT32* r, INT32* g, INT32* b, N64::RDP::Color* vibuff, UINT32 hres)
INLINE void restore_filter16_buffer(INT32* r, INT32* g, INT32* b, Color* vibuff, UINT32 hres)
{
N64::RDP::Color filtered;
N64::RDP::Color leftuppix, leftdownpix, leftpix;
N64::RDP::Color rightuppix, rightdownpix, rightpix;
N64::RDP::Color uppix, downpix;
Color filtered;
Color leftuppix, leftdownpix, leftpix;
Color rightuppix, rightdownpix, rightpix;
Color uppix, downpix;
INT32 ihres = (INT32)hres; //can't apply unary minus to unsigned
leftuppix = vibuff[-ihres - 1];
@ -471,7 +471,7 @@ INLINE void restore_filter16_buffer(INT32* r, INT32* g, INT32* b, N64::RDP::Colo
}
// This is wrong, only the 5 upper bits are compared.
INLINE void restore_two(N64::RDP::Color* filtered, N64::RDP::Color* neighbour)
INLINE void restore_two(Color* filtered, Color* neighbour)
{
if (neighbour->i.r > filtered->i.r)
{

View File

@ -2,18 +2,13 @@
#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 Processor::RenderSpans(int start, int end, int tilenum, bool flip)
void n64_rdp::RenderSpans(int start, int end, int tilenum, bool flip, extent_t *Spans, bool rect, rdp_poly_state &object)
{
int clipy1 = GetScissor()->m_yh;
int clipy2 = GetScissor()->m_yl;
int clipy1 = Scissor.m_yh;
int clipy2 = Scissor.m_yl;
int offset = 0;
if (clipy2 <= 0)
{
@ -22,68 +17,59 @@ void Processor::RenderSpans(int start, int end, int tilenum, bool flip)
if (start < clipy1)
{
offset = clipy1 - start;
start = clipy1;
}
if (start >= clipy2)
{
offset = start - (clipy2 - 1);
start = clipy2 - 1;
}
if (end < clipy1)
{
end = clipy1;
}
if (end >= clipy2) // Needed by 40 Winks
if (end >= clipy2)
{
end = clipy2 - 1;
}
for(int i = start; i <= end; i++)
object.m_rdp = this;
memcpy(&object.MiscState, &MiscState, sizeof(MiscStateT));
memcpy(&object.OtherModes, &OtherModes, sizeof(OtherModesT));
memcpy(&object.SpanBase, &SpanBase, sizeof(SpanBaseT));
memcpy(&object.Scissor, &Scissor, sizeof(Rectangle));
memcpy(&object.m_tiles, &m_tiles, 8 * sizeof(N64Tile));
object.tilenum = tilenum;
object.flip = flip;
object.FillColor = FillColor;
object.rect = rect;
switch(OtherModes.cycle_type)
{
switch(OtherModes.cycle_type)
{
case CYCLE_TYPE_1: Spans[i].Draw1Cycle(i, tilenum, flip); break;
case CYCLE_TYPE_2: Spans[i].Draw2Cycle(i, tilenum, flip); break;
case CYCLE_TYPE_COPY: Spans[i].DrawCopy(i, tilenum, flip); break;
case CYCLE_TYPE_FILL: Spans[i].DrawFill(i, tilenum, flip); break;
}
case CYCLE_TYPE_1:
render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw1Cycle), this), start, (end - start) + 1, Spans + offset);
break;
case CYCLE_TYPE_2:
render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDraw2Cycle), this), start, (end - start) + 1, Spans + offset);
break;
case CYCLE_TYPE_COPY:
render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDrawCopy), this), start, (end - start) + 1, Spans + offset);
break;
case CYCLE_TYPE_FILL:
render_triangle_custom(visarea, render_delegate(FUNC(n64_rdp::SpanDrawFill), this), start, (end - start) + 1, Spans + offset);
break;
}
}
void Span::Dump()
void n64_rdp::RGBAZClip(int sr, int sg, int sb, int sa, int *sz, rdp_span_aux *userdata)
{
printf(" m_lx = %d\n", m_lx);
printf(" m_rx = %d\n", m_rx);
printf(" m_s.w = %08x\n", m_s.w);
printf(" m_t.w = %08x\n", m_t.w);
printf(" m_w.w = %08x\n", m_w.w);
printf(" m_r.w = %08x\n", m_r.w);
printf(" m_g.w = %08x\n", m_g.w);
printf(" m_b.w = %08x\n", m_b.w);
printf(" m_a.w = %08x\n", m_a.w);
printf(" m_z.w = %08x\n", m_z.w);
printf(" CVG: ");
for(int index = 0; index < RDP_CVG_SPAN_MAX; index++)
{
printf("%d", m_cvg[index]);
}
printf("\n");
}
void Span::SetMachine(running_machine &machine)
{
_n64_state *state = machine.driver_data<_n64_state>();
m_machine = &machine;
m_rdp = &state->m_rdp;
}
void Span::RGBAZClip(int sr, int sg, int sb, int sa, int *sz)
{
m_rdp->ShadeColor.i.r = m_rdp->GetSpecial9BitClampTable()[sr & 0x1ff];
m_rdp->ShadeColor.i.g = m_rdp->GetSpecial9BitClampTable()[sg & 0x1ff];
m_rdp->ShadeColor.i.b = m_rdp->GetSpecial9BitClampTable()[sb & 0x1ff];
m_rdp->ShadeColor.i.a = m_rdp->GetSpecial9BitClampTable()[sa & 0x1ff];
userdata->ShadeColor.i.r = m_special_9bit_clamptable[sr & 0x1ff];
userdata->ShadeColor.i.g = m_special_9bit_clamptable[sg & 0x1ff];
userdata->ShadeColor.i.b = m_special_9bit_clamptable[sb & 0x1ff];
userdata->ShadeColor.i.a = m_special_9bit_clamptable[sa & 0x1ff];
INT32 zanded = (*sz) & 0x60000;
@ -97,9 +83,9 @@ void Span::RGBAZClip(int sr, int sg, int sb, int sa, int *sz)
}
}
void Span::RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z)
void n64_rdp::RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT32* b, INT32* a, INT32* z, rdp_span_aux *userdata, const rdp_poly_state &object)
{
if (m_rdp->MiscState.CurrentPixCvg == 8)
if (userdata->CurrentPixCvg == 8)
{
*r >>= 2;
*g >>= 2;
@ -109,17 +95,17 @@ void Span::RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT3
}
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_xr = offx * SIGN13(object.SpanBase.m_span_dr >> 14);
INT32 summand_yr = offy * SIGN13(object.SpanBase.m_span_drdy >> 14);
INT32 summand_xb = offx * SIGN13(object.SpanBase.m_span_db >> 14);
INT32 summand_yb = offy * SIGN13(object.SpanBase.m_span_dbdy >> 14);
INT32 summand_xg = offx * SIGN13(object.SpanBase.m_span_dg >> 14);
INT32 summand_yg = offy * SIGN13(object.SpanBase.m_span_dgdy >> 14);
INT32 summand_xa = offx * SIGN13(object.SpanBase.m_span_da >> 14);
INT32 summand_ya = offy * SIGN13(object.SpanBase.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);
INT32 summand_xz = offx * SIGN22(object.SpanBase.m_span_dz >> 10);
INT32 summand_yz = offy * SIGN22(object.SpanBase.m_span_dzdy >> 10);
*r = ((*r << 2) + summand_xr + summand_yr) >> 4;
*g = ((*g << 2) + summand_xg + summand_yg) >> 4;
@ -129,58 +115,71 @@ void Span::RGBAZCorrectTriangle(INT32 offx, INT32 offy, INT32* r, INT32* g, INT3
}
}
void Span::Draw1Cycle(int index, int tilenum, bool flip)
void n64_rdp::SpanDraw1Cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid)
{
int clipx1 = m_rdp->GetScissor()->m_xh;
int clipx2 = m_rdp->GetScissor()->m_xl;
int clipx1 = object.Scissor.m_xh;
int clipx2 = object.Scissor.m_xl;
n64_rdp *m_rdp = object.m_rdp;
int tilenum = object.tilenum;
bool flip = object.flip;
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;
SpanParam r; r.w = extent.param[SPAN_R].start;
SpanParam g; g.w = extent.param[SPAN_G].start;
SpanParam b; b.w = extent.param[SPAN_B].start;
SpanParam a; a.w = extent.param[SPAN_A].start;
SpanParam z; z.w = extent.param[SPAN_Z].start;
SpanParam s; s.w = extent.param[SPAN_S].start;
SpanParam t; t.w = extent.param[SPAN_T].start;
SpanParam w; w.w = extent.param[SPAN_W].start;
UINT32 zb = m_rdp->MiscState.ZBAddress >> 1;
UINT32 zb = object.MiscState.ZBAddress >> 1;
UINT32 zhb = zb;
UINT8 offx = 0, offy = 0;
INT32 tile1 = tilenum;
m_rdp->TexPipe.CalculateClampDiffs(tile1);
rdp_span_aux *userdata = (rdp_span_aux*)extent.userdata;
bool noisecompute = m_rdp->ColorInputs.combiner_rgbsub_a_r[1] == &m_rdp->NoiseColor.i.r;
bool partialreject = (m_rdp->ColorInputs.blender2b_a[0] == &m_rdp->InvPixelColor.i.a && m_rdp->ColorInputs.blender1b_a[0] == &m_rdp->PixelColor.i.a);
bool bsel0 = (m_rdp->ColorInputs.blender2b_a[0] == &m_rdp->MemoryColor.i.a);
m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object);
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;
bool partialreject = (userdata->ColorInputs.blender2b_a[0] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[0] == &userdata->PixelColor.i.a);
bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a);
int drinc = flip ? (object.SpanBase.m_span_dr) : -object.SpanBase.m_span_dr;
int dginc = flip ? (object.SpanBase.m_span_dg) : -object.SpanBase.m_span_dg;
int dbinc = flip ? (object.SpanBase.m_span_db) : -object.SpanBase.m_span_db;
int dainc = flip ? (object.SpanBase.m_span_da) : -object.SpanBase.m_span_da;
int dzinc = flip ? (object.SpanBase.m_span_dz) : -object.SpanBase.m_span_dz;
int dsinc = flip ? (object.SpanBase.m_span_ds) : -object.SpanBase.m_span_ds;
int dtinc = flip ? (object.SpanBase.m_span_dt) : -object.SpanBase.m_span_dt;
int dwinc = flip ? (object.SpanBase.m_span_dw) : -object.SpanBase.m_span_dw;
int dzpix = object.SpanBase.m_span_dzpix;
int xinc = flip ? 1 : -1;
int fb_index = m_rdp->MiscState.FBWidth * index;
int fb_index = object.MiscState.FBWidth * scanline;
int cdith = 0;
int adith = 0;
int xstart = m_lx;
int xend = m_unscissored_rx;
int xend_scissored = m_rx;
int xstart = extent.startx;
int xend = userdata->m_unscissored_rx;
int xend_scissored = extent.stopx;
int x = xend;
int length = flip ? (xstart - xend) : (xend - xstart);
m_rdp->TexPipe.m_start_span = true;
UINT32 fir, fig, fib;
//if(object.rect) printf("(%s) Scan %d Span %d to %d %d, length %d\n", flip ? "Flip" : "NoFlip", scanline, xstart, xend_scissored, xend, length); fflush(stdout);
if(object.OtherModes.z_source_sel)
{
z.w = ((UINT32)object.MiscState.PrimitiveZ) << 16;
dzpix = object.MiscState.PrimitiveDZ;
dzinc = 0;
}
userdata->m_start_span = true;
for (int j = 0; j <= length; j++)
{
int sr = r.w >> 14;
@ -194,22 +193,15 @@ void Span::Draw1Cycle(int index, int tilenum, bool flip)
INT32 sss = 0;
INT32 sst = 0;
if (m_rdp->OtherModes.z_source_sel)
{
sz = (((UINT32)m_rdp->MiscState.PrimitiveZ) << 6) & 0x3fffff;
dzpix = m_rdp->MiscState.PrimitiveDZ;
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);
m_rdp->lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
if (m_rdp->TexPipe.m_start_span)
if (userdata->m_start_span)
{
if (m_rdp->OtherModes.persp_tex_en)
if (object.OtherModes.persp_tex_en)
{
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
}
@ -220,37 +212,40 @@ void Span::Draw1Cycle(int index, int tilenum, bool flip)
}
else
{
sss = m_rdp->TexPipe.m_precomp_s;
sst = m_rdp->TexPipe.m_precomp_t;
sss = userdata->m_precomp_s;
sst = userdata->m_precomp_t;
}
m_rdp->TexPipe.LOD1Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc);
m_rdp->TexPipe.LOD1Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, userdata, object);
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz);
RGBAZClip(sr, sg, sb, sa, &sz);
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
RGBAZClip(sr, sg, sb, sa, &sz, userdata);
m_rdp->TexPipe.Cycle(&m_rdp->Texel0Color, &m_rdp->Texel0Color, sss, sst, tilenum, 0);
m_rdp->TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tilenum, 0, userdata, object);
m_rdp->ColorCombiner1Cycle(noisecompute);
m_rdp->ColorCombiner1Cycle(userdata);
//Alpha coverage combiner
GetAlphaCvg(&userdata->PixelColor.i.a, userdata, object);
UINT32 curpixel = fb_index + x;
UINT32 zbcur = zb + curpixel;
UINT32 zhbcur = zhb + curpixel;
m_rdp->Framebuffer.Read(curpixel);
((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object);
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix))
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
{
m_rdp->GetDitherValues(index, j, &cdith, &adith);
m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
bool rendered = m_rdp->Blender.Blend1Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0);
bool rendered = m_rdp->Blender.Blend1Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object);
if (rendered)
{
m_rdp->Framebuffer.Write(curpixel, fir, fig, fib);
if (m_rdp->OtherModes.z_update_en)
((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
if (object.OtherModes.z_update_en)
{
m_rdp->ZStore(zbcur, zhbcur, sz);
m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
}
}
}
@ -267,23 +262,28 @@ void Span::Draw1Cycle(int index, int tilenum, bool flip)
x += xinc;
}
//printf("\n");
}
void Span::Draw2Cycle(int index, int tilenum, bool flip)
void n64_rdp::SpanDraw2Cycle(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid)
{
int clipx1 = m_rdp->GetScissor()->m_xh;
int clipx2 = m_rdp->GetScissor()->m_xl;
int clipx1 = object.Scissor.m_xh;
int clipx2 = object.Scissor.m_xl;
n64_rdp *m_rdp = object.m_rdp;
int tilenum = object.tilenum;
bool flip = object.flip;
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;
SpanParam r; r.w = extent.param[SPAN_R].start;
SpanParam g; g.w = extent.param[SPAN_G].start;
SpanParam b; b.w = extent.param[SPAN_B].start;
SpanParam a; a.w = extent.param[SPAN_A].start;
SpanParam z; z.w = extent.param[SPAN_Z].start;
SpanParam s; s.w = extent.param[SPAN_S].start;
SpanParam t; t.w = extent.param[SPAN_T].start;
SpanParam w; w.w = extent.param[SPAN_W].start;
UINT32 zb = m_rdp->MiscState.ZBAddress >> 1;
UINT32 zb = object.MiscState.ZBAddress >> 1;
UINT32 zhb = zb;
UINT8 offx = 0, offy = 0;
@ -295,41 +295,47 @@ void Span::Draw2Cycle(int index, int tilenum, bool flip)
INT32 news = 0;
INT32 newt = 0;
m_rdp->TexPipe.CalculateClampDiffs(tile1);
rdp_span_aux *userdata = (rdp_span_aux*)extent.userdata;
bool noisecompute = (m_rdp->ColorInputs.combiner_rgbsub_a_r[0] == &m_rdp->NoiseColor.i.r || m_rdp->ColorInputs.combiner_rgbsub_a_r[1] == &m_rdp->PixelColor.i.r);
bool partialreject = (m_rdp->ColorInputs.blender2b_a[1] == &m_rdp->InvPixelColor.i.a && m_rdp->ColorInputs.blender1b_a[1] == &m_rdp->PixelColor.i.a);
bool bsel0 = (m_rdp->ColorInputs.blender2b_a[0] == &m_rdp->MemoryColor.i.a);
bool bsel1 = (m_rdp->ColorInputs.blender2b_a[1] == &m_rdp->MemoryColor.i.a);
m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object);
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;
bool partialreject = (userdata->ColorInputs.blender2b_a[1] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[1] == &userdata->PixelColor.i.a);
bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a);
bool bsel1 = (userdata->ColorInputs.blender2b_a[1] == &userdata->MemoryColor.i.a);
int dzpix = object.SpanBase.m_span_dzpix;
int drinc = flip ? (object.SpanBase.m_span_dr) : -object.SpanBase.m_span_dr;
int dginc = flip ? (object.SpanBase.m_span_dg) : -object.SpanBase.m_span_dg;
int dbinc = flip ? (object.SpanBase.m_span_db) : -object.SpanBase.m_span_db;
int dainc = flip ? (object.SpanBase.m_span_da) : -object.SpanBase.m_span_da;
int dzinc = flip ? (object.SpanBase.m_span_dz) : -object.SpanBase.m_span_dz;
int dsinc = flip ? (object.SpanBase.m_span_ds) : -object.SpanBase.m_span_ds;
int dtinc = flip ? (object.SpanBase.m_span_dt) : -object.SpanBase.m_span_dt;
int dwinc = flip ? (object.SpanBase.m_span_dw) : -object.SpanBase.m_span_dw;
int xinc = flip ? 1 : -1;
int fb_index = m_rdp->MiscState.FBWidth * index;
int fb_index = object.MiscState.FBWidth * scanline;
int cdith = 0;
int adith = 0;
int xstart = m_lx;
int xend = m_unscissored_rx;
int xend_scissored = m_rx;
int xstart = extent.startx;
int xend = userdata->m_unscissored_rx;
int xend_scissored = extent.stopx;
int x = xend;
int length = flip ? (xstart - xend) : (xend - xstart);
m_rdp->TexPipe.m_start_span = true;
UINT32 fir, fig, fib;
//printf( "Span length: %d\n", length);
if(object.OtherModes.z_source_sel)
{
z.w = ((UINT32)object.MiscState.PrimitiveZ) << 16;
dzpix = object.MiscState.PrimitiveDZ;
dzinc = 0;
}
userdata->m_start_span = true;
for (int j = 0; j <= length; j++)
{
int sr = r.w >> 14;
@ -345,22 +351,15 @@ void Span::Draw2Cycle(int index, int tilenum, bool flip)
Color c1;
Color c2;
if (m_rdp->OtherModes.z_source_sel)
{
sz = (((UINT32)m_rdp->MiscState.PrimitiveZ) << 6) & 0x3fffff;
dzpix = m_rdp->MiscState.PrimitiveDZ;
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);
m_rdp->lookup_cvmask_derivatives(userdata->m_cvg[x], &offx, &offy, userdata);
if (m_rdp->TexPipe.m_start_span)
if (userdata->m_start_span)
{
if (m_rdp->OtherModes.persp_tex_en)
if (object.OtherModes.persp_tex_en)
{
m_rdp->TCDiv(ss, st, sw, &sss, &sst);
}
@ -371,44 +370,47 @@ void Span::Draw2Cycle(int index, int tilenum, bool flip)
}
else
{
sss = m_rdp->TexPipe.m_precomp_s;
sst = m_rdp->TexPipe.m_precomp_t;
sss = userdata->m_precomp_s;
sst = userdata->m_precomp_t;
}
m_rdp->TexPipe.LOD2Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2);
m_rdp->TexPipe.LOD2Cycle(&sss, &sst, s.w, t.w, w.w, dsinc, dtinc, dwinc, prim_tile, &tile1, &tile2, userdata, object);
news = m_rdp->TexPipe.m_precomp_s;
newt = m_rdp->TexPipe.m_precomp_t;
m_rdp->TexPipe.LOD2CycleLimited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1);
news = userdata->m_precomp_s;
newt = userdata->m_precomp_t;
m_rdp->TexPipe.LOD2CycleLimited(&news, &newt, s.w + dsinc, t.w + dtinc, w.w + dwinc, dsinc, dtinc, dwinc, prim_tile, &newtile1, object);
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz);
RGBAZClip(sr, sg, sb, sa, &sz);
RGBAZCorrectTriangle(offx, offy, &sr, &sg, &sb, &sa, &sz, userdata, object);
RGBAZClip(sr, sg, sb, sa, &sz, userdata);
m_rdp->TexPipe.Cycle(&m_rdp->Texel0Color, &m_rdp->Texel0Color, sss, sst, tile1, 0);
m_rdp->TexPipe.Cycle(&m_rdp->Texel1Color, &m_rdp->Texel0Color, sss, sst, tile2, 1);
m_rdp->TexPipe.Cycle(&userdata->Texel0Color, &userdata->Texel0Color, sss, sst, tile1, 0, userdata, object);
m_rdp->TexPipe.Cycle(&userdata->Texel1Color, &userdata->Texel0Color, sss, sst, tile2, 1, userdata, object);
m_rdp->TexPipe.Cycle(&m_rdp->NextTexelColor, &m_rdp->NextTexelColor, sss, sst, tile2, 1);
m_rdp->TexPipe.Cycle(&userdata->NextTexelColor, &userdata->NextTexelColor, sss, sst, tile2, 1, userdata, object);
m_rdp->ColorCombiner2Cycle(noisecompute);
m_rdp->ColorCombiner2Cycle(userdata);
//Alpha coverage combiner
GetAlphaCvg(&userdata->PixelColor.i.a, userdata, object);
UINT32 curpixel = fb_index + x;
UINT32 zbcur = zb + curpixel;
UINT32 zhbcur = zhb + curpixel;
m_rdp->Framebuffer.Read(curpixel);
((this)->*(_Read[((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en]))(curpixel, userdata, object);
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix))
if(m_rdp->ZCompare(zbcur, zhbcur, sz, dzpix, userdata, object))
{
m_rdp->GetDitherValues(index, j, &cdith, &adith);
m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
bool rendered = m_rdp->Blender.Blend2Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1);
bool rendered = m_rdp->Blender.Blend2Cycle(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object);
if (rendered)
{
m_rdp->Framebuffer.Write(curpixel, fir, fig, fib);
if (m_rdp->OtherModes.z_update_en)
((this)->*(_Write[((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1) | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
if (object.OtherModes.z_update_en)
{
m_rdp->ZStore(zbcur, zhbcur, sz);
m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
}
}
}
@ -427,25 +429,29 @@ void Span::Draw2Cycle(int index, int tilenum, bool flip)
}
}
void Span::DrawCopy(int index, int tilenum, bool flip)
void n64_rdp::SpanDrawCopy(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid)
{
int clipx1 = m_rdp->GetScissor()->m_xh;
int clipx2 = m_rdp->GetScissor()->m_xl;
int clipx1 = object.Scissor.m_xh;
int clipx2 = object.Scissor.m_xl;
n64_rdp *m_rdp = object.m_rdp;
int tilenum = object.tilenum;
bool flip = object.flip;
SpanParam s = m_s;
SpanParam t = m_t;
SpanParam s; s.w = extent.param[SPAN_S].start;
SpanParam t; t.w = extent.param[SPAN_T].start;
int ds = m_rdp->m_span_ds / 4;
int dt = m_rdp->m_span_dt / 4;
int ds = object.SpanBase.m_span_ds / 4;
int dt = object.SpanBase.m_span_dt / 4;
int dsinc = flip ? (ds) : -ds;
int dtinc = flip ? (dt) : -dt;
int xinc = flip ? 1 : -1;
int fb_index = m_rdp->MiscState.FBWidth * index;
int fb_index = object.MiscState.FBWidth * scanline;
int xstart = m_lx;
int xend = m_unscissored_rx;
int xend_scissored = m_rx;
rdp_span_aux *userdata = (rdp_span_aux*)extent.userdata;
int xstart = extent.startx;
int xend = userdata->m_unscissored_rx;
int xend_scissored = extent.stopx;
int x = xend;
@ -459,13 +465,12 @@ void Span::DrawCopy(int index, int tilenum, bool flip)
{
INT32 sss = s.h.h;
INT32 sst = t.h.h;
m_rdp->TexPipe.Copy(&m_rdp->Texel0Color, sss, sst, tilenum);
m_rdp->TexPipe.Copy(&userdata->Texel0Color, sss, sst, tilenum, object, userdata);
UINT32 curpixel = fb_index + x;
m_rdp->MiscState.CurrentPixCvg = m_rdp->Texel0Color.i.a ? 7 : 0;
if ((m_rdp->Texel0Color.i.a != 0) || (!m_rdp->OtherModes.alpha_compare_en))
if ((userdata->Texel0Color.i.a != 0) || (!object.OtherModes.alpha_compare_en))
{
m_rdp->Framebuffer.Copy(curpixel, m_rdp->Texel0Color.i.r, m_rdp->Texel0Color.i.g, m_rdp->Texel0Color.i.b);
((this)->*(_Copy[object.MiscState.FBSize - 2]))(curpixel, userdata->Texel0Color.i.r, userdata->Texel0Color.i.g, userdata->Texel0Color.i.b, userdata->Texel0Color.i.a ? 7 : 0, object);
}
}
@ -475,17 +480,19 @@ void Span::DrawCopy(int index, int tilenum, bool flip)
}
}
void Span::DrawFill(int index, int tilenum, bool flip)
void n64_rdp::SpanDrawFill(INT32 scanline, const extent_t &extent, const rdp_poly_state &object, int threadid)
{
int clipx1 = m_rdp->GetScissor()->m_xh;
int clipx2 = m_rdp->GetScissor()->m_xl;
bool flip = object.flip;
int clipx1 = object.Scissor.m_xh;
int clipx2 = object.Scissor.m_xl;
int xinc = flip ? 1 : -1;
int fb_index = m_rdp->MiscState.FBWidth * index;
int fb_index = object.MiscState.FBWidth * scanline;
int xstart = m_lx;
int xend_scissored = m_rx;
int xstart = extent.startx;
int xend_scissored = extent.stopx;
int x = xend_scissored;
@ -495,14 +502,9 @@ void Span::DrawFill(int index, int tilenum, bool flip)
{
if (x >= clipx1 && x < clipx2)
{
UINT32 curpixel = fb_index + x;
m_rdp->Framebuffer.Fill(curpixel);
((this)->*(_Fill[object.MiscState.FBSize - 2]))(fb_index + x, object);
}
x += xinc;
}
}
}
}

View File

@ -2,20 +2,13 @@
#include "includes/n64.h"
#include "video/n64.h"
namespace N64
{
namespace RDP
{
#define RELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
void TexturePipeT::SetMachine(running_machine &machine)
void N64TexturePipeT::SetMachine(running_machine &machine)
{
_n64_state *state = machine.driver_data<_n64_state>();
n64_state *state = machine.driver_data<n64_state>();
m_machine = &machine;
m_rdp = &state->m_rdp;
m_rdp = state->m_rdp;
for(int i = 0; i < 0x10000; i++)
{
@ -28,9 +21,9 @@ void TexturePipeT::SetMachine(running_machine &machine)
}
}
void TexturePipeT::Mask(INT32* S, INT32* T, INT32 num)
void N64TexturePipeT::Mask(INT32* S, INT32* T, INT32 num, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
if (tile[num].mask_s)
{
@ -55,9 +48,9 @@ void TexturePipeT::Mask(INT32* S, INT32* T, INT32 num)
}
}
void TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num)
void N64TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
if (tile[num].mask_s)
{
@ -102,9 +95,9 @@ void TexturePipeT::MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 n
}
}
void TexturePipeT::ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num)
void N64TexturePipeT::ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
*S = SIGN16(*S);
*T = SIGN16(*T);
if (tile[num].shift_s < 11)
@ -130,9 +123,9 @@ void TexturePipeT::ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT
*maxt = ((*T >> 3) >= tile[num].th);
}
void TexturePipeT::ShiftCopy(INT32* S, INT32* T, UINT32 num)
void N64TexturePipeT::ShiftCopy(INT32* S, INT32* T, UINT32 num, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
*S = SIGN16(*S);
*T = SIGN16(*T);
if (tile[num].shift_s < 11)//?-? tcu_tile
@ -155,9 +148,9 @@ void TexturePipeT::ShiftCopy(INT32* S, INT32* T, UINT32 num)
*T = SIGN16(*T);
}
void TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, INT32 maxs, INT32 maxt, INT32 num)
void N64TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, INT32 maxs, INT32 maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
int dos = tile[num].cs || !tile[num].mask_s;
int dot = tile[num].ct || !tile[num].mask_t;
@ -170,7 +163,7 @@ void TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, IN
}
else if (maxs)
{
*S = m_clamp_s_diff[num];
*S = userdata->m_clamp_s_diff[num];
*SFRAC = 0;
}
else
@ -192,7 +185,7 @@ void TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, IN
}
else if (maxt)
{
*T = m_clamp_t_diff[num];
*T = userdata->m_clamp_t_diff[num];
*TFRAC = 0;
}
else
@ -206,9 +199,9 @@ void TexturePipeT::ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, IN
}
}
void TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT32 num)
void N64TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
int dos = tile[num].cs || !tile[num].mask_s;
int dot = tile[num].ct || !tile[num].mask_t;
@ -220,7 +213,7 @@ void TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT
}
else if (maxs)
{
*S = m_clamp_s_diff[num];
*S = userdata->m_clamp_s_diff[num];
}
else
{
@ -240,7 +233,7 @@ void TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT
}
else if (maxt)
{
*T = m_clamp_t_diff[num];
*T = userdata->m_clamp_t_diff[num];
}
else
{
@ -253,18 +246,18 @@ void TexturePipeT::ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT
}
}
void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle)
void N64TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
#define TRELATIVE(x, y) ((((x) >> 3) - (y)) << 3) | (x & 7);
INT32 bilerp = cycle ? m_rdp->OtherModes.bi_lerp1 : m_rdp->OtherModes.bi_lerp0;
int convert = m_rdp->OtherModes.convert_one && cycle;
INT32 bilerp = cycle ? object.OtherModes.bi_lerp1 : object.OtherModes.bi_lerp0;
int convert = object.OtherModes.convert_one && cycle;
Color t0;
Color t1;
Color t2;
Color t3;
if (m_rdp->OtherModes.sample_type)
if (object.OtherModes.sample_type)
{
int sss1, sst1, sss2, sst2;
@ -278,7 +271,7 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
INT32 maxs;
INT32 maxt;
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum);
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum, object);
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
@ -286,12 +279,12 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
INT32 sfrac = sss1 & 0x1f;
INT32 tfrac = sst1 & 0x1f;
ClampCycle(&sss1, &sst1, &sfrac, &tfrac, maxs, maxt, tilenum);
ClampCycle(&sss1, &sst1, &sfrac, &tfrac, maxs, maxt, tilenum, userdata, object);
sss2 = sss1 + 1;
sst2 = sst1 + 1;
MaskCoupled(&sss1, &sss2, &sst1, &sst2, tilenum);
MaskCoupled(&sss1, &sss2, &sst1, &sst2, tilenum, object);
bool upper = ((sfrac + tfrac) >= 0x20);
@ -301,20 +294,20 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
invtf = 0x20 - tfrac;
}
center = (sfrac == 0x10) && (tfrac == 0x10) && m_rdp->OtherModes.mid_texel;
center = (sfrac == 0x10) && (tfrac == 0x10) && object.OtherModes.mid_texel;
invsf <<= 3;
invtf <<= 3;
sfrac <<= 3;
tfrac <<= 3;
t0.c = Fetch(sss1, sst1, tilenum);
t0.c = Fetch(sss1, sst1, tilenum, object, userdata);
if (bilerp)
{
t1.c = Fetch(sss2, sst1, tilenum);
t2.c = Fetch(sss1, sst2, tilenum);
t3.c = Fetch(sss2, sst2, tilenum);
t1.c = Fetch(sss2, sst1, tilenum, object, userdata);
t2.c = Fetch(sss1, sst2, tilenum, object, userdata);
t3.c = Fetch(sss2, sst2, tilenum, object, userdata);
if (!center)
{
if (upper)
@ -336,7 +329,7 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
TEX->i.b &= 0x1ff;
TEX->i.a &= 0x1ff;
}
else//tf.c,24
else
{
TEX->i.r = (t0.i.r + t1.i.r + t2.i.r + t3.i.r) >> 2;
TEX->i.g = (t0.i.g + t1.i.g + t2.i.g + t3.i.g) >> 2;
@ -377,15 +370,15 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
INT32 maxs;
INT32 maxt;
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum);
ShiftCycle(&sss1, &sst1, &maxs, &maxt, tilenum, object);
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
ClampCycleLight(&sss1, &sst1, maxs, maxt, tilenum);
ClampCycleLight(&sss1, &sst1, maxs, maxt, tilenum, userdata, object);
Mask(&sss1, &sst1, tilenum);
Mask(&sss1, &sst1, tilenum, object);
t0.c = Fetch(sss1, sst1, tilenum);
t0.c = Fetch(sss1, sst1, tilenum, object, userdata);
if (bilerp)
{
*TEX = t0;
@ -419,27 +412,27 @@ void TexturePipeT::Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 t
}
}
void TexturePipeT::Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum)
void N64TexturePipeT::Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
INT32 sss1 = SSS;
INT32 sst1 = SST;
ShiftCopy(&sss1, &sst1, tilenum);
ShiftCopy(&sss1, &sst1, tilenum, object);
sss1 = TRELATIVE(sss1, tile[tilenum].sl);
sst1 = TRELATIVE(sst1, tile[tilenum].tl);
sss1 = (SIGN17(sss1) >> 5) & 0x1fff;
sst1 = (SIGN17(sst1) >> 5) & 0x1fff;
Mask(&sss1, &sst1, tilenum);
TEX->c = Fetch(sss1, sst1, tilenum);
Mask(&sss1, &sst1, tilenum, object);
TEX->c = Fetch(sss1, sst1, tilenum, object, userdata);
}
void TexturePipeT::LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc)
void N64TexturePipeT::LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, rdp_span_aux *userdata, const rdp_poly_state& object)
{
INT32 nextsw = (w + dwinc) >> 16;
INT32 nexts = (s + dsinc) >> 16;
INT32 nextt = (t + dtinc) >> 16;
if (m_rdp->OtherModes.persp_tex_en)
if (object.OtherModes.persp_tex_en)
{
m_rdp->TCDiv(nexts, nextt, nextsw, &nexts, &nextt);
}
@ -448,9 +441,9 @@ void TexturePipeT::LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w,
m_rdp->TCDivNoPersp(nexts, nextt, nextsw, &nexts, &nextt);
}
m_start_span = false;
m_precomp_s = nexts;
m_precomp_t = nextt;
userdata->m_start_span = false;
userdata->m_precomp_s = nexts;
userdata->m_precomp_t = nextt;
int tempanded;
if (*sss & 0x40000)
@ -504,13 +497,13 @@ void TexturePipeT::LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w,
}
}
void TexturePipeT::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 N64TexturePipeT::LOD2Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, INT32* t2, rdp_span_aux *userdata, const rdp_poly_state& object)
{
INT32 nextsw = (w + dwinc) >> 16;
INT32 nexts = (s + dsinc) >> 16;
INT32 nextt = (t + dtinc) >> 16;
if (m_rdp->OtherModes.persp_tex_en)
if (object.OtherModes.persp_tex_en)
{
m_rdp->TCDiv(nexts, nextt, nextsw, &nexts, &nextt);
}
@ -519,9 +512,9 @@ void TexturePipeT::LOD2Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w,
m_rdp->TCDivNoPersp(nexts, nextt, nextsw, &nexts, &nextt);
}
m_start_span = false;
m_precomp_s = nexts;
m_precomp_t = nextt;
userdata->m_start_span = false;
userdata->m_precomp_s = nexts;
userdata->m_precomp_t = nextt;
INT32 lodclamp = (((*sst & 0x60000) > 0) | ((nextt & 0x60000) > 0)) || (((*sss & 0x60000) > 0) | ((nexts & 0x60000) > 0));
@ -593,44 +586,44 @@ void TexturePipeT::LOD2Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w,
{
lod = 0x7fff;
}
else if (lod < m_rdp->MiscState.MinLevel)
else if (lod < object.MiscState.MinLevel)
{
lod = m_rdp->MiscState.MinLevel;
lod = object.MiscState.MinLevel;
}
bool magnify = (lod < 32);
INT32 l_tile = m_rdp->GetLog2((lod >> 5) & 0xff);
bool distant = ((lod & 0x6000) || (l_tile >= m_rdp->MiscState.MaxLevel));
bool distant = ((lod & 0x6000) || (l_tile >= object.MiscState.MaxLevel));
m_rdp->LODFraction = ((lod << 3) >> l_tile) & 0xff;
userdata->LODFraction = ((lod << 3) >> l_tile) & 0xff;
if(!m_rdp->OtherModes.sharpen_tex_en && !m_rdp->OtherModes.detail_tex_en)
if(!object.OtherModes.sharpen_tex_en && !object.OtherModes.detail_tex_en)
{
if (distant)
{
m_rdp->LODFraction = 0xff;
userdata->LODFraction = 0xff;
}
else if (magnify)
{
m_rdp->LODFraction = 0;
userdata->LODFraction = 0;
}
}
if(m_rdp->OtherModes.sharpen_tex_en && magnify)
if(object.OtherModes.sharpen_tex_en && magnify)
{
m_rdp->LODFraction = m_rdp->LODFraction | 0x100;
userdata->LODFraction = userdata->LODFraction | 0x100;
}
if (m_rdp->OtherModes.tex_lod_en)
if (object.OtherModes.tex_lod_en)
{
if (distant)
{
l_tile = m_rdp->MiscState.MaxLevel;
l_tile = object.MiscState.MaxLevel;
}
if (!m_rdp->OtherModes.detail_tex_en)
if (!object.OtherModes.detail_tex_en)
{
*t1 = (prim_tile + l_tile) & 7;
if (!(distant || (!m_rdp->OtherModes.sharpen_tex_en && magnify)))
if (!(distant || (!object.OtherModes.sharpen_tex_en && magnify)))
{
*t2 = (*t1 + 1) & 7;
}
@ -662,13 +655,13 @@ void TexturePipeT::LOD2Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w,
}
}
void TexturePipeT::LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1)
void N64TexturePipeT::LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, const rdp_poly_state& object)
{
INT32 nextsw = (w + dwinc) >> 16;
INT32 nexts = (s + dsinc) >> 16;
INT32 nextt = (t + dtinc) >> 16;
if (m_rdp->OtherModes.persp_tex_en)
if (object.OtherModes.persp_tex_en)
{
m_rdp->TCDiv(nexts, nextt, nextsw, &nexts, &nextt);
}
@ -747,22 +740,22 @@ void TexturePipeT::LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, IN
{
lod = 0x7fff;
}
else if (lod < m_rdp->MiscState.MinLevel)
else if (lod < object.MiscState.MinLevel)
{
lod = m_rdp->MiscState.MinLevel;
lod = object.MiscState.MinLevel;
}
bool magnify = (lod < 32);
INT32 l_tile = m_rdp->GetLog2((lod >> 5) & 0xff);
bool distant = (lod & 0x6000) || (l_tile >= m_rdp->MiscState.MaxLevel);
bool distant = (lod & 0x6000) || (l_tile >= object.MiscState.MaxLevel);
if (m_rdp->OtherModes.tex_lod_en)
if (object.OtherModes.tex_lod_en)
{
if (distant)
{
l_tile = m_rdp->MiscState.MaxLevel;
l_tile = object.MiscState.MaxLevel;
}
if (!m_rdp->OtherModes.detail_tex_en)
if (!object.OtherModes.detail_tex_en)
{
*t1 = (prim_tile + l_tile) & 7;
}
@ -781,35 +774,35 @@ void TexturePipeT::LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, IN
}
}
void TexturePipeT::CalculateClampDiffs(UINT32 prim_tile)
void N64TexturePipeT::CalculateClampDiffs(UINT32 prim_tile, rdp_span_aux *userdata, const rdp_poly_state& object)
{
Tile* tile = m_rdp->GetTiles();
if (m_rdp->OtherModes.cycle_type == CYCLE_TYPE_2)
const N64Tile* tile = object.m_tiles;
if (object.OtherModes.cycle_type == CYCLE_TYPE_2)
{
if (m_rdp->OtherModes.tex_lod_en)
if (object.OtherModes.tex_lod_en)
{
int start = 0;
int end = 7;
for (; start <= end; start++)
{
m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
userdata->m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
userdata->m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
}
}
else
{
int start = prim_tile;
int end = (prim_tile + 1) & 7;
m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
m_clamp_s_diff[end] = (tile[end].sh >> 2) - (tile[end].sl >> 2);
m_clamp_t_diff[end] = (tile[end].th >> 2) - (tile[end].tl >> 2);
userdata->m_clamp_s_diff[start] = (tile[start].sh >> 2) - (tile[start].sl >> 2);
userdata->m_clamp_t_diff[start] = (tile[start].th >> 2) - (tile[start].tl >> 2);
userdata->m_clamp_s_diff[end] = (tile[end].sh >> 2) - (tile[end].sl >> 2);
userdata->m_clamp_t_diff[end] = (tile[end].th >> 2) - (tile[end].tl >> 2);
}
}
else//1-cycle or copy
{
m_clamp_s_diff[prim_tile] = (tile[prim_tile].sh >> 2) - (tile[prim_tile].sl >> 2);
m_clamp_t_diff[prim_tile] = (tile[prim_tile].th >> 2) - (tile[prim_tile].tl >> 2);
userdata->m_clamp_s_diff[prim_tile] = (tile[prim_tile].sh >> 2) - (tile[prim_tile].sl >> 2);
userdata->m_clamp_t_diff[prim_tile] = (tile[prim_tile].th >> 2) - (tile[prim_tile].tl >> 2);
}
}
@ -818,14 +811,14 @@ void TexturePipeT::CalculateClampDiffs(UINT32 prim_tile)
static INT32 sTexAddrSwap16[2] = { WORD_ADDR_XOR, WORD_XOR_DWORD_SWAP };
static INT32 sTexAddrSwap8[2] = { BYTE_ADDR_XOR, BYTE_XOR_DWORD_SWAP };
UINT32 TexturePipeT::_FetchRGBA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x7ff;
UINT16 c = m_rdp->GetTMEM16()[taddr];
c = m_rdp->GetTLUT()[(c >> 8) << 2];
UINT16 c = ((UINT16*)userdata->m_tmem)[taddr];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 8) << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -839,14 +832,14 @@ UINT32 TexturePipeT::_FetchRGBA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tp
#endif
}
UINT32 TexturePipeT::_FetchRGBA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x7ff;
UINT16 c = m_rdp->GetTMEM16()[taddr];
c = m_rdp->GetTLUT()[(c >> 8) << 2];
UINT16 c = ((UINT16*)userdata->m_tmem)[taddr];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 8) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -854,16 +847,16 @@ UINT32 TexturePipeT::_FetchRGBA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tp
return color.c;
}
UINT32 TexturePipeT::_FetchRGBA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x7ff;
#if USE_64K_LUT
return Expand16To32Table[m_rdp->GetTMEM16()[taddr]];
return Expand16To32Table[((UINT16*)userdata->m_tmem)[taddr]];
#else
UINT16 c = m_rdp->GetTMEM16()[taddr];
UINT16 c = ((UINT16*)userdata->m_tmem)[taddr];
Color color;
color.i.r = GET_HI_RGBA16_TMEM(c);
color.i.g = GET_MED_RGBA16_TMEM(c);
@ -873,15 +866,15 @@ UINT32 TexturePipeT::_FetchRGBA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal
#endif
}
UINT32 TexturePipeT::_FetchRGBA_32_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_32_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT32 *tc = m_rdp->GetTMEM32();
UINT32 *tc = ((UINT32*)userdata->m_tmem);
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x3ff;
UINT32 c = tc[taddr];
c = m_rdp->GetTLUT()[(c >> 24) << 2];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 24) << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -895,15 +888,15 @@ UINT32 TexturePipeT::_FetchRGBA_32_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tp
#endif
}
UINT32 TexturePipeT::_FetchRGBA_32_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_32_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT32 *tc = m_rdp->GetTMEM32();
UINT32 *tc = ((UINT32*)userdata->m_tmem);
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x3ff;
UINT32 c = tc[taddr];
c = m_rdp->GetTLUT()[(c >> 24) << 2];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 24) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -912,29 +905,29 @@ UINT32 TexturePipeT::_FetchRGBA_32_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tp
return color.c;
}
UINT32 TexturePipeT::_FetchRGBA_32_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchRGBA_32_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x3ff;
UINT32 c = m_rdp->GetTMEM16()[taddr];
UINT32 c = ((UINT16*)userdata->m_tmem)[taddr];
Color color;
color.i.r = (c >> 8) & 0xff;
color.i.g = c & 0xff;
c = m_rdp->GetTMEM16()[taddr | 0x400];
c = ((UINT16*)userdata->m_tmem)[taddr | 0x400];
color.i.b = (c >> 8) & 0xff;
color.i.a = c & 0xff;
return color.c;
}
UINT32 TexturePipeT::_FetchNOP(INT32 s, INT32 t, INT32 tbase, INT32 tpal) { return 0; }
UINT32 N64TexturePipeT::_FetchNOP(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata) { return 0; }
UINT32 TexturePipeT::_FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT16 *tc = m_rdp->GetTMEM16();
UINT16 *tc = ((UINT16*)userdata->m_tmem);
int taddr = (tbase << 3) + s;
int taddrlow = taddr >> 1;
@ -947,7 +940,7 @@ UINT32 TexturePipeT::_FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT16 c = tc[taddrlow];
INT32 y = m_rdp->GetTMEM()[taddr | 0x800];
INT32 y = userdata->m_tmem[taddr | 0x800];
INT32 u = c >> 8;
INT32 v = c & 0xff;
@ -964,16 +957,16 @@ UINT32 TexturePipeT::_FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchCI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
taddr &= 0x7ff;
UINT8 p = (s & 1) ? (tc[taddr] & 0xf) : (tc[taddr] >> 4);
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | p) << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -987,16 +980,16 @@ UINT32 TexturePipeT::_FetchCI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchCI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
taddr &= 0x7ff;
UINT8 p = (s & 1) ? (tc[taddr] & 0xf) : (tc[taddr] >> 4);
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | p) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -1005,9 +998,9 @@ UINT32 TexturePipeT::_FetchCI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchCI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1021,15 +1014,15 @@ UINT32 TexturePipeT::_FetchCI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchCI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = tc[taddr];
UINT16 c = m_rdp->GetTLUT()[p << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[p << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -1043,15 +1036,15 @@ UINT32 TexturePipeT::_FetchCI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchCI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = tc[taddr];
UINT16 c = m_rdp->GetTLUT()[p << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[p << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -1060,9 +1053,9 @@ UINT32 TexturePipeT::_FetchCI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchCI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchCI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1075,15 +1068,15 @@ UINT32 TexturePipeT::_FetchCI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchIA_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = ((s) & 1) ? (tc[taddr] & 0xf) : (tc[taddr] >> 4);
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | p) << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -1097,15 +1090,15 @@ UINT32 TexturePipeT::_FetchIA_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchIA_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = ((s) & 1) ? (tc[taddr] & 0xf) : (tc[taddr] >> 4);
UINT16 c = m_rdp->GetTLUT()[((tpal << 4) | p) << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | p) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -1114,9 +1107,9 @@ UINT32 TexturePipeT::_FetchIA_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1134,15 +1127,15 @@ UINT32 TexturePipeT::_FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchIA_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = tc[taddr];
UINT16 c = m_rdp->GetTLUT()[p << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[p << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -1156,15 +1149,15 @@ UINT32 TexturePipeT::_FetchIA_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchIA_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 p = tc[taddr];
UINT16 c = m_rdp->GetTLUT()[p << 2];
UINT16 c = ((UINT16*)(userdata->m_tmem + 0x800))[p << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -1173,9 +1166,9 @@ UINT32 TexturePipeT::_FetchIA_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchIA_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1193,15 +1186,15 @@ UINT32 TexturePipeT::_FetchIA_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchIA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT16 *tc = m_rdp->GetTMEM16();
UINT16 *tc = ((UINT16*)userdata->m_tmem);
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x3ff;
UINT16 c = tc[taddr];
c = m_rdp->GetTLUT()[(c >> 8) << 2];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 8) << 2];
#if USE_64K_LUT
return Expand16To32Table[c];
@ -1215,15 +1208,15 @@ UINT32 TexturePipeT::_FetchIA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal
#endif
}
UINT32 TexturePipeT::_FetchIA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT16 *tc = m_rdp->GetTMEM16();
UINT16 *tc = ((UINT16*)userdata->m_tmem);
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x3ff;
UINT16 c = tc[taddr];
c = m_rdp->GetTLUT()[(c >> 8) << 2];
c = ((UINT16*)(userdata->m_tmem + 0x800))[(c >> 8) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (c >> 8) & 0xff;
@ -1232,9 +1225,9 @@ UINT32 TexturePipeT::_FetchIA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal
return color.c;
}
UINT32 TexturePipeT::_FetchIA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchIA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT16 *tc = m_rdp->GetTMEM16();
UINT16 *tc = ((UINT16*)userdata->m_tmem);
int taddr = (tbase << 2) + s;
taddr ^= sTexAddrSwap16[t & 1];
taddr &= 0x7ff;
@ -1251,16 +1244,16 @@ UINT32 TexturePipeT::_FetchIA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 byteval = tc[taddr];
UINT8 c = ((s & 1)) ? (byteval & 0xf) : ((byteval >> 4) & 0xf);
UINT16 k = m_rdp->GetTLUT()[((tpal << 4) | c) << 2];
UINT16 k = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | c) << 2];
#if USE_64K_LUT
return Expand16To32Table[k];
@ -1274,16 +1267,16 @@ UINT32 TexturePipeT::_FetchI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 byteval = tc[taddr];
UINT8 c = ((s & 1)) ? (byteval & 0xf) : ((byteval >> 4) & 0xf);
UINT16 k = m_rdp->GetTLUT()[((tpal << 4) | c) << 2];
UINT16 k = ((UINT16*)(userdata->m_tmem + 0x800))[((tpal << 4) | c) << 2];
Color color;
color.i.r = color.i.g = color.i.b = (k >> 8) & 0xff;
@ -1292,9 +1285,9 @@ UINT32 TexturePipeT::_FetchI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = ((tbase << 4) + s) >> 1;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1312,15 +1305,15 @@ UINT32 TexturePipeT::_FetchI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 c = tc[taddr];
UINT16 k = m_rdp->GetTLUT()[c << 2];
UINT16 k = ((UINT16*)(userdata->m_tmem + 0x800))[c << 2];
#if USE_64K_LUT
return Expand16To32Table[k];
@ -1334,15 +1327,15 @@ UINT32 TexturePipeT::_FetchI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
#endif
}
UINT32 TexturePipeT::_FetchI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0x7ff;
UINT8 c = tc[taddr];
UINT16 k = m_rdp->GetTLUT()[c << 2];
UINT16 k = ((UINT16*)(userdata->m_tmem + 0x800))[c << 2];
Color color;
color.i.r = color.i.g = color.i.b = (k >> 8) & 0xff;
@ -1351,9 +1344,9 @@ UINT32 TexturePipeT::_FetchI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::_FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
UINT32 N64TexturePipeT::_FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata)
{
UINT8 *tc = m_rdp->GetTMEM();
UINT8 *tc = userdata->m_tmem;
int taddr = (tbase << 3) + s;
taddr ^= sTexAddrSwap8[t & 1];
taddr &= 0xfff;
@ -1369,9 +1362,9 @@ UINT32 TexturePipeT::_FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal)
return color.c;
}
UINT32 TexturePipeT::Fetch(INT32 s, INT32 t, INT32 tilenum)
UINT32 N64TexturePipeT::Fetch(INT32 s, INT32 t, INT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata)
{
Tile* tile = m_rdp->GetTiles();
const N64Tile* tile = object.m_tiles;
UINT32 tformat = tile[tilenum].format;
UINT32 tsize = tile[tilenum].size;
@ -1379,11 +1372,7 @@ UINT32 TexturePipeT::Fetch(INT32 s, INT32 t, INT32 tilenum)
tbase += tile[tilenum].tmem;
UINT32 tpal = tile[tilenum].palette;
UINT32 index = (tformat << 4) | (tsize << 2) | (m_rdp->OtherModes.en_tlut << 1) | m_rdp->OtherModes.tlut_type;
UINT32 index = (tformat << 4) | (tsize << 2) | (object.OtherModes.en_tlut << 1) | object.OtherModes.tlut_type;
return ((this)->*(TexelFetch[index]))(s, t, tbase, tpal);
return ((this)->*(TexelFetch[index]))(s, t, tbase, tpal, userdata);
}
} // namespace RDP
} // namespace N64

View File

@ -3,23 +3,18 @@
#include "emu.h"
namespace N64
{
namespace RDP
{
class OtherModes;
class MiscState;
class Processor;
class OtherModesT;
class MiscStateT;
class Color;
class rdp_span_aux;
struct rdp_poly_state;
class TexturePipeT
class N64TexturePipeT
{
public:
typedef UINT32 (N64::RDP::TexturePipeT::*TexelFetcher) (INT32 s, INT32 t, INT32 tbase, INT32 tpal);
typedef UINT32 (N64TexturePipeT::*TexelFetcher) (INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
TexturePipeT()
N64TexturePipeT()
{
m_maskbits_table[0] = 0x3ff;
for(int i = 1; i < 16; i++)
@ -27,135 +22,122 @@ class TexturePipeT
m_maskbits_table[i] = ((UINT16)(0xffff) >> (16 - i)) & 0x3ff;
}
m_start_span = false;
m_precomp_s = 0;
m_precomp_t = 0;
for (int idx = 0; idx < 80; idx++)
{
TexelFetch[idx] = &N64::RDP::TexturePipeT::_FetchNOP;
TexelFetch[idx] = &N64TexturePipeT::_FetchNOP;
}
TexelFetch[ 8] = &N64::RDP::TexturePipeT::_FetchRGBA_16_RAW;
TexelFetch[ 9] = &N64::RDP::TexturePipeT::_FetchRGBA_16_RAW;
TexelFetch[10] = &N64::RDP::TexturePipeT::_FetchRGBA_16_TLUT0;
TexelFetch[11] = &N64::RDP::TexturePipeT::_FetchRGBA_16_TLUT1;
TexelFetch[12] = &N64::RDP::TexturePipeT::_FetchRGBA_32_RAW;
TexelFetch[13] = &N64::RDP::TexturePipeT::_FetchRGBA_32_RAW;
TexelFetch[14] = &N64::RDP::TexturePipeT::_FetchRGBA_32_TLUT0;
TexelFetch[15] = &N64::RDP::TexturePipeT::_FetchRGBA_32_TLUT1;
TexelFetch[ 8] = &N64TexturePipeT::_FetchRGBA_16_RAW;
TexelFetch[ 9] = &N64TexturePipeT::_FetchRGBA_16_RAW;
TexelFetch[10] = &N64TexturePipeT::_FetchRGBA_16_TLUT0;
TexelFetch[11] = &N64TexturePipeT::_FetchRGBA_16_TLUT1;
TexelFetch[12] = &N64TexturePipeT::_FetchRGBA_32_RAW;
TexelFetch[13] = &N64TexturePipeT::_FetchRGBA_32_RAW;
TexelFetch[14] = &N64TexturePipeT::_FetchRGBA_32_TLUT0;
TexelFetch[15] = &N64TexturePipeT::_FetchRGBA_32_TLUT1;
TexelFetch[24] = &N64::RDP::TexturePipeT::_FetchYUV;
TexelFetch[25] = &N64::RDP::TexturePipeT::_FetchYUV;
TexelFetch[26] = &N64::RDP::TexturePipeT::_FetchYUV;
TexelFetch[27] = &N64::RDP::TexturePipeT::_FetchYUV;
TexelFetch[24] = &N64TexturePipeT::_FetchYUV;
TexelFetch[25] = &N64TexturePipeT::_FetchYUV;
TexelFetch[26] = &N64TexturePipeT::_FetchYUV;
TexelFetch[27] = &N64TexturePipeT::_FetchYUV;
TexelFetch[32] = &N64::RDP::TexturePipeT::_FetchCI_4_RAW;
TexelFetch[33] = &N64::RDP::TexturePipeT::_FetchCI_4_RAW;
TexelFetch[34] = &N64::RDP::TexturePipeT::_FetchCI_4_TLUT0;
TexelFetch[35] = &N64::RDP::TexturePipeT::_FetchCI_4_TLUT1;
TexelFetch[36] = &N64::RDP::TexturePipeT::_FetchCI_8_RAW;
TexelFetch[37] = &N64::RDP::TexturePipeT::_FetchCI_8_RAW;
TexelFetch[38] = &N64::RDP::TexturePipeT::_FetchCI_8_TLUT0;
TexelFetch[39] = &N64::RDP::TexturePipeT::_FetchCI_8_TLUT1;
TexelFetch[32] = &N64TexturePipeT::_FetchCI_4_RAW;
TexelFetch[33] = &N64TexturePipeT::_FetchCI_4_RAW;
TexelFetch[34] = &N64TexturePipeT::_FetchCI_4_TLUT0;
TexelFetch[35] = &N64TexturePipeT::_FetchCI_4_TLUT1;
TexelFetch[36] = &N64TexturePipeT::_FetchCI_8_RAW;
TexelFetch[37] = &N64TexturePipeT::_FetchCI_8_RAW;
TexelFetch[38] = &N64TexturePipeT::_FetchCI_8_TLUT0;
TexelFetch[39] = &N64TexturePipeT::_FetchCI_8_TLUT1;
TexelFetch[48] = &N64::RDP::TexturePipeT::_FetchIA_4_RAW;
TexelFetch[49] = &N64::RDP::TexturePipeT::_FetchIA_4_RAW;
TexelFetch[50] = &N64::RDP::TexturePipeT::_FetchIA_4_TLUT0;
TexelFetch[51] = &N64::RDP::TexturePipeT::_FetchIA_4_TLUT1;
TexelFetch[52] = &N64::RDP::TexturePipeT::_FetchIA_8_RAW;
TexelFetch[53] = &N64::RDP::TexturePipeT::_FetchIA_8_RAW;
TexelFetch[54] = &N64::RDP::TexturePipeT::_FetchIA_8_TLUT0;
TexelFetch[55] = &N64::RDP::TexturePipeT::_FetchIA_8_TLUT1;
TexelFetch[56] = &N64::RDP::TexturePipeT::_FetchIA_16_RAW;
TexelFetch[57] = &N64::RDP::TexturePipeT::_FetchIA_16_RAW;
TexelFetch[58] = &N64::RDP::TexturePipeT::_FetchIA_16_TLUT0;
TexelFetch[59] = &N64::RDP::TexturePipeT::_FetchIA_16_TLUT1;
TexelFetch[48] = &N64TexturePipeT::_FetchIA_4_RAW;
TexelFetch[49] = &N64TexturePipeT::_FetchIA_4_RAW;
TexelFetch[50] = &N64TexturePipeT::_FetchIA_4_TLUT0;
TexelFetch[51] = &N64TexturePipeT::_FetchIA_4_TLUT1;
TexelFetch[52] = &N64TexturePipeT::_FetchIA_8_RAW;
TexelFetch[53] = &N64TexturePipeT::_FetchIA_8_RAW;
TexelFetch[54] = &N64TexturePipeT::_FetchIA_8_TLUT0;
TexelFetch[55] = &N64TexturePipeT::_FetchIA_8_TLUT1;
TexelFetch[56] = &N64TexturePipeT::_FetchIA_16_RAW;
TexelFetch[57] = &N64TexturePipeT::_FetchIA_16_RAW;
TexelFetch[58] = &N64TexturePipeT::_FetchIA_16_TLUT0;
TexelFetch[59] = &N64TexturePipeT::_FetchIA_16_TLUT1;
TexelFetch[64] = &N64::RDP::TexturePipeT::_FetchI_4_RAW;
TexelFetch[65] = &N64::RDP::TexturePipeT::_FetchI_4_RAW;
TexelFetch[66] = &N64::RDP::TexturePipeT::_FetchI_4_TLUT0;
TexelFetch[67] = &N64::RDP::TexturePipeT::_FetchI_4_TLUT1;
TexelFetch[68] = &N64::RDP::TexturePipeT::_FetchI_8_RAW;
TexelFetch[69] = &N64::RDP::TexturePipeT::_FetchI_8_RAW;
TexelFetch[70] = &N64::RDP::TexturePipeT::_FetchI_8_TLUT0;
TexelFetch[71] = &N64::RDP::TexturePipeT::_FetchI_8_TLUT1;
TexelFetch[64] = &N64TexturePipeT::_FetchI_4_RAW;
TexelFetch[65] = &N64TexturePipeT::_FetchI_4_RAW;
TexelFetch[66] = &N64TexturePipeT::_FetchI_4_TLUT0;
TexelFetch[67] = &N64TexturePipeT::_FetchI_4_TLUT1;
TexelFetch[68] = &N64TexturePipeT::_FetchI_8_RAW;
TexelFetch[69] = &N64TexturePipeT::_FetchI_8_RAW;
TexelFetch[70] = &N64TexturePipeT::_FetchI_8_TLUT0;
TexelFetch[71] = &N64TexturePipeT::_FetchI_8_TLUT1;
}
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 Cycle(Color* TEX, Color* prev, INT32 SSS, INT32 SST, UINT32 tilenum, UINT32 cycle, rdp_span_aux *userdata, const rdp_poly_state& object);
void Copy(Color* TEX, INT32 SSS, INT32 SST, UINT32 tilenum, const rdp_poly_state& object, rdp_span_aux *userdata);
UINT32 Fetch(INT32 SSS, INT32 SST, INT32 tile, const rdp_poly_state& object, rdp_span_aux *userdata);
void CalculateClampDiffs(UINT32 prim_tile, rdp_span_aux *userdata, const rdp_poly_state& object);
void LOD1Cycle(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, rdp_span_aux *userdata, const rdp_poly_state& object);
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, rdp_span_aux *userdata, const rdp_poly_state& object);
void LOD2CycleLimited(INT32* sss, INT32* sst, INT32 s, INT32 t, INT32 w, INT32 dsinc, INT32 dtinc, INT32 dwinc, INT32 prim_tile, INT32* t1, const rdp_poly_state& object);
void SetMachine(running_machine& machine);
bool m_start_span;
INT32 m_precomp_s;
INT32 m_precomp_t;
private:
UINT32 Expand16To32Table[0x10000];
void Mask(INT32* S, INT32* T, INT32 num);
void MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num);
void Mask(INT32* S, INT32* T, INT32 num, const rdp_poly_state& object);
void MaskCoupled(INT32* S, INT32* S1, INT32* T, INT32* T1, INT32 num, const rdp_poly_state& object);
void ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num);
void ShiftCopy(INT32* S, INT32* T, UINT32 num);
void ShiftCycle(INT32* S, INT32* T, INT32* maxs, INT32* maxt, UINT32 num, const rdp_poly_state& object);
void ShiftCopy(INT32* S, INT32* T, UINT32 num, const rdp_poly_state& object);
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);
void ClampCycle(INT32* S, INT32* T, INT32* SFRAC, INT32* TFRAC, INT32 maxs, INT32 maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object);
void ClampCycleLight(INT32* S, INT32* T, bool maxs, bool maxt, INT32 num, rdp_span_aux *userdata, const rdp_poly_state& object);
UINT32 _FetchNOP(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchNOP(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_32_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_32_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_32_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchRGBA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_32_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_32_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchRGBA_32_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchYUV(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchCI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchCI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchIA_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_16_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_16_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchIA_16_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal);
UINT32 _FetchI_4_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_4_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_4_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_8_TLUT0(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_8_TLUT1(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
UINT32 _FetchI_8_RAW(INT32 s, INT32 t, INT32 tbase, INT32 tpal, rdp_span_aux *userdata);
TexelFetcher TexelFetch[16*5];
running_machine* m_machine;
OtherModes* m_other_modes;
MiscState* m_misc_state;
Processor* m_rdp;
n64_rdp* m_rdp;
INT32 m_maskbits_table[16];
INT32 m_clamp_t_diff[8];
INT32 m_clamp_s_diff[8];
};
} // namespace RDP
} // namespace N64
#endif // _VIDEO_RDPTEXPIPE_H_

View File

@ -1,41 +0,0 @@
#ifndef _VIDEO_RDPTRI_H_
#define _VIDEO_RDPTRI_H_
#include "emu.h"
namespace N64
{
namespace RDP
{
class MiscState;
class Processor;
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, bool rect, bool flip);
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;
Processor* m_rdp;
bool m_shade;
bool m_texture;
bool m_zbuffer;
bool m_rect;
};
} // namespace RDP
} // namespace N64
#endif // _VIDEO_RDPTRI_H_