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

                                





                                                                             
                
                              




                                      



                                       
                                                         
 
                                                                  


                                                                 
                                                                             


 
                                                             
 
                                                                      
                                                                     
                                                  
                                                               









                                       
                                                                
 






























                                                                                   
 
                                  
 
                         


                                               









                                       
                                                       





                                                                                                     

                                            








                                                              
                                                                       










                                       
                                                                         
 


                           



                                                    




                                           
                                                                        


                                        
                                              
                                                                        
                                 
                                                                            

                                                                              


                                      
                                                 
                                                                          
                                 
                                                                            

                                                                                  


                                      
                                               
                                                                       
                                 
                                                                            
                                                                         


                                      
                                                

                                      
                                               
                                                           

                                      
                                               


                                                                                                              
                                                                                      

                                                                            
 
                                                                                     
                                 
                                                                            
                                                                                           
                                                                                    














                                       
                                                                                                                       
 

                                    

                                
                                                                  
 

                                                 
                                                                                                                     
                                                                   
                 

                                                          
                                                                           
                                                    


                                                                                                                 
                                                                                            
 

                                                            
 

                                                                                   
                                                                                                              











                                                                                                                            
                                                                                                       





                                                                                                   
                                                              

                                                                  
                                                                                                                     
                                                                   
                 

                                                          
                                                                           
                                                    
                                 
                                                                                                              





                                                                                                      
                                                                                                 




                                                                                                                        



                                 
// license:BSD-3-Clause
// copyright-holders:Aaron Giles
/***************************************************************************

    Atari Vindicators hardware

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

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



/*************************************
 *
 *  Tilemap callbacks
 *
 *************************************/

TILE_GET_INFO_MEMBER(vindictr_state::get_alpha_tile_info)
{
	uint16_t data = m_alpha_tilemap->basemem_read(tile_index);
	int code = data & 0x3ff;
	int color = ((data >> 10) & 0x0f) | ((data >> 9) & 0x20);
	int opaque = data & 0x8000;
	SET_TILE_INFO_MEMBER(1, code, color, opaque ? TILE_FORCE_LAYER0 : 0);
}


TILE_GET_INFO_MEMBER(vindictr_state::get_playfield_tile_info)
{
	uint16_t data = m_playfield_tilemap->basemem_read(tile_index);
	int code = (m_playfield_tile_bank * 0x1000) + (data & 0xfff);
	int color = 0x10 + 2 * ((data >> 12) & 7);
	SET_TILE_INFO_MEMBER(0, code, color, (data >> 15) & 1);
}



/*************************************
 *
 *  Video system start
 *
 *************************************/

const atari_motion_objects_config vindictr_state::s_mob_config =
{
	0,                  /* index to which gfx system */
	1,                  /* number of motion object banks */
	1,                  /* are the entries linked? */
	0,                  /* are the entries split? */
	0,                  /* render in reverse order? */
	0,                  /* render in swapped X/Y order? */
	0,                  /* does the neighbor bit affect the next object? */
	8,                  /* pixels per SLIP entry (0 for no-slip) */
	0,                  /* pixel offset for SLIPs */
	0,                  /* maximum number of links to visit/scanline (0=all) */

	0x100,              /* base palette entry */
	0x100,              /* maximum number of colors */
	0,                  /* transparent pen index */

	{{ 0,0,0,0x03ff }}, /* mask for the link */
	{{ 0x7fff,0,0,0 }}, /* mask for the code index */
	{{ 0,0x000f,0,0 }}, /* mask for the color */
	{{ 0,0xff80,0,0 }}, /* mask for the X position */
	{{ 0,0,0xff80,0 }}, /* mask for the Y position */
	{{ 0,0,0x0038,0 }}, /* mask for the width, in tiles*/
	{{ 0,0,0x0007,0 }}, /* mask for the height, in tiles */
	{{ 0,0,0x0040,0 }}, /* mask for the horizontal flip */
	{{ 0 }},            /* mask for the vertical flip */
	{{ 0,0x0070,0,0 }}, /* mask for the priority */
	{{ 0 }},            /* mask for the neighbor */
	{{ 0 }},            /* mask for absolute coordinates */

	{{ 0 }},            /* mask for the special value */
	0                  /* resulting value to indicate "special" */
};

void vindictr_state::video_start()
{
	/* save states */
	save_item(NAME(m_playfield_tile_bank));
	save_item(NAME(m_playfield_xscroll));
	save_item(NAME(m_playfield_yscroll));
}



/*************************************
 *
 *  Palette RAM control
 *
 *************************************/

WRITE16_MEMBER( vindictr_state::vindictr_paletteram_w )
{
	static const int ztable[16] =
		{ 0x0, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10, 0x11 };
	int c;

	/* first blend the data */
	COMBINE_DATA(&m_paletteram[offset]);
	data = m_paletteram[offset];

	/* now generate colors at all 16 intensities */
	for (c = 0; c < 8; c++)
	{
		int i = ztable[((data >> 12) + (c * 2)) & 15];
		int r = ((data >> 8) & 15) * i;
		int g = ((data >> 4) & 15) * i;
		int b = ((data >> 0) & 15) * i;

		m_palette->set_pen_color(offset + c*2048,rgb_t(r,g,b));
	}
}



/*************************************
 *
 *  Periodic scanline updater
 *
 *************************************/

void vindictr_state::scanline_update(screen_device &screen, int scanline)
{
	int x;

	/* keep in range */
	int offset = ((scanline - 8) / 8) * 64 + 42;
	if (offset < 0)
		offset += 0x7c0;
	else if (offset >= 0x7c0)
		return;

	/* update the current parameters */
	for (x = 42; x < 64; x++)
	{
		uint16_t data = m_alpha_tilemap->basemem_read(offset++);

		switch ((data >> 9) & 7)
		{
			case 2:     /* /PFB */
				if (m_playfield_tile_bank != (data & 7))
				{
					screen.update_partial(scanline - 1);
					m_playfield_tile_bank = data & 7;
					m_playfield_tilemap->mark_all_dirty();
				}
				break;

			case 3:     /* /PFHSLD */
				if (m_playfield_xscroll != (data & 0x1ff))
				{
					screen.update_partial(scanline - 1);
					m_playfield_tilemap->set_scrollx(0, data);
					m_playfield_xscroll = data & 0x1ff;
				}
				break;

			case 4:     /* /MOHS */
				if (m_mob->xscroll() != (data & 0x1ff))
				{
					screen.update_partial(scanline - 1);
					m_mob->set_xscroll(data & 0x1ff);
				}
				break;

			case 5:     /* /PFSPC */
				break;

			case 6:     /* /VIRQ */
				scanline_int_write_line(1);
				break;

			case 7:     /* /PFVS */
			{
				/* a new vscroll latches the offset into a counter; we must adjust for this */
				int offset = scanline;
				const rectangle &visible_area = screen.visible_area();
				if (offset > visible_area.bottom())
					offset -= visible_area.bottom() + 1;

				if (m_playfield_yscroll != ((data - offset) & 0x1ff))
				{
					screen.update_partial(scanline - 1);
					m_playfield_tilemap->set_scrolly(0, data - offset);
					m_mob->set_yscroll((data - offset) & 0x1ff);
				}
				break;
			}
		}
	}
}



/*************************************
 *
 *  Main refresh
 *
 *************************************/

uint32_t vindictr_state::screen_update_vindictr(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	// start drawing
	m_mob->draw_async(cliprect);

	/* draw the playfield */
	m_playfield_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	// draw and merge the MO
	bitmap_ind16 &mobitmap = m_mob->bitmap();
	for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
		for (int y = rect->top(); y <= rect->bottom(); y++)
		{
			uint16_t *mo = &mobitmap.pix16(y);
			uint16_t *pf = &bitmap.pix16(y);
			for (int x = rect->left(); x <= rect->right(); x++)
				if (mo[x] != 0xffff)
				{
					/* partially verified via schematics (there are a lot of PALs involved!):

					    SHADE = PAL(MPR1-0, LB7-0, PFX6-5, PFX3-2, PF/M)

					    if (SHADE)
					        CRA |= 0x100

					    MOG3-1 = ~MAT3-1 if MAT6==1 and MSD3==1
					*/
					int mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;

					/* upper bit of MO priority signals special rendering and doesn't draw anything */
					if (mopriority & 4)
						continue;

					/* MO pen 1 doesn't draw, but it sets the SHADE flag and bumps the palette offset */
					if ((mo[x] & 0x0f) == 1)
					{
						if ((mo[x] & 0xf0) != 0)
							pf[x] |= 0x100;
					}
					else
						pf[x] = mo[x] & atari_motion_objects_device::DATA_MASK;

					/* don't erase yet -- we need to make another pass later */
				}
		}

	/* add the alpha on top */
	m_alpha_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	/* now go back and process the upper bit of MO priority */
	for (const sparse_dirty_rect *rect = m_mob->first_dirty_rect(cliprect); rect != nullptr; rect = rect->next())
		for (int y = rect->top(); y <= rect->bottom(); y++)
		{
			uint16_t *mo = &mobitmap.pix16(y);
			uint16_t *pf = &bitmap.pix16(y);
			for (int x = rect->left(); x <= rect->right(); x++)
				if (mo[x] != 0xffff)
				{
					int mopriority = mo[x] >> atari_motion_objects_device::PRIORITY_SHIFT;

					/* upper bit of MO priority might mean palette kludges */
					if (mopriority & 4)
					{
						/* if bit 2 is set, start setting high palette bits */
						if (mo[x] & 2)
							m_mob->apply_stain(bitmap, pf, mo, x, y);

						/* if the upper bit of pen data is set, we adjust the final intensity */
						if (mo[x] & 8)
							pf[x] |= (~mo[x] & 0xe0) << 6;
					}
				}
		}
	return 0;
}