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

                                







                                                                           
                
                            







                                      



                                       
                                

                                             











                                              









                                       
                                              
 
                                      

                                             
                                                                                                      


 
                                                 
 
                                

                                                           
                                                
                                 
                                                               



                                                                                        

                                                       


                    

                                                       


                                                        
                                             










                                       
                                         

                                                   
                           
                                                   

                                                              
                                
                                       
                               
                                         


 
                                         

                                                   
                           
                                                   

                                                              
                                
                                       
                               
                                         









                                       
                                            
 
                                          


 
                                           
 
                                          









                                       
                                          
 
                                                    


 
                                          
 
                                                    


 
                                         
 
                                            


 
                                         
 
                                            









                                       
                                                 
 
                               
                                                 


 
                                              
 
                               
                                              


 
                                                
 
                                         


 
                                             
 
                                      









                                       
                                                                               
 



                                                                        
                                            


                                                

                             
                                     


                                                                                 
                                                                              



                                                                                          
                                                                                                 








                                                                                 
                                                                              



                                                                                          
                                                                                           



                         

                                          









                                       
                                                         




                                                                         
                                                                                       



                                                                       
                                                                                
                                                               




                                                                  
                                                                                    
                                                                 


            
                                                                                                 


 
                                                             




                                                                         
                                                                                       






                                                                
                                                                                    


                                                                  
                                                     

            
                                                                                                   









                                       
                                                                
 




                                                                                    
                                               

                                       
 
                                                           
                                     

                                                                                      
                               





                                                        
                       

                                                                                       
                                                                          
 

                                                               

                                                                  
                                 
                                    
                                 


                                                                                                  

                                                          
                                                                                 
                                                        
                                                                          
                                                               
                                                                                 
                                            
                                                                                 

                                                            
                                                                               
                                                        
                                                                          
                                                             
                                                                               
                                            
                                                                               
                                 



                                                                                                          
                               





                                                        


                                                                                       
                                                                          


                                                               

                                                                  


                                    

                                                                                                  

                                                          
                                                                                 
                                                               
                                                                                 
                                                        
                                                                          
                                            
                                                                                 

                                                        
                                                                               
                                                                 
                                                                               
                                                        
                                                                          
                                            
                                                                               



                                 

                                                                                               



                              


                                                                                       
                                                                          


                                           

                                                                  


                                    

                                                                                                  

                                                          
                                                                                 
                                            
                                                                                 

                                                        
                                                                               
                                            
                                                                               



                                 
                                                                                             
                               





                                                          


                                                                                       


                                                                                          

                                                  
                                                                         
                                                       
                                                                  
                                                       
                                                                         
                                                
                                                                  
                                    
                                                                         

                                                    
                                                                       
                                                       
                                                                  
                                                     
                                                                       
                                                
                                                                  
                                    
                                                                       





                                                            
                                                                     
 
                                                      
         


                              
 
                                                                   
 
                                                        
                                     
                                                                               


                                       
                                                                                                                       

                                                                                     



                                                 
                                                                                     

                                                         
                                                                                        












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

    BattleToads

    Video hardware emulation

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

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


#define BT_DEBUG 0



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

void btoads_state::video_start()
{
	/* initialize the swapped pointers */
	m_vram_fg_draw = m_vram_fg0;
	m_vram_fg_display = m_vram_fg1;

	save_item(NAME(m_xscroll0));
	save_item(NAME(m_xscroll1));
	save_item(NAME(m_yscroll0));
	save_item(NAME(m_yscroll1));
	save_item(NAME(m_screen_control));

	save_item(NAME(m_sprite_source_offs));
	save_item(NAME(m_sprite_dest_offs));
	save_item(NAME(m_misc_control));
}



/*************************************
 *
 *  Control registers
 *
 *************************************/

WRITE16_MEMBER( btoads_state::misc_control_w )
{
	COMBINE_DATA(&m_misc_control);

	/* bit 3 controls sound reset line */
	m_audiocpu->set_input_line(INPUT_LINE_RESET, (m_misc_control & 8) ? CLEAR_LINE : ASSERT_LINE);
}


WRITE16_MEMBER( btoads_state::display_control_w )
{
	if (ACCESSING_BITS_8_15)
	{
		/* allow multiple changes during display */
		int scanline = m_screen->vpos();
		if (scanline > 0)
			m_screen->update_partial(scanline - 1);

		/* bit 15 controls which page is rendered and which page is displayed */
		if (data & 0x8000)
		{
			m_vram_fg_draw = m_vram_fg1;
			m_vram_fg_display = m_vram_fg0;
		}
		else
		{
			m_vram_fg_draw = m_vram_fg0;
			m_vram_fg_display = m_vram_fg1;
		}

		/* stash the remaining data for later */
		m_screen_control = data >> 8;
	}
}



/*************************************
 *
 *  Scroll registers
 *
 *************************************/

WRITE16_MEMBER( btoads_state::scroll0_w )
{
	/* allow multiple changes during display */
//  m_screen->update_now();
	m_screen->update_partial(m_screen->vpos());

	/* upper bits are Y scroll, lower bits are X scroll */
	if (ACCESSING_BITS_8_15)
		m_yscroll0 = data >> 8;
	if (ACCESSING_BITS_0_7)
		m_xscroll0 = data & 0xff;
}


WRITE16_MEMBER( btoads_state::scroll1_w )
{
	/* allow multiple changes during display */
//  m_screen->update_now();
	m_screen->update_partial(m_screen->vpos());

	/* upper bits are Y scroll, lower bits are X scroll */
	if (ACCESSING_BITS_8_15)
		m_yscroll1 = data >> 8;
	if (ACCESSING_BITS_0_7)
		m_xscroll1 = data & 0xff;
}



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

WRITE16_MEMBER( btoads_state::paletteram_w )
{
	m_tlc34076->write(offset/2, data);
}


READ16_MEMBER( btoads_state::paletteram_r )
{
	return m_tlc34076->read(offset/2);
}



/*************************************
 *
 *  Background video RAM
 *
 *************************************/

WRITE16_MEMBER( btoads_state::vram_bg0_w )
{
	COMBINE_DATA(&m_vram_bg0[offset & 0x3fcff]);
}


WRITE16_MEMBER( btoads_state::vram_bg1_w )
{
	COMBINE_DATA(&m_vram_bg1[offset & 0x3fcff]);
}


READ16_MEMBER( btoads_state::vram_bg0_r )
{
	return m_vram_bg0[offset & 0x3fcff];
}


READ16_MEMBER( btoads_state::vram_bg1_r )
{
	return m_vram_bg1[offset & 0x3fcff];
}



/*************************************
 *
 *  Foreground video RAM
 *
 *************************************/

WRITE16_MEMBER( btoads_state::vram_fg_display_w )
{
	if (ACCESSING_BITS_0_7)
		m_vram_fg_display[offset] = data;
}


WRITE16_MEMBER( btoads_state::vram_fg_draw_w )
{
	if (ACCESSING_BITS_0_7)
		m_vram_fg_draw[offset] = data;
}


READ16_MEMBER( btoads_state::vram_fg_display_r )
{
	return m_vram_fg_display[offset];
}


READ16_MEMBER( btoads_state::vram_fg_draw_r )
{
	return m_vram_fg_draw[offset];
}



/*************************************
 *
 *  Sprite rendering
 *
 *************************************/

void btoads_state::render_sprite_row(uint16_t *sprite_source, uint32_t address)
{
	int flipxor = ((*m_sprite_control >> 10) & 1) ? 0xffff : 0x0000;
	int width = (~*m_sprite_control & 0x1ff) + 2;
	int color = (~*m_sprite_control >> 8) & 0xf0;
	int srcoffs = m_sprite_source_offs << 8;
	int srcend = srcoffs + (width << 8);
	int srcstep = 0x100 - m_sprite_scale[0];
	int dststep = 0x100 - m_sprite_scale[8];
	int dstoffs = m_sprite_dest_offs << 8;

	/* non-shadow case */
	if (!(m_misc_control & 0x10))
	{
		for ( ; srcoffs < srcend; srcoffs += srcstep, dstoffs += dststep)
		{
			uint16_t src = sprite_source[(srcoffs >> 10) & 0x1ff];
			if (src)
			{
				src = (src >> (((srcoffs ^ flipxor) >> 6) & 0x0c)) & 0x0f;
				if (src)
					m_sprite_dest_base[(dstoffs >> 8) & 0x1ff] = src | color;
			}
		}
	}

	/* shadow case */
	else
	{
		for ( ; srcoffs < srcend; srcoffs += srcstep, dstoffs += dststep)
		{
			uint16_t src = sprite_source[(srcoffs >> 10) & 0x1ff];
			if (src)
			{
				src = (src >> (((srcoffs ^ flipxor) >> 6) & 0x0c)) & 0x0f;
				if (src)
					m_sprite_dest_base[(dstoffs >> 8) & 0x1ff] = color;
			}
		}
	}

	m_sprite_source_offs += width;
	m_sprite_dest_offs = dstoffs >> 8;
}



/*************************************
 *
 *  Shift register read/write
 *
 *************************************/

TMS340X0_TO_SHIFTREG_CB_MEMBER(btoads_state::to_shiftreg)
{
	address &= ~0x40000000;

	/* reads from this first region are usual shift register reads */
	if (address >= 0xa0000000 && address <= 0xa3ffffff)
		memcpy(shiftreg, &m_vram_fg_display[(address & 0x3fffff) >> 4], 0x200);

	/* reads from this region set the sprite destination address */
	else if (address >= 0xa4000000 && address <= 0xa7ffffff)
	{
		m_sprite_dest_base = &m_vram_fg_draw[(address & 0x3fc000) >> 4];
		m_sprite_dest_offs = (address & 0x003fff) >> 5;
	}

	/* reads from this region set the sprite source address */
	else if (address >= 0xa8000000 && address <= 0xabffffff)
	{
		memcpy(shiftreg, &m_vram_fg_data[(address & 0x7fc000) >> 4], 0x400);
		m_sprite_source_offs = (address & 0x003fff) >> 3;
	}

	else
		logerror("%s:btoads_to_shiftreg(%08X)\n", machine().describe_context(), address);
}


TMS340X0_FROM_SHIFTREG_CB_MEMBER(btoads_state::from_shiftreg)
{
	address &= ~0x40000000;

	/* writes to this first region are usual shift register writes */
	if (address >= 0xa0000000 && address <= 0xa3ffffff)
		memcpy(&m_vram_fg_display[(address & 0x3fc000) >> 4], shiftreg, 0x200);

	/* writes to this region are ignored for our purposes */
	else if (address >= 0xa4000000 && address <= 0xa7ffffff)
		;

	/* writes to this region copy standard data */
	else if (address >= 0xa8000000 && address <= 0xabffffff)
		memcpy(&m_vram_fg_data[(address & 0x7fc000) >> 4], shiftreg, 0x400);

	/* writes to this region render the current sprite data */
	else if (address >= 0xac000000 && address <= 0xafffffff)
		render_sprite_row(shiftreg, address);

	else
		logerror("%s:btoads_from_shiftreg(%08X)\n", machine().describe_context(), address);
}



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

TMS340X0_SCANLINE_RGB32_CB_MEMBER(btoads_state::scanline_update)
{
	uint32_t fulladdr = ((params->rowaddr << 16) | params->coladdr) >> 4;
	uint16_t *bg0_base = &m_vram_bg0[(fulladdr + (m_yscroll0 << 10)) & 0x3fc00];
	uint16_t *bg1_base = &m_vram_bg1[(fulladdr + (m_yscroll1 << 10)) & 0x3fc00];
	uint8_t *spr_base = &m_vram_fg_display[fulladdr & 0x3fc00];
	uint32_t *dst = &bitmap.pix32(scanline);
	const pen_t *pens = m_tlc34076->pens();
	int coladdr = fulladdr & 0x3ff;
	int x;

	/* for each scanline, switch off the render mode */
	switch (m_screen_control & 3)
	{
		/* mode 0: used in ship level, snake boss, title screen (free play) */
		/* priority is:
		    1. Sprite pixels with high bit clear
		    2. BG1 pixels with the high bit set
		    3. Sprites
		    4. BG1
		    5. BG0
		*/
		case 0:
			for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
			{
				uint8_t sprpix = spr_base[coladdr & 0xff];

				if (sprpix && !(sprpix & 0x80))
				{
					dst[x + 0] = pens[sprpix];
					dst[x + 1] = pens[sprpix];
				}
				else
				{
					uint16_t bg0pix = bg0_base[(coladdr + m_xscroll0) & 0xff];
					uint16_t bg1pix = bg1_base[(coladdr + m_xscroll1) & 0xff];
					uint8_t sprpix = spr_base[coladdr & 0xff];

					if (bg1pix & 0x80)
						dst[x + 0] = pens[bg1pix & 0xff];
					else if (sprpix)
						dst[x + 0] = pens[sprpix];
					else if (bg1pix & 0xff)
						dst[x + 0] = pens[bg1pix & 0xff];
					else
						dst[x + 0] = pens[bg0pix & 0xff];

					if (bg1pix & 0x8000)
						dst[x + 1] = pens[bg1pix >> 8];
					else if (sprpix)
						dst[x + 1] = pens[sprpix];
					else if (bg1pix >> 8)
						dst[x + 1] = pens[bg1pix >> 8];
					else
						dst[x + 1] = pens[bg0pix >> 8];
				}
			}
			break;

		/* mode 1: used in snow level, title screen (free play), top part of rolling ball level */
		/* priority is:
		    1. Sprite pixels with high bit clear
		    2. BG0
		    3. BG1 pixels with high bit set
		    4. Sprites
		    5. BG1
		*/
		case 1:
			for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
			{
				uint8_t sprpix = spr_base[coladdr & 0xff];

				if (sprpix && !(sprpix & 0x80))
				{
					dst[x + 0] = pens[sprpix];
					dst[x + 1] = pens[sprpix];
				}
				else
				{
					uint16_t bg0pix = bg0_base[(coladdr + m_xscroll0) & 0xff];
					uint16_t bg1pix = bg1_base[(coladdr + m_xscroll1) & 0xff];

					if (bg0pix & 0xff)
						dst[x + 0] = pens[bg0pix & 0xff];
					else if (bg1pix & 0x80)
						dst[x + 0] = pens[bg1pix & 0xff];
					else if (sprpix)
						dst[x + 0] = pens[sprpix];
					else
						dst[x + 0] = pens[bg1pix & 0xff];

					if (bg0pix >> 8)
						dst[x + 1] = pens[bg0pix >> 8];
					else if (bg1pix & 0x8000)
						dst[x + 1] = pens[bg1pix >> 8];
					else if (sprpix)
						dst[x + 1] = pens[sprpix];
					else
						dst[x + 1] = pens[bg1pix >> 8];
				}
			}
			break;

		/* mode 2: used in EOA screen, jetpack level, first level, high score screen */
		/* priority is:
		    1. Sprites
		    2. BG1
		    3. BG0
		*/
		case 2:
			for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
			{
				uint8_t sprpix = spr_base[coladdr & 0xff];

				if (sprpix)
				{
					dst[x + 0] = pens[sprpix];
					dst[x + 1] = pens[sprpix];
				}
				else
				{
					uint16_t bg0pix = bg0_base[(coladdr + m_xscroll0) & 0xff];
					uint16_t bg1pix = bg1_base[(coladdr + m_xscroll1) & 0xff];

					if (bg1pix & 0xff)
						dst[x + 0] = pens[bg1pix & 0xff];
					else
						dst[x + 0] = pens[bg0pix & 0xff];

					if (bg1pix >> 8)
						dst[x + 1] = pens[bg1pix >> 8];
					else
						dst[x + 1] = pens[bg0pix >> 8];
				}
			}
			break;

		/* mode 3: used in toilet level, toad intros, bottom of rolling ball level */
		/* priority is:
		    1. BG1 pixels with the high bit set
		    2. Sprite pixels with the high bit set
		    3. BG1
		    4. Sprites
		    5. BG0
		*/
		case 3:
			for (x = params->heblnk; x < params->hsblnk; x += 2, coladdr++)
			{
				uint16_t bg0pix = bg0_base[(coladdr + m_xscroll0) & 0xff];
				uint16_t bg1pix = bg1_base[(coladdr + m_xscroll1) & 0xff];
				uint8_t sprpix = spr_base[coladdr & 0xff];

				if (bg1pix & 0x80)
					dst[x + 0] = pens[bg1pix & 0xff];
				else if (sprpix & 0x80)
					dst[x + 0] = pens[sprpix];
				else if (bg1pix & 0xff)
					dst[x + 0] = pens[bg1pix & 0xff];
				else if (sprpix)
					dst[x + 0] = pens[sprpix];
				else
					dst[x + 0] = pens[bg0pix & 0xff];

				if (bg1pix & 0x8000)
					dst[x + 1] = pens[bg1pix >> 8];
				else if (sprpix & 0x80)
					dst[x + 1] = pens[sprpix];
				else if (bg1pix >> 8)
					dst[x + 1] = pens[bg1pix >> 8];
				else if (sprpix)
					dst[x + 1] = pens[sprpix];
				else
					dst[x + 1] = pens[bg0pix >> 8];
			}
			break;
	}

	/* debugging - dump the screen contents to a file */
#if BT_DEBUG
	popmessage("screen_control = %02X", m_screen_control & 0x7f);

	if (machine().input().code_pressed(KEYCODE_X))
	{
		char name[10];
		FILE *f;
		int i;

		while (machine().input().code_pressed(KEYCODE_X)) ;

		sprintf(name, "disp%d.log", m_xcount++);
		f = fopen(name, "w");
		fprintf(f, "screen_control = %04X\n\n", m_screen_control << 8);

		for (i = 0; i < 3; i++)
		{
			uint16_t *base = (i == 0) ? (uint16_t *)m_vram_fg_display : (i == 1) ? m_vram_bg0 : m_vram_bg1;
			int xscr = (i == 0) ? 0 : (i == 1) ? m_xscroll0 : m_xscroll1;
			int yscr = (i == 0) ? 0 : (i == 1) ? m_yscroll0 : m_yscroll1;
			int y;

			for (y = 0; y < 224; y++)
			{
				uint32_t offs = ((y + yscr) & 0xff) * TOWORD(0x4000);
				for (x = 0; x < 256; x++)
				{
					uint16_t pix = base[offs + ((x + xscr) & 0xff)];
					fprintf(f, "%02X%02X", pix & 0xff, pix >> 8);
					if (x % 16 == 15) fprintf(f, " ");
				}
				fprintf(f, "\n");
			}
			fprintf(f, "\n\n");
		}
		fclose(f);
	}

	logerror("---VBLANK---\n");
#endif
}