summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author R. Belmont <rb6502@users.noreply.github.com>2019-07-04 12:53:39 -0400
committer GitHub <noreply@github.com>2019-07-04 12:53:39 -0400
commitbbbc56a7f426897cf8354ae4044dee6ff56cdf2f (patch)
treef98127c622368aca0296a7c49b4ccb6f47225823
parentd983efca39b651acb5672a37a5695013ba02783a (diff)
parent2a664c1f23140acc85e2e837da32dabe404f32f3 (diff)
Merge pull request #5306 from enikland2/nes_sms_gun_fix
nes, sms: Fix light gun regression
-rw-r--r--src/devices/bus/nes_ctrl/zapper.cpp14
-rw-r--r--src/devices/bus/sms_ctrl/lphaser.cpp1
-rw-r--r--src/devices/video/ppu2c0x.cpp53
-rw-r--r--src/devices/video/ppu2c0x.h2
-rw-r--r--src/mame/drivers/nes.cpp1
-rw-r--r--src/mame/includes/nes.h1
-rw-r--r--src/mame/machine/playch10.cpp10
-rw-r--r--src/mame/machine/vsnes.cpp10
-rw-r--r--src/mame/video/nes.cpp39
-rw-r--r--src/mame/video/playch10.cpp4
10 files changed, 94 insertions, 41 deletions
diff --git a/src/devices/bus/nes_ctrl/zapper.cpp b/src/devices/bus/nes_ctrl/zapper.cpp
index 195ed891300..746246a8c76 100644
--- a/src/devices/bus/nes_ctrl/zapper.cpp
+++ b/src/devices/bus/nes_ctrl/zapper.cpp
@@ -82,9 +82,21 @@ void nes_zapper_device::device_reset()
uint8_t nes_zapper_device::read_bit34()
{
uint8_t ret = m_trigger->read();
+ int x = m_lightx->read();
+ int y = m_lighty->read();
+
+ // update the screen if necessary
+ if (!screen().vblank())
+ {
+ int vpos = screen().vpos();
+ int hpos = screen().hpos();
+
+ if (vpos > y || (vpos == y && hpos >= x))
+ screen().update_now();
+ }
// get the pixel at the gun position
- rgb_t pix = screen().pixel(m_lightx->read(), m_lighty->read());
+ rgb_t pix = screen().pixel(x, y);
// check if the cursor is over a bright pixel
// FIXME: still a gross hack
diff --git a/src/devices/bus/sms_ctrl/lphaser.cpp b/src/devices/bus/sms_ctrl/lphaser.cpp
index a728930f50e..261f6b13504 100644
--- a/src/devices/bus/sms_ctrl/lphaser.cpp
+++ b/src/devices/bus/sms_ctrl/lphaser.cpp
@@ -231,6 +231,7 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int
/* brightness of the lightgray color in the frame drawn by Light Phaser games */
const uint8_t sensor_min_brightness = 0x7f;
+ screen().update_now();
color = screen().pixel(beam_x, beam_y);
/* reference: http://www.w3.org/TR/AERT#color-contrast */
diff --git a/src/devices/video/ppu2c0x.cpp b/src/devices/video/ppu2c0x.cpp
index f97c91d381b..c4ac3898b4d 100644
--- a/src/devices/video/ppu2c0x.cpp
+++ b/src/devices/video/ppu2c0x.cpp
@@ -979,10 +979,13 @@ void ppu2c0x_device::update_scanline()
/* Render this scanline if appropriate */
if (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES))
{
- /* If background or sprites are enabled, copy the ppu address latch */
- /* Copy only the scroll x-coarse and the x-overflow bit */
- m_refresh_data &= ~0x041f;
- m_refresh_data |= (m_refresh_latch & 0x041f);
+ if (m_scanline_timer->remaining() == attotime::zero)
+ {
+ /* If background or sprites are enabled, copy the ppu address latch */
+ /* Copy only the scroll x-coarse and the x-overflow bit */
+ m_refresh_data &= ~0x041f;
+ m_refresh_data |= (m_refresh_latch & 0x041f);
+ }
// logerror("updating refresh_data: %04x (scanline: %d)\n", m_refresh_data, m_scanline);
render_scanline();
@@ -1014,23 +1017,26 @@ void ppu2c0x_device::update_scanline()
bitmap.pix32(m_scanline, i) = back_pen;
}
- /* increment the fine y-scroll */
- m_refresh_data += 0x1000;
-
- /* if it's rolled, increment the coarse y-scroll */
- if (m_refresh_data & 0x8000)
+ if (m_scanline_timer->remaining() == attotime::zero)
{
- uint16_t tmp;
- tmp = (m_refresh_data & 0x03e0) + 0x20;
- m_refresh_data &= 0x7c1f;
+ /* increment the fine y-scroll */
+ m_refresh_data += 0x1000;
- /* handle bizarro scrolling rollover at the 30th (not 32nd) vertical tile */
- if (tmp == 0x03c0)
- m_refresh_data ^= 0x0800;
- else
- m_refresh_data |= (tmp & 0x03e0);
+ /* if it's rolled, increment the coarse y-scroll */
+ if (m_refresh_data & 0x8000)
+ {
+ uint16_t tmp;
+ tmp = (m_refresh_data & 0x03e0) + 0x20;
+ m_refresh_data &= 0x7c1f;
-// logerror("updating refresh_data: %04x\n", m_refresh_data);
+ /* handle bizarro scrolling rollover at the 30th (not 32nd) vertical tile */
+ if (tmp == 0x03c0)
+ m_refresh_data ^= 0x0800;
+ else
+ m_refresh_data |= (tmp & 0x03e0);
+
+ //logerror("updating refresh_data: %04x\n", m_refresh_data);
+ }
}
}
@@ -1331,13 +1337,18 @@ void ppu2c0x_device::spriteram_dma( address_space &space, const uint8_t page )
*
*************************************/
-void ppu2c0x_device::render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy)
+void ppu2c0x_device::render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy, const rectangle &cliprect)
{
- copybitmap(bitmap, *m_bitmap, flipx, flipy, sx, sy, bitmap.cliprect());
+ if (m_scanline_timer->remaining() != attotime::zero)
+ {
+ // Partial line update, need to render first (especially for light gun emulation).
+ update_scanline();
+ }
+ copybitmap(bitmap, *m_bitmap, flipx, flipy, sx, sy, cliprect);
}
uint32_t ppu2c0x_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- render(bitmap, 0, 0, 0, 0);
+ render(bitmap, 0, 0, 0, 0, cliprect);
return 0;
}
diff --git a/src/devices/video/ppu2c0x.h b/src/devices/video/ppu2c0x.h
index 1f0eb086369..78ebef0b2ce 100644
--- a/src/devices/video/ppu2c0x.h
+++ b/src/devices/video/ppu2c0x.h
@@ -92,7 +92,7 @@ public:
void update_scanline();
void spriteram_dma(address_space &space, const uint8_t page);
- void render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy);
+ void render(bitmap_rgb32 &bitmap, int flipx, int flipy, int sx, int sy, const rectangle &cliprect);
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
int get_current_scanline() { return m_scanline; }
diff --git a/src/mame/drivers/nes.cpp b/src/mame/drivers/nes.cpp
index fc757d17824..5631a9a21fc 100644
--- a/src/mame/drivers/nes.cpp
+++ b/src/mame/drivers/nes.cpp
@@ -65,6 +65,7 @@ void nes_state::nes(machine_config &config)
m_screen->set_size(32*8, 262);
m_screen->set_visarea(0*8, 32*8-1, 0*8, 30*8-1);
m_screen->set_screen_update(FUNC(nes_state::screen_update_nes));
+ m_screen->screen_vblank().set(FUNC(nes_state::screen_vblank_nes));
PPU_2C02(config, m_ppu);
m_ppu->set_cpu_tag(m_maincpu);
diff --git a/src/mame/includes/nes.h b/src/mame/includes/nes.h
index 17d0e8c6437..21d1f8a7d9e 100644
--- a/src/mame/includes/nes.h
+++ b/src/mame/includes/nes.h
@@ -93,6 +93,7 @@ public:
virtual void video_start() override;
virtual void video_reset() override;
uint32_t screen_update_nes(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
+ void screen_vblank_nes(int state);
void init_famicom();
diff --git a/src/mame/machine/playch10.cpp b/src/mame/machine/playch10.cpp
index 2c2c29a9ec3..80f67f75444 100644
--- a/src/mame/machine/playch10.cpp
+++ b/src/mame/machine/playch10.cpp
@@ -225,6 +225,16 @@ READ8_MEMBER(playch10_state::pc10_in1_r)
/* no sprite hit (yet) */
ret |= 0x08;
+ // update the screen if necessary
+ if (!m_ppu->screen().vblank())
+ {
+ int vpos = m_ppu->screen().vpos();
+ int hpos = m_ppu->screen().hpos();
+
+ if (vpos > y || (vpos == y && hpos >= x))
+ m_ppu->screen().update_now();
+ }
+
/* get the pixel at the gun position */
rgb_t pix = m_ppu->screen().pixel(x, y);
diff --git a/src/mame/machine/vsnes.cpp b/src/mame/machine/vsnes.cpp
index f7595acba77..317608c8f55 100644
--- a/src/mame/machine/vsnes.cpp
+++ b/src/mame/machine/vsnes.cpp
@@ -375,6 +375,16 @@ WRITE8_MEMBER(vsnes_state::gun_in0_w)
uint8_t realy = (int)y;
+ // update the screen if necessary
+ if (!m_ppu1->screen().vblank())
+ {
+ int vpos = m_ppu1->screen().vpos();
+ int hpos = m_ppu1->screen().hpos();
+
+ if (vpos > realy || (vpos == realy && hpos >= x))
+ m_ppu1->screen().update_now();
+ }
+
/* get the pixel at the gun position */
rgb_t col = m_ppu1->screen().pixel(x, realy);
uint8_t bright = col.brightness();
diff --git a/src/mame/video/nes.cpp b/src/mame/video/nes.cpp
index 3d2874acea6..267c63d7b46 100644
--- a/src/mame/video/nes.cpp
+++ b/src/mame/video/nes.cpp
@@ -31,27 +31,34 @@ void nes_state::video_start()
uint32_t nes_state::screen_update_nes(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
// render the ppu
- m_ppu->render(bitmap, 0, 0, 0, 0);
+ m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
+ return 0;
+}
- // if this is a disk system game, check for the flip-disk key
- if ((m_cartslot && m_cartslot->exists() && (m_cartslot->get_pcb_id() == STD_DISKSYS)) // first scenario = disksys in m_cartslot (= famicom)
- || m_disk) // second scenario = disk via fixed internal disk option (fds & famitwin)
+void nes_state::screen_vblank_nes(int state)
+{
+ // on rising edge
+ if (!state)
{
- if (m_io_disksel)
+ // if this is a disk system game, check for the flip-disk key
+ if ((m_cartslot && m_cartslot->exists() && (m_cartslot->get_pcb_id() == STD_DISKSYS)) // first scenario = disksys in m_cartslot (= famicom)
+ || m_disk) // second scenario = disk via fixed internal disk option (fds & famitwin)
{
- // latch this input so it doesn't go at warp speed
- if ((m_io_disksel->read() & 0x01) && (!m_last_frame_flip))
+ if (m_io_disksel)
{
- if (m_disk)
- m_disk->disk_flip_side();
- else
- m_cartslot->disk_flip_side();
- m_last_frame_flip = 1;
- }
+ // latch this input so it doesn't go at warp speed
+ if ((m_io_disksel->read() & 0x01) && (!m_last_frame_flip))
+ {
+ if (m_disk)
+ m_disk->disk_flip_side();
+ else
+ m_cartslot->disk_flip_side();
+ m_last_frame_flip = 1;
+ }
- if (!(m_io_disksel->read() & 0x01))
- m_last_frame_flip = 0;
+ if (!(m_io_disksel->read() & 0x01))
+ m_last_frame_flip = 0;
+ }
}
}
- return 0;
}
diff --git a/src/mame/video/playch10.cpp b/src/mame/video/playch10.cpp
index 990820cdfb4..c2e212b45a1 100644
--- a/src/mame/video/playch10.cpp
+++ b/src/mame/video/playch10.cpp
@@ -111,7 +111,7 @@ uint32_t playch10_state::screen_update_playch10_single(screen_device &screen, bi
if (m_pc10_game_mode)
/* render the ppu */
- m_ppu->render(bitmap, 0, 0, 0, 0);
+ m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
else
{
/* When the bios is accessing vram, the video circuitry can't access it */
@@ -129,7 +129,7 @@ uint32_t playch10_state::screen_update_playch10_top(screen_device &screen, bitma
if (!m_pc10_dispmask)
/* render the ppu */
- m_ppu->render(bitmap, 0, 0, 0, 0);
+ m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
else
bitmap.fill(0, cliprect);