micro3d: moved video functions into the driver class (nw)

This commit is contained in:
Ivan Vangelista 2014-10-04 06:26:33 +00:00
parent ac8a857d1c
commit ce9b6a3350
2 changed files with 121 additions and 112 deletions

View File

@ -15,6 +15,21 @@
#define DRMATH_MONITOR_DISPLAY 0 #define DRMATH_MONITOR_DISPLAY 0
struct micro3d_vtx
{
INT32 x, y, z;
};
enum planes
{
CLIP_Z_MIN,
CLIP_Z_MAX,
CLIP_X_MIN,
CLIP_X_MAX,
CLIP_Y_MIN,
CLIP_Y_MAX,
};
class micro3d_state : public driver_device class micro3d_state : public driver_device
{ {
public: public:
@ -26,9 +41,6 @@ public:
micro3d_state(const machine_config &mconfig, device_type type, const char *tag) micro3d_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag), : driver_device(mconfig, type, tag),
m_shared_ram(*this, "shared_ram"),
m_mac_sram(*this, "mac_sram"),
m_micro3d_sprite_vram(*this, "sprite_vram"),
m_maincpu(*this, "maincpu"), m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"), m_audiocpu(*this, "audiocpu"),
m_upd7759(*this, "upd7759"), m_upd7759(*this, "upd7759"),
@ -36,7 +48,19 @@ public:
m_vgb(*this, "vgb"), m_vgb(*this, "vgb"),
m_palette(*this, "palette"), m_palette(*this, "palette"),
m_duart68681(*this, "duart68681"), m_duart68681(*this, "duart68681"),
m_generic_paletteram_16(*this, "paletteram") { } m_generic_paletteram_16(*this, "paletteram"),
m_shared_ram(*this, "shared_ram"),
m_mac_sram(*this, "mac_sram"),
m_sprite_vram(*this, "sprite_vram") { }
required_device<cpu_device> m_maincpu;
required_device<i8051_device> m_audiocpu;
required_device<upd7759_device> m_upd7759;
required_device<cpu_device> m_drmath;
required_device<tms34010_device> m_vgb;
required_device<palette_device> m_palette;
required_device<mc68681_device> m_duart68681;
required_shared_ptr<UINT16> m_generic_paletteram_16;
required_shared_ptr<UINT16> m_shared_ram; required_shared_ptr<UINT16> m_shared_ram;
UINT8 m_m68681_tx0; UINT8 m_m68681_tx0;
@ -66,7 +90,7 @@ public:
UINT32 m_mac_inst; UINT32 m_mac_inst;
/* 2D video */ /* 2D video */
required_shared_ptr<UINT16> m_micro3d_sprite_vram; required_shared_ptr<UINT16> m_sprite_vram;
UINT16 m_creg; UINT16 m_creg;
UINT16 m_xfer3dk; UINT16 m_xfer3dk;
@ -140,24 +164,20 @@ public:
DECLARE_WRITE_LINE_MEMBER(tms_interrupt); DECLARE_WRITE_LINE_MEMBER(tms_interrupt);
TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update); TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update);
required_device<cpu_device> m_maincpu; /* 3D graphics */
required_device<i8051_device> m_audiocpu; int inside(micro3d_vtx *v, enum planes plane);
required_device<upd7759_device> m_upd7759; micro3d_vtx intersect(micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane);
required_device<cpu_device> m_drmath; inline void write_span(UINT32 y, UINT32 x);
required_device<tms34010_device> m_vgb; void draw_line(UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2);
required_device<palette_device> m_palette; void rasterise_spans(UINT32 min_y, UINT32 max_y, UINT32 attr);
required_device<mc68681_device> m_duart68681; int clip_triangle(micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane);
required_shared_ptr<UINT16> m_generic_paletteram_16; void draw_triangles(UINT32 attr);
protected: protected:
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
}; };
struct micro3d_vtx
{
INT32 x, y, z;
};
/*----------- defined in audio/micro3d.c -----------*/ /*----------- defined in audio/micro3d.c -----------*/
struct biquad struct biquad

View File

@ -62,7 +62,7 @@ void micro3d_state::video_reset()
TMS340X0_SCANLINE_IND16_CB_MEMBER(micro3d_state::scanline_update) TMS340X0_SCANLINE_IND16_CB_MEMBER(micro3d_state::scanline_update)
{ {
UINT16 *src = &m_micro3d_sprite_vram[(params->rowaddr << 8) & 0x7fe00]; UINT16 *src = &m_sprite_vram[(params->rowaddr << 8) & 0x7fe00];
UINT16 *dest = &bitmap.pix16(scanline); UINT16 *dest = &bitmap.pix16(scanline);
int coladdr = params->coladdr; int coladdr = params->coladdr;
int sd_11_7 = (m_creg & 0x1f) << 7; int sd_11_7 = (m_creg & 0x1f) << 7;
@ -135,33 +135,23 @@ WRITE_LINE_MEMBER(micro3d_state::tms_interrupt)
* *
*************************************/ *************************************/
enum planes int micro3d_state::inside(micro3d_vtx *v, enum planes plane)
{
CLIP_Z_MIN,
CLIP_Z_MAX,
CLIP_X_MIN,
CLIP_X_MAX,
CLIP_Y_MIN,
CLIP_Y_MAX,
};
static int inside(micro3d_state *state, micro3d_vtx *v, enum planes plane)
{ {
switch (plane) switch (plane)
{ {
case CLIP_Z_MIN: return v->z >= state->m_z_min; case CLIP_Z_MIN: return v->z >= m_z_min;
case CLIP_Z_MAX: return v->z <= state->m_z_max; case CLIP_Z_MAX: return v->z <= m_z_max;
case CLIP_X_MIN: return v->x >= state->m_x_min; case CLIP_X_MIN: return v->x >= m_x_min;
case CLIP_X_MAX: return v->x <= state->m_x_max; case CLIP_X_MAX: return v->x <= m_x_max;
case CLIP_Y_MIN: return v->y >= state->m_y_min; case CLIP_Y_MIN: return v->y >= m_y_min;
case CLIP_Y_MAX: return v->y <= state->m_y_max; case CLIP_Y_MAX: return v->y <= m_y_max;
} }
return 0; return 0;
} }
/* Calculate where two points intersect */ /* Calculate where two points intersect */
static micro3d_vtx intersect(micro3d_state *state, micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane) micro3d_vtx micro3d_state::intersect(micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane)
{ {
float m = 0.0; float m = 0.0;
micro3d_vtx vo = { 0, 0, 0 }; micro3d_vtx vo = { 0, 0, 0 };
@ -186,9 +176,9 @@ static micro3d_vtx intersect(micro3d_state *state, micro3d_vtx *v1, micro3d_vtx
myz = 0.0; myz = 0.0;
} }
vo.x = v2->x + (state->m_z_min - v2->z) * mxz; vo.x = v2->x + (m_z_min - v2->z) * mxz;
vo.y = v2->y + (state->m_z_min - v2->z) * myz; vo.y = v2->y + (m_z_min - v2->z) * myz;
vo.z = state->m_z_min; vo.z = m_z_min;
break; break;
} }
case CLIP_Z_MAX: case CLIP_Z_MAX:
@ -206,44 +196,44 @@ static micro3d_vtx intersect(micro3d_state *state, micro3d_vtx *v1, micro3d_vtx
myz = 0.0; myz = 0.0;
} }
vo.x = v2->x + (state->m_z_max - v2->z) * mxz; vo.x = v2->x + (m_z_max - v2->z) * mxz;
vo.y = v2->y + (state->m_z_max - v2->z) * myz; vo.y = v2->y + (m_z_max - v2->z) * myz;
vo.z = state->m_z_max; vo.z = m_z_max;
break; break;
} }
case CLIP_X_MIN: case CLIP_X_MIN:
{ {
vo.x = state->m_x_min; vo.x = m_x_min;
vo.y = v2->y + (state->m_x_min - v2->x) * m; vo.y = v2->y + (m_x_min - v2->x) * m;
vo.z = 0; vo.z = 0;
break; break;
} }
case CLIP_X_MAX: case CLIP_X_MAX:
{ {
vo.x = state->m_x_max; vo.x = m_x_max;
vo.y = v2->y + (state->m_x_max - v2->x) * m; vo.y = v2->y + (m_x_max - v2->x) * m;
vo.z = 0; vo.z = 0;
break; break;
} }
case CLIP_Y_MIN: case CLIP_Y_MIN:
{ {
if (v1->x != v2->x) if (v1->x != v2->x)
vo.x = v2->x + (state->m_y_min - v2->y) / m; vo.x = v2->x + (m_y_min - v2->y) / m;
else else
vo.x = v2->x; vo.x = v2->x;
vo.y = state->m_y_min; vo.y = m_y_min;
vo.z = 0; vo.z = 0;
break; break;
} }
case CLIP_Y_MAX: case CLIP_Y_MAX:
{ {
if (v1->x != v2->x) if (v1->x != v2->x)
vo.x = v2->x + (state->m_y_max - v2->y) / m; vo.x = v2->x + (m_y_max - v2->y) / m;
else else
vo.x = v2->x; vo.x = v2->x;
vo.y = state->m_y_max; vo.y = m_y_max;
vo.z = 0; vo.z = 0;
break; break;
} }
@ -251,9 +241,9 @@ static micro3d_vtx intersect(micro3d_state *state, micro3d_vtx *v1, micro3d_vtx
return vo; return vo;
} }
INLINE void write_span(micro3d_state *state, UINT32 y, UINT32 x) inline void micro3d_state::write_span(UINT32 y, UINT32 x)
{ {
UINT32 *draw_dpram = state->m_draw_dpram; UINT32 *draw_dpram = m_draw_dpram;
int addr = y << 1; int addr = y << 1;
if (draw_dpram[addr] == 0x3ff000) if (draw_dpram[addr] == 0x3ff000)
@ -263,7 +253,7 @@ INLINE void write_span(micro3d_state *state, UINT32 y, UINT32 x)
else else
{ {
/* Check start */ /* Check start */
if (x < (state->m_draw_dpram[addr] & 0x3ff)) if (x < (m_draw_dpram[addr] & 0x3ff))
{ {
draw_dpram[addr] &= ~0x3ff; draw_dpram[addr] &= ~0x3ff;
draw_dpram[addr] |= x; draw_dpram[addr] |= x;
@ -278,7 +268,7 @@ INLINE void write_span(micro3d_state *state, UINT32 y, UINT32 x)
} }
/* This is the same algorithm used in the 3D tests */ /* This is the same algorithm used in the 3D tests */
static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2) void micro3d_state::draw_line(UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2)
{ {
UINT32 tmp2; UINT32 tmp2;
UINT32 acc; UINT32 acc;
@ -307,7 +297,7 @@ static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UIN
else else
dy = y1 - y2; dy = y1 - y2;
write_span(state, y1, x1); write_span(y1, x1);
if (dx == 0 && dy == 0) if (dx == 0 && dy == 0)
return; return;
@ -329,11 +319,11 @@ static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UIN
{ {
if (~acc & 0x80000000) if (~acc & 0x80000000)
{ {
write_span(state, y1, x1); write_span(y1, x1);
y1 += y_inc; y1 += y_inc;
x1++; x1++;
acc += dy; acc += dy;
write_span(state, y1, x1); write_span(y1, x1);
} }
else else
{ {
@ -344,7 +334,7 @@ static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UIN
} }
if (x2 != x1) if (x2 != x1)
write_span(state, y1, x2); write_span(y1, x2);
} }
else else
@ -360,16 +350,16 @@ static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UIN
if (acc & 0x80000000) if (acc & 0x80000000)
{ {
acc += tmp2; acc += tmp2;
write_span(state, y1, x1); write_span(y1, x1);
y1 += y_inc; y1 += y_inc;
write_span(state, y1, x1); write_span(y1, x1);
} }
else else
{ {
write_span(state, y1, x1); write_span(y1, x1);
x1++; x1++;
y1 += y_inc; y1 += y_inc;
write_span(state, y1, x1); write_span(y1, x1);
acc += dy; acc += dy;
} }
@ -377,11 +367,11 @@ static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UIN
} }
if (x2 != x1) if (x2 != x1)
write_span(state, y1, x2); write_span(y1, x2);
} }
} }
static void rasterise_spans(micro3d_state *state, UINT32 min_y, UINT32 max_y, UINT32 attr) void micro3d_state::rasterise_spans(UINT32 min_y, UINT32 max_y, UINT32 attr)
{ {
int y; int y;
int color = attr & 0xfff; int color = attr & 0xfff;
@ -392,16 +382,16 @@ static void rasterise_spans(micro3d_state *state, UINT32 min_y, UINT32 max_y, UI
{ {
int x; int x;
int addr = y << 1; int addr = y << 1;
UINT16 *dest = &state->m_tmp_buffer[y * 1024]; UINT16 *dest = &m_tmp_buffer[y * 1024];
if (state->m_draw_dpram[addr] == 0x3ff000) if (m_draw_dpram[addr] == 0x3ff000)
{ {
continue; continue;
} }
else else
{ {
int start = state->m_draw_dpram[addr] & 0x3ff; int start = m_draw_dpram[addr] & 0x3ff;
int end = (state->m_draw_dpram[addr] >> 12) & 0x3ff; int end = (m_draw_dpram[addr] >> 12) & 0x3ff;
for (x = start; x <= end; ++x) for (x = start; x <= end; ++x)
dest[x] = color; dest[x] = color;
@ -433,16 +423,16 @@ static void rasterise_spans(micro3d_state *state, UINT32 min_y, UINT32 max_y, UI
{ {
int x; int x;
int addr = y << 1; int addr = y << 1;
UINT16 *dest = &state->m_tmp_buffer[y * 1024]; UINT16 *dest = &m_tmp_buffer[y * 1024];
if (state->m_draw_dpram[addr] == 0x3ff000) if (m_draw_dpram[addr] == 0x3ff000)
{ {
continue; continue;
} }
else else
{ {
int start = state->m_draw_dpram[addr] & 0x3ff; int start = m_draw_dpram[addr] & 0x3ff;
int end = (state->m_draw_dpram[addr] >> 12) & 0x3ff; int end = (m_draw_dpram[addr] >> 12) & 0x3ff;
for (x = start; x <= end; ++x) for (x = start; x <= end; ++x)
{ {
@ -459,7 +449,7 @@ static void rasterise_spans(micro3d_state *state, UINT32 min_y, UINT32 max_y, UI
} }
} }
static int clip_triangle(micro3d_state *state, micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane) int micro3d_state::clip_triangle(micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane)
{ {
micro3d_vtx clip_out[10]; micro3d_vtx clip_out[10];
@ -469,8 +459,8 @@ static int clip_triangle(micro3d_state *state, micro3d_vtx *v, micro3d_vtx *vout
for (i = 0; i < num_vertices; ++i) for (i = 0; i < num_vertices; ++i)
{ {
int v1_in = inside(state, &v[i], plane); int v1_in = inside(&v[i], plane);
int v2_in = inside(state, &v[prev_i], plane); int v2_in = inside(&v[prev_i], plane);
/* Edge is inside */ /* Edge is inside */
if (v1_in && v2_in) if (v1_in && v2_in)
@ -480,13 +470,13 @@ static int clip_triangle(micro3d_state *state, micro3d_vtx *v, micro3d_vtx *vout
/* Edge is leaving */ /* Edge is leaving */
else if (v1_in && !v2_in) else if (v1_in && !v2_in)
{ {
clip_out[clip_verts++] = intersect(state, &v[i], &v[prev_i], plane); clip_out[clip_verts++] = intersect(&v[i], &v[prev_i], plane);
clip_out[clip_verts++] = v[i]; clip_out[clip_verts++] = v[i];
} }
/* Edge is entering */ /* Edge is entering */
else if (!v1_in && v2_in) else if (!v1_in && v2_in)
{ {
clip_out[clip_verts++] = intersect(state, &v[i], &v[prev_i], plane); clip_out[clip_verts++] = intersect(&v[i], &v[prev_i], plane);
} }
prev_i = i; prev_i = i;
@ -496,11 +486,11 @@ static int clip_triangle(micro3d_state *state, micro3d_vtx *v, micro3d_vtx *vout
return clip_verts; return clip_verts;
} }
static void draw_triangles(micro3d_state *state, UINT32 attr) void micro3d_state::draw_triangles(UINT32 attr)
{ {
int i; int i;
int triangles = 0; int triangles = 0;
int vertices = state->m_fifo_idx / 3; int vertices = m_fifo_idx / 3;
int min_y = 0x3ff; int min_y = 0x3ff;
int max_y = 0; int max_y = 0;
@ -508,10 +498,10 @@ static void draw_triangles(micro3d_state *state, UINT32 attr)
if (vertices == 0) if (vertices == 0)
{ {
int y; int y;
int val = ((state->m_x_mid + 16) << 12) | state->m_x_mid; int val = ((m_x_mid + 16) << 12) | m_x_mid;
for (y = state->m_y_mid; y <= state->m_y_mid + 16; ++y) for (y = m_y_mid; y <= m_y_mid + 16; ++y)
state->m_draw_dpram[y << 1] = val; m_draw_dpram[y << 1] = val;
return; return;
} }
@ -525,39 +515,39 @@ static void draw_triangles(micro3d_state *state, UINT32 attr)
micro3d_vtx vo, vm, vn; micro3d_vtx vo, vm, vn;
micro3d_vtx vclip_list[10]; micro3d_vtx vclip_list[10];
vo.x = state->m_vtx_fifo[0]; vo.x = m_vtx_fifo[0];
vo.y = state->m_vtx_fifo[1]; vo.y = m_vtx_fifo[1];
vo.z = state->m_vtx_fifo[2]; vo.z = m_vtx_fifo[2];
vm.x = state->m_vtx_fifo[(i - 1) * 3 + 0]; vm.x = m_vtx_fifo[(i - 1) * 3 + 0];
vm.y = state->m_vtx_fifo[(i - 1) * 3 + 1]; vm.y = m_vtx_fifo[(i - 1) * 3 + 1];
vm.z = state->m_vtx_fifo[(i - 1) * 3 + 2]; vm.z = m_vtx_fifo[(i - 1) * 3 + 2];
vn.x = state->m_vtx_fifo[i * 3 + 0]; vn.x = m_vtx_fifo[i * 3 + 0];
vn.y = state->m_vtx_fifo[i * 3 + 1]; vn.y = m_vtx_fifo[i * 3 + 1];
vn.z = state->m_vtx_fifo[i * 3 + 2]; vn.z = m_vtx_fifo[i * 3 + 2];
vclip_list[0] = vo; vclip_list[0] = vo;
vclip_list[1] = vm; vclip_list[1] = vm;
vclip_list[2] = vn; vclip_list[2] = vn;
/* Clip against near Z and far Z planes */ /* Clip against near Z and far Z planes */
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Z_MIN); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Z_MIN);
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Z_MAX); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Z_MAX);
/* Perform perspective divide */ /* Perform perspective divide */
for (k = 0; k < clip_vertices; ++k) for (k = 0; k < clip_vertices; ++k)
{ {
vclip_list[k].x = vclip_list[k].x * state->m_z_min / vclip_list[k].z; vclip_list[k].x = vclip_list[k].x * m_z_min / vclip_list[k].z;
vclip_list[k].y = vclip_list[k].y * state->m_z_min / vclip_list[k].z; vclip_list[k].y = vclip_list[k].y * m_z_min / vclip_list[k].z;
vclip_list[k].z = 0; vclip_list[k].z = 0;
} }
/* Perform screen-space clipping */ /* Perform screen-space clipping */
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Y_MAX); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Y_MAX);
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_X_MIN); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_X_MIN);
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_X_MAX); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_X_MAX);
clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Y_MIN); clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Y_MIN);
/* Rasterise */ /* Rasterise */
if (clip_vertices >= 3) if (clip_vertices >= 3)
@ -567,11 +557,11 @@ static void draw_triangles(micro3d_state *state, UINT32 attr)
triangles = TRUE; triangles = TRUE;
a.x += state->m_x_mid; a.x += m_x_mid;
a.y += state->m_y_mid; a.y += m_y_mid;
b.x += state->m_x_mid; b.x += m_x_mid;
b.y += state->m_y_mid; b.y += m_y_mid;
/* Keep track of the y-extents so we don't have to scan every line later */ /* Keep track of the y-extents so we don't have to scan every line later */
if (a.y < min_y) if (a.y < min_y)
@ -585,29 +575,29 @@ static void draw_triangles(micro3d_state *state, UINT32 attr)
max_y = b.y; max_y = b.y;
/* Draw the first line of the triangle/fan */ /* Draw the first line of the triangle/fan */
draw_line(state, a.x, a.y, b.x, b.y); draw_line(a.x, a.y, b.x, b.y);
for (k = 2; k < clip_vertices; ++k) for (k = 2; k < clip_vertices; ++k)
{ {
micro3d_vtx c = vclip_list[k]; micro3d_vtx c = vclip_list[k];
c.x += state->m_x_mid; c.x += m_x_mid;
c.y += state->m_y_mid; c.y += m_y_mid;
if (c.y < min_y) if (c.y < min_y)
min_y = c.y; min_y = c.y;
if (c.y > max_y) if (c.y > max_y)
max_y = c.y; max_y = c.y;
draw_line(state, b.x, b.y, c.x, c.y); draw_line(b.x, b.y, c.x, c.y);
draw_line(state, a.x, a.y, c.x, c.y); draw_line(a.x, a.y, c.x, c.y);
b = c; b = c;
} }
} }
} }
if (triangles == TRUE) if (triangles == TRUE)
rasterise_spans(state, min_y, max_y, attr); rasterise_spans(min_y, max_y, attr);
} }
@ -724,8 +714,7 @@ WRITE32_MEMBER(micro3d_state::micro3d_fifo_w)
{ {
if ((opcode == 0x85) || (opcode == 0x8a)) if ((opcode == 0x85) || (opcode == 0x8a))
{ {
micro3d_state *state = machine().driver_data<micro3d_state>(); draw_triangles(data);
draw_triangles(state, data);
m_draw_state = STATE_DRAW_CMD; m_draw_state = STATE_DRAW_CMD;
} }
else else