Popeye: Implemented tile palette banking on TNX1 hardware, the side bars in Sky Skipper are now darker on night time levels. This is a guess based on the prom contents, due to lack of unmodified TNX1 boards. Implemented sprite priority & clipping according to description in http://mametesters.org/view.php?id=3725 (fixes MT03725). [smf]

This commit is contained in:
smf- 2018-01-22 10:09:38 +00:00
parent 0bea73132e
commit 107147fd3d
2 changed files with 145 additions and 91 deletions

View File

@ -30,7 +30,8 @@ public:
required_region_ptr<uint8_t> m_color_prom_spr;
std::unique_ptr<uint8_t[]> m_bitmapram;
std::unique_ptr<bitmap_ind16> m_tmpbitmap2;
std::unique_ptr<bitmap_ind16> m_sprite_bitmap;
std::unique_ptr<bitmap_ind16> m_background_bitmap;
uint8_t m_invertmask;
uint8_t m_bitmap_type;
tilemap_t *m_fg_tilemap;

View File

@ -117,48 +117,10 @@ void popeye_state::convert_color_prom(const uint8_t *color_prom)
{
int i;
/* palette entries 0-15 are used by the background and changed at runtime */
/* palette entries 16-48 are used by tiles and changed at runtime */
/* palette entries 0-15 are directly used by the background and changed at runtime */
color_prom += 32;
/* characters */
#if USE_NEW_COLOR
for (i = 0; i < 16; i++)
{
int prom_offs = i | ((i & 8) << 1); /* address bits 3 and 4 are tied together */
int r, g, b;
r = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 0) & 0x07, 0, popeye_7051_txt_net_info);
g = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 3) & 0x07, 1, popeye_7051_txt_net_info);
b = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 6) & 0x03, 2, popeye_7051_txt_net_info);
m_palette->set_pen_color(16 + (2 * i) + 0,rgb_t(0,0,0));
m_palette->set_pen_color(16 + (2 * i) + 1,rgb_t(r,g,b));
}
#else
for (i = 0;i < 16;i++)
{
int prom_offs = i | ((i & 8) << 1); /* address bits 3 and 4 are tied together */
int bit0,bit1,bit2,r,g,b;
/* red component */
bit0 = ((color_prom[prom_offs] ^ m_invertmask) >> 0) & 0x01;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 1) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 2) & 0x01;
r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* green component */
bit0 = ((color_prom[prom_offs] ^ m_invertmask) >> 3) & 0x01;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 4) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 5) & 0x01;
g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* blue component */
bit0 = 0;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 6) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 7) & 0x01;
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
m_palette->set_pen_color(16 + (2 * i) + 1,rgb_t(r,g,b));
}
#endif
color_prom += 64;
#if USE_NEW_COLOR
/* sprites */
@ -201,6 +163,13 @@ void popeye_state::convert_color_prom(const uint8_t *color_prom)
PALETTE_INIT_MEMBER(popeye_state, tpp1)
{
/* Two of the PROM address pins are tied together */
for (int i = 0; i < 0x20; i++)
{
int color = (i & 0xf) | ((i & 0x8) << 1);
m_color_prom[i + 0x20] = m_color_prom[color + 0x20];
}
m_invertmask = (USE_NEW_COLOR) ? 0x00 : 0xff;
convert_color_prom(m_color_prom);
@ -208,6 +177,13 @@ PALETTE_INIT_MEMBER(popeye_state, tpp1)
PALETTE_INIT_MEMBER(popeye_state,popeyebl)
{
/* Two of the PROM address pins are tied together */
for (int i = 0; i < 0x20; i++)
{
int color = (i & 0xf) | ((i & 0x8) << 1);
m_color_prom[i + 0x20] = m_color_prom[color + 0x20];
}
m_invertmask = (USE_NEW_COLOR) ? 0xff : 0x00;
convert_color_prom(m_color_prom);
@ -278,6 +254,47 @@ void popeye_state::set_background_palette(int bank)
color_prom++;
}
#endif
color_prom = m_color_prom + 32 + 16 * bank;
/* characters */
#if USE_NEW_COLOR
for (i = 0; i < 16; i++)
{
int prom_offs = i;
int r, g, b;
r = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 0) & 0x07, 0, popeye_7051_txt_net_info);
g = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 3) & 0x07, 1, popeye_7051_txt_net_info);
b = compute_res_net(((color_prom[prom_offs] ^ m_invertmask) >> 6) & 0x03, 2, popeye_7051_txt_net_info);
m_palette->set_pen_color(16 + (2 * i) + 0,rgb_t(0,0,0));
m_palette->set_pen_color(16 + (2 * i) + 1,rgb_t(r,g,b));
}
#else
for (i = 0;i < 16;i++)
{
int prom_offs = i;
int bit0,bit1,bit2,r,g,b;
/* red component */
bit0 = ((color_prom[prom_offs] ^ m_invertmask) >> 0) & 0x01;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 1) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 2) & 0x01;
r = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* green component */
bit0 = ((color_prom[prom_offs] ^ m_invertmask) >> 3) & 0x01;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 4) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 5) & 0x01;
g = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
/* blue component */
bit0 = 0;
bit1 = ((color_prom[prom_offs] ^ m_invertmask) >> 6) & 0x01;
bit2 = ((color_prom[prom_offs] ^ m_invertmask) >> 7) & 0x01;
b = 0x21 * bit0 + 0x47 * bit1 + 0x97 * bit2;
m_palette->set_pen_color(16 + (2 * i) + 1,rgb_t(r,g,b));
}
#endif
}
WRITE8_MEMBER(popeye_state::popeye_videoram_w)
@ -311,7 +328,7 @@ WRITE8_MEMBER(popeye_state::tpp2_bitmap_w)
{
for (x = 0; x < 8; x++)
{
m_tmpbitmap2->pix16(sy+y, sx+x) = colour;
m_background_bitmap->pix16(sy+y, sx+x) = colour;
}
}
}
@ -328,7 +345,7 @@ WRITE8_MEMBER(popeye_state::tpp2_bitmap_w)
{
for (x = 0; x < 8; x++)
{
m_tmpbitmap2->pix16(sy+y, sx+x) = colour;
m_background_bitmap->pix16(sy+y, sx+x) = colour;
}
}
}
@ -354,7 +371,8 @@ TILE_GET_INFO_MEMBER(popeye_state::get_fg_tile_info)
void popeye_state::video_start()
{
m_bitmapram = std::make_unique<uint8_t[]>(popeye_bitmapram_size);
m_tmpbitmap2 = std::make_unique<bitmap_ind16>(1024,1024); /* actually 1024x512 but not rolling over vertically? */
m_background_bitmap = std::make_unique<bitmap_ind16>(1024,1024); /* actually 1024x512 but not rolling over vertically? */
m_sprite_bitmap = std::make_unique<bitmap_ind16>(512, 512); // TODO: figure out the right size
m_bitmap_type = TYPE_TNX1;
@ -366,14 +384,16 @@ void popeye_state::video_start()
save_item(NAME(m_field));
save_item(NAME(m_lastflip));
save_item(NAME(*m_tmpbitmap2));
save_item(NAME(*m_background_bitmap));
save_item(NAME(*m_sprite_bitmap));
save_pointer(NAME(m_bitmapram.get()), popeye_bitmapram_size);
}
VIDEO_START_MEMBER(popeye_state,tpp1)
{
m_bitmapram = std::make_unique<uint8_t[]>(popeye_bitmapram_size);
m_tmpbitmap2 = std::make_unique<bitmap_ind16>(512,1024); /* actually 512x512 but not rolling over vertically? */
m_background_bitmap = std::make_unique<bitmap_ind16>(512,1024); /* actually 512x512 but not rolling over vertically? */
m_sprite_bitmap = std::make_unique<bitmap_ind16>(512, 512); // TODO: figure out the right size
m_bitmap_type = TYPE_TPP1;
@ -385,7 +405,8 @@ VIDEO_START_MEMBER(popeye_state,tpp1)
save_item(NAME(m_field));
save_item(NAME(m_lastflip));
save_item(NAME(*m_tmpbitmap2));
save_item(NAME(*m_background_bitmap));
save_item(NAME(*m_sprite_bitmap));
save_pointer(NAME(m_bitmapram.get()), popeye_bitmapram_size);
}
@ -413,59 +434,91 @@ void popeye_state::draw_background(bitmap_ind16 &bitmap, const rectangle &clipre
scrolly = -scrolly;
}
copyscrollbitmap(bitmap,*m_tmpbitmap2,1,&scrollx,1,&scrolly,cliprect);
copyscrollbitmap(bitmap,*m_background_bitmap,1,&scrollx,1,&scrolly,cliprect);
}
void popeye_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect)
{
uint8_t *spriteram = m_spriteram;
int offs;
gfx_element *gfx = m_gfxdecode->gfx(1);
m_sprite_bitmap->fill(0, cliprect);
for (offs = 0;offs < m_spriteram.bytes();offs += 4)
for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
int code,color,flipx,flipy,sx,sy;
/*
* offs+3:
* bit 7 ?
* bit 6 ?
* bit 5 ?
* bit 4 MSB of sprite code
* bit 3 vertical flip
* bit 2 sprite bank
* bit 1 \ color (with bit 2 as well)
* bit 0 /
*/
color = (spriteram[offs + 3] & 0x07);
if (color == 0) continue;
code = (spriteram[offs + 2] & 0x7f)
+ ((spriteram[offs + 3] & 0x10) << 3)
+ ((spriteram[offs + 3] & 0x04) << 6);
color += (*m_palettebank & 0x07) << 3;
flipx = spriteram[offs + 2] & 0x80;
flipy = spriteram[offs + 3] & 0x08;
sx = 2*(spriteram[offs])-8;
sy = 2*(256-spriteram[offs + 1]);
if (flip_screen())
struct attribute_memory
{
flipx = !flipx;
flipy = !flipy;
sx = 496 - sx;
sy = 496 - sy;
int row;
int sx;
uint8_t color;
uint16_t code;
int flipx;
int flipy;
} attributes[64] = { 0 };
for (int offs = 0; offs < m_spriteram.bytes(); offs += 4)
{
int sy = 0x200 - (m_spriteram[offs + 1] * 2);
int row = y - sy;
if (flip_screen())
{
sy ^= 0x1ff;
row = sy - y;
}
if (row >= 0 && row < 16)
{
/*
* offs+3:
* bit 7 ?
* bit 6 ?
* bit 5 ?
* bit 4 MSB of sprite code
* bit 3 vertical flip
* bit 2 sprite bank
* bit 1 \ color (with bit 2 as well)
* bit 0 /
*/
struct attribute_memory *a = &attributes[m_spriteram[offs] >> 2];
a->sx = (2 * m_spriteram[offs]) - 8;
a->row = row;
a->code = ((m_spriteram[offs + 2] & 0x7f)
+ ((m_spriteram[offs + 3] & 0x10) << 3)
+ ((m_spriteram[offs + 3] & 0x04) << 6)) ^ 0x1ff;
a->color = (m_spriteram[offs + 3] & 0x07);
a->flipx = (m_spriteram[offs + 2] & 0x80) ? 0xf : 0;
a->flipy = (m_spriteram[offs + 3] & 0x08) ? 0xf : 0;
}
}
m_gfxdecode->gfx(1)->transpen(bitmap,cliprect,
code ^ 0x1ff,
color,
flipx,flipy,
sx,sy,0);
for (int i = 0; i < 64; i++)
{
struct attribute_memory *a = &attributes[i];
if (a->color != 0)
{
const uint8_t color = a->color + ((*m_palettebank & 0x07) << 3);
const pen_t *pal = &m_palette->pen(gfx->colorbase() + gfx->granularity() * (color % gfx->colors()));
const uint8_t *source_base = gfx->get_data(a->code % gfx->elements());
const uint8_t *source = source_base + (a->row ^ a->flipy) * gfx->rowbytes();
for (int x = 0; x < 16; x++)
{
uint16_t p = source[x ^ a->flipx];
if (p) p = pal[p];
int px = a->sx + x;
if (px >= 0 && px < 512)
{
if (flip_screen())
px ^= 0x1ff;
m_sprite_bitmap->pix(y, px) = p;
}
}
}
}
}
copybitmap_trans(bitmap, *m_sprite_bitmap, 0, 0, 0, 0, cliprect, 0);
}
void popeye_state::draw_field(bitmap_ind16 &bitmap, const rectangle &cliprect)