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

                                  





                                                                            
                
                           
                   
 
 
                                                       


                                                                                      
                               

 

                                                                                
                                                                                                                 
 
                                                       
                                                                          
                                                     
 
                                                   
                                      
                                                    

                               

                                                                           

                             
                                            
                                                   
 
                             

               
                                 

                                               
                                                                                                                     



                                                

                                                                                                            
                 
                                                                                  

                      


                                                                                                    

                      
                                                                                                         

                                                                                  


                      

                                                                                     
 


                 
 
 
                                        
 

                                           


                                                                                                                                         
                                                                                                                   

                 
                                                 


                                    
                                                               
                        
 

                          








                                                            
                                                  


                                                   


                                    
                                                         
 
                                              
                                 
                                                                   
                                                   
                                                                                                       


                                    
                                                                          





                                 
                                                                                                                    
 
                                                       
                                                                          
                                                     
 

                                                   

                                                    
 
                                             

                                                                                     
 
                               

                                                                           

                                                                                              
                                                   
 



                                                                                                    
 
                                                                                                    
                                                                                                         
            
                                                                                  
 
                                                                                                                                
 
                                                         
 
                                                                          


                 








                                                                                                           

                                                                






















                                                                                      
 
                                       
 





















































































                                                                             

                                                                                                                                        
 
                                                                                                                          



































                                                                                                                             
                                                                                                                    
 
                                                       
                                                                          
                                                     
 
                                      

                                                   
 
                                             



                                                                                     
 
                               

                                                                           

                                                                                              
                                                   
                                  

                                                                
                                                                                                     
 



                         
                                                                                              

                              
                                                                                              

                              
 

                                                     
 
                                                                          

                 
// license:BSD-3-Clause
// copyright-holders:Bryan McPhail
/***************************************************************************

    Rohga Video emulation - Bryan McPhail, mish@tendril.co.uk

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

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


WRITE16_MEMBER(rohga_state::rohga_buffer_spriteram16_w)
{
	// Spriteram seems to be triple buffered (no sprite lag on real pcb, but there
	// is on driver with only double buffering)
	m_spriteram[0]->copy();
}

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

uint32_t rohga_state::screen_update_rohga(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
	address_space &space = machine().dummy_space();
	uint16_t flip = m_deco_tilegen[0]->pf_control_r(space, 0, 0xffff);
	uint16_t priority = m_decocomn->priority_r();

	// sprites are flipped relative to tilemaps
	flip_screen_set(BIT(flip, 7));
	m_sprgen[0]->set_flip_screen(!BIT(flip, 7));

	/* Update playfields */
	m_deco_tilegen[0]->pf_update(m_pf_rowscroll[0], m_pf_rowscroll[1]);
	m_deco_tilegen[1]->pf_update(m_pf_rowscroll[2], m_pf_rowscroll[3]);

	/* Draw playfields */
	screen.priority().fill(0, cliprect);
	bitmap.fill(m_palette->pen(768), cliprect);

	switch (priority & 3)
	{
	case 0:
		if (priority & 4)
		{
			// Draw as 1 8BPP layer
			m_deco_tilegen[1]->tilemap_12_combine_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 3);
		}
		else
		{
			// Draw as 2 4BPP layers
			m_deco_tilegen[1]->tilemap_2_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 1);
			m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 2);
		}
		m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 4);
		break;
	case 1:
		m_deco_tilegen[1]->tilemap_2_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 1);
		m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 2);
		m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 4);
		break;
	case 2:
		m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0/*TILEMAP_DRAW_OPAQUE*/, 1);
		m_deco_tilegen[1]->tilemap_2_draw(screen, bitmap, cliprect, 0, 2);
		m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 4);
		break;
	}

	m_sprgen[0]->draw_sprites(bitmap, cliprect, m_spriteram[0]->buffer(), 0x400);
	m_deco_tilegen[0]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);

	return 0;
}



VIDEO_START_MEMBER(rohga_state,wizdfire)
{
	m_sprgen[0]->alloc_sprite_bitmap();
	m_sprgen[1]->alloc_sprite_bitmap();
}

// not amazingly efficient, called multiple times to pull a layer out of the sprite bitmaps, but keeps correct sprite<->sprite priorities
void rohga_state::mixwizdfirelayer(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t pri, uint16_t primask)
{
	int y, x;
	const pen_t *paldata = m_palette->pens();
	bitmap_ind16* sprite_bitmap;
	int penbase;

	sprite_bitmap = &m_sprgen[1]->get_sprite_temp_bitmap();
	penbase = 0x600;

	uint16_t* srcline;
	uint32_t* dstline;


	for (y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		srcline=&sprite_bitmap->pix16(y,0);
		dstline=&bitmap.pix32(y,0);

		for (x=cliprect.min_x;x<=cliprect.max_x;x++)
		{
			uint16_t pix = srcline[x];

			if ((pix & primask) != pri)
				continue;

			if (pix&0xf)
			{
				uint16_t pen = pix&0x1ff;

				if (pen&0x100)
				{
					uint32_t base = dstline[x];
					pen &=0xff;
					dstline[x] = alpha_blend_r32(base, paldata[pen+penbase], 0x80);
				}
				else
				{
					dstline[x] = paldata[pen+penbase];
				}
			}
		}
	}
}

uint32_t rohga_state::screen_update_wizdfire(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	address_space &space = machine().dummy_space();
	uint16_t flip = m_deco_tilegen[0]->pf_control_r(space, 0, 0xffff);
	uint16_t priority = m_decocomn->priority_r();

	// sprites are flipped relative to tilemaps
	flip_screen_set(BIT(flip, 7));
	m_sprgen[0]->set_flip_screen(!BIT(flip, 7));
	m_sprgen[1]->set_flip_screen(!BIT(flip, 7));

	/* draw sprite gfx to temp bitmaps */
	m_sprgen[1]->draw_sprites(bitmap, cliprect, m_spriteram[1]->buffer(), 0x400);
	m_sprgen[0]->draw_sprites(bitmap, cliprect, m_spriteram[0]->buffer(), 0x400);

	/* Update playfields */
	m_deco_tilegen[0]->pf_update(nullptr, nullptr);
	m_deco_tilegen[1]->pf_update(m_pf_rowscroll[2], m_pf_rowscroll[3]);

	/* Draw playfields - Palette of 2nd playfield chip visible if playfields turned off */
	bitmap.fill(m_palette->pen(512), cliprect);

	m_deco_tilegen[1]->tilemap_2_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);
	m_sprgen[0]->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0600, 0x0600, 0x400, 0x1ff);
	m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 0);
	m_sprgen[0]->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0400, 0x0600, 0x400, 0x1ff);

	if ((priority & 0x1f) == 0x1f) /* Wizdfire has bit 0x40 always set, Dark Seal 2 doesn't?! */
		m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, TILEMAP_DRAW_ALPHA(0x80), 0);
	else
		m_deco_tilegen[1]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);

	m_sprgen[0]->inefficient_copy_sprite_bitmap(bitmap, cliprect, 0x0000, 0x0400, 0x400, 0x1ff); // 0x000 and 0x200 of 0x600

	mixwizdfirelayer(bitmap, cliprect, 0x000, 0x000);

	m_deco_tilegen[0]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);
	return 0;
}

void rohga_state::mixnitroballlayer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	int y, x;
	const pen_t *paldata = &m_palette->pen(0);
	bitmap_ind16 *sprite_bitmap1, *sprite_bitmap2;
	bitmap_ind8* priority_bitmap;

	uint16_t priority = m_decocomn->priority_r();

	sprite_bitmap1 = &m_sprgen[0]->get_sprite_temp_bitmap();
	sprite_bitmap2 = &m_sprgen[1]->get_sprite_temp_bitmap();
	priority_bitmap = &screen.priority();

	uint32_t* dstline;
	uint16_t *srcline1, *srcline2;
	uint8_t *srcpriline;

	for (y=cliprect.min_y;y<=cliprect.max_y;y++)
	{
		srcline1=&sprite_bitmap1->pix16(y,0);
		srcline2=&sprite_bitmap2->pix16(y,0);
		srcpriline=&priority_bitmap->pix8(y,0);

		dstline=&bitmap.pix32(y,0);

		for (x=cliprect.min_x;x<=cliprect.max_x;x++)
		{
			uint16_t pix1 = srcline1[x];
			uint16_t pix2 = srcline2[x];

			/* Here we have
			 pix1 - raw pixel / colour / priority data from first 1st chip
			 pix2 - raw pixel / colour / priority data from first 2nd chip
			*/

			int pri1, pri2;

			// pix1 sprite vs playfield
			switch (priority) // TODO : Verify this from real pcb
			{
				case 0x00:
				default:
					{
						switch (pix1 & 0xe00)
						{
							case 0x000:
							default:
								pri1 = 0x200;
								break;
							case 0x200:
								pri1 = 0x020;
								break;
							case 0x400:
								pri1 = 0x008;
								break;
							case 0x600:
								pri1 = 0x002;
								break;
							case 0x800:
								pri1 = 0x100;
								break;
							case 0xa00:
								pri1 = 0x040;
								break;
							case 0xc00:
								pri1 = 0x004;
								break;
							case 0xe00:
								pri1 = 0x001;
								break;
						}
					}
					break;
				case 0x20:
					{
						switch (pix1 & 0xe00)
						{
							case 0x000:
							default:
								pri1 = 0x080;
								break;
							case 0x200:
								pri1 = 0x004;
								break;
							case 0x400:
								pri1 = 0x002;
								break;
							case 0x600:
								pri1 = 0x001;
								break;
							case 0x800:
								pri1 = 0x100;
								break;
							case 0xa00:
								pri1 = 0x020;
								break;
							case 0xc00:
								pri1 = 0x008;
								break;
							case 0xe00:
								pri1 = 0x200;
								break;
						}
					}
					break;
			}

			// pix2 sprite vs pix1 sprite
			pri2 = 0x080;
			switch (priority)
			{
				case 0x00:
				default:
					pri2 = 0x080;
					break;
				case 0x20:
					pri2 = 0x010;
					break;
			}

			uint8_t bgpri = srcpriline[x];
			/* once we get here we have

			pri1 - 0x001/0x002/0x004/0x008/0x010/0x020/0x040/0x080/0x100/0x200 (sprite chip 1 pixel priority relative to bg)
			pri2 - 0x080/0x010 (sprite chip 2 pixel priority relative to bg)

			bgpri - 0x008/0x040 (from drawing tilemaps earlier, to compare above pri1/pri2 priorities against)
			pix1 - same as before (ready to extract just colour data from)
			pix2 - same as before  ^^
			*/

			int drawnpixe1 = 0;
			if (pix1 & 0xf)
			{
				if (pri1 > bgpri)
				{
					dstline[x] = paldata[(pix1&0x1ff)+0x400];
					drawnpixe1 = 1;
				}
			}

			if (pix2 & 0xf)
			{
				if (pri2 > bgpri)
				{
					if ((!drawnpixe1) || (pri2 > pri1))
					{
						if (pix2 & 0x100)
						{
							uint32_t base = dstline[x];
							dstline[x] = alpha_blend_r32(base, paldata[(pix2&0xff)+0x600], 0x80);
						}
						else
						{
							dstline[x] = paldata[(pix2&0xff)+0x600];
						}
					}
				}
			}
		}
	}
}

uint32_t rohga_state::screen_update_nitrobal(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
	address_space &space = machine().dummy_space();
	uint16_t flip = m_deco_tilegen[0]->pf_control_r(space, 0, 0xffff);
	uint16_t priority = m_decocomn->priority_r();

	flip_screen_set(BIT(flip, 7));
	m_sprgen[0]->set_flip_screen(BIT(flip, 7));
	m_sprgen[1]->set_flip_screen(BIT(flip, 7));

	/* draw sprite gfx to temp bitmaps */
	m_sprgen[0]->set_alt_format(true);
	m_sprgen[1]->set_alt_format(true);
	m_sprgen[1]->draw_sprites(bitmap, cliprect, m_spriteram[1]->buffer(), 0x400);
	m_sprgen[0]->draw_sprites(bitmap, cliprect, m_spriteram[0]->buffer(), 0x400);

	/* Update playfields */
	m_deco_tilegen[0]->pf_update(m_pf_rowscroll[0], m_pf_rowscroll[1]);
	m_deco_tilegen[1]->pf_update(m_pf_rowscroll[2], m_pf_rowscroll[3]);

	/* Draw playfields - Palette of 2nd playfield chip visible if playfields turned off */
	bitmap.fill(m_palette->pen(512), cliprect);
	screen.priority().fill(0);

	/* pf3 and pf4 are combined into a single 8bpp bitmap */
	m_deco_tilegen[1]->tilemap_12_combine_draw(screen, bitmap, cliprect, TILEMAP_DRAW_OPAQUE, 0);

	switch (priority)
	{
		case 0:
		default:
			m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 0x008);
			break;
		case 0x20:
			m_deco_tilegen[0]->tilemap_2_draw(screen, bitmap, cliprect, 0, 0x040);
			break;
	}

	/* TODO verify priorities + mixing / alpha */
	mixnitroballlayer(screen,bitmap,cliprect);

	m_deco_tilegen[0]->tilemap_1_draw(screen, bitmap, cliprect, 0, 0);
	return 0;
}