From dc7a43dc04b9624bdf63090262559a85d46926d8 Mon Sep 17 00:00:00 2001 From: buffi Date: Sat, 13 May 2023 23:03:49 +0200 Subject: video/epic12.cpp: Fix clipping of CV1K games (#11227) Change clipping for CV1K games to draw 32 pixels surrounding the visible area. This can be easily seen in Muchi Muchi Pork, which has a VRAM viewer in Special mode (Object Test), which will show 32 px drawn around the visible areas of framebuffers. For most gamers, this wont really matter at all... except for in Muchi Muchi Pork, where changing this actually fixes a bug for Rafute. When Bombing with Rafute, the screen background will go wavy in a sine-like pattern. Currently in mame, the top of screen will show black pixels when this happens. With this fix for clipping, the background will instead be visible correctly. Also renamed the "scroll registers" to have it more clear which one of these are actually used as a "scroll register" (or rather offset for drawing), and which one is strictly used for clipping. --- src/devices/video/epic12.cpp | 70 +++++++++++++++++++++----------------------- src/devices/video/epic12.h | 7 ++--- src/mame/misc/cv1k.cpp | 1 - 3 files changed, 37 insertions(+), 41 deletions(-) diff --git a/src/devices/video/epic12.cpp b/src/devices/video/epic12.cpp index ebad087f080..5e5b36ca9c5 100644 --- a/src/devices/video/epic12.cpp +++ b/src/devices/video/epic12.cpp @@ -25,6 +25,11 @@ static constexpr int EP1C_FRAME_DURATION_NANOSEC = 16666666; static constexpr int EP1C_DRAW_OPERATION_SIZE_BYTES = 20; static constexpr int EP1C_CLIP_OPERATION_SIZE_BYTES = 2; +// When looking at VRAM viewer in Special mode in Muchi Muchi Pork, draws 32 pixels outside of +// the "clip area" is visible. This is likely why the frame buffers will have at least a 32 pixel offset +// from the VRAM borders or other buffers in all games. +static constexpr int EP1C_CLIP_MARGIN = 32; + epic12_device::epic12_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, EPIC12, tag, owner, clock) , device_video_interface(mconfig, *this) @@ -37,15 +42,13 @@ epic12_device::epic12_device(const machine_config &mconfig, const char *tag, dev m_blitter_delay_timer = nullptr; m_blitter_busy = 0; m_gfx_addr = 0; - m_gfx_scroll_0_x = 0; - m_gfx_scroll_0_y = 0; - m_gfx_scroll_1_x = 0; - m_gfx_scroll_1_y = 0; + m_gfx_scroll_x = 0; + m_gfx_scroll_y = 0; + m_gfx_clip_x = 0; + m_gfx_clip_y = 0; m_gfx_addr_shadowcopy = 0; - m_gfx_scroll_0_x_shadowcopy = 0; - m_gfx_scroll_0_y_shadowcopy = 0; - m_gfx_scroll_1_x_shadowcopy = 0; - m_gfx_scroll_1_y_shadowcopy = 0; + m_gfx_clip_x_shadowcopy = 0; + m_gfx_clip_y_shadowcopy = 0; m_blit_delay_ns = 0; m_blit_idle_op_bytes = 0; } @@ -84,15 +87,13 @@ void epic12_device::device_start() m_firmware_version = -1; save_item(NAME(m_gfx_addr)); - save_item(NAME(m_gfx_scroll_0_x)); - save_item(NAME(m_gfx_scroll_0_y)); - save_item(NAME(m_gfx_scroll_1_x)); - save_item(NAME(m_gfx_scroll_1_y)); + save_item(NAME(m_gfx_scroll_x)); + save_item(NAME(m_gfx_scroll_y)); + save_item(NAME(m_gfx_clip_x)); + save_item(NAME(m_gfx_clip_y)); save_item(NAME(m_gfx_addr_shadowcopy)); - save_item(NAME(m_gfx_scroll_0_x_shadowcopy)); - save_item(NAME(m_gfx_scroll_0_y_shadowcopy)); - save_item(NAME(m_gfx_scroll_1_x_shadowcopy)); - save_item(NAME(m_gfx_scroll_1_y_shadowcopy)); + save_item(NAME(m_gfx_clip_x_shadowcopy)); + save_item(NAME(m_gfx_clip_y_shadowcopy)); save_pointer(NAME(m_ram16_copy), m_main_ramsize/2); save_item(NAME(*m_bitmaps)); save_item(NAME(m_firmware_pos)); @@ -676,10 +677,8 @@ void epic12_device::gfx_create_shadow_copy(address_space &space) { offs_t addr = m_gfx_addr & 0x1fffffff; - // TODO: Stop respecting this clipping area in draw operations not fully outside of it. - // For Muchi Muchi Pork, it looks like it draws 32px around visible area, when checking in Special Mode test menu VRAM viewer. - // Draws outside of clip area is also visible in logic analyzer for Pink Sweets. - m_clip.set(m_gfx_scroll_1_x_shadowcopy, m_gfx_scroll_1_x_shadowcopy + 320-1, m_gfx_scroll_1_y_shadowcopy, m_gfx_scroll_1_y_shadowcopy + 240-1); + m_clip.set(m_gfx_clip_x_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_x_shadowcopy + 320 - 1 + EP1C_CLIP_MARGIN, + m_gfx_clip_y_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_y_shadowcopy + 240 - 1 + EP1C_CLIP_MARGIN); while (1) { // request commands from main CPU RAM @@ -693,7 +692,8 @@ void epic12_device::gfx_create_shadow_copy(address_space &space) case 0xc000: if (COPY_NEXT_WORD(space, &addr)) // cliptype - m_clip.set(m_gfx_scroll_1_x_shadowcopy, m_gfx_scroll_1_x_shadowcopy + 320 - 1, m_gfx_scroll_1_y_shadowcopy, m_gfx_scroll_1_y_shadowcopy + 240 - 1); + m_clip.set(m_gfx_clip_x_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_x_shadowcopy + 320 - 1 + EP1C_CLIP_MARGIN, + m_gfx_clip_y_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_y_shadowcopy + 240 - 1 + EP1C_CLIP_MARGIN); else m_clip.set(0, 0x2000 - 1, 0, 0x1000 - 1); idle_blitter(EP1C_CLIP_OPERATION_SIZE_BYTES); @@ -720,7 +720,8 @@ void epic12_device::gfx_create_shadow_copy(address_space &space) void epic12_device::gfx_exec(void) { offs_t addr = m_gfx_addr_shadowcopy & 0x1fffffff; - m_clip.set(m_gfx_scroll_1_x_shadowcopy, m_gfx_scroll_1_x_shadowcopy + 320 - 1, m_gfx_scroll_1_y_shadowcopy, m_gfx_scroll_1_y_shadowcopy + 240 - 1); + m_clip.set(m_gfx_clip_x_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_x_shadowcopy + 320 - 1 + EP1C_CLIP_MARGIN, + m_gfx_clip_y_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_y_shadowcopy + 240 - 1 + EP1C_CLIP_MARGIN); // logerror("GFX EXEC: %08X\n", addr); @@ -737,7 +738,8 @@ void epic12_device::gfx_exec(void) case 0xc000: if (READ_NEXT_WORD(&addr)) // cliptype - m_clip.set(m_gfx_scroll_1_x_shadowcopy, m_gfx_scroll_1_x_shadowcopy + 320 - 1, m_gfx_scroll_1_y_shadowcopy, m_gfx_scroll_1_y_shadowcopy + 240 - 1); + m_clip.set(m_gfx_clip_x_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_x_shadowcopy + 320 - 1 + EP1C_CLIP_MARGIN, + m_gfx_clip_y_shadowcopy - EP1C_CLIP_MARGIN, m_gfx_clip_y_shadowcopy + 240 - 1 + EP1C_CLIP_MARGIN); else m_clip.set(0, 0x2000 - 1, 0, 0x1000 - 1); break; @@ -789,10 +791,8 @@ void epic12_device::gfx_exec_w(address_space &space, offs_t offset, u32 data, u3 osd_work_item_release(m_blitter_request); } - m_gfx_scroll_0_x_shadowcopy = m_gfx_scroll_0_x; - m_gfx_scroll_0_y_shadowcopy = m_gfx_scroll_0_y; - m_gfx_scroll_1_x_shadowcopy = m_gfx_scroll_1_x; - m_gfx_scroll_1_y_shadowcopy = m_gfx_scroll_1_y; + m_gfx_clip_x_shadowcopy = m_gfx_clip_x; + m_gfx_clip_y_shadowcopy = m_gfx_clip_y; // Create a copy of the blit list so we can safely thread it. // Copying the Blitter operations will also estimate the delay needed for processing. @@ -830,8 +830,6 @@ void epic12_device::draw_screen(bitmap_rgb32 &bitmap, const rectangle &cliprect) osd_work_item_release(m_blitter_request); } - int scroll_0_x, scroll_0_y; - bitmap.fill(0, cliprect); #if DEBUG_VRAM_VIEWER @@ -854,8 +852,8 @@ void epic12_device::draw_screen(bitmap_rgb32 &bitmap, const rectangle &cliprect) } #endif - scroll_0_x = -m_gfx_scroll_0_x; - scroll_0_y = -m_gfx_scroll_0_y; + int scroll_x = -m_gfx_scroll_x; + int scroll_y = -m_gfx_scroll_y; #if DEBUG_VRAM_VIEWER @@ -863,7 +861,7 @@ void epic12_device::draw_screen(bitmap_rgb32 &bitmap, const rectangle &cliprect) copybitmap(bitmap, *m_bitmaps, 0, 0, 0, 0, cliprect); else #endif - copyscrollbitmap(bitmap, *m_bitmaps, 1, &scroll_0_x, 1, &scroll_0_y, cliprect); + copyscrollbitmap(bitmap, *m_bitmaps, 1, &scroll_x, 1, &scroll_y, cliprect); } @@ -904,11 +902,11 @@ void epic12_device::blitter_w(address_space &space, offs_t offset, u32 data, u32 break; case 0x14: - COMBINE_DATA(&m_gfx_scroll_0_x); + COMBINE_DATA(&m_gfx_scroll_x); break; case 0x18: - COMBINE_DATA(&m_gfx_scroll_0_y); + COMBINE_DATA(&m_gfx_scroll_y); break; case 0x24: // Some sort of handshake at start of IRQ's. @@ -920,11 +918,11 @@ void epic12_device::blitter_w(address_space &space, offs_t offset, u32 data, u32 break; case 0x40: - COMBINE_DATA(&m_gfx_scroll_1_x); + COMBINE_DATA(&m_gfx_clip_x); break; case 0x44: - COMBINE_DATA(&m_gfx_scroll_1_y); + COMBINE_DATA(&m_gfx_clip_y); break; } diff --git a/src/devices/video/epic12.h b/src/devices/video/epic12.h index cb250b99cee..a314468139b 100644 --- a/src/devices/video/epic12.h +++ b/src/devices/video/epic12.h @@ -34,8 +34,8 @@ public: u16* m_ram16; u32 m_gfx_addr; - u32 m_gfx_scroll_0_x, m_gfx_scroll_0_y; - u32 m_gfx_scroll_1_x, m_gfx_scroll_1_y; + u32 m_gfx_scroll_x, m_gfx_scroll_y; + u32 m_gfx_clip_x, m_gfx_clip_y; int m_gfx_size; std::unique_ptr m_bitmaps; @@ -50,8 +50,7 @@ public: u32 blitter_r(offs_t offset, u32 mem_mask = ~0); void blitter_w(address_space &space, offs_t offset, u32 data, u32 mem_mask = ~0); u32 m_gfx_addr_shadowcopy; - u32 m_gfx_scroll_0_x_shadowcopy, m_gfx_scroll_0_y_shadowcopy; - u32 m_gfx_scroll_1_x_shadowcopy, m_gfx_scroll_1_y_shadowcopy; + u32 m_gfx_clip_x_shadowcopy, m_gfx_clip_y_shadowcopy; std::unique_ptr m_ram16_copy; inline void gfx_upload_shadow_copy(address_space &space, offs_t *addr); inline void gfx_create_shadow_copy(address_space &space); diff --git a/src/mame/misc/cv1k.cpp b/src/mame/misc/cv1k.cpp index 57fc9fe1cd2..b4beefffd46 100644 --- a/src/mame/misc/cv1k.cpp +++ b/src/mame/misc/cv1k.cpp @@ -176,7 +176,6 @@ Touchscreen Remaining Video issues - mmpork startup screen flicker - the FOR USE IN JAPAN screen doesn't appear on the real PCB until after the graphics are fully loaded, it still displays 'please wait' until that point. - - is the use of the 'scroll' registers 100% correct? (related to above?) - Sometimes the 'sprites' in mushisam lag by a frame vs the 'backgrounds' is this a timing problem, does the real game do it? - End of Blit should send IRQ1. (one game has a valid irq routine that looks like it was used for profiling, but nothing depends on it) -- cgit v1.2.3