From 5d50b69b62a010a767df56d8a2fc082fce7062d4 Mon Sep 17 00:00:00 2001 From: Wilbert Pol Date: Sun, 4 Aug 2013 20:28:30 +0000 Subject: [PATCH] (MESS) sms.c: Enhancements for Sega Scope and LCD persistence and fix SMS Light Phaser TH read bug. [Enik Land] --- src/mess/drivers/sms.c | 2 ++ src/mess/includes/sms.h | 1 + src/mess/machine/sega8_slot.c | 6 +++- src/mess/machine/sms.c | 27 +++++++++++++- src/mess/machine/sms_lphaser.c | 64 ++++++++++++++++++++-------------- src/mess/machine/sms_lphaser.h | 5 +-- src/mess/machine/sms_paddle.c | 8 ++--- src/mess/machine/sms_paddle.h | 4 +-- src/mess/machine/sms_rfu.h | 4 +-- src/mess/machine/sms_sports.c | 10 +++--- src/mess/machine/sms_sports.h | 6 ++-- 11 files changed, 91 insertions(+), 46 deletions(-) diff --git a/src/mess/drivers/sms.c b/src/mess/drivers/sms.c index 34953896923..ac86c05b1ff 100644 --- a/src/mess/drivers/sms.c +++ b/src/mess/drivers/sms.c @@ -567,6 +567,7 @@ static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base ) MCFG_PALETTE_INIT(sega315_5124) MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) + MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_ntsc_intf) MCFG_SEGA315_5124_SET_SCREEN("screen") @@ -735,6 +736,7 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) MCFG_PALETTE_INIT(sega315_5124) MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) + MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_pal_intf) MCFG_SEGA315_5124_SET_SCREEN("screen") diff --git a/src/mess/includes/sms.h b/src/mess/includes/sms.h index 700f0a7aeca..27b48e3269f 100644 --- a/src/mess/includes/sms.h +++ b/src/mess/includes/sms.h @@ -155,6 +155,7 @@ public: DECLARE_MACHINE_RESET(sms); DECLARE_VIDEO_START(gamegear); DECLARE_VIDEO_START(sms1); + DECLARE_VIDEO_RESET(sms1); UINT32 screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); UINT32 screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); diff --git a/src/mess/machine/sega8_slot.c b/src/mess/machine/sega8_slot.c index 577d5d3f03d..591207c9145 100644 --- a/src/mess/machine/sega8_slot.c +++ b/src/mess/machine/sega8_slot.c @@ -234,7 +234,7 @@ int sega8_cart_slot_device::verify_cart( UINT8 *magic, int size ) void sega8_cart_slot_device::set_lphaser_xoffset( UINT8 *rom, int size ) { - static const UINT8 signatures[6][16] = + static const UINT8 signatures[7][16] = { /* Spacegun */ { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9d, 0x99, 0x10, 0x90, 0x00, 0x40 }, @@ -248,6 +248,8 @@ void sega8_cart_slot_device::set_lphaser_xoffset( UINT8 *rom, int size ) { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x00, 0x00, 0xb7, 0x55, 0x74, 0x70, 0x00, 0x40 }, /* Assault City */ { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0xff, 0xff, 0x9f, 0x74, 0x34, 0x70, 0x00, 0x40 }, + /* Missile Defense 3-D */ + { 0x54, 0x4d, 0x52, 0x20, 0x53, 0x45, 0x47, 0x41, 0x41, 0x4c, 0x15, 0x4a, 0x01, 0x80, 0x00, 0x4f } }; int xoff = 44; @@ -269,6 +271,8 @@ void sega8_cart_slot_device::set_lphaser_xoffset( UINT8 *rom, int size ) if (!memcmp(&rom[0x7ff0], signatures[5], 16)) xoff = 47; + if (!memcmp(&rom[0x7ff0], signatures[6], 16)) + xoff = 46; } m_cart->set_lphaser_xoffs(xoff); diff --git a/src/mess/machine/sms.c b/src/mess/machine/sms.c index 6a06513c84c..45f5ee23cf3 100644 --- a/src/mess/machine/sms.c +++ b/src/mess/machine/sms.c @@ -965,6 +965,20 @@ VIDEO_START_MEMBER(sms_state,sms1) } +VIDEO_RESET_MEMBER(sms_state,sms1) +{ + if (m_port_scope->read()) + { + UINT8 sscope_binocular_hack = ioport("SSCOPE_BINOCULAR")->read(); + + if (sscope_binocular_hack & 0x01) + m_prevleft_bitmap.fill(RGB_BLACK); + if (sscope_binocular_hack & 0x02) + m_prevright_bitmap.fill(RGB_BLACK); + } +} + + READ32_MEMBER(sms_state::sms_pixel_color) { bitmap_rgb32 &vdp_bitmap = m_vdp->get_bitmap(); @@ -999,7 +1013,7 @@ UINT32 sms_state::screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap if (&screen != m_main_scr) { - sscope = m_port_scope->read_safe(0x00); + sscope = m_port_scope->read(); if (!sscope) { // without SegaScope, both LCDs for glasses go black @@ -1088,11 +1102,22 @@ UINT32 sms_state::screen_update_gamegear(screen_device &screen, bitmap_rgb32 &bi { int x, y; bitmap_rgb32 &vdp_bitmap = m_vdp->get_bitmap(); + static bool prev_bitmap_copied = false; if (!m_port_persist->read()) + { + copybitmap(bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect); + if (prev_bitmap_copied) + { + m_prev_bitmap.fill(RGB_BLACK); + prev_bitmap_copied = false; + } + } + else if (!prev_bitmap_copied) { copybitmap(bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect); copybitmap(m_prev_bitmap, vdp_bitmap, 0, 0, 0, 0, cliprect); + prev_bitmap_copied = true; } else { diff --git a/src/mess/machine/sms_lphaser.c b/src/mess/machine/sms_lphaser.c index 25d5f4273e4..24146ccc848 100644 --- a/src/mess/machine/sms_lphaser.c +++ b/src/mess/machine/sms_lphaser.c @@ -22,10 +22,10 @@ const device_type SMS_LIGHT_PHASER = &device_creator; #define LGUN_X_INTERVAL 4 -INPUT_CHANGED_MEMBER( sms_light_phaser_device::th_pin_w ) +CUSTOM_INPUT_MEMBER( sms_light_phaser_device::th_pin_r ) { - if (newval != oldval) - m_port->th_pin_w(newval); + // The returned value is inverted due to IP_ACTIVE_LOW mapping. + return ~m_sensor_last_state; } @@ -39,11 +39,11 @@ INPUT_CHANGED_MEMBER( sms_light_phaser_device::position_changed ) static INPUT_PORTS_START( sms_light_phaser ) PORT_START("CTRL_PORT") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (trigger) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, th_pin_w, 0) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_light_phaser_device, th_pin_r, NULL) PORT_BIT( 0x9f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("LPHASER_X") - PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, position_changed, 0) + PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, position_changed, 0) PORT_START("LPHASER_Y") PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, position_changed, 0) @@ -86,8 +86,14 @@ sms_light_phaser_device::sms_light_phaser_device(const machine_config &mconfig, void sms_light_phaser_device::device_start() { + save_item(NAME(m_sensor_last_state)); m_lphaser_timer = timer_alloc(TIMER_LPHASER); - m_last_state = 1; +} + + +void sms_light_phaser_device::device_reset() +{ + m_sensor_last_state = 1; // off (1) } @@ -185,24 +191,21 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int pos_changed = 1; } - if (!pos_changed) + if (pos_changed) + break; + + if (m_sensor_last_state == 0) /* sensor is on */ + { + /* keep sensor on until out of the aim area */ + result = 0; + } + else { rgb_t color; UINT8 brightness; /* brightness of the lightgray color in the frame drawn by Light Phaser games */ const UINT8 sensor_min_brightness = 0x7f; - if (m_last_state == 0) /* sensor is on */ - { - /* keep sensor on until out of the aim area */ - result = 0; - /* Set next check for when sensor will be off */ - beam_x = lgun_x + dx_radius + 1; - if (beam_x > visarea.max_x) - beam_x = visarea.max_x + 1; - break; - } - color = m_port->pixel_r(); /* reference: http://www.w3.org/TR/AERT#color-contrast */ @@ -210,13 +213,22 @@ int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int //printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y); result = (brightness >= sensor_min_brightness) ? 0 : 1; + } - /* next check at same line */ + if (result == 0) + { + /* Set next check for when sensor will be off */ + beam_x = lgun_x + dx_radius + 1; + if (beam_x > visarea.max_x) + beam_x = visarea.max_x + 1; + break; + } + else + { + /* Next check after the minimum interval */ beam_x += LGUN_X_INTERVAL; pos_changed = 1; } - else - break; } timer->adjust(m_screen->time_until_pos(beam_y, beam_x)); @@ -242,16 +254,16 @@ UINT16 sms_light_phaser_device::screen_vpos_nonscaled(int scaled_vpos) void sms_light_phaser_device::sensor_check() { - int new_state; + int sensor_new_state; const int x = screen_hpos_nonscaled(m_lphaser_x->read()); const int y = screen_vpos_nonscaled(m_lphaser_y->read()); - new_state = bright_aim_area(m_lphaser_timer, x, y); - if (new_state != m_last_state) + sensor_new_state = bright_aim_area(m_lphaser_timer, x, y); + if (sensor_new_state != m_sensor_last_state) { - m_port->th_pin_w(new_state); - m_last_state = new_state; + m_port->th_pin_w(sensor_new_state); + m_sensor_last_state = sensor_new_state; } } diff --git a/src/mess/machine/sms_lphaser.h b/src/mess/machine/sms_lphaser.h index 3f115e5f0cf..4c4e6aa085e 100644 --- a/src/mess/machine/sms_lphaser.h +++ b/src/mess/machine/sms_lphaser.h @@ -35,12 +35,13 @@ public: // optional information overrides virtual ioport_constructor device_input_ports() const; - DECLARE_INPUT_CHANGED_MEMBER( th_pin_w ); + DECLARE_CUSTOM_INPUT_MEMBER( th_pin_r ); DECLARE_INPUT_CHANGED_MEMBER( position_changed ); protected: // device-level overrides virtual void device_start(); + virtual void device_reset(); // device_sms_control_port_interface overrides virtual UINT8 peripheral_r(); @@ -50,7 +51,7 @@ private: required_ioport m_lphaser_x; required_ioport m_lphaser_y; - int m_last_state; + int m_sensor_last_state; emu_timer *m_lphaser_timer; static const device_timer_id TIMER_LPHASER = 0; diff --git a/src/mess/machine/sms_paddle.c b/src/mess/machine/sms_paddle.c index fe639a91781..ce3f1c7cde6 100644 --- a/src/mess/machine/sms_paddle.c +++ b/src/mess/machine/sms_paddle.c @@ -21,21 +21,21 @@ const device_type SMS_PADDLE = &device_creator; #define PADDLE_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/256) -DECLARE_CUSTOM_INPUT_MEMBER( sms_paddle_device::dir_pins_r ) +CUSTOM_INPUT_MEMBER( sms_paddle_device::dir_pins_r ) { UINT8 data = m_paddle_x->read(); if (m_paddle_read_state) data >>= 4; - // Return the inverted value for the PORT_BIT mapping. + // The returned value is inverted due to IP_ACTIVE_LOW mapping. return ~data; } -DECLARE_CUSTOM_INPUT_MEMBER( sms_paddle_device::tr_pin_r ) +CUSTOM_INPUT_MEMBER( sms_paddle_device::tr_pin_r ) { - // Return the inverted value for the PORT_BIT mapping. + // The returned value is inverted due to IP_ACTIVE_LOW mapping. return ~m_paddle_read_state; } diff --git a/src/mess/machine/sms_paddle.h b/src/mess/machine/sms_paddle.h index 5977c4fc937..a0d1facfa71 100644 --- a/src/mess/machine/sms_paddle.h +++ b/src/mess/machine/sms_paddle.h @@ -34,8 +34,8 @@ public: // optional information overrides virtual ioport_constructor device_input_ports() const; - CUSTOM_INPUT_MEMBER( dir_pins_r ); - CUSTOM_INPUT_MEMBER( tr_pin_r ); + DECLARE_CUSTOM_INPUT_MEMBER( dir_pins_r ); + DECLARE_CUSTOM_INPUT_MEMBER( tr_pin_r ); protected: // device-level overrides diff --git a/src/mess/machine/sms_rfu.h b/src/mess/machine/sms_rfu.h index 9ea1f09e033..78c9bf573c1 100644 --- a/src/mess/machine/sms_rfu.h +++ b/src/mess/machine/sms_rfu.h @@ -34,8 +34,8 @@ public: // optional information overrides virtual ioport_constructor device_input_ports() const; - WRITE_LINE_MEMBER(th_pin_w); - READ32_MEMBER(pixel_r); + DECLARE_WRITE_LINE_MEMBER(th_pin_w); + DECLARE_READ32_MEMBER(pixel_r); protected: // device-level overrides diff --git a/src/mess/machine/sms_sports.c b/src/mess/machine/sms_sports.c index 0fcda8d91c2..412809da8d3 100644 --- a/src/mess/machine/sms_sports.c +++ b/src/mess/machine/sms_sports.c @@ -21,7 +21,7 @@ const device_type SMS_SPORTS_PAD = &device_creator; #define SPORTS_PAD_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/512) -DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r ) +CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r ) { UINT8 data = 0xff; @@ -41,18 +41,18 @@ DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r ) break; } - // Return the inverted value for the PORT_BIT mapping. + // The returned value is inverted due to IP_ACTIVE_LOW mapping. return ~(data & 0x0f); } -DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_device::th_pin_r ) +CUSTOM_INPUT_MEMBER( sms_sports_pad_device::th_pin_r ) { return m_sports_pad_last_data; } -DECLARE_INPUT_CHANGED_MEMBER( sms_sports_pad_device::th_pin_w ) +INPUT_CHANGED_MEMBER( sms_sports_pad_device::th_pin_w ) { attotime cur_time = machine().time(); @@ -74,7 +74,7 @@ static INPUT_PORTS_START( sms_sports_pad ) PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, dir_pins_r, NULL) // Directional pins PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (Button 1) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_r, NULL) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_r, NULL) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // TR (Button 2) PORT_START("SPORTS_OUT") diff --git a/src/mess/machine/sms_sports.h b/src/mess/machine/sms_sports.h index 18b460faf22..13e31fe3fd4 100644 --- a/src/mess/machine/sms_sports.h +++ b/src/mess/machine/sms_sports.h @@ -34,9 +34,9 @@ public: // optional information overrides virtual ioport_constructor device_input_ports() const; - CUSTOM_INPUT_MEMBER( dir_pins_r ); - CUSTOM_INPUT_MEMBER( th_pin_r ); - INPUT_CHANGED_MEMBER( th_pin_w ); + DECLARE_CUSTOM_INPUT_MEMBER( dir_pins_r ); + DECLARE_CUSTOM_INPUT_MEMBER( th_pin_r ); + DECLARE_INPUT_CHANGED_MEMBER( th_pin_w ); protected: // device-level overrides