~ubuntu-branches/debian/wheezy/mame/wheezy

« back to all changes in this revision

Viewing changes to src/mame/video/model2.c

  • Committer: Bazaar Package Importer
  • Author(s): Jordi Mallach, Emmanuel Kasper, Félix Arreola Rodríguez, Jordi Mallach
  • Date: 2011-05-11 21:06:50 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110511210650-jizvh8a6x117y9hr
Tags: 0.142-1
[ Emmanuel Kasper ]
* New upstream release
* Set NOWERROR=1 to allow compiling with gcc-4.6
* Remove fix_powerpc_build.patch, as upstream has taken it in this release
* Add gnome-video-arcade front end as a suggested package

[ Félix Arreola Rodríguez ]
* Add kfreebsd-build.patch to quilt series, to fix build on kfreebsd

[ Jordi Mallach ]
* Remove unneeded and bogus addition of --with-quilt to the dh invocation.
* Add Cesare Falco (long time Ubuntu maintainer) to Uploaders, and wrap
  them into multiple lines.

Show diffs side-by-side

added added

removed removed

Lines of Context:
92
92
 
93
93
#define DEBUG 0
94
94
 
95
 
static poly_manager *poly;
96
95
 
97
96
#define pz              p[0]
98
97
#define pu              p[1]
141
140
typedef struct _poly_extra_data poly_extra_data;
142
141
struct _poly_extra_data
143
142
{
 
143
        model2_state *  state;
144
144
        UINT32          lumabase;
145
145
        UINT32          colorbase;
146
146
        UINT32 *        texsheet;
292
292
 
293
293
/*******************************************
294
294
 *
295
 
 *  Hardware 3D Rasterizer Interal State
 
295
 *  Hardware 3D Rasterizer Internal State
296
296
 *
297
297
 *******************************************/
298
298
 
299
299
#define MAX_TRIANGLES           32768
300
300
 
301
 
typedef struct
 
301
struct _raster_state
302
302
{
303
303
        UINT32                          mode;                           /* bit 0 = Test Mode, bit 2 = Switch 60Hz(1)/30Hz(0) operation */
304
304
        UINT16 *                        texture_rom;            /* Texture ROM pointer */
305
 
        UINT16 *                        texture_ram;            /* Texture RAM pointer */
306
 
        UINT8 *                         log_ram;                        /* Log RAM pointer */
307
305
        INT16                           viewport[4];            /* View port (startx,starty,endx,endy) */
308
306
        INT16                           center[4][2];           /* Centers (eye 0[x,y],1[x,y],2[x,y],3[x,y]) */
309
307
        UINT16                          center_sel;                     /* Selected center */
314
312
        UINT32                          cur_command;            /* Current command */
315
313
        UINT32                          command_buffer[32];     /* Command buffer */
316
314
        UINT32                          command_index;          /* Command buffer index */
317
 
        triangle *                      tri_list;                       /* Triangle list */
 
315
        triangle                        tri_list[MAX_TRIANGLES];                        /* Triangle list */
318
316
        UINT32                          tri_list_index;         /* Triangle list index */
319
 
        triangle **                     tri_sorted_list;        /* Sorted Triangle list */
 
317
        triangle *                      tri_sorted_list[0x10000];       /* Sorted Triangle list */
320
318
        UINT16                          min_z;                          /* Minimum sortable Z value */
321
319
        UINT16                          max_z;                          /* Maximum sortable Z value */
322
 
 
323
 
} raster_state;
324
 
 
325
 
static raster_state raster;
 
320
        UINT16                  texture_ram[0x10000];           /* Texture RAM pointer */
 
321
        UINT8                           log_ram[0x40000];                       /* Log RAM pointer */
 
322
};
 
323
 
326
324
 
327
325
/*******************************************
328
326
 *
330
328
 *
331
329
 *******************************************/
332
330
 
333
 
static void model2_3d_init( running_machine *machine, UINT16 *texture_rom )
 
331
static void model2_3d_init( running_machine &machine, UINT16 *texture_rom )
334
332
{
335
 
        memset( &raster, 0, sizeof( raster_state ) );
336
 
 
337
 
        raster.texture_rom = texture_rom;
338
 
        raster.texture_ram = auto_alloc_array(machine, UINT16, 0x10000);
339
 
        raster.log_ram = auto_alloc_array(machine, UINT8, 0x40000);
340
 
        raster.tri_list = auto_alloc_array(machine, triangle, MAX_TRIANGLES);
341
 
        raster.tri_sorted_list = auto_alloc_array(machine, triangle *, 0x10000);
 
333
        model2_state *state = machine.driver_data<model2_state>();
 
334
 
 
335
        state->m_raster = auto_alloc_clear( machine, raster_state );
 
336
 
 
337
        state->m_raster->texture_rom = texture_rom;
342
338
}
343
339
 
344
340
/*******************************************
347
343
 *
348
344
 *******************************************/
349
345
 
350
 
void model2_3d_set_zclip( UINT8 clip )
 
346
void model2_3d_set_zclip( running_machine &machine, UINT8 clip )
351
347
{
352
 
        raster.master_z_clip = clip;
 
348
        model2_state *state = machine.driver_data<model2_state>();
 
349
        state->m_raster->master_z_clip = clip;
353
350
}
354
351
 
355
352
/*******************************************
358
355
 *
359
356
 *******************************************/
360
357
 
361
 
static void model2_3d_process_quad( UINT32 attr )
 
358
static void model2_3d_process_quad( raster_state *raster, UINT32 attr )
362
359
{
363
360
        _quad_m2        object;
364
361
        UINT16          *th, *tp;
368
365
        float           min_z, max_z;
369
366
 
370
367
        /* extract P0(n-1) */
371
 
        object.v[1].x = u2f( raster.command_buffer[2] << 8 );
372
 
        object.v[1].y = u2f( raster.command_buffer[3] << 8 );
373
 
        object.v[1].pz = u2f( raster.command_buffer[4] << 8 );
 
368
        object.v[1].x = u2f( raster->command_buffer[2] << 8 );
 
369
        object.v[1].y = u2f( raster->command_buffer[3] << 8 );
 
370
        object.v[1].pz = u2f( raster->command_buffer[4] << 8 );
374
371
 
375
372
        /* extract P1(n-1) */
376
 
        object.v[0].x = u2f( raster.command_buffer[5] << 8 );
377
 
        object.v[0].y = u2f( raster.command_buffer[6] << 8 );
378
 
        object.v[0].pz = u2f( raster.command_buffer[7] << 8 );
 
373
        object.v[0].x = u2f( raster->command_buffer[5] << 8 );
 
374
        object.v[0].y = u2f( raster->command_buffer[6] << 8 );
 
375
        object.v[0].pz = u2f( raster->command_buffer[7] << 8 );
379
376
 
380
377
        /* extract P0(n) */
381
 
        object.v[2].x = u2f( raster.command_buffer[11] << 8 );
382
 
        object.v[2].y = u2f( raster.command_buffer[12] << 8 );
383
 
        object.v[2].pz = u2f( raster.command_buffer[13] << 8 );
 
378
        object.v[2].x = u2f( raster->command_buffer[11] << 8 );
 
379
        object.v[2].y = u2f( raster->command_buffer[12] << 8 );
 
380
        object.v[2].pz = u2f( raster->command_buffer[13] << 8 );
384
381
 
385
382
        /* extract P1(n) */
386
 
        object.v[3].x = u2f( raster.command_buffer[14] << 8 );
387
 
        object.v[3].y = u2f( raster.command_buffer[15] << 8 );
388
 
        object.v[3].pz = u2f( raster.command_buffer[16] << 8 );
 
383
        object.v[3].x = u2f( raster->command_buffer[14] << 8 );
 
384
        object.v[3].y = u2f( raster->command_buffer[15] << 8 );
 
385
        object.v[3].pz = u2f( raster->command_buffer[16] << 8 );
389
386
 
390
387
        /* always calculate the min z and max z value */
391
388
        min_z = object.v[0].pz;
401
398
        /* read in the texture information */
402
399
 
403
400
        /* texture point data */
404
 
        if ( raster.command_buffer[0] & 0x800000 )
405
 
                tp = &raster.texture_ram[raster.command_buffer[0] & 0xFFFF];
 
401
        if ( raster->command_buffer[0] & 0x800000 )
 
402
                tp = &raster->texture_ram[raster->command_buffer[0] & 0xFFFF];
406
403
        else
407
 
                tp = &raster.texture_rom[raster.command_buffer[0] & 0x7FFFFF];
 
404
                tp = &raster->texture_rom[raster->command_buffer[0] & 0x7FFFFF];
408
405
 
409
406
        object.v[0].pv = *tp++;
410
407
        object.v[0].pu = *tp++;
416
413
        object.v[3].pu = *tp++;
417
414
 
418
415
        /* update the address */
419
 
        raster.command_buffer[0] += 8;
 
416
        raster->command_buffer[0] += 8;
420
417
 
421
418
        /* texture header data */
422
 
        if ( raster.command_buffer[1] & 0x800000 )
423
 
                th = &raster.texture_ram[raster.command_buffer[1] & 0xFFFF];
 
419
        if ( raster->command_buffer[1] & 0x800000 )
 
420
                th = &raster->texture_ram[raster->command_buffer[1] & 0xFFFF];
424
421
        else
425
 
                th = &raster.texture_rom[raster.command_buffer[1] & 0x7FFFFF];
 
422
                th = &raster->texture_rom[raster->command_buffer[1] & 0x7FFFFF];
426
423
 
427
424
        object.texheader[0] = *th++;
428
425
        object.texheader[1] = *th++;
437
434
                tho |= -16;
438
435
 
439
436
        /* update the address */
440
 
        raster.command_buffer[1] += tho * 4;
 
437
        raster->command_buffer[1] += tho * 4;
441
438
 
442
439
        /* set the luma value of this quad */
443
 
        object.luma = (raster.command_buffer[9] >> 15) & 0xFF;
 
440
        object.luma = (raster->command_buffer[9] >> 15) & 0xFF;
444
441
 
445
442
        /* determine wether we can cull this quad */
446
443
        cull = 0;
449
446
        if ( ((attr >> 17) & 1) == 0 )
450
447
        {
451
448
                /* if it's the backface, cull it */
452
 
                if ( raster.command_buffer[9] & 0x00800000 )
 
449
                if ( raster->command_buffer[9] & 0x00800000 )
453
450
                        cull = 1;
454
451
        }
455
452
 
458
455
                cull = 1;
459
456
 
460
457
        /* if the minimum z value is bigger than the master z clip value, don't render */
461
 
        if ( (INT32)(1.0/min_z) > raster.master_z_clip )
 
458
        if ( (INT32)(1.0/min_z) > raster->master_z_clip )
462
459
                cull = 1;
463
460
 
464
461
        /* if the maximum z value is < 0 then we can safely clip the entire polygon */
466
463
                cull = 1;
467
464
 
468
465
        /* set the object's z value */
469
 
        zvalue = raster.triangle_z;
 
466
        zvalue = raster->triangle_z;
470
467
 
471
468
        /* see if we need to recompute min/max z */
472
469
        if ( (attr >> 10) & 3 )
480
477
                        zvalue = max_z;
481
478
                }
482
479
 
483
 
                raster.triangle_z = zvalue;
 
480
                raster->triangle_z = zvalue;
484
481
        }
485
482
 
486
483
        if ( cull == 0 )
502
499
                        triangle *ztri;
503
500
 
504
501
                        /* adjust and set the object z-sort value */
505
 
                        object.z = float_to_zval( zvalue + raster.z_adjust );
 
502
                        object.z = float_to_zval( zvalue + raster->z_adjust );
506
503
 
507
504
                        /* get our list read to add the triangles */
508
 
                        ztri = raster.tri_sorted_list[object.z];
 
505
                        ztri = raster->tri_sorted_list[object.z];
509
506
 
510
507
                        if ( ztri != NULL )
511
508
                        {
518
515
                        {
519
516
                                triangle        *tri;
520
517
 
521
 
                                tri = &raster.tri_list[raster.tri_list_index++];
 
518
                                tri = &raster->tri_list[raster->tri_list_index++];
522
519
 
523
 
                                if ( raster.tri_list_index >= MAX_TRIANGLES )
 
520
                                if ( raster->tri_list_index >= MAX_TRIANGLES )
524
521
                                {
525
522
                                        fatalerror( "SEGA 3D: Max triangle limit exceeded\n" );
526
523
                                }
534
531
                                tri->luma = object.luma;
535
532
 
536
533
                                /* set the viewport */
537
 
                                tri->viewport[0] = raster.viewport[0];
538
 
                                tri->viewport[1] = raster.viewport[1];
539
 
                                tri->viewport[2] = raster.viewport[2];
540
 
                                tri->viewport[3] = raster.viewport[3];
 
534
                                tri->viewport[0] = raster->viewport[0];
 
535
                                tri->viewport[1] = raster->viewport[1];
 
536
                                tri->viewport[2] = raster->viewport[2];
 
537
                                tri->viewport[3] = raster->viewport[3];
541
538
 
542
539
                                /* set the center */
543
 
                                tri->center[0] = raster.center[raster.center_sel][0];
544
 
                                tri->center[1] = raster.center[raster.center_sel][1];
 
540
                                tri->center[0] = raster->center[raster->center_sel][0];
 
541
                                tri->center[1] = raster->center[raster->center_sel][1];
545
542
 
546
543
                                memcpy( &tri->v[0], &verts[0], sizeof( poly_vertex ) );
547
544
                                memcpy( &tri->v[1], &verts[i-1], sizeof( poly_vertex ) );
552
549
 
553
550
                                if ( ztri == NULL )
554
551
                                {
555
 
                                        raster.tri_sorted_list[object.z] = tri;
 
552
                                        raster->tri_sorted_list[object.z] = tri;
556
553
                                }
557
554
                                else
558
555
                                {
563
560
                        }
564
561
 
565
562
                        /* keep around the min and max z values for this frame */
566
 
                        if ( object.z < raster.min_z ) raster.min_z = object.z;
567
 
                        if ( object.z > raster.max_z ) raster.max_z = object.z;
 
563
                        if ( object.z < raster->min_z ) raster->min_z = object.z;
 
564
                        if ( object.z > raster->max_z ) raster->max_z = object.z;
568
565
                }
569
566
        }
570
567
 
576
573
                {
577
574
                        /* reuse P0(n) and P1(n) */
578
575
                        for( i = 0; i < 6; i++ )                                                                                /* P0(n) -> P0(n-1) */
579
 
                                raster.command_buffer[2+i] = raster.command_buffer[11+i];       /* P1(n) -> P1(n-1) */
 
576
                                raster->command_buffer[2+i] = raster->command_buffer[11+i];     /* P1(n) -> P1(n-1) */
580
577
                }
581
578
                break;
582
579
 
584
581
                {
585
582
                        /* reuse P0(n-1) and P0(n) */
586
583
                        for( i = 0; i < 3; i++ )
587
 
                                raster.command_buffer[5+i] = raster.command_buffer[11+i];       /* P0(n) -> P1(n-1) */
 
584
                                raster->command_buffer[5+i] = raster->command_buffer[11+i];     /* P0(n) -> P1(n-1) */
588
585
                }
589
586
                break;
590
587
 
592
589
                {
593
590
                        /* reuse P1(n-1) and P1(n) */
594
591
                        for( i = 0; i < 3; i++ )
595
 
                                raster.command_buffer[2+i] = raster.command_buffer[14+i];       /* P1(n) -> P1(n-1) */
 
592
                                raster->command_buffer[2+i] = raster->command_buffer[14+i];     /* P1(n) -> P1(n-1) */
596
593
                }
597
594
                break;
598
595
        }
599
596
}
600
597
 
601
 
static void model2_3d_process_triangle( UINT32 attr )
 
598
static void model2_3d_process_triangle( raster_state *raster, UINT32 attr )
602
599
{
603
600
        triangle        object;
604
601
        UINT16          *th, *tp;
608
605
        float           min_z, max_z;
609
606
 
610
607
        /* extract P0(n-1) */
611
 
        object.v[1].x = u2f( raster.command_buffer[2] << 8 );
612
 
        object.v[1].y = u2f( raster.command_buffer[3] << 8 );
613
 
        object.v[1].pz = u2f( raster.command_buffer[4] << 8 );
 
608
        object.v[1].x = u2f( raster->command_buffer[2] << 8 );
 
609
        object.v[1].y = u2f( raster->command_buffer[3] << 8 );
 
610
        object.v[1].pz = u2f( raster->command_buffer[4] << 8 );
614
611
 
615
612
        /* extract P1(n-1) */
616
 
        object.v[0].x = u2f( raster.command_buffer[5] << 8 );
617
 
        object.v[0].y = u2f( raster.command_buffer[6] << 8 );
618
 
        object.v[0].pz = u2f( raster.command_buffer[7] << 8 );
 
613
        object.v[0].x = u2f( raster->command_buffer[5] << 8 );
 
614
        object.v[0].y = u2f( raster->command_buffer[6] << 8 );
 
615
        object.v[0].pz = u2f( raster->command_buffer[7] << 8 );
619
616
 
620
617
        /* extract P0(n) */
621
 
        object.v[2].x = u2f( raster.command_buffer[11] << 8 );
622
 
        object.v[2].y = u2f( raster.command_buffer[12] << 8 );
623
 
        object.v[2].pz = u2f( raster.command_buffer[13] << 8 );
 
618
        object.v[2].x = u2f( raster->command_buffer[11] << 8 );
 
619
        object.v[2].y = u2f( raster->command_buffer[12] << 8 );
 
620
        object.v[2].pz = u2f( raster->command_buffer[13] << 8 );
624
621
 
625
622
        /* for triangles, the rope of P1(n) is achieved by P0(n-1) (linktype 3) */
626
 
        raster.command_buffer[14] = raster.command_buffer[11];
627
 
        raster.command_buffer[15] = raster.command_buffer[12];
628
 
        raster.command_buffer[16] = raster.command_buffer[13];
 
623
        raster->command_buffer[14] = raster->command_buffer[11];
 
624
        raster->command_buffer[15] = raster->command_buffer[12];
 
625
        raster->command_buffer[16] = raster->command_buffer[13];
629
626
 
630
627
        /* always calculate the min z and max z values */
631
628
        min_z = object.v[0].pz;
639
636
        /* read in the texture information */
640
637
 
641
638
        /* texture point data */
642
 
        if ( raster.command_buffer[0] & 0x800000 )
643
 
                tp = &raster.texture_ram[raster.command_buffer[0] & 0xFFFF];
 
639
        if ( raster->command_buffer[0] & 0x800000 )
 
640
                tp = &raster->texture_ram[raster->command_buffer[0] & 0xFFFF];
644
641
        else
645
 
                tp = &raster.texture_rom[raster.command_buffer[0] & 0x7FFFFF];
 
642
                tp = &raster->texture_rom[raster->command_buffer[0] & 0x7FFFFF];
646
643
 
647
644
        object.v[0].pv = *tp++;
648
645
        object.v[0].pu = *tp++;
652
649
        object.v[2].pu = *tp++;
653
650
 
654
651
        /* update the address */
655
 
        raster.command_buffer[0] += 6;
 
652
        raster->command_buffer[0] += 6;
656
653
 
657
654
        /* texture header data */
658
 
        if ( raster.command_buffer[1] & 0x800000 )
659
 
                th = &raster.texture_ram[raster.command_buffer[1] & 0xFFFF];
 
655
        if ( raster->command_buffer[1] & 0x800000 )
 
656
                th = &raster->texture_ram[raster->command_buffer[1] & 0xFFFF];
660
657
        else
661
 
                th = &raster.texture_rom[raster.command_buffer[1] & 0x7FFFFF];
 
658
                th = &raster->texture_rom[raster->command_buffer[1] & 0x7FFFFF];
662
659
 
663
660
        object.texheader[0] = *th++;
664
661
        object.texheader[1] = *th++;
673
670
                tho |= -16;
674
671
 
675
672
        /* update the address */
676
 
        raster.command_buffer[1] += tho * 4;
 
673
        raster->command_buffer[1] += tho * 4;
677
674
 
678
675
        /* set the luma value of this quad */
679
 
        object.luma = (raster.command_buffer[9] >> 15) & 0xFF;
 
676
        object.luma = (raster->command_buffer[9] >> 15) & 0xFF;
680
677
 
681
678
        /* determine wether we can cull this quad */
682
679
        cull = 0;
685
682
        if ( ((attr >> 17) & 1) == 0 )
686
683
        {
687
684
                /* if it's the backface, cull it */
688
 
                if ( raster.command_buffer[9] & 0x00800000 )
 
685
                if ( raster->command_buffer[9] & 0x00800000 )
689
686
                        cull = 1;
690
687
        }
691
688
 
694
691
                cull = 1;
695
692
 
696
693
        /* if the minimum z value is bigger than the master z clip value, don't render */
697
 
        if ( (INT32)(1.0/min_z) > raster.master_z_clip )
 
694
        if ( (INT32)(1.0/min_z) > raster->master_z_clip )
698
695
                cull = 1;
699
696
 
700
697
        /* if the maximum z value is < 0 then we can safely clip the entire polygon */
702
699
                cull = 1;
703
700
 
704
701
        /* set the object's z value */
705
 
        zvalue = raster.triangle_z;
 
702
        zvalue = raster->triangle_z;
706
703
 
707
704
        /* see if we need to recompute min/max z */
708
705
        if ( (attr >> 10) & 3 )
716
713
                        zvalue = max_z;
717
714
                }
718
715
 
719
 
                raster.triangle_z = zvalue;
 
716
                raster->triangle_z = zvalue;
720
717
        }
721
718
 
722
719
        /* if we're not culling, do z-clip and add to out triangle list */
739
736
                        triangle *ztri;
740
737
 
741
738
                        /* adjust and set the object z-sort value */
742
 
                        object.z = float_to_zval( zvalue + raster.z_adjust );
 
739
                        object.z = float_to_zval( zvalue + raster->z_adjust );
743
740
 
744
741
                        /* get our list read to add the triangles */
745
 
                        ztri = raster.tri_sorted_list[object.z];
 
742
                        ztri = raster->tri_sorted_list[object.z];
746
743
 
747
744
                        if ( ztri != NULL )
748
745
                        {
755
752
                        {
756
753
                                triangle        *tri;
757
754
 
758
 
                                tri = &raster.tri_list[raster.tri_list_index++];
 
755
                                tri = &raster->tri_list[raster->tri_list_index++];
759
756
 
760
 
                                if ( raster.tri_list_index >= MAX_TRIANGLES )
 
757
                                if ( raster->tri_list_index >= MAX_TRIANGLES )
761
758
                                {
762
759
                                        fatalerror( "SEGA 3D: Max triangle limit exceeded\n" );
763
760
                                }
771
768
                                tri->luma = object.luma;
772
769
 
773
770
                                /* set the viewport */
774
 
                                tri->viewport[0] = raster.viewport[0];
775
 
                                tri->viewport[1] = raster.viewport[1];
776
 
                                tri->viewport[2] = raster.viewport[2];
777
 
                                tri->viewport[3] = raster.viewport[3];
 
771
                                tri->viewport[0] = raster->viewport[0];
 
772
                                tri->viewport[1] = raster->viewport[1];
 
773
                                tri->viewport[2] = raster->viewport[2];
 
774
                                tri->viewport[3] = raster->viewport[3];
778
775
 
779
776
                                /* set the center */
780
 
                                tri->center[0] = raster.center[raster.center_sel][0];
781
 
                                tri->center[1] = raster.center[raster.center_sel][1];
 
777
                                tri->center[0] = raster->center[raster->center_sel][0];
 
778
                                tri->center[1] = raster->center[raster->center_sel][1];
782
779
 
783
780
                                memcpy( &tri->v[0], &verts[0], sizeof( poly_vertex ) );
784
781
                                memcpy( &tri->v[1], &verts[i-1], sizeof( poly_vertex ) );
789
786
 
790
787
                                if ( ztri == NULL )
791
788
                                {
792
 
                                        raster.tri_sorted_list[object.z] = tri;
 
789
                                        raster->tri_sorted_list[object.z] = tri;
793
790
                                }
794
791
                                else
795
792
                                {
800
797
                        }
801
798
 
802
799
                        /* keep around the min and max z values for this frame */
803
 
                        if ( object.z < raster.min_z ) raster.min_z = object.z;
804
 
                        if ( object.z > raster.max_z ) raster.max_z = object.z;
 
800
                        if ( object.z < raster->min_z ) raster->min_z = object.z;
 
801
                        if ( object.z > raster->max_z ) raster->max_z = object.z;
805
802
                }
806
803
        }
807
804
 
813
810
                {
814
811
                        /* reuse P0(n) and P1(n) */
815
812
                        for( i = 0; i < 6; i++ )                                                                                /* P0(n) -> P0(n-1) */
816
 
                                raster.command_buffer[2+i] = raster.command_buffer[11+i];       /* P1(n) -> P1(n-1) */
 
813
                                raster->command_buffer[2+i] = raster->command_buffer[11+i];     /* P1(n) -> P1(n-1) */
817
814
                }
818
815
                break;
819
816
 
821
818
                {
822
819
                        /* reuse P0(n-1) and P0(n) */
823
820
                        for( i = 0; i < 3; i++ )
824
 
                                raster.command_buffer[5+i] = raster.command_buffer[11+i];       /* P0(n) -> P1(n-1) */
 
821
                                raster->command_buffer[5+i] = raster->command_buffer[11+i];     /* P0(n) -> P1(n-1) */
825
822
                }
826
823
                break;
827
824
 
829
826
                {
830
827
                        /* reuse P1(n-1) and P1(n) */
831
828
                        for( i = 0; i < 3; i++ )
832
 
                                raster.command_buffer[2+i] = raster.command_buffer[14+i];       /* P1(n) -> P1(n-1) */
 
829
                                raster->command_buffer[2+i] = raster->command_buffer[14+i];     /* P1(n) -> P1(n-1) */
833
830
                }
834
831
                break;
835
832
        }
926
923
        model2_3d_render_7      /* checker = 1, textured = 1, translucent = 1 */
927
924
};
928
925
 
929
 
static void model2_3d_render( bitmap_t *bitmap, triangle *tri, const rectangle *cliprect )
 
926
static void model2_3d_render( model2_state *state, bitmap_t *bitmap, triangle *tri, const rectangle *cliprect )
930
927
{
 
928
        poly_manager *poly = state->m_poly;
931
929
        poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly);
932
930
        UINT8           renderer;
933
931
        rectangle       vp;
946
944
        if ( vp.min_y < cliprect->min_y ) vp.min_y = cliprect->min_y;
947
945
        if ( vp.max_y > cliprect->max_y ) vp.max_y = cliprect->max_y;
948
946
 
 
947
        extra->state = state;
949
948
        extra->lumabase = ((tri->texheader[1] & 0xFF) << 7) + ((tri->luma >> 5) ^ 0x7);
950
949
        extra->colorbase = (tri->texheader[3] >> 6) & 0x3FF;
951
950
 
957
956
                extra->texy = 32 * (((tri->texheader[2] >> 6) & 0x1f) + ( tri->texheader[2] & 0x20 ));
958
957
                extra->texmirrorx = (tri->texheader[0] >> 9) & 1;
959
958
                extra->texmirrory = (tri->texheader[0] >> 8) & 1;
960
 
                extra->texsheet = (tri->texheader[2] & 0x1000) ? model2_textureram1 : model2_textureram0;
 
959
                extra->texsheet = (tri->texheader[2] & 0x1000) ? state->m_textureram1 : state->m_textureram0;
961
960
 
962
961
                tri->v[0].pz = 1.0f / (1.0f + tri->v[0].pz);
963
962
                tri->v[0].pu = tri->v[0].pu * tri->v[0].pz * (1.0f / 8.0f);
1008
1007
}
1009
1008
 
1010
1009
/* 3D Rasterizer frame start: Resets frame variables */
1011
 
static void model2_3d_frame_start( void )
 
1010
static void model2_3d_frame_start( model2_state *state )
1012
1011
{
 
1012
        raster_state *raster = state->m_raster;
 
1013
 
1013
1014
        /* reset the triangle list index */
1014
 
        raster.tri_list_index = 0;
 
1015
        raster->tri_list_index = 0;
1015
1016
 
1016
1017
        /* reset the sorted z list */
1017
 
        memset( raster.tri_sorted_list, 0, 0x10000 * sizeof( triangle * ) );
 
1018
        memset( raster->tri_sorted_list, 0, 0x10000 * sizeof( triangle * ) );
1018
1019
 
1019
1020
        /* reset the min-max sortable Z values */
1020
 
        raster.min_z = 0xFFFF;
1021
 
        raster.max_z = 0;
 
1021
        raster->min_z = 0xFFFF;
 
1022
        raster->max_z = 0;
1022
1023
}
1023
1024
 
1024
 
static void model2_3d_frame_end( bitmap_t *bitmap, const rectangle *cliprect )
 
1025
static void model2_3d_frame_end( model2_state *state, bitmap_t *bitmap, const rectangle *cliprect )
1025
1026
{
 
1027
        raster_state *raster = state->m_raster;
1026
1028
        INT32           z;
1027
1029
 
1028
1030
        /* if we have nothing to render, bail */
1029
 
        if ( raster.tri_list_index == 0 )
 
1031
        if ( raster->tri_list_index == 0 )
1030
1032
                return;
1031
1033
 
1032
1034
#if DEBUG
1038
1040
 
1039
1041
                if ( f )
1040
1042
                {
1041
 
                        for( i = 0; i < raster.tri_list_index; i++ )
 
1043
                        for( i = 0; i < raster->tri_list_index; i++ )
1042
1044
                        {
1043
1045
 
1044
1046
                                fprintf( f, "index: %d\n", i );
1045
 
                                fprintf( f, "v0.x = %f, v0.y = %f, v0.z = %f\n", raster.tri_list[i].v[0].x, raster.tri_list[i].v[0].y, raster.tri_list[i].v[0].pz );
1046
 
                                fprintf( f, "v1.x = %f, v1.y = %f, v1.z = %f\n", raster.tri_list[i].v[1].x, raster.tri_list[i].v[1].y, raster.tri_list[i].v[1].pz );
1047
 
                                fprintf( f, "v2.x = %f, v2.y = %f, v2.z = %f\n", raster.tri_list[i].v[2].x, raster.tri_list[i].v[2].y, raster.tri_list[i].v[2].pz );
 
1047
                                fprintf( f, "v0.x = %f, v0.y = %f, v0.z = %f\n", raster->tri_list[i].v[0].x, raster->tri_list[i].v[0].y, raster->tri_list[i].v[0].pz );
 
1048
                                fprintf( f, "v1.x = %f, v1.y = %f, v1.z = %f\n", raster->tri_list[i].v[1].x, raster->tri_list[i].v[1].y, raster->tri_list[i].v[1].pz );
 
1049
                                fprintf( f, "v2.x = %f, v2.y = %f, v2.z = %f\n", raster->tri_list[i].v[2].x, raster->tri_list[i].v[2].y, raster->tri_list[i].v[2].pz );
1048
1050
 
1049
 
                                fprintf( f, "tri z: %04x\n", raster.tri_list[i].pz );
1050
 
                                fprintf( f, "texheader - 0: %04x\n", raster.tri_list[i].texheader[0] );
1051
 
                                fprintf( f, "texheader - 1: %04x\n", raster.tri_list[i].texheader[1] );
1052
 
                                fprintf( f, "texheader - 2: %04x\n", raster.tri_list[i].texheader[2] );
1053
 
                                fprintf( f, "texheader - 3: %04x\n", raster.tri_list[i].texheader[3] );
1054
 
                                fprintf( f, "luma: %02x\n", raster.tri_list[i].luma );
1055
 
                                fprintf( f, "vp.sx: %04x\n", raster.tri_list[i].viewport[0] );
1056
 
                                fprintf( f, "vp.sy: %04x\n", raster.tri_list[i].viewport[1] );
1057
 
                                fprintf( f, "vp.ex: %04x\n", raster.tri_list[i].viewport[2] );
1058
 
                                fprintf( f, "vp.ey: %04x\n", raster.tri_list[i].viewport[3] );
1059
 
                                fprintf( f, "vp.swx: %04x\n", raster.tri_list[i].center[0] );
1060
 
                                fprintf( f, "vp.swy: %04x\n", raster.tri_list[i].center[1] );
 
1051
                                fprintf( f, "tri z: %04x\n", raster->tri_list[i].pz );
 
1052
                                fprintf( f, "texheader - 0: %04x\n", raster->tri_list[i].texheader[0] );
 
1053
                                fprintf( f, "texheader - 1: %04x\n", raster->tri_list[i].texheader[1] );
 
1054
                                fprintf( f, "texheader - 2: %04x\n", raster->tri_list[i].texheader[2] );
 
1055
                                fprintf( f, "texheader - 3: %04x\n", raster->tri_list[i].texheader[3] );
 
1056
                                fprintf( f, "luma: %02x\n", raster->tri_list[i].luma );
 
1057
                                fprintf( f, "vp.sx: %04x\n", raster->tri_list[i].viewport[0] );
 
1058
                                fprintf( f, "vp.sy: %04x\n", raster->tri_list[i].viewport[1] );
 
1059
                                fprintf( f, "vp.ex: %04x\n", raster->tri_list[i].viewport[2] );
 
1060
                                fprintf( f, "vp.ey: %04x\n", raster->tri_list[i].viewport[3] );
 
1061
                                fprintf( f, "vp.swx: %04x\n", raster->tri_list[i].center[0] );
 
1062
                                fprintf( f, "vp.swy: %04x\n", raster->tri_list[i].center[1] );
1061
1063
                                fprintf( f, "\n---\n\n" );
1062
1064
                        }
1063
1065
 
1064
 
                        fprintf( f, "min_z = %04x, max_z = %04x\n", raster.min_z, raster.max_z );
 
1066
                        fprintf( f, "min_z = %04x, max_z = %04x\n", raster->min_z, raster->max_z );
1065
1067
 
1066
1068
                        fclose( f );
1067
1069
                }
1069
1071
#endif
1070
1072
 
1071
1073
        /* go through the Z levels, and render each bucket */
1072
 
        for( z = raster.max_z; z >= raster.min_z; z-- )
 
1074
        for( z = raster->max_z; z >= raster->min_z; z-- )
1073
1075
        {
1074
1076
                /* see if we have items at this z level */
1075
 
                if ( raster.tri_sorted_list[z] != NULL )
 
1077
                if ( raster->tri_sorted_list[z] != NULL )
1076
1078
                {
1077
1079
                        /* get a pointer to the first triangle */
1078
 
                        triangle *tri = raster.tri_sorted_list[z];
 
1080
                        triangle *tri = raster->tri_sorted_list[z];
1079
1081
 
1080
1082
                        /* and loop clipping and rendering each triangle */
1081
1083
                        while( tri != NULL )
1082
1084
                        {
1083
1085
                                /* project and render */
1084
1086
                                model2_3d_project( tri );
1085
 
                                model2_3d_render( bitmap, tri, cliprect );
 
1087
                                model2_3d_render( state, bitmap, tri, cliprect );
1086
1088
 
1087
1089
                                tri = (triangle *)tri->next;
1088
1090
                        }
1089
1091
                }
1090
1092
        }
1091
 
        poly_wait(poly, "End of frame");
 
1093
        poly_wait(state->m_poly, "End of frame");
1092
1094
}
1093
1095
 
1094
1096
/* 3D Rasterizer main data input port */
1095
 
static void model2_3d_push( UINT32 input )
 
1097
static void model2_3d_push( raster_state *raster, UINT32 input )
1096
1098
{
1097
1099
        /* see if we have a command in progress */
1098
 
        if ( raster.cur_command != 0 )
 
1100
        if ( raster->cur_command != 0 )
1099
1101
        {
1100
 
                raster.command_buffer[raster.command_index++] = input;
 
1102
                raster->command_buffer[raster->command_index++] = input;
1101
1103
 
1102
 
                switch( raster.cur_command )
 
1104
                switch( raster->cur_command )
1103
1105
                {
1104
1106
                        case 0x00:      /* NOP */
1105
1107
                        break;
1109
1111
                                UINT32  attr;
1110
1112
 
1111
1113
                                /* start by looking if we have the basic input data */
1112
 
                                if ( raster.command_index < 9 )
 
1114
                                if ( raster->command_index < 9 )
1113
1115
                                        return;
1114
1116
 
1115
1117
                                /* get the attributes */
1116
 
                                attr = raster.command_buffer[8];
 
1118
                                attr = raster->command_buffer[8];
1117
1119
 
1118
1120
                                /* see if we're done */
1119
1121
                                if ( (attr & 3) == 0 )
1120
1122
                                {
1121
 
                                        raster.cur_command = 0;
 
1123
                                        raster->cur_command = 0;
1122
1124
                                        return;
1123
1125
                                }
1124
1126
 
1126
1128
                                if ( attr & 1 )
1127
1129
                                {
1128
1130
                                        /* it's a quad, wait for the rest of the points */
1129
 
                                        if ( raster.command_index < 17 )
 
1131
                                        if ( raster->command_index < 17 )
1130
1132
                                                return;
1131
1133
 
1132
1134
                                        /* we have a full quad info, fill up our quad structure */
1133
 
                                        model2_3d_process_quad( attr );
 
1135
                                        model2_3d_process_quad( raster, attr );
1134
1136
 
1135
1137
                                        /* back up and wait for more data */
1136
 
                                        raster.command_index = 8;
 
1138
                                        raster->command_index = 8;
1137
1139
                                }
1138
1140
                                else
1139
1141
                                {
1140
1142
                                        /* it's a triangle, wait for the rest of the point */
1141
 
                                        if ( raster.command_index < 14 )
 
1143
                                        if ( raster->command_index < 14 )
1142
1144
                                                return;
1143
1145
 
1144
1146
                                        /* we have a full quad info, fill up our quad structure */
1145
 
                                        model2_3d_process_triangle( attr );
 
1147
                                        model2_3d_process_triangle( raster, attr );
1146
1148
 
1147
1149
                                        /* back up and wait for more data */
1148
 
                                        raster.command_index = 8;
 
1150
                                        raster->command_index = 8;
1149
1151
                                }
1150
1152
                        }
1151
1153
                        break;
1155
1157
                                UINT32  i;
1156
1158
 
1157
1159
                                /* make sure we have all the data */
1158
 
                                if ( raster.command_index < 6 )
 
1160
                                if ( raster->command_index < 6 )
1159
1161
                                        return;
1160
1162
 
1161
1163
                                /* coordinates are 12 bit signed */
1162
1164
 
1163
1165
                                /* extract the viewport start x */
1164
 
                                raster.viewport[0] = (raster.command_buffer[0] >> 12) & 0xFFF;
 
1166
                                raster->viewport[0] = (raster->command_buffer[0] >> 12) & 0xFFF;
1165
1167
 
1166
 
                                if ( raster.viewport[0] & 0x800 )
1167
 
                                        raster.viewport[0] = -( 0x800 - (raster.viewport[0] & 0x7FF) );
 
1168
                                if ( raster->viewport[0] & 0x800 )
 
1169
                                        raster->viewport[0] = -( 0x800 - (raster->viewport[0] & 0x7FF) );
1168
1170
 
1169
1171
                                /* extract the viewport start y */
1170
 
                                raster.viewport[1] = raster.command_buffer[0] & 0xFFF;
 
1172
                                raster->viewport[1] = raster->command_buffer[0] & 0xFFF;
1171
1173
 
1172
 
                                if ( raster.viewport[1] & 0x800 )
1173
 
                                        raster.viewport[1] = -( 0x800 - (raster.viewport[1] & 0x7FF) );
 
1174
                                if ( raster->viewport[1] & 0x800 )
 
1175
                                        raster->viewport[1] = -( 0x800 - (raster->viewport[1] & 0x7FF) );
1174
1176
 
1175
1177
                                /* extract the viewport end x */
1176
 
                                raster.viewport[2] = (raster.command_buffer[1] >> 12) & 0xFFF;
 
1178
                                raster->viewport[2] = (raster->command_buffer[1] >> 12) & 0xFFF;
1177
1179
 
1178
 
                                if ( raster.viewport[2] & 0x800 )
1179
 
                                        raster.viewport[2] = -( 0x800 - (raster.viewport[2] & 0x7FF) );
 
1180
                                if ( raster->viewport[2] & 0x800 )
 
1181
                                        raster->viewport[2] = -( 0x800 - (raster->viewport[2] & 0x7FF) );
1180
1182
 
1181
1183
                                /* extract the viewport end y */
1182
 
                                raster.viewport[3] = raster.command_buffer[1] & 0xFFF;
 
1184
                                raster->viewport[3] = raster->command_buffer[1] & 0xFFF;
1183
1185
 
1184
 
                                if ( raster.viewport[3] & 0x800 )
1185
 
                                        raster.viewport[3] = -( 0x800 - (raster.viewport[3] & 0x7FF) );
 
1186
                                if ( raster->viewport[3] & 0x800 )
 
1187
                                        raster->viewport[3] = -( 0x800 - (raster->viewport[3] & 0x7FF) );
1186
1188
 
1187
1189
                                /* extract the centers */
1188
1190
                                for( i = 0; i < 4; i++ )
1189
1191
                                {
1190
1192
                                        /* center x */
1191
 
                                        raster.center[i][0] = (raster.command_buffer[2+i] >> 12) & 0xFFF;
 
1193
                                        raster->center[i][0] = (raster->command_buffer[2+i] >> 12) & 0xFFF;
1192
1194
 
1193
 
                                        if ( raster.center[i][0] & 0x800 )
1194
 
                                                raster.center[i][0] = -( 0x800 - (raster.center[i][0] & 0x7FF) );
 
1195
                                        if ( raster->center[i][0] & 0x800 )
 
1196
                                                raster->center[i][0] = -( 0x800 - (raster->center[i][0] & 0x7FF) );
1195
1197
 
1196
1198
                                        /* center y */
1197
 
                                        raster.center[i][1] = raster.command_buffer[2+i] & 0xFFF;
 
1199
                                        raster->center[i][1] = raster->command_buffer[2+i] & 0xFFF;
1198
1200
 
1199
 
                                        if ( raster.center[i][1] & 0x800 )
1200
 
                                                raster.center[i][1] = -( 0x800 - (raster.center[i][1] & 0x7FF) );
 
1201
                                        if ( raster->center[i][1] & 0x800 )
 
1202
                                                raster->center[i][1] = -( 0x800 - (raster->center[i][1] & 0x7FF) );
1201
1203
                                }
1202
1204
 
1203
1205
                                /* done with this command */
1204
 
                                raster.cur_command = 0;
 
1206
                                raster->cur_command = 0;
1205
1207
                        }
1206
1208
                        break;
1207
1209
 
1208
1210
                        case 0x04:      /* Texture/Log Data write */
1209
1211
                        {
1210
1212
                                /* make sure we have enough data */
1211
 
                                if ( raster.command_index < 2 )
 
1213
                                if ( raster->command_index < 2 )
1212
1214
                                        return;
1213
1215
 
1214
1216
                                /* see if the count is non-zero */
1215
 
                                if ( raster.command_buffer[1] > 0 )
 
1217
                                if ( raster->command_buffer[1] > 0 )
1216
1218
                                {
1217
1219
                                        /* see if we have data available */
1218
 
                                        if ( raster.command_index >= 3 )
 
1220
                                        if ( raster->command_index >= 3 )
1219
1221
                                        {
1220
1222
                                                /* get the address */
1221
 
                                                UINT32  address = raster.command_buffer[0];
 
1223
                                                UINT32  address = raster->command_buffer[0];
1222
1224
 
1223
1225
                                                /* do the write */
1224
1226
                                                if ( address & 0x800000 )
1225
 
                                                        raster.texture_ram[address&0xFFFF] = raster.command_buffer[2];
 
1227
                                                        raster->texture_ram[address&0xFFFF] = raster->command_buffer[2];
1226
1228
                                                else
1227
 
                                                        raster.log_ram[address&0xFFFF] = raster.command_buffer[2];
 
1229
                                                        raster->log_ram[address&0xFFFF] = raster->command_buffer[2];
1228
1230
 
1229
1231
                                                /* increment the address and decrease the count */
1230
 
                                                raster.command_buffer[0]++;
1231
 
                                                raster.command_buffer[1]--;
 
1232
                                                raster->command_buffer[0]++;
 
1233
                                                raster->command_buffer[1]--;
1232
1234
 
1233
1235
                                                /* decrease the index, so we keep placing data in the same slot */
1234
 
                                                raster.command_index--;
 
1236
                                                raster->command_index--;
1235
1237
                                        }
1236
1238
                                }
1237
1239
 
1238
1240
                                /* see if we're done with this command */
1239
 
                                if ( raster.command_buffer[1] == 0 )
1240
 
                                        raster.cur_command = 0;
 
1241
                                if ( raster->command_buffer[1] == 0 )
 
1242
                                        raster->cur_command = 0;
1241
1243
                        }
1242
1244
                        break;
1243
1245
 
1244
1246
                        case 0x08:      /* ZSort mode */
1245
1247
                        {
1246
1248
                                /* save the zsort mode value */
1247
 
                                raster.z_adjust = u2f( raster.command_buffer[0] << 8 );
 
1249
                                raster->z_adjust = u2f( raster->command_buffer[0] << 8 );
1248
1250
 
1249
1251
                                /* done with this command */
1250
 
                                raster.cur_command = 0;
 
1252
                                raster->cur_command = 0;
1251
1253
                        }
1252
1254
                        break;
1253
1255
 
1254
1256
                        default:
1255
1257
                        {
1256
 
                                fatalerror( "SEGA 3D: Unknown rasterizer command %08x\n", raster.cur_command );
 
1258
                                fatalerror( "SEGA 3D: Unknown rasterizer command %08x\n", raster->cur_command );
1257
1259
                        }
1258
1260
                        break;
1259
1261
                }
1261
1263
        else
1262
1264
        {
1263
1265
                /* new command */
1264
 
                raster.cur_command = input & 0x0F;
1265
 
                raster.command_index = 0;
 
1266
                raster->cur_command = input & 0x0F;
 
1267
                raster->command_index = 0;
1266
1268
 
1267
1269
                /* see if it's object data */
1268
 
                if ( raster.cur_command == 1 )
 
1270
                if ( raster->cur_command == 1 )
1269
1271
                {
1270
1272
                        /* extract reverse bit */
1271
 
                        raster.reverse = (input >> 4) & 1;
 
1273
                        raster->reverse = (input >> 4) & 1;
1272
1274
 
1273
1275
                        /* extract center select */
1274
 
                        raster.center_sel = ( input >> 6 ) & 3;
 
1276
                        raster->center_sel = ( input >> 6 ) & 3;
1275
1277
 
1276
1278
                        /* reset the triangle z value */
1277
 
                        raster.triangle_z = 0;
 
1279
                        raster->triangle_z = 0;
1278
1280
                }
1279
1281
        }
1280
1282
}
1289
1291
 *
1290
1292
 *******************************************/
1291
1293
 
1292
 
typedef struct
 
1294
struct _geo_state
1293
1295
{
 
1296
        raster_state *                  raster;
1294
1297
        UINT32                          mode;                                   /* bit 0 = Enable Specular, bit 1 = Calculate Normals */
1295
1298
        UINT32 *                        polygon_rom;                    /* Polygon ROM pointer */
1296
 
        UINT32 *                        polygon_ram0;                   /* Fast Polygon RAM pointer */
1297
 
        UINT32 *                        polygon_ram1;                   /* Slow Polygon RAM pointer */
1298
1299
        float                           matrix[12];                             /* Current Transformation Matrix */
1299
1300
        poly_vertex                     focus;                                  /* Focus (x,y) */
1300
1301
        poly_vertex                     light;                                  /* Light Vector */
1301
1302
        float                           lod;                                    /* LOD */
1302
1303
        float                           coef_table[32];                 /* Distane Coefficient table */
1303
1304
        texture_parameter       texture_parameters[32]; /* Texture parameters */
1304
 
} geo_state;
 
1305
        UINT32                  polygon_ram0[0x8000];                   /* Fast Polygon RAM pointer */
 
1306
        UINT32                  polygon_ram1[0x8000];                   /* Slow Polygon RAM pointer */
 
1307
};
1305
1308
 
1306
 
static geo_state geo;
1307
1309
 
1308
1310
/*******************************************
1309
1311
 *
1311
1313
 *
1312
1314
 *******************************************/
1313
1315
 
1314
 
static void geo_init( running_machine *machine, UINT32 *polygon_rom )
 
1316
static void geo_init( running_machine &machine, UINT32 *polygon_rom )
1315
1317
{
1316
 
        memset( &geo, 0, sizeof( geo_state ) );
 
1318
        model2_state *state = machine.driver_data<model2_state>();
 
1319
        state->m_geo = auto_alloc_clear(machine, geo_state);
1317
1320
 
1318
 
        geo.polygon_rom = polygon_rom;
1319
 
        geo.polygon_ram0 = auto_alloc_array(machine, UINT32, 0x8000);
1320
 
        geo.polygon_ram1 = auto_alloc_array(machine, UINT32, 0x8000);
 
1321
        state->m_geo->raster = state->m_raster;
 
1322
        state->m_geo->polygon_rom = polygon_rom;
1321
1323
}
1322
1324
 
1323
1325
/*******************************************
1327
1329
 *******************************************/
1328
1330
 
1329
1331
/* Parse Polygons: Normals Present, No Specular case */
1330
 
static void geo_parse_np_ns( UINT32 *input, UINT32 count )
 
1332
static void geo_parse_np_ns( geo_state *geo, UINT32 *input, UINT32 count )
1331
1333
{
 
1334
        raster_state *raster = geo->raster;
1332
1335
        poly_vertex     point, normal;
1333
1336
        UINT32  attr, i;
1334
1337
 
1338
1341
        point.pz = u2f( *input++ );
1339
1342
 
1340
1343
        /* transform with the current matrix */
1341
 
        transform_point( &point, geo.matrix );
 
1344
        transform_point( &point, geo->matrix );
1342
1345
 
1343
1346
        /* apply focus */
1344
 
        point.x *= geo.focus.x;
1345
 
        point.y *= geo.focus.y;
 
1347
        point.x *= geo->focus.x;
 
1348
        point.y *= geo->focus.y;
1346
1349
 
1347
1350
        /* push it to the 3d rasterizer */
1348
 
        model2_3d_push( f2u(point.x) >> 8 );
1349
 
        model2_3d_push( f2u(point.y) >> 8 );
1350
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1351
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1352
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1353
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1351
1354
 
1352
1355
        /* read the 2nd point */
1353
1356
        point.x = u2f( *input++ );
1355
1358
        point.pz = u2f( *input++ );
1356
1359
 
1357
1360
        /* transform with the current matrix */
1358
 
        transform_point( &point, geo.matrix );
 
1361
        transform_point( &point, geo->matrix );
1359
1362
 
1360
1363
        /* apply focus */
1361
 
        point.x *= geo.focus.x;
1362
 
        point.y *= geo.focus.y;
 
1364
        point.x *= geo->focus.x;
 
1365
        point.y *= geo->focus.y;
1363
1366
 
1364
1367
        /* push it to the 3d rasterizer */
1365
 
        model2_3d_push( f2u(point.x) >> 8 );
1366
 
        model2_3d_push( f2u(point.y) >> 8 );
1367
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1368
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1369
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1370
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1368
1371
 
1369
1372
        /* loop through the following links */
1370
1373
        for( i = 0; i < count; i++ )
1373
1376
                attr = *input++;
1374
1377
 
1375
1378
                /* push to the 3d rasterizer */
1376
 
                model2_3d_push( attr & 0x0003FFFF );
 
1379
                model2_3d_push( raster, attr & 0x0003FFFF );
1377
1380
 
1378
1381
                /* read in the normal */
1379
1382
                normal.x = u2f(*input++);
1381
1384
                normal.pz = u2f(*input++);
1382
1385
 
1383
1386
                /* transform with the current matrix */
1384
 
                transform_vector( &normal, geo.matrix );
 
1387
                transform_vector( &normal, geo->matrix );
1385
1388
 
1386
1389
                if ( (attr & 3) != 0 ) /* quad or triangle */
1387
1390
                {
1396
1399
                        point.pz = u2f( *input++ );
1397
1400
 
1398
1401
                        /* transform with the current matrix */
1399
 
                        transform_point( &point, geo.matrix );
 
1402
                        transform_point( &point, geo->matrix );
1400
1403
 
1401
1404
                        /* calculate the dot product of the normal and the light vector */
1402
 
                        dotl = dot_product( &normal, &geo.light );
 
1405
                        dotl = dot_product( &normal, &geo->light );
1403
1406
 
1404
1407
                        /* calculate the dot product of the normal and the point */
1405
1408
                        dotp = dot_product( &normal, &point );
1406
1409
 
1407
1410
                        /* apply focus */
1408
 
                        point.x *= geo.focus.x;
1409
 
                        point.y *= geo.focus.y;
 
1411
                        point.x *= geo->focus.x;
 
1412
                        point.y *= geo->focus.y;
1410
1413
 
1411
1414
                        /* determine wether this is the front or the back of the polygon */
1412
1415
                        face = 0x100; /* rear */
1413
1416
                        if ( dotp >= 0 ) face = 0; /* front */
1414
1417
 
1415
1418
                        /* get the texture parameters */
1416
 
                        texparam = &geo.texture_parameters[(attr>>18) & 0x1f];
 
1419
                        texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1417
1420
 
1418
1421
                        /* calculate luminance */
1419
1422
                        if ( (dotl * dotp) < 0 ) luminance = 0;
1429
1432
                        luma += face;
1430
1433
 
1431
1434
                        /* extract distance coefficient */
1432
 
                        coef = geo.coef_table[attr>>27];
 
1435
                        coef = geo->coef_table[attr>>27];
1433
1436
 
1434
1437
                        /* calculate texture level of detail */
1435
 
                        distance = coef * fabs( dotp ) * geo.lod;
 
1438
                        distance = coef * fabs( dotp ) * geo->lod;
1436
1439
 
1437
1440
                        /* push to the 3d rasterizer */
1438
 
                        model2_3d_push( luma << 15 );
1439
 
                        model2_3d_push( f2u(distance) >> 8 );
1440
 
                        model2_3d_push( f2u(point.x) >> 8 );
1441
 
                        model2_3d_push( f2u(point.y) >> 8 );
1442
 
                        model2_3d_push( f2u(point.pz) >> 8 );
 
1441
                        model2_3d_push( raster, luma << 15 );
 
1442
                        model2_3d_push( raster, f2u(distance) >> 8 );
 
1443
                        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1444
                        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1445
                        model2_3d_push( raster, f2u(point.pz) >> 8 );
1443
1446
 
1444
1447
                        /* if it's a quad, push one more point */
1445
1448
                        if ( attr & 1 )
1450
1453
                                point.pz = u2f( *input++ );
1451
1454
 
1452
1455
                                /* transform with the current matrix */
1453
 
                                transform_point( &point, geo.matrix );
 
1456
                                transform_point( &point, geo->matrix );
1454
1457
 
1455
1458
                                /* apply focus */
1456
 
                                point.x *= geo.focus.x;
1457
 
                                point.y *= geo.focus.y;
 
1459
                                point.x *= geo->focus.x;
 
1460
                                point.y *= geo->focus.y;
1458
1461
 
1459
1462
                                /* push to the 3d rasterizer */
1460
 
                                model2_3d_push( f2u(point.x) >> 8 );
1461
 
                                model2_3d_push( f2u(point.y) >> 8 );
1462
 
                                model2_3d_push( f2u(point.pz) >> 8 );
 
1463
                                model2_3d_push( raster, f2u(point.x) >> 8 );
 
1464
                                model2_3d_push( raster, f2u(point.y) >> 8 );
 
1465
                                model2_3d_push( raster, f2u(point.pz) >> 8 );
1463
1466
                        }
1464
1467
                        else /* triangle */
1465
1468
                        {
1474
1477
        }
1475
1478
 
1476
1479
        /* notify the 3d rasterizer we're done */
1477
 
        model2_3d_push( 0 );
 
1480
        model2_3d_push( raster, 0 );
1478
1481
}
1479
1482
 
1480
1483
/* Parse Polygons: Normals Present, Specular case */
1481
 
static void geo_parse_np_s( UINT32 *input, UINT32 count )
 
1484
static void geo_parse_np_s( geo_state *geo, UINT32 *input, UINT32 count )
1482
1485
{
 
1486
        raster_state *raster = geo->raster;
1483
1487
        poly_vertex     point, normal;
1484
1488
        UINT32  attr, i;
1485
1489
 
1489
1493
        point.pz = u2f( *input++ );
1490
1494
 
1491
1495
        /* transform with the current matrix */
1492
 
        transform_point( &point, geo.matrix );
 
1496
        transform_point( &point, geo->matrix );
1493
1497
 
1494
1498
        /* apply focus */
1495
 
        point.x *= geo.focus.x;
1496
 
        point.y *= geo.focus.y;
 
1499
        point.x *= geo->focus.x;
 
1500
        point.y *= geo->focus.y;
1497
1501
 
1498
1502
        /* push it to the 3d rasterizer */
1499
 
        model2_3d_push( f2u(point.x) >> 8 );
1500
 
        model2_3d_push( f2u(point.y) >> 8 );
1501
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1503
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1504
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1505
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1502
1506
 
1503
1507
        /* read the 2nd point */
1504
1508
        point.x = u2f( *input++ );
1506
1510
        point.pz = u2f( *input++ );
1507
1511
 
1508
1512
        /* transform with the current matrix */
1509
 
        transform_point( &point, geo.matrix );
 
1513
        transform_point( &point, geo->matrix );
1510
1514
 
1511
1515
        /* apply focus */
1512
 
        point.x *= geo.focus.x;
1513
 
        point.y *= geo.focus.y;
 
1516
        point.x *= geo->focus.x;
 
1517
        point.y *= geo->focus.y;
1514
1518
 
1515
1519
        /* push it to the 3d rasterizer */
1516
 
        model2_3d_push( f2u(point.x) >> 8 );
1517
 
        model2_3d_push( f2u(point.y) >> 8 );
1518
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1520
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1521
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1522
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1519
1523
 
1520
1524
        /* loop through the following links */
1521
1525
        for( i = 0; i < count; i++ )
1524
1528
                attr = *input++;
1525
1529
 
1526
1530
                /* push to the 3d rasterizer */
1527
 
                model2_3d_push( attr & 0x0003FFFF );
 
1531
                model2_3d_push( raster, attr & 0x0003FFFF );
1528
1532
 
1529
1533
                /* read in the normal */
1530
1534
                normal.x = u2f(*input++);
1532
1536
                normal.pz = u2f(*input++);
1533
1537
 
1534
1538
                /* transform with the current matrix */
1535
 
                transform_vector( &normal, geo.matrix );
 
1539
                transform_vector( &normal, geo->matrix );
1536
1540
 
1537
1541
                if ( (attr & 3) != 0 ) /* quad or triangle */
1538
1542
                {
1547
1551
                        point.pz = u2f( *input++ );
1548
1552
 
1549
1553
                        /* transform with the current matrix */
1550
 
                        transform_point( &point, geo.matrix );
 
1554
                        transform_point( &point, geo->matrix );
1551
1555
 
1552
1556
                        /* calculate the dot product of the normal and the light vector */
1553
 
                        dotl = dot_product( &normal, &geo.light );
 
1557
                        dotl = dot_product( &normal, &geo->light );
1554
1558
 
1555
1559
                        /* calculate the dot product of the normal and the point */
1556
1560
                        dotp = dot_product( &normal, &point );
1557
1561
 
1558
1562
                        /* apply focus */
1559
 
                        point.x *= geo.focus.x;
1560
 
                        point.y *= geo.focus.y;
 
1563
                        point.x *= geo->focus.x;
 
1564
                        point.y *= geo->focus.y;
1561
1565
 
1562
1566
                        /* determine wether this is the front or the back of the polygon */
1563
1567
                        face = 0x100; /* rear */
1564
1568
                        if ( dotp >= 0 ) face = 0; /* front */
1565
1569
 
1566
1570
                        /* get the texture parameters */
1567
 
                        texparam = &geo.texture_parameters[(attr>>18) & 0x1f];
 
1571
                        texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1568
1572
 
1569
1573
                        /* calculate luminance and specular */
1570
1574
                        if ( (dotl * dotp) < 0 ) luminance = 0;
1571
1575
                        else luminance = fabs( dotl );
1572
1576
 
1573
 
                        specular = ((2*dotl) * normal.pz) - geo.light.pz;
 
1577
                        specular = ((2*dotl) * normal.pz) - geo->light.pz;
1574
1578
                        if ( specular < 0 )     specular = 0;
1575
1579
                        if ( texparam->specular_control == 0 ) specular = 0;
1576
1580
                        if ( (texparam->specular_control >> 1) != 0 ) specular *= specular;
1589
1593
                        luma += face;
1590
1594
 
1591
1595
                        /* extract distance coefficient */
1592
 
                        coef = geo.coef_table[attr>>27];
 
1596
                        coef = geo->coef_table[attr>>27];
1593
1597
 
1594
1598
                        /* calculate texture level of detail */
1595
 
                        distance = coef * fabs( dotp ) * geo.lod;
 
1599
                        distance = coef * fabs( dotp ) * geo->lod;
1596
1600
 
1597
1601
                        /* push to the 3d rasterizer */
1598
 
                        model2_3d_push( luma << 15 );
1599
 
                        model2_3d_push( f2u(distance) >> 8 );
1600
 
                        model2_3d_push( f2u(point.x) >> 8 );
1601
 
                        model2_3d_push( f2u(point.y) >> 8 );
1602
 
                        model2_3d_push( f2u(point.pz) >> 8 );
 
1602
                        model2_3d_push( raster, luma << 15 );
 
1603
                        model2_3d_push( raster, f2u(distance) >> 8 );
 
1604
                        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1605
                        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1606
                        model2_3d_push( raster, f2u(point.pz) >> 8 );
1603
1607
 
1604
1608
                        /* if it's a quad, push one more point */
1605
1609
                        if ( attr & 1 )
1610
1614
                                point.pz = u2f( *input++ );
1611
1615
 
1612
1616
                                /* transform with the current matrix */
1613
 
                                transform_point( &point, geo.matrix );
 
1617
                                transform_point( &point, geo->matrix );
1614
1618
 
1615
1619
                                /* apply focus */
1616
 
                                point.x *= geo.focus.x;
1617
 
                                point.y *= geo.focus.y;
 
1620
                                point.x *= geo->focus.x;
 
1621
                                point.y *= geo->focus.y;
1618
1622
 
1619
1623
                                /* push to the 3d rasterizer */
1620
 
                                model2_3d_push( f2u(point.x) >> 8 );
1621
 
                                model2_3d_push( f2u(point.y) >> 8 );
1622
 
                                model2_3d_push( f2u(point.pz) >> 8 );
 
1624
                                model2_3d_push( raster, f2u(point.x) >> 8 );
 
1625
                                model2_3d_push( raster, f2u(point.y) >> 8 );
 
1626
                                model2_3d_push( raster, f2u(point.pz) >> 8 );
1623
1627
                        }
1624
1628
                        else /* triangle */
1625
1629
                        {
1634
1638
        }
1635
1639
 
1636
1640
        /* notify the 3d rasterizer we're done */
1637
 
        model2_3d_push( 0 );
 
1641
        model2_3d_push( raster, 0 );
1638
1642
}
1639
1643
 
1640
1644
/* Parse Polygons: No Normals, No Specular case */
1641
 
static void geo_parse_nn_ns( UINT32 *input, UINT32 count )
 
1645
static void geo_parse_nn_ns( geo_state *geo, UINT32 *input, UINT32 count )
1642
1646
{
 
1647
        raster_state *raster = geo->raster;
1643
1648
        poly_vertex     point, normal, p0, p1, p2, p3;
1644
1649
        UINT32  attr, i;
1645
1650
 
1649
1654
        point.pz = u2f( *input++ );
1650
1655
 
1651
1656
        /* transform with the current matrix */
1652
 
        transform_point( &point, geo.matrix );
 
1657
        transform_point( &point, geo->matrix );
1653
1658
 
1654
1659
        /* save for normal calculation */
1655
1660
        p0.x = point.x; p0.y = point.y; p0.pz = point.pz;
1656
1661
 
1657
1662
        /* apply focus */
1658
 
        point.x *= geo.focus.x;
1659
 
        point.y *= geo.focus.y;
 
1663
        point.x *= geo->focus.x;
 
1664
        point.y *= geo->focus.y;
1660
1665
 
1661
1666
        /* push it to the 3d rasterizer */
1662
 
        model2_3d_push( f2u(point.x) >> 8 );
1663
 
        model2_3d_push( f2u(point.y) >> 8 );
1664
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1667
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1668
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1669
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1665
1670
 
1666
1671
        /* read the 2nd point */
1667
1672
        point.x = u2f( *input++ );
1669
1674
        point.pz = u2f( *input++ );
1670
1675
 
1671
1676
        /* transform with the current matrix */
1672
 
        transform_point( &point, geo.matrix );
 
1677
        transform_point( &point, geo->matrix );
1673
1678
 
1674
1679
        /* save for normal calculation */
1675
1680
        p1.x = point.x; p1.y = point.y; p1.pz = point.pz;
1676
1681
 
1677
1682
        /* apply focus */
1678
 
        point.x *= geo.focus.x;
1679
 
        point.y *= geo.focus.y;
 
1683
        point.x *= geo->focus.x;
 
1684
        point.y *= geo->focus.y;
1680
1685
 
1681
1686
        /* push it to the 3d rasterizer */
1682
 
        model2_3d_push( f2u(point.x) >> 8 );
1683
 
        model2_3d_push( f2u(point.y) >> 8 );
1684
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1687
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1688
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1689
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1685
1690
 
1686
1691
        /* skip 4 */
1687
1692
        input += 4;
1693
1698
                attr = *input++;
1694
1699
 
1695
1700
                /* push to the 3d rasterizer */
1696
 
                model2_3d_push( attr & 0x0003FFFF );
 
1701
                model2_3d_push( raster, attr & 0x0003FFFF );
1697
1702
 
1698
1703
                if ( (attr & 3) != 0 ) /* quad or triangle */
1699
1704
                {
1708
1713
                        point.pz = u2f( *input++ );
1709
1714
 
1710
1715
                        /* transform with the current matrix */
1711
 
                        transform_point( &point, geo.matrix );
 
1716
                        transform_point( &point, geo->matrix );
1712
1717
 
1713
1718
                        /* save for normal calculation */
1714
1719
                        p2.x = point.x; p2.y = point.y; p2.pz = point.pz;
1720
1725
                        normalize_vector( &normal );
1721
1726
 
1722
1727
                        /* calculate the dot product of the normal and the light vector */
1723
 
                        dotl = dot_product( &normal, &geo.light );
 
1728
                        dotl = dot_product( &normal, &geo->light );
1724
1729
 
1725
1730
                        /* calculate the dot product of the normal and the point */
1726
1731
                        dotp = dot_product( &normal, &point );
1727
1732
 
1728
1733
                        /* apply focus */
1729
 
                        point.x *= geo.focus.x;
1730
 
                        point.y *= geo.focus.y;
 
1734
                        point.x *= geo->focus.x;
 
1735
                        point.y *= geo->focus.y;
1731
1736
 
1732
1737
                        /* determine wether this is the front or the back of the polygon */
1733
1738
                        face = 0x100; /* rear */
1734
1739
                        if ( dotp >= 0 ) face = 0; /* front */
1735
1740
 
1736
1741
                        /* get the texture parameters */
1737
 
                        texparam = &geo.texture_parameters[(attr>>18) & 0x1f];
 
1742
                        texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1738
1743
 
1739
1744
                        /* calculate luminance */
1740
1745
                        if ( (dotl * dotp) < 0 ) luminance = 0;
1750
1755
                        luma += face;
1751
1756
 
1752
1757
                        /* extract distance coefficient */
1753
 
                        coef = geo.coef_table[attr>>27];
 
1758
                        coef = geo->coef_table[attr>>27];
1754
1759
 
1755
1760
                        /* calculate texture level of detail */
1756
 
                        distance = coef * fabs( dotp ) * geo.lod;
 
1761
                        distance = coef * fabs( dotp ) * geo->lod;
1757
1762
 
1758
1763
                        /* push to the 3d rasterizer */
1759
 
                        model2_3d_push( luma << 15 );
1760
 
                        model2_3d_push( f2u(distance) >> 8 );
1761
 
                        model2_3d_push( f2u(point.x) >> 8 );
1762
 
                        model2_3d_push( f2u(point.y) >> 8 );
1763
 
                        model2_3d_push( f2u(point.pz) >> 8 );
 
1764
                        model2_3d_push( raster, luma << 15 );
 
1765
                        model2_3d_push( raster, f2u(distance) >> 8 );
 
1766
                        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1767
                        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1768
                        model2_3d_push( raster, f2u(point.pz) >> 8 );
1764
1769
 
1765
1770
                        /* if it's a quad, push one more point */
1766
1771
                        if ( attr & 1 )
1771
1776
                                point.pz = u2f( *input++ );
1772
1777
 
1773
1778
                                /* transform with the current matrix */
1774
 
                                transform_point( &point, geo.matrix );
 
1779
                                transform_point( &point, geo->matrix );
1775
1780
 
1776
1781
                                /* save for normal calculation */
1777
1782
                                p3.x = point.x; p3.y = point.y; p3.pz = point.pz;
1778
1783
 
1779
1784
                                /* apply focus */
1780
 
                                point.x *= geo.focus.x;
1781
 
                                point.y *= geo.focus.y;
 
1785
                                point.x *= geo->focus.x;
 
1786
                                point.y *= geo->focus.y;
1782
1787
 
1783
1788
                                /* push to the 3d rasterizer */
1784
 
                                model2_3d_push( f2u(point.x) >> 8 );
1785
 
                                model2_3d_push( f2u(point.y) >> 8 );
1786
 
                                model2_3d_push( f2u(point.pz) >> 8 );
 
1789
                                model2_3d_push( raster, f2u(point.x) >> 8 );
 
1790
                                model2_3d_push( raster, f2u(point.y) >> 8 );
 
1791
                                model2_3d_push( raster, f2u(point.pz) >> 8 );
1787
1792
                        }
1788
1793
                        else
1789
1794
                        {
1828
1833
        }
1829
1834
 
1830
1835
        /* notify the 3d rasterizer we're done */
1831
 
        model2_3d_push( 0 );
 
1836
        model2_3d_push( raster, 0 );
1832
1837
}
1833
1838
 
1834
1839
/* Parse Polygons: No Normals, Specular case */
1835
 
static void geo_parse_nn_s( UINT32 *input, UINT32 count )
 
1840
static void geo_parse_nn_s( geo_state *geo, UINT32 *input, UINT32 count )
1836
1841
{
 
1842
        raster_state *raster = geo->raster;
1837
1843
        poly_vertex     point, normal, p0, p1, p2, p3;
1838
1844
        UINT32  attr, i;
1839
1845
 
1843
1849
        point.pz = u2f( *input++ );
1844
1850
 
1845
1851
        /* transform with the current matrix */
1846
 
        transform_point( &point, geo.matrix );
 
1852
        transform_point( &point, geo->matrix );
1847
1853
 
1848
1854
        /* save for normal calculation */
1849
1855
        p0.x = point.x; p0.y = point.y; p0.pz = point.pz;
1850
1856
 
1851
1857
        /* apply focus */
1852
 
        point.x *= geo.focus.x;
1853
 
        point.y *= geo.focus.y;
 
1858
        point.x *= geo->focus.x;
 
1859
        point.y *= geo->focus.y;
1854
1860
 
1855
1861
        /* push it to the 3d rasterizer */
1856
 
        model2_3d_push( f2u(point.x) >> 8 );
1857
 
        model2_3d_push( f2u(point.y) >> 8 );
1858
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1862
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1863
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1864
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1859
1865
 
1860
1866
        /* read the 2nd point */
1861
1867
        point.x = u2f( *input++ );
1863
1869
        point.pz = u2f( *input++ );
1864
1870
 
1865
1871
        /* transform with the current matrix */
1866
 
        transform_point( &point, geo.matrix );
 
1872
        transform_point( &point, geo->matrix );
1867
1873
 
1868
1874
        /* save for normal calculation */
1869
1875
        p1.x = point.x; p1.y = point.y; p1.pz = point.pz;
1870
1876
 
1871
1877
        /* apply focus */
1872
 
        point.x *= geo.focus.x;
1873
 
        point.y *= geo.focus.y;
 
1878
        point.x *= geo->focus.x;
 
1879
        point.y *= geo->focus.y;
1874
1880
 
1875
1881
        /* push it to the 3d rasterizer */
1876
 
        model2_3d_push( f2u(point.x) >> 8 );
1877
 
        model2_3d_push( f2u(point.y) >> 8 );
1878
 
        model2_3d_push( f2u(point.pz) >> 8 );
 
1882
        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1883
        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1884
        model2_3d_push( raster, f2u(point.pz) >> 8 );
1879
1885
 
1880
1886
        /* skip 4 */
1881
1887
        input += 4;
1887
1893
                attr = *input++;
1888
1894
 
1889
1895
                /* push to the 3d rasterizer */
1890
 
                model2_3d_push( attr & 0x0003FFFF );
 
1896
                model2_3d_push( raster, attr & 0x0003FFFF );
1891
1897
 
1892
1898
                if ( (attr & 3) != 0 ) /* quad or triangle */
1893
1899
                {
1902
1908
                        point.pz = u2f( *input++ );
1903
1909
 
1904
1910
                        /* transform with the current matrix */
1905
 
                        transform_point( &point, geo.matrix );
 
1911
                        transform_point( &point, geo->matrix );
1906
1912
 
1907
1913
                        /* save for normal calculation */
1908
1914
                        p2.x = point.x; p2.y = point.y; p2.pz = point.pz;
1914
1920
                        normalize_vector( &normal );
1915
1921
 
1916
1922
                        /* calculate the dot product of the normal and the light vector */
1917
 
                        dotl = dot_product( &normal, &geo.light );
 
1923
                        dotl = dot_product( &normal, &geo->light );
1918
1924
 
1919
1925
                        /* calculate the dot product of the normal and the point */
1920
1926
                        dotp = dot_product( &normal, &point );
1921
1927
 
1922
1928
                        /* apply focus */
1923
 
                        point.x *= geo.focus.x;
1924
 
                        point.y *= geo.focus.y;
 
1929
                        point.x *= geo->focus.x;
 
1930
                        point.y *= geo->focus.y;
1925
1931
 
1926
1932
                        /* determine wether this is the front or the back of the polygon */
1927
1933
                        face = 0x100; /* rear */
1928
1934
                        if ( dotp >= 0 ) face = 0; /* front */
1929
1935
 
1930
1936
                        /* get the texture parameters */
1931
 
                        texparam = &geo.texture_parameters[(attr>>18) & 0x1f];
 
1937
                        texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1932
1938
 
1933
1939
                        /* calculate luminance and specular */
1934
1940
                        if ( (dotl * dotp) < 0 ) luminance = 0;
1935
1941
                        else luminance = fabs( dotl );
1936
1942
 
1937
 
                        specular = ((2*dotl) * normal.pz) - geo.light.pz;
 
1943
                        specular = ((2*dotl) * normal.pz) - geo->light.pz;
1938
1944
                        if ( specular < 0 )     specular = 0;
1939
1945
                        if ( texparam->specular_control == 0 ) specular = 0;
1940
1946
                        if ( (texparam->specular_control >> 1) != 0 ) specular *= specular;
1953
1959
                        luma += face;
1954
1960
 
1955
1961
                        /* extract distance coefficient */
1956
 
                        coef = geo.coef_table[attr>>27];
 
1962
                        coef = geo->coef_table[attr>>27];
1957
1963
 
1958
1964
                        /* calculate texture level of detail */
1959
 
                        distance = coef * fabs( dotp ) * geo.lod;
 
1965
                        distance = coef * fabs( dotp ) * geo->lod;
1960
1966
 
1961
1967
                        /* push to the 3d rasterizer */
1962
 
                        model2_3d_push( luma << 15 );
1963
 
                        model2_3d_push( f2u(distance) >> 8 );
1964
 
                        model2_3d_push( f2u(point.x) >> 8 );
1965
 
                        model2_3d_push( f2u(point.y) >> 8 );
1966
 
                        model2_3d_push( f2u(point.pz) >> 8 );
 
1968
                        model2_3d_push( raster, luma << 15 );
 
1969
                        model2_3d_push( raster, f2u(distance) >> 8 );
 
1970
                        model2_3d_push( raster, f2u(point.x) >> 8 );
 
1971
                        model2_3d_push( raster, f2u(point.y) >> 8 );
 
1972
                        model2_3d_push( raster, f2u(point.pz) >> 8 );
1967
1973
 
1968
1974
                        /* if it's a quad, push one more point */
1969
1975
                        if ( attr & 1 )
1974
1980
                                point.pz = u2f( *input++ );
1975
1981
 
1976
1982
                                /* transform with the current matrix */
1977
 
                                transform_point( &point, geo.matrix );
 
1983
                                transform_point( &point, geo->matrix );
1978
1984
 
1979
1985
                                /* save for normal calculation */
1980
1986
                                p3.x = point.x; p3.y = point.y; p3.pz = point.pz;
1981
1987
 
1982
1988
                                /* apply focus */
1983
 
                                point.x *= geo.focus.x;
1984
 
                                point.y *= geo.focus.y;
 
1989
                                point.x *= geo->focus.x;
 
1990
                                point.y *= geo->focus.y;
1985
1991
 
1986
1992
                                /* push to the 3d rasterizer */
1987
 
                                model2_3d_push( f2u(point.x) >> 8 );
1988
 
                                model2_3d_push( f2u(point.y) >> 8 );
1989
 
                                model2_3d_push( f2u(point.pz) >> 8 );
 
1993
                                model2_3d_push( raster, f2u(point.x) >> 8 );
 
1994
                                model2_3d_push( raster, f2u(point.y) >> 8 );
 
1995
                                model2_3d_push( raster, f2u(point.pz) >> 8 );
1990
1996
                        }
1991
1997
                        else
1992
1998
                        {
2031
2037
        }
2032
2038
 
2033
2039
        /* notify the 3d rasterizer we're done */
2034
 
        model2_3d_push( 0 );
 
2040
        model2_3d_push( raster, 0 );
2035
2041
}
2036
2042
 
2037
2043
/*******************************************
2041
2047
 *******************************************/
2042
2048
 
2043
2049
/* Command 00: NOP */
2044
 
static UINT32 * geo_nop( UINT32 opcode, UINT32 *input )
 
2050
static UINT32 * geo_nop( geo_state *geo, UINT32 opcode, UINT32 *input )
2045
2051
{
 
2052
        raster_state *raster = geo->raster;
 
2053
 
2046
2054
        /* push the opcode to the 3d rasterizer */
2047
 
        model2_3d_push( opcode >> 23 );
 
2055
        model2_3d_push( raster, opcode >> 23 );
2048
2056
 
2049
2057
        return input;
2050
2058
}
2051
2059
 
2052
2060
/* Command 01: Object Data */
2053
 
static UINT32 * geo_object_data( UINT32 opcode, UINT32 *input )
 
2061
static UINT32 * geo_object_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2054
2062
{
 
2063
        raster_state *raster = geo->raster;
2055
2064
        UINT32  tpa = *input++;         /* Texture Point Address */
2056
2065
        UINT32  tha = *input++;         /* Texture Header Address */
2057
2066
        UINT32  oba = *input++;         /* Object Address */
2060
2069
        UINT32 *obp;                            /* Object Pointer */
2061
2070
 
2062
2071
        /* push the initial set of data to the 3d rasterizer */
2063
 
        model2_3d_push( opcode >> 23 );
2064
 
        model2_3d_push( tpa );
2065
 
        model2_3d_push( tha );
 
2072
        model2_3d_push( raster, opcode >> 23 );
 
2073
        model2_3d_push( raster, tpa );
 
2074
        model2_3d_push( raster, tha );
2066
2075
 
2067
2076
        /* select where we're reading polygon information from */
2068
2077
        if ( oba & 0x01000000 )
2069
2078
        {
2070
2079
                /* Fast polygon RAM */
2071
 
                obp = &geo.polygon_ram0[oba & 0x7FFF];
 
2080
                obp = &geo->polygon_ram0[oba & 0x7FFF];
2072
2081
        }
2073
2082
        else if ( oba & 0x00800000 )
2074
2083
        {
2075
2084
                /* Polygon ROM */
2076
 
                obp = &geo.polygon_rom[oba & 0x7FFFFF];
 
2085
                obp = &geo->polygon_rom[oba & 0x7FFFFF];
2077
2086
        }
2078
2087
        else
2079
2088
        {
2080
2089
                /* Slow Polygon RAM */
2081
 
                obp = &geo.polygon_ram1[oba & 0x7FFF];
 
2090
                obp = &geo->polygon_ram1[oba & 0x7FFF];
2082
2091
        }
2083
2092
 
2084
 
        switch( geo.mode & 3 )
 
2093
        switch( geo->mode & 3 )
2085
2094
        {
2086
2095
                /* Normals present, No Specular */
2087
 
                case 0: geo_parse_np_ns( obp, obc ); break;
 
2096
                case 0: geo_parse_np_ns( geo, obp, obc ); break;
2088
2097
 
2089
2098
                /* Normals present, Specular */
2090
 
                case 1: geo_parse_np_s( obp, obc ); break;
 
2099
                case 1: geo_parse_np_s( geo, obp, obc ); break;
2091
2100
 
2092
2101
                /* No Normals present, No Specular */
2093
 
                case 2: geo_parse_nn_ns( obp, obc ); break;
 
2102
                case 2: geo_parse_nn_ns( geo, obp, obc ); break;
2094
2103
 
2095
2104
                /* No Normals present, Specular */
2096
 
                case 3: geo_parse_nn_s( obp, obc ); break;
 
2105
                case 3: geo_parse_nn_s( geo, obp, obc ); break;
2097
2106
        }
2098
2107
 
2099
2108
        /* move by 4 parameters */
2101
2110
}
2102
2111
 
2103
2112
/* Command 02: Direct Data */
2104
 
static UINT32 * geo_direct_data( UINT32 opcode, UINT32 *input )
 
2113
static UINT32 * geo_direct_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2105
2114
{
 
2115
        raster_state *raster = geo->raster;
2106
2116
        UINT32  tpa = *input++;         /* Texture Point Address */
2107
2117
        UINT32  tha = *input++;         /* Texture Header Address */
2108
2118
        UINT32  attr;
2109
2119
 
2110
2120
        /* push the initial set of data to the 3d rasterizer */
2111
 
        model2_3d_push( (opcode >> 23) - 1 );
2112
 
        model2_3d_push( tpa );
2113
 
        model2_3d_push( tha );
 
2121
        model2_3d_push( raster, (opcode >> 23) - 1 );
 
2122
        model2_3d_push( raster, tpa );
 
2123
        model2_3d_push( raster, tha );
2114
2124
 
2115
2125
        /* push the initial points */
2116
 
        model2_3d_push( (*input++) >> 8 ); /* x */
2117
 
        model2_3d_push( (*input++) >> 8 ); /* y */
2118
 
        model2_3d_push( (*input++) >> 8 ); /* z */
 
2126
        model2_3d_push( raster, (*input++) >> 8 ); /* x */
 
2127
        model2_3d_push( raster, (*input++) >> 8 ); /* y */
 
2128
        model2_3d_push( raster, (*input++) >> 8 ); /* z */
2119
2129
 
2120
 
        model2_3d_push( (*input++) >> 8 ); /* x */
2121
 
        model2_3d_push( (*input++) >> 8 ); /* y */
2122
 
        model2_3d_push( (*input++) >> 8 ); /* z */
 
2130
        model2_3d_push( raster, (*input++) >> 8 ); /* x */
 
2131
        model2_3d_push( raster, (*input++) >> 8 ); /* y */
 
2132
        model2_3d_push( raster, (*input++) >> 8 ); /* z */
2123
2133
 
2124
2134
        do
2125
2135
        {
2130
2140
                        break;
2131
2141
 
2132
2142
                /* push attributes */
2133
 
                model2_3d_push( attr & 0x00FFFFFF );
 
2143
                model2_3d_push( raster, attr & 0x00FFFFFF );
2134
2144
 
2135
2145
                /* push luma */
2136
 
                model2_3d_push( (*input++) >> 8 );
 
2146
                model2_3d_push( raster, (*input++) >> 8 );
2137
2147
 
2138
2148
                /* push distance */
2139
 
                model2_3d_push( (*input++) >> 8 );
 
2149
                model2_3d_push( raster, (*input++) >> 8 );
2140
2150
 
2141
2151
                /* push the next point */
2142
 
                model2_3d_push( (*input++) >> 8 ); /* x */
2143
 
                model2_3d_push( (*input++) >> 8 ); /* y */
2144
 
                model2_3d_push( (*input++) >> 8 ); /* z */
 
2152
                model2_3d_push( raster, (*input++) >> 8 ); /* x */
 
2153
                model2_3d_push( raster, (*input++) >> 8 ); /* y */
 
2154
                model2_3d_push( raster, (*input++) >> 8 ); /* z */
2145
2155
 
2146
2156
                /* if it's a quad, output another point */
2147
2157
                if ( attr & 1 )
2148
2158
                {
2149
 
                        model2_3d_push( (*input++) >> 8 ); /* x */
2150
 
                        model2_3d_push( (*input++) >> 8 ); /* y */
2151
 
                        model2_3d_push( (*input++) >> 8 ); /* z */
 
2159
                        model2_3d_push( raster, (*input++) >> 8 ); /* x */
 
2160
                        model2_3d_push( raster, (*input++) >> 8 ); /* y */
 
2161
                        model2_3d_push( raster, (*input++) >> 8 ); /* z */
2152
2162
                }
2153
2163
        } while( 1 );
2154
2164
 
2155
2165
        /* we're done */
2156
 
        model2_3d_push( 0 );
 
2166
        model2_3d_push( raster, 0 );
2157
2167
 
2158
2168
        return input;
2159
2169
}
2160
2170
 
2161
2171
/* Command 03: Window Data */
2162
 
static UINT32 * geo_window_data( UINT32 opcode, UINT32 *input )
 
2172
static UINT32 * geo_window_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2163
2173
{
 
2174
        raster_state *raster = geo->raster;
2164
2175
        UINT32  x, y, i;
2165
2176
 
2166
2177
        /* start by pushing the opcode */
2167
 
        model2_3d_push( opcode >> 23 );
 
2178
        model2_3d_push( raster, opcode >> 23 );
2168
2179
 
2169
2180
        /*
2170
2181
        we're going to move 6 coordinates to the 3d rasterizer:
2186
2197
                y &= 0xFFF;
2187
2198
 
2188
2199
                /* push it */
2189
 
                model2_3d_push( x | y );
 
2200
                model2_3d_push( raster, x | y );
2190
2201
        }
2191
2202
 
2192
2203
        return input;
2193
2204
}
2194
2205
 
2195
2206
/* Command 04: Texture Data Write */
2196
 
static UINT32 * geo_texture_data( UINT32 opcode, UINT32 *input )
 
2207
static UINT32 * geo_texture_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2197
2208
{
 
2209
        raster_state *raster = geo->raster;
2198
2210
        UINT32  i, count;
2199
2211
 
2200
2212
        /* start by pushing the opcode */
2201
 
        model2_3d_push( opcode >> 23 );
 
2213
        model2_3d_push( raster, opcode >> 23 );
2202
2214
 
2203
2215
        /* push the starting address/dsp id */
2204
 
        model2_3d_push( *input++ );
 
2216
        model2_3d_push( raster, *input++ );
2205
2217
 
2206
2218
        /* get the count */
2207
2219
        count = *input++;
2208
2220
 
2209
2221
        /* push the count */
2210
 
        model2_3d_push( count );
 
2222
        model2_3d_push( raster, count );
2211
2223
 
2212
2224
        /* loop and send the data */
2213
2225
        for( i = 0; i < count; i++ )
2214
 
                model2_3d_push( *input++ );
 
2226
                model2_3d_push( raster, *input++ );
2215
2227
 
2216
2228
        return input;
2217
2229
}
2218
2230
 
2219
2231
/* Command 05: Polygon Data */
2220
 
static UINT32 * geo_polygon_data( UINT32 opcode, UINT32 *input )
 
2232
static UINT32 * geo_polygon_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2221
2233
{
2222
2234
        UINT32  address, count, i;
2223
2235
        UINT32 *p;
2231
2243
        if ( address & 0x01000000 )
2232
2244
        {
2233
2245
                /* Fast polygon RAM */
2234
 
                p = &geo.polygon_ram0[address & 0x7FFF];
 
2246
                p = &geo->polygon_ram0[address & 0x7FFF];
2235
2247
        }
2236
2248
        else
2237
2249
        {
2238
2250
                /* Slow Polygon RAM */
2239
 
                p = &geo.polygon_ram1[address & 0x7FFF];
 
2251
                p = &geo->polygon_ram1[address & 0x7FFF];
2240
2252
        }
2241
2253
 
2242
2254
        /* read the count */
2250
2262
}
2251
2263
 
2252
2264
/* Command 06: Texture Parameters */
2253
 
static UINT32 * geo_texture_parameters( UINT32 opcode, UINT32 *input )
 
2265
static UINT32 * geo_texture_parameters( geo_state *geo, UINT32 opcode, UINT32 *input )
2254
2266
{
2255
2267
        UINT32  index, count, i, param;
2256
2268
 
2267
2279
                /* read in the texture parameters */
2268
2280
                param = *input++;
2269
2281
 
2270
 
                geo.texture_parameters[index].diffuse = (float)( param & 0xFF );
2271
 
                geo.texture_parameters[index].ambient = (float)( (param >> 8) & 0xFF );
2272
 
                geo.texture_parameters[index].specular_control = (param >> 24) & 0xFF;
2273
 
                geo.texture_parameters[index].specular_scale = (float)( (param >> 16) & 0xFF );
 
2282
                geo->texture_parameters[index].diffuse = (float)( param & 0xFF );
 
2283
                geo->texture_parameters[index].ambient = (float)( (param >> 8) & 0xFF );
 
2284
                geo->texture_parameters[index].specular_control = (param >> 24) & 0xFF;
 
2285
                geo->texture_parameters[index].specular_scale = (float)( (param >> 16) & 0xFF );
2274
2286
 
2275
2287
                /* read in the distance coefficient */
2276
 
                geo.coef_table[index] = u2f(*input++);
 
2288
                geo->coef_table[index] = u2f(*input++);
2277
2289
 
2278
2290
                index = (index + 1) & 0x1F;
2279
2291
        }
2282
2294
}
2283
2295
 
2284
2296
/* Command 07: Geo Mode */
2285
 
static UINT32 * geo_mode( UINT32 opcode, UINT32 *input )
 
2297
static UINT32 * geo_mode( geo_state *geo, UINT32 opcode, UINT32 *input )
2286
2298
{
2287
2299
        (void)opcode;
2288
2300
 
2289
2301
        /* read in the mode */
2290
 
        geo.mode = *input++;
 
2302
        geo->mode = *input++;
2291
2303
 
2292
2304
        return input;
2293
2305
}
2294
2306
 
2295
2307
/* Command 08: ZSort Mode */
2296
 
static UINT32 * geo_zsort_mode( UINT32 opcode, UINT32 *input )
 
2308
static UINT32 * geo_zsort_mode( geo_state *geo, UINT32 opcode, UINT32 *input )
2297
2309
{
 
2310
        raster_state *raster = geo->raster;
 
2311
 
2298
2312
        /* push the opcode */
2299
 
        model2_3d_push( opcode >> 23 );
 
2313
        model2_3d_push( raster, opcode >> 23 );
2300
2314
 
2301
2315
        /* push the mode */
2302
 
        model2_3d_push( (*input++) >> 8 );
 
2316
        model2_3d_push( raster, (*input++) >> 8 );
2303
2317
 
2304
2318
        return input;
2305
2319
}
2306
2320
 
2307
2321
/* Command 09: Focal Distance */
2308
 
static UINT32 * geo_focal_distance( UINT32 opcode, UINT32 *input )
 
2322
static UINT32 * geo_focal_distance( geo_state *geo, UINT32 opcode, UINT32 *input )
2309
2323
{
2310
2324
        (void)opcode;
2311
2325
 
2312
2326
        /* read the x focus value */
2313
 
        geo.focus.x = u2f( *input++ );
 
2327
        geo->focus.x = u2f( *input++ );
2314
2328
 
2315
2329
        /* read the y focus value */
2316
 
        geo.focus.y = u2f( *input++ );
 
2330
        geo->focus.y = u2f( *input++ );
2317
2331
 
2318
2332
        return input;
2319
2333
}
2320
2334
 
2321
2335
/* Command 0A: Light Source Vector Write */
2322
 
static UINT32 * geo_light_source( UINT32 opcode, UINT32 *input )
 
2336
static UINT32 * geo_light_source( geo_state *geo, UINT32 opcode, UINT32 *input )
2323
2337
{
2324
2338
        (void)opcode;
2325
2339
 
2326
2340
        /* read the x light value */
2327
 
        geo.light.x = u2f( *input++ );
 
2341
        geo->light.x = u2f( *input++ );
2328
2342
 
2329
2343
        /* read the y light value */
2330
 
        geo.light.y = u2f( *input++ );
 
2344
        geo->light.y = u2f( *input++ );
2331
2345
 
2332
2346
        /* read the z light value */
2333
 
        geo.light.pz = u2f( *input++ );
 
2347
        geo->light.pz = u2f( *input++ );
2334
2348
 
2335
2349
        return input;
2336
2350
}
2337
2351
 
2338
2352
/* Command 0B: Transformation Matrix Write */
2339
 
static UINT32 * geo_matrix_write( UINT32 opcode, UINT32 *input )
 
2353
static UINT32 * geo_matrix_write( geo_state *geo, UINT32 opcode, UINT32 *input )
2340
2354
{
2341
2355
        UINT32  i;
2342
2356
 
2344
2358
 
2345
2359
        /* read in the transformation matrix */
2346
2360
        for( i = 0; i < 12; i++ )
2347
 
                geo.matrix[i] = u2f( *input++ );
 
2361
                geo->matrix[i] = u2f( *input++ );
2348
2362
 
2349
2363
        return input;
2350
2364
}
2351
2365
 
2352
2366
/* Command 0C: Parallel Transfer Vector Write */
2353
 
static UINT32 * geo_translate_write( UINT32 opcode, UINT32 *input )
 
2367
static UINT32 * geo_translate_write( geo_state *geo, UINT32 opcode, UINT32 *input )
2354
2368
{
2355
2369
        UINT32  i;
2356
2370
 
2358
2372
 
2359
2373
        /* read in the translation vector */
2360
2374
        for( i = 0; i < 3; i++ )
2361
 
                geo.matrix[i+9] = u2f( *input++ );
 
2375
                geo->matrix[i+9] = u2f( *input++ );
2362
2376
 
2363
2377
        return input;
2364
2378
}
2365
2379
 
2366
2380
/* Command 0D: Geo Data Memory Push (undocumented, unsupported) */
2367
 
static UINT32 * geo_data_mem_push( UINT32 opcode, UINT32 *input )
 
2381
static UINT32 * geo_data_mem_push( geo_state *geo, UINT32 opcode, UINT32 *input )
2368
2382
{
2369
2383
        UINT32  address, count, i;
2370
2384
 
2401
2415
}
2402
2416
 
2403
2417
/* Command 0E: Geo Test */
2404
 
static UINT32 * geo_test( UINT32 opcode, UINT32 *input )
 
2418
static UINT32 * geo_test( geo_state *geo, UINT32 opcode, UINT32 *input )
2405
2419
{
2406
2420
        UINT32          data, blocks, address, count, checksum, i;
2407
2421
 
2443
2457
 
2444
2458
                for( j = 0; j < count; j++ )
2445
2459
                {
2446
 
                        data = geo.polygon_rom[address++];
 
2460
                        data = geo->polygon_rom[address++];
2447
2461
 
2448
2462
                        address &= 0x7FFFFF;
2449
2463
 
2471
2485
}
2472
2486
 
2473
2487
/* Command 0F: End */
2474
 
static UINT32 * geo_end( UINT32 opcode, UINT32 *input )
 
2488
static UINT32 * geo_end( geo_state *geo, UINT32 opcode, UINT32 *input )
2475
2489
{
 
2490
        raster_state *raster = geo->raster;
 
2491
 
2476
2492
        (void)opcode;
2477
2493
 
2478
2494
        /* signal the end of this data block the rasterizer */
2479
 
        model2_3d_push( 0xFF000000 );
 
2495
        model2_3d_push( raster, 0xFF000000 );
2480
2496
 
2481
2497
        /* signal end by returning NULL */
2482
2498
        return NULL;
2483
2499
}
2484
2500
 
2485
2501
/* Command 10: Dummy */
2486
 
static UINT32 * geo_dummy( UINT32 opcode, UINT32 *input )
 
2502
static UINT32 * geo_dummy( geo_state *geo, UINT32 opcode, UINT32 *input )
2487
2503
{
2488
2504
        UINT32  data;
2489
2505
        (void)opcode;
2495
2511
}
2496
2512
 
2497
2513
/* Command 14: Log Data Write */
2498
 
static UINT32 * geo_log_data( UINT32 opcode, UINT32 *input )
 
2514
static UINT32 * geo_log_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2499
2515
{
 
2516
        raster_state *raster = geo->raster;
2500
2517
        UINT32  i, count;
2501
2518
 
2502
2519
        /* start by pushing the opcode */
2503
 
        model2_3d_push( opcode >> 23 );
 
2520
        model2_3d_push( raster, opcode >> 23 );
2504
2521
 
2505
2522
        /* push the starting address/dsp id */
2506
 
        model2_3d_push( *input++ );
 
2523
        model2_3d_push( raster, *input++ );
2507
2524
 
2508
2525
        /* get the count */
2509
2526
        count = *input++;
2510
2527
 
2511
2528
        /* push the count */
2512
 
        model2_3d_push( count << 2 );
 
2529
        model2_3d_push( raster, count << 2 );
2513
2530
 
2514
2531
        /* loop and send the data */
2515
2532
        for( i = 0; i < count; i++ )
2516
2533
        {
2517
2534
                UINT32  data = *input++;
2518
2535
 
2519
 
                model2_3d_push( data & 0xff );
2520
 
                model2_3d_push( (data >> 8) & 0xff );
2521
 
                model2_3d_push( (data >> 16) & 0xff );
2522
 
                model2_3d_push( (data >> 24) & 0xff );
 
2536
                model2_3d_push( raster, data & 0xff );
 
2537
                model2_3d_push( raster, (data >> 8) & 0xff );
 
2538
                model2_3d_push( raster, (data >> 16) & 0xff );
 
2539
                model2_3d_push( raster, (data >> 24) & 0xff );
2523
2540
        }
2524
2541
 
2525
2542
        return input;
2526
2543
}
2527
2544
 
2528
2545
/* Command 16: LOD */
2529
 
static UINT32 * geo_lod( UINT32 opcode, UINT32 *input )
 
2546
static UINT32 * geo_lod( geo_state *geo, UINT32 opcode, UINT32 *input )
2530
2547
{
2531
2548
        (void)opcode;
2532
2549
 
2533
2550
        /* read in the LOD */
2534
 
        geo.lod = u2f(*input++);
 
2551
        geo->lod = u2f(*input++);
2535
2552
 
2536
2553
        return input;
2537
2554
}
2538
2555
 
2539
2556
/* Command 1D: Code Upload  (undocumented, unsupported) */
2540
 
static UINT32 * geo_code_upload( UINT32 opcode, UINT32 *input )
 
2557
static UINT32 * geo_code_upload( geo_state *geo, UINT32 opcode, UINT32 *input )
2541
2558
{
2542
2559
        UINT32  flags, count, i;
2543
2560
 
2585
2602
}
2586
2603
 
2587
2604
/* Command 1E: Code Jump (undocumented, unsupported) */
2588
 
static UINT32 * geo_code_jump( UINT32 opcode, UINT32 *input )
 
2605
static UINT32 * geo_code_jump( geo_state *geo, UINT32 opcode, UINT32 *input )
2589
2606
{
2590
2607
        UINT32  address;
2591
2608
 
2609
2626
        return input;
2610
2627
}
2611
2628
 
2612
 
static UINT32 * geo_process_command( UINT32 opcode, UINT32 *input )
 
2629
static UINT32 * geo_process_command( geo_state *geo, UINT32 opcode, UINT32 *input )
2613
2630
{
2614
2631
        switch( opcode >> 23 )
2615
2632
        {
2616
 
                case 0x00: input = geo_nop( opcode, input );                            break;
2617
 
                case 0x01: input = geo_object_data( opcode, input );            break;
2618
 
                case 0x02: input = geo_direct_data( opcode, input );            break;
2619
 
                case 0x03: input = geo_window_data( opcode, input );            break;
2620
 
                case 0x04: input = geo_texture_data( opcode, input );           break;
2621
 
                case 0x05: input = geo_polygon_data( opcode, input );           break;
2622
 
                case 0x06: input = geo_texture_parameters( opcode, input );     break;
2623
 
                case 0x07: input = geo_mode( opcode, input );                           break;
2624
 
                case 0x08: input = geo_zsort_mode( opcode, input );                     break;
2625
 
                case 0x09: input = geo_focal_distance( opcode, input );         break;
2626
 
                case 0x0A: input = geo_light_source( opcode, input );           break;
2627
 
                case 0x0B: input = geo_matrix_write( opcode, input );           break;
2628
 
                case 0x0C: input = geo_translate_write( opcode, input );        break;
2629
 
                case 0x0D: input = geo_data_mem_push( opcode, input );          break;
2630
 
                case 0x0E: input = geo_test( opcode, input );                           break;
2631
 
                case 0x0F: input = geo_end( opcode, input );                            break;
2632
 
                case 0x10: input = geo_dummy( opcode, input );                          break;
2633
 
                case 0x11: input = geo_object_data( opcode, input );            break;
2634
 
                case 0x12: input = geo_direct_data( opcode, input );            break;
2635
 
                case 0x13: input = geo_window_data( opcode, input );            break;
2636
 
                case 0x14: input = geo_log_data( opcode, input );                       break;
2637
 
                case 0x15: input = geo_polygon_data( opcode, input );           break;
2638
 
                case 0x16: input = geo_lod( opcode, input );                            break;
2639
 
                case 0x17: input = geo_mode( opcode, input );                           break;
2640
 
                case 0x18: input = geo_zsort_mode( opcode, input );                     break;
2641
 
                case 0x19: input = geo_focal_distance( opcode, input );         break;
2642
 
                case 0x1A: input = geo_light_source( opcode, input );           break;
2643
 
                case 0x1B: input = geo_matrix_write( opcode, input );           break;
2644
 
                case 0x1C: input = geo_translate_write( opcode, input );        break;
2645
 
                case 0x1D: input = geo_code_upload( opcode, input );            break;
2646
 
                case 0x1E: input = geo_code_jump( opcode, input );                      break;
2647
 
                case 0x1F: input = geo_end( opcode, input );                            break;
 
2633
                case 0x00: input = geo_nop( geo, opcode, input );                               break;
 
2634
                case 0x01: input = geo_object_data( geo, opcode, input );               break;
 
2635
                case 0x02: input = geo_direct_data( geo, opcode, input );               break;
 
2636
                case 0x03: input = geo_window_data( geo, opcode, input );               break;
 
2637
                case 0x04: input = geo_texture_data( geo, opcode, input );              break;
 
2638
                case 0x05: input = geo_polygon_data( geo, opcode, input );              break;
 
2639
                case 0x06: input = geo_texture_parameters( geo, opcode, input );        break;
 
2640
                case 0x07: input = geo_mode( geo, opcode, input );                              break;
 
2641
                case 0x08: input = geo_zsort_mode( geo, opcode, input );                        break;
 
2642
                case 0x09: input = geo_focal_distance( geo, opcode, input );            break;
 
2643
                case 0x0A: input = geo_light_source( geo, opcode, input );              break;
 
2644
                case 0x0B: input = geo_matrix_write( geo, opcode, input );              break;
 
2645
                case 0x0C: input = geo_translate_write( geo, opcode, input );   break;
 
2646
                case 0x0D: input = geo_data_mem_push( geo, opcode, input );             break;
 
2647
                case 0x0E: input = geo_test( geo, opcode, input );                              break;
 
2648
                case 0x0F: input = geo_end( geo, opcode, input );                               break;
 
2649
                case 0x10: input = geo_dummy( geo, opcode, input );                             break;
 
2650
                case 0x11: input = geo_object_data( geo, opcode, input );               break;
 
2651
                case 0x12: input = geo_direct_data( geo, opcode, input );               break;
 
2652
                case 0x13: input = geo_window_data( geo, opcode, input );               break;
 
2653
                case 0x14: input = geo_log_data( geo, opcode, input );                  break;
 
2654
                case 0x15: input = geo_polygon_data( geo, opcode, input );              break;
 
2655
                case 0x16: input = geo_lod( geo, opcode, input );                               break;
 
2656
                case 0x17: input = geo_mode( geo, opcode, input );                              break;
 
2657
                case 0x18: input = geo_zsort_mode( geo, opcode, input );                        break;
 
2658
                case 0x19: input = geo_focal_distance( geo, opcode, input );            break;
 
2659
                case 0x1A: input = geo_light_source( geo, opcode, input );              break;
 
2660
                case 0x1B: input = geo_matrix_write( geo, opcode, input );              break;
 
2661
                case 0x1C: input = geo_translate_write( geo, opcode, input );   break;
 
2662
                case 0x1D: input = geo_code_upload( geo, opcode, input );               break;
 
2663
                case 0x1E: input = geo_code_jump( geo, opcode, input );                 break;
 
2664
                case 0x1F: input = geo_end( geo, opcode, input );                               break;
2648
2665
        }
2649
2666
 
2650
2667
        return input;
2651
2668
}
2652
2669
 
2653
 
static void geo_parse( void )
 
2670
static void geo_parse( model2_state *state )
2654
2671
{
2655
 
        UINT32  address = (geo_read_start_address/4);
2656
 
        UINT32 *input = &model2_bufferram[address];
 
2672
        UINT32  address = (state->m_geo_read_start_address/4);
 
2673
        UINT32 *input = &state->m_bufferram[address];
2657
2674
        UINT32  opcode;
2658
2675
 
2659
 
        while( input != NULL && (input - model2_bufferram) < 0x20000  )
 
2676
        while( input != NULL && (input - state->m_bufferram) < 0x20000  )
2660
2677
        {
2661
2678
                /* read in the opcode */
2662
2679
                opcode = *input++;
2668
2685
                        address = (opcode & 0x7FFFF) / 4;
2669
2686
 
2670
2687
                        /* update our pointer */
2671
 
                        input = &model2_bufferram[address];
 
2688
                        input = &state->m_bufferram[address];
2672
2689
 
2673
2690
                        /* go again */
2674
2691
                        continue;
2675
2692
                }
2676
2693
 
2677
2694
                /* process it */
2678
 
                input = geo_process_command( opcode, input );
 
2695
                input = geo_process_command( state->m_geo, opcode, input );
2679
2696
        }
2680
2697
}
2681
2698
 
2682
2699
/***********************************************************************************************/
2683
2700
 
2684
 
static bitmap_t *sys24_bitmap = NULL;
2685
2701
 
2686
2702
static void model2_exit(running_machine &machine)
2687
2703
{
2688
 
        poly_free(poly);
 
2704
        model2_state *state = machine.driver_data<model2_state>();
 
2705
        poly_free(state->m_poly);
2689
2706
}
2690
2707
 
2691
2708
VIDEO_START(model2)
2692
2709
{
2693
 
        const rectangle &visarea = machine->primary_screen->visible_area();
 
2710
        model2_state *state = machine.driver_data<model2_state>();
 
2711
        const rectangle &visarea = machine.primary_screen->visible_area();
2694
2712
        int     width = visarea.max_x - visarea.min_x;
2695
2713
        int     height = visarea.max_y - visarea.min_y;
2696
2714
 
2697
2715
        sys24_tile_vh_start(machine, 0x3fff);
2698
 
        sys24_bitmap = auto_alloc(machine, bitmap_t(width, height+4, BITMAP_FORMAT_INDEXED16));
2699
 
 
2700
 
        poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), 0);
2701
 
        machine->add_notifier(MACHINE_NOTIFY_EXIT, model2_exit);
 
2716
        state->m_sys24_bitmap = auto_alloc(machine, bitmap_t(width, height+4, BITMAP_FORMAT_INDEXED16));
 
2717
 
 
2718
        state->m_poly = poly_alloc(machine, 4000, sizeof(poly_extra_data), 0);
 
2719
        machine.add_notifier(MACHINE_NOTIFY_EXIT, model2_exit);
 
2720
 
 
2721
        /* initialize the hardware rasterizer */
 
2722
        model2_3d_init( machine, (UINT16*)machine.region("user3")->base() );
2702
2723
 
2703
2724
        /* initialize the geometry engine */
2704
 
        geo_init( machine, (UINT32*)machine->region("user2")->base() );
2705
 
 
2706
 
        /* initialize the hardware rasterizer */
2707
 
        model2_3d_init( machine, (UINT16*)machine->region("user3")->base() );
 
2725
        geo_init( machine, (UINT32*)machine.region("user2")->base() );
2708
2726
}
2709
2727
 
2710
 
static void convert_bitmap( running_machine *machine, bitmap_t *dst, bitmap_t *src, const rectangle *rect )
 
2728
static void convert_bitmap( running_machine &machine, bitmap_t *dst, bitmap_t *src, const rectangle *rect )
2711
2729
{
2712
2730
        int     x, y;
2713
2731
 
2719
2737
                for( x = rect->min_x; x < rect->max_x; x++ )
2720
2738
                {
2721
2739
                        if ( s[x] )
2722
 
                                d[x] = machine->pens[s[x]];
 
2740
                                d[x] = machine.pens[s[x]];
2723
2741
                }
2724
2742
        }
2725
2743
}
2726
2744
 
2727
 
VIDEO_UPDATE(model2)
 
2745
SCREEN_UPDATE(model2)
2728
2746
{
 
2747
        model2_state *state = screen->machine().driver_data<model2_state>();
2729
2748
        logerror("--- frame ---\n");
2730
2749
 
2731
 
        bitmap_fill(bitmap, cliprect, screen->machine->pens[0]);
2732
 
        bitmap_fill(sys24_bitmap, cliprect, 0);
2733
 
 
2734
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 7, 0, 0);
2735
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 6, 0, 0);
2736
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 5, 0, 0);
2737
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 4, 0, 0);
2738
 
 
2739
 
        convert_bitmap(screen->machine, bitmap, sys24_bitmap, cliprect);
 
2750
        bitmap_fill(bitmap, cliprect, screen->machine().pens[0]);
 
2751
        bitmap_fill(state->m_sys24_bitmap, cliprect, 0);
 
2752
 
 
2753
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 7, 0, 0);
 
2754
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 6, 0, 0);
 
2755
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 5, 0, 0);
 
2756
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 4, 0, 0);
 
2757
 
 
2758
        convert_bitmap(screen->machine(), bitmap, state->m_sys24_bitmap, cliprect);
2740
2759
 
2741
2760
        /* tell the rasterizer we're starting a frame */
2742
 
        model2_3d_frame_start();
 
2761
        model2_3d_frame_start(state);
2743
2762
 
2744
2763
        /* let the geometry engine do it's thing */
2745
 
        geo_parse();
 
2764
        geo_parse(state);
2746
2765
 
2747
2766
        /* have the rasterizer output the frame */
2748
 
        model2_3d_frame_end( bitmap, cliprect );
2749
 
 
2750
 
        bitmap_fill(sys24_bitmap, cliprect, 0);
2751
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 3, 0, 0);
2752
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 2, 0, 0);
2753
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 1, 0, 0);
2754
 
        sys24_tile_draw(screen->machine, sys24_bitmap, cliprect, 0, 0, 0);
2755
 
 
2756
 
        convert_bitmap(screen->machine, bitmap, sys24_bitmap, cliprect);
 
2767
        model2_3d_frame_end( state, bitmap, cliprect );
 
2768
 
 
2769
        bitmap_fill(state->m_sys24_bitmap, cliprect, 0);
 
2770
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 3, 0, 0);
 
2771
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 2, 0, 0);
 
2772
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 1, 0, 0);
 
2773
        sys24_tile_draw(screen->machine(), state->m_sys24_bitmap, cliprect, 0, 0, 0);
 
2774
 
 
2775
        convert_bitmap(screen->machine(), bitmap, state->m_sys24_bitmap, cliprect);
2757
2776
 
2758
2777
        return 0;
2759
2778
}