summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author David Haywood <28625134+DavidHaywood@users.noreply.github.com>2017-11-16 13:21:28 +0000
committer David Haywood <28625134+DavidHaywood@users.noreply.github.com>2017-11-16 13:21:28 +0000
commit439ed4ee3f3eafe8783b32aade557ca978bc555b (patch)
tree5eac6d224b475071e1218663afef55cf115271ad
parent4c9bac79ff0cf7aa1b87048485ed8ea77dea8051 (diff)
add yshrink for sprites
-rw-r--r--src/mame/drivers/pgm2.cpp196
1 files changed, 118 insertions, 78 deletions
diff --git a/src/mame/drivers/pgm2.cpp b/src/mame/drivers/pgm2.cpp
index bbd1cb3cbcf..6329aef08e1 100644
--- a/src/mame/drivers/pgm2.cpp
+++ b/src/mame/drivers/pgm2.cpp
@@ -263,7 +263,10 @@ private:
std::unique_ptr<uint32_t[]> m_spritebufferram; // buffered spriteram
bitmap_ind16 m_sprite_bitmap;
-
+
+ void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int flipy);
+ 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_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_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);
@@ -336,8 +339,13 @@ static ADDRESS_MAP_START( pgm2_map, AS_PROGRAM, 32, pgm2_state )
AM_RANGE(0x300a0000, 0x300a07ff) AM_RAM_DEVWRITE("tx_palette", palette_device, write) AM_SHARE("tx_palette")
- AM_RANGE(0x300c0000, 0x300c01ff) AM_RAM AM_SHARE("sp_zoom") // sprite zoom table?
- AM_RANGE(0x300e0000, 0x300e03bf) AM_RAM AM_SHARE("lineram") // linescroll - 0x3bf is enough bytes for 240 lines if each rowscroll value was 8 bytes, but each row is 4, so only half of this is used? or tx can do it too (unlikely, as orl2 writes 256 lines of data) maybe just bad mem check bounds on orleg2, it reports pass even if it fails the first byte!
+ AM_RANGE(0x300c0000, 0x300c01ff) AM_RAM AM_SHARE("sp_zoom") // sprite zoom table - it uploads the same data 4x, maybe xshrink,xgrow,yshrink,ygrow or just redundant mirrors
+
+ /* linescroll ram - it clears to 0x3bf on startup which is enough bytes for 240 lines if each rowscroll value was 8 bytes, but each row is 4,
+ so only half of this is used? or tx can do it too (unlikely, as orl2 writes 256 lines of data) maybe just bad mem check bounds on orleg2.
+ It reports pass even if it fails the first byte but if the first byte passes it attempts to test 0x10000 bytes, which is far too big so
+ what is the real size? */
+ AM_RANGE(0x300e0000, 0x300e03ff) AM_RAM AM_SHARE("lineram") AM_MIRROR(0x000fc00)
AM_RANGE(0x30100000, 0x301000ff) AM_RAM // unknown
@@ -457,8 +465,105 @@ static INPUT_PORTS_START( pgm2 )
INPUT_PORTS_END
+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)
+{
+ for (int xchunk = 0; xchunk < 32; xchunk++)
+ {
+ int realx, pix;
+
+ if (!flipx)
+ {
+ 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 (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;
+ }
+
+
+ if (!flipy)
+ {
+ palette_offset++;
+ }
+ else
+ {
+ palette_offset--;
+ }
+
+ palette_offset &= 0x7ffffff;
+ }
+ }
+}
+inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int flipy)
+{
+ int bits = population_count_32(maskdata);
+
+ if (!flipy)
+ {
+ palette_offset+=bits;
+ }
+ else
+ {
+ palette_offset-=bits;
+ }
+
+ palette_offset &= 0x7ffffff;
+
+}
+
+
+
+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)
+{
+ for (int xdraw = 0; xdraw < sizex; xdraw++)
+ {
+ uint32_t maskdata = m_sprites_mask[mask_offset + 0] << 24;
+ maskdata |= m_sprites_mask[mask_offset + 1] << 16;
+ maskdata |= m_sprites_mask[mask_offset + 2] << 8;
+ maskdata |= m_sprites_mask[mask_offset + 3] << 0;
+
+ if (flipy)
+ {
+ mask_offset -= 4;
+ }
+ else if (!flipy)
+ {
+ mask_offset += 4;
+ }
+
+
+ mask_offset &= 0x3ffffff;
+
+ if (zoomybit) draw_sprite_chunk(cliprect, palette_offset, x, realy, flipx, flipy, sizex, xdraw, pal, maskdata);
+ else skip_sprite_chunk(palette_offset, maskdata, flipy);
+ }
+}
+
void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect, uint32_t* spriteram)
{
m_sprite_bitmap.fill(0x8000, cliprect);
@@ -478,8 +583,6 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
if (endoflist != -1)
{
- uint16_t* dstptr_bitmap;
-
for (int i = 0; i < endoflist-2; i += 4)
{
//printf("sprite with %08x %08x %08x %08x\n", spriteram[i + 0], spriteram[i + 1], spriteram[i + 2], spriteram[i + 3]);
@@ -493,12 +596,14 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6;
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 zoomx = (spriteram[i + 1] & 0x001f0000) >> 16;
- //int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24;
+ //int zoomx = (spriteram[i + 1] & 0x001f0000) >> 16; // might be 7f
+ int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24; // might be 7f
int mask_offset = (spriteram[i + 2]<<1);
int palette_offset = (spriteram[i + 3]);
+ uint32_t zoomy_bits = m_sp_zoom[zoomy];
+
if (x & 0x400) x -=0x800;
if (y & 0x400) y -=0x800;
@@ -510,79 +615,14 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
pal |= (pri << 6); // encode priority with the palette for manual mixing later
- for (int ydraw = 0; ydraw < sizey;ydraw++)
+ int realy = y;
+
+ for (int ydraw = 0; ydraw < sizey; ydraw++)
{
- int realy = ydraw + y;
+ int zoomy_bit = (zoomy_bits >> (ydraw & 0x1f)) & 1;
- for (int xdraw = 0; xdraw < sizex;xdraw++)
- {
- uint32_t maskdata = m_sprites_mask[mask_offset+0] << 24;
- maskdata |= m_sprites_mask[mask_offset+1] << 16;
- maskdata |= m_sprites_mask[mask_offset+2] << 8;
- maskdata |= m_sprites_mask[mask_offset+3] << 0;
-
- if (flipy)
- {
- mask_offset -= 4;
- }
- else if (!flipy)
- {
- mask_offset += 4;
- }
-
-
- mask_offset &= 0x3ffffff;
-
- for (int xchunk = 0;xchunk < 32;xchunk++)
- {
- int realx, pix;
-
- if (!flipx)
- {
- 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 (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);
-
- dstptr_bitmap = &m_sprite_bitmap.pix16(realy);
- dstptr_bitmap[realx] = pendat;
- }
-
-
- if (!flipy)
- {
- palette_offset++;
- }
- else
- {
- palette_offset--;
- }
-
- palette_offset &= 0x7ffffff;
- }
- }
- }
+ draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, flipy, sizex, pal, zoomy_bit);
+ if (zoomy_bit) realy++;
}
}