1 // license:BSD-3-Clause
2 // copyright-holders:R. Belmont, Olivier Galibert, ElSemi, Angelo Salese
3 #ifndef MAME_INCLUDES_MODEL2_H
4 #define MAME_INCLUDES_MODEL2_H
5
6 #pragma once
7
8 #include "audio/dsbz80.h"
9 #include "audio/segam1audio.h"
10 #include "cpu/i960/i960.h"
11 #include "cpu/mb86233/mb86233.h"
12 #include "cpu/sharc/sharc.h"
13 #include "cpu/mb86235/mb86235.h"
14 #include "machine/315-5881_crypt.h"
15 #include "machine/315-5838_317-0229_comp.h"
16 #include "machine/bankdev.h"
17 #include "machine/eepromser.h"
18 #include "machine/gen_fifo.h"
19 #include "machine/i8251.h"
20 #include "machine/m2comm.h"
21 #include "machine/segabill.h"
22 #include "machine/timer.h"
23 #include "sound/scsp.h"
24 #include "video/segaic24.h"
25 #include "video/poly.h"
26 #include "emupal.h"
27 #include "screen.h"
28
29 #include <algorithm>
30
31
32 class model2_renderer;
33
34 class model2_state : public driver_device
35 {
36 public:
37 struct plane;
38 struct texture_parameter;
39 struct triangle;
40 struct quad_m2;
41 struct raster_state;
42 struct geo_state;
43
model2_state(const machine_config & mconfig,device_type type,const char * tag)44 model2_state(const machine_config &mconfig, device_type type, const char *tag) :
45 driver_device(mconfig, type, tag),
46 m_textureram0(*this, "textureram0"),
47 m_textureram1(*this, "textureram1"),
48 m_workram(*this, "workram"),
49 m_bufferram(*this, "bufferram"),
50 m_soundram(*this, "soundram"),
51 m_maincpu(*this,"maincpu"),
52 m_dsbz80(*this, DSBZ80_TAG),
53 m_m1audio(*this, M1AUDIO_TAG),
54 m_uart(*this, "uart"),
55 m_m2comm(*this, "m2comm"),
56 m_audiocpu(*this, "audiocpu"),
57 m_copro_fifo_in(*this, "copro_fifo_in"),
58 m_copro_fifo_out(*this, "copro_fifo_out"),
59 m_drivecpu(*this, "drivecpu"),
60 m_eeprom(*this, "eeprom"),
61 m_tiles(*this, "tile"),
62 m_screen(*this, "screen"),
63 m_palette(*this, "palette"),
64 m_scsp(*this, "scsp"),
65 m_timers(*this, "timer%u", 0U),
66 m_cryptdevice(*this, "315_5881"),
67 m_0229crypt(*this, "317_0229"),
68 m_copro_data(*this, "copro_data"),
69 m_in0(*this, "IN0"),
70 m_gears(*this, "GEARS"),
71 m_lightgun_ports(*this, {"P1_Y", "P1_X", "P2_Y", "P2_X"})
72 { }
73
74 /* Public for access by the rendering functions */
75 required_shared_ptr<u32> m_textureram0;
76 required_shared_ptr<u32> m_textureram1;
77 std::unique_ptr<u16[]> m_palram;
78 std::unique_ptr<u16[]> m_colorxlat;
79 std::unique_ptr<u16[]> m_lumaram;
80 u8 m_gamma_table[256];
81 std::unique_ptr<model2_renderer> m_poly;
82
83 /* Public for access by the ioports */
84 DECLARE_CUSTOM_INPUT_MEMBER(daytona_gearbox_r);
85
86 /* Public for access by MCFG */
87 TIMER_DEVICE_CALLBACK_MEMBER(model2_interrupt);
88 u16 crypt_read_callback(u32 addr);
89 DECLARE_MACHINE_START(model2);
90
91
92 /* Public for access by GAME() */
93 void init_overrev();
94 void init_pltkids();
95 void init_rchase2();
96 void init_manxttdx();
97 void init_doa();
98 void init_zerogun();
99 void init_sgt24h();
100 void init_srallyc();
101 void init_powsledm();
102
103 protected:
104 virtual void machine_start() override;
105 virtual void machine_reset() override;
106
107 required_shared_ptr<u32> m_workram;
108 required_shared_ptr<u32> m_bufferram;
109 std::unique_ptr<u16[]> m_fbvramA;
110 std::unique_ptr<u16[]> m_fbvramB;
111 optional_shared_ptr<u16> m_soundram;
112
113 required_device<i960_cpu_device> m_maincpu;
114 optional_device<dsbz80_device> m_dsbz80; // Z80-based MPEG Digital Sound Board
115 optional_device<segam1audio_device> m_m1audio; // Model 1 standard sound board
116 required_device<i8251_device> m_uart;
117 optional_device<m2comm_device> m_m2comm; // Model 2 communication board
118 optional_device<cpu_device> m_audiocpu;
119 required_device<generic_fifo_u32_device> m_copro_fifo_in;
120 required_device<generic_fifo_u32_device> m_copro_fifo_out;
121 optional_device<cpu_device> m_drivecpu;
122 optional_device<eeprom_serial_93cxx_device> m_eeprom;
123 required_device<segas24_tile_device> m_tiles;
124 required_device<screen_device> m_screen;
125 required_device<palette_device> m_palette;
126 optional_device<scsp_device> m_scsp;
127 required_device_array<timer_device, 4> m_timers;
128 optional_device<sega_315_5881_crypt_device> m_cryptdevice;
129 optional_device<sega_315_5838_comp_device> m_0229crypt;
130 optional_memory_region m_copro_data;
131
132 required_ioport m_in0;
133 optional_ioport m_gears;
134 optional_ioport_array<4> m_lightgun_ports;
135
136 u32 m_timervals[4];
137 u32 m_timerorig[4];
138 int m_timerrun[4];
139 int m_ctrlmode;
140 u16 m_cmd_data;
141 u8 m_driveio_comm_data;
142 int m_iop_write_num;
143 u32 m_iop_data;
144 int m_geo_iop_write_num;
145 u32 m_geo_iop_data;
146
147 u32 m_geo_read_start_address;
148 u32 m_geo_write_start_address;
149 std::unique_ptr<raster_state> m_raster;
150 std::unique_ptr<geo_state> m_geo;
151 bitmap_rgb32 m_sys24_bitmap;
152 // u32 m_soundack;
153 void model2_check_irq_state();
154 void model2_check_irqack_state(u32 data);
155 u8 m_gearsel;
156 u8 m_lightgun_mux;
157
158 // Coprocessor communications
159 u32 copro_prg_r();
160 u32 copro_ctl1_r();
161 void copro_ctl1_w(offs_t offset, u32 data, u32 mem_mask = ~0);
162 u32 copro_status_r();
163
164 // Geometrizer communications
165 void geo_ctl1_w(u32 data);
166 u32 geo_prg_r(offs_t offset);
167 void geo_prg_w(u32 data);
168 u32 geo_r(offs_t offset);
169 void geo_w(offs_t offset, u32 data);
170
171 // Everything else
172 u32 timers_r(offs_t offset);
173 void timers_w(offs_t offset, u32 data, u32 mem_mask = ~0);
174 u16 palette_r(offs_t offset);
175 void palette_w(offs_t offset, u16 data, u16 mem_mask = ~0);
176 u16 colorxlat_r(offs_t offset);
177 void colorxlat_w(offs_t offset, u16 data, u16 mem_mask = ~0);
178 void eeprom_w(u8 data);
179 u8 in0_r();
180 u32 fifo_control_2a_r();
181 u32 videoctl_r();
182 void videoctl_w(offs_t offset, u32 data, u32 mem_mask = ~0);
183 u8 rchase2_drive_board_r();
184 void rchase2_drive_board_w(u8 data);
185 void drive_board_w(u8 data);
186 u8 lightgun_data_r(offs_t offset);
187 u8 lightgun_mux_r();
188 void lightgun_mux_w(u8 data);
189 u8 lightgun_offscreen_r(offs_t offset);
190 u32 irq_request_r();
191 void irq_ack_w(u32 data);
192 u32 irq_enable_r();
193 void irq_enable_w(offs_t offset, u32 data, u32 mem_mask = ~0);
194 u32 model2_serial_r(offs_t offset, u32 mem_mask = ~0);
195 void model2_serial_w(offs_t offset, u32 data, u32 mem_mask = ~0);
196 void horizontal_sync_w(u16 data);
197 void vertical_sync_w(u16 data);
198 u32 doa_prot_r(offs_t offset, u32 mem_mask = ~0);
199 u32 doa_unk_r();
200 void sega_0229_map(address_map &map);
201 int m_prot_a;
202
203 void raster_init(memory_region *texture_rom);
204 void geo_init(memory_region *polygon_rom);
205 u32 render_mode_r();
206 void render_mode_w(u32 data);
207 u16 lumaram_r(offs_t offset);
208 void lumaram_w(offs_t offset, u16 data, u16 mem_mask = ~0);
209 u16 fbvram_bankA_r(offs_t offset);
210 void fbvram_bankA_w(offs_t offset, u16 data, u16 mem_mask = ~0);
211 u16 fbvram_bankB_r(offs_t offset);
212 void fbvram_bankB_w(offs_t offset, u16 data, u16 mem_mask = ~0);
213 void model2_3d_zclip_w(u32 data);
214 void model2snd_ctrl(u16 data);
215 u8 tgpid_r(offs_t offset);
216 u32 polygon_count_r();
217
218 u8 driveio_portg_r();
219 u8 driveio_porth_r();
220 void driveio_port_w(u8 data);
221 void push_geo_data(u32 data);
222 DECLARE_VIDEO_START(model2);
223 void reset_model2_scsp();
224 u32 screen_update_model2(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
225 // DECLARE_WRITE_LINE_MEMBER(screen_vblank_model2);
226 // DECLARE_WRITE_LINE_MEMBER(sound_ready_w);
227 TIMER_DEVICE_CALLBACK_MEMBER(model2_timer_cb);
228 void scsp_irq(offs_t offset, u8 data);
229
230 void model2_3d_frame_start( void );
231 void geo_parse( void );
232 void model2_3d_frame_end( bitmap_rgb32 &bitmap, const rectangle &cliprect );
233 void draw_framebuffer(bitmap_rgb32 &bitmap, const rectangle &cliprect );
234
235 void model2_timers(machine_config &config);
236 void model2_screen(machine_config &config);
237 void model2_scsp(machine_config &config);
238
239 void sj25_0207_01(machine_config &config);
240
241 void drive_io_map(address_map &map);
242 void drive_map(address_map &map);
243 void geo_sharc_map(address_map &map);
244 void model2_base_mem(address_map &map);
245 void model2_5881_mem(address_map &map);
246 void model2_0229_mem(address_map &map);
247 void model2_snd(address_map &map);
248 void scsp_map(address_map &map);
249
250 void debug_init();
251 void debug_commands( int ref, const std::vector<std::string> ¶ms );
252 void debug_geo_dasm_command(int ref, const std::vector<std::string> ¶ms);
253 void debug_tri_dump_command(int ref, const std::vector<std::string> ¶ms);
254 void debug_help_command(int ref, const std::vector<std::string> ¶ms);
255
256 virtual void video_start() override;
257
258 u32 m_intreq;
259 u32 m_intena;
260 u32 m_coproctl;
261 u32 m_coprocnt;
262
263 virtual void copro_halt() = 0;
264 virtual void copro_boot() = 0;
265
266 private:
267 void tri_list_dump(FILE *dst);
268
269 u32 m_geoctl;
270 u32 m_geocnt;
271 u32 m_videocontrol;
272
273 bool m_render_unk;
274 bool m_render_mode;
275 bool m_render_test_mode;
276 int16 m_crtc_xoffset, m_crtc_yoffset;
277
278 u32 *geo_process_command( geo_state *geo, u32 opcode, u32 *input, bool *end_code );
279 // geo commands
280 u32 *geo_nop( geo_state *geo, u32 opcode, u32 *input );
281 u32 *geo_object_data( geo_state *geo, u32 opcode, u32 *input );
282 u32 *geo_direct_data( geo_state *geo, u32 opcode, u32 *input );
283 u32 *geo_window_data( geo_state *geo, u32 opcode, u32 *input );
284 u32 *geo_texture_data( geo_state *geo, u32 opcode, u32 *input );
285 u32 *geo_polygon_data( geo_state *geo, u32 opcode, u32 *input );
286 u32 *geo_texture_parameters( geo_state *geo, u32 opcode, u32 *input );
287 u32 *geo_mode( geo_state *geo, u32 opcode, u32 *input );
288 u32 *geo_zsort_mode( geo_state *geo, u32 opcode, u32 *input );
289 u32 *geo_focal_distance( geo_state *geo, u32 opcode, u32 *input );
290 u32 *geo_light_source( geo_state *geo, u32 opcode, u32 *input );
291 u32 *geo_matrix_write( geo_state *geo, u32 opcode, u32 *input );
292 u32 *geo_translate_write( geo_state *geo, u32 opcode, u32 *input );
293 u32 *geo_data_mem_push( geo_state *geo, u32 opcode, u32 *input );
294 u32 *geo_test( geo_state *geo, u32 opcode, u32 *input );
295 u32 *geo_end( geo_state *geo, u32 opcode, u32 *input );
296 u32 *geo_dummy( geo_state *geo, u32 opcode, u32 *input );
297 u32 *geo_log_data( geo_state *geo, u32 opcode, u32 *input );
298 u32 *geo_lod( geo_state *geo, u32 opcode, u32 *input );
299 u32 *geo_code_upload( geo_state *geo, u32 opcode, u32 *input );
300 u32 *geo_code_jump( geo_state *geo, u32 opcode, u32 *input );
301 // geo code drawing paths
302 void geo_parse_np_ns( geo_state *geo, u32 *input, u32 count );
303 void geo_parse_np_s( geo_state *geo, u32 *input, u32 count );
304 void geo_parse_nn_ns( geo_state *geo, u32 *input, u32 count );
305 void geo_parse_nn_s( geo_state *geo, u32 *input, u32 count );
306
307 // raster functions
308 // main data input port
309 void model2_3d_push( raster_state *raster, u32 input );
310 // quad & triangle push paths
311 void model2_3d_process_quad( raster_state *raster, u32 attr );
312 void model2_3d_process_triangle( raster_state *raster, u32 attr );
313
314 // inliners
315 inline void model2_3d_project( triangle *tri );
316 inline u16 float_to_zval( float floatval );
317 inline bool check_culling( raster_state *raster, u32 attr, float min_z, float max_z );
318 };
319
320 /*****************************
321 *
322 * Model 2/2A TGP support
323 *
324 *****************************/
325
326 class model2_tgp_state : public model2_state
327 {
328 public:
model2_tgp_state(const machine_config & mconfig,device_type type,const char * tag)329 model2_tgp_state(const machine_config &mconfig, device_type type, const char *tag)
330 : model2_state(mconfig, type, tag),
331 m_copro_tgp(*this, "copro_tgp"),
332 m_copro_tgp_program(*this, "copro_tgp_program"),
333 m_copro_tgp_tables(*this, "copro_tgp_tables"),
334 m_copro_tgp_bank(*this, "copro_tgp_bank")
335 {}
336
337 protected:
338 virtual void machine_start() override;
339 virtual void machine_reset() override;
340
341 required_device<mb86234_device> m_copro_tgp;
342 required_shared_ptr<u32> m_copro_tgp_program;
343 required_region_ptr<u32> m_copro_tgp_tables;
344 required_device<address_map_bank_device> m_copro_tgp_bank;
345
346 u32 m_copro_tgp_bank_reg;
347 u32 m_copro_sincos_base;
348 u32 m_copro_inv_base;
349 u32 m_copro_isqrt_base;
350 u32 m_copro_atan_base[4];
351
352 void copro_function_port_w(offs_t offset, u32 data);
353 u32 copro_fifo_r();
354 void copro_fifo_w(u32 data);
355 void tex0_w(offs_t offset, u32 data);
356 void tex1_w(offs_t offset, u32 data);
357
358 void copro_tgp_bank_w(offs_t offset, u32 data, u32 mem_mask = ~0);
359 u32 copro_tgp_memory_r(offs_t offset);
360 void copro_tgp_memory_w(offs_t offset, u32 data, u32 mem_mask = ~0);
361
362 void copro_sincos_w(offs_t offset, u32 data, u32 mem_mask = ~0);
363 u32 copro_sincos_r(offs_t offset);
364 void copro_inv_w(offs_t offset, u32 data, u32 mem_mask = ~0);
365 u32 copro_inv_r(offs_t offset);
366 void copro_isqrt_w(offs_t offset, u32 data, u32 mem_mask = ~0);
367 u32 copro_isqrt_r(offs_t offset);
368 void copro_atan_w(offs_t offset, u32 data, u32 mem_mask = ~0);
369 u32 copro_atan_r();
370
371 void model2_tgp_mem(address_map &map);
372
373 void copro_tgp_prog_map(address_map &map);
374 void copro_tgp_data_map(address_map &map);
375 void copro_tgp_bank_map(address_map &map);
376 void copro_tgp_io_map(address_map &map);
377 void copro_tgp_rf_map(address_map &map);
378
379 virtual void copro_halt() override;
380 virtual void copro_boot() override;
381 };
382
383 /*****************************
384 *
385 * Model 2 support
386 *
387 *****************************/
388
389 class model2o_state : public model2_tgp_state
390 {
391 public:
model2o_state(const machine_config & mconfig,device_type type,const char * tag)392 model2o_state(const machine_config &mconfig, device_type type, const char *tag)
393 : model2_tgp_state(mconfig, type, tag)
394 {}
395
396 void model2o(machine_config &config);
397 void daytona(machine_config &config);
398 void desert(machine_config &config);
399 void vcop(machine_config &config);
400
401 protected:
402 u32 fifo_control_2o_r();
403 void daytona_output_w(u8 data);
404 void desert_output_w(u8 data);
405 void vcop_output_w(u8 data);
406
407 void model2o_mem(address_map &map);
408 };
409
410 /*****************************
411 *
412 * Daytona To The Maxx
413 *
414 *****************************/
415
416 class model2o_maxx_state : public model2o_state
417 {
418 public:
model2o_maxx_state(const machine_config & mconfig,device_type type,const char * tag)419 model2o_maxx_state(const machine_config &mconfig, device_type type, const char *tag)
420 : model2o_state(mconfig, type, tag)
421 {}
422
423 u32 maxx_r(offs_t offset, u32 mem_mask = ~0);
424 void daytona_maxx(machine_config &config);
425 void model2o_maxx_mem(address_map &map);
426
427 private:
428 int m_maxxstate;
429 };
430
431 /*****************************
432 *
433 * Daytona GTX 2004 Edition
434 *
435 *****************************/
436
437 class model2o_gtx_state : public model2o_state
438 {
439 public:
model2o_gtx_state(const machine_config & mconfig,device_type type,const char * tag)440 model2o_gtx_state(const machine_config &mconfig, device_type type, const char *tag)
441 : model2o_state(mconfig, type, tag)
442 {}
443
444 u8 gtx_r(offs_t offset);
445 void daytona_gtx(machine_config &config);
446 void model2o_gtx_mem(address_map &map);
447
448 private:
449 int m_gtx_state;
450 };
451
452 /*****************************
453 *
454 * Model 2A
455 *
456 *****************************/
457
458 class model2a_state : public model2_tgp_state
459 {
460 public:
model2a_state(const machine_config & mconfig,device_type type,const char * tag)461 model2a_state(const machine_config &mconfig, device_type type, const char *tag)
462 : model2_tgp_state(mconfig, type, tag),
463 m_billboard(*this, "billboard")
464 {}
465
466 void manxtt(machine_config &config);
467 void manxttdx(machine_config &config);
468 void model2a(machine_config &config);
469 void model2a_0229(machine_config &config);
470 void model2a_5881(machine_config &config);
471 void srallyc(machine_config &config);
472 void vcop2(machine_config &config);
473 void skytargt(machine_config &config);
474 void zeroguna(machine_config &config);
475
476 protected:
477 virtual void machine_reset() override;
478
479 void model2a_crx_mem(address_map &map);
480 void model2a_5881_mem(address_map &map);
481 void model2a_0229_mem(address_map &map);
482
483 private:
484 required_device<sega_billboard_device> m_billboard;
485 };
486
487 /*****************************
488 *
489 * Model 2B
490 *
491 *****************************/
492
493 class model2b_state : public model2_state
494 {
495 public:
model2b_state(const machine_config & mconfig,device_type type,const char * tag)496 model2b_state(const machine_config &mconfig, device_type type, const char *tag)
497 : model2_state(mconfig, type, tag),
498 m_copro_adsp(*this, "copro_adsp"),
499 m_billboard(*this, "billboard")
500 {}
501
502 void model2b(machine_config &config);
503 void model2b_0229(machine_config &config);
504 void model2b_5881(machine_config &config);
505 void indy500(machine_config &config);
506 void overrev2b(machine_config &config);
507 void powsled(machine_config &config);
508 void rchase2(machine_config &config);
509 void gunblade(machine_config &config);
510 void dynabb(machine_config &config);
511 void zerogun(machine_config &config);
512
513 protected:
514 virtual void machine_start() override;
515 virtual void machine_reset() override;
516
517 required_device<adsp21062_device> m_copro_adsp;
518
519 void copro_function_port_w(offs_t offset, u32 data);
520 u32 copro_fifo_r();
521 void copro_fifo_w(u32 data);
522 void copro_sharc_iop_w(offs_t offset, u32 data);
523 u32 copro_sharc_buffer_r(offs_t offset);
524 void copro_sharc_buffer_w(offs_t offset, u32 data);
525
526 void model2b_crx_mem(address_map &map);
527 void model2b_5881_mem(address_map &map);
528 void model2b_0229_mem(address_map &map);
529 // TODO: split into own class
530 void rchase2_iocpu_map(address_map &map);
531 void rchase2_ioport_map(address_map &map);
532
533 void copro_sharc_map(address_map &map);
534
535 virtual void copro_halt() override;
536 virtual void copro_boot() override;
537
538 private:
539 required_device<sega_billboard_device> m_billboard;
540 };
541
542 /*****************************
543 *
544 * Model 2C
545 *
546 *****************************/
547
548 class model2c_state : public model2_state
549 {
550 public:
model2c_state(const machine_config & mconfig,device_type type,const char * tag)551 model2c_state(const machine_config &mconfig, device_type type, const char *tag)
552 : model2_state(mconfig, type, tag),
553 m_copro_tgpx4(*this, "copro_tgpx4"),
554 m_copro_tgpx4_program(*this, "copro_tgpx4_program")
555 {}
556
557 void model2c(machine_config &config);
558 void model2c_5881(machine_config &config);
559 void skisuprg(machine_config &config);
560 void stcc(machine_config &config);
561 void waverunr(machine_config &config);
562 void bel(machine_config &config);
563 void hotd(machine_config &config);
564 void overrev2c(machine_config &config);
565 void segawski(machine_config &config);
566 void topskatr(machine_config &config);
567
568 protected:
569 virtual void machine_start() override;
570 virtual void machine_reset() override;
571
572 required_device<mb86235_device> m_copro_tgpx4;
573 required_shared_ptr<u64> m_copro_tgpx4_program;
574
575 void copro_function_port_w(offs_t offset, u32 data);
576 u32 copro_fifo_r();
577 void copro_fifo_w(u32 data);
578
579 TIMER_DEVICE_CALLBACK_MEMBER(model2c_interrupt);
580
581 void model2c_crx_mem(address_map &map);
582 void model2c_5881_mem(address_map &map);
583 void copro_tgpx4_map(address_map &map);
584 void copro_tgpx4_data_map(address_map &map);
585
586 virtual void copro_halt() override;
587 virtual void copro_boot() override;
588 };
589
590 /*****************************
591 *
592 * Modern polygon renderer
593 *
594 *****************************/
595
596 struct m2_poly_extra_data
597 {
598 model2_state * state;
599 u32 lumabase;
600 u32 colorbase;
601 u32 * texsheet;
602 u32 texwidth;
603 u32 texheight;
604 u32 texx, texy;
605 u8 texmirrorx;
606 u8 texmirrory;
607 };
608
609
get_texel(u32 base_x,u32 base_y,int x,int y,u32 * sheet)610 static inline u16 get_texel( u32 base_x, u32 base_y, int x, int y, u32 *sheet )
611 {
612 u32 baseoffs = ((base_y/2)*512)+(base_x/2);
613 u32 texeloffs = ((y/2)*512)+(x/2);
614 u32 offset = baseoffs + texeloffs;
615 u32 texel = sheet[offset>>1];
616
617 if ( offset & 1 )
618 texel >>= 16;
619
620 if ( (y & 1) == 0 )
621 texel >>= 8;
622
623 if ( (x & 1) == 0 )
624 texel >>= 4;
625
626 return (texel & 0x0f);
627 }
628
629 // 0x10000 = size of the tri_sorted_list array
630 class model2_renderer : public poly_manager<float, m2_poly_extra_data, 4, 0x10000>
631 {
632 public:
633 typedef void (model2_renderer::*scanline_render_func)(int32_t scanline, const extent_t& extent, const m2_poly_extra_data& object, int threadid);
634
635 public:
636 using triangle = model2_state::triangle;
637
model2_renderer(model2_state & state)638 model2_renderer(model2_state& state)
639 : poly_manager<float, m2_poly_extra_data, 4, 0x10000>(state.machine())
640 , m_state(state)
641 , m_destmap(512, 512)
642 {
643 m_renderfuncs[0] = &model2_renderer::model2_3d_render_0;
644 m_renderfuncs[1] = &model2_renderer::model2_3d_render_1;
645 m_renderfuncs[2] = &model2_renderer::model2_3d_render_2;
646 m_renderfuncs[3] = &model2_renderer::model2_3d_render_3;
647 m_renderfuncs[4] = &model2_renderer::model2_3d_render_4;
648 m_renderfuncs[5] = &model2_renderer::model2_3d_render_5;
649 m_renderfuncs[6] = &model2_renderer::model2_3d_render_6;
650 m_renderfuncs[7] = &model2_renderer::model2_3d_render_7;
651 m_xoffs = 90;
652 m_yoffs = -8;
653 }
654
destmap()655 bitmap_rgb32& destmap() { return m_destmap; }
656
657 void model2_3d_render(triangle *tri, const rectangle &cliprect);
set_xoffset(int16 xoffs)658 void set_xoffset(int16 xoffs) { m_xoffs = xoffs; }
set_yoffset(int16 yoffs)659 void set_yoffset(int16 yoffs) { m_yoffs = yoffs; }
660
661 /* checker = 0, textured = 0, transparent = 0 */
662 #define MODEL2_FUNC 0
663 #define MODEL2_FUNC_NAME model2_3d_render_0
664 #include "video/model2rd.hxx"
665 #undef MODEL2_FUNC
666 #undef MODEL2_FUNC_NAME
667
668 /* checker = 0, textured = 0, translucent = 1 */
669 #define MODEL2_FUNC 1
670 #define MODEL2_FUNC_NAME model2_3d_render_1
671 #include "video/model2rd.hxx"
672 #undef MODEL2_FUNC
673 #undef MODEL2_FUNC_NAME
674
675 /* checker = 0, textured = 1, translucent = 0 */
676 #define MODEL2_FUNC 2
677 #define MODEL2_FUNC_NAME model2_3d_render_2
678 #include "video/model2rd.hxx"
679 #undef MODEL2_FUNC
680 #undef MODEL2_FUNC_NAME
681
682 /* checker = 0, textured = 1, translucent = 1 */
683 #define MODEL2_FUNC 3
684 #define MODEL2_FUNC_NAME model2_3d_render_3
685 #include "video/model2rd.hxx"
686 #undef MODEL2_FUNC
687 #undef MODEL2_FUNC_NAME
688
689 /* checker = 1, textured = 0, translucent = 0 */
690 #define MODEL2_FUNC 4
691 #define MODEL2_FUNC_NAME model2_3d_render_4
692 #include "video/model2rd.hxx"
693 #undef MODEL2_FUNC
694 #undef MODEL2_FUNC_NAME
695
696 /* checker = 1, textured = 0, translucent = 1 */
697 #define MODEL2_FUNC 5
698 #define MODEL2_FUNC_NAME model2_3d_render_5
699 #include "video/model2rd.hxx"
700 #undef MODEL2_FUNC
701 #undef MODEL2_FUNC_NAME
702
703 /* checker = 1, textured = 1, translucent = 0 */
704 #define MODEL2_FUNC 6
705 #define MODEL2_FUNC_NAME model2_3d_render_6
706 #include "video/model2rd.hxx"
707 #undef MODEL2_FUNC
708 #undef MODEL2_FUNC_NAME
709
710 /* checker = 1, textured = 1, translucent = 1 */
711 #define MODEL2_FUNC 7
712 #define MODEL2_FUNC_NAME model2_3d_render_7
713 #include "video/model2rd.hxx"
714 #undef MODEL2_FUNC
715 #undef MODEL2_FUNC_NAME
716
717 scanline_render_func m_renderfuncs[8];
718
719 private:
720 model2_state& m_state;
721 bitmap_rgb32 m_destmap;
722 int16_t m_xoffs,m_yoffs;
723 };
724
725 typedef model2_renderer::vertex_t poly_vertex;
726
727
728 /*******************************************
729 *
730 * Basic Data Types
731 *
732 *******************************************/
733
734 struct model2_state::plane
735 {
planeplane736 plane() : normal(0, 0)
737 {
738 std::fill(std::begin(normal.p), std::end(normal.p), 0);
739 }
740
741 poly_vertex normal;
742 float distance = 0;
743 };
744
745 struct model2_state::texture_parameter
746 {
747 float diffuse = 0;
748 float ambient = 0;
749 u32 specular_control = 0;
750 float specular_scale = 0;
751 };
752
753 struct model2_state::triangle
754 {
triangletriangle755 triangle() : v{ { 0, 0 }, { 0, 0 }, { 0, 0 } }
756 {
757 for (poly_vertex &vertex : v)
758 std::fill(std::begin(vertex.p), std::end(vertex.p), 0);
759 }
760
761 void * next = nullptr;
762 poly_vertex v[3];
763 u16 z = 0;
764 u16 texheader[4] = { 0, 0, 0, 0 };
765 u8 luma = 0;
766 int16_t viewport[4] = { 0, 0, 0, 0 };
767 int16_t center[2] = { 0, 0 };
768 };
769
770 struct model2_state::quad_m2
771 {
quad_m2quad_m2772 quad_m2() : v{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }
773 {
774 for (poly_vertex &vertex : v)
775 std::fill(std::begin(vertex.p), std::end(vertex.p), 0);
776 }
777
778 poly_vertex v[4];
779 u16 z = 0;
780 u16 texheader[4] = { 0, 0, 0, 0 };
781 u8 luma = 0;
782 };
783
784 /*******************************************
785 *
786 * Hardware 3D Rasterizer Internal State
787 *
788 *******************************************/
789
790 #define MAX_TRIANGLES 32768
791
792 struct model2_state::raster_state
793 {
raster_stateraster_state794 raster_state()
795 {
796 std::fill(std::begin(command_buffer), std::end(command_buffer), 0);
797 std::fill(std::begin(tri_sorted_list), std::end(tri_sorted_list), nullptr);
798 std::fill(std::begin(texture_ram), std::end(texture_ram), 0);
799 std::fill(std::begin(log_ram), std::end(log_ram), 0);
800 }
801
802 // u32 mode = 0; // bit 0 = Test Mode, bit 2 = Switch 60Hz(1)/30Hz(0) operation
803 u16 * texture_rom = nullptr; // Texture ROM pointer
804 u32 texture_rom_mask = 0; // Texture ROM mask
805 int16_t viewport[4] = { 0, 0, 0, 0 }; // View port (startx,starty,endx,endy)
806 int16_t center[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; // Centers (eye 0[x,y],1[x,y],2[x,y],3[x,y])
807 u16 center_sel = 0; // Selected center
808 u32 reverse = 0; // Left/Right Reverse
809 float z_adjust = 0; // ZSort Mode
810 float triangle_z = 0; // Current Triangle z value
811 u8 master_z_clip = 0; // Master Z-Clip value
812 u32 cur_command = 0; // Current command
813 u32 command_buffer[32]; // Command buffer
814 u32 command_index = 0; // Command buffer index
815 triangle tri_list[MAX_TRIANGLES]; // Triangle list
816 u32 tri_list_index = 0; // Triangle list index
817 triangle * tri_sorted_list[0x10000]; // Sorted Triangle list
818 u16 min_z = 0; // Minimum sortable Z value
819 u16 max_z = 0; // Maximum sortable Z value
820 u16 texture_ram[0x10000]; // Texture RAM pointer
821 u8 log_ram[0x40000]; // Log RAM pointer
822 };
823
824 /*******************************************
825 *
826 * Geometry Engine Internal State
827 *
828 *******************************************/
829
830 struct model2_state::geo_state
831 {
geo_stategeo_state832 geo_state() : focus(0, 0), light(0, 0)
833 {
834 std::fill(std::begin(matrix), std::end(matrix), 0);
835 std::fill(std::begin(focus.p), std::end(focus.p), 0);
836 std::fill(std::begin(light.p), std::end(light.p), 0);
837 std::fill(std::begin(coef_table), std::end(coef_table), 0);
838 std::fill(std::begin(polygon_ram0), std::end(polygon_ram0), 0);
839 std::fill(std::begin(polygon_ram1), std::end(polygon_ram1), 0);
840 }
841
842 raster_state * raster = nullptr;
843 u32 mode = 0; // bit 0 = Enable Specular, bit 1 = Calculate Normals
844 u32 * polygon_rom = nullptr; // Polygon ROM pointer
845 u32 polygon_rom_mask = 0; // Polygon ROM mask
846 float matrix[12]; // Current Transformation Matrix
847 poly_vertex focus; // Focus (x,y)
848 poly_vertex light; // Light Vector
849 float lod = 0; // LOD
850 float coef_table[32]; // Distane Coefficient table
851 texture_parameter texture_parameters[32]; // Texture parameters
852 u32 polygon_ram0[0x8000]; // Fast Polygon RAM pointer
853 u32 polygon_ram1[0x8000]; // Slow Polygon RAM pointer
854 model2_state * state = nullptr;
855 };
856
857 #endif // MAME_INCLUDES_MODEL2_H
858