// license:BSD-3-Clause // copyright-holders:Olivier Galibert #ifndef MAME_INCLUDES_MODEL1_H #define MAME_INCLUDES_MODEL1_H #pragma once #include "audio/dsbz80.h" #include "audio/segam1audio.h" #include "cpu/mb86233/mb86233.h" #include "cpu/v60/v60.h" #include "machine/i8251.h" #include "machine/gen_fifo.h" #include "machine/mb8421.h" #include "machine/m1comm.h" #include "machine/timer.h" #include "video/segaic24.h" #include "screen.h" #include #include #define DECLARE_TGP_FUNCTION(name) void name() enum {FIFO_SIZE = 256}; enum {MAT_STACK_SIZE = 32}; class model1_state : public driver_device { public: model1_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_dpram(*this, "dpram") , m_m1audio(*this, M1AUDIO_TAG) , m_m1uart(*this, "m1uart") , m_m1comm(*this, "m1comm") , m_dsbz80(*this, DSBZ80_TAG) , m_tgp_copro(*this, "tgp_copro") , m_screen(*this, "screen") , m_copro_fifo_in(*this, "copro_fifo_in") , m_copro_fifo_out(*this, "copro_fifo_out") , m_poly_rom(*this, "polygons") , m_copro_tables(*this, "copro_tables") , m_copro_data(*this, "copro_data") , m_mr2(*this, "mr2") , m_mr(*this, "mr") , m_display_list0(*this, "display_list0") , m_display_list1(*this, "display_list1") , m_color_xlat(*this, "color_xlat") , m_paletteram16(*this, "palette") , m_palette(*this, "palette") , m_tiles(*this, "tile") , m_digits(*this, "digit%u", 0U) { } // Machine DECLARE_MACHINE_START(model1); DECLARE_MACHINE_RESET(model1); DECLARE_READ8_MEMBER(io_r); DECLARE_WRITE8_MEMBER(io_w); DECLARE_WRITE16_MEMBER(bank_w); TIMER_DEVICE_CALLBACK_MEMBER(model1_interrupt); IRQ_CALLBACK_MEMBER(irq_callback); // TGP DECLARE_READ16_MEMBER(fifoin_status_r); DECLARE_WRITE16_MEMBER(md1_w); DECLARE_WRITE16_MEMBER(md0_w); DECLARE_WRITE16_MEMBER(p_w); DECLARE_WRITE16_MEMBER(mr_w); DECLARE_WRITE16_MEMBER(mr2_w); DECLARE_READ16_MEMBER(v60_copro_fifo_r); DECLARE_WRITE16_MEMBER(v60_copro_fifo_w); DECLARE_READ16_MEMBER(v60_copro_ram_adr_r); DECLARE_WRITE16_MEMBER(v60_copro_ram_adr_w); DECLARE_READ16_MEMBER(v60_copro_ram_r); DECLARE_WRITE16_MEMBER(v60_copro_ram_w); DECLARE_READ32_MEMBER(copro_ram_r); DECLARE_WRITE32_MEMBER(copro_ram_w); DECLARE_READ32_MEMBER(copro_fifoin_pop); DECLARE_WRITE32_MEMBER(copro_fifoout_push); DECLARE_WRITE32_MEMBER(copro_sincos_w); DECLARE_READ32_MEMBER(copro_sincos_r); DECLARE_WRITE32_MEMBER(copro_inv_w); DECLARE_READ32_MEMBER(copro_inv_r); DECLARE_WRITE32_MEMBER(copro_isqrt_w); DECLARE_READ32_MEMBER(copro_isqrt_r); DECLARE_WRITE32_MEMBER(copro_atan_w); DECLARE_READ32_MEMBER(copro_atan_r); DECLARE_WRITE32_MEMBER(copro_data_w); DECLARE_READ32_MEMBER(copro_data_r); DECLARE_WRITE32_MEMBER(copro_ramadr_w); DECLARE_READ32_MEMBER(copro_ramadr_r); DECLARE_WRITE32_MEMBER(copro_ramdata_w); DECLARE_READ32_MEMBER(copro_ramdata_r); void copro_hle_vf(); void copro_hle_swa(); void copro_reset(); u32 m_copro_sincos_base; u32 m_copro_inv_base; u32 m_copro_isqrt_base; u32 m_copro_atan_base[4]; u32 m_copro_data_base; u32 m_copro_ram_adr; uint16_t m_r360_state; DECLARE_READ8_MEMBER(r360_r); DECLARE_WRITE8_MEMBER(r360_w); // Rendering DECLARE_VIDEO_START(model1); DECLARE_READ16_MEMBER(model1_listctl_r); DECLARE_WRITE16_MEMBER(model1_listctl_w); uint32_t screen_update_model1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); DECLARE_WRITE_LINE_MEMBER(screen_vblank_model1); struct spoint_t { int32_t x, y; }; struct point_t { float x, y, z; float xx, yy; spoint_t s; }; class quad_t { public: quad_t() { } quad_t(int ccol, float cz, point_t* p0, point_t* p1, point_t* p2, point_t* p3) : p{ p0, p1, p2, p3 } , z(cz) , col(ccol) { } int compare(const quad_t* other) const; point_t *p[4] = { nullptr, nullptr, nullptr, nullptr }; float z = 0; int col = 0; }; struct lightparam_t { float a = 0; float d = 0; float s = 0; int p = 0; }; class view_t { public: view_t() { light.x = 0; light.y = 0; light.z = 0; } void init_translation_matrix(); void set_viewport(float xcenter, float ycenter, float xl, float xr, float yb, float yt); void set_lightparam(int index, float diffuse, float ambient, float specular, int power); void set_zoom(float x, float y); void set_light_direction(float x, float y, float z); void set_translation_matrix(float* mat); void set_view_translation(float x, float y); void project_point(point_t *p) const; void project_point_direct(point_t *p) const; void transform_vector(glm::vec3& p) const; void transform_point(point_t *p) const; void recompute_frustum(); int xc = 0, yc = 0, x1 = 0, y1 = 0, x2 = 0, y2 = 0; float zoomx = 0, zoomy = 0, viewx = 0, viewy = 0; float a_bottom = 0, a_top = 0, a_left = 0, a_right = 0; float vxx = 0, vyy = 0, vzz = 0, ayy = 0, ayyc = 0, ayys = 0; float translation[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; glm::vec3 light; lightparam_t lightparams[32]; }; void model1(machine_config &config); void model1_hle(machine_config &config); void vf(machine_config &config); void vr(machine_config &config); void vformula(machine_config &config); void swa(machine_config &config); void wingwar(machine_config &config); void wingwar360(machine_config &config); void netmerc(machine_config &config); void model1_io(address_map &map); void model1_mem(address_map &map); void model1_comm_mem(address_map &map); void copro_prog_map(address_map &map); void copro_data_map(address_map &map); void copro_external_map(address_map &map); void copro_io_map(address_map &map); void copro_rf_map(address_map &map); void polhemus_map(address_map &map); private: // Machine void irq_raise(int level); void irq_init(); DECLARE_WRITE8_MEMBER(irq_control_w); uint8_t m_irq_status; int m_last_irq; // Devices required_device m_maincpu; // V60 required_device m_dpram; required_device m_m1audio; // Model 1 standard sound board required_device m_m1uart; optional_device m_m1comm; // Model 1 communication board optional_device m_dsbz80; // Digital Sound Board optional_device m_tgp_copro; required_device m_screen; required_device m_copro_fifo_in, m_copro_fifo_out; required_region_ptr m_poly_rom; required_region_ptr m_copro_tables; optional_memory_region m_copro_data; required_shared_ptr m_mr2; required_shared_ptr m_mr; required_shared_ptr m_display_list0; required_shared_ptr m_display_list1; required_shared_ptr m_color_xlat; // Sound int m_sound_irq; // TGP FIFO void fifoout_push(uint32_t data); void fifoout_push_f(float data); uint32_t fifoin_pop(); float fifoin_pop_f(); uint16_t ram_get_i(); float ram_get_f(); u32 m_v60_copro_fifo_r, m_v60_copro_fifo_w; // TGP void tgp_reset(); DECLARE_TGP_FUNCTION( fadd ); DECLARE_TGP_FUNCTION( fsub ); DECLARE_TGP_FUNCTION( fmul ); DECLARE_TGP_FUNCTION( fdiv ); DECLARE_TGP_FUNCTION( matrix_push ); DECLARE_TGP_FUNCTION( matrix_pop ); DECLARE_TGP_FUNCTION( matrix_write ); DECLARE_TGP_FUNCTION( clear_stack ); DECLARE_TGP_FUNCTION( matrix_mul ); DECLARE_TGP_FUNCTION( anglev ); DECLARE_TGP_FUNCTION( triangle_normal ); DECLARE_TGP_FUNCTION( normalize ); DECLARE_TGP_FUNCTION( acc_seti ); DECLARE_TGP_FUNCTION( track_select ); DECLARE_TGP_FUNCTION( load_base ); DECLARE_TGP_FUNCTION( transpose ); DECLARE_TGP_FUNCTION( anglep ); DECLARE_TGP_FUNCTION( matrix_ident ); DECLARE_TGP_FUNCTION( matrix_read ); DECLARE_TGP_FUNCTION( matrix_trans ); DECLARE_TGP_FUNCTION( matrix_scale ); DECLARE_TGP_FUNCTION( matrix_rotx ); DECLARE_TGP_FUNCTION( matrix_roty ); DECLARE_TGP_FUNCTION( matrix_rotz ); DECLARE_TGP_FUNCTION( track_read_quad ); DECLARE_TGP_FUNCTION( intercept ); DECLARE_TGP_FUNCTION( transform_point ); DECLARE_TGP_FUNCTION( fcos_m1 ); DECLARE_TGP_FUNCTION( fsin_m1 ); DECLARE_TGP_FUNCTION( fcosm_m1 ); DECLARE_TGP_FUNCTION( fsinm_m1 ); DECLARE_TGP_FUNCTION( distance3 ); DECLARE_TGP_FUNCTION( ftoi ); DECLARE_TGP_FUNCTION( itof ); DECLARE_TGP_FUNCTION( acc_set ); DECLARE_TGP_FUNCTION( acc_get ); DECLARE_TGP_FUNCTION( acc_add ); DECLARE_TGP_FUNCTION( acc_sub ); DECLARE_TGP_FUNCTION( acc_mul ); DECLARE_TGP_FUNCTION( acc_div ); DECLARE_TGP_FUNCTION( f42 ); DECLARE_TGP_FUNCTION( xyz2rqf ); DECLARE_TGP_FUNCTION( f43 ); DECLARE_TGP_FUNCTION( f43_swa ); DECLARE_TGP_FUNCTION( track_read_tri ); DECLARE_TGP_FUNCTION( matrix_sdir ); DECLARE_TGP_FUNCTION( fsqrt ); DECLARE_TGP_FUNCTION( vlength ); DECLARE_TGP_FUNCTION( f47 ); DECLARE_TGP_FUNCTION( track_read_info ); DECLARE_TGP_FUNCTION( colbox_set ); DECLARE_TGP_FUNCTION( colbox_test ); DECLARE_TGP_FUNCTION( f49_swa ); DECLARE_TGP_FUNCTION( f50_swa ); DECLARE_TGP_FUNCTION( f52 ); DECLARE_TGP_FUNCTION( matrix_rdir ); DECLARE_TGP_FUNCTION( track_lookup ); DECLARE_TGP_FUNCTION( f56 ); DECLARE_TGP_FUNCTION( int_normal ); DECLARE_TGP_FUNCTION( matrix_readt ); DECLARE_TGP_FUNCTION( acc_geti ); DECLARE_TGP_FUNCTION( int_point ); DECLARE_TGP_FUNCTION( col_setcirc ); DECLARE_TGP_FUNCTION( col_testpt ); DECLARE_TGP_FUNCTION( push_and_ident ); DECLARE_TGP_FUNCTION( catmull_rom ); DECLARE_TGP_FUNCTION( distance ); DECLARE_TGP_FUNCTION( car_move ); DECLARE_TGP_FUNCTION( cpa ); DECLARE_TGP_FUNCTION( vmat_store ); DECLARE_TGP_FUNCTION( vmat_restore ); DECLARE_TGP_FUNCTION( vmat_mul ); DECLARE_TGP_FUNCTION( vmat_read ); DECLARE_TGP_FUNCTION( matrix_rtrans ); DECLARE_TGP_FUNCTION( matrix_unrot ); DECLARE_TGP_FUNCTION( f80 ); DECLARE_TGP_FUNCTION( vmat_save ); DECLARE_TGP_FUNCTION( vmat_load ); DECLARE_TGP_FUNCTION( ram_setadr ); DECLARE_TGP_FUNCTION( groundbox_test ); DECLARE_TGP_FUNCTION( f89 ); DECLARE_TGP_FUNCTION( f92 ); DECLARE_TGP_FUNCTION( f93 ); DECLARE_TGP_FUNCTION( f94 ); DECLARE_TGP_FUNCTION( vmat_flatten ); DECLARE_TGP_FUNCTION( vmat_load1 ); DECLARE_TGP_FUNCTION( ram_trans ); DECLARE_TGP_FUNCTION( f98_load ); DECLARE_TGP_FUNCTION( f98 ); DECLARE_TGP_FUNCTION( f99 ); DECLARE_TGP_FUNCTION( f100 ); DECLARE_TGP_FUNCTION( groundbox_set ); DECLARE_TGP_FUNCTION( f102 ); DECLARE_TGP_FUNCTION( f103 ); DECLARE_TGP_FUNCTION( dump ); DECLARE_TGP_FUNCTION( function_get_vf ); DECLARE_TGP_FUNCTION( function_get_swa ); class clipper_t { public: clipper_t() : m_isclipped(nullptr) , m_clip(nullptr) { } clipper_t(std::function isclipped, std::function clip) : m_isclipped(isclipped) , m_clip(clip) { } std::function m_isclipped; std::function m_clip; }; std::unique_ptr m_view; point_t *m_pointdb; point_t *m_pointpt; quad_t *m_quaddb; quad_t *m_quadpt; quad_t **m_quadind; offs_t m_pushpc; u32 m_copro_hle_active_list_pos, m_copro_hle_active_list_length; typedef void (model1_state::*tgp_func)(); struct function { tgp_func cb; int count; }; static float tsin(s16 angle); static float tcos(s16 angle); static const struct function ftab_vf[]; static const struct function ftab_swa[]; uint32_t m_copro_hle_list_length; float m_cmat[12]; float m_mat_stack[MAT_STACK_SIZE][12]; float m_mat_vector[21][12]; int32_t m_mat_stack_pos; float m_acc; float m_tgp_vf_xmin; float m_tgp_vf_xmax; float m_tgp_vf_zmin; float m_tgp_vf_zmax; float m_tgp_vf_ygnd; float m_tgp_vf_yflr; float m_tgp_vf_yjmp; float m_tgp_vr_circx; float m_tgp_vr_circy; float m_tgp_vr_circrad; float m_tgp_vr_cbox[12]; int m_tgp_vr_select; float m_tgp_int_px; float m_tgp_int_py; float m_tgp_int_pz; uint32_t m_tgp_int_adr; uint16_t m_v60_copro_ram_adr; uint16_t m_v60_copro_ram_latch[2]; uint16_t m_copro_hle_ram_scan_adr; std::unique_ptr m_copro_ram_data; float m_tgp_vr_base[4]; int m_ccount; uint16_t m_listctl[2]; uint16_t *m_glist; bool m_render_done; std::unique_ptr m_tgp_ram; std::unique_ptr m_poly_ram; void configure_fifos(); // Rendering helper functions uint32_t readi(int adr) const; int16_t readi16(int adr) const; float readf(int adr) const; void cross_product(point_t* o, const point_t* p, const point_t* q) const; float view_determinant(const point_t *p1, const point_t *p2, const point_t *p3) const; static bool fclip_isc_bottom(view_t*, point_t*); static bool fclip_isc_top(view_t*, point_t*); static bool fclip_isc_left(view_t*, point_t*); static bool fclip_isc_right(view_t*, point_t*); static void fclip_clip_bottom(view_t*, point_t*, point_t*, point_t*); static void fclip_clip_top(view_t*, point_t*, point_t*, point_t*); static void fclip_clip_left(view_t*, point_t*, point_t*, point_t*); static void fclip_clip_right(view_t*, point_t*, point_t*, point_t*); // Rendering void tgp_render(bitmap_rgb32 &bitmap, const rectangle &cliprect); void tgp_scan(); void sort_quads() const; void unsort_quads() const; void draw_quads(bitmap_rgb32 &bitmap, const rectangle &cliprect); static void recompute_frustum(view_t *view); static void draw_hline(bitmap_rgb32 &bitmap, int x1, int x2, int y, int color); static void draw_hline_moired(bitmap_rgb32 &bitmap, int x1, int x2, int y, int color); static void fill_slope(bitmap_rgb32 &bitmap, view_t *view, int color, int32_t x1, int32_t x2, int32_t sl1, int32_t sl2, int32_t y1, int32_t y2, int32_t *nx1, int32_t *nx2); static void fill_line(bitmap_rgb32 &bitmap, view_t *view, int color, int32_t y, int32_t x1, int32_t x2); void fill_quad(bitmap_rgb32 &bitmap, view_t *view, const quad_t& q) const; void fclip_push_quad_next(int level, quad_t& q, point_t *p1, point_t *p2, point_t *p3, point_t *p4); void fclip_push_quad(int level, quad_t& q); static float min4f(float a, float b, float c, float d); static float max4f(float a, float b, float c, float d); static float compute_specular(glm::vec3& normal, glm::vec3& light, float diffuse,int lmode); int push_direct(int list_offset); int draw_direct(bitmap_rgb32 &bitmap, const rectangle &cliprect, int list_offset); int skip_direct(int list_offset) const; void push_object(uint32_t tex_adr, uint32_t poly_adr, uint32_t size); void draw_objects(bitmap_rgb32 &bitmap, const rectangle &cliprect); void set_current_render_list(); int get_list_number(); void end_frame(); clipper_t m_clipfn[4]; // run-time rendering uint16_t* m_display_list_current; optional_shared_ptr m_paletteram16; required_device m_palette; required_device m_tiles; // I/O related output_finder<2> m_digits; DECLARE_READ8_MEMBER(dpram_r); DECLARE_WRITE8_MEMBER(vf_outputs_w); DECLARE_WRITE8_MEMBER(vr_outputs_w); DECLARE_WRITE8_MEMBER(swa_outputs_w); DECLARE_WRITE8_MEMBER(wingwar_outputs_w); DECLARE_WRITE8_MEMBER(wingwar360_outputs_w); DECLARE_WRITE8_MEMBER(netmerc_outputs_w); }; /*----------- defined in machine/model1.c -----------*/ #endif // MAME_INCLUDES_MODEL1_H