seta2.cpp - y zoom improvements (nw) (#6677)

* fix yzoom issue (nw)

* improve penbros, break grdians (nw)

* test grdian improvement (nw)

* minor adjustment (nw)

* tweak (nw)

* seta2.cpp - y zoom improvements (nw)
This commit is contained in:
David Haywood 2020-05-10 14:54:05 +01:00 committed by GitHub
parent 5dca949285
commit f9be8cc9ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -430,11 +430,12 @@ int seta2_state::calculate_global_xoffset(int special)
int seta2_state::calculate_global_yoffset(int special)
{
// Sprites list
int global_yoffset = (m_vregs[0x1a / 2] & 0x7ff); // and 0x18/2 for low bits
if (global_yoffset & 0x400)
global_yoffset -= 0x800;
//int global_yoffset = (m_vregs[0x1a / 2] & 0x7ff); // and 0x18/2 for low bits
//if (global_yoffset & 0x400)
// global_yoffset -= 0x800;
global_yoffset += 1; // +2 for myangel / myangel2?
//global_yoffset += 1; // +2 for myangel / myangel2?
int global_yoffset = 0;
if (special)
global_yoffset = -0x90;
@ -452,7 +453,9 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
uint16_t *s1 = m_private_spriteram.get();
for (; s1 < &m_private_spriteram[0x1000 / 2]; s1 += 4)
int sprite_debug_count = 0;
for (; s1 < &m_private_spriteram[0x1000 / 2]; s1 += 4,sprite_debug_count++)
{
int num = s1[0];
@ -477,13 +480,23 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
xoffs &= 0x3ff;
yoffs &= 0x3ff;
if (yoffs & 0x200)
yoffs -= 0x400;
int global_xoffset = calculate_global_xoffset(special);
int global_yoffset = calculate_global_yoffset(special);
int usedscanline;
if (special)
{
use_shadow = 0;
// which_gfx = 4 << 8;
scanline = realscanline; // no zooming?
usedscanline = realscanline; // no zooming?
}
else
{
usedscanline = scanline;
}
// Number of single-sprites
@ -503,21 +516,40 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
// the 'floating tilemap sprites' are just a window into the tilemap, the position of the sprite does not change the scroll values
// get everything we need to calculate if sprite covers this scanline
int sy = s2[1];
int local_sizey = sy & 0xfc00;
int sy = s2[1] & 0x3ff;
sy += global_yoffset;
sy &= 0x1ff;
if (sy & 0x100)
sy -= 0x200;
sy &= 0x3ff;
if (sy & 0x200)
sy -= 0x400;
int local_sizey = s2[1] & 0xfc00;
int height = use_global_size ? global_sizey : local_sizey;
height = ((height & 0xfc00) >> 10) + 1;
int firstline = (sy + yoffs) & 0x1ff;
if (firstline & 0x100) firstline -= 0x200;
int firstline = (sy + yoffs) & 0x3ff;
if (firstline & 0x200)
firstline -= 0x400;
int endline = firstline + height * 0x10 - 1;
// if the sprite doesn't cover this scanline, bail now
if (firstline > scanline) continue;
if (endline < scanline) continue;
if (endline & 0x200)
endline -= 0x400;
if (endline >= firstline)
{
if (firstline > usedscanline) continue;
if (endline < usedscanline) continue;
}
else
{
// cases where the sprite crosses 0
if ((usedscanline > endline) && (usedscanline < firstline))
continue;
}
// get everything we need to calculate if sprite is actually within the x co-ordinates of the screen
int sx = s2[0];
@ -543,7 +575,7 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
int scrolly = s2[3];
scrolly &= 0x1ff;
scrolly += global_yoffset;
int sourceline = (scanline - scrolly) & 0x1ff;
int sourceline = (usedscanline - scrolly) & 0x1ff;
int scrollx = s2[2];
int is_16x16 = (scrollx & 0x8000) >> 15;
@ -572,26 +604,49 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
else
{
// "normal" sprite
int sy = s2[1];
int sizey = use_global_size ? global_sizey : sy;
sizey = (1 << ((sizey & 0x0c00) >> 10)) - 1;
sy += yoffs;
sy += global_yoffset;
sy &= 0x1ff;
int sy = s2[1] & 0x1ff;
if (sy & 0x100)
sy -= 0x200;
int firstline = sy;
int endline = (sy + (sizey + 1) * 8) - 1;
sy += global_yoffset;
sy &= 0x3ff;
if (realscanline == 128)
{
// printf("%04x %02x %d %d\n", sprite_debug_count, num, yoffs, sy);
}
int sizey = use_global_size ? global_sizey : s2[1] & 0xfc00;
sizey = (1 << ((sizey & 0x0c00) >> 10)) - 1;
int firstline = (sy + yoffs) & 0x3ff;
int endline = (firstline + (sizey + 1) * 8) - 1;
//firstline &= 0x3ff;
endline &= 0x3ff;
if (firstline & 0x200)
firstline -= 0x400;
if (endline & 0x200)
endline -= 0x400;
// if the sprite doesn't cover this scanline, bail now
if (firstline > scanline) continue;
if (endline < scanline) continue;
if (endline >= firstline)
{
if (firstline > usedscanline) continue;
if (endline < usedscanline) continue;
}
else
{
// cases where the sprite crosses 0
if ((usedscanline > endline) && (usedscanline < firstline))
continue;
}
// otherwise get the rest of the things we need to draw
int attr = s2[2];
@ -611,7 +666,7 @@ void seta2_state::draw_sprites(bitmap_ind16 &bitmap, const rectangle &cliprect,
int basecode = code &= ~((sizex + 1) * (sizey + 1) - 1); // see myangel, myangel2 and grdians
int line = scanline - firstline;
int line = usedscanline - firstline;
int y = (line >> 3);
line &= 0x7;
@ -658,9 +713,14 @@ void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
tempcliprect.sety(y, y);
//printf("yscroll: %04x%04x yzoom: %04x%04x | xscroll: %04x%04x xzoom: %04x%04x \n", m_vregs[0x1a/2], m_vregs[0x18/2], m_vregs[0x1e/2], m_vregs[0x1c/2] , m_vregs[0x12/2], m_vregs[0x10/2], m_vregs[0x16/2], m_vregs[0x14/2]);
//printf("yoffset: %04x%04x yzoom: %04x%04x | xoffset: %04x%04x xzoom: %04x%04x \n", m_vregs[0x1a/2], m_vregs[0x18/2], m_vregs[0x1e/2], m_vregs[0x1c/2] , m_vregs[0x12/2], m_vregs[0x10/2], m_vregs[0x16/2], m_vregs[0x14/2]);
// TODO the global yscroll should be applied here too as it can be sub-pixel for precision in zoomed cases
uint32_t yoffset = (m_vregs[0x1a / 2] << 16) | m_vregs[0x18 / 2];
yoffset &= 0x07ffffff;
yoffset = 0x07ffffff - yoffset;
uint32_t yzoom = (m_vregs[0x1e / 2] << 16) | m_vregs[0x1c / 2];
yzoom &= 0x07ffffff;
bool yzoominverted = false;
@ -680,7 +740,15 @@ void seta2_state::draw_sprites(bitmap_ind16& bitmap, const rectangle& cliprect)
else
{
yy = y * yzoom;
yy += yoffset;
yy &= 0x07ffffff;
yy >>= 16;
// printf("line %04x yline requested %04x\n", y, yy);
if (yy & 0x400)
yy -= 0x800;
}
draw_sprites(bitmap, tempcliprect, yy, y);
@ -736,7 +804,7 @@ uint32_t seta2_state::screen_update(screen_device &screen, bitmap_ind16 &bitmap,
WRITE_LINE_MEMBER(seta2_state::screen_vblank)
{
//popmessage("yscroll: %04x%04x yzoom: %04x%04x | xscroll: %04x%04x xzoom: %04x%04x \n", m_vregs[0x1a/2], m_vregs[0x18/2], m_vregs[0x1e/2], m_vregs[0x1c/2] , m_vregs[0x12/2], m_vregs[0x10/2], m_vregs[0x16/2], m_vregs[0x14/2]);
//popmessage("yoffset: %04x%04x yzoom: %04x%04x | xoffset: %04x%04x xzoom: %04x%04x \n", m_vregs[0x1a/2], m_vregs[0x18/2], m_vregs[0x1e/2], m_vregs[0x1c/2] , m_vregs[0x12/2], m_vregs[0x10/2], m_vregs[0x16/2], m_vregs[0x14/2]);
}
// staraudi