nes, sms: Fix light gun regression

This commit is contained in:
Enik Land 2019-07-02 20:51:24 -03:00
parent b1dff791ed
commit 2a664c1f23
10 changed files with 100 additions and 47 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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;
}

View File

@ -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; }

View File

@ -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);

View File

@ -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();

View File

@ -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);

View File

@ -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();

View File

@ -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);
// 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)
{
if (m_io_disksel)
{
// 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;
}
}
m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
return 0;
}
void nes_state::screen_vblank_nes(int state)
{
// on rising edge
if (!state)
{
// 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)
{
if (m_io_disksel)
{
// 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;
}
}
}
}

View File

@ -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);