cobra.c: Implemented framebuffer reads and writes (nw)

This commit is contained in:
Ville Linde 2012-08-05 14:17:13 +00:00
parent 4c9f548bc6
commit 20588708f6

View File

@ -154,7 +154,7 @@
Gfx: Gfx:
- -
Fails on memcheck_teximage(), memcheck_framebuf(), drawcheck() Fails on drawcheck()
0x3806dc(): Waits for [0x7f7ffc] to change (in main) 0x3806dc(): Waits for [0x7f7ffc] to change (in main)
@ -170,6 +170,10 @@
0xa0 0xa4 0xa8 0xac 0xa0 0xa4 0xa8 0xac
0xb0 0xb4 0xb8 0xbc 0xb0 0xb4 0xb8 0xbc
0x00114: High word: framebuffer pitch? Low word: framebuffer pixel size?
0x00118: High word: FB pixel read X pos, Low word: FB pixel read Y pos
0x0011c: Same as above?
0x40160: Some viewport register? (high word: 192, low word: 150) 0x40160: Some viewport register? (high word: 192, low word: 150)
0x40164: Some viewport register? (high word: 352, low word: 275) 0x40164: Some viewport register? (high word: 352, low word: 275)
0x40170: Some viewport register? (high word: 160, low word: 125) 0x40170: Some viewport register? (high word: 160, low word: 125)
@ -203,12 +207,16 @@ struct cobra_polydata
class cobra_renderer : public poly_manager<float, cobra_polydata, 6, 10000> class cobra_renderer : public poly_manager<float, cobra_polydata, 6, 10000>
{ {
public: public:
cobra_renderer(running_machine &machine, bitmap_rgb32 *fb) cobra_renderer(running_machine &machine)
: poly_manager<float, cobra_polydata, 6, 10000>(machine) : poly_manager<float, cobra_polydata, 6, 10000>(machine)
{ {
m_fb = fb; m_texture_ram = auto_alloc_array(machine, UINT32, 0x100000);
m_texture_ram = auto_alloc_array(machine, UINT32, 0x1000000); m_framebuffer = auto_bitmap_rgb32_alloc(machine, 1024, 1024);
m_backbuffer = auto_bitmap_rgb32_alloc(machine, 1024, 1024);
m_overlay = auto_bitmap_rgb32_alloc(machine, 1024, 1024);
m_zbuffer = auto_bitmap_ind32_alloc(machine, 1024, 1024);
m_stencil = auto_bitmap_ind32_alloc(machine, 1024, 1024);
// TODO: these are probably set by some 3D registers // TODO: these are probably set by some 3D registers
m_texture_width = 128; m_texture_width = 128;
@ -226,8 +234,14 @@ public:
UINT32 gfx_read_gram(UINT32 address); UINT32 gfx_read_gram(UINT32 address);
void gfx_write_gram(UINT32 address, UINT32 data); void gfx_write_gram(UINT32 address, UINT32 data);
void display(bitmap_rgb32 *bitmap, const rectangle &cliprect);
private: private:
bitmap_rgb32 *m_fb; bitmap_rgb32 *m_framebuffer;
bitmap_rgb32 *m_backbuffer;
bitmap_rgb32 *m_overlay;
bitmap_ind32 *m_zbuffer;
bitmap_ind32 *m_stencil;
UINT32 *m_texture_ram; UINT32 *m_texture_ram;
int m_texture_width; int m_texture_width;
@ -340,8 +354,6 @@ public:
UINT32 *m_comram[2]; UINT32 *m_comram[2];
int m_comram_page; int m_comram_page;
bitmap_rgb32 *m_framebuffer;
int m_main_debug_state; int m_main_debug_state;
int m_main_debug_state_wc; int m_main_debug_state_wc;
int m_sub_debug_state; int m_sub_debug_state;
@ -372,7 +384,7 @@ public:
void cobra_renderer::render_color_scan(INT32 scanline, const extent_t &extent, const cobra_polydata &extradata, int threadid) void cobra_renderer::render_color_scan(INT32 scanline, const extent_t &extent, const cobra_polydata &extradata, int threadid)
{ {
/* /*
UINT32 *fb = &m_fb->pix32(scanline); UINT32 *fb = &m_framebuffer->pix32(scanline);
UINT32 color = 0xffff0000; // TODO UINT32 color = 0xffff0000; // TODO
@ -389,7 +401,7 @@ void cobra_renderer::render_texture_scan(INT32 scanline, const extent_t &extent,
float v = extent.param[1].start; float v = extent.param[1].start;
float du = extent.param[0].dpdx; float du = extent.param[0].dpdx;
float dv = extent.param[1].dpdx; float dv = extent.param[1].dpdx;
UINT32 *fb = &m_fb->pix32(scanline); UINT32 *fb = &m_framebuffer->pix32(scanline);
for (int x = extent.startx; x < extent.stopx; x++) for (int x = extent.startx; x < extent.stopx; x++)
{ {
@ -429,7 +441,7 @@ void cobra_renderer::draw_point(const rectangle &visarea, vertex_t &v, UINT32 co
if (x >= visarea.min_x && x <= visarea.max_x && if (x >= visarea.min_x && x <= visarea.max_x &&
y >= visarea.min_y && y <= visarea.max_y) y >= visarea.min_y && y <= visarea.max_y)
{ {
UINT32 *fb = &m_fb->pix32(y); UINT32 *fb = &m_framebuffer->pix32(y);
fb[x] = color; fb[x] = color;
} }
} }
@ -457,7 +469,7 @@ void cobra_renderer::draw_line(const rectangle &visarea, vertex_t &v1, vertex_t
{ {
int y = y1 + (dy * (float)(x - x1) / (float)(dx)); int y = y1 + (dy * (float)(x - x1) / (float)(dx));
UINT32 *fb = &m_fb->pix32(y); UINT32 *fb = &m_framebuffer->pix32(y);
fb[x] = color; fb[x] = color;
x++; x++;
@ -470,7 +482,7 @@ void cobra_renderer::draw_line(const rectangle &visarea, vertex_t &v1, vertex_t
{ {
int x = x1 + (dx * (float)(y - y1) / (float)(dy)); int x = x1 + (dx * (float)(y - y1) / (float)(dy));
UINT32 *fb = &m_fb->pix32(y); UINT32 *fb = &m_framebuffer->pix32(y);
fb[x] = color; fb[x] = color;
y++; y++;
@ -488,9 +500,7 @@ VIDEO_START( cobra )
machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(cobra_video_exit), &machine)); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(cobra_video_exit), &machine));
cobra->m_framebuffer = auto_bitmap_rgb32_alloc(machine, 512, 384); cobra->m_renderer = auto_alloc(machine, cobra_renderer(machine));
cobra->m_renderer = auto_alloc(machine, cobra_renderer(machine, cobra->m_framebuffer));
cobra->m_renderer->gfx_init(machine); cobra->m_renderer->gfx_init(machine);
} }
@ -498,7 +508,7 @@ SCREEN_UPDATE_RGB32( cobra )
{ {
cobra_state *cobra = screen.machine().driver_data<cobra_state>(); cobra_state *cobra = screen.machine().driver_data<cobra_state>();
copybitmap_trans(bitmap, *cobra->m_framebuffer, 0, 0, 0, 0, cliprect, 0); cobra->m_renderer->display(&bitmap, cliprect);
return 0; return 0;
} }
@ -1386,6 +1396,11 @@ ADDRESS_MAP_END
#define RE_STATUS_IDLE 0 #define RE_STATUS_IDLE 0
#define RE_STATUS_COMMAND 1 #define RE_STATUS_COMMAND 1
void cobra_renderer::display(bitmap_rgb32 *bitmap, const rectangle &cliprect)
{
copybitmap_trans(*bitmap, *m_framebuffer, 0, 0, 0, 0, cliprect, 0);
}
void cobra_renderer::gfx_init(running_machine &machine) void cobra_renderer::gfx_init(running_machine &machine)
{ {
cobra_state *cobra = machine.driver_data<cobra_state>(); cobra_state *cobra = machine.driver_data<cobra_state>();
@ -1876,11 +1891,10 @@ void cobra_renderer::gfx_fifo_exec(running_machine &machine)
case 0xe8: case 0xe8:
{ {
// Write into a pixelbuffer? // Write into a pixelbuffer
int num = w2; int num = w2;
int i; int i;
//int c=0;
if (fifo_in->current_num() < num) if (fifo_in->current_num() < num)
{ {
@ -1888,30 +1902,44 @@ void cobra_renderer::gfx_fifo_exec(running_machine &machine)
return; return;
} }
if (num > 0) if (num & 3)
fatalerror("gfxfifo_exec: e8 with num %d\n", num);
int x = (m_gfx_gram[0x118/4] >> 16) & 0xffff;
int y = m_gfx_gram[0x118/4] & 0xffff;
for (i=0; i < num; i+=4)
{ {
printf("gfxfifo_exec: unhandled %08X %08X\n", w1, w2); UINT32 *buffer;
switch (m_gfx_gram[0x80104/4])
{
case 0x800000: buffer = &m_framebuffer->pix32(y); break;
case 0x200000: buffer = &m_backbuffer->pix32(y); break;
case 0x0e0000: buffer = &m_overlay->pix32(y); break;
case 0x000800: buffer = &m_zbuffer->pix32(y); break;
case 0x000200: buffer = &m_stencil->pix32(y); break;
default:
{
fatalerror("gfxfifo_exec: fb write to buffer %08X!\n", m_gfx_gram[0x80100/4]);
}
} }
for (i=0; i < num; i++) UINT64 param[4];
{ fifo_in->pop(NULL, &param[0]);
UINT64 param; fifo_in->pop(NULL, &param[1]);
fifo_in->pop(NULL, &param); fifo_in->pop(NULL, &param[2]);
fifo_in->pop(NULL, &param[3]);
/* buffer[x+0] = (UINT32)(param[0]);
if (c == 0) buffer[x+1] = (UINT32)(param[1]);
printf(" "); buffer[x+2] = (UINT32)(param[2]);
printf("%08X ", (UINT32)(param)); buffer[x+3] = (UINT32)(param[3]);
c++; //printf("gfx: fb write %d, %d: %08X %08X %08X %08X\n", x, y, (UINT32)(param[0]), (UINT32)(param[1]), (UINT32)(param[2]), (UINT32)(param[3]));
if (c == 8) y++;
{
printf("\n");
c = 0;
}*/
} }
//printf("\n");
cobra->m_gfx_re_status = RE_STATUS_IDLE; cobra->m_gfx_re_status = RE_STATUS_IDLE;
break; break;
@ -1919,20 +1947,32 @@ void cobra_renderer::gfx_fifo_exec(running_machine &machine)
case 0xe9: case 0xe9:
{ {
// Read a specified pixel position from a pixelbuffer? // Read a specified pixel position from a pixelbuffer
// printf("gfxfifo_exec: unhandled %08X %08X\n", w1, w2); // printf("GFX: FB read X: %d, Y: %d\n", (UINT16)(m_gfx_gram[0x118/4] >> 16), (UINT16)(m_gfx_gram[0x118/4]));
/*{ int x = (m_gfx_gram[0x118/4] >> 16) & 0xffff;
int y = (gfx_gram[0x11c] << 8) | (gfx_gram[0x11d]); int y = m_gfx_gram[0x118/4] & 0xffff;
int x = (gfx_gram[0x11e] << 8) | (gfx_gram[0x11f]);
printf("GFX: E9 on X: %d, Y: %d\n", x, y);
}*/
fifo_out->push(NULL, 0); UINT32 *buffer;
fifo_out->push(NULL, 0); switch (m_gfx_gram[0x80104/4])
fifo_out->push(NULL, 0); {
fifo_out->push(NULL, 0); case 0x800000: buffer = &m_framebuffer->pix32(y); break;
case 0x200000: buffer = &m_backbuffer->pix32(y); break;
case 0x0e0000: buffer = &m_overlay->pix32(y); break;
case 0x000800: buffer = &m_zbuffer->pix32(y); break;
case 0x000200: buffer = &m_stencil->pix32(y); break;
default:
{
fatalerror("gfxfifo_exec: fb read from buffer %08X!\n", m_gfx_gram[0x80100/4]);
}
}
fifo_out->push(NULL, buffer[x+0]);
fifo_out->push(NULL, buffer[x+1]);
fifo_out->push(NULL, buffer[x+2]);
fifo_out->push(NULL, buffer[x+3]);
cobra->m_gfx_re_status = RE_STATUS_IDLE; cobra->m_gfx_re_status = RE_STATUS_IDLE;
break; break;
@ -2099,6 +2139,7 @@ void cobra_renderer::gfx_fifo_exec(running_machine &machine)
cobra->m_gfx_unk_status |= 0x400; cobra->m_gfx_unk_status |= 0x400;
if (cobra->m_gfx_re_word_count == 0)
printf("gfxfifo_exec: tex_ints %d words left\n", num - cobra->m_gfx_re_word_count); printf("gfxfifo_exec: tex_ints %d words left\n", num - cobra->m_gfx_re_word_count);
for (int i=0; i < num_left; i++) for (int i=0; i < num_left; i++)