From f9be8cc9acd8053f2d169c4f7f55daf0bf225fba Mon Sep 17 00:00:00 2001 From: David Haywood <28625134+DavidHaywood@users.noreply.github.com> Date: Sun, 10 May 2020 14:54:05 +0100 Subject: [PATCH] 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) --- src/mame/video/seta2.cpp | 134 +++++++++++++++++++++++++++++---------- 1 file changed, 101 insertions(+), 33 deletions(-) diff --git a/src/mame/video/seta2.cpp b/src/mame/video/seta2.cpp index 0d23634bd56..a8e755697b2 100644 --- a/src/mame/video/seta2.cpp +++ b/src/mame/video/seta2.cpp @@ -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