1��
88��#include "emu.h"
89��#include "video/segaic24.h"
90��#include "video/poly.h"
91��#include "includes/model2.h"
92��
93��#define DEBUG 0
94��
95��
96��#define pz p[0]
97��#define pu p[1]
98��#define pv p[2]
99��
100��
101��
106��
107��struct plane
108��{
109�� poly_vertex normal;
110�� float distance;
111��};
112��
113��struct texture_parameter
114��{
115�� float diffuse;
116�� float ambient;
117�� UINT32 specular_control;
118�� float specular_scale;
119��};
120��
121��struct triangle
122��{
123�� void * next;
124�� poly_vertex v[3];
125�� UINT16 z;
126�� UINT16 texheader[4];
127�� UINT8 luma;
128�� INT16 viewport[4];
129�� INT16 center[2];
130��};
131��
132��struct quad_m2
133��{
134�� poly_vertex v[4];
135�� UINT16 z;
136�� UINT16 texheader[4];
137�� UINT8 luma;
138��};
139��
140��struct poly_extra_data
141��{
142�� model2_state * state;
143�� UINT32 lumabase;
144�� UINT32 colorbase;
145�� UINT32 * texsheet;
146�� UINT32 texwidth;
147�� UINT32 texheight;
148�� UINT32 texx, texy;
149�� UINT8 texmirrorx;
150�� UINT8 texmirrory;
151��};
152��
153��
154��
159��
160��INLINE void transform_point( poly_vertex *point, float *matrix )
161��{
162�� float tx = (point->x * matrix[0]) + (point->y * matrix[3]) + (point->pz * matrix[6]) + (matrix[9]);
163�� float ty = (point->x * matrix[1]) + (point->y * matrix[4]) + (point->pz * matrix[7]) + (matrix[10]);
164�� float tz = (point->x * matrix[2]) + (point->y * matrix[5]) + (point->pz * matrix[8]) + (matrix[11]);
165��
166�� point->x = tx;
167�� point->y = ty;
168�� point->pz = tz;
169��}
170��
171��INLINE void transform_vector( poly_vertex *vector, float *matrix )
172��{
173�� float tx = (vector->x * matrix[0]) + (vector->y * matrix[3]) + (vector->pz * matrix[6]);
174�� float ty = (vector->x * matrix[1]) + (vector->y * matrix[4]) + (vector->pz * matrix[7]);
175�� float tz = (vector->x * matrix[2]) + (vector->y * matrix[5]) + (vector->pz * matrix[8]);
176��
177�� vector->x = tx;
178�� vector->y = ty;
179�� vector->pz = tz;
180��}
181��
182��INLINE void normalize_vector( poly_vertex *vector )
183��{
184�� float n = sqrt( (vector->x * vector->x) + (vector->y * vector->y) + (vector->pz * vector->pz) );
185��
186�� if ( n )
187�� {
188�� float oon = 1.0f / n;
189�� vector->x *= oon;
190�� vector->y *= oon;
191�� vector->pz *= oon;
192�� }
193��}
194��
195��INLINE float dot_product( poly_vertex *v1, poly_vertex *v2 )
196��{
197�� return (v1->x * v2->x) + (v1->y * v2->y) + (v1->pz * v2->pz);
198��}
199��
200��INLINE void vector_cross3( poly_vertex *dst, poly_vertex *v0, poly_vertex *v1, poly_vertex *v2 )
201��{
202�� poly_vertex p1, p2;
203��
204�� p1.x = v1->x - v0->x; p1.y = v1->y - v0->y; p1.pz = v1->pz - v0->pz;
205�� p2.x = v2->x - v0->x; p2.y = v2->y - v0->y; p2.pz = v2->pz - v0->pz;
206��
207�� dst->x = (p1.y * p2.pz) - (p1.pz * p2.y);
208�� dst->y = (p1.pz * p2.x) - (p1.x * p2.pz);
209�� dst->pz = (p1.x * p2.y) - (p1.y * p2.x);
210��}
211��
212��
213��static UINT16 float_to_zval( float floatval )
214��{
215�� INT32 fpint = f2u(floatval);
216�� INT32 exponent = ((fpint >> 23) & 0xff) - 127;
217�� UINT32 mantissa = fpint & 0x7fffff;
218��
219��
220�� mantissa += 0x400;
221�� if (mantissa > 0x7fffff) { exponent++; mantissa = (mantissa & 0x7fffff) >> 1; }
222�� mantissa >>= 11;
223��
224��
225�� if (fpint < 0)
226�� return 0x0000;
227��
228��
229��
230�� if ( exponent < -12 )
231�� return 0x0000;
232��
233��
234�� else if ( exponent < 0 )
235�� return (mantissa | 0x1000) >> -exponent;
236��
237��
238�� else if ( exponent < 15 )
239�� return (( exponent + 1 ) << 12) | mantissa;
240��
241��
242�� return 0xffff;
243��}
244��
245��static INT32 clip_polygon(poly_vertex *v, INT32 num_vertices, plane *cp, poly_vertex *vout)
246��{
247�� poly_vertex *cur, *out;
248�� float curdot, nextdot, scale;
249�� INT32 i, curin, nextin, nextvert, outcount;
250��
251�� outcount = 0;
252��
253�� cur = v;
254�� out = vout;
255��
256�� curdot = dot_product( cur, &cp->normal );
257�� curin = (curdot >= cp->distance) ? 1 : 0;
258��
259�� for( i = 0; i < num_vertices; i++ )
260�� {
261�� nextvert = (i + 1) % num_vertices;
262��
263��
264�� if ( curin ) memcpy( &out[outcount++], cur, sizeof( poly_vertex ) );
265��
266�� nextdot = dot_product( &v[nextvert], &cp->normal );
267�� nextin = (nextdot >= cp->distance) ? 1 : 0;
268��
269��
270�� if ( curin != nextin )
271�� {
272�� scale = (cp->distance - curdot) / (nextdot - curdot);
273��
274�� out[outcount].x = cur->x + ((v[nextvert].x - cur->x) * scale);
275�� out[outcount].y = cur->y + ((v[nextvert].y - cur->y) * scale);
276�� out[outcount].pz = cur->pz + ((v[nextvert].pz - cur->pz) * scale);
277�� out[outcount].pu = (UINT16)((float)cur->pu + (((float)v[nextvert].pu - (float)cur->pu) * scale));
278�� out[outcount].pv = (UINT16)((float)cur->pv + (((float)v[nextvert].pv - (float)cur->pv) * scale));
279�� outcount++;
280�� }
281��
282�� curdot = nextdot;
283�� curin = nextin;
284�� cur++;
285�� }
286��
287�� return outcount;
288��}
289��
290��
291��
292��
297��
298��#define MAX_TRIANGLES 32768
299��
300��struct raster_state
301��{
302�� UINT32 mode;
303�� UINT16 * texture_rom;
304�� INT16 viewport[4];
305�� INT16 center[4][2];
306�� UINT16 center_sel;
307�� UINT32 reverse;
308�� float z_adjust;
309�� float triangle_z;
310�� UINT8 master_z_clip;
311�� UINT32 cur_command;
312�� UINT32 command_buffer[32];
313�� UINT32 command_index;
314�� triangle tri_list[MAX_TRIANGLES];
315�� UINT32 tri_list_index;
316�� triangle * tri_sorted_list[0x10000];
317�� UINT16 min_z;
318�� UINT16 max_z;
319�� UINT16 texture_ram[0x10000];
320�� UINT8 log_ram[0x40000];
321��};
322��
323��
324��
329��
330��static void model2_3d_init( running_machine &machine, UINT16 *texture_rom )
331��{
332�� model2_state *state = machine.driver_data<model2_state>();
333��
334�� state->m_raster = auto_alloc_clear( machine, raster_state );
335��
336�� state->m_raster->texture_rom = texture_rom;
337��}
338��
339��
344��
345��void model2_3d_set_zclip( running_machine &machine, UINT8 clip )
346��{
347�� model2_state *state = machine.driver_data<model2_state>();
348�� state->m_raster->master_z_clip = clip;
349��}
350��
351��
356��
357��static void model2_3d_process_quad( raster_state *raster, UINT32 attr )
358��{
359�� quad_m2 object;
360�� UINT16 *th, *tp;
361�� INT32 tho;
362�� UINT32 cull, i;
363�� float zvalue;
364�� float min_z, max_z;
365��
366��
367�� object.v[1].x = u2f( raster->command_buffer[2] << 8 );
368�� object.v[1].y = u2f( raster->command_buffer[3] << 8 );
369�� object.v[1].pz = u2f( raster->command_buffer[4] << 8 );
370��
371��
372�� object.v[0].x = u2f( raster->command_buffer[5] << 8 );
373�� object.v[0].y = u2f( raster->command_buffer[6] << 8 );
374�� object.v[0].pz = u2f( raster->command_buffer[7] << 8 );
375��
376��
377�� object.v[2].x = u2f( raster->command_buffer[11] << 8 );
378�� object.v[2].y = u2f( raster->command_buffer[12] << 8 );
379�� object.v[2].pz = u2f( raster->command_buffer[13] << 8 );
380��
381��
382�� object.v[3].x = u2f( raster->command_buffer[14] << 8 );
383�� object.v[3].y = u2f( raster->command_buffer[15] << 8 );
384�� object.v[3].pz = u2f( raster->command_buffer[16] << 8 );
385��
386��
387�� min_z = object.v[0].pz;
388�� if ( object.v[1].pz < min_z ) min_z = object.v[1].pz;
389�� if ( object.v[2].pz < min_z ) min_z = object.v[2].pz;
390�� if ( object.v[3].pz < min_z ) min_z = object.v[3].pz;
391��
392�� max_z = object.v[0].pz;
393�� if ( object.v[1].pz > max_z ) max_z = object.v[1].pz;
394�� if ( object.v[2].pz > max_z ) max_z = object.v[2].pz;
395�� if ( object.v[3].pz > max_z ) max_z = object.v[3].pz;
396��
397��
398��
399��
400�� if ( raster->command_buffer[0] & 0x800000 )
401�� tp = &raster->texture_ram[raster->command_buffer[0] & 0xFFFF];
402�� else
403�� tp = &raster->texture_rom[raster->command_buffer[0] & 0x7FFFFF];
404��
405�� object.v[0].pv = *tp++;
406�� object.v[0].pu = *tp++;
407�� object.v[1].pv = *tp++;
408�� object.v[1].pu = *tp++;
409�� object.v[2].pv = *tp++;
410�� object.v[2].pu = *tp++;
411�� object.v[3].pv = *tp++;
412�� object.v[3].pu = *tp++;
413��
414��
415�� raster->command_buffer[0] += 8;
416��
417��
418�� if ( raster->command_buffer[1] & 0x800000 )
419�� th = &raster->texture_ram[raster->command_buffer[1] & 0xFFFF];
420�� else
421�� th = &raster->texture_rom[raster->command_buffer[1] & 0x7FFFFF];
422��
423�� object.texheader[0] = *th++;
424�� object.texheader[1] = *th++;
425�� object.texheader[2] = *th++;
426�� object.texheader[3] = *th++;
427��
428��
429�� tho = (attr >> 12) & 0x1F;
430��
431��
432�� if ( tho & 0x10 )
433�� tho |= -16;
434��
435��
436�� raster->command_buffer[1] += tho * 4;
437��
438��
439�� object.luma = (raster->command_buffer[9] >> 15) & 0xFF;
440��
441��
442�� cull = 0;
443��
444��
445�� if ( ((attr >> 17) & 1) == 0 )
446�� {
447��
448�� if ( raster->command_buffer[9] & 0x00800000 )
449�� cull = 1;
450�� }
451��
452��
453�� if ( ((attr >> 8) & 3) == 0 )
454�� cull = 1;
455��
456��
457�� if ( (INT32)(1.0/min_z) > raster->master_z_clip )
458�� cull = 1;
459��
460��
461�� if ( max_z < 0 )
462�� cull = 1;
463��
464��
465�� zvalue = raster->triangle_z;
466��
467��
468�� if ( (attr >> 10) & 3 )
469�� {
470�� if ( (attr >> 10) & 1 )
471�� {
472�� zvalue = min_z;
473�� }
474�� else if ( (attr >> 10) & 2 )
475�� {
476�� zvalue = max_z;
477�� }
478��
479�� raster->triangle_z = zvalue;
480�� }
481��
482�� if ( cull == 0 )
483�� {
484�� INT32 clipped_verts;
485�� poly_vertex verts[10];
486�� plane clip_plane;
487��
488�� clip_plane.normal.x = 0;
489�� clip_plane.normal.y = 0;
490�� clip_plane.normal.pz = 1;
491�� clip_plane.distance = 0;
492��
493��
494�� clipped_verts = clip_polygon( object.v, 4, &clip_plane, verts);
495��
496�� if ( clipped_verts > 2 )
497�� {
498�� triangle *ztri;
499��
500��
501�� object.z = float_to_zval( zvalue + raster->z_adjust );
502��
503��
504�� ztri = raster->tri_sorted_list[object.z];
505��
506�� if ( ztri != NULL )
507�� {
508�� while( ztri->next != NULL )
509�� ztri = (triangle *)ztri->next;
510�� }
511��
512��
513�� for( i = 2; i < clipped_verts; i++ )
514�� {
515�� triangle *tri;
516��
517�� tri = &raster->tri_list[raster->tri_list_index++];
518��
519�� if ( raster->tri_list_index >= MAX_TRIANGLES )
520�� {
521�� fatalerror( "SEGA 3D: Max triangle limit exceeded\n" );
522�� }
523��
524��
525�� tri->z = object.z;
526�� tri->texheader[0] = object.texheader[0];
527�� tri->texheader[1] = object.texheader[1];
528�� tri->texheader[2] = object.texheader[2];
529�� tri->texheader[3] = object.texheader[3];
530�� tri->luma = object.luma;
531��
532��
533�� tri->viewport[0] = raster->viewport[0];
534�� tri->viewport[1] = raster->viewport[1];
535�� tri->viewport[2] = raster->viewport[2];
536�� tri->viewport[3] = raster->viewport[3];
537��
538��
539�� tri->center[0] = raster->center[raster->center_sel][0];
540�� tri->center[1] = raster->center[raster->center_sel][1];
541��
542�� memcpy( &tri->v[0], &verts[0], sizeof( poly_vertex ) );
543�� memcpy( &tri->v[1], &verts[i-1], sizeof( poly_vertex ) );
544�� memcpy( &tri->v[2], &verts[i], sizeof( poly_vertex ) );
545��
546��
547�� tri->next = NULL;
548��
549�� if ( ztri == NULL )
550�� {
551�� raster->tri_sorted_list[object.z] = tri;
552�� }
553�� else
554�� {
555�� ztri->next = tri;
556�� }
557��
558�� ztri = tri;
559�� }
560��
561��
562�� if ( object.z < raster->min_z ) raster->min_z = object.z;
563�� if ( object.z > raster->max_z ) raster->max_z = object.z;
564�� }
565�� }
566��
567��
568�� switch( ((attr >> 8) & 3) )
569�� {
570�� case 0:
571�� case 2:
572�� {
573��
574�� for( i = 0; i < 6; i++ )
575�� raster->command_buffer[2+i] = raster->command_buffer[11+i];
576�� }
577�� break;
578��
579�� case 1:
580�� {
581��
582�� for( i = 0; i < 3; i++ )
583�� raster->command_buffer[5+i] = raster->command_buffer[11+i];
584�� }
585�� break;
586��
587�� case 3:
588�� {
589��
590�� for( i = 0; i < 3; i++ )
591�� raster->command_buffer[2+i] = raster->command_buffer[14+i];
592�� }
593�� break;
594�� }
595��}
596��
597��static void model2_3d_process_triangle( raster_state *raster, UINT32 attr )
598��{
599�� triangle object;
600�� UINT16 *th, *tp;
601�� INT32 tho;
602�� UINT32 cull, i;
603�� float zvalue;
604�� float min_z, max_z;
605��
606��
607�� object.v[1].x = u2f( raster->command_buffer[2] << 8 );
608�� object.v[1].y = u2f( raster->command_buffer[3] << 8 );
609�� object.v[1].pz = u2f( raster->command_buffer[4] << 8 );
610��
611��
612�� object.v[0].x = u2f( raster->command_buffer[5] << 8 );
613�� object.v[0].y = u2f( raster->command_buffer[6] << 8 );
614�� object.v[0].pz = u2f( raster->command_buffer[7] << 8 );
615��
616��
617�� object.v[2].x = u2f( raster->command_buffer[11] << 8 );
618�� object.v[2].y = u2f( raster->command_buffer[12] << 8 );
619�� object.v[2].pz = u2f( raster->command_buffer[13] << 8 );
620��
621��
622�� raster->command_buffer[14] = raster->command_buffer[11];
623�� raster->command_buffer[15] = raster->command_buffer[12];
624�� raster->command_buffer[16] = raster->command_buffer[13];
625��
626��
627�� min_z = object.v[0].pz;
628�� if ( object.v[1].pz < min_z ) min_z = object.v[1].pz;
629�� if ( object.v[2].pz < min_z ) min_z = object.v[2].pz;
630��
631�� max_z = object.v[0].pz;
632�� if ( object.v[1].pz > max_z ) max_z = object.v[1].pz;
633�� if ( object.v[2].pz > max_z ) max_z = object.v[2].pz;
634��
635��
636��
637��
638�� if ( raster->command_buffer[0] & 0x800000 )
639�� tp = &raster->texture_ram[raster->command_buffer[0] & 0xFFFF];
640�� else
641�� tp = &raster->texture_rom[raster->command_buffer[0] & 0x7FFFFF];
642��
643�� object.v[0].pv = *tp++;
644�� object.v[0].pu = *tp++;
645�� object.v[1].pv = *tp++;
646�� object.v[1].pu = *tp++;
647�� object.v[2].pv = *tp++;
648�� object.v[2].pu = *tp++;
649��
650��
651�� raster->command_buffer[0] += 6;
652��
653��
654�� if ( raster->command_buffer[1] & 0x800000 )
655�� th = &raster->texture_ram[raster->command_buffer[1] & 0xFFFF];
656�� else
657�� th = &raster->texture_rom[raster->command_buffer[1] & 0x7FFFFF];
658��
659�� object.texheader[0] = *th++;
660�� object.texheader[1] = *th++;
661�� object.texheader[2] = *th++;
662�� object.texheader[3] = *th++;
663��
664��
665�� tho = (attr >> 12) & 0x1F;
666��
667��
668�� if ( tho & 0x10 )
669�� tho |= -16;
670��
671��
672�� raster->command_buffer[1] += tho * 4;
673��
674��
675�� object.luma = (raster->command_buffer[9] >> 15) & 0xFF;
676��
677��
678�� cull = 0;
679��
680��
681�� if ( ((attr >> 17) & 1) == 0 )
682�� {
683��
684�� if ( raster->command_buffer[9] & 0x00800000 )
685�� cull = 1;
686�� }
687��
688��
689�� if ( ((attr >> 8) & 3) == 0 )
690�� cull = 1;
691��
692��
693�� if ( (INT32)(1.0/min_z) > raster->master_z_clip )
694�� cull = 1;
695��
696��
697�� if ( max_z < 0 )
698�� cull = 1;
699��
700��
701�� zvalue = raster->triangle_z;
702��
703��
704�� if ( (attr >> 10) & 3 )
705�� {
706�� if ( (attr >> 10) & 1 )
707�� {
708�� zvalue = min_z;
709�� }
710�� else if ( (attr >> 10) & 2 )
711�� {
712�� zvalue = max_z;
713�� }
714��
715�� raster->triangle_z = zvalue;
716�� }
717��
718��
719�� if ( cull == 0 )
720�� {
721�� INT32 clipped_verts;
722�� poly_vertex verts[10];
723�� plane clip_plane;
724��
725�� clip_plane.normal.x = 0;
726�� clip_plane.normal.y = 0;
727�� clip_plane.normal.pz = 1;
728�� clip_plane.distance = 0;
729��
730��
731�� clipped_verts = clip_polygon( object.v, 3, &clip_plane, verts);
732��
733�� if ( clipped_verts > 2 )
734�� {
735�� triangle *ztri;
736��
737��
738�� object.z = float_to_zval( zvalue + raster->z_adjust );
739��
740��
741�� ztri = raster->tri_sorted_list[object.z];
742��
743�� if ( ztri != NULL )
744�� {
745�� while( ztri->next != NULL )
746�� ztri = (triangle *)ztri->next;
747�� }
748��
749��
750�� for( i = 2; i < clipped_verts; i++ )
751�� {
752�� triangle *tri;
753��
754�� tri = &raster->tri_list[raster->tri_list_index++];
755��
756�� if ( raster->tri_list_index >= MAX_TRIANGLES )
757�� {
758�� fatalerror( "SEGA 3D: Max triangle limit exceeded\n" );
759�� }
760��
761��
762�� tri->z = object.z;
763�� tri->texheader[0] = object.texheader[0];
764�� tri->texheader[1] = object.texheader[1];
765�� tri->texheader[2] = object.texheader[2];
766�� tri->texheader[3] = object.texheader[3];
767�� tri->luma = object.luma;
768��
769��
770�� tri->viewport[0] = raster->viewport[0];
771�� tri->viewport[1] = raster->viewport[1];
772�� tri->viewport[2] = raster->viewport[2];
773�� tri->viewport[3] = raster->viewport[3];
774��
775��
776�� tri->center[0] = raster->center[raster->center_sel][0];
777�� tri->center[1] = raster->center[raster->center_sel][1];
778��
779�� memcpy( &tri->v[0], &verts[0], sizeof( poly_vertex ) );
780�� memcpy( &tri->v[1], &verts[i-1], sizeof( poly_vertex ) );
781�� memcpy( &tri->v[2], &verts[i], sizeof( poly_vertex ) );
782��
783��
784�� tri->next = NULL;
785��
786�� if ( ztri == NULL )
787�� {
788�� raster->tri_sorted_list[object.z] = tri;
789�� }
790�� else
791�� {
792�� ztri->next = tri;
793�� }
794��
795�� ztri = tri;
796�� }
797��
798��
799�� if ( object.z < raster->min_z ) raster->min_z = object.z;
800�� if ( object.z > raster->max_z ) raster->max_z = object.z;
801�� }
802�� }
803��
804��
805�� switch( ((attr >> 8) & 3) )
806�� {
807�� case 0:
808�� case 2:
809�� {
810��
811�� for( i = 0; i < 6; i++ )
812�� raster->command_buffer[2+i] = raster->command_buffer[11+i];
813�� }
814�� break;
815��
816�� case 1:
817�� {
818��
819�� for( i = 0; i < 3; i++ )
820�� raster->command_buffer[5+i] = raster->command_buffer[11+i];
821�� }
822�� break;
823��
824�� case 3:
825�� {
826��
827�� for( i = 0; i < 3; i++ )
828�� raster->command_buffer[2+i] = raster->command_buffer[14+i];
829�� }
830�� break;
831�� }
832��}
833��
834��
835��
836��INLINE UINT16 get_texel( UINT32 base_x, UINT32 base_y, int x, int y, UINT32 *sheet )
837��{
838�� UINT32 baseoffs = ((base_y/2)*512)+(base_x/2);
839�� UINT32 texeloffs = ((y/2)*512)+(x/2);
840�� UINT32 offset = baseoffs + texeloffs;
841�� UINT32 texel = sheet[offset>>1];
842��
843�� if ( offset & 1 )
844�� texel >>= 16;
845��
846�� if ( (y & 1) == 0 )
847�� texel >>= 8;
848��
849�� if ( (x & 1) == 0 )
850�� texel >>= 4;
851��
852�� return (texel & 0x0f);
853��}
854��
855��
856��#define MODEL2_FUNC 0
857��#define MODEL2_FUNC_NAME model2_3d_render_0
858��#include "model2rd.c"
859��#undef MODEL2_FUNC
860��#undef MODEL2_FUNC_NAME
861��
862��
863��#define MODEL2_FUNC 1
864��#define MODEL2_FUNC_NAME model2_3d_render_1
865��#include "model2rd.c"
866��#undef MODEL2_FUNC
867��#undef MODEL2_FUNC_NAME
868��
869��
870��#define MODEL2_FUNC 2
871��#define MODEL2_FUNC_NAME model2_3d_render_2
872��#include "model2rd.c"
873��#undef MODEL2_FUNC
874��#undef MODEL2_FUNC_NAME
875��
876��
877��#define MODEL2_FUNC 3
878��#define MODEL2_FUNC_NAME model2_3d_render_3
879��#include "model2rd.c"
880��#undef MODEL2_FUNC
881��#undef MODEL2_FUNC_NAME
882��
883��
884��#define MODEL2_FUNC 4
885��#define MODEL2_FUNC_NAME model2_3d_render_4
886��#include "model2rd.c"
887��#undef MODEL2_FUNC
888��#undef MODEL2_FUNC_NAME
889��
890��
891��#define MODEL2_FUNC 5
892��#define MODEL2_FUNC_NAME model2_3d_render_5
893��#include "model2rd.c"
894��#undef MODEL2_FUNC
895��#undef MODEL2_FUNC_NAME
896��
897��
898��#define MODEL2_FUNC 6
899��#define MODEL2_FUNC_NAME model2_3d_render_6
900��#include "model2rd.c"
901��#undef MODEL2_FUNC
902��#undef MODEL2_FUNC_NAME
903��
904��
905��#define MODEL2_FUNC 7
906��#define MODEL2_FUNC_NAME model2_3d_render_7
907��#include "model2rd.c"
908��#undef MODEL2_FUNC
909��#undef MODEL2_FUNC_NAME
910��
911��
912��
913��static const poly_draw_scanline_func render_funcs[8] =
914��{
915�� model2_3d_render_0,
916�� model2_3d_render_1,
917�� model2_3d_render_2,
918�� model2_3d_render_3,
919�� model2_3d_render_4,
920�� model2_3d_render_5,
921�� model2_3d_render_6,
922�� model2_3d_render_7
923��};
924��
925��static void model2_3d_render( model2_state *state, bitmap_rgb32 &bitmap, triangle *tri, const rectangle &cliprect )
926��{
927�� poly_manager *poly = state->m_poly;
928�� poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(poly);
929�� UINT8 renderer;
930��
931��
932�� renderer = (tri->texheader[0] >> 13) & 7;
933��
934��
935�� rectangle vp(tri->viewport[0] - 8, tri->viewport[2] - 8, (384-tri->viewport[3])+90, (384-tri->viewport[1])+90);
936�� vp &= cliprect;
937��
938�� extra->state = state;
939�� extra->lumabase = ((tri->texheader[1] & 0xFF) << 7) + ((tri->luma >> 5) ^ 0x7);
940�� extra->colorbase = (tri->texheader[3] >> 6) & 0x3FF;
941��
942�� if (renderer & 2)
943�� {
944�� extra->texwidth = 32 << ((tri->texheader[0] >> 0) & 0x7);
945�� extra->texheight = 32 << ((tri->texheader[0] >> 3) & 0x7);
946�� extra->texx = 32 * ((tri->texheader[2] >> 0) & 0x1f);
947�� extra->texy = 32 * (((tri->texheader[2] >> 6) & 0x1f) + ( tri->texheader[2] & 0x20 ));
948�� extra->texmirrorx = (tri->texheader[0] >> 9) & 1;
949�� extra->texmirrory = (tri->texheader[0] >> 8) & 1;
950�� extra->texsheet = (tri->texheader[2] & 0x1000) ? state->m_textureram1 : state->m_textureram0;
951��
952�� tri->v[0].pz = 1.0f / (1.0f + tri->v[0].pz);
953�� tri->v[0].pu = tri->v[0].pu * tri->v[0].pz * (1.0f / 8.0f);
954�� tri->v[0].pv = tri->v[0].pv * tri->v[0].pz * (1.0f / 8.0f);
955�� tri->v[1].pz = 1.0f / (1.0f + tri->v[1].pz);
956�� tri->v[1].pu = tri->v[1].pu * tri->v[1].pz * (1.0f / 8.0f);
957�� tri->v[1].pv = tri->v[1].pv * tri->v[1].pz * (1.0f / 8.0f);
958�� tri->v[2].pz = 1.0f / (1.0f + tri->v[2].pz);
959�� tri->v[2].pu = tri->v[2].pu * tri->v[2].pz * (1.0f / 8.0f);
960�� tri->v[2].pv = tri->v[2].pv * tri->v[2].pz * (1.0f / 8.0f);
961��
962�� poly_render_triangle(poly, &bitmap, vp, render_funcs[renderer], 3, &tri->v[0], &tri->v[1], &tri->v[2]);
963�� }
964�� else
965�� poly_render_triangle(poly, &bitmap, vp, render_funcs[renderer], 0, &tri->v[0], &tri->v[1], &tri->v[2]);
966��}
967��
968��
986��
987��
988��static void model2_3d_project( triangle *tri )
989��{
990�� UINT16 i;
991��
992�� for( i = 0; i < 3; i++ )
993�� {
994��
995�� tri->v[i].x = -8 + tri->center[0] + (tri->v[i].x / (1.0f+tri->v[i].pz));
996�� tri->v[i].y = ((384 - tri->center[1])+90) - (tri->v[i].y / (1.0f+tri->v[i].pz));
997�� }
998��}
999��
1000��
1001��static void model2_3d_frame_start( model2_state *state )
1002��{
1003�� raster_state *raster = state->m_raster;
1004��
1005��
1006�� raster->tri_list_index = 0;
1007��
1008��
1009�� memset( raster->tri_sorted_list, 0, 0x10000 * sizeof( triangle * ) );
1010��
1011��
1012�� raster->min_z = 0xFFFF;
1013�� raster->max_z = 0;
1014��}
1015��
1016��static void model2_3d_frame_end( model2_state *state, bitmap_rgb32 &bitmap, const rectangle &cliprect )
1017��{
1018�� raster_state *raster = state->m_raster;
1019�� INT32 z;
1020��
1021��
1022�� if ( raster->tri_list_index == 0 )
1023�� return;
1024��
1025��#if DEBUG
1026�� if (machine.input().code_pressed(KEYCODE_Q))
1027�� {
1028�� UINT32 i;
1029��
1030�� FILE *f = fopen( "triangles.txt", "w" );
1031��
1032�� if ( f )
1033�� {
1034�� for( i = 0; i < raster->tri_list_index; i++ )
1035�� {
1036��
1037�� fprintf( f, "index: %d\n", i );
1038�� 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 );
1039�� 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 );
1040�� 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 );
1041��
1042�� fprintf( f, "tri z: %04x\n", raster->tri_list[i].pz );
1043�� fprintf( f, "texheader - 0: %04x\n", raster->tri_list[i].texheader[0] );
1044�� fprintf( f, "texheader - 1: %04x\n", raster->tri_list[i].texheader[1] );
1045�� fprintf( f, "texheader - 2: %04x\n", raster->tri_list[i].texheader[2] );
1046�� fprintf( f, "texheader - 3: %04x\n", raster->tri_list[i].texheader[3] );
1047�� fprintf( f, "luma: %02x\n", raster->tri_list[i].luma );
1048�� fprintf( f, "vp.sx: %04x\n", raster->tri_list[i].viewport[0] );
1049�� fprintf( f, "vp.sy: %04x\n", raster->tri_list[i].viewport[1] );
1050�� fprintf( f, "vp.ex: %04x\n", raster->tri_list[i].viewport[2] );
1051�� fprintf( f, "vp.ey: %04x\n", raster->tri_list[i].viewport[3] );
1052�� fprintf( f, "vp.swx: %04x\n", raster->tri_list[i].center[0] );
1053�� fprintf( f, "vp.swy: %04x\n", raster->tri_list[i].center[1] );
1054�� fprintf( f, "\n---\n\n" );
1055�� }
1056��
1057�� fprintf( f, "min_z = %04x, max_z = %04x\n", raster->min_z, raster->max_z );
1058��
1059�� fclose( f );
1060�� }
1061�� }
1062��#endif
1063��
1064��
1065�� for( z = raster->max_z; z >= raster->min_z; z-- )
1066�� {
1067��
1068�� if ( raster->tri_sorted_list[z] != NULL )
1069�� {
1070��
1071�� triangle *tri = raster->tri_sorted_list[z];
1072��
1073��
1074�� while( tri != NULL )
1075�� {
1076��
1077�� model2_3d_project( tri );
1078�� model2_3d_render( state, bitmap, tri, cliprect );
1079��
1080�� tri = (triangle *)tri->next;
1081�� }
1082�� }
1083�� }
1084�� poly_wait(state->m_poly, "End of frame");
1085��}
1086��
1087��
1088��static void model2_3d_push( raster_state *raster, UINT32 input )
1089��{
1090��
1091�� if ( raster->cur_command != 0 )
1092�� {
1093�� raster->command_buffer[raster->command_index++] = input;
1094��
1095�� switch( raster->cur_command )
1096�� {
1097�� case 0x00:
1098�� break;
1099��
1100�� case 0x01:
1101�� {
1102�� UINT32 attr;
1103��
1104��
1105�� if ( raster->command_index < 9 )
1106�� return;
1107��
1108��
1109�� attr = raster->command_buffer[8];
1110��
1111��
1112�� if ( (attr & 3) == 0 )
1113�� {
1114�� raster->cur_command = 0;
1115�� return;
1116�� }
1117��
1118��
1119�� if ( attr & 1 )
1120�� {
1121��
1122�� if ( raster->command_index < 17 )
1123�� return;
1124��
1125��
1126�� model2_3d_process_quad( raster, attr );
1127��
1128��
1129�� raster->command_index = 8;
1130�� }
1131�� else
1132�� {
1133��
1134�� if ( raster->command_index < 14 )
1135�� return;
1136��
1137��
1138�� model2_3d_process_triangle( raster, attr );
1139��
1140��
1141�� raster->command_index = 8;
1142�� }
1143�� }
1144�� break;
1145��
1146�� case 0x03:
1147�� {
1148�� UINT32 i;
1149��
1150��
1151�� if ( raster->command_index < 6 )
1152�� return;
1153��
1154��
1155��
1156��
1157�� raster->viewport[0] = (raster->command_buffer[0] >> 12) & 0xFFF;
1158��
1159�� if ( raster->viewport[0] & 0x800 )
1160�� raster->viewport[0] = -( 0x800 - (raster->viewport[0] & 0x7FF) );
1161��
1162��
1163�� raster->viewport[1] = raster->command_buffer[0] & 0xFFF;
1164��
1165�� if ( raster->viewport[1] & 0x800 )
1166�� raster->viewport[1] = -( 0x800 - (raster->viewport[1] & 0x7FF) );
1167��
1168��
1169�� raster->viewport[2] = (raster->command_buffer[1] >> 12) & 0xFFF;
1170��
1171�� if ( raster->viewport[2] & 0x800 )
1172�� raster->viewport[2] = -( 0x800 - (raster->viewport[2] & 0x7FF) );
1173��
1174��
1175�� raster->viewport[3] = raster->command_buffer[1] & 0xFFF;
1176��
1177�� if ( raster->viewport[3] & 0x800 )
1178�� raster->viewport[3] = -( 0x800 - (raster->viewport[3] & 0x7FF) );
1179��
1180��
1181�� for( i = 0; i < 4; i++ )
1182�� {
1183��
1184�� raster->center[i][0] = (raster->command_buffer[2+i] >> 12) & 0xFFF;
1185��
1186�� if ( raster->center[i][0] & 0x800 )
1187�� raster->center[i][0] = -( 0x800 - (raster->center[i][0] & 0x7FF) );
1188��
1189��
1190�� raster->center[i][1] = raster->command_buffer[2+i] & 0xFFF;
1191��
1192�� if ( raster->center[i][1] & 0x800 )
1193�� raster->center[i][1] = -( 0x800 - (raster->center[i][1] & 0x7FF) );
1194�� }
1195��
1196��
1197�� raster->cur_command = 0;
1198�� }
1199�� break;
1200��
1201�� case 0x04:
1202�� {
1203��
1204�� if ( raster->command_index < 2 )
1205�� return;
1206��
1207��
1208�� if ( raster->command_buffer[1] > 0 )
1209�� {
1210��
1211�� if ( raster->command_index >= 3 )
1212�� {
1213��
1214�� UINT32 address = raster->command_buffer[0];
1215��
1216��
1217�� if ( address & 0x800000 )
1218�� raster->texture_ram[address&0xFFFF] = raster->command_buffer[2];
1219�� else
1220�� raster->log_ram[address&0xFFFF] = raster->command_buffer[2];
1221��
1222��
1223�� raster->command_buffer[0]++;
1224�� raster->command_buffer[1]--;
1225��
1226��
1227�� raster->command_index--;
1228�� }
1229�� }
1230��
1231��
1232�� if ( raster->command_buffer[1] == 0 )
1233�� raster->cur_command = 0;
1234�� }
1235�� break;
1236��
1237�� case 0x08:
1238�� {
1239��
1240�� raster->z_adjust = u2f( raster->command_buffer[0] << 8 );
1241��
1242��
1243�� raster->cur_command = 0;
1244�� }
1245�� break;
1246��
1247�� default:
1248�� {
1249�� fatalerror( "SEGA 3D: Unknown rasterizer command %08x\n", raster->cur_command );
1250�� }
1251�� break;
1252�� }
1253�� }
1254�� else
1255�� {
1256��
1257�� raster->cur_command = input & 0x0F;
1258�� raster->command_index = 0;
1259��
1260��
1261�� if ( raster->cur_command == 1 )
1262�� {
1263��
1264�� raster->reverse = (input >> 4) & 1;
1265��
1266��
1267�� raster->center_sel = ( input >> 6 ) & 3;
1268��
1269��
1270�� raster->triangle_z = 0;
1271�� }
1272�� }
1273��}
1274��
1275��
1276��
1277��
1278��
1279��
1284��
1285��struct geo_state
1286��{
1287�� raster_state * raster;
1288�� UINT32 mode;
1289�� UINT32 * polygon_rom;
1290�� float matrix[12];
1291�� poly_vertex focus;
1292�� poly_vertex light;
1293�� float lod;
1294�� float coef_table[32];
1295�� texture_parameter texture_parameters[32];
1296�� UINT32 polygon_ram0[0x8000];
1297�� UINT32 polygon_ram1[0x8000];
1298��};
1299��
1300��
1301��
1306��
1307��static void geo_init( running_machine &machine, UINT32 *polygon_rom )
1308��{
1309�� model2_state *state = machine.driver_data<model2_state>();
1310�� state->m_geo = auto_alloc_clear(machine, geo_state);
1311��
1312�� state->m_geo->raster = state->m_raster;
1313�� state->m_geo->polygon_rom = polygon_rom;
1314��}
1315��
1316��
1321��
1322��
1323��static void geo_parse_np_ns( geo_state *geo, UINT32 *input, UINT32 count )
1324��{
1325�� raster_state *raster = geo->raster;
1326�� poly_vertex point, normal;
1327�� UINT32 attr, i;
1328��
1329��
1330�� point.x = u2f( *input++ );
1331�� point.y = u2f( *input++ );
1332�� point.pz = u2f( *input++ );
1333��
1334��
1335�� transform_point( &point, geo->matrix );
1336��
1337��
1338�� point.x *= geo->focus.x;
1339�� point.y *= geo->focus.y;
1340��
1341��
1342�� model2_3d_push( raster, f2u(point.x) >> 8 );
1343�� model2_3d_push( raster, f2u(point.y) >> 8 );
1344�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1345��
1346��
1347�� point.x = u2f( *input++ );
1348�� point.y = u2f( *input++ );
1349�� point.pz = u2f( *input++ );
1350��
1351��
1352�� transform_point( &point, geo->matrix );
1353��
1354��
1355�� point.x *= geo->focus.x;
1356�� point.y *= geo->focus.y;
1357��
1358��
1359�� model2_3d_push( raster, f2u(point.x) >> 8 );
1360�� model2_3d_push( raster, f2u(point.y) >> 8 );
1361�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1362��
1363��
1364�� for( i = 0; i < count; i++ )
1365�� {
1366��
1367�� attr = *input++;
1368��
1369��
1370�� model2_3d_push( raster, attr & 0x0003FFFF );
1371��
1372��
1373�� normal.x = u2f(*input++);
1374�� normal.y = u2f(*input++);
1375�� normal.pz = u2f(*input++);
1376��
1377��
1378�� transform_vector( &normal, geo->matrix );
1379��
1380�� if ( (attr & 3) != 0 )
1381�� {
1382�� float dotl, dotp, luminance, distance;
1383�� float coef, face;
1384�� INT32 luma;
1385�� texture_parameter * texparam;
1386��
1387��
1388�� point.x = u2f( *input++ );
1389�� point.y = u2f( *input++ );
1390�� point.pz = u2f( *input++ );
1391��
1392��
1393�� transform_point( &point, geo->matrix );
1394��
1395��
1396�� dotl = dot_product( &normal, &geo->light );
1397��
1398��
1399�� dotp = dot_product( &normal, &point );
1400��
1401��
1402�� point.x *= geo->focus.x;
1403�� point.y *= geo->focus.y;
1404��
1405��
1406�� face = 0x100;
1407�� if ( dotp >= 0 ) face = 0;
1408��
1409��
1410�� texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1411��
1412��
1413�� if ( (dotl * dotp) < 0 ) luminance = 0;
1414�� else luminance = fabs( dotl );
1415��
1416�� luminance = (luminance * texparam->diffuse) + texparam->ambient;
1417�� luma = (INT32)luminance;
1418��
1419�� if ( luma > 255 ) luma = 255;
1420�� if ( luma < 0 ) luma = 0;
1421��
1422��
1423�� luma += face;
1424��
1425��
1426�� coef = geo->coef_table[attr>>27];
1427��
1428��
1429�� distance = coef * fabs( dotp ) * geo->lod;
1430��
1431��
1432�� model2_3d_push( raster, luma << 15 );
1433�� model2_3d_push( raster, f2u(distance) >> 8 );
1434�� model2_3d_push( raster, f2u(point.x) >> 8 );
1435�� model2_3d_push( raster, f2u(point.y) >> 8 );
1436�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1437��
1438��
1439�� if ( attr & 1 )
1440�� {
1441��
1442�� point.x = u2f( *input++ );
1443�� point.y = u2f( *input++ );
1444�� point.pz = u2f( *input++ );
1445��
1446��
1447�� transform_point( &point, geo->matrix );
1448��
1449��
1450�� point.x *= geo->focus.x;
1451�� point.y *= geo->focus.y;
1452��
1453��
1454�� model2_3d_push( raster, f2u(point.x) >> 8 );
1455�� model2_3d_push( raster, f2u(point.y) >> 8 );
1456�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1457�� }
1458�� else
1459�� {
1460��
1461�� input += 3;
1462�� }
1463�� }
1464�� else
1465�� {
1466�� break;
1467�� }
1468�� }
1469��
1470��
1471�� model2_3d_push( raster, 0 );
1472��}
1473��
1474��
1475��static void geo_parse_np_s( geo_state *geo, UINT32 *input, UINT32 count )
1476��{
1477�� raster_state *raster = geo->raster;
1478�� poly_vertex point, normal;
1479�� UINT32 attr, i;
1480��
1481��
1482�� point.x = u2f( *input++ );
1483�� point.y = u2f( *input++ );
1484�� point.pz = u2f( *input++ );
1485��
1486��
1487�� transform_point( &point, geo->matrix );
1488��
1489��
1490�� point.x *= geo->focus.x;
1491�� point.y *= geo->focus.y;
1492��
1493��
1494�� model2_3d_push( raster, f2u(point.x) >> 8 );
1495�� model2_3d_push( raster, f2u(point.y) >> 8 );
1496�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1497��
1498��
1499�� point.x = u2f( *input++ );
1500�� point.y = u2f( *input++ );
1501�� point.pz = u2f( *input++ );
1502��
1503��
1504�� transform_point( &point, geo->matrix );
1505��
1506��
1507�� point.x *= geo->focus.x;
1508�� point.y *= geo->focus.y;
1509��
1510��
1511�� model2_3d_push( raster, f2u(point.x) >> 8 );
1512�� model2_3d_push( raster, f2u(point.y) >> 8 );
1513�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1514��
1515��
1516�� for( i = 0; i < count; i++ )
1517�� {
1518��
1519�� attr = *input++;
1520��
1521��
1522�� model2_3d_push( raster, attr & 0x0003FFFF );
1523��
1524��
1525�� normal.x = u2f(*input++);
1526�� normal.y = u2f(*input++);
1527�� normal.pz = u2f(*input++);
1528��
1529��
1530�� transform_vector( &normal, geo->matrix );
1531��
1532�� if ( (attr & 3) != 0 )
1533�� {
1534�� float dotl, dotp, luminance, distance, specular;
1535�� float coef, face;
1536�� INT32 luma;
1537�� texture_parameter * texparam;
1538��
1539��
1540�� point.x = u2f( *input++ );
1541�� point.y = u2f( *input++ );
1542�� point.pz = u2f( *input++ );
1543��
1544��
1545�� transform_point( &point, geo->matrix );
1546��
1547��
1548�� dotl = dot_product( &normal, &geo->light );
1549��
1550��
1551�� dotp = dot_product( &normal, &point );
1552��
1553��
1554�� point.x *= geo->focus.x;
1555�� point.y *= geo->focus.y;
1556��
1557��
1558�� face = 0x100;
1559�� if ( dotp >= 0 ) face = 0;
1560��
1561��
1562�� texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1563��
1564��
1565�� if ( (dotl * dotp) < 0 ) luminance = 0;
1566�� else luminance = fabs( dotl );
1567��
1568�� specular = ((2*dotl) * normal.pz) - geo->light.pz;
1569�� if ( specular < 0 ) specular = 0;
1570�� if ( texparam->specular_control == 0 ) specular = 0;
1571�� if ( (texparam->specular_control >> 1) != 0 ) specular *= specular;
1572�� if ( (texparam->specular_control >> 2) != 0 ) specular *= specular;
1573�� if ( ((texparam->specular_control+1) >> 3) != 0 ) specular *= specular;
1574��
1575�� specular *= texparam->specular_scale;
1576��
1577�� luminance = (luminance * texparam->diffuse) + texparam->ambient + specular;
1578�� luma = (INT32)luminance;
1579��
1580�� if ( luma > 255 ) luma = 255;
1581�� if ( luma < 0 ) luma = 0;
1582��
1583��
1584�� luma += face;
1585��
1586��
1587�� coef = geo->coef_table[attr>>27];
1588��
1589��
1590�� distance = coef * fabs( dotp ) * geo->lod;
1591��
1592��
1593�� model2_3d_push( raster, luma << 15 );
1594�� model2_3d_push( raster, f2u(distance) >> 8 );
1595�� model2_3d_push( raster, f2u(point.x) >> 8 );
1596�� model2_3d_push( raster, f2u(point.y) >> 8 );
1597�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1598��
1599��
1600�� if ( attr & 1 )
1601�� {
1602��
1603�� point.x = u2f( *input++ );
1604�� point.y = u2f( *input++ );
1605�� point.pz = u2f( *input++ );
1606��
1607��
1608�� transform_point( &point, geo->matrix );
1609��
1610��
1611�� point.x *= geo->focus.x;
1612�� point.y *= geo->focus.y;
1613��
1614��
1615�� model2_3d_push( raster, f2u(point.x) >> 8 );
1616�� model2_3d_push( raster, f2u(point.y) >> 8 );
1617�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1618�� }
1619�� else
1620�� {
1621��
1622�� input += 3;
1623�� }
1624�� }
1625�� else
1626�� {
1627�� break;
1628�� }
1629�� }
1630��
1631��
1632�� model2_3d_push( raster, 0 );
1633��}
1634��
1635��
1636��static void geo_parse_nn_ns( geo_state *geo, UINT32 *input, UINT32 count )
1637��{
1638�� raster_state *raster = geo->raster;
1639�� poly_vertex point, normal, p0, p1, p2, p3;
1640�� UINT32 attr, i;
1641��
1642��
1643�� point.x = u2f( *input++ );
1644�� point.y = u2f( *input++ );
1645�� point.pz = u2f( *input++ );
1646��
1647��
1648�� transform_point( &point, geo->matrix );
1649��
1650��
1651�� p0.x = point.x; p0.y = point.y; p0.pz = point.pz;
1652��
1653��
1654�� point.x *= geo->focus.x;
1655�� point.y *= geo->focus.y;
1656��
1657��
1658�� model2_3d_push( raster, f2u(point.x) >> 8 );
1659�� model2_3d_push( raster, f2u(point.y) >> 8 );
1660�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1661��
1662��
1663�� point.x = u2f( *input++ );
1664�� point.y = u2f( *input++ );
1665�� point.pz = u2f( *input++ );
1666��
1667��
1668�� transform_point( &point, geo->matrix );
1669��
1670��
1671�� p1.x = point.x; p1.y = point.y; p1.pz = point.pz;
1672��
1673��
1674�� point.x *= geo->focus.x;
1675�� point.y *= geo->focus.y;
1676��
1677��
1678�� model2_3d_push( raster, f2u(point.x) >> 8 );
1679�� model2_3d_push( raster, f2u(point.y) >> 8 );
1680�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1681��
1682��
1683�� input += 4;
1684��
1685��
1686�� for( i = 0; i < count; i++ )
1687�� {
1688��
1689�� attr = *input++;
1690��
1691��
1692�� model2_3d_push( raster, attr & 0x0003FFFF );
1693��
1694�� if ( (attr & 3) != 0 )
1695�� {
1696�� float dotl, dotp, luminance, distance;
1697�� float coef, face;
1698�� INT32 luma;
1699�� texture_parameter * texparam;
1700��
1701��
1702�� point.x = u2f( *input++ );
1703�� point.y = u2f( *input++ );
1704�� point.pz = u2f( *input++ );
1705��
1706��
1707�� transform_point( &point, geo->matrix );
1708��
1709��
1710�� p2.x = point.x; p2.y = point.y; p2.pz = point.pz;
1711��
1712��
1713�� vector_cross3( &normal, &p0, &p1, &p2 );
1714��
1715��
1716�� normalize_vector( &normal );
1717��
1718��
1719�� dotl = dot_product( &normal, &geo->light );
1720��
1721��
1722�� dotp = dot_product( &normal, &point );
1723��
1724��
1725�� point.x *= geo->focus.x;
1726�� point.y *= geo->focus.y;
1727��
1728��
1729�� face = 0x100;
1730�� if ( dotp >= 0 ) face = 0;
1731��
1732��
1733�� texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1734��
1735��
1736�� if ( (dotl * dotp) < 0 ) luminance = 0;
1737�� else luminance = fabs( dotl );
1738��
1739�� luminance = (luminance * texparam->diffuse) + texparam->ambient;
1740�� luma = (INT32)luminance;
1741��
1742�� if ( luma > 255 ) luma = 255;
1743�� if ( luma < 0 ) luma = 0;
1744��
1745��
1746�� luma += face;
1747��
1748��
1749�� coef = geo->coef_table[attr>>27];
1750��
1751��
1752�� distance = coef * fabs( dotp ) * geo->lod;
1753��
1754��
1755�� model2_3d_push( raster, luma << 15 );
1756�� model2_3d_push( raster, f2u(distance) >> 8 );
1757�� model2_3d_push( raster, f2u(point.x) >> 8 );
1758�� model2_3d_push( raster, f2u(point.y) >> 8 );
1759�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1760��
1761��
1762�� if ( attr & 1 )
1763�� {
1764��
1765�� point.x = u2f( *input++ );
1766�� point.y = u2f( *input++ );
1767�� point.pz = u2f( *input++ );
1768��
1769��
1770�� transform_point( &point, geo->matrix );
1771��
1772��
1773�� p3.x = point.x; p3.y = point.y; p3.pz = point.pz;
1774��
1775��
1776�� point.x *= geo->focus.x;
1777�� point.y *= geo->focus.y;
1778��
1779��
1780�� model2_3d_push( raster, f2u(point.x) >> 8 );
1781�� model2_3d_push( raster, f2u(point.y) >> 8 );
1782�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1783�� }
1784�� else
1785�� {
1786��
1787�� input += 3;
1788��
1789��
1790�� p3.x = p2.x; p3.y = p2.y; p3.pz = p2.pz;
1791�� }
1792�� }
1793�� else
1794�� {
1795�� break;
1796�� }
1797��
1798��
1799�� switch( (attr>>8) & 3 )
1800�� {
1801�� case 0:
1802�� case 2:
1803�� {
1804��
1805�� p0.x = p2.x; p0.y = p2.y; p0.pz = p2.pz;
1806�� p1.x = p3.x; p1.y = p3.y; p1.pz = p3.pz;
1807�� }
1808�� break;
1809��
1810�� case 1:
1811�� {
1812��
1813�� p1.x = p2.x; p1.y = p2.y; p1.pz = p2.pz;
1814�� }
1815�� break;
1816��
1817�� case 3:
1818�� {
1819��
1820�� p0.x = p3.x; p0.y = p3.y; p0.pz = p3.pz;
1821�� }
1822�� break;
1823�� }
1824�� }
1825��
1826��
1827�� model2_3d_push( raster, 0 );
1828��}
1829��
1830��
1831��static void geo_parse_nn_s( geo_state *geo, UINT32 *input, UINT32 count )
1832��{
1833�� raster_state *raster = geo->raster;
1834�� poly_vertex point, normal, p0, p1, p2, p3;
1835�� UINT32 attr, i;
1836��
1837��
1838�� point.x = u2f( *input++ );
1839�� point.y = u2f( *input++ );
1840�� point.pz = u2f( *input++ );
1841��
1842��
1843�� transform_point( &point, geo->matrix );
1844��
1845��
1846�� p0.x = point.x; p0.y = point.y; p0.pz = point.pz;
1847��
1848��
1849�� point.x *= geo->focus.x;
1850�� point.y *= geo->focus.y;
1851��
1852��
1853�� model2_3d_push( raster, f2u(point.x) >> 8 );
1854�� model2_3d_push( raster, f2u(point.y) >> 8 );
1855�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1856��
1857��
1858�� point.x = u2f( *input++ );
1859�� point.y = u2f( *input++ );
1860�� point.pz = u2f( *input++ );
1861��
1862��
1863�� transform_point( &point, geo->matrix );
1864��
1865��
1866�� p1.x = point.x; p1.y = point.y; p1.pz = point.pz;
1867��
1868��
1869�� point.x *= geo->focus.x;
1870�� point.y *= geo->focus.y;
1871��
1872��
1873�� model2_3d_push( raster, f2u(point.x) >> 8 );
1874�� model2_3d_push( raster, f2u(point.y) >> 8 );
1875�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1876��
1877��
1878�� input += 4;
1879��
1880��
1881�� for( i = 0; i < count; i++ )
1882�� {
1883��
1884�� attr = *input++;
1885��
1886��
1887�� model2_3d_push( raster, attr & 0x0003FFFF );
1888��
1889�� if ( (attr & 3) != 0 )
1890�� {
1891�� float dotl, dotp, luminance, distance, specular;
1892�� float coef, face;
1893�� INT32 luma;
1894�� texture_parameter * texparam;
1895��
1896��
1897�� point.x = u2f( *input++ );
1898�� point.y = u2f( *input++ );
1899�� point.pz = u2f( *input++ );
1900��
1901��
1902�� transform_point( &point, geo->matrix );
1903��
1904��
1905�� p2.x = point.x; p2.y = point.y; p2.pz = point.pz;
1906��
1907��
1908�� vector_cross3( &normal, &p0, &p1, &p2 );
1909��
1910��
1911�� normalize_vector( &normal );
1912��
1913��
1914�� dotl = dot_product( &normal, &geo->light );
1915��
1916��
1917�� dotp = dot_product( &normal, &point );
1918��
1919��
1920�� point.x *= geo->focus.x;
1921�� point.y *= geo->focus.y;
1922��
1923��
1924�� face = 0x100;
1925�� if ( dotp >= 0 ) face = 0;
1926��
1927��
1928�� texparam = &geo->texture_parameters[(attr>>18) & 0x1f];
1929��
1930��
1931�� if ( (dotl * dotp) < 0 ) luminance = 0;
1932�� else luminance = fabs( dotl );
1933��
1934�� specular = ((2*dotl) * normal.pz) - geo->light.pz;
1935�� if ( specular < 0 ) specular = 0;
1936�� if ( texparam->specular_control == 0 ) specular = 0;
1937�� if ( (texparam->specular_control >> 1) != 0 ) specular *= specular;
1938�� if ( (texparam->specular_control >> 2) != 0 ) specular *= specular;
1939�� if ( ((texparam->specular_control+1) >> 3) != 0 ) specular *= specular;
1940��
1941�� specular *= texparam->specular_scale;
1942��
1943�� luminance = (luminance * texparam->diffuse) + texparam->ambient + specular;
1944�� luma = (INT32)luminance;
1945��
1946�� if ( luma > 255 ) luma = 255;
1947�� if ( luma < 0 ) luma = 0;
1948��
1949��
1950�� luma += face;
1951��
1952��
1953�� coef = geo->coef_table[attr>>27];
1954��
1955��
1956�� distance = coef * fabs( dotp ) * geo->lod;
1957��
1958��
1959�� model2_3d_push( raster, luma << 15 );
1960�� model2_3d_push( raster, f2u(distance) >> 8 );
1961�� model2_3d_push( raster, f2u(point.x) >> 8 );
1962�� model2_3d_push( raster, f2u(point.y) >> 8 );
1963�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1964��
1965��
1966�� if ( attr & 1 )
1967�� {
1968��
1969�� point.x = u2f( *input++ );
1970�� point.y = u2f( *input++ );
1971�� point.pz = u2f( *input++ );
1972��
1973��
1974�� transform_point( &point, geo->matrix );
1975��
1976��
1977�� p3.x = point.x; p3.y = point.y; p3.pz = point.pz;
1978��
1979��
1980�� point.x *= geo->focus.x;
1981�� point.y *= geo->focus.y;
1982��
1983��
1984�� model2_3d_push( raster, f2u(point.x) >> 8 );
1985�� model2_3d_push( raster, f2u(point.y) >> 8 );
1986�� model2_3d_push( raster, f2u(point.pz) >> 8 );
1987�� }
1988�� else
1989�� {
1990��
1991�� input += 3;
1992��
1993��
1994�� p3.x = p2.x; p3.y = p2.y; p3.pz = p2.pz;
1995�� }
1996�� }
1997�� else
1998�� {
1999�� break;
2000�� }
2001��
2002��
2003�� switch( (attr>>8) & 3 )
2004�� {
2005�� case 0:
2006�� case 2:
2007�� {
2008��
2009�� p0.x = p2.x; p0.y = p2.y; p0.pz = p2.pz;
2010�� p1.x = p3.x; p1.y = p3.y; p1.pz = p3.pz;
2011�� }
2012�� break;
2013��
2014�� case 1:
2015�� {
2016��
2017�� p1.x = p2.x; p1.y = p2.y; p1.pz = p2.pz;
2018�� }
2019�� break;
2020��
2021�� case 3:
2022�� {
2023��
2024�� p0.x = p3.x; p0.y = p3.y; p0.pz = p3.pz;
2025�� }
2026�� break;
2027�� }
2028�� }
2029��
2030��
2031�� model2_3d_push( raster, 0 );
2032��}
2033��
2034��
2039��
2040��
2041��static UINT32 * geo_nop( geo_state *geo, UINT32 opcode, UINT32 *input )
2042��{
2043�� raster_state *raster = geo->raster;
2044��
2045��
2046�� model2_3d_push( raster, opcode >> 23 );
2047��
2048�� return input;
2049��}
2050��
2051��
2052��static UINT32 * geo_object_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2053��{
2054�� raster_state *raster = geo->raster;
2055�� UINT32 tpa = *input++;
2056�� UINT32 tha = *input++;
2057�� UINT32 oba = *input++;
2058�� UINT32 obc = *input++;
2059��
2060�� UINT32 *obp;
2061��
2062��
2063�� model2_3d_push( raster, opcode >> 23 );
2064�� model2_3d_push( raster, tpa );
2065�� model2_3d_push( raster, tha );
2066��
2067��
2068�� if ( oba & 0x01000000 )
2069�� {
2070��
2071�� obp = &geo->polygon_ram0[oba & 0x7FFF];
2072�� }
2073�� else if ( oba & 0x00800000 )
2074�� {
2075��
2076�� obp = &geo->polygon_rom[oba & 0x7FFFFF];
2077�� }
2078�� else
2079�� {
2080��
2081�� obp = &geo->polygon_ram1[oba & 0x7FFF];
2082�� }
2083��
2084�� switch( geo->mode & 3 )
2085�� {
2086��
2087�� case 0: geo_parse_np_ns( geo, obp, obc ); break;
2088��
2089��
2090�� case 1: geo_parse_np_s( geo, obp, obc ); break;
2091��
2092��
2093�� case 2: geo_parse_nn_ns( geo, obp, obc ); break;
2094��
2095��
2096�� case 3: geo_parse_nn_s( geo, obp, obc ); break;
2097�� }
2098��
2099��
2100�� return input;
2101��}
2102��
2103��
2104��static UINT32 * geo_direct_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2105��{
2106�� raster_state *raster = geo->raster;
2107�� UINT32 tpa = *input++;
2108�� UINT32 tha = *input++;
2109�� UINT32 attr;
2110��
2111��
2112�� model2_3d_push( raster, (opcode >> 23) - 1 );
2113�� model2_3d_push( raster, tpa );
2114�� model2_3d_push( raster, tha );
2115��
2116��
2117�� model2_3d_push( raster, (*input++) >> 8 );
2118�� model2_3d_push( raster, (*input++) >> 8 );
2119�� model2_3d_push( raster, (*input++) >> 8 );
2120��
2121�� model2_3d_push( raster, (*input++) >> 8 );
2122�� model2_3d_push( raster, (*input++) >> 8 );
2123�� model2_3d_push( raster, (*input++) >> 8 );
2124��
2125�� do
2126�� {
2127��
2128�� attr = *input++;
2129��
2130�� if ( (attr & 3) == 0 )
2131�� break;
2132��
2133��
2134�� model2_3d_push( raster, attr & 0x00FFFFFF );
2135��
2136��
2137�� model2_3d_push( raster, (*input++) >> 8 );
2138��
2139��
2140�� model2_3d_push( raster, (*input++) >> 8 );
2141��
2142��
2143�� model2_3d_push( raster, (*input++) >> 8 );
2144�� model2_3d_push( raster, (*input++) >> 8 );
2145�� model2_3d_push( raster, (*input++) >> 8 );
2146��
2147��
2148�� if ( attr & 1 )
2149�� {
2150�� model2_3d_push( raster, (*input++) >> 8 );
2151�� model2_3d_push( raster, (*input++) >> 8 );
2152�� model2_3d_push( raster, (*input++) >> 8 );
2153�� }
2154�� } while( 1 );
2155��
2156��
2157�� model2_3d_push( raster, 0 );
2158��
2159�� return input;
2160��}
2161��
2162��
2163��static UINT32 * geo_window_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2164��{
2165�� raster_state *raster = geo->raster;
2166�� UINT32 x, y, i;
2167��
2168��
2169�� model2_3d_push( raster, opcode >> 23 );
2170��
2171��
2180��
2181�� for( i = 0; i < 6; i++ )
2182�� {
2183��
2184�� y = *input++;
2185��
2186��
2187�� x = ( y & 0x0FFF0000 ) >> 4 ;
2188�� y &= 0xFFF;
2189��
2190��
2191�� model2_3d_push( raster, x | y );
2192�� }
2193��
2194�� return input;
2195��}
2196��
2197��
2198��static UINT32 * geo_texture_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2199��{
2200�� raster_state *raster = geo->raster;
2201�� UINT32 i, count;
2202��
2203��
2204�� model2_3d_push( raster, opcode >> 23 );
2205��
2206��
2207�� model2_3d_push( raster, *input++ );
2208��
2209��
2210�� count = *input++;
2211��
2212��
2213�� model2_3d_push( raster, count );
2214��
2215��
2216�� for( i = 0; i < count; i++ )
2217�� model2_3d_push( raster, *input++ );
2218��
2219�� return input;
2220��}
2221��
2222��
2223��static UINT32 * geo_polygon_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2224��{
2225�� UINT32 address, count, i;
2226�� UINT32 *p;
2227��
2228�� (void)opcode;
2229��
2230��
2231�� address = *input++;
2232��
2233��
2234�� if ( address & 0x01000000 )
2235�� {
2236��
2237�� p = &geo->polygon_ram0[address & 0x7FFF];
2238�� }
2239�� else
2240�� {
2241��
2242�� p = &geo->polygon_ram1[address & 0x7FFF];
2243�� }
2244��
2245��
2246�� count = *input++;
2247��
2248��
2249�� for( i = 0; i < count; i++ )
2250�� *p++ = *input++;
2251��
2252�� return input;
2253��}
2254��
2255��
2256��static UINT32 * geo_texture_parameters( geo_state *geo, UINT32 opcode, UINT32 *input )
2257��{
2258�� UINT32 index, count, i, param;
2259��
2260�� (void)opcode;
2261��
2262��
2263�� index = *input++;
2264��
2265��
2266�� count = *input++;
2267��
2268�� for( i = 0; i < count; i++ )
2269�� {
2270��
2271�� param = *input++;
2272��
2273�� geo->texture_parameters[index].diffuse = (float)( param & 0xFF );
2274�� geo->texture_parameters[index].ambient = (float)( (param >> 8) & 0xFF );
2275�� geo->texture_parameters[index].specular_control = (param >> 24) & 0xFF;
2276�� geo->texture_parameters[index].specular_scale = (float)( (param >> 16) & 0xFF );
2277��
2278��
2279�� geo->coef_table[index] = u2f(*input++);
2280��
2281�� index = (index + 1) & 0x1F;
2282�� }
2283��
2284�� return input;
2285��}
2286��
2287��
2288��static UINT32 * geo_mode( geo_state *geo, UINT32 opcode, UINT32 *input )
2289��{
2290�� (void)opcode;
2291��
2292��
2293�� geo->mode = *input++;
2294��
2295�� return input;
2296��}
2297��
2298��
2299��static UINT32 * geo_zsort_mode( geo_state *geo, UINT32 opcode, UINT32 *input )
2300��{
2301�� raster_state *raster = geo->raster;
2302��
2303��
2304�� model2_3d_push( raster, opcode >> 23 );
2305��
2306��
2307�� model2_3d_push( raster, (*input++) >> 8 );
2308��
2309�� return input;
2310��}
2311��
2312��
2313��static UINT32 * geo_focal_distance( geo_state *geo, UINT32 opcode, UINT32 *input )
2314��{
2315�� (void)opcode;
2316��
2317��
2318�� geo->focus.x = u2f( *input++ );
2319��
2320��
2321�� geo->focus.y = u2f( *input++ );
2322��
2323�� return input;
2324��}
2325��
2326��
2327��static UINT32 * geo_light_source( geo_state *geo, UINT32 opcode, UINT32 *input )
2328��{
2329�� (void)opcode;
2330��
2331��
2332�� geo->light.x = u2f( *input++ );
2333��
2334��
2335�� geo->light.y = u2f( *input++ );
2336��
2337��
2338�� geo->light.pz = u2f( *input++ );
2339��
2340�� return input;
2341��}
2342��
2343��
2344��static UINT32 * geo_matrix_write( geo_state *geo, UINT32 opcode, UINT32 *input )
2345��{
2346�� UINT32 i;
2347��
2348�� (void)opcode;
2349��
2350��
2351�� for( i = 0; i < 12; i++ )
2352�� geo->matrix[i] = u2f( *input++ );
2353��
2354�� return input;
2355��}
2356��
2357��
2358��static UINT32 * geo_translate_write( geo_state *geo, UINT32 opcode, UINT32 *input )
2359��{
2360�� UINT32 i;
2361��
2362�� (void)opcode;
2363��
2364��
2365�� for( i = 0; i < 3; i++ )
2366�� geo->matrix[i+9] = u2f( *input++ );
2367��
2368�� return input;
2369��}
2370��
2371��
2372��static UINT32 * geo_data_mem_push( geo_state *geo, UINT32 opcode, UINT32 *input )
2373��{
2374�� UINT32 address, count, i;
2375��
2376��
2387��
2388��
2389�� (void)opcode;
2390��
2391��
2392�� address = *input++;
2393��
2394��
2395�� count = *input++;
2396��
2397�� logerror( "SEGA GEO: Executing unsupported geo_data_mem_push (address = %08x, count = %08x)\n", address, count );
2398��
2399�� (void)i;
2400��
2404��
2405�� return input;
2406��}
2407��
2408��
2409��static UINT32 * geo_test( geo_state *geo, UINT32 opcode, UINT32 *input )
2410��{
2411�� UINT32 data, blocks, address, count, checksum, i;
2412��
2413�� (void)opcode;
2414��
2415��
2416�� data = 1;
2417��
2418�� for( i = 0; i < 32; i++ )
2419�� {
2420�� if ( *input++ != data )
2421�� {
2422��
2423�� logerror( "SEGA GEO: FIFO Test failed\n" );
2424�� }
2425��
2426�� data <<= 1;
2427�� }
2428��
2429��
2430�� blocks = *input++;
2431��
2432�� for( i = 0; i < blocks; i++ )
2433�� {
2434�� UINT32 sum_even, sum_odd, j;
2435��
2436��
2437�� address = (*input++) & 0x7FFFFF;
2438��
2439��
2440�� count = *input++;
2441��
2442��
2443�� checksum = *input++;
2444��
2445��
2446�� sum_even = 0;
2447�� sum_odd = 0;
2448��
2449�� for( j = 0; j < count; j++ )
2450�� {
2451�� data = geo->polygon_rom[address++];
2452��
2453�� address &= 0x7FFFFF;
2454��
2455�� sum_even += data >> 16;
2456�� sum_even &= 0xFFFF;
2457��
2458�� sum_odd += data & 0xFFFF;
2459�� sum_odd &= 0xFFFF;
2460�� }
2461��
2462�� sum_even += checksum >> 16;
2463�� sum_even &= 0xFFFF;
2464��
2465�� sum_odd += checksum & 0xFFFF;
2466�� sum_odd &= 0xFFFF;
2467��
2468�� if ( sum_even != 0 || sum_odd != 0 )
2469�� {
2470��
2471�� logerror( "SEGA GEO: Polygon ROM Test failed\n" );
2472�� }
2473�� }
2474��
2475�� return input;
2476��}
2477��
2478��
2479��static UINT32 * geo_end( geo_state *geo, UINT32 opcode, UINT32 *input )
2480��{
2481�� raster_state *raster = geo->raster;
2482��
2483�� (void)opcode;
2484��
2485��
2486�� model2_3d_push( raster, 0xFF000000 );
2487��
2488��
2489�� return NULL;
2490��}
2491��
2492��
2493��static UINT32 * geo_dummy( geo_state *geo, UINT32 opcode, UINT32 *input )
2494��{
2495��
2496�� (void)opcode;
2497��
2498��
2499��
2500�� input++;
2501��
2502�� return input;
2503��}
2504��
2505��
2506��static UINT32 * geo_log_data( geo_state *geo, UINT32 opcode, UINT32 *input )
2507��{
2508�� raster_state *raster = geo->raster;
2509�� UINT32 i, count;
2510��
2511��
2512�� model2_3d_push( raster, opcode >> 23 );
2513��
2514��
2515�� model2_3d_push( raster, *input++ );
2516��
2517��
2518�� count = *input++;
2519��
2520��
2521�� model2_3d_push( raster, count << 2 );
2522��
2523��
2524�� for( i = 0; i < count; i++ )
2525�� {
2526�� UINT32 data = *input++;
2527��
2528�� model2_3d_push( raster, data & 0xff );
2529�� model2_3d_push( raster, (data >> 8) & 0xff );
2530�� model2_3d_push( raster, (data >> 16) & 0xff );
2531�� model2_3d_push( raster, (data >> 24) & 0xff );
2532�� }
2533��
2534�� return input;
2535��}
2536��
2537��
2538��static UINT32 * geo_lod( geo_state *geo, UINT32 opcode, UINT32 *input )
2539��{
2540�� (void)opcode;
2541��
2542��
2543�� geo->lod = u2f(*input++);
2544��
2545�� return input;
2546��}
2547��
2548��
2549��static UINT32 * geo_code_upload( geo_state *geo, UINT32 opcode, UINT32 *input )
2550��{
2551�� UINT32 count, i;
2552��
2553��
2559��
2560�� logerror( "SEGA GEO: Uploading debug code (unimplemented)\n" );
2561��
2562�� (void)opcode;
2563��
2564��
2565��
2566�� input++;
2567��
2568��
2569�� count = *input++;
2570��
2571�� for( i = 0; i < count; i++ )
2572�� {
2573�� UINT64 code;
2574��
2575��
2576�� code = *input++;
2577��
2578�� code <<= 32;
2579��
2580��
2581�� code |= *input++;
2582�� code |= (*input++) << 16;
2583�� }
2584��
2585��
2588��
2589��
2593��
2594�� return input;
2595��}
2596��
2597��
2598��static UINT32 * geo_code_jump( geo_state *geo, UINT32 opcode, UINT32 *input )
2599��{
2600��
2601��
2602��
2609��
2610�� logerror( "SEGA GEO: Jumping to debug code (unimplemented)\n" );
2611��
2612�� (void)opcode;
2613��
2614��
2615�� input++;
2616��
2617��
2620�� return input;
2621��}
2622��
2623��static UINT32 * geo_process_command( geo_state *geo, UINT32 opcode, UINT32 *input )
2624��{
2625�� switch( opcode >> 23 )
2626�� {
2627�� case 0x00: input = geo_nop( geo, opcode, input ); break;
2628�� case 0x01: input = geo_object_data( geo, opcode, input ); break;
2629�� case 0x02: input = geo_direct_data( geo, opcode, input ); break;
2630�� case 0x03: input = geo_window_data( geo, opcode, input ); break;
2631�� case 0x04: input = geo_texture_data( geo, opcode, input ); break;
2632�� case 0x05: input = geo_polygon_data( geo, opcode, input ); break;
2633�� case 0x06: input = geo_texture_parameters( geo, opcode, input ); break;
2634�� case 0x07: input = geo_mode( geo, opcode, input ); break;
2635�� case 0x08: input = geo_zsort_mode( geo, opcode, input ); break;
2636�� case 0x09: input = geo_focal_distance( geo, opcode, input ); break;
2637�� case 0x0A: input = geo_light_source( geo, opcode, input ); break;
2638�� case 0x0B: input = geo_matrix_write( geo, opcode, input ); break;
2639�� case 0x0C: input = geo_translate_write( geo, opcode, input ); break;
2640�� case 0x0D: input = geo_data_mem_push( geo, opcode, input ); break;
2641�� case 0x0E: input = geo_test( geo, opcode, input ); break;
2642�� case 0x0F: input = geo_end( geo, opcode, input ); break;
2643�� case 0x10: input = geo_dummy( geo, opcode, input ); break;
2644�� case 0x11: input = geo_object_data( geo, opcode, input ); break;
2645�� case 0x12: input = geo_direct_data( geo, opcode, input ); break;
2646�� case 0x13: input = geo_window_data( geo, opcode, input ); break;
2647�� case 0x14: input = geo_log_data( geo, opcode, input ); break;
2648�� case 0x15: input = geo_polygon_data( geo, opcode, input ); break;
2649�� case 0x16: input = geo_lod( geo, opcode, input ); break;
2650�� case 0x17: input = geo_mode( geo, opcode, input ); break;
2651�� case 0x18: input = geo_zsort_mode( geo, opcode, input ); break;
2652�� case 0x19: input = geo_focal_distance( geo, opcode, input ); break;
2653�� case 0x1A: input = geo_light_source( geo, opcode, input ); break;
2654�� case 0x1B: input = geo_matrix_write( geo, opcode, input ); break;
2655�� case 0x1C: input = geo_translate_write( geo, opcode, input ); break;
2656�� case 0x1D: input = geo_code_upload( geo, opcode, input ); break;
2657�� case 0x1E: input = geo_code_jump( geo, opcode, input ); break;
2658�� case 0x1F: input = geo_end( geo, opcode, input ); break;
2659�� }
2660��
2661�� return input;
2662��}
2663��
2664��static void geo_parse( model2_state *state )
2665��{
2666�� UINT32 address = (state->m_geo_read_start_address/4);
2667�� UINT32 *input = &state->m_bufferram[address];
2668�� UINT32 opcode;
2669��
2670�� while( input != NULL && (input - state->m_bufferram) < 0x20000 )
2671�� {
2672��
2673�� opcode = *input++;
2674��
2675��
2676�� if ( opcode & 0x80000000 )
2677�� {
2678��
2679�� address = (opcode & 0x7FFFF) / 4;
2680��
2681��
2682�� input = &state->m_bufferram[address];
2683��
2684��
2685�� continue;
2686�� }
2687��
2688��
2689�� input = geo_process_command( state->m_geo, opcode, input );
2690�� }
2691��}
2692��
2693��
2694��
2695��
2696��static void model2_exit(running_machine &machine)
2697��{
2698�� model2_state *state = machine.driver_data<model2_state>();
2699�� poly_free(state->m_poly);
2700��}
2701��
2702��VIDEO_START_MEMBER(model2_state,model2)
2703��{
2704�� const rectangle &visarea = machine().primary_screen->visible_area();
2705�� int width = visarea.width();
2706�� int height = visarea.height();
2707��
2708�� m_sys24_bitmap.allocate(width, height+4);
2709��
2710�� m_poly = poly_alloc(machine(), 4000, sizeof(poly_extra_data), 0);
2711�� machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model2_exit), &machine()));
2712��
2713��
2714�� model2_3d_init( machine(), (UINT16*)memregion("user3")->base() );
2715��
2716��
2717�� geo_init( machine(), (UINT32*)memregion("user2")->base() );
2718��}
2719��
2720��UINT32 model2_state::screen_update_model2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
2721��{
2722�� logerror("--- frame ---\n");
2723��
2724�� bitmap.fill(machine().pens[0], cliprect);
2725�� m_sys24_bitmap.fill(0, cliprect);
2726��
2727�� segas24_tile *tile = machine().device<segas24_tile>("tile");
2728�� tile->draw(m_sys24_bitmap, cliprect, 7, 0, 0);
2729�� tile->draw(m_sys24_bitmap, cliprect, 6, 0, 0);
2730�� tile->draw(m_sys24_bitmap, cliprect, 5, 0, 0);
2731�� tile->draw(m_sys24_bitmap, cliprect, 4, 0, 0);
2732��
2733�� copybitmap_trans(bitmap, m_sys24_bitmap, 0, 0, 0, 0, cliprect, 0);
2734��
2735��
2736�� model2_3d_frame_start(this);
2737��
2738��
2739�� geo_parse(this);
2740��
2741��
2742�� model2_3d_frame_end( this, bitmap, cliprect );
2743��
2744�� m_sys24_bitmap.fill(0, cliprect);
2745�� tile->draw(m_sys24_bitmap, cliprect, 3, 0, 0);
2746�� tile->draw(m_sys24_bitmap, cliprect, 2, 0, 0);
2747�� tile->draw(m_sys24_bitmap, cliprect, 1, 0, 0);
2748�� tile->draw(m_sys24_bitmap, cliprect, 0, 0, 0);
2749��
2750�� copybitmap_trans(bitmap, m_sys24_bitmap, 0, 0, 0, 0, cliprect, 0);
2751��
2752�� return 0;
2753��}
2754��