mirror of
https://github.com/holub/mame
synced 2025-05-18 11:39:29 +03:00
chihiro: added support for zbuffer and stencil plus render target methods [Samuele Zannoli]
This commit is contained in:
parent
f815c4fe2a
commit
075a8929c6
@ -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
|
objects have methods used to do drawing
|
||||||
most methods set parameters, others actually draw
|
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:
|
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(channel, 0, sizeof(channel));
|
||||||
memset(pfifo, 0, sizeof(pfifo));
|
memset(pfifo, 0, sizeof(pfifo));
|
||||||
@ -158,7 +158,6 @@ public:
|
|||||||
memset(pmc, 0, sizeof(pmc));
|
memset(pmc, 0, sizeof(pmc));
|
||||||
memset(ramin, 0, sizeof(ramin));
|
memset(ramin, 0, sizeof(ramin));
|
||||||
computedilated();
|
computedilated();
|
||||||
fb.allocate(640, 480);
|
|
||||||
objectdata = &(object_data_alloc());
|
objectdata = &(object_data_alloc());
|
||||||
objectdata->data = this;
|
objectdata->data = this;
|
||||||
combiner.used = 0;
|
combiner.used = 0;
|
||||||
@ -169,6 +168,16 @@ public:
|
|||||||
alpha_test_enabled = false;
|
alpha_test_enabled = false;
|
||||||
alpha_reference = 0;
|
alpha_reference = 0;
|
||||||
alpha_func = nv2a_renderer::ALWAYS;
|
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;
|
blending_enabled = false;
|
||||||
blend_equation = nv2a_renderer::FUNC_ADD;
|
blend_equation = nv2a_renderer::FUNC_ADD;
|
||||||
blend_color = 0;
|
blend_color = 0;
|
||||||
@ -176,6 +185,12 @@ public:
|
|||||||
blend_function_source = nv2a_renderer::ONE;
|
blend_function_source = nv2a_renderer::ONE;
|
||||||
logical_operation_enabled = false;
|
logical_operation_enabled = false;
|
||||||
logical_operation = nv2a_renderer::COPY;
|
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_texttype = -1;
|
||||||
debug_grab_textfile = NULL;
|
debug_grab_textfile = NULL;
|
||||||
memset(vertex_attribute_words, 0, sizeof(vertex_attribute_words));
|
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_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);
|
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);
|
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_registers(UINT32 argb8[6]);
|
||||||
void combiner_initialize_stage(int stage_number);
|
void combiner_initialize_stage(int stage_number);
|
||||||
void combiner_initialize_final();
|
void combiner_initialize_final();
|
||||||
@ -247,6 +262,12 @@ public:
|
|||||||
UINT32 ramin[0x100000 / 4];
|
UINT32 ramin[0x100000 / 4];
|
||||||
UINT32 dma_offset[2];
|
UINT32 dma_offset[2];
|
||||||
UINT32 dma_size[2];
|
UINT32 dma_size[2];
|
||||||
|
rectangle limits_rendertarget;
|
||||||
|
UINT32 pitch_rendertarget;
|
||||||
|
UINT32 pitch_depthbuffer;
|
||||||
|
UINT32 *rendertarget;
|
||||||
|
UINT32 *depthbuffer;
|
||||||
|
UINT32 *displayedtarget;
|
||||||
UINT32 vertexbuffer_address[16];
|
UINT32 vertexbuffer_address[16];
|
||||||
int vertexbuffer_stride[16];
|
int vertexbuffer_stride[16];
|
||||||
int vertexbuffer_kind[16];
|
int vertexbuffer_kind[16];
|
||||||
@ -371,6 +392,16 @@ public:
|
|||||||
bool alpha_test_enabled;
|
bool alpha_test_enabled;
|
||||||
int alpha_func;
|
int alpha_func;
|
||||||
int alpha_reference;
|
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;
|
bool blending_enabled;
|
||||||
int blend_equation;
|
int blend_equation;
|
||||||
int blend_function_source;
|
int blend_function_source;
|
||||||
@ -398,7 +429,6 @@ public:
|
|||||||
int enabled_vertex_attributes;
|
int enabled_vertex_attributes;
|
||||||
int vertex_attribute_words[16];
|
int vertex_attribute_words[16];
|
||||||
int vertex_attribute_offset[16];
|
int vertex_attribute_offset[16];
|
||||||
bitmap_rgb32 fb;
|
|
||||||
UINT32 dilated0[16][2048];
|
UINT32 dilated0[16][2048];
|
||||||
UINT32 dilated1[16][2048];
|
UINT32 dilated1[16][2048];
|
||||||
int dilatechose[256];
|
int dilatechose[256];
|
||||||
@ -406,6 +436,21 @@ public:
|
|||||||
int debug_grab_texttype;
|
int debug_grab_texttype;
|
||||||
char *debug_grab_textfile;
|
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 {
|
enum NV2A_BEGIN_END {
|
||||||
STOP = 0,
|
STOP = 0,
|
||||||
POINTS = 1,
|
POINTS = 1,
|
||||||
|
@ -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 *addr, *daddr;
|
||||||
UINT32 fbcolor;
|
UINT32 fbcolor, deptsten;
|
||||||
UINT32 c[4], fb[4], s[4], d[4], cc[4];
|
UINT32 c[4], fb[4], s[4], d[4], cc[4];
|
||||||
|
UINT32 dep, sten, stenc, stenv;
|
||||||
|
bool stencil_passed;
|
||||||
|
bool depth_passed;
|
||||||
|
|
||||||
addr = this->fb.raw_pixptr(y, x);
|
addr=rendertarget + (pitch_rendertarget / 4)*y + x;
|
||||||
fbcolor = *((UINT32 *)addr);
|
fbcolor = *addr;
|
||||||
|
daddr=depthbuffer + (pitch_depthbuffer / 4)*y + x;
|
||||||
|
deptsten = *daddr;
|
||||||
c[3] = color >> 24;
|
c[3] = color >> 24;
|
||||||
c[2] = (color >> 16) & 255;
|
c[2] = (color >> 16) & 255;
|
||||||
c[1] = (color >> 8) & 255;
|
c[1] = (color >> 8) & 255;
|
||||||
@ -1233,6 +1238,12 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
|
|||||||
cc[2] = (blend_color >> 16) & 255;
|
cc[2] = (blend_color >> 16) & 255;
|
||||||
cc[1] = (blend_color >> 8) & 255;
|
cc[1] = (blend_color >> 8) & 255;
|
||||||
cc[0] = blend_color & 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
|
// ownership test and scissor test not done
|
||||||
// alpha test
|
// alpha test
|
||||||
if (alpha_test_enabled) {
|
if (alpha_test_enabled) {
|
||||||
@ -1268,8 +1279,192 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// stencil test not done
|
// stencil test
|
||||||
// depth buffer test not done
|
stencil_passed = true;
|
||||||
|
if (stencil_test_enabled) {
|
||||||
|
stenc=stencil_mask & stencil_ref;
|
||||||
|
stenv=stencil_mask & sten;
|
||||||
|
switch (stencil_func) {
|
||||||
|
case nv2a_renderer::NEVER:
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::LESS:
|
||||||
|
if (stenc >= stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::EQUAL:
|
||||||
|
if (stenc != stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::LEQUAL:
|
||||||
|
if (stenc > stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::GREATER:
|
||||||
|
if (stenc <= stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::NOTEQUAL:
|
||||||
|
if (stenc == stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::GEQUAL:
|
||||||
|
if (stenc < stenv)
|
||||||
|
stencil_passed = false;
|
||||||
|
break;
|
||||||
|
case nv2a_renderer::ALWAYS:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
// blending
|
// blending
|
||||||
if (blending_enabled) {
|
if (blending_enabled) {
|
||||||
switch (blend_function_source) {
|
switch (blend_function_source) {
|
||||||
@ -1555,7 +1750,11 @@ void nv2a_renderer::write_pixel(int x, int y, UINT32 color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fbcolor = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0];
|
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)
|
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
|
x = extent.stopx - extent.startx - 1; // number of pixels to draw
|
||||||
while (x >= 0) {
|
while (x >= 0) {
|
||||||
UINT32 a8r8g8b8;
|
UINT32 a8r8g8b8;
|
||||||
|
UINT32 z;
|
||||||
int ca, cr, cg, cb;
|
int ca, cr, cg, cb;
|
||||||
int xp = extent.startx + x; // x coordinate of current pixel
|
int xp = extent.startx + x; // x coordinate of current pixel
|
||||||
|
|
||||||
cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
|
cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0;
|
||||||
cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
|
cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0;
|
||||||
cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
|
cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0;
|
||||||
ca = ((extent.param[3].start + (float)x*extent.param[3].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
|
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--;
|
x--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1584,6 +1785,7 @@ void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
UINT32 a8r8g8b8;
|
UINT32 a8r8g8b8;
|
||||||
|
UINT32 z;
|
||||||
|
|
||||||
if (!objectdata.data->texture[0].enabled) {
|
if (!objectdata.data->texture[0].enabled) {
|
||||||
return;
|
return;
|
||||||
@ -1595,10 +1797,11 @@ void nv2a_renderer::render_texture_simple(INT32 scanline, const extent_t &extent
|
|||||||
int up, vp;
|
int up, vp;
|
||||||
int xp = extent.startx + x; // x coordinate of current pixel
|
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
|
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[5].start*(float)(objectdata.data->texture[0].sizev - 1); // y 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);
|
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--;
|
x--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1610,6 +1813,7 @@ void nv2a_renderer::render_register_combiners(INT32 scanline, const extent_t &ex
|
|||||||
int ca, cr, cg, cb;
|
int ca, cr, cg, cb;
|
||||||
UINT32 color[6];
|
UINT32 color[6];
|
||||||
UINT32 a8r8g8b8;
|
UINT32 a8r8g8b8;
|
||||||
|
UINT32 z;
|
||||||
int n;//,m,i,j,k;
|
int n;//,m,i,j,k;
|
||||||
|
|
||||||
color[0] = color[1] = color[2] = color[3] = color[4] = color[5] = 0;
|
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;
|
xp = extent.startx + x;
|
||||||
// 1: fetch data
|
// 1: fetch data
|
||||||
// 1.1: interpolated color from vertices
|
// 1.1: interpolated color from vertices
|
||||||
cb = ((extent.param[0].start + (float)x*extent.param[0].dpdx))*255.0;
|
cb = ((extent.param[PARAM_COLOR_B].start + (float)x*extent.param[PARAM_COLOR_B].dpdx))*255.0;
|
||||||
cg = ((extent.param[1].start + (float)x*extent.param[1].dpdx))*255.0;
|
cg = ((extent.param[PARAM_COLOR_G].start + (float)x*extent.param[PARAM_COLOR_G].dpdx))*255.0;
|
||||||
cr = ((extent.param[2].start + (float)x*extent.param[2].dpdx))*255.0;
|
cr = ((extent.param[PARAM_COLOR_R].start + (float)x*extent.param[PARAM_COLOR_R].dpdx))*255.0;
|
||||||
ca = ((extent.param[3].start + (float)x*extent.param[3].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[0] = (ca << 24) + (cr << 16) + (cg << 8) + cb; // pixel color obtained by interpolating the colors of the vertices
|
||||||
color[1] = 0; // lighting not yet
|
color[1] = 0; // lighting not yet
|
||||||
// 1.2: color for each of the 4 possible textures
|
// 1.2: color for each of the 4 possible textures
|
||||||
for (n = 0; n < 4; n++) {
|
for (n = 0; n < 4; n++) {
|
||||||
if (texture[n].enabled) {
|
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);
|
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[5 + n * 2].start*(float)(objectdata.data->texture[n].sizev - 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);
|
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();
|
combiner_final_output();
|
||||||
a8r8g8b8 = combiner_float_argb8(combiner.output);
|
a8r8g8b8 = combiner_float_argb8(combiner.output);
|
||||||
// 3: write pixel
|
// 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--;
|
x--;
|
||||||
}
|
}
|
||||||
osd_lock_release(combiner.lock);
|
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)
|
void nv2a_renderer::convert_vertices_poly(vertex_nv *source, vertex_t *destination, int count)
|
||||||
{
|
{
|
||||||
|
vertex_nv vert[4];
|
||||||
int m, u;
|
int m, u;
|
||||||
|
|
||||||
// take each vertex with its attributes and obtain data for drawing
|
// 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++) {
|
for (m = 0; m < count; m++) {
|
||||||
destination[m].x = source[m].attribute[0].fv[0];
|
destination[m].x = source[m].attribute[0].fv[0];
|
||||||
destination[m].y = source[m].attribute[0].fv[1];
|
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];
|
destination[m].p[u] = source[m].attribute[3].fv[u];
|
||||||
for (u = 0; u < 4; u++) {
|
for (u = 0; u < 4; u++) {
|
||||||
destination[m].p[4 + u * 2] = source[m].attribute[9 + u].fv[0];
|
destination[m].p[PARAM_TEXTURE0_U + 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_V + u * 2] = source[m].attribute[9 + u].fv[1];
|
||||||
}
|
}
|
||||||
|
destination[m].p[PARAM_Z] = 0+0xffffff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// vertex program
|
// vertex program
|
||||||
vertex_nv vert[4];
|
|
||||||
// run vertex program
|
// run vertex program
|
||||||
vertexprogram.exec.process(vertexprogram.start_instruction, source, vert, count);
|
vertexprogram.exec.process(vertexprogram.start_instruction, source, vert, count);
|
||||||
// copy data for poly.c
|
// copy data for poly.c
|
||||||
for (m = 0; m < count; m++) {
|
for (m = 0; m < count; m++) {
|
||||||
destination[m].x = vert[m].attribute[0].fv[0];
|
destination[m].x = vert[m].attribute[0].fv[0];
|
||||||
destination[m].y = vert[m].attribute[0].fv[1];
|
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];
|
destination[m].p[u] = vert[m].attribute[3].fv[u];
|
||||||
for (u = 0; u < 4; u++) {
|
for (u = 0; u < 4; u++) {
|
||||||
destination[m].p[4 + u * 2] = vert[m].attribute[9 + u].fv[0];
|
destination[m].p[PARAM_TEXTURE0_U + 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_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);
|
read_vertices_0x1810(space, vert, n + offset, 4);
|
||||||
convert_vertices_poly(vert, xy, 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();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2013,7 +2220,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
for (n = 0; n <= count; n++) {
|
for (n = 0; n <= count; n++) {
|
||||||
read_vertices_0x1810(space, vert + ((n + 2) & 3), offset + n, 1);
|
read_vertices_0x1810(space, vert + ((n + 2) & 3), offset + n, 1);
|
||||||
convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 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();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2052,7 +2259,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
address = address + c * 4;
|
address = address + c * 4;
|
||||||
countlen = countlen - c;
|
countlen = countlen - c;
|
||||||
convert_vertices_poly(vert, xy, 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
|
||||||
}
|
}
|
||||||
while (countlen > 0) {
|
while (countlen > 0) {
|
||||||
data = space.read_dword(address);
|
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;
|
address = address + c * 4;
|
||||||
countlen = countlen - c;
|
countlen = countlen - c;
|
||||||
convert_vertices_poly(vert, xy, 3);
|
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) {
|
while (countlen > 0) {
|
||||||
data = space.read_dword(address);
|
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);
|
convert_vertices_poly(vert + ((n + 2) & 3), xy + ((n + 2) & 3), 1);
|
||||||
if (xy[(n + 2) & 3].y > 293800000.0)
|
if (xy[(n + 2) & 3].y > 293800000.0)
|
||||||
xy[(n + 2) & 3].y = xy[(n + 2) & 3].y + 1.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) {
|
while (countlen > 0) {
|
||||||
@ -2170,7 +2377,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
}
|
}
|
||||||
address = address + c * 4;
|
address = address + c * 4;
|
||||||
convert_vertices_poly(vert + ((n & 1) + 1), xy + ((n & 1) + 1), 1);
|
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();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2198,7 +2405,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
address = address + c * 4;
|
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();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2217,7 +2424,7 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
address = address + c * 4;
|
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();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2245,8 +2452,8 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
address = address + c * 4;
|
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(limits_rendertarget, 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 + 2) & 3], xy[(n + 1) & 3], xy[(n + 3) & 3]);
|
||||||
}
|
}
|
||||||
wait();
|
wait();
|
||||||
}
|
}
|
||||||
@ -2320,26 +2527,78 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
space.write_dword(base + offset, data);
|
space.write_dword(base + offset, data);
|
||||||
countlen--;
|
countlen--;
|
||||||
}
|
}
|
||||||
|
if (maddress == 0x1d98) {
|
||||||
|
countlen--;
|
||||||
|
}
|
||||||
|
if (maddress == 0x1d9c) {
|
||||||
|
countlen--;
|
||||||
|
}
|
||||||
if (maddress == 0x1d94) {
|
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
|
// possible buffers: color, depth, stencil, and accumulation
|
||||||
// clear framebuffer
|
// clear framebuffer
|
||||||
if (data & 0xf0) {
|
if (data & 0xf0) {
|
||||||
|
bitmap_rgb32 bm(rendertarget, (limits_rendertarget.right() + 1) * m, (limits_rendertarget.bottom() + 1) * m, pitch_rendertarget / 4); // why *2 ?
|
||||||
// clear colors
|
// clear colors
|
||||||
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
|
UINT32 color = channel[chanel][subchannel].object.method[0x1d90 / 4];
|
||||||
fb.fill(color);
|
bm.fill(color);
|
||||||
//printf("clearscreen\n\r");
|
//printf("clearscreen\n\r");
|
||||||
}
|
}
|
||||||
if (data & 0x03) {
|
if (data & 0x01) {
|
||||||
// clear stencil+zbuffer
|
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--;
|
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) {
|
if (maddress == 0x0210) {
|
||||||
// framebuffer offset ?
|
// framebuffer offset ?
|
||||||
|
rendertarget = (UINT32 *)space.get_write_ptr(data);
|
||||||
|
//printf("Render target at %08X\n\r",data);
|
||||||
countlen--;
|
countlen--;
|
||||||
}
|
}
|
||||||
if (maddress == 0x0214) {
|
if (maddress == 0x0214) {
|
||||||
// zbuffer offset ?
|
// 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--;
|
countlen--;
|
||||||
}
|
}
|
||||||
if (maddress == 0x0300) {
|
if (maddress == 0x0300) {
|
||||||
@ -2357,6 +2616,41 @@ void nv2a_renderer::geforce_exec_method(address_space & space, UINT32 chanel, UI
|
|||||||
else
|
else
|
||||||
blending_enabled = data != 0;
|
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) {
|
if (maddress == 0x0344) {
|
||||||
blend_function_source = data;
|
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 nv2a_renderer::screen_update_callback(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
|
if (displayedtarget != NULL) {
|
||||||
|
bitmap_rgb32 bm(displayedtarget, 640, 480, 640);
|
||||||
UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0);
|
UINT32 *dst = (UINT32 *)bitmap.raw_pixptr(0, 0);
|
||||||
UINT32 *src = (UINT32 *)fb.raw_pixptr(0, 0);
|
|
||||||
|
|
||||||
//printf("updatescreen\n\r");
|
//printf("updatescreen %08X\n\r",pcrtc[0x800/4]);
|
||||||
memcpy(dst, src, bitmap.rowbytes()*bitmap.height());
|
memcpy(dst, displayedtarget, bitmap.rowbytes()*bitmap.height());
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3372,6 +3668,10 @@ WRITE32_MEMBER(nv2a_renderer::geforce_w)
|
|||||||
if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
|
if (e >= (sizeof(pcrtc) / sizeof(UINT32)))
|
||||||
return;
|
return;
|
||||||
COMBINE_DATA(pcrtc + e);
|
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);
|
//logerror("NV_2A: write PCRTC[%06X]=%08X\n",offset*4-0x00600000,data & mem_mask);
|
||||||
}
|
}
|
||||||
else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) {
|
else if ((offset >= 0x00000000 / 4) && (offset < 0x00001000 / 4)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user