Merge pull request #2809 from DavidHaywood/131117

pgm2 - add sprite xgrow/xshrink for basic non-flipped cases
This commit is contained in:
MetalliC 2017-11-16 18:17:42 +02:00 committed by GitHub
commit c7ddaf8284
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -264,9 +264,13 @@ private:
bitmap_ind16 m_sprite_bitmap; bitmap_ind16 m_sprite_bitmap;
void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int flipy); void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse);
void draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int flipx, int flipy, int sizex, int xdraw, int pal, uint32_t maskdata); void draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal);
void draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int flipy, int sizex, int pal, int zoomybit); void draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw);
void draw_sprite_chunk_reverse(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw);
void draw_sprite_chunk_flipx(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw);
void draw_sprite_chunk_flipx_reverse(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw);
void draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int growx);
void draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram); void draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram);
void copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri); void copy_sprites_from_bitmap(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect, int pri);
@ -464,66 +468,124 @@ static INPUT_PORTS_START( pgm2 )
PORT_DIPSETTING( 0x00000000, DEF_STR( On ) ) PORT_DIPSETTING( 0x00000000, DEF_STR( On ) )
INPUT_PORTS_END INPUT_PORTS_END
inline void pgm2_state::draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal)
{
if (cliprect.contains(realx, realy))
{
uint16_t pix = m_sprites_colour[palette_offset] & 0x3f; // there are some stray 0xff bytes in some roms, so mask
uint16_t pendat = pix + (pal * 0x40);
uint16_t* dstptr_bitmap = &m_sprite_bitmap.pix16(realy);
dstptr_bitmap[realx] = pendat;
}
}
inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int flipx, int flipy, int sizex, int xdraw, int pal, uint32_t maskdata) inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw)
{
for (int xchunk = 0; xchunk < 32; xchunk++)
{
int pix = (maskdata >> (31 - xchunk)) & 1;
int xzoombit = (zoomx_bits >> (31 - xchunk)) & 1;
if (growx)
{
if (pix)
{
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
realxdraw++;
if (xzoombit)
{
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
realxdraw++;
}
palette_offset++;
palette_offset &= 0x7ffffff;
}
else
{
realxdraw++;
if (xzoombit) realxdraw++;
}
}
else
{
if (pix)
{
if (xzoombit) draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
palette_offset++;
palette_offset &= 0x7ffffff;
}
if (xzoombit)
realxdraw++;
}
}
}
inline void pgm2_state::draw_sprite_chunk_reverse(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw)
{ {
for (int xchunk = 0; xchunk < 32; xchunk++) for (int xchunk = 0; xchunk < 32; xchunk++)
{ {
int realx, pix; int realx, pix;
if (!flipx) realx = ((x + sizex * 32) - 1) - ((xdraw * 32) + xchunk);
{ pix = (maskdata >> xchunk) & 1;
if (!flipy) realx = x + (xdraw * 32) + xchunk;
else realx = ((x + sizex * 32) - 1) - ((xdraw * 32) + xchunk);
}
else
{
if (!flipy) realx = ((x + sizex * 32) - 1) - ((xdraw * 32) + xchunk);
else realx = x + (xdraw * 32) + xchunk;
}
if (!flipy)
{
pix = (maskdata >> (31 - xchunk)) & 1;
}
else
{
pix = (maskdata >> xchunk) & 1;
}
if (pix) if (pix)
{ {
if (cliprect.contains(realx, realy)) draw_sprite_pixel(cliprect, palette_offset, realx, realy, pal);
{ palette_offset--;
uint16_t pix = m_sprites_colour[palette_offset] & 0x3f; // there are some stray 0xff bytes in some roms, so mask
uint16_t pendat = pix + (pal * 0x40);
uint16_t* dstptr_bitmap = &m_sprite_bitmap.pix16(realy);
dstptr_bitmap[realx] = pendat;
}
if (!flipy)
{
palette_offset++;
}
else
{
palette_offset--;
}
palette_offset &= 0x7ffffff; palette_offset &= 0x7ffffff;
} }
} }
} }
inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int flipy) inline void pgm2_state::draw_sprite_chunk_flipx(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw)
{
for (int xchunk = 0; xchunk < 32; xchunk++)
{
int realx, pix;
realx = ((x + sizex * 32) - 1) - ((xdraw * 32) + xchunk);
pix = (maskdata >> (31 - xchunk)) & 1;
if (pix)
{
draw_sprite_pixel(cliprect, palette_offset, realx, realy, pal);
palette_offset++;
palette_offset &= 0x7ffffff;
}
}
}
inline void pgm2_state::draw_sprite_chunk_flipx_reverse(const rectangle &cliprect, int &palette_offset, int x, int realy, int sizex, int xdraw, int pal, uint32_t maskdata, uint32_t zoomx_bits, int growx, int &realxdraw)
{
for (int xchunk = 0; xchunk < 32; xchunk++)
{
int realx, pix;
realx = x + (xdraw * 32) + xchunk;
pix = (maskdata >> xchunk) & 1;
if (pix)
{
draw_sprite_pixel(cliprect, palette_offset, realx, realy, pal);
palette_offset--;
palette_offset &= 0x7ffffff;
}
}
}
inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse)
{ {
int bits = population_count_32(maskdata); int bits = population_count_32(maskdata);
if (!flipy) if (!reverse)
{ {
palette_offset+=bits; palette_offset+=bits;
} }
@ -538,8 +600,10 @@ inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata
inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int flipy, int sizex, int pal, int zoomybit) inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_offset, int &palette_offset, int x, int realy, int flipx, int reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int growx)
{ {
int realxdraw = 0;
for (int xdraw = 0; xdraw < sizex; xdraw++) for (int xdraw = 0; xdraw < sizex; xdraw++)
{ {
uint32_t maskdata = m_sprites_mask[mask_offset + 0] << 24; uint32_t maskdata = m_sprites_mask[mask_offset + 0] << 24;
@ -547,11 +611,11 @@ inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_of
maskdata |= m_sprites_mask[mask_offset + 2] << 8; maskdata |= m_sprites_mask[mask_offset + 2] << 8;
maskdata |= m_sprites_mask[mask_offset + 3] << 0; maskdata |= m_sprites_mask[mask_offset + 3] << 0;
if (flipy) if (reverse)
{ {
mask_offset -= 4; mask_offset -= 4;
} }
else if (!flipy) else if (!reverse)
{ {
mask_offset += 4; mask_offset += 4;
} }
@ -559,8 +623,21 @@ inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_of
mask_offset &= 0x3ffffff; mask_offset &= 0x3ffffff;
if (zoomybit) draw_sprite_chunk(cliprect, palette_offset, x, realy, flipx, flipy, sizex, xdraw, pal, maskdata); if (zoomybit)
else skip_sprite_chunk(palette_offset, maskdata, flipy); {
if (!flipx)
{
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw);
else draw_sprite_chunk_reverse(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw);
}
else
{
if (!reverse) draw_sprite_chunk_flipx(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw);
else draw_sprite_chunk_flipx_reverse(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw);
}
}
else skip_sprite_chunk(palette_offset, maskdata, reverse);
} }
} }
@ -597,9 +674,9 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
int sizex = (spriteram[i + 1] & 0x0000003f) >> 0; int sizex = (spriteram[i + 1] & 0x0000003f) >> 0;
int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6; int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6;
int flipx = (spriteram[i + 1] & 0x00800000) >> 23; int flipx = (spriteram[i + 1] & 0x00800000) >> 23;
int flipy = (spriteram[i + 1] & 0x80000000) >> 31; // more of a 'reverse entire drawing' flag than y-flip, but used for that purpose int reverse = (spriteram[i + 1] & 0x80000000) >> 31; // more of a 'reverse entire drawing' flag than y-flip, but used for that purpose
//int zoomx = (spriteram[i + 1] & 0x001f0000) >> 16; int zoomx = (spriteram[i + 1] & 0x001f0000) >> 16;
//int growx = (spriteram[i + 1] & 0x00200000) >> 21; int growx = (spriteram[i + 1] & 0x00200000) >> 21;
int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24; int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24;
int growy = (spriteram[i + 1] & 0x20000000) >> 29; int growy = (spriteram[i + 1] & 0x20000000) >> 29;
//int unk1 = (spriteram[i + 1] & 0x40408000) >> 0; //int unk1 = (spriteram[i + 1] & 0x40408000) >> 0;
@ -612,11 +689,12 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
int palette_offset = (spriteram[i + 3]); int palette_offset = (spriteram[i + 3]);
uint32_t zoomy_bits = m_sp_zoom[zoomy]; uint32_t zoomy_bits = m_sp_zoom[zoomy];
uint32_t zoomx_bits = m_sp_zoom[zoomx];
if (x & 0x400) x -=0x800; if (x & 0x400) x -=0x800;
if (y & 0x400) y -=0x800; if (y & 0x400) y -=0x800;
if (flipy) if (reverse)
mask_offset -= 2; mask_offset -= 2;
mask_offset &= 0x3ffffff; mask_offset &= 0x3ffffff;
@ -637,14 +715,14 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
if (!growy) // skipping lines if (!growy) // skipping lines
{ {
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, flipy, sizex, pal, zoomy_bit); draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, zoomy_bit, zoomx_bits, growx);
if (zoomy_bit) realy++; if (zoomy_bit) realy++;
ydraw++; ydraw++;
} }
else // doubling lines else // doubling lines
{ {
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, flipy, sizex, pal, 1); draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, growx);
realy++; realy++;
if (zoomy_bit) if (zoomy_bit)