mirror of
https://github.com/holub/mame
synced 2025-06-25 22:04:15 +03:00
Merge pull request #5306 from enikland2/nes_sms_gun_fix
nes, sms: Fix light gun regression
This commit is contained in:
commit
bbbc56a7f4
@ -82,9 +82,21 @@ void nes_zapper_device::device_reset()
|
|||||||
uint8_t nes_zapper_device::read_bit34()
|
uint8_t nes_zapper_device::read_bit34()
|
||||||
{
|
{
|
||||||
uint8_t ret = m_trigger->read();
|
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
|
// 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
|
// check if the cursor is over a bright pixel
|
||||||
// FIXME: still a gross hack
|
// FIXME: still a gross hack
|
||||||
|
@ -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 */
|
/* brightness of the lightgray color in the frame drawn by Light Phaser games */
|
||||||
const uint8_t sensor_min_brightness = 0x7f;
|
const uint8_t sensor_min_brightness = 0x7f;
|
||||||
|
|
||||||
|
screen().update_now();
|
||||||
color = screen().pixel(beam_x, beam_y);
|
color = screen().pixel(beam_x, beam_y);
|
||||||
|
|
||||||
/* reference: http://www.w3.org/TR/AERT#color-contrast */
|
/* reference: http://www.w3.org/TR/AERT#color-contrast */
|
||||||
|
@ -979,10 +979,13 @@ void ppu2c0x_device::update_scanline()
|
|||||||
/* Render this scanline if appropriate */
|
/* Render this scanline if appropriate */
|
||||||
if (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES))
|
if (m_regs[PPU_CONTROL1] & (PPU_CONTROL1_BACKGROUND | PPU_CONTROL1_SPRITES))
|
||||||
{
|
{
|
||||||
/* If background or sprites are enabled, copy the ppu address latch */
|
if (m_scanline_timer->remaining() == attotime::zero)
|
||||||
/* Copy only the scroll x-coarse and the x-overflow bit */
|
{
|
||||||
m_refresh_data &= ~0x041f;
|
/* If background or sprites are enabled, copy the ppu address latch */
|
||||||
m_refresh_data |= (m_refresh_latch & 0x041f);
|
/* 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);
|
// logerror("updating refresh_data: %04x (scanline: %d)\n", m_refresh_data, m_scanline);
|
||||||
render_scanline();
|
render_scanline();
|
||||||
@ -1014,23 +1017,26 @@ void ppu2c0x_device::update_scanline()
|
|||||||
bitmap.pix32(m_scanline, i) = back_pen;
|
bitmap.pix32(m_scanline, i) = back_pen;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* increment the fine y-scroll */
|
if (m_scanline_timer->remaining() == attotime::zero)
|
||||||
m_refresh_data += 0x1000;
|
|
||||||
|
|
||||||
/* if it's rolled, increment the coarse y-scroll */
|
|
||||||
if (m_refresh_data & 0x8000)
|
|
||||||
{
|
{
|
||||||
uint16_t tmp;
|
/* increment the fine y-scroll */
|
||||||
tmp = (m_refresh_data & 0x03e0) + 0x20;
|
m_refresh_data += 0x1000;
|
||||||
m_refresh_data &= 0x7c1f;
|
|
||||||
|
|
||||||
/* handle bizarro scrolling rollover at the 30th (not 32nd) vertical tile */
|
/* if it's rolled, increment the coarse y-scroll */
|
||||||
if (tmp == 0x03c0)
|
if (m_refresh_data & 0x8000)
|
||||||
m_refresh_data ^= 0x0800;
|
{
|
||||||
else
|
uint16_t tmp;
|
||||||
m_refresh_data |= (tmp & 0x03e0);
|
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)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ public:
|
|||||||
void update_scanline();
|
void update_scanline();
|
||||||
|
|
||||||
void spriteram_dma(address_space &space, const uint8_t page);
|
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);
|
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
|
|
||||||
int get_current_scanline() { return m_scanline; }
|
int get_current_scanline() { return m_scanline; }
|
||||||
|
@ -65,6 +65,7 @@ void nes_state::nes(machine_config &config)
|
|||||||
m_screen->set_size(32*8, 262);
|
m_screen->set_size(32*8, 262);
|
||||||
m_screen->set_visarea(0*8, 32*8-1, 0*8, 30*8-1);
|
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->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);
|
PPU_2C02(config, m_ppu);
|
||||||
m_ppu->set_cpu_tag(m_maincpu);
|
m_ppu->set_cpu_tag(m_maincpu);
|
||||||
|
@ -93,6 +93,7 @@ public:
|
|||||||
virtual void video_start() override;
|
virtual void video_start() override;
|
||||||
virtual void video_reset() override;
|
virtual void video_reset() override;
|
||||||
uint32_t screen_update_nes(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
uint32_t screen_update_nes(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||||
|
void screen_vblank_nes(int state);
|
||||||
|
|
||||||
void init_famicom();
|
void init_famicom();
|
||||||
|
|
||||||
|
@ -225,6 +225,16 @@ READ8_MEMBER(playch10_state::pc10_in1_r)
|
|||||||
/* no sprite hit (yet) */
|
/* no sprite hit (yet) */
|
||||||
ret |= 0x08;
|
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 */
|
/* get the pixel at the gun position */
|
||||||
rgb_t pix = m_ppu->screen().pixel(x, y);
|
rgb_t pix = m_ppu->screen().pixel(x, y);
|
||||||
|
|
||||||
|
@ -375,6 +375,16 @@ WRITE8_MEMBER(vsnes_state::gun_in0_w)
|
|||||||
|
|
||||||
uint8_t realy = (int)y;
|
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 */
|
/* get the pixel at the gun position */
|
||||||
rgb_t col = m_ppu1->screen().pixel(x, realy);
|
rgb_t col = m_ppu1->screen().pixel(x, realy);
|
||||||
uint8_t bright = col.brightness();
|
uint8_t bright = col.brightness();
|
||||||
|
@ -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)
|
uint32_t nes_state::screen_update_nes(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||||
{
|
{
|
||||||
// render the ppu
|
// render the ppu
|
||||||
m_ppu->render(bitmap, 0, 0, 0, 0);
|
m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -111,7 +111,7 @@ uint32_t playch10_state::screen_update_playch10_single(screen_device &screen, bi
|
|||||||
|
|
||||||
if (m_pc10_game_mode)
|
if (m_pc10_game_mode)
|
||||||
/* render the ppu */
|
/* render the ppu */
|
||||||
m_ppu->render(bitmap, 0, 0, 0, 0);
|
m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* When the bios is accessing vram, the video circuitry can't access it */
|
/* 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)
|
if (!m_pc10_dispmask)
|
||||||
/* render the ppu */
|
/* render the ppu */
|
||||||
m_ppu->render(bitmap, 0, 0, 0, 0);
|
m_ppu->render(bitmap, 0, 0, 0, 0, cliprect);
|
||||||
else
|
else
|
||||||
bitmap.fill(0, cliprect);
|
bitmap.fill(0, cliprect);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user