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





                                                                            
                
                            

 





                                                                            
                                                      
                                


                              
 
                                                      
                                

                                                                   
 
                                                      
                                
                              
                                                            

 
                                                             
 

                                                            
 
                                                             

                                                                    
              
         
                                                                        
 
                                                                                            
                                      
                                                        
         
 
                                                                                                
                                                    
 
                               




                                                               
                                                           
 

                                                            

                                                             

                                                                        

              
                                                                    
  
                                                                                                    
                                                


                                                                                                
                                                    
 
                               




                                                               
 
                                                    
 
                                                   
                               





                                   
                                                    
 
                                                   
                               

                                     










                                                                            
                                       
 
                                                                                               
 

                                                                                                                                                                            
 

                                                                                                                                                                                                            
 


                                               
 

                                                   

 
                                       
 
                                                                                               
 

                                                                                                                                                                            
 
                                                                                                                                                                                                                                     
 


                                               
 

                                                   







                                                                            
                                               
 
                                       

 
                                                          
 
                                       
                                                      

 
                                                                       
 

                                              

 
                                                                       
 

                                              

 
                                                
 

                                                              

 
                                                
 
                          
         



                                                                                        
         

                                                                      

 
                                                       
 
                          

 
                                                                      
 
                                    

 
                                                                      
 
                                    

 
                                                                      
 

                                                   

 
                                                                      
 

                                                   

 







                                                                            
                                                                           
                                                                                                

                                                                                                                             
 


                                                
                                                                                                            
                                                                      





                                                  

                                                  





                               

                                
 



















                                                  








                                                        


                                                                                         


                                                           
                                                                                                                                       
                                                                   




                                                                                              








                                                        
                                                                                                       
 
                                                        
 
                                                                             
         
                              
                                                                               

                                          
                                                                       
                                                                 
                                                      
                                                                                      











                                                                          
 
                                  
                 



                                                                                                       

                 




                                                                   


         
                                                                                                       
 
                                           
 


                                             
 
                              
         
                                                        
                                    
                                             

                                                                             


                                             

                                                                   

                              

         

                                            
 



                                                                                  
 
                          
                                                                  
 

                 
// license:BSD-3-Clause
// copyright-holders:David Haywood, Phil Stroffolino, Carlos A. Lozano
/***************************************************************************

  Armed Formation video emulation

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

#include "emu.h"
#include "includes/armedf.h"


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

  Callbacks for the TileMap code

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

TILEMAP_MAPPER_MEMBER(armedf_state::armedf_scan_type1)
{   /* col: 0..63; row: 0..31 */
	/* armed formation */
	return col * 32 + row;
}

TILEMAP_MAPPER_MEMBER(armedf_state::armedf_scan_type2)
{   /* col: 0..63; row: 0..31 */
	return 32 * (31 - row) + (col & 0x1f) + 0x800 * (col / 32);
}

TILEMAP_MAPPER_MEMBER(armedf_state::armedf_scan_type3)
{   /* col: 0..63; row: 0..31 */
	/* legion & legiono */
	return (col & 0x1f) * 32 + row + 0x800 * (col / 32);
}

TILE_GET_INFO_MEMBER(armedf_state::get_nb1414m4_tx_tile_info)
{
	u8 tile_number = m_text_videoram[tile_index] & 0xff;
	u8 attributes;

	/* TODO: Armed F doesn't seem to use the NB1414M4! */
	//if (m_scroll_type == 1)
	//  attributes = m_text_videoram[tile_index + 0x800] & 0xff;
	//else
	{
		attributes = m_text_videoram[tile_index + 0x400] & 0xff;

		// TODO: skip drawing the NB1414M4 params, how the HW actually handles this?
		if (tile_index < 0x12)
			tile_number = attributes = 0x00;
	}

	/* bit 3 controls priority, (0) nb1414m4 has priority over all the other video layers */
	tileinfo.category = (attributes & 0x8) >> 3;

	SET_TILE_INFO_MEMBER(0,
			tile_number + 256 * (attributes & 0x3),
			attributes >> 4,
			0);
}

TILE_GET_INFO_MEMBER(armedf_state::get_armedf_tx_tile_info)
{
	u8 tile_number = m_text_videoram[tile_index] & 0xff;
	u8 attributes;

	/* TODO: Armed F doesn't seem to use the NB1414M4! */
	//if (m_scroll_type == 1)
		attributes = m_text_videoram[tile_index + 0x800] & 0xff;
	//else
	//{
	//  attributes = m_text_videoram[tile_index + 0x400] & 0xff;
//
	//  if (tile_index < 0x12) /* don't draw the NB1414M4 params! TODO: could be a better fix */
	//      tile_number = attributes = 0x00;
	//}

	/* bit 3 controls priority, (0) nb1414m4 has priority over all the other video layers */
	tileinfo.category = (attributes & 0x8) >> 3;

	SET_TILE_INFO_MEMBER(0,
			tile_number + 256 * (attributes & 0x3),
			attributes >> 4,
			0);
}


TILE_GET_INFO_MEMBER(armedf_state::get_fg_tile_info)
{
	const u16 data = m_fg_videoram[tile_index];
	SET_TILE_INFO_MEMBER(1,
			data&0x7ff,
			data>>11,
			0);
}


TILE_GET_INFO_MEMBER(armedf_state::get_bg_tile_info)
{
	const u16 data = m_bg_videoram[tile_index];
	SET_TILE_INFO_MEMBER(2,
			data & 0x3ff,
			data >> 11,
			0);
}



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

  Start the video hardware emulation.

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

VIDEO_START_MEMBER(armedf_state,terraf)
{
	m_sprite_offy = (m_scroll_type & 2 ) ? 0 : 128;  /* legion, legiono, crazy climber 2 */

	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);
	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);

	m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_nb1414m4_tx_tile_info)),
			(m_scroll_type == 2) ? tilemap_mapper_delegate(*this, FUNC(armedf_state::armedf_scan_type3)) : tilemap_mapper_delegate(*this, FUNC(armedf_state::armedf_scan_type2)), 8, 8, 64, 32);

	m_bg_tilemap->set_transparent_pen(0xf);
	m_fg_tilemap->set_transparent_pen(0xf);
	m_tx_tilemap->set_transparent_pen(0xf);

	if (m_scroll_type != 1)
		m_tx_tilemap->set_scrollx(0, -128);
}

VIDEO_START_MEMBER(armedf_state,armedf)
{
	m_sprite_offy = (m_scroll_type & 2 ) ? 0 : 128;  /* legion, legiono, crazy climber 2 */

	m_bg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_bg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);
	m_fg_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_fg_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 64, 32);

	m_tx_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(armedf_state::get_armedf_tx_tile_info)), tilemap_mapper_delegate(*this, FUNC(armedf_state::armedf_scan_type1)), 8, 8, 64, 32);

	m_bg_tilemap->set_transparent_pen(0xf);
	m_fg_tilemap->set_transparent_pen(0xf);
	m_tx_tilemap->set_transparent_pen(0xf);

	if (m_scroll_type != 1)
		m_tx_tilemap->set_scrollx(0, -128);
}

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

  Memory handlers

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

u8 armedf_state::text_videoram_r(offs_t offset)
{
	return m_text_videoram[offset];
}

void armedf_state::text_videoram_w(offs_t offset, u8 data)
{
	m_text_videoram[offset] = data;
	m_tx_tilemap->mark_tile_dirty(offset & 0x7ff);
}

void armedf_state::fg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_fg_videoram[offset]);
	m_fg_tilemap->mark_tile_dirty(offset);
}

void armedf_state::bg_videoram_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_bg_videoram[offset]);
	m_bg_tilemap->mark_tile_dirty(offset);
}

void armedf_state::terrafb_fg_scrolly_w(u8 data)
{
	m_fg_scrolly = (data & 0xff) | (m_fg_scrolly & 0x300);
	m_waiting_msb = 1;
}

void armedf_state::terrafb_fg_scrollx_w(u8 data)
{
	if (m_waiting_msb)
	{
		m_scroll_msb = data;
		m_fg_scrollx = (m_fg_scrollx & 0xff) | (((m_scroll_msb >> 4) & 3) << 8);
		m_fg_scrolly = (m_fg_scrolly & 0xff) | (((m_scroll_msb >> 0) & 3) << 8);
		//popmessage("%04X %04X %04X",data,m_fg_scrollx,m_fg_scrolly);
	}
	else
		m_fg_scrollx = (data & 0xff) | (m_fg_scrollx & 0x300);
}

void armedf_state::terrafb_fg_scroll_msb_arm_w(u8 data)
{
	m_waiting_msb = 0;
}

void armedf_state::fg_scrollx_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_fg_scrollx);
}

void armedf_state::fg_scrolly_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_fg_scrolly);
}

void armedf_state::bg_scrollx_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_bg_scrollx);
	m_bg_tilemap->set_scrollx(0, m_bg_scrollx);
}

void armedf_state::bg_scrolly_w(offs_t offset, u16 data, u16 mem_mask)
{
	COMBINE_DATA(&m_bg_scrolly);
	m_bg_tilemap->set_scrolly(0, m_bg_scrolly);
}



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

  Display refresh

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

/* custom code to handle color cycling effect, handled by m_spr_pal_clut */
void armedf_state::armedf_drawgfx(bitmap_ind16 &dest_bmp,const rectangle &clip,gfx_element *gfx,
							u32 code,u32 color, u32 clut,int flipx,int flipy,int offsx,int offsy,
							bitmap_ind8 &primap, u32 pmask, int transparent_color)
{
	// high bit of the mask is implicitly on
	pmask |= 1 << 31;

	const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
	const u8 *source_base = gfx->get_data(code % gfx->elements());
	int x_index_base, y_index, sx, sy, ex, ey;
	int xinc, yinc;

	xinc = flipx ? -1 : 1;
	yinc = flipy ? -1 : 1;

	x_index_base = flipx ? gfx->width()-1 : 0;
	y_index = flipy ? gfx->height()-1 : 0;

	/* start coordinates */
	sx = offsx;
	sy = offsy;

	/* end coordinates */
	ex = sx + gfx->width();
	ey = sy + gfx->height();

	if (sx < clip.min_x)
	{ /* clip left */
		int pixels = clip.min_x-sx;
		sx += pixels;
		x_index_base += xinc*pixels;
	}
	if (sy < clip.min_y)
	{ /* clip top */
		int pixels = clip.min_y-sy;
		sy += pixels;
		y_index += yinc*pixels;
	}
	/* NS 980211 - fixed incorrect clipping */
	if (ex > clip.max_x+1)
	{ /* clip right */
		ex = clip.max_x+1;
	}
	if (ey > clip.max_y+1)
	{ /* clip bottom */
		ey = clip.max_y+1;
	}

	if (ex > sx)
	{ /* skip if inner loop doesn't draw anything */
		int x, y;

		{
			for (y = sy; y < ey; y++)
			{
				const u8 *source = source_base + y_index*gfx->rowbytes();
				u16 *dest = &dest_bmp.pix16(y);
				u8 *destpri = &primap.pix8(y);
				int x_index = x_index_base;
				for (x = sx; x < ex; x++)
				{
					int c = (source[x_index] & ~0xf) | ((m_spr_pal_clut[clut*0x10+(source[x_index] & 0xf)]) & 0xf);
					if (c != transparent_color)
					{
						if (((1 << (destpri[x] & 0x1f)) & pmask) == 0)
							dest[x] = pal[c];
						destpri[x] = 0x1f;
					}
					x_index += xinc;
				}
				y_index += yinc;
			}
		}
	}
}


void armedf_state::draw_sprites( bitmap_ind16 &bitmap, const rectangle &cliprect, bitmap_ind8 &primap )
{
	u16 *buffered_spriteram = m_spriteram->buffer();

	for (int offs = (m_spriteram->bytes() / 2) - 4; offs >= 0; offs -= 4)
	{
		u32 pmask = 0;
		int code = buffered_spriteram[offs + 1]; /* ??YX?TTTTTTTTTTT */
		int flipx = code & 0x2000;
		int flipy = code & 0x1000;
		int color = (buffered_spriteram[offs + 2] >> 8) & 0x1f;
		int clut = (buffered_spriteram[offs + 2]) & 0x7f;
		int sx = buffered_spriteram[offs + 3];
		int sy = m_sprite_offy + 240 - (buffered_spriteram[offs + 0] & 0x1ff);
		int pri = ((buffered_spriteram[offs + 0] & 0x3000) >> 12);
		if (pri == 3) // mimic previous driver behavior, correct?
			continue;

		if (pri >= 1)
			pmask |= GFX_PMASK_4;
		if (pri >= 2)
			pmask |= GFX_PMASK_2;
		/*
		if (pri >= 3)
			pmask |= GFX_PMASK_1;
		*/

		if (flip_screen())
		{
			sx = 320 - sx + 176;    /* don't ask where 176 comes from, just tried it out */
			sy = 240 - sy + 1;  /* don't ask where 1 comes from, just tried it out */
			flipx = !flipx;     /* the values seem to result in pixel-correct placement */
			flipy = !flipy;     /* in all the games supported by this driver */
		}

		armedf_drawgfx(bitmap,cliprect,m_gfxdecode->gfx(3),
			code & 0xfff,
			color,clut,
			flipx,flipy,
			sx,sy,primap,pmask,15);
	}
}

u32 armedf_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int sprite_enable = m_vreg & 0x200;

	m_bg_tilemap->enable(m_vreg & 0x800);
	m_fg_tilemap->enable(m_vreg & 0x400);
	m_tx_tilemap->enable(m_vreg & 0x100);

	switch (m_scroll_type)
	{
		case 0: /* terra force, kozure ookami */
		case 2: /* legion */
		case 3: /* crazy climber 2 */
			m_fg_tilemap->set_scrollx(0, (m_fg_scrollx & 0x3ff));
			m_fg_tilemap->set_scrolly(0, (m_fg_scrolly & 0x3ff));
			break;

		case 1: /* armed formation */
			m_fg_tilemap->set_scrollx(0, m_fg_scrollx);
			m_fg_tilemap->set_scrolly(0, m_fg_scrolly);
			break;

	}

	screen.priority().fill(0, cliprect);
	bitmap.fill(0xff, cliprect);

	m_tx_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(1), 1);
	m_bg_tilemap->draw(screen, bitmap, cliprect, 0, 1);
	m_fg_tilemap->draw(screen, bitmap, cliprect, 0, 2);
	m_tx_tilemap->draw(screen, bitmap, cliprect, TILEMAP_DRAW_CATEGORY(0), 4);

	if (sprite_enable)
		draw_sprites(bitmap, cliprect, screen.priority());

	return 0;
}