summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author cam900 <dbtlrchl@naver.com>2020-07-22 05:16:03 +0900
committer GitHub <noreply@github.com>2020-07-21 16:16:03 -0400
commita3274c2f3046fd4bac6458a724cd1300f7fcdee9 (patch)
treefad9f5720a67ffc26faae3ffbfe7bb51c1fa03f6
parent232d321b151c5843eb1142a00b9caead4698a228 (diff)
imagetek_i4100.cpp: Partially fix flip screen (#6980)
imagetek_i4100.cpp: Fix Sprite position, Tilemap offsets, glitches in hyprduel hyprduel.cpp: Fix sprite delay metro.cpp: Fix flipped tilemap offset for vmetal
-rw-r--r--src/devices/video/imagetek_i4100.cpp59
-rw-r--r--src/devices/video/imagetek_i4100.h22
-rw-r--r--src/mame/drivers/hyprduel.cpp1
-rw-r--r--src/mame/drivers/metro.cpp6
4 files changed, 42 insertions, 46 deletions
diff --git a/src/devices/video/imagetek_i4100.cpp b/src/devices/video/imagetek_i4100.cpp
index 28fed1c00f6..030314636c1 100644
--- a/src/devices/video/imagetek_i4100.cpp
+++ b/src/devices/video/imagetek_i4100.cpp
@@ -24,7 +24,7 @@
- puzzli: emulate hblank irq and fix video routines here (water effect not emulated,
confirmed on PCB ref). Are the screen_ctrl_w "led" bits actually buffer latches
for the layers? They get written in the middle of the screen, may also be v2 specific.
- - Unemulated flip screen.
+ - Unemulated/Unverified scrolling in flip screen.
============================================================================
@@ -271,6 +271,8 @@ imagetek_i4100_device::imagetek_i4100_device(const machine_config &mconfig, devi
, m_support_16x16(has_ext_tiles)
, m_tilemap_scrolldx{0, 0, 0}
, m_tilemap_scrolldy{0, 0, 0}
+ , m_tilemap_flip_scrolldx{0, 0, 0}
+ , m_tilemap_flip_scrolldy{0, 0, 0}
, m_spriteram_buffered(false)
{
}
@@ -1066,8 +1068,8 @@ void imagetek_i4100_device::draw_sprites(screen_device &screen, bitmap_rgb32 &bi
if (m_screen_flip)
{
- flipx = !flipx; x = max_x - x - width;
- flipy = !flipy; y = max_y - y - height;
+ flipx = !flipx; x = max_x - x - ((width * sprite_ptr->zoom) >> 16);
+ flipy = !flipy; y = max_y - y - ((height * sprite_ptr->zoom) >> 16);
}
draw_spritegfx(screen, bitmap, cliprect,
@@ -1184,54 +1186,27 @@ void imagetek_i4100_device::draw_tilemap(screen_device &screen, bitmap_rgb32 &bi
int const windowwidth = width >> 2;
int const windowheight = height >> 3;
- int const dx = m_tilemap_scrolldx[layer] * (m_screen_flip ? 1 : -1);
- int const dy = m_tilemap_scrolldy[layer] * (m_screen_flip ? 1 : -1);
+ int const dx = m_screen_flip ? m_tilemap_flip_scrolldx[layer] : m_tilemap_scrolldx[layer];
+ int const dy = m_screen_flip ? m_tilemap_flip_scrolldy[layer] : m_tilemap_scrolldy[layer];
sx += dx;
sy += dy;
- int min_x, max_x, min_y, max_y;
-
- // TODO : allow cliprect related drawing with flipscreen
- if (dx != 0)
- {
- min_x = 0;
- max_x = scrwidth - 1;
- }
- else
- {
- min_x = cliprect.min_x;
- max_x = cliprect.max_x;
- }
-
- if (dy != 0)
- {
- min_y = 0;
- max_y = scrheight - 1;
- }
- else
- {
- min_y = cliprect.min_y;
- max_y = cliprect.max_y;
- }
-
- int draw_y = m_screen_flip ? scrheight - min_y - 1 : min_y;
- int draw_inc = m_screen_flip ? -1 : 1;
-
- for (int y = min_y; y <= max_y; draw_y += draw_inc, y++)
+ for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
{
- int const scrolly = (sy + y - wy) & (windowheight - 1);
+ int const resy = (sy + y - wy);
+ int const scrolly = (m_screen_flip ? (scrheight - resy - 1) : resy) & (windowheight - 1);
int srcline = (wy + scrolly) & (height - 1);
int const srctilerow = srcline >> tileshift;
srcline &= tilemask;
- u32 *dst = &bitmap.pix32(draw_y);
- u8 *priority_baseaddr = &priority_bitmap.pix8(draw_y);
+ u32 *dst = &bitmap.pix32(y);
+ u8 *priority_baseaddr = &priority_bitmap.pix8(y);
- int draw_x = m_screen_flip ? scrwidth - min_x - 1 : min_x;
- for (int x = min_x; x <= max_x; draw_x += draw_inc, x++)
+ for (int x = cliprect.min_x; x <= cliprect.max_x; x++)
{
- int const scrollx = (sx + x - wx) & (windowwidth - 1);
+ int const resx = (sx + x - wx);
+ int const scrollx = (m_screen_flip ? (scrwidth - resx - 1) : resx) & (windowwidth - 1);
int srccol = (wx + scrollx) & (width - 1);
int const srctilecol = srccol >> tileshift;
srccol &= tilemask;
@@ -1244,8 +1219,8 @@ void imagetek_i4100_device::draw_tilemap(screen_device &screen, bitmap_rgb32 &bi
if (draw)
{
- dst[draw_x] = dat;
- priority_baseaddr[draw_x] = pcode;
+ dst[x] = dat;
+ priority_baseaddr[x] = pcode;
}
}
}
diff --git a/src/devices/video/imagetek_i4100.h b/src/devices/video/imagetek_i4100.h
index 9936b8f76ab..b0888686604 100644
--- a/src/devices/video/imagetek_i4100.h
+++ b/src/devices/video/imagetek_i4100.h
@@ -32,8 +32,24 @@ public:
void map(address_map &map);
- void set_tmap_xoffsets(int x1, int x2, int x3) { m_tilemap_scrolldx[0] = x1; m_tilemap_scrolldx[1] = x2; m_tilemap_scrolldx[2] = x3; }
- void set_tmap_yoffsets(int y1, int y2, int y3) { m_tilemap_scrolldy[0] = y1; m_tilemap_scrolldy[1] = y2; m_tilemap_scrolldy[2] = y3; }
+ void set_tmap_flip_xoffsets(int x1, int x2, int x3) { m_tilemap_flip_scrolldx[0] = x1; m_tilemap_flip_scrolldx[1] = x2; m_tilemap_flip_scrolldx[2] = x3; }
+ void set_tmap_flip_yoffsets(int y1, int y2, int y3) { m_tilemap_flip_scrolldy[0] = y1; m_tilemap_flip_scrolldy[1] = y2; m_tilemap_flip_scrolldy[2] = y3; }
+ void set_tmap_xoffsets(int x1, int x2, int x3)
+ {
+ m_tilemap_scrolldx[0] = x1;
+ m_tilemap_scrolldx[1] = x2;
+ m_tilemap_scrolldx[2] = x3;
+ // default flip xoffset
+ set_tmap_flip_xoffsets(-x1, -x2, -x3);
+ }
+ void set_tmap_yoffsets(int y1, int y2, int y3)
+ {
+ m_tilemap_scrolldy[0] = y1;
+ m_tilemap_scrolldy[1] = y2;
+ m_tilemap_scrolldy[2] = y3;
+ // default flip yoffset
+ set_tmap_flip_yoffsets(-y1, -y2, -y3);
+ }
auto blit_irq_cb() { return m_blit_irq_cb.bind(); }
void set_spriteram_buffered(bool buffer) { m_spriteram_buffered = buffer; }
@@ -97,6 +113,8 @@ protected:
const bool m_support_8bpp, m_support_16x16;
int m_tilemap_scrolldx[3];
int m_tilemap_scrolldy[3];
+ int m_tilemap_flip_scrolldx[3];
+ int m_tilemap_flip_scrolldy[3];
bool m_spriteram_buffered;
void blt_write(const int tmap, const offs_t offs, const u16 data, const u16 mask);
diff --git a/src/mame/drivers/hyprduel.cpp b/src/mame/drivers/hyprduel.cpp
index b5002b722c7..9bec2908290 100644
--- a/src/mame/drivers/hyprduel.cpp
+++ b/src/mame/drivers/hyprduel.cpp
@@ -436,6 +436,7 @@ void hyprduel_state::i4220_config(machine_config &config)
{
I4220(config, m_vdp, XTAL(26'666'000));
m_vdp->blit_irq_cb().set(FUNC(hyprduel_state::vdp_blit_end_w));
+ m_vdp->set_spriteram_buffered(true); // sprites are 1 frame delayed
screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER));
screen.set_video_attributes(VIDEO_UPDATE_SCANLINE);
diff --git a/src/mame/drivers/metro.cpp b/src/mame/drivers/metro.cpp
index 06902083e85..46523e989a9 100644
--- a/src/mame/drivers/metro.cpp
+++ b/src/mame/drivers/metro.cpp
@@ -3606,8 +3606,10 @@ void metro_state::vmetal(machine_config &config)
m_screen->screen_vblank().set(FUNC(metro_state::vblank_irq));
- m_vdp2->set_tmap_xoffsets(-16,-16,-16);
- m_vdp2->set_tmap_yoffsets(-16,-16,-16);
+ m_vdp2->set_tmap_xoffsets(0,0,0);
+ m_vdp2->set_tmap_yoffsets(0,0,0);
+ m_vdp2->set_tmap_flip_xoffsets(16,16,16);
+ m_vdp2->set_tmap_flip_yoffsets(16,16,16);
/* sound hardware */
SPEAKER(config, "mono").front_center();