Previous 199869 Revisions Next

r32522 Saturday 4th October, 2014 at 06:26:33 UTC by Osso
micro3d: moved video functions into the driver class (nw)
[src/mame/includes]micro3d.h
[src/mame/video]micro3d.c

trunk/src/mame/includes/micro3d.h
r32521r32522
1515#define DRMATH_MONITOR_DISPLAY      0
1616
1717
18struct micro3d_vtx
19{
20   INT32 x, y, z;
21};
22
23enum planes
24{
25      CLIP_Z_MIN,
26      CLIP_Z_MAX,
27      CLIP_X_MIN,
28      CLIP_X_MAX,
29      CLIP_Y_MIN,
30      CLIP_Y_MAX,
31};
32
1833class micro3d_state : public driver_device
1934{
2035public:
r32521r32522
2641
2742   micro3d_state(const machine_config &mconfig, device_type type, const char *tag)
2843      : driver_device(mconfig, type, tag),
29      m_shared_ram(*this, "shared_ram"),
30      m_mac_sram(*this, "mac_sram"),
31      m_micro3d_sprite_vram(*this, "sprite_vram"),
3244      m_maincpu(*this, "maincpu"),
3345      m_audiocpu(*this, "audiocpu"),
3446      m_upd7759(*this, "upd7759"),
r32521r32522
3648      m_vgb(*this, "vgb"),
3749      m_palette(*this, "palette"),
3850      m_duart68681(*this, "duart68681"),
39      m_generic_paletteram_16(*this, "paletteram") { }
51      m_generic_paletteram_16(*this, "paletteram"),
52      m_shared_ram(*this, "shared_ram"),
53      m_mac_sram(*this, "mac_sram"),
54      m_sprite_vram(*this, "sprite_vram") { }
55     
56   required_device<cpu_device> m_maincpu;
57   required_device<i8051_device> m_audiocpu;
58   required_device<upd7759_device> m_upd7759;
59   required_device<cpu_device> m_drmath;
60   required_device<tms34010_device> m_vgb;
61   required_device<palette_device> m_palette;
62   required_device<mc68681_device> m_duart68681;
63   required_shared_ptr<UINT16> m_generic_paletteram_16;
4064
4165   required_shared_ptr<UINT16> m_shared_ram;
4266   UINT8               m_m68681_tx0;
r32521r32522
6690   UINT32              m_mac_inst;
6791
6892   /* 2D video */
69   required_shared_ptr<UINT16> m_micro3d_sprite_vram;
93   required_shared_ptr<UINT16> m_sprite_vram;
7094   UINT16              m_creg;
7195   UINT16              m_xfer3dk;
7296
r32521r32522
140164   DECLARE_WRITE_LINE_MEMBER(tms_interrupt);
141165   TMS340X0_SCANLINE_IND16_CB_MEMBER(scanline_update);
142166
143   required_device<cpu_device> m_maincpu;
144   required_device<i8051_device> m_audiocpu;
145   required_device<upd7759_device> m_upd7759;
146   required_device<cpu_device> m_drmath;
147   required_device<tms34010_device> m_vgb;
148   required_device<palette_device> m_palette;
149   required_device<mc68681_device> m_duart68681;
150   required_shared_ptr<UINT16> m_generic_paletteram_16;
167   /* 3D graphics */
168   int inside(micro3d_vtx *v, enum planes plane);
169   micro3d_vtx intersect(micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane);
170   inline void write_span(UINT32 y, UINT32 x);
171   void draw_line(UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2);
172   void rasterise_spans(UINT32 min_y, UINT32 max_y, UINT32 attr);
173   int clip_triangle(micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane);
174   void draw_triangles(UINT32 attr);
175   
151176
152177protected:
153178   virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
154179};
155180
156struct micro3d_vtx
157{
158   INT32 x, y, z;
159};
160
161181/*----------- defined in audio/micro3d.c -----------*/
162182
163183struct biquad
trunk/src/mame/video/micro3d.c
r32521r32522
6262
6363TMS340X0_SCANLINE_IND16_CB_MEMBER(micro3d_state::scanline_update)
6464{
65   UINT16 *src = &m_micro3d_sprite_vram[(params->rowaddr << 8) & 0x7fe00];
65   UINT16 *src = &m_sprite_vram[(params->rowaddr << 8) & 0x7fe00];
6666   UINT16 *dest = &bitmap.pix16(scanline);
6767   int coladdr = params->coladdr;
6868   int sd_11_7 = (m_creg & 0x1f) << 7;
r32521r32522
135135 *
136136 *************************************/
137137
138enum planes
138int micro3d_state::inside(micro3d_vtx *v, enum planes plane)
139139{
140   CLIP_Z_MIN,
141   CLIP_Z_MAX,
142   CLIP_X_MIN,
143   CLIP_X_MAX,
144   CLIP_Y_MIN,
145   CLIP_Y_MAX,
146};
147
148static int inside(micro3d_state *state, micro3d_vtx *v, enum planes plane)
149{
150140   switch (plane)
151141   {
152      case CLIP_Z_MIN: return v->z >= state->m_z_min;
153      case CLIP_Z_MAX: return v->z <= state->m_z_max;
154      case CLIP_X_MIN: return v->x >= state->m_x_min;
155      case CLIP_X_MAX: return v->x <= state->m_x_max;
156      case CLIP_Y_MIN: return v->y >= state->m_y_min;
157      case CLIP_Y_MAX: return v->y <= state->m_y_max;
142      case CLIP_Z_MIN: return v->z >= m_z_min;
143      case CLIP_Z_MAX: return v->z <= m_z_max;
144      case CLIP_X_MIN: return v->x >= m_x_min;
145      case CLIP_X_MAX: return v->x <= m_x_max;
146      case CLIP_Y_MIN: return v->y >= m_y_min;
147      case CLIP_Y_MAX: return v->y <= m_y_max;
158148   }
159149
160150   return 0;
161151}
162152
163153/* Calculate where two points intersect */
164static micro3d_vtx intersect(micro3d_state *state, micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane)
154micro3d_vtx micro3d_state::intersect(micro3d_vtx *v1, micro3d_vtx *v2, enum planes plane)
165155{
166156   float m = 0.0;
167157   micro3d_vtx vo = { 0, 0, 0 };
r32521r32522
186176            myz = 0.0;
187177         }
188178
189         vo.x = v2->x + (state->m_z_min - v2->z) * mxz;
190         vo.y = v2->y + (state->m_z_min - v2->z) * myz;
191         vo.z = state->m_z_min;
179         vo.x = v2->x + (m_z_min - v2->z) * mxz;
180         vo.y = v2->y + (m_z_min - v2->z) * myz;
181         vo.z = m_z_min;
192182         break;
193183      }
194184      case CLIP_Z_MAX:
r32521r32522
206196            myz = 0.0;
207197         }
208198
209         vo.x = v2->x + (state->m_z_max - v2->z) * mxz;
210         vo.y = v2->y + (state->m_z_max - v2->z) * myz;
211         vo.z = state->m_z_max;
199         vo.x = v2->x + (m_z_max - v2->z) * mxz;
200         vo.y = v2->y + (m_z_max - v2->z) * myz;
201         vo.z = m_z_max;
212202         break;
213203      }
214204      case CLIP_X_MIN:
215205      {
216         vo.x = state->m_x_min;
217         vo.y = v2->y + (state->m_x_min - v2->x) * m;
206         vo.x = m_x_min;
207         vo.y = v2->y + (m_x_min - v2->x) * m;
218208         vo.z = 0;
219209         break;
220210      }
221211      case CLIP_X_MAX:
222212      {
223         vo.x = state->m_x_max;
224         vo.y = v2->y + (state->m_x_max - v2->x) * m;
213         vo.x = m_x_max;
214         vo.y = v2->y + (m_x_max - v2->x) * m;
225215         vo.z = 0;
226216         break;
227217      }
228218      case CLIP_Y_MIN:
229219      {
230220         if (v1->x != v2->x)
231            vo.x = v2->x + (state->m_y_min - v2->y) / m;
221            vo.x = v2->x + (m_y_min - v2->y) / m;
232222         else
233223            vo.x = v2->x;
234224
235         vo.y = state->m_y_min;
225         vo.y = m_y_min;
236226         vo.z = 0;
237227         break;
238228      }
239229      case CLIP_Y_MAX:
240230      {
241231         if (v1->x != v2->x)
242            vo.x = v2->x + (state->m_y_max - v2->y) / m;
232            vo.x = v2->x + (m_y_max - v2->y) / m;
243233         else
244234            vo.x = v2->x;
245235
246         vo.y = state->m_y_max;
236         vo.y = m_y_max;
247237         vo.z = 0;
248238         break;
249239      }
r32521r32522
251241   return vo;
252242}
253243
254INLINE void write_span(micro3d_state *state, UINT32 y, UINT32 x)
244inline void micro3d_state::write_span(UINT32 y, UINT32 x)
255245{
256   UINT32 *draw_dpram = state->m_draw_dpram;
246   UINT32 *draw_dpram = m_draw_dpram;
257247   int addr = y << 1;
258248
259249   if (draw_dpram[addr] == 0x3ff000)
r32521r32522
263253   else
264254   {
265255      /* Check start */
266      if (x < (state->m_draw_dpram[addr] & 0x3ff))
256      if (x < (m_draw_dpram[addr] & 0x3ff))
267257      {
268258         draw_dpram[addr] &= ~0x3ff;
269259         draw_dpram[addr] |= x;
r32521r32522
278268}
279269
280270/* This is the same algorithm used in the 3D tests */
281static void draw_line(micro3d_state *state, UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2)
271void micro3d_state::draw_line(UINT32 x1, UINT32 y1, UINT32 x2, UINT32 y2)
282272{
283273   UINT32 tmp2;
284274   UINT32 acc;
r32521r32522
307297   else
308298      dy = y1 - y2;
309299
310   write_span(state, y1, x1);
300   write_span(y1, x1);
311301
312302   if (dx == 0 && dy == 0)
313303      return;
r32521r32522
329319         {
330320            if (~acc & 0x80000000)
331321            {
332               write_span(state, y1, x1);
322               write_span(y1, x1);
333323               y1 += y_inc;
334324               x1++;
335325               acc += dy;
336               write_span(state, y1, x1);
326               write_span(y1, x1);
337327            }
338328            else
339329            {
r32521r32522
344334      }
345335
346336      if (x2 != x1)
347         write_span(state, y1, x2);
337         write_span(y1, x2);
348338
349339   }
350340   else
r32521r32522
360350            if (acc & 0x80000000)
361351            {
362352               acc += tmp2;
363               write_span(state, y1, x1);
353               write_span(y1, x1);
364354               y1 += y_inc;
365               write_span(state, y1, x1);
355               write_span(y1, x1);
366356            }
367357            else
368358            {
369               write_span(state, y1, x1);
359               write_span(y1, x1);
370360               x1++;
371361               y1 += y_inc;
372               write_span(state, y1, x1);
362               write_span(y1, x1);
373363
374364               acc += dy;
375365            }
r32521r32522
377367      }
378368
379369      if (x2 != x1)
380         write_span(state, y1, x2);
370         write_span(y1, x2);
381371   }
382372}
383373
384static void rasterise_spans(micro3d_state *state, UINT32 min_y, UINT32 max_y, UINT32 attr)
374void micro3d_state::rasterise_spans(UINT32 min_y, UINT32 max_y, UINT32 attr)
385375{
386376   int y;
387377   int color = attr & 0xfff;
r32521r32522
392382      {
393383         int x;
394384         int addr = y << 1;
395         UINT16 *dest = &state->m_tmp_buffer[y * 1024];
385         UINT16 *dest = &m_tmp_buffer[y * 1024];
396386
397         if (state->m_draw_dpram[addr] == 0x3ff000)
387         if (m_draw_dpram[addr] == 0x3ff000)
398388         {
399389            continue;
400390         }
401391         else
402392         {
403            int start = state->m_draw_dpram[addr] & 0x3ff;
404            int end = (state->m_draw_dpram[addr] >> 12) & 0x3ff;
393            int start = m_draw_dpram[addr] & 0x3ff;
394            int end = (m_draw_dpram[addr] >> 12) & 0x3ff;
405395
406396            for (x = start; x <= end; ++x)
407397               dest[x] = color;
r32521r32522
433423      {
434424         int x;
435425         int addr = y << 1;
436         UINT16 *dest = &state->m_tmp_buffer[y * 1024];
426         UINT16 *dest = &m_tmp_buffer[y * 1024];
437427
438         if (state->m_draw_dpram[addr] == 0x3ff000)
428         if (m_draw_dpram[addr] == 0x3ff000)
439429         {
440430            continue;
441431         }
442432         else
443433         {
444            int start = state->m_draw_dpram[addr] & 0x3ff;
445            int end = (state->m_draw_dpram[addr] >> 12) & 0x3ff;
434            int start = m_draw_dpram[addr] & 0x3ff;
435            int end = (m_draw_dpram[addr] >> 12) & 0x3ff;
446436
447437            for (x = start; x <= end; ++x)
448438            {
r32521r32522
459449   }
460450}
461451
462static int clip_triangle(micro3d_state *state, micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane)
452int micro3d_state::clip_triangle(micro3d_vtx *v, micro3d_vtx *vout, int num_vertices, enum planes plane)
463453{
464454   micro3d_vtx clip_out[10];
465455
r32521r32522
469459
470460   for (i = 0; i < num_vertices; ++i)
471461   {
472      int v1_in = inside(state, &v[i], plane);
473      int v2_in = inside(state, &v[prev_i], plane);
462      int v1_in = inside(&v[i], plane);
463      int v2_in = inside(&v[prev_i], plane);
474464
475465      /* Edge is inside */
476466      if (v1_in && v2_in)
r32521r32522
480470      /* Edge is leaving */
481471      else if (v1_in && !v2_in)
482472      {
483         clip_out[clip_verts++] = intersect(state, &v[i], &v[prev_i], plane);
473         clip_out[clip_verts++] = intersect(&v[i], &v[prev_i], plane);
484474         clip_out[clip_verts++] = v[i];
485475      }
486476      /* Edge is entering */
487477      else if (!v1_in && v2_in)
488478      {
489         clip_out[clip_verts++] = intersect(state, &v[i], &v[prev_i], plane);
479         clip_out[clip_verts++] = intersect(&v[i], &v[prev_i], plane);
490480      }
491481
492482      prev_i = i;
r32521r32522
496486   return clip_verts;
497487}
498488
499static void draw_triangles(micro3d_state *state, UINT32 attr)
489void micro3d_state::draw_triangles(UINT32 attr)
500490{
501491   int i;
502492   int triangles = 0;
503   int vertices = state->m_fifo_idx / 3;
493   int vertices = m_fifo_idx / 3;
504494   int min_y = 0x3ff;
505495   int max_y = 0;
506496
r32521r32522
508498   if (vertices == 0)
509499   {
510500      int y;
511      int val = ((state->m_x_mid + 16) << 12) | state->m_x_mid;
501      int val = ((m_x_mid + 16) << 12) | m_x_mid;
512502
513      for (y = state->m_y_mid; y <= state->m_y_mid + 16; ++y)
514         state->m_draw_dpram[y << 1] = val;
503      for (y = m_y_mid; y <= m_y_mid + 16; ++y)
504         m_draw_dpram[y << 1] = val;
515505
516506      return;
517507   }
r32521r32522
525515      micro3d_vtx vo, vm, vn;
526516      micro3d_vtx vclip_list[10];
527517
528      vo.x = state->m_vtx_fifo[0];
529      vo.y = state->m_vtx_fifo[1];
530      vo.z = state->m_vtx_fifo[2];
518      vo.x = m_vtx_fifo[0];
519      vo.y = m_vtx_fifo[1];
520      vo.z = m_vtx_fifo[2];
531521
532      vm.x = state->m_vtx_fifo[(i - 1) * 3 + 0];
533      vm.y = state->m_vtx_fifo[(i - 1) * 3 + 1];
534      vm.z = state->m_vtx_fifo[(i - 1) * 3 + 2];
522      vm.x = m_vtx_fifo[(i - 1) * 3 + 0];
523      vm.y = m_vtx_fifo[(i - 1) * 3 + 1];
524      vm.z = m_vtx_fifo[(i - 1) * 3 + 2];
535525
536      vn.x = state->m_vtx_fifo[i * 3 + 0];
537      vn.y = state->m_vtx_fifo[i * 3 + 1];
538      vn.z = state->m_vtx_fifo[i * 3 + 2];
526      vn.x = m_vtx_fifo[i * 3 + 0];
527      vn.y = m_vtx_fifo[i * 3 + 1];
528      vn.z = m_vtx_fifo[i * 3 + 2];
539529
540530      vclip_list[0] = vo;
541531      vclip_list[1] = vm;
542532      vclip_list[2] = vn;
543533
544534      /* Clip against near Z and far Z planes */
545      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Z_MIN);
546      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Z_MAX);
535      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Z_MIN);
536      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Z_MAX);
547537
548538      /* Perform perspective divide */
549539      for (k = 0; k < clip_vertices; ++k)
550540      {
551         vclip_list[k].x = vclip_list[k].x * state->m_z_min / vclip_list[k].z;
552         vclip_list[k].y = vclip_list[k].y * state->m_z_min / vclip_list[k].z;
541         vclip_list[k].x = vclip_list[k].x * m_z_min / vclip_list[k].z;
542         vclip_list[k].y = vclip_list[k].y * m_z_min / vclip_list[k].z;
553543         vclip_list[k].z = 0;
554544      }
555545
556546      /* Perform screen-space clipping */
557      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Y_MAX);
558      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_X_MIN);
559      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_X_MAX);
560      clip_vertices = clip_triangle(state, vclip_list, vclip_list, clip_vertices, CLIP_Y_MIN);
547      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Y_MAX);
548      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_X_MIN);
549      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_X_MAX);
550      clip_vertices = clip_triangle(vclip_list, vclip_list, clip_vertices, CLIP_Y_MIN);
561551
562552      /* Rasterise */
563553      if (clip_vertices >= 3)
r32521r32522
567557
568558         triangles = TRUE;
569559
570         a.x += state->m_x_mid;
571         a.y += state->m_y_mid;
560         a.x += m_x_mid;
561         a.y += m_y_mid;
572562
573         b.x += state->m_x_mid;
574         b.y += state->m_y_mid;
563         b.x += m_x_mid;
564         b.y += m_y_mid;
575565
576566         /* Keep track of the y-extents so we don't have to scan every line later */
577567         if (a.y < min_y)
r32521r32522
585575            max_y = b.y;
586576
587577         /* Draw the first line of the triangle/fan */
588         draw_line(state, a.x, a.y, b.x, b.y);
578         draw_line(a.x, a.y, b.x, b.y);
589579
590580         for (k = 2; k < clip_vertices; ++k)
591581         {
592582            micro3d_vtx c = vclip_list[k];
593583
594            c.x += state->m_x_mid;
595            c.y += state->m_y_mid;
584            c.x += m_x_mid;
585            c.y += m_y_mid;
596586
597587            if (c.y < min_y)
598588               min_y = c.y;
599589            if (c.y > max_y)
600590               max_y = c.y;
601591
602            draw_line(state, b.x, b.y, c.x, c.y);
603            draw_line(state, a.x, a.y, c.x, c.y);
592            draw_line(b.x, b.y, c.x, c.y);
593            draw_line(a.x, a.y, c.x, c.y);
604594            b = c;
605595         }
606596      }
607597   }
608598
609599   if (triangles == TRUE)
610      rasterise_spans(state, min_y, max_y, attr);
600      rasterise_spans(min_y, max_y, attr);
611601}
612602
613603
r32521r32522
724714      {
725715         if ((opcode == 0x85) || (opcode == 0x8a))
726716         {
727            micro3d_state *state = machine().driver_data<micro3d_state>();
728            draw_triangles(state, data);
717            draw_triangles(data);
729718            m_draw_state = STATE_DRAW_CMD;
730719         }
731720         else

Previous 199869 Revisions Next


© 1997-2024 The MAME Team