mirror of
https://github.com/holub/mame
synced 2025-07-10 04:05:16 +03:00
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:
parent
0bea73132e
commit
107147fd3d
@ -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;
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user