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





                                                                            
                
                           

 
                                       


              

                                                               


                               

                                                       


                   

                                          

                   

                                          


 
                            
 
                           
         







                                                                                        


            







                                                                                        



         
                                       
 

                                           



 
                                                
 
                                               




                                  



                                              



                                       
                                   
 
                                
                                   
 
                                       
                                   

         
                                                                                                    


 
 
                               
 

                                                         


                                                    
 
                                                                                                                                                                   


                                                                     
                                          
 
                                           


 
                                 
 
                                                                         


 
                                 
 
                                       


 
                                                                               




                               
                                               
 

                                     
 
                                                                                  




                                    
                              



         
                                                                               




                               

                                         


                               

                                                   
 
                                                   



         
                                                                                          
 


                             
                                     

                      
                                                                                
         


 
                                                                                                           
 
                   
                                                        
 

                                       



                 
                                             
 
                          
                   
         

                      
                                                                    
 
                                                                     
 

                                           
 

                                                 
 


                                                                
 


                                                                 
 
                                                               
                                                                           
 
                                                                        
                         
                                              













































                                                                              
                                                                           

                                                                                             
                                                                           


                                                                                            
                                                                                                 

                                           
                         


                 
// license:BSD-3-Clause
// copyright-holders:Stefan Jokisch
/***************************************************************************

Atari Tank 8 video emulation

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

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


PALETTE_INIT_MEMBER(tank8_state, tank8)
{
	int i;

	palette.set_indirect_color(8, rgb_t(0x00, 0x00, 0x00));
	palette.set_indirect_color(9, rgb_t(0xff, 0xff, 0xff));

	for (i = 0; i < 8; i++)
	{
		palette.set_pen_indirect(2 * i + 0, 8);
		palette.set_pen_indirect(2 * i + 1, i);
	}

	/* walls */
	palette.set_pen_indirect(0x10, 8);
	palette.set_pen_indirect(0x11, 9);

	/* mines */
	palette.set_pen_indirect(0x12, 8);
	palette.set_pen_indirect(0x13, 9);
}


void tank8_state::set_pens()
{
	if (*m_team & 0x01)
	{
		m_palette->set_indirect_color(0, rgb_t(0xff, 0x00, 0x00)); /* red     */
		m_palette->set_indirect_color(1, rgb_t(0x00, 0x00, 0xff)); /* blue    */
		m_palette->set_indirect_color(2, rgb_t(0xff, 0xff, 0x00)); /* yellow  */
		m_palette->set_indirect_color(3, rgb_t(0x00, 0xff, 0x00)); /* green   */
		m_palette->set_indirect_color(4, rgb_t(0xff, 0x00, 0xff)); /* magenta */
		m_palette->set_indirect_color(5, rgb_t(0xe0, 0xc0, 0x70)); /* puce    */
		m_palette->set_indirect_color(6, rgb_t(0x00, 0xff, 0xff)); /* cyan    */
		m_palette->set_indirect_color(7, rgb_t(0xff, 0xaa, 0xaa)); /* pink    */
	}
	else
	{
		m_palette->set_indirect_color(0, rgb_t(0xff, 0x00, 0x00)); /* red     */
		m_palette->set_indirect_color(2, rgb_t(0xff, 0x00, 0x00)); /* red     */
		m_palette->set_indirect_color(4, rgb_t(0xff, 0x00, 0x00)); /* red     */
		m_palette->set_indirect_color(6, rgb_t(0xff, 0x00, 0x00)); /* red     */
		m_palette->set_indirect_color(1, rgb_t(0x00, 0x00, 0xff)); /* blue    */
		m_palette->set_indirect_color(3, rgb_t(0x00, 0x00, 0xff)); /* blue    */
		m_palette->set_indirect_color(5, rgb_t(0x00, 0x00, 0xff)); /* blue    */
		m_palette->set_indirect_color(7, rgb_t(0x00, 0x00, 0xff)); /* blue    */
	}
}


WRITE8_MEMBER(tank8_state::video_ram_w)
{
	m_video_ram[offset] = data;
	m_tilemap->mark_tile_dirty(offset);
}



TILE_GET_INFO_MEMBER(tank8_state::get_tile_info)
{
	uint8_t code = m_video_ram[tile_index];

	int color = 0;

	if ((code & 0x38) == 0x28)
	{
		if ((code & 7) != 3)
			color = 8; /* walls */
		else
			color = 9; /* mines */
	}
	else
	{
		if (tile_index & 0x010)
			color |= 1;

		if (code & 0x80)
			color |= 2;

		if (tile_index & 0x200)
			color |= 4;
	}

	SET_TILE_INFO_MEMBER(code >> 7, code, color, (code & 0x40) ? (TILE_FLIPX | TILE_FLIPY) : 0);
}



void tank8_state::video_start()
{
	m_collision_timer = timer_alloc(TIMER_COLLISION);

	m_screen->register_screen_bitmap(m_helper1);
	m_screen->register_screen_bitmap(m_helper2);
	m_screen->register_screen_bitmap(m_helper3);

	m_tilemap = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(FUNC(tank8_state::get_tile_info),this), TILEMAP_SCAN_ROWS, 16, 16, 32, 32);

	/* VBLANK starts on scanline #256 and ends on scanline #24 */

	m_tilemap->set_scrolly(0, 2 * 24);

	save_item(NAME(m_collision_index));
}


int tank8_state::get_x_pos(int n)
{
	return 498 - m_pos_h_ram[n] - 2 * (m_pos_d_ram[n] & 128); /* ? */
}


int tank8_state::get_y_pos(int n)
{
	return 2 * m_pos_v_ram[n] - 62;
}


void tank8_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int i;

	for (i = 0; i < 8; i++)
	{
		uint8_t code = ~m_pos_d_ram[i];

		int x = get_x_pos(i);
		int y = get_y_pos(i);

		m_gfxdecode->gfx((code & 0x04) ? 2 : 3)->transpen(bitmap,cliprect,
			code & 0x03,
			i,
			code & 0x10,
			code & 0x08,
			x,
			y, 0);
	}
}


void tank8_state::draw_bullets(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	int i;

	for (i = 0; i < 8; i++)
	{
		int x = get_x_pos(8 + i);
		int y = get_y_pos(8 + i);

		x -= 4; /* ? */

		rectangle rect(x, x + 3, y, y + 4);
		rect &= cliprect;

		bitmap.fill((i << 1) | 0x01, rect);
	}
}


void tank8_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
	case TIMER_COLLISION:
		set_collision(param);
		break;
	default:
		assert_always(false, "Unknown id in tank8_state::device_timer");
	}
}


uint32_t tank8_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	set_pens();
	m_tilemap->draw(screen, bitmap, cliprect, 0, 0);

	draw_sprites(bitmap, cliprect);
	draw_bullets(bitmap, cliprect);
	return 0;
}


WRITE_LINE_MEMBER(tank8_state::screen_vblank)
{
	// on falling edge
	if (!state)
	{
		int x;
		int y;
		const rectangle &visarea = m_screen->visible_area();

		m_tilemap->draw(*m_screen, m_helper1, visarea, 0, 0);

		m_helper2.fill(8, visarea);
		m_helper3.fill(8, visarea);

		draw_sprites(m_helper2, visarea);
		draw_bullets(m_helper3, visarea);

		for (y = visarea.min_y; y <= visarea.max_y; y++)
		{
			int _state = 0;

			const uint16_t* p1 = &m_helper1.pix16(y);
			const uint16_t* p2 = &m_helper2.pix16(y);
			const uint16_t* p3 = &m_helper3.pix16(y);

			if ((m_screen->frame_number() ^ y) & 1)
				continue; /* video display is interlaced */

			for (x = visarea.min_x; x <= visarea.max_x; x++)
			{
				uint8_t index;

				/* neither wall nor mine */
				if ((p1[x] != 0x11) && (p1[x] != 0x13))
				{
					_state = 0;
					continue;
				}

				/* neither tank nor bullet */
				if ((p2[x] == 8) && (p3[x] == 8))
				{
					_state = 0;
					continue;
				}

				/* bullets cannot hit mines */
				if ((p3[x] != 8) && (p1[x] == 0x13))
				{
					_state = 0;
					continue;
				}

				if (_state)
					continue;

				if (p3[x] != 8)
				{
					index = ((p3[x] & ~0x01) >> 1) | 0x18;

					if (1)
						index |= 0x20;

					if (0)
						index |= 0x40;

					if (1)
						index |= 0x80;
				}
				else
				{
					int sprite_num = (p2[x] & ~0x01) >> 1;
					index = sprite_num | 0x10;

					if (p1[x] == 0x11)
						index |= 0x20;

					if (y - get_y_pos(sprite_num) >= 8)
						index |= 0x40; /* collision on bottom side */

					if (x - get_x_pos(sprite_num) >= 8)
						index |= 0x80; /* collision on right side */
				}

				m_collision_timer->adjust(m_screen->time_until_pos(y, x), index);

				_state = 1;
			}
		}
	}
}