summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/video/namcos1.cpp
blob: 0caac817ce091031e314230754c2404414589272 (plain) (tree)
1
2
3
4
5
6
7
8
9

                                  





                                                                    
                
                             
                   














                                            











                                                                    








                                         







                                                                            
                                                                                               




                                                                                 
                                         
                                                            

 
                                                 
 
                                                               

 
                                                 
 
                                                               

 
                                                 
 
                                                               

 
                                                 
 
                                                               

 
                                                 
 
                                                               

 
                                                 
 
                                                               
 








                                                                            
                                 


              
                                                                  
 
                                   





                                                                                                                                                                   
 











                                                                        
 
                                                
                              

                                                      
 

                                                                       
                                                 

                                           
                                                          
 

                                                                    
 
                                        









                                                                            
                                          
 
                                  



                                                 
                                                          





                                                         
                                                                  



         
                                           


                                  
                                   
 


                                                                                    





























                                                                            
                                                                                                        
 


                                                                                        
                                               
 

                                                                              

























                                                                   
                                  






                                         
                                                                              
 
                                                           
                                  
                                                           




                                                                
                                                                    

                                             
                                                             




                                                                
                                                                    
                                                          






                               
                                                                                                             

                                             
                                      

                                                                     
                                                 

                              
                                                      

                                                                                    
                                                                    
                                                   
                                                                    
                                                   
                                                                    
                                                   
                                                                    

                                                   
                             




                              
                                                                                             


                             
                           

                                                                                       
 
                                  




                                           

                                                        


         
                                            






                                                   
                                                                    
                                                                                              


                 
                                               



                 
                                               
 
                      
                  
         
                                   
                 
                                                                 
                                
 





                                                                            
                                           
                 

         
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi
/*******************************************************************

Namco System 1 Video Hardware

*******************************************************************/

#include "emu.h"
#include "includes/namcos1.h"
#include "screen.h"


/*
  video ram map
  0000-1fff : scroll playfield (0) : 64*64*2
  2000-3fff : scroll playfield (1) : 64*64*2
  4000-5fff : scroll playfield (2) : 64*64*2
  6000-6fff : scroll playfield (3) : 64*32*2
  7000-700f : ?
  7010-77ef : fixed playfield (4)  : 36*28*2
  77f0-77ff : ?
  7800-780f : ?
  7810-7fef : fixed playfield (5)  : 36*28*2
  7ff0-7fff : ?
*/

/*
  paletteram map (s1ram  0x0000-0x7fff)
  0000-17ff : palette page0 : sprite
  2000-37ff : palette page1 : playfield
  4000-57ff : palette page2 : playfield (shadow)
  6000-77ff : palette page3 : work RAM

  x800-x807 : CUS116 registers (visibility window)

  so there is just 3x0x2000 RAM, plus the CUS116 internal registers.
*/

/*
  spriteram map (s1ram 0x10000-0x10fff)
  0000-07ff : work ram
  0800-0fef : sprite ram    : 0x10 * 127
  0ff0-0fff : display control registers

  1000-1fff : playfield control registers
*/


/***************************************************************************

  Callbacks for the TileMap code

***************************************************************************/

inline void namcos1_state::get_tile_info(tile_data &tileinfo,int tile_index,uint8_t *info_vram)
{
	int code;

	tile_index <<= 1;
	code = info_vram[tile_index + 1] + ((info_vram[tile_index] & 0x3f) << 8);
	SET_TILE_INFO_MEMBER(0,code,0,0);
	tileinfo.mask_data = &m_tilemap_maskdata[code << 3];
}

TILE_GET_INFO_MEMBER(namcos1_state::bg_get_info0)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x0000]);
}

TILE_GET_INFO_MEMBER(namcos1_state::bg_get_info1)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x2000]);
}

TILE_GET_INFO_MEMBER(namcos1_state::bg_get_info2)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x4000]);
}

TILE_GET_INFO_MEMBER(namcos1_state::bg_get_info3)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x6000]);
}

TILE_GET_INFO_MEMBER(namcos1_state::fg_get_info4)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x7010]);
}

TILE_GET_INFO_MEMBER(namcos1_state::fg_get_info5)
{
	get_tile_info(tileinfo,tile_index,&m_videoram[0x7810]);
}



/***************************************************************************

  Start the video hardware emulation.

***************************************************************************/

void namcos1_state::video_start()
{
	int i;

	m_tilemap_maskdata = (uint8_t *)memregion("gfx1")->base();

	/* initialize playfields */
	m_bg_tilemap[0] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::bg_get_info0),this),TILEMAP_SCAN_ROWS,8,8,64,64);
	m_bg_tilemap[1] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::bg_get_info1),this),TILEMAP_SCAN_ROWS,8,8,64,64);
	m_bg_tilemap[2] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::bg_get_info2),this),TILEMAP_SCAN_ROWS,8,8,64,64);
	m_bg_tilemap[3] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::bg_get_info3),this),TILEMAP_SCAN_ROWS,8,8,64,32);
	m_bg_tilemap[4] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::fg_get_info4),this),TILEMAP_SCAN_ROWS,8,8,36,28);
	m_bg_tilemap[5] = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(namcos1_state::fg_get_info5),this),TILEMAP_SCAN_ROWS,8,8,36,28);

	for (i = 0; i < 4; i++)
	{
		static const int xdisp[] = { 25, 27, 28, 29 };

		m_bg_tilemap[i]->set_scrolldx(xdisp[i], 434 - xdisp[i]);
		m_bg_tilemap[i]->set_scrolldy(-8, 256 + 8);
	}

	m_bg_tilemap[4]->set_scrolldx(73, 73);
	m_bg_tilemap[5]->set_scrolldx(73, 73);
	m_bg_tilemap[4]->set_scrolldy(16, 16);
	m_bg_tilemap[5]->set_scrolldy(16, 16);

	/* set table for sprite color == 0x7f */
	for (i = 0;i < 15;i++)
		m_drawmode_table[i] = DRAWMODE_SHADOW;
	m_drawmode_table[15] = DRAWMODE_NONE;

	/* all palette entries are not affected by shadow sprites... */
	for (i = 0;i < 0x2000;i++)
		m_palette->shadow_table()[i] = i;
	/* ... except for tilemap colors */
	for (i = 0x0800;i < 0x1000;i++)
		m_palette->shadow_table()[i] = i + 0x0800;

	memset(m_playfield_control, 0, sizeof(m_playfield_control));
	m_copy_sprites = 0;

	save_item(NAME(m_copy_sprites));
}



/***************************************************************************

  Memory handlers

***************************************************************************/

WRITE8_MEMBER( namcos1_state::videoram_w )
{
	m_videoram[offset] = data;
	if (offset < 0x7000)
	{   /* background 0-3 */
		int layer = offset >> 13;
		int num = (offset & 0x1fff) >> 1;
		m_bg_tilemap[layer]->mark_tile_dirty(num);
	}
	else
	{   /* foreground 4-5 */
		int layer = (offset >> 11 & 1) + 4;
		int num = ((offset & 0x7ff) - 0x10) >> 1;
		if (num >= 0 && num < 0x3f0)
			m_bg_tilemap[layer]->mark_tile_dirty(num);
	}
}


WRITE8_MEMBER( namcos1_state::spriteram_w )
{
	/* 0000-07ff work ram */
	/* 0800-0fff sprite ram */
	m_spriteram[offset] = data;

	/* a write to this offset tells the sprite chip to buffer the sprite list */
	if (offset == 0x0ff2)
		m_copy_sprites = 1;
}



/***************************************************************************

  Display refresh

***************************************************************************/

/*
sprite format:

0-3  scratchpad RAM
4-9  CPU writes here, hardware copies from here to 10-15
10   xx------  X size (16, 8, 32, 4)
10   --x-----  X flip
10   ---xx---  X offset inside 32x32 tile
10   -----xxx  tile bank
11   xxxxxxxx  tile number
12   xxxxxxx-  color
12   -------x  X position MSB
13   xxxxxxxx  X position
14   xxx-----  priority
14   ---xx---  Y offset inside 32x32 tile
14   -----xx-  Y size (16, 8, 32, 4)
14   -------x  Y flip
15   xxxxxxxx  Y position
*/

void namcos1_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	uint8_t *spriteram = m_spriteram + 0x800;
	const uint8_t *source = &spriteram[0x800-0x20];   /* the last is NOT a sprite */
	const uint8_t *finish = &spriteram[0];
	gfx_element *gfx = m_gfxdecode->gfx(1);

	int sprite_xoffs = spriteram[0x07f5] + ((spriteram[0x07f4] & 1) << 8);
	int sprite_yoffs = spriteram[0x07f7];

	while (source >= finish)
	{
		static const int sprite_size[4] = { 16, 8, 32, 4 };
		int attr1 = source[10];
		int attr2 = source[14];
		int color = source[12];
		int flipx = (attr1 & 0x20) >> 5;
		int flipy = (attr2 & 0x01);
		int sizex = sprite_size[(attr1 & 0xc0) >> 6];
		int sizey = sprite_size[(attr2 & 0x06) >> 1];
		int tx = (attr1 & 0x18) & (~(sizex-1));
		int ty = (attr2 & 0x18) & (~(sizey-1));
		int sx = source[13] + ((color & 0x01) << 8);
		int sy = -source[15] - sizey;
		int sprite = source[11];
		int sprite_bank = attr1 & 7;
		int priority = (source[14] & 0xe0) >> 5;
		int pri_mask = (0xff << (priority + 1)) & 0xff;

		sprite += sprite_bank * 256;
		color = color >> 1;

		sx += sprite_xoffs;
		sy -= sprite_yoffs;

		if (flip_screen())
		{
			sx = -sx - sizex;
			sy = -sy - sizey;
			flipx ^= 1;
			flipy ^= 1;
		}

		sy++;   /* sprites are buffered and delayed by one scanline */

		gfx->set_source_clip(tx, sizex, ty, sizey);
		if (color != 0x7f)
			gfx->prio_transpen(bitmap,cliprect,
					sprite,
					color,
					flipx,flipy,
					sx & 0x1ff,
					((sy + 16) & 0xff) - 16,
					screen.priority(), pri_mask,
					0xf);
		else
			gfx->prio_transtable(bitmap,cliprect,
					sprite,
					color,
					flipx,flipy,
					sx & 0x1ff,
					((sy + 16) & 0xff) - 16,
					screen.priority(), pri_mask,
					m_drawmode_table);

		source -= 0x10;
	}
}



uint32_t namcos1_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int i, j, scrollx, scrolly, priority;
	rectangle new_clip = cliprect;

	/* flip screen is embedded in the sprite control registers */
	flip_screen_set(m_spriteram[0x0ff6] & 1);

	/* background color */
	bitmap.fill(m_palette->black_pen(), cliprect);

	/* berabohm uses asymmetrical visibility windows to iris on the character */
	i = m_c116->get_reg(0) - 1;                         // min x
	if (new_clip.min_x < i) new_clip.min_x = i;
	i = m_c116->get_reg(1) - 1 - 1;                     // max x
	if (new_clip.max_x > i) new_clip.max_x = i;
	i = m_c116->get_reg(2) - 0x11;                      // min y
	if (new_clip.min_y < i) new_clip.min_y = i;
	i = m_c116->get_reg(3) - 0x11 - 1;                  // max y
	if (new_clip.max_y > i) new_clip.max_y = i;

	if (new_clip.empty())
		return 0;


	/* set palette base */
	for (i = 0;i < 6;i++)
		m_bg_tilemap[i]->set_palette_offset((m_playfield_control[i + 24] & 7) * 256);

	for (i = 0;i < 4;i++)
	{
		j = i << 2;
		scrollx = ( m_playfield_control[j+1] + (m_playfield_control[j+0]<<8) );
		scrolly = ( m_playfield_control[j+3] + (m_playfield_control[j+2]<<8) );

		if (flip_screen())
		{
			scrollx = -scrollx;
			scrolly = -scrolly;
		}

		m_bg_tilemap[i]->set_scrollx(0,scrollx);
		m_bg_tilemap[i]->set_scrolly(0,scrolly);
	}


	screen.priority().fill(0, new_clip);

	/* bit 0-2 priority */
	/* bit 3   disable  */
	for (priority = 0; priority < 8;priority++)
	{
		for (i = 0;i < 6;i++)
		{
			if (m_playfield_control[16 + i] == priority)
				m_bg_tilemap[i]->draw(screen, bitmap, new_clip, 0,priority,0);
		}
	}

	draw_sprites(screen, bitmap, new_clip);
	return 0;
}


WRITE_LINE_MEMBER(namcos1_state::screen_vblank)
{
	// rising edge
	if (state)
	{
		if (m_copy_sprites)
		{
			uint8_t *spriteram = m_spriteram + 0x800;
			int i,j;

			for (i = 0;i < 0x800;i += 16)
			{
				for (j = 10;j < 16;j++)
					spriteram[i+j] = spriteram[i+j - 6];
			}

			m_copy_sprites = 0;
		}
	}
}