mirror of
https://github.com/holub/mame
synced 2025-04-26 10:13:37 +03:00
(MESS) sms.c: Enhancements for Sega Scope and LCD persistence and fix SMS Light Phaser TH read bug. [Enik Land]
This commit is contained in:
parent
9eec05fa5d
commit
5d50b69b62
@ -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")
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -22,10 +22,10 @@ const device_type SMS_LIGHT_PHASER = &device_creator<sms_light_phaser_device>;
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -21,21 +21,21 @@ const device_type SMS_PADDLE = &device_creator<sms_paddle_device>;
|
||||
#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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -21,7 +21,7 @@ const device_type SMS_SPORTS_PAD = &device_creator<sms_sports_pad_device>;
|
||||
#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")
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user