Previous 199869 Revisions Next

r32674 Sunday 12th October, 2014 at 00:28:50 UTC by Ville Linde
model3: New 3D renderer + various fixes (still heavily WIP) [Ville Linde]
[src/mame]mame.mak
[src/mame/drivers]model3.c
[src/mame/includes]model3.h
[src/mame/machine]model3.c
[src/mame/video]m3raster.inc model3.c

trunk/src/mame/machine/model3.c
r32673r32674
148148   switch (m_tap_state)
149149   {
150150   case 3:     // Capture-DR
151      //printf("capture dr (IR = %08X%08X\n", (UINT32)(m_ir >> 32),(UINT32)(m_ir));
151152
152      /*
153       * Read ASIC IDs.
154       *
155       * The ID Sequence is:
156       *  - Jupiter
157       *  - Mercury
158       *  - Venus
159       *  - Earth
160       *  - Mars
161       *  - Mars (again)
162       *
163       * Note that different Model 3 steps have different chip
164       * revisions, hence the different IDs returned below.
165       *
166       * On Step 1.5 and 1.0, instruction 0x0C631F8C7FFE is used to retrieve
167       * the ID codes but Step 2.0 is a little weirder. It seems to use this
168       * and either the state of the TAP after reset or other instructions
169       * to read the IDs as well. This can be emulated in one of 2 ways:
170       * Ignore the instruction and always load up the data or load the
171       * data on TAP reset and when the instruction is issued.
172       */
153      if (m_ir == U64(0x000023fffffffffe))
154      {
155         for (int i=0; i < 32; i++)
156         {
157            m_id_data[i] = 0;
158         }
173159
174      if (m_m3_step == 0x10)
175      {
176         insert_id(0x116C7057, 1 + 0 * 32);
177         insert_id(0x216C3057, 1 + 1 * 32);
178         insert_id(0x116C4057, 1 + 2 * 32);
179         insert_id(0x216C5057, 1 + 3 * 32);
180         insert_id(0x116C6057, 1 + 4 * 32 + 1);
181         insert_id(0x116C6057, 1 + 5 * 32 + 1);
160         m_id_size = 41;
161
162         UINT64 res = 0x0040000000;
163
164         int start_bit = 0;
165         for (int i = 41; i >= 0; i--)
166            insert_bit(m_id_data, start_bit++, ((UINT64)(1 << i) & res) ? 1 : 0);
182167      }
183      else if (m_m3_step == 0x15)
168      else if (m_ir == U64(0x00000c631f8c7ffe))
184169      {
185         insert_id(0x316C7057, 1 + 0 * 32);
186         insert_id(0x316C3057, 1 + 1 * 32);
187         insert_id(0x216C4057, 1 + 2 * 32);      // Lost World may to use 0x016C4057
188         insert_id(0x316C5057, 1 + 3 * 32);
189         insert_id(0x216C6057, 1 + 4 * 32 + 1);
190         insert_id(0x216C6057, 1 + 5 * 32 + 1);
170         tap_set_asic_ids();
191171      }
192      else if (m_m3_step >= 0x20)
193      {
194         insert_id(0x416C7057, 1 + 0 * 32);
195         insert_id(0x416C3057, 1 + 1 * 32);
196         insert_id(0x316C4057, 1 + 2 * 32);
197         insert_id(0x416C5057, 1 + 3 * 32);
198         insert_id(0x316C6057, 1 + 4 * 32 + 1);
199         insert_id(0x316C6057, 1 + 5 * 32 + 1);
200      }
201
202172      break;
203173
204174   case 4:     // Shift-DR
r32673r32674
241211   }
242212}
243213
214void model3_state::tap_set_asic_ids()
215{
216   /*
217    * Read ASIC IDs.
218    *
219    * The ID Sequence is:
220    *  - Jupiter
221    *  - Mercury
222    *  - Venus
223    *  - Earth
224    *  - Mars
225    *  - Mars (again)
226    *
227    * Note that different Model 3 steps have different chip
228    * revisions, hence the different IDs returned below.
229    *
230    * On Step 1.5 and 1.0, instruction 0x0C631F8C7FFE is used to retrieve
231    * the ID codes but Step 2.0 is a little weirder. It seems to use this
232    * and either the state of the TAP after reset or other instructions
233    * to read the IDs as well. This can be emulated in one of 2 ways:
234    * Ignore the instruction and always load up the data or load the
235    * data on TAP reset and when the instruction is issued.
236    */
244237
238   for (int i=0; i < 32; i++)
239   {
240      m_id_data[i] = 0;
241   }
242
243   if (m_m3_step == 0x10)
244   {
245      insert_id(0x116C7057, 1 + 0 * 32);
246      insert_id(0x216C3057, 1 + 1 * 32);
247      insert_id(0x116C4057, 1 + 2 * 32);
248      insert_id(0x216C5057, 1 + 3 * 32);
249      insert_id(0x116C6057, 1 + 4 * 32 + 1);
250      insert_id(0x116C6057, 1 + 5 * 32 + 1);
251   }
252   else if (m_m3_step == 0x15)
253   {
254      insert_id(0x316C7057, 1 + 0 * 32);
255      insert_id(0x316C3057, 1 + 1 * 32);
256      insert_id(0x216C4057, 1 + 2 * 32);      // Lost World may to use 0x016C4057
257      insert_id(0x316C5057, 1 + 3 * 32);
258      insert_id(0x216C6057, 1 + 4 * 32 + 1);
259      insert_id(0x216C6057, 1 + 5 * 32 + 1);
260   }
261   else if (m_m3_step >= 0x20)
262   {
263      insert_id(0x416C7057, 1 + 0 * 32);
264      insert_id(0x416C3057, 1 + 1 * 32);
265      insert_id(0x316C4057, 1 + 2 * 32);
266      insert_id(0x416C5057, 1 + 3 * 32);
267      insert_id(0x316C6057, 1 + 4 * 32 + 1);
268      insert_id(0x316C6057, 1 + 5 * 32 + 1);
269   }
270
271   m_id_size = 197;  // 197 bits
272}
273
274
245275/*
246276 * void tap_reset(void);
247277 *
r32673r32674
250280
251281void model3_state::tap_reset()
252282{
253   m_id_size = 197;  // 197 bits
254283   m_tap_state = 0;  // test-logic/reset
284
285   tap_set_asic_ids();
255286}
256287
257288/*****************************************************************************/
trunk/src/mame/includes/model3.h
r32673r32674
1#include "video/polylgcy.h"
1#include "video/poly.h"
22#include "bus/scsi/scsi.h"
33#include "machine/53c810.h"
44#include "audio/dsbz80.h"
r32673r32674
99typedef float VECTOR[4];
1010typedef float VECTOR3[3];
1111
12struct PLANE {
13   float x,y,z,d;
12struct cached_texture
13{
14   cached_texture *next;
15   UINT8       width;
16   UINT8       height;
17   UINT8       format;
18   UINT8       alpha;
19   rgb_t       data[1];
1420};
1521
16struct cached_texture;
22struct m3_plane
23{
24   float x;
25   float y;
26   float z;
27   float d;
28};
1729
30struct m3_vertex
31{
32   float x;
33   float y;
34   float z;
35   float u;
36   float v;
37   float nx;
38   float ny;
39   float nz;
40};
41
42struct m3_clip_vertex
43{
44   float x;
45   float y;
46   float z;
47   float u;
48   float v;
49   float i;
50};
51
52struct m3_triangle
53{
54   m3_clip_vertex v[3];
55
56   cached_texture *texture;
57   int param;
58   int transparency;
59   int intensity;
60   int color;
61};
62
63class model3_renderer;
64
1865class model3_state : public driver_device
1966{
2067public:
r32673r32674
3178      m_dsbz80(*this, DSBZ80_TAG),
3279      m_soundram(*this, "soundram"),
3380      m_gfxdecode(*this, "gfxdecode"),
34      m_palette(*this, "palette") { }
35
36   struct TRIANGLE
81      m_palette(*this, "palette")
3782   {
38      poly_vertex v[3];
39      UINT8 texture_x, texture_y;
40      UINT8 texture_width, texture_height;
41      UINT8 transparency;
42      UINT8 texture_format, param;
43      int intensity;
44      UINT32 color;
45   };
83      m_step15_with_mpc106 = false;
84      m_step20_with_old_real3d = false;
85   }
4686
4787   required_device<cpu_device> m_maincpu;
4888   optional_device<lsi53c810_device> m_lsi53c810;
r32673r32674
5494   required_shared_ptr<UINT64> m_work_ram;
5595   required_shared_ptr<UINT64> m_paletteram64;
5696   optional_device<dsbz80_device> m_dsbz80;    // Z80-based MPEG Digital Sound Board
57   required_shared_ptr<UINT16> m_soundram;
97   required_shared_ptr<UINT16> m_soundram;   
5898
5999   required_device<gfxdecode_device> m_gfxdecode;
60100   required_device<palette_device> m_palette;
r32673r32674
69109   UINT8 m_scsi_irq_state;
70110   int m_crom_bank;
71111   int m_controls_bank;
112   bool m_step15_with_mpc106;
113   bool m_step20_with_old_real3d;
72114   UINT32 m_real3d_device_id;
73   UINT32 m_mpc105_regs[0x40];
74   UINT32 m_mpc105_addr;
75115   int m_pci_bus;
76116   int m_pci_device;
77117   int m_pci_function;
78118   int m_pci_reg;
119   UINT32 m_mpc105_regs[0x40];
120   UINT32 m_mpc105_addr;
79121   UINT32 m_mpc106_regs[0x40];
80122   UINT32 m_mpc106_addr;
81123   UINT32 m_dma_data;
r32673r32674
117159   UINT32 *m_culling_ram;
118160   UINT32 *m_polygon_ram;
119161   int m_real3d_display_list;
120   bitmap_rgb32 m_bitmap3d;
121   bitmap_ind32 m_zbuffer;
122162   rectangle m_clip3d;
123163   rectangle *m_screen_clip;
124164   VECTOR3 m_parallel_light;
125165   float m_parallel_light_intensity;
126166   float m_ambient_light_intensity;
127   legacy_poly_manager *m_poly;
128   int m_list_depth;
129   int m_tick;
130   int m_debug_layer_disable;
131167   UINT64 m_vid_reg0;
132168   int m_matrix_stack_ptr;
169   int m_list_depth;
133170   MATRIX *m_matrix_stack;
134171   MATRIX m_coordinate_system;
135172   float m_viewport_focal_length;
r32673r32674
137174   int m_viewport_region_y;
138175   int m_viewport_region_width;
139176   int m_viewport_region_height;
140   PLANE m_clip_plane[5];
177   m3_plane m_clip_plane[5];
141178   UINT32 m_matrix_base_address;
142179   cached_texture *m_texcache[2][1024/32][2048/32];
143180
181   model3_renderer *m_renderer;
182
144183   DECLARE_READ32_MEMBER(rtc72421_r);
145184   DECLARE_WRITE32_MEMBER(rtc72421_w);
146185   DECLARE_READ64_MEMBER(model3_char_r);
r32673r32674
219258   DECLARE_DRIVER_INIT(dayto2pe);
220259   DECLARE_DRIVER_INIT(spikeout);
221260   DECLARE_DRIVER_INIT(magtruck);
222   DECLARE_DRIVER_INIT(model3_15);
223   virtual void video_start();
261   DECLARE_DRIVER_INIT(lamachin);
262   DECLARE_DRIVER_INIT(model3_15);   
224263   DECLARE_MACHINE_START(model3_10);
225264   DECLARE_MACHINE_RESET(model3_10);
226265   DECLARE_MACHINE_START(model3_15);
r32673r32674
229268   DECLARE_MACHINE_RESET(model3_20);
230269   DECLARE_MACHINE_START(model3_21);
231270   DECLARE_MACHINE_RESET(model3_21);
232   UINT32 screen_update_model3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
233271   TIMER_CALLBACK_MEMBER(model3_sound_timer_tick);
234272   TIMER_DEVICE_CALLBACK_MEMBER(model3_interrupt);
235273   void model3_exit();
r32673r32674
241279   void set_irq_line(UINT8 bit, int line);
242280   void model3_init(int step);
243281   // video
282   virtual void video_start();
283   UINT32 screen_update_model3(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
244284   TILE_GET_INFO_MEMBER(tile_info_layer0_4bit);
245285   TILE_GET_INFO_MEMBER(tile_info_layer1_4bit);
246286   TILE_GET_INFO_MEMBER(tile_info_layer2_4bit);
r32673r32674
262302   void pop_matrix_stack();
263303   void multiply_matrix_stack(MATRIX matrix);
264304   void translate_matrix_stack(float x, float y, float z);
265   void render_one(TRIANGLE *tri);
266305   void draw_model(UINT32 addr);
267306   UINT32 *get_memory_pointer(UINT32 address);
268307   void load_matrix(int matrix_num, MATRIX *out);
r32673r32674
272311   void draw_block(UINT32 address);
273312   void draw_viewport(int pri, UINT32 address);
274313   void real3d_traverse_display_list();
275#ifdef UNUSED_FUNCTION
276   inline void write_texture8(int xpos, int ypos, int width, int height, int page, UINT16 *data);
277   void draw_texture_sheet(bitmap_ind16 &bitmap, const rectangle &cliprect);
278   void copy_screen(bitmap_ind16 &bitmap, const rectangle &cliprect);
279#endif
280314   void real3d_display_list_end();
281315   void real3d_display_list1_dma(UINT32 src, UINT32 dst, int length, int byteswap);
282316   void real3d_display_list2_dma(UINT32 src, UINT32 dst, int length, int byteswap);
r32673r32674
288322   int tap_read();
289323   void tap_write(int tck, int tms, int tdi, int trst);
290324   void tap_reset();
325   void tap_set_asic_ids();
291326};
trunk/src/mame/mame.mak
r32673r32674
29432943$(VIDEO)/model1.o: $(MAMESRC)/includes/model1.h $(MAMESRC)/audio/dsbz80.h
29442944$(MACHINE)/model1.o: $(MAMESRC)/includes/model1.h $(MAMESRC)/audio/dsbz80.h
29452945$(VIDEO)/model2.o:  $(MAMESRC)/video/model2rd.inc
2946$(VIDEO)/model3.o:  $(MAMESRC)/video/m3raster.inc
29472946$(VIDEO)/n64.o:     $(MAMESRC)/video/rdpfiltr.inc
29482947$(DRIVERS)/bfm_sc4.o: $(MAMESRC)/includes/bfm_sc45.h
29492948$(DRIVERS)/bfm_sc5.o: $(MAMESRC)/includes/bfm_sc45.h
trunk/src/mame/video/m3raster.inc
r32673r32674
1static void draw_scanline_normal(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
2{
3   const poly_extra_data *extra = (const poly_extra_data *)extradata;
4   const cached_texture *texture = extra->texture;
5   bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest;
6   UINT32 *p = &destmap->pix32(scanline);
7   UINT32 *d = &extra->zbuffer->pix32(scanline);
8   float ooz = extent->param[0].start;
9   float uoz = extent->param[1].start;
10   float voz = extent->param[2].start;
11   float doozdx = extent->param[0].dpdx;
12   float duozdx = extent->param[1].dpdx;
13   float dvozdx = extent->param[2].dpdx;
14   UINT32 polyi = extra->polygon_intensity;
15   UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
16   UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
17   UINT32 width = 6 + texture->width;
18   int x;
19
20   for (x = extent->startx; x < extent->stopx; x++)
21   {
22      UINT32 iz = ooz * 256.0f;
23      if (iz > d[x])
24      {
25         float z = 1.0f / ooz;
26         UINT32 u = uoz * z;
27         UINT32 v = voz * z;
28         UINT32 u1 = (u >> 8) & umask;
29         UINT32 v1 = (v >> 8) & vmask;
30         UINT32 u2 = (u1 + 1) & umask;
31         UINT32 v2 = (v1 + 1) & vmask;
32         UINT32 pix00 = texture->data[(v1 << width) + u1];
33         UINT32 pix01 = texture->data[(v1 << width) + u2];
34         UINT32 pix10 = texture->data[(v2 << width) + u1];
35         UINT32 pix11 = texture->data[(v2 << width) + u2];
36         UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
37         UINT32 fr = ((texel & 0x00ff0000) * polyi) >> 8;
38         UINT32 fg = ((texel & 0x0000ff00) * polyi) >> 8;
39         UINT32 fb = ((texel & 0x000000ff) * polyi) >> 8;
40         p[x] = 0xff000000 | (fr & 0xff0000) | (fg & 0xff00) | (fb & 0xff);
41         d[x] = iz;
42      }
43
44      ooz += doozdx;
45      uoz += duozdx;
46      voz += dvozdx;
47   }
48}
49
50static void draw_scanline_trans(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
51{
52   const poly_extra_data *extra = (const poly_extra_data *)extradata;
53   const cached_texture *texture = extra->texture;
54   bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest;
55   UINT32 *p = &destmap->pix32(scanline);
56   UINT32 *d = &extra->zbuffer->pix32(scanline);
57   float ooz = extent->param[0].start;
58   float uoz = extent->param[1].start;
59   float voz = extent->param[2].start;
60   float doozdx = extent->param[0].dpdx;
61   float duozdx = extent->param[1].dpdx;
62   float dvozdx = extent->param[2].dpdx;
63   UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
64   int desttrans = 32 - extra->polygon_transparency;
65   UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
66   UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
67   UINT32 width = 6 + texture->width;
68   int x;
69
70   for (x = extent->startx; x < extent->stopx; x++)
71   {
72      UINT32 iz = ooz * 256.0f;
73      if (iz > d[x])
74      {
75         float z = 1.0f / ooz;
76         UINT32 u = uoz * z;
77         UINT32 v = voz * z;
78         UINT32 u1 = (u >> 8) & umask;
79         UINT32 v1 = (v >> 8) & vmask;
80         UINT32 u2 = (u1 + 1) & umask;
81         UINT32 v2 = (v1 + 1) & vmask;
82         UINT32 pix00 = texture->data[(v1 << width) + u1];
83         UINT32 pix01 = texture->data[(v1 << width) + u2];
84         UINT32 pix10 = texture->data[(v2 << width) + u1];
85         UINT32 pix11 = texture->data[(v2 << width) + u2];
86         UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
87         UINT32 fr = ((texel & 0x00ff0000) * polyi) >> 8;
88         UINT32 fg = ((texel & 0x0000ff00) * polyi) >> 8;
89         UINT32 fb = ((texel & 0x000000ff) * polyi) >> 8;
90         UINT32 orig = p[x];
91         fr += ((orig & 0x00ff0000) * desttrans) >> 5;
92         fg += ((orig & 0x0000ff00) * desttrans) >> 5;
93         fb += ((orig & 0x000000ff) * desttrans) >> 5;
94         p[x] = 0xff000000 | (fr & 0xff0000) | (fg & 0xff00) | (fb & 0xff);
95         d[x] = iz;
96      }
97
98      ooz += doozdx;
99      uoz += duozdx;
100      voz += dvozdx;
101   }
102}
103
104
105static void draw_scanline_alpha(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
106{
107   const poly_extra_data *extra = (const poly_extra_data *)extradata;
108   const cached_texture *texture = extra->texture;
109   bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest;
110   UINT32 *p = &destmap->pix32(scanline);
111   UINT32 *d = &extra->zbuffer->pix32(scanline);
112   float ooz = extent->param[0].start;
113   float uoz = extent->param[1].start;
114   float voz = extent->param[2].start;
115   float doozdx = extent->param[0].dpdx;
116   float duozdx = extent->param[1].dpdx;
117   float dvozdx = extent->param[2].dpdx;
118   UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
119   int desttrans = 32 - extra->polygon_transparency;
120   UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
121   UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
122   UINT32 width = 6 + texture->width;
123   int x;
124
125   for (x = extent->startx; x < extent->stopx; x++)
126   {
127      UINT32 iz = ooz * 256.0f;
128      if (iz > d[x])
129      {
130         float z = 1.0f / ooz;
131         UINT32 u = uoz * z;
132         UINT32 v = voz * z;
133         UINT32 u1 = (u >> 8) & umask;
134         UINT32 v1 = (v >> 8) & vmask;
135         UINT32 u2 = (u1 + 1) & umask;
136         UINT32 v2 = (v1 + 1) & vmask;
137         UINT32 pix00 = texture->data[(v1 << width) + u1];
138         UINT32 pix01 = texture->data[(v1 << width) + u2];
139         UINT32 pix10 = texture->data[(v2 << width) + u1];
140         UINT32 pix11 = texture->data[(v2 << width) + u2];
141         UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
142         UINT32 fa = texel >> 24;
143         if (fa != 0)
144         {
145            UINT32 combined = ((fa + 1) * polyi) >> 8;
146            UINT32 fr = ((texel & 0x00ff0000) * combined) >> (8+9);
147            UINT32 fg = ((texel & 0x0000ff00) * combined) >> (8+6);
148            UINT32 fb = ((texel & 0x000000ff) * combined) >> (8+3);
149            UINT32 orig = p[x];
150            combined = ((255 - fa) * desttrans) >> 5;
151            fr += ((orig & 0x00ff0000) * combined) >> 8;
152            fg += ((orig & 0x0000ff00) * combined) >> 8;
153            fb += ((orig & 0x000000ff) * combined) >> 8;
154            p[x] = 0xff000000 | (fr & 0xff0000) | (fg & 0xff00) | (fb & 0xff);
155            d[x] = iz;
156         }
157      }
158
159      ooz += doozdx;
160      uoz += duozdx;
161      voz += dvozdx;
162   }
163}
164
165
166static void draw_scanline_alpha_test(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
167{
168   const poly_extra_data *extra = (const poly_extra_data *)extradata;
169   const cached_texture *texture = extra->texture;
170   bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest;
171   UINT32 *p = &destmap->pix32(scanline);
172   UINT32 *d = &extra->zbuffer->pix32(scanline);
173   float ooz = extent->param[0].start;
174   float uoz = extent->param[1].start;
175   float voz = extent->param[2].start;
176   float doozdx = extent->param[0].dpdx;
177   float duozdx = extent->param[1].dpdx;
178   float dvozdx = extent->param[2].dpdx;
179   UINT32 polyi = (extra->polygon_intensity * extra->polygon_transparency) >> 5;
180   int desttrans = 32 - extra->polygon_transparency;
181   UINT32 umask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
182   UINT32 vmask = (((extra->texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
183   UINT32 width = 6 + texture->width;
184   int x;
185
186   for (x = extent->startx; x < extent->stopx; x++)
187   {
188      UINT32 iz = ooz * 256.0f;
189      if (iz > d[x])
190      {
191         float z = 1.0f / ooz;
192         UINT32 u = uoz * z;
193         UINT32 v = voz * z;
194         UINT32 u1 = (u >> 8) & umask;
195         UINT32 v1 = (v >> 8) & vmask;
196         UINT32 u2 = (u1 + 1) & umask;
197         UINT32 v2 = (v1 + 1) & vmask;
198         UINT32 pix00 = texture->data[(v1 << width) + u1];
199         UINT32 pix01 = texture->data[(v1 << width) + u2];
200         UINT32 pix10 = texture->data[(v2 << width) + u1];
201         UINT32 pix11 = texture->data[(v2 << width) + u2];
202         UINT32 texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);
203         UINT32 fa = texel >> 24;
204         if (fa >= 0xf8)
205         {
206            UINT32 combined = ((fa + 1) * polyi) >> 8;
207            UINT32 fr = ((texel & 0x00ff0000) * combined) >> (8+9);
208            UINT32 fg = ((texel & 0x0000ff00) * combined) >> (8+6);
209            UINT32 fb = ((texel & 0x000000ff) * combined) >> (8+3);
210            UINT32 orig = p[x];
211            combined = ((255 - fa) * desttrans) >> 8;
212            fr += ((orig & 0x00ff0000) * combined) >> 5;
213            fg += ((orig & 0x0000ff00) * combined) >> 5;
214            fb += ((orig & 0x000000ff) * combined) >> 5;
215            p[x] = 0xff000000 | (fr & 0xff0000) | (fg & 0xff00) | (fb & 0xff);
216            d[x] = iz;
217         }
218      }
219
220      ooz += doozdx;
221      uoz += duozdx;
222      voz += dvozdx;
223   }
224}
225
226static void draw_scanline_color(void *dest, INT32 scanline, const poly_extent *extent, const void *extradata, int threadid)
227{
228   const poly_extra_data *extra = (const poly_extra_data *)extradata;
229   bitmap_rgb32 *destmap = (bitmap_rgb32 *)dest;
230   UINT32 *p = &destmap->pix32(scanline);
231   UINT32 *d = &extra->zbuffer->pix32(scanline);
232   float ooz = extent->param[0].start;
233   float doozdx = extent->param[0].dpdx;
234   int fr = (extra->color & 0x7c00) << 9;
235   int fg = (extra->color & 0x03e0) << 6;
236   int fb = (extra->color & 0x001f) << 3;
237   int x;
238
239   // apply intensity
240   fr = (fr * extra->polygon_intensity) >> 8;
241   fg = (fg * extra->polygon_intensity) >> 8;
242   fb = (fb * extra->polygon_intensity) >> 8;
243
244   /* simple case: no transluceny */
245   if (extra->polygon_transparency >= 32)
246   {
247      UINT32 color = (fr & 0x7c00) | (fg & 0x03e0) | (fb & 0x1f);
248      for (x = extent->startx; x < extent->stopx; x++)
249      {
250         UINT32 iz = ooz * 256.0f;
251         if (iz > d[x])
252         {
253            p[x] = color;
254            d[x] = iz;
255         }
256         ooz += doozdx;
257      }
258   }
259
260   /* translucency */
261   else
262   {
263      int polytrans = extra->polygon_transparency;
264
265      fr = (fr * polytrans) >> 5;
266      fg = (fg * polytrans) >> 5;
267      fb = (fb * polytrans) >> 5;
268      polytrans = 32 - polytrans;
269
270      for (x = extent->startx; x < extent->stopx; x++)
271      {
272         UINT32 iz = ooz * 256.0f;
273         if (iz > d[x])
274         {
275            UINT32 orig = p[x];
276            int r = fr + (((orig & 0x00ff0000) * polytrans) >> 5);
277            int g = fg + (((orig & 0x0000ff00) * polytrans) >> 5);
278            int b = fb + (((orig & 0x000000ff) * polytrans) >> 5);
279
280            p[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
281            d[x] = iz;
282         }
283         ooz += doozdx;
284      }
285   }
286}
trunk/src/mame/video/model3.c
r32673r32674
11#include "emu.h"
2#include "video/polylgcy.h"
2#include "video/poly.h"
33#include "video/rgbutil.h"
44#include "includes/model3.h"
55
6#define ENABLE_BILINEAR      1
67
7#define pz  p[0]
8#define pu  p[1]
9#define pv  p[2]
8#define TRI_PARAM_TEXTURE_PAGE          0x1
9#define TRI_PARAM_TEXTURE_MIRROR_U      0x2
10#define TRI_PARAM_TEXTURE_MIRROR_V      0x4
11#define TRI_PARAM_TEXTURE_ENABLE        0x8
12#define TRI_PARAM_ALPHA_TEST            0x10
1013
11
12struct cached_texture
14struct model3_polydata
1315{
14   cached_texture *next;
15   UINT8       width;
16   UINT8       height;
17   UINT8       format;
18   UINT8       alpha;
19   rgb_t       data[1];
16   cached_texture *texture;
17   UINT32 color;
18   UINT32 texture_param;
19   int transparency;
20   int intensity;
2021};
2122
22struct poly_extra_data
23class model3_renderer : public poly_manager<float, model3_polydata, 6, 50000>
2324{
24   cached_texture *texture;
25   bitmap_ind32 *zbuffer;
26   UINT32 color;
27   UINT8 texture_param;
28   int polygon_transparency;
29   int polygon_intensity;
25public:
26   model3_renderer(model3_state &state, int width, int height)
27      : poly_manager<float, model3_polydata, 6, 50000>(state.machine()), m_state(state)
28   {
29      m_fb = auto_bitmap_rgb32_alloc(state.machine(), width, height);
30      m_zb = auto_bitmap_ind32_alloc(state.machine(), width, height);     
31   }
32
33   void draw(bitmap_rgb32 &bitmap, const rectangle &cliprect);
34   void draw_triangle(const m3_triangle* tri);
35   void clear_buffers();
36   void draw_scanline_solid(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
37   void draw_scanline_tex(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
38   void draw_scanline_contour(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
39   void draw_scanline_tex_trans(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
40   void draw_scanline_tex_alpha(INT32 scanline, const extent_t &extent, const model3_polydata &extradata, int threadid);
41
42private:
43   model3_state &m_state;
44   bitmap_rgb32 *m_fb;
45   bitmap_ind32 *m_zb;
3046};
3147
32#define TRI_PARAM_TEXTURE_PAGE          0x1
33#define TRI_PARAM_TEXTURE_MIRROR_U      0x2
34#define TRI_PARAM_TEXTURE_MIRROR_V      0x4
35#define TRI_PARAM_TEXTURE_ENABLE        0x8
36#define TRI_PARAM_ALPHA_TEST            0x10
3748
38#define MAX_TRIANGLES       131072
3949
40
4150/*****************************************************************************/
4251
4352/* matrix stack */
4453#define MATRIX_STACK_SIZE   256
4554
4655
47#ifdef UNUSED_DEFINITION
48static const int num_bits[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
49#endif
50
51
52
53
54
5556#define BYTE_REVERSE32(x)       (((x >> 24) & 0xff) | \
5657                        ((x >> 8) & 0xff00) | \
5758                        ((x << 8) & 0xff0000) | \
r32673r32674
119120    fclose(file);
120121#endif
121122
122   invalidate_texture(0, 0, 0, 6, 5);
123   invalidate_texture(1, 0, 0, 6, 5);
124   poly_free(m_poly);
123//   invalidate_texture(0, 0, 0, 6, 5);
124//   invalidate_texture(1, 0, 0, 6, 5);
125125}
126126
127127void model3_state::video_start()
r32673r32674
148148      8 * 8*8
149149   };
150150
151   m_poly = poly_alloc(machine(), 4000, sizeof(poly_extra_data), 0);
151   int width = m_screen->width();
152   int height = m_screen->height();
153
154   m_renderer = auto_alloc(machine(), model3_renderer(*this, width, height));
155
152156   machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(model3_state::model3_exit), this));
153157
154   m_screen->register_screen_bitmap(m_bitmap3d);
155   m_screen->register_screen_bitmap(m_zbuffer);
156
157158   m_m3_char_ram = auto_alloc_array_clear(machine(), UINT64, 0x100000/8);
158159   m_m3_tile_ram = auto_alloc_array_clear(machine(), UINT64, 0x8000/8);
159160
r32673r32674
170171   /* 4MB Polygon RAM */
171172   m_polygon_ram = auto_alloc_array_clear(machine(), UINT32, 0x400000/4);
172173
173   m_tick = 0;
174   m_debug_layer_disable = 0;
175174   m_vid_reg0 = 0;
176175
177176   m_viewport_focal_length = 300.;
r32673r32674
251250   const pen_t *pens = m_palette->pens();
252251
253252   UINT32* palram = (UINT32*)&m_paletteram64[0];
253   UINT16* rowscroll_ram = (UINT16*)&m_m3_char_ram[0x1ec00];
254254
255255   int x1 = cliprect.min_x;
256256   int y1 = cliprect.min_y;
r32673r32674
273273      UINT32* dst = &bitmap.pix32(y);
274274      UINT16* src = &pixmap.pix16(iy & 0x1ff);
275275
276      int iix = ix;
276      int rowscroll = BYTE_REVERSE16(rowscroll_ram[((layer * 0x200) + y) ^ NATIVE_ENDIAN_VALUE_LE_BE(3,0)]) & 0x7fff;
277      if (rowscroll & 0x100)
278         rowscroll |= ~0x1ff;
277279
278      for (int x = x1; x <= x2; x++)
280      int iix = ix & 0x1ff;
281
282      int rx1 = x1 - (rowscroll * 2);
283      int rx2 = x2 - (rowscroll * 2);
284
285      if (rx1 < 0)
279286      {
287         iix += (0 - rx1);
288         rx1 = 0;
289      }
290      if (rx2 > cliprect.max_x)
291         rx2 = cliprect.max_x;
292
293      for (int x = rx1; x <= rx2; x++)
294      {
280295         UINT16 p0 = src[iix & 0x1ff];
281296         if ((palram[p0^NATIVE_ENDIAN_VALUE_LE_BE(1,0)] & NATIVE_ENDIAN_VALUE_LE_BE(0x00800000,0x00008000)) == 0)
282297         {
283            *dst = pens[p0];
298            dst[x] = pens[p0];
284299         }
285         dst++;
286300         iix++;
287301      }
288302
r32673r32674
324338      draw_layer(bitmap, cliprect, 0, m_layer_priority & 0x10, layer_scroll_x[0], layer_scroll_y[0]);
325339
326340   // render 3D
327   draw_3d_layer(bitmap, cliprect);
341   m_renderer->draw(bitmap, cliprect);
328342
329343   // render enabled layers with priority 1
330344   if ((layer_data[3] & 0x80000000) && (m_layer_priority & 0x8) != 0)
r32673r32674
336350   if ((layer_data[0] & 0x80000000) && (m_layer_priority & 0x1) != 0)
337351      draw_layer(bitmap, cliprect, 0, m_layer_priority & 0x10, layer_scroll_x[0], layer_scroll_y[0]);
338352
339   m_real3d_display_list = 0;
340353   return 0;
341354}
342355
r32673r32674
620633/*****************************************************************************/
621634/* Real3D Graphics stuff */
622635
636/*
637   Real3D Pro-1000 capabilities:
638
639   Coordinate sets
640   - 4096 matrices (matrix base pointer in viewport node)
641
642   Polygons
643   - 32MB max polygon memory. VROM in Model 3, the low 4MB of VROM is overlaid by Polygon RAM for runtime generated content.
644
645   Texture
646   - 2 texture sheets of 2048x1024
647   - Mipmaps located in the bottom right corner
648   - Texture size 32x32 to 1024x1024
649   - Microtextures (is this featured in Model 3?)
650
651   LODs
652   - 127 blend types per viewport with 4 sets of min/max angle or range (where is this in the viewport node?)
653
654   Lighting
655   - Self-luminous lighting (enable and luminosity parameter in polygon structure)
656   - Fixed polygon shading, fixed shading weight per vertex (not found in Model 3, yet)
657   - Flat sun shading (lighting parameters in viewport node) needs a separate enable?
658   - Smooth polygon shading (lighting parameters in viewport, use vertex normals)
659
660   Gamma table
661   - 256 entry 8-bit table, possibly in Polygon RAM
662*/
663
664/*
665   Real3D Memory Structures:
666   
667   Culling Nodes:
668   - Located in Culling RAM (0x8E000000)
669   - Limit of 15 child nodes (nesting), not including polygon nodes
670   - Color table (is this featured in Model 3?)
671
672   0x00:   -------- -------- ------xx -------- Viewport number 0-3
673         -------- -------- -------- ---xx--- Viewport priority
674
675   0x01:   Child node pointer (inherits parameters from this node)
676   0x02:   Sibling node pointer
677   0x03:   Unknown (float)
678   0x04:   Sun light vector Z-component (float)
679   0x05:   Sun light vector X-component (float)
680   0x06:   Sun light vector Y-component (float)
681   0x07:   Sun light intensity (float)
682   0x08:   Far Clip plane Z
683   0x09:   Far Clip plane Distance
684   0x0a:   Near Clip plane Z
685   0x0b:   Near Clip plane Distance
686   0x0c:   Left Clip plane Z
687   0x0d:   Left Clip plane X
688   0x0e:   Top Clip plane Z
689   0x0f:   Top Clip plane Y
690   0x10:   Right Clip plane Z
691   0x11:   Right Clip plane X
692   0x12:   Bottom Clip plane Z
693   0x13:   Bottom Clip plane Y
694
695   0x14:   xxxxxxxx xxxxxxxx -------- -------- Viewport height (14.2 fixed-point)
696         -------- -------- xxxxxxxx xxxxxxxx Viewport width (14.2 fixed-point)
697
698   0x15:   ?
699   0x16:   Matrix base pointer
700   0x17:   LOD blend type table pointer?      (seems to be 8x float per entry)
701   0x18:   ?
702   0x19:   ?
703
704   0x1a:   xxxxxxxx xxxxxxxx -------- -------- Viewport Y coordinate (12.4 fixed-point)
705         -------- -------- xxxxxxxx xxxxxxxx Viewport X coordinate (12.4 fixed-point)
706
707   0x1b:   Copy of word 0x00
708   0x1c:   ?
709
710   0x1d:   xxxxxxxx xxxxxxxx -------- -------- Spotlight Y size
711         -------- -------- xxxxxxxx xxxxxxxx Spotlight Y position (13.3 fixed-point?)
712
713   0x1e:   xxxxxxxx xxxxxxxx -------- -------- Spotlight X size
714         -------- -------- xxxxxxxx xxxxxxxx Spotlight X position (13.3 fixed-point?)
715
716   0x1f:   Light extent (float)
717
718   0x20:   xxxxxxxx -------- -------- -------- ?
719         -------- xxxxxxxx -------- -------- ?
720         -------- -------- --xxx--- -------- Light RGB (RGB111?)
721         -------- -------- -----xxx -------- Light RGB Fog (RGB111?)
722         -------- -------- -------- xxxxxxxx Scroll Fog (0.8 fixed-point?) What is this???
723
724   0x21:   ?
725   0x22:   Fog Color (RGB888)
726   0x23:   Fog Density (float)
727
728   0x24:   xxxxxxxx xxxxxxxx -------- -------- ?
729         -------- -------- xxxxxxxx -------- Sun light ambient (0.8 fixed-point)
730         -------- -------- -------- xxxxxxxx Scroll attenuation (0.8 fixed-point) What is this???
731
732   0x25:   Fog offset
733   0x26:   ?
734   0x27:   ?
735   0x28:   ?
736   0x29:   ?
737   0x2a:   ?
738   0x2b:   ?
739   0x2c:   ?
740   0x2d:   ?
741   0x2e:   ?
742   0x2f:   ?
743
744
745   Sub types:
746   LOD Culling Node. Up to 4 LODs.
747
748   Articulated Part Culling Node (is this used by Model 3?)
749   - An Articulated Part culling node, or six degree–of–freedom node, is used to define
750      geometry that can move relative to the parent coordinate set to which it is attached.
751      Fifteen levels of coordinate set nesting (levels of articulation) are supported.
752   
753   Animation Culling Node
754   - Animation culling nodes are used to build a culling hierarchy for an object with different
755      representations, or animation frames. which can be turned on and off by the
756      application. Each child (culling node or polygon) added to an Animation culling node
757      specifies the frame for which the child is valid.
758   
759   Instance Culling Node
760   - Instance culling nodes define the top of a shared display list segment that can be
761     referenced from other parts of the scene display list.
762
763   Instance Reference Culling Node
764   - An Instance Reference node is considered a leaf node; its
765     "child" is the shared geometry segment. An Instance Reference may be attached to
766     a parent node and may not have any other children, but may have siblings.
767
768   Point Light
769   - A Point Light is used to create an instance of a point luminous feature. The size,
770      feature type, and number of sides of the point light model may be customized.
771
772   Instance Set
773   - An Instance Set is a culling node which defines a set of point features. Each feature
774      is positioned individually. This type of culling node can be used to simulate particles.
775
776
777
778   Instance Node?
779
780   0x00:   xxxxxxxx xxxxxxxx xxxxxx-- -------- Node number/ID?, num of bits unknown
781         -------- -------- -------- ---x---- This node applies translation, else matrix
782         -------- -------- -------- ----x--- LOD enable?
783         -------- -------- -------- -----x-- ?
784         -------- -------- -------- ------x- ?
785         -------- -------- -------- -------x ?
786
787   
788   0x01:   ? (not present on Step 1.0)
789   0x02:   ? (not present on Step 1.0)         Scud Race has 0x00000101
790
791   0x03:   --x----- -------- -------- -------- ?
792         -------- -xxxxxxx xxxx---- -------- LOD?
793         -------- -------- ----xxxx xxxxxxxx Node matrix
794   
795   0x04:   Translation X coordinate
796   0x05:   Translation Y coordinate
797   0x06:   Translation Z coordinate
798   0x07:   Child node pointer
799   0x08:   Sibling node pointer
800
801   0x09:   xxxxxxxx xxxxxxxx -------- -------- Culling or sorting related?
802         -------- -------- xxxxxxxx xxxxxxxx Culling or sorting related?
803
804
805   Polygon Data
806
807   0x00:   -------- xxxxxxxx xxxxxx-- -------- Polygon ID
808         -------- -------- -------- -x------ 0 = Triangle, 1 = Quad
809         -------- -------- -------- ----x--- Vertex 3 shared from previous polygon
810         -------- -------- -------- -----x-- Vertex 2 shared from previous polygon
811         -------- -------- -------- ------x- Vertex 1 shared from previous polygon
812         -------- -------- -------- -------x Vertex 0 shared from previous polygon
813         xxxxxxxx -------- -------- x-xx---- ?
814         -------- -------- ------xx -------- Broken polygons in srally2 set these (a way to mark them for HW to not render?)
815
816   0x01:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Polygon normal X coordinate (2.22 fixed point)
817         -------- -------- -------- -x------ UV format (0 = 13.3, 1 = 16.0)
818         -------- -------- -------- -----x-- If set, this is the last polygon
819         -------- -------- -------- x-xxx-xx ?
820
821   0x02:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Polygon normal Y coordinate (2.22 fixed point)
822         -------- -------- -------- ------x- Texture U mirror enable
823         -------- -------- -------- -------x Texture V mirror enable
824         -------- -------- -------- xxxxxx-- ?
825
826   0x03:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Polygon normal Z coordinate (2.22 fixed point)
827         -------- -------- -------- --xxx--- Texture width (in 8-pixel tiles)
828         -------- -------- -------- -----xxx Texture height (in 8-pixel tiles)
829
830   0x04:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Color (RGB888)
831         -------- -------- -------- -x------ Texture page
832         -------- -------- -------- ---xxxxx Upper 5 bits of texture U coordinate
833         -------- -------- -------- x-x----- ?
834
835   0x05:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Specular color?
836         -------- -------- -------- x------- Low bit of texture U coordinate
837         -------- -------- -------- ---xxxxx Low 5 bits of texture V coordinate
838         -------- -------- -------- -xx----- ?
839
840   0x06:   x------- -------- -------- -------- Texture contour enable
841         -----x-- -------- -------- -------- Texture enable
842         -------- x------- -------- -------- 1 = disable transparency?
843         -------- -xxxxx-- -------- -------- Polygon transparency (0 = fully transparent)
844         -------- -------x -------- -------- 1 = disable lighting
845         -------- -------- xxxxx--- -------- Polygon luminosity
846         -------- -------- ------xx x------- Texture format
847         -------- -------- -------- -------x Alpha enable?
848         -xxxx-xx ------x- -----x-- -xxxxxx- ?
849
850
851   Vertex entry
852
853   0x00:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Vertex X coordinate (17.7 fixed-point in Step 1.0, 13.11 otherwise)
854         -------- -------- -------- xxxxxxxx Vertex normal X (offset from polygon normal)
855
856   0x01:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Vertex Y coordinate
857         -------- -------- -------- xxxxxxxx Vertex normal Y
858
859   0x02:   xxxxxxxx xxxxxxxx xxxxxxxx -------- Vertex Z coordinate
860         -------- -------- -------- xxxxxxxx Vertex normal Z
861
862   0x03:   xxxxxxxx xxxxxxxx -------- -------- Vertex U coordinate
863         -------- -------- xxxxxxxx xxxxxxxx Vertex V coordinate
864
865*/
866
867
623868WRITE64_MEMBER(model3_state::real3d_display_list_w)
624869{
625   if(ACCESSING_BITS_32_63) {
870   if (ACCESSING_BITS_32_63)
871   {
626872      m_display_list_ram[offset*2] = BYTE_REVERSE32((UINT32)(data >> 32));
627873   }
628   if(ACCESSING_BITS_0_31) {
874   if (ACCESSING_BITS_0_31)
875   {
629876      m_display_list_ram[(offset*2)+1] = BYTE_REVERSE32((UINT32)(data));
630877   }
631878}
632879
633880WRITE64_MEMBER(model3_state::real3d_polygon_ram_w)
634881{
635   if(ACCESSING_BITS_32_63) {
882   if (ACCESSING_BITS_32_63)
883   {
636884      m_polygon_ram[offset*2] = BYTE_REVERSE32((UINT32)(data >> 32));
637885   }
638   if(ACCESSING_BITS_0_31) {
886   if (ACCESSING_BITS_0_31)
887   {
639888      m_polygon_ram[(offset*2)+1] = BYTE_REVERSE32((UINT32)(data));
640889   }
641890}
642891
643892static const UINT8 texture_decode[64] =
644893{
645      0,  1,  4,  5,  8,  9, 12, 13,
646      2,  3,  6,  7, 10, 11, 14, 15,
894    0,  1,  4,  5,  8,  9, 12, 13,
895    2,  3,  6,  7, 10, 11, 14, 15,
647896   16, 17, 20, 21, 24, 25, 28, 29,
648897   18, 19, 22, 23, 26, 27, 30, 31,
649898   32, 33, 36, 37, 40, 41, 44, 45,
r32673r32674
7531002   }
7541003   m_texture_fifo_pos = 0;
7551004
756   m_zbuffer.fill(0);
757   m_bitmap3d.fill(0);
1005   m_renderer->clear_buffers();
7581006   
7591007   real3d_traverse_display_list();   
7601008}
r32673r32674
7651013   int d = (dst & 0xffffff) / 4;
7661014   for (int i = 0; i < length; i += 4)
7671015   {
768      UINT32 w;
769      if (byteswap) {
770         w = BYTE_REVERSE32(space.read_dword(src));
771      } else {
772         w = space.read_dword(src);
773      }
1016      UINT32 w = space.read_dword(src);
1017
1018      if (byteswap)
1019         w = BYTE_REVERSE32(w);
1020
7741021      m_display_list_ram[d++] = w;
7751022      src += 4;
7761023   }
r32673r32674
7821029   int d = (dst & 0xffffff) / 4;
7831030   for (int i = 0; i < length; i += 4)
7841031   {
785      UINT32 w;
786      if (byteswap) {
787         w = BYTE_REVERSE32(space.read_dword(src));
788      } else {
789         w = space.read_dword(src);
790      }
1032      UINT32 w = space.read_dword(src);
1033
1034      if (byteswap)
1035         w = BYTE_REVERSE32(w);
1036
7911037      m_culling_ram[d++] = w;
7921038      src += 4;
7931039   }
r32673r32674
8001046   {
8011047      for (int i=0; i < length; i+=12)
8021048      {
803         UINT32 address, header;
1049         UINT32 address = space.read_dword(src+i+0);
1050         UINT32 header = space.read_dword(src+i+4);
8041051
805         if (byteswap) {
806            address = BYTE_REVERSE32(space.read_dword((src+i+0)));
807            header = BYTE_REVERSE32(space.read_dword((src+i+4)));
808         } else {
809            address = space.read_dword((src+i+0));
810            header = space.read_dword((src+i+4));
1052         if (byteswap)
1053         {
1054            address = BYTE_REVERSE32(address);
1055            header = BYTE_REVERSE32(header);
8111056         }
1057
8121058         real3d_upload_texture(header, (UINT32*)&m_vrom[address]);
8131059      }
8141060   }
r32673r32674
8191065   address_space &space = m_maincpu->space(AS_PROGRAM);
8201066   for (int i = 0; i < length; i += 4)
8211067   {
822      UINT32 w;
823      if (byteswap) {
824         w = BYTE_REVERSE32(space.read_dword(src));
825      } else {
826         w = space.read_dword(src);
827      }
1068      UINT32 w = space.read_dword(src);
1069
1070      if (byteswap)
1071         w = BYTE_REVERSE32(w);
1072
8281073      m_texture_fifo[m_texture_fifo_pos] = w;
8291074      m_texture_fifo_pos++;
8301075      src += 4;
r32673r32674
8371082   int d = (dst & 0xffffff) / 4;
8381083   for (int i = 0; i < length; i += 4)
8391084   {
840      UINT32 w;
841      if (byteswap) {
842         w = BYTE_REVERSE32(space.read_dword(src));
843      } else {
844         w = space.read_dword(src);
845      }
1085      UINT32 w = space.read_dword(src);
1086
1087      if (byteswap)
1088         w = BYTE_REVERSE32(w);
1089
8461090      m_polygon_ram[d++] = w;
8471091      src += 4;
8481092   }
r32673r32674
8571101/*****************************************************************************/
8581102/* matrix and vector operations */
8591103
860#ifdef UNUSED_FUNCTION
861INLINE float dot_product(VECTOR a, VECTOR b)
862{
863   return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]);
864}
865#endif
866
8671104INLINE float dot_product3(VECTOR3 a, VECTOR3 b)
8681105{
8691106   return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
r32673r32674
9591196/*****************************************************************************/
9601197/* transformation and rasterizing */
9611198
962#include "m3raster.inc"
963
964INLINE int is_point_inside(float x, float y, float z, PLANE cp)
1199INLINE bool is_point_inside(float x, float y, float z, m3_plane cp)
9651200{
9661201   float s = (x * cp.x) + (y * cp.y) + (z * cp.z) + cp.d;
9671202   if (s >= 0.0f)
968      return 1;
1203      return true;
9691204   else
970      return 0;
1205      return false;
9711206}
9721207
973INLINE float line_plane_intersection(const poly_vertex *v1, const poly_vertex *v2, PLANE cp)
1208INLINE float line_plane_intersection(const m3_clip_vertex *v1, const m3_clip_vertex *v2, m3_plane cp)
9741209{
9751210   float x = v1->x - v2->x;
9761211   float y = v1->y - v2->y;
977   float z = v1->pz - v2->pz;
978   float t = ((cp.x * v1->x) + (cp.y * v1->y) + (cp.z * v1->pz)) / ((cp.x * x) + (cp.y * y) + (cp.z * z));
1212   float z = v1->z - v2->z;
1213   float t = ((cp.x * v1->x) + (cp.y * v1->y) + (cp.z * v1->z)) / ((cp.x * x) + (cp.y * y) + (cp.z * z));
9791214   return t;
9801215}
9811216
982static int clip_polygon(const poly_vertex *v, int num_vertices, PLANE cp, poly_vertex *vout)
1217static int clip_polygon(const m3_clip_vertex *v, int num_vertices, m3_plane cp, m3_clip_vertex *vout)
9831218{
984   poly_vertex clipv[10];
1219   m3_clip_vertex clipv[10];
9851220   int clip_verts = 0;
9861221   float t;
9871222   int i;
r32673r32674
9901225
9911226   for (i=0; i < num_vertices; i++)
9921227   {
993      int v1_in = is_point_inside(v[i].x, v[i].y, v[i].pz, cp);
994      int v2_in = is_point_inside(v[previ].x, v[previ].y, v[previ].pz, cp);
1228      bool v1_in = is_point_inside(v[i].x, v[i].y, v[i].z, cp);
1229      bool v2_in = is_point_inside(v[previ].x, v[previ].y, v[previ].z, cp);
9951230
9961231      if (v1_in && v2_in)         /* edge is completely inside the volume */
9971232      {
r32673r32674
10041239         t = line_plane_intersection(&v[i], &v[previ], cp);
10051240         clipv[clip_verts].x = v[i].x + ((v[previ].x - v[i].x) * t);
10061241         clipv[clip_verts].y = v[i].y + ((v[previ].y - v[i].y) * t);
1007         clipv[clip_verts].pz = v[i].pz + ((v[previ].pz - v[i].pz) * t);
1008         clipv[clip_verts].pu = v[i].pu + ((v[previ].pu - v[i].pu) * t);
1009         clipv[clip_verts].pv = v[i].pv + ((v[previ].pv - v[i].pv) * t);
1242         clipv[clip_verts].z = v[i].z + ((v[previ].z - v[i].z) * t);
1243         clipv[clip_verts].u = v[i].u + ((v[previ].u - v[i].u) * t);
1244         clipv[clip_verts].v = v[i].v + ((v[previ].v - v[i].v) * t);
1245         clipv[clip_verts].i = v[i].i + ((v[previ].i - v[i].i) * t);
10101246         ++clip_verts;
10111247      }
10121248      else if (v1_in && !v2_in)   /* edge is leaving the volume */
r32673r32674
10151251         t = line_plane_intersection(&v[i], &v[previ], cp);
10161252         clipv[clip_verts].x = v[i].x + ((v[previ].x - v[i].x) * t);
10171253         clipv[clip_verts].y = v[i].y + ((v[previ].y - v[i].y) * t);
1018         clipv[clip_verts].pz = v[i].pz + ((v[previ].pz - v[i].pz) * t);
1019         clipv[clip_verts].pu = v[i].pu + ((v[previ].pu - v[i].pu) * t);
1020         clipv[clip_verts].pv = v[i].pv + ((v[previ].pv - v[i].pv) * t);
1254         clipv[clip_verts].z = v[i].z + ((v[previ].z - v[i].z) * t);
1255         clipv[clip_verts].u = v[i].u + ((v[previ].u - v[i].u) * t);
1256         clipv[clip_verts].v = v[i].v + ((v[previ].v - v[i].v) * t);
1257         clipv[clip_verts].i = v[i].i + ((v[previ].i - v[i].i) * t);
10211258         ++clip_verts;
10221259
10231260         /* insert the existing vertex */
r32673r32674
10311268   return clip_verts;
10321269}
10331270
1034void model3_state::render_one(TRIANGLE *tri)
1035{
1036   poly_extra_data *extra = (poly_extra_data *)poly_get_extra_data(m_poly);
1037   poly_draw_scanline_func callback = NULL;
1038
1039   tri->v[0].pz = 1.0f / tri->v[0].pz;
1040   tri->v[1].pz = 1.0f / tri->v[1].pz;
1041   tri->v[2].pz = 1.0f / tri->v[2].pz;
1042
1043   extra->zbuffer = &m_zbuffer;
1044   if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
1045   {
1046      tri->v[0].pu = tri->v[0].pu * tri->v[0].pz * 256.0f;
1047      tri->v[0].pv = tri->v[0].pv * tri->v[0].pz * 256.0f;
1048      tri->v[1].pu = tri->v[1].pu * tri->v[1].pz * 256.0f;
1049      tri->v[1].pv = tri->v[1].pv * tri->v[1].pz * 256.0f;
1050      tri->v[2].pu = tri->v[2].pu * tri->v[2].pz * 256.0f;
1051      tri->v[2].pv = tri->v[2].pv * tri->v[2].pz * 256.0f;
1052
1053      extra->texture = get_texture((tri->param & TRI_PARAM_TEXTURE_PAGE) ? 1 : 0, tri->texture_x, tri->texture_y, tri->texture_width, tri->texture_height, tri->texture_format);
1054      extra->texture_param        = tri->param;
1055      extra->polygon_transparency = tri->transparency;
1056      extra->polygon_intensity    = tri->intensity;
1057
1058      if (tri->param & TRI_PARAM_ALPHA_TEST)
1059         callback = draw_scanline_alpha_test;
1060      else if (extra->texture->alpha == 0xff)
1061         callback = (tri->transparency >= 32) ? draw_scanline_normal : draw_scanline_trans;
1062      else
1063         callback = draw_scanline_alpha;
1064      poly_render_triangle(m_poly, &m_bitmap3d, m_clip3d, callback, 3, &tri->v[0], &tri->v[1], &tri->v[2]);
1065   }
1066   else
1067   {
1068      extra->polygon_transparency = tri->transparency;
1069      extra->polygon_intensity    = tri->intensity;
1070      extra->color                = tri->color;
1071
1072      poly_render_triangle(m_poly, &m_bitmap3d, m_clip3d, draw_scanline_color, 1, &tri->v[0], &tri->v[1], &tri->v[2]);
1073   }
1074}
1075
10761271void model3_state::draw_model(UINT32 addr)
10771272{
1273   // Polygon RAM is mapped to the low 4MB of VROM
10781274   UINT32 *model = (addr >= 0x100000) ? &m_vrom[addr] :  &m_polygon_ram[addr];
1275
10791276   UINT32 header[7];
10801277   int index = 0;
10811278   int last_polygon = FALSE, first_polygon = TRUE, back_face = FALSE;
10821279   int num_vertices;
10831280   int i, v, vi;
10841281   float fixed_point_fraction;
1085   poly_vertex vertex[4];
1086   poly_vertex prev_vertex[4];
1087   poly_vertex clip_vert[10];
1282   m3_vertex vertex[4];
1283   m3_vertex prev_vertex[4];
1284   m3_clip_vertex clip_vert[10];
10881285
10891286   MATRIX transform_matrix;
10901287   float center_x, center_y;
10911288
1092   if(m_step < 0x15) {  /* position coordinates are 17.15 fixed-point in Step 1.0 */
1093      fixed_point_fraction = 1.0f / 32768.0f;
1094   } else {                    /* 13.19 fixed-point in other Steps */
1095      fixed_point_fraction = 1.0f / 524288.0f;
1096   }
1097
1289   if (m_step < 0x15)      // position coordinates are 17.7 fixed-point in Step 1.0
1290      fixed_point_fraction = 1.0f / 128.0f;
1291   else               // 13.11 fixed-point in other Steps
1292      fixed_point_fraction = 1.0f / 2048.0f;
1293   
10981294   get_top_matrix(&transform_matrix);
10991295
11001296   /* current viewport center coordinates on screen */
r32673r32674
11101306      VECTOR3 normal;
11111307      VECTOR3 sn;
11121308      VECTOR p[4];
1113      TRIANGLE tri;
1309      m3_triangle tri;
11141310      float dot;
1115      int intensity;
11161311      int polygon_transparency;
11171312
1118      //
1119      // Header bits:
1120      //
1121      //    0:00FFFC00 - polygon ID
1122      //    0:00000300 - ????
1123      //    0:00000040 - if set, indicates a quad, else it's a triangle
1124      //    0:00000008 - inherit vertex 3 from previous polygon
1125      //    0:00000004 - inherit vertex 2 from previous polygon
1126      //    0:00000002 - inherit vertex 1 from previous polygon
1127      //    0:00000001 - inherit vertex 0 from previous polygon
1128      //
1129      //    1:FFFFFF00 - polygon normal X coordinate, 2.22
1130      //    1:00000040 - if set, U/V is as-is, else divide U/V by 8
1131      //    1:00000004 - if set, indicates last polygon in model
1132      //
1133      //    2:FFFFFF00 - polygon normal Y coordinate, 2.22
1134      //    2:00000002 - if set, mirror texture in U
1135      //    2:00000001 - if set, mirror texture in V
1136      //
1137      //    3:FFFFFF00 - polygon normal Z coordinate, 2.22
1138      //    3:00000038 - texture width, in tiles
1139      //    3:00000007 - texture height, in tiles
1140      //
1141      //    4:FFFFFF00 - RGB lighting color
1142      //    4:00000040 - texture page
1143      //    4:0000001F - upper 5 bits of texture X coordinate
1144      //
1145      //    5:00000080 - low bit of texture X coordinate
1146      //    5:0000001F - low 5 bits of texture Y coordinate
1147      //
1148      //    6:80000000 - if set, enable alpha test
1149      //    6:04000000 - if set, textures enabled
1150      //    6:00800000 - if set, force transparency off
1151      //    6:007C0000 - 5-bit transparency value (0 is transparent, 0x1F is nearly opaque)
1152      //    6:00010000 - if set, disable lighting
1153      //    6:0000F800 - 5-bit additional color control
1154      //    6:00000380 - 3-bit texture format
1155      //    6:00000001 - alpha enable?
1156      //
1157
11581313      for (i = 0; i < 7; i++)
11591314         header[i] = model[index++];
11601315
r32673r32674
11681323      if (header[1] & 0x4)
11691324         last_polygon = TRUE;
11701325
1326      if ((header[0] & 0x300) == 0x300)      // TODO: broken polygons in srally2 have these bits set
1327         return;
1328
11711329      num_vertices = (header[0] & 0x40) ? 4 : 3;
11721330
11731331      /* texture coordinates are 16.0 or 13.3 fixed-point */
r32673r32674
11871345      /* load new vertices */
11881346      for ( ; vi < num_vertices; vi++)
11891347      {
1190         if ((model[index+0] & 0xf0000000) == 0x70000000 ||
1191            (model[index+1] & 0xf0000000) == 0x70000000 ||
1192            (model[index+2] & 0xf0000000) == 0x70000000)
1193            return;
1348         UINT32 xw = model[index++];
1349         UINT32 yw = model[index++];
1350         UINT32 zw = model[index++];
11941351
1195         vertex[vi].x = (float)((INT32)model[index++]) * fixed_point_fraction;
1196         vertex[vi].y = (float)((INT32)model[index++]) * fixed_point_fraction;
1197         vertex[vi].pz = (float)((INT32)model[index++]) * fixed_point_fraction;
1198         vertex[vi].pu = (UINT16)(model[index] >> 16);
1199         vertex[vi].pv = (UINT16)(model[index++]);
1352         vertex[vi].x = (float)((INT32)(xw) >> 8) * fixed_point_fraction;
1353         vertex[vi].y = (float)((INT32)(yw) >> 8) * fixed_point_fraction;
1354         vertex[vi].z = (float)((INT32)(zw) >> 8) * fixed_point_fraction;
1355         vertex[vi].u = (UINT16)(model[index] >> 16);
1356         vertex[vi].v = (UINT16)(model[index++]);
1357//         vertex[vi].nx = normal[0] + ((float)((INT8)(xw)) / 127.0f);
1358//         vertex[vi].ny = normal[1] + ((float)((INT8)(yw)) / 127.0f);
1359//         vertex[vi].nz = normal[2] + ((float)((INT8)(zw)) / 127.0f);
1360
1361         vertex[vi].nx = ((float)((INT8)(xw)) / 127.0f);
1362         vertex[vi].ny = ((float)((INT8)(yw)) / 127.0f);
1363         vertex[vi].nz = ((float)((INT8)(zw)) / 127.0f);
12001364      }
12011365
12021366      /* Copy current vertices as previous vertices */
1203      memcpy(prev_vertex, vertex, sizeof(poly_vertex) * 4);
1367      memcpy(prev_vertex, vertex, sizeof(m3_vertex) * 4);
12041368
1205      color = (((header[4] >> 27) & 0x1f) << 10) | (((header[4] >> 19) & 0x1f) << 5) | ((header[4] >> 11) & 0x1f);
1369      color = (header[4] >> 8) & 0xffffff;
12061370      polygon_transparency =  (header[6] & 0x800000) ? 32 : ((header[6] >> 18) & 0x1f);
12071371
12081372      /* transform polygon normal to view-space */
r32673r32674
12201384      sn[1] *= m_coordinate_system[1][2];
12211385      sn[2] *= m_coordinate_system[2][0];
12221386
1223      /* TODO: depth bias */
1224      /* transform vertices */
1387      // TODO: depth bias
1388      // transform and light vertices
12251389      for (i = 0; i < num_vertices; i++)
12261390      {
12271391         VECTOR vect;
12281392
12291393         vect[0] = vertex[i].x;
12301394         vect[1] = vertex[i].y;
1231         vect[2] = vertex[i].pz;
1395         vect[2] = vertex[i].z;
12321396         vect[3] = 1.0f;
12331397
1234         /* transform to world-space */
1398         // transform to world-space
12351399         matrix_multiply_vector(transform_matrix, vect, &p[i]);
12361400
1237         /* apply coordinate system */
1401         // apply coordinate system
12381402         clip_vert[i].x = p[i][0] * m_coordinate_system[0][1];
12391403         clip_vert[i].y = p[i][1] * m_coordinate_system[1][2];
1240         clip_vert[i].pz = p[i][2] * m_coordinate_system[2][0];
1241         clip_vert[i].pu = vertex[i].pu * texture_coord_scale;
1242         clip_vert[i].pv = vertex[i].pv * texture_coord_scale;
1404         clip_vert[i].z = p[i][2] * m_coordinate_system[2][0];
1405         clip_vert[i].u = vertex[i].u * texture_coord_scale;
1406         clip_vert[i].v = vertex[i].v * texture_coord_scale;
1407
1408         // transform vertex normal
1409         VECTOR3 n;
1410         n[0] = (vertex[i].nx * transform_matrix[0][0]) +
1411               (vertex[i].ny * transform_matrix[1][0]) +
1412               (vertex[i].nz * transform_matrix[2][0]);
1413         n[0] *= m_coordinate_system[0][1];
1414         n[1] = (vertex[i].nx * transform_matrix[0][1]) +
1415               (vertex[i].ny * transform_matrix[1][1]) +
1416               (vertex[i].nz * transform_matrix[2][1]);
1417         n[1] *= m_coordinate_system[1][2];
1418         n[2] = (vertex[i].nx * transform_matrix[0][2]) +
1419               (vertex[i].ny * transform_matrix[1][2]) +
1420               (vertex[i].nz * transform_matrix[2][2]);
1421         n[2] *= m_coordinate_system[2][0];
1422
1423         // lighting
1424         float intensity;
1425         if ((header[6] & 0x10000) == 0)
1426         {
1427            dot = dot_product3(n, m_parallel_light);
1428            intensity = ((dot * m_parallel_light_intensity) + m_ambient_light_intensity) * 255.0f;
1429            if (intensity > 255.0f)
1430            {
1431               intensity = 255.0f;
1432            }
1433            if (intensity < 0.0f)
1434            {
1435               intensity = 0.0f;
1436            }
1437         }
1438         else
1439         {
1440            // apply luminosity
1441            intensity = ((float)((header[6] >> 11) & 0x1f) / 31.0f) * 255.0f;
1442         }
1443
1444         clip_vert[i].i = intensity;
12431445      }
12441446
12451447      /* clip against view frustum */
r32673r32674
12511453
12521454      /* backface culling */
12531455      if( (header[6] & 0x800000) && (!(header[1] & 0x0010)) ) {
1254         if(sn[0]*clip_vert[0].x + sn[1]*clip_vert[0].y + sn[2]*clip_vert[0].pz >0)
1456         if(sn[0]*clip_vert[0].x + sn[1]*clip_vert[0].y + sn[2]*clip_vert[0].z >0)
12551457            back_face = 1;
12561458         else
12571459            back_face = 0;
r32673r32674
12591461      else
12601462         back_face = 0;  //no culling for transparent or two-sided polygons
12611463
1262      if(!back_face)  {
1464      if (!back_face)
1465      {
12631466         /* homogeneous Z-divide, screen-space transformation */
1264         for(i=0; i < num_vertices; i++) {
1265            float ooz = 1.0f / clip_vert[i].pz;
1467         for(i=0; i < num_vertices; i++)
1468         {
1469            float ooz = 1.0f / clip_vert[i].z;
12661470            clip_vert[i].x = ((clip_vert[i].x * ooz) * m_viewport_focal_length) + center_x;
12671471            clip_vert[i].y = ((clip_vert[i].y * ooz) * m_viewport_focal_length) + center_y;
1472            clip_vert[i].u *= ooz;
1473            clip_vert[i].v *= ooz;
12681474         }
12691475
1270         // lighting
1271         if ((header[6] & 0x10000) == 0)
1476
1477         cached_texture* texture;
1478
1479         if (header[6] & 0x4000000)
12721480         {
1273            dot = dot_product3(sn, m_parallel_light);
1274            intensity = ((dot * m_parallel_light_intensity) + m_ambient_light_intensity) * 256.0f;
1275            if (intensity > 256)
1276            {
1277               intensity = 256;
1278            }
1279            if (intensity < 0)
1280            {
1281               intensity = 0;
1282            }
1481            int tex_x = ((header[4] & 0x1f) << 1) | ((header[5] >> 7) & 0x1);
1482            int tex_y = (header[5] & 0x1f);
1483            int tex_width = ((header[3] >> 3) & 0x7);
1484            int tex_height = (header[3] & 0x7);
1485            int tex_format = (header[6] >> 7) & 0x7;
1486
1487            if (tex_width >= 6 || tex_height >= 6)      // srally2 poly ram has degenerate polys with 2k tex size (cpu bug or intended?)
1488               return;
1489
1490            texture = get_texture((header[4] & 0x40) ? 1 : 0, tex_x, tex_y, tex_width, tex_height, tex_format);
12831491         }
12841492         else
12851493         {
1286            // apply luminosity
1287            intensity = 256;
1494            texture = NULL;
12881495         }
12891496
12901497         for (i=2; i < num_vertices; i++)
12911498         {
1292            memcpy(&tri.v[0], &clip_vert[0], sizeof(poly_vertex));
1293            memcpy(&tri.v[1], &clip_vert[i-1], sizeof(poly_vertex));
1294            memcpy(&tri.v[2], &clip_vert[i], sizeof(poly_vertex));
1295            tri.texture_x               = ((header[4] & 0x1f) << 1) | ((header[5] >> 7) & 0x1);
1296            tri.texture_y               = (header[5] & 0x1f);
1297            tri.texture_width           = ((header[3] >> 3) & 0x7);
1298            tri.texture_height          = (header[3] & 0x7);
1299            tri.texture_format          = (header[6] >> 7) & 0x7;
1300            tri.transparency            = polygon_transparency;
1301            tri.intensity               = intensity;
1302            tri.color                   = color;
1499            memcpy(&tri.v[0], &clip_vert[0], sizeof(m3_clip_vertex));
1500            memcpy(&tri.v[1], &clip_vert[i-1], sizeof(m3_clip_vertex));
1501            memcpy(&tri.v[2], &clip_vert[i], sizeof(m3_clip_vertex));
13031502
1503            tri.texture = texture;
1504            tri.transparency = polygon_transparency;
1505            tri.color = color >> 8;
1506
13041507            tri.param   = 0;
13051508            tri.param   |= (header[4] & 0x40) ? TRI_PARAM_TEXTURE_PAGE : 0;
13061509            tri.param   |= (header[6] & 0x4000000) ? TRI_PARAM_TEXTURE_ENABLE : 0;
r32673r32674
13081511            tri.param   |= (header[2] & 0x1) ? TRI_PARAM_TEXTURE_MIRROR_V : 0;
13091512            tri.param   |= (header[6] & 0x80000000) ? TRI_PARAM_ALPHA_TEST : 0;
13101513
1311            render_one(&tri);
1514            m_renderer->draw_triangle(&tri);
13121515         }
13131516      }
13141517   }
r32673r32674
15211724{
15221725   init_matrix_stack();
15231726
1727   m_list_depth = 0;
1728
15241729   for (int pri = 0; pri < 4; pri++)
15251730      draw_viewport(pri, 0x800000);
1526
1527   poly_wait(m_poly, "real3d_traverse_display_list");
15281731}
15291732
1530void model3_state::draw_3d_layer(bitmap_rgb32 &bitmap, const rectangle &cliprect)
1733void model3_renderer::draw(bitmap_rgb32 &bitmap, const rectangle &cliprect)
15311734{
15321735   int i, j;
15331736
15341737   for (j = cliprect.min_y; j <= cliprect.max_y; ++j)
15351738   {
15361739      UINT32 *dst = &bitmap.pix32(j);
1537      UINT32 *src = &m_bitmap3d.pix32(j);
1740      UINT32 *src = &m_fb->pix32(j);
15381741
15391742      for (i = cliprect.min_x; i <= cliprect.max_x; ++i)
15401743      {
r32673r32674
15441747         }
15451748      }
15461749   }
1750}
1751
1752void model3_renderer::clear_buffers()
1753{
1754   rectangle cliprect;
1755   cliprect.min_x = 0;
1756   cliprect.min_y = 0;
1757   cliprect.max_x = 495;
1758   cliprect.max_y = 383;
1759
1760   m_fb->fill(0x00000000, cliprect);
1761   
1762   float zvalue = 10000000000.0f;
1763   m_zb->fill(*(int*)&zvalue, cliprect);
1764}
1765
1766void model3_renderer::draw_triangle(const m3_triangle *tri)
1767{
1768   rectangle cliprect;
1769   cliprect.min_x = 0;
1770   cliprect.min_y = 0;
1771   cliprect.max_x = 495;
1772   cliprect.max_y = 383;
1773
1774   vertex_t v[3];
1775
1776   if (tri->param & TRI_PARAM_TEXTURE_ENABLE)
1777   {
1778      for (int i=0; i < 3; i++)
1779      {
1780         v[i].x = tri->v[i].x;
1781         v[i].y = tri->v[i].y;
1782         v[i].p[0] = tri->v[i].z;
1783         v[i].p[1] = 1.0f / tri->v[i].z;
1784         v[i].p[2] = tri->v[i].u * 256.0f;      // 8 bits of subtexel precision for bilinear filtering
1785         v[i].p[3] = tri->v[i].v * 256.0f;
1786         v[i].p[4] =   tri->v[i].i;
1787      }
1788
1789      model3_polydata &extra = object_data_alloc();
1790      extra.texture = tri->texture;
1791      extra.transparency = tri->transparency;
1792      extra.intensity = tri->intensity;
1793      extra.texture_param = tri->param;
1794
1795      render_delegate rd;
1796      if (tri->param & TRI_PARAM_ALPHA_TEST)
1797      {
1798         rd = render_delegate(FUNC(model3_renderer::draw_scanline_contour), this);
1799      }
1800      else if (extra.texture->alpha == 0xff)
1801      {
1802         if (tri->transparency >= 32)
1803            rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex), this);
1804         else
1805            rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex_trans), this);
1806      }
1807      else
1808      {
1809         rd = render_delegate(FUNC(model3_renderer::draw_scanline_tex_alpha), this);
1810      }
1811
1812      render_triangle(cliprect, rd, 5, v[0], v[1], v[2]);
1813   }
1814   else
1815   {
1816      for (int i=0; i < 3; i++)
1817      {
1818         v[i].x = tri->v[i].x;
1819         v[i].y = tri->v[i].y;
1820         v[i].p[0] = tri->v[i].z;
1821         v[i].p[1] =   tri->v[i].i;
1822      }
1823
1824      model3_polydata &extra = object_data_alloc();
1825
1826      extra.intensity = tri->intensity;
1827      extra.color = tri->color;
1828
1829      render_triangle(cliprect, render_delegate(FUNC(model3_renderer::draw_scanline_solid), this), 2, v[0], v[1], v[2]);
1830   }
1831}
1832
1833void model3_renderer::draw_scanline_solid(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
1834{
1835   UINT32 *fb = &m_fb->pix32(scanline);
1836   float *zb = (float*)&m_zb->pix32(scanline);
1837
1838   float z = extent.param[0].start;
1839   float dz = extent.param[0].dpdx;
1840
1841   float in = extent.param[1].start;
1842   float inz = extent.param[1].dpdx;
1843
1844   int r = polydata.color & 0xff0000;
1845   int g = polydata.color & 0xff00;
1846   int b = polydata.color & 0xff;
1847
1848   int srctrans = polydata.transparency;
1849   int desttrans = 32 - polydata.transparency;
1850
1851   for (int x = extent.startx; x < extent.stopx; x++)
1852   {
1853      if (z < zb[x])
1854      {
1855         int ii = (int)(in);
1856
1857         r = (r * ii) >> 8;
1858         g = (g * ii) >> 8;
1859         b = (b * ii) >> 8;
1860
1861         if (srctrans != 0x1f)
1862         {
1863            UINT32 orig = fb[x];
1864            r = (r * srctrans) >> 5;
1865            g = (g * srctrans) >> 5;
1866            b = (b * srctrans) >> 5;
1867            r += ((orig & 0x00ff0000) * desttrans) >> 5;
1868            g += ((orig & 0x0000ff00) * desttrans) >> 5;
1869            b += ((orig & 0x000000ff) * desttrans) >> 5;
1870         }
1871
1872         fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
1873         zb[x] = z;
1874      }
1875
1876      in += inz;
1877      z += dz;
1878   }
1879}
1880
1881#define TEX_FETCH_NOFILTER()                        \
1882do {                                          \
1883   float intz = 1.0f / ooz;                        \
1884   UINT32 u = uoz * intz;                           \
1885   UINT32 v = voz * intz;                           \
1886   UINT32 u1 = (u >> 8) & umask;                     \
1887   UINT32 v1 = (v >> 8) & vmask;                     \
1888   texel = texture->data[(v1 << width) + u1];            \
1889} while(0);
1890
1891#define TEX_FETCH_BILINEAR()                                       \
1892do {                                                         \
1893   float intz = 1.0f / ooz;                                       \
1894   UINT32 u = uoz * intz;                                          \
1895   UINT32 v = voz * intz;                                          \
1896   UINT32 u1 = (u >> 8) & umask;                                    \
1897   UINT32 v1 = (v >> 8) & vmask;                                    \
1898   UINT32 u2 = (u1 + 1) & umask;                                    \
1899   UINT32 v2 = (v1 + 1) & vmask;                                    \
1900   UINT32 pix00 = texture->data[(v1 << width) + u1];                     \
1901   UINT32 pix01 = texture->data[(v1 << width) + u2];                     \
1902   UINT32 pix10 = texture->data[(v2 << width) + u1];                     \
1903   UINT32 pix11 = texture->data[(v2 << width) + u2];                     \
1904   texel = rgba_bilinear_filter(pix00, pix01, pix10, pix11, u, v);            \
1905} while(0);
1906
1907#if ENABLE_BILINEAR
1908#define TEX_FETCH() TEX_FETCH_BILINEAR()
1909#else
1910#define TEX_FETCH() TEX_FETCH_NOFILTER()
1911#endif
1912
1913void model3_renderer::draw_scanline_tex(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
1914{
1915   UINT32 *fb = &m_fb->pix32(scanline);
1916   float *zb = (float*)&m_zb->pix32(scanline);
1917   const cached_texture *texture = polydata.texture;
1918
1919   float z = extent.param[0].start;
1920   float dz = extent.param[0].dpdx;
1921   float ooz = extent.param[1].start;
1922   float dooz = extent.param[1].dpdx;
1923   float uoz = extent.param[2].start;
1924   float duoz = extent.param[2].dpdx;
1925   float voz = extent.param[3].start;
1926   float dvoz = extent.param[3].dpdx;
1927   float in = extent.param[4].start;
1928   float inz = extent.param[4].dpdx;
1929
1930   UINT32 umask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
1931   UINT32 vmask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
1932   UINT32 width = 6 + texture->width;
1933
1934   for (int x = extent.startx; x < extent.stopx; x++)
1935   {
1936      if (z < zb[x])
1937      {
1938         UINT32 texel;
1939         TEX_FETCH();
1940
1941         int ii = in;
1942
1943         UINT32 r = ((texel & 0xff0000) * ii) >> 8;
1944         UINT32 g = ((texel & 0xff00) * ii) >> 8;
1945         UINT32 b = ((texel & 0xff) * ii) >> 8;
1946
1947         fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
1948         zb[x] = z;
1949      }
1950
1951      ooz += dooz;
1952      uoz += duoz;
1953      voz += dvoz;
1954      in += inz;
1955      z += dz;
1956   }
1957}
1958
1959void model3_renderer::draw_scanline_contour(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
1960{
1961   UINT32 *fb = &m_fb->pix32(scanline);
1962   float *zb = (float*)&m_zb->pix32(scanline);
1963   const cached_texture *texture = polydata.texture;
1964
1965   float z = extent.param[0].start;
1966   float dz = extent.param[0].dpdx;
1967   float ooz = extent.param[1].start;
1968   float dooz = extent.param[1].dpdx;
1969   float uoz = extent.param[2].start;
1970   float duoz = extent.param[2].dpdx;
1971   float voz = extent.param[3].start;
1972   float dvoz = extent.param[3].dpdx;
1973   float in = extent.param[4].start;
1974   float inz = extent.param[4].dpdx;
1975
1976   UINT32 umask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
1977   UINT32 vmask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
1978   UINT32 width = 6 + texture->width;
1979
1980   for (int x = extent.startx; x < extent.stopx; x++)
1981   {
1982      if (z < zb[x])
1983      {
1984         UINT32 texel;
1985         TEX_FETCH();
1986
1987         UINT32 fa = texel >> 24;
1988         if (fa >= 0xf8)
1989         {           
1990            UINT32 r = ((texel & 0x00ff0000) * fa) >> 8;
1991            UINT32 g = ((texel & 0x0000ff00) * fa) >> 8;
1992            UINT32 b = ((texel & 0x000000ff) * fa) >> 8;
1993           
1994            UINT32 orig = fb[x];
1995           
1996            int minalpha = 255 - fa;
1997           
1998            r += ((orig & 0x00ff0000) * minalpha) >> 8;
1999            g += ((orig & 0x0000ff00) * minalpha) >> 8;
2000            b += ((orig & 0x000000ff) * minalpha) >> 8;
2001           
2002            fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
2003            zb[x] = z;
2004         }
2005      }
2006
2007      ooz += dooz;
2008      uoz += duoz;
2009      voz += dvoz;
2010      in += inz;
2011      z += dz;
2012   }
2013}
2014
2015void model3_renderer::draw_scanline_tex_trans(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
2016{
2017   UINT32 *fb = &m_fb->pix32(scanline);
2018   float *zb = (float*)&m_zb->pix32(scanline);
2019   const cached_texture *texture = polydata.texture;
2020
2021   float z = extent.param[0].start;
2022   float dz = extent.param[0].dpdx;
2023   float ooz = extent.param[1].start;
2024   float dooz = extent.param[1].dpdx;
2025   float uoz = extent.param[2].start;
2026   float duoz = extent.param[2].dpdx;
2027   float voz = extent.param[3].start;
2028   float dvoz = extent.param[3].dpdx;
2029   float in = extent.param[4].start;
2030   float inz = extent.param[4].dpdx;
2031
2032   int srctrans = polydata.transparency;
2033   int desttrans = 32 - polydata.transparency;
2034
2035   UINT32 umask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
2036   UINT32 vmask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
2037   UINT32 width = 6 + texture->width;
2038
2039   for (int x = extent.startx; x < extent.stopx; x++)
2040   {
2041      if (z < zb[x])
2042      {
2043         UINT32 texel;
2044         TEX_FETCH();
2045
2046         int ii = (int)in;
2047
2048         UINT32 r = ((texel & 0x00ff0000) * ii) >> 8;
2049         UINT32 g = ((texel & 0x0000ff00) * ii) >> 8;
2050         UINT32 b = ((texel & 0x000000ff) * ii) >> 8;
2051
2052         r = (r * srctrans) >> 5;
2053         g = (g * srctrans) >> 5;
2054         b = (b * srctrans) >> 5;
2055         
2056         UINT32 orig = fb[x];
2057         
2058         r += ((orig & 0x00ff0000) * desttrans) >> 5;
2059         g += ((orig & 0x0000ff00) * desttrans) >> 5;
2060         b += ((orig & 0x000000ff) * desttrans) >> 5;
2061
2062         fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
2063         zb[x] = z;
2064      }
2065
2066      ooz += dooz;
2067      uoz += duoz;
2068      voz += dvoz;
2069      in += inz;
2070      z += dz;
2071   }
2072}
2073
2074void model3_renderer::draw_scanline_tex_alpha(INT32 scanline, const extent_t &extent, const model3_polydata &polydata, int threadid)
2075{
2076   UINT32 *fb = &m_fb->pix32(scanline);
2077   float *zb = (float*)&m_zb->pix32(scanline);
2078   const cached_texture *texture = polydata.texture;
2079
2080   float z = extent.param[0].start;
2081   float dz = extent.param[0].dpdx;
2082   float ooz = extent.param[1].start;
2083   float dooz = extent.param[1].dpdx;
2084   float uoz = extent.param[2].start;
2085   float duoz = extent.param[2].dpdx;
2086   float voz = extent.param[3].start;
2087   float dvoz = extent.param[3].dpdx;
2088   float in = extent.param[4].start;
2089   float inz = extent.param[4].dpdx;
2090
2091//   int srctrans = polydata.transparency;
2092//   int desttrans = 32 - polydata.transparency;
2093
2094   UINT32 umask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_U) ? 64 : 32) << texture->width) - 1;
2095   UINT32 vmask = (((polydata.texture_param & TRI_PARAM_TEXTURE_MIRROR_V) ? 64 : 32) << texture->height) - 1;
2096   UINT32 width = 6 + texture->width;
2097
2098   for (int x = extent.startx; x < extent.stopx; x++)
2099   {
2100      if (z < zb[x])
2101      {
2102         UINT32 texel;
2103         TEX_FETCH();
2104
2105         UINT32 fa = texel >> 24;
2106         if (fa != 0)
2107         {
2108            int ii = (int)in;
2109
2110            UINT32 r = ((texel & 0x00ff0000) * ii) >> 8;
2111            UINT32 g = ((texel & 0x0000ff00) * ii) >> 8;
2112            UINT32 b = ((texel & 0x000000ff) * ii) >> 8;
2113
2114            r = (r * fa) >> 8;
2115            g = (g * fa) >> 8;
2116            b = (b * fa) >> 8;
2117
2118            UINT32 orig = fb[x];
2119
2120            int minalpha = 255 - fa;
2121            r += ((orig & 0x00ff0000) * minalpha) >> 8;
2122            g += ((orig & 0x0000ff00) * minalpha) >> 8;
2123            b += ((orig & 0x000000ff) * minalpha) >> 8;
2124
2125            fb[x] = 0xff000000 | (r & 0xff0000) | (g & 0xff00) | (b & 0xff);
2126            zb[x] = z;
2127         }
2128      }
2129
2130      ooz += dooz;
2131      uoz += duoz;
2132      voz += dvoz;
2133      in += inz;
2134      z += dz;
2135   }
15472136}
No newline at end of file
trunk/src/mame/drivers/model3.c
r32673r32674
1313    Step 2.1: 166 MHz PPC, same 3D engine as 2.0, differences unknown
1414
1515    Game status:
16    vf3/vf3a/vf3tb - don't boot - stuck in poly_wait()
17    bass - boots and runs with 3D
16    vf3/vf3a/vf3tb - crashes
17    bass - works
1818    getbass - I/O board error (?)
1919
20    scud/scuda - boots and runs with 3D (scuda says "for sale and use only in Japan" but is marked Export?)
21    scudj - boots but hangs up (no SCSI IRQs)
22    scudp - shows initial screen, apparently won't go into test mode or advance
23    lostwsga - SCSI IRQ stuck on (boots and runs with 3D if hacked)
24    vs215 - boots and runs with 3D
25    lemans24 - SCSI IRQ stuck on (boots if hacked)
26    vs29815 - write to unknown 53c810 SCSI register
20    scud/scuda - works (scuda says "for sale and use only in Japan" but is marked Export?)
21    scudj - works
22    scudplus - works
23    lostwsga - works
24    vs215 - works
25    lemans24 - works
26    vs29815 - massive memory trashing and page faults
2727
28    vs2 - looks like it should boot but never displays anything
29    harley - boots and runs with 3D after a "NO DAUGHTER BOARD DETECTED" error
30    skichamp - "NO DAUGHTER BOARD DETECTED", doesn't advance (no SCSI IRQs occur)
31    srally2/sraly2dx - doesn't boot (no SCSI IRQs occur, other IRQs look fine)
32    von2/von254g - SCSI IRQ stuck on (boots and runs if SCSI ack is hacked)
33    fvipers2 - says "ONE PROCESSOR DETECTED" and hangs (no SCSI IRQs occur, others look fine)
34    vs298/vs299/vs2v991 - hangs (no SCSI IRQs occur, others look fine)
28    vs2 - waiting for decrementer (same code as eca)
29    harley -
30    skichamp - waiting for decrementer
31    srally2/sraly2dx - works
32    von2/von254g - works
33    fvipers2 - waiting for decrementer (same code as eca)
34    vs298/vs299/vs2v991 - waiting for decrementer
35   oceanhun - same as daytona2
36   lamachin - works
3537
3638    dayto2pe - bug in DRC MMU page-fault handling, causes infinite loop at PC:0x2270 (or debug assert)
3739    daytona2 - As above.
3840    spikeout/spikeofe - As above.
39    dirtdvls/dirtdvla - SCSI IRQ stuck on (boots partially if hacked)
40    swtrilgy - doesn't boot (no SCSI IRQs occur, other IRQs look fine)
41    swtrilga - SCSI IRQ stuck on
42    magtruck - SCSI IRQ stuck on (boots and fails country code check (!) if hacked)
43    eca/ecax - doesn't boot (a few SCSI IRQs occur but then cease, other IRQs look fine)
41    dirtdvls/dirtdvla - works
42    swtrilgy -
43    swtrilga -
44    magtruck - works
45    eca/ecax - waiting for decrementer   
4446
4547===================================================================================
4648
r32673r32674
12421244   m_m3_step = step; // step = BCD hardware rev.  0x10 for 1.0, 0x15 for 1.5, 0x20 for 2.0, etc.
12431245   tap_reset();
12441246
1245   if (step < 0x20) {
1246      if( core_stricmp(machine().system().name, "vs215") == 0 ||
1247         core_stricmp(machine().system().name, "vs29815") == 0 ||
1248         core_stricmp(machine().system().name, "bass") == 0 )
1247   if (step < 0x20)
1248   {
1249      if (m_step15_with_mpc106)
12491250      {
12501251         mpc106_init(machine());
12511252      }
r32673r32674
12551256      }
12561257      m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
12571258   }
1258   else {
1259   else
1260   {
12591261      mpc106_init(machine());
12601262      // some step 2+ games need the older PCI ID (obvious symptom:
12611263      // vbl is enabled briefly then disabled so the game hangs)
1262      if (core_stricmp(machine().system().name, "magtruck") == 0 ||
1263         core_stricmp(machine().system().name, "von254g") == 0)
1264      if (m_step20_with_old_real3d)
12641265      {
12651266         m_real3d_device_id = 0x16c311db; /* PCI Vendor ID (11db = SEGA), Device ID (16c3 = 315-5827) */
12661267      }
r32673r32674
56465647
56475648DRIVER_INIT_MEMBER(model3_state,scud)
56485649{
5649   UINT32 *rom = (UINT32*)memregion("user1")->base();
5650
56515650   DRIVER_INIT_CALL(model3_15);
56525651   /* TODO: network device at 0xC0000000 - FF */
56535652   m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xf9000000, 0xf90000ff, read64_delegate(FUNC(model3_state::scsi_r),this), write64_delegate(FUNC(model3_state::scsi_w),this));
5654
5655   rom[(0x71275c^4)/4] = 0x60000000;
5656   rom[(0x71277c^4)/4] = 0x60000000;
56575653}
56585654
56595655DRIVER_INIT_MEMBER(model3_state,scudplus)
56605656{
5661   UINT32 *rom = (UINT32*)memregion("user1")->base();
5662
56635657   DRIVER_INIT_CALL(model3_15);
56645658   /* TODO: network device at 0xC0000000 - FF */
56655659   m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xc1000000, 0xc10000ff, read64_delegate(FUNC(model3_state::scsi_r),this), write64_delegate(FUNC(model3_state::scsi_w),this));
5666
5667   rom[(0x713724^4)/4] = 0x60000000;
5668   rom[(0x713744^4)/4] = 0x60000000;
5669
5670   rom[(0x741f48^4)/4] = 0x60000000;
5671
5672   rom[(0x741f68^4)/4] = 0x60000000;
5673   rom[(0x741efc^4)/4] = 0x60000000;
56745660}
56755661
56765662DRIVER_INIT_MEMBER(model3_state,scudplusa)
56775663{
5678   //UINT32 *rom = (UINT32*)memregion("user1")->base();
5679
56805664   DRIVER_INIT_CALL(model3_15);
56815665   /* TODO: network device at 0xC0000000 - FF */
56825666   m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xc1000000, 0xc10000ff, read64_delegate(FUNC(model3_state::scsi_r),this), write64_delegate(FUNC(model3_state::scsi_w),this));
5683
5684   //rom[(0x713724^4)/4] = 0x60000000; // Fix ME!!!! Needs to corrected for the non REV A version!!!!
5685   //rom[(0x713744^4)/4] = 0x60000000;
5686
5687   //rom[(0x741f48^4)/4] = 0x60000000;
5688
5689   //rom[(0x741f68^4)/4] = 0x60000000;
5690   //rom[(0x741efc^4)/4] = 0x60000000;
56915667}
56925668
56935669DRIVER_INIT_MEMBER(model3_state,lemans24)
56945670{
5695   UINT32 *rom = (UINT32*)memregion("user1")->base();
56965671   DRIVER_INIT_CALL(model3_15);
56975672
56985673   m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xc1000000, 0xc10000ff, read64_delegate(FUNC(model3_state::scsi_r),this), write64_delegate(FUNC(model3_state::scsi_w),this));
5699
5700   rom[(0x73fe38^4)/4] = 0x38840004;       /* This seems to be an actual bug in the original code */
5701
5702   rom[(0x73eb5c^4)/4] = 0x60000000;
5703   rom[(0x73edd0^4)/4] = 0x60000000;
5704   rom[(0x73edc4^4)/4] = 0x60000000;
5674   
5675//   rom[(0x73fe38^4)/4] = 0x38840004;       /* This seems to be an actual bug in the original code */
57055676}
57065677
57075678DRIVER_INIT_MEMBER(model3_state,vf3)
57085679{
5709   UINT32 *rom = (UINT32*)memregion("user1")->base();
5680   //UINT32 *rom = (UINT32*)memregion("user1")->base();
57105681
57115682   DRIVER_INIT_CALL(model3_10);
57125683
5684   /*
57135685   rom[(0x713c7c^4)/4] = 0x60000000;
57145686   rom[(0x713e54^4)/4] = 0x60000000;
57155687   rom[(0x7125b0^4)/4] = 0x60000000;
57165688   rom[(0x7125d0^4)/4] = 0x60000000;
5717
5689   */
57185690}
57195691
57205692DRIVER_INIT_MEMBER(model3_state,vs215)
57215693{
5722   UINT32 *rom = (UINT32*)memregion("user1")->base();
5694   m_step15_with_mpc106 = true;
57235695
5724   rom[(0x70dde0^4)/4] = 0x60000000;
5725   rom[(0x70e6f0^4)/4] = 0x60000000;
5726   rom[(0x70e710^4)/4] = 0x60000000;
5727
57285696   interleave_vroms(machine());
57295697   m_maincpu->space(AS_PROGRAM).install_read_bank(0xff000000, 0xff7fffff, "bank1" );
57305698
r32673r32674
57395707
57405708DRIVER_INIT_MEMBER(model3_state,vs29815)
57415709{
5710   m_step15_with_mpc106 = true;
5711
57425712   UINT32 *rom = (UINT32*)memregion("user1")->base();
57435713
57445714   rom[(0x6028ec^4)/4] = 0x60000000;
r32673r32674
57585728
57595729DRIVER_INIT_MEMBER(model3_state,bass)
57605730{
5761   UINT32 *rom = (UINT32*)memregion("user1")->base();
5731   m_step15_with_mpc106 = true;
57625732
5763   rom[(0x7999a8^4)/4] = 0x60000000;
5764   rom[(0x7999c8^4)/4] = 0x60000000;
5765
57665733   interleave_vroms(machine());
57675734   m_maincpu->space(AS_PROGRAM).install_read_bank(0xff000000, 0xff7fffff, "bank1" );
57685735
r32673r32674
58655832
58665833DRIVER_INIT_MEMBER(model3_state,harleya)
58675834{
5868   UINT32 *rom = (UINT32*)memregion("user1")->base();
5835   //UINT32 *rom = (UINT32*)memregion("user1")->base();
58695836   DRIVER_INIT_CALL(model3_20);
58705837
58715838   m_network_ram = auto_alloc_array_clear(machine(), UINT64, 0x10000);
58725839   m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0xc0000000, 0xc00fffff, read64_delegate(FUNC(model3_state::network_r),this), write64_delegate(FUNC(model3_state::network_w),this));
58735840
5841   /*
58745842   rom[(0x50e8d4^4)/4] = 0x60000000;
58755843   rom[(0x50e8f4^4)/4] = 0x60000000;
58765844   rom[(0x50fb84^4)/4] = 0x60000000;
58775845   rom[(0x4f736c^4)/4] = 0x60000000;
58785846   rom[(0x4f738c^4)/4] = 0x60000000;
5847   */
58795848}
58805849
58815850
58825851DRIVER_INIT_MEMBER(model3_state,srally2)
5883{
5884   UINT32 *rom = (UINT32*)memregion("user1")->base();
5852{   
58855853   DRIVER_INIT_CALL(model3_20);
58865854
5855
5856   UINT32 *rom = (UINT32*)memregion("user1")->base();   
58875857   rom[(0x7c0c4^4)/4] = 0x60000000;
58885858   rom[(0x7c0c8^4)/4] = 0x60000000;
58895859   rom[(0x7c0cc^4)/4] = 0x60000000;
5860   // Writes command 000023FFFFFFFFFE to JTAG, expects result 0x0040000000 (41 bits)
5861   // Writes command 000003FFFFFFFFFE
5862   // Writes command 00003FFFFFFFFFFE 248 times
5863   // Writes command 000023FFFFFFFFFE, expects result 0x01000000000 (?? bits)
58905864}
58915865
58925866DRIVER_INIT_MEMBER(model3_state,swtrilgy)
58935867{
5894   UINT32 *rom = (UINT32*)memregion("user1")->base();
5868   //UINT32 *rom = (UINT32*)memregion("user1")->base();
58955869   DRIVER_INIT_CALL(model3_20);
58965870
5871   /*
58975872   rom[(0xf0e48^4)/4] = 0x60000000;
58985873   rom[(0x043dc^4)/4] = 0x48000090;
58995874   rom[(0x029a0^4)/4] = 0x60000000;
59005875   rom[(0x02a0c^4)/4] = 0x60000000;
5876   */
59015877}
59025878
59035879DRIVER_INIT_MEMBER(model3_state,swtrilga)
59045880{
5905   UINT32 *rom = (UINT32*)memregion("user1")->base();
5881   //UINT32 *rom = (UINT32*)memregion("user1")->base();
59065882   DRIVER_INIT_CALL(model3_20);
59075883
5908   rom[(0xf6dd0^4)/4] = 0x60000000;
5884   //rom[(0xf6dd0^4)/4] = 0x60000000;
59095885}
59105886
59115887DRIVER_INIT_MEMBER(model3_state,von2)
59125888{
5913   UINT32 *rom = (UINT32*)memregion("user1")->base();
5889   m_step20_with_old_real3d = true;
5890   
59145891   DRIVER_INIT_CALL(model3_20);
5915
5916   rom[(0x189168^4)/4] = 0x60000000;
5917   rom[(0x1890ac^4)/4] = 0x60000000;
5918   rom[(0x1890b8^4)/4] = 0x60000000;
5919   rom[(0x1888a8^4)/4] = 0x60000000;
5920   rom[(0x1891c8^4)/4] = 0x60000000;
59215892}
59225893
59235894DRIVER_INIT_MEMBER(model3_state,dirtdvls)
59245895{
5925   UINT32 *rom = (UINT32*)memregion("user1")->base();
5926   DRIVER_INIT_CALL(model3_20);
5896   m_step20_with_old_real3d = true;
59275897
5928   rom[(0x0600a0^4)/4] = 0x60000000;
5929   rom[(0x0608a4^4)/4] = 0x60000000;
5930   rom[(0x0608b0^4)/4] = 0x60000000;
5931   rom[(0x060960^4)/4] = 0x60000000;
5932   rom[(0x0609c0^4)/4] = 0x60000000;
5933   rom[(0x001e24^4)/4] = 0x60000000;
5898   DRIVER_INIT_CALL(model3_20);
59345899}
59355900
59365901DRIVER_INIT_MEMBER(model3_state,daytona2)
r32673r32674
59825947
59835948DRIVER_INIT_MEMBER(model3_state,eca)
59845949{
5985   UINT32 *rom = (UINT32*)memregion("user1")->base();
5950//   UINT32 *rom = (UINT32*)memregion("user1")->base();
59865951   DRIVER_INIT_CALL(model3_20);
59875952
5988   
5953   /*
59895954   rom[(0x535560^4)/4] = 0x60000000;
59905955   rom[(0x535580^4)/4] = 0x60000000;   
5956   */
59915957}
59925958
59935959DRIVER_INIT_MEMBER(model3_state,skichamp)
59945960{
5995   UINT32 *rom = (UINT32*)memregion("user1")->base();
5961   //UINT32 *rom = (UINT32*)memregion("user1")->base();
59965962   DRIVER_INIT_CALL(model3_20);
59975963
5964   /*
59985965   rom[(0x5263c8^4)/4] = 0x60000000;
59995966   rom[(0x5263e8^4)/4] = 0x60000000;
60005967   rom[(0x516bbc^4)/4] = 0x60000000;
60015968   rom[(0x516b9c^4)/4] = 0x60000000; // decrementer
5969   */
60025970}
60035971
60045972DRIVER_INIT_MEMBER(model3_state,oceanhun)
r32673r32674
60115979
60125980DRIVER_INIT_MEMBER(model3_state,magtruck)
60135981{
5982   m_step20_with_old_real3d = true;
5983
60145984   DRIVER_INIT_CALL(model3_20);
60155985}
60165986
5987DRIVER_INIT_MEMBER(model3_state,lamachin)
5988{
5989   m_step20_with_old_real3d = true;
60175990
5991   DRIVER_INIT_CALL(model3_20);
5992}
5993
5994
60185995/* Model 3 Step 1.0 */
60195996GAME( 1996, vf3,            0, model3_10, model3, model3_state,        vf3, ROT0, "Sega", "Virtua Fighter 3 (Revision C)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60205997GAME( 1996, vf3a,         vf3, model3_10, model3, model3_state,        vf3, ROT0, "Sega", "Virtua Fighter 3 (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
r32673r32674
60396016GAME( 1997, vs2,            0, model3_20, model3, model3_state,        vs2, ROT0, "Sega", "Virtua Striker 2 (Step 2.0)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60406017GAME( 1997, harley,         0, model3_20, harley, model3_state,     harley, ROT0, "Sega", "Harley-Davidson and L.A. Riders (Revision B)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60416018GAME( 1997, harleya,   harley, model3_20, harley, model3_state,     harleya, ROT0, "Sega", "Harley-Davidson and L.A. Riders (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6042GAME( 1998, lamachin,       0, model3_20, model3, model3_state,  model3_20, ROT0, "Sega", "L.A. Machineguns", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6019GAME( 1998, lamachin,       0, model3_20, model3, model3_state,  lamachin, ROT0, "Sega", "L.A. Machineguns", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60436020GAME( 1998, oceanhun,       0, model3_20, model3, model3_state,   oceanhun, ROT0, "Sega", "The Ocean Hunter", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60446021GAME( 1998, skichamp,       0, model3_20, skichamp, model3_state, skichamp, ROT0, "Sega", "Ski Champ", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60456022GAME( 1998, srally2,        0, model3_20, scud, model3_state,      srally2, ROT0, "Sega", "Sega Rally 2", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60466023GAME( 1998, srally2x,       0, model3_20, scud, model3_state,      srally2, ROT0, "Sega", "Sega Rally 2 DX", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60476024GAME( 1998, von2,           0, model3_20, model3, model3_state,       von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (Revision B)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6048GAME( 1998, von254g,     von2, model3_20, model3, model3_state,  model3_20, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (ver 5.4g)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
6025GAME( 1998, von254g,     von2, model3_20, model3, model3_state,       von2, ROT0, "Sega", "Virtual On 2: Oratorio Tangram (ver 5.4g)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60496026GAME( 1998, fvipers2,       0, model3_20, model3, model3_state,  model3_20, ROT0, "Sega", "Fighting Vipers 2 (Revision A)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60506027GAME( 1998, vs298,          0, model3_20, model3, model3_state,      vs298, ROT0, "Sega", "Virtua Striker 2 '98 (Step 2.0)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )
60516028GAME( 1999, vs2v991,        0, model3_20, model3, model3_state,    vs2v991, ROT0, "Sega", "Virtua Striker 2 '99.1 (Revision B)", GAME_NOT_WORKING | GAME_IMPERFECT_GRAPHICS | GAME_IMPERFECT_SOUND )

Previous 199869 Revisions Next


© 1997-2024 The MAME Team