Previous 199869 Revisions Next

r25463 Monday 30th September, 2013 at 05:09:03 UTC by Ryan Holtz
-N64 RDP and RSP improvements [MooglyGuy, Marathon Man]
 * Fixed an RSP DMA edge case when transfer count is greater than 1.
 * Refactored the RDP blender implementation to use function pointers rather
   than deep if/else structures in order to reduce branch prediction penalties
   in the inner software rasterizer loop.
 * Reduced the likelihood that bad triangle commands due to an RSP crash will
   crash MESS.
[src/mame/machine]n64.c
[src/mame/video]n64.c n64.h rdpbhelp.h* rdpblend.c rdpblend.h rdpspn16.c rdptpipe.c rdptpipe.h

trunk/src/mame/machine/n64.c
r25462r25463
566566
567567   UINT32 *sp_mem[2] = { rsp_dmem, rsp_imem };
568568
569   int sp_mem_page = (sp_mem_addr >> 12) & 1;
569570   if(direction == 0)// RDRAM -> I/DMEM
570571   {
571572      for(int c = 0; c <= sp_dma_count; c++)
572573      {
573574         UINT32 src = (sp_dram_addr & 0x007fffff) >> 2;
574         UINT32 dst = (sp_mem_addr & 0x1fff) >> 2;
575         UINT32 dst = (sp_mem_addr & 0xfff) >> 2;
575576
576577         for(int i = 0; i < length / 4; i++)
577578         {
578            sp_mem[(dst + i) >> 10][(dst + i) & 0x3ff] = rdram[src + i];
579            sp_mem[sp_mem_page][(dst + i) & 0x3ff] = rdram[src + i];
579580         }
580581
581582         sp_mem_addr += length;
r25462r25463
588589   {
589590      for(int c = 0; c <= sp_dma_count; c++)
590591      {
591         UINT32 src = (sp_mem_addr & 0x1fff) >> 2;
592         UINT32 src = (sp_mem_addr & 0xfff) >> 2;
592593         UINT32 dst = (sp_dram_addr & 0x007fffff) >> 2;
593594
594595         for(int i = 0; i < length / 4; i++)
595596         {
596            rdram[dst + i] = sp_mem[(src + i) >> 10][(src + i) & 0x3ff];
597            rdram[dst + i] = sp_mem[sp_mem_page][(src + i) & 0x3ff];
597598         }
598599
599600         sp_mem_addr += length;
trunk/src/mame/video/rdptpipe.c
r25462r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Texture Fetch Unit (TF)
5    -------------------
6
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
10
11
12******************************************************************************/
13
114#include "emu.h"
215#include "includes/n64.h"
316#include "video/n64.h"
trunk/src/mame/video/rdptpipe.h
r25462r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Texture Fetch Unit (TF)
5    -------------------
6
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
10
11
12******************************************************************************/
13
114#ifndef _VIDEO_RDPTEXPIPE_H_
215#define _VIDEO_RDPTEXPIPE_H_
316
trunk/src/mame/video/n64.c
r25462r25463
44    SGI/Nintendo Reality Display Processor
55    -------------------
66
7    Initial revision by Ville Linde
8    Many improvements by Harmony, angrylion, Ziggy, Gonetz and Orkin
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
910
10    Class re-write by Harmony
1111
12
1312*******************************************************************************
1413
1514STATUS:
1615
17Much behavior needs verification against real hardware.  Many literal edge
18cases must be verified on real hardware as well.
16Much behavior needs verification against real hardware.  Many edge cases must
17be verified on real hardware as well.
1918
2019TODO:
2120
r25462r25463
3635   if(MiscState.FBSize == 0) return false;
3736
3837   int fbcount = ((MiscState.FBWidth * Scissor.m_yl) << (MiscState.FBSize - 1)) * 3;
39   int zbcount = MiscState.FBWidth * Scissor.m_yl * 2;
4038   int fbaddr = MiscState.FBAddress & 0x007fffff;
41   int zbaddr = MiscState.ZBAddress & 0x007fffff;
4239   if ((addr >= fbaddr) && (addr < (fbaddr + fbcount)))
4340   {
4441      return false;
4542   }
43
44   int zbcount = MiscState.FBWidth * Scissor.m_yl * 2;
45   int zbaddr = MiscState.ZBAddress & 0x007fffff;
4646   if ((addr >= zbaddr) && (addr < (zbaddr + zbcount)))
4747   {
4848      return false;
r25462r25463
899899   *offy = cvarray[index].yoff;
900900}
901901
902void n64_rdp::ZStore(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc)
902void n64_rdp::ZStore(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc)
903903{
904904   UINT16 zval = z_com_table[z & 0x3ffff]|(enc >> 2);
905905   if(zcurpixel <= MEM16_LIMIT)
r25462r25463
20322032   int dzdy_dz = (dzdy >> 16) & 0xffff;
20332033   int dzdx_dz = (dzdx >> 16) & 0xffff;
20342034
2035   extent_t Spans[1024];
2035   extent_t Spans[2048];
20362036
20372037   SpanBase.m_span_drdy = drdy;
20382038   SpanBase.m_span_dgdy = dgdy;
r25462r25463
21212121
21222122   bool new_object = true;
21232123   rdp_poly_state *object = NULL;
2124   bool valid = false;
21242125
21252126   if(flip)
21262127   {
r25462r25463
21352136         int xstart = xleft >> 16; // 319
21362137         int xend = xright >> 16; // 0
21372138         int j = k >> 2;
2139         int spanidx = (k - ycur) >> 2;
21382140         int spix = k & 3;
21392141         valid_y = !(k < yh || k >= yl);
21402142
2141         if (k >= 0 && k < 0x1000)
2143         if (spanidx >= 0 && spanidx < 2048)
21422144         {
21432145            majorxint[spix] = xend; // 0
21442146            minorxint[spix] = xstart; // 319
r25462r25463
21662168                  new_object = false;
21672169               }
21682170
2169               Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
2171               Spans[spanidx].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
21702172               AuxBufPtr += sizeof(rdp_span_aux);
21712173
21722174               if(AuxBufPtr >= EXTENT_AUX_COUNT)
r25462r25463
21742176                  fatalerror("n64_rdp::DrawTriangle: span aux buffer overflow\n");
21752177               }
21762178
2177               rdp_span_aux *userdata = (rdp_span_aux*)Spans[j - (ycur >> 2)].userdata;
2179               rdp_span_aux *userdata = (rdp_span_aux*)Spans[spanidx].userdata;
2180               valid = true;
21782181
21792182               userdata->m_tmem = object->m_tmem;
21802183
r25462r25463
22522255
22532256            if (spix == 3)
22542257            {
2255               Spans[j - (ycur >> 2)].startx = maxxmx;
2256               Spans[j - (ycur >> 2)].stopx = minxhx;
2258               Spans[spanidx].startx = maxxmx;
2259               Spans[spanidx].stopx = minxhx;
22572260               compute_cvg_flip(Spans, majorx, minorx, majorxint, minorxint, j, yh, yl, ycur >> 2);
22582261            }
22592262
22602263            if (spix == ldflag)
22612264            {
2262               ((rdp_span_aux*)Spans[j - (ycur >> 2)].userdata)->m_unscissored_rx = xend;
2265               ((rdp_span_aux*)Spans[spanidx].userdata)->m_unscissored_rx = xend;
22632266               xfrac = ((xright >> 8) & 0xff);
2264               Spans[j - (ycur >> 2)].param[SPAN_R].start = ((r >> 9) << 9) + drdiff - (xfrac * drdxh);
2265               Spans[j - (ycur >> 2)].param[SPAN_G].start = ((g >> 9) << 9) + dgdiff - (xfrac * dgdxh);
2266               Spans[j - (ycur >> 2)].param[SPAN_B].start = ((b >> 9) << 9) + dbdiff - (xfrac * dbdxh);
2267               Spans[j - (ycur >> 2)].param[SPAN_A].start = ((a >> 9) << 9) + dadiff - (xfrac * dadxh);
2268               Spans[j - (ycur >> 2)].param[SPAN_S].start = (((s >> 9) << 9)  + dsdiff - (xfrac * dsdxh)) & ~0x1f;
2269               Spans[j - (ycur >> 2)].param[SPAN_T].start = (((t >> 9) << 9)  + dtdiff - (xfrac * dtdxh)) & ~0x1f;
2270               Spans[j - (ycur >> 2)].param[SPAN_W].start = (((w >> 9) << 9)  + dwdiff - (xfrac * dwdxh)) & ~0x1f;
2271               Spans[j - (ycur >> 2)].param[SPAN_Z].start = ((z >> 9) << 9)  + dzdiff - (xfrac * dzdxh);
2267               Spans[spanidx].param[SPAN_R].start = ((r >> 9) << 9) + drdiff - (xfrac * drdxh);
2268               Spans[spanidx].param[SPAN_G].start = ((g >> 9) << 9) + dgdiff - (xfrac * dgdxh);
2269               Spans[spanidx].param[SPAN_B].start = ((b >> 9) << 9) + dbdiff - (xfrac * dbdxh);
2270               Spans[spanidx].param[SPAN_A].start = ((a >> 9) << 9) + dadiff - (xfrac * dadxh);
2271               Spans[spanidx].param[SPAN_S].start = (((s >> 9) << 9)  + dsdiff - (xfrac * dsdxh)) & ~0x1f;
2272               Spans[spanidx].param[SPAN_T].start = (((t >> 9) << 9)  + dtdiff - (xfrac * dtdxh)) & ~0x1f;
2273               Spans[spanidx].param[SPAN_W].start = (((w >> 9) << 9)  + dwdiff - (xfrac * dwdxh)) & ~0x1f;
2274               Spans[spanidx].param[SPAN_Z].start = ((z >> 9) << 9)  + dzdiff - (xfrac * dzdxh);
22722275            }
22732276         }
22742277
r25462r25463
23012304         int xstart = xleft >> 16;
23022305         int xend = xright >> 16;
23032306         int j = k >> 2;
2307         int spanidx = j - (ycur >> 2);
23042308         int spix = k & 3;
23052309         valid_y = !(k < yh || k >= yl);
23062310
r25462r25463
23322336                  new_object = false;
23332337               }
23342338
2335               Spans[j - (ycur >> 2)].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
2339               Spans[spanidx].userdata = (void*)((UINT8*)AuxBuf + AuxBufPtr);
2340               valid = true;
23362341               AuxBufPtr += sizeof(rdp_span_aux);
23372342
23382343               if(AuxBufPtr >= EXTENT_AUX_COUNT)
r25462r25463
23402345                  fatalerror("n64_rdp::DrawTriangle: span aux buffer overflow\n");
23412346               }
23422347
2343               rdp_span_aux *userdata = (rdp_span_aux*)Spans[j - (ycur >> 2)].userdata;
2348               rdp_span_aux *userdata = (rdp_span_aux*)Spans[spanidx].userdata;
23442349               userdata->m_tmem = object->m_tmem;
23452350
23462351               userdata->BlendColor = BlendColor;
r25462r25463
24172422
24182423            if (spix == 3)
24192424            {
2420               Spans[j - (ycur >> 2)].startx = minxmx;
2421               Spans[j - (ycur >> 2)].stopx = maxxhx;
2425               Spans[spanidx].startx = minxmx;
2426               Spans[spanidx].stopx = maxxhx;
24222427               compute_cvg_noflip(Spans, majorx, minorx, majorxint, minorxint, j, yh, yl, ycur >> 2);
24232428            }
24242429
24252430            if (spix == ldflag)
24262431            {
2427               ((rdp_span_aux*)Spans[j - (ycur >> 2)].userdata)->m_unscissored_rx = xend;
2432               ((rdp_span_aux*)Spans[spanidx].userdata)->m_unscissored_rx = xend;
24282433               xfrac = ((xright >> 8) & 0xff);
2429               Spans[j - (ycur >> 2)].param[SPAN_R].start = ((r >> 9) << 9) + drdiff - (xfrac * drdxh);
2430               Spans[j - (ycur >> 2)].param[SPAN_G].start = ((g >> 9) << 9) + dgdiff - (xfrac * dgdxh);
2431               Spans[j - (ycur >> 2)].param[SPAN_B].start = ((b >> 9) << 9) + dbdiff - (xfrac * dbdxh);
2432               Spans[j - (ycur >> 2)].param[SPAN_A].start = ((a >> 9) << 9) + dadiff - (xfrac * dadxh);
2433               Spans[j - (ycur >> 2)].param[SPAN_S].start = (((s >> 9) << 9)  + dsdiff - (xfrac * dsdxh)) & ~0x1f;
2434               Spans[j - (ycur >> 2)].param[SPAN_T].start = (((t >> 9) << 9)  + dtdiff - (xfrac * dtdxh)) & ~0x1f;
2435               Spans[j - (ycur >> 2)].param[SPAN_W].start = (((w >> 9) << 9)  + dwdiff - (xfrac * dwdxh)) & ~0x1f;
2436               Spans[j - (ycur >> 2)].param[SPAN_Z].start = ((z >> 9) << 9)  + dzdiff - (xfrac * dzdxh);
2434               Spans[spanidx].param[SPAN_R].start = ((r >> 9) << 9) + drdiff - (xfrac * drdxh);
2435               Spans[spanidx].param[SPAN_G].start = ((g >> 9) << 9) + dgdiff - (xfrac * dgdxh);
2436               Spans[spanidx].param[SPAN_B].start = ((b >> 9) << 9) + dbdiff - (xfrac * dbdxh);
2437               Spans[spanidx].param[SPAN_A].start = ((a >> 9) << 9) + dadiff - (xfrac * dadxh);
2438               Spans[spanidx].param[SPAN_S].start = (((s >> 9) << 9)  + dsdiff - (xfrac * dsdxh)) & ~0x1f;
2439               Spans[spanidx].param[SPAN_T].start = (((t >> 9) << 9)  + dtdiff - (xfrac * dtdxh)) & ~0x1f;
2440               Spans[spanidx].param[SPAN_W].start = (((w >> 9) << 9)  + dwdiff - (xfrac * dwdxh)) & ~0x1f;
2441               Spans[spanidx].param[SPAN_Z].start = ((z >> 9) << 9)  + dzdiff - (xfrac * dzdxh);
24372442            }
24382443         }
24392444
r25462r25463
24532458      }
24542459   }
24552460
2456   if(!new_object)
2461   if(!new_object && valid)
24572462   {
24582463      RenderSpans(yh >> 2, yl >> 2, tilenum, flip ? true : false, Spans, rect, object);
24592464   }
trunk/src/mame/video/n64.h
r25462r25463
5656#define MEM16_LIMIT 0x3fffff
5757#define MEM32_LIMIT 0x1fffff
5858
59#define RDP_RANGE_CHECK (0)
59#define RDP_RANGE_CHECK (1)
6060
6161#if RDP_RANGE_CHECK
6262#define CHECK8(in) if(rdp_range_check((in))) { printf("Check8: Address %08x out of range!\n", (in)); fflush(stdout); fatalerror("Address %08x out of range!\n", (in)); }
r25462r25463
7474#define RREADIDX32(in) ((rdp_range_check((in) << 2)) ? 0 : rdram[(in)])
7575
7676#define RWRITEADDR8(in, val)    if(rdp_range_check((in))) { printf("Write8: Address %08x out of range!\n", (in)); fflush(stdout); fatalerror("Address %08x out of range!\n", (in)); } else { ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;}
77#define RWRITEIDX16(in, val)    if(rdp_range_check((in) << 1)) { printf("Write16: Address %08x out of range!\n", (in) << 1); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 1); } else { ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;}
77#define RWRITEIDX16(in, val)    if(rdp_range_check((in) << 1)) { printf("Write16: Address %08x out of range!\n", ((object.MiscState.FBAddress >> 1) + curpixel) << 1); fflush(stdout); fatalerror("Address out of range\n"); } else { ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;}
7878#define RWRITEIDX32(in, val)    if(rdp_range_check((in) << 2)) { printf("Write32: Address %08x out of range!\n", (in) << 2); fflush(stdout); fatalerror("Address %08x out of range!\n", (in) << 2); } else { rdram[(in)] = val;}
7979#else
8080#define RREADADDR8(in) (((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR])
r25462r25463
9090#define U_RREADIDX16(in) (((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR])
9191#define U_RREADIDX32(in) (rdram[(in)])
9292
93#define U_RWRITEADDR8(in, val)  ((UINT8*)rdram)[(in) ^ BYTE_ADDR_XOR] = val;
94#define U_RWRITEIDX16(in, val)  ((UINT16*)rdram)[(in) ^ WORD_ADDR_XOR] = val;
95#define U_RWRITEIDX32(in, val)  rdram[(in)] = val
96
9793#define GETLOWCOL(x)    (((x) & 0x3e) << 2)
9894#define GETMEDCOL(x)    (((x) & 0x7c0) >> 3)
9995#define GETHICOL(x)     (((x) & 0xf800) >> 8)
r25462r25463
508504      const UINT8*    GetMagicMatrix() const { return s_magic_matrix; }
509505      int             GetCurrFIFOIndex() const { return m_cmd_cur; }
510506
511      void            ZStore(UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
507      void            ZStore(const rdp_poly_state &object, UINT32 zcurpixel, UINT32 dzcurpixel, UINT32 z, UINT32 enc);
512508      UINT32          ZDecompress(UINT32 zcurpixel);
513509      UINT32          DZDecompress(UINT32 zcurpixel, UINT32 dzcurpixel);
514510      UINT32          DZCompress(UINT32 value);
trunk/src/mame/video/rdpbhelp.h
r0r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Processor Blend Unit (BL) helper macros
5    -------------------
6
7   by MooglyGuy
8   based on code by Ville Linde, MooglyGuy, angrylion, Ziggy, Gonetz and Orkin
9
10
11******************************************************************************/
12
13#ifndef _VIDEO_RDPBHELP_H_
14#define _VIDEO_RDPBHELP_H_
15
16#include "emu.h"
17#include "includes/n64.h"
18#include "video/n64.h"
19
20#define DITHER_A(val, dith)    \
21   if ((val + dith) >= 0x100)   \
22   {                     \
23      val = 0xff;            \
24   }                     \
25   else                  \
26   {                     \
27      val += dith;         \
28   }
29
30#define DITHER_CHAN(chan, dith)      \
31   if ((chan & 7) > dith)         \
32   {                        \
33      chan = (chan & 0xf8) + 8;   \
34      if (chan > 247)            \
35      {                     \
36         chan = 255;            \
37      }                     \
38   }
39
40#define DITHER_RGB(dith)   \
41   DITHER_CHAN(r, dith)   \
42   DITHER_CHAN(g, dith)   \
43   DITHER_CHAN(b, dith)
44
45#define ALPHA_COMPARE()   \
46   if (((this)->*(compare[acmode]))(userdata->PixelColor.i.a, userdata, object))   \
47   {                                                \
48      return false;                                    \
49   }
50
51#define CVG_COMPARE() \
52   if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))   \
53   {                                                \
54      return false;                                    \
55   }
56
57#define TEST_REJECT() \
58   ALPHA_COMPARE(); \
59   CVG_COMPARE();
60
61#define WRITE_OUT_NB_ND(cycle) \
62   *fr = *userdata->ColorInputs.blender1a_r[cycle];   \
63   *fg = *userdata->ColorInputs.blender1a_g[cycle];   \
64   *fb = *userdata->ColorInputs.blender1a_b[cycle];
65
66#define WRITE_OUT() \
67   *fr = r;   \
68   *fg = g;   \
69   *fb = b;
70
71#define WRITE_BLENDED_COLOR() \
72   userdata->BlendedPixelColor.i.r = r;   \
73   userdata->BlendedPixelColor.i.g = g;   \
74   userdata->BlendedPixelColor.i.b = b;   \
75   userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a;
76
77#define BLEND_CYCLE0(cyc) \
78   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[cyc];   \
79   ((this)->*(cycle##cyc[sel##cyc]))(&r, &g, &b, userdata, object);   \
80
81#define BLEND_CYCLE1(cyc) \
82   if (partialreject && userdata->PixelColor.i.a >= 0xff)   \
83   {                                          \
84      ASSIGN_OUT(cyc);                           \
85   }                                          \
86   else                                       \
87   {                                          \
88      userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[cyc];   \
89      ((this)->*(cycle##cyc[sel##cyc]))(&r, &g, &b, userdata, object);   \
90   }
91
92#define BLEND_CYCLE(cyc, check_reject) \
93   BLEND_CYCLE##check_reject(cyc)
94
95#define BLEND_FACTORS0(cycle) \
96   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3;   \
97   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3;
98
99#define BLEND_FACTORS1(cycle) \
100   UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c;   \
101   UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c;
102
103#define BLEND_SUM0()   ;
104
105#define BLEND_SUM1() \
106   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
107
108#define BLEND_FACTORS(cycle, special, sum)   \
109   BLEND_FACTORS##special(cycle);         \
110   BLEND_SUM##sum();
111
112#define BLEND_MUL(cycle) \
113   *r = (((int)(*userdata->ColorInputs.blender1a_r[cycle]) * (int)(blend1a))) +   \
114      (((int)(*userdata->ColorInputs.blender2a_r[cycle]) * (int)(blend2a)));      \
115   *g = (((int)(*userdata->ColorInputs.blender1a_g[cycle]) * (int)(blend1a))) +   \
116      (((int)(*userdata->ColorInputs.blender2a_g[cycle]) * (int)(blend2a)));      \
117   *b = (((int)(*userdata->ColorInputs.blender1a_b[cycle]) * (int)(blend1a))) +   \
118      (((int)(*userdata->ColorInputs.blender2a_b[cycle]) * (int)(blend2a)));
119
120#define BLEND_ADD1(cycle) \
121   *r += (((int)*userdata->ColorInputs.blender2a_r[cycle]) << 2);   \
122   *g += (((int)*userdata->ColorInputs.blender2a_g[cycle]) << 2);   \
123   *b += (((int)*userdata->ColorInputs.blender2a_b[cycle]) << 2);
124
125#define BLEND_ADD0(cycle) \
126   *r += (int)*userdata->ColorInputs.blender2a_r[cycle];   \
127   *g += (int)*userdata->ColorInputs.blender2a_g[cycle];   \
128   *b += (int)*userdata->ColorInputs.blender2a_b[cycle];
129
130#define BLEND_ADD(cycle, special)   \
131   BLEND_ADD##special(cycle);
132
133#define BLEND_SHIFT(shift)   \
134   *r >>= shift;         \
135   *g >>= shift;         \
136   *b >>= shift;
137
138#define BLEND_CLAMP()      \
139   if (*r > 255) *r = 255;   \
140   if (*g > 255) *g = 255;   \
141   if (*b > 255) *b = 255;
142
143#define BLEND_SCALE()         \
144   if (sum)               \
145   {                     \
146      *r /= sum;            \
147      *g /= sum;            \
148      *b /= sum;            \
149   }                     \
150   else                  \
151   {                     \
152      *r = *g = *b = 0xff;   \
153   }
154
155#define BLEND_SCALE_CLAMP0()   \
156   BLEND_CLAMP();
157
158#define BLEND_SCALE_CLAMP1()   \
159   BLEND_SCALE();            \
160   BLEND_CLAMP();
161
162#define BLEND_SCALE_CLAMP(sum)   \
163   BLEND_SCALE_CLAMP##sum();
164
165#define ASSIGN_OUT(cycle) \
166   r = *userdata->ColorInputs.blender1a_r[cycle];   \
167   g = *userdata->ColorInputs.blender1a_g[cycle];   \
168   b = *userdata->ColorInputs.blender1a_b[cycle];
169
170#endif // _VIDEO_RDPBHELP_H_
No newline at end of file
Property changes on: trunk/src/mame/video/rdpbhelp.h
Added: svn:eol-style
   + native
Added: svn:mime-type
   + text/plain
trunk/src/mame/video/rdpblend.c
r25462r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Processor Blend Unit (BL)
5    -------------------
6
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
10
11
12******************************************************************************/
13
114#include "emu.h"
215#include "includes/n64.h"
316#include "video/n64.h"
17#include "video/rdpbhelp.h"
418
519N64BlenderT::N64BlenderT()
620{
r25462r25463
3145   cycle1[1] = &N64BlenderT::BlendEquationCycle1NoForceSpecial;
3246   cycle1[2] = &N64BlenderT::BlendEquationCycle1ForceNoSpecial;
3347   cycle1[3] = &N64BlenderT::BlendEquationCycle1ForceSpecial;
48
49   compare[0] = &N64BlenderT::AlphaCompareNone;
50   compare[1] = &N64BlenderT::AlphaCompareNone;
51   compare[2] = &N64BlenderT::AlphaCompareNoDither;
52   compare[3] = &N64BlenderT::AlphaCompareDither;
3453}
3554
36#define ALPHA_COMPARE()   \
37   if (!AlphaCompare(userdata->PixelColor.i.a, userdata, object))   \
38   {                                                \
39      return false;                                    \
40   }
41
42#define CVG_COMPARE() \
43   if (object.OtherModes.antialias_en ? (!userdata->CurrentPixCvg) : (!userdata->CurrentCvgBit))   \
44   {                                                \
45      return false;                                    \
46   }
47
48#define TEST_REJECT() \
49   ALPHA_COMPARE() \
50   CVG_COMPARE()
51
52#define WRITE_OUT_NB_ND(cycle) \
53   *fr = *userdata->ColorInputs.blender1a_r[cycle];   \
54   *fg = *userdata->ColorInputs.blender1a_g[cycle];   \
55   *fb = *userdata->ColorInputs.blender1a_b[cycle];
56
57#define WRITE_OUT() \
58   *fr = r;   \
59   *fg = g;   \
60   *fb = b;
61
62#define WRITE_BLENDED_COLOR() \
63   userdata->BlendedPixelColor.i.r = r;   \
64   userdata->BlendedPixelColor.i.g = g;   \
65   userdata->BlendedPixelColor.i.b = b;   \
66   userdata->BlendedPixelColor.i.a = userdata->PixelColor.i.a;
67
68#define BLEND_CYCLE(cyc) \
69   if (partialreject && userdata->PixelColor.i.a >= 0xff)   \
70   {                                          \
71      ASSIGN_OUT(cyc);                           \
72   }                                          \
73   else                                       \
74   {                                          \
75      userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[cyc];   \
76      ((this)->*(cycle##cyc[((object.OtherModes.force_blend & 1) << 1) | (special_bsel##cyc & 1)]))(&r, &g, &b, userdata, object);   \
77   }
78
79#define BLEND_FACTORS(cycle) \
80   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3;   \
81   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3;
82
83#define BLEND_FACTORS_SUM(cycle) \
84   UINT8 blend1a = *userdata->ColorInputs.blender1b_a[cycle] >> 3;   \
85   UINT8 blend2a = *userdata->ColorInputs.blender2b_a[cycle] >> 3;   \
86   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
87
88#define BLEND_FACTORS_SPECIAL(cycle) \
89   UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c;   \
90   UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c;
91
92#define BLEND_FACTORS_SPECIAL_SUM(cycle) \
93   UINT8 blend1a = (*userdata->ColorInputs.blender1b_a[cycle] >> (3 + userdata->ShiftA)) & 0x1c;   \
94   UINT8 blend2a = (*userdata->ColorInputs.blender2b_a[cycle] >> (3 + userdata->ShiftB)) & 0x1c;   \
95   UINT32 sum = ((blend1a >> 2) + (blend2a >> 2) + 1) & 0xf;
96
97#define BLEND_MUL(cycle) \
98   *r = (((int)(*userdata->ColorInputs.blender1a_r[cycle]) * (int)(blend1a))) +   \
99      (((int)(*userdata->ColorInputs.blender2a_r[cycle]) * (int)(blend2a)));      \
100   *g = (((int)(*userdata->ColorInputs.blender1a_g[cycle]) * (int)(blend1a))) +   \
101      (((int)(*userdata->ColorInputs.blender2a_g[cycle]) * (int)(blend2a)));      \
102   *b = (((int)(*userdata->ColorInputs.blender1a_b[cycle]) * (int)(blend1a))) +   \
103      (((int)(*userdata->ColorInputs.blender2a_b[cycle]) * (int)(blend2a)));
104
105#define BLEND_ADD_SPECIAL(cycle) \
106   *r += (((int)*userdata->ColorInputs.blender2a_r[cycle]) << 2);   \
107   *g += (((int)*userdata->ColorInputs.blender2a_g[cycle]) << 2);   \
108   *b += (((int)*userdata->ColorInputs.blender2a_b[cycle]) << 2);
109
110#define BLEND_ADD(cycle) \
111   *r += (int)*userdata->ColorInputs.blender2a_r[cycle];   \
112   *g += (int)*userdata->ColorInputs.blender2a_g[cycle];   \
113   *b += (int)*userdata->ColorInputs.blender2a_b[cycle];
114
115#define BLEND_SHIFT(shift)   \
116   *r >>= shift;         \
117   *g >>= shift;         \
118   *b >>= shift;
119
120#define BLEND_CLAMP()      \
121   if (*r > 255) *r = 255;   \
122   if (*g > 255) *g = 255;   \
123   if (*b > 255) *b = 255;
124
125#define BLEND_SCALE()         \
126   if (sum)               \
127   {                     \
128      *r /= sum;            \
129      *g /= sum;            \
130      *b /= sum;            \
131   }                     \
132   else                  \
133   {                     \
134      *r = *g = *b = 0xff;   \
135   }
136
137
138#define ASSIGN_OUT(cycle) \
139   r = *userdata->ColorInputs.blender1a_r[cycle];   \
140   g = *userdata->ColorInputs.blender1a_g[cycle];   \
141   b = *userdata->ColorInputs.blender1a_b[cycle];
142
143bool N64BlenderT::Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
55bool N64BlenderT::Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
14456{
145   DitherA(&userdata->PixelColor.i.a, adseed);
146   DitherA(&userdata->ShadeColor.i.a, adseed);
147
57   DITHER_A(userdata->PixelColor.i.a, adseed);
58   DITHER_A(userdata->ShadeColor.i.a, adseed);
14859   TEST_REJECT();
14960   WRITE_OUT_NB_ND(0);
15061
15162   return true;
15263}
15364
154bool N64BlenderT::Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
65bool N64BlenderT::Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
15566{
15667   INT32 r, g, b;
15768
158   DitherA(&userdata->PixelColor.i.a, adseed);
159   DitherA(&userdata->ShadeColor.i.a, adseed);
160
69   DITHER_A(userdata->PixelColor.i.a, adseed);
70   DITHER_A(userdata->ShadeColor.i.a, adseed);
16171   TEST_REJECT();
16272   ASSIGN_OUT(0);
163   DitherRGB(&r, &g, &b, dith);
73   DITHER_RGB(dith);
16474   WRITE_OUT();
16575
16676   return true;
16777}
16878
169bool N64BlenderT::Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
79bool N64BlenderT::Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
17080{
171   DitherA(&userdata->ShadeColor.i.a, adseed);
81   DITHER_A(userdata->ShadeColor.i.a, adseed);
17282
17383   TEST_REJECT();
17484   WRITE_OUT_NB_ND(0);
r25462r25463
17686   return true;
17787}
17888
179bool N64BlenderT::Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
89bool N64BlenderT::Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
18090{
18191   INT32 r, g, b;
18292
183   DitherA(&userdata->ShadeColor.i.a, adseed);
93   DITHER_A(userdata->ShadeColor.i.a, adseed);
18494
18595   TEST_REJECT();
18696   ASSIGN_OUT(0);
187   DitherRGB(&r, &g, &b, dith);
97   DITHER_RGB(dith);
18898   WRITE_OUT();
18999
190100   return true;
191101}
192102
193bool N64BlenderT::Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
103bool N64BlenderT::Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
194104{
195105   INT32 r, g, b;
196106
197   DitherA(&userdata->PixelColor.i.a, adseed);
198   DitherA(&userdata->ShadeColor.i.a, adseed);
107   DITHER_A(userdata->PixelColor.i.a, adseed);
108   DITHER_A(userdata->ShadeColor.i.a, adseed);
199109
200110   TEST_REJECT();
201   BLEND_CYCLE(0);
111   BLEND_CYCLE(0, 1);
202112   WRITE_OUT();
203113
204114   return true;
205115}
206116
207bool N64BlenderT::Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
117bool N64BlenderT::Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
208118{
209119   INT32 r, g, b;
210120
211   DitherA(&userdata->PixelColor.i.a, adseed);
212   DitherA(&userdata->ShadeColor.i.a, adseed);
121   DITHER_A(userdata->PixelColor.i.a, adseed);
122   DITHER_A(userdata->ShadeColor.i.a, adseed);
213123
214124   TEST_REJECT();
215   BLEND_CYCLE(0);
216   DitherRGB(&r, &g, &b, dith);
125   BLEND_CYCLE(0, 1);
126   DITHER_RGB(dith);
217127   WRITE_OUT();
218128
219129   return true;
220130}
221131
222bool N64BlenderT::Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
132bool N64BlenderT::Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
223133{
224134   INT32 r, g, b;
225135
226   DitherA(&userdata->ShadeColor.i.a, adseed);
136   DITHER_A(userdata->ShadeColor.i.a, adseed);
227137
228138   TEST_REJECT();
229   BLEND_CYCLE(0);
139   BLEND_CYCLE(0, 1);
230140   WRITE_OUT();
231141
232142   return true;
233143}
234144
235bool N64BlenderT::Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel0, rdp_span_aux *userdata, const rdp_poly_state& object)
145bool N64BlenderT::Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
236146{
237147   INT32 r, g, b;
238148
239   DitherA(&userdata->ShadeColor.i.a, adseed);
149   DITHER_A(userdata->ShadeColor.i.a, adseed);
240150
241151   TEST_REJECT();
242   BLEND_CYCLE(0);
243   DitherRGB(&r, &g, &b, dith);
152   BLEND_CYCLE(0, 1);
153   DITHER_RGB(dith);
244154   WRITE_OUT();
245155
246156   return true;
247157}
248158
249bool N64BlenderT::Blend2CycleNoBlendNoACVGNoDither(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)
159bool N64BlenderT::Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
250160{
251161   INT32 r, g, b;
252162
253   DitherA(&userdata->PixelColor.i.a, adseed);
254   DitherA(&userdata->ShadeColor.i.a, adseed);
163   DITHER_A(userdata->PixelColor.i.a, adseed);
164   DITHER_A(userdata->ShadeColor.i.a, adseed);
255165
256166   TEST_REJECT();
257   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
258   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
167   BLEND_CYCLE(0, 0);
259168   WRITE_BLENDED_COLOR();
260169   WRITE_OUT_NB_ND(1);
261170
262171   return true;
263172}
264173
265bool N64BlenderT::Blend2CycleNoBlendNoACVGDither(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)
174bool N64BlenderT::Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
266175{
267176   INT32 r, g, b;
268177
269   DitherA(&userdata->PixelColor.i.a, adseed);
270   DitherA(&userdata->ShadeColor.i.a, adseed);
178   DITHER_A(userdata->PixelColor.i.a, adseed);
179   DITHER_A(userdata->ShadeColor.i.a, adseed);
271180
272181   TEST_REJECT();
273   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
274   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
182   BLEND_CYCLE(0, 0);
275183   WRITE_BLENDED_COLOR();
276184   ASSIGN_OUT(1);
277   DitherRGB(&r, &g, &b, dith);
185   DITHER_RGB(dith);
278186   WRITE_OUT();
279187
280188   return true;
281189}
282190
283bool N64BlenderT::Blend2CycleNoBlendACVGNoDither(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)
191bool N64BlenderT::Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
284192{
285193   INT32 r, g, b;
286194
287   DitherA(&userdata->ShadeColor.i.a, adseed);
195   DITHER_A(userdata->ShadeColor.i.a, adseed);
288196
289197   TEST_REJECT();
290   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
291   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
198   BLEND_CYCLE(0, 0);
292199   WRITE_BLENDED_COLOR();
293200   WRITE_OUT_NB_ND(1);
294201
295202   return true;
296203}
297204
298bool N64BlenderT::Blend2CycleNoBlendACVGDither(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)
205bool N64BlenderT::Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
299206{
300207   INT32 r, g, b;
301208
302   DitherA(&userdata->ShadeColor.i.a, adseed);
209   DITHER_A(userdata->ShadeColor.i.a, adseed);
303210
304211   TEST_REJECT();
305   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
306   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
212   BLEND_CYCLE(0, 0);
307213   WRITE_BLENDED_COLOR();
308214   ASSIGN_OUT(1);
309   DitherRGB(&r, &g, &b, dith);
215   DITHER_RGB(dith);
310216   WRITE_OUT();
311217
312218   return true;
313219}
314220
315bool N64BlenderT::Blend2CycleBlendNoACVGNoDither(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)
221bool N64BlenderT::Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
316222{
317223   INT32 r, g, b;
318224
319   DitherA(&userdata->PixelColor.i.a, adseed);
320   DitherA(&userdata->ShadeColor.i.a, adseed);
225   DITHER_A(userdata->PixelColor.i.a, adseed);
226   DITHER_A(userdata->ShadeColor.i.a, adseed);
321227
322228   TEST_REJECT();
323   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
324   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
229   BLEND_CYCLE(0, 0);
325230   WRITE_BLENDED_COLOR();
326   BLEND_CYCLE(1);
231   BLEND_CYCLE(1, 1);
327232   WRITE_OUT();
328233
329234   return true;
330235}
331236
332bool N64BlenderT::Blend2CycleBlendNoACVGDither(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)
237bool N64BlenderT::Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
333238{
334239   INT32 r, g, b;
335240
336   DitherA(&userdata->PixelColor.i.a, adseed);
337   DitherA(&userdata->ShadeColor.i.a, adseed);
241   DITHER_A(userdata->PixelColor.i.a, adseed);
242   DITHER_A(userdata->ShadeColor.i.a, adseed);
338243
339244   TEST_REJECT();
340   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
341   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
245   BLEND_CYCLE(0, 0);
342246   WRITE_BLENDED_COLOR();
343   BLEND_CYCLE(1);
344   DitherRGB(&r, &g, &b, dith);
247   BLEND_CYCLE(1, 1);
248   DITHER_RGB(dith);
345249   WRITE_OUT();
346250
347251   return true;
348252}
349253
350bool N64BlenderT::Blend2CycleBlendACVGNoDither(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)
254bool N64BlenderT::Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
351255{
352256   INT32 r, g, b;
353257
354   DitherA(&userdata->ShadeColor.i.a, adseed);
258   DITHER_A(userdata->ShadeColor.i.a, adseed);
355259
356260   TEST_REJECT();
357   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
358   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
261   BLEND_CYCLE(0, 0);
359262   WRITE_BLENDED_COLOR();
360   BLEND_CYCLE(1);
263   BLEND_CYCLE(1, 1);
361264   WRITE_OUT();
362265
363266   return true;
364267}
365268
366bool N64BlenderT::Blend2CycleBlendACVGDither(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)
269bool N64BlenderT::Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object)
367270{
368271   INT32 r, g, b;
369272
370   DitherA(&userdata->ShadeColor.i.a, adseed);
273   DITHER_A(userdata->ShadeColor.i.a, adseed);
371274
372275   TEST_REJECT();
373   userdata->InvPixelColor.i.a = 0xff - *userdata->ColorInputs.blender1b_a[0];
374   ((this)->*(cycle0[((object.OtherModes.force_blend & 1) << 1) | (special_bsel0 & 1)]))(&r, &g, &b, userdata, object);
276   BLEND_CYCLE(0, 0);
375277   WRITE_BLENDED_COLOR();
376   BLEND_CYCLE(1);
377   DitherRGB(&r, &g, &b, dith);
278   BLEND_CYCLE(1, 1);
279   DITHER_RGB(dith);
378280   WRITE_OUT();
379281
380282   return true;
381283}
382284
285#define BLEND_PIPE(cycle, special, sum, shift)   \
286   BLEND_FACTORS(cycle, special, sum);         \
287   BLEND_MUL(cycle);                     \
288   BLEND_ADD(cycle, special);               \
289   BLEND_SHIFT(shift);                     \
290   BLEND_SCALE_CLAMP(sum);
291
383292void N64BlenderT::BlendEquationCycle0NoForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
384293{
385   BLEND_FACTORS_SUM(0);
386   BLEND_MUL(0);
387   BLEND_ADD(0);
388   BLEND_SHIFT(2);
389   BLEND_SCALE();
390   BLEND_CLAMP();
294   BLEND_PIPE(0, 0, 1, 2);
391295}
392296
393297void N64BlenderT::BlendEquationCycle0NoForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
394298{
395   BLEND_FACTORS_SPECIAL_SUM(0);
396   BLEND_MUL(0);
397   BLEND_ADD_SPECIAL(0);
398   BLEND_SHIFT(2);
399   BLEND_SCALE();
400   BLEND_CLAMP();
299   BLEND_PIPE(0, 1, 1, 2);
401300}
402301
403302void N64BlenderT::BlendEquationCycle0ForceNoSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
404303{
405   BLEND_FACTORS(0);
406   BLEND_MUL(0);
407   BLEND_ADD(0);
408   BLEND_SHIFT(5);
409   BLEND_CLAMP();
304   BLEND_PIPE(0, 0, 0, 5);
410305}
411306
412307void N64BlenderT::BlendEquationCycle0ForceSpecial(int* r, int* g, int* b, rdp_span_aux *userdata, const rdp_poly_state& object)
413308{
414   BLEND_FACTORS_SPECIAL(0);
415   BLEND_MUL(0);
416   BLEND_ADD_SPECIAL(0);
417   BLEND_SHIFT(5);
418   BLEND_CLAMP();
309   BLEND_PIPE(0, 1, 0, 5);
419310}
420311
421312void N64BlenderT::BlendEquationCycle1NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
422313{
423   BLEND_FACTORS_SUM(1);
424   BLEND_MUL(1);
425   BLEND_ADD(1);
426   BLEND_SHIFT(2);
427   BLEND_SCALE();
428   BLEND_CLAMP();
314   BLEND_PIPE(1, 0, 1, 2);
429315}
430316
431317void N64BlenderT::BlendEquationCycle1NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
432318{
433   BLEND_FACTORS_SPECIAL_SUM(1);
434   BLEND_MUL(1);
435   BLEND_ADD_SPECIAL(1);
436   BLEND_SHIFT(2);
437   BLEND_SCALE();
438   BLEND_CLAMP();
319   BLEND_PIPE(1, 1, 1, 2);
439320}
440321
441322void N64BlenderT::BlendEquationCycle1ForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
442323{
443   BLEND_FACTORS(1);
444   BLEND_MUL(1);
445   BLEND_ADD(1);
446   BLEND_SHIFT(5);
447   BLEND_CLAMP();
324   BLEND_PIPE(1, 0, 0, 5);
448325}
449326
450327void N64BlenderT::BlendEquationCycle1ForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object)
451328{
452   BLEND_FACTORS_SPECIAL(1);
453   BLEND_MUL(1);
454   BLEND_ADD_SPECIAL(1);
455   BLEND_SHIFT(5);
456   BLEND_CLAMP();
329   BLEND_PIPE(1, 1, 0, 5);
457330}
458331
459bool N64BlenderT::AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
332bool N64BlenderT::AlphaCompareNone(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
460333{
461   INT32 threshold;
462   if (object.OtherModes.alpha_compare_en)
463   {
464      threshold = (object.OtherModes.dither_alpha_en) ? m_rdp->GetRandom() : userdata->BlendColor.i.a;
465      if (alpha < threshold)
466      {
467         return false;
468      }
469      return true;
470   }
471   return true;
334   return false;
472335}
473336
474void N64BlenderT::DitherA(UINT8 *a, int dith)
337bool N64BlenderT::AlphaCompareNoDither(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
475338{
476   INT32 new_a = *a + dith;
477   if(new_a & 0x100)
478   {
479      new_a = 0xff;
480   }
481   *a = (UINT8)new_a;
339   return alpha < userdata->BlendColor.i.a;
482340}
483341
484void N64BlenderT::DitherRGB(INT32 *r, INT32 *g, INT32 *b, int dith)
342bool N64BlenderT::AlphaCompareDither(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object)
485343{
486   if ((*r & 7) > dith)
487   {
488      *r = (*r & 0xf8) + 8;
489      if (*r > 247)
490      {
491         *r = 255;
492      }
493   }
494   if ((*g & 7) > dith)
495   {
496      *g = (*g & 0xf8) + 8;
497      if (*g > 247)
498      {
499         *g = 255;
500      }
501   }
502   if ((*b & 7) > dith)
503   {
504      *b = (*b & 0xf8) + 8;
505      if (*b > 247)
506      {
507         *b = 255;
508      }
509   }
344   return alpha < (rand() & 0xff);
510345}
trunk/src/mame/video/rdpblend.h
r25462r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Processor Blend Unit (BL)
5    -------------------
6
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
10
11
12******************************************************************************/
13
114#ifndef _VIDEO_RDPBLEND_H_
215#define _VIDEO_RDPBLEND_H_
316
r25462r25463
1326class N64BlenderT
1427{
1528   public:
16      typedef bool (N64BlenderT::*Blender1)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
17      typedef bool (N64BlenderT::*Blender2)(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);
29      typedef bool (N64BlenderT::*Blender1)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
30      typedef bool (N64BlenderT::*Blender2)(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
1831      typedef void (N64BlenderT::*BlendEquation)(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
32      typedef bool (N64BlenderT::*AlphaCompare)(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
33
1934      N64BlenderT();
2035
2136      Blender1         blend1[8];
r25462r25463
3045      running_machine*    m_machine;
3146      n64_rdp*            m_rdp;
3247
33      bool            Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
34      bool            Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
35      bool            Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
36      bool            Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
37      bool            Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
38      bool            Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
39      bool            Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
40      bool            Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int special_bsel, rdp_span_aux *userdata, const rdp_poly_state& object);
48      bool            Blend1CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
49      bool            Blend1CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
50      bool            Blend1CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
51      bool            Blend1CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
52      bool            Blend1CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
53      bool            Blend1CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
54      bool            Blend1CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
55      bool            Blend1CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
4156
42      bool            Blend2CycleNoBlendNoACVGNoDither(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);
43      bool            Blend2CycleNoBlendNoACVGDither(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);
44      bool            Blend2CycleNoBlendACVGNoDither(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);
45      bool            Blend2CycleNoBlendACVGDither(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);
46      bool            Blend2CycleBlendNoACVGNoDither(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);
47      bool            Blend2CycleBlendNoACVGDither(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);
48      bool            Blend2CycleBlendACVGNoDither(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);
49      bool            Blend2CycleBlendACVGDither(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);
57      bool            Blend2CycleNoBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
58      bool            Blend2CycleNoBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
59      bool            Blend2CycleNoBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
60      bool            Blend2CycleNoBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
61      bool            Blend2CycleBlendNoACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
62      bool            Blend2CycleBlendNoACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
63      bool            Blend2CycleBlendACVGNoDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
64      bool            Blend2CycleBlendACVGDither(UINT32* fr, UINT32* fg, UINT32* fb, int dith, int adseed, int partialreject, int sel0, int sel1, int acmode, rdp_span_aux *userdata, const rdp_poly_state& object);
5065
5166      void                BlendEquationCycle0NoForceNoSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
5267      void                BlendEquationCycle0NoForceSpecial(INT32* r, INT32* g, INT32* b, rdp_span_aux *userdata, const rdp_poly_state& object);
r25462r25463
6075
6176      BlendEquation      cycle0[4];
6277      BlendEquation      cycle1[4];
78      AlphaCompare      compare[4];
6379
64      bool                AlphaCompare(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
80      bool               AlphaCompareNone(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
81      bool               AlphaCompareNoDither(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
82      bool               AlphaCompareDither(UINT8 alpha, const rdp_span_aux *userdata, const rdp_poly_state& object);
6583
6684      void                DitherRGB(INT32* r, INT32* g, INT32* b, int dith);
6785      void                DitherA(UINT8* a, int dith);
trunk/src/mame/video/rdpspn16.c
r25462r25463
1/******************************************************************************
2
3
4    SGI/Nintendo Reality Display Processor span-drawing functions
5    -------------------
6
7   by MooglyGuy
8   based on initial C code by Ville Linde
9   contains additional improvements from angrylion, Ziggy, Gonetz and Orkin
10
11
12******************************************************************************/
13
114#include "emu.h"
215#include "includes/n64.h"
316#include "video/n64.h"
r25462r25463
135148   SpanParam w; w.w = extent.param[SPAN_W].start;
136149
137150   UINT32 zb = object.MiscState.ZBAddress >> 1;
138   UINT32 zhb = zb;
151   UINT32 zhb = object.MiscState.ZBAddress;
139152   UINT8 offx = 0, offy = 0;
140153
141154   INT32 tile1 = tilenum;
r25462r25463
147160   m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
148161
149162   bool partialreject = (userdata->ColorInputs.blender2b_a[0] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[0] == &userdata->PixelColor.i.a);
150   bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a);
163   int sel0 = (OtherModes.force_blend ? 2 : 0) | ((userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a) ? 1 : 0);
151164
152165   int drinc = object.SpanBase.m_span_dr;
153166   int dginc = object.SpanBase.m_span_dg;
r25462r25463
196209   int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
197210   int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
198211   int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
212   int acmode = (object.OtherModes.alpha_compare_en ? 2 : 0) | (object.OtherModes.dither_alpha_en ? 1 : 0);
213
199214   userdata->m_start_span = true;
200215   for (int j = 0; j <= length; j++)
201216   {
r25462r25463
255270         {
256271            m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
257272
258            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, userdata, object);
273            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend1[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, acmode, userdata, object);
259274
260275            if (rendered)
261276            {
r25462r25463
263278
264279               if (object.OtherModes.z_update_en)
265280               {
266                  m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
281                  m_rdp->ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
267282               }
268283            }
269284         }
r25462r25463
300315   SpanParam w; w.w = extent.param[SPAN_W].start;
301316
302317   UINT32 zb = object.MiscState.ZBAddress >> 1;
303   UINT32 zhb = zb;
318   UINT32 zhb = object.MiscState.ZBAddress;
304319   UINT8 offx = 0, offy = 0;
305320
306321   INT32 tile2 = (tilenum + 1) & 7;
r25462r25463
318333   m_rdp->TexPipe.CalculateClampDiffs(tile1, userdata, object, m_clamp_s_diff, m_clamp_t_diff);
319334
320335   bool partialreject = (userdata->ColorInputs.blender2b_a[1] == &userdata->InvPixelColor.i.a && userdata->ColorInputs.blender1b_a[1] == &userdata->PixelColor.i.a);
321   bool bsel0 = (userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a);
322   bool bsel1 = (userdata->ColorInputs.blender2b_a[1] == &userdata->MemoryColor.i.a);
336   int sel0 = (OtherModes.force_blend ? 2 : 0) | ((userdata->ColorInputs.blender2b_a[0] == &userdata->MemoryColor.i.a) ? 1 : 0);
337   int sel1 = (OtherModes.force_blend ? 2 : 0) | ((userdata->ColorInputs.blender2b_a[1] == &userdata->MemoryColor.i.a) ? 1 : 0);
323338
324339   int dzpix = object.SpanBase.m_span_dzpix;
325340   int drinc = flip ? (object.SpanBase.m_span_dr) : -object.SpanBase.m_span_dr;
r25462r25463
356371   int blend_index = (object.OtherModes.alpha_cvg_select ? 2 : 0) | ((object.OtherModes.rgb_dither_sel < 3) ? 1 : 0);
357372   int read_index = ((object.MiscState.FBSize - 2) << 1) | object.OtherModes.image_read_en;
358373   int write_index = ((object.MiscState.FBSize - 2) << 3) | (object.OtherModes.cvg_dest << 1);
374   int acmode = (object.OtherModes.alpha_compare_en ? 2 : 0) | (object.OtherModes.dither_alpha_en ? 1 : 0);
375
359376   userdata->m_start_span = true;
360377   for (int j = 0; j <= length; j++)
361378   {
r25462r25463
424441         {
425442            m_rdp->GetDitherValues(scanline, j, &cdith, &adith, object);
426443
427            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, bsel0, bsel1, userdata, object);
444            bool rendered = ((&m_rdp->Blender)->*(m_rdp->Blender.blend2[(userdata->BlendEnable << 2) | blend_index]))(&fir, &fig, &fib, cdith, adith, partialreject, sel0, sel1, acmode, userdata, object);
428445
429446            if (rendered)
430447            {
431448               ((this)->*(_Write[write_index | userdata->BlendEnable]))(curpixel, fir, fig, fib, userdata, object);
432449               if (object.OtherModes.z_update_en)
433450               {
434                  m_rdp->ZStore(zbcur, zhbcur, sz, userdata->m_dzpix_enc);
451                  m_rdp->ZStore(object, zbcur, zhbcur, sz, userdata->m_dzpix_enc);
435452               }
436453            }
437454         }

Previous 199869 Revisions Next


© 1997-2024 The MAME Team