// license:LGPL-2.1+ // copyright-holders:David Haywood, Angelo Salese, ElSemi, Andrew Gardner #include "machine/msm6242.h" #include "cpu/mips/mips3.h" #include "cpu/nec/v53.h" #include "sound/l7a1045_l6028_dsp_a.h" #include "video/poly.h" enum { FIGHT_MCU = 1, SHOOT_MCU, RACING_MCU, SAMSHO_MCU, BURIKI_MCU }; enum hng64trans_t { HNG64_TILEMAP_NORMAL = 1, HNG64_TILEMAP_ADDITIVE, HNG64_TILEMAP_ALPHA }; struct blit_parameters { bitmap_rgb32 * bitmap; rectangle cliprect; UINT32 tilemap_priority_code; UINT8 mask; UINT8 value; UINT8 alpha; hng64trans_t drawformat; }; #define HNG64_MASTER_CLOCK 50000000 ///////////////// /// 3d Engine /// ///////////////// struct polyVert { float worldCoords[4]; // World space coordinates (X Y Z 1.0) float texCoords[4]; // Texture coordinates (U V 0 1.0) -> OpenGL style... float normal[4]; // Normal (X Y Z 1.0) float clipCoords[4]; // Homogeneous screen space coordinates (X Y Z W) float light[3]; // The intensity of the illumination at this point }; struct polygon { int n; // Number of sides polyVert vert[10]; // Vertices (maximum number per polygon is 10 -> 3+6) float faceNormal[4]; // Normal of the face overall - for calculating visibility and flat-shading... int visible; // Polygon visibility in scene UINT8 texIndex; // Which texture to draw from (0x00-0x0f) UINT8 texType; // How to index into the texture UINT8 texPageSmall; // Does this polygon use 'small' texture pages? UINT8 texPageHorizOffset; // If it does use small texture pages, how far is this page horizontally offset? UINT8 texPageVertOffset; // If it does use small texture pages, how far is this page vertically offset? UINT32 palOffset; // The base offset where this object's palette starts. UINT32 palPageSize; // The size of the palette page that is being pointed to. UINT32 debugColor; // Will go away someday. Used to explicitly color polygons for debugging. }; ///////////////////////// /// polygon rendering /// ///////////////////////// // Refer to the clipping planes as numbers #define HNG64_LEFT 0 #define HNG64_RIGHT 1 #define HNG64_TOP 2 #define HNG64_BOTTOM 3 #define HNG64_NEAR 4 #define HNG64_FAR 5 //////////////////////////////////// /// Polygon rasterizer interface /// //////////////////////////////////// const int HNG64_MAX_POLYGONS = 10000; typedef frustum_clip_vertex hng64_clip_vertex; struct hng64_poly_data { UINT8 texType; UINT8 texIndex; UINT8 texPageSmall; UINT8 texPageHorizOffset; UINT8 texPageVertOffset; int palOffset; int palPageSize; int debugColor; }; class hng64_state; class hng64_poly_renderer : public poly_manager { public: hng64_poly_renderer(hng64_state& state); void drawShaded(polygon *p); void render_scanline(INT32 scanline, const extent_t& extent, const hng64_poly_data& renderData, int threadid); hng64_state& state() { return m_state; } bitmap_rgb32& colorBuffer3d() { return m_colorBuffer3d; } float* depthBuffer3d() { return m_depthBuffer3d.get(); } private: hng64_state& m_state; // (Temporarily class members - someday they will live in the memory map) bitmap_rgb32 m_colorBuffer3d; std::unique_ptr m_depthBuffer3d; }; class hng64_state : public driver_device { public: hng64_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), m_dsp(*this, "l7a1045"), m_comm(*this, "network"), m_rtc(*this, "rtc"), m_mainram(*this, "mainram"), m_cart(*this, "cart"), m_sysregs(*this, "sysregs"), m_dualport(*this, "dualport"), m_rombase(*this, "rombase"), m_spriteram(*this, "spriteram"), m_spriteregs(*this, "spriteregs"), m_videoram(*this, "videoram"), m_videoregs(*this, "videoregs"), m_tcram(*this, "tcram"), m_3dregs(*this, "3dregs"), m_3d_1(*this, "3d_1"), m_3d_2(*this, "3d_2"), m_com_ram(*this, "com_ram"), m_gfxdecode(*this, "gfxdecode"), m_screen(*this, "screen"), m_palette(*this, "palette") { } required_device m_maincpu; required_device m_audiocpu; required_device m_dsp; required_device m_comm; required_device m_rtc; required_shared_ptr m_mainram; required_shared_ptr m_cart; required_shared_ptr m_sysregs; required_shared_ptr m_dualport; required_shared_ptr m_rombase; required_shared_ptr m_spriteram; required_shared_ptr m_spriteregs; required_shared_ptr m_videoram; required_shared_ptr m_videoregs; required_shared_ptr m_tcram; std::unique_ptr m_dl; required_shared_ptr m_3dregs; required_shared_ptr m_3d_1; required_shared_ptr m_3d_2; required_shared_ptr m_com_ram; //required_shared_ptr m_com_mmu_mem; required_device m_gfxdecode; required_device m_screen; required_device m_palette; int m_mcu_type; std::unique_ptr m_soundram; std::unique_ptr m_soundram2; /* Communications stuff */ std::unique_ptr m_com_op_base; std::unique_ptr m_com_virtual_mem; UINT8 m_com_shared[8]; INT32 m_dma_start; INT32 m_dma_dst; INT32 m_dma_len; UINT32 m_mcu_fake_time; UINT16 m_mcu_en; UINT32 m_activeDisplayList; UINT32 m_no_machine_error_code; UINT32 m_unk_vreg_toggle; UINT32 m_p1_trig; //UINT32 *q2; UINT8 m_screen_dis; struct hng64_tilemap { tilemap_t *m_tilemap_8x8; tilemap_t *m_tilemap_16x16; tilemap_t *m_tilemap_16x16_alt; }; hng64_tilemap m_tilemap[4]; UINT8 m_additive_tilemap_debug; UINT32 m_old_animmask; UINT32 m_old_animbits; UINT16 m_old_tileflags[4]; // 3d State int m_paletteState3d; float m_projectionMatrix[16]; float m_modelViewMatrix[16]; float m_cameraMatrix[16]; float m_lightStrength; float m_lightVector[3]; DECLARE_READ32_MEMBER(hng64_com_r); DECLARE_WRITE32_MEMBER(hng64_com_w); DECLARE_WRITE8_MEMBER(hng64_com_share_w); DECLARE_READ8_MEMBER(hng64_com_share_r); DECLARE_WRITE8_MEMBER(hng64_com_share_mips_w); DECLARE_READ8_MEMBER(hng64_com_share_mips_r); DECLARE_READ32_MEMBER(hng64_sysregs_r); DECLARE_WRITE32_MEMBER(hng64_sysregs_w); DECLARE_READ32_MEMBER(fight_io_r); DECLARE_READ32_MEMBER(samsho_io_r); DECLARE_READ32_MEMBER(shoot_io_r); DECLARE_READ32_MEMBER(racing_io_r); DECLARE_READ32_MEMBER(hng64_dualport_r); DECLARE_WRITE32_MEMBER(hng64_dualport_w); DECLARE_READ32_MEMBER(hng64_3d_1_r); DECLARE_READ32_MEMBER(hng64_3d_2_r); DECLARE_WRITE32_MEMBER(hng64_3d_1_w); DECLARE_WRITE32_MEMBER(hng64_3d_2_w); DECLARE_WRITE16_MEMBER(dl_w); //DECLARE_READ32_MEMBER(dl_r); DECLARE_WRITE32_MEMBER(dl_control_w); DECLARE_WRITE32_MEMBER(dl_upload_w); DECLARE_WRITE32_MEMBER(tcram_w); DECLARE_READ32_MEMBER(tcram_r); DECLARE_READ32_MEMBER(unk_vreg_r); DECLARE_WRITE32_MEMBER(hng64_soundram_w); DECLARE_READ32_MEMBER(hng64_soundram_r); DECLARE_WRITE32_MEMBER(hng64_vregs_w); // not actually used, but left in code so you can turn it and see the (possibly undesired?) behavior, see notes in memory map DECLARE_WRITE32_MEMBER(hng64_soundram2_w); DECLARE_READ32_MEMBER(hng64_soundram2_r); DECLARE_WRITE32_MEMBER(hng64_soundcpu_enable_w); DECLARE_WRITE32_MEMBER(hng64_sprite_clear_even_w); DECLARE_WRITE32_MEMBER(hng64_sprite_clear_odd_w); DECLARE_WRITE32_MEMBER(hng64_videoram_w); DECLARE_READ8_MEMBER(hng64_comm_space_r); DECLARE_WRITE8_MEMBER(hng64_comm_space_w); DECLARE_READ8_MEMBER(hng64_comm_mmu_r); DECLARE_WRITE8_MEMBER(hng64_comm_mmu_w); DECLARE_DRIVER_INIT(hng64_race); DECLARE_DRIVER_INIT(fatfurwa); DECLARE_DRIVER_INIT(buriki); DECLARE_DRIVER_INIT(hng64); DECLARE_DRIVER_INIT(hng64_shoot); DECLARE_DRIVER_INIT(ss64); DECLARE_DRIVER_INIT(hng64_fght); DECLARE_DRIVER_INIT(hng64_reorder_gfx); void set_irq(UINT32 irq_vector); UINT32 m_irq_pending; UINT8 *m_comm_rom; std::unique_ptr m_comm_ram; UINT8 m_mmu_regs[8]; UINT32 m_mmua[6]; UINT16 m_mmub[6]; UINT8 read_comm_data(UINT32 offset); void write_comm_data(UINT32 offset,UINT8 data); int m_irq_level; TILE_GET_INFO_MEMBER(get_hng64_tile0_8x8_info); TILE_GET_INFO_MEMBER(get_hng64_tile0_16x16_info); TILE_GET_INFO_MEMBER(get_hng64_tile1_8x8_info); TILE_GET_INFO_MEMBER(get_hng64_tile1_16x16_info); TILE_GET_INFO_MEMBER(get_hng64_tile2_8x8_info); TILE_GET_INFO_MEMBER(get_hng64_tile2_16x16_info); TILE_GET_INFO_MEMBER(get_hng64_tile3_8x8_info); TILE_GET_INFO_MEMBER(get_hng64_tile3_16x16_info); virtual void machine_start() override; virtual void machine_reset() override; virtual void video_start() override; UINT32 screen_update_hng64(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void screen_eof_hng64(screen_device &screen, bool state); TIMER_DEVICE_CALLBACK_MEMBER(hng64_irq); void do_dma(address_space &space); void hng64_mark_all_tiles_dirty(int tilemap); void hng64_mark_tile_dirty(int tilemap, int tile_index); void hng64_drawtilemap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int tm); void hng64_tilemap_draw_roz_core(screen_device &screen, tilemap_t *tmap, const blit_parameters *blit, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound); void hng64_tilemap_draw_roz(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound, UINT32 flags, UINT8 priority, hng64trans_t drawformat); void hng64_tilemap_draw_roz_primask(screen_device &screen, bitmap_rgb32 &dest, const rectangle &cliprect, tilemap_t *tmap, UINT32 startx, UINT32 starty, int incxx, int incxy, int incyx, int incyy, int wraparound, UINT32 flags, UINT8 priority, UINT8 priority_mask, hng64trans_t drawformat); DECLARE_CUSTOM_INPUT_MEMBER(left_handle_r); DECLARE_CUSTOM_INPUT_MEMBER(right_handle_r); DECLARE_CUSTOM_INPUT_MEMBER(acc_down_r); DECLARE_CUSTOM_INPUT_MEMBER(brake_down_r); std::unique_ptr m_poly_renderer; TIMER_CALLBACK_MEMBER(hng64_3dfifo_processed); UINT8 *m_texturerom; UINT16* m_vertsrom; int m_vertsrom_size; std::vector m_polys; // HNG64_MAX_POLYGONS void clear3d(); void hng64_command3d(const UINT16* packet); void draw_sprites(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); void transition_control(bitmap_rgb32 &bitmap, const rectangle &cliprect); void setCameraTransformation(const UINT16* packet); void setLighting(const UINT16* packet); void set3dFlags(const UINT16* packet); void setCameraProjectionMatrix(const UINT16* packet); void recoverPolygonBlock(const UINT16* packet, int& numPolys); void printPacket(const UINT16* packet, int hex); float uToF(UINT16 input); void matmul4(float *product, const float *a, const float *b); void vecmatmul4(float *product, const float *a, const float *b); float vecDotProduct(const float *a, const float *b); void setIdentity(float *matrix); void normalize(float* x); void reset_sound(); void reset_net(); DECLARE_WRITE_LINE_MEMBER(dma_hreq_cb); DECLARE_READ8_MEMBER(dma_memr_cb); DECLARE_WRITE8_MEMBER(dma_iow3_cb); DECLARE_WRITE_LINE_MEMBER(tcu_tm0_cb); DECLARE_WRITE_LINE_MEMBER(tcu_tm1_cb); DECLARE_WRITE_LINE_MEMBER(tcu_tm2_cb); DECLARE_READ16_MEMBER(hng64_sound_port_0008_r); DECLARE_WRITE16_MEMBER(hng64_sound_port_0008_w); DECLARE_WRITE16_MEMBER(hng64_sound_port_000a_w); DECLARE_WRITE16_MEMBER(hng64_sound_port_000c_w); DECLARE_WRITE16_MEMBER(hng64_sound_port_0080_w); DECLARE_WRITE16_MEMBER(hng64_sound_bank_w); DECLARE_READ16_MEMBER(main_sound_comms_r); DECLARE_WRITE16_MEMBER(main_sound_comms_w); DECLARE_READ16_MEMBER(sound_comms_r); DECLARE_WRITE16_MEMBER(sound_comms_w); UINT16 main_latch[2]; UINT16 sound_latch[2]; };