// license:BSD-3-Clause
// copyright-holders:Bryan McPhail, David Haywood
#include "emu.h"
#include "includes/deadang.h"
#include "screen.h"
/******************************************************************************/
WRITE16_MEMBER(deadang_state::foreground_w)
{
COMBINE_DATA(&m_video_data[offset]);
m_pf1_layer->mark_tile_dirty(offset );
}
WRITE16_MEMBER(deadang_state::text_w)
{
COMBINE_DATA(&m_videoram[offset]);
m_text_layer->mark_tile_dirty(offset );
}
WRITE16_MEMBER(popnrun_state::popnrun_text_w)
{
COMBINE_DATA(&m_videoram[offset]);
m_text_layer->mark_tile_dirty(offset / 2);
}
WRITE16_MEMBER(deadang_state::bank_w)
{
if (ACCESSING_BITS_0_7)
{
m_tilebank = data&1;
if (m_tilebank!=m_oldtilebank)
{
m_oldtilebank = m_tilebank;
m_pf1_layer->mark_all_dirty();
}
}
}
/******************************************************************************/
TILEMAP_MAPPER_MEMBER(deadang_state::bg_scan)
{
return (col&0xf) | ((row&0xf)<<4) | ((col&0x70)<<4) | ((row&0xf0)<<7);
}
TILE_GET_INFO_MEMBER(deadang_state::get_pf3_tile_info)
{
const uint16_t *bgMap = (const uint16_t *)memregion("gfx6")->base();
int code= bgMap[tile_index];
SET_TILE_INFO_MEMBER(4,code&0x7ff,code>>12,0);
}
TILE_GET_INFO_MEMBER(deadang_state::get_pf2_tile_info)
{
const uint16_t *bgMap = (const uint16_t *)memregion("gfx7")->base();
int code= bgMap[tile_index];
SET_TILE_INFO_MEMBER(3,code&0x7ff,code>>12,0);
}
TILE_GET_INFO_MEMBER(deadang_state::get_pf1_tile_info)
{
int tile=m_video_data[tile_index];
int color=tile >> 12;
tile=tile&0xfff;
SET_TILE_INFO_MEMBER(2,tile+m_tilebank*0x1000,color,0);
}
TILE_GET_INFO_MEMBER(deadang_state::get_text_tile_info)
{
int tile=(m_videoram[tile_index] & 0xff) | ((m_videoram[tile_index] >> 6) & 0x300);
int color=(m_videoram[tile_index] >> 8)&0xf;
SET_TILE_INFO_MEMBER(0,tile,color,0);
}
void deadang_state::video_start()
{
m_pf3_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf3_tile_info)), tilemap_mapper_delegate(*this, FUNC(deadang_state::bg_scan)), 16, 16, 128, 256);
m_pf2_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf2_tile_info)), tilemap_mapper_delegate(*this, FUNC(deadang_state::bg_scan)), 16, 16, 128, 256);
m_pf1_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf1_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_text_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_text_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_pf2_layer->set_transparent_pen(15);
m_pf1_layer->set_transparent_pen(15);
m_text_layer->set_transparent_pen(15);
save_item(NAME(m_tilebank));
save_item(NAME(m_oldtilebank));
}
TILE_GET_INFO_MEMBER(popnrun_state::get_popnrun_text_tile_info)
{
int tile = (m_videoram[tile_index*2+0] & 0xff) << 1; // | ((m_videoram[tile_index] >> 6) & 0x300);
int attr = (m_videoram[tile_index*2+1]);
// TODO: not entirely correct (title screen/ranking colors)
// might be down to bitplanes too
int color = (attr & 3) ^ 1;
if(attr & 0x40)
tile |= 1;
SET_TILE_INFO_MEMBER(0,tile,color,0);
}
void popnrun_state::video_start()
{
m_pf3_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf3_tile_info)), tilemap_mapper_delegate(*this, FUNC(deadang_state::bg_scan)), 16, 16, 128, 256);
m_pf2_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf2_tile_info)), tilemap_mapper_delegate(*this, FUNC(deadang_state::bg_scan)), 16, 16, 128, 256);
m_pf1_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(deadang_state::get_pf1_tile_info)), TILEMAP_SCAN_COLS, 16, 16, 32, 32);
m_text_layer = &machine().tilemap().create(*m_gfxdecode, tilemap_get_info_delegate(*this, FUNC(popnrun_state::get_popnrun_text_tile_info)), TILEMAP_SCAN_ROWS, 8, 8, 32, 32);
m_pf2_layer->set_transparent_pen(0);
m_pf1_layer->set_transparent_pen(0);
m_text_layer->set_transparent_pen(0);
save_item(NAME(m_tilebank));
save_item(NAME(m_oldtilebank));
}
void deadang_state::draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int offs,fx,fy,x,y,color,sprite,pri;
for (offs = 0; offs<0x800/2; offs+=4)
{
/* Don't draw empty sprite table entries */
if ((m_spriteram[offs+3] & 0xff00)!=0xf00) continue;
switch (m_spriteram[offs+2]&0xc000) {
default:
case 0xc000: pri=0; break; /* Unknown */
case 0x8000: pri=0; break; /* Over all playfields */
case 0x4000: pri=0xf0; break; /* Under top playfield */
case 0x0000: pri=0xf0|0xcc; break; /* Under middle playfield */
}
fx= m_spriteram[offs+0]&0x2000;
fy= m_spriteram[offs+0]&0x4000;
y = m_spriteram[offs+0] & 0xff;
x = m_spriteram[offs+2] & 0xff;
if (fy) fy=0; else fy=1;
if (m_spriteram[offs+2]&0x100) x=0-(0xff-x);
color = (m_spriteram[offs+1]>>12)&0xf;
sprite = m_spriteram[offs+1]&0xfff;
if (flip_screen()) {
x=240-x;
y=240-y;
if (fx) fx=0; else fx=1;
if (fy) fy=0; else fy=1;
}
m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect,
sprite,
color,fx,fy,x,y,
screen.priority(),pri,15);
}
}
uint32_t deadang_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
/* Setup the tilemaps */
m_pf3_layer->set_scrolly(0, ((m_scroll_ram[0x01]&0xf0)<<4)+((m_scroll_ram[0x02]&0x7f)<<1)+((m_scroll_ram[0x02]&0x80)>>7) );
m_pf3_layer->set_scrollx(0, ((m_scroll_ram[0x09]&0xf0)<<4)+((m_scroll_ram[0x0a]&0x7f)<<1)+((m_scroll_ram[0x0a]&0x80)>>7) );
m_pf1_layer->set_scrolly(0, ((m_scroll_ram[0x11]&0x10)<<4)+((m_scroll_ram[0x12]&0x7f)<<1)+((m_scroll_ram[0x12]&0x80)>>7) );
m_pf1_layer->set_scrollx(0, ((m_scroll_ram[0x19]&0x10)<<4)+((m_scroll_ram[0x1a]&0x7f)<<1)+((m_scroll_ram[0x1a]&0x80)>>7) );
m_pf2_layer->set_scrolly(0, ((m_scroll_ram[0x21]&0xf0)<<4)+((m_scroll_ram[0x22]&0x7f)<<1)+((m_scroll_ram[0x22]&0x80)>>7) );
m_pf2_layer->set_scrollx(0, ((m_scroll_ram[0x29]&0xf0)<<4)+((m_scroll_ram[0x2a]&0x7f)<<1)+((m_scroll_ram[0x2a]&0x80)>>7) );
/* Control byte:
0x01: Background playfield disable
0x02: Middle playfield disable
0x04: Top playfield disable
0x08: ? Toggles at start of game
0x10: Sprite disable
0x20: Unused?
0x40: Flipscreen
0x80: Always set?
*/
m_pf3_layer->enable(!(m_scroll_ram[0x34]&1));
m_pf1_layer->enable(!(m_scroll_ram[0x34]&2));
m_pf2_layer->enable(!(m_scroll_ram[0x34]&4));
flip_screen_set(m_scroll_ram[0x34]&0x40 );
bitmap.fill(m_palette->black_pen(), cliprect);
screen.priority().fill(0, cliprect);
m_pf3_layer->draw(screen, bitmap, cliprect, 0,1);
m_pf1_layer->draw(screen, bitmap, cliprect, 0,2);
m_pf2_layer->draw(screen, bitmap, cliprect, 0,4);
if (!(m_scroll_ram[0x34]&0x10)) draw_sprites(screen, bitmap,cliprect);
m_text_layer->draw(screen, bitmap, cliprect, 0,0);
return 0;
}
void popnrun_state::popnrun_draw_sprites(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int offs,fx,fy,x,y,color,sprite,pri;
// TODO: might have more bits in either 0x3800-0x3bff or 0x3e00-0x3fff
for (offs = 0; offs<0x200/2; offs+=2)
{
/* Don't draw empty sprite table entries */
//if ((m_spriteram[offs+3] & 0xff00)!=0xf00) continue;
pri = 0;
#ifdef UNUSED_FUNCTION
switch (m_spriteram[offs+2]&0xc000) {
default:
case 0xc000: pri=0; break; /* Unknown */
case 0x8000: pri=0; break; /* Over all playfields */
case 0x4000: pri=0xf0; break; /* Under top playfield */
case 0x0000: pri=0xf0|0xcc; break; /* Under middle playfield */
}
#endif
fx = m_spriteram[offs+0]&0x4000;
fy = m_spriteram[offs+0]&0x8000;
y = m_spriteram[offs+1] & 0xff;
x = (m_spriteram[offs+1] >> 8) & 0xff;
#ifdef UNUSED_FUNCTION
if (fy) fy=0; else fy=1;
if (m_spriteram[offs+2]&0x100) x=0-(0xff-x);
#endif
color = (m_spriteram[offs+0]>>12)&0x7;
sprite = m_spriteram[offs+0]&0xfff;
#ifdef UNUSED_FUNCTION
if (flip_screen()) {
x=240-x;
y=240-y;
if (fx) fx=0; else fx=1;
if (fy) fy=0; else fy=1;
}
#endif
m_gfxdecode->gfx(1)->prio_transpen(bitmap,cliprect,
sprite,
color,fx,fy,x,y,
screen.priority(),pri,0);
}
}
uint32_t popnrun_state::popnrun_screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
// TODO: different scroll RAM hookup
// 0x18 seems to enable the various layers
/* Setup the tilemaps */
// m_pf3_layer->set_scrolly(0, ((m_scroll_ram[0x01]&0xf0)<<4)+((m_scroll_ram[0x02]&0x7f)<<1)+((m_scroll_ram[0x02]&0x80)>>7) );
// m_pf3_layer->set_scrollx(0, ((m_scroll_ram[0x09]&0xf0)<<4)+((m_scroll_ram[0x0a]&0x7f)<<1)+((m_scroll_ram[0x0a]&0x80)>>7) );
// m_pf1_layer->set_scrolly(0, ((m_scroll_ram[0x11]&0x10)<<4)+((m_scroll_ram[0x12]&0x7f)<<1)+((m_scroll_ram[0x12]&0x80)>>7) );
// m_pf1_layer->set_scrollx(0, ((m_scroll_ram[0x19]&0x10)<<4)+((m_scroll_ram[0x1a]&0x7f)<<1)+((m_scroll_ram[0x1a]&0x80)>>7) );
// m_pf2_layer->set_scrolly(0, ((m_scroll_ram[0x21]&0xf0)<<4)+((m_scroll_ram[0x22]&0x7f)<<1)+((m_scroll_ram[0x22]&0x80)>>7) );
// m_pf2_layer->set_scrollx(0, ((m_scroll_ram[0x29]&0xf0)<<4)+((m_scroll_ram[0x2a]&0x7f)<<1)+((m_scroll_ram[0x2a]&0x80)>>7) );
m_pf3_layer->enable(!(m_scroll_ram[0x34]&1));
m_pf1_layer->enable(!(m_scroll_ram[0x34]&2));
m_pf2_layer->enable(!(m_scroll_ram[0x34]&4));
// flip_screen_set(m_scroll_ram[0x34]&0x40 );
bitmap.fill(1, cliprect);
screen.priority().fill(0, cliprect);
// 32 pixels?
// int scrollx = (m_scroll_ram[0x4/2] & 0x0f);
// debug tilemap code
// this is likely to be collision data
for(int x=0;x<16;x++)
{
for(int y=0;y<8;y++)
{
int tile = m_video_data[y+x*8+0xc0] & 0xff;
int res_x, res_y;
if(tile != 0)
{
res_x = (x*16) & 0xff;
res_y = y*32;
//if(cliprect.contains(res_x,res_y))
bitmap.plot_box(res_x,res_y,16,16,tile+0x10);
}
tile = m_video_data[y+x*8+0xc0] >> 8;
if(tile != 0)
{
res_x = (x*16) & 0xff;
res_y = y*32+16;
//if(cliprect.contains(res_x,res_y))
bitmap.plot_box(res_x,res_y,16,16,tile+0x10);
}
}
}
//m_pf3_layer->draw(screen, bitmap, cliprect, 0,1);
//m_pf1_layer->draw(screen, bitmap, cliprect, 0,2);
//m_pf2_layer->draw(screen, bitmap, cliprect, 0,4);
if (m_scroll_ram[0x18/2]&0x1)
popnrun_draw_sprites(screen, bitmap,cliprect);
m_text_layer->draw(screen, bitmap, cliprect, 0,0);
return 0;
}