mirror of
https://github.com/holub/mame
synced 2025-04-24 17:30:55 +03:00
pgm2: handle MSB of zooming, used by kov3
This commit is contained in:
parent
0d9939fe5e
commit
d6bf45a382
@ -114,8 +114,8 @@ private:
|
||||
|
||||
void skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse);
|
||||
void draw_sprite_pixel(const rectangle &cliprect, int palette_offset, int realx, int realy, int pal);
|
||||
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, int realdraw_inc, int palette_inc);
|
||||
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_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 repeats, int &realxdraw, int realdraw_inc, int palette_inc);
|
||||
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 xrepeats);
|
||||
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);
|
||||
|
||||
|
@ -14,7 +14,7 @@ inline void pgm2_state::draw_sprite_pixel(const rectangle &cliprect, int palette
|
||||
}
|
||||
}
|
||||
|
||||
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, int realdraw_inc, int palette_inc)
|
||||
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 repeats, int &realxdraw, int realdraw_inc, int palette_inc)
|
||||
{
|
||||
for (int xchunk = 0; xchunk < 32; xchunk++)
|
||||
{
|
||||
@ -30,13 +30,18 @@ inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palett
|
||||
xzoombit = (zoomx_bits >> (31 - xchunk)) & 1;
|
||||
}
|
||||
|
||||
if (growx)
|
||||
if (pix)
|
||||
{
|
||||
if (pix)
|
||||
if (repeats != 0) // grow
|
||||
{
|
||||
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
|
||||
realxdraw += realdraw_inc;
|
||||
// draw it the base number of times
|
||||
for (int i = 0; i < repeats; i++)
|
||||
{
|
||||
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
|
||||
realxdraw += realdraw_inc;
|
||||
}
|
||||
|
||||
// draw it again if zoom bit is set
|
||||
if (xzoombit)
|
||||
{
|
||||
draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
|
||||
@ -46,25 +51,38 @@ inline void pgm2_state::draw_sprite_chunk(const rectangle &cliprect, int &palett
|
||||
palette_offset += palette_inc;
|
||||
palette_offset &= m_sprites_colour_mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
realxdraw += realdraw_inc;
|
||||
if (xzoombit) realxdraw += realdraw_inc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pix)
|
||||
else // shrink
|
||||
{
|
||||
if (xzoombit) draw_sprite_pixel(cliprect, palette_offset, x + realxdraw, realy, pal);
|
||||
|
||||
palette_offset += palette_inc;
|
||||
palette_offset &= m_sprites_colour_mask;
|
||||
}
|
||||
|
||||
if (xzoombit) realxdraw += realdraw_inc;
|
||||
|
||||
if (xzoombit) realxdraw += realdraw_inc;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (repeats != 0) // grow
|
||||
{
|
||||
for (int i = 0; i < repeats; i++)
|
||||
{
|
||||
realxdraw += realdraw_inc;
|
||||
}
|
||||
|
||||
if (xzoombit)
|
||||
{
|
||||
realxdraw += realdraw_inc;
|
||||
}
|
||||
}
|
||||
else // shrink
|
||||
{
|
||||
if (xzoombit) realxdraw += realdraw_inc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline void pgm2_state::skip_sprite_chunk(int &palette_offset, uint32_t maskdata, int reverse)
|
||||
@ -84,7 +102,7 @@ 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 reverse, int sizex, int pal, int zoomybit, int zoomx_bits, int growx)
|
||||
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 xrepeats)
|
||||
{
|
||||
int realxdraw = 0;
|
||||
|
||||
@ -116,13 +134,13 @@ inline void pgm2_state::draw_sprite_line(const rectangle &cliprect, int &mask_of
|
||||
{
|
||||
if (!flipx)
|
||||
{
|
||||
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, 1, 1);
|
||||
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, -1, -1);
|
||||
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, 1);
|
||||
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, -1, 1);
|
||||
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, growx, realxdraw, 1, -1);
|
||||
if (!reverse) draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, -1, 1);
|
||||
else draw_sprite_chunk(cliprect, palette_offset, x, realy, sizex, xdraw, pal, maskdata, zoomx_bits, xrepeats, realxdraw, 1, -1);
|
||||
|
||||
}
|
||||
}
|
||||
@ -138,9 +156,9 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
|
||||
|
||||
//printf("frame\n");
|
||||
|
||||
for (int i = 0;i < 0x2000 / 4;i+=4)
|
||||
for (int i = 0; i < 0x2000 / 4; i += 4)
|
||||
{
|
||||
if (spriteram[i+2] & 0x80000000)
|
||||
if (spriteram[i + 2] & 0x80000000)
|
||||
{
|
||||
endoflist = i;
|
||||
break;
|
||||
@ -149,43 +167,48 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
|
||||
|
||||
if (endoflist != -1)
|
||||
{
|
||||
for (int i = 0; i < endoflist-2; i += 4)
|
||||
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]);
|
||||
|
||||
int x = (spriteram[i + 0] & 0x000007ff) >> 0;
|
||||
int y = (spriteram[i + 0] & 0x003ff800) >> 11;
|
||||
int pal = (spriteram[i + 0] & 0x0fc00000) >> 22;
|
||||
int pri = (spriteram[i + 0] & 0x80000000) >> 31;
|
||||
int x = (spriteram[i + 0] & 0x000007ff) >> 0;
|
||||
int y = (spriteram[i + 0] & 0x003ff800) >> 11;
|
||||
int pal = (spriteram[i + 0] & 0x0fc00000) >> 22;
|
||||
int pri = (spriteram[i + 0] & 0x80000000) >> 31;
|
||||
|
||||
int unk0 = (spriteram[i + 0] & 0x30000000) >> 0;
|
||||
int disable = (spriteram[i + 0] & 0x40000000) >> 30; // kov3 uses this in places (eg. horsemen special move heads) when it can only possibly mean 'disable' also used in places on kov2nl and orleg2, often the 'power up' effects - verify it is disable there too
|
||||
int unk0 = (spriteram[i + 0] & 0x30000000) >> 0;
|
||||
|
||||
// kov3 uses this in places (eg. horsemen special move heads) and shops when it can only possibly mean 'disable'
|
||||
// it is also used in places on kov2nl and orleg2, often the 'power up' effects surrounding your character to create an on/off flicker each frame
|
||||
int disable = (spriteram[i + 0] & 0x40000000) >> 30;
|
||||
if (disable) continue;
|
||||
|
||||
|
||||
int sizex = (spriteram[i + 1] & 0x0000003f) >> 0;
|
||||
int sizey = (spriteram[i + 1] & 0x00007fc0) >> 6;
|
||||
int flipx = (spriteram[i + 1] & 0x00800000) >> 23;
|
||||
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 growx = (spriteram[i + 1] & 0x00200000) >> 21;
|
||||
int zoomy = (spriteram[i + 1] & 0x1f000000) >> 24;
|
||||
int growy = (spriteram[i + 1] & 0x20000000) >> 29;
|
||||
int unk1 = (spriteram[i + 1] & 0x40408000) >> 0;
|
||||
int zoomx = (spriteram[i + 1] & 0x007f0000) >> 16;
|
||||
int zoomy = (spriteram[i + 1] & 0x7f000000) >> 24;
|
||||
int unk1 = (spriteram[i + 1] & 0x00008000) >> 0;
|
||||
|
||||
if (unk0 || unk1)
|
||||
{
|
||||
//popmessage("sprite rendering unused bits set unk0 %08x unk1 %08x\n", unk0, unk1);
|
||||
}
|
||||
|
||||
int mask_offset = (spriteram[i + 2]<<1);
|
||||
int mask_offset = (spriteram[i + 2] << 1);
|
||||
int palette_offset = (spriteram[i + 3]);
|
||||
|
||||
|
||||
// use all the bits of zoom to lookup, probably why the table is copied 4x in RAM
|
||||
uint32_t zoomy_bits = m_sp_zoom[zoomy];
|
||||
uint32_t zoomx_bits = m_sp_zoom[zoomx];
|
||||
|
||||
if (x & 0x400) x -=0x800;
|
||||
if (y & 0x400) y -=0x800;
|
||||
// but use these bits as the scale factor
|
||||
int xrepeats = (zoomx & 0x60)>>5;
|
||||
int yrepeats = (zoomy & 0x60)>>5;
|
||||
|
||||
if (x & 0x400) x -= 0x800;
|
||||
if (y & 0x400) y -= 0x800;
|
||||
|
||||
if (reverse)
|
||||
mask_offset -= 2;
|
||||
@ -198,39 +221,47 @@ void pgm2_state::draw_sprites(screen_device &screen, const rectangle &cliprect,
|
||||
int realy = y;
|
||||
|
||||
int sourceline = 0;
|
||||
for (int ydraw = 0; ydraw < sizey;sourceline++)
|
||||
for (int ydraw = 0; ydraw < sizey; sourceline++)
|
||||
{
|
||||
int zoomy_bit = (zoomy_bits >> (sourceline & 0x1f)) & 1;
|
||||
|
||||
// store these for when we need to draw a line twice
|
||||
uint32_t pre_palette_offset = palette_offset;
|
||||
uint32_t pre_mask_offset = mask_offset;
|
||||
|
||||
if (!growy) // skipping lines
|
||||
|
||||
if (yrepeats != 0) // grow
|
||||
{
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, zoomy_bit, zoomx_bits, growx);
|
||||
if (zoomy_bit) realy++;
|
||||
for (int i = 0; i < yrepeats; i++)
|
||||
{
|
||||
// draw it the base number of times
|
||||
palette_offset = pre_palette_offset;
|
||||
mask_offset = pre_mask_offset;
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats);
|
||||
realy++;
|
||||
}
|
||||
|
||||
ydraw++;
|
||||
}
|
||||
else // doubling lines
|
||||
{
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, growx);
|
||||
realy++;
|
||||
|
||||
if (zoomy_bit) // draw it again
|
||||
if (zoomy_bit) // draw it again if zoom bit is set
|
||||
{
|
||||
palette_offset = pre_palette_offset;
|
||||
mask_offset = pre_mask_offset;
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, growx);
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats);
|
||||
realy++;
|
||||
}
|
||||
|
||||
ydraw++;
|
||||
}
|
||||
else // shrink
|
||||
{
|
||||
draw_sprite_line(cliprect, mask_offset, palette_offset, x, realy, flipx, reverse, sizex, pal, 1, zoomx_bits, xrepeats);
|
||||
|
||||
if (zoomy_bit)
|
||||
{
|
||||
realy++;
|
||||
}
|
||||
ydraw++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user