From a3274c2f3046fd4bac6458a724cd1300f7fcdee9 Mon Sep 17 00:00:00 2001 From: cam900 Date: Wed, 22 Jul 2020 05:16:03 +0900 Subject: 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 --- src/devices/video/imagetek_i4100.cpp | 59 +++++++++++------------------------- src/devices/video/imagetek_i4100.h | 22 ++++++++++++-- src/mame/drivers/hyprduel.cpp | 1 + src/mame/drivers/metro.cpp | 6 ++-- 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(); -- cgit v1.2.3