summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame
diff options
context:
space:
mode:
author yz70s <yz70s@users.noreply.github.com>2014-12-24 18:55:26 +0100
committer yz70s <yz70s@users.noreply.github.com>2014-12-25 13:03:13 +0100
commit075a8929c676e6815e5d0e4578b74f50f5de33b4 (patch)
tree0941e1435219aca6c47ee68d9067d5e7837afbee /src/mame
parentf815c4fe2a0789dfd1e31a709deff1076a35ea8f (diff)
chihiro: added support for zbuffer and stencil plus render target methods [Samuele Zannoli]
Diffstat (limited to 'src/mame')
-rw-r--r--src/mame/includes/chihiro.h55
-rw-r--r--src/mame/video/chihiro.c956
2 files changed, 678 insertions, 333 deletions
diff --git a/src/mame/includes/chihiro.h b/src/mame/includes/chihiro.h
index dda45c9af39..7df854abdab 100644
--- a/src/mame/includes/chihiro.h
+++ b/src/mame/includes/chihiro.h
@@ -147,10 +147,10 @@ offset in ramht+4 contains in the lower 16 bits the offset in RAMIN divided by 1
objects have methods used to do drawing
most methods set parameters, others actually draw
*/
-class nv2a_renderer : public poly_manager<float, nvidia_object_data, 12, 8192>
+class nv2a_renderer : public poly_manager<float, nvidia_object_data, 13, 8192>
{
public:
- nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 12, 8192>(machine)
+ nv2a_renderer(running_machine &machine) : poly_manager<float, nvidia_object_data, 13, 8192>(machine)
{
memset(channel, 0, sizeof(channel));
memset(pfifo, 0, sizeof(pfifo));
@@ -158,7 +158,6 @@ public:
memset(pmc, 0, sizeof(pmc));
memset(ramin, 0, sizeof(ramin));
computedilated();
- fb.allocate(640, 480);
objectdata = &(object_data_alloc());
objectdata->data = this;
combiner.used = 0;
@@ -169,6 +168,16 @@ public:
alpha_test_enabled = false;
alpha_reference = 0;
alpha_func = nv2a_renderer::ALWAYS;
+ depth_test_enabled = false;
+ depth_function = nv2a_renderer::LESS;
+ depth_write_enabled = false;
+ stencil_test_enabled = false;
+ stencil_func = nv2a_renderer::ALWAYS;
+ stencil_ref = 0;
+ stencil_mask = -1;
+ stencil_op_fail = nv2a_renderer::KEEP;
+ stencil_op_zfail = nv2a_renderer::KEEP;
+ stencil_op_zpass = nv2a_renderer::KEEP;
blending_enabled = false;
blend_equation = nv2a_renderer::FUNC_ADD;
blend_color = 0;
@@ -176,6 +185,12 @@ public:
blend_function_source = nv2a_renderer::ONE;
logical_operation_enabled = false;
logical_operation = nv2a_renderer::COPY;
+ limits_rendertarget.set(0, 0, 640, 480);
+ pitch_rendertarget = 0;
+ pitch_depthbuffer = 0;
+ rendertarget = NULL;
+ depthbuffer = NULL;
+ displayedtarget = NULL;
debug_grab_texttype = -1;
debug_grab_textfile = NULL;
memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
@@ -195,7 +210,7 @@ public:
void geforce_read_dma_object(UINT32 handle, UINT32 &offset, UINT32 &size);
void geforce_exec_method(address_space &space, UINT32 channel, UINT32 subchannel, UINT32 method, UINT32 address, int &countlen);
UINT32 texture_get_texel(int number, int x, int y);
- void write_pixel(int x, int y, UINT32 color);
+ void write_pixel(int x, int y, UINT32 color, UINT32 depth);
void combiner_initialize_registers(UINT32 argb8[6]);
void combiner_initialize_stage(int stage_number);
void combiner_initialize_final();
@@ -247,6 +262,12 @@ public:
UINT32 ramin[0x100000 / 4];
UINT32 dma_offset[2];
UINT32 dma_size[2];
+ rectangle limits_rendertarget;
+ UINT32 pitch_rendertarget;
+ UINT32 pitch_depthbuffer;
+ UINT32 *rendertarget;
+ UINT32 *depthbuffer;
+ UINT32 *displayedtarget;
UINT32 vertexbuffer_address[16];
int vertexbuffer_stride[16];
int vertexbuffer_kind[16];
@@ -371,6 +392,16 @@ public:
bool alpha_test_enabled;
int alpha_func;
int alpha_reference;
+ bool depth_test_enabled;
+ int depth_function;
+ bool depth_write_enabled;
+ bool stencil_test_enabled;
+ int stencil_func;
+ int stencil_ref;
+ int stencil_mask;
+ int stencil_op_fail;
+ int stencil_op_zfail;
+ int stencil_op_zpass;
bool blending_enabled;
int blend_equation;
int blend_function_source;
@@ -398,7 +429,6 @@ public:
int enabled_vertex_attributes;
int vertex_attribute_words[16];
int vertex_attribute_offset[16];
- bitmap_rgb32 fb;
UINT32 dilated0[16][2048];
UINT32 dilated1[16][2048];
int dilatechose[256];
@@ -406,6 +436,21 @@ public:
int debug_grab_texttype;
char *debug_grab_textfile;
+ enum VERTEX_PARAMETER {
+ PARAM_COLOR_B = 0,
+ PARAM_COLOR_G = 1,
+ PARAM_COLOR_R = 2,
+ PARAM_COLOR_A = 3,
+ PARAM_TEXTURE0_U = 4,
+ PARAM_TEXTURE0_V = 5,
+ PARAM_TEXTURE1_U = 6,
+ PARAM_TEXTURE1_V = 7,
+ PARAM_TEXTURE2_U = 8,
+ PARAM_TEXTURE2_V = 9,
+ PARAM_TEXTURE3_U = 10,
+ PARAM_TEXTURE3_V = 11,
+ PARAM_Z = 12
+ };
enum NV2A_BEGIN_END {
STOP = 0,
POINTS = 1,
diff --git a/src/mame/video/chihiro.c b/src/mame/video/chihiro.c
index 40186ff88a9..a98778cbfba 100644
--- a/src/mame/video/chihiro.c
+++ b/src/mame/video/chihiro.c
@@ -1213,14 +1213,19 @@ UINT32 nv2a_renderer::texture_get_texel(int number, int x, int y)
}
}
-void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
+void nv2a_renderer::write_pixel(int x, int y, UINT32 color, UINT32 depth)
{
- void *addr;
- UINT32 fbcolor;
+ UINT32 *addr, *daddr;
+ UINT32 fbcolor, deptsten;
UINT32 c[4], fb[4], s[4], d[4], cc[4];
-
- addr = this->fb.raw_pixptr(y, x);
- fbcolor = *((UINT32 *)addr);
+ UINT32 dep, sten, stenc, stenv;
+ bool stencil_passed;
+ bool depth_passed;
+
+ addr=rendertarget + (pitch_rendertarget / 4)*y + x;
+ fbcolor = *addr;
+ daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
+ deptsten = *daddr;
c[3] = color >> 24;
c[2] = (color >> 16) & 255;
c[1] = (color >> 8) & 255;
@@ -1233,329 +1238,523 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
cc[2] = (blend_color >> 16) & 255;
cc[1] = (blend_color >> 8) & 255;
cc[0] = blend_color & 255;
+ dep = deptsten >> 8;
+ sten = deptsten & 255;
+ if (depth > 0xffffff)
+ depth = 0xffffff;
+ if (depth & 0x80000000)
+ depth = 0;
// ownership test and scissor test not done
// alpha test
if (alpha_test_enabled) {
switch (alpha_func) {
+ case nv2a_renderer::NEVER:
+ return;
+ case nv2a_renderer::ALWAYS:
+ default:
+ break;
+ case nv2a_renderer::LESS:
+ if (c[3] >= alpha_reference)
+ return;
+ break;
+ case nv2a_renderer::LEQUAL:
+ if (c[3] > alpha_reference)
+ return;
+ break;
+ case nv2a_renderer::EQUAL:
+ if (c[3] != alpha_reference)
+ return;
+ break;
+ case nv2a_renderer::GEQUAL:
+ if (c[3] < alpha_reference)
+ return;
+ break;
+ case nv2a_renderer::GREATER:
+ if (c[3] <= alpha_reference)
+ return;
+ break;
+ case nv2a_renderer::NOTEQUAL:
+ if (c[3] == alpha_reference)
+ return;
+ break;
+ }
+ }
+ // stencil test
+ stencil_passed = true;
+ if (stencil_test_enabled) {
+ stenc=stencil_mask & stencil_ref;
+ stenv=stencil_mask & sten;
+ switch (stencil_func) {
case nv2a_renderer::NEVER:
- return;
- case nv2a_renderer::ALWAYS:
- default:
+ stencil_passed = false;
break;
case nv2a_renderer::LESS:
- if (c[3] >= alpha_reference)
- return;
- break;
- case nv2a_renderer::LEQUAL:
- if (c[3] > alpha_reference)
- return;
+ if (stenc >= stenv)
+ stencil_passed = false;
break;
case nv2a_renderer::EQUAL:
- if (c[3] != alpha_reference)
- return;
+ if (stenc != stenv)
+ stencil_passed = false;
break;
- case nv2a_renderer::GEQUAL:
- if (c[3] < alpha_reference)
- return;
+ case nv2a_renderer::LEQUAL:
+ if (stenc > stenv)
+ stencil_passed = false;
break;
case nv2a_renderer::GREATER:
- if (c[3] <= alpha_reference)
- return;
+ if (stenc <= stenv)
+ stencil_passed = false;
break;
case nv2a_renderer::NOTEQUAL:
- if (c[3] == alpha_reference)
- return;
+ if (stenc == stenv)
+ stencil_passed = false;
break;
- }
- }
- // stencil test not done
- // depth buffer test not done
- // blending
- if (blending_enabled) {
- switch (blend_function_source) {
- case nv2a_renderer::ZERO:
- s[3] = s[2] = s[1] = s[0] = 0;
+ case nv2a_renderer::GEQUAL:
+ if (stenc < stenv)
+ stencil_passed = false;
break;
- case nv2a_renderer::ONE:
+ case nv2a_renderer::ALWAYS:
default:
- s[3] = s[2] = s[1] = s[0] = 255;
- break;
- case nv2a_renderer::DST_COLOR:
- s[3] = fb[3];
- s[2] = fb[2];
- s[1] = fb[1];
- s[0] = fb[0];
- break;
- case nv2a_renderer::ONE_MINUS_DST_COLOR:
- s[3] = fb[3] ^ 255;
- s[2] = fb[2] ^ 255;
- s[1] = fb[1] ^ 255;
- s[0] = fb[0] ^ 255;
break;
- case nv2a_renderer::SRC_ALPHA:
- s[3] = s[2] = s[1] = s[0] = c[3];
- break;
- case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
- s[3] = s[2] = s[1] = s[0] = c[3] ^ 255;
+ }
+ if (stencil_passed == false) {
+ switch (stencil_op_fail) {
+ case nv2a_renderer::ZEROOP:
+ sten = 0;
+ break;
+ case nv2a_renderer::INVERTOP:
+ sten = sten ^ 255;
+ break;
+ case nv2a_renderer::KEEP:
+ default:
+ break;
+ case nv2a_renderer::REPLACE:
+ sten = stencil_ref;
+ break;
+ case nv2a_renderer::INCR:
+ if (sten < 255)
+ sten++;
+ break;
+ case nv2a_renderer::DECR:
+ if (sten > 0)
+ sten--;
+ break;
+ case nv2a_renderer::INCR_WRAP:
+ if (sten < 255)
+ sten++;
+ else
+ sten = 0;
+ break;
+ case nv2a_renderer::DECR_WRAP:
+ if (sten > 0)
+ sten--;
+ else
+ sten = 255;
+ break;
+ }
+ deptsten = (dep << 8) | sten;
+ *daddr = deptsten;
+ return;
+ }
+ }
+ // depth buffer test
+ depth_passed = true;
+ if (depth_test_enabled) {
+ switch (depth_function) {
+ case nv2a_renderer::NEVER:
+ depth_passed = false;
+ break;
+ case nv2a_renderer::LESS:
+ if (depth >= dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::EQUAL:
+ if (depth != dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::LEQUAL:
+ if (depth > dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::GREATER:
+ if (depth <= dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::NOTEQUAL:
+ if (depth == dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::GEQUAL:
+ if (depth < dep)
+ depth_passed = false;
+ break;
+ case nv2a_renderer::ALWAYS:
+ default:
+ break;
+ }
+ if (depth_passed == false) {
+ switch (stencil_op_zfail) {
+ case nv2a_renderer::ZEROOP:
+ sten = 0;
+ break;
+ case nv2a_renderer::INVERTOP:
+ sten = sten ^ 255;
+ break;
+ case nv2a_renderer::KEEP:
+ default:
+ break;
+ case nv2a_renderer::REPLACE:
+ sten = stencil_ref;
+ break;
+ case nv2a_renderer::INCR:
+ if (sten < 255)
+ sten++;
+ break;
+ case nv2a_renderer::DECR:
+ if (sten > 0)
+ sten--;
+ break;
+ case nv2a_renderer::INCR_WRAP:
+ if (sten < 255)
+ sten++;
+ else
+ sten = 0;
+ break;
+ case nv2a_renderer::DECR_WRAP:
+ if (sten > 0)
+ sten--;
+ else
+ sten = 255;
+ break;
+ }
+ deptsten = (dep << 8) | sten;
+ *daddr = deptsten;
+ return;
+ }
+ switch (stencil_op_zpass) {
+ case nv2a_renderer::ZEROOP:
+ sten = 0;
break;
- case nv2a_renderer::DST_ALPHA:
- s[3] = s[2] = s[1] = s[0] = fb[3];
+ case nv2a_renderer::INVERTOP:
+ sten = sten ^ 255;
break;
- case nv2a_renderer::ONE_MINUS_DST_ALPHA:
- s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255;
+ case nv2a_renderer::KEEP:
+ default:
break;
- case nv2a_renderer::CONSTANT_COLOR:
- s[3] = cc[3];
- s[2] = cc[2];
- s[1] = cc[1];
- s[0] = cc[0];
+ case nv2a_renderer::REPLACE:
+ sten = stencil_ref;
break;
- case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
- s[3] = cc[3] ^ 255;
- s[2] = cc[2] ^ 255;
- s[1] = cc[1] ^ 255;
- s[0] = cc[0] ^ 255;
+ case nv2a_renderer::INCR:
+ if (sten < 255)
+ sten++;
break;
- case nv2a_renderer::CONSTANT_ALPHA:
- s[3] = s[2] = s[1] = s[0] = cc[3];
+ case nv2a_renderer::DECR:
+ if (sten > 0)
+ sten--;
break;
- case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
- s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255;
+ case nv2a_renderer::INCR_WRAP:
+ if (sten < 255)
+ sten++;
+ else
+ sten = 0;
break;
- case nv2a_renderer::SRC_ALPHA_SATURATE:
- s[3] = 255;
- if (c[3] < (fb[3] ^ 255))
- s[2] = c[3];
+ case nv2a_renderer::DECR_WRAP:
+ if (sten > 0)
+ sten--;
else
- s[2] = fb[3];
- s[1] = s[0] = s[2];
+ sten = 255;
break;
}
+ }
+ // blending
+ if (blending_enabled) {
+ switch (blend_function_source) {
+ case nv2a_renderer::ZERO:
+ s[3] = s[2] = s[1] = s[0] = 0;
+ break;
+ case nv2a_renderer::ONE:
+ default:
+ s[3] = s[2] = s[1] = s[0] = 255;
+ break;
+ case nv2a_renderer::DST_COLOR:
+ s[3] = fb[3];
+ s[2] = fb[2];
+ s[1] = fb[1];
+ s[0] = fb[0];
+ break;
+ case nv2a_renderer::ONE_MINUS_DST_COLOR:
+ s[3] = fb[3] ^ 255;
+ s[2] = fb[2] ^ 255;
+ s[1] = fb[1] ^ 255;
+ s[0] = fb[0] ^ 255;
+ break;
+ case nv2a_renderer::SRC_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = c[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = c[3] ^ 255;
+ break;
+ case nv2a_renderer::DST_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = fb[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_DST_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = fb[3] ^ 255;
+ break;
+ case nv2a_renderer::CONSTANT_COLOR:
+ s[3] = cc[3];
+ s[2] = cc[2];
+ s[1] = cc[1];
+ s[0] = cc[0];
+ break;
+ case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
+ s[3] = cc[3] ^ 255;
+ s[2] = cc[2] ^ 255;
+ s[1] = cc[1] ^ 255;
+ s[0] = cc[0] ^ 255;
+ break;
+ case nv2a_renderer::CONSTANT_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = cc[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
+ s[3] = s[2] = s[1] = s[0] = cc[3] ^ 255;
+ break;
+ case nv2a_renderer::SRC_ALPHA_SATURATE:
+ s[3] = 255;
+ if (c[3] < (fb[3] ^ 255))
+ s[2] = c[3];
+ else
+ s[2] = fb[3];
+ s[1] = s[0] = s[2];
+ break;
+ }
switch (blend_function_destination) {
- case nv2a_renderer::ZERO:
- default:
- d[3] = d[2] = d[1] = d[0] = 0;
- break;
- case nv2a_renderer::ONE:
- d[3] = d[2] = d[1] = d[0] = 255;
- break;
- case nv2a_renderer::SRC_COLOR:
- d[3] = c[3];
- d[2] = c[2];
- d[1] = c[1];
- d[0] = c[0];
- break;
- case nv2a_renderer::ONE_MINUS_SRC_COLOR:
- d[3] = c[3] ^ 255;
- d[2] = c[2] ^ 255;
- d[1] = c[1] ^ 255;
- d[0] = c[0] ^ 255;
- break;
- case nv2a_renderer::SRC_ALPHA:
- d[3] = d[2] = d[1] = d[0] = c[3];
- break;
- case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
- d[3] = d[2] = d[1] = d[0] = c[3] ^ 255;
- break;
- case nv2a_renderer::DST_ALPHA:
- d[3] = d[2] = d[1] = d[0] = fb[3];
- break;
- case nv2a_renderer::ONE_MINUS_DST_ALPHA:
- d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255;
- break;
- case nv2a_renderer::CONSTANT_COLOR:
- d[3] = cc[3];
- d[2] = cc[2];
- d[1] = cc[1];
- d[0] = cc[0];
- break;
- case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
- d[3] = cc[3] ^ 255;
- d[2] = cc[2] ^ 255;
- d[1] = cc[1] ^ 255;
- d[0] = cc[0] ^ 255;
- break;
- case nv2a_renderer::CONSTANT_ALPHA:
- d[3] = d[2] = d[1] = d[0] = cc[3];
- break;
- case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
- d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255;
- break;
+ case nv2a_renderer::ZERO:
+ default:
+ d[3] = d[2] = d[1] = d[0] = 0;
+ break;
+ case nv2a_renderer::ONE:
+ d[3] = d[2] = d[1] = d[0] = 255;
+ break;
+ case nv2a_renderer::SRC_COLOR:
+ d[3] = c[3];
+ d[2] = c[2];
+ d[1] = c[1];
+ d[0] = c[0];
+ break;
+ case nv2a_renderer::ONE_MINUS_SRC_COLOR:
+ d[3] = c[3] ^ 255;
+ d[2] = c[2] ^ 255;
+ d[1] = c[1] ^ 255;
+ d[0] = c[0] ^ 255;
+ break;
+ case nv2a_renderer::SRC_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = c[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_SRC_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = c[3] ^ 255;
+ break;
+ case nv2a_renderer::DST_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = fb[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_DST_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = fb[3] ^ 255;
+ break;
+ case nv2a_renderer::CONSTANT_COLOR:
+ d[3] = cc[3];
+ d[2] = cc[2];
+ d[1] = cc[1];
+ d[0] = cc[0];
+ break;
+ case nv2a_renderer::ONE_MINUS_CONSTANT_COLOR:
+ d[3] = cc[3] ^ 255;
+ d[2] = cc[2] ^ 255;
+ d[1] = cc[1] ^ 255;
+ d[0] = cc[0] ^ 255;
+ break;
+ case nv2a_renderer::CONSTANT_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = cc[3];
+ break;
+ case nv2a_renderer::ONE_MINUS_CONSTANT_ALPHA:
+ d[3] = d[2] = d[1] = d[0] = cc[3] ^ 255;
+ break;
}
switch (blend_equation) {
- case nv2a_renderer::FUNC_ADD:
- c[3] = (c[3] * s[3] + fb[3] * d[3]) / 255;
- if (c[3] > 255)
- c[3] = 255;
- c[2] = (c[2] * s[2] + fb[2] * d[2]) / 255;
- if (c[2] > 255)
- c[2] = 255;
- c[1] = (c[1] * s[1] + fb[1] * d[1]) / 255;
- if (c[1] > 255)
- c[1] = 255;
- c[0] = (c[0] * s[0] + fb[0] * d[0]) / 255;
- if (c[0] > 255)
- c[0] = 255;
- break;
- case nv2a_renderer::FUNC_SUBTRACT:
- c[3] = (c[3] * s[3] - fb[3] * d[3]) / 255;
- if (c[3] < 0)
- c[3] = 255;
- c[2] = (c[2] * s[2] - fb[2] * d[2]) / 255;
- if (c[2] < 0)
- c[2] = 255;
- c[1] = (c[1] * s[1] - fb[1] * d[1]) / 255;
- if (c[1] < 0)
- c[1] = 255;
- c[0] = (c[0] * s[0] - fb[0] * d[0]) / 255;
- if (c[0] < 0)
- c[0] = 255;
- break;
- case nv2a_renderer::FUNC_REVERSE_SUBTRACT:
- c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255;
- if (c[3] < 0)
- c[3] = 255;
- c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255;
- if (c[2] < 0)
- c[2] = 255;
- c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255;
- if (c[1] < 0)
- c[1] = 255;
- c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255;
- if (c[0] < 0)
- c[0] = 255;
- break;
- case nv2a_renderer::MIN:
- c[3] = s[3];
- if (d[3] < c[3])
- c[3] = d[3];
- c[2] = s[2];
- if (d[2] < c[2])
- c[2] = d[2];
- c[1] = s[1];
- if (d[1] < c[1])
- c[1] = d[1];
- c[0] = s[0];
- if (d[0] < c[0])
- c[0] = d[0];
- break;
- case nv2a_renderer::MAX:
- c[3] = s[3];
- if (d[3] > c[3])
- c[3] = d[3];
- c[2] = s[2];
- if (d[2] > c[2])
- c[2] = d[2];
- c[1] = s[1];
- if (d[1] > c[1])
- c[1] = d[1];
- c[0] = s[0];
- if (d[0] > c[0])
- c[0] = d[0];
- break;
+ case nv2a_renderer::FUNC_ADD:
+ c[3] = (c[3] * s[3] + fb[3] * d[3]) / 255;
+ if (c[3] > 255)
+ c[3] = 255;
+ c[2] = (c[2] * s[2] + fb[2] * d[2]) / 255;
+ if (c[2] > 255)
+ c[2] = 255;
+ c[1] = (c[1] * s[1] + fb[1] * d[1]) / 255;
+ if (c[1] > 255)
+ c[1] = 255;
+ c[0] = (c[0] * s[0] + fb[0] * d[0]) / 255;
+ if (c[0] > 255)
+ c[0] = 255;
+ break;
+ case nv2a_renderer::FUNC_SUBTRACT:
+ c[3] = (c[3] * s[3] - fb[3] * d[3]) / 255;
+ if (c[3] < 0)
+ c[3] = 255;
+ c[2] = (c[2] * s[2] - fb[2] * d[2]) / 255;
+ if (c[2] < 0)
+ c[2] = 255;
+ c[1] = (c[1] * s[1] - fb[1] * d[1]) / 255;
+ if (c[1] < 0)
+ c[1] = 255;
+ c[0] = (c[0] * s[0] - fb[0] * d[0]) / 255;
+ if (c[0] < 0)
+ c[0] = 255;
+ break;
+ case nv2a_renderer::FUNC_REVERSE_SUBTRACT:
+ c[3] = (fb[3] * d[3] - c[3] * s[3]) / 255;
+ if (c[3] < 0)
+ c[3] = 255;
+ c[2] = (fb[2] * d[2] - c[2] * s[2]) / 255;
+ if (c[2] < 0)
+ c[2] = 255;
+ c[1] = (fb[1] * d[1] - c[1] * s[1]) / 255;
+ if (c[1] < 0)
+ c[1] = 255;
+ c[0] = (fb[0] * d[0] - c[0] * s[0]) / 255;
+ if (c[0] < 0)
+ c[0] = 255;
+ break;
+ case nv2a_renderer::MIN:
+ c[3] = s[3];
+ if (d[3] < c[3])
+ c[3] = d[3];
+ c[2] = s[2];
+ if (d[2] < c[2])
+ c[2] = d[2];
+ c[1] = s[1];
+ if (d[1] < c[1])
+ c[1] = d[1];
+ c[0] = s[0];
+ if (d[0] < c[0])
+ c[0] = d[0];
+ break;
+ case nv2a_renderer::MAX:
+ c[3] = s[3];
+ if (d[3] > c[3])
+ c[3] = d[3];
+ c[2] = s[2];
+ if (d[2] > c[2])
+ c[2] = d[2];
+ c[1] = s[1];
+ if (d[1] > c[1])
+ c[1] = d[1];
+ c[0] = s[0];
+ if (d[0] > c[0])
+ c[0] = d[0];
+ break;
}
}
// dithering not done
// logical operation
if (logical_operation_enabled) {
switch (logical_operation) {
- case nv2a_renderer::CLEAR:
- c[3] = 0;
- c[2] = 0;
- c[1] = 0;
- c[0] = 0;
- break;
- case nv2a_renderer::AND:
- c[3] = c[3] & fb[3];
- c[2] = c[2] & fb[2];
- c[1] = c[1] & fb[1];
- c[0] = c[0] & fb[0];
- break;
- case nv2a_renderer::AND_REVERSE:
- c[3] = c[3] & (fb[3] ^ 255);
- c[2] = c[2] & (fb[2] ^ 255);
- c[1] = c[1] & (fb[1] ^ 255);
- c[0] = c[0] & (fb[0] ^ 255);
- break;
- case nv2a_renderer::COPY:
- default:
- break;
- case nv2a_renderer::AND_INVERTED:
- c[3] = (c[3] ^ 255) & fb[3];
- c[2] = (c[2] ^ 255) & fb[2];
- c[1] = (c[1] ^ 255) & fb[1];
- c[0] = (c[0] ^ 255) & fb[0];
- break;
- case nv2a_renderer::NOOP:
- c[3] = fb[3];
- c[2] = fb[2];
- c[1] = fb[1];
- c[0] = fb[0];
- break;
- case nv2a_renderer::XOR:
- c[3] = c[3] ^ fb[3];
- c[2] = c[2] ^ fb[2];
- c[1] = c[1] ^ fb[1];
- c[0] = c[0] ^ fb[0];
- break;
- case nv2a_renderer::OR:
- c[3] = c[3] | fb[3];
- c[2] = c[2] | fb[2];
- c[1] = c[1] | fb[1];
- c[0] = c[0] | fb[0];
- break;
- case nv2a_renderer::NOR:
- c[3] = (c[3] | fb[3]) ^ 255;
- c[2] = (c[2] | fb[2]) ^ 255;
- c[1] = (c[1] | fb[1]) ^ 255;
- c[0] = (c[0] | fb[0]) ^ 255;
- break;
- case nv2a_renderer::EQUIV:
- c[3] = (c[3] ^ fb[3]) ^ 255;
- c[2] = (c[2] ^ fb[2]) ^ 255;
- c[1] = (c[1] ^ fb[1]) ^ 255;
- c[0] = (c[0] ^ fb[0]) ^ 255;
- break;
- case nv2a_renderer::INVERT:
- c[3] = fb[3] ^ 255;
- c[2] = fb[2] ^ 255;
- c[1] = fb[1] ^ 255;
- c[0] = fb[0] ^ 255;
- break;
- case nv2a_renderer::OR_REVERSE:
- c[3] = c[3] | (fb[3] ^ 255);
- c[2] = c[2] | (fb[2] ^ 255);
- c[1] = c[1] | (fb[1] ^ 255);
- c[0] = c[0] | (fb[0] ^ 255);
- break;
- case nv2a_renderer::COPY_INVERTED:
- c[3] = c[3] ^ 255;
- c[2] = c[2] ^ 255;
- c[1] = c[1] ^ 255;
- c[0] = c[0] ^ 255;
- break;
- case nv2a_renderer::OR_INVERTED:
- c[3] = (c[3] ^ 255) | fb[3];
- c[2] = (c[2] ^ 255) | fb[2];
- c[1] = (c[1] ^ 255) | fb[1];
- c[0] = (c[0] ^ 255) | fb[0];
- break;
- case nv2a_renderer::NAND:
- c[3] = (c[3] & fb[3]) ^ 255;
- c[2] = (c[2] & fb[2]) ^ 255;
- c[1] = (c[1] & fb[1]) ^ 255;
- c[0] = (c[0] & fb[0]) ^ 255;
- break;
- case nv2a_renderer::SET:
- c[3] = 255;
- c[2] = 255;
- c[1] = 255;
- c[0] = 255;
- break;
+ case nv2a_renderer::CLEAR:
+ c[3] = 0;
+ c[2] = 0;
+ c[1] = 0;
+ c[0] = 0;
+ break;
+ case nv2a_renderer::AND:
+ c[3] = c[3] & fb[3];
+ c[2] = c[2] & fb[2];
+ c[1] = c[1] & fb[1];
+ c[0] = c[0] & fb[0];
+ break;
+ case nv2a_renderer::AND_REVERSE:
+ c[3] = c[3] & (fb[3] ^ 255);
+ c[2] = c[2] & (fb[2] ^ 255);
+ c[1] = c[1] & (fb[1] ^ 255);
+ c[0] = c[0] & (fb[0] ^ 255);
+ break;
+ case nv2a_renderer::COPY:
+ default:
+ break;
+ case nv2a_renderer::AND_INVERTED:
+ c[3] = (c[3] ^ 255) & fb[3];
+ c[2] = (c[2] ^ 255) & fb[2];
+ c[1] = (c[1] ^ 255) & fb[1];
+ c[0] = (c[0] ^ 255) & fb[0];
+ break;
+ case nv2a_renderer::NOOP:
+ c[3] = fb[3];
+ c[2] = fb[2];
+ c[1] = fb[1];
+ c[0] = fb[0];
+ break;
+ case nv2a_renderer::XOR:
+ c[3] = c[3] ^ fb[3];
+ c[2] = c[2] ^ fb[2];
+ c[1] = c[1] ^ fb[1];
+ c[0] = c[0] ^ fb[0];
+ break;
+ case nv2a_renderer::OR:
+ c[3] = c[3] | fb[3];
+ c[2] = c[2] | fb[2];
+ c[1] = c[1] | fb[1];
+ c[0] = c[0] | fb[0];
+ break;
+ case nv2a_renderer::NOR:
+ c[3] = (c[3] | fb[3]) ^ 255;
+ c[2] = (c[2] | fb[2]) ^ 255;
+ c[1] = (c[1] | fb[1]) ^ 255;
+ c[0] = (c[0] | fb[0]) ^ 255;
+ break;
+ case nv2a_renderer::EQUIV:
+ c[3] = (c[3] ^ fb[3]) ^ 255;
+ c[2] = (c[2] ^ fb[2]) ^ 255;
+ c[1] = (c[1] ^ fb[1]) ^ 255;
+ c[0] = (c[0] ^ fb[0]) ^ 255;
+ break;
+ case nv2a_renderer::INVERT:
+ c[3] = fb[3] ^ 255;
+ c[2] = fb[2] ^ 255;
+ c[1] = fb[1] ^ 255;
+ c[0] = fb[0] ^ 255;
+ break;
+ case nv2a_renderer::OR_REVERSE:
+ c[3] = c[3] | (fb[3] ^ 255);
+ c[2] = c[2] | (fb[2] ^ 255);
+ c[1] = c[1] | (fb[1] ^ 255);
+ c[0] = c[0] | (fb[0] ^ 255);
+ break;
+ case nv2a_renderer::COPY_INVERTED:
+ c[3] = c[3] ^ 255;
+ c[2] = c[2] ^ 255;
+ c[1] = c[1] ^ 255;
+ c[0] = c[0] ^ 255;
+ break;
+ case nv2a_renderer::OR_INVERTED:
+ c[3] = (c[3] ^ 255) | fb[3];
+ c[2] = (c[2] ^ 255) | fb[2];
+ c[1] = (c[1] ^ 255) | fb[1];
+ c[0] = (c[0] ^ 255) | fb[0];
+ break;
+ case nv2a_renderer::NAND:
+ c[3] = (c[3] & fb[3]) ^ 255;
+ c[2] = (c[2] & fb[2]) ^ 255;
+ c[1] = (c[1] & fb[1]) ^ 255;
+ c[0] = (c[0] & fb[0]) ^ 255;
+ break;
+ case nv2a_renderer::SET:
+ c[3] = 255;
+ c[2] = 255;
+ c[1] = 255;
+ c[0] = 255;
+ break;
}
}
fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
- *((UINT32 *)addr) = fbcolor;
+ *addr = fbcolor;
+ if (depth_write_enabled)
+ dep = depth;
+ deptsten = (dep << 8) | sten;
+ *daddr = deptsten;
}
void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const nvidia_object_data &objectdata, int threadid)
@@ -1567,15 +1766,17 @@ void nv2a_renderer::render_color(INT32 scanline, const extent_t &extent, const n
x = extent.stopx - extent.startx - 1; // number of pixels to draw
while (x >= 0) {
UINT32 a8r8g8b8;
+ UINT32 z;
int ca, cr, cg, cb;
int xp = extent.startx + x; // x coordinate of current pixel
- cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
- cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
- cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
- ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0;
+ cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0;
+ cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0;
+ cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0;
+ ca = ((extent.param[PARAM_COLOR_A].start + (float)x*extent.param[PARAM_COLOR_A].dpdx))*255.0;
a8r8g8b8 = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices
- write_pixel(xp, scanline, a8r8g8b8);
+ z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx);
+ write_pixel(xp, scanline, a8r8g8b8, z);
x--;
}
}
@@ -1584,6 +1785,7 @@ void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent
{
int x;
UINT32 a8r8g8b8;
+ UINT32 z;
if (!objectdata.data->texture[0].enabled) {
return;
@@ -1595,10 +1797,11 @@ void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent
int up, vp;
int xp = extent.startx + x; // x coordinate of current pixel
- up = (extent.param[4].start + (float)x*extent.param[4].dpdx)*(float)(objectdata.data->texture[0].sizeu - 1); // x coordinate of texel in texture
- vp = extent.param[5].start*(float)(objectdata.data->texture[0].sizev - 1); // y coordinate of texel in texture
+ up = (extent.param[PARAM_TEXTURE0_U].start + (float)x*extent.param[PARAM_TEXTURE0_U].dpdx)*(float)(objectdata.data->texture[0].sizeu - 1); // x coordinate of texel in texture
+ vp = (extent.param[PARAM_TEXTURE0_V].start + (float)x*extent.param[PARAM_TEXTURE0_V].dpdx)*(float)(objectdata.data->texture[0].sizev - 1); // y coordinate of texel in texture
a8r8g8b8 = texture_get_texel(0, up, vp);
- write_pixel(xp, scanline, a8r8g8b8);
+ z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx);
+ write_pixel(xp, scanline, a8r8g8b8, z);
x--;
}
}
@@ -1610,6 +1813,7 @@ void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &ex
int ca, cr, cg, cb;
UINT32 color[6];
UINT32 a8r8g8b8;
+ UINT32 z;
int n;//,m,i,j,k;
color[0] = color[1] = color[2] = color[3] = color[4] = color[5] = 0;
@@ -1622,17 +1826,17 @@ void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &ex
xp = extent.startx + x;
// 1: fetch data
// 1.1: interpolated color from vertices
- cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
- cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
- cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
- ca = ((extent.param[3].start + (float)x*extent.param[3].dpdx))*255.0;
+ cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0;
+ cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0;
+ cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0;
+ ca = ((extent.param[PARAM_COLOR_A].start + (float)x*extent.param[PARAM_COLOR_A].dpdx))*255.0;
color[0] = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices
color[1] = 0; // lighting not yet
// 1.2: color for each of the 4 possible textures
for (n = 0; n < 4; n++) {
if (texture[n].enabled) {
- up = (extent.param[4 + n * 2].start + (float)x*extent.param[4 + n * 2].dpdx)*(float)(objectdata.data->texture[n].sizeu - 1);
- vp = extent.param[5 + n * 2].start*(float)(objectdata.data->texture[n].sizev - 1);
+ up = (extent.param[PARAM_TEXTURE0_U + n * 2].start + (float)x*extent.param[PARAM_TEXTURE0_U + n * 2].dpdx)*(float)(objectdata.data->texture[n].sizeu - 1);
+ vp = extent.param[PARAM_TEXTURE0_V + n * 2].start*(float)(objectdata.data->texture[n].sizev - 1);
color[n + 2] = texture_get_texel(n, up, vp);
}
}
@@ -1657,7 +1861,8 @@ void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &ex
combiner_final_output();
a8r8g8b8 = combiner_float_argb8(combiner.output);
// 3: write pixel
- write_pixel(xp, scanline, a8r8g8b8);
+ z = (extent.param[PARAM_Z].start + (float)x*extent.param[PARAM_Z].dpdx);
+ write_pixel(xp, scanline, a8r8g8b8, z);
x--;
}
osd_lock_release(combiner.lock);
@@ -1920,6 +2125,7 @@ int nv2a_renderer::read_vertices_0x1818(address_space & space, vertex_nv *destin
void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count)
{
+ vertex_nv vert[4];
int m, u;
// take each vertex with its attributes and obtain data for drawing
@@ -1930,29 +2136,30 @@ void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destinati
for (m = 0; m < count; m++) {
destination[m].x = source[m].attribute[0].fv[0];
destination[m].y = source[m].attribute[0].fv[1];
- for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a
+ for (u = PARAM_COLOR_B; u <= PARAM_COLOR_A; u++) // 0=b 1=g 2=r 3=a
destination[m].p[u] = source[m].attribute[3].fv[u];
for (u = 0; u < 4; u++) {
- destination[m].p[4 + u * 2] = source[m].attribute[9 + u].fv[0];
- destination[m].p[5 + u * 2] = source[m].attribute[9 + u].fv[1];
+ destination[m].p[PARAM_TEXTURE0_U + u * 2] = source[m].attribute[9 + u].fv[0];
+ destination[m].p[PARAM_TEXTURE0_V + u * 2] = source[m].attribute[9 + u].fv[1];
}
+ destination[m].p[PARAM_Z] = 0+0xffffff;
}
}
else {
// vertex program
- vertex_nv vert[4];
// run vertex program
vertexprogram.exec.process(vertexprogram.start_instruction, source, vert, count);
// copy data for poly.c
for (m = 0; m < count; m++) {
destination[m].x = vert[m].attribute[0].fv[0];
destination[m].y = vert[m].attribute[0].fv[1];
- for (u = 0; u < 4; u++) // 0=b 1=g 2=r 3=a
+ for (u = PARAM_COLOR_B; u <= PARAM_COLOR_A; u++) // 0=b 1=g 2=r 3=a
destination[m].p[u] = vert[m].attribute[3].fv[u];
for (u = 0; u < 4; u++) {
- destination[m].p[4 + u * 2] = vert[m].attribute[9 + u].fv[0];
- destination[m].p[5 + u * 2] = vert[m].attribute[9 + u].fv[1];
+ destination[m].p[PARAM_TEXTURE0_U + u * 2] = vert[m].attribute[9 + u].fv[0];
+ destination[m].p[PARAM_TEXTURE0_V + u * 2] = vert[m].attribute[9 + u].fv[1];
}
+ destination[m].p[PARAM_Z] = vert[m].attribute[0].fv[2];
}
}
}
@@ -1998,7 +2205,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
read_vertices_0x1810(space, vert, n + offset, 4);
convert_vertices_poly(vert, xy, 4);
- render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
+ render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
}
wait();
}
@@ -2013,7 +2220,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
for (n = 0; n <= count; n++) {
read_vertices_0x1810(space, vert + ((n + 2) & 3), offset + n, 1);
convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
}
wait();
}
@@ -2052,7 +2259,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vert, xy, 4);
- render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
+ render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
}
while (countlen > 0) {
data = space.read_dword(address);
@@ -2077,7 +2284,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
address = address + c * 4;
countlen = countlen - c;
convert_vertices_poly(vert, xy, 3);
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[1], xy[2]); // 4 rgba, 4 texture units 2 uv
}
while (countlen > 0) {
data = space.read_dword(address);
@@ -2108,7 +2315,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
if (xy[(n + 2) & 3].y > 293800000.0)
xy[(n + 2) & 3].y = xy[(n + 2) & 3].y + 1.0;
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
}
}
while (countlen > 0) {
@@ -2170,7 +2377,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
}
address = address + c * 4;
convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[0], xy[(~n & 1) + 1], xy[(n & 1) + 1]);
}
wait();
}
@@ -2198,7 +2405,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
break;
}
address = address + c * 4;
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[((n & 1) + n) & 3], xy[((~n & 1) + n) & 3], xy[(2 + n) & 3]);
}
wait();
}
@@ -2217,7 +2424,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
break;
}
address = address + c * 4;
- render_polygon<4>(fb.cliprect(), renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
+ render_polygon<4>(limits_rendertarget, renderspans, 4 + 4 * 2, xy); // 4 rgba, 4 texture units 2 uv
}
wait();
}
@@ -2245,8 +2452,8 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
return;
}
address = address + c * 4;
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]);
- render_triangle(fb.cliprect(), renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[n & 3], xy[(n + 1) & 3], xy[(n + 2) & 3]);
+ render_triangle(limits_rendertarget, renderspans, 4 + 4 * 2, xy[(n + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]);
}
wait();
}
@@ -2320,26 +2527,78 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
space.write_dword(base + offset, data);
countlen--;
}
+ if (maddress == 0x1d98) {
+ countlen--;
+ }
+ if (maddress == 0x1d9c) {
+ countlen--;
+ }
if (maddress == 0x1d94) {
+ int m;
+
+ m = channel[chanel][subchannel].object.method[0x1d7c / 4];
+ if (channel[chanel][subchannel].object.method[0x0208 / 4] & 0x2000)
+ m = 2;
+ else
+ m = 1;
// possible buffers: color, depth, stencil, and accumulation
// clear framebuffer
if (data & 0xf0) {
+ bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
// clear colors
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
- fb.fill(color);
+ bm.fill(color);
//printf("clearscreen\n\r");
}
- if (data & 0x03) {
- // clear stencil+zbuffer
+ if (data & 0x01) {
+ bitmap_rgb32 bm(depthbuffer, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
+ // clear zbuffer
+ UINT32 depth = channel[chanel][subchannel].object.method[0x1d8c / 4];
+ bm.fill(depth);
}
countlen--;
}
+ if (maddress == 0x0200) {
+ //x = data & 0xffff;
+ //w = (data >> 16) & 0xffff;
+ limits_rendertarget.setx(0,((data >> 16) & 0xffff)-1);
+ }
+ if (maddress == 0x0204) {
+ //y = data & 0xffff;
+ //h = (data >> 16) & 0xffff;
+ limits_rendertarget.sety(0,((data >> 16) & 0xffff)-1);
+ }
+ if (maddress == 0x020c) {
+ // line size ?
+ pitch_rendertarget=data & 0xffff;
+ pitch_depthbuffer=(data >> 16) & 0xffff;
+ //printf("Pitch color %04X zbuffer %04X\n\r",pitch_rendertarget,pitch_depthbuffer);
+ countlen--;
+ }
+ if (maddress == 0x0100) {
+ // just temporarily
+ if ((data & 0x1f) == 1) {
+ data = data >> 5;
+ data = data & 0x0ffffff0;
+ displayedtarget = (UINT32 *)space.get_write_ptr(data);
+ }
+ }
if (maddress == 0x0210) {
// framebuffer offset ?
+ rendertarget = (UINT32 *)space.get_write_ptr(data);
+ //printf("Render target at %08X\n\r",data);
countlen--;
}
if (maddress == 0x0214) {
// zbuffer offset ?
+ depthbuffer = (UINT32 *)space.get_write_ptr(data);
+ //printf("Depth buffer at %08X\n\r",data);
+ if ((data == 0) || (data > 0x7ffffffc))
+ depth_write_enabled = false;
+ else if (channel[chanel][subchannel].object.method[0x035c / 4] != 0)
+ depth_write_enabled = true;
+ else
+ depth_write_enabled = false;
countlen--;
}
if (maddress == 0x0300) {
@@ -2357,6 +2616,41 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
else
blending_enabled = data != 0;
}
+ if (maddress == 0x030c) {
+ depth_test_enabled = data != 0;
+ }
+ if (maddress == 0x0354) {
+ depth_function = data;
+ }
+ if (maddress == 0x035c) {
+ UINT32 g = channel[chanel][subchannel].object.method[0x0214 / 4];
+ depth_write_enabled = data != 0;
+ if ((g == 0) || (g > 0x7ffffffc))
+ depth_write_enabled = false;
+ }
+ if (maddress == 0x032c) {
+ stencil_test_enabled = data != 0;
+ }
+ if (maddress == 0x0364) {
+ stencil_func = data;
+ }
+ if (maddress == 0x0368) {
+ if (data > 255)
+ data = 255;
+ stencil_ref = data;
+ }
+ if (maddress == 0x036c) {
+ stencil_mask = data;
+ }
+ if (maddress == 0x0370) {
+ stencil_op_fail = data;
+ }
+ if (maddress == 0x0374) {
+ stencil_op_zfail = data;
+ }
+ if (maddress == 0x0378) {
+ stencil_op_zpass = data;
+ }
if (maddress == 0x0344) {
blend_function_source = data;
}
@@ -3285,11 +3579,13 @@ bool nv2a_renderer::vblank_callback(screen_device &screen, bool state)
UINT32 nv2a_renderer::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0);
- UINT32 *src = (UINT32 *)fb.raw_pixptr(0, 0);
+ if (displayedtarget != NULL) {
+ bitmap_rgb32 bm(displayedtarget, 640, 480, 640);
+ UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0);
- //printf("updatescreen\n\r");
- memcpy(dst, src, bitmap.rowbytes()*bitmap.height());
+ //printf("updatescreen %08X\n\r",pcrtc[0x800/4]);
+ memcpy(dst, displayedtarget, bitmap.rowbytes()*bitmap.height());
+ }
return 0;
}
@@ -3372,6 +3668,10 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
return;
COMBINE_DATA(pcrtc + e);
+ if (e == 0x800 / 4) {
+ displayedtarget = (UINT32 *)space.get_read_ptr(data);
+ //printf("crtc buffer %08X\n\r", data);
+ }
//logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
}
else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) {