text: // license:BSD-3-Clause
  // copyright-holders:Luca Elia
  /**************************************************************************
  
                              Ginga NinkyouDen
                              (C) 1987 Jaleco
  
                      driver by Luca Elia (l.elia@tin.it)
  
  
  Note:   if MAME_DEBUG is defined, pressing Z with:
  
          Q       shows background
          W       shows foreground
          E       shows frontmost (text) layer
          A       shows sprites
  
          Keys can be used togheter!
  
  
  [Screen]
      Visible Size:       256H x 240V
      Dynamic Colors:     256 x 4
      Color Space:        16R x 16G x 16B
  
  [Scrolling layers]
      Format (all layers):    Offset:     0x400    0x000
                              Bit:        fedc---- --------   Color
                                          ----ba98 76543210   Code
  
      [Background]
          Size:               8192 x 512  (static: stored in ROM)
          Scrolling:          X,Y         (registers: $60006.w, $60004.w)
          Tiles Size:         16 x 16
          Tiles Number:       $400
          Colors:             $300-$3ff
  
      [Foreground]
          Size:               4096 x 512
          Scrolling:          X,Y         (registers: $60002.w, $60000.w)
          Tiles Size:         16 x 16
          Tiles Number:       $400
          Colors:             $200-$2ff
  
      [Frontmost]
          Size:               256 x 256
          Scrolling:          -
          Tiles Size:         8 x 8
          Tiles Number:       $200
          Colors:             $000-$0ff
  
  
  [Sprites]
      On Screen:          256
      In ROM:             $a00
      Colors:             $100-$1ff
      Format:             See Below
  
  
  **************************************************************************/
  
  #include "emu.h"
  #include "includes/ginganin.h"
  
  
  /***************************************************************************
  
    Callbacks for the TileMap code
  
  ***************************************************************************/
  
  
  /* Background - Resides in ROM */
  
  #define BG_GFX (0)
  #define BG_NX  (16*32)
  #define BG_NY  (16*2)
  
  TILE_GET_INFO_MEMBER(ginganin_state::get_bg_tile_info)
  {
  	const u32 code = m_bgrom[2 * tile_index + 0] * 256 + m_bgrom[2 * tile_index + 1];
  	tileinfo.set(BG_GFX,
  			code,
  			code >> 12,
  			0);
  }
  
  
  /* Foreground - Resides in RAM */
  
  #define FG_GFX (1)
  #define FG_NX  (16*16)
  #define FG_NY  (16*2)
  
  TILE_GET_INFO_MEMBER(ginganin_state::get_fg_tile_info)
  {
  	const u16 code = m_fgram[tile_index];
  	tileinfo.set(FG_GFX,
  			code,
  			code >> 12,
  			0);
  }
  
  void ginganin_state::fgram_w(offs_t offset, u16 data, u16 mem_mask)
  {
  	COMBINE_DATA(&m_fgram[offset]);
  	m_fg_tilemap->mark_tile_dirty(offset);
  }
  
  
  /* Frontmost (text) Layer - Resides in RAM */
  
  #define TXT_GFX (2)
  #define TXT_NX  (32)
  #define TXT_NY  (32)
  
  TILE_GET_INFO_MEMBER(ginganin_state::get_txt_tile_info)
  {
  	const u16 code = m_txtram[tile_index];
  	tileinfo.set(TXT_GFX,
  			code,
  			code >> 12,
  			0);
  }
  
  void ginganin_state::txtram_w(offs_t offset, u16 data, u16 mem_mask)
  {
  	COMBINE_DATA(&m_txtram[offset]);
  	m_tx_tilemap->mark_tile_dirty(offset);
  }
  
  
  void ginganin_state::video_start()
  {
  	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, BG_NX, BG_NY);
  	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, FG_NX, FG_NY);
  	m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(ginganin_state::get_txt_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, TXT_NX, TXT_NY);
  
  	m_fg_tilemap->set_transparent_pen(15);
  	m_tx_tilemap->set_transparent_pen(15);
  }
  
  
  void ginganin_state::vregs_w(offs_t offset, u16 data, u16 mem_mask)
  {
  	COMBINE_DATA(&m_vregs[offset]);
  	data = m_vregs[offset];
  
  	switch (offset)
  	{
  	case 0:
  		m_fg_tilemap->set_scrolly(0, data);
  		break;
  	case 1:
  		m_fg_tilemap->set_scrollx(0, data);
  		break;
  	case 2:
  		m_bg_tilemap->set_scrolly(0, data);
  		break;
  	case 3:
  		m_bg_tilemap->set_scrollx(0, data);
  		break;
  	case 4:
  		m_layers_ctrl = data;
  		break;
  /*  case 5:
   *      break;
   */
  	case 6:
  		m_flipscreen = !(data & 1);
  		machine().tilemap().set_flip_all(m_flipscreen ? (TILEMAP_FLIPY | TILEMAP_FLIPX) : 0);
  		break;
  	case 7:
  		m_soundlatch->write(data);
  		m_audiocpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
  		break;
  	default:
  		logerror("CPU #0 PC %06X : Warning, videoreg %04X <- %04X\n", m_maincpu->pc(), offset, data);
  	}
  }
  
  
  
  /* --------------------------[ Sprites Format ]----------------------------
  
  Offset:         Values:         Format:
  
  0000.w          y position      fedc ba9- ---- ----     unused
                                  ---- ---8 ---- ----     subtract 256
                                  ---- ---- 7654 3210     position
  
  0002.w          x position      See above
  
  0004.w          code            f--- ---- ---- ----     y flip
                                  -e-- ---- ---- ----     x flip
                                  --dc ---- ---- ----     unused?
                                  ---- ba98 7654 3210     code
  
  0006.w          colour          fedc ---- ---- ----     colour code
                                  ---- ba98 7654 3210     unused?
  
  ------------------------------------------------------------------------ */
  
  void ginganin_state::draw_sprites(bitmap_ind16 &bitmap,const rectangle &cliprect)
  {
  	for (int offs = 0; offs < (m_spriteram.bytes() >> 1); offs += 4)
  	{
  		int y = m_spriteram[offs + 0];
  		int x = m_spriteram[offs + 1];
  		const u32 code = m_spriteram[offs + 2];
  		const u16 attr = m_spriteram[offs + 3];
  		int flipx = code & 0x4000;
  		int flipy = code & 0x8000;
  
  		x = (x & 0xff) - (x & 0x100);
  		y = (y & 0xff) - (y & 0x100);
  
  		if (m_flipscreen)
  		{
  			x = 240 - x;
  			y = 240 - y;
  			flipx = !flipx;
  			flipy = !flipy;
  		}
  
  		m_gfxdecode->gfx(3)->transpen(bitmap,cliprect,
  				code & 0x3fff,
  				attr >> 12,
  				flipx, flipy,
  				x,y,15);
  
  	}
  }
  
  
  u32 ginganin_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
  {
  	int layers_ctrl1 = m_layers_ctrl;
  
  #ifdef MAME_DEBUG
  if (machine().input().code_pressed(KEYCODE_Z))
  {
  	int msk = 0;
  
  	if (machine().input().code_pressed(KEYCODE_Q)) { msk |= 0xfff1;}
  	if (machine().input().code_pressed(KEYCODE_W)) { msk |= 0xfff2;}
  	if (machine().input().code_pressed(KEYCODE_E)) { msk |= 0xfff4;}
  	if (machine().input().code_pressed(KEYCODE_A))  { msk |= 0xfff8;}
  	if (msk != 0) layers_ctrl1 &= msk;
  
  #define SETSCROLL \
  	m_bg_tilemap->set_scrollx(0, m_posx); \
  	m_bg_tilemap->set_scrolly(0, m_posy); \
  	m_fg_tilemap->set_scrollx(0, m_posx); \
  	m_fg_tilemap->set_scrolly(0, m_posy); \
  	popmessage("B>%04X:%04X F>%04X:%04X",m_posx%(BG_NX*16),m_posy%(BG_NY*16),m_posx%(FG_NX*16),m_posy%(FG_NY*16));
  
  	if (machine().input().code_pressed(KEYCODE_L))  { m_posx +=8; SETSCROLL }
  	if (machine().input().code_pressed(KEYCODE_J))  { m_posx -=8; SETSCROLL }
  	if (machine().input().code_pressed(KEYCODE_K))  { m_posy +=8; SETSCROLL }
  	if (machine().input().code_pressed(KEYCODE_I))  { m_posy -=8; SETSCROLL }
  	if (machine().input().code_pressed(KEYCODE_H))  { m_posx = m_posy = 0;  SETSCROLL }
  
  }
  #endif
  
  	if (layers_ctrl1 & 1)
  		m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
  	else
  		bitmap.fill(0, cliprect);
  
  	if (layers_ctrl1 & 2)
  		m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 0);
  	if (layers_ctrl1 & 8)
  		draw_sprites(bitmap, cliprect);
  	if (layers_ctrl1 & 4)
  		m_tx_tilemap->draw(screen, bitmap, cliprect, 0, 0);
  
  	return 0;
  }
  